OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::Step Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Format/STEP.hpp>

Collaboration diagram for Slic3r::Step:

Public Types

enum class  Step_Status {
  LOAD_SUCCESS , LOAD_ERROR , CANCEL , MESH_SUCCESS ,
  MESH_ERROR
}

Public Member Functions

 Step (boost::filesystem::path path, ImportStepProgressFn stepFn=nullptr, StepIsUtf8Fn isUtf8Fn=nullptr)
 Step (std::string path, ImportStepProgressFn stepFn=nullptr, StepIsUtf8Fn isUtf8Fn=nullptr)
 ~Step ()
Step_Status load ()
unsigned int get_triangle_num (double linear_deflection, double angle_deflection)
unsigned int get_triangle_num_tbb (double linear_deflection, double angle_deflection)
void clean_mesh_data ()
Step_Status mesh (Model *model, bool &is_cancel, bool isSplitCompound, double linear_deflection=0.003, double angle_deflection=0.5)
void update_process (int load_stage, int current, int total, bool &cancel)

Public Attributes

std::atomic< bool > m_stop_mesh {false}

Private Member Functions

 Handle (XCAFApp_Application) m_app
 Handle (TDocStd_Document) m_doc
 Handle (XCAFDoc_ShapeTool) m_shape_tool

Private Attributes

std::string m_path
ImportStepProgressFn m_stepFn
StepIsUtf8Fn m_utf8Fn
std::vector< NamedSolid > m_name_solids

Detailed Description

Member Enumeration Documentation

◆ Step_Status

enum class Slic3r::Step::Step_Status
strong
Enumerator
LOAD_SUCCESS 
LOAD_ERROR 
CANCEL 
MESH_SUCCESS 
MESH_ERROR 
99 {
100 LOAD_SUCCESS,
101 LOAD_ERROR,
102 CANCEL,
103 MESH_SUCCESS,
104 MESH_ERROR
105 };

Constructor & Destructor Documentation

◆ Step() [1/2]

Slic3r::Step::Step ( boost::filesystem::path path,
ImportStepProgressFn stepFn = nullptr,
StepIsUtf8Fn isUtf8Fn = nullptr )

Referenced by Step().

Here is the caller graph for this function:

◆ Step() [2/2]

Slic3r::Step::Step ( std::string path,
ImportStepProgressFn stepFn = nullptr,
StepIsUtf8Fn isUtf8Fn = nullptr )
469 :
470 m_path(path),
471 m_stepFn(stepFn),
472 m_utf8Fn(isUtf8Fn)
473{
474 m_app->NewDocument(TCollection_ExtendedString("BinXCAF"), m_doc);
475}
ImportStepProgressFn m_stepFn
Definition STEP.hpp:123
StepIsUtf8Fn m_utf8Fn
Definition STEP.hpp:124
std::string m_path
Definition STEP.hpp:122

References Step(), m_path, m_stepFn, and m_utf8Fn.

Here is the call graph for this function:

◆ ~Step()

Slic3r::Step::~Step ( )
478{
479 m_app->Close(m_doc);
480}

Member Function Documentation

◆ clean_mesh_data()

void Slic3r::Step::clean_mesh_data ( )
731{
732 for (const auto& name_solid : m_name_solids) {
733 BRepTools::Clean(name_solid.solid);
734 }
735}
std::vector< NamedSolid > m_name_solids
Definition STEP.hpp:128

References clean_mesh_data(), and m_name_solids.

Referenced by clean_mesh_data(), get_triangle_num(), and get_triangle_num_tbb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_triangle_num()

unsigned int Slic3r::Step::get_triangle_num ( double linear_deflection,
double angle_deflection )
738{
739 unsigned int tri_num = 0;
740 try {
741 Handle(StepProgressIncdicator) progress = new StepProgressIncdicator(m_stop_mesh);
743 IMeshTools_Parameters param;
744 param.Deflection = linear_deflection;
745 param.Angle = angle_deflection;
746 param.InParallel = true;
747 for (int i = 0; i < m_name_solids.size(); ++i) {
748 BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, param, progress->Start());
749 for (TopExp_Explorer anExpSF(m_name_solids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
750 TopLoc_Location aLoc;
751 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);
752 if (!aTriangulation.IsNull()) {
753 tri_num += aTriangulation->NbTriangles();
754 }
755 }
756 if (m_stop_mesh.load()) {
757 return 0;
758 }
759 }
760 } catch(const Exception &) {
761 return 0;
762 }
763
764 return tri_num;
765}
Handle(XCAFApp_Application) m_app
void clean_mesh_data()
Definition STEP.cpp:730
std::atomic< bool > m_stop_mesh
Definition STEP.hpp:119
Step_Status mesh(Model *model, bool &is_cancel, bool isSplitCompound, double linear_deflection=0.003, double angle_deflection=0.5)
Definition STEP.cpp:556

