Salome HOME
07a634d7c05a05af05ff9c72b4545b676768a781
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IGroupOperations.cxx
1 #include <Standard_Stream.hxx>
2
3 #include <GEOMImpl_IGroupOperations.hxx>
4
5 #include <GEOMImpl_Types.hxx>
6
7 #include <GEOM_Function.hxx>
8 #include <GEOM_ISubShape.hxx>
9 #include <GEOM_PythonDump.hxx>
10
11 #include "utilities.h"
12 #include <OpUtil.hxx>
13 #include <Utils_ExceptHandlers.hxx>
14
15 #include <TFunction_DriverTable.hxx>
16 #include <TFunction_Driver.hxx>
17 #include <TFunction_Logbook.hxx>
18 #include <TDF_Tool.hxx>
19 #include <TDataStd_Integer.hxx>
20
21 #include <TopExp.hxx>
22 #include <TopTools_IndexedMapOfShape.hxx>
23
24 #include <TColStd_HArray1OfInteger.hxx>
25 #include <TColStd_MapOfInteger.hxx>
26 #include <TColStd_ListOfInteger.hxx>
27 #include <TColStd_ListIteratorOfListOfInteger.hxx>
28
29 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
30
31 //=============================================================================
32 /*!
33  *   constructor:
34  */
35 //=============================================================================
36 GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations (GEOM_Engine* theEngine, int theDocID) 
37 : GEOM_IOperations(theEngine, theDocID)
38 {
39   MESSAGE("GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations");
40 }
41
42 //=============================================================================
43 /*!
44  *  destructor
45  */
46 //=============================================================================
47 GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations()
48 {
49   MESSAGE("GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations");
50 }
51
52
53 //=============================================================================
54 /*!
55  *  CreateGroup
56  */
57 //=============================================================================
58 Handle(GEOM_Object) GEOMImpl_IGroupOperations::CreateGroup
59        (Handle(GEOM_Object) theMainShape, TopAbs_ShapeEnum  theShapeType)
60 {
61   SetErrorCode(KO);
62
63   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
64   anArray->SetValue(1, -1);
65
66   //Add a new Fillet object
67   Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theMainShape, anArray);
68
69   //Set a GROUP type
70   aGroup->SetType(GEOM_GROUP);
71
72   //Set a sub shape type
73   TDF_Label aFreeLabel = aGroup->GetFreeLabel();
74   TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
75
76   //Make a Python command
77   Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
78   //TCollection_AsciiString anOldDescr = aFunction->GetDescription();
79
80   //GEOM::TPythonDump(aFunction) << anOldDescr.ToCString() << "\n\t" << aGroup
81   GEOM::TPythonDump(aFunction) << aGroup
82     << " = geompy.CreateGroup(" << theMainShape << ", " << (int)theShapeType << ")";
83
84   SetErrorCode(OK);
85   return aGroup; 
86 }
87
88 //=============================================================================
89 /*!
90  *  AddObject
91  */
92 //=============================================================================
93 void GEOMImpl_IGroupOperations::AddObject(Handle(GEOM_Object) theGroup, int theSubShapeID)
94 {
95   SetErrorCode(KO);
96   if(theGroup.IsNull()) return;
97
98   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
99   if(aFunction.IsNull()) return;
100
101   GEOM_ISubShape aSSI(aFunction);
102   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
103   if(aSeq.IsNull()) return;
104   if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
105     aSeq->SetValue(1, theSubShapeID);
106   }
107   else {
108     Standard_Integer aLength = aSeq->Length();
109     Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength+1);
110     for(Standard_Integer i = 1; i<=aLength; i++) {
111       aNewSeq->SetValue(i, aSeq->Value(i));
112       if(aSeq->Value(i) == theSubShapeID) {
113         SetErrorCode(ALREADY_PRESENT);
114         return; //
115       }
116     }
117     aNewSeq->SetValue(aLength+1, theSubShapeID);
118     aSSI.SetIndices(aNewSeq);
119   }
120
121   //Make a Python command 
122   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
123
124   GEOM::TPythonDump(aFunction) << anOldDescr.ToCString() << "\n\t"
125     << "geompy.AddObject(" << theGroup << ", " << theSubShapeID << ")";
126
127   SetErrorCode(OK);
128   return; 
129 }
130
131 //=============================================================================
132 /*!
133  *  RemoveObject
134  */
135 //=============================================================================
136 void GEOMImpl_IGroupOperations::RemoveObject (Handle(GEOM_Object) theGroup, int theSubShapeID)
137 {
138   SetErrorCode(KO);
139   if(theGroup.IsNull()) return;
140
141   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
142   if(aFunction.IsNull()) return;
143
144   GEOM_ISubShape aSSI(aFunction);
145   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
146   if(aSeq.IsNull()) return;
147   if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
148     SetErrorCode(NOT_EXISTS);
149     return;
150   }
151   else {
152     Handle(TColStd_HArray1OfInteger) aNewSeq;
153     Standard_Integer aLength = aSeq->Length();
154     if(aLength == 1) {
155       if(aSeq->Value(1) != theSubShapeID) {
156         SetErrorCode(NOT_EXISTS);
157         return;         
158       }
159       aNewSeq = new TColStd_HArray1OfInteger(1,1);
160       aNewSeq->SetValue(1, -1);
161     }
162     else {
163       aNewSeq = new TColStd_HArray1OfInteger(1, aLength-1);
164       Standard_Boolean isFound = Standard_False;
165       for(Standard_Integer i = 1, k=1; i<=aLength; i++) {
166         if(i == aLength && !isFound) {
167           SetErrorCode(NOT_EXISTS);
168           return; 
169         }
170         if(aSeq->Value(i) == theSubShapeID) {
171           isFound = Standard_True;
172           continue;
173         }
174         aNewSeq->SetValue(k, aSeq->Value(i));
175         k++;
176       }
177
178       if(!isFound) {
179         SetErrorCode(NOT_EXISTS);
180         return; 
181       }
182     }
183
184     aSSI.SetIndices(aNewSeq);
185   }
186
187   //Make a Python command 
188   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
189
190   GEOM::TPythonDump(aFunction) << anOldDescr.ToCString() << "\n\t"
191     << "geompy.RemoveObject(" << theGroup << ", " << theSubShapeID << ")";
192
193   SetErrorCode(OK);
194   return; 
195 }
196
197 //=============================================================================
198 /*!
199  *  UnionList
200  */
201 //=============================================================================
202 void GEOMImpl_IGroupOperations::UnionList (Handle(GEOM_Object) theGroup,
203                                            const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
204 {
205   SetErrorCode(KO);
206   if (theGroup.IsNull()) return;
207
208   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
209   if (aFunction.IsNull()) return;
210
211   GEOM_ISubShape aSSI (aFunction);
212
213   // New contents of the group
214   TColStd_ListOfInteger aNewIDs;
215   TColStd_MapOfInteger mapIDs;
216
217   // Add current IDs to the list
218   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
219   if (aSeq.IsNull()) return;
220   Standard_Integer val_j, aLength = aSeq->Length();
221
222   for (Standard_Integer j = 1; j <= aLength; j++) {
223     val_j = aSeq->Value(j);
224     if (val_j > 0 && mapIDs.Add(val_j)) {
225       aNewIDs.Append(val_j);
226     }
227   }
228
229   // Get Main Shape
230   Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
231   if (aMainShapeFunc.IsNull()) return;
232   TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
233   if (aLabel.IsRoot()) return;
234   Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
235   if (aMainObj.IsNull()) return;
236   TopoDS_Shape aMainShape = aMainObj->GetValue();
237   if (aMainShape.IsNull()) return;
238
239   TopTools_IndexedMapOfShape mapIndices;
240   TopExp::MapShapes(aMainShape, mapIndices);
241
242   // Get IDs of sub-shapes to add
243   Standard_Integer i, new_id, aLen = theSubShapes->Length();
244   for (i = 1; i <= aLen; i++) {
245     Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
246
247     if (anObj_i->IsMainShape()) {
248       TopoDS_Shape aShape_i = anObj_i->GetValue();
249       if (mapIndices.Contains(aShape_i)) {
250         new_id = mapIndices.FindIndex(aShape_i);
251         if (mapIDs.Add(new_id)) {
252           aNewIDs.Append(new_id);
253         }
254       } else {
255         SetErrorCode("One of given objects can not be added to the group, because it is not a sub-shape of the group's main shape");
256         return;
257       }
258     } else {
259       // Check main shape of sub-shape to add
260       Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1);
261       if (aFunc_i.IsNull()) return;
262
263       GEOM_ISubShape aSSI_i (aFunc_i);
264
265       Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape();
266       if (aMainShapeFunc_i.IsNull()) return;
267       TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry();
268       if (aLabel_i.IsRoot()) return;
269       Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel);
270       if (aMainObj_i.IsNull()) return;
271       TopoDS_Shape aMainShape_i = aMainObj_i->GetValue();
272       if (aMainShape_i.IsNull()) return;
273
274       if (aMainShape_i.IsSame(aMainShape)) {
275         // add all sub-shape IDs to the list
276
277         // Get IDs
278         Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
279         if (aSeq_i.IsNull()) return;
280         Standard_Integer aLength_i = aSeq_i->Length();
281
282         for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
283           new_id = aSeq_i->Value(i_j);
284           if (new_id > 0) {
285             if (mapIDs.Add(new_id)) {
286               aNewIDs.Append(new_id);
287             }
288           }
289         }
290
291       } else if (mapIndices.Contains(aMainShape_i)) {
292         // compute new IDs and add them to the list
293         TopTools_IndexedMapOfShape mapIndices_i;
294         TopExp::MapShapes(aMainShape_i, mapIndices_i);
295
296         // Get IDs
297         Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
298         if (aSeq_i.IsNull()) return;
299         Standard_Integer aLength_i = aSeq_i->Length();
300
301         for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
302           if (aSeq_i->Value(i_j) > 0) {
303             TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j);
304             new_id = mapIndices.FindIndex(aShape_i_j);
305             if (mapIDs.Add(new_id)) {
306               aNewIDs.Append(new_id);
307             }
308           }
309         }
310
311       } else {
312         SetErrorCode("One of given objects can not be added to the group, because it is not a sub-shape of the group's main shape");
313         return;
314       }
315     }
316   }
317
318   if (aNewIDs.Extent() > 0) {
319     Standard_Integer k = 1;
320     TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
321     Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
322     for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
323       aNewSeq->SetValue(k, aNewIDsIter.Value());
324     }
325
326     aSSI.SetIndices(aNewSeq);
327   }
328
329   //Make a Python command 
330   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
331
332   GEOM::TPythonDump pd (aFunction);
333   pd << anOldDescr.ToCString() << "\n\t" << "geompy.UnionList(" << theGroup << ", [";
334
335   for (i = 1; i <= aLen; i++) {
336     Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
337     pd << anObj_i << (( i < aLen ) ? ", " : "])");
338   }
339
340   SetErrorCode(OK);
341 }
342
343 //=============================================================================
344 /*!
345  *  DifferenceList
346  */
347 //=============================================================================
348 void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
349                                                 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
350 {
351   SetErrorCode(KO);
352   if (theGroup.IsNull()) return;
353
354   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
355   if (aFunction.IsNull()) return;
356
357   GEOM_ISubShape aSSI (aFunction);
358
359   // Map of IDs to be removed
360   TColStd_MapOfInteger mapIDsToRemove;
361
362   // Map of current IDs
363   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
364   if (aSeq.IsNull()) return;
365   Standard_Integer aLength = aSeq->Length();
366
367   if (aLength == 1 && aSeq->Value(1) == -1) // empty group
368     return;
369
370   TColStd_MapOfInteger mapIDsCurrent;
371   Standard_Integer j = 1;
372   for (; j <= aLength; j++) {
373     mapIDsCurrent.Add(aSeq->Value(j));
374   }
375
376   // Get Main Shape
377   Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
378   if (aMainShapeFunc.IsNull()) return;
379   TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
380   if (aLabel.IsRoot()) return;
381   Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
382   if (aMainObj.IsNull()) return;
383   TopoDS_Shape aMainShape = aMainObj->GetValue();
384   if (aMainShape.IsNull()) return;
385
386   TopTools_IndexedMapOfShape mapIndices;
387   TopExp::MapShapes(aMainShape, mapIndices);
388
389   // Get IDs of sub-shapes to be removed
390   Standard_Integer i, rem_id, aLen = theSubShapes->Length();
391   for (i = 1; i <= aLen; i++) {
392     Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
393
394     if (anObj_i->IsMainShape()) {
395       TopoDS_Shape aShape_i = anObj_i->GetValue();
396       if (mapIndices.Contains(aShape_i)) {
397         rem_id = mapIndices.FindIndex(aShape_i);
398         if (mapIDsCurrent.Contains(rem_id)) {
399           mapIDsToRemove.Add(rem_id);
400         }
401       } else {
402         SetErrorCode("One of given objects can not be removed from the group, because it is not a sub-shape of the group's main shape");
403         return;
404       }
405     } else {
406       // Check main shape of sub-shape to be removed
407       Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1);
408       if (aFunc_i.IsNull()) return;
409
410       GEOM_ISubShape aSSI_i (aFunc_i);
411
412       Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape();
413       if (aMainShapeFunc_i.IsNull()) return;
414       TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry();
415       if (aLabel_i.IsRoot()) return;
416       Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel);
417       if (aMainObj_i.IsNull()) return;
418       TopoDS_Shape aMainShape_i = aMainObj_i->GetValue();
419       if (aMainShape_i.IsNull()) return;
420
421       if (aMainShape_i.IsSame(aMainShape)) {
422         // remove all sub-shapes
423
424         // Get IDs
425         Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
426         if (aSeq_i.IsNull()) return;
427         Standard_Integer aLength_i = aSeq_i->Length();
428
429         for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
430           rem_id = aSeq_i->Value(i_j);
431           if (rem_id > 0) {
432             if (mapIDsCurrent.Contains(rem_id)) {
433               mapIDsToRemove.Add(rem_id);
434             }
435           }
436         }
437
438       } else if (mapIndices.Contains(aMainShape_i)) {
439         // compute new IDs and add them to the map of ids to be removed
440         TopTools_IndexedMapOfShape mapIndices_i;
441         TopExp::MapShapes(aMainShape_i, mapIndices_i);
442
443         // Get IDs
444         Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices();
445         if (aSeq_i.IsNull()) return;
446         Standard_Integer aLength_i = aSeq_i->Length();
447
448         for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) {
449           if (aSeq_i->Value(i_j) > 0) {
450             TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j);
451             rem_id = mapIndices.FindIndex(aShape_i_j);
452             if (mapIDsCurrent.Contains(rem_id)) {
453               mapIDsToRemove.Add(rem_id);
454             }
455           }
456         }
457
458       } else {
459         SetErrorCode("One of given objects can not be removed from the group, because it is not a sub-shape of the group's main shape");
460         return;
461       }
462     }
463   }
464
465   if (mapIDsToRemove.Extent() > 0) {
466     Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
467     Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
468
469     for (j = 1; j <= aLength; j++) {
470       if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
471         aNewSeq->SetValue(k, aSeq->Value(j));
472         k++;
473       }
474     }
475
476     aSSI.SetIndices(aNewSeq);
477   }
478
479   //Make a Python command
480   TCollection_AsciiString anOldDescr = aFunction->GetDescription();
481
482   GEOM::TPythonDump pd (aFunction);
483   pd << anOldDescr.ToCString() << "\n\t" << "geompy.DifferenceList(" << theGroup << ", [";
484
485   for (i = 1; i <= aLen; i++) {
486     Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
487     pd << anObj_i << (( i < aLen ) ? ", " : "])");
488   }
489
490   SetErrorCode(OK);
491 }
492 //=============================================================================
493 /*!
494  *  UnionIDs
495  */
496 //=============================================================================
497 void GEOMImpl_IGroupOperations::UnionIDs (Handle(GEOM_Object) theGroup,
498                                           const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
499 {
500   SetErrorCode(KO);
501   if (theGroup.IsNull()) return;
502
503   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
504   if (aFunction.IsNull()) return;
505
506   GEOM_ISubShape aSSI (aFunction);
507
508   // New contents of the group
509   TColStd_ListOfInteger aNewIDs;
510   TColStd_MapOfInteger mapIDs;
511
512   // Add current IDs to the list
513   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
514   if (aSeq.IsNull()) return;
515   Standard_Integer val_j, aLength = aSeq->Length();
516
517   for (Standard_Integer j = 1; j <= aLength; j++) {
518     val_j = aSeq->Value(j);
519     if (val_j > 0 && mapIDs.Add(val_j)) {
520       aNewIDs.Append(val_j);
521     }
522   }
523
524   // Get Main Shape
525   Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
526   if (aMainShapeFunc.IsNull()) return;
527   TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
528   if (aLabel.IsRoot()) return;
529   Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
530   if (aMainObj.IsNull()) return;
531   TopoDS_Shape aMainShape = aMainObj->GetValue();
532   if (aMainShape.IsNull()) return;
533
534   TopTools_IndexedMapOfShape mapIndices;
535   TopExp::MapShapes(aMainShape, mapIndices);
536
537   // Get IDs of sub-shapes to add
538   Standard_Integer i, new_id, aLen = theSubShapes->Length();
539   for (i = 1; i <= aLen; i++) {
540     new_id = theSubShapes->Value(i);
541
542     if (0 < new_id && new_id <= mapIndices.Extent()) {
543       if (mapIDs.Add(new_id)) {
544         aNewIDs.Append(new_id);
545       }
546     }
547   }
548
549   if (aNewIDs.Extent() > 0) {
550     Standard_Integer k = 1;
551     TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
552     Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
553     for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
554       aNewSeq->SetValue(k, aNewIDsIter.Value());
555     }
556
557     aSSI.SetIndices(aNewSeq);
558   }
559
560   SetErrorCode(OK);
561 }
562
563 //=============================================================================
564 /*!
565  *  DifferenceIDs
566  */
567 //=============================================================================
568 void GEOMImpl_IGroupOperations::DifferenceIDs (Handle(GEOM_Object) theGroup,
569                                                const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
570 {
571   SetErrorCode(KO);
572   if (theGroup.IsNull()) return;
573
574   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
575   if (aFunction.IsNull()) return;
576
577   GEOM_ISubShape aSSI (aFunction);
578
579   // Map of IDs to be removed
580   TColStd_MapOfInteger mapIDsToRemove;
581
582   // Map of current IDs
583   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
584   if (aSeq.IsNull()) return;
585   Standard_Integer aLength = aSeq->Length();
586
587   if (aLength == 1 && aSeq->Value(1) == -1) // empty group
588     return;
589
590   TColStd_MapOfInteger mapIDsCurrent;
591   Standard_Integer j = 1;
592   for (; j <= aLength; j++) {
593     mapIDsCurrent.Add(aSeq->Value(j));
594   }
595
596   // Get Main Shape
597   Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
598   if (aMainShapeFunc.IsNull()) return;
599   TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
600   if (aLabel.IsRoot()) return;
601   Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
602   if (aMainObj.IsNull()) return;
603   TopoDS_Shape aMainShape = aMainObj->GetValue();
604   if (aMainShape.IsNull()) return;
605
606   TopTools_IndexedMapOfShape mapIndices;
607   TopExp::MapShapes(aMainShape, mapIndices);
608
609   // Get IDs of sub-shapes to be removed
610   Standard_Integer i, rem_id, aLen = theSubShapes->Length();
611   for (i = 1; i <= aLen; i++) {
612     rem_id = theSubShapes->Value(i);
613     if (mapIDsCurrent.Contains(rem_id)) {
614       mapIDsToRemove.Add(rem_id);
615     }
616   }
617
618   if (mapIDsToRemove.Extent() > 0) {
619     Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
620     Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
621
622     for (j = 1; j <= aLength; j++) {
623       if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
624         aNewSeq->SetValue(k, aSeq->Value(j));
625         k++;
626       }
627     }
628
629     aSSI.SetIndices(aNewSeq);
630   }
631
632   SetErrorCode(OK);
633 }
634
635 //=============================================================================
636 /*!
637  *  GetType
638  */
639 //=============================================================================
640 TopAbs_ShapeEnum GEOMImpl_IGroupOperations::GetType(Handle(GEOM_Object) theGroup)
641 {
642   SetErrorCode(KO);
643
644   TDF_Label aFreeLabel = theGroup->GetFreeLabel();
645   Handle(TDataStd_Integer) anAttrib;
646   if(!aFreeLabel.FindAttribute(TDataStd_Integer::GetID(), anAttrib)) return TopAbs_SHAPE;
647  
648   SetErrorCode(OK);
649   return (TopAbs_ShapeEnum) anAttrib->Get(); 
650 }
651
652 //=============================================================================
653 /*!
654  *  GetMainShape
655  */
656 //=============================================================================
657 Handle(GEOM_Object) GEOMImpl_IGroupOperations::GetMainShape (Handle(GEOM_Object) theGroup)
658 {
659   SetErrorCode(KO);
660
661   if(theGroup.IsNull()) return NULL;
662
663   Handle(GEOM_Function) aGroupFunction = theGroup->GetFunction(1);
664   if (aGroupFunction.IsNull()) return NULL;
665
666   GEOM_ISubShape aSSI (aGroupFunction);
667   Handle(GEOM_Function) aMainShapeFunction = aSSI.GetMainShape();
668   if (aMainShapeFunction.IsNull()) return NULL;
669
670   TDF_Label aLabel = aMainShapeFunction->GetOwnerEntry();
671   Handle(GEOM_Object) aMainShape = GEOM_Object::GetObject(aLabel);
672   if (aMainShape.IsNull()) return NULL;
673
674   //Make a Python command
675   TCollection_AsciiString anOldDescr = aGroupFunction->GetDescription();
676
677   GEOM::TPythonDump(aGroupFunction) << anOldDescr.ToCString() << "\n\t"
678     << aMainShape << " = geompy.GetMainShape(" << theGroup << ")";
679
680   SetErrorCode(OK);
681   return aMainShape; 
682 }
683
684 //=============================================================================
685 /*!
686  *  GetObjects
687  */
688 //=============================================================================
689 Handle(TColStd_HArray1OfInteger) GEOMImpl_IGroupOperations::GetObjects(Handle(GEOM_Object) theGroup)
690 {
691   SetErrorCode(KO);
692   
693    if(theGroup.IsNull()) return NULL;
694
695   Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
696   if(aFunction.IsNull()) return NULL;
697   
698   GEOM_ISubShape aSSI(aFunction);
699   Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
700   if(aSeq.IsNull()) return NULL;
701
702   if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
703     SetErrorCode(OK);
704     return NULL;
705   }
706
707   SetErrorCode(OK);
708   return aSeq;
709 }