diff --git a/src/ifcgeom/mapping/IfcCurveSegment.cpp b/src/ifcgeom/mapping/IfcCurveSegment.cpp index 1ca2e1b56f..73d2a555a3 100644 --- a/src/ifcgeom/mapping/IfcCurveSegment.cpp +++ b/src/ifcgeom/mapping/IfcCurveSegment.cpp @@ -55,8 +55,10 @@ double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_ return fabs(clothoid->ClothoidConstant()*sqrt(PI))*param_value; } else if (auto circ = crv->as()) { return circ->Radius() * param_value; +#ifdef SCHEMA_HAS_IfcPolynomialCurve } else if (auto poly = crv->as()) { return param_value; +#endif } else { throw std::runtime_error("Unsupported curve measure type"); } @@ -75,7 +77,9 @@ double translate_if_param_value(const IfcSchema::IfcCurve* crv, IfcSchema::IfcCu typedef boost::mpl::vector< IfcSchema::IfcLine , IfcSchema::IfcCircle +#ifdef SCHEMA_HAS_IfcPolynomialCurve , IfcSchema::IfcPolynomialCurve +#endif #ifdef SCHEMA_HAS_IfcClothoid , IfcSchema::IfcClothoid #endif @@ -198,8 +202,12 @@ class curve_segment_evaluator { inst_(inst), length_unit_(length_unit), parent_curve_(inst->ParentCurve()) { - +#ifdef SCHEMA_IfcCurveSegment_HAS_UsingCurves auto composite_curves = inst->UsingCurves(); +#else + aggregate_of::ptr composite_curves; + throw std::runtime_error("Schema not supported"); +#endif // Find the next segment after inst const IfcSchema::IfcCurveSegment* next_inst = nullptr; @@ -245,17 +253,23 @@ class curve_segment_evaluator { segment_type_ = is_horizontal ? ST_HORIZONTAL : is_vertical ? ST_VERTICAL : is_cant ? ST_CANT : ST_HORIZONTAL; - +#ifdef SCHEMA_IfcCurveSegment_HAS_SegmentStart start_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentStart()) * length_unit; +#else + throw std::runtime_error("Schema not supported"); +#endif length_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentLength()) * length_unit; projected_length_ = length_; // initialize with something reasonable if (inst) { +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement curve_segment_placement_ = taxonomy::cast(mapping_->map(inst->Placement()))->ccomponents(); +#endif } - if (next_inst) { +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement next_segment_placement_ = taxonomy::cast(mapping_->map(next_inst->Placement()))->ccomponents(); +#endif } else { // there is not a next segment, however IfcGradientCurve and IfcSegmentReferenceCurve have an // optional EndPoint which services the same purpose as the zero-length last segment. @@ -264,7 +278,9 @@ class curve_segment_evaluator { auto& cc = *(composite_curves)->begin(); if (segment_type_ == ST_VERTICAL) { auto gradient_curve = cc->as(); +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement end_point = gradient_curve->EndPoint(); +#endif } else if (segment_type_ == ST_CANT) { auto segmented_reference_curve = cc->as(); end_point = segmented_reference_curve->EndPoint(); @@ -776,9 +792,13 @@ class curve_segment_evaluator { auto A0 = c->ConstantTerm(); auto A1 = c->LinearTerm(); auto A2 = c->QuadraticTerm(); - auto A3 = c->CubicTerm(); - boost::optional A4, A5, A6, A7; - + boost::optional A3, A4, A5, A6, A7; +#ifdef SCHEMA_IfcThirdOrderPolynomialSpiral_HAS_CubicTerm + A3 = c->CubicTerm(); +#else + A3 = c->QubicTerm(); +#endif + if (segment_type_ == ST_CANT) { polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7); } else { @@ -832,7 +852,10 @@ class curve_segment_evaluator { if (segment_type_ == ST_HORIZONTAL) { convert_u = [](double u) { return u; }; } else { - auto curve_segment_placement = taxonomy::cast(mapping_->map(inst_->Placement()))->ccomponents(); + Eigen::Matrix4d curve_segment_placement; +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement + curve_segment_placement = taxonomy::cast(mapping_->map(inst_->Placement()))->ccomponents(); +#endif auto csStartX = curve_segment_placement(0, 3); auto csStartY = curve_segment_placement(1, 3); auto csStartDx = curve_segment_placement(0, 0); @@ -1015,6 +1038,7 @@ class curve_segment_evaluator { } } +#ifdef SCHEMA_HAS_IfcPolynomialCurve void operator()(const IfcSchema::IfcPolynomialCurve* pc) { // see https://forums.buildingsmart.org/t/ifcpolynomialcurve-clarification/4716 for discussion on IfcPolynomialCurve auto coeffX = pc->CoefficientsX().get_value_or(std::vector()); @@ -1159,6 +1183,7 @@ class curve_segment_evaluator { [](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }); } } +#endif }; } // namespace diff --git a/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp b/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp index d7b15859d3..28e23fb30f 100644 --- a/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcFixedReferenceSweptAreaSolid.cpp @@ -38,7 +38,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid function_item_evaluator evaluator(settings_,fn); double start = 0; double end = fn->length(); -#ifdef SCHEMA_HAS_IfcDirectrixCurveSweptAreaSolid + // IfcPointByDistanceExpression is introduced in rc2, the code below doesn't work on rc1 because startparam is optional +#if defined(SCHEMA_HAS_IfcDirectrixCurveSweptAreaSolid) && defined(SCHEMA_HAS_IfcPointByDistanceExpression) // IfcDirectrixCurveSweptAreaSolid introduced in 4.3 changed attribute type // from optional IfcParamValue to optional IfcCurveMeasureSelect. // Invocation of mapping on pre-4.3 models can never result in a piecewise_function. diff --git a/src/ifcgeom/mapping/IfcGradientCurve.cpp b/src/ifcgeom/mapping/IfcGradientCurve.cpp index 0d6572cd73..db016df0ca 100644 --- a/src/ifcgeom/mapping/IfcGradientCurve.cpp +++ b/src/ifcgeom/mapping/IfcGradientCurve.cpp @@ -53,7 +53,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) { // Get starting position of gradient curve, which is relative to the base curve // The gradient curve can start before or after the start of the base curve auto first_segment = *(segments->begin()); - auto p = taxonomy::cast(map(first_segment->as()->Placement())); + taxonomy::matrix4::ptr p; +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement + p = taxonomy::cast(map(first_segment->as()->Placement())); +#else + throw std::runtime_error("Unsupported schema"); +#endif const Eigen::Matrix4d& m = p->ccomponents(); double gradient_start = m(0, 3); // start of vertical (row 0, col 3) - "Distance Along" horizontal curve diff --git a/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp b/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp index fe5b31c56f..82eea17648 100644 --- a/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp +++ b/src/ifcgeom/mapping/IfcSectionedSolidHorizontal.cpp @@ -55,7 +55,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* in for (auto& cs : *css) { faces.push_back(std::move(taxonomy::cast(map(cs)))); } -#ifdef SCHEMA_HAS_IfcPointByDistanceExpression +#if defined(SCHEMA_HAS_IfcPointByDistanceExpression) && !defined(SCHEMA_IfcSectionedSurface_HAS_FixedAxisVertical) for (auto& csp : *csps) { auto pbde = csp->Location()->as(true); diff --git a/src/ifcgeom/mapping/IfcSectionedSurface.cpp b/src/ifcgeom/mapping/IfcSectionedSurface.cpp index 4948ddd0a0..1111d4dac5 100644 --- a/src/ifcgeom/mapping/IfcSectionedSurface.cpp +++ b/src/ifcgeom/mapping/IfcSectionedSurface.cpp @@ -55,7 +55,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) { for (auto& cs : *css) { faces.push_back(std::move(taxonomy::cast(map(cs)))); } -#ifdef SCHEMA_HAS_IfcPointByDistanceExpression + // IfcSectionedSurface::FixedAxisVertical removed in rc4, where CrossSectionPositions was IfcPointByDistanceExpression instead of IfcAxis2PlacementLinear +#if defined(SCHEMA_HAS_IfcPointByDistanceExpression) && !defined(SCHEMA_IfcSectionedSurface_HAS_FixedAxisVertical) for (auto& csp : *csps) { auto pbde = csp->Location()->as(true); diff --git a/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp b/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp index 37a7af5b9f..c8e89a8ccc 100644 --- a/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp +++ b/src/ifcgeom/mapping/IfcSegmentedReferenceCurve.cpp @@ -53,8 +53,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins // Get starting position of cant curve, relative to the gradient curve. // The cant curve can start before or after the start of the gradient curve auto first_segment = *(segments->begin()); - auto p = taxonomy::cast(map(first_segment->as()->Placement())); - const Eigen::Matrix4d& m = p->ccomponents(); + taxonomy::matrix4::ptr p; +#ifdef SCHEMA_IfcCurveSegment_HAS_Placement + p = taxonomy::cast(map(first_segment->as()->Placement())); +#else + throw std::runtime_error("Unsupported schema"); +#endif + const Eigen::Matrix4d& m = p->ccomponents(); double cant_start = m(0, 3); // start of cant curve auto cant = taxonomy::make(cant_start,spans); diff --git a/src/serializers/schema_dependent/XmlSerializer.cpp b/src/serializers/schema_dependent/XmlSerializer.cpp index e98b0fbe4e..2a72f42637 100644 --- a/src/serializers/schema_dependent/XmlSerializer.cpp +++ b/src/serializers/schema_dependent/XmlSerializer.cpp @@ -362,7 +362,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc } } -#ifdef SCHEMA_HAS_IfcAlignmentSegment +#if defined(SCHEMA_HAS_IfcAlignmentSegment) && defined(SCHEMA_IfcAlignmentSegment_HAS_DesignParameters) if (auto* als = product->as()) { ptree node; format_entity_instance(mapping, als->DesignParameters(), node, child, false);