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