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