mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-30 12:09:51 +00:00
Fixes IfcOffsetCurveByDistance
This commit is contained in:
@@ -122,7 +122,7 @@ struct gradient_fn_evaluator : public fn_evaluator {
|
|||||||
// Put curvature back into the solution matrix
|
// Put curvature back into the solution matrix
|
||||||
// curvature for vertical is in column 0, need it to be in column 1
|
// curvature for vertical is in column 0, need it to be in column 1
|
||||||
// so it doesn't add to curvature for horizontal
|
// so it doesn't add to curvature for horizontal
|
||||||
std::swap(vertical_curvature(3, 0), vertical_curvature(3, 1));
|
std::swap(vertical_curvature(0), vertical_curvature(1));
|
||||||
m.row(3) = horizontal_curvature + vertical_curvature;
|
m.row(3) = horizontal_curvature + vertical_curvature;
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
|
|||||||
@@ -39,15 +39,29 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
auto first_offset_value = *(offset_values->begin());
|
auto first_offset_value = *(offset_values->begin());
|
||||||
|
|
||||||
auto basis_curve = inst->BasisCurve();
|
auto basis_curve = inst->BasisCurve();
|
||||||
auto curve = taxonomy::dcast<taxonomy::function_item>(map(basis_curve));
|
|
||||||
if (!curve) {
|
// // IfcOffsetCurveByDistances can be based on another IfcOffsetCurveByDistances, an IfcGradientCurve, or an IfcCompositeCurve
|
||||||
|
// // When based on IfcOffsetCurveByDistances, it creates a chain of curves that we must navigate down to the base curve.
|
||||||
|
// // The source curve is IfcGradientCurve or IfcCompositeCurve. This loop drills down to the base curve.
|
||||||
|
// while (auto offset_curve = basis_curve->as<IfcSchema::IfcOffsetCurveByDistances>()) {
|
||||||
|
// basis_curve = offset_curve;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//#if defined SCHEMA_HAS_IfcGradientCurve
|
||||||
|
// if (auto gc = basis_curve->as<IfcSchema::IfcGradientCurve>()) {
|
||||||
|
// basis_curve = gc->BaseCurve();
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
auto basis_curve_fn = taxonomy::dcast<taxonomy::function_item>(map(basis_curve));
|
||||||
|
if (!basis_curve_fn) {
|
||||||
// Only implement on alignment curves
|
// Only implement on alignment curves
|
||||||
Logger::Warning("IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst);
|
Logger::Warning("IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
double start = curve->start();
|
double start = basis_curve_fn->start();
|
||||||
double basis_curve_length = curve->length();
|
double basis_curve_length = basis_curve_fn->length();
|
||||||
|
|
||||||
taxonomy::piecewise_function::spans_t offset_spans;
|
taxonomy::piecewise_function::spans_t offset_spans;
|
||||||
|
|
||||||
@@ -56,6 +70,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
#else
|
#else
|
||||||
double first_distance = *first_offset_value->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
double first_distance = *first_offset_value->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
||||||
#endif
|
#endif
|
||||||
|
first_distance *= length_unit_;
|
||||||
|
|
||||||
if (first_distance < 0.0) {
|
if (first_distance < 0.0) {
|
||||||
Logger::Warning("IfcOffsetCurveByDistance first offset value is before the start of the curve.");
|
Logger::Warning("IfcOffsetCurveByDistance first offset value is before the start of the curve.");
|
||||||
@@ -83,31 +98,28 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
auto prev = std::prev(next);
|
auto prev = std::prev(next);
|
||||||
auto end = offset_values->end();
|
auto end = offset_values->end();
|
||||||
for (; next != end; prev++, next++) {
|
for (; next != end; prev++, next++) {
|
||||||
#if defined SCHEMA_HAS_IfcPointByDistanceExpression
|
|
||||||
if ((*prev)->BasisCurve() != basis_curve || (*next)->BasisCurve() != basis_curve) {
|
|
||||||
Logger::Error("All offsets from a IfcOffsetCurveByDistances must refer to the same BasisCurve");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined SCHEMA_HAS_IfcDistanceExpression
|
#if defined SCHEMA_HAS_IfcDistanceExpression
|
||||||
double dn = (*next)->DistanceAlong();
|
|
||||||
double dp = (*prev)->DistanceAlong();
|
double dp = (*prev)->DistanceAlong();
|
||||||
|
double dn = (*next)->DistanceAlong();
|
||||||
#else
|
#else
|
||||||
double dn = *(*next)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
|
||||||
double dp = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
double dp = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
||||||
|
double dn = *(*next)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
|
||||||
#endif
|
#endif
|
||||||
if ((dp < 0.0 || basis_curve_length < dp)
|
dp *= length_unit_;
|
||||||
|
dn *= length_unit_;
|
||||||
|
|
||||||
|
if ((dp < 0.0 || basis_curve_length < dp) // previous is out of range
|
||||||
||
|
||
|
||||||
(dn < 0.0 || basis_curve_length < dn)
|
(dn < 0.0 || basis_curve_length < dn) // next is out of range
|
||||||
||
|
||
|
||||||
(dn < dp)
|
(dn < dp) // next is before previous
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Logger::Warning("IfcOffsetCurveByDistance offset value is out of bounds.");
|
Logger::Warning("IfcOffsetCurveByDistance offset value is out of bounds.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double l = (dn - dp)*length_unit_;
|
double l = (dn - dp);
|
||||||
double yn = (*next)->OffsetLateral().get_value_or(0.0) * length_unit_;
|
double yn = (*next)->OffsetLateral().get_value_or(0.0) * length_unit_;
|
||||||
double yp = (*prev)->OffsetLateral().get_value_or(0.0) * length_unit_;
|
double yp = (*prev)->OffsetLateral().get_value_or(0.0) * length_unit_;
|
||||||
double zn = (*next)->OffsetVertical().get_value_or(0.0) * length_unit_;
|
double zn = (*next)->OffsetVertical().get_value_or(0.0) * length_unit_;
|
||||||
@@ -152,7 +164,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
|
|
||||||
auto offsets = taxonomy::make<taxonomy::piecewise_function>(start,offset_spans);
|
auto offsets = taxonomy::make<taxonomy::piecewise_function>(start,offset_spans);
|
||||||
|
|
||||||
auto fn = taxonomy::make<taxonomy::offset_function>(curve, offsets);
|
auto fn = taxonomy::make<taxonomy::offset_function>(basis_curve_fn, offsets);
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ def create_as_offset_curve(
|
|||||||
_create_offset_curve_representation(file, alignment, offsets)
|
_create_offset_curve_representation(file, alignment, offsets)
|
||||||
|
|
||||||
# define stationing
|
# define stationing
|
||||||
name = ifcopenshell.util.alignment.station_as_string(file, start_station)
|
#name = ifcopenshell.util.alignment.station_as_string(file, start_station)
|
||||||
referent = ifcopenshell.api.alignment.add_stationing_referent(file, alignment, 0.0, start_station, name)
|
#referent = ifcopenshell.api.alignment.add_stationing_referent(file, alignment, 0.0, start_station, name)
|
||||||
ifcopenshell.api.nest.reorder_nesting(file, referent, -1, 0)
|
#ifcopenshell.api.nest.reorder_nesting(file, referent, -1, 0)
|
||||||
|
|
||||||
# IFC 4.1.4.1.1 Alignment Aggregation To Project
|
# IFC 4.1.4.1.1 Alignment Aggregation To Project
|
||||||
project = file.by_type("IfcProject")[0]
|
project = file.by_type("IfcProject")[0]
|
||||||
|
|||||||
Reference in New Issue
Block a user