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