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