QIDISlicer1.0.0

This commit is contained in:
sunsets
2023-06-10 10:14:12 +08:00
parent f2e20e1a90
commit b4cd486f2d
3475 changed files with 1973675 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
cmake_minimum_required(VERSION 3.13)
project(OCCTWrapper)
if (APPLE)
# TODO: we need to fix notarization with the separate shared library
add_library(OCCTWrapper STATIC OCCTWrapper.cpp)
else ()
add_library(OCCTWrapper MODULE OCCTWrapper.cpp)
endif ()
set_target_properties(OCCTWrapper
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src"
PREFIX ""
)
include(GenerateExportHeader)
generate_export_header(OCCTWrapper)
find_package(OpenCASCADE 7.6.2 REQUIRED)
set(OCCT_LIBS
TKXDESTEP
TKSTEP
TKSTEP209
TKSTEPAttr
TKSTEPBase
TKXCAF
TKXSBase
TKVCAF
TKCAF
TKLCAF
TKCDF
TKV3d
TKService
TKMesh
TKBO
TKPrim
TKHLR
TKShHealing
TKTopAlgo
TKGeomAlgo
TKBRep
TKGeomBase
TKG3d
TKG2d
TKMath
TKernel
)
slic3r_remap_configs("${OCCT_LIBS}" RelWithDebInfo Release)
target_include_directories(OCCTWrapper PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(OCCTWrapper PUBLIC ${OpenCASCADE_INCLUDE_DIR})
target_link_libraries(OCCTWrapper ${OCCT_LIBS})
include(GNUInstallDirs)
install(TARGETS OCCTWrapper DESTINATION "${CMAKE_INSTALL_BINDIR}")

View File

@@ -0,0 +1,201 @@
#include "OCCTWrapper.hpp"
#include "occtwrapper_export.h"
#include <cassert>
#ifdef _WIN32
#define DIR_SEPARATOR '\\'
#else
#define DIR_SEPARATOR '/'
#endif
#include "STEPCAFControl_Reader.hxx"
#include "BRepMesh_IncrementalMesh.hxx"
#include "XCAFDoc_DocumentTool.hxx"
#include "XCAFDoc_ShapeTool.hxx"
#include "XCAFApp_Application.hxx"
#include "TopoDS_Builder.hxx"
#include "TopoDS.hxx"
#include "TDataStd_Name.hxx"
#include "BRepBuilderAPI_Transform.hxx"
#include "TopExp_Explorer.hxx"
#include "BRep_Tool.hxx"
const double STEP_TRANS_CHORD_ERROR = 0.005;
const double STEP_TRANS_ANGLE_RES = 1;
// const int LOAD_STEP_STAGE_READ_FILE = 0;
// const int LOAD_STEP_STAGE_GET_SOLID = 1;
// const int LOAD_STEP_STAGE_GET_MESH = 2;
namespace Slic3r {
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 Handle(XCAFDoc_ShapeTool) shapeTool,
const TDF_Label label, std::vector<NamedSolid>& namedSolids)
{
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))
name = TCollection_AsciiString(shapeName->Get()).ToCString();
TopLoc_Location localLocation = location * shapeTool->GetLocation(label);
TDF_LabelSequence components;
if (shapeTool->GetComponents(referredLabel, components)) {
for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex) {
getNamedSolids(localLocation, shapeTool, components.Value(compIndex), namedSolids);
}
} else {
TopoDS_Shape shape;
shapeTool->GetShape(referredLabel, shape);
TopAbs_ShapeEnum shape_type = shape.ShapeType();
BRepBuilderAPI_Transform transform(shape, localLocation, Standard_True);
switch (shape_type) {
case TopAbs_COMPOUND:
namedSolids.emplace_back(TopoDS::Compound(transform.Shape()), name);
break;
case TopAbs_COMPSOLID:
namedSolids.emplace_back(TopoDS::CompSolid(transform.Shape()), name);
break;
case TopAbs_SOLID:
namedSolids.emplace_back(TopoDS::Solid(transform.Shape()), name);
break;
default:
break;
}
}
}
extern "C" OCCTWRAPPER_EXPORT bool load_step_internal(const char *path, OCCTResult* res /*BBS:, ImportStepProgressFn proFn*/)
{
try {
//bool cb_cancel = false;
//if (proFn) {
// proFn(LOAD_STEP_STAGE_READ_FILE, 0, 1, cb_cancel);
// if (cb_cancel)
// return false;
//}
std::vector<NamedSolid> namedSolids;
Handle(TDocStd_Document) document;
Handle(XCAFApp_Application) application = XCAFApp_Application::GetApplication();
application->NewDocument(path, 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(path);
if (stat != IFSelect_RetDone || !reader.Transfer(document)) {
application->Close(document);
res->error_str = std::string{"Could not read '"} + path + "'";
return false;
}
Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main());
TDF_LabelSequence topLevelShapes;
shapeTool->GetFreeShapes(topLevelShapes);
Standard_Integer topShapeLength = topLevelShapes.Length() + 1;
for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) {
//if (proFn) {
// proFn(LOAD_STEP_STAGE_GET_SOLID, iLabel, topShapeLength, cb_cancel);
// if (cb_cancel) {
// shapeTool.reset(nullptr);
// application->Close(document);
// return false;
// }
//}
getNamedSolids(TopLoc_Location{}, shapeTool, topLevelShapes.Value(iLabel), namedSolids);
}
// Now the object name. Set it to filename without suffix.
// This will later be changed if only one volume is loaded.
const char *last_slash = strrchr(path, DIR_SEPARATOR);
std::string obj_name((last_slash == nullptr) ? path : last_slash + 1);
res->object_name = obj_name;
for (size_t i = 0; i < namedSolids.size(); ++i) {
//BBS:if (proFn) {
// proFn(LOAD_STEP_STAGE_GET_MESH, i, namedSolids.size(), cb_cancel);
// if (cb_cancel) {
// model->delete_object(new_object);
// shapeTool.reset(nullptr);
// application->Close(document);
// return false;
// }
//}
res->volumes.emplace_back();
auto& vertices = res->volumes.back().vertices;
auto& indices = res->volumes.back().indices;
BRepMesh_IncrementalMesh mesh(namedSolids[i].solid, STEP_TRANS_CHORD_ERROR, false, STEP_TRANS_ANGLE_RES, true);
for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
const int aNodeOffset = int(vertices.size());
const TopoDS_Shape& aFace = anExpSF.Current();
TopLoc_Location aLoc;
Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(TopoDS::Face(aFace), aLoc);
if (aTriangulation.IsNull())
continue;
// First copy vertices (will create duplicates).
gp_Trsf aTrsf = aLoc.Transformation();
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
aPnt.Transform(aTrsf);
vertices.push_back({float(aPnt.X()), float(aPnt.Y()), float(aPnt.Z())});
}
// Now the indices.
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
Standard_Integer anId[3];
aTri.Get(anId[0], anId[1], anId[2]);
if (anOrientation == TopAbs_REVERSED)
std::swap(anId[1], anId[2]);
// Account for the vertices we already have from previous faces.
// anId is 1-based index !
indices.push_back({anId[0] - 1 + aNodeOffset,
anId[1] - 1 + aNodeOffset,
anId[2] - 1 + aNodeOffset});
}
}
res->volumes.back().volume_name = namedSolids[i].name;
if (vertices.empty())
res->volumes.pop_back();
}
shapeTool.reset(nullptr);
application->Close(document);
if (res->volumes.empty())
return false;
} catch (const std::exception& ex) {
res->error_str = ex.what();
return false;
} catch (...) {
res->error_str = "An exception was thrown in load_step_internal.";
return false;
}
return true;
}
}; // namespace Slic3r

View File

@@ -0,0 +1,27 @@
#ifndef occtwrapper_OCCTWrapper_hpp_
#define occtwrapper_OCCTWrapper_hpp_
#include <array>
#include <string>
#include <vector>
namespace Slic3r {
struct OCCTVolume {
std::string volume_name;
std::vector<std::array<float, 3>> vertices;
std::vector<std::array<int, 3>> indices;
};
struct OCCTResult {
std::string error_str;
std::string object_name;
std::vector<OCCTVolume> volumes;
};
using LoadStepFn = bool (*)(const char *path, OCCTResult* occt_result);
}; // namespace Slic3r
#endif // occtwrapper_OCCTWrapper_hpp_