mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 13:52:23 +00:00
Work towards v1.0 data model with encapsulated weak_ptr as basis for instances
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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.) {
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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"
|
||||
|
||||
+402
-388
File diff suppressed because it is too large
Load Diff
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user