ENH:loading the step in boost thread

github: #6079
Change-Id: I0a289fc9730e7d091a71137cf11a711dfee5392f
(cherry picked from commit b454e7d8bb91b62b3be6121c567f7aee291eff50)
This commit is contained in:
Mack 2025-03-25 11:28:07 +08:00 committed by lane.wei
parent cf63988a45
commit b7ffba39e4
3 changed files with 466 additions and 216 deletions

View File

@ -1,6 +1,7 @@
#include "../libslic3r.h" #include "../libslic3r.h"
#include "../Model.hpp" #include "../Model.hpp"
#include "../TriangleMesh.hpp" #include "../TriangleMesh.hpp"
#include "libslic3r/Thread.hpp"
#include "STEP.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, //bool load_step(const char *path, Model *model, bool& is_cancel,
double linear_defletion/*=0.003*/, // double linear_defletion/*=0.003*/,
double angle_defletion/*= 0.5*/, // double angle_defletion/*= 0.5*/,
bool isSplitCompound, // bool isSplitCompound,
ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn, long& mesh_face_num) // ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn, long& mesh_face_num)
{ //{
bool cb_cancel = false; // bool cb_cancel = false;
if (stepFn) { // if (stepFn) {
stepFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel); // stepFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel);
is_cancel = cb_cancel; // is_cancel = cb_cancel;
if (cb_cancel) { // if (cb_cancel) {
return false; // return false;
} // }
} // }
//
if (!StepPreProcessor::isUtf8File(path) && isUtf8Fn) // if (!StepPreProcessor::isUtf8File(path) && isUtf8Fn)
isUtf8Fn(false); // isUtf8Fn(false);
std::string file_after_preprocess = std::string(path); // std::string file_after_preprocess = std::string(path);
//
std::vector<NamedSolid> namedSolids; // std::vector<NamedSolid> namedSolids;
Handle(TDocStd_Document) document; // Handle(TDocStd_Document) document;
Handle(XCAFApp_Application) application = XCAFApp_Application::GetApplication(); // Handle(XCAFApp_Application) application = XCAFApp_Application::GetApplication();
application->NewDocument(file_after_preprocess.c_str(), document); // application->NewDocument(file_after_preprocess.c_str(), document);
STEPCAFControl_Reader reader; // STEPCAFControl_Reader reader;
reader.SetNameMode(true); // reader.SetNameMode(true);
//BBS: Todo, read file is slow which cause the progress_bar no update and gui no response // //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()); // IFSelect_ReturnStatus stat = reader.ReadFile(file_after_preprocess.c_str());
if (stat != IFSelect_RetDone || !reader.Transfer(document)) { // if (stat != IFSelect_RetDone || !reader.Transfer(document)) {
application->Close(document); // application->Close(document);
throw std::logic_error{ std::string{"Could not read '"} + path + "'" }; // throw std::logic_error{ std::string{"Could not read '"} + path + "'" };
return false; // return false;
} // }
Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main()); // Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main());
TDF_LabelSequence topLevelShapes; // TDF_LabelSequence topLevelShapes;
shapeTool->GetFreeShapes(topLevelShapes); // shapeTool->GetFreeShapes(topLevelShapes);
//
unsigned int id{1}; // unsigned int id{1};
Standard_Integer topShapeLength = topLevelShapes.Length() + 1; // Standard_Integer topShapeLength = topLevelShapes.Length() + 1;
auto stage_unit2 = topShapeLength / LOAD_STEP_STAGE_UNIT_NUM + 1; // auto stage_unit2 = topShapeLength / LOAD_STEP_STAGE_UNIT_NUM + 1;
//
for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) { // for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) {
if (stepFn) { // if (stepFn) {
if ((iLabel % stage_unit2) == 0) { // if ((iLabel % stage_unit2) == 0) {
stepFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel); // stepFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel);
is_cancel = cb_cancel; // is_cancel = cb_cancel;
} // }
if (cb_cancel) { // if (cb_cancel) {
shapeTool.reset(nullptr); // shapeTool.reset(nullptr);
application->Close(document); // application->Close(document);
return false; // return false;
} // }
} // }
getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound); // getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound);
} // }
//
std::vector<stl_file> stl; // std::vector<stl_file> stl;
stl.resize(namedSolids.size()); // stl.resize(namedSolids.size());
tbb::parallel_for(tbb::blocked_range<size_t>(0, namedSolids.size()), [&](const tbb::blocked_range<size_t> &range) { // tbb::parallel_for(tbb::blocked_range<size_t>(0, namedSolids.size()), [&](const tbb::blocked_range<size_t> &range) {
for (size_t i = range.begin(); i < range.end(); i++) { // for (size_t i = range.begin(); i < range.end(); i++) {
BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_defletion, false, angle_defletion, true); // BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_defletion, false, angle_defletion, true);
// BBS: calculate total number of the nodes and triangles // // BBS: calculate total number of the nodes and triangles
int aNbNodes = 0; // int aNbNodes = 0;
int aNbTriangles = 0; // int aNbTriangles = 0;
for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { // for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
TopLoc_Location aLoc; // TopLoc_Location aLoc;
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc); // Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);
if (!aTriangulation.IsNull()) { // if (!aTriangulation.IsNull()) {
aNbNodes += aTriangulation->NbNodes(); // aNbNodes += aTriangulation->NbNodes();
aNbTriangles += aTriangulation->NbTriangles(); // aNbTriangles += aTriangulation->NbTriangles();
} // }
} // }
//
if (aNbTriangles == 0 || aNbNodes == 0) // if (aNbTriangles == 0 || aNbNodes == 0)
// BBS: No triangulation on the shape. // // BBS: No triangulation on the shape.
continue; // continue;
//
stl[i].stats.type = inmemory; // stl[i].stats.type = inmemory;
stl[i].stats.number_of_facets = (uint32_t) aNbTriangles; // stl[i].stats.number_of_facets = (uint32_t) aNbTriangles;
stl[i].stats.original_num_facets = stl[i].stats.number_of_facets; // stl[i].stats.original_num_facets = stl[i].stats.number_of_facets;
stl_allocate(&stl[i]); // stl_allocate(&stl[i]);
//
std::vector<Vec3f> points; // std::vector<Vec3f> points;
points.reserve(aNbNodes); // points.reserve(aNbNodes);
// BBS: count faces missing triangulation // // BBS: count faces missing triangulation
Standard_Integer aNbFacesNoTri = 0; // Standard_Integer aNbFacesNoTri = 0;
// BBS: fill temporary triangulation // // BBS: fill temporary triangulation
Standard_Integer aNodeOffset = 0; // Standard_Integer aNodeOffset = 0;
Standard_Integer aTriangleOffet = 0; // Standard_Integer aTriangleOffet = 0;
for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) { // for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
const TopoDS_Shape &aFace = anExpSF.Current(); // const TopoDS_Shape &aFace = anExpSF.Current();
TopLoc_Location aLoc; // TopLoc_Location aLoc;
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc); // Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc);
if (aTriangulation.IsNull()) { // if (aTriangulation.IsNull()) {
++aNbFacesNoTri; // ++aNbFacesNoTri;
continue; // continue;
} // }
// BBS: copy nodes // // BBS: copy nodes
gp_Trsf aTrsf = aLoc.Transformation(); // gp_Trsf aTrsf = aLoc.Transformation();
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) { // for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
gp_Pnt aPnt = aTriangulation->Node(aNodeIter); // gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
aPnt.Transform(aTrsf); // aPnt.Transform(aTrsf);
points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()))); // points.emplace_back(std::move(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z())));
} // }
// BBS: copy triangles // // BBS: copy triangles
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); // const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
Standard_Integer anId[3] = {}; // Standard_Integer anId[3] = {};
for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) { // for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter); // Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
//
aTri.Get(anId[0], anId[1], anId[2]); // aTri.Get(anId[0], anId[1], anId[2]);
if (anOrientation == TopAbs_REVERSED) // if (anOrientation == TopAbs_REVERSED)
std::swap(anId[1], anId[2]); // std::swap(anId[1], anId[2]);
// BBS: save triangles facets // // BBS: save triangles facets
stl_facet facet; // stl_facet facet;
facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast<float>(); // facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast<float>();
facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast<float>(); // facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast<float>();
facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast<float>(); // facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast<float>();
facet.extra[0] = 0; // facet.extra[0] = 0;
facet.extra[1] = 0; // facet.extra[1] = 0;
stl_normal normal; // stl_normal normal;
stl_calculate_normal(normal, &facet); // stl_calculate_normal(normal, &facet);
stl_normalize_vector(normal); // stl_normalize_vector(normal);
facet.normal = normal; // facet.normal = normal;
stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet; // stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet;
} // }
//
aNodeOffset += aTriangulation->NbNodes(); // aNodeOffset += aTriangulation->NbNodes();
aTriangleOffet += aTriangulation->NbTriangles(); // aTriangleOffet += aTriangulation->NbTriangles();
} // }
} // }
}); // });
//
if (mesh_face_num != -1) { // if (mesh_face_num != -1) {
for (size_t i = 0; i < stl.size(); i++) { // for (size_t i = 0; i < stl.size(); i++) {
// Test for overflow // // Test for overflow
mesh_face_num += stl[i].stats.number_of_facets; // mesh_face_num += stl[i].stats.number_of_facets;
} // }
return true; // return true;
} // }
//
ModelObject *new_object = model->add_object(); // ModelObject *new_object = model->add_object();
const char * last_slash = strrchr(path, DIR_SEPARATOR); // const char * last_slash = strrchr(path, DIR_SEPARATOR);
new_object->name.assign((last_slash == nullptr) ? path : last_slash + 1); // new_object->name.assign((last_slash == nullptr) ? path : last_slash + 1);
new_object->input_file = path; // new_object->input_file = path;
//
auto stage_unit3 = stl.size() / LOAD_STEP_STAGE_UNIT_NUM + 1; // auto stage_unit3 = stl.size() / LOAD_STEP_STAGE_UNIT_NUM + 1;
for (size_t i = 0; i < stl.size(); i++) { // for (size_t i = 0; i < stl.size(); i++) {
if (stepFn) { // if (stepFn) {
if ((i % stage_unit3) == 0) { // if ((i % stage_unit3) == 0) {
stepFn(LOAD_STEP_STAGE_GET_MESH, i, stl.size(), cb_cancel); // stepFn(LOAD_STEP_STAGE_GET_MESH, i, stl.size(), cb_cancel);
is_cancel = cb_cancel; // is_cancel = cb_cancel;
} // }
if (cb_cancel) { // if (cb_cancel) {
model->delete_object(new_object); // model->delete_object(new_object);
shapeTool.reset(nullptr); // shapeTool.reset(nullptr);
application->Close(document); // application->Close(document);
return false; // return false;
} // }
} // }
//
//BBS: maybe mesh is empty from step file. Don't add // //BBS: maybe mesh is empty from step file. Don't add
if (stl[i].stats.number_of_facets > 0) { // if (stl[i].stats.number_of_facets > 0) {
TriangleMesh triangle_mesh; // TriangleMesh triangle_mesh;
triangle_mesh.from_stl(stl[i]); // triangle_mesh.from_stl(stl[i]);
ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh)); // ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh));
new_volume->name = namedSolids[i].name; // new_volume->name = namedSolids[i].name;
new_volume->source.input_file = path; // new_volume->source.input_file = path;
new_volume->source.object_idx = (int)model->objects.size() - 1; // new_volume->source.object_idx = (int)model->objects.size() - 1;
new_volume->source.volume_idx = (int)new_object->volumes.size() - 1; // new_volume->source.volume_idx = (int)new_object->volumes.size() - 1;
} // }
} // }
//
shapeTool.reset(nullptr); // shapeTool.reset(nullptr);
application->Close(document); // application->Close(document);
//
//BBS: no valid shape from the step, delete the new object as well // //BBS: no valid shape from the step, delete the new object as well
if (new_object->volumes.size() == 0) { // if (new_object->volumes.size() == 0) {
model->delete_object(new_object); // model->delete_object(new_object);
return false; // return false;
} // }
//
return true; // return true;
} //}
Step::Step(fs::path path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn): Step::Step(fs::path path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn):
m_stepFn(stepFn), m_stepFn(stepFn),
@ -425,30 +426,257 @@ Step::Step(std::string path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn)
m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc); 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) { if (!StepPreProcessor::isUtf8File(m_path.c_str()) && m_utf8Fn) {
m_utf8Fn(false); m_utf8Fn(false);
return false; return Step_Status::LOAD_ERROR;
}
std::atomic<bool> 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;
} }
STEPCAFControl_Reader reader; }
reader.SetNameMode(true);
IFSelect_ReturnStatus stat = reader.ReadFile(m_path.c_str()); Step::Step_Status Step::mesh(Model* model,
if (stat != IFSelect_RetDone || !reader.Transfer(m_doc)) { bool& is_cancel,
m_app->Close(m_doc); bool isSplitCompound,
return false; double linear_defletion/*=0.003*/,
double angle_defletion/*= 0.5*/)
{
bool task_result = false;
bool cb_cancel = false;
float progress = .0;
std::atomic<int> meshed_solid_num = 0;
std::vector<NamedSolid> 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<double>(iLabel) / (topShapeLength-1);
if (cb_cancel) {
return;
}
getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound);
}
std::vector<stl_file> stl;
stl.resize(namedSolids.size());
tbb::parallel_for(tbb::blocked_range<size_t>(0, namedSolids.size()), [&](const tbb::blocked_range<size_t>& 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<Vec3f> 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<float>();
facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast<float>();
facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast<float>();
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<float>(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<int>(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<int>((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<int>(progress * 10), 20, cb_cancel);
}
}
}
if (cb_cancel) {
if (task) {
if (task->joinable()) {
task->join();
delete task;
}
}
return Step_Status::CANCEL;
}
} }
m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main()); if (task) {
TDF_LabelSequence topLevelShapes; if (task->joinable()) {
m_shape_tool->GetFreeShapes(topLevelShapes); task->join();
unsigned int id{ 1 }; delete task;
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; //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;
}
return Step_Status::MESH_SUCCESS;
} }
void Step::clean_mesh_data() void Step::clean_mesh_data()

