Skip to content

Commit d46dfb6

Browse files
committed
Work on serializers
1 parent 830a03f commit d46dfb6

9 files changed

Lines changed: 145 additions & 128 deletions

File tree

src/ifcconvert/ColladaSerializer.cpp

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
#include <string>
3333
#include <cmath>
3434

35-
using namespace IfcSchema;
36-
3735
static std::string& collada_id(std::string& s)
3836
{
3937
IfcUtil::sanitate_material_name(s);
@@ -431,31 +429,22 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
431429
}
432430

433431
std::string ColladaSerializer::ColladaExporter::differentiateSlabTypes(const IfcGeom::TriangulationElement<real_t>* o) {
434-
IfcSlab* slab = (IfcSlab*)o->product();
435432
std::string result;
436-
switch (slab->PredefinedType())
437-
{
438-
case (IfcSlabTypeEnum::IfcSlabType_FLOOR):
439-
result = "_Floor";
440-
break;
441-
case (IfcSlabTypeEnum::IfcSlabType_ROOF):
442-
result = "_Roof";
443-
break;
444-
case (IfcSlabTypeEnum::IfcSlabType_LANDING):
445-
result = "_Landing";
446-
break;
447-
case (IfcSlabTypeEnum::IfcSlabType_BASESLAB):
448-
result = "_BaseSlab";
449-
break;
450-
case (IfcSlabTypeEnum::IfcSlabType_NOTDEFINED):
451-
result = "_NotDefined";
452-
break;
453-
default:
454-
if (slab->hasObjectType()) { result = "_" + slab->ObjectType(); }
455-
else { result = "_Unknown"; }
456-
break;
433+
434+
if (!o->product()->get("ObjectType")->isNull()) {
435+
const std::string object_type = *o->product()->get("ObjectType");
436+
result = "_" + object_type;
437+
} else {
438+
result = "_Unknown";
457439
}
440+
441+
const std::string slabtype = *o->product()->get("PredefinedType");
442+
if (slabtype != "NOTDEFINED" && slabtype != "USERDEFINED") {
443+
result = "_" + slabtype;
444+
}
445+
458446
collada_id(result);
447+
459448
return result;
460449
}
461450

src/ifcconvert/IfcConvert.cpp

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace po = boost::program_options;
5656

5757
void print_version()
5858
{
59-
std::cout << "IfcOpenShell " << IfcSchema::Identifier << " IfcConvert " << IFCOPENSHELL_VERSION << " (OCC " << OCC_VERSION_STRING_EXT << ")\n";
59+
std::cout << "IfcOpenShell " << " IfcConvert " << IFCOPENSHELL_VERSION << " (OCC " << OCC_VERSION_STRING_EXT << ")\n";
6060
}
6161

6262
void print_usage(bool suggest_help = true)
@@ -116,6 +116,7 @@ static std::stringstream log_stream;
116116
void write_log();
117117

118118
/// @todo make the filters non-global
119+
/*
119120
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
120121
IfcGeom::layer_filter layer_filter;
121122
const std::string NAME_ARG = "Name", GUID_ARG = "GlobalId", DESC_ARG = "Description", TAG_ARG = "Tag";
@@ -147,6 +148,7 @@ struct exclusion_traverse_filter : public geom_filter { exclusion_traverse_filte
147148
size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&);
148149
void parse_filter(geom_filter &, const std::vector<std::string>&);
149150
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
151+
*/
150152

151153
bool init_input_file(const std::string& filename, IfcParse::IfcFile& ifc_file, bool no_progress, bool mmap);
152154

@@ -170,11 +172,13 @@ int main(int argc, char** argv)
170172

171173

172174
double deflection_tolerance;
173-
inclusion_filter include_filter;
175+
/*
176+
inclusion_filter include_filter;
174177
inclusion_traverse_filter include_traverse_filter;
175178
exclusion_filter exclude_filter;
176179
exclusion_traverse_filter exclude_traverse_filter;
177180
std::string filter_filename;
181+
*/
178182

179183
po::options_description geom_options("Geometry options");
180184
geom_options.add_options()
@@ -190,7 +194,7 @@ int main(int argc, char** argv)
190194
"vector will only contain unique xyz-triplets. This results in a "
191195
"manifold mesh which is useful for modelling applications, but might "
192196
"result in unwanted shading artefacts in rendering applications.")
193-
("use-world-coords",
197+
("use-world-coords",
194198
"Specifies whether to apply the local placements of building elements "
195199
"directly to the coordinates of the representation mesh rather than "
196200
"to represent the local placement in the 4x3 matrix, which will in that "
@@ -199,7 +203,7 @@ int main(int argc, char** argv)
199203
"Specifies whether to convert back geometrical output back to the "
200204
"unit of measure in which it is defined in the IFC file. Default is "
201205
"to use meters.")
202-
("sew-shells",
206+
("sew-shells",
203207
"Specifies whether to sew the faces of IfcConnectedFaceSets together. "
204208
"This is a potentially time consuming operation, but guarantees a "
205209
"consistent orientation of surface normals, even if the faces are not "
@@ -209,53 +213,56 @@ int main(int argc, char** argv)
209213
// arguments where not introduced yet and a work-around was implemented to
210214
// subtract multiple openings as a single compound. This hack is obsolete
211215
// for newer versions of Open CASCADE.
212-
("merge-boolean-operands",
216+
("merge-boolean-operands",
213217
"Specifies whether to merge all IfcOpeningElement operands into a single "
214218
"operand before applying the subtraction operation. This may "
215219
"introduce a performance improvement at the risk of failing, in "
216220
"which case the subtraction is applied one-by-one.")
217221
#endif
218-
("disable-opening-subtractions",
222+
("disable-opening-subtractions",
219223
"Specifies whether to disable the boolean subtraction of "
220224
"IfcOpeningElement Representations from their RelatingElements.")
221-
("enable-layerset-slicing",
225+
("enable-layerset-slicing",
222226
"Specifies whether to enable the slicing of products according "
223227
"to their associated IfcMaterialLayerSet.")
224-
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
225-
"Specifies that the entities that match a specific filtering criteria are to be included in the geometrical output:\n"
226-
"1) 'entities': the following list of types should be included. SVG output defaults "
227-
"to IfcSpace to be included. The entity names are handled case-insensitively.\n"
228-
"2) 'layers': the entities that are assigned to presentation layers of which names "
229-
"match the given values should be included.\n"
230-
"3) 'arg <ArgumentName>': the following list of values for that specific argument should be included. "
231-
"Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n"
232-
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
233-
"--include and --exclude cannot be placed right before input file argument and "
234-
"only single of each argument supported for now. See also --exclude.")
235-
("include+", po::value<inclusion_traverse_filter>(&include_traverse_filter)->multitoken(),
236-
"Same as --include but applies filtering also to the decomposition and/or containment (IsDecomposedBy, "
237-
"HasOpenings, FillsVoid, ContainedInStructure) of the filtered entity, e.g. --include+=arg Name \"Level 1\" "
238-
"includes entity with name \"Level 1\" and all of its children. See --include for more information. ")
239-
("exclude", po::value<exclusion_filter>(&exclude_filter)->multitoken(),
240-
"Specifies that the entities that match a specific filtering criteria are to be excluded in the geometrical output."
241-
"See --include for syntax and more details. The default value is '--exclude=entities IfcOpeningElement IfcSpace'.")
242-
("exclude+", po::value<exclusion_traverse_filter>(&exclude_traverse_filter)->multitoken(),
243-
"Same as --exclude but applies filtering also to the decomposition and/or containment "
244-
"of the filtered entity. See --include+ for more details.")
245-
("no-normals",
246-
"Disables computation of normals. Saves time and file size and is useful "
247-
"in instances where you're going to recompute normals for the exported "
248-
"model in other modelling application in any case.")
249-
("deflection-tolerance", po::value<double>(&deflection_tolerance)->default_value(1e-3),
250-
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
251-
("generate-uvs",
252-
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
253-
"Not guaranteed to work properly if used with --weld-vertices.")
254-
("filter-file", po::value<std::string>(&filter_filename),
255-
"Specifies a filter file that describes the used filtering criteria. Supported formats "
256-
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters."
257-
"Multiple filters of same type with different values can be inserted on their own lines. "
258-
"See --include, --include+, --exclude, and --exclude+ for more details.");
228+
/*
229+
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
230+
"Specifies that the entities that match a specific filtering criteria are to be included in the geometrical output:\n"
231+
"1) 'entities': the following list of types should be included. SVG output defaults "
232+
"to IfcSpace to be included. The entity names are handled case-insensitively.\n"
233+
"2) 'layers': the entities that are assigned to presentation layers of which names "
234+
"match the given values should be included.\n"
235+
"3) 'arg <ArgumentName>': the following list of values for that specific argument should be included. "
236+
"Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n"
237+
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
238+
"--include and --exclude cannot be placed right before input file argument and "
239+
"only single of each argument supported for now. See also --exclude.")
240+
("include+", po::value<inclusion_traverse_filter>(&include_traverse_filter)->multitoken(),
241+
"Same as --include but applies filtering also to the decomposition and/or containment (IsDecomposedBy, "
242+
"HasOpenings, FillsVoid, ContainedInStructure) of the filtered entity, e.g. --include+=arg Name \"Level 1\" "
243+
"includes entity with name \"Level 1\" and all of its children. See --include for more information. ")
244+
("exclude", po::value<exclusion_filter>(&exclude_filter)->multitoken(),
245+
"Specifies that the entities that match a specific filtering criteria are to be excluded in the geometrical output."
246+
"See --include for syntax and more details. The default value is '--exclude=entities IfcOpeningElement IfcSpace'.")
247+
("exclude+", po::value<exclusion_traverse_filter>(&exclude_traverse_filter)->multitoken(),
248+
"Same as --exclude but applies filtering also to the decomposition and/or containment "
249+
"of the filtered entity. See --include+ for more details.")
250+
("filter-file", po::value<std::string>(&filter_filename),
251+
"Specifies a filter file that describes the used filtering criteria. Supported formats "
252+
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters."
253+
"Multiple filters of same type with different values can be inserted on their own lines. "
254+
"See --include, --include+, --exclude, and --exclude+ for more details.");
255+
*/
256+
("no-normals",
257+
"Disables computation of normals. Saves time and file size and is useful "
258+
"in instances where you're going to recompute normals for the exported "
259+
"model in other modelling application in any case.")
260+
("deflection-tolerance", po::value<double>(&deflection_tolerance)->default_value(1e-3),
261+
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
262+
("generate-uvs",
263+
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
264+
"Not guaranteed to work properly if used with --weld-vertices.");
265+
259266

260267
std::string bounds, offset_str;
261268
#ifdef HAVE_ICU
@@ -456,6 +463,7 @@ int main(int argc, char** argv)
456463
return exit_code;
457464
}
458465

466+
/*
459467
if (!filter_filename.empty()) {
460468
size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter);
461469
if (num_filters) {
@@ -465,7 +473,7 @@ int main(int argc, char** argv)
465473
return EXIT_FAILURE;
466474
}
467475
}
468-
476+
469477
/// @todo Clean up this filter code further.
470478
std::vector<geom_filter> used_filters;
471479
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }
@@ -485,6 +493,7 @@ int main(int argc, char** argv)
485493
if (!name_filter.values.empty()) { name_filter.update_description(); Logger::Notice(name_filter.description); }
486494
if (!desc_filter.values.empty()) { desc_filter.update_description(); Logger::Notice(desc_filter.description); }
487495
if (!tag_filter.values.empty()) { tag_filter.update_description(); Logger::Notice(tag_filter.description); }
496+
*/
488497

489498
SerializerSettings settings;
490499
/// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn.
@@ -588,7 +597,7 @@ int main(int argc, char** argv)
588597
return EXIT_FAILURE;
589598
}
590599

591-
IfcGeom::Iterator<real_t> context_iterator(settings, &ifc_file, filter_funcs);
600+
IfcGeom::Iterator<real_t> context_iterator(settings, &ifc_file);
592601
if (!context_iterator.initialize()) {
593602
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
594603
/// and for a case we found no entities that satisfy our filtering criteria.
@@ -599,10 +608,10 @@ int main(int argc, char** argv)
599608
return EXIT_FAILURE;
600609
}
601610

602-
serializer->setFile(context_iterator.getFile());
611+
serializer->setFile(context_iterator.file());
603612

604613
if (convert_back_units) {
605-
serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast<float>(context_iterator.getUnitMagnitude()));
614+
serializer->setUnitNameAndMagnitude(context_iterator.unit_name(), static_cast<float>(context_iterator.unit_magnitude()));
606615
} else {
607616
serializer->setUnitNameAndMagnitude("METER", 1.0f);
608617
}
@@ -619,10 +628,13 @@ int main(int argc, char** argv)
619628
delete serializer;
620629
return EXIT_FAILURE;
621630
}
631+
throw std::runtime_error("needs more work");
632+
/*
622633
gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5;
623634
offset[0] = -center.X();
624635
offset[1] = -center.Y();
625636
offset[2] = -center.Z();
637+
*/
626638
} else {
627639
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
628640
std::cerr << "[Error] Invalid use of --model-offset\n";
@@ -716,16 +728,17 @@ void write_log() {
716728
}
717729
}
718730

719-
bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file, bool no_progress, bool mmap)
720-
{
731+
bool init_input_file(const std::string& filename, IfcParse::IfcFile* ifc_file, bool no_progress, bool mmap) {
732+
721733
// Prevent IfcFile::Init() prints by setting output to null temporarily
722734
if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
723735

724736
#ifdef USE_MMAP
725-
if (!ifc_file.Init(filename, mmap)) {
737+
ifc_file = new IfcParse::IfcFile(filename, mmap);
726738
#else
727739
(void)mmap;
728-
if (!ifc_file.Init(filename)) {
740+
ifc_file = new IfcParse::IfcFile(filename);
741+
if (!ifc_file->good()) {
729742
#endif
730743
Logger::Error("Unable to parse input file '" + filename + "'");
731744
return false;
@@ -734,8 +747,10 @@ bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file, b
734747
if (no_progress) { Logger::SetOutput(&std::cout, &log_stream); }
735748

736749
return true;
750+
737751
}
738752

753+
/*
739754
bool append_filter(const std::string& type, const std::vector<std::string>& values, geom_filter& filter)
740755
{
741756
geom_filter temp;
@@ -928,3 +943,4 @@ std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& fil
928943
929944
return filter_funcs;
930945
}
946+
*/

src/ifcconvert/OpenCascadeBasedSerializer.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <cstdio>
2323

2424
#include <Standard_Version.hxx>
25+
#include <BRepBuilderAPI_Transform.hxx>
2526

2627
#include "OpenCascadeBasedSerializer.h"
2728

@@ -34,23 +35,16 @@ bool OpenCascadeBasedSerializer::ready() {
3435
}
3536

3637
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<real_t>* o) {
37-
for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) {
38-
gp_GTrsf gtrsf = it->Placement();
38+
TopoDS_Shape compound = o->geometry().as_compound();
3939

40-
const gp_Trsf& o_trsf = o->transformation().data();
41-
gtrsf.PreMultiply(o_trsf);
42-
43-
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
44-
gp_Trsf scale;
45-
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
46-
gtrsf.PreMultiply(scale);
47-
}
40+
if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) {
41+
gp_Trsf scale;
42+
scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude());
4843

49-
const TopoDS_Shape& s = it->Shape();
50-
const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, gtrsf);
51-
52-
writeShape(moved_shape);
44+
compound = BRepBuilderAPI_Transform(compound, scale, true).Shape();
5345
}
46+
47+
writeShape(compound);
5448
}
5549

5650
#define RATHER_SMALL (1e-3)

0 commit comments

Comments
 (0)