References clean_mesh_data(), get_triangle_num(), Handle(), m_name_solids, m_stop_mesh, and mesh().

Referenced by get_triangle_num().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_triangle_num_tbb()

unsigned int Slic3r::Step::get_triangle_num_tbb ( double linear_deflection,
double angle_deflection )
768{
769 unsigned int tri_num = 0;
771 tbb::parallel_for(tbb::blocked_range<size_t>(0, m_name_solids.size()),
772 [&](const tbb::blocked_range<size_t>& range) {
773 for (size_t i = range.begin(); i < range.end(); i++) {
774 unsigned int solids_tri_num = 0;
775 BRepMesh_IncrementalMesh mesh(m_name_solids[i].solid, linear_deflection, false, angle_deflection, true);
776 for (TopExp_Explorer anExpSF(m_name_solids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
777 TopLoc_Location aLoc;
778 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);
779 if (!aTriangulation.IsNull()) {
780 solids_tri_num += aTriangulation->NbTriangles();
781 }
782 }
783 m_name_solids[i].tri_face_cout = solids_tri_num;
784 }
785
786 });
787 for (int i = 0; i < m_name_solids.size(); ++i) {
788 tri_num += m_name_solids[i].tri_face_cout;
789 }
790 return tri_num;
791}
auto range(Cont &&cont)
Definition libslic3r.h:405

References clean_mesh_data(), get_triangle_num_tbb(), m_name_solids, and Slic3r::range().

Referenced by get_triangle_num_tbb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Handle() [1/3]

Slic3r::Step::Handle ( TDocStd_Document )
private

◆ Handle() [2/3]

Slic3r::Step::Handle ( XCAFApp_Application )
private

Referenced by get_triangle_num(), and load().

Here is the caller graph for this function:

◆ Handle() [3/3]

Slic3r::Step::Handle ( XCAFDoc_ShapeTool )
private

◆ load()

Step::Step_Status Slic3r::Step::load ( )
490{
492 m_utf8Fn(false);
494 }
495 std::atomic<bool> stop_load_flag = false;
496 Handle(StepProgressIncdicator) incdicator = new StepProgressIncdicator(stop_load_flag);
497 bool task_result = false;
498 bool cb_cancel = false;
499 int progress = 0;
500 bool load_result = false;
501 auto task = new boost::thread(Slic3r::create_thread([&]() -> void {
502
503 STEPCAFControl_Reader reader;
504 reader.SetNameMode(true);
505 IFSelect_ReturnStatus stat = reader.ReadFile(m_path.c_str());
506 if (cb_cancel) return;
507 progress = 3;
508 if (stat != IFSelect_RetDone || !reader.Transfer(m_doc, incdicator->Start())) {
509 load_result = false;
510 task_result = true;
511 return;
512 }
513 if (cb_cancel) return;
514 progress = 6;
515 m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main());
516 NCollection_Sequence<TDF_Label> topLevelShapes;
517 m_shape_tool->GetFreeShapes(topLevelShapes);
518 unsigned int id{ 1 };
519 int topShapeLength = topLevelShapes.Length() + 1;
520 for (int iLabel = 1; iLabel < topShapeLength; ++iLabel) {
521 if (cb_cancel) return;
522 getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids);
523 }
524 progress = 10;
525 load_result = true;
526 task_result = true;
527 }));
528 while (!task_result) {
529 boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
530 update_process(LOAD_STEP_STAGE_READ_FILE, progress, 10, cb_cancel);
531 if (cb_cancel) {
532 stop_load_flag.store(true);
533 if (task) {
534 if (task->joinable()) {
535 task->join();
536 delete task;
537 }
538 }
539 return Step_Status::CANCEL;
540 }
541 }
542 if (task){
543 if (task->joinable()) {
544 task->join();
545 delete task;
546 }
547 }
548 if (load_result) {
550 }else {
552 }
553
554}
static bool isUtf8File(const char *path)
Definition STEP.cpp:116
void update_process(int load_stage, int current, int total, bool &cancel)
Definition STEP.cpp:482
@ CANCEL
Definition STEP.hpp:102
@ LOAD_SUCCESS
Definition STEP.hpp:100
@ LOAD_ERROR
Definition STEP.hpp:101
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, bool isSplitCompound=false)
Definition STEP.cpp:204
boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn)
Definition Thread.hpp:48
const int LOAD_STEP_STAGE_READ_FILE
Definition STEP.hpp:28

