--unify-shapes setting

This commit is contained in:
Thomas Krijnen
2024-10-07 20:47:01 +02:00
parent 461e3d478a
commit 250fad696e
5 changed files with 39 additions and 204 deletions
+1 -1
View File
@@ -70,7 +70,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels {
virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information>&) { throw std::runtime_error("Not implemented"); }
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) = 0;
virtual bool unify_shapes(const IfcGeom::ConversionResults&, IfcGeom::ConversionResults&) { throw std::runtime_error("Unification of shapes not implemented in this kernel"); }
};
AbstractKernel* construct(IfcParse::IfcFile* file, const std::string& geometry_library, Settings& conv_settings);
+8 -1
View File
@@ -201,6 +201,13 @@ namespace ifcopenshell {
static constexpr bool defaultvalue = false;
};
struct UnifyShapes : public SettingBase<UnifyShapes, bool> {
static constexpr const char* const name = "unify-shapes";
static constexpr const char* const description = "Unify adjacent co-planar and co-linear subshapes (topological entities "
"sharing the same geometric domain) before triangulation or further processing";
static constexpr bool defaultvalue = false;
};
struct UseMaterialNames : public SettingBase<UseMaterialNames, bool> {
static constexpr const char* const name = "use-material-names";
static constexpr const char* const description = "Use material names instead of unique IDs for naming materials upon serialization. "
@@ -493,7 +500,7 @@ namespace ifcopenshell {
};
class IFC_GEOM_API Settings : public SettingsContainer<
std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, SurfaceColour, WeldVertices, UseWorldCoords, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, KeepBoundingBoxes, PiecewiseStepType, PiecewiseStepParam, NoParallelMapping, ModelOffset, ModelRotation, TriangulationType>
std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, OutputDimensionality, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, SurfaceColour, WeldVertices, UseWorldCoords, UnifyShapes, UseMaterialNames, ConvertBackUnits, ContextIds, ContextTypes, ContextIdentifiers, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, CircleSegments, KeepBoundingBoxes, PiecewiseStepType, PiecewiseStepParam, NoParallelMapping, ModelOffset, ModelRotation, TriangulationType>
>
{};
}
+21 -13
View File
@@ -208,29 +208,37 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
Logger::Message(Logger::LOG_ERROR, "Error processing openings for:", product);
}
if (caught_error && opened_shapes.size() < shapes.size()) {
opened_shapes = shapes;
}
if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
it->prepend(place);
if (!(caught_error && opened_shapes.size() < shapes.size())) {
if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
it->prepend(place);
}
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
representation_id_builder << "-world-coords";
}
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
representation_id_builder << "-world-coords";
shapes = opened_shapes;
}
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), opened_shapes);
} else if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
for (auto it = shapes.begin(); it != shapes.end(); ++it) {
it->prepend(place);
}
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
representation_id_builder << "-world-coords";
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
} else {
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
}
if (settings_.get<ifcopenshell::geometry::settings::UnifyShapes>().get()) {
IfcGeom::ConversionResults unified_shapes;
try {
if (kernel_->unify_shapes(shapes, unified_shapes)) {
std::swap(shapes, unified_shapes);
}
} catch (std::exception& e) {
Logger::Error(e);
}
}
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
std::string context_string = "";
// IfcShapeRepresentation.
@@ -23,175 +23,12 @@
* *
********************************************************************************/
// #include <set>
// #include <algorithm>
// #include <numeric>
//
// #include <Standard_Version.hxx>
//
// #include <gp_Pnt.hxx>
// #include <gp_Vec.hxx>
// #include <gp_Dir.hxx>
// #include <gp_Pnt2d.hxx>
// #include <gp_GTrsf.hxx>
// #include <gp_GTrsf2d.hxx>
// #include <gp_Trsf.hxx>
// #include <gp_Trsf2d.hxx>
// #include <gp_Ax3.hxx>
// #include <gp_Pln.hxx>
//
// #include <Geom_Line.hxx>
// #include <Geom_Circle.hxx>
//
// #include <Geom_Plane.hxx>
// #include <Geom_OffsetCurve.hxx>
// #include <Geom_OffsetSurface.hxx>
// #include <Geom_CylindricalSurface.hxx>
// #include <Geom_SurfaceOfLinearExtrusion.hxx>
//
// #include <GeomAPI_IntCS.hxx>
// #include <GeomAPI_IntSS.hxx>
//
// #include <BRepBndLib.hxx>
// #include <BRepOffsetAPI_Sewing.hxx>
// #include <BRepBuilderAPI_MakeFace.hxx>
// #include <BRepBuilderAPI_MakeEdge.hxx>
// #include <BRepBuilderAPI_MakeWire.hxx>
// #include <BRepBuilderAPI_MakePolygon.hxx>
// #include <BRepBuilderAPI_MakeVertex.hxx>
//
// #include <TopoDS.hxx>
// #include <TopoDS_Wire.hxx>
// #include <TopoDS_Face.hxx>
// #include <TopoDS_CompSolid.hxx>
//
// #include <TopExp.hxx>
// #include <TopExp_Explorer.hxx>
//
// #include <BRepPrimAPI_MakePrism.hxx>
// #include <BRepBuilderAPI_MakeShell.hxx>
// #include <BRepBuilderAPI_MakeSolid.hxx>
// #include <BRepPrimAPI_MakeHalfSpace.hxx>
// #include <BRepAlgoAPI_Cut.hxx>
// #include <BRepAlgoAPI_Fuse.hxx>
// #include <BRepAlgoAPI_Common.hxx>
// #include <BRepAlgoAPI_BooleanOperation.hxx>
// #if OCC_VERSION_HEX >= 0x70200
// #include <BRepAlgoAPI_Splitter.hxx>
// #endif
//
// #include <BRepAlgo_NormalProjection.hxx>
//
// #include <ShapeFix_Shape.hxx>
// #include <ShapeFix_ShapeTolerance.hxx>
// #include <ShapeFix_Solid.hxx>
// #include <ShapeFix_Shell.hxx>
//
// #include <ShapeAnalysis_Curve.hxx>
// #include <ShapeAnalysis_Surface.hxx>
//
//
// #include <BRepFilletAPI_MakeFillet2d.hxx>
//
// #include <TopLoc_Location.hxx>
//
// #include <GProp_GProps.hxx>
// #include <BRepGProp.hxx>
//
// #include <BRepBuilderAPI_Transform.hxx>
// #include <BRepBuilderAPI_GTransform.hxx>
//
// #include <BRepGProp_Face.hxx>
// #include <BRepCheck.hxx>
// #include <BRepCheck_Analyzer.hxx>
//
// #include <BRepMesh_IncrementalMesh.hxx>
// #include <BRepTools.hxx>
// #include <BRepTools_WireExplorer.hxx>
//
// #include <Poly_Triangulation.hxx>
// #include <Poly_Array1OfTriangle.hxx>
//
// #include <TopTools_IndexedMapOfShape.hxx>
// #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
//
// #include <BOPAlgo_PaveFiller.hxx>
//
// #include <GCPnts_AbscissaPoint.hxx>
//
// #include <BRepClass3d_SolidClassifier.hxx>
//
// #include <GeomAPI_ExtremaCurveCurve.hxx>
//
// #include <Extrema_ExtCS.hxx>
//
// #include <ShapeAnalysis_Edge.hxx>
//
// #if OCC_VERSION_HEX >= 0x70200
// #include <BOPAlgo_Alerts.hxx>
// #endif
//
// #include "../../../ifcparse/macros.h"
// #include "../../../ifcparse/IfcSIPrefix.h"
//
// #include "../../../ifcparse/IfcFile.h"
//
#include "OpenCascadeKernel.h"
// #include "IfcGeomTree.h"
#include "boolean_utils.h"
// #include "wire_utils.h"
#include "base_utils.h"
// #include "layerset.h"
//
// #include <memory>
// #include <thread>
//
// #if OCC_VERSION_HEX < 0x60900
// #ifdef _MSC_VER
// #pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.")
// #else
// #warning "You are linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade."
// #endif
// #endif
//
// namespace {
// struct POSTFIX_SCHEMA(factory_t) {
// IfcGeom::Kernel* operator()(IfcParse::IfcFile* file) const {
// IfcGeom::POSTFIX_SCHEMA(Kernel)* k = new IfcGeom::POSTFIX_SCHEMA(Kernel);
// if (file) {
//
// }
// return k;
// }
// };
// }
//
// void MAKE_INIT_FN(KernelImplementation_)(IfcGeom::impl::KernelFactoryImplementation* mapping) {
// static const std::string schema_name = STRINGIFY(IfcSchema);
// POSTFIX_SCHEMA(factory_t) factory;
// mapping->bind(schema_name, factory);
// }
//
// #define Kernel POSTFIX_SCHEMA(Kernel)
//
// void IfcGeom::Kernel::set_offset(const std::array<double, 3> &p_offset) {
// offset = gp_Vec(p_offset[0], p_offset[1], p_offset[2]);
//
// offset_and_rotation = util::combine_offset_and_rotation(offset, rotation);
// }
//
// void IfcGeom::Kernel::set_rotation(const std::array<double, 4> &p_rotation) {
// rotation = gp_Quaternion(p_rotation[0], p_rotation[1], p_rotation[2], p_rotation[3]);
//
// offset_and_rotation = util::combine_offset_and_rotation(offset, rotation);
// }
//
#include <BRepPrimAPI_MakeRevol.hxx>
namespace {
struct opening_sorter {
@@ -391,7 +228,13 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
return true;
}
#include <BRepPrimAPI_MakeRevol.hxx>
bool IfcGeom::OpenCascadeKernel::unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output) {
std::transform(input.begin(), input.end(), std::back_inserter(output), [this](auto v) {
auto& s = std::static_pointer_cast<OpenCascadeShape>(v.Shape())->shape();
return IfcGeom::ConversionResult(v.ItemId(), new OpenCascadeShape(util::unify(s, settings_.get<ifcopenshell::geometry::settings::Precision>().get())), v.StylePtr());
});
return true;
}
bool IfcGeom::OpenCascadeKernel::convert_impl(const taxonomy::revolve::ptr r, IfcGeom::ConversionResults& results) {
@@ -79,22 +79,6 @@ private:
bool non_manifold_;
void loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
/*
bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l);
bool construct(const std::vector<double>& cp, gp_Pnt* l);
const void* get_idx(const IfcSchema::IfcCartesianPoint* cp) {
return cp;
}
const void* get_idx(const std::vector<double>& cp) {
return &cp;
}
std::vector<const void*> get_idxs(const IfcSchema::IfcPolyLoop* lp);
std::vector<const void*> get_idxs(const std::vector<int>& it);
*/
public:
faceset_helper(OpenCascadeKernel* kernel, const ifcopenshell::geometry::taxonomy::shell::ptr l);
~faceset_helper();
@@ -111,15 +95,7 @@ private:
faceset_helper* faceset_helper_;
// @todo these should be moved to the mapping
/*
gp_Vec offset = gp_Vec{0.0, 0.0, 0.0};
gp_Quaternion rotation = gp_Quaternion{};
gp_Trsf offset_and_rotation = gp_Trsf();
*/
double precision_;
public:
OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings)
: AbstractKernel("opencascade", settings)
@@ -150,6 +126,7 @@ public:
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<ifcopenshell::geometry::taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
virtual bool unify_shapes(const IfcGeom::ConversionResults& input, IfcGeom::ConversionResults& output);
typedef boost::variant<Handle(Geom_Curve), TopoDS_Wire> curve_creation_visitor_result_type;
curve_creation_visitor_result_type convert_curve(const ifcopenshell::geometry::taxonomy::ptr);