Merge branch 'main' of https://github.com/FreeCAD/FreeCAD.git into toponamingTopoShapeWire

# Conflicts:
#	src/Mod/Part/App/TopoShape.h
#	src/Mod/Part/App/TopoShapeExpansion.cpp
This commit is contained in:
CalligaroV
2024-02-07 23:51:49 +01:00
142 changed files with 7035 additions and 3003 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -65,18 +65,26 @@
#include <Base/Persistence.h>
#include <Base/Vector3D.h>
#include <Mod/Part/PartGlobal.h>
#include <BRepAdaptor_Surface.hxx>
#include "GeometryExtension.h"
namespace Part {
enum KeepTag
{
NewTag, // Assign a new tag
CopyTag // Keep the existing tag
};
class PartExport Geometry: public Base::Persistence
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
~Geometry() override;
static std::unique_ptr<Geometry> fromShape(const TopoDS_Shape &s, bool silent=false);
virtual TopoDS_Shape toShape() const = 0;
virtual const Handle(Geom_Geometry)& handle() const = 0;
// Persistence implementer ---------------------
@@ -97,6 +105,9 @@ public:
/// returns the tag of the geometry object
boost::uuids::uuid getTag() const;
virtual bool isSame(const Geometry &other, double tol, double atol) const = 0;
bool hasSameExtensions(const Geometry &other) const;
std::vector<std::weak_ptr<const GeometryExtension>> getExtensions() const;
bool hasExtension(const Base::Type & type) const;
@@ -109,12 +120,12 @@ public:
void deleteExtension(const Base::Type & type);
void deleteExtension(const std::string & name);
void mirror(const Base::Vector3d& point);
void mirror(const Base::Vector3d& point, const Base::Vector3d& dir);
void rotate(const Base::Placement& plm);
void scale(const Base::Vector3d& vec, double scale);
void transform(const Base::Matrix4D& mat);
void translate(const Base::Vector3d& vec);
void mirror(const Base::Vector3d& point) const;
void mirror(const Base::Vector3d& point, const Base::Vector3d& dir) const;
void rotate(const Base::Placement& plm) const;
void scale(const Base::Vector3d& vec, double scale) const;
void transform(const Base::Matrix4D& mat) const;
void translate(const Base::Vector3d& vec) const;
protected:
/// create a new tag for the geometry object
@@ -141,8 +152,8 @@ class PartExport GeomPoint : public Geometry
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomPoint();
GeomPoint(const Handle(Geom_CartesianPoint)&);
GeomPoint(const Base::Vector3d&);
explicit GeomPoint(const Handle(Geom_CartesianPoint)&);
explicit GeomPoint(const Base::Vector3d&);
~GeomPoint() override;
Geometry *copy() const override;
TopoDS_Shape toShape() const override;
@@ -152,8 +163,15 @@ public:
void Save(Base::Writer &/*writer*/) const override;
void Restore(Base::XMLReader &/*reader*/) override;
// Base implementer ----------------------------
PyObject *getPyObject() override;
PyObject* getPyObject() override;
/**
* Compare this point to another one.
* @param other Other geometry point. Can pass in Other geometry types but will not match
* @param tol Points meed to be within tol^2 to match.
* @param atol Angle tolerance is not used for points.
* @return True if a match is found.
*/
bool isSame(const Geometry& other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override;
void setHandle(const Handle(Geom_CartesianPoint)&);
@@ -165,6 +183,9 @@ private:
};
class GeomBSplineCurve;
class GeomLine;
class GeomLineSegment;
class PartExport GeomCurve : public Geometry
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
@@ -172,6 +193,9 @@ public:
GeomCurve();
~GeomCurve() override;
static bool isLinear(const Handle(Geom_Curve) &c, Base::Vector3d *dir = nullptr, Base::Vector3d *base = nullptr);
bool isLinear(Base::Vector3d *dir = nullptr, Base::Vector3d *base = nullptr) const;
TopoDS_Shape toShape() const override;
/*!
* \brief toBSpline Converts the curve to a B-spline
@@ -207,8 +231,11 @@ public:
Base::Vector3d value(double u) const;
GeomLine* toLine(KeepTag clone = CopyTag) const;
GeomLineSegment* toLineSegment(KeepTag clone = CopyTag) const;
protected:
static bool intersect(const Handle(Geom_Curve) c, const Handle(Geom_Curve) c2,
static bool intersect(const Handle(Geom_Curve)& c, const Handle(Geom_Curve)& c2,
std::vector<std::pair<Base::Vector3d, Base::Vector3d>>& points,
double tol = Precision::Confusion());
};
@@ -230,7 +257,7 @@ class PartExport GeomBezierCurve : public GeomBoundedCurve
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomBezierCurve();
GeomBezierCurve(const Handle(Geom_BezierCurve)&);
explicit GeomBezierCurve(const Handle(Geom_BezierCurve)&);
GeomBezierCurve(const std::vector<Base::Vector3d>&, const std::vector<double>&);
~GeomBezierCurve() override;
Geometry *copy() const override;
@@ -242,7 +269,8 @@ public:
void Save (Base::Writer &/*writer*/) const override;
void Restore(Base::XMLReader &/*reader*/) override;
// Base implementer ----------------------------
PyObject *getPyObject() override;
PyObject *getPyObject(void) override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_BezierCurve)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -256,7 +284,7 @@ class PartExport GeomBSplineCurve : public GeomBoundedCurve
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomBSplineCurve();
GeomBSplineCurve(const Handle(Geom_BSplineCurve)&);
explicit GeomBSplineCurve(const Handle(Geom_BSplineCurve)&);
GeomBSplineCurve( const std::vector<Base::Vector3d>& poles, const std::vector<double>& weights,
const std::vector<double>& knots, const std::vector<int>& multiplicities,
@@ -325,7 +353,9 @@ public:
void Save(Base::Writer &/*writer*/) const override;
void Restore(Base::XMLReader &/*reader*/) override;
// Base implementer ----------------------------
PyObject *getPyObject() override;
PyObject *getPyObject(void) override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_BSplineCurve)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -377,6 +407,8 @@ public:
PyObject *getPyObject() override = 0;
GeomBSplineCurve* toNurbs(double first, double last) const override;
bool isSame(const Geometry &other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override = 0;
};
@@ -385,7 +417,7 @@ class PartExport GeomTrimmedCurve : public GeomBoundedCurve
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomTrimmedCurve();
GeomTrimmedCurve(const Handle(Geom_TrimmedCurve)&);
explicit GeomTrimmedCurve(const Handle(Geom_TrimmedCurve)&);
~GeomTrimmedCurve() override;
Geometry *copy() const override;
@@ -394,9 +426,11 @@ public:
void Save(Base::Writer &/*writer*/) const override;
void Restore(Base::XMLReader &/*reader*/) override;
// Base implementer ----------------------------
PyObject *getPyObject() override;
PyObject *getPyObject(void) override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
bool isSame(const Geometry &other, double tol, double atol) const override;
virtual void setHandle(const Handle(Geom_TrimmedCurve)&);
const Handle(Geom_Geometry)& handle() const override;
bool intersectBasisCurves( const GeomTrimmedCurve * c,
@@ -467,7 +501,7 @@ class PartExport GeomCircle : public GeomConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomCircle();
GeomCircle(const Handle(Geom_Circle)&);
explicit GeomCircle(const Handle(Geom_Circle)&);
~GeomCircle() override;
Geometry *copy() const override;
@@ -482,6 +516,8 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
bool isSame(const Geometry &other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override;
void setHandle(const Handle(Geom_Circle)&);
@@ -495,7 +531,7 @@ class PartExport GeomArcOfCircle : public GeomArcOfConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomArcOfCircle();
GeomArcOfCircle(const Handle(Geom_Circle)&);
explicit GeomArcOfCircle(const Handle(Geom_Circle)&);
~GeomArcOfCircle() override;
Geometry *copy() const override;
@@ -515,7 +551,7 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
void setHandle(const Handle(Geom_TrimmedCurve)&) override;
void setHandle(const Handle(Geom_Circle)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -526,7 +562,7 @@ class PartExport GeomEllipse : public GeomConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomEllipse();
GeomEllipse(const Handle(Geom_Ellipse)&);
explicit GeomEllipse(const Handle(Geom_Ellipse)&);
~GeomEllipse() override;
Geometry *copy() const override;
@@ -546,6 +582,8 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_Ellipse) &e);
const Handle(Geom_Geometry)& handle() const override;
@@ -558,7 +596,7 @@ class PartExport GeomArcOfEllipse : public GeomArcOfConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomArcOfEllipse();
GeomArcOfEllipse(const Handle(Geom_Ellipse)&);
explicit GeomArcOfEllipse(const Handle(Geom_Ellipse)&);
~GeomArcOfEllipse() override;
Geometry *copy() const override;
@@ -581,7 +619,7 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
void setHandle(const Handle(Geom_TrimmedCurve)&) override;
void setHandle(const Handle(Geom_Ellipse)&);
const Handle(Geom_Geometry)& handle() const override;
};
@@ -592,7 +630,7 @@ class PartExport GeomHyperbola : public GeomConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomHyperbola();
GeomHyperbola(const Handle(Geom_Hyperbola)&);
explicit GeomHyperbola(const Handle(Geom_Hyperbola)&);
~GeomHyperbola() override;
Geometry *copy() const override;
@@ -609,6 +647,8 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
bool isSame(const Geometry &other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override;
void setHandle(const Handle(Geom_Hyperbola)&);
@@ -621,7 +661,7 @@ class PartExport GeomArcOfHyperbola : public GeomArcOfConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomArcOfHyperbola();
GeomArcOfHyperbola(const Handle(Geom_Hyperbola)&);
explicit GeomArcOfHyperbola(const Handle(Geom_Hyperbola)&);
~GeomArcOfHyperbola() override;
Geometry *copy() const override;
@@ -644,7 +684,7 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
void setHandle(const Handle(Geom_TrimmedCurve)&) override;
void setHandle(const Handle(Geom_Hyperbola)&);
const Handle(Geom_Geometry)& handle() const override;
};
@@ -654,7 +694,7 @@ class PartExport GeomParabola : public GeomConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomParabola();
GeomParabola(const Handle(Geom_Parabola)&);
explicit GeomParabola(const Handle(Geom_Parabola)&);
~GeomParabola() override;
Geometry *copy() const override;
@@ -669,6 +709,8 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
bool isSame(const Geometry &other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override;
void setHandle(const Handle(Geom_Parabola)&);
@@ -681,7 +723,7 @@ class PartExport GeomArcOfParabola : public GeomArcOfConic
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomArcOfParabola();
GeomArcOfParabola(const Handle(Geom_Parabola)&);
explicit GeomArcOfParabola(const Handle(Geom_Parabola)&);
~GeomArcOfParabola() override;
Geometry *copy() const override;
@@ -701,7 +743,7 @@ public:
PyObject *getPyObject() override;
GeomBSplineCurve* toNurbs(double first, double last) const override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
void setHandle(const Handle(Geom_TrimmedCurve)&) override;
void setHandle(const Handle(Geom_Parabola)&);
const Handle(Geom_Geometry)& handle() const override;
};
@@ -711,7 +753,7 @@ class PartExport GeomLine : public GeomCurve
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomLine();
GeomLine(const Handle(Geom_Line)&);
explicit GeomLine(const Handle(Geom_Line)&);
GeomLine(const Base::Vector3d& Pos, const Base::Vector3d& Dir);
~GeomLine() override;
Geometry *copy() const override;
@@ -727,6 +769,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
const Handle(Geom_Geometry)& handle() const override;
void setHandle(const Handle(Geom_Line)&);
@@ -739,7 +783,7 @@ class PartExport GeomLineSegment : public GeomTrimmedCurve
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomLineSegment();
GeomLineSegment(const Handle(Geom_Line)& l);
explicit GeomLineSegment(const Handle(Geom_Line)& l);
~GeomLineSegment() override;
Geometry *copy() const override;
@@ -756,7 +800,7 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
void setHandle(const Handle(Geom_TrimmedCurve)&);
void setHandle(const Handle(Geom_TrimmedCurve)&) override;
void setHandle(const Handle(Geom_Line)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -769,10 +813,13 @@ public:
GeomOffsetCurve();
GeomOffsetCurve(const Handle(Geom_Curve)&, double, const gp_Dir&);
GeomOffsetCurve(const Handle(Geom_Curve)&, double, Base::Vector3d&);
GeomOffsetCurve(const Handle(Geom_OffsetCurve)&);
explicit GeomOffsetCurve(const Handle(Geom_OffsetCurve)&);
~GeomOffsetCurve() override;
Geometry *copy() const override;
Base::Vector3d getDir() const;
double getOffset() const;
// Persistence implementer ---------------------
unsigned int getMemSize() const override;
void Save(Base::Writer &/*writer*/) const override;
@@ -780,6 +827,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_OffsetCurve)& c);
const Handle(Geom_Geometry)& handle() const override;
@@ -787,6 +836,8 @@ private:
Handle(Geom_OffsetCurve) myCurve;
};
class GeomPlane;
class PartExport GeomSurface : public Geometry
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
@@ -801,7 +852,13 @@ public:
GeomSurface();
~GeomSurface() override;
static bool isPlanar(const Handle(Geom_Surface) &s, gp_Pln *pln=nullptr, double tol=1e-7);
bool isPlanar(gp_Pln *pln=nullptr, double tol=1e-7) const;
TopoDS_Shape toShape() const override;
GeomPlane *toPlane(bool clone=true, double tol=1e-7) const;
bool tangentU(double u, double v, gp_Dir& dirU) const;
bool tangentV(double u, double v, gp_Dir& dirV) const;
bool normal(double u, double v, gp_Dir& dir) const;
@@ -824,7 +881,7 @@ class PartExport GeomBezierSurface : public GeomSurface
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomBezierSurface();
GeomBezierSurface(const Handle(Geom_BezierSurface)&);
explicit GeomBezierSurface(const Handle(Geom_BezierSurface)&);
~GeomBezierSurface() override;
Geometry *copy() const override;
@@ -835,6 +892,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_BezierSurface)& b);
const Handle(Geom_Geometry)& handle() const override;
@@ -847,7 +906,7 @@ class PartExport GeomBSplineSurface : public GeomSurface
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomBSplineSurface();
GeomBSplineSurface(const Handle(Geom_BSplineSurface)&);
explicit GeomBSplineSurface(const Handle(Geom_BSplineSurface)&);
~GeomBSplineSurface() override;
Geometry *copy() const override;
@@ -859,6 +918,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_BSplineSurface)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -866,12 +927,30 @@ private:
Handle(Geom_BSplineSurface) mySurface;
};
class PartExport GeomCylinder : public GeomSurface
class PartExport GeomElementarySurface : public GeomSurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
protected:
GeomElementarySurface();
public:
~GeomElementarySurface() override;
Base::Vector3d getLocation() const;
Base::Vector3d getDir() const;
Base::Vector3d getXDir() const;
Base::Vector3d getYDir() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
};
class PartExport GeomCylinder : public GeomElementarySurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomCylinder();
GeomCylinder(const Handle(Geom_CylindricalSurface)&);
explicit GeomCylinder(const Handle(Geom_CylindricalSurface)&);
~GeomCylinder() override;
Geometry *copy() const override;
@@ -882,6 +961,10 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
double getRadius() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_CylindricalSurface)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -889,12 +972,12 @@ private:
Handle(Geom_CylindricalSurface) mySurface;
};
class PartExport GeomCone : public GeomSurface
class PartExport GeomCone : public GeomElementarySurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomCone();
GeomCone(const Handle(Geom_ConicalSurface)&);
explicit GeomCone(const Handle(Geom_ConicalSurface)&);
~GeomCone() override;
Geometry *copy() const override;
@@ -905,6 +988,11 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
double getRadius() const;
double getSemiAngle() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_ConicalSurface)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -915,12 +1003,12 @@ private:
Handle(Geom_ConicalSurface) mySurface;
};
class PartExport GeomSphere : public GeomSurface
class PartExport GeomSphere : public GeomElementarySurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomSphere();
GeomSphere(const Handle(Geom_SphericalSurface)&);
explicit GeomSphere(const Handle(Geom_SphericalSurface)&);
~GeomSphere() override;
Geometry *copy() const override;
@@ -931,6 +1019,10 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
double getRadius(void) const;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_SphericalSurface)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -938,12 +1030,12 @@ private:
Handle(Geom_SphericalSurface) mySurface;
};
class PartExport GeomToroid : public GeomSurface
class PartExport GeomToroid : public GeomElementarySurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomToroid();
GeomToroid(const Handle(Geom_ToroidalSurface)&);
explicit GeomToroid(const Handle(Geom_ToroidalSurface)&);
~GeomToroid() override;
Geometry *copy() const override;
@@ -954,6 +1046,11 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
double getMajorRadius() const;
double getMinorRadius() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_ToroidalSurface)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -961,12 +1058,13 @@ private:
Handle(Geom_ToroidalSurface) mySurface;
};
class PartExport GeomPlane : public GeomSurface
class PartExport GeomPlane : public GeomElementarySurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomPlane();
GeomPlane(const Handle(Geom_Plane)&);
explicit GeomPlane(const Handle(Geom_Plane)&);
explicit GeomPlane(const gp_Pln &pln);
~GeomPlane() override;
Geometry *copy() const override;
@@ -977,6 +1075,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_Plane)&);
const Handle(Geom_Geometry)& handle() const override;
@@ -990,7 +1090,7 @@ class PartExport GeomOffsetSurface : public GeomSurface
public:
GeomOffsetSurface();
GeomOffsetSurface(const Handle(Geom_Surface)&, double);
GeomOffsetSurface(const Handle(Geom_OffsetSurface)&);
explicit GeomOffsetSurface(const Handle(Geom_OffsetSurface)&);
~GeomOffsetSurface() override;
Geometry *copy() const override;
@@ -1001,6 +1101,10 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
double getOffset() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_OffsetSurface)& s);
const Handle(Geom_Geometry)& handle() const override;
@@ -1014,8 +1118,8 @@ class PartExport GeomPlateSurface : public GeomSurface
public:
GeomPlateSurface();
GeomPlateSurface(const Handle(Geom_Surface)&, const Plate_Plate&);
GeomPlateSurface(const GeomPlate_BuildPlateSurface&);
GeomPlateSurface(const Handle(GeomPlate_Surface)&);
explicit GeomPlateSurface(const GeomPlate_BuildPlateSurface&);
explicit GeomPlateSurface(const Handle(GeomPlate_Surface)&);
~GeomPlateSurface() override;
Geometry *copy() const override;
@@ -1026,6 +1130,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(GeomPlate_Surface)& s);
const Handle(Geom_Geometry)& handle() const override;
@@ -1038,7 +1144,7 @@ class PartExport GeomTrimmedSurface : public GeomSurface
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomTrimmedSurface();
GeomTrimmedSurface(const Handle(Geom_RectangularTrimmedSurface)&);
explicit GeomTrimmedSurface(const Handle(Geom_RectangularTrimmedSurface)&);
~GeomTrimmedSurface() override;
Geometry *copy() const override;
@@ -1049,6 +1155,8 @@ public:
// Base implementer ----------------------------
PyObject *getPyObject() override;
bool isSame(const Geometry &other, double tol, double atol) const override;
void setHandle(const Handle(Geom_RectangularTrimmedSurface)& s);
const Handle(Geom_Geometry)& handle() const override;
@@ -1056,13 +1164,28 @@ private:
Handle(Geom_RectangularTrimmedSurface) mySurface;
};
class PartExport GeomSurfaceOfRevolution : public GeomSurface
class PartExport GeomSweptSurface : public GeomSurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
protected:
GeomSweptSurface();
public:
~GeomSweptSurface() override;
Base::Vector3d getDir() const;
bool isSame(const Geometry &other, double tol, double atol) const override;
};
class PartExport GeomSurfaceOfRevolution : public GeomSweptSurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
GeomSurfaceOfRevolution();
GeomSurfaceOfRevolution(const Handle(Geom_Curve)&, const gp_Ax1&);
GeomSurfaceOfRevolution(const Handle(Geom_SurfaceOfRevolution)&);
explicit GeomSurfaceOfRevolution(const Handle(Geom_SurfaceOfRevolution)&);
~GeomSurfaceOfRevolution() override;
Geometry *copy() const override;
@@ -1080,7 +1203,7 @@ private:
Handle(Geom_SurfaceOfRevolution) mySurface;
};
class PartExport GeomSurfaceOfExtrusion : public GeomSurface
class PartExport GeomSurfaceOfExtrusion : public GeomSweptSurface
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
@@ -1127,16 +1250,19 @@ PartExport
GeomArcOfCircle *createFilletGeometry(const GeomLineSegment *lineSeg1, const GeomLineSegment *lineSeg2,
const Base::Vector3d &center, double radius);
PartExport
std::unique_ptr<GeomSurface> makeFromSurface(const Handle(Geom_Surface)&);
std::unique_ptr<GeomSurface> makeFromSurface(const Handle(Geom_Surface)&, bool silent=false);
PartExport
std::unique_ptr<GeomCurve> makeFromCurve(const Handle(Geom_Curve)&);
std::unique_ptr<GeomSurface> makeFromSurfaceAdaptor(const BRepAdaptor_Surface&, bool silent=false);
PartExport
std::unique_ptr<GeomCurve> makeFromTrimmedCurve(const Handle(Geom_Curve)&, double f, double l);
std::unique_ptr<GeomCurve> makeFromCurve(const Handle(Geom_Curve)&, bool silent=false);
PartExport
std::unique_ptr<GeomCurve> makeFromCurveAdaptor(const Adaptor3d_Curve&);
std::unique_ptr<GeomCurve> makeFromTrimmedCurve(const Handle(Geom_Curve)&, double f, double l, bool silent=false);
PartExport
std::unique_ptr<GeomCurve> makeFromCurveAdaptor(const Adaptor3d_Curve&, bool silent=false);
}
#endif // PART_GEOMETRY_H