References CANCEL, Slic3r::create_thread(), Slic3r::getNamedSolids(), Handle(), Slic3r::StepPreProcessor::isUtf8File(), LOAD_ERROR, Slic3r::LOAD_STEP_STAGE_READ_FILE, LOAD_SUCCESS, m_name_solids, m_path, m_utf8Fn, and update_process().

Referenced by Slic3r::Model::read_from_step().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mesh()

Step::Step_Status Slic3r::Step::mesh ( Model * model,
bool & is_cancel,
bool isSplitCompound,
double linear_deflection = 0.003,
double angle_deflection = 0.5 )
562{
563 bool task_result = false;
564 bool cb_cancel = false;
565 float progress = .0;
566 std::atomic<int> meshed_solid_num = 0;
567 std::vector<NamedSolid> namedSolids;
568 float progress_2 = .0;
569 ModelObject* new_object = model->add_object();
570 const char* last_slash = strrchr(m_path.c_str(), DIR_SEPARATOR);
571 new_object->name.assign((last_slash == nullptr) ? m_path.c_str() : last_slash + 1);
572 new_object->input_file = m_path.c_str();
573
574 auto task = new boost::thread(Slic3r::create_thread([&]() -> void {
575 NCollection_Sequence<TDF_Label> topLevelShapes;
576 m_shape_tool->GetFreeShapes(topLevelShapes);
577 unsigned int id{ 1 };
578 int topShapeLength = topLevelShapes.Length() + 1;
579
580 for (int iLabel = 1; iLabel < topShapeLength; ++iLabel) {
581 progress = static_cast<double>(iLabel) / (topShapeLength-1);
582 if (cb_cancel) {
583 return;
584 }
585 getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), namedSolids, isSplitCompound);
586 }
587
588 std::vector<stl_file> stl;
589 stl.resize(namedSolids.size());
590 tbb::parallel_for(tbb::blocked_range<size_t>(0, namedSolids.size()), [&](const tbb::blocked_range<size_t>& range) {
591 for (size_t i = range.begin(); i < range.end(); i++) {
592 BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, linear_deflection, false, angle_deflection, true);
593 // BBS: calculate total number of the nodes and triangles
594 int aNbNodes = 0;
595 int aNbTriangles = 0;
596 for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
597 TopLoc_Location aLoc;
598 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(anExpSF.Current()), aLoc);
599 if (!aTriangulation.IsNull()) {
600 aNbNodes += aTriangulation->NbNodes();
601 aNbTriangles += aTriangulation->NbTriangles();
602 }
603 }
604
605 if (aNbTriangles == 0 || aNbNodes == 0)
606 // BBS: No triangulation on the shape.
607 continue;
608
609 stl[i].stats.type = inmemory;
610 stl[i].stats.number_of_facets = (uint32_t)aNbTriangles;
611 stl[i].stats.original_num_facets = stl[i].stats.number_of_facets;
612 stl_allocate(&stl[i]);
613
614 std::vector<Vec3f> points;
615 points.reserve(aNbNodes);
616 // BBS: count faces missing triangulation
617 int aNbFacesNoTri = 0;
618 // BBS: fill temporary triangulation
619 int aNodeOffset = 0;
620 int aTriangleOffet = 0;
621 for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
622 const TopoDS_Shape& aFace = anExpSF.Current();
623 TopLoc_Location aLoc;
624 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc);
625 if (aTriangulation.IsNull()) {
626 ++aNbFacesNoTri;
627 continue;
628 }
629 // BBS: copy nodes
630 gp_Trsf aTrsf = aLoc.Transformation();
631 for (int aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
632 gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
633 aPnt.Transform(aTrsf);
634 points.emplace_back(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()));
635 }
636 // BBS: copy triangles
637 const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
638 int anId[3] = {};
639 for (int aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
640 Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
641
642 aTri.Get(anId[0], anId[1], anId[2]);
643 if (anOrientation == TopAbs_REVERSED)
644 std::swap(anId[1], anId[2]);
645 // BBS: save triangles facets
646 stl_facet facet;
647 facet.vertex[0] = points[anId[0] + aNodeOffset - 1].cast<float>();
648 facet.vertex[1] = points[anId[1] + aNodeOffset - 1].cast<float>();
649 facet.vertex[2] = points[anId[2] + aNodeOffset - 1].cast<float>();
650 facet.extra[0] = 0;
651 facet.extra[1] = 0;
652 stl_normal normal;
653 stl_calculate_normal(normal, &facet);
654 stl_normalize_vector(normal);
655 facet.normal = normal;
656 stl[i].facet_start[aTriangleOffet + aTriIter - 1] = facet;
657 }
658
659 aNodeOffset += aTriangulation->NbNodes();
660 aTriangleOffet += aTriangulation->NbTriangles();
661 }
662 meshed_solid_num.fetch_add(1, std::memory_order_relaxed);
663 }
664 });
665
666
667 for (size_t i = 0; i < stl.size(); i++) {
668 progress_2 = static_cast<float>(i) / stl.size();
669 if (cb_cancel)
670 return;
671
672 //BBS: maybe mesh is empty from step file. Don't add
673 if (stl[i].stats.number_of_facets > 0) {
674 TriangleMesh triangle_mesh;
675 triangle_mesh.from_stl(stl[i]);
676 ModelVolume* new_volume = new_object->add_volume(std::move(triangle_mesh));
677 new_volume->name = namedSolids[i].name;
678 new_volume->source.input_file = m_path.c_str();
679 new_volume->source.object_idx = (int)model->objects.size() - 1;
680 new_volume->source.volume_idx = (int)new_object->volumes.size() - 1;
681 }
682 }
683 task_result = true;
684 }));
685
686 while (!task_result) {
687 boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
688 if (progress_2 > 0) {
689 // third progress
690 update_process(LOAD_STEP_STAGE_GET_MESH, static_cast<int>(progress_2 * 100), 100, cb_cancel);
691 }else {
692 if (meshed_solid_num.load()) {
693 // second progress
694 int meshed_solid = meshed_solid_num.load();
695 update_process(LOAD_STEP_STAGE_GET_SOLID, static_cast<int>((float)meshed_solid / namedSolids.size() * 10) + 10, 20, cb_cancel);
696 } else {
697 if (progress > 0) {
698 // first progress
699 update_process(LOAD_STEP_STAGE_GET_SOLID, static_cast<int>(progress * 10), 20, cb_cancel);
700 }
701 }
702 }
703
704
705 if (cb_cancel) {
706 if (task) {
707 if (task->joinable()) {
708 task->join();
709 delete task;
710 }
711 }
712 return Step_Status::CANCEL;
713 }
714 }
715 if (task) {
716 if (task->joinable()) {
717 task->join();
718 delete task;
719 }
720 }
721
722 //BBS: no valid shape from the step, delete the new object as well
723 if (new_object->volumes.size() == 0) {
724 model->delete_object(new_object);
726 }
728}
#define DIR_SEPARATOR
Definition DRC.cpp:34
@ MESH_SUCCESS
Definition STEP.hpp:103
@ MESH_ERROR
Definition STEP.hpp:104
const int LOAD_STEP_STAGE_GET_MESH
Definition STEP.hpp:30
const int LOAD_STEP_STAGE_GET_SOLID
Definition STEP.hpp:29

