Site local placement (#240)

* ifcgeom: Add placement_rel_to for convert()

Change geometry conversion in `convert()` for `ObjectPlacement` such
that we can stop the `PlacementRelTo()` recursion when we hit an
`ObjectPlacement` that places a certain type, e.g. a `IfcSite'.

Introduce a new IteratorSetting `SITE_LOCAL_PLACEMENT` which will be
exposed in `IfcConvert`.

* IfcConvert: Add --site-local-placement

Some IFC authoring tools may put the global origo at a large distance
away from the actual building geometry. Also, the global X- and Y-axes
may be at arbitrary angles with natural building axes. Using
--center-model or --model-offset may place the converted geometry closer
to origo, but will still use the global IFC definition of axis
directions. Also, in a scenario with multiple IFC files for one
construction site, using --center-model on each of them would not
generate consistent geometry across OBJ or DAE files.

Solve this by introducing --site-local-placement which will disregard
the ObjectPlacement at the IfcSite level.
This commit is contained in:
Anders Granskogen Bjørnstad
2017-08-19 17:21:10 +02:00
committed by Thomas Krijnen
parent 7bea054c1e
commit 475b8554a8
5 changed files with 39 additions and 5 deletions
+10
View File
@@ -293,6 +293,9 @@ int main(int argc, char** argv)
"all placements as an offset. Applicable for OBJ and DAE output.") "all placements as an offset. Applicable for OBJ and DAE output.")
("model-offset", po::value<std::string>(&offset_str), ("model-offset", po::value<std::string>(&offset_str),
"Applies an arbitrary offset of form 'x;y;z' to all placements. Applicable for OBJ and DAE output.") "Applies an arbitrary offset of form 'x;y;z' to all placements. Applicable for OBJ and DAE output.")
("site-local-placement",
"Place elements locally in the IfcSite coordinate system, instead of placing "
"them in the IFC global coords. Applicable for OBJ and DAE output.")
("precision", po::value<short>(&precision)->default_value(SerializerSettings::DEFAULT_PRECISION), ("precision", po::value<short>(&precision)->default_value(SerializerSettings::DEFAULT_PRECISION),
"Sets the precision to be used to format floating-point values, 15 by default. " "Sets the precision to be used to format floating-point values, 15 by default. "
"Use a negative value to use the system's default precision (should be 6 typically). " "Use a negative value to use the system's default precision (should be 6 typically). "
@@ -364,6 +367,7 @@ int main(int argc, char** argv)
const bool no_normals = vmap.count("no-normals") != 0 ; const bool no_normals = vmap.count("no-normals") != 0 ;
const bool center_model = vmap.count("center-model") != 0 ; const bool center_model = vmap.count("center-model") != 0 ;
const bool model_offset = vmap.count("model-offset") != 0 ; const bool model_offset = vmap.count("model-offset") != 0 ;
const bool site_local_placement = vmap.count("site-local-placement") != 0 ;
const bool generate_uvs = vmap.count("generate-uvs") != 0 ; const bool generate_uvs = vmap.count("generate-uvs") != 0 ;
#ifdef HAVE_ICU #ifdef HAVE_ICU
@@ -496,6 +500,7 @@ int main(int argc, char** argv)
settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals); settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals);
settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs); settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs);
settings.set(IfcGeom::IteratorSettings::SEARCH_FLOOR, use_element_hierarchy); settings.set(IfcGeom::IteratorSettings::SEARCH_FLOOR, use_element_hierarchy);
settings.set(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT, site_local_placement);
settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names); settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names);
settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids); settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids);
@@ -602,6 +607,11 @@ int main(int argc, char** argv)
if (center_model || model_offset) { if (center_model || model_offset) {
double* offset = serializer->settings().offset; double* offset = serializer->settings().offset;
if (center_model) { if (center_model) {
if (site_local_placement) {
Logger::Error("Cannot use --center-model together with --site-local-placement");
delete serializer;
return EXIT_FAILURE;
}
gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5; gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5;
offset[0] = -center.X(); offset[0] = -center.X();
offset[1] = -center.Y(); offset[1] = -center.Y();
+7
View File
@@ -99,6 +99,10 @@ private:
std::map<int, SurfaceStyle> style_cache; std::map<int, SurfaceStyle> style_cache;
const SurfaceStyle* internalize_surface_style(const std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*>& shading_style); const SurfaceStyle* internalize_surface_style(const std::pair<IfcSchema::IfcSurfaceStyle*, IfcSchema::IfcSurfaceStyleShading*>& shading_style);
// For stopping PlacementRelTo recursion in convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf)
IfcSchema::Type::Enum placement_rel_to;
public: public:
Kernel() Kernel()
: deflection_tolerance(0.001) : deflection_tolerance(0.001)
@@ -109,6 +113,7 @@ public:
, ifc_planeangle_unit(-1.0) , ifc_planeangle_unit(-1.0)
, modelling_precision(0.00001) , modelling_precision(0.00001)
, dimensionality(1.) , dimensionality(1.)
, placement_rel_to(IfcSchema::Type::UNDEFINED)
{} {}
Kernel(const Kernel& other) { Kernel(const Kernel& other) {
@@ -313,6 +318,8 @@ public:
#endif #endif
} }
void set_conversion_placement_rel_to(IfcSchema::Type::Enum type);
#include "IfcRegisterGeomHeader.h" #include "IfcRegisterGeomHeader.h"
}; };
+16 -4
View File
@@ -357,6 +357,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d
return true; return true;
} }
void IfcGeom::Kernel::set_conversion_placement_rel_to(IfcSchema::Type::Enum type) {
placement_rel_to = type;
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) { bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& trsf) {
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf) IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) { if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
@@ -372,12 +376,20 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& t
trsf.PreMultiply(trsf2); trsf.PreMultiply(trsf2);
} }
if ( current->hasPlacementRelTo() ) { if ( current->hasPlacementRelTo() ) {
IfcSchema::IfcObjectPlacement* relto = current->PlacementRelTo(); IfcSchema::IfcObjectPlacement* parent = current->PlacementRelTo();
if ( relto->is(IfcSchema::Type::IfcLocalPlacement) ) IfcSchema::IfcProduct::list::ptr parentPlaces = parent->PlacesObject();
bool parentPlacesType = false;
for ( IfcSchema::IfcProduct::list::it iter = parentPlaces->begin();
iter != parentPlaces->end(); ++iter) {
if ( (*iter)->is(placement_rel_to) ) parentPlacesType = true;
}
if ( parentPlacesType ) break;
else if ( parent->is(IfcSchema::Type::IfcLocalPlacement) )
current = (IfcSchema::IfcLocalPlacement*)current->PlacementRelTo(); current = (IfcSchema::IfcLocalPlacement*)current->PlacementRelTo();
else break; else break;
} else break; } else break;
} }
CACHE(IfcObjectPlacement,l,trsf) CACHE(IfcObjectPlacement,l,trsf)
return true; return true;
} }
+3
View File
@@ -755,6 +755,9 @@ namespace IfcGeom {
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1); kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES)
? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
kernel.set_conversion_placement_rel_to(IfcSchema::Type::IfcSite);
}
} }
bool owns_ifc_file; bool owns_ifc_file;
+3 -1
View File
@@ -80,8 +80,10 @@ namespace IfcGeom
APPLY_LAYERSETS = 1 << 13, APPLY_LAYERSETS = 1 << 13,
/// Search for a parent of type IfcBuildingStorey for each representation /// Search for a parent of type IfcBuildingStorey for each representation
SEARCH_FLOOR = 1 << 14, SEARCH_FLOOR = 1 << 14,
///
SITE_LOCAL_PLACEMENT = 1 << 15,
/// Number of different setting flags. /// Number of different setting flags.
NUM_SETTINGS = 14 NUM_SETTINGS = 15
}; };
/// Used to store logical OR combination of setting flags. /// Used to store logical OR combination of setting flags.
typedef unsigned SettingField; typedef unsigned SettingField;