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