]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_GlueDriver.cxx
Salome HOME
Add of exports
[modules/geom.git] / src / GEOMImpl / GEOMImpl_GlueDriver.cxx
1 // Copyright (C) 2007-2013  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 #include <Standard_Stream.hxx>
23
24 #include <GEOMImpl_GlueDriver.hxx>
25 #include <GEOMImpl_IGlue.hxx>
26 #include <GEOMImpl_Types.hxx>
27
28 #include <GEOM_Object.hxx>
29 #include <GEOM_Function.hxx>
30
31 #include "GEOMAlgo_Gluer2.hxx"
32 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
33 #include "GEOMAlgo_CoupleOfShapes.hxx"
34 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
35
36 #include <Basics_OCCTVersion.hxx>
37
38 #include "utilities.h"
39
40 #include <TDataStd_IntegerArray.hxx>
41 #include <TNaming_CopyShape.hxx>
42
43 #include <TopExp.hxx>
44 #include <TopoDS_Shape.hxx>
45 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
48 #include <TopTools_ListIteratorOfListOfShape.hxx>
49
50 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
51
52 #include <ShapeFix_Shape.hxx>
53
54 #include <Standard_NullObject.hxx>
55 #include <Standard_Failure.hxx>
56
57 #define MSG_BAD_TOLERANCE "Tolerance is too big"
58 #define MSG_BAD_ARG_SHAPE "Argument shape is not a compound of hexahedral solids"
59
60 //=======================================================================
61 //function : GEOMImpl_GlueDriver
62 //purpose  :
63 //=======================================================================
64 GEOMImpl_GlueDriver::GEOMImpl_GlueDriver()
65 {
66 }
67
68 //=======================================================================
69 //function : GetID
70 //purpose  :
71 //=======================================================================
72 const Standard_GUID& GEOMImpl_GlueDriver::GetID()
73 {
74   static Standard_GUID aGlueDriver("FF1BBB63-5D14-4df2-980B-3A668264EA16");
75   return aGlueDriver;
76 }
77
78 //=======================================================================
79 //function : GlueFacesWithWarnings
80 //purpose  :
81 //=======================================================================
82 /*
83 TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape,
84                                                          const Standard_Real theTolerance,
85                                                          const Standard_Boolean doKeepNonSolids,
86                                                          TCollection_AsciiString& theWarning) const
87 {
88   Standard_Integer iErr, iWrn;
89   TopoDS_Shape aRes;
90   GEOMAlgo_Gluer aGluer;
91
92   aGluer.SetShape(theShape);
93   aGluer.SetTolerance(theTolerance);
94   aGluer.SetCheckGeometry(Standard_True);
95   aGluer.SetKeepNonSolids(doKeepNonSolids);
96
97   aGluer.Perform();
98
99   iErr = aGluer.ErrorStatus();
100   if (iErr) {
101     switch (iErr) {
102     case 2:
103       Standard_Failure::Raise("No vertices found in source shape");
104       break;
105     case 3:
106     case 4:
107       Standard_Failure::Raise(MSG_BAD_TOLERANCE " or " MSG_BAD_ARG_SHAPE);
108       break;
109     case 5:
110       Standard_Failure::Raise("Source shape is Null");
111       break;
112     case 6:
113       Standard_Failure::Raise("Result shape is Null");
114       break;
115     case 100:
116       Standard_Failure::Raise(MSG_BAD_TOLERANCE);
117       break;
118     case 101:
119     case 102:
120       Standard_Failure::Raise(MSG_BAD_ARG_SHAPE);
121       break;
122     case 200:
123       Standard_Failure::Raise("Error occured during check of geometric coincidence");
124       break;
125     default:
126       {
127         // description of all errors see in GEOMAlgo_Gluer.cxx
128         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
129         aMsg += TCollection_AsciiString(iErr);
130         Standard_Failure::Raise(aMsg.ToCString());
131         break;
132       }
133     }
134     return aRes;
135   }
136
137   iWrn = aGluer.WarningStatus();
138   if (iWrn) {
139     switch (iWrn) {
140     case 1:
141       {
142         Standard_Integer nbAlone = aGluer.AloneShapes();
143         theWarning = TCollection_AsciiString(nbAlone);
144         theWarning += " solid(s) can not be glued by faces";
145       }
146       break;
147     default:
148       // description of all warnings see in GEOMAlgo_Gluer.cxx
149       theWarning = "Warning in GEOMAlgo_Gluer with code ";
150       theWarning += TCollection_AsciiString(iWrn);
151       break;
152     }
153   }
154
155   aRes = aGluer.Result();
156
157   // SKL 18.01.2010 - patch for 20662
158   Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aRes);
159   aSfs->SetPrecision(Precision::Confusion());
160   aSfs->Perform();
161   aRes = aSfs->Shape();
162
163   // Fill history to be used by GetInPlace functionality
164   TopTools_IndexedMapOfShape aResIndices;
165   TopExp::MapShapes(aRes, aResIndices);
166
167   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
168
169   // history for all argument shapes
170   TDF_LabelSequence aLabelSeq;
171   aFunction->GetDependency(aLabelSeq);
172   Standard_Integer nbArg = aLabelSeq.Length();
173
174   for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
175
176     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
177
178     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
179     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
180
181     TopTools_IndexedMapOfShape anArgumentIndices;
182     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
183     Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
184
185     // Find corresponding label in history
186     TDF_Label anArgumentHistoryLabel =
187       aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
188
189     for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
190       TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
191       const TopTools_ListOfShape& aModified = aGluer.Modified(anEntity);
192       Standard_Integer nbModified = aModified.Extent();
193
194       if (nbModified > 0) {
195         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
196         Handle(TDataStd_IntegerArray) anAttr =
197           TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
198
199         TopTools_ListIteratorOfListOfShape itM (aModified);
200         for (int im = 1; itM.More(); itM.Next(), ++im) {
201           int id = aResIndices.FindIndex(itM.Value());
202           anAttr->SetValue(im, id);
203         }
204       }
205     }
206   }
207
208   return aRes;
209 }
210
211 //=======================================================================
212 //function : GlueFaces
213 //purpose  :
214 //=======================================================================
215 TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
216                                              const Standard_Real theTolerance,
217                                              const Standard_Boolean doKeepNonSolids)
218 {
219   TopoDS_Shape aRes;
220   GEOMAlgo_Gluer aGluer;
221
222   aGluer.SetShape(theShape);
223   aGluer.SetTolerance(theTolerance);
224   aGluer.SetCheckGeometry(Standard_True);
225   aGluer.SetKeepNonSolids(doKeepNonSolids);
226
227   aGluer.Perform();
228
229   Standard_Integer iErr = aGluer.ErrorStatus();
230   if (iErr) {
231     switch (iErr) {
232     case 2:
233       Standard_Failure::Raise("No vertices found in source shape");
234       break;
235     case 5:
236       Standard_Failure::Raise("Source shape is Null");
237       break;
238     case 6:
239       Standard_Failure::Raise("Result shape is Null");
240       break;
241     case 200:
242       Standard_Failure::Raise("Error occured during check of geometric coincidence");
243       break;
244     default:
245       {
246         // description of all errors see in GEOMAlgo_Gluer.cxx
247         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code ");
248         aMsg += TCollection_AsciiString(iErr);
249         Standard_Failure::Raise(aMsg.ToCString());
250         break;
251       }
252     }
253     return aRes;
254   }
255
256   Standard_Integer iWrn = aGluer.WarningStatus();
257   if (iWrn) {
258     switch (iWrn) {
259     case 1:
260       MESSAGE("Some shapes can not be glued by faces");
261       break;
262     default:
263       // description of all warnings see in GEOMAlgo_Gluer.cxx
264       MESSAGE("Warning in GEOMAlgo_Gluer with code " << iWrn);
265       break;
266     }
267   }
268
269   aRes = aGluer.Result();
270
271   return aRes;
272 }
273
274 //=======================================================================
275 //function : GlueFacesByList
276 //purpose  :
277 //=======================================================================
278 TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesByList (const TopoDS_Shape& theShape,
279                                                    const Standard_Real theTolerance,
280                                                    const Standard_Boolean doKeepNonSolids,
281                                                    const TopTools_MapOfShape& aFaces)
282 {
283   TopoDS_Shape aRes;
284
285   GEOMAlgo_Gluer1 aGluer;
286   GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
287   GEOMAlgo_CoupleOfShapes aCS;
288   GEOMAlgo_ListOfCoupleOfShapes aLCS;
289
290   aGluer.SetShape(theShape);
291   aGluer.SetTolerance(theTolerance);
292   aGluer.SetKeepNonSolids(doKeepNonSolids);
293   aGluer.Perform();
294   Standard_Integer iErr = aGluer.ErrorStatus();
295   if (iErr) return aRes;
296
297   TopTools_ListOfShape listShape;
298   const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
299   // Access to faces
300   aItCS.Initialize(aLCSG);
301   for (; aItCS.More(); aItCS.Next()) {
302     const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
303     const TopoDS_Shape& aF1 = aCSG.Shape1();
304     const TopoDS_Shape& aF2 = aCSG.Shape2();
305     if (aFaces.Contains(aF1) || aFaces.Contains(aF2))
306       continue;
307     aCS.SetShapes(aF1,aF2);
308     aLCS.Append(aCS);
309   }
310
311   //cout<<"aLCS.Extent() = "<<aLCS.Extent()<<endl;
312   if (aLCS.Extent()>0) {
313     aGluer.SetFacesToUnglue(aLCS);
314     aGluer.UnglueFaces();
315     iErr = aGluer.ErrorStatus();
316     if (iErr) return aRes;
317   }
318
319   aRes = aGluer.Result();
320
321   return aRes;
322 }
323 */
324
325 //=======================================================================
326 //function : GlueFaces
327 //purpose  :
328 //=======================================================================
329 TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape,
330                                              const Standard_Real theTolerance,
331                                              const Standard_Boolean doKeepNonSolids)
332 {
333   TopoDS_Shape aRes;
334
335   GEOMAlgo_Gluer2 aGA;
336
337   // 1. Initialization
338   aGA.SetArgument(theShape);
339   aGA.SetTolerance(theTolerance);
340   aGA.SetKeepNonSolids(doKeepNonSolids);
341
342   // 2. Detect interferred shapes
343   aGA.Detect();
344
345   //Standard_Integer iWrnDetect = aGA.WarningStatus();
346   //if (iWrnDetect == 2) {
347   //  Standard_Failure::Raise("GLUE_ERROR_STICKED_SHAPES");
348   //}
349
350   Standard_Integer iErr = aGA.ErrorStatus();
351   if (iErr) {
352     switch (iErr) {
353     case 11:
354       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
355       break;
356     case 13:
357     case 14:
358       Standard_Failure::Raise("PerformImagesToWork failed");
359       break;
360     default:
361       {
362         // description of all errors see in GEOMAlgo_Gluer2.cxx
363         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
364         aMsg += TCollection_AsciiString(iErr);
365         Standard_Failure::Raise(aMsg.ToCString());
366         break;
367       }
368     }
369     return aRes;
370   }
371
372   // 3. Set shapes to glue. If the operator is absent, the whole gluing will be done
373   //aGA.SetShapesToGlue(aMSG);
374
375   // 4. Gluing
376   aGA.Perform();
377   iErr = aGA.ErrorStatus();
378   if (iErr) {
379     switch (iErr) {
380     case 11:
381       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
382       break;
383     case 13:
384     case 14:
385       Standard_Failure::Raise("PerformImagesToWork failed");
386       break;
387     default:
388       {
389         // description of all errors see in GEOMAlgo_Gluer2.cxx
390         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
391         aMsg += TCollection_AsciiString(iErr);
392         Standard_Failure::Raise(aMsg.ToCString());
393         break;
394       }
395     }
396     return aRes;
397   }
398
399   Standard_Integer iWrn = aGA.WarningStatus();
400   if (iWrn) {
401     switch (iWrn) {
402     case 1:
403       MESSAGE("No shapes to glue");
404       break;
405     default:
406       // description of all warnings see in GEOMAlgo_Gluer2.cxx
407       MESSAGE("Warning in GEOMAlgo_Gluer2 with code " << iWrn);
408       break;
409     }
410   }
411
412   // 5. Result
413   aRes = aGA.Shape();
414
415   return aRes;
416 }
417
418 //=======================================================================
419 //function : GlueWithWarnings
420 //purpose  :
421 //=======================================================================
422 TopoDS_Shape GEOMImpl_GlueDriver::GlueWithWarnings (const TopoDS_Shape& theShape,
423                                                     const Standard_Real theTolerance,
424                                                     const TopAbs_ShapeEnum theShapeType,
425                                                     const Standard_Boolean doKeepNonSolids,
426                                                     TCollection_AsciiString& theWarning,
427                                                     const TopTools_DataMapOfShapeShape& aCopyMap) const
428 {
429   TopoDS_Shape aRes;
430
431   GEOMAlgo_Gluer2 aGA;
432
433   // 1. Initialization
434   aGA.SetArgument(theShape);
435   aGA.SetTolerance(theTolerance);
436   aGA.SetKeepNonSolids(doKeepNonSolids);
437
438   // 2. Detect interferred shapes
439   aGA.Detect();
440
441   //modified by NIZNHY-PKV Tue Mar 13 14:07:12 2012f
442 #if OCC_VERSION_LARGE > 0x06050200
443   Standard_Integer iWrnDetect = aGA.WarningStatus();
444   if (iWrnDetect == 2) {
445     Standard_Failure::Raise("GLUE_ERROR_STICKED_SHAPES");
446   }
447 #endif
448   //modified by NIZNHY-PKV Tue Mar 13 14:07:14 2012t
449
450   Standard_Integer iErr = aGA.ErrorStatus();
451   if (iErr) {
452     switch (iErr) {
453     case 11:
454       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
455       break;
456     case 13:
457     case 14:
458       Standard_Failure::Raise("PerformImagesToWork failed");
459       break;
460     default:
461       {
462         // description of all errors see in GEOMAlgo_Gluer2.cxx
463         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
464         aMsg += TCollection_AsciiString(iErr);
465         Standard_Failure::Raise(aMsg.ToCString());
466         break;
467       }
468     }
469     return aRes;
470   }
471
472   if (theShapeType != TopAbs_FACE) {
473     // 3. Fill shapes to glue aMSG
474     TopTools_DataMapOfShapeListOfShape aMSG;
475     const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected();
476     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD;
477     aItMSD.Initialize(aMSD);
478     for (; aItMSD.More(); aItMSD.Next()) {
479       const TopoDS_Shape& aSx = aItMSD.Key();
480       const TopTools_ListOfShape& aLSD = aItMSD.Value();
481       if (aSx.ShapeType() == theShapeType) {
482         aMSG.Bind(aSx, aLSD);
483       }
484     }
485
486     // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done
487     aGA.SetShapesToGlue(aMSG);
488   }
489
490   // 5. Gluing
491   aGA.Perform();
492   iErr = aGA.ErrorStatus();
493   if (iErr) {
494     switch (iErr) {
495     case 11:
496       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
497       break;
498     case 13:
499     case 14:
500       Standard_Failure::Raise("PerformImagesToWork failed");
501       break;
502     default:
503       {
504         // description of all errors see in GEOMAlgo_Gluer2.cxx
505         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
506         aMsg += TCollection_AsciiString(iErr);
507         Standard_Failure::Raise(aMsg.ToCString());
508         break;
509       }
510     }
511     return aRes;
512   }
513
514   Standard_Integer iWrn = aGA.WarningStatus();
515   if (iWrn) {
516     switch (iWrn) {
517     case 1:
518       theWarning = "No shapes to glue";
519       break;
520     default:
521       // description of all warnings see in GEOMAlgo_Gluer2.cxx
522       theWarning = "Warning in GEOMAlgo_Gluer2 with code ";
523       theWarning += TCollection_AsciiString(iWrn);
524       break;
525     }
526   }
527
528   // 6. Result
529   aRes = aGA.Shape();
530
531   // 7. Fill history to be used by GetInPlace functionality
532   TopTools_IndexedMapOfShape aResIndices;
533   TopExp::MapShapes(aRes, aResIndices);
534
535   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
536
537   // history for all argument shapes
538   TDF_LabelSequence aLabelSeq;
539   aFunction->GetDependency(aLabelSeq);
540   Standard_Integer nbArg = aLabelSeq.Length();
541
542   for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
543
544     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
545
546     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
547     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
548
549     TopTools_IndexedMapOfShape anArgumentIndices;
550     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
551     Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
552
553     // Find corresponding label in history
554     TDF_Label anArgumentHistoryLabel =
555       aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
556
557     TopTools_ListOfShape aModified;
558     for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
559       TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
560       if (aCopyMap.IsBound(anEntity)) {
561         anEntity = aCopyMap.Find(anEntity);
562       }
563       aModified = aGA.Modified(anEntity);
564       Standard_Integer nbModified = aModified.Extent();
565       if (!nbModified && aResIndices.Contains(anEntity)) {
566         aModified.Append(anEntity);
567         nbModified = 1;
568       }
569
570       if (nbModified > 0) {
571         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
572         Handle(TDataStd_IntegerArray) anAttr =
573           TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
574
575         TopTools_ListIteratorOfListOfShape itM (aModified);
576         for (int im = 1; itM.More(); itM.Next(), ++im) {
577           int id = aResIndices.FindIndex(itM.Value());
578           anAttr->SetValue(im, id);
579         }
580       }
581     }
582   }
583
584   return aRes;
585 }
586
587 //=======================================================================
588 //function : GlueByList
589 //purpose  :
590 //=======================================================================
591 TopoDS_Shape GEOMImpl_GlueDriver::GlueByList (const TopoDS_Shape& theShape,
592                                               const Standard_Real theTolerance,
593                                               const Standard_Boolean doKeepNonSolids,
594                                               const TopTools_MapOfShape& theShapesList,
595                                               const Standard_Boolean doGlueAllEdges)
596 {
597   TopoDS_Shape aRes;
598
599   GEOMAlgo_Gluer2 aGA;
600
601   // 1. Initialization
602   aGA.SetArgument(theShape);
603   aGA.SetTolerance(theTolerance);
604   aGA.SetKeepNonSolids(doKeepNonSolids);
605
606   // 2. Detect interferred shapes
607   aGA.Detect();
608
609   //modified by NIZNHY-PKV Tue Mar 13 14:07:12 2012f
610 #if OCC_VERSION_LARGE > 0x06050200
611   Standard_Integer iWrnDetect = aGA.WarningStatus();
612   if (iWrnDetect == 2) {
613     /*
614     TopTools_ListIteratorOfListOfShape aItLS;
615
616     // Sticked shapes are detected
617     const TopTools_IndexedDataMapOfShapeListOfShape& aIDMSS = pGluer2->StickedShapes();
618
619     Standard_Integer i, aNb = aIDMSS.Extent();
620     for (i = 1; i <= aNb; ++i) {
621       // ancestor aSa (edge, wire face,..)  
622       const TopoDS_Shape& aSa = aIDMSS.FindKey(i); 
623
624       // successors aSs (vertex, edge, ...)
625       // of the ancestor that are sticked 
626       // for given value of the tolerance
627       const TopTools_ListOfShape& aLSS = aIDMSS.FindFromIndex(i);
628       aItLS.Initialize(aLSS);
629       for (; aItLS.More(); aItLS.Next()) {
630         const TopoDS_Shape& aSs = aItLS.Value();
631       }
632     }
633     */
634     Standard_Failure::Raise("GLUE_ERROR_STICKED_SHAPES");
635   }
636 #endif
637   //modified by NIZNHY-PKV Tue Mar 13 14:07:14 2012t
638
639   Standard_Integer iErr = aGA.ErrorStatus();
640   if (iErr) {
641     switch (iErr) {
642     case 11:
643       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
644       break;
645     case 13:
646     case 14:
647       Standard_Failure::Raise("PerformImagesToWork failed");
648       break;
649     default:
650       {
651         // description of all errors see in GEOMAlgo_Gluer2.cxx
652         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
653         aMsg += TCollection_AsciiString(iErr);
654         Standard_Failure::Raise(aMsg.ToCString());
655         break;
656       }
657     }
658     return aRes;
659   }
660
661   // 3. Fill shapes to glue aMSG
662   TopTools_DataMapOfShapeListOfShape aMSG;
663   const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected();
664   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD;
665   aItMSD.Initialize(aMSD);
666   for (; aItMSD.More(); aItMSD.Next()) {
667     const TopoDS_Shape& aSx = aItMSD.Key();
668     const TopTools_ListOfShape& aLSD = aItMSD.Value();
669     TopTools_ListIteratorOfListOfShape anItLSD (aLSD);
670     bool isToGlue = false;
671     if (doGlueAllEdges && aSx.ShapeType() == TopAbs_EDGE) {
672       isToGlue = true;
673     }
674     else {
675       for (; anItLSD.More() && !isToGlue; anItLSD.Next()) {
676         if (theShapesList.Contains(anItLSD.Value())) {
677           isToGlue = true;
678         }
679       }
680     }
681     if (isToGlue) {
682       aMSG.Bind(aSx, aLSD);
683     }
684   }
685
686   // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done
687   aGA.SetShapesToGlue(aMSG);
688
689   // 5. Gluing
690   aGA.Perform();
691   iErr = aGA.ErrorStatus();
692   if (iErr) {
693     switch (iErr) {
694     case 11:
695       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
696       break;
697     case 13:
698     case 14:
699       Standard_Failure::Raise("PerformImagesToWork failed");
700       break;
701     default:
702       {
703         // description of all errors see in GEOMAlgo_Gluer2.cxx
704         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
705         aMsg += TCollection_AsciiString(iErr);
706         Standard_Failure::Raise(aMsg.ToCString());
707         break;
708       }
709     }
710     return aRes;
711   }
712
713   Standard_Integer iWrn = aGA.WarningStatus();
714   if (iWrn) {
715     switch (iWrn) {
716     case 1:
717       MESSAGE("No shapes to glue");
718       break;
719     default:
720       // description of all warnings see in GEOMAlgo_Gluer2.cxx
721       MESSAGE("Warning in GEOMAlgo_Gluer2 with code " << iWrn);
722       break;
723     }
724   }
725
726   // 6. Result
727   aRes = aGA.Shape();
728
729   return aRes;
730 }
731
732 //=======================================================================
733 //function : Execute
734 //purpose  :
735 //=======================================================================
736 Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
737 {
738   if (Label().IsNull()) return 0;
739   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
740
741   GEOMImpl_IGlue aCI (aFunction);
742   Standard_Integer aType = aFunction->GetType();
743
744   TopoDS_Shape aShape;
745   TCollection_AsciiString aWrn;
746
747   Handle(GEOM_Function) aRefBase = aCI.GetBase();
748   TopoDS_Shape aShapeBase = aRefBase->GetValue();
749   if (aShapeBase.IsNull()) {
750     Standard_NullObject::Raise("Shape for gluing is null");
751   }
752
753   Standard_Real tol3d = aCI.GetTolerance();
754
755   Standard_Boolean aKeepNonSolids = aCI.GetKeepNonSolids();
756
757   // Copy initial shape to prevent its modification by gluing algorithm
758   TopoDS_Shape aShapeCopy;
759   TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
760   TNaming_CopyShape::CopyTool(aShapeBase, aMapTShapes, aShapeCopy);
761   //
762   // map sub-shapes
763   TopTools_IndexedMapOfShape aShapeBase_inds, aShapeCopy_inds;
764   TopTools_DataMapOfShapeShape aCopyMap;
765   Standard_Integer aNbInd, i;
766   //
767   TopExp::MapShapes(aShapeBase, aShapeBase_inds);
768   TopExp::MapShapes(aShapeCopy, aShapeCopy_inds);
769   //
770   aNbInd = aShapeBase_inds.Extent();
771   for (i = 1; i <= aNbInd; ++i) {
772     aCopyMap.Bind(aShapeBase_inds(i), aShapeCopy_inds(i));
773   }
774   //
775   if (aType == GLUE_FACES) {
776     aShape = GlueWithWarnings(aShapeCopy, tol3d, TopAbs_FACE, aKeepNonSolids, aWrn, aCopyMap);
777   }
778   else if (aType == GLUE_EDGES) {
779     aShape = GlueWithWarnings(aShapeCopy, tol3d, TopAbs_EDGE, aKeepNonSolids, aWrn, aCopyMap);
780   }
781   else if (aType == GLUE_FACES_BY_LIST || aType == GLUE_EDGES_BY_LIST) {
782     Handle(TColStd_HSequenceOfTransient) SF = aCI.GetFaces();
783     TopTools_MapOfShape aFaces;
784
785     for (i = 1; i <= SF->Length(); i++) {
786       Handle(Standard_Transient) anItem = SF->Value(i);
787       if (anItem.IsNull())
788         continue;
789       Handle(GEOM_Function) aRefSh = Handle(GEOM_Function)::DownCast(anItem);
790       if (aRefSh.IsNull())
791         continue;
792       TopoDS_Shape aFace = aRefSh->GetValue();
793       if (aFace.IsNull())
794         continue;
795
796       // get copy of face to correspond to aShapeCopy
797       if (aShapeBase_inds.Contains(aFace)) {
798         int ind = aShapeBase_inds.FindIndex(aFace);
799         aFace = aShapeCopy_inds.FindKey(ind);
800
801         aFaces.Add(aFace);
802       }
803     }
804
805     Standard_Boolean aGlueAllEdges = Standard_False;
806     if (aType == GLUE_FACES_BY_LIST)
807       aGlueAllEdges = aCI.GetGlueAllEdges();
808
809     //aShape = GlueFacesByList(aShapeBase, tol3d, aKeepNonSolids, aFaces);
810     aShape = GlueByList(aShapeCopy, tol3d, aKeepNonSolids, aFaces, aGlueAllEdges);
811   }
812
813   if (aShape.IsNull()) return 0;
814
815   aFunction->SetValue(aShape);
816
817   log.SetTouched(Label());
818
819   if (!aWrn.IsEmpty()) {
820     Standard_Failure::Raise(aWrn.ToCString());
821   }
822
823   return 1;
824 }
825
826 //================================================================================
827 /*!
828  * \brief Returns a name of creation operation and names and values of creation parameters
829  */
830 //================================================================================
831
832 bool GEOMImpl_GlueDriver::
833 GetCreationInformation(std::string&             theOperationName,
834                        std::vector<GEOM_Param>& theParams)
835 {
836   if (Label().IsNull()) return 0;
837   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
838
839   GEOMImpl_IGlue aCI( function );
840   Standard_Integer aType = function->GetType();
841
842   switch ( aType ) {
843   case GLUE_FACES:
844     theOperationName = "GLUE_FACES";
845     AddParam( theParams, "Selected shape", aCI.GetBase() );
846     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
847     AddParam( theParams, "To keep non solids", aCI.GetKeepNonSolids() );
848     break;
849   case GLUE_EDGES:
850     theOperationName = "GLUE_EDGES";
851     AddParam( theParams, "Selected shape", aCI.GetBase() );
852     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
853     break;
854   case GLUE_FACES_BY_LIST:
855     theOperationName = "GLUE_FACES";
856     AddParam( theParams, "Selected shape", aCI.GetBase() );
857     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
858     AddParam( theParams, "Faces", aCI.GetFaces() );
859     AddParam( theParams, "To keep non solids", aCI.GetKeepNonSolids() );
860     AddParam( theParams, "To glue all edges", aCI.GetGlueAllEdges() );
861     break;
862   case GLUE_EDGES_BY_LIST:
863     theOperationName = "GLUE_EDGES";
864     AddParam( theParams, "Selected shape", aCI.GetBase() );
865     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
866     AddParam( theParams, "Edges", aCI.GetFaces() );
867     break;
868   default:
869     return false;
870   }
871   
872   return true;
873 }
874
875 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_GlueDriver,GEOM_BaseDriver);
876 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_GlueDriver,GEOM_BaseDriver);