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