mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0028467: Improve UnifySameDomain performance
This patch turns off some not needed modes of fix in the called ShapeFix_Face algorithm. It stores pcurves on planes in the edges to avoid repeated computation of the same pcurves many times (it is done only when SafeInputMode is false). It avoids unnecessary replace/apply actions in the modification context. It removes the code that makes decomposition of surface of the face on several faces. The new command buildpcurvesonplane has been added, which builds and stores pcurves of edges on planar faces. This is useful for investigations how presence of pcurves on planes influence performance of algorithms. Make drawing of dimension line in snowflake test independent on the order of vertices in the result.
This commit is contained in:
@@ -15,9 +15,6 @@
|
||||
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_CurveRepresentation.hxx>
|
||||
#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
|
||||
#include <BRep_TEdge.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepLib_MakeEdge.hxx>
|
||||
@@ -34,6 +31,7 @@
|
||||
#include <Geom_ElementarySurface.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <Geom_OffsetSurface.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
||||
@@ -52,15 +50,10 @@
|
||||
#include <ShapeAnalysis_WireOrder.hxx>
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeExtend_CompositeSurface.hxx>
|
||||
#include <ShapeFix_ComposeShell.hxx>
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_SequenceOfWireSegment.hxx>
|
||||
#include <ShapeFix_Shell.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeFix_WireSegment.hxx>
|
||||
#include <ShapeUpgrade_RemoveLocations.hxx>
|
||||
#include <ShapeUpgrade_UnifySameDomain.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TColGeom2d_Array1OfBSplineCurve.hxx>
|
||||
@@ -68,7 +61,6 @@
|
||||
#include <TColGeom2d_SequenceOfBoundedCurve.hxx>
|
||||
#include <TColGeom_Array1OfBSplineCurve.hxx>
|
||||
#include <TColGeom_HArray1OfBSplineCurve.hxx>
|
||||
#include <TColGeom_HArray2OfSurface.hxx>
|
||||
#include <TColGeom_SequenceOfSurface.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_MapOfInteger.hxx>
|
||||
@@ -85,7 +77,6 @@
|
||||
#include <TopTools_SequenceOfShape.hxx>
|
||||
#include <gp_Circ.hxx>
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepClass_FaceClassifier.hxx>
|
||||
#include <BRepAdaptor_Curve2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
|
||||
@@ -1229,37 +1220,6 @@ void ShapeUpgrade_UnifySameDomain::KeepShapes(const TopTools_MapOfShape& theShap
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : putIntWires
|
||||
//purpose : Add internal wires that are classified inside the face as a subshape,
|
||||
// and remove them from the sequence
|
||||
//=======================================================================
|
||||
static void putIntWires(TopoDS_Shape& theFace, TopTools_SequenceOfShape& theWires)
|
||||
{
|
||||
TopoDS_Face& aFace = TopoDS::Face(theFace);
|
||||
for (Standard_Integer i=1; i <= theWires.Length(); i++)
|
||||
{
|
||||
TopoDS_Shape aWire = theWires(i);
|
||||
gp_Pnt2d aP2d;
|
||||
Standard_Boolean isP2d = Standard_False;
|
||||
for (TopoDS_Iterator it(aWire); it.More() && !isP2d; it.Next())
|
||||
{
|
||||
const TopoDS_Edge& anEdge = TopoDS::Edge(it.Value());
|
||||
Standard_Real aFirst, aLast;
|
||||
Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aFace, aFirst, aLast);
|
||||
aC2d->D0((aFirst + aLast) * 0.5, aP2d);
|
||||
isP2d = Standard_True;
|
||||
}
|
||||
BRepClass_FaceClassifier aClass(aFace, aP2d, Precision::PConfusion());
|
||||
if (aClass.State() == TopAbs_IN)
|
||||
{
|
||||
BRep_Builder().Add(aFace, aWire);
|
||||
theWires.Remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UnifyFaces
|
||||
//purpose :
|
||||
@@ -1290,6 +1250,24 @@ void ShapeUpgrade_UnifySameDomain::UnifyFaces()
|
||||
myShape = myContext->Apply(myShape);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetFixWireModes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static void SetFixWireModes(ShapeFix_Face& theSff)
|
||||
{
|
||||
Handle(ShapeFix_Wire) aFixWire = theSff.FixWireTool();
|
||||
aFixWire->FixSelfIntersectionMode() = 0;
|
||||
aFixWire->FixNonAdjacentIntersectingEdgesMode() = 0;
|
||||
aFixWire->FixLackingMode() = 0;
|
||||
aFixWire->FixNotchedEdgesMode() = 0;
|
||||
aFixWire->ModifyTopologyMode() = Standard_False;
|
||||
aFixWire->ModifyRemoveLoopMode() = 0;
|
||||
aFixWire->FixGapsByRangesMode() = Standard_False;
|
||||
aFixWire->FixSmallMode() = 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IntUnifyFaces
|
||||
//purpose :
|
||||
@@ -1306,10 +1284,6 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
// map of processed shapes
|
||||
TopTools_MapOfShape aProcessed;
|
||||
|
||||
// Check status of the unification
|
||||
Standard_Integer NbModif = 0;
|
||||
Standard_Boolean hasFailed = Standard_False;
|
||||
|
||||
// processing each face
|
||||
TopExp_Explorer exp;
|
||||
for (exp.Init(theInpShape, TopAbs_FACE); exp.More(); exp.Next()) {
|
||||
@@ -1356,6 +1330,11 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
continue;
|
||||
}
|
||||
|
||||
// for a planar face create and store pcurve of edge on face
|
||||
// to speed up all operations
|
||||
if (!mySafeInputMode && aBaseSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
|
||||
BRepLib::BuildPCurveForEdgeOnPlane(edge, aFace);
|
||||
|
||||
// get normal of the face to compare it with normals of other faces
|
||||
gp_Dir aDN1;
|
||||
//
|
||||
@@ -1416,8 +1395,6 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
for (i = 1; i <= faces.Length(); i++) {
|
||||
TopExp::MapShapesAndAncestors(faces(i), TopAbs_EDGE, TopAbs_FACE, aMapEF);
|
||||
}
|
||||
if (mySafeInputMode)
|
||||
UpdateMapOfShapes(myKeepShapes, myContext);
|
||||
// Collect keep edges and multi-connected edges, i.e. edges that are internal to
|
||||
// the set of selected faces and have connections to other faces.
|
||||
TopTools_ListOfShape aKeepEdges;
|
||||
@@ -1506,13 +1483,12 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
|
||||
// all faces collected in the sequence. Perform union of faces
|
||||
if (faces.Length() > 1) {
|
||||
NbModif++;
|
||||
TopoDS_Face aResult;
|
||||
BRep_Builder B;
|
||||
B.MakeFace(aResult,aBaseSurface,aBaseLocation,0);
|
||||
Standard_Integer nbWires = 0;
|
||||
|
||||
TopoDS_Face tmpF = TopoDS::Face(myContext->Apply(faces(1).Oriented(TopAbs_FORWARD)));
|
||||
TopoDS_Face tmpF = TopoDS::Face(faces(1).Oriented(TopAbs_FORWARD));
|
||||
|
||||
// connecting wires
|
||||
while (edges.Length()>0) {
|
||||
@@ -1559,12 +1535,10 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
|
||||
// sorting any type of edges
|
||||
aWire.Closed (BRep_Tool::IsClosed (aWire));
|
||||
aWire = TopoDS::Wire(myContext->Apply(aWire));
|
||||
|
||||
Handle(ShapeFix_Wire) sfw = new ShapeFix_Wire(aWire,tmpF,Precision::Confusion());
|
||||
if (mySafeInputMode)
|
||||
sfw->SetContext(myContext);
|
||||
sfw->FixEdgeCurves();
|
||||
sfw->FixReorder();
|
||||
Standard_Boolean isDegRemoved = Standard_False;
|
||||
if(!sfw->StatusReorder ( ShapeExtend_FAIL )) {
|
||||
@@ -1584,12 +1558,11 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
if(isDegRemoved)
|
||||
sfw->FixDegenerated();
|
||||
}
|
||||
TopoDS_Wire aWireFixed = sfw->Wire();
|
||||
myContext->Replace(aWire,aWireFixed);
|
||||
aWire = sfw->Wire();
|
||||
|
||||
// add resulting wire
|
||||
if(isEdge3d) {
|
||||
B.Add(aResult,aWireFixed);
|
||||
B.Add(aResult,aWire);
|
||||
}
|
||||
else {
|
||||
// sorting edges
|
||||
@@ -1639,99 +1612,25 @@ void ShapeUpgrade_UnifySameDomain::IntUnifyFaces(const TopoDS_Shape& theInpShape
|
||||
}
|
||||
}
|
||||
|
||||
// perform substitution of face
|
||||
myContext->Replace(myContext->Apply(aFace),aResult);
|
||||
|
||||
ShapeFix_Face sff (aResult);
|
||||
//Initializing by tolerances
|
||||
sff.SetPrecision(Precision::Confusion());
|
||||
sff.SetMinTolerance(Precision::Confusion());
|
||||
sff.SetMaxTolerance(1.);
|
||||
//Setting modes
|
||||
sff.FixOrientationMode() = 0;
|
||||
//sff.FixWireMode() = 0;
|
||||
sff.SetContext(myContext);
|
||||
SetFixWireModes(sff);
|
||||
if (mySafeInputMode)
|
||||
sff.SetContext(myContext);
|
||||
// Applying the fixes
|
||||
sff.Perform();
|
||||
if(sff.Status(ShapeExtend_FAIL))
|
||||
hasFailed = Standard_True;
|
||||
|
||||
// breaking down to several faces
|
||||
TopoDS_Shape theResult = myContext->Apply(aResult);
|
||||
for (TopExp_Explorer aFaceExp (theResult,TopAbs_FACE); aFaceExp.More(); aFaceExp.Next()) {
|
||||
TopoDS_Face aCurrent = TopoDS::Face(aFaceExp.Current().Oriented(TopAbs_FORWARD));
|
||||
Handle(TColGeom_HArray2OfSurface) grid = new TColGeom_HArray2OfSurface ( 1, 1, 1, 1 );
|
||||
grid->SetValue ( 1, 1, aBaseSurface );
|
||||
Handle(ShapeExtend_CompositeSurface) G = new ShapeExtend_CompositeSurface ( grid );
|
||||
ShapeFix_ComposeShell CompShell;
|
||||
CompShell.Init ( G, aBaseLocation, aCurrent, ::Precision::Confusion() );//myPrecision
|
||||
CompShell.SetContext( myContext );
|
||||
|
||||
TopTools_SequenceOfShape parts, anIntWires;
|
||||
ShapeFix_SequenceOfWireSegment wires;
|
||||
for(TopExp_Explorer W_Exp(aCurrent,TopAbs_WIRE);W_Exp.More();W_Exp.Next()) {
|
||||
const TopoDS_Wire& aWire = TopoDS::Wire(W_Exp.Current());
|
||||
// check if the wire is ordinary (contains non-internal edges)
|
||||
Standard_Boolean isInternal = Standard_True;
|
||||
for (TopoDS_Iterator it(aWire); it.More() && isInternal; it.Next())
|
||||
isInternal = (it.Value().Orientation() == TopAbs_INTERNAL);
|
||||
if (isInternal)
|
||||
{
|
||||
// place internal wire separately
|
||||
anIntWires.Append(aWire);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle(ShapeExtend_WireData) sbwd =
|
||||
new ShapeExtend_WireData (aWire);
|
||||
ShapeFix_WireSegment seg ( sbwd, TopAbs_REVERSED );
|
||||
wires.Append(seg);
|
||||
}
|
||||
}
|
||||
|
||||
CompShell.DispatchWires( parts, wires );
|
||||
for (Standard_Integer j=1; j <= parts.Length(); j++ ) {
|
||||
ShapeFix_Face aFixOrient(TopoDS::Face(parts(j)));
|
||||
aFixOrient.SetContext(myContext);
|
||||
aFixOrient.FixOrientation();
|
||||
// put internal wires to faces
|
||||
putIntWires(parts(j), anIntWires);
|
||||
}
|
||||
|
||||
TopoDS_Shape CompRes;
|
||||
if ( parts.Length() !=1 ) {
|
||||
TopoDS_Shell S;
|
||||
B.MakeShell ( S );
|
||||
for ( i=1; i <= parts.Length(); i++ )
|
||||
B.Add ( S, parts(i) );
|
||||
S.Closed (BRep_Tool::IsClosed (S));
|
||||
CompRes = S;
|
||||
}
|
||||
else CompRes = parts(1);
|
||||
|
||||
myContext->Replace(aCurrent,CompRes);
|
||||
if(!sff.Status(ShapeExtend_FAIL))
|
||||
{
|
||||
// perform substitution of faces
|
||||
aResult = sff.Face();
|
||||
myContext->Merge(faces, aResult);
|
||||
}
|
||||
|
||||
const TopoDS_Shape aResult3 = myContext->Apply(theResult);
|
||||
myContext->Merge(faces, aResult3);
|
||||
}
|
||||
} // end processing each face
|
||||
|
||||
//TopoDS_Shape aResult = Shape;
|
||||
if (NbModif > 0 && !hasFailed) {
|
||||
TopoDS_Shape aResult = myContext->Apply(theInpShape);
|
||||
|
||||
ShapeFix_Edge sfe;
|
||||
if (!myContext.IsNull()) sfe.SetContext(myContext);
|
||||
for (exp.Init(aResult,TopAbs_EDGE); exp.More(); exp.Next()) {
|
||||
TopoDS_Edge E = TopoDS::Edge(exp.Current());
|
||||
sfe.FixVertexTolerance (E);
|
||||
// ptv add fix same parameter
|
||||
sfe.FixSameParameter(E, Precision::Confusion());
|
||||
}
|
||||
|
||||
myContext->Replace(theInpShape, aResult);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -1859,13 +1758,38 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
|
||||
TopoDS_Face aFace = TopoDS::Face(myContext->Apply(ChangedFaces.FindKey(i)));
|
||||
if (aFace.IsNull())
|
||||
continue;
|
||||
Handle(ShapeFix_Face) sff = new ShapeFix_Face(aFace);
|
||||
sff->SetContext(myContext);
|
||||
sff->SetPrecision(aPrec);
|
||||
sff->SetMinTolerance(aPrec);
|
||||
sff->SetMaxTolerance(Max(1., aPrec*1000.));
|
||||
sff->Perform();
|
||||
TopoDS_Shape aNewFace = sff->Face();
|
||||
|
||||
// for a planar face create and store pcurve of edge on face
|
||||
// to speed up all operations; but this is allowed only when non-safe mode in force
|
||||
if (!mySafeInputMode)
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace, aLoc);
|
||||
aSurface = ClearRts(aSurface);
|
||||
if (aSurface->IsKind(STANDARD_TYPE(Geom_Plane)))
|
||||
{
|
||||
TopTools_ListOfShape aLE;
|
||||
for (TopExp_Explorer anEx(aFace, TopAbs_EDGE); anEx.More(); anEx.Next())
|
||||
aLE.Append(anEx.Current());
|
||||
BRepLib::BuildPCurveForEdgesOnPlane(aLE, aFace);
|
||||
}
|
||||
}
|
||||
|
||||
ShapeFix_Face sff(aFace);
|
||||
if (mySafeInputMode)
|
||||
sff.SetContext(myContext);
|
||||
sff.SetPrecision(aPrec);
|
||||
sff.SetMinTolerance(aPrec);
|
||||
sff.SetMaxTolerance(Max(1., aPrec*1000.));
|
||||
sff.FixOrientationMode() = 0;
|
||||
sff.FixAddNaturalBoundMode() = 0;
|
||||
sff.FixIntersectingWiresMode() = 0;
|
||||
sff.FixLoopWiresMode() = 0;
|
||||
sff.FixSplitFaceMode() = 0;
|
||||
sff.FixPeriodicDegeneratedMode() = 0;
|
||||
SetFixWireModes(sff);
|
||||
sff.Perform();
|
||||
TopoDS_Shape aNewFace = sff.Face();
|
||||
myContext->Replace(aFace,aNewFace);
|
||||
}
|
||||
|
||||
@@ -1892,37 +1816,16 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
|
||||
myShape = myContext->Apply(myShape);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : UnifyFacesAndEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeUpgrade_UnifySameDomain::UnifyFacesAndEdges()
|
||||
{
|
||||
UnifyFaces();
|
||||
|
||||
/*
|
||||
ShapeUpgrade_RemoveLocations RemLoc;
|
||||
RemLoc.Remove(myShape);
|
||||
myShape = RemLoc.GetResult();
|
||||
*/
|
||||
|
||||
UnifyEdges();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Build
|
||||
//purpose : builds the resulting shape
|
||||
//=======================================================================
|
||||
void ShapeUpgrade_UnifySameDomain::Build()
|
||||
{
|
||||
if (myUnifyFaces && myUnifyEdges)
|
||||
UnifyFacesAndEdges();
|
||||
|
||||
else if (myUnifyEdges)
|
||||
UnifyEdges();
|
||||
else if (myUnifyFaces)
|
||||
if (myUnifyFaces)
|
||||
UnifyFaces();
|
||||
if (myUnifyEdges)
|
||||
UnifyEdges();
|
||||
|
||||
// Fill the history of modifications during the operation
|
||||
FillHistory();
|
||||
|
Reference in New Issue
Block a user