View File

@ -88,14 +88,28 @@ private:
class Step class Step
{ {
public: 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(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
Step(std::string 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(double linear_defletion, double angle_defletion);
unsigned int get_triangle_num_tbb(double linear_defletion, double angle_defletion); unsigned int get_triangle_num_tbb(double linear_defletion, double angle_defletion);
void clean_mesh_data(); 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<bool> m_stop_mesh; std::atomic<bool> m_stop_mesh;
void update_process(int load_stage, int current, int total, bool& cancel);
private: private:
std::string m_path; std::string m_path;
ImportStepProgressFn m_stepFn; ImportStepProgressFn m_stepFn;

View File

@ -197,26 +197,34 @@ Model Model::read_from_step(const std::string&
Model model; Model model;
bool result = false; bool result = false;
bool is_cb_cancel = false; bool is_cb_cancel = false;
std::string message; Step::Step_Status status;
Step step_file(input_file); Step step_file(input_file, stepFn);
step_file.load(); status = step_file.load();
if(status != Step::Step_Status::LOAD_SUCCESS) {
goto _finished;
}
if (step_mesh_fn) { if (step_mesh_fn) {
if (step_mesh_fn(step_file, linear_defletion, angle_defletion, is_split_compound) == -1) { 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; Model empty_model;
return empty_model; return empty_model;
} }
} case Step::Step_Status::LOAD_ERROR:
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())
throw Slic3r::RuntimeError(_L("Loading of a model file failed.")); throw Slic3r::RuntimeError(_L("Loading of a model file failed."));
else case Step::Step_Status::MESH_ERROR:
throw Slic3r::RuntimeError(message); throw Slic3r::RuntimeError(_L("Meshing of a model file failed or no valid shape."));
default:
break;
} }
if (model.objects.empty()) if (model.objects.empty())