Work on shell conversino

This commit is contained in:
Thomas Krijnen
2019-08-25 16:07:10 +02:00
parent 41d7fb32da
commit 8b4900b0e1
5 changed files with 62 additions and 35 deletions
@@ -48,6 +48,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels {
virtual bool convert_impl(const taxonomy::bspline*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::edge*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::loop*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::face*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::node*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); }
@@ -106,33 +106,33 @@
#include <memory>
#include "../../../ifcparse/IfcLogger.h"
#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
using namespace ifcopenshell::geometry;
using namespace ifcopenshell::geometry::kernels;
bool OpenCascadeKernel::convert(const taxonomy::extrusion& extrusion, TopoDS_Shape& shape) {
const double& height = extrusion.depth;
bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Shape& shape) {
const double& height = extrusion->depth;
if (height < precision_) {
Logger::Error("Non-positive extrusion height encountered for:", extrusion.instance);
Logger::Error("Non-positive extrusion height encountered for:", extrusion->instance);
return false;
}
TopoDS_Shape face;
if (!convert(extrusion.basis, face)) {
if (!convert(&extrusion->basis, face)) {
return false;
}
gp_Trsf trsf;
if (!convert(extrusion.matrix, trsf)) {
gp_GTrsf gtrsf;
if (!convert(&extrusion->matrix, gtrsf)) {
Logger::Error("Unable to move extrusion");
}
auto trsf = gtrsf.Trsf();
auto fs = extrusion->direction.components.data();
gp_Dir dir(fs[0], fs[1], fs[2]);
gp_Dir dir;
if (!convert(extrusion.direction, dir)) {
return false;
}
shape.Nullify();
if (face.ShapeType() == TopAbs_COMPOUND) {
@@ -169,3 +169,27 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion& extrusion, TopoDS_Sha
return !shape.IsNull();
}
bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion* extrusion, ifcopenshell::geometry::ConversionResults& results) {
TopoDS_Shape shape;
if (!convert(extrusion, shape)) {
return false;
}
results.emplace_back(ConversionResult(
extrusion->instance->data().id(),
extrusion->matrix,
new OpenCascadeShape(shape),
extrusion->surface_style
));
return true;
}
bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) {
// @todo check
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 4; ++i) {
trsf.SetValue(i + 1, j + 1, matrix->components(i, j));
}
}
return true;
}
@@ -12,7 +12,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const settings& setti
// @todo check
gp_GTrsf trsf;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < j; ++i) {
for (int j = 0; j < 4; ++i) {
trsf.SetValue(i + 1, j + 1, place.components(i, j));
}
}
@@ -111,7 +111,6 @@ namespace kernels {
class IFC_GEOM_API OpenCascadeKernel : public AbstractKernel {
private:
/*
// faceset_helper traverses the forward instance references of IfcConnectedFaceSet and then provides a mapping
// M of (IfcCartesianPoint, IfcCartesianPoint) -> TopoDS_Edge, where M(a, b) is a partner of M(b, a), ie share
// the same underlying edge but with orientation reversed. This then later speeds op the process of creating a
@@ -120,22 +119,22 @@ namespace kernels {
class faceset_helper {
private:
OpenCascadeKernel* kernel_;
std::set<const IfcSchema::IfcPolyLoop*> duplicates_;
std::set<int> duplicates_;
std::map<int, int> vertex_mapping_;
std::map<std::pair<int, int>, TopoDS_Edge> edges_;
double eps_;
bool non_manifold_;
template <typename Fn>
void loop_(IfcSchema::IfcCartesianPoint::list::ptr& ps, const Fn& callback) {
if (ps->size() < 3) {
void loop_(const taxonomy::loop* ps, const Fn& callback) {
if (ps->children.size() < 3) {
return;
}
auto a = *(ps->end() - 1);
auto a = boost::get<taxonomy::point3>(((taxonomy::edge*) ps->children.back())->start).instance;
auto A = a->data().id();
for (auto& b : *ps) {
auto B = b->data().id();
for (auto& b : ps->children) {
auto B = boost::get<taxonomy::point3>(((taxonomy::edge*) b)->start).instance->data().id();
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
bool fwd = C < D;
if (!fwd) {
@@ -148,16 +147,16 @@ namespace kernels {
}
}
public:
faceset_helper(OpenCascadeKernel* kernel, const IfcSchema::IfcConnectedFaceSet* l);
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell* l);
~faceset_helper();
bool non_manifold() const { return non_manifold_; }
bool& non_manifold() { return non_manifold_; }
bool edge(const IfcSchema::IfcCartesianPoint* a, const IfcSchema::IfcCartesianPoint* b, TopoDS_Edge& e) {
int A = vertex_mapping_[a->data().id()];
int B = vertex_mapping_[b->data().id()];
bool edge(const taxonomy::point3& a, const taxonomy::point3& b, TopoDS_Edge& e) {
int A = vertex_mapping_[a.instance->data().id()];
int B = vertex_mapping_[b.instance->data().id()];
if (A == B) {
return false;
}
@@ -174,15 +173,14 @@ namespace kernels {
return true;
}
bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) {
if (duplicates_.find(loop) != duplicates_.end()) {
bool wire(const taxonomy::loop* loop, TopoDS_Wire& wire) {
if (duplicates_.find(loop->instance->data().id()) != duplicates_.end()) {
return false;
}
BRep_Builder builder;
builder.MakeWire(wire);
int count = 0;
auto ps = loop->Polygon();
loop_(ps, [this, &builder, &wire, &count](int A, int B, bool fwd) {
loop_(loop, [this, &builder, &wire, &count](int A, int B, bool fwd) {
TopoDS_Edge e;
if (edge(A, B, e)) {
if (!fwd) {
@@ -195,12 +193,15 @@ namespace kernels {
if (count >= 3) {
wire.Closed(true);
/*
@todo
TopTools_ListOfShape results;
if (kernel_->wire_intersections(wire, results)) {
Logger::Warning("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected", loop);
kernel_->select_largest(results, wire);
non_manifold_ = true;
}
*/
return true;
} else {
@@ -213,13 +214,12 @@ namespace kernels {
}
};
/*
#ifndef NO_CACHE
POSTFIX_SCHEMA(Cache) cache;
#endif
*/
class faceset_helper {};
faceset_helper* faceset_helper_;
double precision_;
@@ -233,10 +233,12 @@ namespace kernels {
*this = other;
}
bool convert(const geometry::taxonomy::extrusion&, TopoDS_Shape&);
bool convert(const geometry::taxonomy::face&, TopoDS_Shape&);
bool convert(const geometry::taxonomy::matrix4&, gp_Trsf&);
bool convert(const geometry::taxonomy::direction3&, gp_Dir&);
bool convert(const taxonomy::extrusion*, TopoDS_Shape&);
bool convert(const taxonomy::face*, TopoDS_Shape&);
bool convert(const taxonomy::matrix4*, gp_GTrsf&);
virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&);
};
/*
@@ -96,7 +96,7 @@ ifcopenshell::geometry::ConversionResultShape* ifcopenshell::geometry::Represent
// @todo, check
gp_GTrsf trsf;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < j; ++i) {
for (int j = 0; j < 4; ++i) {
trsf.SetValue(i + 1, j + 1, it->Placement().components(i, j));
}
}
@@ -241,7 +241,7 @@ bool ifcopenshell::geometry::Representation::BRep::calculate_projected_surface_a
// @todo check
gp_GTrsf trsf;
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < j; ++i) {
for (int j = 0; j < 4; ++i) {
trsf.SetValue(i + 1, j + 1, place.components(i, j));
}
}