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
+16 -4
View File
@@ -357,6 +357,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d
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) {
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
@@ -372,12 +376,20 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& t
trsf.PreMultiply(trsf2);
}
if ( current->hasPlacementRelTo() ) {
IfcSchema::IfcObjectPlacement* relto = current->PlacementRelTo();
if ( relto->is(IfcSchema::Type::IfcLocalPlacement) )
IfcSchema::IfcObjectPlacement* parent = current->PlacementRelTo();
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();
else break;
else break;
} else break;
}
CACHE(IfcObjectPlacement,l,trsf)
return true;
}
}