Replies: 1 comment 1 reply
-
Thanks for the detailed write up. One other thing we can do is go backwards over the unnamed implicit inverse associated with the Segments attribute. Lookup the index in those Segments from the 'parent' and keep note of the segment following that. See code sketch below: taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
// @todo: rb figure out what to do with the zero length segments at the end of compound curves
IfcSchema::IfcCurveSegment* next = nullptr;
auto compcurves = inst->data().getInverse(&IfcSchema::IfcCompositeCurve::Class(), 0);
if (compcurves && compcurves->size() == 1) {
auto segments = (*compcurves->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments();
bool emit_next = false;
for (auto& s : *segments) {
if (emit_next) {
next = s->as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
}
} In case there are multiple composite curves using the same segments that wouldn't work, because we can never recover the context in which the segment is being processed. This, as opposed to the approach you are presenting. One downside of the approach you are presenting is that it will likely become harder again to get the representation of a single IfcAlignmentSegment represented by an IfcCurveSegment directly, because in this case the call stack does not include evaluating the composite. So I would propose this inverse lookup approach for now, as is that it is a little bit less intrusive and that there might be other cases where some sort of context is passed to the mapping function. I was thinking about using something like bgl named_parameters for that https://www.boost.org/doc/libs/1_83_0/libs/graph/doc/bgl_named_params.html |
Beta Was this translation helpful? Give feedback.
-
@aothms @civilx64
It looks like there is an architecture problem with v0.8 for mapping IfcCurveSegment for IfcCompositeCurve, IfcGradientCurve, and IfcSegmentedReferenceCurve.
As I understand the spec, and supported by discussions (buildingSMART/IFC4.3.x-development#702), the IfcCurveSegment.Placement of one segment defines the end point of the previous IfcCurveSegment, which leads to the need for a zero-length segment at the end of the curve. Numeric errors in the generated geometry can be corrected knowing the expected end point.
For IfcSegmentReferenceCurve, the cant vertical deviation and rate of rotation is defined by the IfcCurveSegment.Placement for each consecutive segment pair. For cant
To support this, I think that
mapping::map_impl(const IfcSchema::IfcCurveSegment* inst)
needs to have two parameters,mapping::map_impl(const IfcSchema::IfcCurveSegment* inst,const IfcSchema::IfcCurveSegment* next_inst)
The
mapping::map_impl
method for IfcCompositeCurve, IfcGradientCurve, and (under construction) IfcSegmentedReferenceCurve all have a loop that traverses the individual IfcCurveSegment entities composing the curveIfcOpenShell/src/ifcgeom/mapping/IfcGradientCurve.cpp
Lines 32 to 47 in 2a53911
This loop may need to be changed to something like this pseudo-code,
However,
map
is defined as a pure-virtual method inabstract_mapping
.A solution could be to add a mapping function declaration to abstract_mapping that takes two parameters (maybe call it map_adjacement or map_related or just overload map).
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*,const IfcUtil::IfcBaseInterface*) = 0;
Then implement in
mapping
asbind_pair_convert_impl.i would be similar to bind_convert_impl.i except that
item = map_impl(inst->as<IfcSchema::T>());
would becomeitem = map_impl(inst->as<IfcSchema::T>(),next_inst->as<IfcSchema::T>());
A new
bind_pair_convert_decl.i
is then neededAnd a new
mapping_pair.i
is needed, removingBIND(IfcCurveSegment);
from mapping.iWhat do you think?
Beta Was this translation helpful? Give feedback.
All reactions