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