0026586: Eliminate compile warnings obtained by building occt with vc14: declaration...
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <BOPAlgo_WireEdgeSet.hxx>
18 #include <BOPAlgo_WireSplitter.hxx>
19 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
20 #include <BOPCol_IndexedMapOfShape.hxx>
21 #include <BOPCol_ListOfShape.hxx>
22 #include <BOPCol_MapOfShape.hxx>
23 #include <BOPCol_NCVector.hxx>
24 #include <BOPCol_Parallel.hxx>
25 #include <BOPTools.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRep_Tool.hxx>
28 #include <TopoDS.hxx>
29 #include <TopoDS_Edge.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Iterator.hxx>
32 #include <TopoDS_Shape.hxx>
33 #include <TopoDS_Wire.hxx>
34
35 //=======================================================================
36 //function : 
37 //purpose  : 
38 //=======================================================================
39 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter()
40 :
41   BOPAlgo_Algo(),
42   myWES(NULL),
43   myLCB(myAllocator)
44 {
45 }
46 //=======================================================================
47 //function : 
48 //purpose  : 
49 //=======================================================================
50 BOPAlgo_WireSplitter::BOPAlgo_WireSplitter
51   (const Handle(NCollection_BaseAllocator)& theAllocator)
52 :
53   BOPAlgo_Algo(theAllocator),
54   myWES(NULL),
55   myLCB(myAllocator)
56 {
57 }
58 //=======================================================================
59 //function : ~
60 //purpose  : 
61 //=======================================================================
62 BOPAlgo_WireSplitter::~BOPAlgo_WireSplitter()
63 {
64 }
65 //=======================================================================
66 //function : SetWES
67 //purpose  : 
68 //=======================================================================
69 void BOPAlgo_WireSplitter::SetWES(const BOPAlgo_WireEdgeSet& theWES)
70 {
71   myWES=(BOPAlgo_WireEdgeSet*)&theWES;
72 }
73 //=======================================================================
74 //function : WES
75 //purpose  : 
76 //=======================================================================
77 BOPAlgo_WireEdgeSet& BOPAlgo_WireSplitter::WES()
78 {
79   return *myWES;
80 }
81 //=======================================================================
82 // function: CheckData
83 // purpose: 
84 //=======================================================================
85 void BOPAlgo_WireSplitter::CheckData()
86 {
87   myErrorStatus=0;
88   if (!myWES) {
89     myErrorStatus=10;
90     return;
91   }
92 }
93 //=======================================================================
94 //function : Perform
95 //purpose  : 
96 //=======================================================================
97 void BOPAlgo_WireSplitter::Perform()
98 {
99   myErrorStatus=0;
100   //
101   CheckData();
102   if (myErrorStatus) {
103     return;
104   }
105   //
106   MakeConnexityBlocks();
107   MakeWires();
108 }
109
110 //=======================================================================
111 //function : MakeConnexityBlocks
112 //purpose  : 
113 //=======================================================================
114 void BOPAlgo_WireSplitter::MakeConnexityBlocks()
115 {
116   Standard_Boolean bRegular, bClosed;
117   Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
118   TopoDS_Iterator aItE;
119   TopoDS_Shape aER;
120   BOPCol_ListIteratorOfListOfShape aIt;
121   //
122   BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
123   BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
124   BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
125   BOPCol_MapOfShape aMER(100, myAllocator);
126   BOPCol_MapOfShape aMEP(100, myAllocator);
127   BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
128   BOPCol_MapOfShape aMVS(100, myAllocator);
129   //
130   myLCB.Clear();
131   //
132   const BOPCol_ListOfShape& aLSE=myWES->StartElements();
133   aIt.Initialize(aLSE);
134   for (; aIt.More(); aIt.Next()) {
135     const TopoDS_Shape& aE=aIt.Value();
136     if (aMEP.Add(aE)) {
137       BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
138     }
139     else {
140       aMER.Add(aE);
141     }
142   }
143   //
144   // 2
145   aNbV=aMVE.Extent();
146   for (i=1; i<=aNbV; ++i) {
147     aNbVS=aMVS.Extent();
148     if (aNbVS==aNbV) {
149       break;
150     }
151     //
152     const TopoDS_Shape& aV=aMVE.FindKey(i);
153     //
154     if (!aMVS.Add(aV)) {
155       continue;
156     }
157         // aMVS - globally processed vertices
158     //
159     //------------------------------------- goal: aMEC
160     aMEC.Clear();    // aMEC - edges of CB
161     aMVP.Clear();    // aMVP - vertices to process right now 
162     aMVAdd.Clear();  // aMVAdd vertices to process on next step of while(1)
163     //
164     aMVP.Add(aV);
165     //
166     for(;;) {
167       aNbVP=aMVP.Extent();
168       for (k=1; k<=aNbVP; ++k) {
169         const TopoDS_Shape& aVP=aMVP(k);
170         const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
171         aIt.Initialize(aLE);
172         for (; aIt.More(); aIt.Next()) {
173           const TopoDS_Shape& aE=aIt.Value();
174           if (aMEC.Add(aE)) {
175             aItE.Initialize(aE);
176             for (; aItE.More(); aItE.Next()) {
177               const TopoDS_Shape& aVE=aItE.Value();
178               if (aMVS.Add(aVE)) {
179                 aMVAdd.Add(aVE);
180               }
181             }
182           }
183         }
184       }//for (k=1; k<=aNbVP; ++k) {
185       //
186       aNbVP=aMVAdd.Extent();
187       if (!aNbVP) {
188         break; // from while(1)
189       }
190       //
191       aMVP.Clear();
192       //
193       for (k=1; k<=aNbVP; ++k) {
194         const TopoDS_Shape& aVE=aMVAdd(k);
195         aMVP.Add(aVE);
196       }
197       aMVAdd.Clear();
198     }// while(1) {
199
200     //-------------------------------------
201     BOPTools_ConnexityBlock aCB(myAllocator);
202     BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
203     
204     BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
205     //
206     bRegular=Standard_True;
207     Standard_Integer aNbCB = aMEC.Extent();
208     for (j = 1; j <= aNbCB; j++) {
209       aER = aMEC(j);
210       //
211       if (aMER.Contains(aER)) {
212         aER.Orientation(TopAbs_FORWARD);
213         aLEC.Append(aER);
214         aER.Orientation(TopAbs_REVERSED);
215         aLEC.Append(aER);
216         bRegular=Standard_False;
217       }
218       else {
219         aLEC.Append(aER);
220       }
221       //
222       if (bRegular) {
223         BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
224       }
225     }
226     //
227     if (bRegular) {
228       Standard_Integer aNbVR, aNbER;
229       //
230       aNbVR=aMVER.Extent();
231       for (k=1; k<=aNbVR; ++k) {
232         const BOPCol_ListOfShape& aLER=aMVER(k);
233         aNbER=aLER.Extent();
234         if (aNbER==1) {
235           const TopoDS_Edge& aEx=TopoDS::Edge(aER);
236           bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
237           if (!bClosed) {
238             bRegular=!bRegular;
239             break;
240           }
241         }
242         if (aNbER>2) {
243           bRegular=!bRegular;
244           break;
245         }
246       }
247     }
248     //
249     aCB.SetRegular(bRegular);
250     myLCB.Append(aCB);
251   }
252 }
253 /////////////////////////////////////////////////////////////////////////
254
255 typedef BOPCol_NCVector<BOPTools_ConnexityBlock> \
256   BOPTools_VectorOfConnexityBlock;
257
258 //=======================================================================
259 //class    : WireSplitterFunctor
260 //purpose  : 
261 //=======================================================================
262 class BOPAlgo_WireSplitterFunctor
263 {
264 protected:
265   TopoDS_Face myFace;
266   BOPTools_VectorOfConnexityBlock* myPVCB;
267
268 public:
269   //
270   BOPAlgo_WireSplitterFunctor(const TopoDS_Face& aF,
271                               BOPTools_VectorOfConnexityBlock& aVCB)
272   : myFace(aF), myPVCB(&aVCB)
273   {
274   }
275   //
276   void operator()( const Standard_Integer& theIndex ) const
277   {
278     BOPTools_VectorOfConnexityBlock& aVCB = *myPVCB;
279     BOPTools_ConnexityBlock& aCB = aVCB(theIndex);
280     BOPAlgo_WireSplitter::SplitBlock(myFace, aCB);
281   }
282 };
283 //=======================================================================
284 //class    : BOPAlgo_WireSplitterCnt
285 //purpose  : 
286 //=======================================================================
287 class BOPAlgo_WireSplitterCnt
288 {
289 public:
290   //-------------------------------
291   // Perform
292   Standard_EXPORT 
293   static void Perform(const Standard_Boolean bRunParallel,
294                       const TopoDS_Face& aF,
295                       BOPTools_VectorOfConnexityBlock& aVCB)
296   {
297     //
298     BOPAlgo_WireSplitterFunctor aWSF(aF, aVCB);
299     Standard_Integer aNbVCB = aVCB.Extent();
300     //
301     OSD_Parallel::For(0, aNbVCB, aWSF, !bRunParallel);
302   }
303 };
304 //=======================================================================
305 //function : MakeWires
306 //purpose  : 
307 //=======================================================================
308 void BOPAlgo_WireSplitter::MakeWires()
309 {
310   Standard_Boolean bIsRegular;
311   Standard_Integer aNbVCB, k;
312   TopoDS_Wire aW;
313   BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
314   BOPCol_ListIteratorOfListOfShape aIt;
315   BOPTools_VectorOfConnexityBlock aVCB;
316   //
317   aItCB.Initialize(myLCB);
318   for (; aItCB.More(); aItCB.Next()) {
319     BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
320     bIsRegular=aCB.IsRegular();
321     if (bIsRegular) {
322       BOPCol_ListOfShape& aLE=aCB.ChangeShapes();
323       BOPAlgo_WireSplitter::MakeWire(aLE, aW);
324       myWES->AddShape(aW);
325     }
326     else {
327       aVCB.Append(aCB);
328     }
329   }
330   //
331   aNbVCB=aVCB.Extent();
332   const TopoDS_Face& aF=myWES->Face();
333   //===================================================
334   BOPAlgo_WireSplitterCnt::Perform(myRunParallel, aF, aVCB);
335   //===================================================
336   for (k=0; k<aNbVCB; ++k) {
337     const BOPTools_ConnexityBlock& aCB=aVCB(k);
338     const BOPCol_ListOfShape& aLW=aCB.Loops();
339     aIt.Initialize(aLW);
340     for (; aIt.More(); aIt.Next()) {
341       const TopoDS_Shape& aWx=aIt.Value();
342       myWES->AddShape(aWx);
343     }
344   }
345 }