1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0026682: TopExp::MapShapesAndAncestors() will build map with duplicated ancestors.

The new method TopExp::MapShapesAndUniqueAncestors has been implemented, which excludes duplication of ancestors in the list items. The optional Boolean argument 'useOrientation' of this method points whether two same shapes with different orientation will be considered equal.
OCCT code has been inspected and MapShapesAndAncestors has been replaced with MapShapesAndUniqueAncestors where it is necessary.
This commit is contained in:
mpa 2017-03-03 13:57:36 +03:00 committed by mkv
parent 4d597f3e2f
commit f1191d3099
13 changed files with 93 additions and 241 deletions

View File

@ -192,8 +192,8 @@ void ReduceVertexTolerance (const TopoDS_Shape& aS)
Standard_Integer i, aNbV;
TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap;
TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
aNbV=aVEMap.Extent();
for (i=1; i<=aNbV; i++) {
@ -299,7 +299,6 @@ void ProcessVertex(const TopoDS_Vertex& aV,
TopAbs_Orientation anOrV;
TopTools_ListIteratorOfListOfShape anIt;
TopTools_MapOfShape aProcessedEdges;
TopExp_Explorer aVExp;
BRep_ListIteratorOfListOfCurveRepresentation itcr;
@ -314,11 +313,6 @@ void ProcessVertex(const TopoDS_Vertex& aV,
for (; anIt.More(); anIt.Next()) {
const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
//
if (aProcessedEdges.Contains(aE)) {
continue;
}
aProcessedEdges.Add(aE);
//
Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape());
const TopLoc_Location& Eloc = aE.Location();
//
@ -395,32 +389,20 @@ void ProcessVertex(const TopoDS_Vertex& aV,
return;
}
//
aProcessedEdges.Clear();
anIt.Initialize(aLE);
for (; anIt.More(); anIt.Next()) {
const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
if (aProcessedEdges.Contains(aE)) {
continue;
}
aProcessedEdges.Add(aE);
aTolE =BRep_Tool::Tolerance(aE);
if (aTolMax2 < aTolE) {
aTolMax2=aTolE;
}
}
//
aProcessedEdges.Clear();
anIt.Initialize(aLF);
for (; anIt.More(); anIt.Next()) {
const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
if (aProcessedEdges.Contains(aF)) {
continue;
}
aProcessedEdges.Add(aF);
aTolE =BRep_Tool::Tolerance(aF);
if (aTolMax2 < aTolE) {
aTolMax2=aTolE;

View File

@ -1470,20 +1470,17 @@ void BRepLib::UpdateTolerances(const TopoDS_Shape& aShape,
//Vertices are processed
const Standard_Real BigTol = 1.e10;
parents.Clear();
TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, parents);
TopExp::MapShapesAndUniqueAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, parents);
TColStd_MapOfTransient Initialized;
TopTools_MapOfShape Done;
Standard_Integer nbV = parents.Extent();
for (iCur=1; iCur<=nbV; iCur++) {
tol=0;
Done.Clear();
const TopoDS_Vertex& V = TopoDS::Vertex(parents.FindKey(iCur));
Bnd_Box box;
box.Add(BRep_Tool::Pnt(V));
gp_Pnt p3d;
for (lConx.Initialize(parents(iCur)); lConx.More(); lConx.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(lConx.Value());
if(!Done.Add(E)) continue;
tol=Max(tol, BRep_Tool::Tolerance(E));
if(tol > BigTol) continue;
if(!BRep_Tool::SameRange(E)) continue;

View File

@ -380,7 +380,7 @@ void BRepLib_FuseEdges::BuildListEdges()
myMapVerLstEdg.Clear();
myMapEdgLstFac.Clear();
BuildAncestors(myShape,TopAbs_VERTEX,TopAbs_EDGE,myMapVerLstEdg);
TopExp::MapShapesAndUniqueAncestors(myShape,TopAbs_VERTEX,TopAbs_EDGE,myMapVerLstEdg);
TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgLstFac);
Standard_Integer iEdg;
@ -1000,49 +1000,6 @@ Standard_Boolean BRepLib_FuseEdges::SameSupport(const TopoDS_Edge& E1,
return Standard_False;
}
//=======================================================================
//function : BuildAncestors
//purpose : This function is like TopExp::MapShapesAndAncestors except
// that in the list of shape we do not want duplicate shapes.
// if this is useful for other purpose we should create a new method in
// TopExp
//=======================================================================
void BRepLib_FuseEdges::BuildAncestors
(const TopoDS_Shape& S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape& M) const
{
TopTools_MapOfShape mapDuplicate;
TopTools_ListIteratorOfListOfShape it;
Standard_Integer iSh;
TopExp::MapShapesAndAncestors(S,TS,TA,M);
// for each shape of M
for (iSh = 1; iSh <= M.Extent(); iSh++) {
TopTools_ListOfShape& Lsh = M(iSh);
mapDuplicate.Clear();
// we check for duplicate in the list of Shape
it.Initialize(Lsh);
while (it.More() ) {
if (!mapDuplicate.Contains(it.Value())) {
mapDuplicate.Add(it.Value());
it.Next();
}
else {
Lsh.Remove(it);
}
}
}
}
//=======================================================================
//function : UpdatePCurve
//purpose :

View File

@ -101,12 +101,6 @@ protected:
private:
//! build a map of shapes and ancestors, like
//! TopExp.MapShapesAndAncestors, but we remove duplicate
//! shapes in list of shapes.
Standard_EXPORT void BuildAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M) const;
//! Build the all the lists of edges that are to be fused
Standard_EXPORT void BuildListEdges();

View File

@ -126,27 +126,11 @@ static void EdgeAnalyse(const TopoDS_Edge& E,
//=======================================================================
static void BuildAncestors (const TopoDS_Shape& S,
TopTools_IndexedDataMapOfShapeListOfShape& MA)
TopTools_IndexedDataMapOfShapeListOfShape& MA)
{
MA.Clear();
TopExp::MapShapesAndAncestors(S,TopAbs_VERTEX,TopAbs_EDGE,MA);
TopExp::MapShapesAndAncestors(S,TopAbs_EDGE ,TopAbs_FACE,MA);
// Purge ancestors.
TopTools_MapOfShape Map;
for (Standard_Integer i = 1; i <= MA.Extent(); i++) {
Map.Clear();
TopTools_ListOfShape& L = MA(i);
TopTools_ListIteratorOfListOfShape it(L);
while (it.More()) {
if (!Map.Add(it.Value())) {
L.Remove(it);
}
else {
it.Next();
}
}
}
TopExp::MapShapesAndUniqueAncestors(S,TopAbs_VERTEX,TopAbs_EDGE,MA);
TopExp::MapShapesAndUniqueAncestors(S,TopAbs_EDGE ,TopAbs_FACE,MA);
}
//=======================================================================

View File

@ -445,33 +445,7 @@ void BRepOffset_Inter3d::ConnexIntByInt
TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap);
//
// make vertex-faces connexity map with unique ancestors
// TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
TopExp_Explorer aExpF(SI, TopAbs_FACE);
for (; aExpF.More(); aExpF.Next()) {
const TopoDS_Shape& aF = aExpF.Current();
//
TopExp_Explorer aExpV(aF, TopAbs_VERTEX);
for (; aExpV.More(); aExpV.Next()) {
const TopoDS_Shape& aV = aExpV.Current();
//
TopTools_ListOfShape *pLF = aMVF.ChangeSeek(aV);
if (!pLF) {
pLF = &aMVF(aMVF.Add(aV, TopTools_ListOfShape()));
pLF->Append(aF);
continue;
}
//
TopTools_ListIteratorOfListOfShape aItLF(*pLF);
for (; aItLF.More(); aItLF.Next()) {
if (aItLF.Value().IsSame(aF)) {
break;
}
}
if (!aItLF.More()) {
pLF->Append(aF);
}
}
}
TopExp::MapShapesAndUniqueAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF);
}
//
TopTools_DataMapOfShapeListOfShape aDMVLF1, aDMVLF2, aDMIntFF;

View File

@ -40,7 +40,7 @@
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
//=======================================================================
//function : QANewBRepNaming_ImportShape
@ -205,45 +205,18 @@ void QANewBRepNaming_ImportShape::LoadNextLevels(const TopoDS_Shape& S,
void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
const Handle(TDF_TagSource)& Tagger) const
{
// vro: It sets vertices twicely:
// TopTools_IndexedDataMapOfShapeListOfShape vertexNaborFaces;
// TopExp::MapShapesAndAncestors(S, TopAbs_VERTEX, TopAbs_FACE, vertexNaborFaces);
TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
TopTools_ListOfShape empty;
TopExp_Explorer explF(S, TopAbs_FACE);
for (; explF.More(); explF.Next()) {
const TopoDS_Shape& aFace = explF.Current();
TopExp_Explorer explV(aFace, TopAbs_EDGE);
for (; explV.More(); explV.Next()) {
const TopoDS_Shape& anEdge = explV.Current();
if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
Standard_Boolean faceIsNew = Standard_True;
TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
for (; itrF.More(); itrF.Next()) {
if (itrF.Value().IsSame(aFace)) {
faceIsNew = Standard_False;
break;
}
}
if (faceIsNew) {
edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
}
}
}
TopTools_IndexedDataMapOfShapeListOfShape edgeNaborFaces;
TopExp::MapShapesAndUniqueAncestors(S, TopAbs_EDGE, TopAbs_FACE, edgeNaborFaces);
TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator becouse we need keep edges order
for(;anEx.More();anEx.Next()) {
TopTools_MapOfShape aEdgesToRemove;
for(Standard_Integer i = 1; i <= edgeNaborFaces.Extent(); i++) {
Standard_Boolean aC0 = Standard_False;
TopoDS_Shape anEdge1 = anEx.Current();
if (edgeNaborFaces.IsBound(anEdge1)) {
TopTools_ListOfShape aEdgesToRemove; // record items to be removed from the map (should be done after iteration)
aEdgesToRemove.Append (anEdge1);
const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
for (; itr.More(); itr.Next()) {
TopoDS_Shape anEdge2 = itr.Key();
if (anEdge1.IsSame(anEdge2)) continue;
const TopTools_ListOfShape& aList2 = itr.Value();
TopoDS_Shape anEdge1 = edgeNaborFaces.FindKey(i);
if (aEdgesToRemove.Add(anEdge1)) {
const TopTools_ListOfShape& aList1 = edgeNaborFaces.FindFromIndex(i);
for(Standard_Integer j = i + 1; j <= edgeNaborFaces.Extent(); j++) {
TopoDS_Shape anEdge2 = edgeNaborFaces.FindKey(j);
const TopTools_ListOfShape& aList2 = edgeNaborFaces.FindFromIndex(j);
// compare lists of the neighbour faces of edge1 and edge2
if (aList1.Extent() == aList2.Extent()) {
Standard_Integer aMatches = 0;
@ -254,14 +227,11 @@ void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
aC0=Standard_True;
TNaming_Builder bC0Edge(Tagger->NewChild());
bC0Edge.Generated(anEdge2);
aEdgesToRemove.Append (anEdge2);
aEdgesToRemove.Add(anEdge2);
}
}
}
// remove items from the data map
for(TopTools_ListIteratorOfListOfShape anIt(aEdgesToRemove); anIt.More(); anIt.Next())
edgeNaborFaces.UnBind(anIt.Value());
}
}
if (aC0) {
TNaming_Builder bC0Edge(Tagger->NewChild());
bC0Edge.Generated(anEdge1);

View File

@ -1134,11 +1134,7 @@ static void CheckSharedVertices(const TopTools_SequenceOfShape& theSeqEdges,
for (Standard_Integer k = 1; k <= SeqVertexes.Length()/* && !IsSharedVertexPresent*/; k++ )
{
const TopTools_ListOfShape& ListEdgesV1 = theMapEdgesVertex.FindFromKey(SeqVertexes(k));
TopTools_MapOfShape aMapOfEdges;
TopTools_ListIteratorOfListOfShape iter(ListEdgesV1);
for (; iter.More(); iter.Next())
aMapOfEdges.Add(iter.Value());
if (aMapOfEdges.Extent() > 2 || theMapKeepShape.Contains(SeqVertexes(k)))
if (ListEdgesV1.Extent() > 2 || theMapKeepShape.Contains(SeqVertexes(k)))
theShareVertMap.Add(SeqVertexes(k));
}
//return theShareVertMap.IsEmpty() ? false : true;
@ -1832,7 +1828,7 @@ void ShapeUpgrade_UnifySameDomain::UnifyEdges()
// creating map of vertex edges
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgesVertex;
TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
TopExp::MapShapesAndUniqueAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMapEdgesVertex);
//Handle(ShapeBuild_ReShape) aContext = new ShapeBuild_ReShape;
TopoDS_Shape aRes = myShape;

View File

@ -99,7 +99,55 @@ void TopExp::MapShapesAndAncestors
}
}
//=======================================================================
//function : MapShapesAndUniqueAncestors
//purpose :
//=======================================================================
void TopExp::MapShapesAndUniqueAncestors
(const TopoDS_Shape& S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape& M,
const Standard_Boolean useOrientation)
{
TopTools_ListOfShape empty;
// visit ancestors
TopExp_Explorer exa(S,TA);
while (exa.More())
{
// visit shapes
const TopoDS_Shape& anc = exa.Current();
TopExp_Explorer exs(anc,TS);
while (exs.More())
{
Standard_Integer index = M.FindIndex(exs.Current());
if (index == 0)
index = M.Add(exs.Current(),empty);
TopTools_ListOfShape& aList = M(index);
// check if anc already exists in a list
TopTools_ListIteratorOfListOfShape it(aList);
for (; it.More(); it.Next())
if (useOrientation? anc.IsEqual(it.Value()) : anc.IsSame(it.Value()))
break;
if (!it.More())
aList.Append(anc);
exs.Next();
}
exa.Next();
}
// visit shapes not under ancestors
TopExp_Explorer ex(S,TS,TA);
while (ex.More())
{
Standard_Integer index = M.FindIndex(ex.Current());
if (index == 0)
M.Add(ex.Current(),empty);
ex.Next();
}
}
//=======================================================================
//function : FirstVertex

View File

@ -66,6 +66,15 @@ public:
//! Warning: The map is not cleared at first.
Standard_EXPORT static void MapShapesAndAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M);
//! Stores in the map <M> all the subshape of <S> of
//! type <TS> for each one append to the list all
//! unique ancestors of type <TA>. For example map all
//! the edges and bind the list of faces.
//! useOrientation = True : taking account the ancestor orientation
//! Warning: The map is not cleared at first.
Standard_EXPORT static void MapShapesAndUniqueAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M,
const Standard_Boolean useOrientation = Standard_False);
//! Returns the Vertex of orientation FORWARD in E. If
//! there is none returns a Null Shape.
//! CumOri = True : taking account the edge orientation

View File

@ -174,7 +174,7 @@ void TopOpeBRepBuild_Builder::End()
#endif
TopTools_IndexedDataMapOfShapeListOfShape idmoelof; TopExp::MapShapesAndAncestors(R,TopAbs_EDGE,TopAbs_FACE,idmoelof);
TopTools_IndexedDataMapOfShapeListOfShape idmovloe; TopExp::MapShapesAndAncestors(R,TopAbs_VERTEX,TopAbs_EDGE,idmovloe);
TopTools_IndexedDataMapOfShapeListOfShape idmovloe; TopExp::MapShapesAndUniqueAncestors(R,TopAbs_VERTEX,TopAbs_EDGE,idmovloe);
TopTools_IndexedDataMapOfShapeListOfShape idmovloes; for (TopTools_ListIteratorOfListOfShape I(LOES);I.More();I.Next())
TopExp::MapShapesAndAncestors(I.Value(),TopAbs_VERTEX,TopAbs_EDGE,idmovloes);
Standard_Integer iv,nv = idmovloe.Extent();
@ -184,33 +184,23 @@ void TopOpeBRepBuild_Builder::End()
Standard_Boolean isbe = idmovloes.Contains(V);
if ( !isbe ) continue;
const TopTools_ListOfShape& loe1 = idmovloe.FindFromIndex(iv);
#ifdef OCCT_DEBUG
// Standard_Integer nloe1 = loe1.Extent();
#endif
TopTools_MapOfShape mose; //une seule fois chaque arete
TopTools_ListOfShape loe;
TopTools_ListIteratorOfListOfShape iloe;
for (iloe.Initialize(loe1);iloe.More();iloe.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
Standard_Boolean isb = mose.Contains(E); if (isb) continue;
mose.Add(E);loe.Append(E);
}
const TopTools_ListOfShape& loe = idmovloe.FindFromIndex(iv);
#ifdef OCCT_DEBUG
// Standard_Integer nloe = loe.Extent();
#endif
TopTools_ListIteratorOfListOfShape iloe;
for (iloe.Initialize(loe);iloe.More();iloe.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
Standard_Integer nlof = lof.Extent();
nP1 += nlof+1;
const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
Standard_Integer nlof = lof.Extent();
nP1 += nlof+1;
}
TColgp_Array1OfPnt TP(1,nP1);
Standard_Integer nP2 = 0;
for (iloe.Initialize(loe);iloe.More();iloe.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
const TopoDS_Edge& E = TopoDS::Edge(iloe.Value());
Standard_Real pv = BRep_Tool::Parameter(V,E);
gp_Pnt Pv;
Standard_Real f,l;Handle(Geom_Curve) C3D = BRep_Tool::Curve(E,f,l);
@ -218,12 +208,12 @@ void TopOpeBRepBuild_Builder::End()
Pv = C3D->Value(pv);
TP(++nP2) = Pv;
}
const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
const TopTools_ListOfShape& lof = idmoelof.FindFromKey(E);
#ifdef OCCT_DEBUG
// Standard_Integer nlof = lof.Extent();
#endif
for (TopTools_ListIteratorOfListOfShape ilof(lof);ilof.More();ilof.Next()) {
const TopoDS_Face& F = TopoDS::Face(ilof.Value());
for (TopTools_ListIteratorOfListOfShape ilof(lof);ilof.More();ilof.Next()) {
const TopoDS_Face& F = TopoDS::Face(ilof.Value());
Standard_Real tolpc;
Standard_Boolean pcf = FC2D_HasCurveOnSurface(E,F);
Handle(Geom2d_Curve) C2D;

View File

@ -239,7 +239,7 @@ void TopOpeBRepTool_FuseEdges::BuildListEdges()
myMapVerLstEdg.Clear();
myMapEdgLstFac.Clear();
BuildAncestors(myShape,TopAbs_VERTEX,TopAbs_EDGE,myMapVerLstEdg);
TopExp::MapShapesAndUniqueAncestors(myShape,TopAbs_VERTEX,TopAbs_EDGE,myMapVerLstEdg);
TopExp::MapShapesAndAncestors(myShape,TopAbs_EDGE,TopAbs_FACE,myMapEdgLstFac);
Standard_Integer iEdg;
@ -826,49 +826,6 @@ Standard_Boolean TopOpeBRepTool_FuseEdges::SameSupport(const TopoDS_Edge& E1,
return Standard_False;
}
//=======================================================================
//function : BuildAncestors
//purpose : This function is like TopExp::MapShapesAndAncestors except
// that in the list of shape we do not want duplicate shapes.
// if this is useful for other purpose we should create a new method in
// TopExp
//=======================================================================
void TopOpeBRepTool_FuseEdges::BuildAncestors
(const TopoDS_Shape& S,
const TopAbs_ShapeEnum TS,
const TopAbs_ShapeEnum TA,
TopTools_IndexedDataMapOfShapeListOfShape& M) const
{
TopTools_MapOfShape mapDuplicate;
TopTools_ListIteratorOfListOfShape it;
Standard_Integer iSh;
TopExp::MapShapesAndAncestors(S,TS,TA,M);
// for each shape of M
for (iSh = 1; iSh <= M.Extent(); iSh++) {
TopTools_ListOfShape& Lsh = M(iSh);
mapDuplicate.Clear();
// we check for duplicate in the list of Shape
it.Initialize(Lsh);
while (it.More() ) {
if (!mapDuplicate.Contains(it.Value())) {
mapDuplicate.Add(it.Value());
it.Next();
}
else {
Lsh.Remove(it);
}
}
}
}
//=======================================================================
//function : UpdatePCurve
//purpose :

View File

@ -98,12 +98,6 @@ protected:
private:
//! build a map of shapes and ancestors, like
//! TopExp.MapShapesAndAncestors, but we remove duplicate
//! shapes in list of shapes.
Standard_EXPORT void BuildAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M) const;
//! Build the all the lists of edges that are to be fused
Standard_EXPORT void BuildListEdges();