Salome HOME
GlueFaces/Edges: protect initial shapes from modifications.
[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) const
427 {
428   TopoDS_Shape aRes;
429
430   GEOMAlgo_Gluer2 aGA;
431
432   // 1. Initialization
433   aGA.SetArgument(theShape);
434   aGA.SetTolerance(theTolerance);
435   aGA.SetKeepNonSolids(doKeepNonSolids);
436
437   // 2. Detect interferred shapes
438   aGA.Detect();
439
440   //modified by NIZNHY-PKV Tue Mar 13 14:07:12 2012f
441 #if OCC_VERSION_LARGE > 0x06050200
442   Standard_Integer iWrnDetect = aGA.WarningStatus();
443   if (iWrnDetect == 2) {
444     Standard_Failure::Raise("GLUE_ERROR_STICKED_SHAPES");
445   }
446 #endif
447   //modified by NIZNHY-PKV Tue Mar 13 14:07:14 2012t
448
449   Standard_Integer iErr = aGA.ErrorStatus();
450   if (iErr) {
451     switch (iErr) {
452     case 11:
453       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
454       break;
455     case 13:
456     case 14:
457       Standard_Failure::Raise("PerformImagesToWork failed");
458       break;
459     default:
460       {
461         // description of all errors see in GEOMAlgo_Gluer2.cxx
462         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
463         aMsg += TCollection_AsciiString(iErr);
464         Standard_Failure::Raise(aMsg.ToCString());
465         break;
466       }
467     }
468     return aRes;
469   }
470
471   if (theShapeType != TopAbs_FACE) {
472     // 3. Fill shapes to glue aMSG
473     TopTools_DataMapOfShapeListOfShape aMSG;
474     const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected();
475     TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD;
476     aItMSD.Initialize(aMSD);
477     for (; aItMSD.More(); aItMSD.Next()) {
478       const TopoDS_Shape& aSx = aItMSD.Key();
479       const TopTools_ListOfShape& aLSD = aItMSD.Value();
480       if (aSx.ShapeType() == theShapeType) {
481         aMSG.Bind(aSx, aLSD);
482       }
483     }
484
485     // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done
486     aGA.SetShapesToGlue(aMSG);
487   }
488
489   // 5. Gluing
490   aGA.Perform();
491   iErr = aGA.ErrorStatus();
492   if (iErr) {
493     switch (iErr) {
494     case 11:
495       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
496       break;
497     case 13:
498     case 14:
499       Standard_Failure::Raise("PerformImagesToWork failed");
500       break;
501     default:
502       {
503         // description of all errors see in GEOMAlgo_Gluer2.cxx
504         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
505         aMsg += TCollection_AsciiString(iErr);
506         Standard_Failure::Raise(aMsg.ToCString());
507         break;
508       }
509     }
510     return aRes;
511   }
512
513   Standard_Integer iWrn = aGA.WarningStatus();
514   if (iWrn) {
515     switch (iWrn) {
516     case 1:
517       theWarning = "No shapes to glue";
518       break;
519     default:
520       // description of all warnings see in GEOMAlgo_Gluer2.cxx
521       theWarning = "Warning in GEOMAlgo_Gluer2 with code ";
522       theWarning += TCollection_AsciiString(iWrn);
523       break;
524     }
525   }
526
527   // 6. Result
528   aRes = aGA.Shape();
529
530   // 7. Fill history to be used by GetInPlace functionality
531   TopTools_IndexedMapOfShape aResIndices;
532   TopExp::MapShapes(aRes, aResIndices);
533
534   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
535
536   // history for all argument shapes
537   TDF_LabelSequence aLabelSeq;
538   aFunction->GetDependency(aLabelSeq);
539   Standard_Integer nbArg = aLabelSeq.Length();
540
541   for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) {
542
543     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
544
545     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
546     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
547
548     TopTools_IndexedMapOfShape anArgumentIndices;
549     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
550     Standard_Integer nbArgumentEntities = anArgumentIndices.Extent();
551
552     // Find corresponding label in history
553     TDF_Label anArgumentHistoryLabel =
554       aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True);
555
556     for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) {
557       TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie);
558       const TopTools_ListOfShape& aModified = aGA.Modified(anEntity);
559       Standard_Integer nbModified = aModified.Extent();
560
561       if (nbModified > 0) {
562         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True);
563         Handle(TDataStd_IntegerArray) anAttr =
564           TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified);
565
566         TopTools_ListIteratorOfListOfShape itM (aModified);
567         for (int im = 1; itM.More(); itM.Next(), ++im) {
568           int id = aResIndices.FindIndex(itM.Value());
569           anAttr->SetValue(im, id);
570         }
571       }
572     }
573   }
574
575   return aRes;
576 }
577
578 //=======================================================================
579 //function : GlueByList
580 //purpose  :
581 //=======================================================================
582 TopoDS_Shape GEOMImpl_GlueDriver::GlueByList (const TopoDS_Shape& theShape,
583                                               const Standard_Real theTolerance,
584                                               const Standard_Boolean doKeepNonSolids,
585                                               const TopTools_MapOfShape& theShapesList,
586                                               const Standard_Boolean doGlueAllEdges)
587 {
588   TopoDS_Shape aRes;
589
590   GEOMAlgo_Gluer2 aGA;
591
592   // 1. Initialization
593   aGA.SetArgument(theShape);
594   aGA.SetTolerance(theTolerance);
595   aGA.SetKeepNonSolids(doKeepNonSolids);
596
597   // 2. Detect interferred shapes
598   aGA.Detect();
599
600   //modified by NIZNHY-PKV Tue Mar 13 14:07:12 2012f
601 #if OCC_VERSION_LARGE > 0x06050200
602   Standard_Integer iWrnDetect = aGA.WarningStatus();
603   if (iWrnDetect == 2) {
604     /*
605     TopTools_ListIteratorOfListOfShape aItLS;
606
607     // Sticked shapes are detected
608     const TopTools_IndexedDataMapOfShapeListOfShape& aIDMSS = pGluer2->StickedShapes();
609
610     Standard_Integer i, aNb = aIDMSS.Extent();
611     for (i = 1; i <= aNb; ++i) {
612       // ancestor aSa (edge, wire face,..)  
613       const TopoDS_Shape& aSa = aIDMSS.FindKey(i); 
614
615       // successors aSs (vertex, edge, ...)
616       // of the ancestor that are sticked 
617       // for given value of the tolerance
618       const TopTools_ListOfShape& aLSS = aIDMSS.FindFromIndex(i);
619       aItLS.Initialize(aLSS);
620       for (; aItLS.More(); aItLS.Next()) {
621         const TopoDS_Shape& aSs = aItLS.Value();
622       }
623     }
624     */
625     Standard_Failure::Raise("GLUE_ERROR_STICKED_SHAPES");
626   }
627 #endif
628   //modified by NIZNHY-PKV Tue Mar 13 14:07:14 2012t
629
630   Standard_Integer iErr = aGA.ErrorStatus();
631   if (iErr) {
632     switch (iErr) {
633     case 11:
634       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
635       break;
636     case 13:
637     case 14:
638       Standard_Failure::Raise("PerformImagesToWork failed");
639       break;
640     default:
641       {
642         // description of all errors see in GEOMAlgo_Gluer2.cxx
643         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
644         aMsg += TCollection_AsciiString(iErr);
645         Standard_Failure::Raise(aMsg.ToCString());
646         break;
647       }
648     }
649     return aRes;
650   }
651
652   // 3. Fill shapes to glue aMSG
653   TopTools_DataMapOfShapeListOfShape aMSG;
654   const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected();
655   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD;
656   aItMSD.Initialize(aMSD);
657   for (; aItMSD.More(); aItMSD.Next()) {
658     const TopoDS_Shape& aSx = aItMSD.Key();
659     const TopTools_ListOfShape& aLSD = aItMSD.Value();
660     TopTools_ListIteratorOfListOfShape anItLSD (aLSD);
661     bool isToGlue = false;
662     if (doGlueAllEdges && aSx.ShapeType() == TopAbs_EDGE) {
663       isToGlue = true;
664     }
665     else {
666       for (; anItLSD.More() && !isToGlue; anItLSD.Next()) {
667         if (theShapesList.Contains(anItLSD.Value())) {
668           isToGlue = true;
669         }
670       }
671     }
672     if (isToGlue) {
673       aMSG.Bind(aSx, aLSD);
674     }
675   }
676
677   // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done
678   aGA.SetShapesToGlue(aMSG);
679
680   // 5. Gluing
681   aGA.Perform();
682   iErr = aGA.ErrorStatus();
683   if (iErr) {
684     switch (iErr) {
685     case 11:
686       Standard_Failure::Raise("GEOMAlgo_GlueDetector failed");
687       break;
688     case 13:
689     case 14:
690       Standard_Failure::Raise("PerformImagesToWork failed");
691       break;
692     default:
693       {
694         // description of all errors see in GEOMAlgo_Gluer2.cxx
695         TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code ");
696         aMsg += TCollection_AsciiString(iErr);
697         Standard_Failure::Raise(aMsg.ToCString());
698         break;
699       }
700     }
701     return aRes;
702   }
703
704   Standard_Integer iWrn = aGA.WarningStatus();
705   if (iWrn) {
706     switch (iWrn) {
707     case 1:
708       MESSAGE("No shapes to glue");
709       break;
710     default:
711       // description of all warnings see in GEOMAlgo_Gluer2.cxx
712       MESSAGE("Warning in GEOMAlgo_Gluer2 with code " << iWrn);
713       break;
714     }
715   }
716
717   // 6. Result
718   aRes = aGA.Shape();
719
720   return aRes;
721 }
722
723 //=======================================================================
724 //function : Execute
725 //purpose  :
726 //=======================================================================
727 Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const
728 {
729   if (Label().IsNull()) return 0;
730   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
731
732   GEOMImpl_IGlue aCI (aFunction);
733   Standard_Integer aType = aFunction->GetType();
734
735   TopoDS_Shape aShape;
736   TCollection_AsciiString aWrn;
737
738   Handle(GEOM_Function) aRefBase = aCI.GetBase();
739   TopoDS_Shape aShapeBase = aRefBase->GetValue();
740   if (aShapeBase.IsNull()) {
741     Standard_NullObject::Raise("Shape for gluing is null");
742   }
743
744   Standard_Real tol3d = aCI.GetTolerance();
745
746   Standard_Boolean aKeepNonSolids = aCI.GetKeepNonSolids();
747
748   // Copy initial shape to prevent its modification by gluing algorithm
749   TopoDS_Shape aShapeCopy;
750   TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
751   TNaming_CopyShape::CopyTool(aShapeBase, aMapTShapes, aShapeCopy);
752
753   if (aType == GLUE_FACES) {
754     //aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aKeepNonSolids, aWrn);
755     aShape = GlueWithWarnings(aShapeCopy, tol3d, TopAbs_FACE, aKeepNonSolids, aWrn);
756   }
757   else if (aType == GLUE_EDGES) {
758     aShape = GlueWithWarnings(aShapeCopy, tol3d, TopAbs_EDGE, aKeepNonSolids, aWrn);
759   }
760   else if (aType == GLUE_FACES_BY_LIST || aType == GLUE_EDGES_BY_LIST) {
761     Handle(TColStd_HSequenceOfTransient) SF = aCI.GetFaces();
762     TopTools_MapOfShape aFaces;
763     int i = 1;
764
765     // map sub-shapes to select faces from aShapeCopy
766     TopTools_IndexedMapOfShape aShapeBase_inds;
767     TopTools_IndexedMapOfShape aShapeCopy_inds;
768     TopExp::MapShapes(aShapeBase, aShapeBase_inds);
769     TopExp::MapShapes(aShapeCopy, aShapeCopy_inds);
770
771     for (; i <= SF->Length(); i++) {
772       Handle(Standard_Transient) anItem = SF->Value(i);
773       if (anItem.IsNull())
774         continue;
775       Handle(GEOM_Function) aRefSh = Handle(GEOM_Function)::DownCast(anItem);
776       if (aRefSh.IsNull())
777         continue;
778       TopoDS_Shape aFace = aRefSh->GetValue();
779       if (aFace.IsNull())
780         continue;
781
782       // get copy of face to correspond to aShapeCopy
783       if (aShapeBase_inds.Contains(aFace)) {
784         int ind = aShapeBase_inds.FindIndex(aFace);
785         aFace = aShapeCopy_inds.FindKey(ind);
786
787         aFaces.Add(aFace);
788       }
789     }
790
791     Standard_Boolean aGlueAllEdges = Standard_False;
792     if (aType == GLUE_FACES_BY_LIST)
793       aGlueAllEdges = aCI.GetGlueAllEdges();
794
795     //aShape = GlueFacesByList(aShapeBase, tol3d, aKeepNonSolids, aFaces);
796     aShape = GlueByList(aShapeCopy, tol3d, aKeepNonSolids, aFaces, aGlueAllEdges);
797   }
798
799   if (aShape.IsNull()) return 0;
800
801   aFunction->SetValue(aShape);
802
803   log.SetTouched(Label());
804
805   if (!aWrn.IsEmpty()) {
806     Standard_Failure::Raise(aWrn.ToCString());
807   }
808
809   return 1;
810 }
811
812 //================================================================================
813 /*!
814  * \brief Returns a name of creation operation and names and values of creation parameters
815  */
816 //================================================================================
817
818 bool GEOMImpl_GlueDriver::
819 GetCreationInformation(std::string&             theOperationName,
820                        std::vector<GEOM_Param>& theParams)
821 {
822   if (Label().IsNull()) return 0;
823   Handle(GEOM_Function) function = GEOM_Function::GetFunction(Label());
824
825   GEOMImpl_IGlue aCI( function );
826   Standard_Integer aType = function->GetType();
827
828   switch ( aType ) {
829   case GLUE_FACES:
830     theOperationName = "GLUE_FACES";
831     AddParam( theParams, "Selected shape", aCI.GetBase() );
832     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
833     AddParam( theParams, "To keep non solids", aCI.GetKeepNonSolids() );
834     break;
835   case GLUE_EDGES:
836     theOperationName = "GLUE_EDGES";
837     AddParam( theParams, "Selected shape", aCI.GetBase() );
838     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
839     break;
840   case GLUE_FACES_BY_LIST:
841     theOperationName = "GLUE_FACES";
842     AddParam( theParams, "Selected shape", aCI.GetBase() );
843     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
844     AddParam( theParams, "Faces", aCI.GetFaces() );
845     AddParam( theParams, "To keep non solids", aCI.GetKeepNonSolids() );
846     AddParam( theParams, "To glue all edges", aCI.GetGlueAllEdges() );
847     break;
848   case GLUE_EDGES_BY_LIST:
849     theOperationName = "GLUE_EDGES";
850     AddParam( theParams, "Selected shape", aCI.GetBase() );
851     AddParam( theParams, "Tolerance", aCI.GetTolerance() );
852     AddParam( theParams, "Edges", aCI.GetFaces() );
853     break;
854   default:
855     return false;
856   }
857   
858   return true;
859 }
860
861 IMPLEMENT_STANDARD_HANDLE (GEOMImpl_GlueDriver,GEOM_BaseDriver);
862 IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_GlueDriver,GEOM_BaseDriver);