diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp index e125bfb88..4a8ed0fe5 100644 --- a/src/libslic3r/Format/STEP.cpp +++ b/src/libslic3r/Format/STEP.cpp @@ -1,6 +1,7 @@ #include "../libslic3r.h" #include "../Model.hpp" #include "../TriangleMesh.hpp" +#include "libslic3r/Thread.hpp" #include "STEP.hpp" @@ -225,189 +226,189 @@ static void getNamedSolids(const TopLoc_Location& location, } } -bool load_step(const char *path, Model *model, bool& is_cancel, - double linear_defletion/*=0.003*/, - double angle_defletion/*= 0.5*/, - bool isSplitCompound, - ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn, long& mesh_face_num) -{ - bool cb_cancel = false; - if (stepFn) { - stepFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel); - is_cancel = cb_cancel; - if (cb_cancel) { - return false; - } - } - - if (!StepPreProcessor::isUtf8File(path) && isUtf8Fn) - isUtf8Fn(false); - std::string file_after_preprocess = std::string(path); - - std::vector namedSolids; - Handle(TDocStd_Document) document; - Handle(XCAFApp_Application) application = XCAFApp_Application::GetApplication(); - application->NewDocument(file_after_preprocess.c_str(), document); - STEPCAFControl_Reader reader; - reader.SetNameMode(true); - //BBS: Todo, read file is slow which cause the progress_bar no update and gui no response - IFSelect_ReturnStatus stat = reader.ReadFile(file_after_preprocess.c_str()); - if (stat != IFSelect_RetDone || !reader.Transfer(document)) { - application->Close(document); - throw std::logic_error{ std::string{"Could not read '"} + path + "'" }; - return false; - } - Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main()); - TDF_LabelSequence topLevelShapes; - shapeTool->GetFreeShapes(topLevelShapes); - - unsigned int id{1}; - Standard_Integer topShapeLength = topLevelShapes.Length() + 1; - auto stage_unit2 = topShapeLength / LOAD_STEP_STAGE_UNIT_NUM + 1; - - for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { - if (stepFn) { - if ((iLabel % stage_unit2) == 0) { - stepFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel); - is_cancel = cb_cancel; - } - if (cb_cancel) { - shapeTool.reset(nullptr); - application->Close(document); - return false; - } - } - getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound); - } - - std::vector stl; - stl.resize(namedSolids.size()); - tbb::parallel_for(tbb::blocked_range(0, namedSolids.size()), [&](const tbb::blocked_range &range) { - for (size_t i = range.begin(); i < range.end(); i++) { - BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_defletion, false, angle_defletion, true); - // BBS: calculate total number of the nodes and triangles - int aNbNodes = 0; - int aNbTriangles = 0; - for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { - TopLoc_Location aLoc; - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); - if (!aTriangulation.IsNull()) { - aNbNodes += aTriangulation->NbNodes(); - aNbTriangles += aTriangulation->NbTriangles(); - } - } - - if (aNbTriangles == 0 || aNbNodes == 0) - // BBS: No triangulation on the shape. - continue; - - stl[i].stats.type = inmemory; - stl[i].stats.number_of_facets = (uint32_t) aNbTriangles; - stl[i].stats.original_num_facets = stl[i].stats.number_of_facets; - stl_allocate(&stl[i]); - - std::vector points; - points.reserve(aNbNodes); - // BBS: count faces missing triangulation - Standard_Integer aNbFacesNoTri = 0; - // BBS: fill temporary triangulation - Standard_Integer aNodeOffset = 0; - Standard_Integer aTriangleOffet = 0; - for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { - const TopoDS_Shape &aFace = anExpSF.Current(); - TopLoc_Location aLoc; - Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); - if (aTriangulation.IsNull()) { - ++aNbFacesNoTri; - continue; - } - // BBS: copy nodes - gp_Trsf aTrsf = aLoc.Transformation(); - for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { - gp_Pnt aPnt = aTriangulation->Node(aNodeIter); - aPnt.Transform(aTrsf); - points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); - } - // BBS: copy triangles - const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); - Standard_Integer anId[3] = {}; - for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { - Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); - - aTri.Get(anId[0], anId[1], anId[2]); - if (anOrientation == TopAbs_REVERSED) - std::swap(anId[1], anId[2]); - // BBS: save triangles facets - stl_facet facet; - facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast(); - facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast(); - facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast(); - facet.extra[0] = 0; - facet.extra[1] = 0; - stl_normal normal; - stl_calculate_normal(normal, &facet); - stl_normalize_vector(normal); - facet.normal = normal; - stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet; - } - - aNodeOffset += aTriangulation->NbNodes(); - aTriangleOffet += aTriangulation->NbTriangles(); - } - } - }); - - if (mesh_face_num != -1) { - for (size_t i = 0; i < stl.size(); i++) { - // Test for overflow - mesh_face_num += stl[i].stats.number_of_facets; - } - return true; - } - - ModelObject *new_object = model->add_object(); - const char * last_slash = strrchr(path, DIR_SEPARATOR); - new_object->name.assign((last_slash == nullptr) ? path : last_slash + 1); - new_object->input_file = path; - - auto stage_unit3 = stl.size() / LOAD_STEP_STAGE_UNIT_NUM + 1; - for (size_t i = 0; i < stl.size(); i++) { - if (stepFn) { - if ((i % stage_unit3) == 0) { - stepFn(LOAD_STEP_STAGE_GET_MESH, i, stl.size(), cb_cancel); - is_cancel = cb_cancel; - } - if (cb_cancel) { - model->delete_object(new_object); - shapeTool.reset(nullptr); - application->Close(document); - return false; - } - } - - //BBS: maybe mesh is empty from step file. Don't add - if (stl[i].stats.number_of_facets > 0) { - TriangleMesh triangle_mesh; - triangle_mesh.from_stl(stl[i]); - ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh)); - new_volume->name = namedSolids[i].name; - new_volume->source.input_file = path; - new_volume->source.object_idx = (int)model->objects.size() - 1; - new_volume->source.volume_idx = (int)new_object->volumes.size() - 1; - } - } - - shapeTool.reset(nullptr); - application->Close(document); - - //BBS: no valid shape from the step, delete the new object as well - if (new_object->volumes.size() == 0) { - model->delete_object(new_object); - return false; - } - - return true; -} +//bool load_step(const char *path, Model *model, bool& is_cancel, +// double linear_defletion/*=0.003*/, +// double angle_defletion/*= 0.5*/, +// bool isSplitCompound, +// ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn, long& mesh_face_num) +//{ +// bool cb_cancel = false; +// if (stepFn) { +// stepFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel); +// is_cancel = cb_cancel; +// if (cb_cancel) { +// return false; +// } +// } +// +// if (!StepPreProcessor::isUtf8File(path) && isUtf8Fn) +// isUtf8Fn(false); +// std::string file_after_preprocess = std::string(path); +// +// std::vector namedSolids; +// Handle(TDocStd_Document) document; +// Handle(XCAFApp_Application) application = XCAFApp_Application::GetApplication(); +// application->NewDocument(file_after_preprocess.c_str(), document); +// STEPCAFControl_Reader reader; +// reader.SetNameMode(true); +// //BBS: Todo, read file is slow which cause the progress_bar no update and gui no response +// IFSelect_ReturnStatus stat = reader.ReadFile(file_after_preprocess.c_str()); +// if (stat != IFSelect_RetDone || !reader.Transfer(document)) { +// application->Close(document); +// throw std::logic_error{ std::string{"Could not read '"} + path + "'" }; +// return false; +// } +// Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main()); +// TDF_LabelSequence topLevelShapes; +// shapeTool->GetFreeShapes(topLevelShapes); +// +// unsigned int id{1}; +// Standard_Integer topShapeLength = topLevelShapes.Length() + 1; +// auto stage_unit2 = topShapeLength / LOAD_STEP_STAGE_UNIT_NUM + 1; +// +// for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { +// if (stepFn) { +// if ((iLabel % stage_unit2) == 0) { +// stepFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel); +// is_cancel = cb_cancel; +// } +// if (cb_cancel) { +// shapeTool.reset(nullptr); +// application->Close(document); +// return false; +// } +// } +// getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound); +// } +// +// std::vector stl; +// stl.resize(namedSolids.size()); +// tbb::parallel_for(tbb::blocked_range(0, namedSolids.size()), [&](const tbb::blocked_range &range) { +// for (size_t i = range.begin(); i < range.end(); i++) { +// BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_defletion, false, angle_defletion, true); +// // BBS: calculate total number of the nodes and triangles +// int aNbNodes = 0; +// int aNbTriangles = 0; +// for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { +// TopLoc_Location aLoc; +// Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); +// if (!aTriangulation.IsNull()) { +// aNbNodes += aTriangulation->NbNodes(); +// aNbTriangles += aTriangulation->NbTriangles(); +// } +// } +// +// if (aNbTriangles == 0 || aNbNodes == 0) +// // BBS: No triangulation on the shape. +// continue; +// +// stl[i].stats.type = inmemory; +// stl[i].stats.number_of_facets = (uint32_t) aNbTriangles; +// stl[i].stats.original_num_facets = stl[i].stats.number_of_facets; +// stl_allocate(&stl[i]); +// +// std::vector points; +// points.reserve(aNbNodes); +// // BBS: count faces missing triangulation +// Standard_Integer aNbFacesNoTri = 0; +// // BBS: fill temporary triangulation +// Standard_Integer aNodeOffset = 0; +// Standard_Integer aTriangleOffet = 0; +// for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { +// const TopoDS_Shape &aFace = anExpSF.Current(); +// TopLoc_Location aLoc; +// Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); +// if (aTriangulation.IsNull()) { +// ++aNbFacesNoTri; +// continue; +// } +// // BBS: copy nodes +// gp_Trsf aTrsf = aLoc.Transformation(); +// for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { +// gp_Pnt aPnt = aTriangulation->Node(aNodeIter); +// aPnt.Transform(aTrsf); +// points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); +// } +// // BBS: copy triangles +// const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); +// Standard_Integer anId[3] = {}; +// for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { +// Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); +// +// aTri.Get(anId[0], anId[1], anId[2]); +// if (anOrientation == TopAbs_REVERSED) +// std::swap(anId[1], anId[2]); +// // BBS: save triangles facets +// stl_facet facet; +// facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast(); +// facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast(); +// facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast(); +// facet.extra[0] = 0; +// facet.extra[1] = 0; +// stl_normal normal; +// stl_calculate_normal(normal, &facet); +// stl_normalize_vector(normal); +// facet.normal = normal; +// stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet; +// } +// +// aNodeOffset += aTriangulation->NbNodes(); +// aTriangleOffet += aTriangulation->NbTriangles(); +// } +// } +// }); +// +// if (mesh_face_num != -1) { +// for (size_t i = 0; i < stl.size(); i++) { +// // Test for overflow +// mesh_face_num += stl[i].stats.number_of_facets; +// } +// return true; +// } +// +// ModelObject *new_object = model->add_object(); +// const char * last_slash = strrchr(path, DIR_SEPARATOR); +// new_object->name.assign((last_slash == nullptr) ? path : last_slash + 1); +// new_object->input_file = path; +// +// auto stage_unit3 = stl.size() / LOAD_STEP_STAGE_UNIT_NUM + 1; +// for (size_t i = 0; i < stl.size(); i++) { +// if (stepFn) { +// if ((i % stage_unit3) == 0) { +// stepFn(LOAD_STEP_STAGE_GET_MESH, i, stl.size(), cb_cancel); +// is_cancel = cb_cancel; +// } +// if (cb_cancel) { +// model->delete_object(new_object); +// shapeTool.reset(nullptr); +// application->Close(document); +// return false; +// } +// } +// +// //BBS: maybe mesh is empty from step file. Don't add +// if (stl[i].stats.number_of_facets > 0) { +// TriangleMesh triangle_mesh; +// triangle_mesh.from_stl(stl[i]); +// ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh)); +// new_volume->name = namedSolids[i].name; +// new_volume->source.input_file = path; +// new_volume->source.object_idx = (int)model->objects.size() - 1; +// new_volume->source.volume_idx = (int)new_object->volumes.size() - 1; +// } +// } +// +// shapeTool.reset(nullptr); +// application->Close(document); +// +// //BBS: no valid shape from the step, delete the new object as well +// if (new_object->volumes.size() == 0) { +// model->delete_object(new_object); +// return false; +// } +// +// return true; +//} Step::Step(fs::path path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn): m_stepFn(stepFn), @@ -425,30 +426,257 @@ Step::Step(std::string path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn) m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc); } -bool Step::load() +Step::~Step() +{ + m_app->Close(m_doc); +} + +void Step::update_process(int load_stage, int current, int total, bool& cancel) +{ + if (m_stepFn) { + m_stepFn(load_stage, current, total, cancel); + } +} + +Step::Step_Status Step::load() { if (!StepPreProcessor::isUtf8File(m_path.c_str()) && m_utf8Fn) { m_utf8Fn(false); - return false; + return Step_Status::LOAD_ERROR; + } + std::atomic stop_load_flag = false; + Handle(StepProgressIncdicator) incdicator = new StepProgressIncdicator(stop_load_flag); + bool task_result = false; + bool cb_cancel = false; + int progress = 0; + bool load_result = false; + auto task = new boost::thread(Slic3r::create_thread([&]() -> void { + + STEPCAFControl_Reader reader; + reader.SetNameMode(true); + IFSelect_ReturnStatus stat = reader.ReadFile(m_path.c_str()); + if (cb_cancel) return; + progress = 3; + if (stat != IFSelect_RetDone || !reader.Transfer(m_doc, incdicator->Start())) { + load_result = false; + task_result = true; + return; + } + if (cb_cancel) return; + progress = 6; + m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main()); + TDF_LabelSequence topLevelShapes; + m_shape_tool->GetFreeShapes(topLevelShapes); + unsigned int id{ 1 }; + Standard_Integer topShapeLength = topLevelShapes.Length() + 1; + for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { + if (cb_cancel) return; + getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids); + } + progress = 10; + load_result = true; + task_result = true; + })); + while (!task_result) { + boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); + update_process(LOAD_STEP_STAGE_READ_FILE, progress, 10, cb_cancel); + if (cb_cancel) { + stop_load_flag.store(true); + if (task) { + if (task->joinable()) { + task->join(); + delete task; + } + } + return Step_Status::CANCEL; + } + } + if (task){ + if (task->joinable()) { + task->join(); + delete task; + } + } + if (load_result) { + return Step_Status::LOAD_SUCCESS; + }else { + return Step_Status::LOAD_ERROR; + } + +} + +Step::Step_Status Step::mesh(Model* model, + bool& is_cancel, + bool isSplitCompound, + double linear_defletion/*=0.003*/, + double angle_defletion/*= 0.5*/) + +{ + bool task_result = false; + bool cb_cancel = false; + float progress = .0; + std::atomic meshed_solid_num = 0; + std::vector namedSolids; + float progress_2 = .0; + ModelObject* new_object = model->add_object(); + const char* last_slash = strrchr(m_path.c_str(), DIR_SEPARATOR); + new_object->name.assign((last_slash == nullptr) ? m_path.c_str() : last_slash + 1); + new_object->input_file = m_path.c_str(); + + auto task = new boost::thread(Slic3r::create_thread([&]() -> void { + TDF_LabelSequence topLevelShapes; + m_shape_tool->GetFreeShapes(topLevelShapes); + unsigned int id{ 1 }; + Standard_Integer topShapeLength = topLevelShapes.Length() + 1; + + for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { + progress = static_cast(iLabel) / (topShapeLength-1); + if (cb_cancel) { + return; + } + getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound); + } + + std::vector stl; + stl.resize(namedSolids.size()); + tbb::parallel_for(tbb::blocked_range(0, namedSolids.size()), [&](const tbb::blocked_range& range) { + for (size_t i = range.begin(); i < range.end(); i++) { + BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_defletion, false, angle_defletion, true); + // BBS: calculate total number of the nodes and triangles + int aNbNodes = 0; + int aNbTriangles = 0; + for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); + if (!aTriangulation.IsNull()) { + aNbNodes += aTriangulation->NbNodes(); + aNbTriangles += aTriangulation->NbTriangles(); + } + } + + if (aNbTriangles == 0 || aNbNodes == 0) + // BBS: No triangulation on the shape. + continue; + + stl[i].stats.type = inmemory; + stl[i].stats.number_of_facets = (uint32_t)aNbTriangles; + stl[i].stats.original_num_facets = stl[i].stats.number_of_facets; + stl_allocate(&stl[i]); + + std::vector points; + points.reserve(aNbNodes); + // BBS: count faces missing triangulation + Standard_Integer aNbFacesNoTri = 0; + // BBS: fill temporary triangulation + Standard_Integer aNodeOffset = 0; + Standard_Integer aTriangleOffet = 0; + for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { + const TopoDS_Shape& aFace = anExpSF.Current(); + TopLoc_Location aLoc; + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); + if (aTriangulation.IsNull()) { + ++aNbFacesNoTri; + continue; + } + // BBS: copy nodes + gp_Trsf aTrsf = aLoc.Transformation(); + for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { + gp_Pnt aPnt = aTriangulation->Node(aNodeIter); + aPnt.Transform(aTrsf); + points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); + } + // BBS: copy triangles + const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); + Standard_Integer anId[3] = {}; + for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { + Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); + + aTri.Get(anId[0], anId[1], anId[2]); + if (anOrientation == TopAbs_REVERSED) + std::swap(anId[1], anId[2]); + // BBS: save triangles facets + stl_facet facet; + facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast(); + facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast(); + facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast(); + facet.extra[0] = 0; + facet.extra[1] = 0; + stl_normal normal; + stl_calculate_normal(normal, &facet); + stl_normalize_vector(normal); + facet.normal = normal; + stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet; + } + + aNodeOffset += aTriangulation->NbNodes(); + aTriangleOffet += aTriangulation->NbTriangles(); + } + meshed_solid_num.fetch_add(1, std::memory_order_relaxed); + } + }); + + + for (size_t i = 0; i < stl.size(); i++) { + progress_2 = static_cast(i) / stl.size(); + if (cb_cancel) + return; + + //BBS: maybe mesh is empty from step file. Don't add + if (stl[i].stats.number_of_facets > 0) { + TriangleMesh triangle_mesh; + triangle_mesh.from_stl(stl[i]); + ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh)); + new_volume->name = namedSolids[i].name; + new_volume->source.input_file = m_path.c_str(); + new_volume->source.object_idx = (int)model->objects.size() - 1; + new_volume->source.volume_idx = (int)new_object->volumes.size() - 1; + } + } + task_result = true; + })); + + while (!task_result) { + boost::this_thread::sleep_for(boost::chrono::milliseconds(300)); + if (progress_2 > 0) { + // third progress + update_process(LOAD_STEP_STAGE_GET_MESH, static_cast(progress_2 * 100), 100, cb_cancel); + }else { + if (meshed_solid_num.load()) { + // second progress + int meshed_solid = meshed_solid_num.load(); + update_process(LOAD_STEP_STAGE_GET_SOLID, static_cast((float)meshed_solid / namedSolids.size() * 10) + 10, 20, cb_cancel); + } else { + if (progress > 0) { + // first progress + update_process(LOAD_STEP_STAGE_GET_SOLID, static_cast(progress * 10), 20, cb_cancel); + } + } + } + + + if (cb_cancel) { + if (task) { + if (task->joinable()) { + task->join(); + delete task; + } + } + return Step_Status::CANCEL; + } + } + if (task) { + if (task->joinable()) { + task->join(); + delete task; + } } - STEPCAFControl_Reader reader; - reader.SetNameMode(true); - IFSelect_ReturnStatus stat = reader.ReadFile(m_path.c_str()); - if (stat != IFSelect_RetDone || !reader.Transfer(m_doc)) { - m_app->Close(m_doc); - return false; + //BBS: no valid shape from the step, delete the new object as well + if (new_object->volumes.size() == 0) { + model->delete_object(new_object); + return Step_Status::MESH_ERROR; } - m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main()); - TDF_LabelSequence topLevelShapes; - m_shape_tool->GetFreeShapes(topLevelShapes); - unsigned int id{ 1 }; - Standard_Integer topShapeLength = topLevelShapes.Length() + 1; - for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { - getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids); - } - - return true; + return Step_Status::MESH_SUCCESS; } void Step::clean_mesh_data() diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp index b37e85a22..2ce46b963 100644 --- a/src/libslic3r/Format/STEP.hpp +++ b/src/libslic3r/Format/STEP.hpp @@ -88,14 +88,28 @@ private: class Step { public: + enum class Step_Status { + LOAD_SUCCESS, + LOAD_ERROR, + CANCEL, + MESH_SUCCESS, + MESH_ERROR + }; Step(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr); Step(std::string path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr); - bool load(); + ~Step(); + Step_Status load(); unsigned int get_triangle_num(double linear_defletion, double angle_defletion); unsigned int get_triangle_num_tbb(double linear_defletion, double angle_defletion); void clean_mesh_data(); + Step_Status mesh(Model* model, + bool& is_cancel, + bool isSplitCompound, + double linear_defletion = 0.003, + double angle_defletion = 0.5); std::atomic m_stop_mesh; + void update_process(int load_stage, int current, int total, bool& cancel); private: std::string m_path; ImportStepProgressFn m_stepFn; diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index a1a8839dc..d4d5d83db 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -197,26 +197,34 @@ Model Model::read_from_step(const std::string& Model model; bool result = false; bool is_cb_cancel = false; - std::string message; - Step step_file(input_file); - step_file.load(); + Step::Step_Status status; + Step step_file(input_file, stepFn); + status = step_file.load(); + if(status != Step::Step_Status::LOAD_SUCCESS) { + goto _finished; + } if (step_mesh_fn) { if (step_mesh_fn(step_file, linear_defletion, angle_defletion, is_split_compound) == -1) { + status = Step::Step_Status::CANCEL; + goto _finished; + } + } + + status = step_file.mesh(&model, is_cb_cancel, is_split_compound, linear_defletion, angle_defletion); + +_finished: + + switch (status){ + case Step::Step_Status::CANCEL: { Model empty_model; return empty_model; } - } - result = load_step(input_file.c_str(), &model, is_cb_cancel, linear_defletion, angle_defletion, is_split_compound, stepFn, stepIsUtf8Fn); - if (is_cb_cancel) { - Model empty_model; - return empty_model; - } - - if (!result) { - if (message.empty()) + case Step::Step_Status::LOAD_ERROR: throw Slic3r::RuntimeError(_L("Loading of a model file failed.")); - else - throw Slic3r::RuntimeError(message); + case Step::Step_Status::MESH_ERROR: + throw Slic3r::RuntimeError(_L("Meshing of a model file failed or no valid shape.")); + default: + break; } if (model.objects.empty())