diff --git a/resources/images/step_mesh_info.svg b/resources/images/step_mesh_info.svg
new file mode 100644
index 0000000000..28f840853a
--- /dev/null
+++ b/resources/images/step_mesh_info.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp
index 4586a7f52d..6b4954a024 100644
--- a/src/OrcaSlicer.cpp
+++ b/src/OrcaSlicer.cpp
@@ -1386,7 +1386,7 @@ int CLI::run(int argc, char **argv)
// BBS: adjust whebackup
//LoadStrategy strategy = LoadStrategy::LoadModel | LoadStrategy::LoadConfig|LoadStrategy::AddDefaultInstances;
//if (load_aux) strategy = strategy | LoadStrategy::LoadAuxiliary;
- model = Model::read_from_file(file, &config, &config_substitutions, strategy, &plate_data_src, &project_presets, &is_bbl_3mf, &file_version, nullptr, nullptr, nullptr, nullptr, nullptr, plate_to_slice);
+ model = Model::read_from_file(file, &config, &config_substitutions, strategy, &plate_data_src, &project_presets, &is_bbl_3mf, &file_version, nullptr, nullptr, nullptr, plate_to_slice);
if (is_bbl_3mf)
{
if (!first_file)
diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp
index 9a09335e97..588d1e0c0a 100644
--- a/src/libslic3r/AppConfig.cpp
+++ b/src/libslic3r/AppConfig.cpp
@@ -411,6 +411,17 @@ void AppConfig::set_defaults()
set_str("print", "timelapse", "1");
}
+ if (get("enable_step_mesh_setting").empty()) {
+ set_bool("enable_step_mesh_setting", true);
+ }
+ if (get("linear_defletion", "angle_defletion").empty()) {
+ set("linear_defletion", "0.003");
+ set("angle_defletion", "0.5");
+ }
+ if (get("is_split_compound").empty()) {
+ set_bool("is_split_compound", false);
+ }
+
// Remove legacy window positions/sizes
erase("app", "main_frame_maximized");
erase("app", "main_frame_pos");
diff --git a/src/libslic3r/Format/STEP.cpp b/src/libslic3r/Format/STEP.cpp
index 45e938d1b6..5105d26776 100644
--- a/src/libslic3r/Format/STEP.cpp
+++ b/src/libslic3r/Format/STEP.cpp
@@ -33,9 +33,8 @@
#include "TopExp_Explorer.hxx"
#include "TopExp_Explorer.hxx"
#include "BRep_Tool.hxx"
-
-const double STEP_TRANS_CHORD_ERROR = 0.003;
-const double STEP_TRANS_ANGLE_RES = 0.5;
+#include "BRepTools.hxx"
+#include
namespace Slic3r {
@@ -166,26 +165,24 @@ 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& namedSolids) {
+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& namedSolids,
+ bool isSplitCompound = false) {
TDF_Label referredLabel{label};
if (shapeTool->IsReference(label))
shapeTool->GetReferredShape(label, referredLabel);
std::string name;
Handle(TDataStd_Name) shapeName;
- if (referredLabel.FindAttribute(TDataStd_Name::GetID(), shapeName))
+ if (referredLabel.FindAttribute(TDataStd_Name::GetID(), shapeName) ||
+ label.FindAttribute(TDataStd_Name::GetID(), shapeName))
name = TCollection_AsciiString(shapeName->Get()).ToCString();
- if (name == "")
+ if (name == "" || !StepPreProcessor::isUtf8(name))
name = std::to_string(id++);
std::string fullName{name};
@@ -193,7 +190,7 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p
TDF_LabelSequence components;
if (shapeTool->GetComponents(referredLabel, components)) {
for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex) {
- getNamedSolids(localLocation, fullName, id, shapeTool, components.Value(compIndex), namedSolids);
+ getNamedSolids(localLocation, fullName, id, shapeTool, components.Value(compIndex), namedSolids, isSplitCompound);
}
} else {
TopoDS_Shape shape;
@@ -204,12 +201,20 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p
int i = 0;
switch (shape_type) {
case TopAbs_COMPOUND:
+ if (!isSplitCompound) {
+ namedSolids.emplace_back(TopoDS::Compound(transform.Shape()), fullName);
+ break;
+ }
case TopAbs_COMPSOLID:
- for (explorer.Init(transform.Shape(), TopAbs_SOLID); explorer.More(); explorer.Next()) {
- i++;
- const TopoDS_Shape& currentShape = explorer.Current();
- namedSolids.emplace_back(TopoDS::Solid(currentShape), fullName + "-SOLID-" + std::to_string(i));
- }
+ if (!isSplitCompound) {
+ namedSolids.emplace_back(TopoDS::CompSolid(transform.Shape()), fullName);
+ } else {
+ for (explorer.Init(transform.Shape(), TopAbs_SOLID); explorer.More(); explorer.Next()) {
+ 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);
@@ -223,7 +228,11 @@ static void getNamedSolids(const TopLoc_Location& location, const std::string& p
}
}
-bool load_step(const char *path, Model *model, bool& is_cancel, ImportStepProgressFn stepFn, StepIsUtf8Fn isUtf8Fn)
+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) {
@@ -271,14 +280,14 @@ bool load_step(const char *path, Model *model, bool& is_cancel, ImportStepProgre
return false;
}
}
- getNamedSolids(TopLoc_Location{}, "", id, shapeTool, topLevelShapes.Value(iLabel), namedSolids);
+ 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, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true);
+ 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;
@@ -324,7 +333,7 @@ bool load_step(const char *path, Model *model, bool& is_cancel, ImportStepProgre
}
// 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);
@@ -351,6 +360,14 @@ bool load_step(const char *path, Model *model, bool& is_cancel, ImportStepProgre
}
});
+ 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);
@@ -395,4 +412,109 @@ bool load_step(const char *path, Model *model, bool& is_cancel, ImportStepProgre
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;
+ try {
+ 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;
+ }
+ }
+ } catch(Exception e) {
+ 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(0, m_name_solids.size()),
+ [&](const tbb::blocked_range& 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
diff --git a/src/libslic3r/Format/STEP.hpp b/src/libslic3r/Format/STEP.hpp
index b86933a346..85c8f655ef 100644
--- a/src/libslic3r/Format/STEP.hpp
+++ b/src/libslic3r/Format/STEP.hpp
@@ -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
+#include
+#include
+#include
+
+namespace fs = boost::filesystem;
namespace Slic3r {
@@ -16,8 +25,25 @@ const int LOAD_STEP_STAGE_UNIT_NUM = 5;
typedef std::function ImportStepProgressFn;
typedef std::function 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, ImportStepProgressFn proFn = nullptr, StepIsUtf8Fn isUtf8Fn = nullptr);
+extern bool load_step(const char *path, Model *model,
+ bool& is_cancel,
+ double linear_defletion = 0.003,
+ double angle_defletion = 0.5,
+ bool isSplitCompound = false,
+ ImportStepProgressFn proFn = nullptr,
+ StepIsUtf8Fn isUtf8Fn = nullptr,
+ long& mesh_face_num = *(new long(-1)));
//BBS: Used to detect what kind of encoded type is used in name field of step
// If is encoded in UTF8, the file don't need to be handled, then return the original path directly.
@@ -36,14 +62,49 @@ class StepPreProcessor {
public:
bool preprocess(const char* path, std::string &output_path);
static bool isUtf8File(const char* path);
-private:
static bool isUtf8(const std::string str);
+private:
static bool isGBK(const std::string str);
static int preNum(const unsigned char byte);
//BBS: default is UTF8 for most step file.
EncodedType m_encode_type = EncodedType::UTF8;
};
+class StepProgressIncdicator : public Message_ProgressIndicator
+{
+public:
+ StepProgressIncdicator(std::atomic& 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& 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 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 m_name_solids;
+};
+
}; // namespace Slic3r
#endif /* slic3r_Format_STEP_hpp_ */
diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp
index dcbf0120b8..fba27b289b 100644
--- a/src/libslic3r/GCode/CoolingBuffer.hpp
+++ b/src/libslic3r/GCode/CoolingBuffer.hpp
@@ -4,6 +4,7 @@
#include "../libslic3r.h"
#include