References Slic3r::Model::add_object(), Slic3r::ModelObject::add_volume(), Slic3r::create_thread(), DIR_SEPARATOR, Slic3r::TriangleMesh::from_stl(), Slic3r::getNamedSolids(), Slic3r::ModelObject::input_file, Slic3r::ModelVolume::Source::input_file, m_path, Slic3r::ModelObject::name, Slic3r::ModelVolume::name, Slic3r::ModelVolume::Source::object_idx, Slic3r::Model::objects, Slic3r::range(), Slic3r::ModelVolume::source, Slic3r::ModelVolume::Source::volume_idx, and Slic3r::ModelObject::volumes.

Referenced by get_triangle_num(), and Slic3r::Model::read_from_step().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_process()

void Slic3r::Step::update_process ( int load_stage,
int current,
int total,
bool & cancel )
483{
484 if (m_stepFn) {
485 m_stepFn(load_stage, current, total, cancel);
486 }
487}

References m_stepFn.

Referenced by load().

Here is the caller graph for this function:

Member Data Documentation

◆ m_name_solids

std::vector<NamedSolid> Slic3r::Step::m_name_solids
private

◆ m_path

std::string Slic3r::Step::m_path
private

Referenced by Step(), load(), and mesh().

◆ m_stepFn

ImportStepProgressFn Slic3r::Step::m_stepFn
private

Referenced by Step(), and update_process().

◆ m_stop_mesh

std::atomic<bool> Slic3r::Step::m_stop_mesh {false}
119{false};

Referenced by get_triangle_num().

◆ m_utf8Fn

StepIsUtf8Fn Slic3r::Step::m_utf8Fn
private

Referenced by Step(), and load().


The documentation for this class was generated from the following files:
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Format/STEP.hpp
  • /home/runner/work/OrcaSlicer/OrcaSlicer/src/libslic3r/Format/STEP.cpp