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