mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Move sweep directrix closer to origin #7408
This commit is contained in:
@@ -84,6 +84,50 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, TopoDS_Shape& result) {
|
bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, TopoDS_Shape& result) {
|
||||||
|
using namespace ifcopenshell::geometry;
|
||||||
|
|
||||||
|
bool applied_temporary_offset = false;
|
||||||
|
Eigen::Vector3d mean;
|
||||||
|
|
||||||
|
auto curve = scs->curve;
|
||||||
|
|
||||||
|
// Apply temporary offset if the geometry is far away from origin
|
||||||
|
// Re: https://github.com/IfcOpenShell/IfcOpenShell/issues/7408
|
||||||
|
// The norm2 that used as a treshold is actually really small though
|
||||||
|
// is this a coincedence that it solves the problem in this one test case?
|
||||||
|
if (curve->kind() == taxonomy::LOOP && std::dynamic_pointer_cast<taxonomy::loop>(curve)->is_polyhedron()) {
|
||||||
|
Eigen::Vector3d sum = Eigen::Vector3d::Zero();
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
visit_2<taxonomy::point3, taxonomy::loop>(std::dynamic_pointer_cast<taxonomy::loop>(curve), [&](const taxonomy::point3::ptr& p) {
|
||||||
|
const Eigen::Vector3d& coords = p->ccomponents();
|
||||||
|
|
||||||
|
sum += coords;
|
||||||
|
++count;
|
||||||
|
});
|
||||||
|
|
||||||
|
mean = (count > 0) ? (sum / static_cast<double>(count)).eval() : Eigen::Vector3d::Zero().eval();
|
||||||
|
|
||||||
|
if (mean.norm() > 1.e2) {
|
||||||
|
curve = taxonomy::loop::ptr((taxonomy::loop*)scs->curve->clone_());
|
||||||
|
applied_temporary_offset = true;
|
||||||
|
std::set<taxonomy::point3::ptr> unique_points;
|
||||||
|
for (auto& e : std::dynamic_pointer_cast<taxonomy::loop>(curve)->children) {
|
||||||
|
auto* a = boost::get<taxonomy::point3::ptr>(&e->start);
|
||||||
|
auto* b = boost::get<taxonomy::point3::ptr>(&e->end);
|
||||||
|
if (a) {
|
||||||
|
unique_points.insert(*a);
|
||||||
|
}
|
||||||
|
if (b) {
|
||||||
|
unique_points.insert(*b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto& p : unique_points) {
|
||||||
|
p->components() -= mean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto w = convert_curve(scs->curve);
|
auto w = convert_curve(scs->curve);
|
||||||
if (w.which() != 2) {
|
if (w.which() != 2) {
|
||||||
Logger::Error("Unsupported directrix");
|
Logger::Error("Unsupported directrix");
|
||||||
@@ -207,13 +251,13 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
|
|||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
for (TopExp_Explorer exp(face, TopAbs_WIRE); exp.More(); exp.Next()) {
|
for (TopExp_Explorer exp(face, TopAbs_WIRE); exp.More(); exp.Next()) {
|
||||||
const auto& section = TopoDS::Wire(exp.Current());
|
const auto& section = TopoDS::Wire(exp.Current());
|
||||||
if (section.IsSame(outer) != i == 0) {
|
if (section.IsSame(outer) != (i == 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BRepOffsetAPI_MakePipeShell builder(wire);
|
BRepOffsetAPI_MakePipeShell builder(wire);
|
||||||
builder.Add(section);
|
builder.Add(section);
|
||||||
builder.SetTransitionMode(contains_circular_segments(wire) && wire_is_c1_continuous(wire, 1.e-2) ? BRepBuilderAPI_Transformed : BRepBuilderAPI_RightCorner);
|
builder.SetTransitionMode(contains_circular_segments(wire) && wire_is_c1_continuous(wire, 1.e-2) ? BRepBuilderAPI_Transformed : BRepBuilderAPI_RightCorner);
|
||||||
if (directrix_on_plane) {
|
if (directrix_on_plane) {
|
||||||
builder.SetMode(pln.Axis().Direction());
|
builder.SetMode(pln.Axis().Direction());
|
||||||
} else if (!is_plane) {
|
} else if (!is_plane) {
|
||||||
@@ -238,8 +282,8 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
|
|||||||
mf1.reset(new BRepBuilderAPI_MakeFace(f1));
|
mf1.reset(new BRepBuilderAPI_MakeFace(f1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TopExp_Explorer exp(builder.Shape(), TopAbs_FACE); exp.More(); exp.Next()) {
|
for (TopExp_Explorer exp2(builder.Shape(), TopAbs_FACE); exp2.More(); exp2.Next()) {
|
||||||
BB.Add(comp, exp.Current());
|
BB.Add(comp, exp2.Current());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,6 +298,12 @@ bool OpenCascadeKernel::convert(const taxonomy::sweep_along_curve::ptr scs, Topo
|
|||||||
|
|
||||||
result = BRepBuilderAPI_MakeSolid(comp).Solid();
|
result = BRepBuilderAPI_MakeSolid(comp).Solid();
|
||||||
|
|
||||||
|
if (applied_temporary_offset) {
|
||||||
|
gp_Trsf trsf;
|
||||||
|
trsf.SetTranslation(gp_Vec(-mean.x(), -mean.y(), -mean.z()));
|
||||||
|
result.Move(trsf);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-30
@@ -1649,42 +1649,34 @@ typedef item const* ptr;
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U, typename Fn>
|
template <typename T, typename U, typename Fn>
|
||||||
void visit_2(const typename U::ptr& c, const Fn& fn) {
|
void visit_2(const typename U::ptr& collection, const Fn& fn) {
|
||||||
static_assert(std::is_same<T, taxonomy::point3>::value, "@todo Only implemented for point3");
|
static_assert(std::is_same<T, taxonomy::point3>::value, "@todo Only implemented for point3");
|
||||||
for (auto& i : c->children) {
|
for (auto& child : collection->children) {
|
||||||
// @todo Sad... now that we have templated collection members,
|
// @todo Sad... now that we have templated collection members,
|
||||||
// we can't generally use collection_base anymore as a cast target.
|
// we can't generally use collection_base anymore as a cast target.
|
||||||
if (auto s = taxonomy::dcast<taxonomy::collection>(i)) {
|
if (auto col = std::dynamic_pointer_cast<taxonomy::collection>(child)) {
|
||||||
visit_2<T, taxonomy::collection>(s, fn);
|
visit_2<T, taxonomy::collection>(col, fn);
|
||||||
}
|
} else if (auto loop = std::dynamic_pointer_cast<taxonomy::loop>(child)) {
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::loop>(i)) {
|
visit_2<T, taxonomy::loop>(loop, fn);
|
||||||
visit_2<T, taxonomy::loop>(s, fn);
|
} else if (auto face = std::dynamic_pointer_cast<taxonomy::face>(child)) {
|
||||||
}
|
visit_2<T, taxonomy::face>(face, fn);
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::face>(i)) {
|
} else if (auto shell = std::dynamic_pointer_cast<taxonomy::shell>(child)) {
|
||||||
visit_2<T, taxonomy::face>(s, fn);
|
visit_2<T, taxonomy::shell>(shell, fn);
|
||||||
}
|
} else if (auto solid = std::dynamic_pointer_cast<taxonomy::solid>(child)) {
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::shell>(i)) {
|
visit_2<T, taxonomy::solid>(solid, fn);
|
||||||
visit_2<T, taxonomy::shell>(s, fn);
|
} else if (auto loft = std::dynamic_pointer_cast<taxonomy::loft>(child)) {
|
||||||
}
|
visit_2<T, taxonomy::loft>(loft, fn);
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::solid>(i)) {
|
} else if (auto bl = std::dynamic_pointer_cast<taxonomy::boolean_result>(child)) {
|
||||||
visit_2<T, taxonomy::solid>(s, fn);
|
visit_2<T, taxonomy::boolean_result>(bl, fn);
|
||||||
}
|
} else if (auto pt = std::dynamic_pointer_cast<taxonomy::point3>(child)) {
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::loft>(i)) {
|
|
||||||
visit_2<T, taxonomy::loft>(s, fn);
|
|
||||||
}
|
|
||||||
else if (auto s = taxonomy::dcast<taxonomy::boolean_result>(i)) {
|
|
||||||
visit_2<T, taxonomy::boolean_result>(s, fn);
|
|
||||||
}
|
|
||||||
else if (auto pt = taxonomy::dcast<taxonomy::point3>(i)) {
|
|
||||||
fn(pt);
|
fn(pt);
|
||||||
}
|
} else if (auto ed = std::dynamic_pointer_cast<taxonomy::edge>(child)) {
|
||||||
else if (auto l = taxonomy::dcast<taxonomy::edge>(i)) {
|
|
||||||
// @todo maybe make edge a collection then as well?
|
// @todo maybe make edge a collection then as well?
|
||||||
if (l->start.which() == 1) {
|
if (ed->start.which() == 1) {
|
||||||
fn(boost::get<taxonomy::point3::ptr>(l->start));
|
fn(boost::get<taxonomy::point3::ptr>(ed->start));
|
||||||
}
|
}
|
||||||
if (l->end.which() == 1) {
|
if (ed->end.which() == 1) {
|
||||||
fn(boost::get<taxonomy::point3::ptr>(l->end));
|
fn(boost::get<taxonomy::point3::ptr>(ed->end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user