Part/Toponaming: Merge makECopy from Toponaming
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user