View File

@@ -78,3 +78,14 @@ void GeometryPersistenceExtension::Restore(Base::XMLReader &reader)
{
restoreAttributes(reader);
}
bool GeometryPersistenceExtension::isSame(const GeometryPersistenceExtension &other) const
{
static Base::StringWriter writer,writer2;
// writer.clear();
Save(writer);
// writer2.clear();
other.Save(writer2);
return writer.getString() == writer2.getString();
}

View File

@@ -75,6 +75,8 @@ public:
void Save(Base::Writer &/*writer*/) const;
void Restore(Base::XMLReader &/*reader*/);
bool isSame(const GeometryPersistenceExtension &other) const;
protected:
virtual void restoreAttributes(Base::XMLReader &/*reader*/);
virtual void saveAttributes(Base::Writer &writer) const;

View File

@@ -150,6 +150,7 @@
#include <BRepFeat_SplitShape.hxx>
#include <BRepFill.hxx>
#include <BRepFill_Filling.hxx>
#include <BRepFill_Generator.hxx>
#include <BRepFilletAPI_MakeChamfer.hxx>
#include <BRepFilletAPI_MakeFillet.hxx>
#include <BRepGProp.hxx>

View File

@@ -4090,12 +4090,15 @@ TopoShape &TopoShape::makeFace(const std::vector<TopoShape> &shapes, const char
return *this;
}
TopoShape &TopoShape::makeRefine(const TopoShape &shape, const char *op, bool no_fail) {
TopoShape &TopoShape::makeRefine(const TopoShape &shape, const char *op, RefineFail no_fail)
{
(void)op;
_Shape.Nullify();
if(shape.isNull()) {
if(!no_fail)
if (no_fail == RefineFail::throwException) {
HANDLE_NULL_SHAPE;
}
return *this;
}
try {
@@ -4103,7 +4106,9 @@ TopoShape &TopoShape::makeRefine(const TopoShape &shape, const char *op, bool no
_Shape = mkRefine.Shape();
return *this;
}catch (Standard_Failure &) {
if(!no_fail) throw;
if(no_fail == RefineFail::throwException ) {
throw;
}
}
*this = shape;
return *this;

View File

@@ -37,7 +37,12 @@
#include <TopoDS_Compound.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BRepBuilderAPI_MakeShape.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>
#include <BRepOffsetAPI_MakePipeShell.hxx>
#include <BRepFeat_MakePrism.hxx>
#include <BRepPrimAPI_MakeHalfSpace.hxx>
class gp_Ax1;
class gp_Ax2;
@@ -106,6 +111,13 @@ enum class HistoryTraceType
followTypeChange
};
/// Behavior of refines when a problem arises; either leave the shape untouched or throw an exception.
/// This replaces a boolean parameter in the original Toponaming branch by realthunder..
enum class RefineFail
{
shapeUntouched,
throwException
};
/** The representation for a CAD Shape
*/
@@ -390,6 +402,7 @@ public:
void sewShape(double tolerance = 1.0e-06);
bool fix();
bool fix(double, double, double);
bool fixSolidOrientation();
bool removeInternalWires(double);
TopoDS_Shape removeSplitter() const;
TopoDS_Shape defeaturing(const std::vector<TopoDS_Shape>& s) const;
@@ -585,9 +598,47 @@ public:
{
return TopoShape().makeGTransform(*this, mat, op, copy);
}
/** Refine the input shape by merging faces/edges that share the same geometry
*
* @param source: input shape
* @param op: optional string to be encoded into topo naming for indicating
* the operation
* @param no_fail: if throwException, throw exception if failed to refine. Or else,
* if shapeUntouched the shape remains untouched if failed.
*
* @return The original content of this TopoShape is discarded and replaced
* with the refined shape. The function returns the TopoShape
* itself as a self reference so that multiple operations can be
* carried out for the same shape in the same line of code.
*/
TopoShape& makeElementRefine(const TopoShape& source,
const char* op = nullptr,
RefineFail no_fail = RefineFail::throwException);
TopoShape& makeRefine(const TopoShape& shape, const char* op = nullptr, bool no_fail = true);
TopoShape makeRefine(const char* op = nullptr, bool no_fail = true) const
/** Refine the input shape by merging faces/edges that share the same geometry
*
* @param source: input shape
* @param op: optional string to be encoded into topo naming for indicating
* the operation
* @param no_fail: if throwException, throw exception if failed to refine. Or else,
* if shapeUntouched the shape remains untouched if failed.
*
* @return Return a refined shape. The shape itself is not modified
*/
TopoShape makeElementRefine(const char* op = nullptr,
RefineFail no_fail = RefineFail::throwException) const
{
return TopoShape(Tag, Hasher).makeElementRefine(*this, op, no_fail);
}
TopoShape& makeRefine(const TopoShape& shape,
const char* op = nullptr,
RefineFail no_fail = RefineFail::throwException);
TopoShape makeRefine(const char* op = nullptr,
RefineFail no_fail = RefineFail::throwException) const
{
return TopoShape().makeRefine(*this, op, no_fail);
}
@@ -879,9 +930,9 @@ public:
* a self reference so that multiple operations can be carried out
* for the same shape in the same line of code.
*/
// TopoShape& makeElementShellFromWires(const std::vector<TopoShape>& wires,
// bool silent = true,
// const char* op = nullptr);
TopoShape& makeElementShellFromWires(const std::vector<TopoShape>& wires,
bool silent = true,
const char* op = nullptr);
/* Make a shell with input wires
*
* @param wires: input wires
@@ -891,10 +942,10 @@ public:
*
* @return Return the new shape. The TopoShape itself is not modified.
*/
// TopoShape& makeElementShellFromWires(bool silent = true, const char* op = nullptr)
// {
// return makeElementShellFromWires(getSubTopoShapes(TopAbs_WIRE), silent, op);
// }
TopoShape& makeElementShellFromWires(bool silent = true, const char* op = nullptr)
{
return makeElementShellFromWires(getSubTopoShapes(TopAbs_WIRE), silent, op);
}
TopoShape& makeElementFace(const std::vector<TopoShape>& shapes,
const char* op = nullptr,
@@ -984,6 +1035,222 @@ public:
CN,
};
/** Generic shape making with mapped element name from shape history
*
* @param mkShape: OCCT shape maker.
* @param sources: list of source shapes.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepBuilderAPI_MakeShape& mkShape,
const std::vector<TopoShape>& sources,
const char* op = nullptr);
/** Generic shape making with mapped element name from shape history
*
* @param mkShape: OCCT shape maker.
* @param source: source shape.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepBuilderAPI_MakeShape& mkShape,
const TopoShape& source,
const char* op = nullptr);
/** Generic shape making with mapped element name from shape history
*
* @param mkShape: OCCT shape maker.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return Returns the new shape built by the shape maker with mappend element
* name generated using this shape as the source. The shape itself
* is not modified.
*/
TopoShape makeElementShape(BRepBuilderAPI_MakeShape& mkShape, const char* op = nullptr) const
{
return TopoShape(0, Hasher).makeElementShape(mkShape, *this, op);
}
/** Specialized shape making for BRepBuilderAPI_Sewing with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param sources: list of source shapes.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepBuilderAPI_Sewing& mkShape,
const std::vector<TopoShape>& sources,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_Sewing with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param source: source shape.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepBuilderAPI_Sewing& mkShape,
const TopoShape& source,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_Sewing with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return Returns the new shape built by the shape maker with mappend element
* name generated using this shape as the source. The shape itself
* is not modified.
*/
TopoShape makeElementShape(BRepBuilderAPI_Sewing& mkShape, const char* op = nullptr) const
{
return TopoShape(0, Hasher).makeElementShape(mkShape, *this, op);
}
/** Specialized shape making for BRepBuilderAPI_ThruSections with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param sources: list of source shapes.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepOffsetAPI_ThruSections& mkShape,
const std::vector<TopoShape>& sources,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_Sewing with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param source: source shape.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepOffsetAPI_ThruSections& mkShape,
const TopoShape& source,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_Sewing with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return Returns the new shape built by the shape maker with mappend element
* name generated using this shape as the source. The shape itself
* is not modified.
*/
TopoShape makeElementShape(BRepOffsetAPI_ThruSections& mkShape, const char* op = nullptr) const
{
return TopoShape(0, Hasher).makeElementShape(mkShape, *this, op);
}
/** Specialized shape making for BRepBuilderAPI_MakePipeShell with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param sources: list of source shapes.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepOffsetAPI_MakePipeShell& mkShape,
const std::vector<TopoShape>& sources,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_MakeHalfSpace with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param source: source shape.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepPrimAPI_MakeHalfSpace& mkShape,
const TopoShape& source,
const char* op = nullptr);
/** Specialized shape making for BRepBuilderAPI_MakeHalfSpace with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return Returns the new shape built by the shape maker with mappend element
* name generated using this shape as the source. The shape itself
* is not modified.
*/
TopoShape makeElementShape(BRepPrimAPI_MakeHalfSpace& mkShape, const char* op = nullptr) const
{
return TopoShape(0, Hasher).makeElementShape(mkShape, *this, op);
}
/** Specialized shape making for BRepBuilderAPI_MakePrism with mapped element name
*
* @param mkShape: OCCT shape maker.
* @param sources: list of source shapes.
* @param op: optional string to be encoded into topo naming for indicating
* the operation
*
* @return The original content of this TopoShape is discarded and replaced
* with the new shape built by the shape maker. The function
* returns the TopoShape itself as a self reference so that
* multiple operations can be carried out for the same shape in the
* same line of code.
*/
TopoShape& makeElementShape(BRepFeat_MakePrism& mkShape,
const std::vector<TopoShape>& sources,
const TopoShape& uptoface,
const char* op);
/** Helper class to return the generated and modified shape given an input shape
*
* Shape history information is extracted using OCCT APIs
* BRepBuilderAPI_MakeShape::Generated/Modified(). However, there is often
* some glitches in various derived class. So we use this class as an
* abstraction, and create various derived classes to deal with the glitches.
*/
friend class TopoShapeCache;
private:
@@ -1013,9 +1280,11 @@ private:
void Nullify()
{
_owner->resetElementMap();
_owner->_cache.reset();
_owner->_parentCache.reset();
if (!this->IsNull()) {
_owner->resetElementMap();
_owner->_cache.reset();
_owner->_parentCache.reset();
}
}
const TopLoc_Location& Location() const

View File

@@ -29,6 +29,7 @@
#include <BRepBuilderAPI_MakeWire.hxx>
#include <modelRefine.h>
#include <BRepCheck_Analyzer.hxx>
#include <BRepFill_Generator.hxx>
#include <BRepTools.hxx>
@@ -51,11 +52,12 @@
#include "TopoShape.h"
#include "TopoShapeCache.h"
#include "TopoShapeOpCode.h"
#include "TopoShapeMapper.h"
#include "FaceMaker.h"
#include "TopoShapeOpCode.h"
#include <App/ElementNamingUtils.h>
#include <BRepLib.hxx>
FC_LOG_LEVEL_INIT("TopoShape", true, true) // NOLINT
@@ -272,6 +274,7 @@ size_t checkSubshapeCount(const TopoShape& topoShape1,
}
return count;
}
} // namespace
void TopoShape::setupChild(Data::ElementMap::MappedChildElements& child,
@@ -325,7 +328,7 @@ void warnIfLogging()
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
FC_WARN("hasher mismatch"); // NOLINT
}
};
}
void hasherMismatchError()
{
@@ -401,11 +404,11 @@ void TopoShape::mapSubElementTypeForShape(const TopoShape& other,
sids.clear();
}
}
std::ostringstream ss;
char elementType {shapeName(type)[0]};
if (!elementMap()) {
FC_THROWM(NullShapeException, "No element map"); // NOLINT
}
std::ostringstream ss;
elementMap()->encodeElementName(elementType, name, ss, &sids, Tag, op, other.Tag);
elementMap()->setElementName(element, name, Tag, &sids);
}
@@ -532,86 +535,6 @@ void TopoShape::mapSubElement(const std::vector<TopoShape>& shapes, const char*
}
}
const std::vector<TopoDS_Shape> &
MapperMaker::modified(const TopoDS_Shape &s) const
{
_res.clear();
try {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(maker.Modified(s)); it.More(); it.Next())
_res.push_back(it.Value());
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
const std::vector<TopoDS_Shape> &
MapperMaker::generated(const TopoDS_Shape &s) const
{
_res.clear();
try {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(maker.Generated(s)); it.More(); it.Next())
_res.push_back(it.Value());
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
MapperHistory::MapperHistory(const Handle(BRepTools_History) &history)
:history(history)
{}
MapperHistory::MapperHistory(const Handle(BRepTools_ReShape) &reshape)
{
if (reshape)
history = reshape->History();
}
MapperHistory::MapperHistory(ShapeFix_Root &fix)
{
if (fix.Context())
history = fix.Context()->History();
}
const std::vector<TopoDS_Shape> &
MapperHistory::modified(const TopoDS_Shape &s) const
{
_res.clear();
try {
if (history) {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(history->Modified(s)); it.More(); it.Next())
_res.push_back(it.Value());
}
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
const std::vector<TopoDS_Shape> &
MapperHistory::generated(const TopoDS_Shape &s) const
{
_res.clear();
try {
if (history) {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(history->Generated(s)); it.More(); it.Next())
_res.push_back(it.Value());
}
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
struct ShapeInfo
{
const TopoDS_Shape& shape;
@@ -626,7 +549,7 @@ struct ShapeInfo
, shapetype(TopoShape::shapeName(type).c_str())
{}
int count() const
[[nodiscard]] int count() const
{
return cache.count();
}
@@ -847,7 +770,7 @@ TopoShape& TopoShape::makeShapeWithElementMap(const TopoDS_Shape& shape,
// First, collect names from other shapes that generates or modifies the
// new shape
for (auto& pinfo : infos) {
for (auto& pinfo : infos) { // Walk Vertexes, then Edges, then Faces
auto& info = *pinfo;
for (const auto & incomingShape : shapes) {
if (!canMapElement(incomingShape)) {
@@ -1721,6 +1644,142 @@ TopoShape &TopoShape::makeElementCopy(const TopoShape &shape, const char *op, bo
return *this;
}
struct MapperSewing: Part::TopoShape::Mapper
{
BRepBuilderAPI_Sewing& maker;
explicit MapperSewing(BRepBuilderAPI_Sewing& maker)
: maker(maker)
{}
const std::vector<TopoDS_Shape>& modified(const TopoDS_Shape& s) const override
{
_res.clear();
try {
const auto& shape = maker.Modified(s);
if (!shape.IsNull() && !shape.IsSame(s)) {
_res.push_back(shape);
}
else {
const auto& sshape = maker.ModifiedSubShape(s);
if (!sshape.IsNull() && !sshape.IsSame(s)) {
_res.push_back(sshape);
}
}
}
catch (const Standard_Failure& e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
}
return _res;
}
};
struct MapperThruSections: MapperMaker
{
TopoShape firstProfile;
TopoShape lastProfile;
MapperThruSections(BRepOffsetAPI_ThruSections& tmaker, const std::vector<TopoShape>& profiles)
: MapperMaker(tmaker)
{
if (!tmaker.FirstShape().IsNull()) {
firstProfile = profiles.front();
}
if (!tmaker.LastShape().IsNull()) {
lastProfile = profiles.back();
}
}
const std::vector<TopoDS_Shape>& generated(const TopoDS_Shape& s) const override
{
MapperMaker::generated(s);
if ( ! _res.empty()) {
return _res;
}
try {
auto& tmaker = dynamic_cast<BRepOffsetAPI_ThruSections&>(maker);
auto shape = tmaker.GeneratedFace(s);
if (!shape.IsNull()) {
_res.push_back(shape);
}
if (firstProfile.getShape().IsSame(s) || firstProfile.findShape(s)) {
_res.push_back(tmaker.FirstShape());
}
else if (lastProfile.getShape().IsSame(s) || lastProfile.findShape(s)) {
_res.push_back(tmaker.LastShape());
}
}
catch (const Standard_Failure& e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
}
return _res;
}
};
TopoShape& TopoShape::makeElementShape(BRepBuilderAPI_MakeShape& mkShape,
const TopoShape& source,
const char* op)
{
std::vector<TopoShape> sources(1, source);
return makeElementShape(mkShape, sources, op);
}
TopoShape& TopoShape::makeElementShape(BRepBuilderAPI_MakeShape& mkShape,
const std::vector<TopoShape>& shapes,
const char* op)
{
return makeShapeWithElementMap(mkShape.Shape(), MapperMaker(mkShape), shapes, op);
}
TopoShape&
TopoShape::makeElementShape(BRepOffsetAPI_ThruSections& mk, const TopoShape& source, const char* op)
{
if (!op) {
op = Part::OpCodes::ThruSections;
}
return makeElementShape(mk, std::vector<TopoShape>(1, source), op);
}
TopoShape& TopoShape::makeElementShape(BRepOffsetAPI_ThruSections& mk,
const std::vector<TopoShape>& sources,
const char* op)
{
if (!op) {
op = Part::OpCodes::ThruSections;
}
return makeShapeWithElementMap(mk.Shape(), MapperThruSections(mk, sources), sources, op);
}
TopoShape& TopoShape::makeElementShape(BRepBuilderAPI_Sewing& mk,
const std::vector<TopoShape>& shapes,
const char* op)
{
if (!op) {
op = Part::OpCodes::Sewing;
}
return makeShapeWithElementMap(mk.SewedShape(), MapperSewing(mk), shapes, op);
}
TopoShape&
TopoShape::makeElementShape(BRepBuilderAPI_Sewing& mkShape, const TopoShape& source, const char* op)
{
if (!op) {
op = Part::OpCodes::Sewing;
}
return makeElementShape(mkShape, std::vector<TopoShape>(1, source), op);
}
TopoShape& TopoShape::makeElementShape(BRepPrimAPI_MakeHalfSpace& mkShape,
const TopoShape& source,
const char* op)
{
if (!op) {
op = Part::OpCodes::HalfSpace;
}
return makeShapeWithElementMap(mkShape.Solid(), MapperMaker(mkShape), {source}, op);
}
TopoShape& TopoShape::makeElementFace(const TopoShape& shape,
const char* op,
@@ -1798,6 +1857,57 @@ TopoShape& TopoShape::makeElementFace(const std::vector<TopoShape>& shapes,
return *this;
}
class MyRefineMaker : public BRepBuilderAPI_RefineModel
{
public:
explicit MyRefineMaker(const TopoDS_Shape &s)
:BRepBuilderAPI_RefineModel(s)
{}
void populate(ShapeMapper &mapper)
{
for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(this->myModified); it.More(); it.Next())
{
if (it.Key().IsNull()) continue;
mapper.populate(MappingStatus::Generated, it.Key(), it.Value());
}
}
};
TopoShape& TopoShape::makeElementRefine(const TopoShape& shape, const char* op, RefineFail no_fail)
{
if (shape.isNull()) {
if (no_fail == RefineFail::throwException) {
FC_THROWM(NullShapeException, "Null shape");
}
_Shape.Nullify();
return *this;
}
if (!op) {
op = Part::OpCodes::Refine;
}
bool closed = shape.isClosed();
try {
MyRefineMaker mkRefine(shape.getShape());
GenericShapeMapper mapper;
mkRefine.populate(mapper);
mapper.init(shape, mkRefine.Shape());
makeShapeWithElementMap(mkRefine.Shape(), mapper, {shape}, op);
// For some reason, refine operation may reverse the solid
fixSolidOrientation();
if (isClosed() == closed) {
return *this;
}
}
catch (Standard_Failure&) {
if (no_fail == RefineFail::throwException) {
throw;
}
}
*this = shape;
return *this;
}
/**
* Encode and set an element name in the elementMap. If a hasher is defined, apply it to the name.
*
@@ -1818,7 +1928,7 @@ Data::MappedName TopoShape::setElementComboName(const Data::IndexedName& element
const Data::ElementIDRefs* _sids)
{
if (names.empty()) {
return Data::MappedName();
return Data::MappedName {};
}
std::string _marker;
if (!marker) {
@@ -1897,7 +2007,7 @@ TopoShape TopoShape::splitWires(std::vector<TopoShape>* inner, SplitWireReorient
tmp = BRepTools::OuterWire(TopoDS::Face(getSubShape(TopAbs_FACE, 1)));
}
if (tmp.IsNull()) {
return TopoShape();
return TopoShape {};
}
const auto& wires = getSubTopoShapes(TopAbs_WIRE);
auto it = wires.begin();
@@ -1964,7 +2074,7 @@ TopoShape TopoShape::splitWires(std::vector<TopoShape>* inner, SplitWireReorient
}
}
}
return TopoShape();
return TopoShape {};
}
struct MapperFill: Part::TopoShape::Mapper
@@ -1991,6 +2101,90 @@ struct MapperFill: Part::TopoShape::Mapper
}
};
const std::vector<TopoDS_Shape>& MapperMaker::modified(const TopoDS_Shape& s) const
{
_res.clear();
try {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(maker.Modified(s)); it.More(); it.Next()) {
_res.push_back(it.Value());
}
}
catch (const Standard_Failure& e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
}
return _res;
}
const std::vector<TopoDS_Shape>& MapperMaker::generated(const TopoDS_Shape& s) const
{
_res.clear();
try {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(maker.Generated(s)); it.More(); it.Next()) {
_res.push_back(it.Value());
}
}
catch (const Standard_Failure& e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
}
return _res;
}
MapperHistory::MapperHistory(const Handle(BRepTools_History) &history)
:history(history)
{}
MapperHistory::MapperHistory(const Handle(BRepTools_ReShape) &reshape)
{
if (reshape)
history = reshape->History();
}
MapperHistory::MapperHistory(ShapeFix_Root &fix)
{
if (fix.Context())
history = fix.Context()->History();
}
const std::vector<TopoDS_Shape> &
MapperHistory::modified(const TopoDS_Shape &s) const
{
_res.clear();
try {
if (history) {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(history->Modified(s)); it.More(); it.Next())
_res.push_back(it.Value());
}
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
const std::vector<TopoDS_Shape> &
MapperHistory::generated(const TopoDS_Shape &s) const
{
_res.clear();
try {
if (history) {
TopTools_ListIteratorOfListOfShape it;
for (it.Initialize(history->Generated(s)); it.More(); it.Next())
_res.push_back(it.Value());
}
} catch (const Standard_Failure & e) {
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG))
FC_WARN("Exception on shape mapper: " << e.GetMessageString());
}
return _res;
}
// topo naming counterpart of TopoShape::makeShell()
TopoShape& TopoShape::makeElementShell(bool silent, const char* op)
{
@@ -2082,28 +2276,81 @@ TopoShape& TopoShape::makeElementShell(bool silent, const char* op)
return *this;
}
// TopoShape& TopoShape::makeElementShellFromWires(const std::vector<TopoShape>& wires,
// bool silent,
// const char* op)
// {
// BRepFill_Generator maker;
// for (auto& w : wires) {
// if (w.shapeType(silent) == TopAbs_WIRE) {
// maker.AddWire(TopoDS::Wire(w.getShape()));
// }
// }
// if (wires.empty()) {
// if (silent) {
// _Shape.Nullify();
// return *this;
// }
// FC_THROWM(NullShapeException, "No input shapes");
// }
// maker.Perform();
// this->makeShapeWithElementMap(maker.Shell(), MapperFill(maker), wires, op);
// return *this;
// }
TopoShape& TopoShape::makeElementShellFromWires(const std::vector<TopoShape>& wires,
bool silent,
const char* op)
{
BRepFill_Generator maker;
for (auto& w : wires) {
if (w.shapeType(silent) == TopAbs_WIRE) {
maker.AddWire(TopoDS::Wire(w.getShape()));
}
}
if (wires.empty()) {
if (silent) {
_Shape.Nullify();
return *this;
}
FC_THROWM(NullShapeException, "No input shapes");
}
maker.Perform();
this->makeShapeWithElementMap(maker.Shell(), MapperFill(maker), wires, op);
return *this;
}
bool TopoShape::fixSolidOrientation()
{
if (isNull()) {
return false;
}
if (shapeType() == TopAbs_SOLID) {
TopoDS_Solid solid = TopoDS::Solid(_Shape);
BRepLib::OrientClosedSolid(solid);
if (solid.IsEqual(_Shape)) {
return false;
}
setShape(solid, false);
return true;
}
if (shapeType() == TopAbs_COMPOUND || shapeType() == TopAbs_COMPSOLID) {
auto shapes = getSubTopoShapes();
bool touched = false;
for (auto& s : shapes) {
if (s.fixSolidOrientation()) {
touched = true;
}
}
if (!touched) {
return false;
}
BRep_Builder builder;
if (shapeType() == TopAbs_COMPOUND) {
TopoDS_Compound comp;
builder.MakeCompound(comp);
for (auto& s : shapes) {
if (!s.isNull()) {
builder.Add(comp, s.getShape());
}
}
setShape(comp, false);
}
else {
TopoDS_CompSolid comp;
builder.MakeCompSolid(comp);
for (auto& s : shapes) {
if (!s.isNull()) {
builder.Add(comp, s.getShape());
}
}
setShape(comp, false);
}
return true;
}
return false;
}
} // namespace Part

View File

@@ -1,6 +1,31 @@
#include "PreCompiled.h"
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include <BRep_Tool.hxx>
#include <TopoDS_Edge.hxx>
#include "TopoShapeMapper.h"
#include "Geometry.h"
namespace Part
{
@@ -96,4 +121,79 @@ void ShapeMapper::insert(MappingStatus status,
}
};
void GenericShapeMapper::init(const TopoShape& src, const TopoDS_Shape& dst)
{
for (TopExp_Explorer exp(dst, TopAbs_FACE); exp.More(); exp.Next()) {
const TopoDS_Shape& dstFace = exp.Current();
if (src.findShape(dstFace)) {
continue;
}
#if OCC_VERSION_HEX < 0x070800
struct TopoDS_ShapeHasher
{
std::size_t operator()(const TopoDS_Shape& key) const
{
return key.HashCode(IntegerLast());
}
};
std::unordered_map<TopoDS_Shape, int, TopoDS_ShapeHasher> map;
#else
std::unordered_map<TopoDS_Shape, int> map;
#endif
bool found = false;
// Try to find a face in the src that shares at least two edges (or one
// closed edge) with dstFace.
// TODO: consider degenerative cases of two or more edges on the same line.
for (TopExp_Explorer it(dstFace, TopAbs_EDGE); it.More(); it.Next()) {
int idx = src.findShape(it.Current());
if (!idx) {
continue;
}
TopoDS_Edge e = TopoDS::Edge(it.Current());
if (BRep_Tool::IsClosed(e)) {
// closed edge, one face is enough
TopoDS_Shape face =
src.findAncestorShape(src.getSubShape(TopAbs_EDGE, idx), TopAbs_FACE);
if (!face.IsNull()) {
this->insert(MappingStatus::Generated, face, dstFace);
found = true;
break;
}
continue;
}
for (auto& face :
src.findAncestorsShapes(src.getSubShape(TopAbs_EDGE, idx), TopAbs_FACE)) {
int& cnt = map[face];
if (++cnt == 2) {
this->insert(MappingStatus::Generated, face, dstFace);
found = true;
break;
}
if (found) {
break;
}
}
}
if (found) {
continue;
}
// if no face matches, try search by geometry surface
std::unique_ptr<Geometry> g(Geometry::fromShape(dstFace));
if (!g) {
continue;
}
for (auto& v : map) {
std::unique_ptr<Geometry> g2(Geometry::fromShape(v.first));
if (g2 && g2->isSame(*g, 1e-7, 1e-12)) {
this->insert(MappingStatus::Generated, v.first, dstFace);
break;
}
}
}
}
} // namespace Part

View File

@@ -1,10 +1,33 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include <map>
#include <unordered_set>
#include <vector>
#include <ShapeBuild_ReShape.hxx>
#include <Standard_Version.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS.hxx>
#include <TopExp_Explorer.hxx>
#include "TopoShape.h"
@@ -144,6 +167,13 @@ struct PartExport ShapeMapper: TopoShape::Mapper
std::unordered_set<TopoDS_Shape, ShapeHasher, ShapeHasher> _modifiedShapes;
};
/** Generic shape mapper from a given source to an output shape
*/
struct PartExport GenericShapeMapper: ShapeMapper {
/// Populate the map with a given source shape to an output shape
void init(const TopoShape &src, const TopoDS_Shape &dst);
};
/// Parameters for TopoShape::makeElementFilledFace()
struct PartExport TopoShape::BRepFillingParams
{

View File

@@ -210,7 +210,7 @@ public:
private:
void LogModifications(const ModelRefine::FaceUniter& uniter);
private:
protected:
TopTools_DataMapOfShapeListOfShape myModified;
TopTools_ListOfShape myEmptyList;
TopTools_ListOfShape myDeleted;