From 3d47f5cecdcb3a23f5cba1b55724f0f0cab0bcd4 Mon Sep 17 00:00:00 2001 From: ifcquery Date: Sun, 2 Jul 2023 21:36:35 +0200 Subject: [PATCH] small bug fixes --- IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h | 58 +-- IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h | 2 +- .../src/ifcpp/geometry/CurveConverter.h | 2 +- .../src/ifcpp/geometry/FaceConverter.h | 4 +- .../src/ifcpp/geometry/GeomDebugDump.h | 406 +++++++++++++----- .../src/ifcpp/geometry/GeometryConverter.h | 6 +- .../src/ifcpp/geometry/GeometryInputData.cpp | 29 +- .../src/ifcpp/geometry/GeometrySettings.h | 16 +- IfcPlusPlus/src/ifcpp/geometry/MeshOps.cpp | 47 +- IfcPlusPlus/src/ifcpp/geometry/MeshOpsDebug.h | 284 ------------ .../src/ifcpp/geometry/PlacementConverter.h | 3 +- .../src/ifcpp/geometry/ProfileConverter.h | 18 +- .../ifcpp/geometry/RepresentationConverter.h | 6 +- .../src/ifcpp/geometry/SolidModelConverter.h | 4 +- IfcPlusPlus/src/ifcpp/geometry/Sweeper.h | 6 +- IfcPlusPlus/src/ifcpp/model/BuildingModel.cpp | 10 +- IfcPlusPlus/src/ifcpp/model/BuildingModel.h | 2 +- IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.cpp | 30 +- IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.h | 1 + .../CreateIfcWallAndWriteFile/src/main.cpp | 22 +- 20 files changed, 421 insertions(+), 535 deletions(-) delete mode 100644 IfcPlusPlus/src/ifcpp/geometry/MeshOpsDebug.h diff --git a/IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h b/IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h index 8db717fa8..3a7bc1041 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/CSG_Adapter.h @@ -26,14 +26,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OU #include "IncludeCarveHeaders.h" #include "MeshOps.h" -#include "MeshOpsDebug.h" #include "GeometryInputData.h" -//#define _USE_MANIFOLD_CSG -#ifdef _USE_MANIFOLD_CSG -#include "CSG_Manifold.h" -#endif - #ifdef _DEBUG static int csg_compute_count = 0; #endif @@ -97,6 +91,7 @@ namespace CSG_Adapter CarveMeshNormalizer normMesh(bbox1, bbox2, normalizeCoords); normMesh.m_disableNormalizeAll = false; + int tag = entity->m_tag; GeomProcessingParams paramsUnscaled(geomSettingsDefault, false); shared_ptr geomSettings(new GeometrySettings(geomSettingsDefault)); double scale = normMesh.getScale(); @@ -104,12 +99,11 @@ namespace CSG_Adapter { scale = 1.0; } - double epsDefault = geomSettings->getEpsilonCoplanarDistance(); + double epsDefault = geomSettings->getEpsilonMergePoints(); double epsMinFaceAreaDefault = geomSettings->getMinTriangleArea(); - double CARVE_EPSILON = epsDefault;// 10.0 * epsDefault * scale; double epsMinFaceArea = epsMinFaceAreaDefault * ( scale * scale ); double epsCoplanarAngle = geomSettings->getEpsilonCoplanarAngle() * scale; - geomSettings->setEpsilonCoplanarDistance(CARVE_EPSILON); + geomSettings->setEpsilonMergePoints(epsDefault); geomSettings->setEpsilonCoplanarAngle(epsCoplanarAngle); geomSettings->setMinTriangleArea(epsMinFaceArea); GeomProcessingParams paramsScaled(geomSettings, false); @@ -118,7 +112,7 @@ namespace CSG_Adapter paramsUnscaled.ifc_entity = entity.get(); paramsUnscaled.callbackFunc = report_callback; - bool intersecting = checkBoundinbBoxIntersection(bbox1, bbox2, operation, CARVE_EPSILON); + bool intersecting = checkBoundinbBoxIntersection(bbox1, bbox2, operation, epsDefault); if (!intersecting) { assignResultOnFail(op1Orig, op2Orig, operation, result); @@ -152,18 +146,22 @@ namespace CSG_Adapter try { // normalize first, so that EPS values match the size of different meshes - normMesh.normalizeMesh(op1, "op1", CARVE_EPSILON); - normMesh.normalizeMesh(op2, "op2", CARVE_EPSILON); + normMesh.normalizeMesh(op1, "op1", epsDefault); + normMesh.normalizeMesh(op2, "op2", epsDefault); + + if (tag == 5598) + { + paramsScaled.debugDump = true; + } bool op1_dumped = false; bool op2_dumped = false; - int tag = entity->m_tag; MeshOps::flattenFacePlanes(op1, op2, paramsScaled); #ifdef _DEBUG ++csg_compute_count; - DumpSettingsStruct dumpColorSettings; - dumpColorSettings.eps = CARVE_EPSILON; + GeomDebugDump::DumpSettingsStruct dumpColorSettings; + dumpColorSettings.eps = epsDefault; CarveMeshNormalizer normMesh_scaleMeshDump(normMesh); if (!normalizeCoords) { @@ -172,9 +170,9 @@ namespace CSG_Adapter paramsUnscaled.normalizer = &normMesh_scaleMeshDump; } - if (csg_compute_count == 24 || tag == 99427) + if (csg_compute_count == 24 || tag == 5598) { - dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled); + GeomDebugDump::dumpOperands(op1, op2, result, tag, op1_dumped, op2_dumped, dumpColorSettings, paramsScaled); } if (infoMesh1orig.zeroAreaFaces.size() > 0) @@ -228,7 +226,7 @@ namespace CSG_Adapter shared_ptr > op1Clone(op1Orig->clone()); MeshSetInfo infoMesh1copy(report_callback, entity.get()); MeshOps::checkMeshSetValidAndClosed(op1Clone, infoMesh1copy, paramsScaled); - normMesh.normalizeMesh(op1Clone, "op1Clone", CARVE_EPSILON); + normMesh.normalizeMesh(op1Clone, "op1Clone", epsDefault); MeshOps::simplifyMeshSet(op1Clone, paramsScaled, triangulateOperands, shouldBeClosedManifold); @@ -246,7 +244,7 @@ namespace CSG_Adapter MeshSetInfo infoMesh1copy(report_callback, entity.get()); MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1copy, paramsUnscaled); - normMesh.normalizeMesh(op1, "op1orig", CARVE_EPSILON); + normMesh.normalizeMesh(op1, "op1orig", epsDefault); operand1valid = MeshOps::checkMeshSetValidAndClosed(op1, infoMesh1, paramsScaled); if (!operand1valid && operand1origvalid) { @@ -264,7 +262,7 @@ namespace CSG_Adapter MeshSetInfo infoMesh2copy(report_callback, entity.get()); bool operand2copy_valid = MeshOps::checkMeshSetValidAndClosed(op2, infoMesh2copy, paramsUnscaled); - normMesh.normalizeMesh(op2, "op2orig", CARVE_EPSILON); + normMesh.normalizeMesh(op2, "op2orig", epsDefault); operand2valid = MeshOps::checkMeshSetValidAndClosed(op2, infoMesh2, paramsScaled); if (!operand2valid && operand2origvalid) { @@ -307,7 +305,7 @@ namespace CSG_Adapter if (infoMesh2.degenerateEdges.size() > 0) { paramsScaled.allowDegenerateEdges = true; } ////////////////////// compute carve csg operation ///////////////////////////////////////////// - carve::csg::CSG csg(CARVE_EPSILON); + carve::csg::CSG csg(epsDefault); result = shared_ptr >(csg.compute(op1.get(), op2.get(), operation, nullptr, carve::csg::CSG::CLASSIFY_EDGE)); MeshSetInfo infoResult( report_callback, entity.get() ); @@ -344,7 +342,7 @@ namespace CSG_Adapter // TODO: check for fail with closed mesh, but not fully sliced through. if (!result_meshset_ok) { - carve::csg::CSG csg(CARVE_EPSILON); + carve::csg::CSG csg(epsDefault); result = shared_ptr >(csg.compute(op1.get(), op2.get(), operation, nullptr, carve::csg::CSG::CLASSIFY_NORMAL)); result_meshset_ok = MeshOps::checkMeshSetValidAndClosed(result, infoResult, paramsScaled); @@ -368,16 +366,6 @@ namespace CSG_Adapter } #endif - if( !result_meshset_ok ) - { - //dumpMeshes = true; - -#ifdef _USE_MANIFOLD_CSG - computeCSG_Manifold(op1, op2, operation, result, CARVE_EPSILON, report_callback, entity); - result_meshset_ok = MeshOps::checkMeshSetValidAndClosed(result, infoResult, report_callback, entity.get()); -#endif - } - if( !result_meshset_ok ) { strs_err << "csg operation failed" << std::endl; @@ -421,7 +409,7 @@ namespace CSG_Adapter bool result_meshset_ok_beforeDeNormalize = MeshOps::checkMeshSetValidAndClosed(result, infoMesh_beforeDeNormalize, paramsScaled); #endif - normMesh.deNormalizeMesh(result, "", CARVE_EPSILON); + normMesh.deNormalizeMesh(result, "", epsDefault); #ifdef _DEBUG { @@ -497,8 +485,8 @@ namespace CSG_Adapter if (!operand1valid_2) { std::cout << "!operand1valid after computeCSG_Carve" << std::endl; - DumpSettingsStruct dumpSet; - dumpWithLabel("computeCSG_Carve:result:op1 ", op1, dumpSet, params, true, true); + GeomDebugDump::DumpSettingsStruct dumpSet; + GeomDebugDump::dumpWithLabel("computeCSG_Carve:result:op1 ", op1, dumpSet, params, true, true); } #endif continue; diff --git a/IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h b/IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h index 6d0028990..a7916db78 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h +++ b/IfcPlusPlus/src/ifcpp/geometry/ConverterOSG.h @@ -721,7 +721,7 @@ class ConverterOSG : public StatusCallback void convertMeshSets(std::vector > >& vecMeshSets, osg::Geode* geode, size_t ii_item, bool disableBackfaceCulling) { double min_triangle_area = m_geom_settings->getMinTriangleArea(); - double eps = m_geom_settings->getEpsilonCoplanarDistance(); + double eps = m_geom_settings->getEpsilonMergePoints(); double crease_angle = m_faces_crease_angle; for (size_t ii = 0; ii < vecMeshSets.size(); ++ii) { diff --git a/IfcPlusPlus/src/ifcpp/geometry/CurveConverter.h b/IfcPlusPlus/src/ifcpp/geometry/CurveConverter.h index c205f9e0c..bd22f0b75 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/CurveConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/CurveConverter.h @@ -125,7 +125,7 @@ class CurveConverter : public StatusCallback std::vector >& trim1_vec, std::vector >& trim2_vec, bool senseAgreement) const { double lengthFactor = m_point_converter->getUnitConverter()->getLengthInMeterFactor(); - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); // ENTITY IfcCurve ABSTRACT SUPERTYPE OF (ONEOF(IfcBoundedCurve, IfcConic, IfcLine, IfcOffsetCurve2D, IfcOffsetCurve3D, IfcPCurve)) shared_ptr bounded_curve = dynamic_pointer_cast(ifc_curve); diff --git a/IfcPlusPlus/src/ifcpp/geometry/FaceConverter.h b/IfcPlusPlus/src/ifcpp/geometry/FaceConverter.h index 9e864621f..87edc6ce7 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/FaceConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/FaceConverter.h @@ -138,7 +138,7 @@ class FaceConverter : public StatusCallback m_curve_converter->convertIfcCurve( inner_boundary, inner_boundary_loop, segment_start_points, true ); } - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); PolyInputCache3D poly_cache(CARVE_EPSILON); bool mergeAlignedEdges = true; GeomProcessingParams params( m_geom_settings, outer_boundary.get(), this ); @@ -328,7 +328,7 @@ class FaceConverter : public StatusCallback { return; } - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); PolyInputCache3D poly_cache(CARVE_EPSILON); GeomProcessingParams params( m_geom_settings, nullptr, this ); diff --git a/IfcPlusPlus/src/ifcpp/geometry/GeomDebugDump.h b/IfcPlusPlus/src/ifcpp/geometry/GeomDebugDump.h index c75b8cd79..0df6569c5 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/GeomDebugDump.h +++ b/IfcPlusPlus/src/ifcpp/geometry/GeomDebugDump.h @@ -88,6 +88,38 @@ namespace GeomDebugDump int dump_buffering = 0; }; + static size_t numM6 = 0; + static size_t dumpFaceCount = 0; + static int mergedFacesDumpCount = 0; + static size_t numPointsAtCorner = 0; + + struct DumpSettingsStruct + { + DumpSettingsStruct() + { + + } + glm::vec4 colorLabel = glm::vec4(0.3, 0.33, 0.33, 1.); + glm::vec4 colorMesh = glm::vec4(0.4, 0.5, 0.7, 0.4); + glm::vec4 colorOpenEdges = glm::vec4(0.99, 0.2, 0.2, 0.4); + glm::vec4 colorValidMesh = glm::vec4(0.3, 0.8, 0.3, 0.4); + bool triangulateBeforeDump = true; + double eps = 1.0; + }; + + static int findVertexIndexInVector(const std::vector >& vec_vertices, const carve::mesh::Vertex<3>* v) + { + for (size_t iiv = 0; iiv < vec_vertices.size(); ++iiv) + { + const carve::mesh::Vertex<3>& vertex = vec_vertices[iiv]; + if (v == &vertex) + { + return iiv; + } + } + return -1; + } + static void convertPlacement(double local_x[3], double local_z[3], double location[3], shared_ptr& axis2placement3d, std::vector >& vec_new_entities) { if (!axis2placement3d) @@ -375,19 +407,6 @@ namespace GeomDebugDump dumpPolyline(loops_2d, color, move_dump_position); } - static int findVertexIndexInVector(const std::vector >& vec_vertices, const carve::mesh::Vertex<3>* v) - { - for( size_t iiv = 0; iiv < vec_vertices.size(); ++iiv ) - { - const carve::mesh::Vertex<3>& vertex = vec_vertices[iiv]; - if( v == &vertex ) - { - return iiv; - } - } - return -1; - } - static void MeshSet2Stream(const carve::mesh::MeshSet<3>* meshsetInput, const vec3& offset, const glm::vec4& color, std::stringstream& strs_out, bool trianglesAndQuadsOnly = false ) { if( !meshsetInput ) @@ -870,23 +889,104 @@ namespace GeomDebugDump dumpMeshset(meshset, color, drawNormals, move_offset); } - static void dumpFaces( const std::vector* >& vecFaces, const glm::vec4& color, bool move_offset = true ) + inline void dumpMeshset(const shared_ptr >& meshset, const glm::vec4& color, bool move_offset = true) + { + if (meshset->meshes.size() == 0) + { + return; + } + + bool allowDegenerateEdges = true; + MeshSetInfo info; + shared_ptr geomSettings(new GeometrySettings()); + GeomProcessingParams params(geomSettings, false); + MeshOps::checkMeshSetPointers(meshset, allowDegenerateEdges, params, info); + if (!info.allPointersValid) + { + return; + } + + vec3 offset = carve::geom::VECTOR(0, GeomDebugDump::DumpData::instance().dump_y_pos_geom, 0); + shared_ptr > meshset_copy(meshset->clone()); + + //MeshOps::retriangulateMeshSetForExport(meshset_copy, params ); + GeomDebugDump::dumpMeshset(meshset_copy.get(), offset, color); + + if (move_offset) + { + GeomDebugDump::DumpData::instance().dump_y_pos_geom += meshset->getAABB().extent.y * 2.2; + } + } + + static void dumpVertex(const vec3& point, const glm::vec4& color, std::string& label) + { + double y_pos = DumpData::instance().dump_y_pos_geom + point.y; + + std::stringstream strs_out; + strs_out << "Vertex{" << std::endl; + strs_out << "color{" << color.x << ", " << color.y << ", " << color.z << ", " << color.w << "}" << std::endl; + strs_out << "coords{" << point.x << ", " << y_pos << ", " << point.z << "}" << std::endl; + strs_out << "label{\"" << label << "\"}" << std::endl; + strs_out << "}" << std::endl << std::endl; + std::string strs_out_str = strs_out.str(); + appendToOutput(strs_out); + } + + static void dumpCountLabel(const vec3& point) + { + std::string label = std::to_string(DumpData::instance().dumpCount); + const glm::vec4 color(0.4, 0.4, 0.15, 0.9); + std::stringstream strs_out; + strs_out << "Vertex{" << std::endl; + strs_out << "color{" << color.x << ", " << color.y << ", " << color.z << ", " << color.w << "}" << std::endl; + strs_out << "coords{" << point.x << ", " << point.y + DumpData::instance().dump_y_pos_geom << ", " << point.z << "}" << std::endl; + strs_out << "label{\"" << label << "\"}" << std::endl; + strs_out << "}" << std::endl << std::endl; + + appendToOutput(strs_out); + } + + static void dumpLocalCoordinateSystem() + { + std::stringstream strs_out; + strs_out << "Polyline{" << std::endl; + strs_out << "color{1,0,0,1}," << std::endl; + strs_out << R"(pointLabels: "no",)" << std::endl; + strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {5, " << DumpData::instance().dump_y_pos_geom << ", 0}}" << std::endl; + strs_out << std::endl << "}" << std::endl; // Polyline + + strs_out << "Polyline{" << std::endl; + strs_out << "color{0,1,0,1}" << std::endl; + strs_out << R"(pointLabels: "no",)" << std::endl; + strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {0, " << 5 + DumpData::instance().dump_y_pos_geom << ", 0}}" << std::endl; + strs_out << std::endl << "}" << std::endl; // Polyline + + strs_out << "Polyline{" << std::endl; + strs_out << "color{0,0,1,1}" << std::endl; + strs_out << R"(pointLabels: "no",)" << std::endl; + strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {0, " << DumpData::instance().dump_y_pos_geom << ", 5}}" << std::endl; + strs_out << std::endl << "}" << std::endl; // Polyline + + appendToOutput(strs_out); + } + + static void dumpFaces(const std::vector* >& vecFaces, const glm::vec4& color, bool move_offset = true) { PolyInputCache3D poly_cache; size_t ii = 0; - for( const carve::mesh::Face<3>* face : vecFaces ) + for (const carve::mesh::Face<3>*face : vecFaces) { - if( !face ) + if (!face) { continue; } - if( !face->edge ) + if (!face->edge) { continue; } - if( face->n_edges > 100000 ) + if (face->n_edges > 100000) { std::cout << "face->n_edges > 100000" << std::endl; } @@ -899,27 +999,27 @@ namespace GeomDebugDump { ++countEdges; edge = edge->next; - if( face->edge == edge ) + if (face->edge == edge) { break; } - } while( countEdges < 10000 ); + } while (countEdges < 10000); - if( countEdges > face->n_edges ) + if (countEdges > face->n_edges) { std::cout << "countEdges > face->n_edges" << std::endl; } - - if( countEdges > 100000 ) + + if (countEdges > 100000) { std::cout << "face->n_edges > 100000" << std::endl; } - + std::vector::vertex_t* > faceVertices; face->getVertices(faceVertices); - + std::vector faceIndexes; - for( const carve::mesh::Face<3>::vertex_t * vertex : faceVertices ) + for (const carve::mesh::Face<3>::vertex_t * vertex : faceVertices) { const carve::geom::vector<3>& vertexPoint = vertex->v; size_t idx = poly_cache.addPoint(vertexPoint); @@ -930,7 +1030,7 @@ namespace GeomDebugDump poly_cache.m_poly_data->addFace(faceIndexes.begin(), faceIndexes.end()); ++ii; } - + if (poly_cache.m_poly_data->points.size() < 3) { return; @@ -940,6 +1040,169 @@ namespace GeomDebugDump dumpMeshset(meshset, color, drawNormals, move_offset); } + static void dumpEdge(carve::mesh::Edge<3>* e, const glm::vec4& color, bool checkZeroAreaFaces, bool move_offset) + { + if (e->vert == nullptr) + { + return; + } + auto p1 = e->v1()->v; + auto p2 = e->v2()->v; + + double edgeLength = (p2 - p1).length(); + + std::vector line = { carve::geom::VECTOR(p1.x, p1.y, p1.z), carve::geom::VECTOR(p2.x, p2.y, p2.z) }; + + dumpPolyline(line, color, false); + + if (e->face) + { + if (checkZeroAreaFaces) + { + double faceArea = MeshOps::computeFaceArea(e->face); + if (std::abs(faceArea) < EPS_M6) + { + std::cout << "faceArea) < EPS_M6 )" << std::endl; + } + } + std::vector* > vecFaces = { e->face }; + dumpFaces(vecFaces, color, false); + } + + if (move_offset) + { + moveOffset(0.00005); + } + } + + static void dumpWithLabel(std::string labelStr, shared_ptr >& meshsetInput, const DumpSettingsStruct& colorSettings, const GeomProcessingParams& params, bool moveOffsetBefore, bool moveOffsetAfter) + { + if (!meshsetInput) + { + return; + } + + MeshSetInfo infoMeshsetInput; + bool meshset_input_ok = MeshOps::checkMeshSetValidAndClosed(meshsetInput, infoMeshsetInput, params); + auto aabbInput = meshsetInput->getAABB(); + shared_ptr > meshset = meshsetInput; + if (params.normalizer != nullptr) + { + meshset = shared_ptr >(meshsetInput->clone()); + params.normalizer->normalizeMesh(meshset, "", params.epsMergePoints); + } + + auto aabb = meshset->getAABB(); + if (!aabb.isEmpty()) + { + double minX = aabb.pos.x - aabb.extent.x - 0.08; + double maxX = aabb.pos.x + aabb.extent.x; + double minZ = 0;// aabb.pos.z - aabb.extent.z; + if (minX < GeomDebugDump::DumpData::instance().labelPos.x) + { + vec3& labelPos = GeomDebugDump::DumpData::instance().labelPos; + labelPos = carve::geom::VECTOR(minX, labelPos.y, labelPos.z); + + vec3& countLabelPos = GeomDebugDump::DumpData::instance().countLabelPos; + countLabelPos = carve::geom::VECTOR(maxX + 0.3, countLabelPos.y, countLabelPos.z); + } + } + + if (moveOffsetBefore) + { + GeomDebugDump::moveOffset(0.4); + } + + + glm::vec4 colorCurrentLabel = colorSettings.colorLabel; + if (infoMeshsetInput.meshSetValid) + { + colorCurrentLabel = colorSettings.colorValidMesh; + labelStr += ", valid: yes"; + } + else + { + if (meshset->meshes.size() > 0) + { + colorCurrentLabel = colorSettings.colorOpenEdges; + labelStr += ", valid: no, "; + if (infoMeshsetInput.numOpenEdges > 0) + { + labelStr += std::to_string(infoMeshsetInput.numOpenEdges) + "_open_edges"; + } + + if (infoMeshsetInput.degenerateEdges.size() > 0) + { + labelStr += std::to_string(infoMeshsetInput.degenerateEdges.size()) + "_degenerate_edges"; + } + + if (infoMeshsetInput.zeroAreaFaces.size() > 0) + { + labelStr += std::to_string(infoMeshsetInput.zeroAreaFaces.size()) + "_0area_faces"; + } + } + else + { + colorCurrentLabel = colorSettings.colorOpenEdges; + labelStr += ", 0 meshes"; + } + + if (infoMeshsetInput.numOpenEdges == 4) + { + int wait = 0; + } + } + + if (GeomDebugDump::DumpData::instance().dumpCount >= 7) + { + int wait = 0; + } + + GeomDebugDump::dumpVertex(GeomDebugDump::DumpData::instance().labelPos, colorCurrentLabel, labelStr); + GeomDebugDump::dumpCountLabel(GeomDebugDump::DumpData::instance().countLabelPos); + bool drawNormals = !meshset_input_ok; + GeomDebugDump::dumpMeshset(meshset, colorSettings.colorMesh, drawNormals, false); + + bool moveOffset = false; + if (moveOffsetAfter) + { + double dy = meshset->getAABB().extent.y; + GeomDebugDump::moveOffset(dy * 2 + 0.2); + moveOffset = true; + } + + if (infoMeshsetInput.degenerateEdges.size() > 0) + { + for (auto e : infoMeshsetInput.degenerateEdges) + { + GeomDebugDump::dumpEdge(e, colorSettings.colorOpenEdges, params.checkZeroAreaFaces, moveOffset); + } + } + } + + inline void dumpOperands(shared_ptr >& op1, shared_ptr >& op2, shared_ptr >& result, + int tag, bool& op1_dumped, bool& op2_dumped, DumpSettingsStruct& dumpColorSettings, GeomProcessingParams& paramsPrime) + { + GeomProcessingParams params(paramsPrime); + params.checkZeroAreaFaces = false; + GeomDebugDump::moveOffset(0.2); + GeomDebugDump::dumpLocalCoordinateSystem(); + + if (!op1_dumped) + { + op1_dumped = true; + dumpWithLabel("computeCSG::op1", op1, dumpColorSettings, params, true, false); + } + + if (!op2_dumped) + { + op2_dumped = true; + dumpWithLabel("computeCSG::op2", op2, dumpColorSettings, params, false, false); + } + + dumpWithLabel("computeCSG::result", result, dumpColorSettings, params, true, true); + } + static void dumpFacePolygon(const carve::mesh::Face<3>* face, glm::vec4& color1, bool moveOffset) { if( !face ) @@ -1000,41 +1263,6 @@ namespace GeomDebugDump } } - static void dumpEdge(carve::mesh::Edge<3>* e, const glm::vec4& color, bool checkZeroAreaFaces, bool move_offset) - { - if (e->vert == nullptr) - { - return; - } - auto p1 = e->v1()->v; - auto p2 = e->v2()->v; - - double edgeLength = (p2 - p1).length(); - - std::vector line = { carve::geom::VECTOR(p1.x, p1.y, p1.z), carve::geom::VECTOR(p2.x, p2.y, p2.z) }; - - dumpPolyline(line, color, false); - - if (e->face) - { - if (checkZeroAreaFaces) - { - double faceArea = MeshOps::computeFaceArea(e->face); - if (std::abs(faceArea) < EPS_M6) - { - std::cout << "faceArea) < EPS_M6 )" << std::endl; - } - } - std::vector* > vecFaces = { e->face }; - dumpFaces(vecFaces, color, false); - } - - if (move_offset) - { - moveOffset(0.00005); - } - } - static void dumpMeshsetOpenEdges(const shared_ptr >& meshset, const glm::vec4& colorInput, bool checkZeroAreaFaces, bool move_offset ) { glm::vec4 color = colorInput; @@ -1100,58 +1328,6 @@ namespace GeomDebugDump } } - static void dumpLocalCoordinateSystem() - { - std::stringstream strs_out; - strs_out << "Polyline{" << std::endl; - strs_out << "color{1,0,0,1}," << std::endl; - strs_out << R"(pointLabels: "no",)" << std::endl; - strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {5, " << DumpData::instance().dump_y_pos_geom << ", 0}}" << std::endl; - strs_out << std::endl << "}" << std::endl; // Polyline - - strs_out << "Polyline{" << std::endl; - strs_out << "color{0,1,0,1}" << std::endl; - strs_out << R"(pointLabels: "no",)" << std::endl; - strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {0, " << 5 + DumpData::instance().dump_y_pos_geom << ", 0}}" << std::endl; - strs_out << std::endl << "}" << std::endl; // Polyline - - strs_out << "Polyline{" << std::endl; - strs_out << "color{0,0,1,1}" << std::endl; - strs_out << R"(pointLabels: "no",)" << std::endl; - strs_out << "vertices{ {0, " << DumpData::instance().dump_y_pos_geom << ", 0}, {0, " << DumpData::instance().dump_y_pos_geom << ", 5}}" << std::endl; - strs_out << std::endl << "}" << std::endl; // Polyline - - appendToOutput(strs_out); - } - - static void dumpVertex(const vec3& point, const glm::vec4& color, std::string& label) - { - double y_pos = DumpData::instance().dump_y_pos_geom + point.y; - - std::stringstream strs_out; - strs_out << "Vertex{" << std::endl; - strs_out << "color{" << color.x << ", " << color.y << ", " << color.z << ", " << color.w << "}" << std::endl; - strs_out << "coords{" << point.x << ", " << y_pos << ", " << point.z << "}" << std::endl; - strs_out << "label{\"" << label << "\"}" << std::endl; - strs_out << "}" << std::endl << std::endl; - std::string strs_out_str = strs_out.str(); - appendToOutput(strs_out); - } - - static void dumpCountLabel(const vec3& point) - { - std::string label = std::to_string(DumpData::instance().dumpCount); - const glm::vec4 color(0.4, 0.4, 0.15, 0.9); - std::stringstream strs_out; - strs_out << "Vertex{" << std::endl; - strs_out << "color{" << color.x << ", " << color.y << ", " << color.z << ", " << color.w << "}" << std::endl; - strs_out << "coords{" << point.x << ", " << point.y + DumpData::instance().dump_y_pos_geom << ", " << point.z << "}" << std::endl; - strs_out << "label{\"" << label << "\"}" << std::endl; - strs_out << "}" << std::endl << std::endl; - - appendToOutput(strs_out); - } - static void dumpEdges( const shared_ptr > meshset, const std::vector* >& vec_edges ) { std::stringstream strs_out; @@ -1444,7 +1620,7 @@ namespace GeomDebugDump // write IFC file in STEP format std::string file_path = "dumpEntity.ifc"; - ifc_model->initFileHeader(file_path); + ifc_model->initFileHeader(file_path, "IfcPlusPlus"); std::stringstream stream; shared_ptr step_writer(new WriterSTEP()); diff --git a/IfcPlusPlus/src/ifcpp/geometry/GeometryConverter.h b/IfcPlusPlus/src/ifcpp/geometry/GeometryConverter.h index 53c3a3d0b..facfce95a 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/GeometryConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/GeometryConverter.h @@ -138,7 +138,7 @@ class GeometryConverter : public StatusCallback void setCsgEps(double eps) { - m_geom_settings->setEpsilonCoplanarDistance(eps); + m_geom_settings->setEpsilonMergePoints(eps); } void setModel( shared_ptr model ) @@ -658,9 +658,9 @@ class GeometryConverter : public StatusCallback setCsgEps(1.5e-08 * length_in_meter); if( std::abs(length_in_meter) > EPS_M14 ) { - double eps = m_geom_settings->getEpsilonCoplanarDistance(); + double eps = m_geom_settings->getEpsilonMergePoints(); eps /= length_in_meter; - m_geom_settings->setEpsilonCoplanarDistance(eps); + m_geom_settings->setEpsilonMergePoints(eps); m_geom_settings->setEpsilonCoplanarAngle(eps * 0.1); } diff --git a/IfcPlusPlus/src/ifcpp/geometry/GeometryInputData.cpp b/IfcPlusPlus/src/ifcpp/geometry/GeometryInputData.cpp index 1957ddd4e..bc8442cde 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/GeometryInputData.cpp +++ b/IfcPlusPlus/src/ifcpp/geometry/GeometryInputData.cpp @@ -558,24 +558,29 @@ bool ItemShapeData::addClosedPolyhedron(const shared_ptr > meshset(poly_data->createMesh(mesh_input_options, eps)); - -#ifdef _DEBUG - //std::cout << "failed to correct polyhedron data\n"; - if (params.debugDump) - { - glm::vec4 color(0.3, 0.4, 0.5, 1.0); - GeomDebugDump::dumpMeshsetOpenEdges(meshset, color, false, false); - GeomDebugDump::dumpMeshset(meshset.get(), color, false); - } -#endif - bool triangulateOperands = false; bool shouldBeClosedManifold = true; - //MeshOps::fixMeshset(meshset, params); MeshOps::simplifyMeshSet(meshset, params, triangulateOperands, shouldBeClosedManifold); + + MeshSetInfo infoTriangulated; + bool validMesh = MeshOps::checkMeshSetValidAndClosed(meshset, infoTriangulated, params); + if (validMesh) + { + m_meshsets.push_back(meshset); + return true; + } } } +#ifdef _DEBUG + //std::cout << "failed to correct polyhedron data\n"; + if (params.debugDump) + { + GeomDebugDump::DumpSettingsStruct dumpColorSettings; + dumpWithLabel("addClosedPolyhedron::meshsetUnchanged", meshsetUnchanged, dumpColorSettings, params, true, false); + } +#endif + if (meshsetUnchanged->isClosed()) { m_meshsets.push_back(meshsetUnchanged); diff --git a/IfcPlusPlus/src/ifcpp/geometry/GeometrySettings.h b/IfcPlusPlus/src/ifcpp/geometry/GeometrySettings.h index b816cb38c..b6ccf46d1 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/GeometrySettings.h +++ b/IfcPlusPlus/src/ifcpp/geometry/GeometrySettings.h @@ -60,7 +60,7 @@ class GeometrySettings m_handle_layer_assignments = other->m_handle_layer_assignments; m_render_bounding_box = other->m_render_bounding_box; m_min_triangle_area = other->m_min_triangle_area; - m_epsCoplanarDistance = other->m_epsCoplanarDistance; + m_epsilonMergePoints = other->m_epsilonMergePoints; m_epsCoplanarAngle = other->m_epsCoplanarAngle; } @@ -110,14 +110,14 @@ class GeometrySettings return false; } - void setEpsilonCoplanarDistance(double eps) + void setEpsilonMergePoints(double eps) { - m_epsCoplanarDistance = eps; + m_epsilonMergePoints = eps; } - double getEpsilonCoplanarDistance() + double getEpsilonMergePoints() { - return m_epsCoplanarDistance; + return m_epsilonMergePoints; } void setEpsilonCoplanarAngle(double eps) @@ -146,7 +146,7 @@ class GeometrySettings bool m_handle_layer_assignments = true; bool m_render_bounding_box = false; double m_min_triangle_area = 1e-9; - double m_epsCoplanarDistance = 1.5e-8; + double m_epsilonMergePoints = 1.5e-8; double m_epsCoplanarAngle = 1e-10; std::function m_num_vertices_per_circle_given_radius = [&](double radius) @@ -161,7 +161,7 @@ struct GeomProcessingParams { GeomProcessingParams( shared_ptr& generalSettings ) { - epsMergePoints = generalSettings->getEpsilonCoplanarDistance(); + epsMergePoints = generalSettings->getEpsilonMergePoints(); epsMergeAlignedEdgesAngle = generalSettings->getEpsilonCoplanarAngle(); minFaceArea = generalSettings->getMinTriangleArea(); mergeAlignedEdges = generalSettings->m_mergeAlignedEdges; @@ -197,7 +197,7 @@ struct GeomProcessingParams StatusCallback* callbackFunc = nullptr; double epsMergePoints = 1e-9; - double epsMergeAlignedEdgesAngle = 1e-10; + double epsMergeAlignedEdgesAngle = 1e-6; double minFaceArea = 1e-12; bool mergeAlignedEdges = true; bool allowFinEdges = false; diff --git a/IfcPlusPlus/src/ifcpp/geometry/MeshOps.cpp b/IfcPlusPlus/src/ifcpp/geometry/MeshOps.cpp index 6bfad270a..ea86e7256 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/MeshOps.cpp +++ b/IfcPlusPlus/src/ifcpp/geometry/MeshOps.cpp @@ -802,16 +802,16 @@ void MeshOps::retriangulateMeshSetForExport( shared_ptr bool dumpMesh = true; if (validInput && dumpMesh && meshset->vertex_storage.size() > 60) { - DumpSettingsStruct dumpSet; + GeomDebugDump::DumpSettingsStruct dumpSet; dumpSet.triangulateBeforeDump = false; GeomProcessingParams paramCopy(params); paramCopy.checkZeroAreaFaces = false; GeomDebugDump::dumpLocalCoordinateSystem(); GeomDebugDump::moveOffset(0.3); - dumpWithLabel("triangulate:input ", meshset, dumpSet, paramCopy, true, true); + GeomDebugDump::dumpWithLabel("triangulate:input ", meshset, dumpSet, paramCopy, true, true); GeomDebugDump::moveOffset(0.3); - dumpWithLabel("triangulate:result", meshsetTriangulated, dumpSet, paramCopy, true, true); + GeomDebugDump::dumpWithLabel("triangulate:result", meshsetTriangulated, dumpSet, paramCopy, true, true); } #endif MeshOps::checkMeshSetValidAndClosed(meshsetTriangulated, infoTriangulated, params); @@ -919,7 +919,7 @@ void MeshOps::retriangulateMeshSetForBoolOp_earcut(shared_ptr if (std::abs(area) > params.minFaceArea) { - if (!onMainAxis) - { - std::cout << "dotProduct: " << dotProduct << std::endl; - } + onMainAxis; } #endif @@ -1895,9 +1892,9 @@ void MeshOps::removeDegenerateFacesInMeshSet(shared_ptr #ifdef _DEBUG if (meshInputOk && !mesh_ok) { - DumpSettingsStruct dumpColorSettings; - dumpWithLabel("removeDegenerateFacesInMeshSet--input", meshsetInput, dumpColorSettings, params, true, true); - dumpWithLabel("removeDegenerateFacesInMeshSet--result", resultFromPolyhedron, dumpColorSettings, params, true, true); + GeomDebugDump::DumpSettingsStruct dumpColorSettings; + GeomDebugDump::dumpWithLabel("removeDegenerateFacesInMeshSet--input", meshsetInput, dumpColorSettings, params, true, true); + GeomDebugDump::dumpWithLabel("removeDegenerateFacesInMeshSet--result", resultFromPolyhedron, dumpColorSettings, params, true, true); } #endif @@ -2988,9 +2985,9 @@ size_t mergeAlignedEdges(shared_ptr >& meshset, GeomProc if (params.debugDump) { GeomDebugDump::moveOffset(0.3); - DumpSettingsStruct dumpColorSettings; + GeomDebugDump::DumpSettingsStruct dumpColorSettings; params.checkZeroAreaFaces = true; - dumpWithLabel("mesh-merged-faces", meshset, dumpColorSettings, params, true, true); + GeomDebugDump::dumpWithLabel("mesh-merged-faces", meshset, dumpColorSettings, params, true, true); } double dx = edgeVector.x - edgeNextVector.x; @@ -3097,13 +3094,13 @@ void MeshOps::simplifyMeshSet(shared_ptr >& meshsetInput shared_ptr > meshset(meshsetInput->clone()); #ifdef _DEBUG - DumpSettingsStruct dumpColorSettings; + GeomDebugDump::DumpSettingsStruct dumpColorSettings; if (dumpPolygon) { GeomProcessingParams par(params); par.checkZeroAreaFaces = false; - dumpWithLabel("simplify--input", meshset, dumpColorSettings, par, true, true); + GeomDebugDump::dumpWithLabel("simplify--input", meshset, dumpColorSettings, par, true, true); } if (dumpPolygon) @@ -3138,7 +3135,6 @@ void MeshOps::simplifyMeshSet(shared_ptr >& meshsetInput } bool validMeshset = MeshOps::checkMeshSetValidAndClosed(meshset, info, params); - if (!validMeshset) { resolveOpenEdges(meshset, params); @@ -3819,7 +3815,7 @@ bool intersectRayTriangle(const glm::dvec3& rayOrigin, const glm::dvec3& rayDire void MeshOps::flattenFacePlanes(shared_ptr >& op1, shared_ptr >& op2, const GeomProcessingParams& params) { // project face points into coplanar face - double epsAngle = params.epsMergeAlignedEdgesAngle;// eps * 5.0; + double epsAngle = params.epsMergeAlignedEdgesAngle * 100.0; double epsDistanceSinglePoints = params.epsMergePoints * 10.0; double epsDistanceFaceCentroids = params.epsMergePoints * 10.0; double epsMinDistanceMovePoints2 = params.epsMergePoints * 0.01 * params.epsMergePoints * 0.01; @@ -3961,7 +3957,12 @@ void MeshOps::flattenFacePlanes(shared_ptr >& op1, share double dz = vert->v.z - v.z; double distance2 = dx * dx + dy * dy + dz * dz; - if (distance2 > epsMinDistanceMovePoints2 && distance2 < epsDistanceSinglePoints * epsDistanceSinglePoints) + //if (distance2 > epsMinDistanceMovePoints2 && distance2 < epsDistanceSinglePoints * epsDistanceSinglePoints) + //{ + // vert->v = v; + //} + + if (distance2 > 0.0 && distance2 < epsDistanceSinglePoints * epsDistanceSinglePoints) { vert->v = v; } diff --git a/IfcPlusPlus/src/ifcpp/geometry/MeshOpsDebug.h b/IfcPlusPlus/src/ifcpp/geometry/MeshOpsDebug.h deleted file mode 100644 index 4fdbc8615..000000000 --- a/IfcPlusPlus/src/ifcpp/geometry/MeshOpsDebug.h +++ /dev/null @@ -1,284 +0,0 @@ -/* -*-c++-*- IfcQuery www.ifcquery.com -* -MIT License - -Copyright (c) 2017 Fabian Gerold - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#pragma once - -#ifdef _DEBUG -#include "MeshOps.h" -static size_t numM6 = 0; -static size_t dumpFaceCount = 0; -static int mergedFacesDumpCount = 0; -static size_t numPointsAtCorner = 0; - -struct DumpSettingsStruct -{ - DumpSettingsStruct() - { - - } - glm::vec4 colorLabel = glm::vec4(0.3, 0.33, 0.33, 1.); - glm::vec4 colorMesh = glm::vec4(0.4, 0.5, 0.7, 0.4); - glm::vec4 colorOpenEdges = glm::vec4(0.99, 0.2, 0.2, 0.4); - glm::vec4 colorValidMesh = glm::vec4(0.3, 0.8, 0.3, 0.4); - bool triangulateBeforeDump = true; - double eps = 1.0; -}; - -static void getFaceIndexes(const carve::mesh::Face<3>* face, const std::vector >& vec_vertices, std::vector& result) -{ - carve::mesh::Edge<3>* edge = face->edge; - for( size_t i3 = 0; i3 < face->n_edges; ++i3 ) - { - const carve::mesh::Vertex<3>* v = edge->vert; - //const vec3& v = edge->vert->v; - //static int findVertexIndex(const std::vector >&vec_vertices, const carve::mesh::Vertex<3>*v) - int idx = GeomDebugDump::findVertexIndexInVector(vec_vertices, v); - result.push_back(idx); - edge = edge->next; - } -} - -static void getFaceIndexes(const carve::mesh::Face<3>* face, const std::vector >& vec_vertices, std::set& result) -{ - carve::mesh::Edge<3>* edge = face->edge; - for( size_t i3 = 0; i3 < face->n_edges; ++i3 ) - { - const carve::mesh::Vertex<3>* v = edge->vert; - int idx = GeomDebugDump::findVertexIndexInVector(vec_vertices, v); - result.insert(idx); - edge = edge->next; - } -} - -static bool GetPolygonNormalAndArea( const std::vector& polygon, glm::dvec3& normal, double& area ) -{ - normal = glm::dvec3(); - area = 0.0; - int n = polygon.size(); - if( n < 3 ) - { - return false; - } - - if( 3 == n ) - { - glm::dvec3 a = polygon[0]; - glm::dvec3 b = polygon[1]; - glm::dvec3 c = polygon[2]; - glm::dvec3 v = b - a; - normal = cross( v, ( c - a ) ); - } - else if( 4 == n ) - { - glm::dvec3 a = polygon[0]; - glm::dvec3 b = polygon[1]; - glm::dvec3 c = polygon[2]; - glm::dvec3 d = polygon[3]; - - normal.x = ( c.y - a.y ) * ( d.z - b.z ) + ( c.z - a.z ) * ( b.y - d.y ); - normal.y = ( c.z - a.z ) * ( d.x - b.x ) + ( c.x - a.x ) * ( b.z - d.z ); - normal.z = ( c.x - a.x ) * ( d.y - b.y ) + ( c.y - a.y ) * ( b.x - d.x ); - - } - else if( 4 < n ) - { - glm::dvec3 a; - glm::dvec3 b = polygon[n - 2]; - glm::dvec3 c = polygon[n - 1]; - glm::dvec3 s; - - for( int i = 0; i < n; ++i ) { - a = b; - b = c; - c = polygon[i]; - - normal.x += b.y * (c.z - a.z); - normal.y += b.z * (c.x - a.x); - normal.z += b.x * (c.y - a.y); - - s += c; - } - } - - double length = glm::length( normal ); - if( std::abs(length) < EPS_M8 ) - { - return false; - } - - normal /= length; - area = 0.5 * length; - return true; -} - -inline void dumpMeshset(const shared_ptr >& meshset, const glm::vec4& color, bool move_offset = true) -{ - if( meshset->meshes.size() == 0 ) - { - return; - } - - bool allowDegenerateEdges = true; - MeshSetInfo info; - shared_ptr geomSettings(new GeometrySettings()); - GeomProcessingParams params(geomSettings, false); - MeshOps::checkMeshSetPointers(meshset, allowDegenerateEdges, params, info); - if( !info.allPointersValid ) - { - return; - } - - vec3 offset = carve::geom::VECTOR(0, GeomDebugDump::DumpData::instance().dump_y_pos_geom, 0); - shared_ptr > meshset_copy(meshset->clone()); - - //MeshOps::retriangulateMeshSetForExport(meshset_copy, params ); - GeomDebugDump::dumpMeshset(meshset_copy.get(), offset, color); - - if( move_offset ) - { - GeomDebugDump::DumpData::instance().dump_y_pos_geom += meshset->getAABB().extent.y * 2.2; - } -} - -static void dumpWithLabel(std::string labelStr, shared_ptr >& meshsetInput, const DumpSettingsStruct& colorSettings, const GeomProcessingParams& params, bool moveOffsetBefore, bool moveOffsetAfter) -{ - if( !meshsetInput ) - { - return; - } - - MeshSetInfo infoMeshsetInput; - bool meshset_input_ok = MeshOps::checkMeshSetValidAndClosed(meshsetInput, infoMeshsetInput, params); - auto aabbInput = meshsetInput->getAABB(); - shared_ptr > meshset = meshsetInput; - if (params.normalizer != nullptr) - { - meshset = shared_ptr >(meshsetInput->clone()); - params.normalizer->normalizeMesh(meshset, "", params.epsMergePoints); - } - - auto aabb = meshset->getAABB(); - if (!aabb.isEmpty()) - { - double minX = aabb.pos.x - aabb.extent.x - 0.08; - double maxX = aabb.pos.x + aabb.extent.x; - double minZ = 0;// aabb.pos.z - aabb.extent.z; - if (minX < GeomDebugDump::DumpData::instance().labelPos.x) - { - vec3& labelPos = GeomDebugDump::DumpData::instance().labelPos; - labelPos = carve::geom::VECTOR(minX, labelPos.y, labelPos.z); - - vec3& countLabelPos = GeomDebugDump::DumpData::instance().countLabelPos; - countLabelPos = carve::geom::VECTOR(maxX + 0.3, countLabelPos.y, countLabelPos.z); - } - } - - if (moveOffsetBefore) - { - GeomDebugDump::moveOffset(0.4); - } - - - glm::vec4 colorCurrentLabel = colorSettings.colorLabel; - if(infoMeshsetInput.meshSetValid ) - { - colorCurrentLabel = colorSettings.colorValidMesh; - labelStr += ", valid: yes"; - } - else - { - if (meshset->meshes.size() > 0) - { - colorCurrentLabel = colorSettings.colorOpenEdges; - labelStr += ", valid: no, "; - if (infoMeshsetInput.numOpenEdges > 0) - { - labelStr += std::to_string(infoMeshsetInput.numOpenEdges) + "_open_edges"; - } - - if (infoMeshsetInput.degenerateEdges.size() > 0) - { - labelStr += std::to_string(infoMeshsetInput.degenerateEdges.size()) + "_degenerate_edges"; - } - - if (infoMeshsetInput.zeroAreaFaces.size() > 0) - { - labelStr += std::to_string(infoMeshsetInput.zeroAreaFaces.size()) + "_0area_faces"; - } - } - else - { - colorCurrentLabel = colorSettings.colorOpenEdges; - labelStr += ", 0 meshes"; - } - - if(infoMeshsetInput.numOpenEdges == 4 ) - { - int wait = 0; - } - } - - if( GeomDebugDump::DumpData::instance().dumpCount >= 7 ) - { - int wait = 0; - } - - GeomDebugDump::dumpVertex(GeomDebugDump::DumpData::instance().labelPos, colorCurrentLabel, labelStr); - GeomDebugDump::dumpCountLabel(GeomDebugDump::DumpData::instance().countLabelPos); - bool drawNormals = !meshset_input_ok; - GeomDebugDump::dumpMeshset(meshset, colorSettings.colorMesh, drawNormals, false); - - bool moveOffset = false; - if( moveOffsetAfter ) - { - double dy = meshset->getAABB().extent.y; - GeomDebugDump::moveOffset(dy*2 + 0.2); - moveOffset = true; - } - - if (infoMeshsetInput.degenerateEdges.size() > 0) - { - for (auto e : infoMeshsetInput.degenerateEdges) - { - GeomDebugDump::dumpEdge(e, colorSettings.colorOpenEdges, params.checkZeroAreaFaces, moveOffset); - } - } -} - -inline void dumpOperands(shared_ptr >& op1, shared_ptr >& op2, shared_ptr >& result, - int tag, bool& op1_dumped, bool& op2_dumped, DumpSettingsStruct& dumpColorSettings, GeomProcessingParams& paramsPrime) -{ - GeomProcessingParams params(paramsPrime); - params.checkZeroAreaFaces = false; - GeomDebugDump::moveOffset(0.2); - GeomDebugDump::dumpLocalCoordinateSystem(); - - if (!op1_dumped) - { - op1_dumped = true; - dumpWithLabel("computeCSG::op1", op1, dumpColorSettings, params, true, false); - } - - if (!op2_dumped) - { - op2_dumped = true; - dumpWithLabel("computeCSG::op2", op2, dumpColorSettings, params, false, false); - } - - dumpWithLabel("computeCSG::result", result, dumpColorSettings, params, true, true); -} -#endif diff --git a/IfcPlusPlus/src/ifcpp/geometry/PlacementConverter.h b/IfcPlusPlus/src/ifcpp/geometry/PlacementConverter.h index 850930f5f..0e7c19bb2 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/PlacementConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/PlacementConverter.h @@ -295,7 +295,7 @@ class PlacementConverter : public StatusCallback { cartesianPoint = shared_ptr(new IfcCartesianPoint()); axis2placement3d->m_Location = cartesianPoint; - + if( tag > 0 ) { axis2placement3d->m_Location->m_tag = tag++; @@ -305,6 +305,7 @@ class PlacementConverter : public StatusCallback cartesianPoint->m_Coordinates[0] = translate.x / length_factor; cartesianPoint->m_Coordinates[1] = translate.y / length_factor; cartesianPoint->m_Coordinates[2] = translate.z / length_factor; + cartesianPoint->m_size = 3; if( !axis2placement3d->m_Axis ) { diff --git a/IfcPlusPlus/src/ifcpp/geometry/ProfileConverter.h b/IfcPlusPlus/src/ifcpp/geometry/ProfileConverter.h index 008dad167..77fbd9f91 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/ProfileConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/ProfileConverter.h @@ -188,7 +188,7 @@ class ProfileConverter : public StatusCallback shared_ptr ifc_curve = profile->m_Curve; const shared_ptr& uc = m_curve_converter->getPointConverter()->getUnitConverter(); - double CARVE_EPSILON = m_curve_converter->getGeomSettings()->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_curve_converter->getGeomSettings()->getEpsilonMergePoints(); // IfcCenterLineProfileDef shared_ptr center_line_profile_def = dynamic_pointer_cast( profile ); @@ -1048,8 +1048,10 @@ class ProfileConverter : public StatusCallback simplifyPaths( m_paths ); } - static void simplifyPaths( std::vector >& paths ) + void simplifyPaths( std::vector >& paths ) { + double epsMergePoints = m_curve_converter->getGeomSettings()->getEpsilonMergePoints(); + double epsAngleAlignedEdges = m_curve_converter->getGeomSettings()->getEpsilonCoplanarAngle(); for( std::vector >::iterator it_paths = paths.begin(); it_paths != paths.end(); ++it_paths ) { std::vector& path = ( *it_paths ); @@ -1057,11 +1059,11 @@ class ProfileConverter : public StatusCallback { continue; } - simplifyPath( path ); + simplifyPath( path, epsMergePoints, epsAngleAlignedEdges); } } - static void simplifyPath( std::vector& path ) + static void simplifyPath( std::vector& path, double epsMergePoints, double epsAngleAlignedEdges ) { if( path.size() < 3 ) { @@ -1074,7 +1076,7 @@ class ProfileConverter : public StatusCallback vec2& current = path[i]; vec2 segment1 = current - previous; - if( segment1.length2() < 0.000000001 ) + if( segment1.length2() < epsMergePoints) { path.erase( path.begin() + i ); continue; @@ -1093,7 +1095,7 @@ class ProfileConverter : public StatusCallback vec2 segment2 = next - current; segment2.normalize(); double angle = std::abs( segment1.x*segment2.x + segment1.y*segment2.y ); - if( std::abs( angle - 1 ) < 0.00001 ) + if( std::abs( angle - 1 ) < epsAngleAlignedEdges) { // points are colinear, current point can be removed path.erase( path.begin() + i ); @@ -1111,14 +1113,14 @@ class ProfileConverter : public StatusCallback vec2& first = path.front(); vec2& last = path.back(); - if( ( last - first ).length2() < 0.000001 ) + if( ( last - first ).length2() < epsMergePoints) { vec2 first_segment = path[1] - first; first_segment.normalize(); vec2 last_segment = last - path[path.size() - 2]; last_segment.normalize(); double angle = std::abs( first_segment.x*last_segment.x + first_segment.y*last_segment.y ); - if( std::abs( angle - 1 ) < 0.00001 ) + if( std::abs( angle - 1 ) < epsAngleAlignedEdges) { // remove first and last point path.erase( path.begin() ); diff --git a/IfcPlusPlus/src/ifcpp/geometry/RepresentationConverter.h b/IfcPlusPlus/src/ifcpp/geometry/RepresentationConverter.h index 1ac6f2215..34debda7f 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/RepresentationConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/RepresentationConverter.h @@ -258,7 +258,7 @@ class RepresentationConverter : public StatusCallback if( map_matrix_origin && map_matrix_target ) { carve::math::Matrix mapped_pos(map_matrix_target->m_matrix*map_matrix_origin->m_matrix); - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); mapped_input_data->applyTransformToItem(mapped_pos, CARVE_EPSILON); } representation_data->addChildItem( mapped_input_data, representation_data ); @@ -476,7 +476,7 @@ class RepresentationConverter : public StatusCallback return; } - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); GeomProcessingParams params(m_geom_settings, geom_item.get(), this); shared_ptr tessellatedItem = dynamic_pointer_cast(geom_item); @@ -827,7 +827,7 @@ class RepresentationConverter : public StatusCallback } GeomProcessingParams params(m_geom_settings, topological_item.get(), this); - double CARVE_EPSILON = m_geom_settings->getEpsilonCoplanarDistance(); + double CARVE_EPSILON = m_geom_settings->getEpsilonMergePoints(); const double length_factor = m_unit_converter->getLengthInMeterFactor(); const shared_ptr topo_edge = dynamic_pointer_cast( topological_item ); if( topo_edge ) diff --git a/IfcPlusPlus/src/ifcpp/geometry/SolidModelConverter.h b/IfcPlusPlus/src/ifcpp/geometry/SolidModelConverter.h index 980ade88d..9e0c162f1 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/SolidModelConverter.h +++ b/IfcPlusPlus/src/ifcpp/geometry/SolidModelConverter.h @@ -442,7 +442,7 @@ class SolidModelConverter : public StatusCallback } // triangulate - double eps = m_geom_settings->getEpsilonCoplanarDistance(); + double eps = m_geom_settings->getEpsilonMergePoints(); std::vector path_merged; std::vector > path_incorporated_holes; std::vector triangulated; @@ -1317,7 +1317,7 @@ class SolidModelConverter : public StatusCallback shared_ptr bounded_curve = polygonal_half_space->m_PolygonalBoundary; m_curve_converter->convertIfcCurve2D( bounded_curve, polygonal_boundary, segment_start_points_2d, true ); ProfileConverter::deleteLastPointIfEqualToFirst( polygonal_boundary ); - ProfileConverter::simplifyPath( polygonal_boundary ); + ProfileConverter::simplifyPath( polygonal_boundary, m_geom_settings->getEpsilonMergePoints(), m_geom_settings->getEpsilonCoplanarAngle() ); vec3 solid_extrusion_direction = boundary_plane_normal; double agreement_check = dot( base_surface_plane.N, boundary_plane_normal ); diff --git a/IfcPlusPlus/src/ifcpp/geometry/Sweeper.h b/IfcPlusPlus/src/ifcpp/geometry/Sweeper.h index 6343478e8..bdb5550f0 100644 --- a/IfcPlusPlus/src/ifcpp/geometry/Sweeper.h +++ b/IfcPlusPlus/src/ifcpp/geometry/Sweeper.h @@ -241,7 +241,7 @@ class Sweeper : public StatusCallback #ifdef _DEBUG if( params.ifc_entity ) { - if( params.ifc_entity->m_tag == 258816 ) + if( params.ifc_entity->m_tag == 373882) { glm::vec4 color(0.3, 0.4, 0.5, 1.0); for( size_t ii = 0; ii < faceLoopsTriangulate.size(); ++ii ) @@ -841,7 +841,7 @@ class Sweeper : public StatusCallback vec3 normal_first_loop; bool warning_small_loop_detected = false; bool polyline_created = false; - double eps = m_geom_settings->getEpsilonCoplanarDistance(); + double eps = m_geom_settings->getEpsilonMergePoints(); for( size_t i_face_loops = 0; i_face_loops < profile_paths_input.size(); ++i_face_loops ) { @@ -1074,7 +1074,7 @@ class Sweeper : public StatusCallback // | | // 0-------face_loops[0]--------1 - double eps = m_geom_settings->getEpsilonCoplanarDistance(); + double eps = m_geom_settings->getEpsilonMergePoints(); std::vector > > profile_paths_enclosed; findEnclosedLoops(profile_paths_input, profile_paths_enclosed, eps); diff --git a/IfcPlusPlus/src/ifcpp/model/BuildingModel.cpp b/IfcPlusPlus/src/ifcpp/model/BuildingModel.cpp index 265edf635..169057c69 100644 --- a/IfcPlusPlus/src/ifcpp/model/BuildingModel.cpp +++ b/IfcPlusPlus/src/ifcpp/model/BuildingModel.cpp @@ -72,7 +72,7 @@ BuildingModel::BuildingModel() { m_unit_converter = std::make_shared( ); m_unit_converter->setMessageTarget( this ); - initFileHeader( "IfcPlusPlus-export.ifc" ); + initFileHeader( "IfcPlusPlus-export.ifc", "IfcPlusPlus" ); } BuildingModel::~BuildingModel()= default; @@ -504,10 +504,10 @@ void BuildingModel::removeUnreferencedEntities() } } -void BuildingModel::initFileHeader( std::string file_name ) +void BuildingModel::initFileHeader( const std::string& fileName, const std::string& generatingApplication ) { - m_file_name = file_name; - std::string filename_escaped = encodeStepString( file_name ); + m_file_name = fileName; + std::string filename_escaped = encodeStepString( fileName ); std::stringstream strs; strs << "HEADER;" << std::endl; strs << "FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1');" << std::endl; @@ -525,7 +525,7 @@ void BuildingModel::initFileHeader( std::string file_name ) std::string str(buffer); strs << buffer; - strs << "',(''),('',''),'','IfcPlusPlus','');" << std::endl; + strs << "',(''),('',''),'',' " << generatingApplication << "','');" << std::endl; strs << "FILE_SCHEMA(('" << getIfcSchemaVersionCurrent() << "'));" << std::endl; strs << "ENDSEC;" << std::endl; diff --git a/IfcPlusPlus/src/ifcpp/model/BuildingModel.h b/IfcPlusPlus/src/ifcpp/model/BuildingModel.h index 115048f17..843902cb6 100644 --- a/IfcPlusPlus/src/ifcpp/model/BuildingModel.h +++ b/IfcPlusPlus/src/ifcpp/model/BuildingModel.h @@ -78,7 +78,7 @@ class IFCQUERY_EXPORT BuildingModel : public StatusCallback void resetIfcModel(); void updateCache(); void clearCache(); - void initFileHeader( std::string file_name ); + void initFileHeader( const std::string& fileName, const std::string& generatingApplication ); static void collectDependentEntities( shared_ptr entity, std::map >& target_map, bool resolveInverseAttributes = false ); friend class ReaderSTEP; diff --git a/IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.cpp b/IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.cpp index 431fb6d4b..f4f9c2e99 100644 --- a/IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.cpp +++ b/IfcPlusPlus/src/ifcpp/reader/ReaderSTEP.cpp @@ -57,7 +57,8 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OU #include #include #endif -#include + +#include #include "ifcpp/model/OpenMPIncludes.h" #include "ReaderUtil.h" @@ -85,7 +86,7 @@ void ReaderSTEP::loadModelFromFile( const std::string& filePath, shared_ptr archive(new Zippy::ZipArchive()); + archive->Open(filePath.c_str()); + + std::vector entryNames = archive->GetEntryNames(); + if( entryNames.size() == 0 ) { - zip_entry_openbyindex(zip, 0); - { - zip_entry_fread(zip, uncompressedFileName.c_str()); - } - zip_entry_close(zip); - zip_close(zip); + return; } - + + std::string zipcontent = archive->GetEntry(entryNames[0]).GetDataAsString(); + std::ofstream zipFileUncompressed(uncompressedFileName, std::ofstream::out); + zipFileUncompressed << zipcontent; + zipFileUncompressed.close(); std::ifstream infile; infile.open(uncompressedFileName.c_str(), std::ifstream::in); - if (!infile.is_open()) + if( !infile.is_open() ) { std::stringstream strs; strs << "Could not unzip file: " << filePath; @@ -116,6 +119,7 @@ void ReaderSTEP::loadModelFromFile( const std::string& filePath, shared_ptrm_Coordinates[0] = location[0]; cartesianPoint->m_Coordinates[1] = location[1]; cartesianPoint->m_Coordinates[2] = location[2]; + cartesianPoint->m_size = 3; if (!axis2placement3d->m_Axis) { @@ -119,6 +120,7 @@ shared_ptr createIfcCartesianPoint(double x, double y, std::v shared_ptr pt(new IfcCartesianPoint()); pt->m_Coordinates[0] = x; pt->m_Coordinates[1] = y; + pt->m_size = 2; vec_new_entities.push_back(pt); return pt; } @@ -129,6 +131,7 @@ shared_ptr createIfcCartesianPoint(double x, double y, double pt->m_Coordinates[0] = x; pt->m_Coordinates[1] = y; pt->m_Coordinates[2] = z; + pt->m_size = 3; vec_new_entities.push_back(pt); return pt; } @@ -247,17 +250,10 @@ void LoadWallExample(shared_ptr& ifc_model, bool add_property_set // position of the solid extruded_solid->m_Position = shared_ptr(new IfcAxis2Placement3D()); vec_new_entities.push_back(extruded_solid->m_Position); - extruded_solid->m_Position->m_Axis = createIfcDirection(0, 0, 1, vec_new_entities); // z axis - vec_new_entities.push_back(extruded_solid->m_Position->m_Axis); - - extruded_solid->m_Position->m_RefDirection = createIfcDirection(1, 0, 0, vec_new_entities); // x axis - vec_new_entities.push_back(extruded_solid->m_Position->m_RefDirection); - - extruded_solid->m_Position->m_Location = createIfcCartesianPoint(0, 0, lower_level, vec_new_entities); - vec_new_entities.push_back(extruded_solid->m_Position->m_Location); - - extruded_solid->m_ExtrudedDirection = createIfcDirection(0, 0, 1, vec_new_entities); // extrusion direction - vec_new_entities.push_back(extruded_solid->m_ExtrudedDirection); + extruded_solid->m_Position->m_Axis = createIfcDirection(0, 0, 1, vec_new_entities); // z axis + extruded_solid->m_Position->m_RefDirection = createIfcDirection(1, 0, 0, vec_new_entities); // x axis + extruded_solid->m_Position->m_Location = createIfcCartesianPoint(0, 0, lower_level, vec_new_entities); + extruded_solid->m_ExtrudedDirection = createIfcDirection(0, 0, 1, vec_new_entities); // extrusion direction // length of extrusion: extruded_solid->m_Depth = shared_ptr(new IfcPositiveLengthMeasure()); @@ -275,19 +271,15 @@ void LoadWallExample(shared_ptr& ifc_model, bool add_property_set // these four points define the 2d polyline that is going to be extruded in z-direction: shared_ptr ifc_point1 = createIfcCartesianPoint(0, 0, vec_new_entities); - vec_new_entities.push_back(ifc_point1); poly_line->m_Points.push_back(ifc_point1); shared_ptr ifc_point2 = createIfcCartesianPoint(wall_length, 0, vec_new_entities); - vec_new_entities.push_back(ifc_point2); poly_line->m_Points.push_back(ifc_point2); shared_ptr ifc_point3 = createIfcCartesianPoint(wall_length, wall_thickness, vec_new_entities); - vec_new_entities.push_back(ifc_point3); poly_line->m_Points.push_back(ifc_point3); shared_ptr ifc_point4 = createIfcCartesianPoint(0.0, wall_thickness, vec_new_entities); - vec_new_entities.push_back(ifc_point4); poly_line->m_Points.push_back(ifc_point4); shape_representation->m_Items.push_back(extruded_solid);