Binds the modeling core the app builds every feature out of — 93 of its 138 symbols now resolve, up from 34. New modules: GeomAbs, Geom2d, Geom, TCollection, TColgp, TColStd, GProp, BRepGProp, Bnd, BRepBndLib, Adaptor3d, BRepAdaptor, GeomLProp, GeomAPI, BRepBuilderAPI, BOPAlgo, BRepAlgoAPI, BRepPrimAPI, GC, BRepMesh; gp and BRep_Tool completed. Three structural decisions: - BRepBuilderAPI_MakeShape carries Build/Shape/Generated/Modified/IsDeleted for every maker in the binding, so the booleans, the primitives and (later) the fillet builders all answer the app's duck-typed provenance layer through ordinary virtual dispatch. History lists come back copied, so they outlive the builder. - The executing two-argument BRepAlgoAPI constructors stay unbound; operands go in through SetArguments/SetTools. Section keeps Init1/Init2, which are plain setters. BOPAlgo moved up from Inc 2 — SetGlue needs its enum. - Adaptor3d is registered although the app never imports it: every method it calls on BRepAdaptor_Curve/Surface is a virtual declared there, so binding them once on the bases leaves mod_BRepAdaptor.cpp with just constructors. Gate: tests/test_inc1_modeling.py against reference values gen_fixtures.py now records from the stock wheel — measurements, per-face area/centroid in map order, mesh counts, and the boolean history map compared exactly, since that is the substrate the app's topological naming is built on. tools/sigdiff.py compares our bound surface against stock's, because a wrong nb::init<> is silent: MakePrism's five-argument form bound OCCT's semi-infinite gp_Dir overload (gp_Dir converts from gp_Vec), producing a valid solid of the wrong shape with the flags shifted along. The fixture digest caught it; sigdiff finds the class of bug directly, and now reports only one deliberate deviation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfriM8XUkn7uYf5Dwe2xo6
88 lines
3.9 KiB
C++
88 lines
3.9 KiB
C++
/*
|
|
OCP.Geom — the analytic curves and surfaces behind the topology.
|
|
|
|
The app imports only three of these, but it *receives* the two abstract
|
|
bases: BRep_Tool.Surface_s hands back a Handle(Geom_Surface), and
|
|
GC_MakeArcOfCircle a Handle(Geom_TrimmedCurve), both of which then travel
|
|
into BRepBuilderAPI_MakeEdge/MakeFace. So the bases have to be registered
|
|
for those returns to convert, and the concrete leaves for the constructors
|
|
the app calls.
|
|
|
|
Deliberately partial: the concrete subclasses OCCT may hand back
|
|
(Geom_Plane, Geom_Circle, ...) are not registered, so such a return arrives
|
|
as its static type, Geom_Surface. That is fine here — the app reads
|
|
surface *kinds* off BRepAdaptor_Surface, never off the Geom object, and no
|
|
call site does DownCast or isinstance on one. Add a leaf the day one does.
|
|
|
|
Surface_s returns the face's live surface when the location is identity, a
|
|
transformed copy otherwise; the handle caster wraps whatever OCCT gives
|
|
back without copying, which is upstream's behaviour too.
|
|
*/
|
|
|
|
#include "../common/occt_module.h"
|
|
#include "../common/occt_policies.h"
|
|
#include "../common/occt_transient.h"
|
|
|
|
#include <Geom_BSplineCurve.hxx>
|
|
#include <Geom_BSplineSurface.hxx>
|
|
#include <Geom_CylindricalSurface.hxx>
|
|
#include <Geom_OffsetSurface.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <Geom_TrimmedCurve.hxx>
|
|
#include <TColStd_Array1OfInteger.hxx>
|
|
#include <TColStd_Array1OfReal.hxx>
|
|
#include <TColgp_Array1OfPnt.hxx>
|
|
#include <gp_Ax3.hxx>
|
|
#include <gp_Pnt.hxx>
|
|
|
|
void register_Geom(nb::module_ &root) {
|
|
nb::module_ m = ocp_submodule(root, "Geom");
|
|
|
|
// ------------------------------------------------------------ curves --
|
|
|
|
nb::class_<Geom_Curve, Standard_Transient>(m, "Geom_Curve")
|
|
.def("FirstParameter", &Geom_Curve::FirstParameter)
|
|
.def("LastParameter", &Geom_Curve::LastParameter)
|
|
.def("IsClosed", &Geom_Curve::IsClosed)
|
|
.def("IsPeriodic", &Geom_Curve::IsPeriodic)
|
|
.def("Value", &Geom_Curve::Value, "U"_a, OCP_RETURN_COPY);
|
|
|
|
nb::class_<Geom_TrimmedCurve, Geom_Curve>(m, "Geom_TrimmedCurve");
|
|
|
|
nb::class_<Geom_BSplineCurve, Geom_Curve>(m, "Geom_BSplineCurve")
|
|
.def(ocp_new<Geom_BSplineCurve, const TColgp_Array1OfPnt &,
|
|
const TColStd_Array1OfReal &,
|
|
const TColStd_Array1OfInteger &, const Standard_Integer,
|
|
const Standard_Boolean>(),
|
|
"Poles"_a, "Knots"_a, "Multiplicities"_a, "Degree"_a,
|
|
"Periodic"_a = Standard_False)
|
|
.def("Degree", &Geom_BSplineCurve::Degree)
|
|
.def("NbPoles", &Geom_BSplineCurve::NbPoles)
|
|
.def("NbKnots", &Geom_BSplineCurve::NbKnots);
|
|
|
|
// ---------------------------------------------------------- surfaces --
|
|
|
|
nb::class_<Geom_Surface, Standard_Transient>(m, "Geom_Surface")
|
|
.def("Value", &Geom_Surface::Value, "U"_a, "V"_a, OCP_RETURN_COPY)
|
|
.def("IsUPeriodic", &Geom_Surface::IsUPeriodic)
|
|
.def("IsVPeriodic", &Geom_Surface::IsVPeriodic)
|
|
.def("IsUClosed", &Geom_Surface::IsUClosed)
|
|
.def("IsVClosed", &Geom_Surface::IsVClosed);
|
|
|
|
nb::class_<Geom_BSplineSurface, Geom_Surface>(m, "Geom_BSplineSurface");
|
|
|
|
nb::class_<Geom_CylindricalSurface, Geom_Surface>(m,
|
|
"Geom_CylindricalSurface")
|
|
.def(ocp_new<Geom_CylindricalSurface, const gp_Ax3 &,
|
|
const Standard_Real>(),
|
|
"A3"_a, "Radius"_a)
|
|
.def("Radius", &Geom_CylindricalSurface::Radius);
|
|
|
|
nb::class_<Geom_OffsetSurface, Geom_Surface>(m, "Geom_OffsetSurface")
|
|
.def(ocp_new<Geom_OffsetSurface, const opencascade::handle<Geom_Surface> &,
|
|
const Standard_Real, const Standard_Boolean>(),
|
|
"S"_a, "Offset"_a, "isNotCheckC0"_a = Standard_False)
|
|
.def("Offset", &Geom_OffsetSurface::Offset)
|
|
.def("BasisSurface", &Geom_OffsetSurface::BasisSurface);
|
|
}
|