a2ff1b90a9f61ae276777fae0424a96a8dc829f2
[occt.git] / src / BOPAlgo / BOPAlgo_WireSplitter.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #include <BOPAlgo_WireSplitter.ixx>
21
22 #include <TopoDS_Shape.hxx>
23 #include <TopoDS_Iterator.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS.hxx>
26 #include <TopoDS_Wire.hxx>
27
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30
31 #include <BOPCol_ListOfShape.hxx>
32 #include <BOPCol_IndexedMapOfShape.hxx>
33 #include <BOPCol_MapOfShape.hxx>
34 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
35
36 #include <BOPTools.hxx>
37
38
39 //=======================================================================
40 //function : 
41 //purpose  : 
42 //=======================================================================
43   BOPAlgo_WireSplitter::BOPAlgo_WireSplitter()
44 :
45   BOPAlgo_Algo(),
46   myWES(NULL),
47   myLCB(myAllocator)
48 {
49 }
50 //=======================================================================
51 //function : 
52 //purpose  : 
53 //=======================================================================
54   BOPAlgo_WireSplitter::BOPAlgo_WireSplitter(const Handle(NCollection_BaseAllocator)& theAllocator)
55 :
56   BOPAlgo_Algo(theAllocator),
57   myWES(NULL),
58   myLCB(myAllocator)
59 {
60 }
61 //=======================================================================
62 //function : ~
63 //purpose  : 
64 //=======================================================================
65   BOPAlgo_WireSplitter::~BOPAlgo_WireSplitter()
66 {
67 }
68 //=======================================================================
69 //function : SetWES
70 //purpose  : 
71 //=======================================================================
72   void BOPAlgo_WireSplitter::SetWES(const BOPAlgo_WireEdgeSet& theWES)
73 {
74   myWES=(BOPAlgo_WireEdgeSet*)&theWES;
75 }
76 //=======================================================================
77 //function : WES
78 //purpose  : 
79 //=======================================================================
80   BOPAlgo_WireEdgeSet& BOPAlgo_WireSplitter::WES()
81 {
82   return *myWES;
83 }
84 //=======================================================================
85 // function: CheckData
86 // purpose: 
87 //=======================================================================
88   void BOPAlgo_WireSplitter::CheckData()
89 {
90   myErrorStatus=0;
91   if (!myWES) {
92     myErrorStatus=10;
93     return;
94   }
95 }
96 //=======================================================================
97 //function : Perform
98 //purpose  : 
99 //=======================================================================
100   void BOPAlgo_WireSplitter::Perform()
101 {
102   myErrorStatus=0;
103   //
104   CheckData();
105   if (myErrorStatus) {
106     return;
107   }
108   //
109   MakeConnexityBlocks();
110   MakeWires();
111 }
112 //=======================================================================
113 //function : MakeWires
114 //purpose  : 
115 //=======================================================================
116   void BOPAlgo_WireSplitter::MakeWires()
117 {
118   Standard_Boolean bIsRegular;
119   TopoDS_Wire aW;
120   BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
121   BOPCol_ListIteratorOfListOfShape aIt;
122   //
123   aItCB.Initialize(myLCB);
124   for (; aItCB.More(); aItCB.Next()) {
125     BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
126     bIsRegular=aCB.IsRegular();
127     if (bIsRegular) {
128       BOPCol_ListOfShape& aLE=aCB.ChangeShapes();
129       BOPAlgo_WireSplitter::MakeWire(aLE, aW);
130       myWES->AddShape(aW);
131     }
132     else {
133       SplitBlock(aCB);
134       //
135       const BOPCol_ListOfShape& aLW=aCB.Loops();
136       aIt.Initialize(aLW);
137       for (; aIt.More(); aIt.Next()) {
138         const TopoDS_Shape& aWx=aIt.Value();
139         myWES->AddShape(aWx);
140       }
141     }
142   }
143 }
144 //=======================================================================
145 //function : MakeConnexityBlocks
146 //purpose  : 
147 //=======================================================================
148   void BOPAlgo_WireSplitter::MakeConnexityBlocks()
149 {
150   Standard_Boolean bRegular, bClosed;
151   Standard_Integer i, j, aNbV, aNbVS, aNbVP, k;
152   TopoDS_Iterator aItE;
153   TopoDS_Shape aER;
154   BOPCol_ListIteratorOfListOfShape aIt;
155   BOPCol_MapIteratorOfMapOfShape aItM;
156   //
157   BOPCol_IndexedDataMapOfShapeListOfShape aMVE(100, myAllocator);
158   BOPCol_IndexedMapOfShape aMVP(100, myAllocator);
159   BOPCol_IndexedMapOfShape aMEC(100, myAllocator);
160   BOPCol_MapOfShape aMER(100, myAllocator);
161   BOPCol_MapOfShape aMEP(100, myAllocator);
162   BOPCol_IndexedMapOfShape aMVAdd(100, myAllocator);
163   BOPCol_MapOfShape aMVS(100, myAllocator);
164   //
165   myLCB.Clear();
166   //
167   const BOPCol_ListOfShape& aLSE=myWES->StartElements();
168   aIt.Initialize(aLSE);
169   for (; aIt.More(); aIt.Next()) {
170     const TopoDS_Shape& aE=aIt.Value();
171     if (aMEP.Add(aE)) {
172       BOPTools::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
173     }
174     else {
175       aMER.Add(aE);
176     }
177   }
178   //
179   // 2
180   aNbV=aMVE.Extent();
181   for (i=1; i<=aNbV; ++i) {
182     aNbVS=aMVS.Extent();
183     if (aNbVS==aNbV) {
184       break;
185     }
186     //
187     const TopoDS_Shape& aV=aMVE.FindKey(i);
188     //
189     if (!aMVS.Add(aV)) {
190       continue;
191     }
192         // aMVS - globally processed vertices
193     //
194     //------------------------------------- goal: aMEC
195     aMEC.Clear();    // aMEC - edges of CB
196     aMVP.Clear();    // aMVP - vertices to process right now 
197     aMVAdd.Clear();  // aMVAdd vertices to process on next step of while(1)
198     //
199     aMVP.Add(aV);
200     //
201     while(1) {
202       aNbVP=aMVP.Extent();
203       for (k=1; k<=aNbVP; ++k) {
204         const TopoDS_Shape& aVP=aMVP(k);
205         const BOPCol_ListOfShape& aLE=aMVE.FindFromKey(aVP);
206         aIt.Initialize(aLE);
207         for (; aIt.More(); aIt.Next()) {
208           const TopoDS_Shape& aE=aIt.Value();
209           if (aMEC.Add(aE)) {
210             aItE.Initialize(aE);
211             for (; aItE.More(); aItE.Next()) {
212               const TopoDS_Shape& aVE=aItE.Value();
213               if (aMVS.Add(aVE)) {
214                 aMVAdd.Add(aVE);
215               }
216             }
217           }
218         }
219       }//for (; aItM.More(); aItM.Next()) {
220       //
221       aNbVP=aMVAdd.Extent();
222       if (!aNbVP) {
223         break; // from while(1)
224       }
225       //
226       aMVP.Clear();
227       //
228       for (k=1; k<=aNbVP; ++k) {
229         const TopoDS_Shape& aVE=aMVAdd(k);
230         aMVP.Add(aVE);
231       }
232       aMVAdd.Clear();
233     }// while(1) {
234
235     //-------------------------------------
236     BOPTools_ConnexityBlock aCB(myAllocator);
237     BOPCol_ListOfShape& aLEC=aCB.ChangeShapes();
238     
239     BOPCol_IndexedDataMapOfShapeListOfShape aMVER(100, myAllocator);
240     //
241     bRegular=Standard_True;
242     Standard_Integer aNbCB = aMEC.Extent();
243     for (j = 1; j <= aNbCB; j++) {
244       aER = aMEC(j);
245       //
246       if (aMER.Contains(aER)) {
247         aER.Orientation(TopAbs_FORWARD);
248         aLEC.Append(aER);
249         aER.Orientation(TopAbs_REVERSED);
250         aLEC.Append(aER);
251         bRegular=Standard_False;
252       }
253       else {
254         aLEC.Append(aER);
255       }
256       //
257       if (bRegular) {
258         BOPTools::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
259       }
260     }
261     //
262     if (bRegular) {
263       Standard_Integer k, aNbVR, aNbER;
264       //
265       aNbVR=aMVER.Extent();
266       for (k=1; k<=aNbVR; ++k) {
267         const BOPCol_ListOfShape& aLER=aMVER(k);
268         aNbER=aLER.Extent();
269         if (aNbER==1) {
270           const TopoDS_Edge& aEx=TopoDS::Edge(aER);
271           bClosed=BRep_Tool::IsClosed(aEx, myWES->Face());
272           if (!bClosed) {
273             bRegular=!bRegular;
274             break;
275           }
276         }
277         if (aNbER>2) {
278           bRegular=!bRegular;
279           break;
280         }
281       }
282     }
283     //
284     aCB.SetRegular(bRegular);
285     myLCB.Append(aCB);
286   }
287 }