1 // Created on: 2001-01-16
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
17 #include <BRep_Builder.hxx>
18 #include <BRep_Tool.hxx>
19 #include <BRepAlgo_EdgeConnector.hxx>
20 #include <BRepBuilderAPI_MakeWire.hxx>
21 #include <BRepExtrema_DistShapeShape.hxx>
22 #include <BRepIntCurveSurface_Inter.hxx>
23 #include <BRepTopAdaptor_FClass2d.hxx>
24 #include <Geom_Curve.hxx>
25 #include <GeomAdaptor_Curve.hxx>
26 #include <GeomAPI_ProjectPointOnCurve.hxx>
27 #include <GeomAPI_ProjectPointOnSurf.hxx>
28 #include <GeomProjLib.hxx>
30 #include <Precision.hxx>
31 #include <QANewModTopOpe_Glue.hxx>
32 #include <TColgp_SequenceOfPnt.hxx>
33 #include <TColStd_Array2OfInteger.hxx>
34 #include <TColStd_SequenceOfInteger.hxx>
35 #include <TColStd_SequenceOfReal.hxx>
37 #include <TopExp_Explorer.hxx>
39 #include <TopoDS_Edge.hxx>
40 #include <TopoDS_Face.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Shape.hxx>
43 #include <TopoDS_Vertex.hxx>
44 #include <TopOpeBRepTool_TOOL.hxx>
45 #include <TopTools_Array2OfShape.hxx>
46 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_IndexedMapOfShape.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 //#include <BRepClass_FaceClassifier.hxx>
52 //=======================================================================
53 //function : IsOnSurface
55 //=======================================================================
56 static Standard_Boolean
57 IsOnSurface (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
59 Standard_Real aParF, aParL, aTolEdge;
60 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL);
61 if (aCurve.IsNull()) return Standard_False;
62 aTolEdge = BRep_Tool::Tolerance(theEdge);
63 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
65 // define check points
66 Standard_Real aParams[4];
67 Standard_Real aDeltaRange = aParL - aParF;
69 aParams[1] = aParF + aDeltaRange * 0.382;
70 aParams[2] = aParF + aDeltaRange * 0.618;
74 // check distance to the surface
75 Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace);
77 for (i=0; i < 4; i++) {
78 aPnt = aCurve->Value(aParams[i]);
79 GeomAPI_ProjectPointOnSurf aProjector(aPnt, aSurf);
80 if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol)
81 return Standard_False;
87 //=======================================================================
88 //function : ProcessEdgeFaceInterference
90 //=======================================================================
93 ProcessEdgeFaceInterference (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
94 TopoDS_Shape& theNewFace,
95 TopTools_ListOfShape& theListE,
96 TColgp_SequenceOfPnt& thePoints1,
97 TColgp_SequenceOfPnt& thePoints2,
98 TColStd_SequenceOfInteger& theEdgeOnSurface,
99 TopTools_DataMapOfShapeListOfShape& theMapSubst,
100 TopTools_DataMapOfShapeListOfShape& theMapGener)
105 Standard_Boolean anIsOnSurface = IsOnSurface(theEdge, theFace);
106 TColgp_SequenceOfPnt aPntOfInter;
107 TColStd_SequenceOfReal aW;
108 TopTools_ListOfShape aListOfIntVert;
110 //check intersection points
111 BRepIntCurveSurface_Inter anInter;
113 const TopoDS_Edge& anE = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD));
114 Handle(Geom_Curve) aC =
115 BRep_Tool::Curve(anE, f, l);
116 GeomAdaptor_Curve anAdC(aC, f, l);
117 anInter.Init(theFace, anAdC, Precision::PConfusion());
118 for(; anInter.More(); anInter.Next()) {
119 if(anInter.State() == TopAbs_ON) { continue;}
120 aPntOfInter.Append(anInter.Pnt());
121 aW.Append(anInter.W());
126 TopoDS_Vertex aV1, aV2;
127 TopExp::Vertices(anE, aV1, aV2);
129 aBld.MakeCompound(TopoDS::Compound(aCmp));
131 if(!aV1.IsSame(aV2)) aBld.Add(aCmp, aV2);
133 TopoDS_Iterator anItV(theEdge);
134 for(; anItV.More(); anItV.Next()) {
135 if(anItV.Value().Orientation() == TopAbs_INTERNAL)
136 aBld.Add(aCmp, anItV.Value());
139 BRepExtrema_DistShapeShape aExtrema (theFace, aCmp);
140 if (aExtrema.IsDone()) {
141 Standard_Integer nbSol = aExtrema.NbSolution(), i, j;
142 Standard_Real aDist = aExtrema.Value(), aTol;
143 Standard_Integer n = aPntOfInter.Length();
144 for (i=1; i <= nbSol; i++) {
145 if(aExtrema.SupportTypeShape1(i) != BRepExtrema_IsInFace) continue;
146 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
147 aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aS2));
148 if(aDist > aTol) continue;
149 aListOfIntVert.Append(aS2);
150 //check intersection points on coincidence with vertex
151 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aS2));
152 for(j=1; j <= n; j++) {
153 if(aP.Distance(aPntOfInter(j)) > aTol) continue;
154 aPntOfInter.Remove(j);
164 TopExp_Explorer aExp (theFace.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
165 Standard_Boolean IsNotInternal = Standard_True;
166 Standard_Boolean InsertVertexInBoundary = Standard_True;
167 Standard_Integer aN = thePoints1.Length();
168 for (; aExp.More(); aExp.Next()) {
169 const TopoDS_Edge& aE = TopoDS::Edge (aExp.Current());
170 IsNotInternal = Standard_True;
171 InsertVertexInBoundary = Standard_True;
172 if(aE.Orientation() == TopAbs_EXTERNAL) continue;
173 if(aE.Orientation() == TopAbs_INTERNAL) IsNotInternal = Standard_False;
174 // if (aE.Orientation() != TopAbs_FORWARD &&
175 // aE.Orientation() != TopAbs_REVERSED) continue;
177 BRepExtrema_DistShapeShape aExtrema (aE.Oriented(TopAbs_FORWARD),
178 theEdge.Oriented(TopAbs_FORWARD));
179 if (!aExtrema.IsDone()) continue;
180 Standard_Integer nbSol = aExtrema.NbSolution(), i;
181 Standard_Real aDist = aExtrema.Value();
182 for (i=1; i <= nbSol; i++) {
183 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
184 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
186 // check distance against tolerances
187 Standard_Real aTol1, aTol2;
188 if (aS1.ShapeType() == TopAbs_VERTEX)
189 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
191 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
192 if (aS2.ShapeType() == TopAbs_VERTEX)
193 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
195 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
196 if (aDist > aTol1 + aTol2) continue;
198 // avoid to process the same points twice
199 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
200 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
202 for (j=1; j<=thePoints1.Length(); j++) {
203 if (aPnt1.IsEqual(thePoints1(j),Precision::Confusion()) &&
204 aPnt2.IsEqual(thePoints2(j),Precision::Confusion())) {
205 // if(anIsOnSurface && (theEdgeOnSurface(j) == 1)) break;
206 // if(!anIsOnSurface && (theEdgeOnSurface(j) == 0)) break;
210 if (j > aN && j <= thePoints1.Length()) continue;
212 thePoints1.Remove(j);
213 thePoints2.Remove(j);
214 theEdgeOnSurface.Remove(j);
215 InsertVertexInBoundary = Standard_False;
218 thePoints1.Append (aPnt1);
219 thePoints2.Append (aPnt2);
220 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
221 // find or make the intersection vertex
222 TopoDS_Vertex aVerInt;
223 if (aS2.ShapeType() == TopAbs_VERTEX)
224 aVerInt = TopoDS::Vertex (aS2);
225 else if (aS1.ShapeType() == TopAbs_VERTEX)
226 aVerInt = TopoDS::Vertex (aS1);
229 Standard_Real aTol = Max (aTol1+aDist, aTol2);
230 aBld.MakeVertex (aVerInt, aPnt2, aTol);
233 if (aS1.ShapeType() == TopAbs_VERTEX) {
234 if (!aS1.IsSame(aVerInt) && !theMapSubst.IsBound(aS1)) {
235 // replace vertex from Face with vertex from Edge
236 const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1);
237 // update intersection vertex
238 aTol2 = Max (aTol2, aTol1 + aDist);
239 // Standard_Real aPar = BRep_Tool::Parameter (aVer1, aE);
240 gp_Pnt aP = BRep_Tool::Pnt(aVerInt);
241 // aBld.UpdateVertex (aVerInt, aPar, aE, aTol2);
242 aBld.UpdateVertex (aVerInt, aP, aTol2);
244 TopTools_ListOfShape aList;
245 aList.Append (aVerInt);
246 theMapSubst.Bind (aVer1, aList);
250 else { // aS1 is the same edge as aE
251 // insert intersection vertex in edge from Shell as internal
253 aExtrema.ParOnEdgeS1(i, aPar);
255 if (!theMapSubst.IsBound(aS1)) {
256 // for Mandrake-10 - mkv,02.06.06 - theMapSubst.Bind (aE, TopTools_ListOfShape());
257 TopTools_ListOfShape aListOfShape1;
258 theMapSubst.Bind (aE, aListOfShape1);
260 TopTools_ListOfShape& aListSubst = theMapSubst(aS1);
262 Standard_Boolean aListWasEmpty = Standard_False;
263 if (aListSubst.IsEmpty()) {
264 aListWasEmpty = Standard_True;
265 aEdge = TopoDS::Edge (aS1);
268 // find split by parameter
269 TopTools_ListIteratorOfListOfShape aIt (aListSubst);
270 for (; aIt.More(); aIt.Next()) {
271 Standard_Real aParF, aParL;
272 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
273 BRep_Tool::Range (aE1, aParF, aParL);
274 if (aParF < aPar && aPar < aParL) {
280 aListSubst.Remove (aIt);
283 // unusual, needed split not found, skip to next extrema solution
287 if(InsertVertexInBoundary) {
288 // TopoDS_Edge aNewEdge;
289 // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge);
290 TopTools_ListOfShape aListE;
291 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
292 // aListSubst.Append (aNewEdge);
293 aListSubst.Append (aListE);
294 if (!theMapGener.IsBound(aS1)) {
295 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS1, TopTools_ListOfShape());
296 TopTools_ListOfShape aListOfShape2;
297 theMapGener.Bind(aS1, aListOfShape2);
299 theMapGener(aS1).Append (aVerInt);
302 if(!aListWasEmpty) aListSubst.Append(aEdge);
306 Standard_Boolean isS2InternalVertex =
307 (aS2.ShapeType() == TopAbs_VERTEX && aS2.Orientation() == TopAbs_INTERNAL);
309 if (aS2.ShapeType() == TopAbs_EDGE || isS2InternalVertex) {
312 if (isS2InternalVertex)
313 aPar = BRep_Tool::Parameter (aVerInt, theEdge);
315 aExtrema.ParOnEdgeS2(i, aPar);
318 if (theListE.IsEmpty()) {
322 // find split by parameter
323 TopTools_ListIteratorOfListOfShape aIt (theListE);
324 for (; aIt.More(); aIt.Next()) {
325 Standard_Real aParF, aParL;
326 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
327 BRep_Tool::Range (aE1, aParF, aParL);
328 if (aParF < aPar && aPar < aParL) {
334 theListE.Remove (aIt);
336 // unusual, needed split not found, skip to next extrema solution
340 TopTools_ListOfShape aListE;
341 if(anIsOnSurface && IsNotInternal) {
343 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
344 theListE.Append (aListE);
347 //insert internal vertex in aEdge
348 if(!isS2InternalVertex) {
349 TopoDS_Edge aNewEdge;
350 // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVerInt, aPar, aNewEdge);
351 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aVerInt, aPar, aListE);
352 // theListE.Append(aNewEdge);
353 theListE.Append (aListE);
354 if (!theMapGener.IsBound(aS2)) {
355 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(aS2, TopTools_ListOfShape());
356 TopTools_ListOfShape aListOfShape3;
357 theMapGener.Bind(aS2, aListOfShape3);
359 theMapGener(aS2).Append (aVerInt);
368 // treatmen intersection points
369 // insert internal vertices in face
370 TopTools_ListIteratorOfListOfShape aIt (aListOfIntVert);
373 theNewFace = theFace;
374 for(; aIt.More(); aIt.Next()) {
375 aP = BRep_Tool::Pnt(TopoDS::Vertex(aIt.Value()));
376 aTol = BRep_Tool::Tolerance(TopoDS::Vertex(aIt.Value()));
378 for (j=1; j<=thePoints1.Length(); j++) {
379 if (aP.IsEqual(thePoints1(j),aTol)) break;
381 if (j <= thePoints1.Length()) continue;
382 thePoints1.Append (aP);
383 thePoints2.Append (aP);
384 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
386 // insert internal vertex in face;
387 QANewModTopOpe_Glue aFVGluing(theNewFace, aIt.Value());
388 theNewFace = aFVGluing.Shape();
390 // insert intersection vertices in face and in edge
392 for(k = 1; k <= aPntOfInter.Length(); k++) {
394 for (j=1; j<=thePoints1.Length(); j++) {
395 if (aPntOfInter(k).IsEqual(thePoints1(j),Precision::Confusion())) break;
397 if (j <= thePoints1.Length()) continue;
399 thePoints1.Append (aPntOfInter(k));
400 thePoints2.Append (aPntOfInter(k));
401 theEdgeOnSurface.Append(anIsOnSurface ? 1 : 0);
403 Standard_Real aPar = aW(k);
405 aBld.MakeVertex (aV, aPntOfInter(k), Precision::Confusion());
407 QANewModTopOpe_Glue aFVGluing(theNewFace, aV);
408 theNewFace = aFVGluing.Shape();
409 if (!theMapGener.IsBound(theFace)) {
410 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theFace, TopTools_ListOfShape());
411 TopTools_ListOfShape aListOfShape4;
412 theMapGener.Bind(theFace, aListOfShape4);
414 theMapGener(theFace).Append (aV);
417 if (theListE.IsEmpty())
420 // find split by parameter
421 aIt.Initialize (theListE);
422 for (; aIt.More(); aIt.Next()) {
423 Standard_Real aParF, aParL;
424 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
425 BRep_Tool::Range (aE1, aParF, aParL);
426 if (aParF < aPar && aPar < aParL) {
432 theListE.Remove (aIt);
434 // unusual, needed split not found, skip to next intersection solution
438 // TopoDS_Edge aNewEdge;
439 // QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aV, aPar, aNewEdge);
440 // theListE.Append(aNewEdge);
441 TopTools_ListOfShape aListE;
442 QANewModTopOpe_Glue::SplitEdgeByVertex (aEdge, aV, aPar, aListE);
443 theListE.Append (aListE);
444 if (!theMapGener.IsBound(theEdge)) {
445 // for Mandrake-10 - mkv,02.06.06 - theMapGener.Bind(theEdge, TopTools_ListOfShape());
446 TopTools_ListOfShape aListOfShape5;
447 theMapGener.Bind(theEdge, aListOfShape5);
449 theMapGener(theEdge).Append (aV);
455 if (theListE.IsEmpty())
456 theListE.Append (theEdge);
460 //=======================================================================
461 //function : ClassifyEdgeFace
463 //=======================================================================
466 ClassifyEdgeFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace,
467 TopoDS_Edge& theEdgeOn,
468 const TopTools_DataMapOfShapeListOfShape& theMapSubst)
470 Standard_Real aParF, aParL, aTolEdge;
471 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aParF, aParL);
472 if (aCurve.IsNull()) return TopAbs_OUT;
473 aTolEdge = BRep_Tool::Tolerance(theEdge);
474 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
476 // define check points
477 Standard_Real aParams[4];
478 Standard_Real aDeltaRange = aParL - aParF;
480 aParams[1] = aParF + aDeltaRange * 0.382;
481 aParams[2] = aParF + aDeltaRange * 0.618;
486 // check distance to the surface
487 Standard_Real aTol = aTolEdge + BRep_Tool::Tolerance(theFace);
489 for (i=0; i < 4; i++) {
490 aPnts[i] = aCurve->Value(aParams[i]);
491 GeomAPI_ProjectPointOnSurf aProjector(aPnts[i], aSurf);
492 if (!aProjector.IsDone() || aProjector.LowerDistance() > aTol)
495 aProjector.LowerDistanceParameters(u,v);
496 aPnts2d[i].SetCoord(u,v);
499 // check distance to edges
500 TopExp_Explorer aExp (theFace, TopAbs_EDGE);
501 for (; aExp.More(); aExp.Next()) {
502 const TopoDS_Shape& aE = aExp.Current();
503 // if (aE.Orientation() == TopAbs_FORWARD || aE.Orientation() == TopAbs_REVERSED) {
504 if (aE.Orientation() != TopAbs_EXTERNAL) {
505 TopTools_ListOfShape aListSingle;
506 TopTools_ListIteratorOfListOfShape aIt;
507 if (theMapSubst.IsBound(aE)) {
508 aIt.Initialize (theMapSubst(aE));
511 aListSingle.Append (aE);
512 aIt.Initialize (aListSingle);
515 for (; aIt.More(); aIt.Next()) { // for each split
516 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt.Value());
517 Standard_Real aPF, aPL;
518 Handle(Geom_Curve) aCrv = BRep_Tool::Curve(aE1, aPF, aPL);
519 if (aCrv.IsNull()) continue;
520 Standard_Real aTol1 = aTolEdge + BRep_Tool::Tolerance(aE1);
522 for (i=0; i < 4; i++) {
523 GeomAPI_ProjectPointOnCurve aProjector(aPnts[i], aCrv, aPF, aPL);
524 if (aProjector.NbPoints() == 0 || aProjector.LowerDistance() > aTol1)
527 if (i == 4) { // all points are on an edge
535 // use 2d face classifier
536 // BRepClass_FaceClassifier aClf;
537 BRepTopAdaptor_FClass2d aClf(theFace, Precision::PConfusion());
538 for (i=0; i < 4; i++) {
539 if (aClf.Perform (aPnts2d[i]) == TopAbs_OUT)
546 //=======================================================================
547 //function : UpdateEdgeOnFace
549 //=======================================================================
551 static Standard_Boolean
552 UpdateEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace)
555 Standard_Real aPF, aPL, aTolEdge;
556 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aPF, aPL);
557 if (aCurve.IsNull()) return Standard_False;
558 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(theFace);
559 if (aSurf.IsNull()) return Standard_False;
560 aTolEdge = BRep_Tool::Tolerance(theEdge);
562 Standard_Real aTolApprox = Max (aTolEdge, BRep_Tool::Tolerance(theFace));
563 Handle(Geom2d_Curve) aCrv2d = GeomProjLib::Curve2d (aCurve, aPF, aPL, aSurf,
565 if (!aCrv2d.IsNull()) {
566 aTolEdge = Max (aTolEdge, aTolApprox);
567 aBld.UpdateEdge (theEdge, aCrv2d, theFace, aTolEdge);
568 return Standard_True;
570 return Standard_False;
573 //=======================================================================
574 //function : PerformShellWire
576 //=======================================================================
579 QANewModTopOpe_Glue::PerformShellWire()
581 TopoDS_Shape& myS1=myArguments.First();
582 TopoDS_Shape& myS2=myTools.First();
584 Standard_Boolean anOnlyOneFace = Standard_False;
586 if(myS1.ShapeType() == TopAbs_FACE) {
588 aBld.MakeShell(TopoDS::Shell(aShell));
589 aBld.Add(aShell, myS1);
591 anOnlyOneFace = Standard_True;
594 if(myS2.ShapeType() == TopAbs_EDGE) {
595 myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2));
598 TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD);
599 TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD);
600 BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F);
601 if (!aExtrema.IsDone())
604 TopTools_IndexedDataMapOfShapeListOfShape aMapAnc1;
605 TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc1);
606 TopExp::MapShapesAndAncestors (aS1F, TopAbs_VERTEX, TopAbs_FACE, aMapAnc1);
607 TopExp::MapShapesAndAncestors (aS1F, TopAbs_EDGE, TopAbs_FACE, aMapAnc1);
608 TopTools_IndexedDataMapOfShapeListOfShape aMapAnc2;
609 TopExp::MapShapesAndAncestors (aS2F, TopAbs_VERTEX, TopAbs_EDGE, aMapAnc2);
610 TopExp::MapShapesAndAncestors (aS2F, TopAbs_EDGE, TopAbs_WIRE, aMapAnc2);
611 TopTools_IndexedDataMapOfShapeListOfShape aMapFE;
613 // process extrema points
614 Standard_Boolean anIsCoincided = Standard_False;
615 Standard_Integer nbSol = aExtrema.NbSolution(), i;
616 Standard_Real aDist = aExtrema.Value();
617 for (i=1; i <= nbSol; i++) {
618 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
619 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
621 // check distance against tolerances
622 Standard_Real aTol1, aTol2;
623 if (aS1.ShapeType() == TopAbs_VERTEX)
624 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
625 else if (aS1.ShapeType() == TopAbs_EDGE)
626 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
628 aTol1 = BRep_Tool::Tolerance (TopoDS::Face(aS1));
629 if (aS2.ShapeType() == TopAbs_VERTEX)
630 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
632 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
633 if (aDist > aTol1 + aTol2) continue;
635 anIsCoincided = Standard_True;
637 // determine contacted faces from Shell and edges from Wire
638 // and remember them in the map
639 TopTools_ListOfShape aListF, aListE;
640 if (aS1.ShapeType() == TopAbs_FACE) {
644 TopTools_ListIteratorOfListOfShape aIt (aMapAnc1.FindFromKey(aS1));
645 for (; aIt.More(); aIt.Next())
646 if (aIt.Value().ShapeType() == TopAbs_FACE)
647 aListF.Append (aIt.Value());
649 if (aS2.ShapeType() == TopAbs_EDGE) {
653 TopTools_ListIteratorOfListOfShape aIt (aMapAnc2.FindFromKey(aS2));
654 for (; aIt.More(); aIt.Next())
655 aListE.Append (aIt.Value());
657 TopTools_ListIteratorOfListOfShape aItF (aListF);
658 for (; aItF.More(); aItF.Next()) {
659 if (!aMapFE.Contains (aItF.Value())) {
660 // for Mandrake-10 - mkv,02.06.06 - aMapFE.Add (aItF.Value(), TopTools_ListOfShape());
661 TopTools_ListOfShape aListOfShape1;
662 aMapFE.Add (aItF.Value(), aListOfShape1);
664 TopTools_ListOfShape& aLE = aMapFE.ChangeFromKey(aItF.Value());
665 TopTools_MapOfShape aMapE;
666 TopTools_ListIteratorOfListOfShape aItE (aLE);
667 for (; aItE.More(); aItE.Next())
668 aMapE.Add (aItE.Value());
669 for (aItE.Initialize (aListE); aItE.More(); aItE.Next())
670 if (!aMapE.Contains (aItE.Value()))
671 aLE.Append(aItE.Value());
676 if(!anIsCoincided) return;
678 // for each touched face make wire and add it in face as internal
680 TopTools_MapOfShape aMapUsedEdges;
681 TColgp_SequenceOfPnt aPoints1;
682 TColgp_SequenceOfPnt aPoints2;
683 TColStd_SequenceOfInteger aEdgeOnSurface;
684 TopTools_DataMapOfShapeListOfShape aMapSubst;
685 for (i=1; i <= aMapFE.Extent(); i++) {
686 const TopoDS_Face& aFace = TopoDS::Face (aMapFE.FindKey(i));
687 TopoDS_Shape aNewFace;
689 // form the new wire:
690 // get all edges contacting the face, split them by the face boundary,
691 // get those splits which are inside the face.
692 Standard_Boolean isWireMade = Standard_False;
694 aBld.MakeWire (TopoDS::Wire (aWire));
695 TopTools_ListIteratorOfListOfShape aIt (aMapFE(i));
696 for (; aIt.More(); aIt.Next()) { // for each edge contacting the face
697 const TopoDS_Shape& aEdge = aIt.Value();
698 if (aMapUsedEdges.Contains(aEdge)) continue;
700 TopTools_ListOfShape aListSingle;
701 aListSingle.Append (aEdge);
702 TopTools_ListOfShape& aListRef = (aMapSubst.IsBound(aEdge)
705 TopTools_ListIteratorOfListOfShape aIt1 (aListRef);
706 while (aIt1.More()) { // for each old split
707 const TopoDS_Edge& aE1 = TopoDS::Edge (aIt1.Value());
708 if (!aMapUsedEdges.Contains(aE1)) {
709 TopTools_ListOfShape aListE;
710 ProcessEdgeFaceInterference (aE1, aFace, aNewFace, aListE, aPoints1, aPoints2,
711 aEdgeOnSurface, aMapSubst, myMapGener);
712 TopTools_ListIteratorOfListOfShape aIt2 (aListE);
713 for (aIt2.Initialize(aListE); aIt2.More(); aIt2.Next()) {
714 const TopoDS_Edge& aE2 = TopoDS::Edge (aIt2.Value());
716 TopAbs_State aState = ClassifyEdgeFace (aE2, aFace, aEon, aMapSubst);
717 if (aState == TopAbs_IN ) {
718 if (UpdateEdgeOnFace (aE2, aFace)) {
719 isWireMade = Standard_True;
720 aBld.Add (aWire, aE2);
721 aMapUsedEdges.Add (aE2);
722 if (!myMapGener.IsBound(aFace)) {
723 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aFace, TopTools_ListOfShape());
724 TopTools_ListOfShape aListOfShape2;
725 myMapGener.Bind(aFace, aListOfShape2);
727 myMapGener(aFace).Append (aE2);
730 else if(aState == TopAbs_ON) {
731 aMapUsedEdges.Add (aE2);
734 Standard_Boolean IsTheSame = Standard_False;
735 if(aListE.Extent() == 1) {
736 IsTheSame = aE1.IsSame(aListE.First());
738 if (aListE.Extent() > 1 || !IsTheSame) {
739 // replace old split with new splits
740 if (aMapSubst.IsBound(aEdge)) {
741 aListRef.InsertBefore (aListE, aIt1);
742 aListRef.Remove (aIt1);
745 else aMapSubst.Bind (aEdge, aListE);
752 if(!aNewFace.IsSame(aFace) && !aNewFace.IsNull()) {
753 if(!aMapSubst.IsBound(aFace)) {
754 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aFace, TopTools_ListOfShape());
755 TopTools_ListOfShape aListOfShape3;
756 aMapSubst.Bind (aFace, aListOfShape3);
758 aMapSubst(aFace).Append(aNewFace);
762 // add new wire to face
763 TopoDS_Shape aDummy = aNewFace.EmptyCopied().Oriented(TopAbs_FORWARD);
764 TopoDS_Face aNewFace1 = TopoDS::Face (aDummy);
765 aBld.NaturalRestriction (aNewFace1, BRep_Tool::NaturalRestriction(aFace));
766 TopoDS_Iterator aIterF (aNewFace, Standard_False);
767 for (; aIterF.More(); aIterF.Next()) {
768 aBld.Add (aNewFace1, aIterF.Value());
770 aWire = FindWireOrUpdateMap (aWire, aMapAnc2);
771 aBld.Add (aNewFace1, aWire.Oriented(TopAbs_INTERNAL));
773 TopTools_ListOfShape aList;
774 aList.Append (aNewFace1.Oriented(aFace.Orientation()));
775 if(aMapSubst.IsBound(aFace)) aMapSubst.UnBind(aFace);
776 aMapSubst.Bind (aFace, aList);
780 // make wires from the left edges
782 // if (!aMapUsedEdges.IsEmpty()) {
783 Handle(BRepAlgo_EdgeConnector) aConnector = new BRepAlgo_EdgeConnector;
784 // TopoDS_Iterator aIterW (myS2, Standard_False);
785 TopExp_Explorer anExpW (myS2, TopAbs_EDGE);
786 for (; anExpW.More(); anExpW.Next()) {
787 const TopoDS_Edge& aEdge = TopoDS::Edge (anExpW.Current());
788 if (aMapUsedEdges.Contains(aEdge)) continue;
790 if (aMapSubst.IsBound(aEdge)) {
791 TopTools_ListIteratorOfListOfShape aIt (aMapSubst(aEdge));
792 for (; aIt.More(); aIt.Next()) { // for each old split
793 if (aMapUsedEdges.Contains(aIt.Value())) continue;
794 aConnector->Add (TopoDS::Edge(aIt.Value()));
795 aConnector->AddStart (TopoDS::Edge(aIt.Value()));
799 aConnector->Add (aEdge);
800 aConnector->AddStart (aEdge);
804 // for Mandrake-10 - mkv,02.06.06 - myMapModif.Bind (myS2, TopTools_ListOfShape());
805 TopTools_ListOfShape aListOfShape4;
806 myMapModif.Bind (myS2, aListOfShape4);
807 TopTools_ListOfShape& aListW = aConnector->MakeBlock();
808 if (aConnector->IsDone()) {
809 // TopAbs_Orientation aOri = myS2.Orientation();
810 TopTools_ListIteratorOfListOfShape aIt (aListW);
811 // for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
812 myMapModif(myS2).Append (aListW);
816 // construct the result
818 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst);
820 for (; aIterM.More(); aIterM.Next()) {
821 TopAbs_Orientation aOri = TopAbs_FORWARD;
822 TopTools_ListIteratorOfListOfShape aIt (aIterM.Value());
823 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
824 if(!aIterM.Value().IsEmpty()) mySubst.Substitute (aIterM.Key(), aIterM.Value());
825 aOri = aIterM.Key().Orientation();
826 aIt.Initialize (aIterM.Value());
827 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
828 if(!aIterM.Value().IsEmpty()) myMapModif.Bind (aIterM.Key(), aIterM.Value());
832 TopoDS_Shape aNewS1 = myS1;
834 if (mySubst.IsCopied(myS1)) {
835 aNewS1 = mySubst.Copy(myS1).First();
836 if(aNewS1.ShapeType() == TopAbs_SHELL && anOnlyOneFace) {
837 TopoDS_Iterator anIter(aNewS1);
838 aNewS1 = anIter.Value();
840 aNewS1.Orientation(myS1.Orientation());
843 if (myMapModif.IsBound (myS2) && myMapModif(myS2).IsEmpty()) {
844 // all wire is on shell
846 myMapModif.UnBind (myS2);
849 // all wire or part of wire is out of shell
850 aBld.MakeCompound (TopoDS::Compound(myShape));
851 aBld.Add(myShape, aNewS1);
852 if (myMapModif.IsBound (myS2)) {
853 TopTools_ListIteratorOfListOfShape aIt (myMapModif(myS2));
854 for (; aIt.More(); aIt.Next()) {
855 // check if wire contains only one edge
856 TopoDS_Iterator aTDIt(aIt.Value());
857 TopoDS_Shape anE = aTDIt.Value();
859 if(aTDIt.More()) aBld.Add (myShape, aIt.Value());
860 else aBld.Add (myShape, anE);
863 else aBld.Add (myShape, myS2);
870 //=======================================================================
871 //function : IsOverlapped
872 //purpose : Checks if theEdge2 lies on theEdge1. It is known that the
873 // boundary vertices of theEdge2 lie on theEdge1.
874 //=======================================================================
876 static Standard_Boolean IsOverlapped(const TopoDS_Edge &theEdge1,
877 const TopoDS_Edge &theEdge2)
879 Standard_Real aParF1, aParL1;
880 Standard_Real aParF2, aParL2;
881 Handle(Geom_Curve) aC1 = BRep_Tool::Curve(theEdge1, aParF1, aParL1);
882 Handle(Geom_Curve) aC2 = BRep_Tool::Curve(theEdge2, aParF2, aParL2);
884 if (aC1.IsNull() || aC2.IsNull())
885 return Standard_False;
887 GeomAdaptor_Curve aGAC1(aC1, aParF1, aParL1);
888 GeomAdaptor_Curve aGAC2(aC2, aParF2, aParL2);
889 Extrema_ExtPC anExtPC;
890 Standard_Integer aNbPoints = 5;
891 Standard_Real aDelta = (aParL2 - aParF2)/(aNbPoints + 1.);
892 Standard_Real aCurPar = aParF2 + aDelta;
894 Standard_Real aMaxDist = Max(BRep_Tool::Tolerance(theEdge1),
895 BRep_Tool::Tolerance(theEdge2));
897 anExtPC.Initialize(aGAC1, aParF1, aParL1);
899 for (i = 1; i <= aNbPoints; i++) {
900 gp_Pnt aPnt = aGAC2.Value(aCurPar);
902 anExtPC.Perform(aPnt);
904 if (!anExtPC.IsDone())
905 return Standard_False;
908 Standard_Integer aNbExt = anExtPC.NbExt();
909 Standard_Boolean isPOnC1 = Standard_False;
911 for (j = 1; j <= aNbExt && !isPOnC1; j++) {
912 if (anExtPC.IsMin(j)) {
913 gp_Pnt anExtP = anExtPC.Point(j).Value();
915 isPOnC1 = (aPnt.Distance(anExtP) <= aMaxDist);
919 return Standard_False;
924 return Standard_True;
927 //=======================================================================
928 //function : SplitEdge
929 //purpose : This function splits the edge into subedges by two given vertices.
930 //=======================================================================
932 static void SplitEdge(const TopoDS_Edge &theEdge,
933 const TopTools_IndexedMapOfShape &theVertices,
934 TopTools_ListOfShape &theSplits)
936 //const TopoDS_Edge aNewEdge;
939 BRep_Builder aBuilder;
941 TopoDS_Edge aNewEdge = TopoDS::Edge(theEdge.Oriented(TopAbs_FORWARD).EmptyCopied());
942 TopExp::Vertices(theEdge, aV1, aV2);
943 aBuilder.Add(aNewEdge, aV1);
945 // Construction of the copied edge with
946 // the internal vertices of the map theVertices.
950 for (i = 1; i <= theVertices.Extent(); i++)
952 const TopoDS_Shape &theVtx = theVertices.FindKey(i);
954 if (!aV1.IsSame(theVtx) && !aV2.IsSame(theVtx))
955 aBuilder.Add(aNewEdge, theVtx.Oriented(TopAbs_INTERNAL));
958 aBuilder.Add(aNewEdge, aV2);
962 // Splitting of the new edge.
963 if (!TopOpeBRepTool_TOOL::SplitE(aNewEdge, theSplits)) {
965 theSplits.Append(theEdge);
970 // Addition of the other internal vertices into the corresponding splits.
971 TopoDS_Iterator anIter(theEdge, Standard_False);
973 for (; anIter.More(); anIter.Next())
975 TopoDS_Vertex aCurVtx = TopoDS::Vertex(anIter.Value());
977 // for each vertex which is not the same as aV1, aV2, theIntV1 or theIntV2.
978 if (!aCurVtx.IsSame(aV1) && !aCurVtx.IsSame(aV2) && !theVertices.Contains(aCurVtx))
980 TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits);
981 Standard_Real aCurPar = BRep_Tool::Parameter(aCurVtx, theEdge);
983 // Search for the split the current vertex belongs to.
984 for (; anEdgeIter.More(); anEdgeIter.Next())
986 TopoDS_Edge anEdge = TopoDS::Edge(anEdgeIter.Value());
990 BRep_Tool::Range(anEdge, aFPar, aLPar);
992 if (aCurPar > aFPar && aCurPar < aLPar)
994 aBuilder.Add(anEdge, aCurVtx);
1001 // Setting the orientation of each split equal to the orientation of theEdge.
1002 TopTools_ListIteratorOfListOfShape anEdgeIter(theSplits);
1003 TopAbs_Orientation anOri = theEdge.Orientation();
1005 for (; anEdgeIter.More(); anEdgeIter.Next())
1007 TopoDS_Shape &anEdge = anEdgeIter.Value();
1008 anEdge.Orientation(anOri);
1012 //=======================================================================
1013 //function : RemoveCommonPart
1015 //=======================================================================
1017 static void RemoveCommonPart
1018 (const TopoDS_Edge &theE1,
1019 const TopoDS_Edge &theE2,
1020 TopTools_DataMapOfShapeListOfShape &theMapSubst)
1022 if (theMapSubst.IsBound(theE1)) {
1023 const TopTools_ListOfShape &aLOfE1 = theMapSubst.Find(theE1);
1024 TopTools_ListIteratorOfListOfShape anIter(aLOfE1);
1026 // For each split in the list aLOfE1 recursively call this function.
1027 for (; anIter.More(); anIter.Next()) {
1028 TopoDS_Edge anEdge1 = TopoDS::Edge(anIter.Value());
1030 RemoveCommonPart(anEdge1, theE2, theMapSubst);
1036 if (theMapSubst.IsBound(theE2)) {
1037 const TopTools_ListOfShape &aLOfE2 = theMapSubst.Find(theE2);
1038 TopTools_ListIteratorOfListOfShape anIter(aLOfE2);
1040 // For each split in the list aLOfE2 recursively call this function.
1041 for (; anIter.More(); anIter.Next()) {
1042 TopoDS_Edge anEdge2 = TopoDS::Edge(anIter.Value());
1044 RemoveCommonPart(theE1, anEdge2, theMapSubst);
1050 TopTools_IndexedMapOfShape aMapVtx;
1051 TopTools_IndexedMapOfShape aMapCommonVtx;
1053 // Searching for common vertices:
1054 TopExp::MapShapes(theE1, aMapVtx);
1055 TopoDS_Iterator anIter(theE2, Standard_False);
1057 for (; anIter.More(); anIter.Next()) {
1058 TopoDS_Shape aVtx = anIter.Value();
1060 if (aMapVtx.Contains(aVtx)) {
1061 aMapCommonVtx.Add(aVtx);
1065 // If there are at least two common vertices we can check overlapping:
1066 if (aMapCommonVtx.Extent() <= 1)
1069 TopTools_ListOfShape aSplits;
1071 SplitEdge(theE2, aMapCommonVtx, aSplits);
1073 TopTools_ListIteratorOfListOfShape aSplitIter(aSplits);
1074 Standard_Boolean isModified = Standard_False;
1076 for (; aSplitIter.More();) {
1077 TopoDS_Edge aSplit = TopoDS::Edge(aSplitIter.Value());
1079 if (IsOverlapped(theE1, aSplit)) {
1080 // Removal of overlapping split from the list of splits
1081 aSplits.Remove(aSplitIter);
1082 isModified = Standard_True;
1088 // If we deleted some splits, we should save the splits
1089 // of theE2 in order to use them in further overlapping checks.
1091 theMapSubst.Bind(theE2, aSplits);
1094 //=======================================================================
1095 //function : GetSplits
1096 //purpose : This function removes returns the splits build from theEdge.
1097 // If there are no ones the edge itself will be added to theSplits.
1098 //=======================================================================
1100 static void GetSplits(const TopoDS_Shape &theEdge,
1101 const TopTools_DataMapOfShapeListOfShape &theMapSubst,
1102 TopTools_ListOfShape &theSplits)
1104 if (theMapSubst.IsBound(theEdge)) {
1105 const TopTools_ListOfShape &theList =
1106 theMapSubst.Find(theEdge);
1107 TopTools_ListIteratorOfListOfShape anEdgeIter(theList);
1109 for (; anEdgeIter.More(); anEdgeIter.Next()) {
1110 const TopoDS_Shape &anEdge = anEdgeIter.Value();
1112 GetSplits(anEdge, theMapSubst, theSplits);
1115 theSplits.Append(theEdge);
1119 //=======================================================================
1120 //function : isWireModified
1121 //purpose : Checks if the given wire was modified.
1122 //=======================================================================
1124 static Standard_Boolean isWireModified
1125 (const TopoDS_Shape &theWire,
1126 const TopTools_DataMapOfShapeListOfShape &theMapSubst)
1128 TopExp_Explorer anExp(theWire, TopAbs_EDGE);
1130 for(; anExp.More(); anExp.Next()) {
1131 const TopoDS_Shape &anEdge = anExp.Current();
1133 if (theMapSubst.IsBound(anEdge))
1134 return Standard_True;
1137 return Standard_False;
1140 //=======================================================================
1141 //function : RemoveOverlappedEdges
1142 //purpose : This function removes doubled common parts of edges from theS2.
1143 //=======================================================================
1145 static TopoDS_Shape RemoveOverlappedEdges
1146 (const TopoDS_Shape &theS1,
1147 const TopoDS_Shape &theS2,
1148 TopTools_DataMapOfShapeListOfShape &theMapModif)
1150 TopExp_Explorer anExp1(theS1, TopAbs_EDGE);
1151 TopTools_DataMapOfShapeListOfShape aMapModif;
1153 // For each couple of edges we remove a common part if any.
1154 for(; anExp1.More(); anExp1.Next()) {
1155 TopoDS_Edge anEdge1 = TopoDS::Edge(anExp1.Current());
1156 TopExp_Explorer anExp2(theS2, TopAbs_EDGE);
1158 for(; anExp2.More(); anExp2.Next()) {
1159 TopoDS_Edge anEdge2 = TopoDS::Edge(anExp2.Current());
1161 RemoveCommonPart(anEdge1, anEdge2, aMapModif);
1165 // Searching for built splits for every edge.
1167 TopoDS_Shape aNewS2;
1168 BRep_Builder aBuilder;
1170 aBuilder.MakeCompound(TopoDS::Compound(aNewS));
1171 aBuilder.MakeCompound(TopoDS::Compound(aNewS2));
1172 aBuilder.Add(aNewS, theS1);
1174 TopExp_Explorer anExpWire(theS2, TopAbs_WIRE);
1176 for(; anExpWire.More(); anExpWire.Next()) {
1177 const TopoDS_Shape &aWire = anExpWire.Current();
1179 if (isWireModified(aWire, aMapModif)) {
1180 TopExp_Explorer anExpEdge(aWire, TopAbs_EDGE);
1181 TopoDS_Shape aNewComp;
1183 aBuilder.MakeCompound(TopoDS::Compound(aNewComp));
1185 for(; anExpEdge.More(); anExpEdge.Next()) {
1186 const TopoDS_Shape &anEdge = anExpEdge.Current();
1187 TopTools_ListOfShape aSplits;
1189 GetSplits(anEdge, aMapModif, aSplits);
1191 if (!aSplits.IsEmpty() && !anEdge.IsSame(aSplits.First())) {
1192 if (!theMapModif.IsBound(anEdge))
1193 theMapModif.Bind(anEdge, aSplits);
1194 } else if (aSplits.IsEmpty()) {
1195 theMapModif.Bind(anEdge, aSplits);
1198 TopTools_ListIteratorOfListOfShape aSplitIter(aSplits);
1200 for (; aSplitIter.More(); aSplitIter.Next()) {
1201 const TopoDS_Shape &aSplit = aSplitIter.Value();
1203 aBuilder.Add(aNewComp, aSplit);
1207 // Addition of new compound if it is not empty
1208 TopoDS_Iterator aSubShIter(aNewComp);
1210 if (aSubShIter.More())
1211 aBuilder.Add(aNewS2, aNewComp);
1213 aBuilder.Add(aNewS2, aWire);
1217 // Addition of new shape if it is not empty
1218 TopoDS_Iterator aSubShIter(aNewS2);
1220 if (aSubShIter.More())
1221 aBuilder.Add(aNewS, aNewS2);
1226 //=======================================================================
1227 //function : FillMapModif
1228 //purpose : This function fills the map of modified sub-shapes of theShape
1229 //=======================================================================
1231 static void FillMapModif(const BRepTools_Substitution &theSubst,
1232 const TopoDS_Shape &theShape,
1233 TopTools_DataMapOfShapeListOfShape &theMapModif)
1235 TopAbs_ShapeEnum aType = theShape.ShapeType();
1237 if (aType == TopAbs_EDGE || aType == TopAbs_VERTEX) {
1238 if (theSubst.IsCopied(theShape)) {
1239 const TopTools_ListOfShape &aModifShapes = theSubst.Copy(theShape);
1241 if (!theMapModif.IsBound(theShape))
1242 theMapModif.Bind(theShape, aModifShapes);
1246 TopoDS_Iterator anIter(theShape, Standard_False);
1247 TopTools_MapOfShape aUsedShapes;
1249 for (; anIter.More(); anIter.Next()) {
1250 const TopoDS_Shape &aSubShape = anIter.Value();
1252 if (!aUsedShapes.Add(aSubShape))
1255 FillMapModif(theSubst, aSubShape, theMapModif);
1259 //=======================================================================
1260 //function : PerformWires
1261 //purpose : gluing two wires
1262 //=======================================================================
1265 QANewModTopOpe_Glue::PerformWires()
1267 TopoDS_Shape& myS1=myArguments.First();
1268 TopoDS_Shape& myS2=myTools.First();
1270 Standard_Boolean S1IsEdge = Standard_False, S2IsEdge = Standard_False;
1271 if(myS1.ShapeType() == TopAbs_EDGE) {
1272 myS1 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS1));
1273 S1IsEdge = Standard_True;
1275 if(myS2.ShapeType() == TopAbs_EDGE) {
1276 myS2 = BRepBuilderAPI_MakeWire(TopoDS::Edge(myS2));
1277 S2IsEdge = Standard_True;
1280 TopoDS_Shape aS1F = myS1.Oriented(TopAbs_FORWARD);
1281 TopoDS_Shape aS2F = myS2.Oriented(TopAbs_FORWARD);
1282 BRepExtrema_DistShapeShape aExtrema (aS1F, aS2F);
1283 if (!aExtrema.IsDone())
1286 // process extrema points
1288 TColStd_SequenceOfInteger VVInt;
1289 TColStd_SequenceOfInteger VEInt;
1290 TColStd_SequenceOfInteger EEInt;
1293 Standard_Boolean anIsCoincided = Standard_False;
1294 Standard_Boolean S1IsVert = Standard_True;
1295 Standard_Boolean S2IsVert = Standard_True;
1296 Standard_Real aTol1, aTol2;
1297 Standard_Integer nbSol = aExtrema.NbSolution(), i, j, k;
1298 Standard_Real aDist = aExtrema.Value();
1299 for (i=1; i <= nbSol; i++) {
1300 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
1301 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
1302 S1IsVert = Standard_True;
1303 S2IsVert = Standard_True;
1304 // check distance against tolerances
1305 if (aS1.ShapeType() == TopAbs_VERTEX)
1306 aTol1 = BRep_Tool::Tolerance (TopoDS::Vertex(aS1));
1308 aTol1 = BRep_Tool::Tolerance (TopoDS::Edge(aS1));
1309 S1IsVert = Standard_False;
1312 if (aS2.ShapeType() == TopAbs_VERTEX)
1313 aTol2 = BRep_Tool::Tolerance (TopoDS::Vertex(aS2));
1315 aTol2 = BRep_Tool::Tolerance (TopoDS::Edge(aS2));
1316 S2IsVert = Standard_False;
1319 if (aDist > aTol1 + aTol2) continue;
1321 anIsCoincided = Standard_True;
1323 if(S1IsVert && S2IsVert) {
1324 if(!aS1.IsSame(aS2)) VVInt.Append(i);
1326 else if(S1IsVert || S2IsVert)
1332 if(!anIsCoincided) return;
1335 TColgp_SequenceOfPnt aPoints1;
1336 TColgp_SequenceOfPnt aPoints2;
1337 TopTools_DataMapOfShapeListOfShape aMapSubst;
1339 for(k = 1; k <= VVInt.Length(); k++) {
1340 // avoid to process the same points twice
1342 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1343 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1344 for (j=1; j<=aPoints1.Length(); j++) {
1345 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1346 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1350 if (j <= aPoints1.Length()) continue;
1351 aPoints1.Append (aPnt1);
1352 aPoints2.Append (aPnt2);
1354 const TopoDS_Vertex& aVer1 = TopoDS::Vertex(aExtrema.SupportOnShape1(i));
1355 const TopoDS_Vertex& aVer2 = TopoDS::Vertex(aExtrema.SupportOnShape2(i));
1356 aTol1 = BRep_Tool::Tolerance(aVer1);
1357 aTol2 = BRep_Tool::Tolerance(aVer2);
1358 aTol1 = Max(aTol1, aTol2 + aDist);
1359 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1360 aBld.UpdateVertex (aVer1, aP, aTol1);
1361 TopTools_ListOfShape aList;
1362 aList.Append (aVer1);
1363 aMapSubst.Bind (aVer2, aList);
1367 for(k = 1; k <= VEInt.Length(); k++) {
1368 // avoid to process the same points twice
1370 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1371 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1372 for (j=1; j<=aPoints1.Length(); j++) {
1373 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1374 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1378 if (j <= aPoints1.Length()) continue;
1379 aPoints1.Append (aPnt1);
1380 aPoints2.Append (aPnt2);
1382 TopoDS_Shape aS1 = aExtrema.SupportOnShape1(i);
1383 TopoDS_Shape aS2 = aExtrema.SupportOnShape2(i);
1385 if(aS1.ShapeType() == TopAbs_VERTEX) {
1386 TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS1);
1387 const TopoDS_Edge& aE2 = TopoDS::Edge(aS2);
1388 aTol1 = BRep_Tool::Tolerance(aVer1);
1389 aTol2 = BRep_Tool::Tolerance(aE2);
1390 aTol1 = Max(aTol1, aTol2 + aDist);
1391 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1392 aBld.UpdateVertex (aVer1, aP, aTol1);
1394 aExtrema.ParOnEdgeS2(i, aPar);
1395 if (!aMapSubst.IsBound(aE2)) {
1396 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1397 TopTools_ListOfShape aListOfShape1;
1398 aMapSubst.Bind (aE2, aListOfShape1);
1400 TopTools_ListOfShape& aListSubst = aMapSubst(aE2);
1402 if (aListSubst.IsEmpty()) {
1406 aEdge = TopoDS::Edge(aListSubst.First());
1410 TopoDS_Edge aNewEdge;
1411 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge);
1412 aListSubst.Append (aNewEdge);
1415 TopoDS_Vertex& aVer1 = TopoDS::Vertex(aS2);
1416 const TopoDS_Edge& aE2 = TopoDS::Edge(aS1);
1417 aTol1 = BRep_Tool::Tolerance(aVer1);
1418 aTol2 = BRep_Tool::Tolerance(aE2);
1419 aTol1 = Max(aTol1, aTol2 + aDist);
1420 gp_Pnt aP = BRep_Tool::Pnt(aVer1);
1421 aBld.UpdateVertex (aVer1, aP, aTol1);
1423 aExtrema.ParOnEdgeS1(i, aPar);
1424 if (!aMapSubst.IsBound(aE2)) {
1425 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1426 TopTools_ListOfShape aListOfShape2;
1427 aMapSubst.Bind (aE2, aListOfShape2);
1429 TopTools_ListOfShape& aListSubst = aMapSubst(aE2);
1431 if (aListSubst.IsEmpty()) {
1435 aEdge = TopoDS::Edge(aListSubst.First());
1439 TopoDS_Edge aNewEdge;
1440 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer1, aPar, aNewEdge);
1441 aListSubst.Append (aNewEdge);
1445 for(k = 1; k <= EEInt.Length(); k++) {
1446 // avoid to process the same points twice
1448 gp_Pnt aPnt1 = aExtrema.PointOnShape1(i);
1449 gp_Pnt aPnt2 = aExtrema.PointOnShape2(i);
1450 for (j=1; j<=aPoints1.Length(); j++) {
1451 if (aPnt1.IsEqual(aPoints1(j),Precision::Confusion()) &&
1452 aPnt2.IsEqual(aPoints2(j),Precision::Confusion())) {
1456 if (j <= aPoints1.Length()) continue;
1457 aPoints1.Append (aPnt1);
1458 aPoints2.Append (aPnt2);
1460 const TopoDS_Edge& aE1 = TopoDS::Edge(aExtrema.SupportOnShape1(i));
1461 const TopoDS_Edge& aE2 = TopoDS::Edge(aExtrema.SupportOnShape2(i));
1463 aTol1 = BRep_Tool::Tolerance(aE1);
1464 aTol2 = BRep_Tool::Tolerance(aE2);
1465 gp_Pnt aP((aPnt1.X() + aPnt2.X())*.5, (aPnt1.Y() + aPnt2.Y())*.5, (aPnt1.Z() + aPnt2.Z())*.5);
1466 aTol1 = Max(aTol1+.5*aDist, aTol2+.5*aDist);
1467 aTol1 = Max(aTol1, Precision::Confusion());
1470 aBld.MakeVertex(aVer, aP, aTol1);
1473 aExtrema.ParOnEdgeS1(i, aPar);
1474 if (!aMapSubst.IsBound(aE1)) {
1475 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE1, TopTools_ListOfShape());
1476 TopTools_ListOfShape aListOfShape3;
1477 aMapSubst.Bind (aE1, aListOfShape3);
1479 TopTools_ListOfShape& aListSubst1 = aMapSubst(aE1);
1481 if (aListSubst1.IsEmpty()) {
1485 aEdge = TopoDS::Edge(aListSubst1.First());
1486 aListSubst1.Clear();
1489 TopoDS_Edge aNewEdge;
1490 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge);
1491 aListSubst1.Append (aNewEdge);
1493 if(!myMapGener.IsBound(aE1)) {
1494 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE1, TopTools_ListOfShape());
1495 TopTools_ListOfShape aListOfShape4;
1496 myMapGener.Bind(aE1, aListOfShape4);
1498 myMapGener(aE1).Append(aVer);
1500 aExtrema.ParOnEdgeS2(i, aPar);
1501 if (!aMapSubst.IsBound(aE2)) {
1502 // for Mandrake-10 - mkv,02.06.06 - aMapSubst.Bind (aE2, TopTools_ListOfShape());
1503 TopTools_ListOfShape aListOfShape5;
1504 aMapSubst.Bind (aE2, aListOfShape5);
1506 TopTools_ListOfShape& aListSubst2 = aMapSubst(aE2);
1507 if (aListSubst2.IsEmpty()) {
1511 aEdge = TopoDS::Edge(aListSubst2.First());
1512 aListSubst2.Clear();
1515 QANewModTopOpe_Glue::InsertVertexInEdge (aEdge, aVer, aPar, aNewEdge);
1516 aListSubst2.Append (aNewEdge);
1518 if(!myMapGener.IsBound(aE2)) {
1519 // for Mandrake-10 - mkv,02.06.06 - myMapGener.Bind(aE2, TopTools_ListOfShape());
1520 TopTools_ListOfShape aListOfShape6;
1521 myMapGener.Bind(aE2, aListOfShape6);
1523 myMapGener(aE2).Append(aVer);
1527 aBld.MakeCompound (TopoDS::Compound(myShape));
1528 aBld.Add(myShape, myS1);
1529 aBld.Add(myShape, myS2);
1531 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aIterM(aMapSubst);
1532 for (; aIterM.More(); aIterM.Next()) {
1533 TopAbs_Orientation aOri = TopAbs_FORWARD;
1534 TopTools_ListIteratorOfListOfShape aIt (aIterM.Value());
1535 for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
1536 if(aIterM.Key().ShapeType() == TopAbs_EDGE) {
1537 TopoDS_Edge aEdge = TopoDS::Edge(aIterM.Value().First());
1538 TopTools_ListOfShape& aListSubst = aMapSubst(aIterM.Key());
1540 if(!TopOpeBRepTool_TOOL::SplitE(aEdge, aListSubst)) {
1541 aListSubst.Append(aEdge);
1544 mySubst.Substitute (aIterM.Key(), aIterM.Value());
1545 // aOri = aIterM.Key().Orientation();
1546 // aIt.Initialize (aIterM.Value());
1547 // for (; aIt.More(); aIt.Next()) aIt.Value().Orientation(aOri);
1548 // myMapModif.Bind (aIterM.Key(), aIterM.Value());
1551 mySubst.Build(myShape);
1553 FillMapModif(mySubst, myS1, myMapModif);
1554 FillMapModif(mySubst, myS2, myMapModif);
1556 if (mySubst.IsCopied(myS1) || mySubst.IsCopied(myS2)) {
1557 TopoDS_Shape aNewS1;
1558 TopoDS_Shape aNewS2;
1560 if (mySubst.IsCopied(myS1))
1561 aNewS1 = mySubst.Copy(myS1).First();
1566 TopoDS_Iterator aTDIt(aNewS1);
1567 TopoDS_Shape aE = aTDIt.Value();
1569 if(!aTDIt.More()) aNewS1 = aE;
1572 if (mySubst.IsCopied(myS2))
1573 aNewS2 = mySubst.Copy(myS2).First();
1578 TopoDS_Iterator aTDIt(aNewS2);
1579 TopoDS_Shape aE = aTDIt.Value();
1581 if(!aTDIt.More()) aNewS2 = aE;
1584 myShape = RemoveOverlappedEdges(aNewS1, aNewS2, myMapModif);