Skip to content

Commit 0da0e63

Browse files
committed
Begin to implement IfcConvert enhancements discussed in IfcOpenShell#20. Remove C++-specific getters and setters and use the same set() and get() functions in in both C++ and Python. Enhance output of IfcConvert, especially in error situations (spamming a hundred lines of options always hides the original error message), utilize Boost's foreach macro to provide cleaner iteration code.
1 parent e35cefa commit 0da0e63

File tree

14 files changed

+426
-311
lines changed

14 files changed

+426
-311
lines changed

src/ifcconvert/IfcConvert.cpp

Lines changed: 194 additions & 94 deletions
Large diffs are not rendered by default.

src/ifcconvert/OpenCascadeBasedSerializer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<double>* o) {
4343
const gp_Trsf& o_trsf = o->transformation().data();
4444
gtrsf.PreMultiply(o_trsf);
4545

46-
if (o->geometry().settings().convert_back_units()) {
46+
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
4747
gp_Trsf scale;
4848
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
4949
gtrsf.PreMultiply(scale);

src/ifcconvert/XmlSerializer.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
#include <boost/property_tree/ptree.hpp>
2323
#include <boost/property_tree/xml_parser.hpp>
24-
#include <boost/foreach.hpp>
2524
#include <boost/version.hpp>
2625

2726
#include "XmlSerializer.h"
@@ -256,16 +255,16 @@ void XmlSerializer::finalize() {
256255
ptree root, header, decomposition, properties;
257256

258257
// Write the SPF header as XML nodes.
259-
BOOST_FOREACH(const std::string& s, file->header().file_description().description()) {
258+
foreach(const std::string& s, file->header().file_description().description()) {
260259
header.add_child("file_description.description", ptree(s));
261260
}
262-
BOOST_FOREACH(const std::string& s, file->header().file_name().author()) {
261+
foreach(const std::string& s, file->header().file_name().author()) {
263262
header.add_child("file_name.author", ptree(s));
264263
}
265-
BOOST_FOREACH(const std::string& s, file->header().file_name().organization()) {
264+
foreach(const std::string& s, file->header().file_name().organization()) {
266265
header.add_child("file_name.organization", ptree(s));
267266
}
268-
BOOST_FOREACH(const std::string& s, file->header().file_schema().schema_identifiers()) {
267+
foreach(const std::string& s, file->header().file_schema().schema_identifiers()) {
269268
header.add_child("file_schema.schema_identifiers", ptree(s));
270269
}
271270
header.put("file_description.implementation_level", file->header().file_description().implementation_level());
@@ -298,4 +297,4 @@ void XmlSerializer::finalize() {
298297
boost::property_tree::xml_writer_settings<char> settings('\t', 1);
299298
#endif
300299
boost::property_tree::write_xml(xml_filename, root, std::locale(), settings);
301-
}
300+
}

src/ifcgeom/IfcGeomElement.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace IfcGeom {
4444
for(int i = 1; i < 5; ++i) {
4545
for (int j = 1; j < 4; ++j) {
4646
const double trsf_value = trsf.Value(j,i);
47-
const double matrix_value = i == 4 && settings.convert_back_units()
47+
const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS)
4848
? trsf_value / settings.unit_magnitude()
4949
: trsf_value;
5050
_data.push_back(static_cast<P>(matrix_value));

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,11 +1103,11 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
11031103
const std::string product_type = IfcSchema::Type::ToString(product->type());
11041104
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
11051105

1106-
if ( !settings.disable_opening_subtractions() && openings && openings->size() ) {
1106+
if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
11071107
IfcGeom::IfcRepresentationShapeItems opened_shapes;
11081108
try {
11091109
#if OCC_VERSION_HEX < 0x60900
1110-
const bool faster_booleans = settings.faster_booleans();
1110+
const bool faster_booleans = settings.get(IteratorSettings::FASTER_BOOLEANS);
11111111
#else
11121112
const bool faster_booleans = true;
11131113
#endif
@@ -1123,14 +1123,14 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
11231123
} catch(...) {
11241124
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product->entity);
11251125
}
1126-
if ( settings.use_world_coords() ) {
1126+
if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
11271127
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
11281128
it->prepend(trsf);
11291129
}
11301130
trsf = gp_Trsf();
11311131
}
11321132
shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), opened_shapes);
1133-
} else if ( settings.use_world_coords() ) {
1133+
} else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
11341134
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
11351135
it->prepend(trsf);
11361136
}

src/ifcgeom/IfcGeomIterator.h

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ namespace IfcGeom {
8686
template <typename P>
8787
class Iterator {
8888
private:
89+
Iterator(const Iterator&); // N/I
90+
Iterator& operator=(const Iterator&); // N/I
91+
8992
Kernel kernel;
9093
IteratorSettings settings;
9194

@@ -121,6 +124,7 @@ namespace IfcGeom {
121124
}
122125
}
123126

127+
std::set<boost::regex> names_to_include_or_exclude; // regex containing a name or a wildcard expression
124128
std::set<IfcSchema::Type::Enum> entities_to_include_or_exclude;
125129
bool include_entities_in_processing;
126130

@@ -148,7 +152,7 @@ namespace IfcGeom {
148152
} catch (...) {}
149153

150154
std::set<std::string> context_types;
151-
if (!settings.exclude_solids_and_surfaces()) {
155+
if (!settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
152156
// Really this should only be 'Model', as per
153157
// the standard 'Design' is deprecated. So,
154158
// just for backwards compatibility:
@@ -157,7 +161,7 @@ namespace IfcGeom {
157161
// DDS likes to output 'model view'
158162
context_types.insert("model view");
159163
}
160-
if (settings.include_curves()) {
164+
if (settings.get(IteratorSettings::INCLUDE_CURVES)) {
161165
context_types.insert("plan");
162166
}
163167

@@ -250,36 +254,46 @@ namespace IfcGeom {
250254
return true;
251255
}
252256

253-
int progress() {
254-
return 100 * done / total;
255-
}
257+
int progress() const { return 100 * done / total; }
256258

257-
const std::string& getUnitName() {
258-
return unit_name;
259-
}
259+
const std::string& getUnitName() const { return unit_name; }
260260

261-
const P getUnitMagnitude() {
262-
return unit_magnitude;
263-
}
261+
P getUnitMagnitude() const { return unit_magnitude; }
264262

265-
const std::string getLog() {
266-
return Logger::GetLog();
267-
}
263+
std::string getLog() const { return Logger::GetLog(); }
268264

269-
IfcParse::IfcFile* getFile() {
270-
return ifc_file;
271-
}
265+
IfcParse::IfcFile* getFile() const { return ifc_file; }
272266

267+
/// @note Entity names are handled case-insensitively.
273268
void includeEntities(const std::set<std::string>& entities) {
274269
populate_set(entities);
275270
include_entities_in_processing = true;
276271
}
277272

273+
/// @note Entity names are handled case-insensitively.
278274
void excludeEntities(const std::set<std::string>& entities) {
279275
populate_set(entities);
280276
include_entities_in_processing = false;
281277
}
282278

279+
// Arbitrary names or wildcard expressions are handled case-sensitively.
280+
void include_entity_names(const std::vector<std::string>& names)
281+
{
282+
names_to_include_or_exclude.clear();
283+
foreach(const std::string &name, names)
284+
names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name));
285+
include_entities_in_processing = true;
286+
}
287+
288+
// Arbitrary names or wildcard expressions are handled case-sensitively.
289+
void exclude_entity_names(const std::vector<std::string>& names)
290+
{
291+
names_to_include_or_exclude.clear();
292+
foreach(const std::string &name, names)
293+
names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name));
294+
include_entities_in_processing = false;
295+
}
296+
283297
private:
284298
// Move to the next IfcRepresentation
285299
void _nextShape() {
@@ -330,6 +344,14 @@ namespace IfcGeom {
330344
break;
331345
}
332346
}
347+
348+
foreach(const boost::regex& r, names_to_include_or_exclude) {
349+
if (boost::regex_match((*it)->Name(), r)) {
350+
found = true;
351+
break;
352+
}
353+
}
354+
333355
if (found == include_entities_in_processing) {
334356
ifcproducts->push(*jt);
335357
}
@@ -382,13 +404,17 @@ namespace IfcGeom {
382404
return create();
383405
}
384406

385-
Element<P>* get() {
386-
// TODO: Test settings and throw
387-
if (current_triangulation) return current_triangulation;
388-
else if (current_serialization) return current_serialization;
389-
else if (current_shape_model) return current_shape_model;
390-
else return 0;
391-
}
407+
/// Gets or takes the representation of the current geometrical entity.
408+
/// @param take_ownership Pass in 'true' as if wishing to maintain the element lifetime yourself.
409+
Element<P>* get(bool take_ownership = false)
410+
{
411+
// TODO: Test settings and throw
412+
Element<P>* ret = 0;
413+
if (current_triangulation) { ret = current_triangulation; if (take_ownership) current_triangulation = 0; }
414+
else if (current_serialization) { ret = current_serialization; if (take_ownership) current_serialization = 0; }
415+
else if (current_shape_model) { ret = current_shape_model; if (take_ownership) current_shape_model = 0; }
416+
return ret;
417+
}
392418

393419
const Element<P>* getObject(int id) {
394420

@@ -430,12 +456,12 @@ namespace IfcGeom {
430456
current_shape_model = create_shape_model_for_next_entity();
431457
} catch (...) {}
432458
if (!current_shape_model) return false;
433-
if (settings.use_brep_data()) {
459+
if (settings.get(IteratorSettings::USE_BREP_DATA)) {
434460
try {
435461
current_serialization = new SerializedElement<P>(*current_shape_model);
436462
} catch (...) {}
437463
return !!current_serialization;
438-
} else if (!settings.disable_triangulation()) {
464+
} else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) {
439465
try {
440466
current_triangulation = new TriangulationElement<P>(*current_shape_model);
441467
} catch (...) {}
@@ -457,8 +483,8 @@ namespace IfcGeom {
457483
unit_name = "METER";
458484
unit_magnitude = 1.f;
459485

460-
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1);
461-
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.));
486+
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
487+
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
462488
}
463489

464490
bool owns_ifc_file;

0 commit comments

Comments
 (0)