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