Skip to content

Commit

Permalink
ENH: step mesh operation adjustment
Browse files Browse the repository at this point in the history
1.Put commctrl.h into pch precompilation(OCCT conflicts)

2.Replace input wxWidgets to support loss focus verification(STUDIO-8101)

3.Optimize slider interaction and trigger mesh when push up slider(STUDIO-8099)

4.Optimize step loading method, separate import of step and mesh

5.Fix dialog cancel button logic;

6.mesh tasks into sub-threads to prevent blocking the UI;

JIRA: STUDIO-8101 STUDIO-8099
Change-Id: I50bbb43953a5128f358c6880032d20693531333b
  • Loading branch information
MackBambu authored and lanewei120 committed Oct 15, 2024
1 parent 387dc63 commit ed7ab6b
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 94 deletions.
113 changes: 104 additions & 9 deletions src/libslic3r/Format/STEP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "TopExp_Explorer.hxx"
#include "TopExp_Explorer.hxx"
#include "BRep_Tool.hxx"
#include "BRepTools.hxx"
#include <IMeshTools_Parameters.hxx>


namespace Slic3r {
Expand Down Expand Up @@ -163,13 +165,6 @@ int StepPreProcessor::preNum(const unsigned char byte) {
return num;
}

struct NamedSolid {
NamedSolid(const TopoDS_Shape& s,
const std::string& n) : solid{s}, name{n} {}
const TopoDS_Shape solid;
const std::string name;
};

static void getNamedSolids(const TopLoc_Location& location, const std::string& prefix,
unsigned int& id, const Handle(XCAFDoc_ShapeTool) shapeTool,
const TDF_Label label, std::vector<NamedSolid>& namedSolids) {
Expand Down Expand Up @@ -206,7 +201,7 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p
i++;
const TopoDS_Shape& currentShape = explorer.Current();
namedSolids.emplace_back(TopoDS::Solid(currentShape), fullName + "-SOLID-" + std::to_string(i));
}
}
break;
case TopAbs_SOLID:
namedSolids.emplace_back(TopoDS::Solid(transform.Shape()), fullName);
Expand Down Expand Up @@ -321,7 +316,7 @@ bool load_step(const char *path, Model *model, bool& is_cancel,
}
// BBS: copy triangles
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
Standard_Integer anId[3];
Standard_Integer anId[3] = {};
for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);

Expand Down Expand Up @@ -400,4 +395,104 @@ bool load_step(const char *path, Model *model, bool& is_cancel,
return true;
}

Step::Step(fs::path path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn):
m_stepFn(stepFn),
m_utf8Fn(isUtf8Fn)
{
m_path = path.string();
m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc);
}

Step::Step(std::string path, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn) :
m_path(path),
m_stepFn(stepFn),
m_utf8Fn(isUtf8Fn)
{
m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc);
}

bool Step::load()
{
if (!StepPreProcessor::isUtf8File(m_path.c_str()) && m_utf8Fn) {
m_utf8Fn(false);
return false;
}

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;
}
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;
}

void Step::clean_mesh_data()
{
for (const auto& name_solid : m_name_solids) {
BRepTools::Clean(name_solid.solid);
}
}

unsigned int Step::get_triangle_num(double linear_defletion, double angle_defletion)
{
unsigned int tri_num = 0;
Handle(StepProgressIncdicator) progress = new StepProgressIncdicator(m_stop_mesh);
clean_mesh_data();
IMeshTools_Parameters param;
param.Deflection = linear_defletion;
param.Angle = angle_defletion;
param.InParallel = true;
for (int i = 0; i < m_name_solids.size(); ++i) {
BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, param, progress->Start());
for (TopExp_Explorer anExpSF(m_name_solids[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()) {
tri_num += aTriangulation->NbTriangles();
}
}
if (m_stop_mesh.load()) {
return 0;
}
}
return tri_num;
}

unsigned int Step::get_triangle_num_tbb(double linear_defletion, double angle_defletion)
{
unsigned int tri_num = 0;
clean_mesh_data();
tbb::parallel_for(tbb::blocked_range<size_t>(0, m_name_solids.size()),
[&](const tbb::blocked_range<size_t>& range) {
for (size_t i = range.begin(); i < range.end(); i++) {
unsigned int solids_tri_num = 0;
BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, linear_defletion, false, angle_defletion, true);
for (TopExp_Explorer anExpSF(m_name_solids[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()) {
solids_tri_num += aTriangulation->NbTriangles();
}
}
m_name_solids[i].tri_face_cout = solids_tri_num;
}

});
for (int i = 0; i < m_name_solids.size(); ++i) {
tri_num += m_name_solids[i].tri_face_cout;
}
return tri_num;
}

}; // namespace Slic3r
54 changes: 54 additions & 0 deletions src/libslic3r/Format/STEP.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
#ifndef slic3r_Format_STEP_hpp_
#define slic3r_Format_STEP_hpp_
#include "XCAFDoc_DocumentTool.hxx"
#include "XCAFApp_Application.hxx"
#include "XCAFDoc_ShapeTool.hxx"
#include <boost/filesystem/path.hpp>
#include <boost/filesystem.hpp>
#include <Message_ProgressIndicator.hxx>
#include <atomic>

namespace fs = boost::filesystem;

