Salome HOME
Porting to OCCT development version: Standard_PI -> M_PI
[modules/geom.git] / src / GEOMAlgo / GEOMAlgo_Gluer2.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:        GEOMAlgo_Gluer2.cxx
23 // Author:      Peter KURNEV
24
25 #include <GEOMAlgo_Gluer2.hxx>
26
27 #include <TopAbs_ShapeEnum.hxx>
28
29 #include <TopoDS_Compound.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <TopoDS_Shape.hxx>
32 #include <TopoDS_Vertex.hxx>
33
34 #include <BRep_Builder.hxx>
35 #include <TopExp.hxx>
36 #include <BRepLib.hxx>
37
38 #include <TopTools_MapOfShape.hxx>
39 #include <TopTools_MapIteratorOfMapOfShape.hxx>
40 #include <TopTools_DataMapOfShapeShape.hxx>
41 #include <TopTools_ListOfShape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
43 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45
46 #include <GEOMAlgo_GlueDetector.hxx>
47 #include <GEOMAlgo_Tools3D.hxx>
48
49 //=======================================================================
50 //function : GEOMAlgo_Gluer2
51 //purpose  : 
52 //=======================================================================
53 GEOMAlgo_Gluer2::GEOMAlgo_Gluer2()
54 :
55   GEOMAlgo_GluerAlgo(),
56   GEOMAlgo_BuilderShape()
57 {
58   myTolerance=0.0001;
59 }
60 //=======================================================================
61 //function : ~GEOMAlgo_Gluer2
62 //purpose  : 
63 //=======================================================================
64 GEOMAlgo_Gluer2::~GEOMAlgo_Gluer2()
65 {
66 }
67 //=======================================================================
68 //function : Clear
69 //purpose  : 
70 //=======================================================================
71 void GEOMAlgo_Gluer2::Clear()
72 {
73   myErrorStatus=0;
74   myWarningStatus=0;
75   //
76   GEOMAlgo_GluerAlgo::Clear();
77   //
78   myImagesDetected.Clear();
79   myOriginsDetected.Clear();
80   myShapesToGlue.Clear();
81   myImagesToWork.Clear();
82   myOriginsToWork.Clear();
83   myKeepNonSolids=Standard_False;
84 }
85 //=======================================================================
86 //function : SetShapesToGlue
87 //purpose  : 
88 //=======================================================================
89 void GEOMAlgo_Gluer2::SetShapesToGlue(const TopTools_DataMapOfShapeListOfShape& aM)
90 {
91   myShapesToGlue=aM;
92 }
93 //=======================================================================
94 //function : ShapesToGlue
95 //purpose  : 
96 //=======================================================================
97 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ShapesToGlue()const
98 {
99   return myShapesToGlue;
100 }
101 //=======================================================================
102 //function : SetKeepNonSolids
103 //purpose  : 
104 //=======================================================================
105 void GEOMAlgo_Gluer2::SetKeepNonSolids(const Standard_Boolean aFlag)
106 {
107   myKeepNonSolids=aFlag;
108 }
109 //=======================================================================
110 //function : KeepNonSolids
111 //purpose  : 
112 //=======================================================================
113 Standard_Boolean GEOMAlgo_Gluer2::KeepNonSolids()const 
114 {
115   return myKeepNonSolids;
116 }
117 //=======================================================================
118 //function : ShapesDetected
119 //purpose  : 
120 //=======================================================================
121 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ShapesDetected()const
122 {
123   return myImagesDetected;
124 }
125 //=======================================================================
126 //function : ImagesToWork
127 //purpose  : 
128 //=======================================================================
129 const TopTools_DataMapOfShapeListOfShape& GEOMAlgo_Gluer2::ImagesToWork()const
130 {
131   return myImagesToWork;
132 }
133 //=======================================================================
134 //function : Perform
135 //purpose  : 
136 //=======================================================================
137 void GEOMAlgo_Gluer2::Perform()
138 {
139   myErrorStatus=0;
140   myWarningStatus=0;
141   // 
142   CheckData();
143   if (myErrorStatus) {
144     return;
145   }
146   //
147   PerformShapesToWork();
148   if (myErrorStatus) {
149     return;
150   }
151   if (myWarningStatus==1) {// no shapes to glue
152     myShape=myArgument;
153     return;
154   }
155   //
156   FillVertices();
157   if (myErrorStatus) {
158     return;
159   }
160   //
161   FillEdges();
162   if (myErrorStatus) {
163     return;
164   }
165   //
166   FillWires();
167   if (myErrorStatus) {
168     return;
169   }
170   //
171   FillFaces();
172   if (myErrorStatus) {
173     return;
174   }
175   //
176   FillShells();
177   if (myErrorStatus) {
178     return;
179   }
180   //
181   FillSolids();
182   if (myErrorStatus) {
183     return;
184   }
185   //
186   FillCompSolids();
187   if (myErrorStatus) {
188     return;
189   }
190   //
191   FillCompounds();
192   if (myErrorStatus) {
193     return;
194   }
195   //
196   BuildResult();
197   if (myErrorStatus) {
198     return;
199   }
200   //
201   PrepareHistory();
202   if (myErrorStatus) {
203     return;
204   }
205   //
206   BRepLib::SameParameter(myShape, myTolerance, Standard_True);
207 }
208 //=======================================================================
209 //function : CheckData
210 //purpose  : 
211 //=======================================================================
212 void GEOMAlgo_Gluer2::CheckData()
213 {
214   Standard_Integer aNbSG, i;
215   TopAbs_ShapeEnum aType, aTypeX;
216   TopTools_ListIteratorOfListOfShape aItLS;
217   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
218   //
219   myErrorStatus=0;
220   myWarningStatus=0;
221   //
222   aNbSG=myShapesToGlue.Extent();
223   if (aNbSG) {
224     // Check myShapesToGlue
225     aItDMSLS.Initialize(myShapesToGlue);
226     for (; aItDMSLS.More(); aItDMSLS.Next()) {
227       //const TopoDS_Shape& aSkey=aItDMSLS.Key();
228       const TopTools_ListOfShape& aLSG=aItDMSLS.Value();
229       aItLS.Initialize(aLSG);
230       for (i=0; aItLS.More(); aItLS.Next(), ++i) {
231         const TopoDS_Shape& aSG=aItLS.Value();
232         aTypeX=aSG.ShapeType();
233         if (!i) {
234           aType=aTypeX;
235           if (!(aType==TopAbs_VERTEX || 
236                 aType==TopAbs_EDGE || 
237                 aType==TopAbs_FACE)) {
238             myErrorStatus=21;// non-brep shapes
239             return;
240           }
241           continue;
242         }
243         if (aTypeX!=aType) {
244           myErrorStatus=20;// non-homogeneous shapes
245           return;
246         }
247       }
248     }
249   }// if (aNbSG) {
250 }
251 //=======================================================================
252 //function : FillEdges
253 //purpose  : 
254 //=======================================================================
255 void GEOMAlgo_Gluer2::FillEdges()
256 {
257   FillBRepShapes(TopAbs_EDGE);
258
259 //=======================================================================
260 //function : FillFaces
261 //purpose  : 
262 //=======================================================================
263 void GEOMAlgo_Gluer2::FillFaces()
264 {
265   FillBRepShapes(TopAbs_FACE);
266 }
267 //=======================================================================
268 //function : FillWires
269 //purpose  : 
270 //=======================================================================
271 void GEOMAlgo_Gluer2::FillWires()
272 {
273   FillContainers(TopAbs_WIRE);
274 }
275 //=======================================================================
276 //function : FillShells
277 //purpose  : 
278 //=======================================================================
279 void GEOMAlgo_Gluer2::FillShells()
280 {
281   FillContainers(TopAbs_SHELL);
282 }
283 //=======================================================================
284 //function : FillSolids
285 //purpose  : 
286 //=======================================================================
287 void GEOMAlgo_Gluer2::FillSolids()
288 {
289   FillContainers(TopAbs_SOLID);
290
291 //=======================================================================
292 //function : FillCompSolids
293 //purpose  : 
294 //=======================================================================
295 void GEOMAlgo_Gluer2::FillCompSolids()
296 {
297   FillContainers(TopAbs_COMPSOLID);
298
299 //=======================================================================
300 //function : FillVertices
301 //purpose  : 
302 //=======================================================================
303 void GEOMAlgo_Gluer2::FillVertices()
304 {
305   TopAbs_ShapeEnum aType;
306   TopoDS_Vertex aVnew;
307   TopTools_ListIteratorOfListOfShape aItLS;
308   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS;
309   //
310   myErrorStatus=0;
311   myWarningStatus=0;
312   //
313   aItDMSLS.Initialize(myImagesToWork);
314   for (; aItDMSLS.More(); aItDMSLS.Next()) {
315     const TopoDS_Shape& aSkey=aItDMSLS.Key();
316     aType=aSkey.ShapeType();
317     if (aType!=TopAbs_VERTEX) {
318       continue;
319     }
320     //
321     const TopTools_ListOfShape& aLSD=aItDMSLS.Value();
322     //
323     GEOMAlgo_Gluer2::MakeVertex(aLSD, aVnew);
324     //
325     myImages.Bind(aVnew, aLSD);
326     //
327     aItLS.Initialize(aLSD);
328     for (; aItLS.More(); aItLS.Next()) {
329       const TopoDS_Shape& aV=aItLS.Value();
330       myOrigins.Bind(aV, aVnew);
331     }
332   }
333 }
334 //=======================================================================
335 //function : FillBRepShapes
336 //purpose  : 
337 //=======================================================================
338 void GEOMAlgo_Gluer2::FillBRepShapes(const TopAbs_ShapeEnum theType)
339
340   Standard_Boolean bHasImage, bIsToWork;
341   Standard_Integer i, aNbE;
342   TopoDS_Iterator aItS;
343   TopoDS_Shape aEnew;
344   TopTools_IndexedMapOfShape aME;
345   TopTools_MapOfShape aMFence;
346   TopTools_ListIteratorOfListOfShape aItLS;
347   //
348   myErrorStatus=0;
349   myWarningStatus=0;
350   //
351   TopExp::MapShapes(myArgument, theType, aME);
352   //
353   aNbE=aME.Extent();
354   for (i=1; i<=aNbE; ++i) {
355     const TopoDS_Shape& aE=aME(i);
356     //
357     if (!aMFence.Add(aE)) {
358       continue;
359     }
360     //
361     bIsToWork=myOriginsToWork.IsBound(aE);
362     bHasImage=HasImage(aE);
363     if (!bHasImage && !bIsToWork) {
364       continue;
365     }
366     //
367     MakeBRepShapes(aE, aEnew);
368     //
369     //myImages / myOrigins
370     if (bIsToWork) {
371       const TopoDS_Shape& aSkey=myOriginsToWork.Find(aE);
372       const TopTools_ListOfShape& aLSD=myImagesToWork.Find(aSkey);
373       //
374       myImages.Bind(aEnew, aLSD);
375       //
376       aItLS.Initialize(aLSD);
377       for (; aItLS.More(); aItLS.Next()) {
378         const TopoDS_Shape& aEx=aItLS.Value();
379         myOrigins.Bind(aEx, aEnew);
380         //
381         aMFence.Add(aEx);
382       }
383     }
384     else {
385       TopTools_ListOfShape aLSD;
386       //
387       aLSD.Append(aE);
388       myImages.Bind(aEnew, aLSD);
389       myOrigins.Bind(aE, aEnew);
390     }
391   }//for (i=1; i<=aNbF; ++i) {
392 }
393 //=======================================================================
394 //function : FillContainers
395 //purpose  : 
396 //=======================================================================
397 void GEOMAlgo_Gluer2::FillContainers(const TopAbs_ShapeEnum aType)
398 {
399   Standard_Boolean bHasImage, bToReverse;
400   Standard_Integer i, aNbW;
401   TopoDS_Shape aWnew, aEnew;
402   TopoDS_Iterator aItS;
403   BRep_Builder aBB;
404   TopTools_IndexedMapOfShape aMW;
405   TopTools_MapOfShape aMFence;
406   //
407   myErrorStatus=0;
408   myWarningStatus=0;
409   //
410   TopExp::MapShapes(myArgument, aType, aMW);
411   //
412   aNbW=aMW.Extent();
413   for (i=1; i<=aNbW; ++i) {
414     const TopoDS_Shape& aW=aMW(i);
415     //
416     if (!aMFence.Add(aW)) {
417       continue;
418     }
419     //
420     bHasImage=HasImage(aW);
421     if (!bHasImage) {
422       continue;
423     }
424     //
425     GEOMAlgo_Tools3D::MakeContainer(aType, aWnew);
426     //modified by NIZNHY-PKV Tue May 10 13:46:30 2011f
427     aWnew.Orientation(aW.Orientation());
428     //modified by NIZNHY-PKV Tue May 10 13:46:32 2011t
429     //
430     aItS.Initialize(aW);
431     for (; aItS.More(); aItS.Next()) {
432       const TopoDS_Shape& aE=aItS.Value();
433       if (myOrigins.IsBound(aE)) {
434         aEnew=myOrigins.Find(aE);
435         //
436         bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aEnew, aE, myContext);
437         if (bToReverse) {
438           aEnew.Reverse();
439         }
440         //
441         aBB.Add(aWnew, aEnew);
442       }
443       else {
444         aBB.Add(aWnew, aE);
445       }
446     }
447     //
448     //modified by NIZNHY-PKV Tue May 10 13:46:19 2011f
449     //aWnew.Orientation(aW.Orientation());
450     //modified by NIZNHY-PKV Tue May 10 13:46:22 2011t
451     //
452     //myImages / myOrigins
453     TopTools_ListOfShape aLSD;
454     //
455     aLSD.Append(aW);
456     myImages.Bind(aWnew, aLSD);
457     myOrigins.Bind(aW, aWnew);
458     //
459   }//for (i=1; i<=aNbE; ++i) {
460 }
461 //=======================================================================
462 //function : FillCompounds
463 //purpose  : 
464 //=======================================================================
465 void GEOMAlgo_Gluer2::FillCompounds()
466 {
467   TopAbs_ShapeEnum aType;
468   TopoDS_Iterator aItC;
469   //
470   myErrorStatus=0;
471   myWarningStatus=0;
472   //
473   aItC.Initialize(myArgument);
474   for (; aItC.More(); aItC.Next()) {
475     const TopoDS_Shape& aCx=aItC.Value();
476     aType=aCx.ShapeType();
477     if (aType==TopAbs_COMPOUND) {
478       FillCompound(aCx);
479     }
480   }
481 }
482 //=======================================================================
483 //function : FillCompound
484 //purpose  : 
485 //=======================================================================
486 void GEOMAlgo_Gluer2::FillCompound(const TopoDS_Shape& aC)
487 {
488   Standard_Boolean bHasImage;
489   TopAbs_ShapeEnum aType;
490   TopoDS_Shape aCnew, aCXnew;
491   TopoDS_Iterator aItC;
492   BRep_Builder aBB;
493   //
494   bHasImage=HasImage(aC);
495   if (!bHasImage) {
496     return;
497   }
498   //
499   GEOMAlgo_Tools3D::MakeContainer(TopAbs_COMPOUND, aCnew);
500   //
501   aItC.Initialize(aC);
502   for (; aItC.More(); aItC.Next()) {
503     const TopoDS_Shape& aCX=aItC.Value();
504     aType=aCX.ShapeType();
505     //
506     if (aType==TopAbs_COMPOUND) {
507       FillCompound(aCX);
508     }
509     //
510     if (myOrigins.IsBound(aCX)) {
511       aCXnew=myOrigins.Find(aCX);
512       aCXnew.Orientation(aCX.Orientation());
513       aBB.Add(aCnew, aCXnew);
514     }
515     else {
516       aBB.Add(aCnew, aCX);
517     }
518   }
519   //
520   //myImages / myOrigins
521   TopTools_ListOfShape aLSD;
522   //
523   aLSD.Append(aC);
524   myImages.Bind(aCnew, aLSD);
525   myOrigins.Bind(aC, aCnew);
526 }
527 //=======================================================================
528 //function : HasImage
529 //purpose  : 
530 //=======================================================================
531 Standard_Boolean GEOMAlgo_Gluer2::HasImage(const TopoDS_Shape& aC)
532 {
533   Standard_Boolean bRet;
534   TopAbs_ShapeEnum aType;
535   TopoDS_Iterator aItC;
536   //
537   bRet=Standard_False;
538   aItC.Initialize(aC);
539   for (; aItC.More(); aItC.Next()) {
540     const TopoDS_Shape& aCx=aItC.Value();
541     aType=aCx.ShapeType();
542     //
543     if (aType==TopAbs_COMPOUND) {
544       bRet=HasImage(aCx);
545       if (bRet) {
546         return bRet;
547       }
548     }
549     else {
550       bRet=myOrigins.IsBound(aCx);
551       if (bRet) {
552         return bRet;
553       }
554     }
555   }
556   //
557   bRet=myOrigins.IsBound(aC);
558   //
559   return bRet;
560 }
561 //=======================================================================
562 //function : BuildResult
563 //purpose  : 
564 //=======================================================================
565 void GEOMAlgo_Gluer2::BuildResult()
566 {
567   Standard_Boolean bHasImage;
568   TopoDS_Shape aCnew, aCXnew;
569   TopoDS_Iterator aItC;
570   BRep_Builder aBB;
571   //
572   myErrorStatus=0;
573   myWarningStatus=0;
574   //
575   aItC.Initialize(myArgument);
576   for (; aItC.More(); aItC.Next()) {
577     const TopoDS_Shape& aCx=aItC.Value();
578     bHasImage=HasImage(aCx);
579     if (bHasImage) {
580       break;
581     }
582   }
583   //
584   if (!bHasImage) {
585     myShape=myArgument;
586     return;
587   }
588   //
589   GEOMAlgo_Tools3D::MakeContainer(TopAbs_COMPOUND, aCnew);
590   //
591   aItC.Initialize(myArgument);
592   for (; aItC.More(); aItC.Next()) {
593     const TopoDS_Shape& aCX=aItC.Value();
594     if (myOrigins.IsBound(aCX)) {
595       aCXnew=myOrigins.Find(aCX);
596       aCXnew.Orientation(aCX.Orientation());
597       aBB.Add(aCnew, aCXnew);
598     }
599     else {
600       aBB.Add(aCnew, aCX);
601     }
602   }
603   //
604   if (!myKeepNonSolids) {
605     Standard_Integer i, aNb;
606     TopoDS_Shape aCnew1;
607     TopTools_IndexedMapOfShape aM;
608     //
609     GEOMAlgo_Tools3D::MakeContainer(TopAbs_COMPOUND, aCnew1);
610     //
611     TopExp::MapShapes(aCnew, TopAbs_SOLID, aM);
612     
613     aNb=aM.Extent();
614     for (i=1; i<=aNb; ++i) {
615       const TopoDS_Shape& aS=aM(i);
616       aBB.Add(aCnew1, aS);
617     }
618     aCnew=aCnew1;
619   }
620   //
621   myShape=aCnew;
622 }
623 //--------------------------------------------------------
624 //
625 // ErrorStatus
626 // 11   - GEOMAlgo_GlueDetector failed
627 // 13   - PerformImagesToWork failed
628 // 14   - PerformImagesToWork failed
629 //
630 // WarningStatus
631 // 1    - no shapes to glue