1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14 
15 
16 #include <Bnd_Box.hxx>
17 #include <BOPDS_CommonBlock.hxx>
18 #include <BOPDS_DS.hxx>
19 #include <BOPDS_FaceInfo.hxx>
20 #include <BOPDS_IndexRange.hxx>
21 #include <BOPDS_MapOfPave.hxx>
22 #include <BOPDS_MapOfPaveBlock.hxx>
23 #include <BOPDS_Pair.hxx>
24 #include <BOPDS_PaveBlock.hxx>
25 #include <BOPDS_ShapeInfo.hxx>
26 #include <BOPDS_VectorOfPave.hxx>
27 #include <BOPTools_AlgoTools.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRep_TEdge.hxx>
31 #include <BRep_TFace.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_TVertex.hxx>
34 #include <BRepBndLib.hxx>
35 #include <Geom_Curve.hxx>
36 #include <GeomAPI_ProjectPointOnCurve.hxx>
37 #include <gp_Pnt.hxx>
38 #include <IntTools_Tools.hxx>
39 #include <NCollection_BaseAllocator.hxx>
40 #include <Precision.hxx>
41 #include <Standard_Assert.hxx>
42 #include <TopoDS.hxx>
43 #include <TopoDS_Edge.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Iterator.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopoDS_Vertex.hxx>
48 #include <TColStd_DataMapOfIntegerListOfInteger.hxx>
49 #include <TColStd_ListOfInteger.hxx>
50 #include <TColStd_MapOfInteger.hxx>
51 #include <TopTools_DataMapOfShapeInteger.hxx>
52 #include <TopTools_MapOfShape.hxx>
53 #include <algorithm>
54 //
55 
56 static
57   void TotalShapes(const TopoDS_Shape& aS,
58                    Standard_Integer& aNbS,
59                    TopTools_MapOfShape& aMS);
60 
61 static
62   Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
63                                  const TopoDS_Edge& aE);
64 
65 //=======================================================================
66 //function :
67 //purpose  :
68 //=======================================================================
BOPDS_DS()69 BOPDS_DS::BOPDS_DS()
70 :
71   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
72   myArguments(myAllocator),
73   myRanges(0,myAllocator),
74   myLines(0, myAllocator),
75   myMapShapeIndex(100, myAllocator),
76   myPaveBlocksPool(0,myAllocator),
77   myMapPBCB(100, myAllocator),
78   myFaceInfoPool(0, myAllocator),
79   myShapesSD(100, myAllocator),
80   myMapVE(100, myAllocator),
81   myInterfTB(100, myAllocator),
82   myInterfVV(0, myAllocator),
83   myInterfVE(0, myAllocator),
84   myInterfVF(0, myAllocator),
85   myInterfEE(0, myAllocator),
86   myInterfEF(0, myAllocator),
87   myInterfFF(0, myAllocator),
88   myInterfVZ(0, myAllocator),
89   myInterfEZ(0, myAllocator),
90   myInterfFZ(0, myAllocator),
91   myInterfZZ(0, myAllocator),
92   myInterfered(100, myAllocator)
93 {
94   myNbShapes=0;
95   myNbSourceShapes=0;
96 }
97 //=======================================================================
98 //function :
99 //purpose  :
100 //=======================================================================
BOPDS_DS(const Handle (NCollection_BaseAllocator)& theAllocator)101 BOPDS_DS::BOPDS_DS(const Handle(NCollection_BaseAllocator)& theAllocator)
102 :
103   myAllocator(theAllocator),
104   myArguments(myAllocator),
105   myRanges(0, myAllocator),
106   myLines(0, myAllocator),
107   myMapShapeIndex(100, myAllocator),
108   myPaveBlocksPool(0, myAllocator),
109   myMapPBCB(100, myAllocator),
110   myFaceInfoPool(0, myAllocator),
111   myShapesSD(100, myAllocator),
112   myMapVE(100, myAllocator),
113   myInterfTB(100, myAllocator),
114   myInterfVV(0, myAllocator),
115   myInterfVE(0, myAllocator),
116   myInterfVF(0, myAllocator),
117   myInterfEE(0, myAllocator),
118   myInterfEF(0, myAllocator),
119   myInterfFF(0, myAllocator),
120   myInterfVZ(0, myAllocator),
121   myInterfEZ(0, myAllocator),
122   myInterfFZ(0, myAllocator),
123   myInterfZZ(0, myAllocator),
124   myInterfered(100, myAllocator)
125 {
126   myNbShapes=0;
127   myNbSourceShapes=0;
128 }
129 //=======================================================================
130 //function : ~
131 //purpose  :
132 //=======================================================================
~BOPDS_DS()133 BOPDS_DS::~BOPDS_DS()
134 {
135   Clear();
136 }
137 //=======================================================================
138 //function : Clear
139 //purpose  :
140 //=======================================================================
Clear()141 void BOPDS_DS::Clear()
142 {
143   myNbShapes=0;
144   myNbSourceShapes=0;
145   //
146   myArguments.Clear();
147   myRanges.Clear();
148   myLines.Clear();
149   myMapShapeIndex.Clear();
150   myPaveBlocksPool.Clear();
151   myFaceInfoPool.Clear();
152   myShapesSD.Clear();
153   myMapVE.Clear();
154   myMapPBCB.Clear();
155   myInterfTB.Clear();
156   myInterfVV.Clear();
157   myInterfVE.Clear();
158   myInterfVF.Clear();
159   myInterfEE.Clear();
160   myInterfEF.Clear();
161   myInterfFF.Clear();
162   myInterfVZ.Clear();
163   myInterfEZ.Clear();
164   myInterfFZ.Clear();
165   myInterfZZ.Clear();
166   myInterfered.Clear();
167 }
168 //=======================================================================
169 //function : SetArguments
170 //purpose  :
171 //=======================================================================
SetArguments(const TopTools_ListOfShape & theLS)172 void BOPDS_DS::SetArguments(const TopTools_ListOfShape& theLS)
173 {
174   myArguments=theLS;
175 }
176 //=======================================================================
177 //function : Arguments
178 //purpose  :
179 //=======================================================================
Arguments() const180 const TopTools_ListOfShape& BOPDS_DS::Arguments()const
181 {
182   return myArguments;
183 }
184 //=======================================================================
185 //function : Allocator
186 //purpose  :
187 //=======================================================================
Handle(NCollection_BaseAllocator)188 const Handle(NCollection_BaseAllocator)& BOPDS_DS::Allocator()const
189 {
190   return myAllocator;
191 }
192 
193 //=======================================================================
194 //function : NbShapes
195 //purpose  :
196 //=======================================================================
NbShapes() const197 Standard_Integer BOPDS_DS::NbShapes()const
198 {
199   return myLines.Size();
200 }
201 //=======================================================================
202 //function : NbSourceShapes
203 //purpose  :
204 //=======================================================================
NbSourceShapes() const205 Standard_Integer BOPDS_DS::NbSourceShapes()const
206 {
207   return myNbSourceShapes;
208 }
209 //=======================================================================
210 //function : NbRanges
211 //purpose  :
212 //=======================================================================
NbRanges() const213 Standard_Integer BOPDS_DS::NbRanges()const
214 {
215   return myRanges.Size();
216 }
217 //=======================================================================
218 //function : Range
219 //purpose  :
220 //=======================================================================
Range(const Standard_Integer theI) const221 const BOPDS_IndexRange& BOPDS_DS::Range(const Standard_Integer theI)const
222 {
223   return myRanges(theI);
224 }
225 //=======================================================================
226 //function : Rank
227 //purpose  :
228 //=======================================================================
Rank(const Standard_Integer theI) const229 Standard_Integer BOPDS_DS::Rank(const Standard_Integer theI)const
230 {
231   Standard_Integer i, aNb, iErr;
232   //
233   iErr=-1;
234   aNb=NbRanges();
235   for(i=0; i<aNb; ++i) {
236     const BOPDS_IndexRange& aR=Range(i);
237     if (aR.Contains(theI)) {
238       return i;
239     }
240   }
241   return iErr;
242 }
243 //=======================================================================
244 //function : IsNewShape
245 //purpose  :
246 //=======================================================================
IsNewShape(const Standard_Integer theI) const247 Standard_Boolean BOPDS_DS::IsNewShape(const Standard_Integer theI)const
248 {
249   return theI>=NbSourceShapes();
250 }
251 //=======================================================================
252 //function : Append
253 //purpose  :
254 //=======================================================================
Append(const BOPDS_ShapeInfo & theSI)255 Standard_Integer BOPDS_DS::Append(const BOPDS_ShapeInfo& theSI)
256 {
257   Standard_Integer iX;
258   //
259   myLines.Appended()=theSI;
260   iX=myLines.Length()-1;
261   myMapShapeIndex.Bind(theSI.Shape(), iX);
262   //
263   return iX;
264 }
265 //=======================================================================
266 //function : Append
267 //purpose  :
268 //=======================================================================
Append(const TopoDS_Shape & theS)269 Standard_Integer BOPDS_DS::Append(const TopoDS_Shape& theS)
270 {
271   Standard_Integer iX;
272   //
273   myLines.Appended().SetShape(theS);
274   iX=myLines.Length()-1;
275   myMapShapeIndex.Bind(theS, iX);
276   return iX;
277 }
278 //=======================================================================
279 //function : ShapeInfo
280 //purpose  :
281 //=======================================================================
ShapeInfo(const Standard_Integer theI) const282 const BOPDS_ShapeInfo& BOPDS_DS::ShapeInfo
283   (const Standard_Integer theI)const
284 {
285   return myLines(theI);
286 }
287 //=======================================================================
288 //function : ChangeShapeInfo
289 //purpose  :
290 //=======================================================================
ChangeShapeInfo(const Standard_Integer theI)291 BOPDS_ShapeInfo& BOPDS_DS::ChangeShapeInfo(const Standard_Integer theI)
292 {
293   BOPDS_ShapeInfo *pSI;
294   //
295   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI);
296   pSI=(BOPDS_ShapeInfo *)&aSI;
297   return *pSI;
298 }
299 //=======================================================================
300 //function : Shape
301 //purpose  :
302 //=======================================================================
Shape(const Standard_Integer theI) const303 const TopoDS_Shape& BOPDS_DS::Shape(const Standard_Integer theI)const
304 {
305 
306   const TopoDS_Shape& aS=ShapeInfo(theI).Shape();
307   return aS;
308 }
309 //=======================================================================
310 //function : Index
311 //purpose  :
312 //=======================================================================
Index(const TopoDS_Shape & theS) const313 Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS)const
314 {
315   Standard_Integer iRet;
316   //
317   iRet=-1;
318   if (myMapShapeIndex.IsBound(theS)) {
319     iRet=myMapShapeIndex.Find(theS);
320   }
321   return iRet;
322 }
323 //=======================================================================
324 //function : Init
325 //purpose  :
326 //=======================================================================
Init(const Standard_Real theFuzz)327 void BOPDS_DS::Init(const Standard_Real theFuzz)
328 {
329   Standard_Integer i1, i2, j, aI, aNb, aNbS, aNbE, aNbSx;
330   Standard_Integer n1, n2, n3, nV, nW, nE, aNbF;
331   Standard_Real aTol, aTolAdd;
332   TopAbs_ShapeEnum aTS;
333   TopoDS_Iterator aItS;
334   TColStd_ListIteratorOfListOfInteger aIt1, aIt2, aIt3;
335   TopTools_ListIteratorOfListOfShape aIt;
336   BOPDS_IndexRange aR;
337   Handle(NCollection_BaseAllocator) aAllocator;
338   TopTools_MapOfShape aMS;
339   //
340   // 1 Append Source Shapes
341   aNb=myArguments.Extent();
342   if (!aNb) {
343     return;
344   }
345   //
346   myRanges.SetIncrement(aNb);
347   //
348   aNbS=0;
349   aIt.Initialize(myArguments);
350   for (; aIt.More(); aIt.Next()) {
351     const TopoDS_Shape& aSx=aIt.Value();
352     //
353     aNbSx=0;
354     TotalShapes(aSx, aNbSx, aMS);
355     //
356     aNbS=aNbS+aNbSx;
357   }
358   aMS.Clear();
359   //
360   myLines.SetIncrement(2*aNbS);
361   //-----------------------------------------------------scope_1 f
362   aAllocator=
363     NCollection_BaseAllocator::CommonBaseAllocator();
364   //
365   //
366   i1=0;
367   i2=0;
368   aIt.Initialize(myArguments);
369   for (; aIt.More(); aIt.Next()) {
370     const TopoDS_Shape& aS=aIt.Value();
371     if (myMapShapeIndex.IsBound(aS)) {
372       continue;
373     }
374     aI=Append(aS);
375     //
376     InitShape(aI, aS);
377     //
378     i2=NbShapes()-1;
379     aR.SetIndices(i1, i2);
380     myRanges.Append(aR);
381     i1=i2+1;
382   }
383   //
384   aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
385   myNbSourceShapes = NbShapes();
386   //
387   // 2 Bounding Boxes
388   //
389   // 2.1 Vertex
390   for (j=0; j<myNbSourceShapes; ++j) {
391     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
392     //
393     const TopoDS_Shape& aS=aSI.Shape();
394     //
395     aTS=aSI.ShapeType();
396     //
397     if (aTS==TopAbs_VERTEX) {
398       Bnd_Box& aBox=aSI.ChangeBox();
399       const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aS);
400       const gp_Pnt& aP=BRep_Tool::Pnt(aV);
401       aTol = BRep_Tool::Tolerance(aV);
402       aBox.SetGap(aTol + aTolAdd);
403       aBox.Add(aP);
404     }
405   }
406   // 2.2 Edge
407   aNbE=0;
408   for (j=0; j<myNbSourceShapes; ++j) {
409     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
410     //
411     aTS=aSI.ShapeType();
412     if (aTS==TopAbs_EDGE) {
413       const TopoDS_Shape& aS=aSI.Shape();
414       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
415       aTol = BRep_Tool::Tolerance(aE);
416       //
417       if (!BRep_Tool::Degenerated(aE)) {
418         Standard_Boolean bInf1, bInf2;
419         Standard_Integer aIx;
420         Standard_Real aT1, aT2;
421         gp_Pnt aPx;
422         Handle(Geom_Curve) aC3D;
423         TopoDS_Vertex aVx;
424         TopoDS_Edge aEx;
425         BRep_Builder aBB;
426         BOPDS_ShapeInfo aSIx;
427         //
428         TColStd_ListOfInteger& aLI=aSI.ChangeSubShapes();
429         //
430         aEx=aE;
431         aEx.Orientation(TopAbs_FORWARD);
432         //
433         aC3D=BRep_Tool::Curve (aEx, aT1, aT2);
434         bInf1=Precision::IsNegativeInfinite(aT1);
435         bInf2=Precision::IsPositiveInfinite(aT2);
436         //
437         if (bInf1) {
438           aC3D->D0(aT1, aPx);
439           aBB.MakeVertex(aVx, aPx, aTol);
440           aVx.Orientation(TopAbs_FORWARD);
441           //
442           aSIx.SetShape(aVx);
443           aSIx.SetShapeType(TopAbs_VERTEX);
444           aSIx.SetFlag(1); //infinite flag
445           //
446           aIx=Append(aSIx);
447           aLI.Append(aIx);
448         }
449         if (bInf2) {
450           aC3D->D0(aT2, aPx);
451           aBB.MakeVertex(aVx, aPx, aTol);
452           aVx.Orientation(TopAbs_REVERSED);
453           //
454           aSIx.SetShape(aVx);
455           aSIx.SetShapeType(TopAbs_VERTEX);
456           aSIx.SetFlag(1);//infinite flag
457           //
458           aIx=Append(aSIx);
459           aLI.Append(aIx);
460         }
461       }
462       else {
463         aSI.SetFlag(j);
464       }
465       //
466       Bnd_Box& aBox=aSI.ChangeBox();
467       BRepBndLib::Add(aE, aBox);
468       //
469       const TColStd_ListOfInteger& aLV=aSI.SubShapes();
470       aIt1.Initialize(aLV);
471       for (; aIt1.More(); aIt1.Next()) {
472         nV=aIt1.Value();
473         BOPDS_ShapeInfo& aSIV=ChangeShapeInfo(nV);
474         Bnd_Box& aBx=aSIV.ChangeBox();
475         aBox.Add(aBx);
476       }
477       aBox.SetGap(aBox.GetGap() + aTolAdd);
478       ++aNbE;
479     }
480   }
481   // 2.3 Face
482   TColStd_MapOfInteger aMI(100, aAllocator);
483   TColStd_MapIteratorOfMapOfInteger aItMI;
484   //
485   aNbF=0;
486   for (j=0; j<myNbSourceShapes; ++j) {
487     BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
488     //
489     aTS=aSI.ShapeType();
490     if (aTS==TopAbs_FACE) {
491       const TopoDS_Shape& aS=aSI.Shape();
492       //
493       Bnd_Box& aBox=aSI.ChangeBox();
494       BRepBndLib::Add(aS, aBox);
495       //
496       TColStd_ListOfInteger& aLW=aSI.ChangeSubShapes();
497       aIt1.Initialize(aLW);
498       for (; aIt1.More(); aIt1.Next()) {
499         nW=aIt1.Value();
500         BOPDS_ShapeInfo& aSIW=ChangeShapeInfo(nW);
501         //
502         const TColStd_ListOfInteger& aLE=aSIW.SubShapes();
503         aIt2.Initialize(aLE);
504         for (; aIt2.More(); aIt2.Next()) {
505           nE=aIt2.Value();
506           BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
507           Bnd_Box& aBx=aSIE.ChangeBox();
508           aBox.Add(aBx);
509           aMI.Add(nE);
510           //
511           const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aSIE.Shape());
512           if (BRep_Tool::Degenerated(aE)) {
513             aSIE.SetFlag(j);
514           }
515           //
516           const TColStd_ListOfInteger& aLV=aSIE.SubShapes();
517           aIt3.Initialize(aLV);
518           for (; aIt3.More(); aIt3.Next()) {
519             nV=aIt3.Value();
520             aMI.Add(nV);
521           }
522         }
523       }//for (; aIt1.More(); aIt1.Next()) {
524       //
525       // pure internal vertices on the face
526       aItS.Initialize(aS);
527       for (; aItS.More(); aItS.Next()) {
528         const TopoDS_Shape& aSx=aItS.Value();
529         if (aSx.ShapeType()==TopAbs_VERTEX){
530           nV=Index(aSx);
531           aMI.Add(nV);
532         }
533       }
534       //
535       //
536       // For a Face: change wires for BRep sub-shapes
537       aLW.Clear();
538       aItMI.Initialize(aMI);
539       for (; aItMI.More(); aItMI.Next()) {
540         nV=aItMI.Value();
541         aLW.Append(nV);
542       }
543       aMI.Clear();
544       aBox.SetGap(aBox.GetGap() + aTolAdd);
545       ++aNbF;
546     }//if (aTS==TopAbs_FACE) {
547   }//for (j=0; j<myNbSourceShapes; ++j) {
548   //
549   // For the check mode we need to compute the bounding box for solid.
550   // Otherwise, it will be computed on the building stage
551   Standard_Boolean bCheckMode = (myArguments.Extent() == 1);
552   if (bCheckMode)
553   {
554     // 2.4 Solids
555     for (j=0; j<myNbSourceShapes; ++j) {
556       BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
557       //
558       aTS=aSI.ShapeType();
559       if (aTS!=TopAbs_SOLID) {
560         continue;
561       }
562       Bnd_Box& aBox=aSI.ChangeBox();
563       BuildBndBoxSolid(j, aBox);
564       //
565       //
566       // update sub-shapes by BRep comprising ones
567       aMI.Clear();
568       TColStd_ListOfInteger& aLI1=aSI.ChangeSubShapes();
569       //
570       aIt1.Initialize(aLI1);
571       for (; aIt1.More(); aIt1.Next()) {
572         n1=aIt1.Value();
573         BOPDS_ShapeInfo& aSI1=ChangeShapeInfo(n1);
574         if (aSI1.ShapeType()!=TopAbs_SHELL) {
575           continue;
576         }
577         //
578         const TColStd_ListOfInteger& aLI2=aSI1.SubShapes();
579         aIt2.Initialize(aLI2);
580         for (; aIt2.More(); aIt2.Next()) {
581           n2=aIt2.Value();
582           BOPDS_ShapeInfo& aSI2=ChangeShapeInfo(n2);
583           if (aSI2.ShapeType()!=TopAbs_FACE) {
584             continue;
585           }
586           //
587           aMI.Add(n2);
588           //
589           const TColStd_ListOfInteger& aLI3=aSI2.SubShapes();
590           aIt3.Initialize(aLI3);
591           for (; aIt3.More(); aIt3.Next()) {
592             n3=aIt3.Value();
593             aMI.Add(n3);
594           }
595         }
596       }
597       //
598       aLI1.Clear();
599       aItMI.Initialize(aMI);
600       for (; aItMI.More(); aItMI.Next()) {
601         n1=aItMI.Value();
602         aLI1.Append(n1);
603       }
604       aMI.Clear();
605     }//for (j=0; j<myNbSourceShapes; ++j) {
606   }
607   //
608   aMI.Clear();
609   //-----------------------------------------------------
610   //
611   // Prepare Vertex-Edge connection map
612   for (nE = 0; nE < myNbSourceShapes; ++nE)
613   {
614     BOPDS_ShapeInfo& aSI = ChangeShapeInfo(nE);
615     if (aSI.ShapeType() != TopAbs_EDGE)
616       continue;
617 
618     const TColStd_ListOfInteger& aLV = aSI.SubShapes();
619     aIt1.Initialize(aLV);
620     for (; aIt1.More(); aIt1.Next())
621     {
622       nV = aIt1.Value();
623       TColStd_ListOfInteger* pLE = myMapVE.ChangeSeek(nV);
624       if (!pLE) {
625         pLE = myMapVE.Bound(nV, TColStd_ListOfInteger(myAllocator));
626         pLE->Append(nE);
627       }
628       else
629       {
630         // provide uniqueness of the edges in the list
631         for (aIt2.Initialize(*pLE); aIt2.More(); aIt2.Next())
632         {
633           if (aIt2.Value() == nE)
634             break;
635         }
636         if (!aIt2.More())
637           pLE->Append(nE);
638       }
639     }
640   }
641   //-----------------------------------------------------scope_1 t
642   // 3 myPaveBlocksPool
643   // 4. myFaceInfoPool
644   myPaveBlocksPool.SetIncrement(aNbE);
645   myFaceInfoPool.SetIncrement(aNbF);
646 }
647 //=======================================================================
648 //function : InitShape
649 //purpose  :
650 //=======================================================================
InitShape(const Standard_Integer aI,const TopoDS_Shape & aS)651 void BOPDS_DS::InitShape
652   (const Standard_Integer aI,
653    const TopoDS_Shape& aS)
654 {
655   Standard_Integer aIx;
656   TopoDS_Iterator aIt;
657   TColStd_ListIteratorOfListOfInteger aIt1;
658   //
659   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(aI);
660   aSI.SetShapeType(aS.ShapeType());
661   TColStd_ListOfInteger& aLI=aSI.ChangeSubShapes();
662   //
663   TColStd_MapOfInteger aM;
664   //
665   aIt1.Initialize(aLI);
666   for (; aIt1.More(); aIt1.Next()) {
667     aM.Add(aIt1.Value());
668   }
669   //
670   aIt.Initialize(aS);
671   for (; aIt.More(); aIt.Next()) {
672     const TopoDS_Shape& aSx=aIt.Value();
673     const Standard_Integer* pIx = myMapShapeIndex.Seek(aSx);
674     aIx = (pIx ? *pIx : Append(aSx));
675     //
676     InitShape(aIx, aSx);
677     //
678     if (aM.Add(aIx)) {
679       aLI.Append(aIx);
680     }
681   }
682 }
683 
684 //=======================================================================
685 //function : HasInterfShapeSubShapes
686 //purpose  :
687 //=======================================================================
HasInterfShapeSubShapes(const Standard_Integer theI1,const Standard_Integer theI2,const Standard_Boolean theFlag) const688 Standard_Boolean BOPDS_DS::HasInterfShapeSubShapes
689   (const Standard_Integer theI1,
690    const Standard_Integer theI2,
691    const Standard_Boolean theFlag)const
692 {
693   Standard_Boolean bRet;
694   Standard_Integer n2;
695   TColStd_ListIteratorOfListOfInteger aIt;
696   bRet = Standard_False;
697   //
698   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI2);
699   const TColStd_ListOfInteger& aLI=aSI.SubShapes();
700   aIt.Initialize(aLI);
701   for (; aIt.More(); aIt.Next()) {
702     n2=aIt.Value();
703     bRet=HasInterf(theI1, n2);
704     if (theFlag) {
705       if(bRet) {
706         break;
707       }
708     }
709     else {
710       if(!bRet) {
711         break;
712       }
713     }
714   }
715   return bRet;
716 }
717 //=======================================================================
718 //function : HasInterfSubShapes
719 //purpose  :
720 //=======================================================================
HasInterfSubShapes(const Standard_Integer theI1,const Standard_Integer theI2) const721 Standard_Boolean BOPDS_DS::HasInterfSubShapes
722   (const Standard_Integer theI1,
723    const Standard_Integer theI2)const
724 {
725   Standard_Boolean bRet;
726   Standard_Integer n1;
727   TColStd_ListIteratorOfListOfInteger aIt;
728   bRet = Standard_False;
729   //
730   const BOPDS_ShapeInfo& aSI=ShapeInfo(theI1);
731   const TColStd_ListOfInteger& aLI=aSI.SubShapes();
732   aIt.Initialize(aLI);
733   for (; aIt.More(); aIt.Next()) {
734     n1=aIt.Value();
735     bRet=HasInterfShapeSubShapes(n1, theI2);
736     if(bRet) {
737       break;
738     }
739   }
740   return bRet;
741 }
742 //
743 // PaveBlocks
744 //=======================================================================
745 //function : PaveBlocksPool
746 //purpose  :
747 //=======================================================================
PaveBlocksPool() const748 const BOPDS_VectorOfListOfPaveBlock& BOPDS_DS::PaveBlocksPool()const
749 {
750   return myPaveBlocksPool;
751 }
752 //=======================================================================
753 //function : ChangePaveBlocksPool
754 //purpose  :
755 //=======================================================================
ChangePaveBlocksPool()756 BOPDS_VectorOfListOfPaveBlock& BOPDS_DS::ChangePaveBlocksPool()
757 {
758   return myPaveBlocksPool;
759 }
760 //=======================================================================
761 //function : HasPaveBlocks
762 //purpose  :
763 //=======================================================================
HasPaveBlocks(const Standard_Integer theI) const764 Standard_Boolean BOPDS_DS::HasPaveBlocks(const Standard_Integer theI)const
765 {
766   return ShapeInfo(theI).HasReference();
767 }
768 //=======================================================================
769 //function : PaveBlocks
770 //purpose  :
771 //=======================================================================
PaveBlocks(const Standard_Integer theI) const772 const BOPDS_ListOfPaveBlock& BOPDS_DS::PaveBlocks
773   (const Standard_Integer theI)const
774 {
775   static BOPDS_ListOfPaveBlock sLPB;
776   Standard_Integer aRef;
777   //
778   if (HasPaveBlocks(theI)) {
779     aRef=ShapeInfo(theI).Reference();
780     const BOPDS_ListOfPaveBlock& aLPB=myPaveBlocksPool(aRef);
781     return aLPB;
782   }
783   return sLPB;
784 }
785 
786 //=======================================================================
787 //function : ChangePaveBlocks
788 //purpose  :
789 //=======================================================================
ChangePaveBlocks(const Standard_Integer theI)790 BOPDS_ListOfPaveBlock& BOPDS_DS::ChangePaveBlocks
791   (const Standard_Integer theI)
792 {
793   Standard_Boolean bHasReference;
794   Standard_Integer aRef;
795   //
796   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
797   bHasReference=aSI.HasReference();
798   if (!bHasReference) {
799     InitPaveBlocks(theI);
800   }
801   //
802   aRef=aSI.Reference();
803   return myPaveBlocksPool(aRef);
804 }
805 //=======================================================================
806 //function : InitPaveBlocks
807 //purpose  :
808 //=======================================================================
InitPaveBlocks(const Standard_Integer theI)809 void BOPDS_DS::InitPaveBlocks(const Standard_Integer theI)
810 {
811   Standard_Integer nV=0, iRef, aNbV, nVSD;
812   Standard_Real aT;
813   TopAbs_Orientation aOrE;
814   TopoDS_Vertex aV;
815   TColStd_ListIteratorOfListOfInteger aIt;
816   BOPDS_Pave aPave;
817   Handle(BOPDS_PaveBlock) aPB;
818   //
819   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
820   const TopoDS_Edge& aE=*(TopoDS_Edge*)(&aSI.Shape());
821   aOrE=aE.Orientation();
822   //
823   const TColStd_ListOfInteger& aLV=aSI.SubShapes();
824   aNbV=aLV.Extent();
825   if (!aNbV) {
826     return;
827   }
828   //
829   aPB=new BOPDS_PaveBlock;
830   aPB->SetOriginalEdge(theI);
831   //
832   if (aOrE!=TopAbs_INTERNAL) {
833     aIt.Initialize(aLV);
834     for (; aIt.More(); aIt.Next()) {
835       nV=aIt.Value();
836       //
837       const BOPDS_ShapeInfo& aSIV=ShapeInfo(nV);
838       aV=*(TopoDS_Vertex*)(&aSIV.Shape());
839       if (aSIV.HasFlag()) {
840         aT=ComputeParameter(aV, aE);
841       }
842       else {
843         aT=BRep_Tool::Parameter(aV, aE);
844       }
845       //
846       if (HasShapeSD(nV, nVSD)) {
847         nV=nVSD;
848       }
849       aPave.SetIndex(nV);
850       aPave.SetParameter(aT);
851       if (aSI.HasFlag())
852         // for a degenerated edge append pave unconditionally
853         aPB->AppendExtPave1(aPave);
854       else
855         aPB->AppendExtPave(aPave);
856     }
857     //
858     if (aNbV==1) {
859       aV.Reverse();
860       aT=BRep_Tool::Parameter(aV, aE);
861       aPave.SetIndex(nV);
862       aPave.SetParameter(aT);
863       aPB->AppendExtPave1(aPave);
864     }
865   }
866   //
867   else {
868     TopoDS_Iterator aItE;
869     //
870     aItE.Initialize(aE, Standard_False, Standard_True);
871     for (; aItE.More(); aItE.Next()) {
872       aV=*((TopoDS_Vertex*)&aItE.Value());
873       nV=Index(aV);
874       //
875       const BOPDS_ShapeInfo& aSIV=ShapeInfo(nV);
876       if (aSIV.HasFlag()) {
877         aT=ComputeParameter(aV, aE);
878       }
879       else {
880         aT=BRep_Tool::Parameter(aV, aE);
881       }
882       //
883       if (HasShapeSD(nV, nVSD)) {
884         nV=nVSD;
885       }
886       aPave.SetIndex(nV);
887       aPave.SetParameter(aT);
888       aPB->AppendExtPave1(aPave);
889     }
890   }
891   //
892   BOPDS_ListOfPaveBlock &aLPB=myPaveBlocksPool.Appended();
893   iRef=myPaveBlocksPool.Length()-1;
894   //
895   aPB->Update(aLPB, Standard_False);
896   aSI.SetReference(iRef);
897 }
898 //=======================================================================
899 //function : UpdatePaveBlocks
900 //purpose  :
901 //=======================================================================
UpdatePaveBlocks()902 void BOPDS_DS::UpdatePaveBlocks()
903 {
904   Standard_Integer i, aNbPBP;
905   BOPDS_ListOfPaveBlock aLPBN(myAllocator);
906   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
907   //
908   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
909   //
910   aNbPBP=aPBP.Size();
911   for (i=0; i<aNbPBP; ++i) {
912     BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
913     //
914     aItPB.Initialize(aLPB);
915     for (; aItPB.More();) {
916       Handle(BOPDS_PaveBlock)& aPB=aItPB.ChangeValue();
917       //
918       if (!aPB->IsToUpdate()) {
919         aItPB.Next();
920         continue;
921       }
922       //
923       aLPBN.Clear();
924       aPB->Update(aLPBN);
925       //
926       aLPB.Remove(aItPB);
927       //
928       aLPB.Append(aLPBN);
929     }// for (; aItPB.More(); aItPB.Next()) {
930   }// for (i=0; i<aNbPBP; ++i) {
931 }
932 //=======================================================================
933 //function : UpdatePaveBlock
934 //purpose  :
935 //=======================================================================
UpdatePaveBlock(const Handle (BOPDS_PaveBlock)& thePB)936 void BOPDS_DS::UpdatePaveBlock(const Handle(BOPDS_PaveBlock)& thePB)
937 {
938   if (!thePB->IsToUpdate()){
939     return;
940   }
941   //
942   Standard_Integer nE, iRef;
943   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBN;
944   BOPDS_ListOfPaveBlock aLPBN(myAllocator);
945   Handle(BOPDS_PaveBlock) aPB;
946   //
947   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
948   //
949   nE=thePB->OriginalEdge();
950   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(nE);
951   iRef=aSI.Reference();
952   BOPDS_ListOfPaveBlock& aLPB=aPBP(iRef);
953   //
954   aItPB.Initialize(aLPB);
955   for (; aItPB.More(); aItPB.Next()) {
956     aPB=aItPB.ChangeValue();
957     if (aPB==thePB) {
958       aPB->Update(aLPBN);
959       aLPB.Append(aLPBN);
960       aLPB.Remove(aItPB);
961       break;
962     }
963   }
964 }
965 //=======================================================================
966 //function : UpdateCommonBlock
967 //purpose  :
968 //=======================================================================
UpdateCommonBlock(const Handle (BOPDS_CommonBlock)& theCB,const Standard_Real theFuzz)969 void BOPDS_DS::UpdateCommonBlock(const Handle(BOPDS_CommonBlock)& theCB,
970                                  const Standard_Real theFuzz)
971 {
972   Standard_Integer nE, iRef, n1, n2;
973   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB, aItPBN;
974   BOPDS_ListOfPaveBlock aLPBN;
975   NCollection_DataMap<BOPDS_Pair, BOPDS_ListOfPaveBlock, BOPDS_PairMapHasher> aMPKLPB;
976   NCollection_DataMap<BOPDS_Pair, BOPDS_ListOfPaveBlock, BOPDS_PairMapHasher>::Iterator aItMPKLPB;
977   Handle(BOPDS_PaveBlock) aPB;
978   Handle(BOPDS_CommonBlock) aCBx;
979   BOPDS_Pair aPK;
980   //
981   const BOPDS_ListOfPaveBlock& aLPBCB=theCB->PaveBlocks();
982   if (!aLPBCB.First()->IsToUpdate()){
983     return;
984   }
985   //
986   const TColStd_ListOfInteger& aLF=theCB->Faces();
987   //
988   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
989   //
990   aItPBCB.Initialize(aLPBCB);
991   for (; aItPBCB.More(); aItPBCB.Next()) {
992     const Handle(BOPDS_PaveBlock)& aPBCB=aItPBCB.ChangeValue();
993     //
994     nE=aPBCB->OriginalEdge();
995     iRef=ChangeShapeInfo(nE).Reference();
996     BOPDS_ListOfPaveBlock& aLPB=aPBP(iRef);
997     //
998     aItPB.Initialize(aLPB);
999     for (; aItPB.More(); aItPB.Next()) {
1000       aPB=aItPB.ChangeValue();
1001       if (aPB==aPBCB) {
1002         //
1003         aLPBN.Clear();
1004         aPB->Update(aLPBN);
1005         //
1006         aItPBN.Initialize(aLPBN);
1007         for (; aItPBN.More(); aItPBN.Next()) {
1008           Handle(BOPDS_PaveBlock)& aPBN=aItPBN.ChangeValue();
1009           aLPB.Append(aPBN);
1010           //
1011           aPBN->Indices(n1, n2);
1012           aPK.SetIndices(n1, n2);
1013           if (aMPKLPB.IsBound(aPK)) {
1014             BOPDS_ListOfPaveBlock& aLPBx=aMPKLPB.ChangeFind(aPK);
1015             aLPBx.Append(aPBN);
1016           }
1017           else {
1018             BOPDS_ListOfPaveBlock aLPBx;
1019             aLPBx.Append(aPBN);
1020             aMPKLPB.Bind(aPK, aLPBx);
1021           }
1022         }
1023         aLPB.Remove(aItPB);
1024         break;
1025       }
1026     }
1027   }
1028   //
1029   aItMPKLPB.Initialize(aMPKLPB);
1030   for (; aItMPKLPB.More(); aItMPKLPB.Next()) {
1031     BOPDS_ListOfPaveBlock& aLPBx=aItMPKLPB.ChangeValue();
1032     //
1033     while (aLPBx.Extent()) {
1034       Standard_Boolean bCoinside;
1035       BOPDS_ListOfPaveBlock aLPBxN;
1036       //
1037       aItPB.Initialize(aLPBx);
1038       for(; aItPB.More(); ) {
1039         const Handle(BOPDS_PaveBlock)& aPBx=aItPB.Value();
1040         if (aLPBxN.Extent()) {
1041           const Handle(BOPDS_PaveBlock)& aPBCx = aLPBxN.First();
1042           bCoinside = CheckCoincidence(aPBx, aPBCx, theFuzz);
1043           if (bCoinside) {
1044             aLPBxN.Append(aPBx);
1045             aLPBx.Remove(aItPB);
1046             continue;
1047           }//if (bCoinside) {
1048         }//if (aLPBxN.Extent()) {
1049         else {
1050           aLPBxN.Append(aPBx);
1051           aLPBx.Remove(aItPB);
1052           continue;
1053         }
1054         aItPB.Next();
1055       }//for(; aItPB.More(); ) {
1056       //
1057       aCBx=new BOPDS_CommonBlock;
1058       aCBx->SetPaveBlocks(aLPBxN);
1059       aCBx->SetFaces(aLF);
1060       //
1061       aItPB.Initialize(aLPBxN);
1062       for (; aItPB.More(); aItPB.Next()) {
1063         aPB=aItPB.ChangeValue();
1064         SetCommonBlock(aPB, aCBx);
1065       }
1066     }
1067   }
1068 }
1069 
1070 //=======================================================================
1071 // function: RealPaveBlock
1072 // purpose:
1073 //=======================================================================
Handle(BOPDS_PaveBlock)1074 Handle(BOPDS_PaveBlock) BOPDS_DS::RealPaveBlock
1075     (const Handle(BOPDS_PaveBlock)& thePB) const
1076 {
1077   if (IsCommonBlock(thePB)) {
1078     const Handle(BOPDS_CommonBlock)& aCB = CommonBlock(thePB);
1079     const Handle(BOPDS_PaveBlock)& aPB = aCB->PaveBlock1();
1080     return aPB;
1081   }
1082   return thePB;
1083 }
1084 
1085 //=======================================================================
1086 // function: IsCommonBlockOnEdge
1087 // purpose:
1088 //=======================================================================
IsCommonBlockOnEdge(const Handle (BOPDS_PaveBlock)& thePB) const1089 Standard_Boolean BOPDS_DS::IsCommonBlockOnEdge
1090     (const Handle(BOPDS_PaveBlock)& thePB) const
1091 {
1092   if (IsCommonBlock(thePB)) {
1093     const Handle(BOPDS_CommonBlock)& aCB = CommonBlock(thePB);
1094     return aCB->PaveBlocks().Extent()>1;
1095   }
1096   return Standard_False;
1097 }
1098 
1099 //=======================================================================
1100 //function : IsCommonBlock
1101 //purpose  :
1102 //=======================================================================
IsCommonBlock(const Handle (BOPDS_PaveBlock)& thePB) const1103 Standard_Boolean BOPDS_DS::IsCommonBlock
1104     (const Handle(BOPDS_PaveBlock)& thePB) const
1105 {
1106   return myMapPBCB.IsBound(thePB);
1107 }
1108 
1109 //=======================================================================
1110 //function : CommonBlock
1111 //purpose  :
1112 //=======================================================================
Handle(BOPDS_CommonBlock)1113 Handle(BOPDS_CommonBlock) BOPDS_DS::CommonBlock
1114     (const Handle(BOPDS_PaveBlock)& thePB) const
1115 {
1116   return (IsCommonBlock(thePB) ? myMapPBCB.Find(thePB) : NULL);
1117 }
1118 
1119 //=======================================================================
1120 //function : SetCommonBlock
1121 //purpose  :
1122 //=======================================================================
SetCommonBlock(const Handle (BOPDS_PaveBlock)& thePB,const Handle (BOPDS_CommonBlock)& theCB)1123 void BOPDS_DS::SetCommonBlock(const Handle(BOPDS_PaveBlock)& thePB,
1124                               const Handle(BOPDS_CommonBlock)& theCB)
1125 {
1126   if (IsCommonBlock(thePB)) {
1127     Handle(BOPDS_CommonBlock)& aCB = myMapPBCB.ChangeFind(thePB);
1128     aCB=theCB;
1129   }
1130   else {
1131     myMapPBCB.Bind(thePB, theCB);
1132   }
1133 }
1134 
1135 //
1136 // FaceInfo
1137 //
1138 
1139 //=======================================================================
1140 //function : FaceInfoPool
1141 //purpose  :
1142 //=======================================================================
FaceInfoPool() const1143 const BOPDS_VectorOfFaceInfo& BOPDS_DS::FaceInfoPool()const
1144 {
1145   return myFaceInfoPool;
1146 }
1147 //=======================================================================
1148 //function : HasFaceInfo
1149 //purpose  :
1150 //=======================================================================
HasFaceInfo(const Standard_Integer theI) const1151 Standard_Boolean BOPDS_DS::HasFaceInfo(const Standard_Integer theI)const
1152 {
1153   return ShapeInfo(theI).HasReference();
1154 }
1155 //=======================================================================
1156 //function : FaceInfo
1157 //purpose  :
1158 //=======================================================================
FaceInfo(const Standard_Integer theI) const1159 const BOPDS_FaceInfo& BOPDS_DS::FaceInfo(const Standard_Integer theI)const
1160 {
1161   static BOPDS_FaceInfo sFI;
1162   Standard_Integer aRef;
1163   //
1164   if (HasFaceInfo(theI)) {
1165     aRef=ShapeInfo(theI).Reference();
1166     const BOPDS_FaceInfo& aFI=myFaceInfoPool(aRef);
1167     return aFI;
1168   }
1169   return sFI;
1170 }
1171 //=======================================================================
1172 //function : ChangeFaceInfo
1173 //purpose  :
1174 //=======================================================================
ChangeFaceInfo(const Standard_Integer theI)1175 BOPDS_FaceInfo& BOPDS_DS::ChangeFaceInfo(const Standard_Integer theI)
1176 {
1177   Standard_Boolean bHasReference;
1178   Standard_Integer aRef;
1179   BOPDS_FaceInfo* pFI;
1180   //
1181   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1182   bHasReference=aSI.HasReference();
1183   if (!bHasReference) {
1184     InitFaceInfo(theI);
1185   }
1186   //
1187   aRef=aSI.Reference();
1188   const BOPDS_FaceInfo& aFI=myFaceInfoPool(aRef);
1189   pFI=(BOPDS_FaceInfo*)&aFI;
1190   return *pFI;
1191 }
1192 //=======================================================================
1193 //function : InitFaceInfo
1194 //purpose  :
1195 //=======================================================================
InitFaceInfo(const Standard_Integer theI)1196 void BOPDS_DS::InitFaceInfo(const Standard_Integer theI)
1197 {
1198   Standard_Integer iRef;
1199   //
1200   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1201   BOPDS_FaceInfo &aFI=myFaceInfoPool.Appended();
1202   iRef=myFaceInfoPool.Length()-1;
1203   aSI.SetReference(iRef);
1204   //
1205   aFI.SetIndex(theI);
1206   InitFaceInfoIn(theI);
1207   UpdateFaceInfoOn(theI);
1208 }
1209 //=======================================================================
1210 //function : InitFaceInfoIn
1211 //purpose  :
1212 //=======================================================================
InitFaceInfoIn(const Standard_Integer theI)1213 void BOPDS_DS::InitFaceInfoIn (const Standard_Integer theI)
1214 {
1215   BOPDS_ShapeInfo& aSI = ChangeShapeInfo (theI);
1216   if (aSI.HasReference())
1217   {
1218     BOPDS_FaceInfo& aFI = myFaceInfoPool (aSI.Reference());
1219     const TopoDS_Shape& aF = Shape (theI);
1220     for (TopoDS_Iterator itS (aF); itS.More(); itS.Next())
1221     {
1222       const TopoDS_Shape& aV = itS.Value();
1223       if (aV.ShapeType() == TopAbs_VERTEX)
1224       {
1225         Standard_Integer nV = Index (aV);
1226         HasShapeSD (nV, nV);
1227         aFI.ChangeVerticesIn().Add (nV);
1228       }
1229     }
1230   }
1231 }
1232 
1233 //=======================================================================
1234 //function : UpdateFaceInfoIn
1235 //purpose  :
1236 //=======================================================================
UpdateFaceInfoIn(const Standard_Integer theI)1237 void BOPDS_DS::UpdateFaceInfoIn(const Standard_Integer theI)
1238 {
1239   Standard_Integer iRef;
1240   //
1241   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1242   if (aSI.HasReference()) {
1243     iRef=aSI.Reference();
1244     BOPDS_FaceInfo &aFI=myFaceInfoPool(iRef);
1245     //
1246     BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.ChangePaveBlocksIn();
1247     TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
1248     aMPBIn.Clear();
1249     aMVIn.Clear();
1250     FaceInfoIn(theI, aMPBIn, aMVIn);
1251   }
1252 }
1253 //=======================================================================
1254 //function : UpdateFaceInfoOn
1255 //purpose  :
1256 //=======================================================================
UpdateFaceInfoOn(const Standard_Integer theI)1257 void BOPDS_DS::UpdateFaceInfoOn(const Standard_Integer theI)
1258 {
1259   Standard_Integer iRef;
1260   //
1261   BOPDS_ShapeInfo& aSI=ChangeShapeInfo(theI);
1262   if (aSI.HasReference()) {
1263     iRef=aSI.Reference();
1264     BOPDS_FaceInfo &aFI=myFaceInfoPool(iRef);
1265     //
1266     BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.ChangePaveBlocksOn();
1267     TColStd_MapOfInteger& aMVOn=aFI.ChangeVerticesOn();
1268     aMPBOn.Clear();
1269     aMVOn.Clear();
1270     FaceInfoOn(theI, aMPBOn, aMVOn);
1271   }
1272 }
1273 //=======================================================================
1274 //function : FaceInfoOn
1275 //purpose  :
1276 //=======================================================================
FaceInfoOn(const Standard_Integer theF,BOPDS_IndexedMapOfPaveBlock & theMPB,TColStd_MapOfInteger & theMI)1277 void BOPDS_DS::FaceInfoOn(const Standard_Integer theF,
1278                           BOPDS_IndexedMapOfPaveBlock& theMPB,
1279                           TColStd_MapOfInteger& theMI)
1280 {
1281   Standard_Integer nS, nSD, nV1, nV2;
1282   TColStd_ListIteratorOfListOfInteger aIt;
1283   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
1284   //
1285   const BOPDS_ShapeInfo& aSI=ShapeInfo(theF);
1286   const TColStd_ListOfInteger& aLI=aSI.SubShapes();
1287   aIt.Initialize(aLI);
1288   for (; aIt.More(); aIt.Next()) {
1289     nS=aIt.Value();
1290     const BOPDS_ShapeInfo& aSIE=ShapeInfo(nS);
1291     if (aSIE.ShapeType()==TopAbs_EDGE) {
1292       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nS);
1293       aItPB.Initialize(aLPB);
1294       for (; aItPB.More(); aItPB.Next()) {
1295         const Handle(BOPDS_PaveBlock)& aPB=aItPB.Value();
1296         aPB->Indices(nV1, nV2);
1297         theMI.Add(nV1);
1298         theMI.Add(nV2);
1299         Handle(BOPDS_PaveBlock) aPBR=RealPaveBlock(aPB);
1300         theMPB.Add(aPBR);
1301       }
1302     }//if (aSIE.ShapeType()==TopAbs_EDGE)
1303     else {
1304       // nE is TopAbs_VERTEX
1305       if (HasShapeSD(nS, nSD)) {
1306         nS=nSD;
1307       }
1308       theMI.Add(nS);
1309     }
1310   }
1311 }
1312 //=======================================================================
1313 //function : FaceInfoIn
1314 //purpose  :
1315 //=======================================================================
FaceInfoIn(const Standard_Integer theF,BOPDS_IndexedMapOfPaveBlock & theMPB,TColStd_MapOfInteger & theMI)1316 void BOPDS_DS::FaceInfoIn(const Standard_Integer theF,
1317                           BOPDS_IndexedMapOfPaveBlock& theMPB,
1318                           TColStd_MapOfInteger& theMI)
1319 {
1320   Standard_Integer i, aNbVF, aNbEF, nV, nE, nVSD;
1321   TopoDS_Iterator aItS;
1322   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
1323   //
1324   // 1. Pure internal vertices on the face
1325   const TopoDS_Shape& aF=Shape(theF);
1326   aItS.Initialize(aF);
1327   for (; aItS.More(); aItS.Next()) {
1328     const TopoDS_Shape& aSx=aItS.Value();
1329     if (aSx.ShapeType()==TopAbs_VERTEX){
1330       nV=Index(aSx);
1331       if (HasShapeSD(nV, nVSD)) {
1332         nV=nVSD;
1333       }
1334       theMI.Add(nV);
1335     }
1336   }
1337   //
1338   // 2. aVFs
1339   BOPDS_VectorOfInterfVF& aVFs=InterfVF();
1340   aNbVF=aVFs.Length();
1341   for (i=0; i<aNbVF; ++i) {
1342     BOPDS_InterfVF& aVF=aVFs(i);
1343     if(aVF.Contains(theF)) {
1344       nV=aVF.OppositeIndex(theF);
1345       if (HasShapeSD(nV, nVSD)) {
1346         nV=nVSD;
1347       }
1348       theMI.Add(nV);
1349     }
1350   }
1351   //
1352   // 3. aEFs
1353   BOPDS_VectorOfInterfEF& aEFs=InterfEF();
1354   aNbEF=aEFs.Length();
1355   for (i=0; i<aNbEF; ++i) {
1356     BOPDS_InterfEF& aEF=aEFs(i);
1357     if(aEF.Contains(theF)) {
1358       if(aEF.HasIndexNew(nV)) {
1359         if (HasShapeSD(nV, nVSD)) {
1360           nV=nVSD;
1361         }
1362         theMI.Add(nV);
1363       }
1364       else {
1365         nE=aEF.OppositeIndex(theF);
1366         const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1367         aItPB.Initialize(aLPB);
1368         for (; aItPB.More(); aItPB.Next()) {
1369           const Handle(BOPDS_PaveBlock)& aPB=aItPB.Value();
1370           if (IsCommonBlock(aPB)) {
1371             const Handle(BOPDS_CommonBlock)& aCB=CommonBlock(aPB);
1372             if (aCB->Contains(theF)) {
1373               const Handle(BOPDS_PaveBlock)& aPB1=aCB->PaveBlock1();
1374               theMPB.Add(aPB1);
1375             }
1376           }
1377         }// for (; aItPB.More(); aItPB.Next()) {
1378       }// else {
1379     }// if(aEF.Contains(theF)) {
1380   }// for (i=0; i<aNbEF; ++i) {
1381 }
1382 
1383 //=======================================================================
1384 //function : UpdateFaceInfoIn
1385 //purpose  :
1386 //=======================================================================
UpdateFaceInfoIn(const TColStd_MapOfInteger & theFaces)1387 void BOPDS_DS::UpdateFaceInfoIn (const TColStd_MapOfInteger& theFaces)
1388 {
1389   for (TColStd_MapOfInteger::Iterator itM (theFaces); itM.More(); itM.Next())
1390   {
1391     const Standard_Integer nF = itM.Value();
1392     BOPDS_ShapeInfo& aSI = ChangeShapeInfo (nF);
1393     if (!aSI.HasReference())
1394     {
1395       myFaceInfoPool.Appended().SetIndex (nF);
1396       aSI.SetReference (myFaceInfoPool.Length() - 1);
1397     }
1398     BOPDS_FaceInfo& aFI = myFaceInfoPool (aSI.Reference());
1399     aFI.ChangePaveBlocksIn().Clear();
1400     aFI.ChangeVerticesIn().Clear();
1401 
1402     // 1. Add pure internal vertices on the face
1403     InitFaceInfoIn (nF);
1404   }
1405 
1406   // 2. Analyze Vertex-Face interferences
1407   BOPDS_VectorOfInterfVF& aVFs = InterfVF();
1408   const Standard_Integer aNbVF = aVFs.Length();
1409   for (Standard_Integer iVF = 0; iVF < aNbVF; ++iVF)
1410   {
1411     BOPDS_InterfVF& aVF = aVFs (iVF);
1412     const Standard_Integer nF = aVF.Index2();
1413     if (theFaces.Contains (nF))
1414     {
1415       Standard_Integer nV = aVF.Index1();
1416       HasShapeSD (nV, nV);
1417       myFaceInfoPool (ShapeInfo (nF).Reference()).ChangeVerticesIn().Add (nV);
1418     }
1419   }
1420   //
1421   // 3. Analyze Edge-Face interferences
1422   BOPDS_VectorOfInterfEF& aEFs = InterfEF();
1423   const Standard_Integer aNbEF = aEFs.Length();
1424   for (Standard_Integer iEF = 0; iEF < aNbEF; ++iEF)
1425   {
1426     BOPDS_InterfEF& aEF = aEFs (iEF);
1427     const Standard_Integer nF = aEF.Index2();
1428     if (theFaces.Contains (nF))
1429     {
1430       BOPDS_FaceInfo& aFI = myFaceInfoPool (ShapeInfo (nF).Reference());
1431       Standard_Integer nVNew;
1432       if (aEF.HasIndexNew (nVNew))
1433       {
1434         HasShapeSD (nVNew, nVNew);
1435         aFI.ChangeVerticesIn().Add (nVNew);
1436       }
1437       else
1438       {
1439         const Standard_Integer nE = aEF.Index1();
1440         const BOPDS_ListOfPaveBlock& aLPB = PaveBlocks (nE);
1441         for (BOPDS_ListOfPaveBlock::Iterator itPB (aLPB); itPB.More(); itPB.Next())
1442         {
1443           const Handle(BOPDS_PaveBlock)& aPB = itPB.Value();
1444           const Handle(BOPDS_CommonBlock)& aCB = CommonBlock (aPB);
1445           if (!aCB.IsNull())
1446           {
1447             if (aCB->Contains (nF))
1448             {
1449               const Handle(BOPDS_PaveBlock)& aPBR = aCB->PaveBlock1();
1450               aFI.ChangePaveBlocksIn().Add(aPBR);
1451             }
1452           }
1453         }
1454       }
1455     }
1456   }
1457 }
1458 
1459 //=======================================================================
1460 //function : UpdateFaceInfoOn
1461 //purpose  :
1462 //=======================================================================
UpdateFaceInfoOn(const TColStd_MapOfInteger & theFaces)1463 void BOPDS_DS::UpdateFaceInfoOn (const TColStd_MapOfInteger& theFaces)
1464 {
1465   for (TColStd_MapOfInteger::Iterator itM (theFaces); itM.More(); itM.Next())
1466   {
1467     const Standard_Integer nF = itM.Value();
1468     BOPDS_ShapeInfo& aSI = ChangeShapeInfo (nF);
1469     if (!aSI.HasReference())
1470     {
1471       myFaceInfoPool.Appended().SetIndex (nF);
1472       aSI.SetReference (myFaceInfoPool.Length() - 1);
1473     }
1474     BOPDS_FaceInfo& aFI = myFaceInfoPool (aSI.Reference());
1475     aFI.ChangePaveBlocksOn().Clear();
1476     aFI.ChangeVerticesOn().Clear();
1477 
1478     FaceInfoOn (nF, aFI.ChangePaveBlocksOn(), aFI.ChangeVerticesOn());
1479   }
1480 }
1481 
1482 //=======================================================================
1483 //function : RefineFaceInfoOn
1484 //purpose  :
1485 //=======================================================================
RefineFaceInfoOn()1486 void BOPDS_DS::RefineFaceInfoOn()
1487 {
1488   Standard_Integer i, aNb, nF, aNbPB, j;
1489   BOPDS_IndexedMapOfPaveBlock aMPB;
1490   //
1491   aNb=myFaceInfoPool.Length();
1492   for (i=0; i<aNb; ++i) {
1493     BOPDS_FaceInfo &aFI=myFaceInfoPool(i);
1494     nF=aFI.Index();
1495     UpdateFaceInfoOn(nF);
1496     BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.ChangePaveBlocksOn();
1497     //
1498     aMPB.Clear();
1499     aMPB.Assign(aMPBOn);
1500     aMPBOn.Clear();
1501     //
1502     aNbPB=aMPB.Extent();
1503     for (j=1; j<=aNbPB; ++j) {
1504       const Handle(BOPDS_PaveBlock)& aPB=aMPB(j);
1505       if (aPB->HasEdge()) {
1506         aMPBOn.Add(aPB);
1507       }
1508     }
1509   }
1510 }
1511 
1512 //=======================================================================
1513 //function : RefineFaceInfoIn
1514 //purpose  :
1515 //=======================================================================
RefineFaceInfoIn()1516 void BOPDS_DS::RefineFaceInfoIn()
1517 {
1518   for (Standard_Integer i = 0; i < myNbSourceShapes; ++i)
1519   {
1520     const BOPDS_ShapeInfo& aSI = ShapeInfo(i);
1521     if (aSI.ShapeType() != TopAbs_FACE)
1522       continue;
1523 
1524     if (!aSI.HasReference())
1525       continue;
1526 
1527     BOPDS_FaceInfo& aFI = ChangeFaceInfo(i);
1528 
1529     const BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.PaveBlocksOn();
1530     BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1531 
1532     if (aMPBIn.IsEmpty() || aMPBOn.IsEmpty())
1533       continue;
1534 
1535     BOPDS_IndexedMapOfPaveBlock aMPBInNew;
1536 
1537     const Standard_Integer aNbPBIn = aMPBIn.Extent();
1538     for (Standard_Integer j = 1; j <= aNbPBIn; ++j)
1539     {
1540       if (!aMPBOn.Contains(aMPBIn(j)))
1541         aMPBInNew.Add(aMPBIn(j));
1542     }
1543 
1544     if (aMPBInNew.Extent() < aNbPBIn)
1545       aMPBIn = aMPBInNew;
1546   }
1547 }
1548 
1549 //=======================================================================
1550 //function : AloneVertices
1551 //purpose  :
1552 //=======================================================================
AloneVertices(const Standard_Integer theI,TColStd_ListOfInteger & theLI) const1553 void BOPDS_DS::AloneVertices(const Standard_Integer theI,
1554                              TColStd_ListOfInteger& theLI)const
1555 {
1556   if (HasFaceInfo(theI)) {
1557     //
1558     Standard_Integer i, j, nV1, nV2, nV, aNbPB;
1559     TColStd_MapIteratorOfMapOfInteger aItMI;
1560     //
1561     TColStd_MapOfInteger aMI(100, myAllocator);
1562     //
1563     const BOPDS_FaceInfo& aFI=FaceInfo(theI);
1564     //
1565     for (i = 0; i < 2; ++i) {
1566       const BOPDS_IndexedMapOfPaveBlock& aMPB=
1567         (!i) ? aFI.PaveBlocksIn() : aFI.PaveBlocksSc();
1568       aNbPB = aMPB.Extent();
1569       for (j = 1; j <= aNbPB; ++j) {
1570         const Handle(BOPDS_PaveBlock)& aPB = aMPB(j);
1571         aPB->Indices(nV1, nV2);
1572         aMI.Add(nV1);
1573         aMI.Add(nV2);
1574       }
1575     }
1576     //
1577     for (i=0; i<2; ++i) {
1578       const TColStd_MapOfInteger& aMIV=
1579         (!i) ? aFI.VerticesIn() : aFI.VerticesSc();
1580       aItMI.Initialize(aMIV);
1581       for (; aItMI.More(); aItMI.Next()) {
1582         nV=aItMI.Value();
1583         if (nV>=0) {
1584           if (aMI.Add(nV)) {
1585             theLI.Append(nV);
1586           }
1587         }
1588       }
1589     }
1590   }
1591 }
1592 //=======================================================================
1593 //function : VerticesOnIn
1594 //purpose  :
1595 //=======================================================================
SubShapesOnIn(const Standard_Integer theNF1,const Standard_Integer theNF2,TColStd_MapOfInteger & theMVOnIn,TColStd_MapOfInteger & theMVCommon,BOPDS_IndexedMapOfPaveBlock & thePBOnIn,BOPDS_MapOfPaveBlock & theCommonPB) const1596 void BOPDS_DS::SubShapesOnIn(const Standard_Integer theNF1,
1597                              const Standard_Integer theNF2,
1598                              TColStd_MapOfInteger& theMVOnIn,
1599                              TColStd_MapOfInteger& theMVCommon,
1600                              BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
1601                              BOPDS_MapOfPaveBlock& theCommonPB)const
1602 {
1603   Standard_Integer i, j, nV, nV1, nV2, aNbPB;
1604   TColStd_MapIteratorOfMapOfInteger aIt;
1605   BOPDS_IndexedMapOfPaveBlock pMPB[4];
1606   //
1607   const BOPDS_FaceInfo& aFI1 = FaceInfo(theNF1);
1608   const BOPDS_FaceInfo& aFI2 = FaceInfo(theNF2);
1609   //
1610   pMPB[0] = aFI1.PaveBlocksOn();
1611   pMPB[1] = aFI1.PaveBlocksIn();
1612   pMPB[2] = aFI2.PaveBlocksOn();
1613   pMPB[3] = aFI2.PaveBlocksIn();
1614   //
1615   for (i = 0; i < 4; ++i)
1616   {
1617     aNbPB = pMPB[i].Extent();
1618     for (j = 1; j <= aNbPB; ++j)
1619     {
1620       const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j);
1621       thePBOnIn.Add(aPB);
1622       aPB->Indices(nV1, nV2);
1623 
1624       theMVOnIn.Add(nV1);
1625       theMVOnIn.Add(nV2);
1626 
1627       if (i < 2)
1628       {
1629         if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
1630         {
1631           theCommonPB.Add(aPB);
1632           theMVCommon.Add(nV1);
1633           theMVCommon.Add(nV2);
1634         }
1635       }
1636     }
1637   }
1638   //
1639   const TColStd_MapOfInteger& aMVOn1 = aFI1.VerticesOn();
1640   const TColStd_MapOfInteger& aMVIn1 = aFI1.VerticesIn();
1641   const TColStd_MapOfInteger& aMVOn2 = aFI2.VerticesOn();
1642   const TColStd_MapOfInteger& aMVIn2 = aFI2.VerticesIn();
1643   //
1644   for (i = 0; i < 2; ++i)
1645   {
1646     const TColStd_MapOfInteger& aMV1 = (!i) ? aMVOn1 : aMVIn1;
1647     aIt.Initialize(aMV1);
1648     for (; aIt.More(); aIt.Next())
1649     {
1650       nV = aIt.Value();
1651       if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV))
1652       {
1653         theMVOnIn.Add(nV);
1654 
1655         // Vertex taken from the 1st face is in the 2nd one.
1656         theMVCommon.Add(nV);
1657       }
1658     }
1659   }
1660 }
1661 //=======================================================================
1662 //function : SharedEdges
1663 //purpose  :
1664 //=======================================================================
SharedEdges(const Standard_Integer nF1,const Standard_Integer nF2,TColStd_ListOfInteger & theLI,const Handle (NCollection_BaseAllocator)& aAllocator)1665 void BOPDS_DS::SharedEdges(const Standard_Integer nF1,
1666       const Standard_Integer nF2,
1667       TColStd_ListOfInteger& theLI,
1668       const Handle(NCollection_BaseAllocator)& aAllocator)
1669 {
1670   Standard_Integer nE, nSp;
1671   TColStd_ListIteratorOfListOfInteger aItLI;
1672   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1673   TColStd_MapOfInteger aMI(100, aAllocator);
1674   //
1675   const BOPDS_ShapeInfo& aSI1=ShapeInfo(nF1);
1676   const TColStd_ListOfInteger& aLI1=aSI1.SubShapes();
1677   aItLI.Initialize(aLI1);
1678   for (; aItLI.More(); aItLI.Next()) {
1679     nE=aItLI.Value();
1680     const BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
1681     if(aSIE.ShapeType()==TopAbs_EDGE) {
1682       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1683       if (aLPB.IsEmpty()) {
1684         aMI.Add(nE);
1685       }
1686       else {
1687         aItLPB.Initialize(aLPB);
1688         for (; aItLPB.More(); aItLPB.Next()) {
1689           const Handle(BOPDS_PaveBlock) aPB=RealPaveBlock(aItLPB.Value());
1690           nSp=aPB->Edge();
1691           aMI.Add(nSp);
1692         }
1693       }
1694     }
1695   }
1696   //
1697   const BOPDS_ShapeInfo& aSI2=ShapeInfo(nF2);
1698   const TColStd_ListOfInteger& aLI2=aSI2.SubShapes();
1699   aItLI.Initialize(aLI2);
1700   for (; aItLI.More(); aItLI.Next()) {
1701     nE=aItLI.Value();
1702     const BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
1703     if(aSIE.ShapeType()==TopAbs_EDGE) {
1704       const BOPDS_ListOfPaveBlock& aLPB=PaveBlocks(nE);
1705       if (aLPB.IsEmpty()) {
1706         if (aMI.Contains(nE)) {
1707           theLI.Append(nE);
1708         }
1709       }
1710       else {
1711         aItLPB.Initialize(aLPB);
1712         for (; aItLPB.More(); aItLPB.Next()) {
1713           const Handle(BOPDS_PaveBlock) aPB=RealPaveBlock(aItLPB.Value());
1714           nSp=aPB->Edge();
1715           if (aMI.Contains(nSp)) {
1716             theLI.Append(nSp);
1717           }
1718         }
1719       }
1720     }
1721   }
1722 }
1723 
1724 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1725 //
1726 // same domain shapes
1727 //
1728 //=======================================================================
1729 //function : ShapesSD
1730 //purpose  :
1731 //=======================================================================
ShapesSD()1732 TColStd_DataMapOfIntegerInteger& BOPDS_DS::ShapesSD()
1733 {
1734   return myShapesSD;
1735 }
1736 //=======================================================================
1737 //function : AddShapeSD
1738 //purpose  :
1739 //=======================================================================
AddShapeSD(const Standard_Integer theIndex,const Standard_Integer theIndexSD)1740 void BOPDS_DS::AddShapeSD(const Standard_Integer theIndex,
1741                           const Standard_Integer theIndexSD)
1742 {
1743   if (theIndex != theIndexSD)
1744     myShapesSD.Bind(theIndex, theIndexSD);
1745 }
1746 //=======================================================================
1747 //function : HasShapeSD
1748 //purpose  :
1749 //=======================================================================
HasShapeSD(const Standard_Integer theIndex,Standard_Integer & theIndexSD) const1750 Standard_Boolean BOPDS_DS::HasShapeSD
1751   (const Standard_Integer theIndex,
1752    Standard_Integer& theIndexSD)const
1753 {
1754   Standard_Boolean bHasSD = Standard_False;
1755   const Standard_Integer *pSD = myShapesSD.Seek(theIndex);
1756   while (pSD) {
1757     theIndexSD = *pSD;
1758     bHasSD = Standard_True;
1759     pSD = myShapesSD.Seek(theIndexSD);
1760   }
1761   return bHasSD;
1762 }
1763 //=======================================================================
1764 //function : Dump
1765 //purpose  :
1766 //=======================================================================
Dump() const1767 void BOPDS_DS::Dump()const
1768 {
1769   Standard_Integer i, aNb, aNbSS;
1770   //
1771   printf(" *** DS ***\n");
1772   aNb=NbRanges();
1773   printf(" Ranges:%d\n", aNb);
1774   for (i=0; i<aNb; ++i) {
1775     const BOPDS_IndexRange& aR=Range(i);
1776     aR.Dump();
1777     printf("\n");
1778   }
1779   //
1780   aNbSS=NbSourceShapes();
1781   printf(" Shapes:%d\n", aNbSS);
1782   aNb=NbShapes();
1783   for (i=0; i<aNb; ++i) {
1784     const BOPDS_ShapeInfo& aSI=ShapeInfo(i);
1785     printf(" %d :", i);
1786     aSI.Dump();
1787     printf("\n");
1788     if (i==aNbSS-1) {
1789       printf(" ****** adds\n");
1790     }
1791   }
1792   printf(" ******\n");
1793 }
1794 
1795 //=======================================================================
1796 // function: CheckCoincidence
1797 // purpose:
1798 //=======================================================================
CheckCoincidence(const Handle (BOPDS_PaveBlock)& aPB1,const Handle (BOPDS_PaveBlock)& aPB2,const Standard_Real theFuzz)1799 Standard_Boolean BOPDS_DS::CheckCoincidence
1800   (const Handle(BOPDS_PaveBlock)& aPB1,
1801    const Handle(BOPDS_PaveBlock)& aPB2,
1802    const Standard_Real theFuzz)
1803 {
1804   Standard_Boolean bRet;
1805   Standard_Integer nE1, nE2, aNbPoints;
1806   Standard_Real aT11, aT12, aT21, aT22, aT1m, aD, aTol, aT2x;
1807   gp_Pnt aP1m;
1808   //
1809   bRet=Standard_False;
1810   //
1811   aPB1->Range(aT11, aT12);
1812   aT1m=IntTools_Tools::IntermediatePoint (aT11, aT12);
1813   nE1=aPB1->OriginalEdge();
1814   const TopoDS_Edge& aE1=(*(TopoDS_Edge*)(&Shape(nE1)));
1815   BOPTools_AlgoTools::PointOnEdge(aE1, aT1m, aP1m);
1816   //
1817   aPB2->Range(aT21, aT22);
1818   nE2=aPB2->OriginalEdge();
1819   const TopoDS_Edge& aE2=(*(TopoDS_Edge*)(&Shape(nE2)));
1820   //
1821   Standard_Real f, l;
1822   Handle(Geom_Curve)aC2 = BRep_Tool::Curve (aE2, f, l);
1823   GeomAPI_ProjectPointOnCurve aPPC;
1824   aPPC.Init(aC2, f, l);
1825   aPPC.Perform(aP1m);
1826   aNbPoints=aPPC.NbPoints();
1827   if (aNbPoints) {
1828     aD=aPPC.LowerDistance();
1829     //
1830     aTol = BRep_Tool::MaxTolerance(aE1, TopAbs_VERTEX);
1831     aTol = aTol + BRep_Tool::MaxTolerance(aE2, TopAbs_VERTEX) + Max(theFuzz, Precision::Confusion());
1832     if (aD<aTol) {
1833       aT2x=aPPC.LowerDistanceParameter();
1834       if (aT2x>aT21 && aT2x<aT22) {
1835         return !bRet;
1836       }
1837     }
1838   }
1839   return bRet;
1840 }
1841 //=======================================================================
1842 // function: IsSubShape
1843 // purpose:
1844 //=======================================================================
IsSubShape(const Standard_Integer theI1,const Standard_Integer theI2)1845 Standard_Boolean BOPDS_DS::IsSubShape
1846   (const Standard_Integer theI1,
1847    const Standard_Integer theI2)
1848 {
1849   Standard_Boolean bRet;
1850   Standard_Integer nS;
1851   bRet = Standard_False;
1852   //
1853   TColStd_ListIteratorOfListOfInteger aItLI;
1854   //
1855   const BOPDS_ShapeInfo& aSI = ShapeInfo(theI2);
1856   const TColStd_ListOfInteger& aLI = aSI.SubShapes();
1857   aItLI.Initialize(aLI);
1858   for(;aItLI.More(); aItLI.Next()) {
1859     nS = aItLI.Value();
1860     if (nS == theI1) {
1861       bRet = Standard_True;
1862       break;
1863     }
1864   }
1865 
1866   return bRet;
1867 }
1868 //=======================================================================
1869 // function: Paves
1870 // purpose:
1871 //=======================================================================
Paves(const Standard_Integer theEdge,BOPDS_ListOfPave & theLP)1872 void BOPDS_DS::Paves(const Standard_Integer theEdge,
1873                      BOPDS_ListOfPave& theLP)
1874 {
1875   Standard_Integer aNb, i;
1876   BOPDS_ListIteratorOfListOfPaveBlock aIt;
1877   BOPDS_MapOfPave aMP;
1878   //
1879   const BOPDS_ListOfPaveBlock& aLPB = PaveBlocks(theEdge);
1880   aNb = aLPB.Extent() + 1;
1881   if (aNb == 1) {
1882     return;
1883   }
1884   //
1885   BOPDS_VectorOfPave pPaves(1, aNb);
1886   //
1887   i = 1;
1888   aIt.Initialize(aLPB);
1889   for (; aIt.More(); aIt.Next()) {
1890     const Handle(BOPDS_PaveBlock)& aPB = aIt.Value();
1891     const BOPDS_Pave& aPave1 = aPB->Pave1();
1892     const BOPDS_Pave& aPave2 = aPB->Pave2();
1893     //
1894     if (aMP.Add(aPave1)){
1895       pPaves(i) = aPave1;
1896       ++i;
1897     }
1898     //
1899     if (aMP.Add(aPave2)){
1900       pPaves(i) = aPave2;
1901       ++i;
1902     }
1903   }
1904   //
1905   Standard_ASSERT_VOID(aNb == aMP.Extent(), "Abnormal number of paves");
1906   //
1907   std::sort(pPaves.begin(), pPaves.end());
1908   //
1909   for (i = 1; i <= aNb; ++i) {
1910     theLP.Append(pPaves(i));
1911   }
1912 }
1913 //=======================================================================
1914 //function : TotalShapes
1915 //purpose  :
1916 //=======================================================================
TotalShapes(const TopoDS_Shape & aS,Standard_Integer & aNbS,TopTools_MapOfShape & aMS)1917 void TotalShapes(const TopoDS_Shape& aS,
1918                  Standard_Integer& aNbS,
1919                  TopTools_MapOfShape& aMS)
1920 {
1921   if (aMS.Add(aS)) {
1922     TopoDS_Iterator aIt;
1923     ++aNbS;
1924     aIt.Initialize(aS);
1925     for (; aIt.More(); aIt.Next()) {
1926       const TopoDS_Shape& aSx=aIt.Value();
1927       TotalShapes(aSx, aNbS, aMS);
1928     }
1929   }
1930 }
1931 
1932 //=======================================================================
1933 //function : ComputeParameter
1934 //purpose  :
1935 //=======================================================================
ComputeParameter(const TopoDS_Vertex & aV,const TopoDS_Edge & aE)1936 Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
1937                                const TopoDS_Edge& aE)
1938 {
1939   Standard_Real aT1, aT2, aTRet, aTolE2, aD2;
1940   gp_Pnt aPC, aPV;
1941   Handle(Geom_Curve) aC3D;
1942   TopoDS_Edge aEE;
1943   //
1944   aEE=aE;
1945   aEE.Orientation(TopAbs_FORWARD);
1946   //
1947   aTRet=0.;
1948   //
1949   aTolE2=BRep_Tool::Tolerance(aE);
1950   aTolE2=aTolE2*aTolE2;
1951   //
1952   aPV=BRep_Tool::Pnt(aV);
1953   //
1954   aC3D=BRep_Tool::Curve (aEE, aT1, aT2);
1955   //
1956   aC3D->D0(aT1, aPC);
1957   aD2=aPC.SquareDistance(aPV);
1958   if (aD2<aTolE2) {
1959     aTRet=aT1;
1960   }
1961   //
1962   aC3D->D0(aT2, aPC);
1963   aD2=aPC.SquareDistance(aPV);
1964   if (aD2<aTolE2) {
1965     aTRet=aT2;
1966   }
1967   //
1968   return aTRet;
1969 }
1970 //=======================================================================
1971 //function : BuildBndBoxSolid
1972 //purpose  :
1973 //=======================================================================
BuildBndBoxSolid(const Standard_Integer theIndex,Bnd_Box & aBoxS,const Standard_Boolean theCheckInverted)1974 void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
1975                                 Bnd_Box& aBoxS,
1976                                 const Standard_Boolean theCheckInverted)
1977 {
1978   Standard_Boolean bIsOpenBox, bIsInverted;
1979   Standard_Integer nSh, nFc;
1980   Standard_Real aTolS, aTolFc;
1981   TColStd_ListIteratorOfListOfInteger aItLI, aItLI1;
1982   //
1983   const BOPDS_ShapeInfo& aSI=ShapeInfo(theIndex);
1984   const TopoDS_Shape& aS=aSI.Shape();
1985   const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
1986   //
1987   bIsOpenBox=Standard_False;
1988   //
1989   aTolS=0.;
1990   const TColStd_ListOfInteger& aLISh=aSI.SubShapes();
1991   aItLI.Initialize(aLISh);
1992   for (; aItLI.More(); aItLI.Next()) {
1993     nSh=aItLI.Value();
1994     const BOPDS_ShapeInfo& aSISh=ShapeInfo(nSh);
1995     if (aSISh.ShapeType()!=TopAbs_SHELL) {
1996       continue;
1997     }
1998     //
1999     const TColStd_ListOfInteger& aLIFc=aSISh.SubShapes();
2000     aItLI1.Initialize(aLIFc);
2001     for (; aItLI1.More(); aItLI1.Next()) {
2002       nFc=aItLI1.Value();
2003       const BOPDS_ShapeInfo& aSIFc=ShapeInfo(nFc);
2004       if (aSIFc.ShapeType()!=TopAbs_FACE) {
2005         continue;
2006       }
2007       //
2008       const Bnd_Box& aBFc=aSIFc.Box();
2009       aBoxS.Add(aBFc);
2010       //
2011       if (!bIsOpenBox) {
2012         bIsOpenBox=(aBFc.IsOpenXmin() || aBFc.IsOpenXmax() ||
2013                     aBFc.IsOpenYmin() || aBFc.IsOpenYmax() ||
2014                     aBFc.IsOpenZmin() || aBFc.IsOpenZmax());
2015         if (bIsOpenBox) {
2016           break;
2017         }
2018       }
2019       //
2020       const TopoDS_Face& aFc=*((TopoDS_Face*)&aSIFc.Shape());
2021       aTolFc=BRep_Tool::Tolerance(aFc);
2022       if (aTolFc>aTolS) {
2023         aTolS=aTolFc;
2024       }
2025     }//for (; aItLI1.More(); aItLI1.Next()) {
2026     if (bIsOpenBox) {
2027       break;
2028     }
2029     //
2030     const TopoDS_Shell& aSh=*((TopoDS_Shell*)&aSISh.Shape());
2031     bIsOpenBox=BOPTools_AlgoTools::IsOpenShell(aSh);
2032     if (bIsOpenBox) {
2033       break;
2034     }
2035   }//for (; aItLI.More(); aItLI.Next()) {
2036   //
2037   if (bIsOpenBox) {
2038     aBoxS.SetWhole();
2039   }
2040   else if (theCheckInverted) {
2041     bIsInverted=BOPTools_AlgoTools::IsInvertedSolid(aSolid);
2042     if (bIsInverted) {
2043       aBoxS.SetWhole();
2044     }
2045   }
2046 }
2047 
2048 //=======================================================================
2049 //function : UpdatePaveBlocksWithSDVertices
2050 //purpose  :
2051 //=======================================================================
UpdatePaveBlocksWithSDVertices()2052 void BOPDS_DS::UpdatePaveBlocksWithSDVertices()
2053 {
2054   Standard_Integer i, aNbPBP;
2055   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2056   //
2057   BOPDS_VectorOfListOfPaveBlock& aPBP=myPaveBlocksPool;
2058   //
2059   aNbPBP=aPBP.Size();
2060   for (i = 0; i < aNbPBP; ++i) {
2061     BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2062     //
2063     aItPB.Initialize(aLPB);
2064     for (; aItPB.More(); aItPB.Next()) {
2065       Handle(BOPDS_PaveBlock)& aPB = aItPB.ChangeValue();
2066       UpdatePaveBlockWithSDVertices(aPB);
2067     }// for (; aItPB.More(); aItPB.Next()) {
2068   }// for (i = 0; i < aNbPBP; ++i) {
2069 }
2070 //=======================================================================
2071 //function : UpdatePaveBlockWithSDVertices
2072 //purpose  :
2073 //=======================================================================
UpdatePaveBlockWithSDVertices(const Handle (BOPDS_PaveBlock)& thePB)2074 void BOPDS_DS::UpdatePaveBlockWithSDVertices
2075   (const Handle(BOPDS_PaveBlock)& thePB)
2076 {
2077   Standard_Integer nV1, nV2;
2078   BOPDS_Pave aPave1, aPave2;
2079   //
2080   aPave1 = thePB->Pave1();
2081   aPave2 = thePB->Pave2();
2082   //
2083   nV1 = aPave1.Index();
2084   nV2 = aPave2.Index();
2085   //
2086   if (HasShapeSD(nV1, nV1)) {
2087     aPave1.SetIndex(nV1);
2088     thePB->SetPave1(aPave1);
2089   }
2090   //
2091   if (HasShapeSD(nV2, nV2)) {
2092     aPave2.SetIndex(nV2);
2093     thePB->SetPave2(aPave2);
2094   }
2095 }
2096 //=======================================================================
2097 //function : UpdateCommonBlockWithSDVertices
2098 //purpose  :
2099 //=======================================================================
UpdateCommonBlockWithSDVertices(const Handle (BOPDS_CommonBlock)& theCB)2100 void BOPDS_DS::UpdateCommonBlockWithSDVertices
2101   (const Handle(BOPDS_CommonBlock)& theCB)
2102 {
2103   const BOPDS_ListOfPaveBlock& aLPB = theCB->PaveBlocks();
2104   BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2105   for (; aItPB.More(); aItPB.Next()) {
2106     const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2107     UpdatePaveBlockWithSDVertices(aPB);
2108   }
2109 }
2110 //=======================================================================
2111 //function : InitPaveBlocksForVertex
2112 //purpose  :
2113 //=======================================================================
InitPaveBlocksForVertex(const Standard_Integer theNV)2114 void BOPDS_DS::InitPaveBlocksForVertex(const Standard_Integer theNV)
2115 {
2116   const TColStd_ListOfInteger* pLE = myMapVE.Seek(theNV);
2117   if (!pLE)
2118     return;
2119 
2120   TColStd_ListIteratorOfListOfInteger aItLE(*pLE);
2121   for (; aItLE.More(); aItLE.Next())
2122     ChangePaveBlocks(aItLE.Value());
2123 }
2124 
2125 //=======================================================================
2126 //function : ReleasePaveBlocks
2127 //purpose  :
2128 //=======================================================================
ReleasePaveBlocks()2129 void BOPDS_DS::ReleasePaveBlocks()
2130 {
2131   // It is necessary to remove the reference to PaveBlocks for the untouched
2132   // edges to avoid creation of the same images for them.
2133   // Pave blocks for this reference should be cleared.
2134   // This will allow to differ the small edges, for which it is
2135   // impossible to even build a pave block from the normal edges for which the
2136   // pave block have been created, but stayed untouched.
2137   // The small edge, for which no pave blocks have been created,
2138   // should be avoided in the result, thus the reference to empty list
2139   // of pave blocks will stay to mark the edge as Deleted.
2140 
2141   BOPDS_VectorOfListOfPaveBlock& aPBP = ChangePaveBlocksPool();
2142   Standard_Integer aNbPBP = aPBP.Length();
2143   if (!aNbPBP) {
2144     return;
2145   }
2146   //
2147   for (Standard_Integer i = 0; i < aNbPBP; ++i) {
2148     BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2149     if (aLPB.Extent() == 1) {
2150       const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
2151       if (!IsCommonBlock(aPB)) {
2152         Standard_Integer nV1, nV2;
2153         aPB->Indices(nV1, nV2);
2154         if (!IsNewShape(nV1) && !IsNewShape(nV2)) {
2155           // Both vertices are original, thus the PB is untouched.
2156           // Remove reference for the original edge
2157           Standard_Integer nE = aPB->OriginalEdge();
2158           if (nE >= 0) {
2159             ChangeShapeInfo(nE).SetReference(-1);
2160           }
2161           // Clear contents of the list
2162           aLPB.Clear();
2163         }
2164       }
2165     }
2166   }
2167 }
2168 
2169 //=======================================================================
2170 //function : IsValidShrunkData
2171 //purpose  :
2172 //=======================================================================
IsValidShrunkData(const Handle (BOPDS_PaveBlock)& thePB)2173 Standard_Boolean BOPDS_DS::IsValidShrunkData(const Handle(BOPDS_PaveBlock)& thePB)
2174 {
2175   if (!thePB->HasShrunkData())
2176     return Standard_False;
2177 
2178   // Compare the distances from the bounds of the shrunk range to the vertices
2179   // with the tolerance values of vertices
2180 
2181   // Shrunk range
2182   Standard_Real aTS[2];
2183   Bnd_Box aBox;
2184   Standard_Boolean bIsSplit;
2185   //
2186   thePB->ShrunkData(aTS[0], aTS[1], aBox, bIsSplit);
2187   //
2188   // Vertices
2189   Standard_Integer nV[2];
2190   thePB->Indices(nV[0], nV[1]);
2191   //
2192   const TopoDS_Edge& aE = TopoDS::Edge(Shape(thePB->OriginalEdge()));
2193   BRepAdaptor_Curve aBAC(aE);
2194   //
2195   Standard_Real anEps = BRep_Tool::Tolerance(aE) * 0.01;
2196   //
2197   for (Standard_Integer i = 0; i < 2; ++i) {
2198     const TopoDS_Vertex& aV = TopoDS::Vertex(Shape(nV[i]));
2199     Standard_Real aTol = BRep_Tool::Tolerance(aV) + Precision::Confusion();
2200     // Bounding point
2201     gp_Pnt aP = BRep_Tool::Pnt(aV);
2202     //
2203     // Point on the end of shrunk range
2204     gp_Pnt aPS = aBAC.Value(aTS[i]);
2205     //
2206     Standard_Real aDist = aP.Distance(aPS);
2207     if (aTol - aDist > anEps) {
2208       return Standard_False;
2209     }
2210   }
2211   return Standard_True;
2212 }