Salome HOME
Merging with WPdev
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_WESCorrector.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 // File:        NMTAlgo_WESCorrector.cxx
21 // Created:     
22 // Author:      Peter KURNEV
23 //              <pkv@irinox>
24
25
26 #include <GEOMAlgo_WESCorrector.ixx>
27
28 #include <TopoDS.hxx>
29 #include <TopoDS_Shape.hxx>
30 #include <TopoDS_Wire.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Edge.hxx>
33
34 #include <BRep_Builder.hxx>
35 #include <BRep_Tool.hxx>
36
37 #include <TopTools_IndexedMapOfOrientedShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39
40 #include <BOP_ConnexityBlock.hxx>
41 #include <BOP_ListIteratorOfListOfConnexityBlock.hxx>
42
43 #include <BOPTColStd_ListOfListOfShape.hxx>
44 #include <BOPTColStd_ListIteratorOfListOfListOfShape.hxx>
45
46 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
47 #include <NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx>
48 #include <TopExp.hxx>
49 #include <TopTools_IndexedMapOfShape.hxx>
50 #include <TopTools_MapOfShape.hxx>
51 #include <TopTools_MapIteratorOfMapOfShape.hxx>
52 #include <TopoDS_Iterator.hxx>
53 #include <GEOMAlgo_WireSplitter.hxx>
54
55
56 static
57   void MakeWire(const TopTools_ListOfShape& aLE, 
58                 TopoDS_Wire& newWire);
59
60 //=======================================================================
61 // function: 
62 // purpose: 
63 //=======================================================================
64   GEOMAlgo_WESCorrector::GEOMAlgo_WESCorrector()
65 :
66   GEOMAlgo_Algo()
67 {
68 }
69 //=======================================================================
70 // function: ~
71 // purpose: 
72 //=======================================================================
73   GEOMAlgo_WESCorrector::~GEOMAlgo_WESCorrector()
74 {
75 }
76 //=======================================================================
77 // function: SetWES
78 // purpose: 
79 //=======================================================================
80   void GEOMAlgo_WESCorrector::SetWES (const GEOMAlgo_WireEdgeSet& aWES)
81 {
82   GEOMAlgo_WireEdgeSet* pWES=(GEOMAlgo_WireEdgeSet*) &aWES;
83   myWES=pWES;
84 }
85 //=======================================================================
86 // function: WES
87 // purpose: 
88 //=======================================================================
89   GEOMAlgo_WireEdgeSet& GEOMAlgo_WESCorrector::WES () 
90 {
91   return *myWES;
92 }
93 //=======================================================================
94 // function: NewWES
95 // purpose: 
96 //=======================================================================
97   GEOMAlgo_WireEdgeSet& GEOMAlgo_WESCorrector::NewWES () 
98 {
99   return myNewWES;
100 }
101 //=======================================================================
102 // function: Perform
103 // purpose: 
104 //=======================================================================
105   void GEOMAlgo_WESCorrector::Perform()
106 {
107   myErrorStatus=0;
108   //
109   DoConnexityBlocks();
110   DoCorrections();
111 }
112 //=======================================================================
113 // function: DoConnexityBlocks
114 // purpose: 
115 //=======================================================================
116   void GEOMAlgo_WESCorrector::DoConnexityBlocks()
117 {
118   Standard_Boolean bRegular;
119   Standard_Integer i, aNbV, j, aNbC, aNbVP, aNbVS;
120   TopTools_ListIteratorOfListOfShape aIt;
121   TopoDS_Iterator aItE;
122   TopoDS_Shape aER;
123   TopTools_IndexedMapOfShape aMER, aMEP, aMEC, aMVP;
124   TopTools_IndexedMapOfShape aMVS, aMVAdd;
125   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
126   //
127   // 1. aMVE;
128   const TopTools_ListOfShape& aLSE=myWES->StartElements();
129   aIt.Initialize(aLSE);
130   for (; aIt.More(); aIt.Next()) {
131     const TopoDS_Shape& aE=aIt.Value();
132     if (!aMEP.Contains(aE)) {
133       aMEP.Add(aE);
134       TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
135     }
136     else {
137       aMER.Add(aE);
138     }
139   }
140   //
141   // 2. 
142   aNbV=aMVE.Extent();
143   for (i=1; i<=aNbV; ++i) {
144     const TopoDS_Shape& aV=aMVE.FindKey(i);
145     //
146     aNbVS=aMVS.Extent();
147     if (aNbVS==aNbV) {
148       break;
149     }
150     //
151     if (aMVS.Contains(aV)) {
152       continue;
153     }
154     aMVS.Add(aV);    // aMVS - globally processed vertices
155     //
156     //------------------------------------- goal: aMEC
157     aMEC.Clear();    // aMEC - edges of CB
158     aMVP.Clear();    // aMVP - vertices to process right now 
159     aMVAdd.Clear();  // aMVAdd vertices to process on next step of while(1)
160     //
161     aMVP.Add(aV);
162     //
163     while(1) {
164       aNbVP=aMVP.Extent();
165       for (j=1; j<=aNbVP; ++j) {
166         const TopoDS_Shape& aVP=aMVP(j);
167         const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aVP);
168         aIt.Initialize(aLE);
169         for (; aIt.More(); aIt.Next()) {
170           const TopoDS_Shape& aE=aIt.Value();
171           if (aMEC.Contains(aE)) {
172             continue;
173           }
174           aMEC.Add(aE);
175           //
176           aItE.Initialize(aE);
177           for (; aItE.More(); aItE.Next()) {
178             const TopoDS_Shape& aVE=aItE.Value();
179             if (!aMVS.Contains(aVE)) {
180               aMVS.Add(aVE);
181               aMVAdd.Add(aVE);
182             }
183           }
184         }
185       }//for (j=1; j<=aNbVP; ++j) 
186       //
187       aNbVP=aMVAdd.Extent();
188       if (!aNbVP) {
189         break; // from while(1)
190       }
191       //
192       aMVP.Clear();
193       for (j=1; j<=aNbVP; ++j) {
194         const TopoDS_Shape& aVE=aMVAdd(j);
195         aMVP.Add(aVE);
196       }
197       aMVAdd.Clear();
198     }// while(1) {
199     //-------------------------------------
200     BOP_ConnexityBlock aCB;
201     TopTools_ListOfShape aLEC;
202     TopTools_IndexedDataMapOfShapeListOfShape aMVER;
203     //
204     bRegular=Standard_True;
205    
206     aNbC=aMEC.Extent();
207     for (j=1; j<=aNbC; ++j) {
208       aER=aMEC(j);
209       //
210       if (aMER.Contains(aER)) {
211         Standard_Boolean bClosed;
212         //
213         aER.Orientation(TopAbs_FORWARD);
214         aLEC.Append(aER);
215         aER.Orientation(TopAbs_REVERSED);
216         aLEC.Append(aER);
217         //
218         bClosed=BRep_Tool::IsClosed(TopoDS::Edge(aER), myWES->Face());
219         if (!bClosed) {
220           bRegular=Standard_False;
221         }
222       }
223       else {
224         aLEC.Append(aER);
225       }
226       //
227       if (bRegular) {
228         TopExp::MapShapesAndAncestors(aER, TopAbs_VERTEX, TopAbs_EDGE, aMVER);
229       }
230     }//for (j=1; j<=aNbC; ++j) {
231     //
232     if (bRegular) {
233       Standard_Integer k, aNbVR, aNbER;
234       //
235       aNbVR=aMVER.Extent();
236       for (k=1; k<=aNbVR; ++k) {
237         const TopTools_ListOfShape& aLER=aMVER(k);//?? it was aMVE(k)
238         aNbER=aLER.Extent();
239         if (aNbER==1) {
240           const TopoDS_Edge& aEx=TopoDS::Edge(aER);
241           if (!BRep_Tool::IsClosed(aEx, myWES->Face())) {
242             bRegular=!bRegular;
243             break;
244           }
245         }
246         if (aNbER>2) {
247           bRegular=!bRegular;
248           break;
249         }
250       }
251     }
252     //
253     aCB.SetShapes(aLEC);
254     aCB.SetRegularity(bRegular);
255     myConnexityBlocks.Append(aCB);
256     aMEC.Clear();
257   }//for (i=1; i<=aNbV; ++i) {
258 }
259
260 //=======================================================================
261 // function: DoCorrections
262 // purpose: 
263 //=======================================================================
264   void GEOMAlgo_WESCorrector::DoCorrections()
265 {
266   Standard_Boolean bIsRegular, bIsNothingToDo;
267   Standard_Integer iErr;
268   TopoDS_Wire aW;
269   BOP_ListIteratorOfListOfConnexityBlock aCBIt;
270   //
271   const TopoDS_Face& aF=myWES->Face();
272   //
273   myNewWES.SetFace(aF);
274   aCBIt.Initialize(myConnexityBlocks);
275   for (; aCBIt.More(); aCBIt.Next()) {
276     const BOP_ConnexityBlock& aCB=aCBIt.Value();
277     const TopTools_ListOfShape& aLE=aCB.Shapes();
278
279     bIsRegular=aCB.IsRegular();
280
281     if (bIsRegular) {
282       MakeWire(aLE, aW);
283       myNewWES.AddShape (aW);
284       continue;
285     }
286     //
287     GEOMAlgo_WireSplitter aWS;
288     //
289     aWS.SetFace(aF);
290     aWS.SetEdges(aLE);
291     //
292     aWS.Perform();
293     iErr=aWS.ErrorStatus();
294     if (iErr) {
295       continue;
296     }
297     bIsNothingToDo=aWS.IsNothingToDo();
298     if (bIsNothingToDo) {
299       MakeWire(aLE, aW);
300       myNewWES.AddShape (aW);
301       continue;
302     }
303     //
304     const BOPTColStd_ListOfListOfShape& aSSS=aWS.Shapes();
305     
306     BOPTColStd_ListIteratorOfListOfListOfShape aWireIt(aSSS);
307     for (; aWireIt.More(); aWireIt.Next()) {
308       const TopTools_ListOfShape& aLEx=aWireIt.Value();
309       //
310       MakeWire(aLEx, aW);
311       myNewWES.AddShape (aW);
312     }
313   }
314 }
315 //=======================================================================
316 // function: MakeWire
317 // purpose: 
318 //=======================================================================
319   void MakeWire(const TopTools_ListOfShape& aLE, 
320                 TopoDS_Wire& newWire)
321 {
322   BRep_Builder aBB;
323   aBB.MakeWire(newWire);
324
325   TopTools_ListIteratorOfListOfShape anIt(aLE);
326   for (; anIt.More(); anIt.Next()){
327     const TopoDS_Edge& aE=TopoDS::Edge(anIt.Value());
328     aBB.Add(newWire, aE);
329   }
330 }