mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0024265: Replacing vertices with tolerance that covers lacking edge by two new vertices and lacking edge
ShapeFix_LackingEdgeRecover was introduced "fixlackingedges" draw command waas introduced don't process a vertex if it is shared by more than 2 edges placed on one face;
This commit is contained in:
parent
0fbfbd6029
commit
13be736516
@ -46,6 +46,7 @@
|
||||
#include <ShapeFix_Wireframe.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_LackingEdgeRecover.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ShapeExtend_DataMapOfShapeListOfMsg.hxx>
|
||||
#include <ShapeExtend_MsgRegistrator.hxx>
|
||||
@ -567,6 +568,52 @@ Standard_Integer fixsmall(Draw_Interpretor& di, Standard_Integer n, const char**
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : fixlackingedges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Integer fixlackingedges(Draw_Interpretor& di, Standard_Integer n, const char** a)
|
||||
{
|
||||
if( n < 3)
|
||||
{
|
||||
di << "\nInvalid number of arguments\n";
|
||||
return 1;
|
||||
}
|
||||
Standard_Integer aCurIndexOfArg = 1;
|
||||
|
||||
// result shape
|
||||
Standard_CString aNameOfModifiedShape = a[aCurIndexOfArg];
|
||||
|
||||
// source shape
|
||||
aCurIndexOfArg++;
|
||||
TopoDS_Shape aShape = DBRep::Get(a[aCurIndexOfArg]);
|
||||
if (aShape.IsNull())
|
||||
{
|
||||
di << "\nthe shape is null\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// max tolerance
|
||||
Standard_Real aMaxTol = 0.01;
|
||||
aCurIndexOfArg++;
|
||||
if (aCurIndexOfArg < n)
|
||||
aMaxTol = Draw::Atof(a[aCurIndexOfArg]);
|
||||
|
||||
Handle(ShapeFix_LackingEdgeRecover) aLackingEdgeTool =
|
||||
new ShapeFix_LackingEdgeRecover;
|
||||
|
||||
aLackingEdgeTool->SetMaxTolerance(aMaxTol);
|
||||
aLackingEdgeTool->Init(aShape);
|
||||
aLackingEdgeTool->Perform();
|
||||
|
||||
TopoDS_Shape aModifiedShape = aLackingEdgeTool->Shape();
|
||||
|
||||
DBRep::Set ( aNameOfModifiedShape, aModifiedShape );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : fixsmalledges
|
||||
//purpose :
|
||||
@ -775,8 +822,8 @@ static Standard_Integer connectedges(Draw_Interpretor& di, Standard_Integer n, c
|
||||
__FILE__,reface,g);
|
||||
theCommands.Add ("fixshape","res shape [preci [maxpreci]] [{switches}]",
|
||||
__FILE__,fixshape,g);
|
||||
// theCommands.Add ("testfill","result edge1 edge2",
|
||||
// __FILE__,XSHAPE_testfill,g);
|
||||
theCommands.Add ("fixlackingedges","result shape [toler]",
|
||||
__FILE__,fixlackingedges,g);
|
||||
theCommands.Add ("fixwgaps","result shape [toler=0]",
|
||||
__FILE__,fixgaps,g);
|
||||
theCommands.Add ("fixsmall","result shape [toler=1.]",
|
||||
|
@ -33,6 +33,7 @@ uses
|
||||
GeomAbs,
|
||||
Adaptor3d,
|
||||
TCollection,
|
||||
TColgp,
|
||||
TColStd,
|
||||
TopAbs,
|
||||
TopLoc,
|
||||
@ -103,8 +104,11 @@ is
|
||||
|
||||
class IntersectionTool;
|
||||
---Purpose: Tool for fixing selfintersecting wire
|
||||
-- and intersecting wires
|
||||
|
||||
-- and intersecting wires
|
||||
|
||||
class LackingEdgeRecover;
|
||||
---Purpose: Tool for lacking edges recover
|
||||
|
||||
class SplitTool;
|
||||
---Purpose: Tool for splitting and cutting edges; incudes methods
|
||||
-- used in OverlappingTool and IntersectionTool
|
||||
@ -142,6 +146,12 @@ is
|
||||
---Purpose: Removes edges which are less than given tolerance from shape
|
||||
-- with help of ShapeFix_Wire::FixSmall()
|
||||
|
||||
RecoverLackingEdges (theShape: Shape from TopoDS; theMaxTolerance: Real; theContext: in out ReShape from ShapeBuild)
|
||||
returns Shape from TopoDS;
|
||||
---Purpose: Recovers lacking edges by replacing of vertices with tolerance
|
||||
-- greater than max tolerance by couple of vertices with "normal"
|
||||
-- tolerance and lacking edge between them
|
||||
|
||||
FixVertexPosition(theshape: in out Shape from TopoDS;
|
||||
theTolerance: Real;
|
||||
thecontext: ReShape from ShapeBuild) returns Boolean;
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeFix_Face.hxx>
|
||||
#include <ShapeFix_LackingEdgeRecover.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <GeomAdaptor_HSurface.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
@ -712,3 +713,23 @@ Standard_Real ShapeFix::LeastEdgeSize(TopoDS_Shape& theShape)
|
||||
aRes = sqrt(aRes);
|
||||
return aRes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : RecoverLackingEdges
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
TopoDS_Shape ShapeFix::RecoverLackingEdges(const TopoDS_Shape& theShape,
|
||||
const Standard_Real theMaxTolerance,
|
||||
Handle(ShapeBuild_ReShape)& theContext)
|
||||
{
|
||||
Handle(ShapeFix_LackingEdgeRecover) aLackingEdgeTool =
|
||||
new ShapeFix_LackingEdgeRecover;
|
||||
|
||||
aLackingEdgeTool->SetContext(theContext);
|
||||
aLackingEdgeTool->SetMaxTolerance(theMaxTolerance);
|
||||
aLackingEdgeTool->Init(theShape);
|
||||
aLackingEdgeTool->Perform();
|
||||
|
||||
return aLackingEdgeTool->Shape();
|
||||
}
|
||||
|
113
src/ShapeFix/ShapeFix_LackingEdgeRecover.cdl
Normal file
113
src/ShapeFix/ShapeFix_LackingEdgeRecover.cdl
Normal file
@ -0,0 +1,113 @@
|
||||
-- Created on: 10.10.2013
|
||||
-- Created by: Briginas Ivan
|
||||
|
||||
class LackingEdgeRecover from ShapeFix inherits Root from ShapeFix
|
||||
|
||||
---Purpose: Fixing lacking edge
|
||||
|
||||
uses
|
||||
|
||||
Shape from TopoDS,
|
||||
Face from TopoDS,
|
||||
Wire from TopoDS,
|
||||
Edge from TopoDS,
|
||||
Vertex from TopoDS,
|
||||
Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
BSplineCurve from Geom2d,
|
||||
Curve from Geom2d,
|
||||
WireData from ShapeExtend,
|
||||
Root from ShapeFix,
|
||||
SequenceOfPnt from TColgp
|
||||
|
||||
is
|
||||
|
||||
Create returns LackingEdgeRecover from ShapeFix;
|
||||
---Purpose: Default constructor set precision and status message
|
||||
-- and drops all fixing statuses
|
||||
|
||||
Create (theShape: Shape from TopoDS)
|
||||
returns LackingEdgeRecover from ShapeFix;
|
||||
---Purpose: Constructor call Init method
|
||||
|
||||
Init (me: mutable; theShape: Shape from TopoDS);
|
||||
---Purpose: apply current context to the shape.
|
||||
|
||||
Perform (me: mutable);
|
||||
---Purpose: split vertices with big tolerance covering missed edge,
|
||||
-- into two new vertices and lacking edge
|
||||
|
||||
Shape (me) returns Shape from TopoDS;
|
||||
---Purpose: Returns resulting shape
|
||||
|
||||
ConvertLackingVerticesTo2D(me;
|
||||
theWire: Wire from TopoDS;
|
||||
theFace: Face from TopoDS;
|
||||
theFirstVertex: Vertex from TopoDS;
|
||||
theSecondVertex: Vertex from TopoDS;
|
||||
theFirstPnt2D: in out Pnt2d from gp;
|
||||
theSecondPnt2D: in out Pnt2d from gp);
|
||||
---Purpose: seek the ends of parametric curves of edges that share
|
||||
-- input vertices (first and second) update the first and
|
||||
-- the second points by found results
|
||||
|
||||
MakeBSplineLackingCurve2D(me;
|
||||
theFirstPnt2D: Pnt2d from gp;
|
||||
theSecondPnt2D: Pnt2d from gp)
|
||||
returns BSplineCurve from Geom2d;
|
||||
---Purpose: create and return b-spline in 2D space
|
||||
|
||||
|
||||
IsWireStrip(me;
|
||||
theWire: Wire from TopoDS;
|
||||
theFace: Face from TopoDS;
|
||||
theVertex: Vertex from TopoDS;
|
||||
theFirstPnt: in out Pnt from gp;
|
||||
theSecondPnt: in out Pnt from gp) returns Boolean;
|
||||
---Purpose: 1. build vector between the ends of the parametric curves (of
|
||||
-- edges belonging to the wire) that share the vertex;
|
||||
-- 2. project the wire on the built vector
|
||||
-- 3. return TRUE if the length of the projection is less than
|
||||
-- the length of the built vector which was multiplied by <br>
|
||||
-- predefined (2) number
|
||||
|
||||
ReplaceVertex(me;
|
||||
theVertex: Vertex from TopoDS;
|
||||
theEdge: Edge from TopoDS;
|
||||
theFace: Face from TopoDS;
|
||||
theListOfFirstPnt: SequenceOfPnt from TColgp;
|
||||
theFirstVertex: Vertex from TopoDS;
|
||||
theSecondVertex: Vertex from TopoDS)
|
||||
returns Edge from TopoDS;
|
||||
---Purpose: replace the vertex of the edge by the first or the second vertex
|
||||
-- before replacing the method choose what vertex should be used for
|
||||
-- replacing return modified edge (with replaced vertex)
|
||||
|
||||
ConvertTo2D(me;
|
||||
theEdge : Edge from TopoDS;
|
||||
theVertex : Vertex from TopoDS;
|
||||
theCurve2D : Curve from Geom2d;
|
||||
thePFirst : Real;
|
||||
thePSecond : Real)
|
||||
returns Pnt2d from gp;
|
||||
---Purpose: calculate parametric representation the vertex on the curve 2d
|
||||
-- return this representation
|
||||
|
||||
ProjectTo2DVector(me;
|
||||
theWireData : WireData from ShapeExtend;
|
||||
theFace : Face from TopoDS;
|
||||
thePntNbPerEdgeForProj : Real;
|
||||
thePFirst2D : Pnt2d from gp;
|
||||
thePSecond2D : Pnt2d from gp)
|
||||
returns Real;
|
||||
---Purpose: 1. project the wire (equidistant point of it) on the vector
|
||||
-- is formed by the first and second parametric points
|
||||
-- 2. calculate and RETURN length of the projection
|
||||
|
||||
fields
|
||||
|
||||
myShape : Shape from TopoDS is protected;
|
||||
myRecoveredShape : Shape from TopoDS is protected;
|
||||
myStatus : Integer is protected;
|
||||
|
||||
end LackingEdgeRecover;
|
795
src/ShapeFix/ShapeFix_LackingEdgeRecover.cxx
Normal file
795
src/ShapeFix/ShapeFix_LackingEdgeRecover.cxx
Normal file
@ -0,0 +1,795 @@
|
||||
// File: ShapeFix_LackingEdgeRecover.cxx
|
||||
// Created: 10.10.2013
|
||||
// Author: Briginas Ivan
|
||||
|
||||
#include <ShapeFix_LackingEdgeRecover.hxx>
|
||||
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
|
||||
#include <BRepLib.hxx>
|
||||
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColgp_SequenceOfPnt.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
|
||||
#include <ShapeBuild_Edge.hxx>
|
||||
|
||||
#include <ShapeExtend.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
|
||||
#include <ShapeFix_Edge.hxx>
|
||||
|
||||
#include <Standard_Assert.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (ShapeFix_LackingEdgeRecover, ShapeFix_Root)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(ShapeFix_LackingEdgeRecover, ShapeFix_Root)
|
||||
|
||||
inline Standard_Boolean IsEqual(const TopoDS_Edge& theEdge1,
|
||||
const TopoDS_Edge& theEdge2)
|
||||
{
|
||||
return theEdge1.IsSame(theEdge2);
|
||||
}
|
||||
|
||||
inline Standard_Boolean IsEqual(const TopoDS_Face& theFace1,
|
||||
const TopoDS_Face& theFace2)
|
||||
{
|
||||
return theFace1.IsEqual(theFace2);
|
||||
}
|
||||
|
||||
ShapeFix_LackingEdgeRecover::ShapeFix_LackingEdgeRecover()
|
||||
{
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
SetPrecision(Precision::Confusion());
|
||||
}
|
||||
|
||||
ShapeFix_LackingEdgeRecover::ShapeFix_LackingEdgeRecover(const TopoDS_Shape& theShape)
|
||||
{
|
||||
this->Init(theShape);
|
||||
}
|
||||
|
||||
TopoDS_Shape ShapeFix_LackingEdgeRecover::Shape() const
|
||||
{
|
||||
return myRecoveredShape;
|
||||
}
|
||||
|
||||
void ShapeFix_LackingEdgeRecover::Init(const TopoDS_Shape& theShape)
|
||||
{
|
||||
myShape = theShape;
|
||||
if ( Context().IsNull() )
|
||||
SetContext ( new ShapeBuild_ReShape );
|
||||
|
||||
myRecoveredShape = theShape;
|
||||
}
|
||||
|
||||
void ShapeFix_LackingEdgeRecover::Perform()
|
||||
{
|
||||
myRecoveredShape = Context()->Apply(myShape);
|
||||
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aVertexEdgesMap, aVertexWiresMap,
|
||||
anEdgeFacesMap, aWireFacesMap;
|
||||
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_VERTEX, TopAbs_EDGE, aVertexEdgesMap);
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_VERTEX, TopAbs_WIRE, aVertexWiresMap);
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_EDGE, TopAbs_FACE, anEdgeFacesMap);
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_WIRE, TopAbs_FACE, aWireFacesMap);
|
||||
|
||||
NCollection_List< std::pair<TopoDS_Vertex, TopoDS_Vertex> > aVerticesForLackingEdgesBuilding;
|
||||
typedef NCollection_DataMap<TopoDS_Face, Standard_Integer> FaceDataMap;
|
||||
|
||||
// search vertices with tolerance greater than specified threshold (theMaxTol)
|
||||
TopTools_IndexedMapOfShape aShapeVertexMap;
|
||||
TopExp::MapShapes(myRecoveredShape, TopAbs_VERTEX, aShapeVertexMap);
|
||||
|
||||
Standard_Integer aVertIter = 1; // start from 1
|
||||
for (; aVertIter <= aShapeVertexMap.Extent(); ++aVertIter)
|
||||
{
|
||||
TopoDS_Vertex aCurVertex = TopoDS::Vertex (aShapeVertexMap.FindKey(aVertIter));
|
||||
Standard_Real aCurTol = BRep_Tool::Tolerance (aCurVertex);
|
||||
|
||||
// skip vertices with tolerance lesser than theMaxTol
|
||||
if (aCurTol < this->MaxTolerance())
|
||||
continue;
|
||||
|
||||
const TopTools_ListOfShape& aSharingWiresOfCurVertex = aVertexWiresMap.FindFromKey (aCurVertex);
|
||||
|
||||
// process each edge
|
||||
Standard_Boolean anIsVertexReplaced = Standard_False;
|
||||
gp_Pnt aFirstNewPnt, aSecondNewPnt; // these points will replace vertex with big tolerance
|
||||
|
||||
TopTools_ListIteratorOfListOfShape anWireIter(aSharingWiresOfCurVertex);
|
||||
for (;anWireIter.More() && !anIsVertexReplaced; anWireIter.Next())
|
||||
{
|
||||
const TopoDS_Wire& aCurWire = TopoDS::Wire(anWireIter.Value());
|
||||
|
||||
const TopTools_ListOfShape& aSharingFacesOfCurWire =
|
||||
aWireFacesMap.FindFromKey (anWireIter.Value());
|
||||
|
||||
// (IMPORTANT) process just first found face
|
||||
TopTools_ListIteratorOfListOfShape aSharingFacesOfCurWireIter(aSharingFacesOfCurWire);
|
||||
for (; aSharingFacesOfCurWireIter.More() && !anIsVertexReplaced; aSharingFacesOfCurWireIter.Next())
|
||||
{
|
||||
// replace the vertex if sharing wire is strip
|
||||
anIsVertexReplaced = IsWireStrip(aCurWire, TopoDS::Face(aSharingFacesOfCurWireIter.Value()),
|
||||
aCurVertex, aFirstNewPnt, aSecondNewPnt);
|
||||
}
|
||||
}
|
||||
|
||||
//int todo_streach_degenerated_edge;
|
||||
|
||||
if (!anIsVertexReplaced)
|
||||
continue;
|
||||
|
||||
|
||||
const TopTools_ListOfShape& aSharingEdgesOfCurVertex =
|
||||
aVertexEdgesMap.FindFromKey (aCurVertex);
|
||||
|
||||
FaceDataMap aSharingFacesMap;
|
||||
Standard_Boolean anIsCurVertexSkipped = Standard_False;
|
||||
|
||||
// split sharing edges into two groups
|
||||
TColgp_SequenceOfPnt aFirstPntList, aSecondPntList;
|
||||
NCollection_Map<TopoDS_Edge> anEdgeMap;
|
||||
TopTools_ListIteratorOfListOfShape aSharingEdgesOfCurVertexIter(aSharingEdgesOfCurVertex);
|
||||
for (; aSharingEdgesOfCurVertexIter.More(); aSharingEdgesOfCurVertexIter.Next())
|
||||
{
|
||||
const TopoDS_Edge& aCurIntEdge = TopoDS::Edge(aSharingEdgesOfCurVertexIter.Value());
|
||||
|
||||
if (!anEdgeMap.Contains(aCurIntEdge))
|
||||
anEdgeMap.Add(aCurIntEdge);
|
||||
else
|
||||
continue;
|
||||
|
||||
if (!anEdgeFacesMap.Contains(aCurIntEdge))
|
||||
continue;
|
||||
const TopTools_ListOfShape& aSharingFacesOfCurIntEdge = anEdgeFacesMap.FindFromKey (aCurIntEdge);
|
||||
|
||||
if (aSharingFacesOfCurIntEdge.IsEmpty())
|
||||
continue;
|
||||
|
||||
// collect all sharing faces
|
||||
TopTools_ListIteratorOfListOfShape aSharingFacesIter(aSharingFacesOfCurIntEdge);
|
||||
for(; aSharingFacesIter.More(); aSharingFacesIter.Next())
|
||||
{
|
||||
const TopoDS_Face aCurShFace = TopoDS::Face(aSharingFacesIter.Value());
|
||||
|
||||
if (!aSharingFacesMap.IsBound(aCurShFace))
|
||||
aSharingFacesMap.Bind(aCurShFace, 1);
|
||||
else
|
||||
aSharingFacesMap(aCurShFace)++;
|
||||
}
|
||||
|
||||
// skip the case when a vertex is being shared by more
|
||||
// than 2 edges that belong to one face
|
||||
Standard_Integer aMaxNbEdgesOnOneFace = 2;
|
||||
for (FaceDataMap::Iterator anIt(aSharingFacesMap);
|
||||
anIt.More() && !anIsCurVertexSkipped; anIt.Next())
|
||||
{
|
||||
if (anIt.Value() > aMaxNbEdgesOnOneFace)
|
||||
anIsCurVertexSkipped = Standard_True;
|
||||
}
|
||||
|
||||
// break processing of edges that share the cur vertex
|
||||
if (anIsCurVertexSkipped)
|
||||
break;
|
||||
|
||||
// take first sharing face
|
||||
const TopoDS_Face& aCurIntFace = TopoDS::Face(aSharingFacesOfCurIntEdge.First());
|
||||
|
||||
TopLoc_Location aLocation;
|
||||
Handle(Geom_Surface) aCurIntSurf = BRep_Tool::Surface (aCurIntFace, aLocation);
|
||||
|
||||
Standard_Real aPFirstParamOfCurIntEdge, aPLastParamOfCurIntEdge;
|
||||
Handle(Geom2d_Curve) aPCurveOfCurIntEdge =
|
||||
BRep_Tool::CurveOnSurface (aCurIntEdge, aCurIntFace,
|
||||
aPFirstParamOfCurIntEdge, aPLastParamOfCurIntEdge);
|
||||
|
||||
// sort couple of vertices of the current internal edge
|
||||
TopoDS_Iterator anVerticesIter(aCurIntEdge, TopAbs_VERTEX);
|
||||
for (; anVerticesIter.More(); anVerticesIter.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aCurInternalVertex = TopoDS::Vertex(anVerticesIter.Value());
|
||||
|
||||
if(!aCurInternalVertex.IsSame(aCurVertex))
|
||||
continue;
|
||||
|
||||
gp_Pnt2d anAddingPnt2D = ConvertTo2D(aCurIntEdge, aCurInternalVertex, aPCurveOfCurIntEdge,
|
||||
aPFirstParamOfCurIntEdge, aPLastParamOfCurIntEdge);
|
||||
|
||||
gp_Pnt anAddingPnt;
|
||||
aCurIntSurf->D0(anAddingPnt2D.X(), anAddingPnt2D.Y(), anAddingPnt);
|
||||
|
||||
Standard_Real aDist2ToFirstNewPnt = aFirstNewPnt.SquareDistance(anAddingPnt);
|
||||
Standard_Real aDist2ToSecondNewPnt = aSecondNewPnt.SquareDistance(anAddingPnt);
|
||||
|
||||
if (aDist2ToFirstNewPnt < aDist2ToSecondNewPnt)
|
||||
aFirstPntList.Append(anAddingPnt);
|
||||
else
|
||||
aSecondPntList.Append(anAddingPnt);
|
||||
}
|
||||
}
|
||||
|
||||
if (anIsCurVertexSkipped)
|
||||
continue;
|
||||
|
||||
if (aFirstPntList.IsEmpty() || aSecondPntList.IsEmpty())
|
||||
continue;
|
||||
|
||||
// === process FIRST group
|
||||
// mean point of first group
|
||||
gp_XYZ aTotalXYZ;
|
||||
for (Standard_Integer aCurIndex = 1; aCurIndex <= aFirstPntList.Length(); aCurIndex++)
|
||||
aTotalXYZ += aFirstPntList.Value(aCurIndex).XYZ();
|
||||
|
||||
gp_Pnt aMeanFirstNewPnt(aTotalXYZ/aFirstPntList.Length());
|
||||
// === END process FIRST group
|
||||
|
||||
// === process SECOND group
|
||||
// mean point of second group
|
||||
aTotalXYZ = gp_XYZ();
|
||||
for (Standard_Integer aCurIndex = 1; aCurIndex <= aSecondPntList.Length(); aCurIndex++)
|
||||
aTotalXYZ += aSecondPntList.Value(aCurIndex).XYZ();
|
||||
|
||||
gp_Pnt aMeanSecondNewPnt(aTotalXYZ/aSecondPntList.Length());
|
||||
// === END process SECOND group
|
||||
|
||||
// create new vertices
|
||||
BRep_Builder aBuilder;
|
||||
TopoDS_Vertex aFirstNewVertex, aSecondNewVertex;
|
||||
// tolerance of vertices will be corrected during future edge replacement
|
||||
aBuilder.MakeVertex (aFirstNewVertex, aMeanFirstNewPnt, Precision::Confusion());
|
||||
aBuilder.MakeVertex (aSecondNewVertex, aMeanSecondNewPnt, Precision::Confusion());
|
||||
|
||||
// fill in for building lacking edges
|
||||
aVerticesForLackingEdgesBuilding.Append(std::make_pair(aFirstNewVertex, aSecondNewVertex));
|
||||
|
||||
// tool for fixing of vertex tolerance
|
||||
Handle(ShapeFix_Edge) anEdgeFixer = new ShapeFix_Edge;
|
||||
|
||||
// update the shape to replace vertex with big tolerance by two new vertices
|
||||
aSharingEdgesOfCurVertexIter.Initialize(aSharingEdgesOfCurVertex);
|
||||
for (; aSharingEdgesOfCurVertexIter.More(); aSharingEdgesOfCurVertexIter.Next())
|
||||
{
|
||||
const TopoDS_Edge& aCurIntUnUpdatedEdge = TopoDS::Edge(aSharingEdgesOfCurVertexIter.Value());
|
||||
|
||||
// current updated edge
|
||||
TopoDS_Edge aCurIntEdge = TopoDS::Edge(Context()->Apply(aCurIntUnUpdatedEdge));
|
||||
|
||||
// the copy of the current internal updated edge
|
||||
TopoDS_Edge aModifedEdge = TopoDS::Edge(Context()->Apply(aCurIntUnUpdatedEdge));
|
||||
|
||||
// take first sharing face
|
||||
const TopTools_ListOfShape& aSharingFacesOfCurIntEdge = anEdgeFacesMap.FindFromKey (aCurIntUnUpdatedEdge);
|
||||
const TopoDS_Face& aCurIntFace = TopoDS::Face(aSharingFacesOfCurIntEdge.First());
|
||||
|
||||
TopoDS_Iterator aVertIterOfCurIntEdge(aCurIntEdge);
|
||||
for (; aVertIterOfCurIntEdge.More(); aVertIterOfCurIntEdge.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aCurVertexOfCurIntEdge = TopoDS::Vertex(aVertIterOfCurIntEdge.Value());
|
||||
|
||||
if (!aCurVertexOfCurIntEdge.IsSame(aCurVertex))
|
||||
continue;
|
||||
|
||||
// replace the current vertex of the current internal edge by couple of new vertices
|
||||
aModifedEdge = ReplaceVertex(aCurVertexOfCurIntEdge, aModifedEdge,
|
||||
aCurIntFace, aFirstPntList,
|
||||
aFirstNewVertex, aSecondNewVertex);
|
||||
|
||||
// increase tolerance of vertices of the modified
|
||||
// edge if the ones don't cover the tolerance
|
||||
// of the modified edge
|
||||
anEdgeFixer->FixVertexTolerance(aModifedEdge);
|
||||
}
|
||||
|
||||
// update the context
|
||||
Context()->Replace(aCurIntEdge, aModifedEdge);
|
||||
}
|
||||
}
|
||||
|
||||
// apply the changes containing all replacements with vertices
|
||||
myRecoveredShape = Context()->Apply(myRecoveredShape);
|
||||
|
||||
// add lacking edges into the modified shape (it doesn't contain vertices with big tolerance already)
|
||||
TopTools_IndexedDataMapOfShapeListOfShape anUpdatedVertexWiresMap, anUpdatedWireFacesMap;
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_VERTEX, TopAbs_WIRE, anUpdatedVertexWiresMap);
|
||||
TopExp::MapShapesAndAncestors(myRecoveredShape, TopAbs_WIRE, TopAbs_FACE, anUpdatedWireFacesMap);
|
||||
|
||||
NCollection_List< std::pair<TopoDS_Vertex, TopoDS_Vertex> >::Iterator
|
||||
aVerticesForLackingEdgesIter(aVerticesForLackingEdgesBuilding);
|
||||
|
||||
// run through all pairs of new vertices to add lacking edge between them
|
||||
for (; aVerticesForLackingEdgesIter.More(); aVerticesForLackingEdgesIter.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aFirstNewVertex = aVerticesForLackingEdgesIter.Value().first;
|
||||
const TopoDS_Vertex& aSecondNewVertex = aVerticesForLackingEdgesIter.Value().second;
|
||||
|
||||
// wires share the first new vertex
|
||||
if (!anUpdatedVertexWiresMap.Contains(aFirstNewVertex))
|
||||
continue;
|
||||
const TopTools_ListOfShape& aSharingWiresOfFirstNewVertex =
|
||||
anUpdatedVertexWiresMap.FindFromKey (aFirstNewVertex);
|
||||
|
||||
// wires share the second new vertex
|
||||
if (!anUpdatedVertexWiresMap.Contains(aSecondNewVertex))
|
||||
continue;
|
||||
const TopTools_ListOfShape& aSharingWiresOfSecondNewVertex =
|
||||
anUpdatedVertexWiresMap.FindFromKey (aSecondNewVertex);
|
||||
|
||||
// seek the intersection of two lists of sharing wires
|
||||
TopTools_ListIteratorOfListOfShape anIterOfFirstWireList(aSharingWiresOfFirstNewVertex);
|
||||
|
||||
TopTools_ListOfShape anIntersectOfTwoLists;
|
||||
for (; anIterOfFirstWireList.More(); anIterOfFirstWireList.Next())
|
||||
{
|
||||
TopTools_ListIteratorOfListOfShape anIterOfSecondWireList(aSharingWiresOfSecondNewVertex);
|
||||
for (; anIterOfSecondWireList.More(); anIterOfSecondWireList.Next())
|
||||
{
|
||||
if (anIterOfFirstWireList.Value().IsSame(anIterOfSecondWireList.Value()))
|
||||
anIntersectOfTwoLists.Append(anIterOfFirstWireList.Value());
|
||||
}
|
||||
}
|
||||
|
||||
// tool for fixing of vertex tolerance to cover edge tolerance that contains this vertex
|
||||
Handle(ShapeFix_Edge) anEdgeFixer = new ShapeFix_Edge;
|
||||
TopoDS_Edge aLackingEdge;
|
||||
BRep_Builder aBuilder;
|
||||
|
||||
// add lacking edge to each intersected wire by replacing one their edge
|
||||
TopTools_ListIteratorOfListOfShape anIterOfIntersetionList(anIntersectOfTwoLists);
|
||||
for (; anIterOfIntersetionList.More(); anIterOfIntersetionList.Next())
|
||||
{
|
||||
const TopoDS_Wire& aCurWire = TopoDS::Wire(anIterOfIntersetionList.Value());
|
||||
|
||||
// faces of doesn't updated wire
|
||||
const TopTools_ListOfShape& aSharingFacesOfCurWire =
|
||||
anUpdatedWireFacesMap.FindFromKey (aCurWire);
|
||||
|
||||
if (aSharingFacesOfCurWire.Extent() == 0)
|
||||
continue;
|
||||
|
||||
// _first_ found face containing the current wire
|
||||
const TopoDS_Face& aCurFace = TopoDS::Face(aSharingFacesOfCurWire.First());
|
||||
|
||||
TopLoc_Location aLocation;
|
||||
Handle(Geom_Surface) aCurSurf = BRep_Tool::Surface (aCurFace, aLocation);
|
||||
|
||||
TopoDS_Wire anUpdatedCurWire = TopoDS::Wire(Context()->Apply(aCurWire));
|
||||
|
||||
// seek 2d points (from doesn't updated wire) for 2d pcurve building
|
||||
gp_Pnt2d aFirst2D, aSecond2D;
|
||||
ConvertLackingVerticesTo2D(aCurWire, aCurFace, aFirstNewVertex, aSecondNewVertex, aFirst2D, aSecond2D);
|
||||
|
||||
// create 2d pcurve for lacking edge
|
||||
const Handle(Geom2d_BSplineCurve)& aBSplineLackingCurve2D =
|
||||
MakeBSplineLackingCurve2D(aFirst2D, aSecond2D);
|
||||
|
||||
if (aLackingEdge.IsNull())
|
||||
aLackingEdge = BRepBuilderAPI_MakeEdge(aBSplineLackingCurve2D, aCurSurf, aFirstNewVertex, aSecondNewVertex);
|
||||
|
||||
// add pcurve to the lacking edge
|
||||
aBuilder.UpdateEdge(aLackingEdge, aBSplineLackingCurve2D, aCurSurf, aLocation,
|
||||
BRep_Tool::Tolerance(aLackingEdge));
|
||||
|
||||
// set orientation of the lacking edge
|
||||
TopAbs_Orientation anOrientOfLackingEdge = TopAbs_FORWARD;
|
||||
for (TopoDS_Iterator anEdgeIter(aCurWire); anEdgeIter.More(); anEdgeIter.Next())
|
||||
{
|
||||
const TopoDS_Edge& aCurIntEdge = TopoDS::Edge(anEdgeIter.Value());
|
||||
|
||||
if (aFirstNewVertex.IsSame(TopExp::FirstVertex(aCurIntEdge)))
|
||||
{
|
||||
if (aCurIntEdge.Orientation() == TopAbs_FORWARD)
|
||||
anOrientOfLackingEdge = TopAbs_REVERSED;
|
||||
else
|
||||
anOrientOfLackingEdge = TopAbs_FORWARD;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (aFirstNewVertex.IsSame(TopExp::LastVertex(aCurIntEdge)))
|
||||
{
|
||||
if (aCurIntEdge.Orientation() == TopAbs_FORWARD)
|
||||
anOrientOfLackingEdge = TopAbs_FORWARD;
|
||||
else
|
||||
anOrientOfLackingEdge = TopAbs_REVERSED;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aLackingEdge = TopoDS::Edge(aLackingEdge.Oriented(anOrientOfLackingEdge));
|
||||
|
||||
// add lacking edge to current wire
|
||||
anUpdatedCurWire.Free(Standard_True);
|
||||
aBuilder.Add(anUpdatedCurWire, aLackingEdge);
|
||||
|
||||
Context()->Replace(aCurWire, anUpdatedCurWire);
|
||||
}
|
||||
|
||||
BRepLib::BuildCurve3d(aLackingEdge);
|
||||
BRepLib::SameParameter(aLackingEdge, 1.e-5, Standard_True);
|
||||
}
|
||||
|
||||
myRecoveredShape = Context()->Apply(myRecoveredShape);
|
||||
|
||||
myStatus = ShapeExtend::EncodeStatus ( ShapeExtend_OK );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ReplaceVertex
|
||||
//purpose : replace the input vertex by couple of new ones
|
||||
//=======================================================================
|
||||
TopoDS_Edge ShapeFix_LackingEdgeRecover::ReplaceVertex(const TopoDS_Vertex& theVert /*theBeingReplacedVertex*/,
|
||||
const TopoDS_Edge& theEdge /*theBeingReplacedEdge */,
|
||||
const TopoDS_Face& theFace,
|
||||
const TColgp_SequenceOfPnt&
|
||||
theListOfFirstPnt,
|
||||
const TopoDS_Vertex& theFirstVertex,
|
||||
const TopoDS_Vertex& theSecondVertex) const
|
||||
{
|
||||
Standard_Real aPFirstParamOfEdge, aPLastParamOfEdge;
|
||||
Handle(Geom2d_Curve) aPCurveOfCurIntEdge =
|
||||
BRep_Tool::CurveOnSurface (theEdge, theFace, aPFirstParamOfEdge, aPLastParamOfEdge);
|
||||
|
||||
TopAbs_Orientation anOrientOfVert = theVert.Orientation();
|
||||
|
||||
// seek the end of pcurve that shares the input vertex
|
||||
gp_Pnt2d aBeingSoughtPnt2D = ConvertTo2D(theEdge, theVert, aPCurveOfCurIntEdge,
|
||||
aPFirstParamOfEdge, aPLastParamOfEdge);
|
||||
|
||||
TopLoc_Location aLocation;
|
||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (theFace, aLocation);
|
||||
|
||||
// convert the found end of pcurve to point in 3D space
|
||||
gp_Pnt aBeingSoughtPnt;
|
||||
aSurf->D0(aBeingSoughtPnt2D.X(), aBeingSoughtPnt2D.Y(), aBeingSoughtPnt);
|
||||
|
||||
// seek what list contains found 3D point
|
||||
Standard_Boolean anIsBeingSoughtPntInFirstList = Standard_False;
|
||||
Standard_Integer aCurIndex = 1;
|
||||
for (; aCurIndex <= theListOfFirstPnt.Length() && !anIsBeingSoughtPntInFirstList; aCurIndex++)
|
||||
if (aBeingSoughtPnt.Distance(theListOfFirstPnt.Value(aCurIndex)) <= Precision::Confusion())
|
||||
anIsBeingSoughtPntInFirstList = Standard_True;
|
||||
|
||||
// choose what vertex in the edge will be replaced taking into account found
|
||||
// list containing this found 3d point
|
||||
TopoDS_Vertex aBeingSoughtVertex;
|
||||
if (anIsBeingSoughtPntInFirstList)
|
||||
aBeingSoughtVertex = TopoDS::Vertex(theFirstVertex.Oriented(anOrientOfVert));
|
||||
else
|
||||
aBeingSoughtVertex = TopoDS::Vertex(theSecondVertex.Oriented(anOrientOfVert));
|
||||
|
||||
TopoDS_Edge aModifiedEdge;
|
||||
ShapeBuild_Edge anEdgeBuilder;
|
||||
|
||||
// replace the vertex in the edge by chosen vertex
|
||||
if (anOrientOfVert == TopAbs_FORWARD)
|
||||
aModifiedEdge = anEdgeBuilder.CopyReplaceVertices(theEdge, aBeingSoughtVertex, TopoDS_Vertex());
|
||||
else
|
||||
aModifiedEdge = anEdgeBuilder.CopyReplaceVertices(theEdge, TopoDS_Vertex(), aBeingSoughtVertex);
|
||||
|
||||
return aModifiedEdge;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsWireStrip
|
||||
//purpose : find out wire is strip or not
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeFix_LackingEdgeRecover::IsWireStrip(const TopoDS_Wire& theWire,
|
||||
const TopoDS_Face& theFace,
|
||||
const TopoDS_Vertex& theVertex,
|
||||
gp_Pnt& theFirstPnt, gp_Pnt& theSecondPnt) const
|
||||
{
|
||||
// if the wide of the wire projection in parametric space of the face
|
||||
// on vector (which is formed by the first and second input points; theirs analogues in
|
||||
// parametric space of the face) will be less than this parameter - aStripRation
|
||||
// then wire is detected as a strip
|
||||
Standard_Real aStripRatio = 2.0;
|
||||
|
||||
// number of equidistant points on each edge for wire projection
|
||||
// in parametric space on the vector that was described previously
|
||||
Standard_Integer aPntNbPerEdgeForProj = 10;
|
||||
|
||||
// the analogues of the first and second points in parametric space of the face
|
||||
gp_Pnt2d aPFirst2D, aPSecond2D;
|
||||
|
||||
// the wire is explored by BRepTools_WireExplorer and it is
|
||||
// guaranteed that edges will be SEQUENCIALLY connected
|
||||
Standard_Boolean isNOTExpByBRepTools_WireExplorer = Standard_False;
|
||||
Handle(ShapeExtend_WireData) anEdgeExp =
|
||||
new ShapeExtend_WireData(theWire, isNOTExpByBRepTools_WireExplorer);
|
||||
|
||||
Standard_Integer aStartIndex = 1; // start index of ShapeExtend_WireData
|
||||
Standard_Integer anEndIndex = anEdgeExp->NbEdges();
|
||||
|
||||
if (anEndIndex == 0) // the WIRE IS EMPTY
|
||||
return Standard_False;
|
||||
|
||||
// run through all edges and seek couple of edges which share the vertex
|
||||
Standard_Integer anEdgeIndex, anEdgeIndex_Prev, anEdgeIndex_Next;
|
||||
for (anEdgeIndex = aStartIndex; anEdgeIndex <= anEndIndex; anEdgeIndex++)
|
||||
{
|
||||
// index of previous edge
|
||||
if (anEdgeIndex == aStartIndex) anEdgeIndex_Prev = anEndIndex;
|
||||
else anEdgeIndex_Prev = anEdgeIndex-1;
|
||||
|
||||
// index of next element
|
||||
if (anEdgeIndex == anEndIndex) anEdgeIndex_Next = aStartIndex;
|
||||
else anEdgeIndex_Next = anEdgeIndex+1;
|
||||
|
||||
const TopoDS_Edge& aCurEdge = anEdgeExp->Edge(anEdgeIndex);
|
||||
|
||||
TopoDS_Vertex aCurFirstVertex = TopExp::FirstVertex(aCurEdge);
|
||||
TopoDS_Vertex aCurLastVertex = TopExp::LastVertex(aCurEdge);
|
||||
|
||||
Standard_Boolean anIsFirstBelong = theVertex.IsSame(aCurFirstVertex);
|
||||
Standard_Boolean anIsLastBelong = theVertex.IsSame(aCurLastVertex);
|
||||
|
||||
if (!anIsFirstBelong && !anIsLastBelong)
|
||||
continue;
|
||||
|
||||
//int todo_investigate_degenerated_edge;
|
||||
|
||||
Standard_Real aPFirstParamOfCurEdge, aPLastParamOfCurEdge;
|
||||
Handle(Geom2d_Curve) aPCurveOfCurEdge =
|
||||
BRep_Tool::CurveOnSurface (aCurEdge, theFace, aPFirstParamOfCurEdge, aPLastParamOfCurEdge);
|
||||
|
||||
if (anIsFirstBelong && anIsLastBelong) // both ends of current edge belong to the vertex
|
||||
{
|
||||
aPCurveOfCurEdge->D0(aPFirstParamOfCurEdge, aPFirst2D);
|
||||
aPCurveOfCurEdge->D0(aPLastParamOfCurEdge, aPSecond2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (anIsFirstBelong) // first end of current edge
|
||||
aPCurveOfCurEdge->D0(aPFirstParamOfCurEdge, aPFirst2D);
|
||||
else if (anIsLastBelong) // last end of current edge
|
||||
aPCurveOfCurEdge->D0(aPLastParamOfCurEdge, aPFirst2D);
|
||||
|
||||
// is second edge nether next edge in the sequence or previous?
|
||||
TopAbs_Orientation aCurEdgeOrient = aCurEdge.Orientation();
|
||||
Standard_Boolean anIsSecondANextEdge =
|
||||
(aCurEdgeOrient == TopAbs_FORWARD && anIsLastBelong) ||
|
||||
(aCurEdgeOrient == TopAbs_REVERSED && anIsFirstBelong);
|
||||
|
||||
Standard_Integer anIndexOfEdgeWithSecondPnt =
|
||||
(anIsSecondANextEdge ? anEdgeIndex_Next : anEdgeIndex_Prev);
|
||||
|
||||
//
|
||||
const TopoDS_Edge& anEdgeWithSecondPnt = anEdgeExp->Edge(anIndexOfEdgeWithSecondPnt);
|
||||
TopAbs_Orientation anOrientOfEdgeWithSecondPnt = anEdgeWithSecondPnt.Orientation();
|
||||
|
||||
Standard_Boolean isFirstVertexOfEdgeWithSecondPnt = Standard_True;
|
||||
if (anIsSecondANextEdge) // next edge in the edge sequence
|
||||
{
|
||||
if (anOrientOfEdgeWithSecondPnt == TopAbs_FORWARD)
|
||||
isFirstVertexOfEdgeWithSecondPnt = Standard_True;
|
||||
else
|
||||
isFirstVertexOfEdgeWithSecondPnt = Standard_False;
|
||||
}
|
||||
else // previous edge in sequence in the edge sequence
|
||||
{
|
||||
if (anOrientOfEdgeWithSecondPnt == TopAbs_FORWARD)
|
||||
isFirstVertexOfEdgeWithSecondPnt = Standard_False;
|
||||
else
|
||||
isFirstVertexOfEdgeWithSecondPnt = Standard_True;
|
||||
}
|
||||
|
||||
Standard_Real aFirstParamOfEdgeWithSecondPnt, aLastParamOfEdgeWithSecondPnt;
|
||||
Handle(Geom2d_Curve) aPCurveOfEdgeWithSecondPnt =
|
||||
BRep_Tool::CurveOnSurface (anEdgeWithSecondPnt, theFace,
|
||||
aFirstParamOfEdgeWithSecondPnt,
|
||||
aLastParamOfEdgeWithSecondPnt);
|
||||
|
||||
if (isFirstVertexOfEdgeWithSecondPnt)
|
||||
aPCurveOfEdgeWithSecondPnt->D0(aFirstParamOfEdgeWithSecondPnt, aPSecond2D);
|
||||
else
|
||||
aPCurveOfEdgeWithSecondPnt->D0(aLastParamOfEdgeWithSecondPnt, aPSecond2D);
|
||||
}
|
||||
|
||||
if (aPFirst2D.Distance(aPSecond2D) <= Precision::Confusion())
|
||||
continue;
|
||||
|
||||
// project points of edges on aPVec2D
|
||||
Standard_Real aProjLength = ProjectTo2DVector(anEdgeExp, theFace, aPntNbPerEdgeForProj, aPFirst2D, aPSecond2D);
|
||||
|
||||
gp_Vec2d aPVec2D(aPFirst2D, aPSecond2D);
|
||||
if (aProjLength <= aStripRatio*aPVec2D.Magnitude())
|
||||
{
|
||||
TopLoc_Location aLocation;
|
||||
Handle(Geom_Surface) aSurf = BRep_Tool::Surface (theFace, aLocation);
|
||||
|
||||
aSurf->D0(aPFirst2D.X() , aPFirst2D.Y(), theFirstPnt);
|
||||
aSurf->D0(aPSecond2D.X(), aPSecond2D.Y(), theSecondPnt);
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertLackingVerticesTo2D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void ShapeFix_LackingEdgeRecover::ConvertLackingVerticesTo2D(const TopoDS_Wire& theWire,
|
||||
const TopoDS_Face& theFace,
|
||||
const TopoDS_Vertex& theFirstVertex,
|
||||
const TopoDS_Vertex& theSecondVertex,
|
||||
gp_Pnt2d& theFirstPnt2D,
|
||||
gp_Pnt2d& theSecondPnt2D) const
|
||||
{
|
||||
Standard_Boolean aHasFirstBeenFound = Standard_False;
|
||||
Standard_Boolean aHasSecondBeenFound = Standard_False;
|
||||
TopoDS_Iterator anEdgeIter(theWire);
|
||||
for (; anEdgeIter.More(); anEdgeIter.Next())
|
||||
{
|
||||
const TopoDS_Edge& aCurEdge = TopoDS::Edge(anEdgeIter.Value());
|
||||
|
||||
Standard_Real aPFirstParamOfCurEdge, aPLastParamOfCurEdge;
|
||||
Handle(Geom2d_Curve) aCurCurve2D =
|
||||
BRep_Tool::CurveOnSurface(aCurEdge, theFace, aPFirstParamOfCurEdge, aPLastParamOfCurEdge);
|
||||
|
||||
TopoDS_Iterator aVertexIter(aCurEdge);
|
||||
for (; aVertexIter.More(); aVertexIter.Next())
|
||||
{
|
||||
const TopoDS_Vertex& aCurVertex = TopoDS::Vertex(aVertexIter.Value());
|
||||
if (!aHasFirstBeenFound)
|
||||
{
|
||||
if (theFirstVertex.IsSame(aCurVertex))
|
||||
{
|
||||
aHasFirstBeenFound = Standard_True;
|
||||
theFirstPnt2D = ConvertTo2D(aCurEdge, aCurVertex, aCurCurve2D,
|
||||
aPFirstParamOfCurEdge, aPLastParamOfCurEdge);
|
||||
}
|
||||
}
|
||||
|
||||
if (!aHasSecondBeenFound)
|
||||
{
|
||||
if (theSecondVertex.IsSame(aCurVertex))
|
||||
{
|
||||
aHasSecondBeenFound = Standard_True;
|
||||
theSecondPnt2D = ConvertTo2D(aCurEdge, aCurVertex, aCurCurve2D,
|
||||
aPFirstParamOfCurEdge, aPLastParamOfCurEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aHasFirstBeenFound && aHasSecondBeenFound)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MakeBSplineLackingCurve2D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Handle(Geom2d_BSplineCurve) ShapeFix_LackingEdgeRecover::MakeBSplineLackingCurve2D(
|
||||
const gp_Pnt2d& theFirstPnt2D,
|
||||
const gp_Pnt2d& theSecondPnt2D) const
|
||||
{
|
||||
TColgp_Array1OfPnt2d aPolesOfBSplineCurve (1, 2);
|
||||
aPolesOfBSplineCurve(1).SetCoord(theFirstPnt2D.X(), theFirstPnt2D.Y());
|
||||
aPolesOfBSplineCurve(2).SetCoord(theSecondPnt2D.X(), theSecondPnt2D.Y());
|
||||
|
||||
TColStd_Array1OfReal aKnotesOfBSplineCurve(1, 2);
|
||||
aKnotesOfBSplineCurve(1) = 0.0;
|
||||
aKnotesOfBSplineCurve(2) = 1.0;
|
||||
|
||||
TColStd_Array1OfInteger aMultiplicities (1, 2);
|
||||
aMultiplicities(1) = 2;
|
||||
aMultiplicities(2) = 2;
|
||||
|
||||
return new Geom2d_BSplineCurve(aPolesOfBSplineCurve, aKnotesOfBSplineCurve, aMultiplicities, 1, 0);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertTo2D
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
gp_Pnt2d ShapeFix_LackingEdgeRecover::ConvertTo2D(const TopoDS_Edge& theEdge,
|
||||
const TopoDS_Vertex& theVertex,
|
||||
const Handle(Geom2d_Curve)& theCurve2D,
|
||||
const Standard_Real thePFirst,
|
||||
const Standard_Real thePLast) const
|
||||
{
|
||||
gp_Pnt2d aPnt2d;
|
||||
if (theEdge.Orientation() == TopAbs_FORWARD)
|
||||
{
|
||||
if (theVertex.Orientation() == TopAbs_FORWARD)
|
||||
theCurve2D->D0(thePFirst, aPnt2d);
|
||||
else
|
||||
theCurve2D->D0(thePLast, aPnt2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (theVertex.Orientation() == TopAbs_FORWARD)
|
||||
theCurve2D->D0(thePLast, aPnt2d);
|
||||
else
|
||||
theCurve2D->D0(thePFirst, aPnt2d);
|
||||
}
|
||||
|
||||
return aPnt2d;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ProjectTo2DVector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real ShapeFix_LackingEdgeRecover::ProjectTo2DVector(const Handle(ShapeExtend_WireData)& theWireData,
|
||||
const TopoDS_Face& theFace,
|
||||
const Standard_Real thePntNbPerEdgeForProj,
|
||||
const gp_Pnt2d& thePFirst2D,
|
||||
const gp_Pnt2d& thePSecond2D) const
|
||||
{
|
||||
gp_Vec2d aPVec2D(thePFirst2D, thePSecond2D);
|
||||
|
||||
Standard_Integer aStartIndex = 1; // start index of ShapeExtend_WireData
|
||||
Standard_Integer anEndIndex = theWireData->NbEdges();
|
||||
|
||||
// project points of edges on aPVec2D
|
||||
Standard_Real aMaxWireValue = -Precision::Infinite();
|
||||
Standard_Real aMinWireValue = Precision::Infinite();
|
||||
|
||||
Standard_Integer aCurEdgeIndex = aStartIndex;
|
||||
for (; aCurEdgeIndex <= anEndIndex; aCurEdgeIndex++)
|
||||
{
|
||||
Standard_Real aPFirstParamOfIntCurEdge, aPLastParamOfIntCurEdge;
|
||||
Handle(Geom2d_Curve) aPCurveOfIntCurEdge =
|
||||
BRep_Tool::CurveOnSurface (theWireData->Edge(aCurEdgeIndex), theFace,
|
||||
aPFirstParamOfIntCurEdge, aPLastParamOfIntCurEdge);
|
||||
|
||||
// split the curve of the current edge on aPntNbPerEdgeForProj parts
|
||||
Standard_Integer aCurStep = 0;
|
||||
Standard_Real aPCurParam = aPFirstParamOfIntCurEdge;
|
||||
Standard_Real aStepSize = (aPLastParamOfIntCurEdge - aPFirstParamOfIntCurEdge)/thePntNbPerEdgeForProj;
|
||||
while (aPCurParam <= aPLastParamOfIntCurEdge)
|
||||
{
|
||||
aPCurParam = aPFirstParamOfIntCurEdge + aCurStep*aStepSize;
|
||||
|
||||
gp_Pnt2d aPCur2D;
|
||||
aPCurveOfIntCurEdge->D0(aPCurParam, aPCur2D);
|
||||
|
||||
// project current parametric point on the vector (by scalar product)
|
||||
Standard_Real aStepFromPFirst2D = aPVec2D*gp_Vec2d(thePFirst2D, aPCur2D) / aPVec2D.Magnitude();
|
||||
|
||||
aMaxWireValue = Max(aMaxWireValue, aStepFromPFirst2D);
|
||||
aMinWireValue = Min(aMinWireValue, aStepFromPFirst2D);
|
||||
|
||||
aCurStep++;
|
||||
}
|
||||
}
|
||||
|
||||
return Abs(aMaxWireValue - aMinWireValue);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user