mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-22 06:41:01 +00:00
build: update OCCT to 8.0.1 (faster STEP and Design tab, Windows STEP crash fix) (#16089)
This commit is contained in:
1 parent
0fd04ff07c
commit
78a4f2867c
22 files changed
+1665
-476
No files matched your search
@@ -37,10 +37,9 @@
|
||||
#include <cstdint>
|
||||
#include <cereal/cereal.hpp>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <BRepPrimAPI_MakeCylinder.hxx>
|
||||
#include <BRepPrimAPI_MakeCone.hxx>
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepPrimAPI_MakeRevol.hxx>
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
@@ -53,7 +52,7 @@
|
||||
#include <Geom_ConicalSurface.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <GeomAbs_Shape.hxx> // SurfaceFill: GeomAbs_C0
|
||||
#include <GCE2d_MakeSegment.hxx>
|
||||
#include <GC_MakeSegment2d.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopAbs.hxx>
|
||||
@@ -105,7 +104,7 @@ static TopoDS_Wire make_helix_wire(const gp_Ax3& axis, double radius,
|
||||
// In the surface (u,v) parametrization u is the angle, v the axial height.
|
||||
gp_Pnt2d p0(0.0, 0.0);
|
||||
gp_Pnt2d p1(2.0 * M_PI * turns, height);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GCE2d_MakeSegment(p0, p1);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GC_MakeSegment2d(p0, p1);
|
||||
TopoDS_Edge e = BRepBuilderAPI_MakeEdge(seg, cyl).Edge();
|
||||
BRepLib::BuildCurves3d(e);
|
||||
return BRepBuilderAPI_MakeWire(e).Wire();
|
||||
@@ -147,14 +146,14 @@ static TopoDS_Wire make_helix_spine(const CadFeature& f, std::string& err)
|
||||
double u1 = f.helix_left_handed ? -2.0 * M_PI * turns : 2.0 * M_PI * turns;
|
||||
gp_Pnt2d p0(0.0, 0.0);
|
||||
gp_Pnt2d p1(u1, H);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GCE2d_MakeSegment(p0, p1);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GC_MakeSegment2d(p0, p1);
|
||||
e = BRepBuilderAPI_MakeEdge(seg, cone).Edge();
|
||||
} else {
|
||||
Handle(Geom_CylindricalSurface) cyl = new Geom_CylindricalSurface(ax3, R);
|
||||
double u1 = f.helix_left_handed ? -2.0 * M_PI * turns : 2.0 * M_PI * turns;
|
||||
gp_Pnt2d p0(0.0, 0.0);
|
||||
gp_Pnt2d p1(u1, H);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GCE2d_MakeSegment(p0, p1);
|
||||
Handle(Geom2d_TrimmedCurve) seg = GC_MakeSegment2d(p0, p1);
|
||||
e = BRepBuilderAPI_MakeEdge(seg, cyl).Edge();
|
||||
}
|
||||
BRepLib::BuildCurves3d(e);
|
||||
@@ -193,7 +192,7 @@ static TopoDS_Wire make_thread_profile(const gp_Pnt& origin, const gp_Dir& xdir,
|
||||
gp_Pnt top (origin.XYZ() + (vx * inner).XYZ() + (vz * ( half)).XYZ());
|
||||
gp_Pnt bot (origin.XYZ() + (vx * inner).XYZ() + (vz * (-half)).XYZ());
|
||||
gp_Pnt apex(origin.XYZ() + (vx * crest).XYZ());
|
||||
BRepBuilderAPI_MakePolygon poly(top, bot, apex, Standard_True);
|
||||
BRepBuilderAPI_MakePolygon poly(top, bot, apex, true);
|
||||
return poly.Wire(); // closed triangle, swept by MakePipeShell with a fixed binormal
|
||||
}
|
||||
|
||||
@@ -2368,10 +2367,12 @@ void CadDocument::apply_feature(TopoDS_Shape& result, bool& have_body,
|
||||
TopoDS_Wire wire = build_sketch_wire(sk);
|
||||
if (wire.IsNull()) throw std::runtime_error("surface-extrude: empty profile");
|
||||
gp_Dir nrm(sk.plane.normal.x(), sk.plane.normal.y(), sk.plane.normal.z());
|
||||
gp_Vec v(nrm.XYZ() * f.distance);
|
||||
TopoDS_Shape shell = BRepPrimAPI_MakePrism(wire, v, false, true).Shape();
|
||||
if (shell.IsNull()) throw std::runtime_error("surface-extrude: prism failed");
|
||||
result = shell; have_body = true;
|
||||
try {
|
||||
result = SketchEngine::make_prism(wire, gp_Vec(nrm.XYZ() * f.distance));
|
||||
} catch (const std::exception& e) {
|
||||
throw std::runtime_error(std::string("surface-extrude: ") + (*e.what() ? e.what() : "prism failed"));
|
||||
}
|
||||
have_body = true;
|
||||
break;
|
||||
}
|
||||
case CadFeatureType::SurfaceRevolve: {
|
||||
@@ -2584,7 +2585,7 @@ void CadDocument::apply_feature(TopoDS_Shape& result, bool& have_body,
|
||||
double h = f.rib_thickness * 0.5;
|
||||
Vec2d q0 = a + perp*h, q1 = b + perp*h, q2 = b - perp*h, q3 = a - perp*h;
|
||||
auto w3 = [&](const Vec2d& p){ Vec3d w = pl.to_world(p); return gp_Pnt(w.x(),w.y(),w.z()); };
|
||||
BRepBuilderAPI_MakePolygon poly(w3(q0), w3(q1), w3(q2), w3(q3), Standard_True);
|
||||
BRepBuilderAPI_MakePolygon poly(w3(q0), w3(q1), w3(q2), w3(q3), true);
|
||||
if (!poly.IsDone()) throw std::runtime_error("rib: profile failed");
|
||||
TopoDS_Shape wall = SketchEngine::make_extrude(poly.Wire(), pl, f.rib_depth, false, 0.0);
|
||||
if (wall.IsNull()) throw std::runtime_error("rib: extrude failed");
|
||||
@@ -2746,7 +2747,7 @@ void CadDocument::apply_feature(TopoDS_Shape& result, bool& have_body,
|
||||
if (!have_body) throw std::runtime_error("shell needs a body");
|
||||
// Hollow the body to a wall thickness; the picked face (if any) is removed so the
|
||||
// shell is open there. MakeThickSolidByJoin with a NEGATIVE offset shells inward.
|
||||
TopTools_ListOfShape remove;
|
||||
NCollection_List<TopoDS_Shape> remove;
|
||||
if (f.shell_face >= 0) {
|
||||
TopoDS_Face fc = GeometryEngine::face_by_index(result, f.shell_face);
|
||||
if (!fc.IsNull()) remove.Append(fc);
|
||||
@@ -2769,7 +2770,7 @@ void CadDocument::apply_feature(TopoDS_Shape& result, bool& have_body,
|
||||
// ponytail: neutral plane / pull direction fixed to world up; pick-based neutral plane
|
||||
// deferred (same as the datum-plane pick types, dgv).
|
||||
Bnd_Box bb; BRepBndLib::Add(result, bb);
|
||||
Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
double xmin, ymin, zmin, xmax, ymax, zmax;
|
||||
bb.Get(xmin, ymin, zmin, xmax, ymax, zmax);
|
||||
gp_Dir pull(0, 0, 1);
|
||||
gp_Pln neutral(gp_Pnt(0, 0, zmin), pull);
|
||||
@@ -2850,7 +2851,7 @@ void CadDocument::apply_boolean(std::vector<CadBody>& bodies, const CadFeature&
|
||||
const TopoDS_Shape B = bodies[tool].shape; // tool, consumed unless kept
|
||||
if (A.IsNull() || B.IsNull()) return;
|
||||
|
||||
TopTools_ListOfShape args, tools;
|
||||
NCollection_List<TopoDS_Shape> args, tools;
|
||||
args.Append(A);
|
||||
tools.Append(B);
|
||||
auto run = [&](BRepAlgoAPI_BooleanOperation& bop) -> TopoDS_Shape {
|
||||
@@ -3091,7 +3092,7 @@ void CadDocument::apply_thicken_surface(std::vector<CadBody>& bodies, const CadF
|
||||
int n_faces = 0;
|
||||
for (TopExp_Explorer fe(sheet, TopAbs_FACE); fe.More(); fe.Next()) ++n_faces;
|
||||
|
||||
TopTools_ListOfShape caps;
|
||||
NCollection_List<TopoDS_Shape> caps;
|
||||
if (n_faces > 1) {
|
||||
ShapeAnalysis_FreeBounds fb(sheet);
|
||||
for (TopExp_Explorer we(fb.GetClosedWires(), TopAbs_WIRE); we.More(); we.Next()) {
|
||||
@@ -3113,7 +3114,7 @@ void CadDocument::apply_thicken_surface(std::vector<CadBody>& bodies, const CadF
|
||||
} else {
|
||||
BRepBuilderAPI_Sewing sewer(1.0e-3);
|
||||
sewer.Add(sheet);
|
||||
for (TopTools_ListIteratorOfListOfShape it(caps); it.More(); it.Next())
|
||||
for (NCollection_List<TopoDS_Shape>::Iterator it(caps); it.More(); it.Next())
|
||||
sewer.Add(it.Value());
|
||||
sewer.Perform();
|
||||
|
||||
@@ -3674,13 +3675,8 @@ bool CadDocument::recompute()
|
||||
if (b.source_feature < 0)
|
||||
b.source_feature = int(fi);
|
||||
}
|
||||
} catch (const Standard_Failure& e) {
|
||||
// OCCT raises Standard_Failure (NOT a std::exception) — must be caught
|
||||
// here or it escapes the event handler and terminates the app.
|
||||
error = e.GetMessageString() ? e.GetMessageString() : "OCCT operation failed";
|
||||
return false;
|
||||
} catch (const std::exception& e) {
|
||||
error = e.what();
|
||||
error = *e.what() ? e.what() : "OCCT operation failed";
|
||||
return false;
|
||||
} catch (...) {
|
||||
error = "unknown geometry error";
|
||||
@@ -3782,11 +3778,8 @@ bool CadDocument::preview(const CadFeature& candidate, TriangleMesh& out_mesh,
|
||||
std::vector<CadBody> tmp = bodies; // start from the current committed bodies
|
||||
try {
|
||||
route_feature(tmp, candidate); // candidate may append a new body or mutate one
|
||||
} catch (const Standard_Failure& e) {
|
||||
err = e.GetMessageString() ? e.GetMessageString() : "OCCT operation failed";
|
||||
return false;
|
||||
} catch (const std::exception& e) {
|
||||
err = e.what();
|
||||
err = *e.what() ? e.what() : "OCCT operation failed";
|
||||
return false;
|
||||
} catch (...) {
|
||||
err = "unknown geometry error";
|
||||
@@ -3986,13 +3979,9 @@ bool CadDocument::deserialize_recipe(const std::string& blob)
|
||||
error = "saved with an older version of the Design tab (format v"
|
||||
+ std::to_string(v) + "); this project cannot be opened by this build";
|
||||
return false;
|
||||
} catch (const Standard_Failure& e) {
|
||||
const char* what = e.GetMessageString();
|
||||
error = std::string("CAD data could not be read")
|
||||
+ (what && *what ? ": " + std::string(what) : "");
|
||||
return false;
|
||||
} catch (const std::exception& e) {
|
||||
error = std::string("CAD data could not be read: ") + e.what();
|
||||
error = std::string("CAD data could not be read")
|
||||
+ (*e.what() ? ": " + std::string(e.what()) : "");
|
||||
return false;
|
||||
} catch (...) {
|
||||
error = "CAD data could not be read";
|
||||
@@ -4034,11 +4023,8 @@ bool CadDocument::export_step(const std::string& path,
|
||||
err = "cannot write STEP file";
|
||||
return false;
|
||||
}
|
||||
} catch (const Standard_Failure& e) {
|
||||
err = e.GetMessageString() ? e.GetMessageString() : "OCCT failed to write STEP";
|
||||
return false;
|
||||
} catch (const std::exception& e) {
|
||||
err = e.what();
|
||||
err = *e.what() ? e.what() : "OCCT failed to write STEP";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -4109,8 +4095,7 @@ std::vector<CadDocument::Interference> CadDocument::check_interference(double mi
|
||||
if (bodies[j].shape.IsNull() || is_sheet_shape(bodies[j].shape)) continue;
|
||||
|
||||
double v = 0;
|
||||
// A boolean that blows up on one pair must not lose the report for the others,
|
||||
// and OCCT signals those as Standard_Failure, which is NOT a std::exception.
|
||||
// A boolean that fails on one pair must not lose the report for the others.
|
||||
try {
|
||||
BRepAlgoAPI_Common common(bodies[i].shape, bodies[j].shape);
|
||||
common.Build();
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopTools.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_ShapeMapHasher.hxx>
|
||||
#include <NCollection_IndexedDataMap.hxx>
|
||||
#include <NCollection_IndexedMap.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
@@ -62,6 +63,8 @@
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
using ShapeIndexMap = NCollection_IndexedMap<TopoDS_Shape, TopTools_ShapeMapHasher>;
|
||||
|
||||
// ---- STEP import (B-rep, not mesh) ----
|
||||
std::vector<TopoDS_Shape> GeometryEngine::read_step_solids(const std::string& path, std::string& err)
|
||||
{
|
||||
@@ -82,7 +85,7 @@ std::vector<TopoDS_Shape> GeometryEngine::read_step_solids(const std::string& pa
|
||||
if (out.empty())
|
||||
out.push_back(shape);
|
||||
} catch (const Standard_Failure& e) {
|
||||
err = e.GetMessageString() ? e.GetMessageString() : "OCCT failed to read STEP";
|
||||
err = *e.what() ? e.what() : "OCCT failed to read STEP";
|
||||
out.clear();
|
||||
}
|
||||
return out;
|
||||
@@ -299,13 +302,13 @@ std::vector<TopoDS_Edge> GeometryEngine::collect_edges(const TopoDS_Shape& solid
|
||||
}
|
||||
|
||||
// Build edge-to-face map once
|
||||
TopTools_IndexedDataMapOfShapeListOfShape edgeFaceMap;
|
||||
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher> edgeFaceMap;
|
||||
TopExp::MapShapesAndAncestors(solid, TopAbs_EDGE, TopAbs_FACE, edgeFaceMap);
|
||||
|
||||
for (TopExp_Explorer edgeExp(solid, TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(edgeExp.Current());
|
||||
if (!edgeFaceMap.Contains(edge)) continue;
|
||||
const TopTools_ListOfShape& faces = edgeFaceMap.FindFromKey(edge);
|
||||
const NCollection_List<TopoDS_Shape>& faces = edgeFaceMap.FindFromKey(edge);
|
||||
|
||||
bool include = false;
|
||||
for (auto it = faces.begin(); it != faces.end(); ++it) {
|
||||
@@ -569,7 +572,7 @@ std::vector<TopoDS_Face> GeometryEngine::faces_of(const TopoDS_Shape& shape)
|
||||
|
||||
std::vector<TopoDS_Edge> GeometryEngine::edges_of(const TopoDS_Shape& shape)
|
||||
{
|
||||
TopTools_IndexedMapOfShape map;
|
||||
ShapeIndexMap map;
|
||||
TopExp::MapShapes(shape, TopAbs_EDGE, map); // same order as edge_by_index
|
||||
std::vector<TopoDS_Edge> out;
|
||||
out.reserve(map.Extent());
|
||||
@@ -581,7 +584,7 @@ std::vector<TopoDS_Edge> GeometryEngine::edges_of(const TopoDS_Shape& shape)
|
||||
std::vector<TopoDS_Edge> GeometryEngine::edges_of_face(const TopoDS_Face& face)
|
||||
{
|
||||
std::vector<TopoDS_Edge> result;
|
||||
TopTools_IndexedMapOfShape map;
|
||||
ShapeIndexMap map;
|
||||
TopExp::MapShapes(face, TopAbs_EDGE, map);
|
||||
for (int i = 1; i <= map.Extent(); ++i)
|
||||
result.push_back(TopoDS::Edge(map(i)));
|
||||
@@ -704,14 +707,14 @@ bool GeometryEngine::face_plane_bounds(const TopoDS_Face& face, const Vec3d& ori
|
||||
|
||||
int GeometryEngine::edge_count(const TopoDS_Shape& shape)
|
||||
{
|
||||
TopTools_IndexedMapOfShape map;
|
||||
ShapeIndexMap map;
|
||||
TopExp::MapShapes(shape, TopAbs_EDGE, map);
|
||||
return map.Extent();
|
||||
}
|
||||
|
||||
TopoDS_Edge GeometryEngine::edge_by_index(const TopoDS_Shape& shape, int index)
|
||||
{
|
||||
TopTools_IndexedMapOfShape map;
|
||||
ShapeIndexMap map;
|
||||
TopExp::MapShapes(shape, TopAbs_EDGE, map);
|
||||
if (index < 0 || index >= map.Extent())
|
||||
return TopoDS_Edge();
|
||||
@@ -720,7 +723,7 @@ TopoDS_Edge GeometryEngine::edge_by_index(const TopoDS_Shape& shape, int index)
|
||||
|
||||
int GeometryEngine::edge_index_of(const TopoDS_Shape& shape, const TopoDS_Edge& edge)
|
||||
{
|
||||
TopTools_IndexedMapOfShape map;
|
||||
ShapeIndexMap map;
|
||||
TopExp::MapShapes(shape, TopAbs_EDGE, map);
|
||||
int idx = map.FindIndex(edge);
|
||||
return (idx > 0) ? (idx - 1) : -1;
|
||||
|
||||
@@ -27,9 +27,7 @@
|
||||
#include <GC_MakeArcOfEllipse.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <gp_Circ.hxx>
|
||||
#include <gp_Elips.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
@@ -179,21 +177,23 @@ TopoDS_Wire SketchProfile::to_occt_wire(const SketchPlane& plane) const
|
||||
|
||||
// ---- SketchEngine ----
|
||||
|
||||
TopoDS_Shape SketchEngine::make_prism(const TopoDS_Shape& base, const gp_Vec& vec)
|
||||
{
|
||||
if (vec.Magnitude() < 1e-9) throw std::runtime_error("extrude depth is zero");
|
||||
BRepPrimAPI_MakePrism prism(base, vec);
|
||||
if (!prism.IsDone()) throw std::runtime_error("extrude failed");
|
||||
return prism.Shape();
|
||||
}
|
||||
|
||||
static TopoDS_Shape extrude_face_internal(const TopoDS_Face& face, const gp_Dir& dir, double length, bool symmetric)
|
||||
{
|
||||
gp_Vec vec = gp_Vec(dir) * length;
|
||||
if (symmetric) {
|
||||
gp_Vec halfVec = gp_Vec(dir) * (length / 2.0);
|
||||
BRepPrimAPI_MakePrism pos(face, halfVec);
|
||||
BRepPrimAPI_MakePrism neg(face, -halfVec);
|
||||
if (!pos.IsDone() || !neg.IsDone()) throw std::runtime_error("Symmetric extrude failed");
|
||||
BRepAlgoAPI_Fuse fuse(pos.Shape(), neg.Shape());
|
||||
BRepAlgoAPI_Fuse fuse(SketchEngine::make_prism(face, halfVec), SketchEngine::make_prism(face, -halfVec));
|
||||
if (!fuse.IsDone()) throw std::runtime_error("Fuse failed");
|
||||
return fuse.Shape();
|
||||
}
|
||||
BRepPrimAPI_MakePrism prism(face, vec);
|
||||
if (!prism.IsDone()) throw std::runtime_error("Extrude failed");
|
||||
return prism.Shape();
|
||||
return SketchEngine::make_prism(face, gp_Vec(dir) * length);
|
||||
}
|
||||
|
||||
TopoDS_Shape SketchEngine::make_extrude(const TopoDS_Wire& wire, const SketchPlane& plane,
|
||||
@@ -224,12 +224,9 @@ TopoDS_Shape SketchEngine::make_extrude_two_sided(const TopoDS_Face& face, const
|
||||
{
|
||||
gp_Dir dir(plane.normal.x(), plane.normal.y(), plane.normal.z());
|
||||
const double u = std::abs(up), d = std::abs(down);
|
||||
if (u < 1e-9 && d < 1e-9) return TopoDS_Shape();
|
||||
if (d < 1e-9) { BRepPrimAPI_MakePrism p(face, gp_Vec(dir) * u); return p.Shape(); }
|
||||
if (u < 1e-9) { BRepPrimAPI_MakePrism p(face, gp_Vec(dir) * -d); return p.Shape(); }
|
||||
BRepPrimAPI_MakePrism pos(face, gp_Vec(dir) * u);
|
||||
BRepPrimAPI_MakePrism neg(face, gp_Vec(dir) * -d);
|
||||
BRepAlgoAPI_Fuse fuse(pos.Shape(), neg.Shape());
|
||||
if (d < 1e-9) return make_prism(face, gp_Vec(dir) * u);
|
||||
if (u < 1e-9) return make_prism(face, gp_Vec(dir) * -d);
|
||||
BRepAlgoAPI_Fuse fuse(make_prism(face, gp_Vec(dir) * u), make_prism(face, gp_Vec(dir) * -d));
|
||||
if (!fuse.IsDone()) throw std::runtime_error("two-sided extrude fuse failed");
|
||||
return fuse.Shape();
|
||||
}
|
||||
@@ -240,8 +237,8 @@ TopoDS_Shape SketchEngine::make_extrude_taper(const TopoDS_Wire& wire, const Ske
|
||||
gp_Dir dir(plane.normal.x(), plane.normal.y(), plane.normal.z());
|
||||
auto straight = [&]() -> TopoDS_Shape {
|
||||
BRepBuilderAPI_MakeFace fm(wire);
|
||||
BRepPrimAPI_MakePrism prism(fm.Face(), gp_Vec(dir) * length);
|
||||
return prism.Shape();
|
||||
if (!fm.IsDone()) throw std::runtime_error("Failed to make face from wire");
|
||||
return make_prism(fm.Face(), gp_Vec(dir) * length);
|
||||
};
|
||||
if (std::abs(taper_deg) >= 89.0 || std::abs(length) < 1e-9) return straight();
|
||||
const double off = length * std::tan(taper_deg * M_PI / 180.0);
|
||||
@@ -258,10 +255,10 @@ TopoDS_Shape SketchEngine::make_extrude_taper(const TopoDS_Wire& wire, const Ske
|
||||
if (topFlat.IsNull()) return straight();
|
||||
// 2) lift it along the normal by `length`
|
||||
gp_Trsf tr; tr.SetTranslation(gp_Vec(dir) * length);
|
||||
BRepBuilderAPI_Transform xf(topFlat, tr, Standard_True);
|
||||
BRepBuilderAPI_Transform xf(topFlat, tr, true);
|
||||
TopoDS_Wire topWire = TopoDS::Wire(xf.Shape());
|
||||
// 3) loft base -> top into a solid
|
||||
BRepOffsetAPI_ThruSections loft(Standard_True /*solid*/, Standard_False /*ruled*/);
|
||||
BRepOffsetAPI_ThruSections loft(true /*solid*/, false /*ruled*/);
|
||||
loft.AddWire(wire);
|
||||
loft.AddWire(topWire);
|
||||
loft.Build();
|
||||
@@ -285,6 +282,9 @@ TopoDS_Shape SketchEngine::make_extrude_regions(
|
||||
const std::vector<std::vector<std::vector<Vec2d>>>& regions,
|
||||
const SketchPlane& plane, double length, bool symmetric)
|
||||
{
|
||||
// The loop below skips regions that fail, so a zero depth is rejected before it.
|
||||
if (std::abs(length) < 1e-9) throw std::runtime_error("extrude depth is zero");
|
||||
|
||||
// Drop consecutive coincident points and the closing duplicate. FreeType /
|
||||
// SVG flattening routinely emits repeated points which would build a
|
||||
// degenerate OCCT edge and make the wire builder throw — sanitising keeps a
|
||||
@@ -406,8 +406,7 @@ TopoDS_Shape SketchEngine::make_loft(const std::vector<TopoDS_Wire>& profiles, b
|
||||
{
|
||||
if (profiles.size() < 2)
|
||||
throw std::runtime_error("loft needs at least 2 profiles");
|
||||
BRepOffsetAPI_ThruSections loft(Standard_True /*solid*/,
|
||||
ruled ? Standard_True : Standard_False);
|
||||
BRepOffsetAPI_ThruSections loft(true /*solid*/, ruled);
|
||||
for (const TopoDS_Wire& w : profiles) {
|
||||
if (w.IsNull()) throw std::runtime_error("loft: null profile wire");
|
||||
loft.AddWire(w);
|
||||
@@ -424,8 +423,7 @@ TopoDS_Shape SketchEngine::make_loft_surface(const std::vector<TopoDS_Wire>& pro
|
||||
{
|
||||
if (profiles.size() < 2)
|
||||
throw std::runtime_error("loft needs at least 2 profiles");
|
||||
BRepOffsetAPI_ThruSections loft(Standard_False /*shell, no end caps*/,
|
||||
ruled ? Standard_True : Standard_False);
|
||||
BRepOffsetAPI_ThruSections loft(false /*shell, no end caps*/, ruled);
|
||||
for (const TopoDS_Wire& w : profiles) {
|
||||
if (w.IsNull()) throw std::runtime_error("loft: null profile wire");
|
||||
loft.AddWire(w);
|
||||
@@ -597,15 +595,15 @@ std::vector<TopoDS_Wire> SketchEngine::entities_to_wires(const std::vector<Sketc
|
||||
const int n = int(c.ctrl.size());
|
||||
const int p = n >= 4 ? 3 : (n >= 2 ? n - 1 : 0);
|
||||
if (p < 1) return Handle(Geom_BSplineCurve)();
|
||||
TColgp_Array1OfPnt poles(1, n);
|
||||
NCollection_Array1<gp_Pnt> poles(1, n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Vec3d w = plane.to_world(c.ctrl[i]);
|
||||
poles.SetValue(i + 1, gp_Pnt(w.x(), w.y(), w.z()));
|
||||
}
|
||||
const int interior = n - p - 1; // count of single interior knots
|
||||
const int nknots = interior + 2;
|
||||
TColStd_Array1OfReal knots(1, nknots);
|
||||
TColStd_Array1OfInteger mults(1, nknots);
|
||||
NCollection_Array1<double> knots(1, nknots);
|
||||
NCollection_Array1<int> mults(1, nknots);
|
||||
knots.SetValue(1, 0.0); mults.SetValue(1, p + 1);
|
||||
for (int i = 1; i <= interior; ++i) { knots.SetValue(i + 1, double(i)); mults.SetValue(i + 1, 1); }
|
||||
knots.SetValue(nknots, double(interior + 1)); mults.SetValue(nknots, p + 1);
|
||||
@@ -808,7 +806,7 @@ std::vector<TopoDS_Wire> SketchEngine::entities_to_wires(const std::vector<Sketc
|
||||
wm.Add(BRepBuilderAPI_MakeEdge(va, vb).Edge());
|
||||
} else if (e->type == SketchEntity::Type::EllipseArc) {
|
||||
if (e->radius <= 1e-9 || e->rminor <= 1e-9) return {};
|
||||
GC_MakeArcOfEllipse arc_maker(make_elips(*e), e->start_angle, e->end_angle, Standard_True);
|
||||
GC_MakeArcOfEllipse arc_maker(make_elips(*e), e->start_angle, e->end_angle, true);
|
||||
if (!arc_maker.IsDone()) return {};
|
||||
wm.Add(BRepBuilderAPI_MakeEdge(arc_maker.Value(), va, vb).Edge());
|
||||
} else if (e->type == SketchEntity::Type::Arc) {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Ax3.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
@@ -227,6 +228,8 @@ struct SketchParams {
|
||||
class SketchEngine
|
||||
{
|
||||
public:
|
||||
// Throws on a zero vector, for which OCCT returns a degenerate solid.
|
||||
static TopoDS_Shape make_prism(const TopoDS_Shape& base, const gp_Vec& vec);
|
||||
static TopoDS_Shape make_extrude(const TopoDS_Wire& wire, const SketchPlane& plane,
|
||||
double length, bool symmetric = false, double taper_deg = 0.0);
|
||||
static TopoDS_Shape make_extrude(const TopoDS_Face& face, const SketchPlane& plane,
|
||||
|
||||
@@ -648,11 +648,8 @@ find_package(JPEG REQUIRED)
|
||||
find_package(Draco REQUIRED)
|
||||
|
||||
set(OCCT_LIBS
|
||||
TKXDESTEP
|
||||
TKSTEP
|
||||
TKSTEP209
|
||||
TKSTEPAttr
|
||||
TKSTEPBase
|
||||
TKDESTEP
|
||||
TKDE
|
||||
TKXCAF
|
||||
TKXSBase
|
||||
TKVCAF
|
||||
@@ -699,6 +696,22 @@ if (SLIC3R_CAD)
|
||||
endif ()
|
||||
# Published for the Windows packaging step in the top-level CMakeLists.txt.
|
||||
set(OCCT_LIBS "${OCCT_LIBS}" CACHE INTERNAL "OCCT toolkits linked by libslic3r")
|
||||
if (WIN32)
|
||||
# OCCT installs RelWithDebInfo and Debug builds to bin/occti and bin/occtd, so each build
|
||||
# type's DLL directory is read from the imported target, falling back to the first installed
|
||||
# build, as CMake does when linking.
|
||||
get_target_property(_occt_configs TKernel IMPORTED_CONFIGURATIONS)
|
||||
list(GET _occt_configs 0 _occt_fallback)
|
||||
foreach (_build_config IN ITEMS DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)
|
||||
set(_occt_config ${_occt_fallback})
|
||||
if (_build_config IN_LIST _occt_configs)
|
||||
set(_occt_config ${_build_config})
|
||||
endif ()
|
||||
get_target_property(_occt_dll TKernel IMPORTED_LOCATION_${_occt_config})
|
||||
get_filename_component(_occt_bin "${_occt_dll}" DIRECTORY)
|
||||
set(OCCT_BIN_DIR_${_build_config} "${_occt_bin}" CACHE INTERNAL "OCCT DLL directory for ${_build_config} builds")
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
target_link_libraries(libslic3r
|
||||
PUBLIC
|
||||
@@ -733,6 +746,12 @@ target_link_libraries(libslic3r
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
# OCCT's static targets name FreeType as a bare "freetype", which the macOS linker cannot
|
||||
# find; this target maps that name to FREETYPE_LIBRARIES.
|
||||
if (NOT TARGET freetype)
|
||||
add_library(freetype INTERFACE IMPORTED GLOBAL)
|
||||
target_link_libraries(freetype INTERFACE ${FREETYPE_LIBRARIES})
|
||||
endif ()
|
||||
# Link freetype for OCCT dependency (CAD operations need font rendering)
|
||||
target_link_libraries(libslic3r PRIVATE ${FREETYPE_LIBRARIES})
|
||||
if (NOT APPLE)
|
||||
|
||||
@@ -47,7 +47,8 @@
|
||||
#include "XCAFDoc_DocumentTool.hxx"
|
||||
#include "XCAFDoc_ShapeTool.hxx"
|
||||
#include "XCAFApp_Application.hxx"
|
||||
#include "TDF_LabelSequence.hxx"
|
||||
#include "NCollection_Sequence.hxx"
|
||||
#include "TDF_Label.hxx"
|
||||
#include "TopoDS_Solid.hxx"
|
||||
#include "TopoDS_Compound.hxx"
|
||||
#include "TopoDS_Builder.hxx"
|
||||
@@ -223,9 +224,9 @@ static void getNamedSolids(const TopLoc_Location& location,
|
||||
std::string fullName{name};
|
||||
|
||||
TopLoc_Location localLocation = location * shapeTool->GetLocation(label);
|
||||
TDF_LabelSequence components;
|
||||
NCollection_Sequence<TDF_Label> components;
|
||||
if (shapeTool->GetComponents(referredLabel, components)) {
|
||||
for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex) {
|
||||
for (int compIndex = 1; compIndex <= components.Length(); ++compIndex) {
|
||||
getNamedSolids(localLocation, fullName, id, shapeTool, components.Value(compIndex), namedSolids, isSplitCompound);
|
||||
}
|
||||
} else {
|
||||
@@ -233,7 +234,7 @@ static void getNamedSolids(const TopLoc_Location& location,
|
||||
TopExp_Explorer explorer;
|
||||
shapeTool->GetShape(referredLabel, shape);
|
||||
TopAbs_ShapeEnum shape_type = shape.ShapeType();
|
||||
BRepBuilderAPI_Transform transform(shape, localLocation, Standard_True);
|
||||
BRepBuilderAPI_Transform transform(shape, localLocation, true);
|
||||
int i = 0;
|
||||
switch (shape_type) {
|
||||
case TopAbs_COMPOUND:
|
||||
@@ -503,11 +504,11 @@ Step::Step_Status Step::load()
|
||||
if (cb_cancel) return;
|
||||
progress = 6;
|
||||
m_shape_tool = XCAFDoc_DocumentTool::ShapeTool(m_doc->Main());
|
||||
TDF_LabelSequence topLevelShapes;
|
||||
NCollection_Sequence<TDF_Label> topLevelShapes;
|
||||
m_shape_tool->GetFreeShapes(topLevelShapes);
|
||||
unsigned int id{ 1 };
|
||||
Standard_Integer topShapeLength = topLevelShapes.Length() + 1;
|
||||
for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) {
|
||||
int topShapeLength = topLevelShapes.Length() + 1;
|
||||
for (int iLabel = 1; iLabel < topShapeLength; ++iLabel) {
|
||||
if (cb_cancel) return;
|
||||
getNamedSolids(TopLoc_Location{}, "", id, m_shape_tool, topLevelShapes.Value(iLabel), m_name_solids);
|
||||
}
|
||||
@@ -562,12 +563,12 @@ Step::Step_Status Step::mesh(Model* model,
|
||||
new_object->input_file = m_path.c_str();
|
||||
|
||||
auto task = new boost::thread(Slic3r::create_thread([&]() -> void {
|
||||
TDF_LabelSequence topLevelShapes;
|
||||
NCollection_Sequence<TDF_Label> topLevelShapes;
|
||||
m_shape_tool->GetFreeShapes(topLevelShapes);
|
||||
unsigned int id{ 1 };
|
||||
Standard_Integer topShapeLength = topLevelShapes.Length() + 1;
|
||||
int topShapeLength = topLevelShapes.Length() + 1;
|
||||
|
||||
for (Standard_Integer iLabel = 1; iLabel < topShapeLength; ++iLabel) {
|
||||
for (int iLabel = 1; iLabel < topShapeLength; ++iLabel) {
|
||||
progress = static_cast<double>(iLabel) / (topShapeLength-1);
|
||||
if (cb_cancel) {
|
||||
return;
|
||||
@@ -604,10 +605,10 @@ Step::Step_Status Step::mesh(Model* model,
|
||||
std::vector<Vec3f> points;
|
||||
points.reserve(aNbNodes);
|
||||
// BBS: count faces missing triangulation
|
||||
Standard_Integer aNbFacesNoTri = 0;
|
||||
int aNbFacesNoTri = 0;
|
||||
// BBS: fill temporary triangulation
|
||||
Standard_Integer aNodeOffset = 0;
|
||||
Standard_Integer aTriangleOffet = 0;
|
||||
int aNodeOffset = 0;
|
||||
int aTriangleOffet = 0;
|
||||
for (TopExp_Explorer anExpSF(namedSolids[i].solid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
|
||||
const TopoDS_Shape& aFace = anExpSF.Current();
|
||||
TopLoc_Location aLoc;
|
||||
@@ -618,15 +619,15 @@ Step::Step_Status Step::mesh(Model* model,
|
||||
}
|
||||
// BBS: copy nodes
|
||||
gp_Trsf aTrsf = aLoc.Transformation();
|
||||
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
for (int aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
|
||||
aPnt.Transform(aTrsf);
|
||||
points.emplace_back(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) {
|
||||
int anId[3] = {};
|
||||
for (int aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
|
||||
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
|
||||
|
||||
aTri.Get(anId[0], anId[1], anId[2]);
|
||||
|
||||
@@ -84,9 +84,9 @@ class StepProgressIncdicator : public Message_ProgressIndicator
|
||||
public:
|
||||
StepProgressIncdicator(std::atomic<bool>& stop_flag) : should_stop(stop_flag){}
|
||||
|
||||
Standard_Boolean UserBreak() override { return should_stop.load(); }
|
||||
bool UserBreak() override { return should_stop.load(); }
|
||||
|
||||
void Show(const Message_ProgressScope&, const Standard_Boolean) override {
|
||||
void Show(const Message_ProgressScope&, const bool) override {
|
||||
std::cout << "Progress: " << std::fixed << std::setprecision(2) << 100.0 * GetPosition() << "%" << std::endl;
|
||||
}
|
||||
private:
|
||||
|
||||
@@ -339,10 +339,10 @@ bool load_svg(const char *path, Model *model, std::string &message)
|
||||
std::vector<Vec3f> points;
|
||||
points.reserve(aNbNodes);
|
||||
// BBS: count faces missing triangulation
|
||||
Standard_Integer aNbFacesNoTri = 0;
|
||||
int aNbFacesNoTri = 0;
|
||||
// BBS: fill temporary triangulation
|
||||
Standard_Integer aNodeOffset = 0;
|
||||
Standard_Integer aTriangleOffet = 0;
|
||||
int aNodeOffset = 0;
|
||||
int aTriangleOffet = 0;
|
||||
for (TopExp_Explorer anExpSF(namedSolids[i].shape, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
|
||||
const TopoDS_Shape &aFace = anExpSF.Current();
|
||||
TopLoc_Location aLoc;
|
||||
@@ -353,15 +353,15 @@ bool load_svg(const char *path, Model *model, std::string &message)
|
||||
}
|
||||
// BBS: copy nodes
|
||||
gp_Trsf aTrsf = aLoc.Transformation();
|
||||
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
for (int aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
|
||||
aPnt.Transform(aTrsf);
|
||||
points.emplace_back(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) {
|
||||
int anId[3];
|
||||
for (int aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
|
||||
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
|
||||
|
||||
aTri.Get(anId[0], anId[1], anId[2]);
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
#include "Font_BRepTextBuilder.hxx"
|
||||
#include "BRepPrimAPI_MakePrism.hxx"
|
||||
#include "Font_FontMgr.hxx"
|
||||
#include "NCollection_Sequence.hxx"
|
||||
#include "TCollection_HAsciiString.hxx"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
@@ -57,7 +59,7 @@ namespace Slic3r {
|
||||
|
||||
static std::map<std::string, std::string> g_occt_fonts_maps; //map<font_name, font_path>
|
||||
|
||||
static const std::vector<Standard_CString> fonts_suffix{ "Bold", "Medium", "Heavy", "Italic", "Oblique", "Inclined", "Light", "Thin",
|
||||
static const std::vector<const char*> fonts_suffix{ "Bold", "Medium", "Heavy", "Italic", "Oblique", "Inclined", "Light", "Thin",
|
||||
"Semibold", "ExtraBold", "ExtraBold", "Semilight", "SemiLight", "ExtraLight", "Extralight", "Ultralight",
|
||||
"Condensed", "Ultra", "Extra", "Expanded", "Extended", "1", "2", "3", "4", "5", "6", "7", "8", "9", "Al Tarikh"};
|
||||
|
||||
@@ -73,7 +75,7 @@ std::vector<std::string> init_occt_fonts()
|
||||
Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
|
||||
aFontMgr->InitFontDataBase();
|
||||
|
||||
TColStd_SequenceOfHAsciiString availFontNames;
|
||||
NCollection_Sequence<Handle(TCollection_HAsciiString)> availFontNames;
|
||||
aFontMgr->GetAvailableFontsNames(availFontNames);
|
||||
stdFontNames.reserve(availFontNames.Size());
|
||||
|
||||
@@ -122,16 +124,14 @@ std::vector<std::string> init_occt_fonts()
|
||||
|
||||
static bool TextToBRep(const char* text, const char* font, const float theTextHeight, Font_FontAspect& theFontAspect, TopoDS_Shape& theShape, double& text_width)
|
||||
{
|
||||
Standard_Integer anArgIt = 1;
|
||||
Standard_CString aName = "text_shape";
|
||||
Standard_CString aText = text;
|
||||
const char* aText = text;
|
||||
|
||||
Font_BRepFont aFont;
|
||||
//TCollection_AsciiString aFontName("Courier");
|
||||
TCollection_AsciiString aFontName(font);
|
||||
Standard_Real aTextHeight = theTextHeight;
|
||||
double aTextHeight = theTextHeight;
|
||||
Font_FontAspect aFontAspect = theFontAspect;
|
||||
Standard_Boolean anIsCompositeCurve = Standard_False;
|
||||
bool anIsCompositeCurve = false;
|
||||
gp_Ax3 aPenAx3(gp::XOY());
|
||||
gp_Dir aNormal(0.0, 0.0, 1.0);
|
||||
gp_Dir aDirection(1.0, 0.0, 0.0);
|
||||
@@ -156,10 +156,10 @@ static bool TextToBRep(const char* text, const char* font, const float theTextHe
|
||||
// get the text width
|
||||
text_width = 0;
|
||||
NCollection_String coll_str = aText;
|
||||
for (NCollection_Utf8Iter anIter = coll_str.Iterator(); *anIter != 0;) {
|
||||
const Standard_Utf32Char aCharThis = *anIter;
|
||||
const Standard_Utf32Char aCharNext = *++anIter;
|
||||
double width = aFont.AdvanceX(aCharThis, aCharNext);
|
||||
for (auto anIter = coll_str.Iterator(); *anIter != 0;) {
|
||||
const char32_t aCharThis = *anIter;
|
||||
const char32_t aCharNext = *++anIter;
|
||||
double width = aFont.AdvanceX(aCharThis, aCharNext);
|
||||
text_width += width;
|
||||
}
|
||||
|
||||
@@ -173,9 +173,9 @@ static bool Prism(const TopoDS_Shape& theBase, const float thickness, TopoDS_Sha
|
||||
if (theBase.IsNull()) return false;
|
||||
|
||||
gp_Vec V(0.f, 0.f, thickness);
|
||||
BRepPrimAPI_MakePrism* Prism = new BRepPrimAPI_MakePrism(theBase, V, Standard_False);
|
||||
BRepPrimAPI_MakePrism prism(theBase, V, false);
|
||||
|
||||
theSolid = Prism->Shape();
|
||||
theSolid = prism.Shape();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -205,10 +205,10 @@ static void MakeMesh(TopoDS_Shape& theSolid, TriangleMesh& theMesh)
|
||||
std::vector<Vec3f> points;
|
||||
points.reserve(aNbNodes);
|
||||
//BBS: count faces missing triangulation
|
||||
Standard_Integer aNbFacesNoTri = 0;
|
||||
int aNbFacesNoTri = 0;
|
||||
//BBS: fill temporary triangulation
|
||||
Standard_Integer aNodeOffset = 0;
|
||||
Standard_Integer aTriangleOffet = 0;
|
||||
int aNodeOffset = 0;
|
||||
int aTriangleOffet = 0;
|
||||
for (TopExp_Explorer anExpSF(theSolid, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) {
|
||||
const TopoDS_Shape& aFace = anExpSF.Current();
|
||||
TopLoc_Location aLoc;
|
||||
@@ -219,21 +219,21 @@ static void MakeMesh(TopoDS_Shape& theSolid, TriangleMesh& theMesh)
|
||||
}
|
||||
//BBS: copy nodes
|
||||
gp_Trsf aTrsf = aLoc.Transformation();
|
||||
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
for (int aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter) {
|
||||
gp_Pnt aPnt = aTriangulation->Node(aNodeIter);
|
||||
aPnt.Transform(aTrsf);
|
||||
points.emplace_back(Vec3f(aPnt.X(), aPnt.Y(), aPnt.Z()));
|
||||
}
|
||||
//BBS: copy triangles
|
||||
const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
|
||||
for (Standard_Integer aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
|
||||
for (int aTriIter = 1; aTriIter <= aTriangulation->NbTriangles(); ++aTriIter) {
|
||||
Poly_Triangle aTri = aTriangulation->Triangle(aTriIter);
|
||||
|
||||
Standard_Integer anId[3];
|
||||
int anId[3];
|
||||
aTri.Get(anId[0], anId[1], anId[2]);
|
||||
if (anOrientation == TopAbs_REVERSED) {
|
||||
//BBS: swap 1, 2.
|
||||
Standard_Integer aTmpIdx = anId[1];
|
||||
int aTmpIdx = anId[1];
|
||||
anId[1] = anId[2];
|
||||
anId[2] = aTmpIdx;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/log/trivial.hpp> // the offer/atlas join check reports on the log
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdarg> // offer_trace: diagnostic row dump for the offer ladder
|
||||
@@ -4694,7 +4693,7 @@ void DesignPanel::on_import_svg()
|
||||
// (parse + tessellate); running it inline froze the whole window — the compositor marked the
|
||||
// app unresponsive and nothing repainted. The dialog is app-modal, so the document cannot be
|
||||
// touched while the worker owns it. Exceptions must not escape the worker: `work` is expected
|
||||
// to swallow them (OCCT throws Standard_Failure, which is not a std::exception).
|
||||
// to swallow them.
|
||||
static void run_off_ui_thread(wxWindow* parent, const wxString& message, const std::function<void()>& work)
|
||||
{
|
||||
std::atomic<bool> done{false};
|
||||
@@ -4722,10 +4721,6 @@ static void run_off_ui_thread(wxWindow* parent, const wxString& message, const s
|
||||
worker.join();
|
||||
}
|
||||
|
||||
// Rebuild the document off the UI thread. Every feature op (fillet, cut, shell, boolean, ...)
|
||||
// goes through recompute(), and on a heavy imported solid that is seconds of OCCT work — inline
|
||||
// it freezes the window. OCCT throws Standard_Failure, which is not a std::exception and would
|
||||
// terminate the process if it escaped the worker, so both are caught here.
|
||||
// Keep the Model's copy of the recipe in step with the document.
|
||||
//
|
||||
// This used to be written in exactly ONE place — on_commit(), as a side effect of Commit to
|
||||
@@ -4756,18 +4751,15 @@ void DesignPanel::sync_recipe_to_model()
|
||||
Slic3r::put_other_changes();
|
||||
}
|
||||
|
||||
// Runs recompute() off the UI thread, because on a heavy imported solid it takes seconds.
|
||||
bool DesignPanel::recompute_guarded(const wxString& message)
|
||||
{
|
||||
bool ok = false;
|
||||
run_off_ui_thread(this, message, [this, &ok]() {
|
||||
try {
|
||||
ok = m_doc.recompute();
|
||||
} catch (const Standard_Failure& e) {
|
||||
const char* what = e.GetMessageString();
|
||||
m_doc.error = (what != nullptr && *what != '\0') ? what : "OCCT failure";
|
||||
ok = false;
|
||||
} catch (const std::exception& e) {
|
||||
m_doc.error = e.what();
|
||||
m_doc.error = *e.what() ? e.what() : "OCCT failure";
|
||||
ok = false;
|
||||
}
|
||||
});
|
||||
@@ -4792,11 +4784,8 @@ void DesignPanel::on_import_step()
|
||||
run_off_ui_thread(this, _L("Reading STEP…"), [&]() {
|
||||
try {
|
||||
solids = GeometryEngine::read_step_solids(path, err);
|
||||
} catch (const Standard_Failure& e) {
|
||||
const char* what = e.GetMessageString();
|
||||
err = (what != nullptr && *what != '\0') ? what : "OCCT failure";
|
||||
} catch (const std::exception& e) {
|
||||
err = e.what();
|
||||
err = *e.what() ? e.what() : "OCCT failure";
|
||||
}
|
||||
});
|
||||
if (solids.empty()) {
|
||||
@@ -4820,11 +4809,8 @@ void DesignPanel::on_import_step()
|
||||
run_off_ui_thread(this, _L("Rebuilding model…"), [&]() {
|
||||
try {
|
||||
rebuilt = m_doc.recompute();
|
||||
} catch (const Standard_Failure& e) {
|
||||
const char* what = e.GetMessageString();
|
||||
m_doc.error = (what != nullptr && *what != '\0') ? what : "OCCT failure";
|
||||
} catch (const std::exception& e) {
|
||||
m_doc.error = e.what();
|
||||
m_doc.error = *e.what() ? e.what() : "OCCT failure";
|
||||
}
|
||||
});
|
||||
if (!rebuilt) {
|
||||
@@ -4901,12 +4887,8 @@ void DesignPanel::on_import_mesh()
|
||||
try {
|
||||
shape = GeometryEngine::mesh_to_brep(mesh.its, MESH_IMPORT_TOLERANCE,
|
||||
MESH_IMPORT_MERGE_ANGLE_DEG, stats);
|
||||
} catch (const Standard_Failure& e) { // on OCCT >= 8 Standard_Failure derives from std::exception — must precede that handler
|
||||
fail(_L("Mesh conversion failed: ") + wxString::FromUTF8(
|
||||
e.GetMessageString() ? e.GetMessageString() : "OCCT error"));
|
||||
return;
|
||||
} catch (const std::exception& e) {
|
||||
fail(_L("Mesh conversion failed: ") + wxString::FromUTF8(e.what()));
|
||||
fail(_L("Mesh conversion failed: ") + wxString::FromUTF8(*e.what() ? e.what() : "OCCT error"));
|
||||
return;
|
||||
}
|
||||
if (shape.IsNull()) { fail(_L("Mesh conversion produced no geometry")); return; }
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <Standard_Failure.hxx> // OCCT base error (not a std::exception)
|
||||
#include <Standard_Failure.hxx> // OCCT base error
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/MainFrame.hpp"
|
||||
@@ -637,9 +637,9 @@ json slice_body(DesignPanel* panel, const json& params)
|
||||
: plane_name == "YZ" ? gp_Dir(1, 0, 0)
|
||||
: gp_Dir(0, 0, 1);
|
||||
gp_Pnt o(n.X() * offset, n.Y() * offset, n.Z() * offset);
|
||||
BRepAlgoAPI_Section sect(shape, gp_Pln(o, n), Standard_False);
|
||||
sect.ComputePCurveOn1(Standard_False);
|
||||
sect.Approximation(Standard_True);
|
||||
BRepAlgoAPI_Section sect(shape, gp_Pln(o, n), false);
|
||||
sect.ComputePCurveOn1(false);
|
||||
sect.Approximation(true);
|
||||
sect.Build();
|
||||
if (!sect.IsDone()) throw std::runtime_error("section failed");
|
||||
std::vector<std::vector<Vec3d>> segs;
|
||||
@@ -751,7 +751,7 @@ ShapeMetrics shape_metrics(const TopoDS_Shape& s)
|
||||
GProp_GProps vp; BRepGProp::VolumeProperties(s, vp);
|
||||
gp_Pnt c = vp.CentreOfMass();
|
||||
Bnd_Box bb; BRepBndLib::Add(s, bb);
|
||||
Standard_Real x0, y0, z0, x1, y1, z1; bb.Get(x0, y0, z0, x1, y1, z1);
|
||||
double x0, y0, z0, x1, y1, z1; bb.Get(x0, y0, z0, x1, y1, z1);
|
||||
return {vp.Mass(), Vec3d(c.X(), c.Y(), c.Z()), Vec3d(x0, y0, z0), Vec3d(x1, y1, z1)};
|
||||
}
|
||||
|
||||
@@ -2095,8 +2095,8 @@ std::string handle_on_main(const std::string& method, const json& params, const
|
||||
if (method == "mate") return rpc_result(id, action_mate(panel, params));
|
||||
if (method == "check_interference") return rpc_result(id, action_check_interference(panel, params));
|
||||
return rpc_error(id, -32601, "Unknown method: " + method);
|
||||
} catch (const Standard_Failure& ex) { // OCCT errors are NOT std::exception
|
||||
return rpc_error(id, -32000, std::string("OCCT: ") + (ex.GetMessageString() ? ex.GetMessageString() : "failure"));
|
||||
} catch (const Standard_Failure& ex) { // derives from std::exception, so it comes first
|
||||
return rpc_error(id, -32000, std::string("OCCT: ") + (*ex.what() ? ex.what() : "failure"));
|
||||
} catch (const std::exception& ex) {
|
||||
return rpc_error(id, -32000, ex.what());
|
||||
}
|
||||
|
||||
@@ -827,7 +827,7 @@ indexed_triangle_set GLGizmoCut3D::its_make_groove_plane()
|
||||
|
||||
float slot_mouth_outer_x = slot_neck_half_width + flap_taper_offset; // upper_x extension
|
||||
float slot_neck_outer_x = slot_mouth_half_width + flap_taper_offset; // lower_x extension
|
||||
float slot_outer_x_max = Max(slot_neck_outer_x, slot_mouth_outer_x); // max x extension
|
||||
float slot_outer_x_max = std::max(slot_neck_outer_x, slot_mouth_outer_x); // max x extension
|
||||
|
||||
float slot_neck_inner_x = slot_neck_half_width - flap_taper_offset; // upper_x narrowing
|
||||
float slot_mouth_inner_x = slot_mouth_half_width - flap_taper_offset; // lower_x narrowing
|
||||
|
||||
Reference in new issue
Block a user