namespace Slic3r {

Expand All @@ -16,6 +25,16 @@ const int LOAD_STEP_STAGE_UNIT_NUM = 5;
typedef std::function<void(int load_stage, int current, int total, bool& cancel)> ImportStepProgressFn;
typedef std::function<void(bool isUtf8)> StepIsUtf8Fn;

struct NamedSolid
{
NamedSolid(const TopoDS_Shape& s,
const std::string& n) : solid{ s }, name{ n } {
}
const TopoDS_Shape solid;
const std::string name;
int tri_face_cout = 0;
};

//BBS: Load an step file into a provided model.
extern bool load_step(const char *path, Model *model,
bool& is_cancel,
Expand Down Expand Up @@ -50,6 +69,41 @@ class StepPreProcessor {
EncodedType m_encode_type = EncodedType::UTF8;
};

class StepProgressIncdicator : public Message_ProgressIndicator
{
public:
StepProgressIncdicator(std::atomic<bool>& stop_flag) : should_stop(stop_flag){}

Standard_Boolean UserBreak() override { return should_stop.load(); }

void Show(const Message_ProgressScope&, const Standard_Boolean) override {
std::cout << "Progress: " << GetPosition() << "%" << std::endl;
}
private:
std::atomic<bool>& should_stop;
};

class Step
{
public:
Step(fs::path path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
Step(std::string path, ImportStepProgressFn stepFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
bool 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();

std::atomic<bool> m_stop_mesh;
private:
std::string m_path;
ImportStepProgressFn m_stepFn;
StepIsUtf8Fn m_utf8Fn;
Handle(XCAFApp_Application) m_app = XCAFApp_Application::GetApplication();
Handle(TDocStd_Document) m_doc;
Handle(XCAFDoc_ShapeTool) m_shape_tool;
std::vector<NamedSolid> m_name_solids;
};

}; // namespace Slic3r

#endif /* slic3r_Format_STEP_hpp_ */
12 changes: 6 additions & 6 deletions src/libslic3r/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
BBLProject * project,
int plate_id,
ObjImportColorFn objFn,
std::function<int(double&, double&)> step_mesh_fn)
std::function<int(Slic3r::Step&, double&, double&)> step_mesh_fn)
{
Model model;

Expand Down Expand Up @@ -223,15 +223,15 @@ Model Model::read_from_file(const std::string& input_file, DynamicPrintConfig* c
boost::algorithm::iends_with(input_file, ".step")) {
double linear_defletion = 0.003;
double angle_defletion = 0.5;
Step step_file(input_file);
step_file.load();
if (step_mesh_fn) {
if (step_mesh_fn(linear_defletion, angle_defletion) == -1) {
result = false;
goto end;
if (step_mesh_fn(step_file, linear_defletion, angle_defletion) == -1) {
Model empty_model;
return empty_model;
}
}
result = load_step(input_file.c_str(), &model, is_cb_cancel, linear_defletion, angle_defletion, stepFn, stepIsUtf8Fn);
end:
BOOST_LOG_TRIVIAL(info) << "Cancel step mesh dialog";
} else if (boost::algorithm::iends_with(input_file, ".stl"))
result = load_stl(input_file.c_str(), &model, nullptr, stlFn);
else if (boost::algorithm::iends_with(input_file, ".oltp"))
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1596,7 +1596,7 @@ class Model final : public ObjectBase
BBLProject * project = nullptr,
int plate_id = 0,
ObjImportColorFn objFn = nullptr,
std::function<int(double&, double&)> step_mesh_fn = nullptr
std::function<int(Slic3r::Step&, double&, double&)> step_mesh_fn = nullptr
);
// BBS
static bool obj_import_vertex_color_deal(const std::vector<unsigned char> &vertex_filament_ids, const unsigned char &first_extruder_id, Model *model);
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/CameraUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Points CameraUtils::project(const Camera & camera,
return result;
}

Point CameraUtils::project(const Camera &camera, const Vec3d &point)
Slic3r::Point CameraUtils::project(const Camera &camera, const Vec3d &point)
{
// IMPROVE: do it faster when you need it (inspire in project multi point)
return project(camera, std::vector{point}).front();
Expand Down
2 changes: 1 addition & 1 deletion src/slic3r/GUI/CameraUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CameraUtils
/// <returns>projected points by camera into coordinate of camera.
/// x(from left to right), y(from top to bottom)</returns>
static Points project(const Camera& camera, const std::vector<Vec3d> &points);
static Point project(const Camera& camera, const Vec3d &point);
static Slic3r::Point project(const Camera& camera, const Vec3d &point);

/// <summary>
/// Create hull around GLVolume in 2d space of camera
Expand Down
2 changes: 2 additions & 0 deletions src/slic3r/GUI/Gizmos/GLGizmoBrimEars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ class GLGizmoBrimEars : public GLGizmoBase
void find_single();
};

wxDECLARE_EVENT(wxEVT_THREAD_DONE, wxCommandEvent);

} // namespace GUI
} // namespace Slic3r

Expand Down
6 changes: 3 additions & 3 deletions src/slic3r/GUI/Plater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4011,17 +4011,17 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
filament_ids.clear();
}
};
auto step_mesh = [this, &path, &is_user_cancel](double& linear_value, double& angle_value)-> int {
auto step_mesh = [this, &path, &is_user_cancel](Slic3r::Step& file, double& linear_value, double& angle_value)-> int {
if (boost::iends_with(path.string(), ".step") ||
boost::iends_with(path.string(), ".stp")){
StepMeshDialog mesh_dlg(nullptr, path);
StepMeshDialog mesh_dlg(nullptr, file);
if (mesh_dlg.ShowModal() == wxID_OK) {
linear_value = mesh_dlg.get_linear_defletion();
angle_value = mesh_dlg.get_angle_defletion();
return 1;
}
}
is_user_cancel = false;
is_user_cancel = true;
return -1;
};
model = Slic3r::Model:: read_from_file(
Expand Down
Loading

0 comments on commit ed7ab6b

Please sign in to comment.