Work towards v1.0 data model with encapsulated weak_ptr as basis for instances

This commit is contained in:
Thomas Krijnen
2026-01-04 10:40:02 +01:00
parent f09ca658f1
commit 7098beb819
210 changed files with 28269 additions and 26471 deletions
@@ -23,16 +23,16 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAnnotationFillArea* inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst->OuterBoundary()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAnnotationFillArea& inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst.OuterBoundary()));
if (loop) {
auto face = taxonomy::make<taxonomy::face>();
loop->external = true;
face->children = { loop };
if (inst->InnerBoundaries()) {
IfcSchema::IfcCurve::list::ptr inner_boundaries = *inst->InnerBoundaries();
for (auto& v : *inner_boundaries) {
if (inst.InnerBoundaries()) {
std::vector<IfcSchema::IfcCurve> inner_boundaries = *inst.InnerBoundaries();
for (auto& v : inner_boundaries) {
auto inner_loop = taxonomy::cast<taxonomy::loop>(map(v));
if (inner_loop) {
inner_loop->external = false;
@@ -23,10 +23,10 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst->OuterCurve()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef& inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst.OuterCurve()));
if (loop) {
if (inst->ProfileType() == IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
if (inst.ProfileType() == IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
return loop;
}
@@ -34,10 +34,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* i
loop->external = true;
face->children = { loop };
if (inst->as<IfcSchema::IfcArbitraryProfileDefWithVoids>()) {
auto with_voids = inst->as<IfcSchema::IfcArbitraryProfileDefWithVoids>();
auto voids = with_voids->InnerCurves();
for (auto& v : *voids) {
if (inst.as<IfcSchema::IfcArbitraryProfileDefWithVoids>()) {
auto with_voids = inst.as<IfcSchema::IfcArbitraryProfileDefWithVoids>();
auto voids = with_voids.InnerCurves();
for (auto& v : voids) {
auto inner_loop = taxonomy::cast<taxonomy::loop>(map(v));
if (inner_loop) {
inner_loop->external = false;
@@ -23,8 +23,8 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef* inst) {
auto mapped = map(inst->Curve());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef& inst) {
auto mapped = map(inst.Curve());
if (mapped->kind() == taxonomy::LOOP) {
auto r = taxonomy::loop::ptr((taxonomy::loop*)mapped->clone_());
r->closed = false;
+4 -4
View File
@@ -22,17 +22,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement& inst) {
Eigen::Vector3d P(0, 0, 0), axis(0, 0, 1), ref;
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasAxis = inst->Axis();
const bool hasAxis = inst.Axis();
if (hasAxis) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *v->components_;
}
+4 -4
View File
@@ -23,17 +23,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D& inst) {
Eigen::Vector3d P(0, 0, 0), axis(0, 0, 1), V(1, 0, 0);
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasRef = !!inst->RefDirection();
const bool hasRef = !!inst.RefDirection();
if (hasRef) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
V = *v->components_;
}
return taxonomy::make<taxonomy::matrix4>(P, axis, V);
+6 -6
View File
@@ -23,28 +23,28 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D& inst) {
Eigen::Vector3d o(0, 0, 0), axis(0, 0, 1), refDirection, X(1, 0, 0);
try {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst->Location()));
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
o = *v->components_;
} catch (const std::exception&) {
Logger::Warning("Placement with invalid Location:", inst);
}
const bool hasAxis = !!inst->Axis();
const bool hasRef = !!inst->RefDirection();
const bool hasAxis = !!inst.Axis();
const bool hasRef = !!inst.RefDirection();
if (hasAxis != hasRef) {
Logger::Warning("Axis and RefDirection should be specified together", inst);
}
if (hasAxis) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *v->components_;
}
if (hasRef) {
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr v = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *v->components_;
} else {
if (acos(axis.dot(X)) > 1.e-5) {
@@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry;
#if defined SCHEMA_HAS_IfcAxis2PlacementLinear
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear& inst) {
if (!inst->Location()->as<IfcSchema::IfcPointByDistanceExpression>()) {
if (!inst.Location().as<IfcSchema::IfcPointByDistanceExpression>()) {
Logger::Error(std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear"));
}
Eigen::Vector3d o, axis(0, 0, 1), refDirection;
taxonomy::matrix4::ptr m = taxonomy::cast<taxonomy::matrix4>(map(inst->Location()));
taxonomy::matrix4::ptr m = taxonomy::cast<taxonomy::matrix4>(map(inst.Location()));
o = m->components().col(3).head<3>();
// From 8.9.3.4 IfcAxis2PlacementLinear there are 4 cases that need to be considered
@@ -40,8 +40,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
// 3) Neither Axis or RefDirection are provided
// 4) Both Axis and RefDirection are provided
const bool hasAxis = inst->Axis() != nullptr;
const bool hasRef = inst->RefDirection() != nullptr;
const bool hasAxis = !!inst.Axis();
const bool hasRef = !!inst.RefDirection();
/*
if (hasAxis != hasRef) {
@@ -50,7 +50,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
*/
if (hasAxis && !hasRef) {
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *a->components_;
refDirection = m->components().col(0).head<3>(); // RefDirection is the curve tangent when omitted
@@ -58,7 +58,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
// axis.cross(refDirection) gives y. y.cross(axis) gives x=refDirection
refDirection = axis.cross(refDirection).cross(axis);
} else if (!hasAxis && hasRef) {
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *r->components_;
Eigen::Vector3d up(0, 0, 1);
axis = refDirection.cross(up.cross(refDirection));
@@ -67,10 +67,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear* inst)
Eigen::Vector3d up(0, 0, 1);
axis = refDirection.cross(up.cross(refDirection));
} else {
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst->Axis()));
taxonomy::direction3::ptr a = taxonomy::cast<taxonomy::direction3>(map(inst.Axis()));
axis = *a->components_;
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst->RefDirection()));
taxonomy::direction3::ptr r = taxonomy::cast<taxonomy::direction3>(map(inst.RefDirection()));
refDirection = *r->components_;
refDirection = axis.cross(refDirection).cross(axis); // refDirection needs to be orthogonal to axis
}
@@ -25,20 +25,20 @@
using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcBSplineCurveWithKnots
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots& inst) {
auto bc = taxonomy::make<taxonomy::bspline_curve>();
const IfcSchema::IfcCartesianPoint::list::ptr cps = inst->ControlPointsList();
const std::vector<IfcSchema::IfcCartesianPoint> cps = inst.ControlPointsList();
std::vector<taxonomy::point3::ptr> points;
std::transform(cps->begin(), cps->end(), std::back_inserter(points), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
std::transform(cps.begin(), cps.end(), std::back_inserter(points), [this](const IfcSchema::IfcCartesianPoint& cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
bc->control_points = points;
bc->multiplicities = inst->KnotMultiplicities();
bc->knots = inst->Knots();
if (inst->as<IfcSchema::IfcRationalBSplineCurveWithKnots>()) {
bc->weights = inst->as<IfcSchema::IfcRationalBSplineCurveWithKnots>()->WeightsData();
bc->multiplicities = inst.KnotMultiplicities();
bc->knots = inst.Knots();
if (inst.as<IfcSchema::IfcRationalBSplineCurveWithKnots>()) {
bc->weights = inst.as<IfcSchema::IfcRationalBSplineCurveWithKnots>().WeightsData();
}
bc->degree = inst->Degree();
bc->degree = inst.Degree();
return bc;
}
@@ -25,22 +25,22 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcBSplineSurfaceWithKnots
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots& inst) {
auto bs = taxonomy::make<taxonomy::bspline_surface>();
auto cps = inst->ControlPointsList();
std::transform(cps->begin(), cps->end(), std::back_inserter(bs->control_points), [this](const std::vector<IfcSchema::IfcCartesianPoint*>& inner) {
auto cps = inst.ControlPointsList();
std::transform(cps.begin(), cps.end(), std::back_inserter(bs->control_points), [this](const std::vector<IfcSchema::IfcCartesianPoint>& inner) {
std::vector<taxonomy::point3::ptr> ps;
std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](const IfcSchema::IfcCartesianPoint& cp) { return taxonomy::cast<taxonomy::point3>(map(cp)); });
return ps;
});
bs->multiplicities = { inst->UMultiplicities(), inst->VMultiplicities() };
bs->knots = { inst->UKnots(), inst->VKnots() };
if (inst->as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()) {
bs->weights = inst->as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()->WeightsData();
bs->multiplicities = { inst.UMultiplicities(), inst.VMultiplicities() };
bs->knots = { inst.UKnots(), inst.VKnots() };
if (inst.as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>()) {
bs->weights = inst.as<IfcSchema::IfcRationalBSplineSurfaceWithKnots>().WeightsData();
}
bs->degree = { inst->UDegree(), inst->VDegree() };
bs->degree = { inst.UDegree(), inst.VDegree() };
return bs;
}
+5 -5
View File
@@ -22,13 +22,13 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBlock* inst) {
const double dx = inst->XLength() * length_unit_;
const double dy = inst->YLength() * length_unit_;
const double dz = inst->ZLength() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBlock& inst) {
const double dx = inst.XLength() * length_unit_;
const double dy = inst.YLength() * length_unit_;
const double dz = inst.ZLength() * length_unit_;
auto solid = create_box(dx, dy, dz);
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return solid;
}
+12 -12
View File
@@ -37,22 +37,22 @@ namespace {
}
}
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
IfcSchema::IfcBooleanOperand* operand1 = inst->FirstOperand();
IfcSchema::IfcBooleanOperand* operand2 = inst->SecondOperand();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult& inst) {
IfcSchema::IfcBooleanOperand operand1 = inst.FirstOperand();
IfcSchema::IfcBooleanOperand operand2 = inst.SecondOperand();
bool has_halfspace_operand = false;
std::vector<IfcSchema::IfcBooleanOperand*> operands;
std::vector<IfcSchema::IfcBooleanOperand> operands;
operands.push_back(operand2);
auto op = boolean_op_type(inst->Operator());
auto op = boolean_op_type(inst.Operator());
if (op == taxonomy::boolean_result::SUBTRACTION) {
int n_half_space_operands = 0;
bool process_as_list = true;
while (true) {
auto res1 = operand1->as<IfcSchema::IfcBooleanResult>();
if (res1 && res1->SecondOperand()->as<IfcSchema::IfcHalfSpaceSolid>() && ++n_half_space_operands > 8) {
auto res1 = operand1.as<IfcSchema::IfcBooleanResult>();
if (res1 && res1.SecondOperand().as<IfcSchema::IfcHalfSpaceSolid>() && ++n_half_space_operands > 8) {
// There is something peculiar about many half space subtraction operands that OCCT does not like.
// Often these are used to create a semi-curved arch, as is the case in 693. Supplying all these
// operands at once apparently leads to too many edge-edge interference checks.
@@ -62,9 +62,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
break;
}
if (res1) {
if (boolean_op_type(res1->Operator()) == op) {
operand1 = res1->FirstOperand();
operands.push_back(res1->SecondOperand());
if (boolean_op_type(res1.Operator()) == op) {
operand1 = res1.FirstOperand();
operands.push_back(res1.SecondOperand());
} else {
process_as_list = false;
break;
@@ -75,14 +75,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) {
}
if (!process_as_list) {
operand1 = inst->FirstOperand();
operand1 = inst.FirstOperand();
operands = { operand2 };
}
}
operands.insert(operands.begin(), operand1);
auto br = map_to_collection<taxonomy::boolean_result>(this, &operands);
auto br = map_to_collection<taxonomy::boolean_result>(this, operands);
if (br) {
br->operation = op;
}
+5 -5
View File
@@ -22,17 +22,17 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBoundingBox* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBoundingBox& inst) {
if (!settings_.get<settings::KeepBoundingBoxes>().get()) {
failed_on_purpose_.insert(inst);
return nullptr;
}
const double dx = inst->XDim() * length_unit_;
const double dy = inst->YDim() * length_unit_;
const double dz = inst->ZDim() * length_unit_;
const double dx = inst.XDim() * length_unit_;
const double dy = inst.YDim() * length_unit_;
const double dz = inst.ZDim() * length_unit_;
taxonomy::point3::ptr corner = taxonomy::cast<taxonomy::point3>(map(inst->Corner()));
taxonomy::point3::ptr corner = taxonomy::cast<taxonomy::point3>(map(inst.Corner()));
auto solid = create_box(corner->ccomponents().x(), corner->ccomponents().y(), corner->ccomponents().z(), dx, dy, dz);
return solid;
+9 -9
View File
@@ -27,16 +27,16 @@ using namespace ifcopenshell::geometry;
#include <vector>
#include <boost/optional/optional.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) {
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->Width() / 2.0f * length_unit_;
const double d1 = inst->WallThickness() * length_unit_;
const double d2 = inst->Girth() * length_unit_;
bool doFillet = !!inst->InternalFilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef& inst) {
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.Width() / 2.0f * length_unit_;
const double d1 = inst.WallThickness() * length_unit_;
const double d2 = inst.Girth() * length_unit_;
bool doFillet = !!inst.InternalFilletRadius();
double f1 = 0;
double f2 = 0;
if ( doFillet ) {
f1 = *inst->InternalFilletRadius() * length_unit_;
f1 = *inst.InternalFilletRadius() * length_unit_;
f2 = f1 + d1;
}
@@ -50,10 +50,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianPoint* inst) {
std::vector<double> xyz = inst->Coordinates();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianPoint& inst) {
std::vector<double> xyz = inst.Coordinates();
return taxonomy::make<taxonomy::point3>(
xyz.size() >= 1 ? xyz[0] * length_unit_ : 0.,
xyz.size() >= 2 ? xyz[1] * length_unit_ : 0.,
@@ -21,26 +21,26 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D& inst) {
auto m = taxonomy::make<taxonomy::matrix4>();
Eigen::Vector4d origin, axis1(1.0, 0.0, 0.0, 0.0), axis2(0.0, 1.0, 0.0, 0.0), axis3(0.0, 0.0, 1.0, 0.0);
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst->LocalOrigin()));
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst.LocalOrigin()));
origin << *O->components_, 1.0;
if (inst->Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis1()));
if (inst.Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis1()));
axis1 << *ax1->components_, 0.0;
if (!inst->Axis2()) {
if (!inst.Axis2()) {
// orthogonal complement
axis2 << -axis1(1), axis1(0), 0., 0.;
}
}
if (inst->Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis2()));
if (inst.Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis2()));
axis2 << *ax2->components_, 0.0;
if (!inst->Axis2()) {
if (!inst.Axis2()) {
// orthogonal complement
axis1 << -axis2(1), axis2(0), 0., 0.;
}
@@ -49,12 +49,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpera
double scale1, scale2;
scale1 = 1.0;
if (inst->Scale()) {
scale1 = *inst->Scale();
if (inst.Scale()) {
scale1 = *inst.Scale();
}
if (inst->as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>()) {
auto nu = inst->as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>();
scale2 = nu->Scale2() ? *nu->Scale2() : scale1;
if (inst.as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>()) {
auto nu = inst.as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>();
scale2 = nu.Scale2() ? *nu.Scale2() : scale1;
} else {
scale2 = scale1;
}
@@ -21,26 +21,26 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D& inst) {
Eigen::Vector4d origin;
Eigen::Vector4d axis1(1., 0., 0., 0.);
Eigen::Vector4d axis2(0., 1., 0., 0.);
Eigen::Vector4d axis3(0., 0., 1., 0.);
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst->LocalOrigin()));
taxonomy::point3::ptr O = taxonomy::cast<taxonomy::point3>(map(inst.LocalOrigin()));
origin << *O->components_, 1.0;
if (inst->Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis1()));
if (inst.Axis1()) {
taxonomy::direction3::ptr ax1 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis1()));
axis1 << *ax1->components_, 0.0;
}
if (inst->Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis2()));
if (inst.Axis2()) {
taxonomy::direction3::ptr ax2 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis2()));
axis2 << *ax2->components_, 0.0;
}
if (inst->Axis3()) {
taxonomy::direction3::ptr ax3 = taxonomy::cast<taxonomy::direction3>(map(inst->Axis3()));
if (inst.Axis3()) {
taxonomy::direction3::ptr ax3 = taxonomy::cast<taxonomy::direction3>(map(inst.Axis3()));
axis3 << *ax3->components_, 0.0;
}
@@ -52,13 +52,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpera
double scale1, scale2, scale3;
scale1 = 1.;
if (inst->Scale()) {
scale1 = *inst->Scale();
if (inst.Scale()) {
scale1 = *inst.Scale();
}
if (inst->as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>()) {
auto nu = inst->as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>();
scale2 = nu->Scale2() ? *nu->Scale2() : scale1;
scale3 = nu->Scale3() ? *nu->Scale3() : scale1;
if (inst.as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>()) {
auto nu = inst.as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>();
scale2 = nu.Scale2() ? *nu.Scale2() : scale1;
scale3 = nu.Scale3() ? *nu.Scale3() : scale1;
} else {
scale2 = scale3 = scale1;
}
@@ -21,14 +21,14 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef& inst) {
return nullptr;
/*
const double d = inst->Thickness() * length_unit_ / 2.;
const double d = inst.Thickness() * length_unit_ / 2.;
auto f = taxonomy::make<taxonomy::face>();
auto ofc = taxonomy::make<taxonomy::offset_curve>();
ofc->basis = map(inst->Curve());
ofc->basis = map(inst.Curve());
ofc->offset = d;
// @todo
// f->children.push_back(ofc);
@@ -39,7 +39,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst)
/*
TopoDS_Wire wire;
if (!convert_wire(inst->Curve(), wire)) return false;
if (!convert_wire(inst.Curve(), wire)) return false;
// BRepOffsetAPI_MakeOffset insists on creating circular arc
// segments for joining the curves that constitute the center
+3 -5
View File
@@ -21,16 +21,14 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
#define ALMOST_ZERO 1.e-7;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle* inst) {
const double r = inst->Radius() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle& inst) {
const double r = inst.Radius() * length_unit_;
if (r < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
return nullptr;
}
IfcSchema::IfcAxis2Placement* placement = inst->Position();
auto placement = inst.Position();
auto c = taxonomy::make<taxonomy::circle>();
c->radius = r;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(placement));
+6 -6
View File
@@ -23,11 +23,11 @@ using namespace ifcopenshell::geometry;
#include <boost/math/constants/constants.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) {
std::vector<double> radii = { inst->Radius() * length_unit_ };
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef& inst) {
std::vector<double> radii = { inst.Radius() * length_unit_ };
if (inst->as<IfcSchema::IfcCircleHollowProfileDef>()) {
double t = inst->as<IfcSchema::IfcCircleHollowProfileDef>()->WallThickness() * length_unit_;
if (inst.as<IfcSchema::IfcCircleHollowProfileDef>()) {
double t = inst.as<IfcSchema::IfcCircleHollowProfileDef>().WallThickness() * length_unit_;
radii.push_back(radii.front() - t);
}
@@ -42,10 +42,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) {
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
} else {
// matrix needs to be set on elementary curves
c->matrix = taxonomy::make<taxonomy::matrix4>();
+17 -17
View File
@@ -21,38 +21,38 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve& inst) {
auto loop = taxonomy::make<taxonomy::loop>();
taxonomy::piecewise_function::spans_t spans;
#ifdef SCHEMA_HAS_IfcSegment
// 4x3
IfcSchema::IfcSegment::list::ptr segments = inst->Segments();
std::vector<IfcSchema::IfcSegment> segments = inst.Segments();
#else
IfcSchema::IfcCompositeCurveSegment::list::ptr segments = inst->Segments();
std::vector<IfcSchema::IfcCompositeCurveSegment> segments = inst.Segments();
#endif
for (auto& segment : *segments) {
if (segment->as<IfcSchema::IfcCompositeCurveSegment>() && segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve()->as<IfcSchema::IfcLine>()) {
for (auto& segment : segments) {
if (segment.as<IfcSchema::IfcCompositeCurveSegment>() && segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>()) {
Logger::Notice("Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment);
double u0 = 0.0;
double u1 = segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve()->as<IfcSchema::IfcLine>()->Dir()->Magnitude() * length_unit_;
double u1 = segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>().Dir().Magnitude() * length_unit_;
if (u1 < settings_.get<settings::Precision>().get()) {
Logger::Warning("Segment length below tolerance", segment);
}
auto e = taxonomy::make<taxonomy::edge>();
e->basis = map(segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve());
e->basis = map(segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve());
e->start = u0;
e->end = u1;
e->curve_sense.reset(segment->as<IfcSchema::IfcCompositeCurveSegment>()->SameSense());
e->curve_sense.emplace(segment.as<IfcSchema::IfcCompositeCurveSegment>().SameSense());
loop->children.push_back(e);
}
else if (segment->as<IfcSchema::IfcCompositeCurveSegment>()) {
auto crv = map(segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve());
else if (segment.as<IfcSchema::IfcCompositeCurveSegment>()) {
auto crv = map(segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve());
if (crv) {
if (!segment->as<IfcSchema::IfcCompositeCurveSegment>()->SameSense()) {
if (!segment.as<IfcSchema::IfcCompositeCurveSegment>().SameSense()) {
crv->reverse();
}
if (crv->kind() == taxonomy::EDGE) {
@@ -62,7 +62,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
for (auto& s : taxonomy::cast<taxonomy::loop>(crv)->children) {
loop->children.push_back(s);
}
} else if ((crv->kind() == taxonomy::CIRCLE || crv->kind() == taxonomy::ELLIPSE) && segments->size() == 1) {
} else if ((crv->kind() == taxonomy::CIRCLE || crv->kind() == taxonomy::ELLIPSE) && segments.size() == 1) {
// A circle or ellipse segment is a full circle/ellipse, only possible when it is the only segment
std::shared_ptr<taxonomy::edge> e = std::make_shared<taxonomy::edge>();
e->basis = crv;
@@ -76,9 +76,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
}
}
#ifdef SCHEMA_HAS_IfcCurveSegment
else if (segment->as<IfcSchema::IfcCurveSegment>()) {
else if (segment.as<IfcSchema::IfcCurveSegment>()) {
// @todo check that we don't get a mixture of implicit and explicit definitions
auto crv = map(segment->as<IfcSchema::IfcCurveSegment>());
auto crv = map(segment.as<IfcSchema::IfcCurveSegment>());
if (crv && crv->kind() == taxonomy::LOOP) {
for (auto& s : taxonomy::cast<taxonomy::loop>(crv)->children) {
loop->children.push_back(s);
@@ -95,8 +95,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
}
if (spans.empty()) {
aggregate_of_instance::ptr profile = inst->file_->getInverse(inst->id(), &IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = profile && profile->size() > 0;
std::vector<express::Entity> profile = inst.data()->file()->getInverse(inst.id(), &IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = !profile.empty();
loop->closed = force_close;
loop->instance = inst;
return loop;
@@ -182,7 +182,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wi
TopTools_ListIteratorOfListOfShape it(converted_segments);
aggregate_of_instance::ptr profile = inst->data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
std::vector<express::Base> profile = inst.data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
const bool force_close = profile && profile->size() > 0;
util::wire_builder bld(getValue(GV_PRECISION), l);
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeProfileDef* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeProfileDef& inst) {
// @todo double check that this is actually supported
IfcSchema::IfcProfileDef::list::ptr profiles = inst->Profiles();
std::vector<IfcSchema::IfcProfileDef> profiles = inst.Profiles();
return map_to_collection<>(this, profiles);
}
+3 -3
View File
@@ -21,11 +21,11 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcConnectedFaceSet* inst) {
auto shell = map_to_collection<taxonomy::shell>(this, inst->CfsFaces());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcConnectedFaceSet& inst) {
auto shell = map_to_collection<taxonomy::shell>(this, inst.CfsFaces());
if (!shell) {
return nullptr;
}
shell->closed = inst->declaration().is(IfcSchema::IfcClosedShell::Class());
shell->closed = inst.declaration().is(IfcSchema::IfcClosedShell::Class());
return shell;
}
@@ -25,25 +25,25 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcCraneRailAShapeProfileDef
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef* inst) {
double oh = inst->OverallHeight() * length_unit_;
double bw2 = inst->BaseWidth2() * length_unit_;
double hw = inst->HeadWidth() * length_unit_;
double hd2 = inst->HeadDepth2() * length_unit_;
double hd3 = inst->HeadDepth3() * length_unit_;
double wt = inst->WebThickness() * length_unit_;
double bw4 = inst->BaseWidth4() * length_unit_;
double bd1 = inst->BaseDepth1() * length_unit_;
double bd2 = inst->BaseDepth2() * length_unit_;
double bd3 = inst->BaseDepth3() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef& inst) {
double oh = inst.OverallHeight() * length_unit_;
double bw2 = inst.BaseWidth2() * length_unit_;
double hw = inst.HeadWidth() * length_unit_;
double hd2 = inst.HeadDepth2() * length_unit_;
double hd3 = inst.HeadDepth3() * length_unit_;
double wt = inst.WebThickness() * length_unit_;
double bw4 = inst.BaseWidth4() * length_unit_;
double bd1 = inst.BaseDepth1() * length_unit_;
double bd2 = inst.BaseDepth2() * length_unit_;
double bd3 = inst.BaseDepth3() * length_unit_;
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCsgSolid* inst) {
return map(inst->TreeRootExpression());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCsgSolid& inst) {
return map(inst.TreeRootExpression());
}
+6 -6
View File
@@ -21,15 +21,15 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane* inst) {
taxonomy::plane::ptr pl = taxonomy::cast<taxonomy::plane>(map(inst->BasisSurface()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane& inst) {
taxonomy::plane::ptr pl = taxonomy::cast<taxonomy::plane>(map(inst.BasisSurface()));
auto f = taxonomy::make<taxonomy::face>();
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(inst->OuterBoundary())));
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(inst.OuterBoundary())));
IfcSchema::IfcCurve::list::ptr boundaries = inst->InnerBoundaries();
std::vector<IfcSchema::IfcCurve> boundaries = inst.InnerBoundaries();
for (IfcSchema::IfcCurve::list::it it = boundaries->begin(); it != boundaries->end(); ++it) {
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(*it)));
for (auto& b : boundaries) {
f->children.push_back(taxonomy::cast<taxonomy::loop>(map(b)));
}
f->matrix = pl->matrix;
+133 -137
View File
@@ -44,19 +44,19 @@ enum segment_type_t {
// @todo use std::numbers::pi when upgrading to C++ 20
static const double PI = boost::math::constants::pi<double>();
double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_value) {
double translate_to_length_measure(const IfcSchema::IfcCurve& crv, double param_value) {
if (std::abs(param_value) < 1.e-7) {
return param_value;
} else if (auto line = crv->as<IfcSchema::IfcLine>()) {
return line->Dir()->Magnitude() * param_value;
} else if (auto clothoid = crv->as<IfcSchema::IfcClothoid>()) {
} else if (auto line = crv.as<IfcSchema::IfcLine>()) {
return line.Dir().Magnitude() * param_value;
} else if (auto clothoid = crv.as<IfcSchema::IfcClothoid>()) {
// param_value = 1.0, corresponds to tangent direction = PI/2
// param_value = (arc length)/fabs(A*PI)
return fabs(clothoid->ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv->as<IfcSchema::IfcCircle>()) {
return circ->Radius() * param_value;
return fabs(clothoid.ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv.as<IfcSchema::IfcCircle>()) {
return circ.Radius() * param_value;
#ifdef SCHEMA_HAS_IfcPolynomialCurve
} else if (auto poly = crv->as<IfcSchema::IfcPolynomialCurve>()) {
} else if (auto poly = crv.as<IfcSchema::IfcPolynomialCurve>()) {
return param_value;
#endif
} else {
@@ -64,12 +64,12 @@ double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_
}
}
double translate_if_param_value(const IfcSchema::IfcCurve* crv, IfcSchema::IfcCurveMeasureSelect* val) {
if (auto param = val->as<IfcSchema::IfcParameterValue>()) {
double translate_if_param_value(const IfcSchema::IfcCurve& crv, const IfcSchema::IfcCurveMeasureSelect& val) {
if (auto param = val.as<IfcSchema::IfcParameterValue>()) {
// We don't care whether length- or positive length measure.
return translate_to_length_measure(crv, *param);
return translate_to_length_measure(crv, param);
} else {
return val->as<IfcUtil::IfcBaseClass>()->get_attribute_value(0);
return val.concrete().get_attribute_value(0);
}
}
@@ -181,12 +181,12 @@ struct cant_curve_segment_function {
class curve_segment_evaluator {
private:
mapping* mapping_ = nullptr;
const IfcSchema::IfcCurveSegment* inst_ = nullptr; // this curve segment instance
IfcSchema::IfcCurveSegment inst_; // this curve segment instance
double length_unit_;
double start_;
double length_; // length along the curve, as provided from the IfcCurveSegment
segment_type_t segment_type_;
const IfcSchema::IfcCurve* parent_curve_ = nullptr;
IfcSchema::IfcCurve parent_curve_;
double projected_length_; // for vertical segments, this is the length of curve projected onto the "Distance Along" axis
@@ -197,51 +197,47 @@ class curve_segment_evaluator {
std::optional<Eigen::Matrix4d> next_segment_placement_; // placement of the next segment
public:
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment* inst, double length_unit)
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment& inst, double length_unit)
: mapping_(mapping),
inst_(inst),
length_unit_(length_unit),
parent_curve_(inst->ParentCurve()) {
parent_curve_(inst.ParentCurve()) {
#ifdef SCHEMA_IfcSegment_HAS_UsingCurves
auto composite_curves = inst->UsingCurves();
auto composite_curves = inst.UsingCurves();
#else
aggregate_of<IfcSchema::IfcCompositeCurve>::ptr composite_curves;
throw std::runtime_error("Schema not supported");
#endif
// Find the next segment after inst
const IfcSchema::IfcCurveSegment* next_inst = nullptr;
if (composite_curves) {
if (composite_curves->size() == 1) {
auto segments = (*composite_curves->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments();
bool emit_next = false;
for (auto& s : *segments) {
if (emit_next) {
next_inst = s->as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
IfcSchema::IfcCurveSegment next_inst;
if (composite_curves.size() == 1) {
auto segments = composite_curves.front().as<IfcSchema::IfcCompositeCurve>().Segments();
bool emit_next = false;
for (auto& s : segments) {
if (emit_next) {
next_inst = s.as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
}
bool is_horizontal = false;
bool is_vertical = false;
bool is_cant = false;
if (composite_curves) {
for (auto& cc : *composite_curves) {
if (cc->as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc->as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
for (auto& cc : composite_curves) {
if (cc.as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc.as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
}
@@ -254,36 +250,36 @@ 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;
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;
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<taxonomy::matrix4>(mapping_->map(inst->Placement()))->ccomponents();
curve_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst.Placement()))->ccomponents();
#endif
}
if (next_inst) {
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(next_inst->Placement()))->ccomponents();
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(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.
IfcSchema::IfcPlacement* end_point = nullptr;
if (composite_curves->size() == 1) {
auto& cc = *(composite_curves)->begin();
IfcSchema::IfcPlacement end_point;
if (composite_curves.size() == 1) {
auto& cc = composite_curves.front();
if (segment_type_ == ST_VERTICAL) {
auto gradient_curve = cc->as<IfcSchema::IfcGradientCurve>();
auto gradient_curve = cc.as<IfcSchema::IfcGradientCurve>();
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
end_point = gradient_curve->EndPoint();
end_point = gradient_curve.EndPoint();
#endif
} else if (segment_type_ == ST_CANT) {
auto segmented_reference_curve = cc->as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve->EndPoint();
auto segmented_reference_curve = cc.as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve.EndPoint();
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point.");
@@ -297,8 +293,8 @@ class curve_segment_evaluator {
// Take the boost::type value from mpl::for_each and test it against our curve instance
template <typename T>
void operator()(boost::type<T>) {
if (parent_curve_->as<T>()) {
(*this)(parent_curve_->as<T>());
if (parent_curve_.as<T>()) {
(*this)(parent_curve_.as<T>());
}
}
@@ -308,7 +304,7 @@ class curve_segment_evaluator {
taxonomy::ptr get_segment_curve_function() {
if (!parent_curve_fn_ || !parent_curve_start_point_) {
Logger::Error(std::runtime_error(inst_->ParentCurve()->declaration().name() + " not implemented"), inst_);
Logger::Error(std::runtime_error(inst_.ParentCurve().declaration().name() + " not implemented"), inst_);
}
auto length = fabs(this->length());
@@ -521,9 +517,9 @@ class curve_segment_evaluator {
// returns function for super elevation and the slope of the super elevation curve if the super elevation is constant
// over the length of the segment. otherwise, no functions are returned because they are the same as the cant tilt angle
// functions.
std::pair<boost::optional<std::function<double(double)>>, boost::optional<std::function<double(double)>>> get_superelevation_functions() {
boost::optional<std::function<double(double)>> superelevation_fn;
boost::optional<std::function<double(double)>> superelevation_slope_fn;
std::pair<std::optional<std::function<double(double)>>, std::optional<std::function<double(double)>>> get_superelevation_functions() {
std::optional<std::function<double(double)>> superelevation_fn;
std::optional<std::function<double(double)>> superelevation_slope_fn;
if (curve_segment_placement_.has_value() && next_segment_placement_.has_value()) {
double y1 = (*curve_segment_placement_)(1, 3);
@@ -541,12 +537,12 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcClothoid
void operator()(const IfcSchema::IfcClothoid* c) {
auto A = c->ClothoidConstant() * length_unit_;
void operator()(const IfcSchema::IfcClothoid& c) {
auto A = c.ClothoidConstant() * length_unit_;
auto L = length(); // already includes length_unit_
if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A, L](double t) -> double { return A ? L * L * A * t / fabs(pow(A, 3)) : 0.0; };
@@ -570,12 +566,12 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcCosineSpiral
void operator()(const IfcSchema::IfcCosineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcCosineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto cosine_term = c->CosineTerm() * length_unit_;
auto cosine_term = c.CosineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
@@ -594,7 +590,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, cosine_term, L](double t) -> double {
@@ -632,16 +628,16 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcSineSpiral
void operator()(const IfcSchema::IfcSineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcSineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto linear_term = c->LinearTerm();
auto linear_term = c.LinearTerm();
if (linear_term.has_value()) {
linear_term.value() *= length_unit_;
}
auto sine_term = c->SineTerm() * length_unit_;
auto sine_term = c.SineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
auto theta = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -661,7 +657,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -698,16 +694,16 @@ class curve_segment_evaluator {
}
#endif
void polynomial_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
void polynomial_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
auto theta = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_ * length_unit_, lu = length_unit_](double t) -> double {
auto a0 = A0.get_value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
};
@@ -718,14 +714,14 @@ class curve_segment_evaluator {
// this is same as cant function in polynomial_cant_spiral
auto curvature = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -734,20 +730,20 @@ class curve_segment_evaluator {
set_spiral_function(s, fn_x, fn_y, curvature);
}
void polynomial_cant_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
boost::optional<std::function<double(double)>> super, slope;
void polynomial_cant_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -758,13 +754,13 @@ class curve_segment_evaluator {
if (!slope.has_value()) {
slope = [A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
}
@@ -773,11 +769,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcSecondOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -788,15 +784,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcThirdOrderPolynomialSpiral
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
#ifdef SCHEMA_IfcThirdOrderPolynomialSpiral_HAS_CubicTerm
A3 = c->CubicTerm();
A3 = c.CubicTerm();
#else
A3 = c->QubicTerm();
A3 = c.QubicTerm();
#endif
if (segment_type_ == ST_CANT) {
@@ -808,15 +804,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcSeventhOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
auto A3 = c->CubicTerm();
auto A4 = c->QuarticTerm();
auto A5 = c->QuinticTerm();
auto A6 = c->SexticTerm();
auto A7 = c->SepticTerm();
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
auto A3 = c.CubicTerm();
auto A4 = c.QuarticTerm();
auto A5 = c.QuinticTerm();
auto A6 = c.SexticTerm();
auto A7 = c.SepticTerm();
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -826,10 +822,10 @@ class curve_segment_evaluator {
}
#endif
void operator()(const IfcSchema::IfcCircle* c) {
void operator()(const IfcSchema::IfcCircle& c) {
if (segment_type_ == ST_HORIZONTAL || segment_type_ == ST_VERTICAL) {
auto R = c->Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c->Position()))->ccomponents();
auto R = c.Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c.Position()))->ccomponents();
// center point of the parent curve
auto pcCenterX = parent_curve_position(0, 3);
@@ -854,7 +850,7 @@ class curve_segment_evaluator {
} else {
Eigen::Matrix4d curve_segment_placement;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_->Placement()))->ccomponents();
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_.Placement()))->ccomponents();
#endif
auto csStartX = curve_segment_placement(0, 3);
auto csStartY = curve_segment_placement(1, 3);
@@ -965,10 +961,10 @@ class curve_segment_evaluator {
}
}
void operator()(const IfcSchema::IfcLine* l) {
void operator()(const IfcSchema::IfcLine& l) {
projected_length_ = length_;
auto c = l->Pnt()->Coordinates();
auto c = l.Pnt().Coordinates();
auto pcX = c[0] * length_unit_;
auto pcY = c[1] * length_unit_;
@@ -980,7 +976,7 @@ class curve_segment_evaluator {
//
// Magnitude is not used because it relates to the parameterization of the line, which isn't currently done for IfcCurveSegment
// @todo - parameterization was recently added so Magnitude needs to be taking into consideration
auto dr = l->Dir()->Orientation()->DirectionRatios();
auto dr = l.Dir().Orientation().DirectionRatios();
// normalize the direction ratios
double m_squared = std::inner_product(dr.begin(), dr.end(), dr.begin(), 0.0);
@@ -1039,11 +1035,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcPolynomialCurve
void operator()(const IfcSchema::IfcPolynomialCurve* pc) {
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<double>());
auto coeffY = pc->CoefficientsY().get_value_or(std::vector<double>());
auto coeffZ = pc->CoefficientsZ().get_value_or(std::vector<double>());
auto coeffX = pc.CoefficientsX().value_or(std::vector<double>());
auto coeffY = pc.CoefficientsY().value_or(std::vector<double>());
auto coeffZ = pc.CoefficientsZ().value_or(std::vector<double>());
if (!coeffZ.empty()) {
Logger::Warning("Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc);
}
@@ -1187,7 +1183,7 @@ class curve_segment_evaluator {
};
} // namespace
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment& inst) {
curve_segment_evaluator cse(this, inst, length_unit_);
boost::mpl::for_each<curve_seg_types, boost::type<boost::mpl::_>>(std::ref(cse));
return cse.get_segment_curve_function();
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcCylindricalSurface
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCylindricalSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCylindricalSurface& inst) {
auto c = taxonomy::make<taxonomy::cylinder>();
c->radius = inst->Radius() * length_unit_;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
c->radius = inst.Radius() * length_unit_;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return c;
}
+4 -4
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
auto it = map(inst->ParentProfile());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef& inst) {
auto it = map(inst.ParentProfile());
if (it == nullptr) {
return nullptr;
}
@@ -32,7 +32,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
taxonomy::matrix4::ptr m;
bool is_mirror = false;
#ifdef SCHEMA_HAS_IfcMirroredProfileDef
if (inst->as<IfcSchema::IfcMirroredProfileDef>()) {
if (inst.as<IfcSchema::IfcMirroredProfileDef>()) {
m = taxonomy::make<taxonomy::matrix4>();
// @todo test
m->components().col(0) *= -1.;
@@ -40,7 +40,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) {
}
#endif
if (!is_mirror) {
m = taxonomy::cast<taxonomy::matrix4>(map(inst->Operator()));
m = taxonomy::cast<taxonomy::matrix4>(map(inst.Operator()));
if (!m) {
return nullptr;
}
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDirection* inst) {
auto coords = inst->DirectionRatios();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDirection& inst) {
auto coords = inst.DirectionRatios();
return taxonomy::make<taxonomy::direction3>(
coords.size() >= 1 ? coords[0] : 0.,
coords.size() >= 2 ? coords[1] : 0.,
+10 -8
View File
@@ -21,15 +21,17 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) {
if (!inst->EdgeStart()->declaration().is(IfcSchema::IfcVertexPoint::Class()) || !inst->EdgeEnd()->declaration().is(IfcSchema::IfcVertexPoint::Class())) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge& inst) {
auto v1 = inst.EdgeStart().as<IfcSchema::IfcVertexPoint>();
auto v2 = inst.EdgeStart().as<IfcSchema::IfcVertexPoint>();
if (!v1 || !v2) {
Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", inst);
return nullptr;
}
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) inst->EdgeStart())->VertexGeometry();
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) inst->EdgeEnd())->VertexGeometry();
if (!pnt1->declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2->declaration().is(IfcSchema::IfcCartesianPoint::Class())) {
auto pnt1 = v1.VertexGeometry();
auto pnt2 = v2.VertexGeometry();
if (!pnt1.declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2.declaration().is(IfcSchema::IfcCartesianPoint::Class())) {
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", inst);
return nullptr;
}
@@ -39,15 +41,15 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) {
e->start = taxonomy::cast<taxonomy::point3>(map(pnt1));
e->end = taxonomy::cast<taxonomy::point3>(map(pnt2));
if (inst->as<IfcSchema::IfcEdgeCurve>()) {
auto basis = map(inst->as<IfcSchema::IfcEdgeCurve>()->EdgeGeometry());
if (auto ec = inst.as<IfcSchema::IfcEdgeCurve>()) {
auto basis = map(ec.EdgeGeometry());
auto loop = taxonomy::dcast<taxonomy::loop>(basis);
if (loop && loop->children.size() == 1) {
loop->calculate_linear_edge_curves();
basis = loop->children[0]->basis;
}
e->basis = basis;
e->curve_sense = inst->as<IfcSchema::IfcEdgeCurve>()->SameSense();
e->curve_sense = ec.SameSense();
}
return e;
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdgeLoop* inst) {
return map_to_collection<taxonomy::loop>(this, inst->EdgeList());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdgeLoop& inst) {
return map_to_collection<taxonomy::loop>(this, inst.EdgeList());
}
+4 -4
View File
@@ -21,9 +21,9 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) {
double x = inst->SemiAxis1() * length_unit_;
double y = inst->SemiAxis2() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse& inst) {
double x = inst.SemiAxis1() * length_unit_;
double y = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
@@ -31,7 +31,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) {
}
auto el = taxonomy::make<taxonomy::ellipse>();
el->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
el->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
// Open Cascade does not allow ellipses of which the minor radius
// is greater than the major radius. Hence, in this case, the
+5 -5
View File
@@ -21,9 +21,9 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) {
double rx = inst->SemiAxis1() * length_unit_;
double ry = inst->SemiAxis2() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef& inst) {
double rx = inst.SemiAxis1() * length_unit_;
double ry = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (rx < tol || ry < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
@@ -35,10 +35,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
} else {
// matrix needs to be set on elementary curves.
m4 = taxonomy::make<taxonomy::matrix4>();
+7 -7
View File
@@ -24,8 +24,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
const double height = inst->Depth() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
#ifndef PERMISSIVE_EXTRUSION
@@ -36,10 +36,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
#ifdef PERMISSIVE_EXTRUSION
@@ -49,7 +49,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
}
#endif
auto basis = map(inst->SweptArea());
auto basis = map(inst.SweptArea());
if (auto bases = taxonomy::dcast<taxonomy::collection>(basis)) {
// @todo this requires a unified approach for all sweeps
auto c = taxonomy::make<taxonomy::collection>();
@@ -58,7 +58,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
taxonomy::make<taxonomy::extrusion>(
matrix,
taxonomy::cast<taxonomy::face>(f),
taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection())),
taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection())),
height
)
);
@@ -69,7 +69,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
return taxonomy::make<taxonomy::extrusion>(
matrix,
taxonomy::cast<taxonomy::face>(basis),
taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection())),
taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection())),
height
);
}
@@ -24,22 +24,22 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcExtrudedAreaSolidTapered
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) {
const double height = inst->Depth() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
return nullptr;
}
taxonomy::direction3::ptr dir = taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection()));
taxonomy::direction3::ptr dir = taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection()));
Eigen::Affine3d af3d(Eigen::Translation3d(height * dir->ccomponents()));
Eigen::Matrix4d end_profile = af3d.matrix();
auto loft = taxonomy::make<taxonomy::loft>();
loft->axis = nullptr;
loft->children = {
taxonomy::cast<taxonomy::face>(map(inst->SweptArea())),
taxonomy::cast<taxonomy::face>(map(inst->EndSweptArea()))
taxonomy::cast<taxonomy::face>(map(inst.SweptArea())),
taxonomy::cast<taxonomy::face>(map(inst.EndSweptArea()))
};
if (!loft->children.back()->matrix) {
@@ -51,10 +51,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* in
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
loft->matrix = matrix;
+8 -331
View File
@@ -21,16 +21,16 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace& inst) {
auto face = taxonomy::make<taxonomy::face>();
auto bounds = inst->Bounds();
for (auto& bound : *bounds) {
if (auto r = taxonomy::cast<taxonomy::loop>(map(bound->Bound()))) {
if (!bound->Orientation()) {
auto bounds = inst.Bounds();
for (auto& bound : bounds) {
if (auto r = taxonomy::cast<taxonomy::loop>(map(bound.Bound()))) {
if (!bound.Orientation()) {
r->reverse();
}
// @todo check why loop sets external to true initially
r->external = bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class());
r->external = bound.declaration().is(IfcSchema::IfcFaceOuterBound::Class());
/*
// Make a copy in case we need immutability later for e.g. caching
auto s = r->clone();
@@ -42,10 +42,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
}
}
auto face_surface = inst->as<IfcSchema::IfcFaceSurface>();
auto face_surface = inst.as<IfcSchema::IfcFaceSurface>();
if (face_surface) {
face->basis = map(face_surface->FaceSurface());
face->basis = map(face_surface.FaceSurface());
}
if (face->children.empty()) {
@@ -56,326 +56,3 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) {
}
return face;
}
/*
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <Geom_Line.hxx>
#include <Geom_Plane.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
#include <ShapeFix_Shape.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
#include <BRep_Tool.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <BRepLib_FindSurface.hxx>
#include <ShapeExtend_MsgRegistrator.hxx>
#include <Message_Msg.hxx>
#include "mapping.h"
#include "../ifcgeom_schema_agnostic/face_definition.h"
#include "../ifcgeom_schema_agnostic/wire_utils.h"
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* l, TopoDS_Shape& result) {
IfcSchema::IfcFaceBound::list::ptr bounds = inst->Bounds();
util::face_definition fd;
const bool is_face_surface = inst->declaration().is(IfcSchema::IfcFaceSurface::Class());
if (is_face_surface) {
IfcSchema::IfcFaceSurface* fs = (IfcSchema::IfcFaceSurface*) l;
fs->FaceSurface();
// FIXME: Surfaces are interpreted as a TopoDS_Shape
TopoDS_Shape surface_shape;
if (!convert_shape(fs->FaceSurface(), surface_shape)) return false;
// FIXME: Assert this obtains the only face
TopExp_Explorer exp(surface_shape, TopAbs_FACE);
if (!exp.More()) return false;
TopoDS_Face surface = TopoDS::Face(exp.Current());
fd.surface() = BRep_Tool::Surface(surface);
}
const int num_bounds = bounds->size();
int num_outer_bounds = 0;
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
IfcSchema::IfcFaceBound* bound = *it;
if (bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class())) num_outer_bounds ++;
}
// The number of outer bounds should be one according to the schema. Also Open Cascade
// expects this, but it is not strictly checked. Regardless, if the number is greater,
// the face will still be processed as long as there are no holes. A compound of faces
// is returned in that case.
if (num_bounds > 1 && num_outer_bounds > 1 && num_bounds != num_outer_bounds) {
Logger::Message(Logger::LOG_ERROR, "Invalid configuration of boundaries for:", l);
return false;
}
if (num_outer_bounds > 1) {
Logger::Message(Logger::LOG_WARNING, "Multiple outer boundaries for:", l);
fd.all_outer() = true;
}
TopTools_DataMapOfShapeInteger wire_senses;
for (int process_interior = 0; process_interior <= 1; ++process_interior) {
for (IfcSchema::IfcFaceBound::list::it it = bounds->begin(); it != bounds->end(); ++it) {
IfcSchema::IfcFaceBound* bound = *it;
IfcSchema::IfcLoop* loop = bound->Bound();
bool same_sense = bound->Orientation();
const bool is_interior =
!bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class()) &&
(num_bounds > 1) &&
(num_outer_bounds < num_bounds);
// The exterior face boundary is processed first
if (is_interior == !process_interior) continue;
TopTools_ListOfShape wires;
TopoDS_Wire wire;
if (faceset_helper_ && loop->as<IfcSchema::IfcPolyLoop>()) {
if (!faceset_helper_->wires(loop->as<IfcSchema::IfcPolyLoop>(), wires)) {
Logger::Message(Logger::LOG_WARNING, "Face boundary loop not included", loop);
continue;
}
} else {
if (convert_wire(loop, wire)) {
wires.Append(wire);
} else {
Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop);
return false;
}
}
if (wires.Size() > 1) {
Logger::Message(Logger::LOG_WARNING, "Face loop definition results in " + std::to_string(wires.Size()) + " loops", loop);
if (!is_interior) {
fd.all_outer() = true;
}
}
for (auto& w : wires) {
if (!same_sense) {
w.Reverse();
}
wire_senses.Bind(w.Oriented(TopAbs_FORWARD), same_sense ? TopAbs_FORWARD : TopAbs_REVERSED);
fd.wires().emplace_back(TopoDS::Wire(w));
}
}
}
if (fd.wires().empty()) {
Logger::Warning("Face with no boundaries", l);
return false;
}
if (fd.surface().IsNull()) {
// Use the first wire to find a plane manually for polygonal wires
const TopoDS_Wire& wire = fd.wires().front();
if (util::is_polyhedron(wire)) {
TopExp_Explorer exp(wire, TopAbs_EDGE);
int count = 0;
TopoDS_Edge edges[2];
for (; exp.More(); exp.Next(), count++) {
if (count < 2) {
edges[count] = TopoDS::Edge(exp.Current());
}
}
if (count == 3) {
// Help Open Cascade by finding the plane more efficiently
double _, __;
Handle(Geom_Line) c1 = Handle(Geom_Line)::DownCast(BRep_Tool::Curve(edges[0], _, __));
Handle(Geom_Line) c2 = Handle(Geom_Line)::DownCast(BRep_Tool::Curve(edges[1], _, __));
const gp_Vec ab = c1->Position().Direction();
const gp_Vec ac = c2->Position().Direction();
const gp_Vec cross = ab.Crossed(ac);
if (cross.SquareMagnitude() > ALMOST_ZERO) {
const gp_Dir n = cross;
fd.surface() = new Geom_Plane(c1->Position().Location(), n);
}
} else {
gp_Pln pln;
if (util::approximate_plane_through_wire(wire, pln, getValue(GV_PRECISION))) {
fd.surface() = new Geom_Plane(pln);
}
}
}
}
if (fd.surface().IsNull()) {
// BRepLib_FindSurface is used in case no surface is found or provided
const TopoDS_Wire& wire = fd.wires().front();
BRepLib_FindSurface fs(wire, getValue(GV_PRECISION), true, true);
if (fs.Found()) {
fd.surface() = fs.Surface();
ShapeFix_ShapeTolerance ftol;
ftol.SetTolerance(wire, fs.ToleranceReached(), TopAbs_WIRE);
}
}
TopTools_ListOfShape face_list;
if (fd.surface().IsNull()) {
// The set of wires is triangulated in case no surface can be found
Logger::Message(Logger::LOG_WARNING, "Triangulating face boundaries for face", l);
if (fd.all_outer()) {
for (const auto& w : fd.wires()) {
TopTools_ListOfShape fl;
auto r = util::triangulate_wire({ w }, fl);
if (r == util::TRIANGULATE_WIRE_FAIL) {
continue;
}
face_list.Append(fl);
if (faceset_helper_ && r == util::TRIANGULATE_WIRE_NON_MANIFOLD) {
faceset_helper_->non_manifold() = true;
}
}
} else {
auto r = util::triangulate_wire(fd.wires(), face_list);
if (r != util::TRIANGULATE_WIRE_FAIL) {
if (faceset_helper_ && r == util::TRIANGULATE_WIRE_NON_MANIFOLD) {
faceset_helper_->non_manifold() = true;
}
}
}
} else if (!fd.all_outer()) {
BRepBuilderAPI_MakeFace mf(fd.surface(), fd.outer_wire());
TopoDS_Face f = mf.Face();
if (mf.IsDone()) {
if (std::distance(fd.inner_wires().first, fd.inner_wires().second)) {
mf.Init(f);
for (auto it = fd.inner_wires().first; it != fd.inner_wires().second; ++it) {
mf.Add(*it);
}
face_list.Append(mf.Face());
} else {
face_list.Append(f);
}
}
} else {
for (const auto& w : fd.wires()) {
BRepBuilderAPI_MakeFace mf(fd.surface(), w);
if (mf.IsDone()) {
face_list.Append(mf.Face());
}
}
}
if (!fd.surface().IsNull()) {
// Some fixes for orientation and p-curves. If we have no surface, it
// means the face has been triangulated in which case none of these
// fixes are necessary.
if (fd.surface()->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
// In case of (non-planar) face surface, p-curves need to be computed.
// For planar faces, Open Cascade generates p-curves on the fly.
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
ShapeFix_Shape sfs(it.Value());
Handle(ShapeExtend_MsgRegistrator) msg;
msg = new ShapeExtend_MsgRegistrator;
sfs.SetMsgRegistrator(msg);
sfs.Perform();
it.Value() = sfs.Shape();
ShapeExtend_DataMapIteratorOfDataMapOfShapeListOfMsg jt(msg->MapShape());
for (; jt.More(); jt.Next()) {
Message_ListIteratorOfListOfMsg kt(jt.Value());
for (; kt.More(); kt.Next()) {
char* c = new char[kt.Value().Value().LengthOfCString() + 1];
kt.Value().Value().ToUTF8CString(c);
Logger::Notice(c, l);
delete[] c;
}
}
}
}
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
const TopoDS_Face& face = TopoDS::Face(it.Value());
ShapeFix_Face sfs(TopoDS::Face(face));
TopTools_DataMapOfShapeListOfShape wire_map;
sfs.FixOrientation(wire_map);
TopoDS_Iterator jt(face, false);
for (; jt.More(); jt.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(jt.Value());
// tfk: @todo if wire_map contains w, I would assume wire_senses also contains w,
// this is not the case in github issue #405.
if (wire_map.IsBound(w) && wire_senses.IsBound(w)) {
const TopTools_ListOfShape& shapes = wire_map.Find(w);
TopTools_ListIteratorOfListOfShape kt(shapes);
for (; kt.More(); kt.Next()) {
// Apparently the wire got reversed, so register it with opposite orientation in the map
wire_senses.Bind(kt.Value(), wire_senses.Find(w) == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
}
}
}
it.Value() = sfs.Face();
}
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
TopoDS_Face& face = TopoDS::Face(it.Value());
bool all_reversed = true;
TopoDS_Iterator jt(face, false);
for (; jt.More(); jt.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(jt.Value());
if (!wire_senses.IsBound(w.Oriented(TopAbs_FORWARD)) || (w.Orientation() == wire_senses.Find(w.Oriented(TopAbs_FORWARD)))) {
all_reversed = false;
}
}
if (all_reversed) {
face.Reverse();
}
}
}
if (face_list.Extent() == 0) {
return false;
} else if (face_list.Extent() > 1) {
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
for (TopTools_ListIteratorOfListOfShape it(face_list); it.More(); it.Next()) {
TopoDS_Face& face = TopoDS::Face(it.Value());
builder.Add(compound, face);
}
result = compound;
} else {
result = face_list.First();
}
return true;
}
*/
@@ -21,7 +21,7 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel& inst) {
// @todo check styles?
return map_to_collection(this, inst->FbsmFaces());
return map_to_collection(this, inst.FbsmFaces());
}
@@ -24,10 +24,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcFixedReferenceSweptAreaSolid
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid* inst) {
auto dir = map(inst->Directrix());
auto ref = taxonomy::cast<taxonomy::direction3>(map(inst->FixedReference()));
auto profile = taxonomy::cast<taxonomy::face>(map(inst->SweptArea()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid& inst) {
auto dir = map(inst.Directrix());
auto ref = taxonomy::cast<taxonomy::direction3>(map(inst.FixedReference()));
auto profile = taxonomy::cast<taxonomy::face>(map(inst.SweptArea()));
auto loft = taxonomy::make<taxonomy::loft>();
// @todo intialize as default
@@ -42,14 +42,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
// 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.
if (inst->StartParam() && inst->StartParam()->as<IfcSchema::IfcLengthMeasure>()) {
double s = *inst->StartParam()->as<IfcSchema::IfcLengthMeasure>();
if (inst.StartParam() && inst.StartParam().as<IfcSchema::IfcLengthMeasure>()) {
double s = inst.StartParam().as<IfcSchema::IfcLengthMeasure>();
if (s > start) {
start = s;
}
}
if (inst->EndParam() && inst->EndParam()->as<IfcSchema::IfcLengthMeasure>()) {
double e = *inst->EndParam()->as<IfcSchema::IfcLengthMeasure>();
if (inst.EndParam() && inst.EndParam().as<IfcSchema::IfcLengthMeasure>()) {
double e = inst.EndParam().as<IfcSchema::IfcLengthMeasure>();
if (e < end) {
end = e;
}
@@ -71,7 +71,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
bool is_directrix_derived = false;
#ifdef SCHEMA_HAS_IfcDirectrixDerivedReferenceSweptAreaSolid
if (inst->as<IfcSchema::IfcDirectrixDerivedReferenceSweptAreaSolid>()) {
if (inst.as<IfcSchema::IfcDirectrixDerivedReferenceSweptAreaSolid>()) {
is_directrix_derived = true;
}
#endif
@@ -116,8 +116,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFixedReferenceSweptAreaSolid
}
} else {
taxonomy::matrix4::ptr matrix;
if (inst->Position() != nullptr) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
if (inst.Position()) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
// TODO: Implement handling for non-alignment curves using sweep_along_curve
auto sweep = taxonomy::make<taxonomy::sweep_along_curve>(
+2 -2
View File
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGeometricSet* inst) {
return map_to_collection(this, inst->Elements());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGeometricSet& inst) {
return map_to_collection(this, inst.Elements());
}
+9 -9
View File
@@ -24,18 +24,18 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcGradientCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
if (!inst->BaseCurve()->as<IfcSchema::IfcCompositeCurve>())
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve& inst) {
if (!inst.BaseCurve().as<IfcSchema::IfcCompositeCurve>())
Logger::Warning("Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
auto segments = inst->Segments();
auto segments = inst.Segments();
taxonomy::piecewise_function::spans_t spans;
for (auto& segment : *segments) {
if (segment->as<IfcSchema::IfcCurveSegment>()) {
for (auto& segment : segments) {
if (segment.as<IfcSchema::IfcCurveSegment>()) {
// @todo check that we don't get a mixture of implicit and explicit definitions
auto crv = map(segment->as<IfcSchema::IfcCurveSegment>());
auto crv = map(segment.as<IfcSchema::IfcCurveSegment>());
if (auto fi = taxonomy::dcast<taxonomy::function_item>(crv); crv && fi /*crv->kind() == taxonomy::FUNCTION_ITEM*/) {
// crv->kind() is polymorphic and the kind of the actual function_item is returned. PWF can have spans of any FUNCTION_ITEM
// for this reason, a dynamic cast is used and if crv is a function_item it is added to the span
@@ -52,10 +52,10 @@ 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& first_segment = segments.front();
taxonomy::matrix4::ptr p;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment->as<IfcSchema::IfcCurveSegment>()->Placement()));
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment.as<IfcSchema::IfcCurveSegment>().Placement()));
#else
throw std::runtime_error("Unsupported schema");
#endif
@@ -66,7 +66,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
auto vertical = taxonomy::make<taxonomy::piecewise_function>(gradient_start, spans);
// create the horizontal pwf
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst.BaseCurve()));
// create the composite gradient curve function
auto gradient_function = taxonomy::make<taxonomy::gradient_function>(horizontal, vertical, inst);
+6 -5
View File
@@ -21,16 +21,17 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) {
IfcSchema::IfcSurface* surface = inst->BaseSurface();
if (!surface->declaration().is(IfcSchema::IfcPlane::Class())) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid& inst) {
auto surface = inst.BaseSurface();
auto plane = surface.as<IfcSchema::IfcPlane>();
if (!plane) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface);
return nullptr;
}
auto p = taxonomy::make<taxonomy::plane>();
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(((IfcSchema::IfcPlane*)surface)->Position()));
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(plane.Position()));
auto f = taxonomy::make<taxonomy::face>();
f->orientation.reset(!inst->AgreementFlag());
f->orientation.emplace(!inst.AgreementFlag());
f->basis = p;
auto sh = taxonomy::make<taxonomy::shell>();
sh->children.push_back(f);
+19 -20
View File
@@ -23,21 +23,21 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
const bool doFillet1 = !!inst->FilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef& inst) {
const bool doFillet1 = !!inst.FilletRadius();
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
const bool doFlangeEdgeRadius = !!inst->FlangeEdgeRadius();
const bool hasSlope = !!inst->FlangeSlope();
const bool doFlangeEdgeRadius = !!inst.FlangeEdgeRadius();
const bool hasSlope = !!inst.FlangeSlope();
#else
const bool doFlangeEdgeRadius = false;
#endif
const double x1 = inst->OverallWidth() / 2.0f * length_unit_;
const double y = inst->OverallDepth() / 2.0f * length_unit_;
const double d1 = inst->WebThickness() / 2.0f * length_unit_;
const double ft1 = inst->FlangeThickness() * length_unit_;
const double x1 = inst.OverallWidth() / 2.0f * length_unit_;
const double y = inst.OverallDepth() / 2.0f * length_unit_;
const double d1 = inst.WebThickness() / 2.0f * length_unit_;
const double ft1 = inst.FlangeThickness() * length_unit_;
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
const double slope = inst->FlangeSlope().get_value_or(0.) * angle_unit_;
const double slope = inst.FlangeSlope().value_or(0.) * angle_unit_;
#endif
double dy = 0.;
@@ -49,11 +49,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
double ft2 = ft1;
if (doFillet1) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
#ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius
if (doFlangeEdgeRadius) {
fe1 = *inst->FlangeEdgeRadius() * length_unit_;
fe1 = *inst.FlangeEdgeRadius() * length_unit_;
}
if (hasSlope) {
dy = (x1 - d1) * tan(slope);
@@ -63,15 +63,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
bool doFillet2 = doFillet1;
// @todo in IFC4 a IfcAsymmetricIShapeProfileDef is not a subtype anymore of IfcIShapeProfileDef!
if (inst->declaration().is(IfcSchema::IfcAsymmetricIShapeProfileDef::Class())) {
IfcSchema::IfcAsymmetricIShapeProfileDef* assym = (IfcSchema::IfcAsymmetricIShapeProfileDef*) inst;
x2 = assym->TopFlangeWidth() / 2. * length_unit_;
doFillet2 = !!assym->TopFlangeFilletRadius();
if (auto assym = inst.as<IfcSchema::IfcAsymmetricIShapeProfileDef>()) {
x2 = assym.TopFlangeWidth() / 2. * length_unit_;
doFillet2 = !!assym.TopFlangeFilletRadius();
if (doFillet2) {
f2 = *assym->TopFlangeFilletRadius() * length_unit_;
f2 = *assym.TopFlangeFilletRadius() * length_unit_;
}
if (assym->TopFlangeThickness()) {
ft2 = *assym->TopFlangeThickness() * length_unit_;
if (assym.TopFlangeThickness()) {
ft2 = *assym.TopFlangeThickness() * length_unit_;
}
} else {
f2 = f1;
@@ -88,10 +87,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+14 -17
View File
@@ -23,14 +23,14 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcIndexedPolyCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve& inst) {
IfcSchema::IfcCartesianPointList* point_list = inst->Points();
auto point_list = inst.Points();
std::vector< std::vector<double> > coordinates;
if (point_list->as<IfcSchema::IfcCartesianPointList2D>()) {
coordinates = point_list->as<IfcSchema::IfcCartesianPointList2D>()->CoordList();
} else if (point_list->as<IfcSchema::IfcCartesianPointList3D>()) {
coordinates = point_list->as<IfcSchema::IfcCartesianPointList3D>()->CoordList();
if (point_list.as<IfcSchema::IfcCartesianPointList2D>()) {
coordinates = point_list.as<IfcSchema::IfcCartesianPointList2D>().CoordList();
} else if (point_list.as<IfcSchema::IfcCartesianPointList3D>()) {
coordinates = point_list.as<IfcSchema::IfcCartesianPointList3D>().CoordList();
}
std::vector<taxonomy::point3::ptr> points;
@@ -50,13 +50,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
auto loop = taxonomy::make<taxonomy::loop>();
if(inst->Segments()) {
auto segments = *inst->Segments();
for (auto it = segments->begin(); it != segments->end(); ++it) {
auto segment = *it;
if (segment->as<IfcSchema::IfcLineIndex>()) {
IfcSchema::IfcLineIndex* line = segment->as<IfcSchema::IfcLineIndex>();
std::vector<int> indices = *line;
if(inst.Segments()) {
auto segments = inst.Segments();
for (auto& segment : *segments) {
if (auto line = segment.as<IfcSchema::IfcLineIndex>()) {
std::vector<int> indices = line;
taxonomy::point3::ptr previous;
for (std::vector<int>::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) {
if (*jt < 1 || *jt > max_index) {
@@ -68,9 +66,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
}
previous = current;
}
} else if (segment->as<IfcSchema::IfcArcIndex>()) {
IfcSchema::IfcArcIndex* arc = segment->as<IfcSchema::IfcArcIndex>();
std::vector<int> indices = *arc;
} else if (auto arc = segment.as<IfcSchema::IfcArcIndex>()) {
std::vector<int> indices = arc;
if (indices.size() != 3) {
throw IfcParse::IfcException("Invalid IfcArcIndex encountered");
}
@@ -93,7 +90,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) {
Logger::Warning("Ignoring segment on", inst);
}
} else {
throw IfcParse::IfcException("Unexpected IfcIndexedPolyCurve segment of type " + segment->as<IfcUtil::IfcBaseClass>()->declaration().name());
throw IfcParse::IfcException("Unexpected IfcIndexedPolyCurve segment of type " + segment.concrete().declaration().name());
}
}
} else if (points.begin() < points.end()) {
+12 -12
View File
@@ -23,23 +23,23 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) {
const bool hasSlope = !!inst->LegSlope();
const bool doEdgeFillet = !!inst->EdgeRadius();
const bool doFillet = !!inst->FilletRadius();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef& inst) {
const bool hasSlope = !!inst.LegSlope();
const bool doEdgeFillet = !!inst.EdgeRadius();
const bool doFillet = !!inst.FilletRadius();
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->Width().get_value_or(inst->Depth()) / 2.0f * length_unit_;
const double d = inst->Thickness() * length_unit_;
const double slope = inst->LegSlope().get_value_or(0.) * angle_unit_;
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.Width().value_or(inst.Depth()) / 2.0f * length_unit_;
const double d = inst.Thickness() * length_unit_;
const double slope = inst.LegSlope().value_or(0.) * angle_unit_;
double f1 = 0.0f;
double f2 = 0.0f;
if (doFillet) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
if ( doEdgeFillet) {
f2 = *inst->EdgeRadius() * length_unit_;
f2 = *inst.EdgeRadius() * length_unit_;
}
const double tol = settings_.get<settings::Precision>().get();
@@ -88,10 +88,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+3 -3
View File
@@ -21,11 +21,11 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLine* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLine& inst) {
// @todo test with trimmed curve on non-normalized direction
auto l = taxonomy::make<taxonomy::line>();
auto pnt = taxonomy::cast<taxonomy::point3>(map(inst->Pnt()));
auto dir = taxonomy::cast<taxonomy::direction3>(map(inst->Dir()));
auto pnt = taxonomy::cast<taxonomy::point3>(map(inst.Pnt()));
auto dir = taxonomy::cast<taxonomy::direction3>(map(inst.Dir()));
l->matrix = taxonomy::make<taxonomy::matrix4>(pnt->ccomponents(), dir->ccomponents());
return l;
}
+8 -8
View File
@@ -21,24 +21,24 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep* inst) {
IfcSchema::IfcClosedShell::list::ptr voids(new IfcSchema::IfcClosedShell::list);
if (inst->declaration().is(IfcSchema::IfcFacetedBrepWithVoids::Class())) {
voids = inst->as<IfcSchema::IfcFacetedBrepWithVoids>()->Voids();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep& inst) {
std::vector<IfcSchema::IfcClosedShell> voids;
if (inst.declaration().is(IfcSchema::IfcFacetedBrepWithVoids::Class())) {
voids = inst.as<IfcSchema::IfcFacetedBrepWithVoids>().Voids();
}
#ifdef SCHEMA_HAS_IfcAdvancedBrepWithVoids
if (inst->declaration().is(IfcSchema::IfcAdvancedBrepWithVoids::Class())) {
voids = inst->as<IfcSchema::IfcAdvancedBrepWithVoids>()->Voids();
if (inst.declaration().is(IfcSchema::IfcAdvancedBrepWithVoids::Class())) {
voids = inst.as<IfcSchema::IfcAdvancedBrepWithVoids>().Voids();
}
#endif
taxonomy::solid::ptr solid;
if (voids->size()) {
if (!voids.empty()) {
solid = map_to_collection<taxonomy::solid>(this, voids);
} else {
solid = taxonomy::make<taxonomy::solid>();
}
solid->children.insert(solid->children.begin(), taxonomy::cast<taxonomy::shell>(map(inst->Outer())));
solid->children.insert(solid->children.begin(), taxonomy::cast<taxonomy::shell>(map(inst.Outer())));
return solid;
}
+6 -6
View File
@@ -21,19 +21,19 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem* inst) {
IfcSchema::IfcCartesianTransformationOperator* transform = inst->MappingTarget();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem& inst) {
auto transform = inst.MappingTarget();
taxonomy::matrix4::ptr gtrsf = taxonomy::cast<taxonomy::matrix4>(map(transform));
IfcSchema::IfcRepresentationMap* rmap = inst->MappingSource();
IfcSchema::IfcAxis2Placement* placement = rmap->MappingOrigin();
auto rmap = inst.MappingSource();
auto placement = rmap.MappingOrigin();
taxonomy::matrix4::ptr trsf2 = taxonomy::cast<taxonomy::matrix4>(map(placement));
Eigen::Matrix4d res = gtrsf->ccomponents() * trsf2->ccomponents();
// @todo immutable for caching?
// @todo allow for multiple levels of matrix?
auto shapes = taxonomy::dcast<taxonomy::collection>(map(rmap->MappedRepresentation()));
auto shapes = taxonomy::dcast<taxonomy::collection>(map(rmap.MappedRepresentation()));
if (shapes == nullptr) {
if (failed_on_purpose_.find(rmap->MappedRepresentation()) != failed_on_purpose_.end()) {
if (failed_on_purpose_.find(rmap.MappedRepresentation()) != failed_on_purpose_.end()) {
// propagate
failed_on_purpose_.insert(inst);
}
+18 -18
View File
@@ -21,45 +21,45 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) {
const IfcSchema::IfcObjectPlacement* relative_to = nullptr;
const IfcUtil::IfcBaseInterface* transform;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement& inst) {
IfcSchema::IfcObjectPlacement relative_to;
express::Base transform;
const IfcSchema::IfcAxis2Placement3D* fallback = nullptr;
IfcSchema::IfcAxis2Placement3D fallback;
if (inst->as<IfcSchema::IfcLocalPlacement>()) {
transform = inst->as<IfcSchema::IfcLocalPlacement>()->RelativePlacement();
if (inst.as<IfcSchema::IfcLocalPlacement>()) {
transform = inst.as<IfcSchema::IfcLocalPlacement>().RelativePlacement();
}
#ifdef SCHEMA_HAS_IfcLinearPlacement
else if (inst->as<IfcSchema::IfcLinearPlacement>()) {
else if (inst.as<IfcSchema::IfcLinearPlacement>()) {
#ifdef SCHEMA_IfcLinearPlacement_HAS_RelativePlacement
transform = inst->as<IfcSchema::IfcLinearPlacement>()->RelativePlacement();
fallback = inst->as<IfcSchema::IfcLinearPlacement>()->CartesianPosition();
transform = inst.as<IfcSchema::IfcLinearPlacement>().RelativePlacement();
fallback = inst.as<IfcSchema::IfcLinearPlacement>().CartesianPosition();
#else
// @todo Ifc4x1 and Ifc4x2 don't have RelativePlacement
return nullptr;
#endif
}
#endif
else if (inst->as<IfcSchema::IfcGridPlacement>()) {
else if (inst.as<IfcSchema::IfcGridPlacement>()) {
// @todo a bit harder to map without kernel
return nullptr;
}
#ifdef SCHEMA_IfcObjectPlacement_HAS_PlacementRelTo
relative_to = inst->PlacementRelTo();
relative_to = inst.PlacementRelTo();
#else
if (inst->as<IfcSchema::IfcLocalPlacement>()) {
relative_to = inst->as<IfcSchema::IfcLocalPlacement>()->PlacementRelTo();
if (inst.as<IfcSchema::IfcLocalPlacement>()) {
relative_to = inst.as<IfcSchema::IfcLocalPlacement>()->PlacementRelTo();
}
#endif
bool parent_placement_ignored = false;
if (relative_to && (placement_rel_to_type_ || placement_rel_to_instance_)) {
IfcSchema::IfcProduct::list::ptr parent_places = relative_to->PlacesObject();
for (auto iter = parent_places->begin(); iter != parent_places->end(); ++iter) {
if ((placement_rel_to_type_ && (*iter)->declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && (*iter)->as<IfcUtil::IfcBaseEntity>() == placement_rel_to_instance_)) {
std::vector<IfcSchema::IfcProduct> parent_places = relative_to.PlacesObject();
for (auto& pp : parent_places) {
if ((placement_rel_to_type_ && pp.declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && pp == placement_rel_to_instance_)) {
parent_placement_ignored = true;
}
}
@@ -108,7 +108,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) {
/*
// @todo
if (gridp = inst->as<IfcSchema::IfcGridPlacement>()) {
if (gridp = inst.as<IfcSchema::IfcGridPlacement>()) {
gp_Trsf grid_position;
auto axes = gridp->PlacementLocation()->IntersectingAxes();
@@ -30,15 +30,15 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcOffsetCurveByDistances
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst) {
auto offset_values = inst->OffsetValues();
if (offset_values->size() == 0) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst) {
auto offset_values = inst.OffsetValues();
if (offset_values.empty()) {
Logger::Error("IfcOffsetCurveByDistances must have at least one offset value");
}
auto first_offset_value = *(offset_values->begin());
auto& first_offset_value = offset_values.front();
auto basis_curve = inst->BasisCurve();
auto basis_curve = inst.BasisCurve();
// // 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.
@@ -66,9 +66,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
taxonomy::piecewise_function::spans_t offset_spans;
#if defined SCHEMA_HAS_IfcDistanceExpression
double first_distance = first_offset_value->DistanceAlong();
double first_distance = first_offset_value.DistanceAlong();
#else
double first_distance = *first_offset_value->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double first_distance = first_offset_value.DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
#endif
first_distance *= length_unit_;
@@ -80,8 +80,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
{
// First offset is defined after the start of the curve so the lateral and vertical offsets
// implicitly continue with the same value towards the start of the basis curve
double py = first_offset_value->OffsetLateral().get_value_or(0.0);
double pz = first_offset_value->OffsetVertical().get_value_or(0.0);
double py = first_offset_value.OffsetLateral().value_or(0.0);
double pz = first_offset_value.OffsetVertical().value_or(0.0);
py *= length_unit_;
pz *= length_unit_;
@@ -93,17 +93,17 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
offset_spans.emplace_back(taxonomy::make<taxonomy::functor_item>(first_distance, fn));
}
auto iter = offset_values->begin();
auto iter = offset_values.begin();
auto next = std::next(iter);
auto prev = std::prev(next);
auto end = offset_values->end();
auto end = offset_values.end();
for (; next != end; prev++, next++) {
#if defined SCHEMA_HAS_IfcDistanceExpression
double dp = (*prev)->DistanceAlong();
double dn = (*next)->DistanceAlong();
double dp = (*prev).DistanceAlong();
double dn = (*next).DistanceAlong();
#else
double dp = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double dn = *(*next)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>();
double dp = prev->DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
double dn = next->DistanceAlong().as<IfcSchema::IfcLengthMeasure>();
#endif
dp *= length_unit_;
dn *= length_unit_;
@@ -115,10 +115,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
}
double l = (dn - dp);
double yn = (*next)->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 zp = (*prev)->OffsetVertical().get_value_or(0.0) * length_unit_;
double yn = next->OffsetLateral().value_or(0.0) * length_unit_;
double yp = prev->OffsetLateral().value_or(0.0) * length_unit_;
double zn = next->OffsetVertical().value_or(0.0) * length_unit_;
double zp = prev->OffsetVertical().value_or(0.0) * length_unit_;
if ( (dp < 0.0 && dn < 0.0) || (basis_curve_length < dp && basis_curve_length < dn) ) {
// both points are either before the start of the curve or after the end of the curve. ignore them.
@@ -160,14 +160,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
#if defined SCHEMA_HAS_IfcDistanceExpression
double last_distance = (*prev)->DistanceAlong() * length_unit_;
#else
double last_distance = *(*prev)->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>() * length_unit_;
double last_distance = (double) prev->DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_;
#endif
if (last_distance < basis_curve_length) {
// Last offset is defined before the end of the curve so the lateral and vertical offsets
// implicitly continue with the same value towards the end of the basis curve
double py = (*prev)->OffsetLateral().get_value_or(0.0);
double pz = (*prev)->OffsetVertical().get_value_or(0.0);
double py = prev->OffsetLateral().value_or(0.0);
double pz = prev->OffsetVertical().value_or(0.0);
py *= length_unit_;
pz *= length_unit_;
double l = basis_curve_length - last_distance;
+13 -13
View File
@@ -30,37 +30,37 @@ const double PI = boost::math::constants::pi<double>();
#ifdef SCHEMA_HAS_IfcOpenCrossProfileDef
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) {
if (inst->ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef& inst) {
if (inst.ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
Logger::Warning("Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst);
return nullptr;
}
std::vector<taxonomy::point3::ptr> points;
taxonomy::point3::ptr start;
if (inst->OffsetPoint()) {
start = taxonomy::cast<taxonomy::point3>(map(inst->OffsetPoint()));
if (inst.OffsetPoint()) {
start = taxonomy::cast<taxonomy::point3>(map(inst.OffsetPoint()));
} else {
start = taxonomy::make<taxonomy::point3>(0., 0., 0.);
}
points.push_back(start);
boost::optional<std::vector<std::string>> tags = inst->Tags();
boost::optional<std::string> tag = boost::none;
if (tags.has_value() && !tags.get().empty()) {
tag = tags.get()[0];
std::optional<std::vector<std::string>> tags = inst.Tags();
std::optional<std::string> tag;
if (tags.has_value() && !tags.value().empty()) {
tag = tags.value()[0];
}
// start->tag = tag;
auto widths = inst->Widths();
auto angles = inst->Slopes(); // these are actually angles, but the attribute is called Slopes
auto widths = inst.Widths();
auto angles = inst.Slopes(); // these are actually angles, but the attribute is called Slopes
if (widths.size() != angles.size()) {
Logger::Warning("Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst);
return nullptr;
}
auto horizontal_widths = inst->HorizontalWidths();
auto horizontal_widths = inst.HorizontalWidths();
double x = start->ccomponents().x();
double y = start->ccomponents().y();
@@ -75,8 +75,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef* inst) {
y += dy;
z += dz;
if (tags.has_value() && !tags.get().empty()) {
tag = tags.get()[i+1];
if (tags.has_value() && !tags.value().empty()) {
tag = tags.value()[i+1];
}
points.push_back(taxonomy::make<taxonomy::point3>(x, y, z));
+3 -3
View File
@@ -21,10 +21,10 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOrientedEdge* inst) {
auto e = taxonomy::cast<taxonomy::edge>(map(inst->EdgeElement()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOrientedEdge& inst) {
auto e = taxonomy::cast<taxonomy::edge>(map(inst.EdgeElement()));
e.reset(e->clone_());
if (!inst->Orientation()) {
if (!inst.Orientation()) {
e->reverse();
}
return e;
+2 -2
View File
@@ -21,8 +21,8 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPlane* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPlane& inst) {
auto p = taxonomy::make<taxonomy::plane>();
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
p->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return p;
}
@@ -26,9 +26,9 @@ using namespace ifcopenshell::geometry;
#if defined SCHEMA_HAS_IfcPointByDistanceExpression
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression* inst) {
auto u = (*inst->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>()) * length_unit_;
auto basis_curve = map(inst->BasisCurve());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression& inst) {
auto u = (double) inst.DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_;
auto basis_curve = map(inst.BasisCurve());
taxonomy::function_item::ptr curve = taxonomy::dcast<taxonomy::function_item>(basis_curve);
if (!curve) {
// if the basis curve is not a function_item, the cast it to piecewise_function. the casting operator
@@ -43,19 +43,19 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression* i
auto z = m.col(2).head<3>();
auto x = m.col(0).head<3>();
if (inst->OffsetLateral().has_value()) {
auto offset_lateral = inst->OffsetLateral().get() * length_unit_;
if (inst.OffsetLateral().has_value()) {
auto offset_lateral = inst.OffsetLateral().value() * length_unit_;
auto y = Eigen::Vector3d(m.col(1)(0), m.col(1)(1), m.col(1)(2));
o += offset_lateral * y;
}
if (inst->OffsetVertical().has_value()) {
auto offset_vertical = inst->OffsetVertical().get() * length_unit_;
if (inst.OffsetVertical().has_value()) {
auto offset_vertical = inst.OffsetVertical().value() * length_unit_;
o += offset_vertical * z;
}
if (inst->OffsetLongitudinal().has_value()) {
auto offset_longitudinal = inst->OffsetLongitudinal().get() * length_unit_;
if (inst.OffsetLongitudinal().has_value()) {
auto offset_longitudinal = inst.OffsetLongitudinal().value() * length_unit_;
o += offset_longitudinal* x;
}
+4 -4
View File
@@ -23,13 +23,13 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) {
IfcSchema::IfcCartesianPoint::list::ptr points = inst->Polygon();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop& inst) {
std::vector<IfcSchema::IfcCartesianPoint> points = inst.Polygon();
// Parse and store the points in a sequence
std::vector<taxonomy::point3::ptr> polygon;
polygon.reserve(points->size());
std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) {
polygon.reserve(points.size());
std::transform(points.begin(), points.end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint& p) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
@@ -21,10 +21,10 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace* inst) {
auto s = taxonomy::cast<taxonomy::solid>(map_impl((IfcSchema::IfcHalfSpaceSolid*) inst));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace& inst) {
auto s = taxonomy::cast<taxonomy::solid>(map_impl((IfcSchema::IfcHalfSpaceSolid&) inst));
auto f = s->children[0]->children[0];
f->children = { taxonomy::cast<taxonomy::loop>(map(inst->PolygonalBoundary())) };
f->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
f->children = { taxonomy::cast<taxonomy::loop>(map(inst.PolygonalBoundary())) };
f->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return s;
}
+8 -8
View File
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcPolygonalFaceSet
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
IfcSchema::IfcCartesianPointList3D* point_list = inst->Coordinates();
auto coordinates = point_list->CoordList();
auto polygonal_faces = inst->Faces();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet& inst) {
auto point_list = inst.Coordinates();
auto coordinates = point_list.CoordList();
auto polygonal_faces = inst.Faces();
std::vector<taxonomy::point3::ptr> points;
points.reserve(coordinates.size());
@@ -41,7 +41,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
auto shell = taxonomy::make<taxonomy::shell>();
for (auto& f : *polygonal_faces) {
for (auto& f : polygonal_faces) {
auto fa = taxonomy::make<taxonomy::face>();
shell->children.push_back(fa);
@@ -49,7 +49,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
auto loop = taxonomy::make<taxonomy::loop>();
fa->children = { loop };
loop->external = true;
auto indices = f->CoordIndex();
auto indices = f.CoordIndex();
taxonomy::point3::ptr previous;
for (std::vector<int>::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) {
if (*jt < 1 || *jt > max_index) {
@@ -67,8 +67,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) {
}
}
if (f->as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()) {
auto indices = f->as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()->InnerCoordIndices();
if (auto withvoids = f.as<IfcSchema::IfcIndexedPolygonalFaceWithVoids>()) {
auto indices = withvoids.InnerCoordIndices();
{
taxonomy::point3::ptr previous;
for (auto& li : indices) {
+4 -4
View File
@@ -23,13 +23,13 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) {
IfcSchema::IfcCartesianPoint::list::ptr points = inst->Points();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline& inst) {
std::vector<IfcSchema::IfcCartesianPoint> points = inst.Points();
// Parse and store the points in a sequence
std::vector<taxonomy::point3::ptr> polygon;
polygon.reserve(points->size());
std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) {
polygon.reserve(points.size());
std::transform(points.begin(), points.end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint& p) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
+6 -6
View File
@@ -4,12 +4,12 @@ using namespace ifcopenshell::geometry;
using namespace IfcGeom;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct& inst) {
// @todo decide on this, what happens in the product mapping?
// currently things like openings, layers and materials are processed in the converter
auto c = taxonomy::make<taxonomy::collection>();
if (inst->ObjectPlacement()) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->ObjectPlacement()));
if (inst.ObjectPlacement()) {
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.ObjectPlacement()));
} else {
// @todo Otherwise we get crashes in the serializer, but maybe fix them there..?
c->matrix = taxonomy::make<taxonomy::matrix4>();
@@ -21,7 +21,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
auto openings = find_openings(inst);
// @todo const cast
auto reps = inst->data().file->traverse((IfcSchema::IfcProduct*) inst, 2)->as<IfcSchema::IfcRepresentation>();
auto reps = inst.data().file->traverse((IfcSchema::IfcProduct*) inst, 2)->as<IfcSchema::IfcRepresentation>();
IfcSchema::IfcRepresentation* body = nullptr;
for (auto& rep : *reps) {
if (rep->RepresentationIdentifier()) {
@@ -35,7 +35,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
}
auto c = new taxonomy::collection;
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->ObjectPlacement()));
c->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.ObjectPlacement()));
const auto single_material = get_single_material_association(inst);
if (single_material) {
@@ -54,7 +54,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) {
ci.setIdentity();
}
aggregate_of_instance::ptr operands(new aggregate_of_instance);
std::vector<express::Base> operands(new aggregate_of_instance);
operands->push(body);
operands->push(openings);
auto n = map_to_collection<taxonomy::boolean_result>(this, operands);
@@ -23,16 +23,16 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
const double d = inst->WallThickness() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef& inst) {
const double x = inst.XDim() / 2.0f * length_unit_;
const double y = inst.YDim() / 2.0f * length_unit_;
const double d = inst.WallThickness() * length_unit_;
const bool fr1 = !!inst->OuterFilletRadius();
const bool fr2 = !!inst->InnerFilletRadius();
const bool fr1 = !!inst.OuterFilletRadius();
const bool fr2 = !!inst.InnerFilletRadius();
const double r1 = fr1 ? (*inst->OuterFilletRadius()) * length_unit_ : 0.;
const double r2 = fr2 ? (*inst->InnerFilletRadius()) * length_unit_ : 0.;
const double r1 = fr1 ? (*inst.OuterFilletRadius()) * length_unit_ : 0.;
const double r2 = fr2 ? (*inst.InnerFilletRadius()) * length_unit_ : 0.;
const double tol = settings_.get<settings::Precision>().get();
@@ -44,10 +44,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* i
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
auto s1 = profile_helper(m4, {
@@ -23,9 +23,9 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef& inst) {
const double x = inst.XDim() / 2.0f * length_unit_;
const double y = inst.YDim() / 2.0f * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
@@ -37,10 +37,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularPyramid* inst) {
const double dx = inst->XLength() * length_unit_;
const double dy = inst->YLength() * length_unit_;
const double dz = inst->Height() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularPyramid& inst) {
const double dx = inst.XLength() * length_unit_;
const double dy = inst.YLength() * length_unit_;
const double dz = inst.Height() * length_unit_;
auto solid = taxonomy::make<taxonomy::solid>();
auto shell = taxonomy::make<taxonomy::shell>();
@@ -105,7 +105,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularPyramid* inst) {
face->children.push_back(polygon_from_points(points));
}
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
solid->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
return solid;
}
@@ -21,19 +21,19 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularTrimmedSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularTrimmedSurface& inst) {
// @todo we'll need to add support for p-curves at some point, but not now.
return nullptr;
/*
if (!inst->BasisSurface()->declaration().is(IfcSchema::IfcPlane::Class())) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", inst->BasisSurface());
if (!inst.BasisSurface()->declaration().is(IfcSchema::IfcPlane::Class())) {
Logger::Message(Logger::LOG_ERROR, "Unsupported BasisSurface:", inst.BasisSurface());
return false;
}
gp_Pln pln;
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) inst->BasisSurface(), pln);
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) inst.BasisSurface(), pln);
BRepBuilderAPI_MakeFace mf(pln, inst->U1(), inst->U2(), inst->V1(), inst->V2());
BRepBuilderAPI_MakeFace mf(pln, inst.U1(), inst.U2(), inst.V1(), inst.V2());
face = mf.Face();
+4 -4
View File
@@ -21,14 +21,14 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation& inst) {
auto items_to_include = this->settings_.get<settings::OutputDimensionality>().get();
auto items = map_to_collection(this, inst->Items());
auto items = map_to_collection(this, inst.Items());
if (!items) {
auto its = inst->Items();
auto its = inst.Items();
bool empty_on_purpose = true;
for (auto& itm : *its) {
for (auto& itm : its) {
if (failed_on_purpose_.find(itm) == failed_on_purpose_.end()) {
empty_on_purpose = false;
}
+9 -9
View File
@@ -23,20 +23,20 @@ using namespace ifcopenshell::geometry;
#include <boost/math/constants/constants.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRevolvedAreaSolid* inst) {
const double ang = inst->Angle() * angle_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRevolvedAreaSolid& inst) {
const double ang = inst.Angle() * angle_unit_;
taxonomy::cast<taxonomy::face>(map(inst->SweptArea()));
taxonomy::cast<taxonomy::face>(map(inst.SweptArea()));
boost::optional<double> angle;
std::optional<double> angle;
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
if (ang < boost::math::constants::pi<double>() * 2. - 1.e-5) {
@@ -45,9 +45,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRevolvedAreaSolid* inst) {
return taxonomy::make<taxonomy::revolve>(
matrix,
taxonomy::cast<taxonomy::face>(map(inst->SweptArea())),
taxonomy::cast<taxonomy::point3>(map(inst->Axis()->Location())),
taxonomy::cast<taxonomy::direction3>(map(inst->Axis()->Axis())),
taxonomy::cast<taxonomy::face>(map(inst.SweptArea())),
taxonomy::cast<taxonomy::point3>(map(inst.Axis().Location())),
taxonomy::cast<taxonomy::direction3>(map(inst.Axis().Axis())),
angle
);
+4 -4
View File
@@ -21,16 +21,16 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCone* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCone& inst) {
// @todo
return nullptr;
/*
const double r = inst->BottomRadius() * length_unit_;
const double h = inst->Height() * length_unit_;
const double r = inst.BottomRadius() * length_unit_;
const double h = inst.Height() * length_unit_;
BRepPrimAPI_MakeCone builder(r, 0., h);
gp_Trsf trsf;
IfcGeom::Kernel::convert(inst->Position(),trsf);
IfcGeom::Kernel::convert(inst.Position(),trsf);
// IfcCsgPrimitive3D.Position has unit scale factor
shape = builder.Solid().Moved(trsf);
@@ -21,17 +21,17 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCylinder* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCylinder& inst) {
// @todo
return nullptr;
/*
const double r = inst->Radius() * length_unit_;
const double h = inst->Height() * length_unit_;
const double r = inst.Radius() * length_unit_;
const double h = inst.Height() * length_unit_;
BRepPrimAPI_MakeCylinder builder(r, h);
gp_Trsf trsf;
IfcGeom::Kernel::convert(inst->Position(),trsf);
IfcGeom::Kernel::convert(inst.Position(),trsf);
// IfcCsgPrimitive3D.Position has unit scale factor
shape = builder.Solid().Moved(trsf);
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
const double r = inst->RoundingRadius() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef& inst) {
const double x = inst.XDim() / 2.0f * length_unit_;
const double y = inst.YDim() / 2.0f * length_unit_;
const double r = inst.RoundingRadius() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
@@ -38,10 +38,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef*
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
@@ -27,10 +27,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcSectionedSolidHorizontal
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal& inst) {
std::vector<cross_section> cross_sections;
auto dir = map(inst->Directrix());
auto dir = map(inst.Directrix());
auto fn = taxonomy::dcast<taxonomy::function_item>(dir);
if (!fn) {
// Only implement on alignment curves
@@ -39,8 +39,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* in
}
{
auto css = inst->CrossSections();
auto csps = inst->CrossSectionPositions();
auto css = inst.CrossSections();
auto csps = inst.CrossSectionPositions();
std::vector<taxonomy::face::ptr> faces;
// The PointByDistanceExpressions are factored out into (a) a cartesian offset relative to the
@@ -49,43 +49,43 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal* in
// The longitudes determine the range of the sweep and the offsets are interpolated in between
// sweep segments.
std::vector<Eigen::Vector3d> profile_offsets;
std::vector<boost::optional<Eigen::Matrix3d>> profile_rotations;
std::vector<std::optional<Eigen::Matrix3d>> profile_rotations;
std::vector<double> longitudes;
for (auto& cs : *css) {
for (auto& cs : css) {
faces.push_back(std::move(taxonomy::cast<taxonomy::face>(map(cs))));
}
#if defined(SCHEMA_HAS_IfcPointByDistanceExpression) && !defined(SCHEMA_IfcSectionedSurface_HAS_FixedAxisVertical)
for (auto& csp : *csps) {
auto pbde = csp->Location()->as<IfcSchema::IfcPointByDistanceExpression>(true);
for (auto& csp : csps) {
auto pbde = csp.Location().as<IfcSchema::IfcPointByDistanceExpression>();
longitudes.push_back(*pbde->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>(true) * length_unit_);
longitudes.push_back((double) pbde.DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_);
// Corresponds to the profile X, Y directions (hopefully).
Eigen::Vector3d po(
pbde->OffsetLateral().get_value_or(0.),
pbde.OffsetLateral().value_or(0.),
// @todo I don't understand whether vertical is an offset relative to the tangent plane or to the global XY plane
pbde->OffsetVertical().get_value_or(0.),
pbde.OffsetVertical().value_or(0.),
0.
);
profile_offsets.push_back(po);
boost::optional<Eigen::Matrix3d> rot;
if (csp->Axis() && csp->RefDirection()) {
std::optional<Eigen::Matrix3d> rot;
if (csp.Axis() && csp.RefDirection()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
taxonomy::cast<taxonomy::direction3>(map(csp->Axis()))->ccomponents(),
taxonomy::cast<taxonomy::direction3>(map(csp->RefDirection()))->ccomponents()).ccomponents().block<3,3>(0,0);
} else if (csp->Axis()) {
taxonomy::cast<taxonomy::direction3>(map(csp.Axis()))->ccomponents(),
taxonomy::cast<taxonomy::direction3>(map(csp.RefDirection()))->ccomponents()).ccomponents().block<3,3>(0,0);
} else if (csp.Axis()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
taxonomy::cast<taxonomy::direction3>(map(csp->Axis()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp->RefDirection()) {
taxonomy::cast<taxonomy::direction3>(map(csp.Axis()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp.RefDirection()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
Eigen::Vector3d(0, 0, 1),
taxonomy::cast<taxonomy::direction3>(map(csp->RefDirection()))->ccomponents()
taxonomy::cast<taxonomy::direction3>(map(csp.RefDirection()))->ccomponents()
).ccomponents().block<3, 3>(0, 0);
}
profile_rotations.push_back(rot);
+19 -19
View File
@@ -27,10 +27,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcSectionedSurface
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface& inst) {
std::vector<cross_section> cross_sections;
auto dir = map(inst->Directrix());
auto dir = map(inst.Directrix());
auto fn = taxonomy::dcast<taxonomy::function_item>(dir);
if (!fn) {
// Only implement on alignment curves
@@ -40,8 +40,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) {
{
auto css = inst->CrossSections();
auto csps = inst->CrossSectionPositions();
auto css = inst.CrossSections();
auto csps = inst.CrossSectionPositions();
std::vector<taxonomy::geom_item::ptr> faces;
// The PointByDistanceExpressions are factored out into (a) a cartesian offset relative to the
@@ -50,44 +50,44 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface* inst) {
// The longitudes determine the range of the sweep and the offsets are interpolated in between
// sweep segments.
std::vector<Eigen::Vector3d> profile_offsets;
std::vector<boost::optional<Eigen::Matrix3d>> profile_rotations;
std::vector<std::optional<Eigen::Matrix3d>> profile_rotations;
std::vector<double> longitudes;
for (auto& cs : *css) {
for (auto& cs : css) {
faces.push_back(std::move(taxonomy::cast<taxonomy::geom_item>(map(cs))));
}
// 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<IfcSchema::IfcPointByDistanceExpression>(true);
for (auto& csp : csps) {
auto pbde = csp.Location().as<IfcSchema::IfcPointByDistanceExpression>();
longitudes.push_back(*pbde->DistanceAlong()->as<IfcSchema::IfcLengthMeasure>(true) * length_unit_);
longitudes.push_back((double) pbde.DistanceAlong().as<IfcSchema::IfcLengthMeasure>() * length_unit_);
// Corresponds to the profile X, Y directions (hopefully).
Eigen::Vector3d po(
pbde->OffsetLateral().get_value_or(0.),
pbde.OffsetLateral().value_or(0.),
// @todo I don't understand whether vertical is an offset relative to the tangent plane or to the global XY plane
pbde->OffsetVertical().get_value_or(0.),
pbde.OffsetVertical().value_or(0.),
0.
);
profile_offsets.push_back(po);
boost::optional<Eigen::Matrix3d> rot;
if (csp->Axis() && csp->RefDirection()) {
std::optional<Eigen::Matrix3d> rot;
if (csp.Axis() && csp.RefDirection()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
taxonomy::cast<taxonomy::direction3>(map(csp->Axis()))->ccomponents(),
taxonomy::cast<taxonomy::direction3>(map(csp->RefDirection()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp->Axis()) {
taxonomy::cast<taxonomy::direction3>(map(csp.Axis()))->ccomponents(),
taxonomy::cast<taxonomy::direction3>(map(csp.RefDirection()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp.Axis()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
taxonomy::cast<taxonomy::direction3>(map(csp->Axis()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp->RefDirection()) {
taxonomy::cast<taxonomy::direction3>(map(csp.Axis()))->ccomponents()).ccomponents().block<3, 3>(0, 0);
} else if (csp.RefDirection()) {
rot = taxonomy::matrix4(
Eigen::Vector3d(0, 0, 0),
Eigen::Vector3d(0, 0, 1),
taxonomy::cast<taxonomy::direction3>(map(csp->RefDirection()))->ccomponents())
taxonomy::cast<taxonomy::direction3>(map(csp.RefDirection()))->ccomponents())
.ccomponents()
.block<3, 3>(0, 0);
}
@@ -25,17 +25,17 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcSegmentedReferenceCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* inst) {
if (!inst->BaseCurve()->as<IfcSchema::IfcGradientCurve>())
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve& inst) {
if (!inst.BaseCurve().as<IfcSchema::IfcGradientCurve>())
Logger::Warning("Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3
auto segments = inst->Segments();
auto segments = inst.Segments();
taxonomy::piecewise_function::spans_t spans;
for (auto& segment : *segments) {
if (segment->as<IfcSchema::IfcCurveSegment>()) {
for (auto& segment : segments) {
if (auto cseg = segment.as<IfcSchema::IfcCurveSegment>()) {
// @todo check that we don't get a mixture of implicit and explicit definitions
auto crv = map(segment->as<IfcSchema::IfcCurveSegment>());
auto crv = map(cseg);
if (auto fi = taxonomy::dcast<taxonomy::function_item>(crv); crv && fi /*crv->kind() == taxonomy::FUNCTION_ITEM*/) {
// crv->kind() is polymorphic and the kind of the actual function_item is returned. PWF can have spans of any FUNCTION_ITEM
// for this reason, a dynamic cast is used and if crv is a function_item it is added to the span
@@ -52,10 +52,10 @@ 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& first_segment = segments.front();
taxonomy::matrix4::ptr p;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment->as<IfcSchema::IfcCurveSegment>()->Placement()));
p = taxonomy::cast<taxonomy::matrix4>(map(first_segment.as<IfcSchema::IfcCurveSegment>().Placement()));
#else
throw std::runtime_error("Unsupported schema");
#endif
@@ -63,7 +63,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
double cant_start = m(0, 3); // start of cant curve
auto cant = taxonomy::make<taxonomy::piecewise_function>(cant_start,spans);
auto gradient = taxonomy::cast<taxonomy::gradient_function>(map(inst->BaseCurve()));
auto gradient = taxonomy::cast<taxonomy::gradient_function>(map(inst.BaseCurve()));
auto cant_function = taxonomy::make<taxonomy::cant_function>(gradient, cant, inst);
if (!(0 < cant_function->length())) {
@@ -21,6 +21,6 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcShellBasedSurfaceModel* inst) {
return map_to_collection(this, inst->SbsmBoundary());
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcShellBasedSurfaceModel& inst) {
return map_to_collection(this, inst.SbsmBoundary());
}
+3 -3
View File
@@ -21,13 +21,13 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphere* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphere& inst) {
auto sol = taxonomy::make<taxonomy::solid>();
auto shl = taxonomy::make<taxonomy::shell>();
auto fac = taxonomy::make<taxonomy::face>();
auto spr = taxonomy::make<taxonomy::sphere>();
spr->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
spr->radius = inst->Radius() * length_unit_;
spr->matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
spr->radius = inst.Radius() * length_unit_;
fac->basis = spr;
shl->children.push_back(fac);
sol->children.push_back(shl);
+3 -3
View File
@@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcSphericalSurface
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphericalSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphericalSurface& inst) {
return nullptr;
/*
gp_Trsf trsf;
IfcGeom::Kernel::convert(inst->Position(), trsf);
IfcGeom::Kernel::convert(inst.Position(), trsf);
// IfcElementarySurface.Position has unit scale factor
face = BRepBuilderAPI_MakeFace(new Geom_SphericalSurface(gp::XOY(), inst->Radius() * length_unit_), getValue(GV_PRECISION)).Face().Moved(trsf);
face = BRepBuilderAPI_MakeFace(new Geom_SphericalSurface(gp::XOY(), inst.Radius() * length_unit_), getValue(GV_PRECISION)).Face().Moved(trsf);
return true;
*/
}
+1 -1
View File
@@ -22,7 +22,7 @@
using namespace ifcopenshell::geometry;
/*
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSubedge* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSubedge& inst) {
// @todo
return nullptr;
}
+2 -2
View File
@@ -22,8 +22,8 @@
using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcSurfaceCurve
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurve& inst) {
// @todo take into account PCurves.
return map(inst->Curve3D());
return map(inst.Curve3D());
}
#endif
@@ -21,19 +21,19 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* inst) {
taxonomy::face::ptr f = taxonomy::cast<taxonomy::face>(map(inst->SweptArea()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid& inst) {
taxonomy::face::ptr f = taxonomy::cast<taxonomy::face>(map(inst.SweptArea()));
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
auto scs = taxonomy::make<taxonomy::sweep_along_curve>(matrix, f, map(inst->ReferenceSurface()), map(inst->Directrix()));
auto scs = taxonomy::make<taxonomy::sweep_along_curve>(matrix, f, map(inst.ReferenceSurface()), map(inst.Directrix()));
scs->matrix = matrix;
return scs;
@@ -44,11 +44,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid*
TopoDS_Face surface_face;
TopoDS_Wire wire, section;
const bool is_plane = inst->ReferenceSurface()->declaration().is(IfcSchema::IfcPlane::Class());
const bool is_plane = inst.ReferenceSurface()->declaration().is(IfcSchema::IfcPlane::Class());
if (!is_plane) {
TopoDS_Shape surface_shell;
if (!convert_shape(inst->ReferenceSurface(), surface_shell)) {
if (!convert_shape(inst.ReferenceSurface(), surface_shell)) {
Logger::Error("Failed to convert reference surface", l);
return false;
}
@@ -65,7 +65,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid*
bool directrix_on_plane = is_plane;
if (is_plane) {
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) inst->ReferenceSurface(), pln);
IfcGeom::Kernel::convert((IfcSchema::IfcPlane*) inst.ReferenceSurface(), pln);
// As per Informal propositions 2: The Directrix shall lie on the ReferenceSurface.
// This is not always the case with the test files in the repository. I am not sure
@@ -21,20 +21,20 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfLinearExtrusion* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfLinearExtrusion& inst) {
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return taxonomy::make<taxonomy::extrusion>(
matrix,
map(inst->SweptCurve()),
taxonomy::cast<taxonomy::direction3>(map(inst->ExtrudedDirection())),
map(inst.SweptCurve()),
taxonomy::cast<taxonomy::direction3>(map(inst.ExtrudedDirection())),
std::numeric_limits<double>::infinity()
);
}
@@ -21,21 +21,21 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfRevolution* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfRevolution& inst) {
taxonomy::matrix4::ptr matrix;
bool has_position = true;
#ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL
has_position = inst->Position() != nullptr;
has_position = !!inst.Position();
#endif
if (has_position) {
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
matrix = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return taxonomy::make<taxonomy::revolve>(
matrix,
taxonomy::cast<taxonomy::loop>(map(inst->SweptCurve())),
taxonomy::cast<taxonomy::point3>(map(inst->AxisPosition()->Location())),
taxonomy::cast<taxonomy::direction3>(map(inst->AxisPosition()->Axis())),
boost::none
taxonomy::cast<taxonomy::loop>(map(inst.SweptCurve())),
taxonomy::cast<taxonomy::point3>(map(inst.AxisPosition().Location())),
taxonomy::cast<taxonomy::direction3>(map(inst.AxisPosition().Axis())),
std::nullopt
);
}
+18 -18
View File
@@ -49,18 +49,18 @@ namespace {
}
*/
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst->Directrix()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid& inst) {
auto loop = taxonomy::cast<taxonomy::loop>(map(inst.Directrix()));
// Start- EndParam became optional in IFC4
#ifdef SCHEMA_IfcSweptDiskSolid_StartParam_IS_OPTIONAL
auto sp = inst->StartParam();
auto ep = inst->EndParam();
auto sp = inst.StartParam();
auto ep = inst.EndParam();
#else
boost::optional<double> sp, ep;
std::optional<double> sp, ep;
try {
sp = inst->StartParam();
ep = inst->EndParam();
sp = inst.StartParam();
ep = inst.EndParam();
} catch (const IfcParse::IfcException& e) {
Logger::Warning(e);
}
@@ -69,19 +69,19 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
const double tol = settings_.get<settings::Precision>().get();
#ifdef SCHEMA_HAS_IfcSweptDiskSolidPolygonal
if (inst->as<IfcSchema::IfcSweptDiskSolidPolygonal>()) {
auto fr = inst->as<IfcSchema::IfcSweptDiskSolidPolygonal>()->FilletRadius();
if (inst.as<IfcSchema::IfcSweptDiskSolidPolygonal>()) {
auto fr = inst.as<IfcSchema::IfcSweptDiskSolidPolygonal>().FilletRadius();
if (fr && *fr > tol) {
fillet_loop(loop, *fr);
}
}
#endif
std::vector<double> radii = { inst->Radius() * length_unit_ };
std::vector<double> radii = { inst.Radius() * length_unit_ };
if (inst->InnerRadius()) {
if (inst.InnerRadius()) {
// Subtraction of pipes with small radii is unstable.
radii.push_back(*inst->InnerRadius() * length_unit_);
radii.push_back(*inst.InnerRadius() * length_unit_);
}
auto f = taxonomy::make<taxonomy::face>();
@@ -117,9 +117,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
TopoDS_Wire wire, section1, section2;
bool hasInnerRadius = !!inst->InnerRadius();
bool hasInnerRadius = !!inst.InnerRadius();
if (!convert_wire(inst->Directrix(), wire)) {
if (!convert_wire(inst.Directrix(), wire)) {
return false;
}
@@ -151,8 +151,8 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
double fillet = 0.;
#ifdef SCHEMA_HAS_IfcSweptDiskSolidPolygonal
if (inst->as<IfcSchema::IfcSweptDiskSolidPolygonal>()) {
auto fr = inst->as<IfcSchema::IfcSweptDiskSolidPolygonal>()->FilletRadius();
if (inst.as<IfcSchema::IfcSweptDiskSolidPolygonal>()) {
auto fr = inst.as<IfcSchema::IfcSweptDiskSolidPolygonal>()->FilletRadius();
if (fr) {
fillet = *fr;
}
@@ -274,7 +274,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
// made that the parametric range over which to be swept matches the IfcCurve in
// its entirety.
util::process_sweep(wire, inst->Radius() * length_unit_, shape);
util::process_sweep(wire, inst.Radius() * length_unit_, shape);
if (shape.IsNull()) {
return false;
@@ -284,7 +284,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
if (hasInnerRadius) {
// Subtraction of pipes with small radii is unstable.
r2 = *inst->InnerRadius() * length_unit_;
r2 = *inst.InnerRadius() * length_unit_;
}
if (r2 > getValue(GV_PRECISION) * 10.) {
+17 -17
View File
@@ -23,19 +23,19 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) {
const bool doFlangeEdgeFillet = !!inst->FlangeEdgeRadius();
const bool doWebEdgeFillet = !!inst->WebEdgeRadius();
const bool doFillet = !!inst->FilletRadius();
const bool hasFlangeSlope = !!inst->FlangeSlope();
const bool hasWebSlope = !!inst->WebSlope();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef& inst) {
const bool doFlangeEdgeFillet = !!inst.FlangeEdgeRadius();
const bool doWebEdgeFillet = !!inst.WebEdgeRadius();
const bool doFillet = !!inst.FilletRadius();
const bool hasFlangeSlope = !!inst.FlangeSlope();
const bool hasWebSlope = !!inst.WebSlope();
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->FlangeWidth() / 2.0f * length_unit_;
const double d1 = inst->WebThickness() * length_unit_;
const double d2 = inst->FlangeThickness() * length_unit_;
const double flangeSlope = hasFlangeSlope ? (*inst->FlangeSlope() * angle_unit_) : 0.;
const double webSlope = hasWebSlope ? (*inst->WebSlope() * angle_unit_) : 0.;
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.FlangeWidth() / 2.0f * length_unit_;
const double d1 = inst.WebThickness() * length_unit_;
const double d2 = inst.FlangeThickness() * length_unit_;
const double flangeSlope = hasFlangeSlope ? (*inst.FlangeSlope() * angle_unit_) : 0.;
const double webSlope = hasWebSlope ? (*inst.WebSlope() * angle_unit_) : 0.;
const double tol = settings_.get<settings::Precision>().get();
@@ -53,13 +53,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) {
double f3 = 0.0f;
if (doFillet) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
if (doWebEdgeFillet) {
f2 = *inst->WebEdgeRadius() * length_unit_;
f2 = *inst.WebEdgeRadius() * length_unit_;
}
if (doFlangeEdgeFillet) {
f3 = *inst->FlangeEdgeRadius() * length_unit_;
f3 = *inst.FlangeEdgeRadius() * length_unit_;
}
double xx, xy;
@@ -102,10 +102,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+3 -3
View File
@@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcToroidalSurface
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcToroidalSurface* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcToroidalSurface& inst) {
return nullptr;
/*
gp_Trsf trsf;
IfcGeom::Kernel::convert(inst->Position(), trsf);
IfcGeom::Kernel::convert(inst.Position(), trsf);
// IfcElementarySurface.Position has unit scale factor
face = BRepBuilderAPI_MakeFace(new Geom_ToroidalSurface(gp::XOY(), inst->MajorRadius() * length_unit_, inst->MinorRadius() * length_unit_), getValue(GV_PRECISION)).Face().Moved(trsf);
face = BRepBuilderAPI_MakeFace(new Geom_ToroidalSurface(gp::XOY(), inst.MajorRadius() * length_unit_, inst.MinorRadius() * length_unit_), getValue(GV_PRECISION)).Face().Moved(trsf);
return true;
*/
}
@@ -23,11 +23,11 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) {
const double x1 = inst->BottomXDim() / 2. * length_unit_;
const double w = inst->TopXDim() * length_unit_;
const double dx = inst->TopXOffset() * length_unit_;
const double y = inst->YDim() / 2. * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef& inst) {
const double x1 = inst.BottomXDim() / 2. * length_unit_;
const double w = inst.TopXDim() * length_unit_;
const double dx = inst.TopXOffset() * length_unit_;
const double y = inst.YDim() / 2. * length_unit_;
// See: https://forums.buildingsmart.org/t/how-are-the-sides-of-ifctrapeziumprofiledefs-bounding-box-calculated-in-most-implementations/2945/8
// The trapezium x center should not be midway of BottomXDim but rather at the center of the overall bounding box.
@@ -43,10 +43,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
@@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry;
#ifdef SCHEMA_HAS_IfcTriangulatedFaceSet
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTriangulatedFaceSet* inst) {
IfcSchema::IfcCartesianPointList3D* point_list = inst->Coordinates();
auto coordinates = point_list->CoordList();
std::vector<std::vector<int>> indices_list = inst->CoordIndex();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTriangulatedFaceSet& inst) {
auto point_list = inst.Coordinates();
auto coordinates = point_list.CoordList();
std::vector<std::vector<int>> indices_list = inst.CoordIndex();
std::vector<taxonomy::point3::ptr> points;
points.reserve(coordinates.size());
+27 -29
View File
@@ -23,19 +23,19 @@ using namespace ifcopenshell::geometry;
#include <boost/math/constants/constants.hpp>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve& inst) {
static const double pi = boost::math::constants::pi<double>();
IfcSchema::IfcCurve* basis_curve = inst->BasisCurve();
bool isConic = basis_curve->declaration().is(IfcSchema::IfcConic::Class());
auto basis_curve = inst.BasisCurve();
bool isConic = basis_curve.declaration().is(IfcSchema::IfcConic::Class());
double parameterFactor = isConic ? angle_unit_ : length_unit_;
auto tc = taxonomy::make<taxonomy::edge>();
tc->basis = map(inst->BasisCurve());
tc->basis = map(inst.BasisCurve());
bool trim_cartesian = inst->MasterRepresentation() != IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER;
auto trims1 = inst->Trim1();
auto trims2 = inst->Trim2();
bool trim_cartesian = inst.MasterRepresentation() != IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER;
auto trims1 = inst.Trim1();
auto trims2 = inst.Trim2();
// reversed orientation handling happens in geometry kernel
unsigned sense_agreement = 0;
@@ -44,27 +44,27 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
bool has_flts[2] = {false,false};
bool has_pnts[2] = {false,false};
tc->curve_sense = inst->SenseAgreement();
tc->curve_sense = inst.SenseAgreement();
for (auto it = trims1->begin(); it != trims1->end(); it ++) {
for (auto it = trims1.begin(); it != trims1.end(); it ++) {
auto i = *it;
if (i->as<IfcSchema::IfcCartesianPoint>()) {
if (i.as<IfcSchema::IfcCartesianPoint>()) {
pnts[sense_agreement] = taxonomy::cast<taxonomy::point3>(map(i));
has_pnts[sense_agreement] = true;
} else if (i->as<IfcSchema::IfcParameterValue>()) {
const double value = *i->as<IfcSchema::IfcParameterValue>();
} else if (i.as<IfcSchema::IfcParameterValue>()) {
const double value = i.as<IfcSchema::IfcParameterValue>();
flts[sense_agreement] = value * parameterFactor;
has_flts[sense_agreement] = true;
}
}
for (auto it = trims2->begin(); it != trims2->end(); it ++) {
for (auto it = trims2.begin(); it != trims2.end(); it ++) {
auto i = *it;
if (i->as<IfcSchema::IfcCartesianPoint>()) {
if (i.as<IfcSchema::IfcCartesianPoint>()) {
pnts[1 - sense_agreement] = taxonomy::cast<taxonomy::point3>(map(i));
has_pnts[1-sense_agreement] = true;
} else if (i->as<IfcSchema::IfcParameterValue>()) {
const double value = *i->as<IfcSchema::IfcParameterValue>();
} else if (i.as<IfcSchema::IfcParameterValue>()) {
const double value = i.as<IfcSchema::IfcParameterValue>();
flts[1-sense_agreement] = value * parameterFactor;
has_flts[1-sense_agreement] = true;
}
@@ -86,15 +86,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
// is defined by an IfcCartesianPoint and an IfcVector with Magnitude. Because
// the vector is normalised when passed to Geom_Line constructor the magnitude
// needs to be factored in with the IfcParameterValue here.
if (basis_curve->declaration().is(IfcSchema::IfcLine::Class())) {
IfcSchema::IfcLine* line = static_cast<IfcSchema::IfcLine*>(basis_curve);
const double magnitude = line->Dir()->Magnitude();
if (auto lin = basis_curve.as<IfcSchema::IfcLine>()) {
const double magnitude = lin.Dir().Magnitude();
flts[0] *= magnitude; flts[1] *= magnitude;
}
if (basis_curve->declaration().is(IfcSchema::IfcEllipse::Class())) {
IfcSchema::IfcEllipse* ellipse = static_cast<IfcSchema::IfcEllipse*>(basis_curve);
double x = ellipse->SemiAxis1() * length_unit_;
double y = ellipse->SemiAxis2() * length_unit_;
if (auto ellipse = basis_curve.as<IfcSchema::IfcEllipse>()) {
double x = ellipse.SemiAxis1() * length_unit_;
double y = ellipse.SemiAxis2() * length_unit_;
const bool rotated = y > x;
// @todo do we apply this rotation here or in the kernel.
if (rotated) {
@@ -116,12 +114,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
// A good criterion for determining whether to take full curve
// or trimmed segment would be whether there are other curve segments or this
// is the only one.
boost::optional<size_t> num_segments;
auto segment = inst->file_->getInverse(inst->id(), & IfcSchema::IfcCompositeCurveSegment::Class(), -1);
if (segment->size() == 1) {
auto comp = (*segment->begin())->file_->getInverse((*segment->begin())->id(), &IfcSchema::IfcCompositeCurve::Class(), -1);
if (comp->size() == 1) {
num_segments = (*comp->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments()->size();
std::optional<size_t> num_segments;
auto segment = inst.data()->file()->getInverse(inst.id(), & IfcSchema::IfcCompositeCurveSegment::Class(), -1);
if (segment.size() == 1) {
auto comp = segment.front().data()->file()->getInverse(segment.front().id(), &IfcSchema::IfcCompositeCurve::Class(), -1);
if (comp.size() == 1) {
num_segments = comp.front().as<IfcSchema::IfcCompositeCurve>().Segments().size();
}
}
+13 -13
View File
@@ -23,16 +23,16 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) {
const bool doEdgeFillet = !!inst->EdgeRadius();
const bool doFillet = !!inst->FilletRadius();
const bool hasSlope = !!inst->FlangeSlope();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef& inst) {
const bool doEdgeFillet = !!inst.EdgeRadius();
const bool doFillet = !!inst.FilletRadius();
const bool hasSlope = !!inst.FlangeSlope();
const double y = inst->Depth() / 2.0f * length_unit_;
const double x = inst->FlangeWidth() / 2.0f * length_unit_;
const double d1 = inst->WebThickness() * length_unit_;
const double d2 = inst->FlangeThickness() * length_unit_;
const double slope = inst->FlangeSlope().get_value_or(0.) * angle_unit_;
const double y = inst.Depth() / 2.0f * length_unit_;
const double x = inst.FlangeWidth() / 2.0f * length_unit_;
const double d1 = inst.WebThickness() * length_unit_;
const double d2 = inst.FlangeThickness() * length_unit_;
const double slope = inst.FlangeSlope().value_or(0.) * angle_unit_;
double dy1 = 0.0f;
double dy2 = 0.0f;
@@ -40,10 +40,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) {
double f2 = 0.0f;
if (doFillet) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
if (doEdgeFillet) {
f2 = *inst->EdgeRadius() * length_unit_;
f2 = *inst.EdgeRadius() * length_unit_;
}
if (hasSlope) {
@@ -61,10 +61,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+3 -3
View File
@@ -21,9 +21,9 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcVector* inst) {
auto d = taxonomy::cast<taxonomy::direction3>(map(inst->Orientation()));
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcVector& inst) {
auto d = taxonomy::cast<taxonomy::direction3>(map(inst.Orientation()));
d = taxonomy::direction3::ptr(d->clone_());
d->components() *= inst->Magnitude() * length_unit_;
d->components() *= inst.Magnitude() * length_unit_;
return d;
}
+11 -11
View File
@@ -23,23 +23,23 @@ using namespace ifcopenshell::geometry;
#include "../profile_helper.h"
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) {
const double x = inst->FlangeWidth() * length_unit_;
const double y = inst->Depth() / 2.0f * length_unit_;
const double dx = inst->WebThickness() / 2.0f * length_unit_;
const double dy = inst->FlangeThickness() * length_unit_;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef& inst) {
const double x = inst.FlangeWidth() * length_unit_;
const double y = inst.Depth() / 2.0f * length_unit_;
const double dx = inst.WebThickness() / 2.0f * length_unit_;
const double dy = inst.FlangeThickness() * length_unit_;
bool doFillet = !!inst->FilletRadius();
bool doEdgeFillet = !!inst->EdgeRadius();
bool doFillet = !!inst.FilletRadius();
bool doEdgeFillet = !!inst.EdgeRadius();
double f1 = 0.;
double f2 = 0.;
if ( doFillet ) {
f1 = *inst->FilletRadius() * length_unit_;
f1 = *inst.FilletRadius() * length_unit_;
}
if ( doEdgeFillet ) {
f2 = *inst->EdgeRadius() * length_unit_;
f2 = *inst.EdgeRadius() * length_unit_;
}
const double tol = settings_.get<settings::Precision>().get();
@@ -52,10 +52,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) {
taxonomy::matrix4::ptr m4;
bool has_position = true;
#ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL
has_position = !!inst->Position();
has_position = !!inst.Position();
#endif
if (has_position) {
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst->Position()));
m4 = taxonomy::cast<taxonomy::matrix4>(map(inst.Position()));
}
return profile_helper(m4, {
+1 -1
View File
@@ -2,6 +2,6 @@
#undef BIND
#endif
#define BIND(T) ifcopenshell::geometry::taxonomy::ptr map_impl(const IfcSchema::T*);
#define BIND(T) ifcopenshell::geometry::taxonomy::ptr map_impl(const IfcSchema::T&);
#include "mapping.i"
File diff suppressed because it is too large Load Diff
+29 -29
View File
@@ -29,35 +29,35 @@ namespace geometry {
std::mutex cache_guard_; // provides mutually exclusive access to cache_
const IfcParse::declaration* placement_rel_to_type_;
const IfcUtil::IfcBaseEntity* placement_rel_to_instance_;
const express::Base placement_rel_to_instance_;
Eigen::Matrix4d offset_and_rotation_ = Eigen::Matrix4d::Identity();
void initialize_units_();
void addRepresentationsFromContextIds(IfcSchema::IfcRepresentation::list::ptr&);
void addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation::list::ptr&);
void addRepresentationsFromContextIds(std::vector<IfcSchema::IfcRepresentation>&);
void addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRepresentation>&);
// Set of instances to mark failures that are intended, such as representations not
// resulting in any items due to dimensionality filters.
std::set<const IfcUtil::IfcBaseInterface*> failed_on_purpose_;
std::set<const IfcSchema::IfcRepresentationMap*> not_reusable_maps_;
std::set<express::Base> failed_on_purpose_;
std::set<IfcSchema::IfcRepresentationMap> not_reusable_maps_;
template <typename T>
void process_mapping(bool& matched, taxonomy::ptr& item, IfcUtil::IfcBaseInterface const * inst) {
if (!item && inst->as<T>()) {
void process_mapping(bool& matched, taxonomy::ptr& item, const express::Base& inst) {
if (!item && inst.as<T>()) {
matched = true;
try {
item = map_impl(inst->as<T>());
item = map_impl(inst.as<T>());
if (item != nullptr) {
if (item->instance == nullptr) {
if (!item->instance) {
item->instance = inst;
}
try {
if (inst->as<IfcSchema::IfcRepresentationItem>() && !inst->as<IfcSchema::IfcStyledItem>() &&
if (inst.as<IfcSchema::IfcRepresentationItem>() && !inst.as<IfcSchema::IfcStyledItem>() &&
/* @todo */
(item->kind() == taxonomy::SOLID || item->kind() == taxonomy::SHELL || item->kind() == taxonomy::COLLECTION || item->kind() == taxonomy::EXTRUSION || item->kind() == taxonomy::LOFT || item->kind() == taxonomy::BOOLEAN_RESULT || item->kind() == taxonomy::REVOLVE || item->kind() == taxonomy::SWEEP_ALONG_CURVE || item->kind() == taxonomy::FACE)
) {
auto style = find_style(inst->as<IfcSchema::IfcRepresentationItem>());
auto style = find_style(inst.as<IfcSchema::IfcRepresentationItem>());
if (style) {
auto mstyle = map(style);
if (mstyle) {
@@ -76,30 +76,30 @@ namespace geometry {
}
}
}
const IfcSchema::IfcStyledItem* find_style(const IfcSchema::IfcRepresentationItem*);
IfcSchema::IfcStyledItem find_style(const IfcSchema::IfcRepresentationItem&);
public:
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) {
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(nullptr) {
initialize_units_();
}
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*);
virtual ifcopenshell::geometry::taxonomy::ptr map(const express::Base&);
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters);
virtual std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers(IfcUtil::IfcBaseEntity*);
virtual std::map<std::string, express::Base> get_layers(const express::Base&);
virtual void initialize_settings();
virtual double get_length_unit() const { return length_unit_; }
virtual const std::string& get_length_unit_name() const { return length_unit_name_; }
virtual aggregate_of_instance::ptr find_openings(const IfcUtil::IfcBaseEntity*);
virtual IfcUtil::IfcBaseEntity* representation_of(const IfcUtil::IfcBaseEntity* product);
virtual std::vector<express::Base> find_openings(const express::Base&);
virtual express::Base representation_of(const express::Base& product);
virtual const IfcUtil::IfcBaseEntity* get_product_type(const IfcUtil::IfcBaseEntity* product_);
virtual const IfcUtil::IfcBaseEntity* get_single_material_association(const IfcUtil::IfcBaseEntity* product);
IfcSchema::IfcRepresentation* representation_mapped_to(const IfcSchema::IfcRepresentation* representation);
IfcSchema::IfcProduct::list::ptr products_represented_by(const IfcSchema::IfcRepresentation* representation, IfcSchema::IfcRepresentationMap*& rmap, bool only_direct=false);
bool reuse_ok_(const IfcSchema::IfcProduct::list::ptr& products);
IfcUtil::IfcBaseEntity* get_decomposing_entity(const IfcUtil::IfcBaseEntity* product, bool include_openings);
virtual const express::Base get_product_type(const express::Base& product_);
virtual const express::Base get_single_material_association(const express::Base& product);
IfcSchema::IfcRepresentation representation_mapped_to(const IfcSchema::IfcRepresentation& representation);
std::vector<IfcSchema::IfcProduct> products_represented_by(const IfcSchema::IfcRepresentation& representation, IfcSchema::IfcRepresentationMap& rmap, bool only_direct = false);
bool reuse_ok_(const std::vector<IfcSchema::IfcProduct>& products);
express::Base get_decomposing_entity(const express::Base& product, bool include_openings);
bool get_layerset_information(const IfcUtil::IfcBaseInterface*, layerset_information&, int&);
bool get_wall_neighbours(const IfcUtil::IfcBaseInterface*, std::vector<endpoint_connection>&);
IfcSchema::IfcRepresentation* find_representation(const IfcSchema::IfcProduct*, const std::string&);
bool get_layerset_information(const express::Base&, layerset_information&, int&);
bool get_wall_neighbours(const express::Base&, std::vector<endpoint_connection>&);
IfcSchema::IfcRepresentation find_representation(const IfcSchema::IfcProduct&, const std::string&);
#include "bind_convert_decl.i"
};
@@ -132,9 +132,9 @@ namespace geometry {
template <typename U = taxonomy::collection, typename T>
typename U::ptr map_to_collection(POSTFIX_SCHEMA(mapping)* m, const T& ts) {
auto c = taxonomy::make<U>();
if (ts->size()) {
for (auto it = ts->begin(); it != ts->end(); ++it) {
if (auto r = m->map(*it)) {
if (ts.size()) {
for (auto& t : ts) {
if (auto r = m->map(t)) {
c->children.push_back(taxonomy::cast<typename element_type<U>::type>(r));
}
}