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