10C Inc 2: feature tail
119 of the app's 138 symbols now resolve; only the I/O modules and the Inc 4 tail are left. New: GCE2d, GCPnts, BRepFilletAPI, BRepOffsetAPI, ShapeAnalysis, ShapeFix, ShapeUpgrade, BRepCheck, BRepTools, BRepLib, BRepExtrema, BRepClass3d, IntCurvesFace, plus TopTools_HSequenceOfShape. The fillet and chamfer builders derive BRepBuilderAPI_MakeShape, so their history comes from the base bound in Inc 1 — which is what lets the app read a blend's provenance the same way it reads a boolean's. The Inc 2 gate compares that history exactly, alongside the splitter's, which is what sketch-region attribution depends on. Two shapes of deviation, both commented where they are bound: - Trailing enum arguments are left off four constructors (fillet's ChFi3d_FilletShape, MakeThickSolidByJoin's mode/join pair, BRepExtrema's Extrema flags, and Inc 1's GeomAPI_ProjectPointOnSurf). An unregistered enum cannot serve as a default argument — nanobind converts defaults at binding time, so it fails the whole module's import with std::bad_cast. The app never overrides any of them, so OCCT's own defaults apply and behaviour is unchanged. - ShapeAnalysis_FreeBounds.ConnectEdgesToWires reassigns a Handle& out parameter, which the caster cannot honour because it hands C++ a copy of the handle. The lambda splices the result into the sequence the caller passed, so the pass-empty-then-read shape the app uses still works. This is the one place upstream's holder semantics and ours differ observably. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfriM8XUkn7uYf5Dwe2xo6
This commit is contained in:
29
src/core.cpp
29
src/core.cpp
@@ -52,6 +52,20 @@ void register_BRepAlgoAPI(nb::module_ &);
|
||||
void register_BRepPrimAPI(nb::module_ &);
|
||||
void register_GC(nb::module_ &);
|
||||
void register_BRepMesh(nb::module_ &);
|
||||
// Inc 2 — feature tail
|
||||
void register_GCE2d(nb::module_ &);
|
||||
void register_GCPnts(nb::module_ &);
|
||||
void register_BRepFilletAPI(nb::module_ &);
|
||||
void register_BRepOffsetAPI(nb::module_ &);
|
||||
void register_ShapeAnalysis(nb::module_ &);
|
||||
void register_ShapeFix(nb::module_ &);
|
||||
void register_ShapeUpgrade(nb::module_ &);
|
||||
void register_BRepCheck(nb::module_ &);
|
||||
void register_BRepTools(nb::module_ &);
|
||||
void register_BRepLib(nb::module_ &);
|
||||
void register_BRepExtrema(nb::module_ &);
|
||||
void register_BRepClass3d(nb::module_ &);
|
||||
void register_IntCurvesFace(nb::module_ &);
|
||||
void register_ext(nb::module_ &);
|
||||
|
||||
NB_MODULE(_OCP, m) {
|
||||
@@ -95,6 +109,21 @@ NB_MODULE(_OCP, m) {
|
||||
register_GC(m);
|
||||
register_BRepMesh(m);
|
||||
|
||||
// Inc 2.
|
||||
register_GCE2d(m);
|
||||
register_GCPnts(m);
|
||||
register_BRepFilletAPI(m);
|
||||
register_BRepOffsetAPI(m);
|
||||
register_ShapeAnalysis(m);
|
||||
register_ShapeFix(m);
|
||||
register_ShapeUpgrade(m);
|
||||
register_BRepCheck(m);
|
||||
register_BRepTools(m);
|
||||
register_BRepLib(m);
|
||||
register_BRepExtrema(m);
|
||||
register_BRepClass3d(m);
|
||||
register_IntCurvesFace(m);
|
||||
|
||||
register_ext(m);
|
||||
|
||||
m.attr("__all_modules__") = ocp_module_registry();
|
||||
|
||||
89
src/modules/mod_BRepCheck.cpp
Normal file
89
src/modules/mod_BRepCheck.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
OCP.BRepCheck — shape validity.
|
||||
|
||||
The analyzer runs on every preview and after every boolean. Its
|
||||
constructor does the work, so that is what releases the GIL; the per-face
|
||||
Result() lookups afterwards are cheap.
|
||||
|
||||
Only the two status values the app tests for are worth calling out —
|
||||
it names the self-intersecting/intersecting-wire pair when deciding whether
|
||||
an imported shape is repairable — but the whole enum is bound, since it is
|
||||
what Result() reports through.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepCheck_Result.hxx>
|
||||
#include <BRepCheck_Status.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
void register_BRepCheck(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepCheck");
|
||||
|
||||
nb::enum_<BRepCheck_Status>(m, "BRepCheck_Status", nb::is_arithmetic())
|
||||
.value("BRepCheck_NoError", BRepCheck_NoError)
|
||||
.value("BRepCheck_InvalidPointOnCurve", BRepCheck_InvalidPointOnCurve)
|
||||
.value("BRepCheck_InvalidPointOnCurveOnSurface",
|
||||
BRepCheck_InvalidPointOnCurveOnSurface)
|
||||
.value("BRepCheck_InvalidPointOnSurface", BRepCheck_InvalidPointOnSurface)
|
||||
.value("BRepCheck_No3DCurve", BRepCheck_No3DCurve)
|
||||
.value("BRepCheck_Multiple3DCurve", BRepCheck_Multiple3DCurve)
|
||||
.value("BRepCheck_Invalid3DCurve", BRepCheck_Invalid3DCurve)
|
||||
.value("BRepCheck_NoCurveOnSurface", BRepCheck_NoCurveOnSurface)
|
||||
.value("BRepCheck_InvalidCurveOnSurface", BRepCheck_InvalidCurveOnSurface)
|
||||
.value("BRepCheck_InvalidCurveOnClosedSurface",
|
||||
BRepCheck_InvalidCurveOnClosedSurface)
|
||||
.value("BRepCheck_InvalidSameRangeFlag", BRepCheck_InvalidSameRangeFlag)
|
||||
.value("BRepCheck_InvalidSameParameterFlag",
|
||||
BRepCheck_InvalidSameParameterFlag)
|
||||
.value("BRepCheck_InvalidDegeneratedFlag", BRepCheck_InvalidDegeneratedFlag)
|
||||
.value("BRepCheck_FreeEdge", BRepCheck_FreeEdge)
|
||||
.value("BRepCheck_InvalidMultiConnexity", BRepCheck_InvalidMultiConnexity)
|
||||
.value("BRepCheck_InvalidRange", BRepCheck_InvalidRange)
|
||||
.value("BRepCheck_EmptyWire", BRepCheck_EmptyWire)
|
||||
.value("BRepCheck_RedundantEdge", BRepCheck_RedundantEdge)
|
||||
.value("BRepCheck_SelfIntersectingWire", BRepCheck_SelfIntersectingWire)
|
||||
.value("BRepCheck_NoSurface", BRepCheck_NoSurface)
|
||||
.value("BRepCheck_InvalidWire", BRepCheck_InvalidWire)
|
||||
.value("BRepCheck_RedundantWire", BRepCheck_RedundantWire)
|
||||
.value("BRepCheck_IntersectingWires", BRepCheck_IntersectingWires)
|
||||
.value("BRepCheck_InvalidImbricationOfWires",
|
||||
BRepCheck_InvalidImbricationOfWires)
|
||||
.value("BRepCheck_EmptyShell", BRepCheck_EmptyShell)
|
||||
.value("BRepCheck_RedundantFace", BRepCheck_RedundantFace)
|
||||
.value("BRepCheck_InvalidImbricationOfShells",
|
||||
BRepCheck_InvalidImbricationOfShells)
|
||||
.value("BRepCheck_UnorientableShape", BRepCheck_UnorientableShape)
|
||||
.value("BRepCheck_NotClosed", BRepCheck_NotClosed)
|
||||
.value("BRepCheck_NotConnected", BRepCheck_NotConnected)
|
||||
.value("BRepCheck_SubshapeNotInShape", BRepCheck_SubshapeNotInShape)
|
||||
.value("BRepCheck_BadOrientation", BRepCheck_BadOrientation)
|
||||
.value("BRepCheck_BadOrientationOfSubshape",
|
||||
BRepCheck_BadOrientationOfSubshape)
|
||||
.value("BRepCheck_InvalidPolygonOnTriangulation",
|
||||
BRepCheck_InvalidPolygonOnTriangulation)
|
||||
.value("BRepCheck_InvalidToleranceValue", BRepCheck_InvalidToleranceValue)
|
||||
.value("BRepCheck_EnclosedRegion", BRepCheck_EnclosedRegion)
|
||||
.value("BRepCheck_CheckFail", BRepCheck_CheckFail)
|
||||
.export_values();
|
||||
|
||||
nb::class_<BRepCheck_Result, Standard_Transient>(m, "BRepCheck_Result")
|
||||
.def("Status", &BRepCheck_Result::Status, OCP_RETURN_COPY)
|
||||
.def("IsMinimum", &BRepCheck_Result::IsMinimum);
|
||||
|
||||
nb::class_<BRepCheck_Analyzer>(m, "BRepCheck_Analyzer")
|
||||
.def(nb::init<const TopoDS_Shape &, const Standard_Boolean,
|
||||
const Standard_Boolean, const Standard_Boolean>(),
|
||||
"S"_a, "GeomControls"_a = Standard_True,
|
||||
"theIsParallel"_a = Standard_False,
|
||||
"theIsExact"_a = Standard_False, OCP_NOGIL)
|
||||
.def("IsValid", nb::overload_cast<>(&BRepCheck_Analyzer::IsValid,
|
||||
nb::const_))
|
||||
.def("IsValid",
|
||||
nb::overload_cast<const TopoDS_Shape &>(&BRepCheck_Analyzer::IsValid,
|
||||
nb::const_),
|
||||
"S"_a)
|
||||
.def("Result", &BRepCheck_Analyzer::Result, "theSubS"_a);
|
||||
}
|
||||
31
src/modules/mod_BRepClass3d.cpp
Normal file
31
src/modules/mod_BRepClass3d.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
OCP.BRepClass3d — point-in-solid classification.
|
||||
|
||||
Answers "is this point inside the material", which the app uses to decide
|
||||
which side of a face to grow a feature from and to verify that a thread
|
||||
groove did not gouge its shoulder. The three-argument constructor
|
||||
classifies immediately; the default one needs a separate Perform.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
void register_BRepClass3d(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepClass3d");
|
||||
|
||||
nb::class_<BRepClass3d_SolidClassifier>(m, "BRepClass3d_SolidClassifier")
|
||||
.def(nb::init<>())
|
||||
.def(nb::init<const TopoDS_Shape &>(), "S"_a, OCP_NOGIL)
|
||||
.def(nb::init<const TopoDS_Shape &, const gp_Pnt &,
|
||||
const Standard_Real>(),
|
||||
"S"_a, "P"_a, "Tol"_a, OCP_NOGIL)
|
||||
.def("Load", &BRepClass3d_SolidClassifier::Load, "S"_a, OCP_NOGIL)
|
||||
.def("Perform", &BRepClass3d_SolidClassifier::Perform, "P"_a, "Tol"_a,
|
||||
OCP_NOGIL)
|
||||
.def("State", &BRepClass3d_SolidClassifier::State)
|
||||
.def("IsOnAFace", &BRepClass3d_SolidClassifier::IsOnAFace);
|
||||
}
|
||||
34
src/modules/mod_BRepExtrema.cpp
Normal file
34
src/modules/mod_BRepExtrema.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
OCP.BRepExtrema — minimum distance between two shapes.
|
||||
|
||||
Used by the measurement tools and the interference check. The constructor
|
||||
performs the search, so it releases the GIL.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepExtrema_DistShapeShape.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
void register_BRepExtrema(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepExtrema");
|
||||
|
||||
nb::class_<BRepExtrema_DistShapeShape>(m, "BRepExtrema_DistShapeShape")
|
||||
.def(nb::init<>())
|
||||
// Without the Extrema flag/algo overload: unregistered enums cannot
|
||||
// serve as default arguments, and the app takes OCCT's defaults.
|
||||
.def(nb::init<const TopoDS_Shape &, const TopoDS_Shape &>(), "Shape1"_a,
|
||||
"Shape2"_a, OCP_NOGIL)
|
||||
.def(
|
||||
"Perform", [](BRepExtrema_DistShapeShape &self) { self.Perform(); },
|
||||
OCP_NOGIL)
|
||||
.def("IsDone", &BRepExtrema_DistShapeShape::IsDone)
|
||||
.def("NbSolution", &BRepExtrema_DistShapeShape::NbSolution)
|
||||
.def("Value", &BRepExtrema_DistShapeShape::Value)
|
||||
.def("PointOnShape1", &BRepExtrema_DistShapeShape::PointOnShape1, "N"_a,
|
||||
OCP_RETURN_COPY)
|
||||
.def("PointOnShape2", &BRepExtrema_DistShapeShape::PointOnShape2, "N"_a,
|
||||
OCP_RETURN_COPY);
|
||||
}
|
||||
66
src/modules/mod_BRepFilletAPI.cpp
Normal file
66
src/modules/mod_BRepFilletAPI.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
OCP.BRepFilletAPI — fillets and chamfers.
|
||||
|
||||
Both derive BRepBuilderAPI_MakeShape, so Build/Shape and — importantly —
|
||||
the Generated/Modified/IsDeleted history come from there. The app reads
|
||||
that history to attribute the blend faces back to the feature that made
|
||||
them, the same way it reads a boolean's.
|
||||
|
||||
These are the two operations the app runs in an isolated subprocess, since
|
||||
OCCT can hard-fault on a degenerate blend; nothing here changes that, but
|
||||
releasing the GIL on Build() is what lets the pool overlap work.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepBuilderAPI_MakeShape.hxx>
|
||||
#include <BRepFilletAPI_MakeChamfer.hxx>
|
||||
#include <BRepFilletAPI_MakeFillet.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
void register_BRepFilletAPI(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepFilletAPI");
|
||||
|
||||
nb::class_<BRepFilletAPI_MakeFillet, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepFilletAPI_MakeFillet")
|
||||
// The ChFi3d_FilletShape overload is left out: it exists only to
|
||||
// carry a default the app never overrides, and binding an unregistered
|
||||
// enum as a default argument fails at module-init time.
|
||||
.def(nb::init<const TopoDS_Shape &>(), "S"_a)
|
||||
.def("Add",
|
||||
nb::overload_cast<const Standard_Real, const TopoDS_Edge &>(
|
||||
&BRepFilletAPI_MakeFillet::Add),
|
||||
"Radius"_a, "E"_a)
|
||||
.def("Add",
|
||||
nb::overload_cast<const Standard_Real, const Standard_Real,
|
||||
const TopoDS_Edge &>(
|
||||
&BRepFilletAPI_MakeFillet::Add),
|
||||
"R1"_a, "R2"_a, "E"_a)
|
||||
.def("NbContours", &BRepFilletAPI_MakeFillet::NbContours)
|
||||
.def("Reset", &BRepFilletAPI_MakeFillet::Reset);
|
||||
|
||||
nb::class_<BRepFilletAPI_MakeChamfer, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepFilletAPI_MakeChamfer")
|
||||
.def(nb::init<const TopoDS_Shape &>(), "S"_a)
|
||||
.def("Add",
|
||||
nb::overload_cast<const TopoDS_Edge &>(
|
||||
&BRepFilletAPI_MakeChamfer::Add),
|
||||
"E"_a)
|
||||
.def("Add",
|
||||
nb::overload_cast<const Standard_Real, const TopoDS_Edge &>(
|
||||
&BRepFilletAPI_MakeChamfer::Add),
|
||||
"Dis"_a, "E"_a)
|
||||
.def("Add",
|
||||
nb::overload_cast<const Standard_Real, const Standard_Real,
|
||||
const TopoDS_Edge &, const TopoDS_Face &>(
|
||||
&BRepFilletAPI_MakeChamfer::Add),
|
||||
"Dis1"_a, "Dis2"_a, "E"_a, "F"_a)
|
||||
// Distance-and-angle, which is how the app words an asymmetric chamfer.
|
||||
.def("AddDA", &BRepFilletAPI_MakeChamfer::AddDA, "Dis"_a, "Angle"_a,
|
||||
"E"_a, "F"_a)
|
||||
.def("NbContours", &BRepFilletAPI_MakeChamfer::NbContours)
|
||||
.def("Reset", &BRepFilletAPI_MakeChamfer::Reset);
|
||||
}
|
||||
31
src/modules/mod_BRepLib.cpp
Normal file
31
src/modules/mod_BRepLib.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
OCP.BRepLib — repairs applied to shapes built edge by edge.
|
||||
|
||||
BuildCurves3d recovers the 3D curve of an edge that only carries a pcurve,
|
||||
which is how the thread's helical edges (laid out in the cylinder's UV
|
||||
space) become real geometry. OrientClosedSolid fixes a solid built from a
|
||||
sewn shell whose orientation came out inward.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepLib.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
|
||||
void register_BRepLib(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepLib");
|
||||
|
||||
nb::class_<BRepLib> cls(m, "BRepLib");
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "BuildCurves3d",
|
||||
[](const TopoDS_Shape &S) { return BRepLib::BuildCurves3d(S); }, "S"_a,
|
||||
OCP_NOGIL);
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "OrientClosedSolid",
|
||||
[](TopoDS_Solid &solid) { return BRepLib::OrientClosedSolid(solid); },
|
||||
"solid"_a, OCP_NOGIL);
|
||||
}
|
||||
86
src/modules/mod_BRepOffsetAPI.cpp
Normal file
86
src/modules/mod_BRepOffsetAPI.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
OCP.BRepOffsetAPI — sweeps, lofts, shells and drafts.
|
||||
|
||||
All five derive BRepBuilderAPI_MakeShape, so Build/Shape/history come from
|
||||
there. MakeThickSolid is the one with an unusual shape: it is default
|
||||
constructed and then told what to do by MakeThickSolidBySimple (a sheet
|
||||
thickened into a wall) or MakeThickSolidByJoin (a solid hollowed with
|
||||
faces removed), each of which does the work — so those get the GIL release
|
||||
rather than Build().
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <BRepBuilderAPI_MakeShape.hxx>
|
||||
#include <BRepOffsetAPI_DraftAngle.hxx>
|
||||
#include <BRepOffsetAPI_MakePipe.hxx>
|
||||
#include <BRepOffsetAPI_MakePipeShell.hxx>
|
||||
#include <BRepOffsetAPI_MakeThickSolid.hxx>
|
||||
#include <BRepOffsetAPI_ThruSections.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
|
||||
void register_BRepOffsetAPI(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepOffsetAPI");
|
||||
|
||||
nb::class_<BRepOffsetAPI_ThruSections, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepOffsetAPI_ThruSections")
|
||||
.def(nb::init<const Standard_Boolean, const Standard_Boolean,
|
||||
const Standard_Real>(),
|
||||
"isSolid"_a = Standard_False, "ruled"_a = Standard_False,
|
||||
"pres3d"_a = 1.0e-06)
|
||||
.def("AddWire", &BRepOffsetAPI_ThruSections::AddWire, "wire"_a)
|
||||
.def("CheckCompatibility",
|
||||
&BRepOffsetAPI_ThruSections::CheckCompatibility, "check"_a = true);
|
||||
|
||||
nb::class_<BRepOffsetAPI_MakePipe, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepOffsetAPI_MakePipe")
|
||||
.def(nb::init<const TopoDS_Wire &, const TopoDS_Shape &>(), "Spine"_a,
|
||||
"Profile"_a, OCP_NOGIL);
|
||||
|
||||
nb::class_<BRepOffsetAPI_MakePipeShell, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepOffsetAPI_MakePipeShell")
|
||||
.def(nb::init<const TopoDS_Wire &>(), "Spine"_a)
|
||||
.def("SetMode",
|
||||
nb::overload_cast<const Standard_Boolean>(
|
||||
&BRepOffsetAPI_MakePipeShell::SetMode),
|
||||
"IsFrenet"_a = Standard_False)
|
||||
.def("Add",
|
||||
nb::overload_cast<const TopoDS_Shape &, const Standard_Boolean,
|
||||
const Standard_Boolean>(
|
||||
&BRepOffsetAPI_MakePipeShell::Add),
|
||||
"Profile"_a, "WithContact"_a = Standard_False,
|
||||
"WithCorrection"_a = Standard_False)
|
||||
.def("MakeSolid", &BRepOffsetAPI_MakePipeShell::MakeSolid, OCP_NOGIL);
|
||||
|
||||
nb::class_<BRepOffsetAPI_MakeThickSolid, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepOffsetAPI_MakeThickSolid")
|
||||
.def(nb::init<>())
|
||||
.def("MakeThickSolidBySimple",
|
||||
&BRepOffsetAPI_MakeThickSolid::MakeThickSolidBySimple, "theS"_a,
|
||||
"theOffsetValue"_a, OCP_NOGIL)
|
||||
// The trailing mode/join arguments are left off: they are enums the
|
||||
// app never overrides, and an unregistered enum used as a default
|
||||
// argument fails at module-init time. OCCT's own defaults apply.
|
||||
.def(
|
||||
"MakeThickSolidByJoin",
|
||||
[](BRepOffsetAPI_MakeThickSolid &self, const TopoDS_Shape &S,
|
||||
const TopTools_ListOfShape &ClosingFaces,
|
||||
const Standard_Real Offset, const Standard_Real Tol) {
|
||||
self.MakeThickSolidByJoin(S, ClosingFaces, Offset, Tol);
|
||||
},
|
||||
"S"_a, "ClosingFaces"_a, "Offset"_a, "Tol"_a, OCP_NOGIL);
|
||||
|
||||
nb::class_<BRepOffsetAPI_DraftAngle, BRepBuilderAPI_MakeShape>(
|
||||
m, "BRepOffsetAPI_DraftAngle")
|
||||
.def(nb::init<const TopoDS_Shape &>(), "S"_a)
|
||||
.def("Add", &BRepOffsetAPI_DraftAngle::Add, "F"_a, "D"_a, "Angle"_a,
|
||||
"NeutralPlane"_a, "Flag"_a = Standard_True)
|
||||
.def("AddDone", &BRepOffsetAPI_DraftAngle::AddDone)
|
||||
.def("Remove", &BRepOffsetAPI_DraftAngle::Remove, "F"_a);
|
||||
}
|
||||
70
src/modules/mod_BRepTools.cpp
Normal file
70
src/modules/mod_BRepTools.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
OCP.BRepTools — assorted topology utilities.
|
||||
|
||||
Clean drops an existing triangulation, which the tessellation path does
|
||||
before re-meshing at a different deflection (OCCT keeps whatever mesh a
|
||||
shape already carries, so without this the second pass is a no-op).
|
||||
OuterWire and UVBounds are queries; WireExplorer walks a wire's edges in
|
||||
connection order rather than map order, which is what wire-following code
|
||||
needs.
|
||||
|
||||
UVBounds reports four scalar out-parameters, so it returns a tuple —
|
||||
upstream does the same, and `umin, umax, vmin, vmax = ...` is how the app
|
||||
calls it.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <nanobind/stl/tuple.h>
|
||||
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
void register_BRepTools(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "BRepTools");
|
||||
|
||||
nb::class_<BRepTools_WireExplorer>(m, "BRepTools_WireExplorer")
|
||||
.def(nb::init<>())
|
||||
.def(nb::init<const TopoDS_Wire &>(), "W"_a)
|
||||
.def(nb::init<const TopoDS_Wire &, const TopoDS_Face &>(), "W"_a, "F"_a)
|
||||
.def("Init", nb::overload_cast<const TopoDS_Wire &>(
|
||||
&BRepTools_WireExplorer::Init),
|
||||
"W"_a)
|
||||
.def("More", &BRepTools_WireExplorer::More)
|
||||
.def("Next", &BRepTools_WireExplorer::Next)
|
||||
.def("Current", &BRepTools_WireExplorer::Current, OCP_RETURN_COPY)
|
||||
.def("Orientation", &BRepTools_WireExplorer::Orientation)
|
||||
.def("CurrentVertex", &BRepTools_WireExplorer::CurrentVertex,
|
||||
OCP_RETURN_COPY)
|
||||
.def("Clear", &BRepTools_WireExplorer::Clear);
|
||||
|
||||
nb::class_<BRepTools> cls(m, "BRepTools");
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "Clean",
|
||||
[](const TopoDS_Shape &S, const Standard_Boolean force) {
|
||||
BRepTools::Clean(S, force);
|
||||
},
|
||||
"S"_a, "force"_a = Standard_False, OCP_NOGIL);
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "OuterWire",
|
||||
[](const TopoDS_Face &F) { return BRepTools::OuterWire(F); }, "F"_a);
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "UVBounds",
|
||||
[](const TopoDS_Face &F) {
|
||||
Standard_Real umin = 0.0, umax = 0.0, vmin = 0.0, vmax = 0.0;
|
||||
BRepTools::UVBounds(F, umin, umax, vmin, vmax);
|
||||
return std::make_tuple(umin, umax, vmin, vmax);
|
||||
},
|
||||
"F"_a);
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "Update",
|
||||
[](const TopoDS_Shape &S) { BRepTools::Update(S); }, "S"_a);
|
||||
}
|
||||
30
src/modules/mod_GCE2d.cpp
Normal file
30
src/modules/mod_GCE2d.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
OCP.GCE2d — 2D geometry constructors.
|
||||
|
||||
Used to lay curves out in a surface's UV space before lifting them onto it
|
||||
with BRepBuilderAPI_MakeEdge: a thread's helix is a straight line in the
|
||||
cylinder's parameter space, and curved text emboss draws its glyph
|
||||
outlines the same way.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
|
||||
#include <GCE2d_MakeLine.hxx>
|
||||
#include <GCE2d_MakeSegment.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
void register_GCE2d(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "GCE2d");
|
||||
|
||||
nb::class_<GCE2d_MakeLine>(m, "GCE2d_MakeLine")
|
||||
.def(nb::init<const gp_Pnt2d &, const gp_Dir2d &>(), "P"_a, "V"_a)
|
||||
.def(nb::init<const gp_Pnt2d &, const gp_Pnt2d &>(), "P1"_a, "P2"_a)
|
||||
.def("IsDone", &GCE2d_MakeLine::IsDone)
|
||||
.def("Value", &GCE2d_MakeLine::Value);
|
||||
|
||||
nb::class_<GCE2d_MakeSegment>(m, "GCE2d_MakeSegment")
|
||||
.def(nb::init<const gp_Pnt2d &, const gp_Pnt2d &>(), "P1"_a, "P2"_a)
|
||||
.def("IsDone", &GCE2d_MakeSegment::IsDone)
|
||||
.def("Value", &GCE2d_MakeSegment::Value);
|
||||
}
|
||||
61
src/modules/mod_GCPnts.cpp
Normal file
61
src/modules/mod_GCPnts.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
OCP.GCPnts — curve discretisation.
|
||||
|
||||
TangentialDeflection is what turns every model edge into the polyline the
|
||||
viewport draws, so it runs once per edge on every tessellation; AbscissaPoint
|
||||
measures arc length for the edge anchors. Both take an Adaptor3d_Curve,
|
||||
whose methods are bound on the base in mod_Adaptor3d.cpp.
|
||||
|
||||
The constructors compute — there is no deferred form — so they bind as
|
||||
stock does.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <Adaptor3d_Curve.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
#include <GCPnts_TangentialDeflection.hxx>
|
||||
#include <GCPnts_UniformDeflection.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
void register_GCPnts(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "GCPnts");
|
||||
|
||||
nb::class_<GCPnts_TangentialDeflection>(m, "GCPnts_TangentialDeflection")
|
||||
.def(nb::init<const Adaptor3d_Curve &, const Standard_Real,
|
||||
const Standard_Real, const Standard_Integer,
|
||||
const Standard_Real, const Standard_Real>(),
|
||||
"C"_a, "AngularDeflection"_a, "CurvatureDeflection"_a,
|
||||
"MinimumOfPoints"_a = 2, "UTol"_a = 1.0e-9,
|
||||
"theMinLen"_a = 1.0e-7, OCP_NOGIL)
|
||||
.def("NbPoints", &GCPnts_TangentialDeflection::NbPoints)
|
||||
.def("Value", &GCPnts_TangentialDeflection::Value, "I"_a,
|
||||
OCP_RETURN_COPY)
|
||||
.def("Parameter", &GCPnts_TangentialDeflection::Parameter, "I"_a);
|
||||
|
||||
nb::class_<GCPnts_UniformDeflection>(m, "GCPnts_UniformDeflection")
|
||||
.def(nb::init<>())
|
||||
.def(nb::init<const Adaptor3d_Curve &, const Standard_Real,
|
||||
const Standard_Boolean>(),
|
||||
"C"_a, "Deflection"_a, "WithControl"_a = Standard_True, OCP_NOGIL)
|
||||
.def("IsDone", &GCPnts_UniformDeflection::IsDone)
|
||||
.def("NbPoints", &GCPnts_UniformDeflection::NbPoints)
|
||||
.def("Value", &GCPnts_UniformDeflection::Value, "Index"_a,
|
||||
OCP_RETURN_COPY)
|
||||
.def("Parameter", &GCPnts_UniformDeflection::Parameter, "Index"_a);
|
||||
|
||||
nb::class_<GCPnts_AbscissaPoint> abscissa(m, "GCPnts_AbscissaPoint");
|
||||
abscissa.def(nb::init<>());
|
||||
OCP_DEF_S(
|
||||
abscissa, "Length",
|
||||
[](const Adaptor3d_Curve &C) { return GCPnts_AbscissaPoint::Length(C); },
|
||||
"C"_a, OCP_NOGIL);
|
||||
OCP_DEF_S(
|
||||
abscissa, "Length",
|
||||
[](const Adaptor3d_Curve &C, const Standard_Real U1,
|
||||
const Standard_Real U2) {
|
||||
return GCPnts_AbscissaPoint::Length(C, U1, U2);
|
||||
},
|
||||
"C"_a, "U1"_a, "U2"_a, OCP_NOGIL);
|
||||
}
|
||||
42
src/modules/mod_IntCurvesFace.cpp
Normal file
42
src/modules/mod_IntCurvesFace.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
OCP.IntCurvesFace — ray casting against a shape.
|
||||
|
||||
The surface-pattern feature fires a ray from each sample point along the
|
||||
inverted normal to find the opposite wall, which is how it measures local
|
||||
wall thickness. Load prepares the shape once; PerformNearest runs per ray
|
||||
inside a Python loop, so both release the GIL but neither is a long call.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <IntCurvesFace_ShapeIntersector.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
void register_IntCurvesFace(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "IntCurvesFace");
|
||||
|
||||
nb::class_<IntCurvesFace_ShapeIntersector>(m,
|
||||
"IntCurvesFace_ShapeIntersector")
|
||||
.def(nb::init<>())
|
||||
.def("Load", &IntCurvesFace_ShapeIntersector::Load, "Sh"_a, "Tol"_a,
|
||||
OCP_NOGIL)
|
||||
.def("PerformNearest",
|
||||
nb::overload_cast<const gp_Lin &, const Standard_Real,
|
||||
const Standard_Real>(
|
||||
&IntCurvesFace_ShapeIntersector::PerformNearest),
|
||||
"L"_a, "PInf"_a, "PSup"_a, OCP_NOGIL)
|
||||
.def("Perform",
|
||||
nb::overload_cast<const gp_Lin &, const Standard_Real,
|
||||
const Standard_Real>(
|
||||
&IntCurvesFace_ShapeIntersector::Perform),
|
||||
"L"_a, "PInf"_a, "PSup"_a, OCP_NOGIL)
|
||||
.def("IsDone", &IntCurvesFace_ShapeIntersector::IsDone)
|
||||
.def("NbPnt", &IntCurvesFace_ShapeIntersector::NbPnt)
|
||||
.def("Pnt", &IntCurvesFace_ShapeIntersector::Pnt, "I"_a, OCP_RETURN_COPY)
|
||||
.def("WParameter", &IntCurvesFace_ShapeIntersector::WParameter, "I"_a)
|
||||
.def("Face", &IntCurvesFace_ShapeIntersector::Face, "I"_a,
|
||||
OCP_RETURN_COPY);
|
||||
}
|
||||
61
src/modules/mod_ShapeAnalysis.cpp
Normal file
61
src/modules/mod_ShapeAnalysis.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
OCP.ShapeAnalysis — free-boundary detection.
|
||||
|
||||
One use: import health counts the edges bounding a single face after a
|
||||
virtual sew, which is how it tells a watertight solid from a holed shell.
|
||||
|
||||
ConnectEdgesToWires is the one place upstream's holder semantics and this
|
||||
binding's caster differ observably. Its `wires` parameter is a
|
||||
Handle& that the function *reassigns*, and the caster hands C++ a copy of
|
||||
the handle rather than a reference into the Python instance — so the
|
||||
reassignment would be invisible. The lambda splices the result back into
|
||||
the sequence the caller passed, preserving the pass-empty-then-read shape
|
||||
the app uses.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
void register_ShapeAnalysis(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "ShapeAnalysis");
|
||||
|
||||
nb::class_<ShapeAnalysis_FreeBounds> cls(m, "ShapeAnalysis_FreeBounds");
|
||||
cls.def(nb::init<>())
|
||||
.def(nb::init<const TopoDS_Shape &, const Standard_Real,
|
||||
const Standard_Boolean, const Standard_Boolean>(),
|
||||
"shape"_a, "toler"_a, "splitclosed"_a = Standard_False,
|
||||
"splitopen"_a = Standard_True, OCP_NOGIL)
|
||||
.def(nb::init<const TopoDS_Shape &, const Standard_Boolean,
|
||||
const Standard_Boolean, const Standard_Boolean>(),
|
||||
"shape"_a, "splitclosed"_a = Standard_False,
|
||||
"splitopen"_a = Standard_True,
|
||||
"checkinternaledges"_a = Standard_False, OCP_NOGIL)
|
||||
.def("GetClosedWires", &ShapeAnalysis_FreeBounds::GetClosedWires,
|
||||
OCP_RETURN_COPY)
|
||||
.def("GetOpenWires", &ShapeAnalysis_FreeBounds::GetOpenWires,
|
||||
OCP_RETURN_COPY);
|
||||
|
||||
OCP_DEF_S(
|
||||
cls, "ConnectEdgesToWires",
|
||||
[](opencascade::handle<TopTools_HSequenceOfShape> &edges,
|
||||
const Standard_Real toler, const Standard_Boolean shared,
|
||||
opencascade::handle<TopTools_HSequenceOfShape> &wires) {
|
||||
opencascade::handle<TopTools_HSequenceOfShape> out;
|
||||
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, toler, shared,
|
||||
out);
|
||||
// The caller keeps its own sequence object; fill that rather than
|
||||
// rebinding a handle it cannot see.
|
||||
if (!wires.IsNull()) {
|
||||
wires->Clear();
|
||||
if (!out.IsNull()) {
|
||||
wires->Append(out->ChangeSequence());
|
||||
}
|
||||
}
|
||||
},
|
||||
"edges"_a, "toler"_a, "shared"_a, "wires"_a, OCP_NOGIL);
|
||||
}
|
||||
63
src/modules/mod_ShapeFix.cpp
Normal file
63
src/modules/mod_ShapeFix.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
OCP.ShapeFix — geometry healing.
|
||||
|
||||
Used on imported geometry and after the operations that are known to
|
||||
produce slightly invalid output (curved text emboss, thickened sheets).
|
||||
These are transients, so their constructors go through ocp_new.
|
||||
|
||||
Perform() is where the work happens, not Build(), so that is what releases
|
||||
the GIL.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
#include "../common/occt_transient.h"
|
||||
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Shell.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
|
||||
void register_ShapeFix(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "ShapeFix");
|
||||
|
||||
nb::class_<ShapeFix_Shape, Standard_Transient>(m, "ShapeFix_Shape")
|
||||
.def(ocp_new<ShapeFix_Shape>())
|
||||
.def(ocp_new<ShapeFix_Shape, const TopoDS_Shape &>(), "shape"_a)
|
||||
.def("Init", nb::overload_cast<const TopoDS_Shape &>(&ShapeFix_Shape::Init),
|
||||
"shape"_a)
|
||||
.def(
|
||||
"Perform", [](ShapeFix_Shape &self) { return self.Perform(); },
|
||||
OCP_NOGIL)
|
||||
.def("Shape", &ShapeFix_Shape::Shape, OCP_RETURN_COPY)
|
||||
.def("SetPrecision", &ShapeFix_Shape::SetPrecision, "preci"_a)
|
||||
.def("SetMinTolerance", &ShapeFix_Shape::SetMinTolerance, "mintol"_a)
|
||||
.def("SetMaxTolerance", &ShapeFix_Shape::SetMaxTolerance, "maxtol"_a);
|
||||
|
||||
nb::class_<ShapeFix_Face, Standard_Transient>(m, "ShapeFix_Face")
|
||||
.def(ocp_new<ShapeFix_Face>())
|
||||
.def(ocp_new<ShapeFix_Face, const TopoDS_Face &>(), "face"_a)
|
||||
.def(
|
||||
"Perform", [](ShapeFix_Face &self) { return self.Perform(); },
|
||||
OCP_NOGIL)
|
||||
.def("FixOrientation",
|
||||
nb::overload_cast<>(&ShapeFix_Face::FixOrientation), OCP_NOGIL)
|
||||
.def("Face", &ShapeFix_Face::Face, OCP_RETURN_COPY);
|
||||
|
||||
nb::class_<ShapeFix_Solid, Standard_Transient>(m, "ShapeFix_Solid")
|
||||
.def(ocp_new<ShapeFix_Solid>())
|
||||
.def(ocp_new<ShapeFix_Solid, const TopoDS_Solid &>(), "solid"_a)
|
||||
.def(
|
||||
"Perform", [](ShapeFix_Solid &self) { return self.Perform(); },
|
||||
OCP_NOGIL)
|
||||
.def(
|
||||
"SolidFromShell",
|
||||
[](ShapeFix_Solid &self, const TopoDS_Shell &shell) {
|
||||
return self.SolidFromShell(shell);
|
||||
},
|
||||
"shell"_a, OCP_RETURN_COPY, OCP_NOGIL)
|
||||
.def("Shape", &ShapeFix_Solid::Shape, OCP_RETURN_COPY);
|
||||
}
|
||||
35
src/modules/mod_ShapeUpgrade.cpp
Normal file
35
src/modules/mod_ShapeUpgrade.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
OCP.ShapeUpgrade — merge faces and edges that share a surface.
|
||||
|
||||
The app runs this after almost every fuse, so a bidirectional extrude ends
|
||||
up with the face count of a single prism rather than two prisms glued at
|
||||
the sketch plane. Not a MakeShape, so Build/Shape are its own.
|
||||
*/
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
#include "../common/occt_transient.h"
|
||||
|
||||
#include <ShapeUpgrade_UnifySameDomain.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
void register_ShapeUpgrade(nb::module_ &root) {
|
||||
nb::module_ m = ocp_submodule(root, "ShapeUpgrade");
|
||||
|
||||
nb::class_<ShapeUpgrade_UnifySameDomain, Standard_Transient>(
|
||||
m, "ShapeUpgrade_UnifySameDomain")
|
||||
.def(ocp_new<ShapeUpgrade_UnifySameDomain>())
|
||||
.def(ocp_new<ShapeUpgrade_UnifySameDomain, const TopoDS_Shape &,
|
||||
const Standard_Boolean, const Standard_Boolean,
|
||||
const Standard_Boolean>(),
|
||||
"aShape"_a, "UnifyEdges"_a = Standard_True,
|
||||
"UnifyFaces"_a = Standard_True,
|
||||
"ConcatBSplines"_a = Standard_False)
|
||||
.def("Initialize", &ShapeUpgrade_UnifySameDomain::Initialize, "aShape"_a,
|
||||
"UnifyEdges"_a = Standard_True, "UnifyFaces"_a = Standard_True,
|
||||
"ConcatBSplines"_a = Standard_False)
|
||||
.def("SetSafeInputMode", &ShapeUpgrade_UnifySameDomain::SetSafeInputMode,
|
||||
"theValue"_a)
|
||||
.def("Build", &ShapeUpgrade_UnifySameDomain::Build, OCP_NOGIL)
|
||||
.def("Shape", &ShapeUpgrade_UnifySameDomain::Shape, OCP_RETURN_COPY);
|
||||
}
|
||||
@@ -10,11 +10,13 @@
|
||||
|
||||
#include "../common/occt_module.h"
|
||||
#include "../common/occt_policies.h"
|
||||
#include "../common/occt_transient.h"
|
||||
|
||||
#include <nanobind/make_iterator.h>
|
||||
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
|
||||
void register_TopTools(nb::module_ &root) {
|
||||
@@ -97,4 +99,26 @@ void register_TopTools(nb::module_ &root) {
|
||||
self.Clear(Standard_True);
|
||||
})
|
||||
.def("__len__", &TopTools_IndexedDataMapOfShapeListOfShape::Size);
|
||||
|
||||
// A transient sequence, unlike the maps above — ShapeAnalysis_FreeBounds
|
||||
// takes and returns it by handle.
|
||||
nb::class_<TopTools_HSequenceOfShape, Standard_Transient>(
|
||||
m, "TopTools_HSequenceOfShape")
|
||||
.def(ocp_new<TopTools_HSequenceOfShape>())
|
||||
.def(
|
||||
"Append",
|
||||
[](TopTools_HSequenceOfShape &self, const TopoDS_Shape &item) {
|
||||
self.Append(item);
|
||||
},
|
||||
"theItem"_a)
|
||||
.def("Length", &TopTools_HSequenceOfShape::Length)
|
||||
.def("IsEmpty", &TopTools_HSequenceOfShape::IsEmpty)
|
||||
.def(
|
||||
"Value",
|
||||
[](const TopTools_HSequenceOfShape &self, Standard_Integer index) {
|
||||
return self.Value(index);
|
||||
},
|
||||
"theIndex"_a, OCP_RETURN_COPY)
|
||||
.def("Clear", [](TopTools_HSequenceOfShape &self) { self.Clear(); })
|
||||
.def("__len__", &TopTools_HSequenceOfShape::Length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user