diff --git a/deps/+OCCT/OCCT.cmake b/deps/+OCCT/OCCT.cmake index 5b7743e581..81cdf46dee 100644 --- a/deps/+OCCT/OCCT.cmake +++ b/deps/+OCCT/OCCT.cmake @@ -1,7 +1,9 @@ add_cmake_project(OCCT - #LMBBS: changed version to 7.6.2 - URL https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/V7_6_2.zip - URL_HASH SHA256=c696b923593e8c18d059709717dbf155b3e72fdd283c8522047a790ec3a432c5 + # Versions newer than 7.6.1 contain a bug that causes chamfers to be triangulated incorrectly. + # So, before any updating, it is necessary to check whether SPE-2257 is still happening. + # In version 7.8.1, this bug has still not been fixed. + URL https://github.com/Open-Cascade-SAS/OCCT/archive/refs/tags/V7_6_1.zip + URL_HASH SHA256=b7cf65430d6f099adc9df1749473235de7941120b5b5dd356067d12d0909b1d3 PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/occt_toolkit.cmake ./adm/cmake/ CMAKE_ARGS diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index 2894d45a35..c2761e07c0 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -106,23 +106,13 @@ bool load_step(const char *path, Model *model /*BBS:, ImportStepProgressFn proFn else new_object->name = occt_object.object_name; - - for (size_t i=0; iadd_volume(std::move(triangle_mesh)); new_volume->name = occt_object.volumes[i].volume_name.empty() - ? std::string("Part") + std::to_string(i+1) + ? std::string("Part") + std::to_string(i + 1) : occt_object.volumes[i].volume_name; new_volume->source.input_file = path; new_volume->source.object_idx = (int)model->objects.size() - 1; diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index f9a94bd9a9..85ec9011ad 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -197,6 +197,24 @@ static void trianglemesh_repair_on_import(stl_file &stl) BOOST_LOG_TRIVIAL(debug) << "TriangleMesh::repair() finished"; } +void TriangleMesh::from_facets(std::vector &&facets, bool repair) +{ + stl_file stl; + stl.stats.type = inmemory; + stl.stats.number_of_facets = uint32_t(facets.size()); + stl.stats.original_num_facets = int(stl.stats.number_of_facets); + + stl_allocate(&stl); + stl.facet_start = std::move(facets); + + if (repair) { + trianglemesh_repair_on_import(stl); + } + + stl_generate_shared_vertices(&stl, this->its); + fill_initial_stats(this->its, this->m_stats); +} + bool TriangleMesh::ReadSTLFile(const char* input_file, bool repair) { stl_file stl; diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 34dc6cedae..9d46a79210 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -116,6 +116,7 @@ public: explicit TriangleMesh(const indexed_triangle_set &M); explicit TriangleMesh(indexed_triangle_set &&M, const RepairedMeshErrors& repaired_errors = RepairedMeshErrors()); void clear() { this->its.clear(); m_stats.clear(); } + void from_facets(std::vector &&facets, bool repair = true); bool ReadSTLFile(const char* input_file, bool repair = true); bool write_ascii(const char* output_file); bool write_binary(const char* output_file); diff --git a/src/occt_wrapper/CMakeLists.txt b/src/occt_wrapper/CMakeLists.txt index 8ab9fb4be8..f6df6e7a60 100644 --- a/src/occt_wrapper/CMakeLists.txt +++ b/src/occt_wrapper/CMakeLists.txt @@ -19,7 +19,7 @@ include(GenerateExportHeader) generate_export_header(OCCTWrapper) -find_package(OpenCASCADE 7.6.2 REQUIRED) +find_package(OpenCASCADE 7.6.1 REQUIRED) set(OCCT_LIBS TKXDESTEP @@ -55,6 +55,7 @@ slic3r_remap_configs("${OCCT_LIBS}" RelWithDebInfo Release) target_include_directories(OCCTWrapper PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(OCCTWrapper PUBLIC ${OpenCASCADE_INCLUDE_DIR}) target_link_libraries(OCCTWrapper ${OCCT_LIBS}) +target_link_libraries(OCCTWrapper libslic3r admesh) include(GNUInstallDirs) diff --git a/src/occt_wrapper/OCCTWrapper.cpp b/src/occt_wrapper/OCCTWrapper.cpp index e41d8953ff..6ed3870c2d 100644 --- a/src/occt_wrapper/OCCTWrapper.cpp +++ b/src/occt_wrapper/OCCTWrapper.cpp @@ -21,6 +21,8 @@ #include "BRepBuilderAPI_Transform.hxx" #include "TopExp_Explorer.hxx" #include "BRep_Tool.hxx" +#include "admesh/stl.h" +#include "libslic3r/Point.hpp" const double STEP_TRANS_CHORD_ERROR = 0.005; const double STEP_TRANS_ANGLE_RES = 1; @@ -126,24 +128,13 @@ try { std::string obj_name((last_slash == nullptr) ? path : last_slash + 1); res->object_name = obj_name; - for (size_t i = 0; i < namedSolids.size(); ++i) { - //BBS:if (proFn) { - // proFn(LOAD_STEP_STAGE_GET_MESH, i, namedSolids.size(), cb_cancel); - // if (cb_cancel) { - // model->delete_object(new_object); - // shapeTool.reset(nullptr); - // application->Close(document); - // return false; - // } - //} - + for (const NamedSolid &namedSolid : namedSolids) { + BRepMesh_IncrementalMesh mesh(namedSolid.solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); res->volumes.emplace_back(); - auto& vertices = res->volumes.back().vertices; - auto& indices = res->volumes.back().indices; - BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true); - - for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + std::vector vertices; + std::vector &facets = res->volumes.back().facets; + for (TopExp_Explorer anExpSF(namedSolid.solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { const int aNodeOffset = int(vertices.size()); const TopoDS_Shape& aFace = anExpSF.Current(); TopLoc_Location aLoc; @@ -156,27 +147,33 @@ try { for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { gp_Pnt aPnt = aTriangulation->Node(aNodeIter); aPnt.Transform(aTrsf); - vertices.push_back({float(aPnt.X()), float(aPnt.Y()), float(aPnt.Z())}); + vertices.emplace_back(std::move(Vec3f(float(aPnt.X()), float(aPnt.Y()), float(aPnt.Z())))); } - // Now the indices. + + // Now copy the facets. const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { + const int aTriangleOffet = int(facets.size()); Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); Standard_Integer anId[3]; aTri.Get(anId[0], anId[1], anId[2]); - if (anOrientation == TopAbs_REVERSED) + if (anOrientation == TopAbs_REVERSED) { std::swap(anId[1], anId[2]); + } - // Account for the vertices we already have from previous faces. - // anId is 1-based index ! - indices.push_back({anId[0] - 1 + aNodeOffset, - anId[1] - 1 + aNodeOffset, - anId[2] - 1 + aNodeOffset}); + stl_facet facet; + facet.vertex[0] = vertices[anId[0] + aNodeOffset - 1]; + facet.vertex[1] = vertices[anId[1] + aNodeOffset - 1]; + facet.vertex[2] = vertices[anId[2] + aNodeOffset - 1]; + facet.normal = (facet.vertex[1] - facet.vertex[0]).cross(facet.vertex[2] - facet.vertex[1]).normalized(); + facet.extra[0] = 0; + facet.extra[1] = 0; + facets.emplace_back(std::move(facet)); } } - res->volumes.back().volume_name = namedSolids[i].name; + res->volumes.back().volume_name = namedSolid.name; if (vertices.empty()) res->volumes.pop_back(); diff --git a/src/occt_wrapper/OCCTWrapper.hpp b/src/occt_wrapper/OCCTWrapper.hpp index e87becb70f..7c86998f21 100644 --- a/src/occt_wrapper/OCCTWrapper.hpp +++ b/src/occt_wrapper/OCCTWrapper.hpp @@ -6,12 +6,13 @@ #include #include +struct stl_facet; + namespace Slic3r { struct OCCTVolume { - std::string volume_name; - std::vector> vertices; - std::vector> indices; + std::string volume_name; + std::vector facets; }; struct OCCTResult {