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 "../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<NamedSolid> 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_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();
}
}
});
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<NamedSolid> 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_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();
// }
// }
// });
//
// 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<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;
}
}
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<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;
}
}
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()

View File

@ -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<bool> m_stop_mesh;
void update_process(int load_stage, int current, int total, bool& cancel);
private:
std::string m_path;
ImportStepProgressFn m_stepFn;

View File

@ -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())