1 // Created on: 2003-10-21
2 // Created by: Mikhail KLOKOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15 
16 
17 #include <BOPAlgo_BOP.hxx>
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <BOPDS_DS.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAlgoAPI_Section.hxx>
23 #include <BRepFill_TrimShellCorner.hxx>
24 #include <BRepLib_MakeEdge.hxx>
25 #include <BRepLib_MakeWire.hxx>
26 #include <BRepLib_MakeVertex.hxx>
27 #include <BRepTools_ReShape.hxx>
28 #include <gce_MakeLin.hxx>
29 #include <GCPnts_UniformAbscissa.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom_Curve.hxx>
32 #include <GeomLib.hxx>
33 #include <gp_Ax2.hxx>
34 #include <gp_Pln.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <IntTools_BeanFaceIntersector.hxx>
37 #include <IntTools_Context.hxx>
38 #include <IntTools_Range.hxx>
39 #include <IntTools_Tools.hxx>
40 #include <TColgp_Array1OfDir.hxx>
41 #include <TColgp_Array1OfPnt.hxx>
42 #include <TColgp_Array2OfPnt.hxx>
43 #include <TColgp_SequenceOfPnt.hxx>
44 #include <TColStd_Array1OfBoolean.hxx>
45 #include <TColStd_ListIteratorOfListOfInteger.hxx>
46 #include <TColStd_ListOfInteger.hxx>
47 #include <TopExp.hxx>
48 #include <TopExp_Explorer.hxx>
49 #include <TopLoc_Location.hxx>
50 #include <TopoDS.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Iterator.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Shell.hxx>
56 #include <TopoDS_Wire.hxx>
57 #include <TopTools_Array1OfListOfShape.hxx>
58 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
59 #include <TopTools_DataMapOfShapeListOfShape.hxx>
60 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
61 #include <TopTools_ListIteratorOfListOfShape.hxx>
62 #include <TopTools_ListOfShape.hxx>
63 #include <TopTools_MapOfShape.hxx>
64 #include <TopTools_SequenceOfShape.hxx>
65 #include <BRepExtrema_ExtCC.hxx>
66 
67 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
68                                                 TopoDS_Compound&     theComp,
69                                                 const gp_Ax1&        theAxis);
70 
71 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
72                                         const TopoDS_Vertex&  theVertex2,
73                                         const gp_Ax1&         theAxis,
74                                         TopoDS_Compound&      theComp,
75                                         TopTools_ListOfShape& theElist);
76 
77 static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
78                                          const TopoDS_Edge&   theLastEdge,
79                                          const TopoDS_Vertex& theFirstVertex,
80                                          const TopoDS_Vertex& theLastVertex,
81                                          TopoDS_Vertex&       theCommonVertex);
82 
83 static Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
84                                          const Standard_Integer   theEIndex1,
85                                          const Standard_Integer   theEIndex2,
86                                          TopoDS_Vertex&           theCommonVertex,
87                                          Standard_Real&           theParamOnE1,
88                                          Standard_Real&           theParamOnE2);
89 
90 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)&     theUEdges,
91                                     const BOPDS_PDS&                           theDS,
92                                     TopTools_DataMapOfShapeListOfShape&        theHistMap);
93 
94 static void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)&     theVEdges,
95                                 const Standard_Integer                     theIndex,
96                                 const TopoDS_Shape&                        theNewVedge,
97                                 TopTools_DataMapOfShapeListOfShape&        theHistMap);
98 
99 static void FindFreeVertices(const TopoDS_Shape&         theShape,
100                              const TopTools_MapOfShape&  theVerticesToAvoid,
101                              TopTools_ListOfShape&       theListOfVertex);
102 
103 static Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape&  theOrderedList,
104                                             const gp_Pnt2d&              theFirstPoint,
105                                             const gp_Pnt2d&              theLastPoint,
106                                             const TopoDS_Face&           theFace,
107                                             TopTools_ListOfShape&        theOrientedList);
108 
109 static Standard_Boolean FillGap(const TopoDS_Vertex&   theFirstVertex,
110                                 const TopoDS_Vertex&   theLastVertex,
111                                 const gp_Pnt2d&        theFirstPoint,
112                                 const gp_Pnt2d&        theLastPoint,
113                                 const TopoDS_Face&     theFace,
114                                 const TopoDS_Compound& theSectionEdges,
115                                 TopTools_ListOfShape&  theOrderedList);
116 
117 static Standard_Boolean FindNextEdge(const TopoDS_Vertex&   theFirstVertex,
118                                      const TopoDS_Vertex&   theLastVertex,
119                                      const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
120                                      const TopTools_MapOfShape& theMapToAvoid,
121                                      TopTools_ListOfShape&  theOrderedList);
122 
123 static Standard_Boolean FindVertex(const TopoDS_Edge&                        theEdge,
124                                    const Standard_Integer                    theRank,
125                                    const BOPDS_PDS&                          theDS,
126                                    const TopTools_DataMapOfShapeListOfShape& theHistMap,
127                                    TopoDS_Vertex&                            theVertex,
128                                    BOPDS_Pave&                               thePave);
129 
130 static Standard_Boolean FindNextVertex(const Standard_Integer                    theEdgeIndex,
131                                        const BOPDS_Pave&                         thePrevPave,
132                                        const BOPDS_PDS&                          theDS,
133                                        TopoDS_Vertex&                            theNextVertex,
134                                        BOPDS_Pave&                               thePave);
135 
136 static Standard_Boolean GetPave(const Standard_Integer    theEdgeIndex,
137                                 const Standard_Boolean    isFirst,
138                                 const BOPDS_PDS&          theDS,
139                                 BOPDS_Pave&               thePave);
140 
141 static Standard_Boolean FindFromUEdge(const TopoDS_Edge&                        theUE1Old,
142                                       const TopoDS_Edge&                        theUE2Old,
143                                       const TopoDS_Edge&                        theUE1New,
144                                       const TopoDS_Edge&                        theUE2New,
145                                       const TopoDS_Face&                        theFace,
146                                       const TopoDS_Compound&                    theSecEdges,
147                                       const Standard_Integer                    theRank,
148                                       const TopoDS_Edge&                        theBoundEdge,
149                                       const Standard_Integer                    theBoundEdgeIndex,
150                                       const BOPDS_PDS&                          theDS,
151                                       const TopTools_DataMapOfShapeListOfShape& theHistMap,
152                                       TopoDS_Compound&                          theSecEdgesNew,
153                                       TopTools_ListOfShape&                     theListOfWireEdges,
154                                       BOPDS_Pave&                               theFoundPave,
155                                       Standard_Boolean&                         isOnUEdge);
156 
157 static Standard_Boolean FindFromVEdge(const BOPDS_Pave&                         thePrevPave,
158                                       const Standard_Boolean&                   isOnUEdge,
159                                       const TopoDS_Edge&                        theUE1Old,
160                                       const TopoDS_Edge&                        theUE2Old,
161                                       const TopoDS_Face&                        theFace,
162                                       const TopoDS_Compound&                    theSecEdges,
163                                       const Standard_Integer                    theRank,
164                                       const TopoDS_Edge&                        theBoundEdge,
165                                       const Standard_Integer                    theBoundEdgeIndex,
166                                       const BOPDS_PDS&                          theDS,
167                                       const TopTools_DataMapOfShapeListOfShape& theHistMap,
168                                       TopTools_ListOfShape&                     theListOfWireEdges,
169                                       Standard_Boolean&                         isSectionFound);
170 
171 static void RemoveEdges(const TopoDS_Compound&      theSourceComp,
172                         const TopTools_ListOfShape& theListToRemove,
173                         TopoDS_Compound&            theResultComp);
174 
175 static Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve&       theBCurves,
176                                            const TopoDS_Face&               theSecPlane,
177                                            const BOPDS_PDS&                 theDS,
178                                            TopoDS_Compound&                 theResult);
179 
180 static Standard_Boolean GetUEdges(const Standard_Integer                     theIndex,
181                                   const Standard_Integer                     theRank,
182                                   const Handle(TopTools_HArray2OfShape)&     theUEdges,
183                                   const TopoDS_Edge&                         theBoundEdge,
184                                   const TopoDS_Face&                         theFace,
185                                   TopoDS_Edge&                               theFirstUEdge,
186                                   TopoDS_Edge&                               theSecondUEdge);
187 
188 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
189                                                         gp_Pln& thePlane,
190                                                         Standard_Boolean& IsSingular);
191 
192 static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
193                               const TopoDS_Vertex& theConstVertex,
194                               TopoDS_Vertex&       theVertex,
195                               const Standard_Real  theParam);
196 
197 
198 // ===========================================================================================
199 // function: Constructor
200 // purpose:
201 // ===========================================================================================
BRepFill_TrimShellCorner(const Handle (TopTools_HArray2OfShape)& theFaces,const BRepFill_TransitionStyle theTransition,const gp_Ax2 & theAxeOfBisPlane)202 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
203                                                    const BRepFill_TransitionStyle         theTransition,
204                                                    const gp_Ax2&                          theAxeOfBisPlane) :
205   myTransition(theTransition),
206   myAxeOfBisPlane(theAxeOfBisPlane),
207   myDone(Standard_False),
208   myHasSection(Standard_False)
209 {
210   myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(),
211                                         theFaces->LowerCol(), theFaces->UpperCol());
212   myFaces->ChangeArray2() = theFaces->Array2();
213 }
214 
215 // ===========================================================================================
216 // function: AddBounds
217 // purpose:
218 // ===========================================================================================
AddBounds(const Handle (TopTools_HArray2OfShape)& theBounds)219 void BRepFill_TrimShellCorner::AddBounds(const Handle(TopTools_HArray2OfShape)& theBounds)
220 {
221   myBounds = new TopTools_HArray2OfShape(theBounds->LowerRow(), theBounds->UpperRow(),
222                                          theBounds->LowerCol(), theBounds->UpperCol());
223   myBounds->ChangeArray2() = theBounds->Array2();
224 }
225 
226 // ===========================================================================================
227 // function: AddUEdges
228 // purpose:
229 // ===========================================================================================
AddUEdges(const Handle (TopTools_HArray2OfShape)& theUEdges)230 void BRepFill_TrimShellCorner::AddUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges)
231 {
232   myUEdges = new TopTools_HArray2OfShape(theUEdges->LowerRow(), theUEdges->UpperRow(),
233                                          theUEdges->LowerCol(), theUEdges->UpperCol());
234   myUEdges->ChangeArray2() = theUEdges->Array2();
235 }
236 
237 // ===========================================================================================
238 // function: AddVEdges
239 // purpose:
240 // ===========================================================================================
AddVEdges(const Handle (TopTools_HArray2OfShape)& theVEdges,const Standard_Integer theIndex)241 void BRepFill_TrimShellCorner::AddVEdges(const Handle(TopTools_HArray2OfShape)& theVEdges,
242                                          const Standard_Integer theIndex)
243 {
244   myVEdges = new TopTools_HArray1OfShape(theVEdges->LowerRow(), theVEdges->UpperRow());
245 
246   for (Standard_Integer i = theVEdges->LowerRow(); i <= theVEdges->UpperRow(); i++)
247     myVEdges->SetValue(i, theVEdges->Value(i, theIndex));
248 }
249 
250 // ===========================================================================================
251 // function: Perform
252 // purpose:
253 // ===========================================================================================
Perform()254 void BRepFill_TrimShellCorner::Perform()
255 {
256   Standard_Integer anIndex1, anIndex2, nF1, nF2, i, j, aNbP, aNbC;
257   Standard_Boolean bhassec;
258 
259   myDone = Standard_False;
260   myHistMap.Clear();
261 
262   if(myFaces->RowLength() != 2)
263     return;
264   Standard_Integer ii = 0, jj = 0;
265   BRep_Builder aBB;
266 
267   for(jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
268     TopoDS_Shell aShell;
269     aBB.MakeShell(aShell);
270 
271     for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
272       aBB.Add(aShell, myFaces->Value(ii, jj));
273     }
274     aShell.Closed (BRep_Tool::IsClosed (aShell));
275 
276     if(jj == myFaces->LowerCol()) {
277       myShape1 = aShell;
278     }
279     else {
280       myShape2 = aShell;
281     }
282   }
283 
284   Standard_Real aMaxTol = 0.;
285   TopExp_Explorer anExp(myShape1, TopAbs_VERTEX);
286   for (; anExp.More(); anExp.Next())
287   {
288     aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
289   }
290 
291   anExp.Init(myShape2, TopAbs_VERTEX);
292   for (; anExp.More(); anExp.Next())
293   {
294     aMaxTol = Max(aMaxTol, BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Current())));
295   }
296 
297   Standard_Real aFuzzy = 4.*Precision::Confusion();
298   BOPAlgo_PaveFiller aPF;
299   TopTools_ListOfShape aLS;
300   aLS.Append(myShape1);
301   aLS.Append(myShape2);
302   aPF.SetArguments(aLS);
303   if (aMaxTol < 1.005 * Precision::Confusion())
304   {
305     aFuzzy = Max(aPF.FuzzyValue(), aFuzzy);
306     aPF.SetFuzzyValue(aFuzzy);
307   }
308   //
309   aPF.Perform();
310   if (aPF.HasErrors()) {
311     return;
312   }
313   //
314   const BOPDS_PDS& theDS = aPF.PDS();
315   //
316   BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
317   Standard_Integer aNbFFs = aFFs.Length();
318 
319   if(!SplitUEdges(myUEdges, theDS, myHistMap)) {
320     return;
321   }
322 
323   for(ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
324     TopoDS_Shape aF1 = myFaces->Value(ii, myFaces->LowerCol());
325     TopoDS_Shape aF2 = myFaces->Value(ii, myFaces->UpperCol());
326     //
327     anIndex1 = theDS->Index(aF1);
328     anIndex2 = theDS->Index(aF2);
329 
330     if((anIndex1 == -1) || (anIndex2 == -1))
331       continue;
332 
333     for (i=0; i < aNbFFs; ++i) {
334       BOPDS_InterfFF& aFFi = aFFs(i);
335       aFFi.Indices(nF1, nF2);
336       //
337       BOPDS_VectorOfPoint& aVP=aFFi.ChangePoints();
338       aNbP=aVP.Length();
339       const BOPDS_VectorOfCurve& aVC=aFFi.Curves();
340       aNbC=aVC.Length();
341       if (!aNbP && !aNbC) {
342 	if (!theDS->HasInterfSubShapes(nF1, nF2)) {
343           continue;
344         }
345       }
346       //
347       if((nF1 == anIndex1) && (nF2 == anIndex2)) {
348         bhassec = Standard_False;
349         //
350         for (j = 0; j < aNbC; ++j) {
351           const BOPDS_Curve& aBCurve = aVC(j);
352           const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
353           //
354           if (aSectEdges.Extent()) {
355             bhassec = Standard_True;
356             break;
357           }
358         }
359 
360         if(!bhassec) {
361           if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
362             myHistMap.Clear();
363             return;
364           }
365         }
366         else {
367           if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
368             myHistMap.Clear();
369             return;
370           }
371         }
372         break;
373       }
374     }
375   }
376   myDone = Standard_True;
377 }
378 
379 // ===========================================================================================
380 // function: IsDone
381 // purpose:
382 // ===========================================================================================
IsDone() const383 Standard_Boolean BRepFill_TrimShellCorner::IsDone() const
384 {
385   return myDone;
386 }
387 
388 // ===========================================================================================
389 // function: HasSection
390 // purpose:
391 // ===========================================================================================
HasSection() const392 Standard_Boolean BRepFill_TrimShellCorner::HasSection() const
393 {
394   return myHasSection;
395 }
396 
397 // ===========================================================================================
398 // function: Modified
399 // purpose:
400 // ===========================================================================================
Modified(const TopoDS_Shape & theShape,TopTools_ListOfShape & theModified)401 void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape&   theShape,
402                                         TopTools_ListOfShape& theModified)
403 {
404   theModified.Clear();
405 
406   if(myHistMap.IsBound(theShape)) {
407     theModified = myHistMap.Find(theShape);
408   }
409 }
410 
411 // ----------------------------------------------------------------------------------------------------
412 // function: MakeFacesNonSec
413 // purpose:         Updates <myHistMap> by new faces in the case when old faces do not intersect
414 // ----------------------------------------------------------------------------------------------------
415 Standard_Boolean
MakeFacesNonSec(const Standard_Integer theIndex,const BOPDS_PDS & theDS,const Standard_Integer theFaceIndex1,const Standard_Integer theFaceIndex2)416 BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer                     theIndex,
417                                           const BOPDS_PDS&                           theDS,
418                                           const Standard_Integer                     theFaceIndex1,
419                                           const Standard_Integer                     theFaceIndex2)
420 {
421   Standard_Boolean bHasNewEdge = Standard_False;
422   TopoDS_Edge aNewEdge;
423 
424   BRep_Builder aBB;
425   const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
426   const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
427 
428   // search common vertex between bounds. begin
429   TopoDS_Vertex aCommonVertex;
430   Standard_Integer anIndex1 = theDS->Index(aE1);
431   Standard_Integer anIndex2 = theDS->Index(aE2);
432   Standard_Real apar1 = 0., apar2 = 0.;
433 
434   Standard_Boolean bvertexfound =
435     FindCommonVertex(theDS, anIndex1, anIndex2, aCommonVertex, apar1, apar2);
436   // search common vertex between bounds. end
437 
438   Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
439 
440   // search common vertices between uedges. begin
441   TopTools_ListOfShape aCommonVertices;
442   Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
443   Standard_Integer ueit = 0, eindex = 0;
444 
445   for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
446     const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
447     const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
448     TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
449     TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
450 
451     if (myHistMap.IsBound(aShape1)) {
452       const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
453 
454       if(!lst.IsEmpty())
455         aUE1 = TopoDS::Edge(lst.First());
456     }
457 
458     if (myHistMap.IsBound(aShape2)) {
459       const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
460 
461       if(!lst.IsEmpty())
462         aUE2 = TopoDS::Edge(lst.First());
463     }
464 
465     if(!aShape1.IsSame(aUE1))
466       aSubstitutor->Replace(aShape1.Oriented(TopAbs_FORWARD), aUE1.Oriented(TopAbs_FORWARD));
467 
468     if(!aShape2.IsSame(aUE2))
469       aSubstitutor->Replace(aShape2.Oriented(TopAbs_FORWARD), aUE2.Oriented(TopAbs_FORWARD));
470 
471     TopoDS_Vertex V1 = TopExp::LastVertex(aUE1);
472     TopoDS_Vertex V2 = TopExp::FirstVertex(aUE2);
473 
474     if(V1.IsSame(V2)) {
475       acommonflag = (acommonflag == 0) ? ueit : 3;
476       aCommonVertices.Append(V1);
477     }
478   }
479   // search common vertices between uedges. end
480 
481   if(bvertexfound) {
482     if(aCommonVertices.Extent() != 1)
483       return Standard_False;
484 
485     if(acommonflag == 1)
486       aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()), aCommonVertex);
487     else
488       aNewEdge = BRepLib_MakeEdge(aCommonVertex, TopoDS::Vertex(aCommonVertices.First()));
489 
490     bHasNewEdge = Standard_True;
491   }
492 
493   if(aCommonVertices.Extent() == 2) {
494     aNewEdge = BRepLib_MakeEdge(TopoDS::Vertex(aCommonVertices.First()),
495                                 TopoDS::Vertex(aCommonVertices.Last()));
496     bHasNewEdge = Standard_True;
497   }
498   Standard_Integer fit = 0;
499 
500   for(fit = 1; fit <= 2; fit++) {
501     TopoDS_Compound aComp;
502     TopTools_MapOfShape aMapV;
503     aBB.MakeCompound(aComp);
504 
505     for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
506       const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
507       TopoDS_Shape aUE = aShape;
508 
509       if(myHistMap.IsBound(aShape)) {
510         const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
511 
512         if(!lst.IsEmpty())
513           aUE = TopoDS::Edge(lst.First());
514       }
515       const TopoDS_Shape& aV = (fit == 1) ? TopExp::FirstVertex(TopoDS::Edge(aUE)) : TopExp::LastVertex(TopoDS::Edge(aUE));
516       aMapV.Add(aV);
517       aBB.Add(aComp, aUE);
518     }
519 
520     if(bHasNewEdge) {
521       aBB.Add(aComp, aNewEdge);
522       StoreVedgeInHistMap(myVEdges, theIndex, aNewEdge, myHistMap);
523     }
524 
525     TopTools_ListOfShape alonevertices;
526     FindFreeVertices(aComp, aMapV, alonevertices);
527 
528     if(!alonevertices.IsEmpty() && (alonevertices.Extent() != 2))
529       return Standard_False;
530 
531     Standard_Integer aFaceIndex = (fit == 1) ? theFaceIndex1 : theFaceIndex2;
532     TopoDS_Shape aFace          = theDS->Shape(aFaceIndex);
533     TopAbs_Orientation aFaceOri = aFace.Orientation();
534     aFace.Orientation(TopAbs_FORWARD);
535 
536     TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
537 
538     if(bHasNewEdge) {
539       aNewEdge.Orientation(TopAbs_FORWARD);
540     }
541 
542     TopTools_ListOfShape aOrderedList;
543 
544     if(!alonevertices.IsEmpty()) {
545       Standard_Integer anEIndex = (fit == 1) ? anIndex1 : anIndex2;
546       Standard_Boolean bfound1 = Standard_False;
547       Standard_Boolean bfound2 = Standard_False;
548       Standard_Real aparam1 = 0., aparam2 = 0.;
549 
550       BOPDS_ListOfPave aLP;
551       theDS->Paves(anEIndex, aLP);
552       BOPDS_ListIteratorOfListOfPave aIt;
553       aIt.Initialize(aLP);
554       for ( ; aIt.More(); aIt.Next()) {
555         const BOPDS_Pave& aPave = aIt.Value();
556         TopoDS_Shape aV = theDS->Shape(aPave.Index());
557 
558         if(aV.IsSame(alonevertices.First())) {
559           if(!bfound1) {
560             aparam1 = aPave.Parameter();
561             bfound1 = Standard_True;
562           }
563         }
564 
565         if(aV.IsSame(alonevertices.Last())) {
566           if(!bfound2) {
567             aparam2 = aPave.Parameter();
568             bfound2 = Standard_True;
569           }
570         }
571       }
572 
573       if(bfound1 && bfound2) {
574         TopoDS_Edge aNewBoundE;
575 
576         if(fit == 1) {
577           aNewBoundE = TopoDS::Edge(aE1.EmptyCopied());
578         }
579         else {
580           aNewBoundE = TopoDS::Edge(aE2.EmptyCopied());
581         }
582         TopoDS_Vertex aV1, aV2;
583 
584         if(aparam1 < aparam2) {
585           aV1 = TopoDS::Vertex(alonevertices.First());
586           aV2 = TopoDS::Vertex(alonevertices.Last());
587         }
588         else {
589           aV1 = TopoDS::Vertex(alonevertices.Last());
590           aV2 = TopoDS::Vertex(alonevertices.First());
591           Standard_Real tmp = aparam1;
592           aparam1 = aparam2;
593           aparam2 = tmp;
594         }
595         aV1.Orientation(TopAbs_FORWARD);
596         aV2.Orientation(TopAbs_REVERSED);
597         aBB.Add(aNewBoundE, aV1);
598         aBB.Add(aNewBoundE, aV2);
599         aBB.Range(aNewBoundE, aparam1, aparam2);
600         aNewBoundE.Orientation(TopAbs_FORWARD);
601 
602         aOrderedList.Append(aNewBoundE);
603 
604         if(bHasNewEdge) {
605           TopExp_Explorer anExpV(aNewEdge, TopAbs_VERTEX);
606           Standard_Boolean bfoundv = Standard_False;
607 
608           for(; !bfoundv && anExpV.More(); anExpV.Next()) {
609             if(aV2.IsSame(anExpV.Current()))
610               bfoundv = Standard_True;
611           }
612 
613           if(bfoundv)
614             aOrderedList.Append(aNewEdge);
615           else
616             aOrderedList.Prepend(aNewEdge);
617         }
618       }
619       else {
620         return Standard_False;
621       }
622     }
623     else {
624       if(bHasNewEdge) {
625         aOrderedList.Append(aNewEdge);
626       }
627     }
628 
629     if(!aOrderedList.IsEmpty()) {
630       TopoDS_Wire aW;
631       aBB.MakeWire(aW);
632       TopTools_ListIteratorOfListOfShape anItE(aOrderedList);
633 
634       for(; anItE.More(); anItE.Next()) {
635         aBB.Add(aW, anItE.Value());
636       }
637       if(fit == 1)
638         aSubstitutor->Replace(aE1.Oriented(TopAbs_FORWARD), aW);
639       else
640         aSubstitutor->Replace(aE2.Oriented(TopAbs_FORWARD), aW);
641     }
642 
643     aSubstitutor->Apply(aFace);
644     TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
645     aNewFace.Orientation(aFaceOri);
646     TopTools_ListOfShape atmpList;
647     atmpList.Append(aNewFace);
648     myHistMap.Bind(aFace, atmpList);
649 
650     anExpE.Init(aFace, TopAbs_EDGE);
651 
652     for(; anExpE.More(); anExpE.Next()) {
653       TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
654 
655       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
656         continue;
657 
658       if (myHistMap.IsBound(anExpE.Current()))
659         continue;
660       TopTools_ListOfShape aListOfNewEdge;
661       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
662 
663       for(; anExpE2.More(); anExpE2.Next()) {
664         aListOfNewEdge.Append(anExpE2.Current());
665       }
666       myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
667     }
668   }
669 
670   return Standard_True;
671 }
672 
673 // ----------------------------------------------------------------------------------------------------
674 // function: MakeFacesSec
675 // purpose:  Updates <myHistMap> by new faces in the case when old faces intersect each other
676 // ----------------------------------------------------------------------------------------------------
677 Standard_Boolean
MakeFacesSec(const Standard_Integer theIndex,const BOPDS_PDS & theDS,const Standard_Integer theFaceIndex1,const Standard_Integer theFaceIndex2,const Standard_Integer theSSInterfIndex)678 BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer                     theIndex,
679                                        const BOPDS_PDS&                           theDS,
680                                        const Standard_Integer                     theFaceIndex1,
681                                        const Standard_Integer                     theFaceIndex2,
682                                        const Standard_Integer                     theSSInterfIndex)
683 {
684   const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
685   const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
686   const BOPDS_VectorOfCurve& aBCurves = aFFi.Curves();
687 
688   TopoDS_Compound aSecEdges;
689   TopoDS_Face aSecPlane;
690 
691   if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
692     return Standard_False;
693 
694   //Extract vertices on the intersection of correspondent U-edges
695   const TopoDS_Shape& LeftE1  = myUEdges->Value(theIndex, 1);
696   const TopoDS_Shape& LeftE2  = myUEdges->Value(theIndex, 2);
697   const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1);
698   const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2);
699 
700   Standard_Integer IndexOfLeftE1  = theDS->Index(LeftE1);
701   Standard_Integer IndexOfLeftE2  = theDS->Index(LeftE2);
702   Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
703   Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
704 
705   TopoDS_Vertex FirstVertex, LastVertex;
706   Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
707   FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2,
708                    FirstVertex, ParamOnLeftE1, ParamOnLeftE2);
709   FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2,
710                    LastVertex, ParamOnRightE1, ParamOnRightE2);
711 
712   TopoDS_Shape SecWire;
713   gp_Pln SecPlane;
714   Standard_Boolean IsSingular;
715   Standard_Boolean WireFound = ChooseSection(aSecEdges,
716                                              FirstVertex, LastVertex,
717                                              SecWire, SecPlane, IsSingular );
718 
719   if(WireFound) {
720     //aSecEdges = SecWire;
721     TopoDS_Compound aComp;
722     BRep_Builder BB;
723     BB.MakeCompound(aComp);
724     TopExp_Explorer explo( SecWire, TopAbs_EDGE );
725 
726     for (; explo.More(); explo.Next())
727       BB.Add( aComp, explo.Current() );
728     aSecEdges = aComp;
729 
730     StoreVedgeInHistMap(myVEdges, theIndex, SecWire, myHistMap);
731   }
732 
733   TopTools_ListOfShape aCommonVertices;
734 //  Standard_Integer acommonflag = 0; // 0 - no, 1 - first pair, 2 - second pair, 3 - both
735   Standard_Integer fit = 0; //, ueit = 0, eindex = 0, i = 0;
736   Handle(BRepTools_ReShape) aSubstitutor = new BRepTools_ReShape();
737 
738   for(fit = 0; fit < 2; fit++) {
739     Standard_Integer aFaceIndex = (fit == 0) ? theFaceIndex1 : theFaceIndex2;
740     TopoDS_Face aFace = TopoDS::Face(theDS->Shape(aFaceIndex));
741     TopAbs_Orientation aFaceOri = aFace.Orientation();
742     TopoDS_Face aFaceF = aFace;
743     aFaceF.Orientation(TopAbs_FORWARD);
744     TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit));
745     Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
746     TopoDS_Edge aUE1;
747     TopoDS_Edge aUE2;
748 
749     if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
750       return Standard_False;
751 
752     TopoDS_Edge aUE1old = aUE1;
753     TopoDS_Edge aUE2old = aUE2;
754 
755     if (myHistMap.IsBound(aUE1)) {
756       const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
757 
758       if(!lst.IsEmpty()) {
759         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
760 
761         if(!aUE1.IsSame(anEdge))
762           aSubstitutor->Replace(aUE1.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
763         aUE1 = TopoDS::Edge(anEdge);
764       }
765     }
766 
767     if (myHistMap.IsBound(aUE2)) {
768       const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
769 
770       if(!lst.IsEmpty()) {
771         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
772 
773         if(!aUE2.IsSame(anEdge))
774           aSubstitutor->Replace(aUE2.Oriented(TopAbs_FORWARD), anEdge.Oriented(TopAbs_FORWARD));
775         aUE2 = TopoDS::Edge(anEdge);
776       }
777     }
778     TopoDS_Vertex aPrevVertex, aNextVertex;
779     TopoDS_Compound aCompOfSecEdges = aSecEdges;
780     TopTools_ListOfShape aListOfWireEdges;
781     BRep_Builder aBB;
782     BOPDS_Pave aPave1;
783     Standard_Boolean isPave1OnUEdge = Standard_True;
784 
785     if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex,
786                      theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
787       TopTools_ListOfShape aSecondListOfEdges;
788       Standard_Boolean bisSectionFound = Standard_False;
789 
790       if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge,
791                         aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
792         return Standard_False;
793       }
794 
795       if(!bisSectionFound && aListOfWireEdges.IsEmpty()) {
796         return Standard_False;
797       }
798       aListOfWireEdges.Append(aSecondListOfEdges);
799     }
800     else {
801       return Standard_False;
802     }
803 
804     if(!aListOfWireEdges.IsEmpty()) {
805       TopoDS_Wire aW;
806       aBB.MakeWire(aW);
807       TopTools_ListIteratorOfListOfShape aEIt(aListOfWireEdges);
808 
809       for(; aEIt.More(); aEIt.Next()) {
810         if(!aBoundEdge.IsSame(aEIt.Value()))
811           aBB.Add(aW, aEIt.Value());
812       }
813       aSubstitutor->Replace(aBoundEdge.Oriented(TopAbs_FORWARD), aW);
814     }
815 
816     aSubstitutor->Apply(aFace);
817     TopoDS_Shape aNewFace = aSubstitutor->Value(aFace);
818     aNewFace.Orientation(aFaceOri);
819     TopTools_ListOfShape atmpList;
820     atmpList.Append(aNewFace);
821     myHistMap.Bind(aFace, atmpList);
822 
823     TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
824 
825     for(; anExpE.More(); anExpE.Next()) {
826       TopoDS_Shape aNewValue = aSubstitutor->Value(anExpE.Current());
827 
828       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
829         continue;
830 
831       if (myHistMap.IsBound(anExpE.Current()))
832         continue;
833       TopTools_ListOfShape aListOfNewEdge;
834       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
835 
836       for(; anExpE2.More(); anExpE2.Next()) {
837         aListOfNewEdge.Append(anExpE2.Current());
838       }
839       myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
840     }
841   }
842   return Standard_True;
843 }
844 
845 //=======================================================================
846 //function : ChooseSection
847 //purpose  :
848 //=======================================================================
ChooseSection(const TopoDS_Shape & Comp,const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,TopoDS_Shape & resWire,gp_Pln & resPlane,Standard_Boolean & IsSingular)849 Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
850                                                          const TopoDS_Vertex& theFirstVertex,
851                                                          const TopoDS_Vertex& theLastVertex,
852                                                          TopoDS_Shape& resWire,
853                                                          gp_Pln& resPlane,
854                                                          Standard_Boolean& IsSingular)
855 {
856   IsSingular = Standard_False;
857 
858   Standard_Integer ind, i, j;
859   BRep_Builder BB;
860 
861   if (myTransition == BRepFill_Right &&
862       !theFirstVertex.IsNull() &&
863       !theLastVertex.IsNull()) //the case where section wire goes from
864     //its known first vertex to its known last vertex
865   {
866     TopoDS_Wire NewWire;
867     BB.MakeWire(NewWire);
868 
869     TopoDS_Compound OldComp;
870     BB.MakeCompound( OldComp );
871     TopoDS_Iterator iter( Comp );
872     for (; iter.More(); iter.Next())
873       BB.Add( OldComp, iter.Value() );
874 
875     TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex,
876                                                           OldComp,
877                                                           myAxeOfBisPlane.Axis());
878     if (FirstEdge.IsNull())
879       return Standard_False;
880 
881     iter.Initialize(OldComp);
882     if (!iter.More())
883     {
884       iter.Initialize(Comp);
885       BB.Add( OldComp, iter.Value() );
886     }
887     TopoDS_Edge LastEdge  = FindEdgeCloseToBisectorPlane(theLastVertex,
888                                                           OldComp,
889                                                           myAxeOfBisPlane.Axis());
890     if (LastEdge.IsNull())
891       return Standard_False;
892 
893     if (FirstEdge.IsNull() || LastEdge.IsNull())
894     {
895       return Standard_False;
896     }
897 
898     BB.Add(NewWire, FirstEdge);
899 
900     if (!FirstEdge.IsSame(LastEdge))
901     {
902       TopoDS_Vertex aCommonVertex;
903       Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge,
904                                                              theFirstVertex, theLastVertex,
905                                                              aCommonVertex);
906       if (CommonVertexExists)
907         BB.Add(NewWire, LastEdge);
908       else
909       {
910         TopoDS_Vertex Vertex1, Vertex2, V1, V2;
911         TopExp::Vertices(FirstEdge, V1, V2);
912         Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1;
913         TopExp::Vertices(LastEdge, V1, V2);
914         Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1;
915 
916         TopTools_ListOfShape MiddleEdges;
917         if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
918         {
919           TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
920           for (; itl.More(); itl.Next())
921             BB.Add(NewWire, itl.Value());
922           BB.Add(NewWire, LastEdge);
923         }
924         else
925         {
926           //trim <FirstEdge> and <LastEdge> in the points of extrema
927           //these points become new vertex with centre between them
928           BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
929           if (Extrema.IsDone() && Extrema.NbExt() > 0)
930           {
931             Standard_Integer imin = 1;
932             for (i = 2; i <= Extrema.NbExt(); i++)
933               if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
934                 imin = i;
935 
936             Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
937             Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
938             Standard_Real ParamOnLastEdge  = Extrema.ParameterOnE2(imin);
939             gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
940             gp_Pnt PointOnLastEdge  = Extrema.PointOnE2(imin);
941             gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2);
942             aCommonVertex = BRepLib_MakeVertex(MidPnt);
943             BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2);
944 
945             UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
946             UpdateSectionEdge(LastEdge,  theLastVertex,  aCommonVertex, ParamOnLastEdge);
947 
948             BB.Add(NewWire, LastEdge);
949           }
950         }
951       }
952     }
953 
954     resWire = NewWire;
955     resPlane = gp_Pln(myAxeOfBisPlane);
956     return Standard_True;
957   }
958 
959   //General case: try to find continuous section closest to bisector plane
960   TopoDS_Compound OldComp;
961   BRep_Builder B;
962   B.MakeCompound( OldComp );
963   TopoDS_Iterator iter( Comp );
964   for (; iter.More(); iter.Next())
965     B.Add( OldComp, iter.Value() );
966 
967   Standard_Boolean anError = Standard_False;
968   //TopoDS_Wire NewWire [2];
969   TopTools_SequenceOfShape Wseq;
970   for (;;)
971   {
972     TopExp_Explorer explo( OldComp, TopAbs_EDGE );
973     if (!explo.More())
974       break;
975     TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
976     TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
977     B.Remove( OldComp, FirstEdge );
978     if (NewWire.Closed())
979     {
980       Wseq.Append(NewWire);
981       continue;
982     }
983 
984     for (;;)
985     {
986       TopoDS_Vertex Extremity [2];
987       TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
988       if (Extremity[0].IsNull() || Extremity[1].IsNull())
989       {
990         anError = Standard_True;
991         break;
992       }
993       TopTools_IndexedDataMapOfShapeListOfShape VEmap;
994       TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
995       TopTools_ListOfShape Vedges [2];
996       for (j = 0; j < 2; j++)
997         if (VEmap.Contains( Extremity[j] ))
998           Vedges[j] = VEmap.FindFromKey( Extremity[j] );
999       if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
1000         //no more edges in OldComp to continue NewWire
1001         break;
1002       Standard_Boolean Modified = Standard_False;
1003       for (j = 0; j < 2; j++)
1004       {
1005         if (Vedges[j].Extent() == 1)
1006         {
1007           const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
1008           NewWire = BRepLib_MakeWire( NewWire, anEdge );
1009           B.Remove( OldComp, anEdge );
1010           Modified = Standard_True;
1011         }
1012       }
1013       if (!Modified) //only multiple connections
1014       {
1015         ind = (Vedges[0].IsEmpty())? 1 : 0;
1016         TopTools_SequenceOfShape Edges;
1017         TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
1018         for (; itl.More(); itl.Next())
1019           Edges.Append( itl.Value() );
1020         Standard_Integer theind=0;
1021         Standard_Real MinDeviation = RealLast();
1022         for (j = 1; j <= Edges.Length(); j++)
1023         {
1024           TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
1025           gp_Pln aPlane;
1026           Standard_Boolean issing;
1027           Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
1028           if (Deviation < MinDeviation)
1029           {
1030             MinDeviation = Deviation;
1031             theind = j;
1032           }
1033         }
1034         NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
1035         B.Remove( OldComp, Edges(theind) );
1036       }
1037       if (NewWire.Closed())
1038         break;
1039     }
1040     Wseq.Append(NewWire);
1041     if (anError)
1042       break;
1043   }
1044 
1045   Standard_Real MinAngle = RealLast();
1046   TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
1047   if (!anError && !Explo.More()) //wires are built successfully and compound <OldComp> is empty
1048   {
1049     if (Wseq.Length() == 1) //only one wire => it becomes result
1050     {
1051       resWire = Wseq.First();
1052       ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
1053       return Standard_True;
1054     }
1055     else //we must choose the wire which average plane is closest to bisector plane
1056     {    //(check angle between axes)
1057       for (i = 1; i <= Wseq.Length(); i++)
1058       {
1059         TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
1060         gp_Pln aPln;
1061         Standard_Boolean issing;
1062         ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
1063         if (issing)
1064           continue;
1065 
1066         Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() );
1067         if (Angle > M_PI/2)
1068           Angle = M_PI - Angle;
1069 
1070         if (Angle < MinAngle)
1071         {
1072           MinAngle = Angle;
1073           resWire = aWire;
1074           resPlane = aPln;
1075         }
1076       }
1077       return Standard_True;
1078     }
1079   }
1080   return Standard_False;
1081 }
1082 
1083 
1084 // ------------------------------------------------------------------------------------------
1085 // static function: SplitUEdges
1086 // purpose:
1087 // ------------------------------------------------------------------------------------------
SplitUEdges(const Handle (TopTools_HArray2OfShape)& theUEdges,const BOPDS_PDS & theDS,TopTools_DataMapOfShapeListOfShape & theHistMap)1088 Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)&     theUEdges,
1089                              const BOPDS_PDS&                           theDS,
1090                              TopTools_DataMapOfShapeListOfShape&        theHistMap) {
1091 
1092   const BOPDS_VectorOfInterfVV& aVVs = theDS->InterfVV();
1093 
1094   BRep_Builder aBB;
1095   Standard_Integer ueit = 0, upRow, lowCol, upCol;
1096   TopTools_Array2OfShape aNewVertices(1,2,1,2);
1097   //
1098   upRow = theUEdges->UpperRow();
1099   lowCol = theUEdges->LowerCol();
1100   upCol = theUEdges->UpperCol();
1101   //
1102   for(ueit = theUEdges->LowerRow(); ueit <= upRow; ueit++) {
1103     const TopoDS_Shape& aE1 = theUEdges->Value(ueit, lowCol);
1104     const TopoDS_Shape& aE2 = theUEdges->Value(ueit, upCol);
1105 
1106     if(theHistMap.IsBound(aE1) || theHistMap.IsBound(aE2))
1107       continue;
1108 
1109     Standard_Integer anEIndex1 = theDS->Index(aE1);
1110     Standard_Integer anEIndex2 = theDS->Index(aE2);
1111 
1112     TopoDS_Vertex aCommonVertex;
1113     Standard_Real apar1 = 0., apar2 = 0.;
1114     Standard_Boolean bvertexfound =
1115       FindCommonVertex(theDS, anEIndex1, anEIndex2, aCommonVertex, apar1, apar2);
1116     //
1117     if(!bvertexfound) {
1118       TopoDS_Vertex V1 = TopExp::LastVertex(TopoDS::Edge(aE1));
1119       TopoDS_Vertex V2 = TopExp::FirstVertex(TopoDS::Edge(aE2));
1120       Standard_Integer vindex1 = theDS->Index(V1);
1121       Standard_Integer vindex2 = theDS->Index(V2);
1122       Standard_Integer vvit = 0;
1123       Standard_Integer aNbVVs = aVVs.Length();
1124 
1125       for(vvit = 0; !bvertexfound && (vvit < aNbVVs); vvit++) {
1126         //const BOPTools_VVInterference& aVV = aVVs(vvit);
1127         const BOPDS_InterfVV& aVV = aVVs(vvit);
1128 
1129         if(((vindex1 == aVV.Index1()) && (vindex2 == aVV.Index2())) ||
1130            ((vindex1 == aVV.Index2()) && (vindex2 == aVV.Index1()))) {
1131 
1132           if(!aVV.HasIndexNew()) {
1133             continue;
1134           }
1135           aCommonVertex = TopoDS::Vertex(theDS->Shape(aVV.IndexNew()));
1136           bvertexfound = Standard_True;
1137           apar1 = BRep_Tool::Parameter(V1, TopoDS::Edge(aE1));
1138           apar2 = BRep_Tool::Parameter(V2, TopoDS::Edge(aE2));
1139         }
1140       }
1141     }
1142 
1143     if(bvertexfound) {
1144       TopoDS_Vertex aV1, aV2;
1145       Standard_Real f = 0., l = 0.;
1146       //
1147       TopoDS_Edge aNewE1 = TopoDS::Edge(aE1.EmptyCopied());
1148       TopExp::Vertices(TopoDS::Edge(aE1), aV1, aV2);
1149       aNewE1.Orientation(TopAbs_FORWARD);
1150       aV1.Orientation(TopAbs_FORWARD);
1151       aBB.Add(aNewE1, aV1);
1152       aCommonVertex.Orientation(TopAbs_REVERSED);
1153       aBB.Add(aNewE1, aCommonVertex);
1154       BRep_Tool::Range(TopoDS::Edge(aE1), f, l);
1155       aBB.Range(aNewE1, f, apar1);
1156 
1157       //
1158       TopoDS_Edge aNewE2 = TopoDS::Edge(aE2.EmptyCopied());
1159       TopExp::Vertices(TopoDS::Edge(aE2), aV1, aV2);
1160       aNewE2.Orientation(TopAbs_FORWARD);
1161       aCommonVertex.Orientation(TopAbs_FORWARD);
1162       aBB.Add(aNewE2, aCommonVertex);
1163       aBB.Add(aNewE2, aV2);
1164       BRep_Tool::Range(TopoDS::Edge(aE2), f, l);
1165       aBB.Range(aNewE2, apar2, l);
1166 
1167       TopTools_ListOfShape lst;
1168       lst.Append(aNewE1);
1169       theHistMap.Bind(aE1, lst);
1170       lst.Clear();
1171       lst.Append(aNewE2);
1172       theHistMap.Bind(aE2, lst);
1173     }
1174   }
1175   return Standard_True;
1176 }
1177 
1178 // ------------------------------------------------------------------------------------------
1179 // static function: StoreVedgeInHistMap
1180 // purpose:
1181 // ------------------------------------------------------------------------------------------
StoreVedgeInHistMap(const Handle (TopTools_HArray1OfShape)& theVEdges,const Standard_Integer theIndex,const TopoDS_Shape & theNewVshape,TopTools_DataMapOfShapeListOfShape & theHistMap)1182 void StoreVedgeInHistMap(const Handle(TopTools_HArray1OfShape)&     theVEdges,
1183                          const Standard_Integer                     theIndex,
1184                          const TopoDS_Shape&                        theNewVshape,
1185                          TopTools_DataMapOfShapeListOfShape&        theHistMap)
1186 {
1187   //Replace default value in the map (v-iso edge of face)
1188   //by intersection of two consecutive faces
1189   const TopoDS_Shape& aVEdge = theVEdges->Value(theIndex);
1190 
1191   theHistMap.Bound(aVEdge, TopTools_ListOfShape())->Append(theNewVshape);
1192 }
1193 
1194 // ------------------------------------------------------------------------------------------
1195 // static function: FindFreeVertices
1196 // purpose:
1197 // ------------------------------------------------------------------------------------------
FindFreeVertices(const TopoDS_Shape & theShape,const TopTools_MapOfShape & theVerticesToAvoid,TopTools_ListOfShape & theListOfVertex)1198 void FindFreeVertices(const TopoDS_Shape&         theShape,
1199                       const TopTools_MapOfShape&  theVerticesToAvoid,
1200                       TopTools_ListOfShape&       theListOfVertex) {
1201 
1202   theListOfVertex.Clear();
1203   TopTools_IndexedDataMapOfShapeListOfShape aMap;
1204   TopExp::MapShapesAndAncestors(theShape, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1205   Standard_Integer i = 0;
1206 
1207   for(i = 1; i <= aMap.Extent(); i++) {
1208     const TopoDS_Shape& aKey = aMap.FindKey(i);
1209 
1210     if(theVerticesToAvoid.Contains(aKey))
1211       continue;
1212     const TopTools_ListOfShape& aList = aMap.FindFromIndex(i);
1213 
1214     if(aList.Extent() < 2) {
1215       theListOfVertex.Append(aKey);
1216     }
1217   }
1218 }
1219 
1220 // ------------------------------------------------------------------------------------------
1221 // static function: FindCommonVertex
1222 // purpose:
1223 // ------------------------------------------------------------------------------------------
FindCommonVertex(const BOPDS_PDS & theDS,const Standard_Integer theEIndex1,const Standard_Integer theEIndex2,TopoDS_Vertex & theCommonVertex,Standard_Real & theParamOnE1,Standard_Real & theParamOnE2)1224 Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
1225                                   const Standard_Integer   theEIndex1,
1226                                   const Standard_Integer   theEIndex2,
1227                                   TopoDS_Vertex&           theCommonVertex,
1228                                   Standard_Real&           theParamOnE1,
1229                                   Standard_Real&           theParamOnE2) {
1230 
1231   const BOPDS_VectorOfInterfEE& aEEs = theDS->InterfEE();
1232 
1233   Standard_Boolean bvertexfound = Standard_False;
1234   TopoDS_Vertex aCommonVertex;
1235   Standard_Integer eeit = 0;
1236 
1237   Standard_Integer aNbEEs;
1238   aNbEEs = aEEs.Length();
1239   for(eeit = 0; eeit < aNbEEs; ++eeit) {
1240     const BOPDS_InterfEE& aEE = aEEs(eeit);
1241 
1242     if((theEIndex1 == aEE.Index1() && theEIndex2 == aEE.Index2()) ||
1243        (theEIndex1 == aEE.Index2() && theEIndex2 == aEE.Index1())) {
1244 
1245       if(!aEE.HasIndexNew())
1246         continue;
1247 
1248       IntTools_CommonPrt aCP = aEE.CommonPart();
1249       if(aCP.Type() == TopAbs_VERTEX)
1250       {
1251         theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
1252 
1253         if (theEIndex1 == aEE.Index1())
1254           IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
1255         else
1256           IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
1257 
1258         //
1259         bvertexfound = Standard_True;
1260         break;
1261       }
1262     }
1263   }
1264   return bvertexfound;
1265 }
1266 
1267 // ----------------------------------------------------------------------------------------------------
1268 // static function: GetUEdges
1269 // purpose:
1270 // ----------------------------------------------------------------------------------------------------
GetUEdges(const Standard_Integer theIndex,const Standard_Integer theRank,const Handle (TopTools_HArray2OfShape)& theUEdges,const TopoDS_Edge & theBoundEdge,const TopoDS_Face & theFace,TopoDS_Edge & theFirstUEdge,TopoDS_Edge & theSecondUEdge)1271 Standard_Boolean GetUEdges(const Standard_Integer                     theIndex,
1272                            const Standard_Integer                     theRank,
1273                            const Handle(TopTools_HArray2OfShape)&     theUEdges,
1274                            const TopoDS_Edge&                         theBoundEdge,
1275                            const TopoDS_Face&                         theFace,
1276                            TopoDS_Edge&                               theFirstUEdge,
1277                            TopoDS_Edge&                               theSecondUEdge) {
1278   const TopoDS_Shape& aUE1 = theUEdges->Value(theIndex, theUEdges->LowerCol() + theRank);
1279   const TopoDS_Shape& aUE2 = theUEdges->Value(theIndex + 1, theUEdges->LowerCol() + theRank);
1280 
1281   TopoDS_Face aFace = theFace;
1282   aFace.Orientation(TopAbs_FORWARD);
1283   TopoDS_Edge E1, E2;
1284   TopExp_Explorer anExp(aFace, TopAbs_EDGE);
1285 
1286   for(; anExp.More(); anExp.Next()) {
1287     if(E1.IsNull() && aUE1.IsSame(anExp.Current())) {
1288       E1 = TopoDS::Edge(anExp.Current());
1289     }
1290     else if(E2.IsNull() && aUE2.IsSame(anExp.Current())) {
1291       E2 = TopoDS::Edge(anExp.Current());
1292     }
1293   }
1294 
1295   if(E1.IsNull() || E2.IsNull())
1296     return Standard_False;
1297 
1298   Standard_Real f, l;
1299   Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1, aFace, f, l);
1300 
1301   if(C1.IsNull())
1302      return Standard_False;
1303   gp_Pnt2d PU1 = (theRank == 0) ? C1->Value(l) : C1->Value(f);
1304   Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFace, f, l);
1305 
1306   if(C2.IsNull())
1307     return Standard_False;
1308   BRep_Tool::Range(theBoundEdge, f, l);
1309   gp_Pnt2d pf = C2->Value(f);
1310   TopoDS_Vertex aV = (theRank == 0) ? TopExp::LastVertex(E1) : TopExp::FirstVertex(E1);
1311   Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1312   BRepAdaptor_Surface aBAS(aFace, Standard_False);
1313 
1314   if(pf.Distance(PU1) > aBAS.UResolution(aTolerance)) {
1315     TopoDS_Edge atmpE = E1;
1316     E1 = E2;
1317     E2 = atmpE;
1318   }
1319   theFirstUEdge = E1;
1320   theSecondUEdge = E2;
1321   return Standard_True;
1322 }
1323 
1324 // ----------------------------------------------------------------------------------------------------
1325 // static function: FillGap
1326 // purpose:
1327 // ----------------------------------------------------------------------------------------------------
FillGap(const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,const gp_Pnt2d & theFirstPoint,const gp_Pnt2d & theLastPoint,const TopoDS_Face & theFace,const TopoDS_Compound & theSectionEdges,TopTools_ListOfShape & theOrderedList)1328 Standard_Boolean FillGap(const TopoDS_Vertex&   theFirstVertex,
1329                          const TopoDS_Vertex&   theLastVertex,
1330                          const gp_Pnt2d&        theFirstPoint,
1331                          const gp_Pnt2d&        theLastPoint,
1332                          const TopoDS_Face&     theFace,
1333                          const TopoDS_Compound& theSectionEdges,
1334                          TopTools_ListOfShape&  theOrderedList) {
1335 
1336   TopTools_IndexedDataMapOfShapeListOfShape aMap;
1337   TopExp::MapShapesAndAncestors(theSectionEdges, TopAbs_VERTEX, TopAbs_EDGE, aMap);
1338 
1339   if(aMap.IsEmpty()) {
1340     return Standard_False;
1341   }
1342 
1343   if(!aMap.Contains(theFirstVertex) ||
1344      !aMap.Contains(theLastVertex)) {
1345     return Standard_False;
1346   }
1347   TopTools_ListOfShape aListOfEdge;
1348 //  Standard_Integer i = 0;
1349 //  TopoDS_Vertex aCurVertex = theFirstVertex;
1350   TopTools_MapOfShape aMapToAvoid;
1351 
1352   if(FindNextEdge(theFirstVertex, theLastVertex, aMap, aMapToAvoid, aListOfEdge)) {
1353     if(!aListOfEdge.IsEmpty()) {
1354       return CheckAndOrientEdges(aListOfEdge, theFirstPoint, theLastPoint, theFace, theOrderedList);
1355     }
1356   }
1357   return Standard_False;
1358 }
1359 
1360 // ----------------------------------------------------------------------------------------------------
1361 // static function: FindNextEdge
1362 // purpose:
1363 // ----------------------------------------------------------------------------------------------------
FindNextEdge(const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,const TopTools_IndexedDataMapOfShapeListOfShape & theMapVE,const TopTools_MapOfShape & theMapToAvoid,TopTools_ListOfShape & theOrderedList)1364 Standard_Boolean FindNextEdge(const TopoDS_Vertex&   theFirstVertex,
1365                               const TopoDS_Vertex&   theLastVertex,
1366                               const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE,
1367                               const TopTools_MapOfShape& theMapToAvoid,
1368                               TopTools_ListOfShape&  theOrderedList) {
1369   TopoDS_Vertex aCurVertex = theFirstVertex;
1370   TopTools_MapOfShape aMapToAvoid;
1371   aMapToAvoid = theMapToAvoid;
1372   TopTools_ListOfShape aListOfEdge;
1373   Standard_Integer i = 0;
1374 
1375   for(i = 1; i <= theMapVE.Extent(); i++) {
1376     if(!theMapVE.Contains(aCurVertex))
1377       break;
1378     const TopTools_ListOfShape& lste = theMapVE.FindFromKey(aCurVertex);
1379     Standard_Boolean befound = Standard_False;
1380 
1381     TopTools_ListIteratorOfListOfShape anIt(lste);
1382 
1383     for(; anIt.More(); anIt.Next()) {
1384       TopoDS_Shape anEdge = anIt.Value();
1385       TopoDS_Vertex aSaveCurVertex = aCurVertex;
1386 
1387       if(!aMapToAvoid.Contains(anEdge)) {
1388         TopoDS_Vertex V1, V2;
1389         TopExp::Vertices(TopoDS::Edge(anEdge), V1, V2);
1390 
1391         if(!aCurVertex.IsSame(V1)) {
1392           aCurVertex = V1;
1393         }
1394         else if(!aCurVertex.IsSame(V2)) {
1395           aCurVertex = V2;
1396         }
1397         aMapToAvoid.Add(anEdge);
1398         befound = Standard_True;
1399         aListOfEdge.Append(anEdge);
1400 
1401         if(!aCurVertex.IsSame(theLastVertex)) {
1402           TopTools_ListOfShape aListtmp;
1403 
1404           if(!FindNextEdge(aCurVertex, theLastVertex, theMapVE, aMapToAvoid, aListtmp)) {
1405             aListOfEdge.Clear();
1406             aCurVertex = aSaveCurVertex;
1407             continue;
1408           }
1409           else {
1410             aListOfEdge.Append(aListtmp);
1411             theOrderedList.Append(aListOfEdge);
1412             return Standard_True;
1413           }
1414         }
1415         break;
1416       }
1417     }
1418 
1419     if(aCurVertex.IsSame(theLastVertex))
1420       break;
1421 
1422     if(!befound) {
1423       return Standard_False;
1424     }
1425   }
1426 
1427   if(aCurVertex.IsSame(theLastVertex)) {
1428     theOrderedList.Append(aListOfEdge);
1429     return Standard_True;
1430   }
1431   return Standard_False;
1432 }
1433 
1434 // ----------------------------------------------------------------------------------------------------
1435 // static function: CheckAndOrientEdges
1436 // purpose:
1437 // ----------------------------------------------------------------------------------------------------
CheckAndOrientEdges(const TopTools_ListOfShape & theOrderedList,const gp_Pnt2d & theFirstPoint,const gp_Pnt2d & theLastPoint,const TopoDS_Face & theFace,TopTools_ListOfShape & theOrientedList)1438 Standard_Boolean CheckAndOrientEdges(const TopTools_ListOfShape&  theOrderedList,
1439                                      const gp_Pnt2d&              theFirstPoint,
1440                                      const gp_Pnt2d&              theLastPoint,
1441                                      const TopoDS_Face&           theFace,
1442                                      TopTools_ListOfShape&        theOrientedList) {
1443   TopTools_ListIteratorOfListOfShape anIt(theOrderedList);
1444 
1445   if(!anIt.More())
1446     return Standard_True;
1447 
1448   Standard_Real f, l;
1449   TopoDS_Edge aEPrev = TopoDS::Edge(anIt.Value());
1450   anIt.Next();
1451 
1452   Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(aEPrev, theFace, f, l);
1453   TopoDS_Vertex Vf, Vl;
1454   TopExp::Vertices(aEPrev, Vf, Vl);
1455   BRepAdaptor_Surface aBAS(theFace, Standard_False);
1456 
1457   Standard_Real aTolerance1 = (Vf.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vf);
1458   Standard_Real aTolerance2 = (Vl.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(Vl);
1459   Standard_Real utol = aBAS.UResolution(aTolerance1);
1460   Standard_Real vtol = aBAS.VResolution(aTolerance1);
1461   aTolerance1 = (utol > vtol) ? utol : vtol;
1462   utol = aBAS.UResolution(aTolerance2);
1463   vtol = aBAS.VResolution(aTolerance2);
1464   aTolerance2 = (utol > vtol) ? utol : vtol;
1465 
1466   gp_Pnt2d ap = aCurve->Value(f);
1467   Standard_Boolean bFirstFound = Standard_False;
1468   Standard_Boolean bLastFound = Standard_False;
1469 
1470   if(ap.Distance(theFirstPoint) < aTolerance1) {
1471     if(theOrientedList.IsEmpty())
1472       theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1473     bFirstFound = Standard_True;
1474   }
1475   else if(ap.Distance(theLastPoint) < aTolerance1) {
1476     if(theOrientedList.IsEmpty())
1477       theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1478     bLastFound = Standard_True;
1479   }
1480   ap = aCurve->Value(l);
1481 
1482   if(ap.Distance(theLastPoint) < aTolerance2) {
1483     if(theOrientedList.IsEmpty())
1484       theOrientedList.Append(aEPrev.Oriented(TopAbs_FORWARD));
1485     bLastFound = Standard_True;
1486   }
1487   else if(ap.Distance(theFirstPoint) < aTolerance2) {
1488     if(theOrientedList.IsEmpty())
1489       theOrientedList.Append(aEPrev.Oriented(TopAbs_REVERSED));
1490     bFirstFound = Standard_True;
1491   }
1492 
1493   if (!theOrientedList.IsEmpty())
1494     aEPrev = TopoDS::Edge (theOrientedList.Last());
1495 
1496   for(; anIt.More(); anIt.Next()) {
1497     const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value());
1498     TopoDS_Vertex aV11, aV12;
1499     TopExp::Vertices(aEPrev, aV11, aV12, Standard_True);
1500     TopoDS_Vertex aV21, aV22;
1501     TopExp::Vertices(aE, aV21, aV22, Standard_False);
1502 
1503     TopAbs_Orientation anOri =
1504       (aV12.IsSame (aV21) || aV11.IsSame (aV22)) ? TopAbs_FORWARD : TopAbs_REVERSED;
1505     theOrientedList.Append(aE.Oriented(anOri));
1506     aEPrev = TopoDS::Edge (theOrientedList.Last());
1507 
1508     aTolerance1 = (aV21.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV21);
1509     aTolerance2 = (aV22.IsNull()) ? Precision::Confusion() : BRep_Tool::Tolerance(aV22);
1510     utol = aBAS.UResolution(aTolerance1);
1511     vtol = aBAS.VResolution(aTolerance1);
1512     aTolerance1 = (utol > vtol) ? utol : vtol;
1513     utol = aBAS.UResolution(aTolerance2);
1514     vtol = aBAS.VResolution(aTolerance2);
1515     aTolerance2 = (utol > vtol) ? utol : vtol;
1516     aCurve = BRep_Tool::CurveOnSurface(aE, theFace, f, l);
1517     ap = aCurve->Value(f);
1518 
1519     if(ap.Distance(theFirstPoint) < aTolerance1) {
1520       bFirstFound = Standard_True;
1521     }
1522     else if(ap.Distance(theLastPoint) < aTolerance1) {
1523       bLastFound = Standard_True;
1524     }
1525     ap = aCurve->Value(l);
1526 
1527     if(ap.Distance(theFirstPoint) < aTolerance2) {
1528       bFirstFound = Standard_True;
1529     }
1530     else if(ap.Distance(theLastPoint) < aTolerance2) {
1531       bLastFound = Standard_True;
1532     }
1533   }
1534 
1535   return bFirstFound && bLastFound;
1536 }
1537 
1538 // ----------------------------------------------------------------------------------------------------
1539 // static function: FindVertex
1540 // purpose:
1541 // ----------------------------------------------------------------------------------------------------
FindVertex(const TopoDS_Edge & theEdge,const Standard_Integer theRank,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopoDS_Vertex & theVertex,BOPDS_Pave & thePave)1542 Standard_Boolean FindVertex(const TopoDS_Edge&                        theEdge,
1543                             const Standard_Integer                    theRank,
1544                             const BOPDS_PDS&                          theDS,
1545                             const TopTools_DataMapOfShapeListOfShape& theHistMap,
1546                             TopoDS_Vertex&                            theVertex,
1547                             BOPDS_Pave&                               thePave) {
1548 
1549   if(!theHistMap.IsBound(theEdge))
1550     return Standard_False;
1551 
1552   const TopTools_ListOfShape& lst = theHistMap.Find(theEdge);
1553 
1554   if(lst.IsEmpty())
1555     return Standard_False;
1556 
1557   TopoDS_Edge aNewEdge = TopoDS::Edge(lst.First());
1558   Standard_Real f, l;
1559   BRep_Tool::Range(aNewEdge, f, l);
1560 
1561   if(theRank == 0) {
1562     thePave.SetParameter(l);
1563     theVertex = TopExp::LastVertex(aNewEdge);
1564   }
1565   else {
1566     thePave.SetParameter(f);
1567     theVertex = TopExp::FirstVertex(aNewEdge);
1568   }
1569   Standard_Integer anIndex = theDS->Index(theVertex);
1570   if (anIndex == -1) {
1571     Standard_Integer i, i1, i2;
1572     i1=theDS->NbSourceShapes();
1573     i2=theDS->NbShapes();
1574     for (i=i1; i<i2; ++i) {
1575       const TopoDS_Shape& aSx=theDS->Shape(i);
1576       if(aSx.IsSame(theVertex)) {
1577         anIndex = i;
1578         break;
1579       }
1580     }
1581   }
1582 
1583   thePave.SetIndex(anIndex);
1584 
1585   return Standard_True;
1586 }
1587 
1588 // ----------------------------------------------------------------------------------------------------
1589 // static function: FindNextVertex
1590 // purpose:
1591 // ----------------------------------------------------------------------------------------------------
FindNextVertex(const Standard_Integer theEdgeIndex,const BOPDS_Pave & thePrevPave,const BOPDS_PDS & theDS,TopoDS_Vertex & theNextVertex,BOPDS_Pave & thePave)1592 Standard_Boolean FindNextVertex(const Standard_Integer                    theEdgeIndex,
1593                                 const BOPDS_Pave&                         thePrevPave,
1594                                 const BOPDS_PDS&                          theDS,
1595                                 TopoDS_Vertex&                            theNextVertex,
1596                                 BOPDS_Pave&                               thePave) {
1597 
1598   Standard_Boolean bTakePave, bFound;
1599   BOPDS_Pave aTmpPave;
1600   BOPDS_ListIteratorOfListOfPave aItP;
1601   //
1602   BOPDS_Pave anullpave;
1603   bFound = Standard_False;
1604   bTakePave = thePrevPave.IsEqual(anullpave);
1605 
1606   BOPDS_ListOfPave aLP;
1607   theDS->Paves(theEdgeIndex, aLP);
1608   aItP.Initialize(aLP);
1609   for (; aItP.More(); aItP.Next()) {
1610     aTmpPave = aItP.Value();
1611     //
1612     if (bTakePave) {
1613       if (theDS->IsNewShape(aTmpPave.Index())) {
1614         theNextVertex = *(TopoDS_Vertex*)&theDS->Shape(aTmpPave.Index());
1615         thePave = aTmpPave;
1616         bFound = Standard_True;
1617         break;
1618       }
1619     }
1620     //
1621     else if (aTmpPave.IsEqual(thePrevPave)) {
1622       bTakePave = Standard_True;
1623     }
1624   }
1625 
1626   return bFound;
1627 }
1628 
1629 // ----------------------------------------------------------------------------------------------------
1630 // static function: GetPave
1631 // purpose:
1632 // ----------------------------------------------------------------------------------------------------
GetPave(const Standard_Integer theEdgeIndex,const Standard_Boolean isFirst,const BOPDS_PDS & theDS,BOPDS_Pave & thePave)1633 Standard_Boolean GetPave(const Standard_Integer    theEdgeIndex,
1634                          const Standard_Boolean    isFirst,
1635                          const BOPDS_PDS&          theDS,
1636                          BOPDS_Pave&               thePave) {
1637 
1638   Handle(BOPDS_PaveBlock) aPB;
1639   BOPDS_ListOfPave aLP;
1640 
1641   theDS->Paves(theEdgeIndex, aLP);
1642   if (!aLP.Extent()) {
1643     return Standard_False;
1644   }
1645   //
1646   if (isFirst) {
1647     thePave = aLP.First();
1648   }
1649   else {
1650     thePave = aLP.Last();
1651   }
1652 
1653   return Standard_True;
1654 }
1655 
1656 // ----------------------------------------------------------------------------------------------------
1657 // static function: FindFromUEdge
1658 // purpose:
1659 // ----------------------------------------------------------------------------------------------------
FindFromUEdge(const TopoDS_Edge & theUE1Old,const TopoDS_Edge & theUE2Old,const TopoDS_Edge & theUE1New,const TopoDS_Edge & theUE2New,const TopoDS_Face & theFace,const TopoDS_Compound & theSecEdges,const Standard_Integer theRank,const TopoDS_Edge & theBoundEdge,const Standard_Integer theBoundEdgeIndex,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopoDS_Compound & theSecEdgesNew,TopTools_ListOfShape & theListOfWireEdges,BOPDS_Pave & theFoundPave,Standard_Boolean & isOnUEdge)1660 Standard_Boolean FindFromUEdge(const TopoDS_Edge&                        theUE1Old,
1661                                const TopoDS_Edge&                        theUE2Old,
1662                                const TopoDS_Edge&                        theUE1New,
1663                                const TopoDS_Edge&                        theUE2New,
1664                                const TopoDS_Face&                        theFace,
1665                                const TopoDS_Compound&                    theSecEdges,
1666                                const Standard_Integer                    theRank,
1667                                const TopoDS_Edge&                        theBoundEdge,
1668                                const Standard_Integer                    theBoundEdgeIndex,
1669                                const BOPDS_PDS&                          theDS,
1670                                const TopTools_DataMapOfShapeListOfShape& theHistMap,
1671                                TopoDS_Compound&                          theSecEdgesNew,
1672                                TopTools_ListOfShape&                     theListOfWireEdges,
1673                                BOPDS_Pave&                               theFoundPave,
1674                                Standard_Boolean&                         isOnUEdge) {
1675   theFoundPave.SetIndex(0);
1676   theFoundPave.SetParameter(0.);
1677   isOnUEdge = Standard_True;
1678 
1679   TopoDS_Face aFaceF = theFace;
1680   aFaceF.Orientation(TopAbs_FORWARD);
1681   TopoDS_Vertex aPrevVertex, aNextVertex;
1682   TopoDS_Compound aCompOfSecEdges = theSecEdges;
1683   TopTools_ListOfShape aListOfWireEdges;
1684 //  BRep_Builder aBB;
1685 
1686   BOPDS_Pave aPave1, aPave2;
1687   Standard_Real f = 0., l = 0.;
1688   gp_Pnt2d p1, p2;
1689   TopoDS_Vertex aFirstV, aLastV;
1690   BOPDS_Pave atmpPave;
1691 
1692   if(!FindVertex(theUE1Old, theRank, theDS, theHistMap, aPrevVertex, atmpPave)) {
1693     return Standard_True;
1694   }
1695 
1696   if(aPrevVertex.IsNull()) {
1697     return Standard_False;
1698   }
1699 
1700   aFirstV = aPrevVertex;
1701   Standard_Boolean bSecFound = Standard_False;
1702   Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1New, aFaceF, f, l);
1703   p1 = (theRank == 0) ? aC1->Value(l) : aC1->Value(f);
1704   BOPDS_Pave afoundpave;
1705   BOPDS_ListOfPave aLP;
1706   theDS->Paves(theBoundEdgeIndex, aLP);
1707   Standard_Integer nbpave = aLP.Extent();
1708   Standard_Integer pit = 0;
1709 
1710   while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1711     aLastV = aNextVertex;
1712     Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1713     p2 = aC2->Value(aPave2.Parameter());
1714     TopTools_ListOfShape aOrderedList;
1715 
1716     if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1717       // remove found edges...
1718       TopoDS_Compound aComp;
1719       RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1720       aCompOfSecEdges = aComp;
1721       aListOfWireEdges.Append(aOrderedList);
1722       afoundpave = aPave2;
1723       isOnUEdge = Standard_False;
1724       bSecFound = Standard_True;
1725       break;
1726     }
1727     aPrevVertex = aNextVertex;
1728     aPave1 = aPave2;
1729     pit++;
1730   }
1731 
1732   if(!bSecFound && FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1733     aLastV = aNextVertex;
1734     Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theUE2New, aFaceF, f, l);
1735     p2 = aC2->Value(aPave2.Parameter());
1736     TopTools_ListOfShape aOrderedList;
1737 
1738     if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1739       // remove found edges...
1740       TopoDS_Compound aComp;
1741 
1742       RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1743       aCompOfSecEdges = aComp;
1744       aListOfWireEdges.Append(aOrderedList);
1745       afoundpave = aPave2;
1746       bSecFound = Standard_True;
1747       isOnUEdge = Standard_True;
1748     }
1749   }
1750 
1751   if(bSecFound) {
1752     theFoundPave = afoundpave;
1753     theListOfWireEdges = aListOfWireEdges;
1754     theSecEdgesNew = aCompOfSecEdges;
1755   }
1756   return Standard_True;
1757 }
1758 
1759 
1760 // ----------------------------------------------------------------------------------------------------
1761 // static function: FindFromVEdge
1762 // purpose:
1763 // ----------------------------------------------------------------------------------------------------
FindFromVEdge(const BOPDS_Pave & thePrevPave,const Standard_Boolean & isOnUEdge,const TopoDS_Edge & theUE1Old,const TopoDS_Edge & theUE2Old,const TopoDS_Face & theFace,const TopoDS_Compound & theSecEdges,const Standard_Integer theRank,const TopoDS_Edge & theBoundEdge,const Standard_Integer theBoundEdgeIndex,const BOPDS_PDS & theDS,const TopTools_DataMapOfShapeListOfShape & theHistMap,TopTools_ListOfShape & theListOfWireEdges,Standard_Boolean & isSectionFound)1764 Standard_Boolean FindFromVEdge(const BOPDS_Pave&                         thePrevPave,
1765                                const Standard_Boolean&                   isOnUEdge,
1766                                const TopoDS_Edge&                        theUE1Old,
1767                                const TopoDS_Edge&                        theUE2Old,
1768                                const TopoDS_Face&                        theFace,
1769                                const TopoDS_Compound&                    theSecEdges,
1770                                const Standard_Integer                    theRank,
1771                                const TopoDS_Edge&                        theBoundEdge,
1772                                const Standard_Integer                    theBoundEdgeIndex,
1773                                const BOPDS_PDS&                          theDS,
1774                                const TopTools_DataMapOfShapeListOfShape& theHistMap,
1775                                TopTools_ListOfShape&                     theListOfWireEdges,
1776                                Standard_Boolean&                         isSectionFound) {
1777 
1778   theListOfWireEdges.Clear();
1779   isSectionFound = Standard_False;
1780   //
1781   TopoDS_Face aFaceF = theFace;
1782   aFaceF.Orientation(TopAbs_FORWARD);
1783   TopoDS_Vertex aPrevVertex, aNextVertex;
1784   TopoDS_Compound aCompOfSecEdges = theSecEdges;
1785   TopTools_ListOfShape aListOfWireEdges;
1786 //  BRep_Builder aBB;
1787 
1788   BOPDS_Pave aPave1, aPave2;
1789 
1790   if(isOnUEdge) {
1791     TopoDS_Vertex atmpVertex;
1792     BOPDS_Pave aPaveOfE2;
1793 
1794     if(FindVertex(theUE2Old, theRank, theDS, theHistMap, atmpVertex, aPaveOfE2)) {
1795       if(thePrevPave.IsEqual(aPaveOfE2))
1796         return Standard_True;
1797     }
1798   }
1799 
1800   Standard_Real f = 0., l = 0.;
1801   gp_Pnt2d p1(0., 0.), p2(0., 0.);
1802   TopoDS_Vertex aFirstV, aLastV;
1803   Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(theUE1Old, aFaceF, f, l);
1804   Handle(Geom2d_Curve) aC2 = BRep_Tool::CurveOnSurface(theBoundEdge, aFaceF, f, l);
1805   Standard_Boolean bSecFound = Standard_False;
1806 
1807   aPave1 = thePrevPave;
1808 
1809   if(isOnUEdge) {
1810     BOPDS_Pave atmpPave;
1811 
1812     if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1813       return Standard_False;
1814     }
1815     aPave1 = atmpPave;
1816   }
1817   p1 = aC2->Value(aPave1.Parameter());
1818   aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1819 
1820   BOPDS_ListOfPave aLP;
1821   theDS->Paves(theBoundEdgeIndex, aLP);
1822   Standard_Integer nbpave = aLP.Extent();
1823   Standard_Integer pit = 0;
1824   TopTools_Array1OfListOfShape anArrayOfListOfSec(1, nbpave);
1825 
1826   // by pairs non continuously. begin
1827   Standard_Integer k = 0;
1828   BOPDS_Pave aFirstPave = aPave1;
1829   TopoDS_Vertex aFirstVertex = aPrevVertex;
1830   gp_Pnt2d apfirst = p1;
1831   BOPDS_ListOfPave aFirstPaves, aLastPaves;
1832   TColStd_ListOfInteger aListOfFlags;
1833   Standard_Integer apaircounter = 1;
1834 
1835   for(k = 0; k < nbpave; k++) {
1836     aPave1 = aFirstPave;
1837     p1 = apfirst;
1838     aPrevVertex = aFirstVertex;
1839     Standard_Boolean bfound = Standard_False;
1840     pit = 0;
1841 
1842     while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1843       aFirstV = aPrevVertex;
1844       aLastV = aNextVertex;
1845       p2 = aC2->Value(aPave2.Parameter());
1846 
1847       TopTools_ListOfShape aOrderedList;
1848 
1849       if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1850         TopoDS_Compound aComp;
1851         RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1852         aCompOfSecEdges = aComp;
1853 
1854         anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1855         aFirstPaves.Append(aFirstPave);
1856         aLastPaves.Append(aPave2);
1857         aListOfFlags.Append(1);
1858         aFirstPave = aPave2;
1859         aFirstVertex = aNextVertex;
1860         apfirst = p2;
1861         aPrevVertex = aNextVertex;
1862         bSecFound = Standard_True;
1863         bfound = Standard_True;
1864       }
1865       aPave1 = aPave2;
1866       pit++;
1867     }
1868 
1869     if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
1870       aFirstV = aPrevVertex;
1871       aLastV = aNextVertex;
1872       Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1873       p2 = aC3->Value(aPave2.Parameter());
1874 
1875       TopTools_ListOfShape aOrderedList;
1876 
1877       if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1878         TopoDS_Compound aComp;
1879         RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1880         aCompOfSecEdges = aComp;
1881         anArrayOfListOfSec(apaircounter++).Append(aOrderedList);
1882         aFirstPaves.Append(aFirstPave);
1883         aLastPaves.Append(aPave2);
1884         aListOfFlags.Append(0);
1885         bSecFound = Standard_True;
1886         break;
1887       }
1888     }
1889 
1890     if(!bfound) {
1891       if(!FindNextVertex(theBoundEdgeIndex, aFirstPave, theDS, aNextVertex, aPave2)) {
1892         break;
1893       }
1894       aFirstPave = aPave2;
1895       apfirst = aC2->Value(aPave2.Parameter());
1896       aFirstVertex = aNextVertex;
1897     }
1898   }
1899   // by pairs non continuously. end
1900 
1901   // by pairs continuously. begin
1902   aPave1 = thePrevPave;
1903 
1904   if(isOnUEdge) {
1905     BOPDS_Pave atmpPave;
1906 
1907     if(!GetPave(theBoundEdgeIndex, Standard_True, theDS, atmpPave)) {
1908       return Standard_False;
1909     }
1910     aPave1 = atmpPave;
1911   }
1912   p1 = aC2->Value(aPave1.Parameter());
1913   aPrevVertex = TopoDS::Vertex(theDS->Shape(aPave1.Index()));
1914 
1915   pit = 0;
1916 
1917   while(FindNextVertex(theBoundEdgeIndex, aPave1, theDS, aNextVertex, aPave2) && (pit < nbpave)) {
1918     aFirstV = aPrevVertex;
1919     aLastV = aNextVertex;
1920     p2 = aC2->Value(aPave2.Parameter());
1921 
1922     Standard_Boolean bisinside = Standard_False;
1923     Standard_Integer apbindex = 0;
1924     Standard_Integer apbcounter = 1;
1925     BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1926     BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
1927     TColStd_ListIteratorOfListOfInteger aFlagIt;
1928 
1929     for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
1930         aPIt1.More() && aPIt2.More() && aFlagIt.More();
1931         aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
1932 
1933       Standard_Boolean bfin = Standard_False;
1934       Standard_Boolean blin = Standard_False;
1935 
1936       if(aPave1.IsEqual(aPIt1.Value())) {
1937         bfin = Standard_True;
1938       }
1939       else {
1940         bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
1941       }
1942 
1943       if(aFlagIt.Value()) {
1944         if(aPave2.IsEqual(aPIt2.Value())) {
1945           blin = Standard_True;
1946         }
1947         else {
1948           blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
1949         }
1950       }
1951       else {
1952         if((aPave2.Index() == aPIt2.Value().Index()) && (aPave2.Index() > 0)) {
1953           Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
1954           gp_Pnt2d p3 = pc->Value(aPIt2.Value().Parameter());
1955           TopoDS_Vertex aV = TopoDS::Vertex(theDS->Shape(aPave2.Index()));
1956           BRepAdaptor_Surface aBAS(aFaceF, Standard_False);
1957           Standard_Real aTolerance = BRep_Tool::Tolerance(aV);
1958           Standard_Real utol = aBAS.UResolution(aTolerance);
1959           Standard_Real vtol = aBAS.VResolution(aTolerance);
1960           aTolerance = (utol > vtol) ? utol : vtol;
1961 
1962           if(p2.Distance(p3) < aTolerance)
1963             blin = Standard_True;
1964         }
1965       }
1966 
1967       if(bfin && blin) {
1968         apbindex = apbcounter;
1969         bisinside = Standard_True;
1970         break;
1971       }
1972     }
1973 
1974     if(!bisinside) {
1975 
1976       TopTools_ListOfShape aOrderedList;
1977 
1978       if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
1979         TopoDS_Compound aComp;
1980         RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
1981         aCompOfSecEdges = aComp;
1982         aListOfWireEdges.Append(aOrderedList);
1983 
1984         bSecFound = Standard_True;
1985       }
1986       else {
1987         TopoDS_Edge aESplit;
1988         // get split
1989         aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
1990 
1991         for(; aPBIt.More(); aPBIt.Next()) {
1992           const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
1993           if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
1994               aPB1->Pave1().IsEqual(aPave1) &&
1995               aPB1->Pave2().IsEqual(aPave2) ) {
1996             if(aPB1->Edge() > 0) {
1997               aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
1998               break;
1999             }
2000           }
2001         }
2002 
2003         if(!aESplit.IsNull()) {
2004           aListOfWireEdges.Append(aESplit);
2005         }
2006       }
2007     }
2008     else {
2009       if(apbindex > 0) {
2010         TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2011         aListOfWireEdges.Append(aListOfSec);
2012       }
2013     }
2014     aPave1 = aPave2;
2015     aPrevVertex = aNextVertex;
2016     p1 = p2;
2017     pit++;
2018   }
2019 
2020   if(FindVertex(theUE2Old, theRank, theDS, theHistMap, aNextVertex, aPave2)) {
2021     aFirstV = aPrevVertex;
2022     aLastV = aNextVertex;
2023     Handle(Geom2d_Curve) aC3 = BRep_Tool::CurveOnSurface(theUE2Old, aFaceF, f, l);
2024     p2 = aC3->Value(aPave2.Parameter());
2025 
2026     Standard_Boolean bisinside = Standard_False;
2027     Standard_Integer apbindex = 0;
2028     Standard_Integer apbcounter = 1;
2029     BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2030     BOPDS_ListIteratorOfListOfPave aPIt1, aPIt2;
2031     TColStd_ListIteratorOfListOfInteger aFlagIt;
2032 
2033     for(aPIt1.Initialize(aFirstPaves), aPIt2.Initialize(aLastPaves), aFlagIt.Initialize(aListOfFlags);
2034         aPIt1.More() && aPIt2.More() && aFlagIt.More();
2035         aPIt1.Next(), aPIt2.Next(), aFlagIt.Next(), apbcounter++) {
2036 
2037       Standard_Boolean bfin = Standard_False;
2038       Standard_Boolean blin = Standard_False;
2039 
2040       if(aPave1.IsEqual(aPIt1.Value())) {
2041         bfin = Standard_True;
2042       }
2043       else {
2044         bfin = (aPave1.Parameter() > aPIt1.Value().Parameter());
2045       }
2046 
2047       if(aFlagIt.Value()) {
2048         if(aPave2.IsEqual(aPIt2.Value())) {
2049           blin = Standard_True;
2050         }
2051         else {
2052           blin = (aPave2.Parameter() < aPIt2.Value().Parameter());
2053         }
2054       }
2055       else {
2056         blin = Standard_True;
2057       }
2058 
2059       if(bfin && blin) {
2060         apbindex = apbcounter;
2061         bisinside = Standard_True;
2062         break;
2063       }
2064     }
2065 
2066     if(!bisinside) {
2067 
2068       TopTools_ListOfShape aOrderedList;
2069 
2070       if(FillGap(aFirstV, aLastV, p1, p2, aFaceF, aCompOfSecEdges, aOrderedList)) {
2071         TopoDS_Compound aComp;
2072         RemoveEdges(aCompOfSecEdges, aOrderedList, aComp);
2073         aCompOfSecEdges = aComp;
2074         aListOfWireEdges.Append(aOrderedList);
2075 
2076         bSecFound = Standard_True;
2077       }
2078       else {
2079         //add split
2080         TopoDS_Edge aESplit;
2081         // get split
2082         if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2083           return Standard_False;
2084         //
2085         aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2086         for(; aPBIt.More(); aPBIt.Next()) {
2087           const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2088           if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2089               aPB1->Pave1().IsEqual(aPave1) &&
2090               aPB1->Pave2().IsEqual(aPave2) ) {
2091             if(aPB1->Edge() > 0) {
2092               aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2093               break;
2094             }
2095           }
2096         }
2097 
2098         if(!aESplit.IsNull()) {
2099           aListOfWireEdges.Append(aESplit);
2100         }
2101       }
2102     }
2103     else {
2104       if(apbindex > 0) {
2105         TopTools_ListOfShape& aListOfSec = anArrayOfListOfSec(apbindex);
2106         aListOfWireEdges.Append(aListOfSec);
2107       }
2108     }
2109   }
2110   else {
2111     //add split
2112     TopoDS_Edge aESplit;
2113     // get split
2114     if(!GetPave(theBoundEdgeIndex, Standard_False, theDS, aPave2))
2115       return Standard_False;
2116 
2117     BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2118     aPBIt.Initialize(theDS->PaveBlocks(theBoundEdgeIndex));
2119     for(; aPBIt.More(); aPBIt.Next()) {
2120       const Handle(BOPDS_PaveBlock)& aPB1 = aPBIt.Value();
2121       if (aPB1->OriginalEdge() == theBoundEdgeIndex &&
2122           aPB1->Pave1().IsEqual(aPave1) &&
2123           aPB1->Pave2().IsEqual(aPave2) ) {
2124         if(aPB1->Edge() > 0) {
2125           aESplit = *(TopoDS_Edge*)&theDS->Shape(aPB1->Edge());
2126           break;
2127         }
2128       }
2129     }
2130 
2131     if(!aESplit.IsNull()) {
2132       aListOfWireEdges.Append(aESplit);
2133     }
2134   }
2135 
2136   // by pairs continuously. end
2137   theListOfWireEdges = aListOfWireEdges;
2138   isSectionFound = bSecFound;
2139   return Standard_True;
2140 }
2141 
2142 // ----------------------------------------------------------------------------------------------------
2143 // static function: RemoveEdges
2144 // purpose:
2145 // ----------------------------------------------------------------------------------------------------
RemoveEdges(const TopoDS_Compound & theSourceComp,const TopTools_ListOfShape & theListToRemove,TopoDS_Compound & theResultComp)2146 void RemoveEdges(const TopoDS_Compound&      theSourceComp,
2147                  const TopTools_ListOfShape& theListToRemove,
2148                  TopoDS_Compound&            theResultComp) {
2149   BRep_Builder aBB;
2150   TopoDS_Compound aComp;
2151   aBB.MakeCompound(aComp);
2152   TopExp_Explorer anExp(theSourceComp, TopAbs_EDGE);
2153 
2154   for(; anExp.More(); anExp.Next()) {
2155     Standard_Boolean bfound = Standard_False;
2156     TopTools_ListIteratorOfListOfShape anIt(theListToRemove);
2157 
2158     for(; !bfound && anIt.More(); anIt.Next()) {
2159       bfound = anExp.Current().IsSame(anIt.Value());
2160     }
2161 
2162     if(!bfound) {
2163       aBB.Add(aComp, anExp.Current());
2164     }
2165   }
2166   theResultComp = aComp;
2167 }
2168 
2169 // ----------------------------------------------------------------------------------------------------
2170 // static function: FilterSectionEdges
2171 // purpose:
2172 // ----------------------------------------------------------------------------------------------------
FilterSectionEdges(const BOPDS_VectorOfCurve & theBCurves,const TopoDS_Face & theSecPlane,const BOPDS_PDS & theDS,TopoDS_Compound & theResult)2173 Standard_Boolean FilterSectionEdges(const BOPDS_VectorOfCurve&       theBCurves,
2174                                     const TopoDS_Face&               theSecPlane,
2175                                     const BOPDS_PDS&                 theDS,
2176                                     TopoDS_Compound&                 theResult) {
2177 
2178   theResult.Nullify();
2179 
2180   BRep_Builder aBB;
2181   aBB.MakeCompound(theResult);
2182   Standard_Integer aNbCurves = theBCurves.Length();
2183   Standard_Integer cit = 0;
2184   BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
2185 
2186   for(cit = 0; cit < aNbCurves; ++cit) {
2187     const BOPDS_Curve& aBCurve = theBCurves(cit);
2188     const BOPDS_ListOfPaveBlock& aSectEdges = aBCurve.PaveBlocks();
2189 
2190     aPBIt.Initialize(aSectEdges);
2191     for (; aPBIt.More(); aPBIt.Next()) {
2192       const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
2193       Standard_Integer nSect = aPB->Edge();
2194       const TopoDS_Shape& aS = theDS->Shape(nSect);
2195       TopoDS_Edge anEdge = TopoDS::Edge(aS);
2196       Standard_Boolean bAddEdge = Standard_True;
2197 
2198       if(!theSecPlane.IsNull()) {
2199         IntTools_BeanFaceIntersector anIntersector(anEdge, theSecPlane);
2200         Standard_Real f = 0., l = 0.;
2201         BRep_Tool::Range(anEdge, f, l);
2202         anIntersector.SetBeanParameters(f, l);
2203         //
2204         Handle(IntTools_Context) aContext = new IntTools_Context;
2205         anIntersector.SetContext(aContext);
2206         //
2207         anIntersector.Perform();
2208 
2209         if(anIntersector.IsDone()) {
2210           bAddEdge = Standard_False;
2211           Standard_Integer r = 0;
2212 
2213           for(r = 1; r <= anIntersector.Result().Length(); r++) {
2214             const IntTools_Range& aRange = anIntersector.Result().Value(r);
2215 
2216             if(((aRange.First() - f) < Precision::PConfusion()) &&
2217                ((l - aRange.Last()) < Precision::PConfusion())) {
2218               bAddEdge = Standard_True;
2219               break;
2220             }//if(((aRange.First() - f) < Precision::PConfusion()) &&
2221           }//for(r = 1; r <= anIntersector.Result().Length(); r++) {
2222         }//if(anIntersector.IsDone()) {
2223       }//if(!theSecPlane.IsNull()) {
2224 
2225       if(bAddEdge) {
2226         aBB.Add(theResult, aS);
2227       }
2228     }//for (; aPBIt.More(); aPBIt.Next()) {
2229   }//for(cit = 0; cit < aNbCurves; ++cit) {
2230 
2231   return Standard_True;
2232 }
2233 
2234 
2235 //=======================================================================
2236 //function : ComputeAveragePlaneAndMaxDeviation
2237 //purpose  :
2238 //=======================================================================
ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape & aWire,gp_Pln & thePlane,Standard_Boolean & IsSingular)2239 static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWire,
2240                                                         gp_Pln& thePlane,
2241                                                         Standard_Boolean& IsSingular)
2242 {
2243   Standard_Integer N = 40;
2244   Standard_Integer nedges = aWire.NbChildren();
2245 
2246   TColgp_Array1OfPnt Pnts( 1, nedges*N );
2247   Standard_Integer ind = 1, i;
2248   for (TopoDS_Iterator iter (aWire); iter.More(); iter.Next())
2249     {
2250       const TopoDS_Edge& anEdge = TopoDS::Edge( iter.Value() );
2251       BRepAdaptor_Curve aCurve(anEdge);
2252       GCPnts_UniformAbscissa Distribution( aCurve, N+1 );
2253       for (i = 1; i <= N; i++)
2254         {
2255           Standard_Real par = Distribution.Parameter(i);
2256           Pnts( ind++ ) = aCurve.Value(par);
2257         }
2258     }
2259 
2260   gp_Ax2 Axe;
2261   GeomLib::AxeOfInertia( Pnts, Axe, IsSingular );
2262   if (IsSingular)
2263     return -1;
2264 
2265   thePlane = gp_Pln( Axe );
2266   Standard_Real MaxDeviation = 0;
2267   for (i = 1; i <= Pnts.Length(); i++)
2268     {
2269       Standard_Real dist = thePlane.Distance( Pnts(i) );
2270       if (dist > MaxDeviation)
2271         MaxDeviation = dist;
2272     }
2273   return MaxDeviation;
2274 }
2275 
2276 
UpdateSectionEdge(TopoDS_Edge & theEdge,const TopoDS_Vertex & theConstVertex,TopoDS_Vertex & theVertex,const Standard_Real theParam)2277 static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
2278                               const TopoDS_Vertex& theConstVertex,
2279                               TopoDS_Vertex&       theVertex,
2280                               const Standard_Real  theParam)
2281 {
2282   TopoDS_Edge F_Edge = theEdge;
2283   F_Edge.Orientation(TopAbs_FORWARD);
2284 
2285   TopAbs_Orientation OrOfVertex;
2286   TopoDS_Vertex V1, V2, AnotherVertex;
2287   TopExp::Vertices(F_Edge, V1, V2);
2288   if (theConstVertex.IsSame(V1))
2289   {
2290     //OrOfConst = TopAbs_FORWARD;
2291     OrOfVertex = TopAbs_REVERSED;
2292     AnotherVertex = V2;
2293   }
2294   else
2295   {
2296     //OrOfConst = TopAbs_REVERSED;
2297     OrOfVertex = TopAbs_FORWARD;
2298     AnotherVertex = V1;
2299   }
2300 
2301   BRep_Builder BB;
2302   Standard_Real fpar, lpar;
2303   BRep_Tool::Range(F_Edge, fpar, lpar);
2304   if (OrOfVertex == TopAbs_FORWARD)
2305     fpar = theParam;
2306   else
2307     lpar = theParam;
2308   BB.Range(F_Edge, fpar, lpar);
2309 
2310   F_Edge.Free(Standard_True);
2311   BB.Remove(F_Edge, AnotherVertex);
2312   theVertex.Orientation(OrOfVertex);
2313   BB.Add(F_Edge, theVertex);
2314 }
2315 
2316 //Finds the edge connected to <theVertex> in the compound <theComp>
2317 //that is closest to bisector plane angularly.
2318 //Removes found edge from <theComp>
2319 //<theAxis> is the axis of bisector plane
FindEdgeCloseToBisectorPlane(const TopoDS_Vertex & theVertex,TopoDS_Compound & theComp,const gp_Ax1 & theAxis)2320 static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
2321                                                 TopoDS_Compound&     theComp,
2322                                                 const gp_Ax1&        theAxis)
2323 {
2324   TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2325   TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2326 
2327   TopoDS_Edge MinEdge;
2328   if (!VEmap.Contains(theVertex))
2329     return MinEdge;
2330 
2331   BRep_Builder BB;
2332 
2333   const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
2334   if (Edges.Extent() == 1)
2335     MinEdge = TopoDS::Edge(Edges.First());
2336   else
2337   {
2338     TopTools_ListIteratorOfListOfShape itl(Edges);
2339     Standard_Real MinAngle = RealLast();
2340     for (; itl.More(); itl.Next())
2341     {
2342       const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2343       TopoDS_Wire aWire;
2344       BB.MakeWire(aWire);
2345       BB.Add(aWire, anEdge);
2346       gp_Pln aPln;
2347       Standard_Boolean issing;
2348       ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
2349       Standard_Real anAngle;
2350       if (issing) //edge is a segment of line
2351       {
2352         //<anAngle> is angle between <anEdge> and its projection on bisector plane
2353         BRepAdaptor_Curve BAcurve(anEdge);
2354         gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
2355         gp_Pnt LastPnt  = BAcurve.Value(BAcurve.LastParameter());
2356         gp_Vec EdgeVec(FirstPnt, LastPnt);
2357         gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
2358         anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
2359         if (anAngle > M_PI/2)
2360           anAngle = M_PI - anAngle;
2361         anAngle = M_PI/2 - anAngle;
2362       }
2363       else
2364       {
2365         anAngle = aPln.Axis().Angle( theAxis );
2366         if (anAngle > M_PI/2)
2367           anAngle = M_PI - anAngle;
2368       }
2369 
2370       if (anAngle < MinAngle)
2371       {
2372         MinAngle = anAngle;
2373         MinEdge  = anEdge;
2374       }
2375     }
2376   } //else (more than one edge)
2377 
2378   BB.Remove(theComp, MinEdge);
2379   return MinEdge;
2380 }
2381 
FindMiddleEdges(const TopoDS_Vertex & theVertex1,const TopoDS_Vertex & theVertex2,const gp_Ax1 & theAxis,TopoDS_Compound & theComp,TopTools_ListOfShape & theElist)2382 static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
2383                                         const TopoDS_Vertex&  theVertex2,
2384                                         const gp_Ax1&         theAxis,
2385                                         TopoDS_Compound&      theComp,
2386                                         TopTools_ListOfShape& theElist)
2387 {
2388   TopTools_IndexedDataMapOfShapeListOfShape VEmap;
2389   TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
2390   if (VEmap.IsEmpty())
2391     return Standard_False;
2392 
2393   if (!VEmap.Contains(theVertex1) ||
2394       !VEmap.Contains(theVertex2))
2395     return Standard_False;
2396 
2397   TopoDS_Vertex CurVertex = theVertex1;
2398   for (;;)
2399   {
2400     TopoDS_Edge CurEdge;
2401 
2402     CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
2403     if (CurEdge.IsNull())
2404       return Standard_False;
2405 
2406     TopoDS_Vertex V1, V2;
2407     TopExp::Vertices(CurEdge, V1, V2);
2408     CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2409 
2410     theElist.Append(CurEdge);
2411     if (CurVertex.IsSame(theVertex2))
2412       return Standard_True;
2413   }
2414 }
2415 
FindCommonVertex(const TopoDS_Edge & theFirstEdge,const TopoDS_Edge & theLastEdge,const TopoDS_Vertex & theFirstVertex,const TopoDS_Vertex & theLastVertex,TopoDS_Vertex & theCommonVertex)2416 static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
2417                                          const TopoDS_Edge&   theLastEdge,
2418                                          const TopoDS_Vertex& theFirstVertex,
2419                                          const TopoDS_Vertex& theLastVertex,
2420                                          TopoDS_Vertex&       theCommonVertex)
2421 {
2422   if (!theFirstVertex.IsSame(theLastVertex))
2423   {
2424     Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
2425                                                                theLastEdge,
2426                                                                theCommonVertex);
2427     return CommonVertexExists;
2428   }
2429 
2430   TopoDS_Vertex V1, V2, V3, V4;
2431   TopExp::Vertices(theFirstEdge, V1, V2);
2432   TopExp::Vertices(theLastEdge, V3, V4);
2433 
2434   if (V1.IsSame(theFirstVertex))
2435   {
2436     if (V2.IsSame(V3) ||
2437         V2.IsSame(V4))
2438     {
2439       theCommonVertex = V2;
2440       return Standard_True;
2441     }
2442   }
2443   else
2444   {
2445     if (V1.IsSame(V3) ||
2446         V1.IsSame(V4))
2447     {
2448       theCommonVertex = V1;
2449       return Standard_True;
2450     }
2451   }
2452 
2453   return Standard_False;
2454 }
2455