mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 05:52:33 +00:00
Major update: taxonomy shared pointers, collection type safety, work towards hashing
This commit is contained in:
@@ -406,7 +406,7 @@ namespace IfcGeom {
|
||||
auto compound_generic = elem->geometry().as_compound();
|
||||
auto compound = ((ifcopenshell::geometry::OpenCascadeShape*)compound_generic)->shape();
|
||||
|
||||
const auto& m = elem->transformation().data().ccomponents();
|
||||
const auto& m = elem->transformation().data()->ccomponents();
|
||||
gp_Trsf tr;
|
||||
tr.SetValues(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace {
|
||||
|
||||
void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
|
||||
|
||||
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf);
|
||||
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf);
|
||||
// above can be static?
|
||||
|
||||
// A 3x3 matrix to rotate the vertex normals
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||
|
||||
util::boolean_settings bst;
|
||||
@@ -252,7 +252,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
|
||||
auto gtrsf = opening_shapes[i].Placement();
|
||||
// @todo check
|
||||
Eigen::Matrix4d m = relative * gtrsf.ccomponents();
|
||||
Eigen::Matrix4d m = relative * gtrsf->ccomponents();
|
||||
gp_Trsf trsf;
|
||||
trsf.SetValues(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
@@ -308,7 +308,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
} else {
|
||||
entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, conv_settings_.getValue(ConversionSettings::GV_PRECISION));
|
||||
}
|
||||
const auto& m = it3->Placement().ccomponents();
|
||||
const auto& m = it3->Placement()->ccomponents();
|
||||
// @todo
|
||||
// if (entity_shape_gtrsf.Form() == gp_Other) {
|
||||
// Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity);
|
||||
@@ -383,7 +383,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
combined_result = C;
|
||||
}
|
||||
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), &it3->Style()));
|
||||
cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), it3->StylePtr()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -713,10 +713,10 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
// try {
|
||||
// IfcSchema::IfcRepresentationItem::list::ptr items = representation->Items();
|
||||
// if (items->size() == 1) {
|
||||
// IfcSchema::IfcRepresentationItem* item = *items->begin();
|
||||
// IfcSchema::IfcRepresentationptr item = *items->begin();
|
||||
// if (item->declaration().is(IfcSchema::IfcMappedItem::Class())) {
|
||||
// if (item->StyledByItem()->size() == 0) {
|
||||
// IfcSchema::IfcMappedItem* mapped_item = item->as<IfcSchema::IfcMappedItem>();
|
||||
// IfcSchema::IfcMappedptr mapped_item = item->as<IfcSchema::IfcMappedItem>();
|
||||
// if (is_identity_transform(mapped_item->MappingTarget())) {
|
||||
// IfcSchema::IfcRepresentationMap* map = mapped_item->MappingSource();
|
||||
// if (is_identity_transform(map->MappingOrigin())) {
|
||||
@@ -767,7 +767,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
// if (is_identity_transform(map->MappingOrigin())) {
|
||||
// IfcSchema::IfcMappedItem::list::ptr items = map->MapUsage();
|
||||
// for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||
// IfcSchema::IfcMappedItem* item = *it;
|
||||
// IfcSchema::IfcMappedptr item = *it;
|
||||
// if (item->StyledByItem()->size() != 0) continue;
|
||||
//
|
||||
// if (!is_identity_transform(item->MappingTarget())) {
|
||||
@@ -1265,7 +1265,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) {
|
||||
// const IfcSchema::IfcRepresentationptr IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// if (item->StyledByItem()->size()) {
|
||||
// return item;
|
||||
// }
|
||||
@@ -1435,7 +1435,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
|
||||
// return style_cache[surface_style_id] = surface_style_ptr_const;
|
||||
// }
|
||||
//
|
||||
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationItem* item) {
|
||||
// std::shared_ptr<const IfcGeom::SurfaceStyle> IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationptr item) {
|
||||
// return internalize_surface_style(get_surface_style<IfcSchema::IfcSurfaceStyleShading>(item));
|
||||
// }
|
||||
//
|
||||
|
||||
@@ -81,7 +81,7 @@ private:
|
||||
double eps_;
|
||||
bool non_manifold_;
|
||||
|
||||
void loop_(const taxonomy::loop* ps, const std::function<void(int, int, bool)>& callback);
|
||||
void loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
|
||||
|
||||
/*
|
||||
bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l);
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
std::vector<const void*> get_idxs(const std::vector<int>& it);
|
||||
*/
|
||||
public:
|
||||
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell* l);
|
||||
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell::ptr l);
|
||||
~faceset_helper();
|
||||
|
||||
bool non_manifold() const { return non_manifold_; }
|
||||
@@ -108,8 +108,8 @@ private:
|
||||
|
||||
bool edge(int A, int B, TopoDS_Edge& e);
|
||||
|
||||
bool wire(const taxonomy::loop* loop, TopoDS_Wire& wire);
|
||||
bool wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires);
|
||||
bool wire(const taxonomy::loop::ptr loop, TopoDS_Wire& wire);
|
||||
bool wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires);
|
||||
};
|
||||
|
||||
faceset_helper* faceset_helper_;
|
||||
@@ -130,25 +130,25 @@ public:
|
||||
, precision_(settings.getValue(ConversionSettings::GV_PRECISION))
|
||||
{}
|
||||
|
||||
bool convert(const taxonomy::extrusion*, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::face*, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::loop*, TopoDS_Wire&);
|
||||
bool convert(const taxonomy::matrix4*, gp_GTrsf&);
|
||||
bool convert(const taxonomy::shell*, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::solid*, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf);
|
||||
bool convert(const taxonomy::extrusion::ptr, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::face::ptr, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::loop::ptr, TopoDS_Wire&);
|
||||
bool convert(const taxonomy::matrix4::ptr, gp_GTrsf&);
|
||||
bool convert(const taxonomy::shell::ptr, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::solid::ptr, TopoDS_Shape&);
|
||||
bool convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
|
||||
|
||||
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const taxonomy::matrix4& t);
|
||||
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t);
|
||||
TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t);
|
||||
|
||||
virtual bool convert_impl(const taxonomy::face*, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
|
||||
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
|
||||
|
||||
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::item*, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
|
||||
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
|
||||
|
||||
template <typename T, typename U>
|
||||
|
||||
@@ -761,7 +761,7 @@ bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes,
|
||||
}
|
||||
|
||||
// @todo refactor, also should be GTrsf
|
||||
const auto& m = it->Placement().ccomponents();
|
||||
const auto& m = it->Placement()->ccomponents();
|
||||
gp_Trsf trsf;
|
||||
trsf.SetValues(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResults& results) {
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
|
||||
bool valid_result = false;
|
||||
bool first = true;
|
||||
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
|
||||
@@ -51,7 +51,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
|
||||
TopoDS_Shape a;
|
||||
TopTools_ListOfShape b;
|
||||
|
||||
taxonomy::style* first_item_style = nullptr;
|
||||
taxonomy::style::ptr first_item_style;
|
||||
|
||||
for (auto& c : br->children) {
|
||||
IfcGeom::ConversionResults cr;
|
||||
@@ -59,10 +59,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
|
||||
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
|
||||
// @todo A will be null on union/intersection, intended?
|
||||
IfcGeom::util::flatten_shape_list(cr, a, false, conv_settings_.getValue(ifcopenshell::geometry::ConversionSettings::GV_PRECISION));
|
||||
first_item_style = ((taxonomy::geom_item*)c)->surface_style;
|
||||
first_item_style = c->surface_style;
|
||||
if (!first_item_style && c->kind() == taxonomy::COLLECTION) {
|
||||
// @todo recursively right?
|
||||
first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style;
|
||||
first_item_style = taxonomy::cast<taxonomy::geom_item>(taxonomy::cast<taxonomy::collection>(c)->children[0])->surface_style;
|
||||
}
|
||||
|
||||
if (conv_settings_.getValue(ConversionSettings::GV_DISABLE_BOOLEAN_RESULT) > 0.0) {
|
||||
@@ -84,7 +84,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers
|
||||
for (auto& r : cr) {
|
||||
auto S = ((OpenCascadeShape*)r.Shape())->shape();
|
||||
gp_GTrsf trsf;
|
||||
convert(&r.Placement(), trsf);
|
||||
convert(r.Placement(), trsf);
|
||||
// @todo it really confuses me why I cannot use Moved() here instead
|
||||
S.Location(S.Location() * trsf.Trsf());
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf) {
|
||||
bool OpenCascadeKernel::convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf) {
|
||||
const bool is_rational = !!bs->weights;
|
||||
|
||||
TColgp_Array2OfPnt Poles(0, (int)bs->control_points.size() - 1, 0, (int)(*bs->control_points.begin()).size() - 1);
|
||||
@@ -22,7 +22,7 @@ bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom
|
||||
for (auto it = bs->control_points.begin(); it != bs->control_points.end(); ++it, ++i) {
|
||||
j = 0;
|
||||
for (auto jt = (*it).begin(); jt != (*it).end(); ++jt, ++j) {
|
||||
Poles(i, j) = convert_xyz<gp_Pnt>(*jt);
|
||||
Poles(i, j) = convert_xyz<gp_Pnt>(**jt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry;
|
||||
using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Shape& shape) {
|
||||
bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) {
|
||||
const double& height = extrusion->depth;
|
||||
|
||||
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
|
||||
@@ -15,7 +15,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
|
||||
}
|
||||
|
||||
TopoDS_Shape face;
|
||||
if (!convert(&extrusion->basis, face)) {
|
||||
if (!convert(extrusion->basis, face)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
|
||||
auto trsf = gtrsf.Trsf();
|
||||
*/
|
||||
|
||||
const auto& fs = extrusion->direction.ccomponents();
|
||||
const auto& fs = extrusion->direction->ccomponents();
|
||||
gp_Dir dir(fs(0), fs(1), fs(2));
|
||||
|
||||
shape.Nullify();
|
||||
@@ -71,7 +71,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
|
||||
return !shape.IsNull();
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion* extrusion, IfcGeom::ConversionResults& results) {
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) {
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(extrusion, shape)) {
|
||||
return false;
|
||||
|
||||
@@ -47,9 +47,7 @@ using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result) {
|
||||
auto bounds = face->children_as<taxonomy::loop>();
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result) {
|
||||
face_definition fd;
|
||||
|
||||
const bool is_face_surface = false; /* todo */
|
||||
@@ -71,10 +69,10 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
|
||||
}
|
||||
*/
|
||||
|
||||
const int num_bounds = bounds.size();
|
||||
const int num_bounds = face->children.size();
|
||||
int num_outer_bounds = 0;
|
||||
|
||||
for (auto& bound : bounds) {
|
||||
for (auto& bound : face->children) {
|
||||
if (bound->external.get_value_or(false)) {
|
||||
num_outer_bounds++;
|
||||
}
|
||||
@@ -97,7 +95,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
|
||||
TopTools_DataMapOfShapeInteger wire_senses;
|
||||
|
||||
for (int process_interior = 0; process_interior <= 1; ++process_interior) {
|
||||
for (auto& bound : bounds) {
|
||||
for (auto& bound : face->children) {
|
||||
bool same_sense = true; /* todo bound->Orientation(); */
|
||||
|
||||
const bool is_interior =
|
||||
@@ -302,7 +300,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::ConversionResults& results) {
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::ConversionResults& results) {
|
||||
throw std::runtime_error("Root-level face not expected");
|
||||
/*
|
||||
|
||||
@@ -320,7 +318,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::Conver
|
||||
}
|
||||
|
||||
// @todo boundary
|
||||
const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents();
|
||||
const auto& m = ((taxonomy::geom_ptr)face->basis)->matrix.ccomponents();
|
||||
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
|
||||
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? -pln.Axis().Direction() : pln.Axis().Direction());
|
||||
TopoDS_Shape shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
|
||||
|
||||
@@ -27,21 +27,21 @@ namespace {
|
||||
|
||||
IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
OpenCascadeKernel* kernel,
|
||||
const taxonomy::shell* shell
|
||||
const taxonomy::shell::ptr shell
|
||||
)
|
||||
: kernel_(kernel)
|
||||
, non_manifold_(false)
|
||||
{
|
||||
// @todo use pointers?
|
||||
std::vector<taxonomy::point3> points;
|
||||
std::vector<taxonomy::loop*> loops;
|
||||
std::vector<taxonomy::point3::ptr> points;
|
||||
std::vector<taxonomy::loop::ptr> loops;
|
||||
|
||||
for (auto& f : shell->children_as<taxonomy::face>()) {
|
||||
for (auto& l : f->children_as<taxonomy::loop>()) {
|
||||
for (auto& f : shell->children) {
|
||||
for (auto& l : f->children) {
|
||||
loops.push_back(l);
|
||||
for (auto& e : l->children_as<taxonomy::edge>()) {
|
||||
for (auto& e : l->children) {
|
||||
// @todo make sure only cartesian points are provided here
|
||||
points.push_back(boost::get<taxonomy::point3>(e->start));
|
||||
points.push_back(boost::get<taxonomy::point3::ptr>(e->start));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
|
||||
Bnd_Box box;
|
||||
for (size_t i = 0; i < points.size(); ++i) {
|
||||
gp_Pnt* p = new gp_Pnt(convert_xyz<gp_Pnt>(points[i]));
|
||||
gp_Pnt* p = new gp_Pnt(convert_xyz<gp_Pnt>(*points[i]));
|
||||
pnts[i].reset(p);
|
||||
B.MakeVertex(vertices[i], *p, Precision::Confusion());
|
||||
tree.add(i, vertices[i]);
|
||||
@@ -116,7 +116,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
find_neighbours(tree, pnts, vs, pnt_i, eps_);
|
||||
|
||||
for (int v : vs) {
|
||||
auto& pt = points[v];
|
||||
auto& pt = *points[v];
|
||||
// NB: insert() ignores duplicate keys
|
||||
// v-1?
|
||||
// @todo this reliable also in case of tesselations?
|
||||
@@ -192,15 +192,15 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
|
||||
}
|
||||
}
|
||||
|
||||
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop* ps, const std::function<void(int, int, bool)>& callback) {
|
||||
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
|
||||
if (ps->children.size() < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto a = boost::get<taxonomy::point3>(((taxonomy::edge*) ps->children.back())->start);
|
||||
auto A = a.identity();
|
||||
auto a = boost::get<taxonomy::point3::ptr>(ps->children.back()->start);
|
||||
auto A = a->identity();
|
||||
for (auto& b : ps->children) {
|
||||
auto B = boost::get<taxonomy::point3>(((taxonomy::edge*) b)->start).identity();
|
||||
auto B = boost::get<taxonomy::point3::ptr>(b->start)->identity();
|
||||
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
|
||||
bool fwd = C < D;
|
||||
if (!fwd) {
|
||||
@@ -222,7 +222,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge&
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop, TopoDS_Wire& w) {
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop::ptr loop, TopoDS_Wire& w) {
|
||||
TopTools_ListOfShape ws;
|
||||
if (!wires(loop, ws)) {
|
||||
return false;
|
||||
@@ -231,7 +231,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires) {
|
||||
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires) {
|
||||
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style>& styles, ConversionResults& result, double tol) {
|
||||
bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
|
||||
Bnd_Box bb;
|
||||
TopoDS_Shape input;
|
||||
flatten_shape_list(items, input, false, tol);
|
||||
@@ -249,8 +249,8 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a, b;
|
||||
if (split_solid_by_shell(((OpenCascadeShape*)it->Shape())->shape(), shells.First(), a, b, tol)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -269,7 +269,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(s, shells, tol, slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
@@ -282,7 +282,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const
|
||||
|
||||
}
|
||||
|
||||
bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style>& styles, ConversionResults& result, double tol) {
|
||||
bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles, ConversionResults& result, double tol) {
|
||||
if (surfaces.size() < 3) {
|
||||
|
||||
return false;
|
||||
@@ -292,8 +292,8 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) {
|
||||
TopoDS_Shape a, b;
|
||||
if (split_solid_by_surface(((OpenCascadeShape*)it->Shape())->shape(), surfaces[1], a, b, tol)) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr())));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -360,7 +360,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve
|
||||
std::vector<TopoDS_Shape> slices;
|
||||
if (split(s, operands, tol, slices) && slices.size() == styles.size()) {
|
||||
for (size_t i = 0; i < slices.size(); ++i) {
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style())));
|
||||
result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr())));
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace util {
|
||||
bool apply_layerset(const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults&, double tol);
|
||||
bool apply_layerset(const ConversionResults&, const std::vector<Handle_Geom_Surface>&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
|
||||
|
||||
bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<ifcopenshell::geometry::taxonomy::style>&, ConversionResults&, double tol);
|
||||
bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&, ConversionResults&, double tol);
|
||||
|
||||
bool split_solid_by_surface(const TopoDS_Shape&, const Handle_Geom_Surface&, TopoDS_Shape&, TopoDS_Shape&, double tol);
|
||||
|
||||
|
||||
@@ -26,21 +26,21 @@ using namespace IfcGeom::util;
|
||||
|
||||
namespace {
|
||||
typedef boost::variant<Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
|
||||
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve);
|
||||
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve);
|
||||
|
||||
struct curve_creation_visitor {
|
||||
OpenCascadeKernel* kernel;
|
||||
curve_creation_visitor_result_type result;
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve& bc) {
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve::ptr& bc) {
|
||||
|
||||
const bool is_rational = !!bc.weights;
|
||||
const bool is_rational = !!bc->weights;
|
||||
|
||||
TColgp_Array1OfPnt Poles(0, bc.control_points.size() - 1);
|
||||
TColStd_Array1OfReal Weights(0, bc.control_points.size() - 1);
|
||||
TColStd_Array1OfReal Knots(0, (int)bc.knots.size() - 1);
|
||||
TColStd_Array1OfInteger Mults(0, (int)bc.knots.size() - 1);
|
||||
Standard_Integer Degree = bc.degree;
|
||||
TColgp_Array1OfPnt Poles(0, bc->control_points.size() - 1);
|
||||
TColStd_Array1OfReal Weights(0, bc->control_points.size() - 1);
|
||||
TColStd_Array1OfReal Knots(0, (int)bc->knots.size() - 1);
|
||||
TColStd_Array1OfInteger Mults(0, (int)bc->knots.size() - 1);
|
||||
Standard_Integer Degree = bc->degree;
|
||||
Standard_Boolean Periodic = false;
|
||||
// @tfk: it appears to be wrong to expect a period curve when the curve is closed, see #586
|
||||
// Standard_Boolean Periodic = l->ClosedCurve();
|
||||
@@ -49,23 +49,23 @@ namespace {
|
||||
|
||||
if (is_rational) {
|
||||
i = 0;
|
||||
for (auto it = bc.weights->begin(); it != bc.weights->end(); ++it, ++i) {
|
||||
for (auto it = bc->weights->begin(); it != bc->weights->end(); ++it, ++i) {
|
||||
Weights(i) = *it;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto it = bc.control_points.begin(); it != bc.control_points.end(); ++it, ++i) {
|
||||
Poles(i) = OpenCascadeKernel::convert_xyz<gp_Pnt>(*it);
|
||||
for (auto it = bc->control_points.begin(); it != bc->control_points.end(); ++it, ++i) {
|
||||
Poles(i) = OpenCascadeKernel::convert_xyz<gp_Pnt>(**it);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto it = bc.multiplicities.begin(); it != bc.multiplicities.end(); ++it, ++i) {
|
||||
for (auto it = bc->multiplicities.begin(); it != bc->multiplicities.end(); ++it, ++i) {
|
||||
Mults(i) = *it;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (auto it = bc.knots.begin(); it != bc.knots.end(); ++it, ++i) {
|
||||
for (auto it = bc->knots.begin(); it != bc->knots.end(); ++it, ++i) {
|
||||
Knots(i) = *it;
|
||||
}
|
||||
|
||||
@@ -76,44 +76,44 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::line& l) {
|
||||
const auto& m = l.matrix.ccomponents();
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::line::ptr& l) {
|
||||
const auto& m = l->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Line(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))));
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::circle& c) {
|
||||
const auto& m = c.matrix.ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), c.radius));
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::circle::ptr& c) {
|
||||
const auto& m = c->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), c->radius));
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::ellipse& e) {
|
||||
const auto& m = e.matrix.ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), e.radius, e.radius2));
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::ellipse::ptr& e) {
|
||||
const auto& m = e->matrix->ccomponents();
|
||||
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2<gp_Pnt>(m.col(3)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(2)), OpenCascadeKernel::convert_xyz2<gp_Dir>(m.col(0))), e->radius, e->radius2));
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::loop& l) {
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::loop::ptr& l) {
|
||||
TopoDS_Wire wire;
|
||||
kernel->convert(&l, wire);
|
||||
kernel->convert(l, wire);
|
||||
return result = wire;
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::edge& e) {
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) {
|
||||
// @todo for polyloops/-lines we should probably construct edges based on correct oriented TopoDS_Vertex instead.
|
||||
|
||||
if (e.start.which() != e.end.which()) {
|
||||
if (e->start.which() != e->end.which()) {
|
||||
throw std::runtime_error("Different trim types not supported");
|
||||
}
|
||||
|
||||
TopoDS_Edge E;
|
||||
if (e.basis) {
|
||||
auto crv_or_wire = convert_curve(kernel, e.basis);
|
||||
if (e->basis) {
|
||||
auto crv_or_wire = convert_curve(kernel, e->basis);
|
||||
Handle(Geom_Curve) curve;
|
||||
if (crv_or_wire.which() == 0) {
|
||||
curve = boost::get<Handle(Geom_Curve)>(crv_or_wire);
|
||||
} else {
|
||||
// @todo
|
||||
const double precision_ = 1.e-5;
|
||||
Logger::Warning("Approximating BasisCurve due to possible discontinuities", e.instance);
|
||||
Logger::Warning("Approximating BasisCurve due to possible discontinuities", e->instance);
|
||||
const auto& w = boost::get<TopoDS_Wire>(crv_or_wire);
|
||||
#if OCC_VERSION_HEX < 0x70600
|
||||
BRepAdaptor_CompCurve cc(w, true);
|
||||
@@ -126,13 +126,13 @@ namespace {
|
||||
curve = approx.Curve();
|
||||
}
|
||||
|
||||
const bool reversed = !((taxonomy::geom_item*)e.basis)->orientation.get_value_or(true);
|
||||
const bool is_conic = e.basis->kind() == taxonomy::ELLIPSE || e.basis->kind() == taxonomy::CIRCLE;
|
||||
const bool reversed = !taxonomy::cast<taxonomy::geom_item>(e->basis)->orientation.get_value_or(true);
|
||||
const bool is_conic = e->basis->kind() == taxonomy::ELLIPSE || e->basis->kind() == taxonomy::CIRCLE;
|
||||
|
||||
// @todo, copy over logic from previous IfcTrimmedCurve handling
|
||||
if (e.start.which() == 0) {
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.end));
|
||||
if (e->start.which() == 0) {
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
|
||||
|
||||
if (reversed) {
|
||||
std::swap(p1, p2);
|
||||
@@ -140,8 +140,8 @@ namespace {
|
||||
|
||||
E = BRepBuilderAPI_MakeEdge(curve, p1, p2).Edge();
|
||||
} else {
|
||||
auto v1 = boost::get<double>(e.start);
|
||||
auto v2 = boost::get<double>(e.end);
|
||||
auto v1 = boost::get<double>(e->start);
|
||||
auto v2 = boost::get<double>(e->end);
|
||||
|
||||
if (reversed) {
|
||||
std::swap(v1, v2);
|
||||
@@ -158,11 +158,11 @@ namespace {
|
||||
E.Reverse();
|
||||
}
|
||||
} else {
|
||||
if (e.start.which() != 0) {
|
||||
if (e->start.which() != 0) {
|
||||
throw std::runtime_error("Non-cartesian trim on edge without curve");
|
||||
}
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(boost::get<taxonomy::point3>(e.end));
|
||||
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
|
||||
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
|
||||
|
||||
E = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
|
||||
}
|
||||
@@ -173,13 +173,13 @@ namespace {
|
||||
return result = W;
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::offset_curve& l) {
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::offset_curve::ptr&) {
|
||||
// @todo
|
||||
throw std::runtime_error("Offset curves not supported as part of loop");
|
||||
}
|
||||
};
|
||||
|
||||
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve) {
|
||||
curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve) {
|
||||
curve_creation_visitor v{ kernel };
|
||||
if (dispatch_curve_creation<curve_creation_visitor, 0>::dispatch(curve, v)) {
|
||||
return v.result;
|
||||
@@ -189,12 +189,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::loop* loop, TopoDS_Wire& wire) {
|
||||
auto segments = loop->children_as<taxonomy::edge>();
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) {
|
||||
TopTools_ListOfShape converted_segments;
|
||||
|
||||
for (auto& segment : segments) {
|
||||
for (auto& segment : loop->children) {
|
||||
auto segment_wire = boost::get<TopoDS_Wire>(convert_curve(this, segment));
|
||||
|
||||
#ifdef IFOPSH_DEBUG
|
||||
|
||||
@@ -5,7 +5,7 @@ using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) {
|
||||
bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf) {
|
||||
// @todo check
|
||||
const auto& m = matrix->ccomponents();
|
||||
gp_Mat mat(
|
||||
|
||||
@@ -7,13 +7,12 @@ using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
|
||||
bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shape) {
|
||||
std::unique_ptr<faceset_helper> helper_scope;
|
||||
helper_scope.reset(new faceset_helper(this, l));
|
||||
|
||||
faceset_helper_ = helper_scope.get();
|
||||
|
||||
auto faces = l->children_as<taxonomy::face>();
|
||||
double minimal_face_area = precision_ * precision_ * 0.5;
|
||||
|
||||
double min_face_area = faceset_helper_
|
||||
@@ -21,7 +20,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
|
||||
: minimal_face_area;
|
||||
|
||||
TopTools_ListOfShape face_list;
|
||||
for (auto& face : faces) {
|
||||
for (auto& face : l->children) {
|
||||
bool success = false;
|
||||
TopoDS_Face occ_face;
|
||||
|
||||
@@ -88,7 +87,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::shell *shell, IfcGeom::ConversionResults& results) {
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) {
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(shell, shape)) {
|
||||
return false;
|
||||
|
||||
@@ -29,59 +29,57 @@ using namespace ifcopenshell::geometry::kernels;
|
||||
using namespace IfcGeom;
|
||||
using namespace IfcGeom::util;
|
||||
|
||||
bool OpenCascadeKernel::convert(const taxonomy::solid* solid, TopoDS_Shape& result) {
|
||||
bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& result) {
|
||||
BRep_Builder BB;
|
||||
TopoDS_Solid S;
|
||||
for (auto& s : solid->children) {
|
||||
if (s->kind() == taxonomy::FACE) {
|
||||
// halfspace
|
||||
if (solid->children.size() != 1) {
|
||||
throw std::runtime_error("Unexpected number of children on solid");
|
||||
}
|
||||
|
||||
auto face = (taxonomy::face*) s;
|
||||
|
||||
const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents();
|
||||
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
|
||||
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
|
||||
TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
|
||||
|
||||
if (!face->children.empty()) {
|
||||
TopoDS_Wire wire;
|
||||
gp_GTrsf gtrsf;
|
||||
|
||||
if (convert((taxonomy::loop*)face->children[0], wire) && wire.Closed() && convert(&face->matrix, gtrsf)) {
|
||||
gp_Trsf trsf = gtrsf.Trsf();
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200));
|
||||
gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0));
|
||||
|
||||
// `trsf` and `down` both have a unit scale factor
|
||||
prism.Move(trsf*down);
|
||||
|
||||
halfspace = BRepAlgoAPI_Common(halfspace, prism);
|
||||
}
|
||||
}
|
||||
|
||||
result = halfspace;
|
||||
return true;
|
||||
} else {
|
||||
if (s->kind() != taxonomy::SHELL) {
|
||||
throw std::runtime_error("Unexpected child in solid");
|
||||
}
|
||||
if (S.IsNull()) {
|
||||
BB.MakeSolid(S);
|
||||
}
|
||||
TopoDS_Shell shl;
|
||||
convert(((taxonomy::shell*)s), shl);
|
||||
BB.Add(S, shl);
|
||||
if (solid->instance->declaration().is("IfcHalfSpaceSolid")) {
|
||||
// halfspace
|
||||
if (solid->children.size() != 1) {
|
||||
throw std::runtime_error("Unexpected number of children on solid");
|
||||
}
|
||||
|
||||
auto face = solid->children[0]->children[0];
|
||||
|
||||
const auto& m = taxonomy::cast<taxonomy::plane>(face->basis)->matrix->ccomponents();
|
||||
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
|
||||
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction());
|
||||
TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
|
||||
|
||||
if (!face->children.empty()) {
|
||||
TopoDS_Wire wire;
|
||||
gp_GTrsf gtrsf;
|
||||
|
||||
if (convert((taxonomy::loop::ptr)face->children[0], wire) && wire.Closed() && convert(face->matrix, gtrsf)) {
|
||||
gp_Trsf trsf = gtrsf.Trsf();
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200));
|
||||
gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0));
|
||||
|
||||
// `trsf` and `down` both have a unit scale factor
|
||||
prism.Move(trsf*down);
|
||||
|
||||
halfspace = BRepAlgoAPI_Common(halfspace, prism);
|
||||
}
|
||||
}
|
||||
|
||||
result = halfspace;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto& s : solid->children) {
|
||||
if (S.IsNull()) {
|
||||
BB.MakeSolid(S);
|
||||
}
|
||||
TopoDS_Shell shl;
|
||||
convert(((taxonomy::shell::ptr)s), shl);
|
||||
BB.Add(S, shl);
|
||||
}
|
||||
if (!S.IsNull()) {
|
||||
result = S;
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::solid* solid , IfcGeom::ConversionResults& results) {
|
||||
bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid , IfcGeom::ConversionResults& results) {
|
||||
TopoDS_Shape shape;
|
||||
if (!convert(solid, shape)) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user