Part/Toponaming: Merge makECopy from Toponaming

This commit is contained in:
Chris Hennes
2024-01-15 19:07:18 -06:00
parent e78be6ca61
commit 99ad972319
3 changed files with 104 additions and 0 deletions

View File

@@ -3146,6 +3146,54 @@ void TopoShape::sewShape(double tolerance)
this->_Shape = sew.SewedShape();
}
bool TopoShape::fix()
{
if (this->_Shape.IsNull())
return false;
// First, we do fix regardless if the current shape is valid or not,
// because not all problems that are handled by ShapeFix_Shape can be
// recognized by BRepCheck_Analyzer.
//
// Second, for some reason, a failed fix (i.e. a fix that produces invalid shape)
// will affect the input shape. (See // https://github.com/realthunder/FreeCAD/issues/585,
// BTW, the file attached in the issue also shows that ShapeFix_Shape may
// actually make a valid input shape invalid). So, it actually change the
// underlying shape data. Therefore, we try with a copy first.
auto copy = makECopy();
ShapeFix_Shape fix(copy._Shape);
fix.Perform();
if (fix.Shape().IsSame(copy._Shape))
return false;
BRepCheck_Analyzer aChecker(fix.Shape());
if (!aChecker.IsValid())
return false;
// If the above fix produces a valid shape, then we fix the original shape,
// because BRepBuilderAPI_Copy has some undesired side effect (e.g. flatten
// underlying shape, and thus break internal shape sharing).
ShapeFix_Shape fixThis(this->_Shape);
fixThis.Perform();
aChecker.Init(fixThis.Shape());
if (aChecker.IsValid()) {
// Must call makESHAPE() (which calls mapSubElement()) to remap element
// names because ShapeFix_Shape may delete (e.g. small edges) or modify
// the input shape.
//
// See https://github.com/realthunder/FreeCAD/issues/595. Sketch001
// has small edges. Simply recompute the sketch to trigger call of fix()
// through makEWires(), and it will remove those edges. Without
// remapping, there will be invalid index jumpping in reference in
// Sketch002.ExternalEdge5.
makESHAPE(fixThis.Shape(), MapperHistory(fixThis), {*this});
} else
makESHAPE(fix.Shape(), MapperHistory(fix), {copy});
return true;
}
bool TopoShape::fix(double precision, double mintol, double maxtol)
{
if (this->_Shape.IsNull())

View File

@@ -384,6 +384,7 @@ public:
TopoDS_Shape replaceShape(const std::vector<std::pair<TopoDS_Shape, TopoDS_Shape>>& s) const;
TopoDS_Shape removeShape(const std::vector<TopoDS_Shape>& s) const;
void sewShape(double tolerance = 1.0e-06);
bool fix();
bool fix(double, double, double);
bool removeInternalWires(double);
TopoDS_Shape removeSplitter() const;
@@ -755,6 +756,37 @@ public:
return TopoShape(0, Hasher).makeElementWires(*this, op, tol, policy, output);
}
/** Make a deep copy of the shape
*
* @param source: input shape
* @param op: optional string to be encoded into topo naming for indicating
* the operation
* @param copyGeom: whether to copy internal geometry of the shape
* @param copyMesh: whether to copy internal meshes of the shape
*
* @return The original content of this TopoShape is discarded and replaced
* with a deep copy of the input 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 &makECopy(const TopoShape &source, const char *op=nullptr, bool copyGeom=true, bool copyMesh=false);
/** Make a deep copy of the shape
*
* @param op: optional string to be encoded into topo naming for indicating
* the operation
* @param copyGeom: whether to copy internal geometry of the shape
* @param copyMesh: whether to copy internal meshes of the shape
*
* @return Return a deep copy of the shape. The shape itself is not
* modified
*/
TopoShape makECopy(const char *op=nullptr, bool copyGeom=true, bool copyMesh=false) const {
return TopoShape(Tag,Hasher).makECopy(*this,op,copyGeom,copyMesh);
}
friend class TopoShapeCache;
private:

View File

@@ -29,6 +29,7 @@
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <TopTools_HSequenceOfShape.hxx>
@@ -860,4 +861,27 @@ TopoShape& TopoShape::makeElementOrderedWires(const std::vector<TopoShape>& shap
return makeElementCompound(wires, nullptr, SingleShapeCompoundCreationPolicy::RETURN_SHAPE);
}
TopoShape &TopoShape::makECopy(const TopoShape &shape, const char *op, bool copyGeom, bool copyMesh)
{
if(shape.isNull())
return *this;
TopoShape tmp(shape);
#if OCC_VERSION_HEX >= 0x070000
tmp.setShape(BRepBuilderAPI_Copy(shape.getShape(),copyGeom,copyMesh).Shape(), false);
#else
tmp.setShape(BRepBuilderAPI_Copy(shape.getShape()).Shape(), false);
#endif
if(op || (shape.Tag && shape.Tag!=Tag)) {
setShape(tmp._Shape);
initCache();
if (!Hasher)
Hasher = tmp.Hasher;
copyElementMap(tmp, op);
}else
*this = tmp;
return *this;
}
} // namespace Part