1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_IGroupOperations.hxx>
27 #include <GEOMImpl_Types.hxx>
29 #include <GEOM_Function.hxx>
30 #include <GEOM_ISubShape.hxx>
31 #include <GEOM_PythonDump.hxx>
33 #include "utilities.h"
35 #include <Utils_ExceptHandlers.hxx>
37 #include <TFunction_DriverTable.hxx>
38 #include <TFunction_Driver.hxx>
39 #include <TFunction_Logbook.hxx>
40 #include <TDF_Tool.hxx>
41 #include <TDataStd_Integer.hxx>
44 #include <TopExp_Explorer.hxx>
45 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <TColStd_HArray1OfInteger.hxx>
48 #include <TColStd_MapOfInteger.hxx>
49 #include <TColStd_ListOfInteger.hxx>
50 #include <TColStd_ListIteratorOfListOfInteger.hxx>
52 //=============================================================================
56 //=============================================================================
57 GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations (GEOM_Engine* theEngine, int theDocID)
58 : GEOM_IOperations(theEngine, theDocID)
60 MESSAGE("GEOMImpl_IGroupOperations::GEOMImpl_IGroupOperations");
63 //=============================================================================
67 //=============================================================================
68 GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations()
70 MESSAGE("GEOMImpl_IGroupOperations::~GEOMImpl_IGroupOperations");
74 //=============================================================================
78 //=============================================================================
79 Handle(GEOM_Object) GEOMImpl_IGroupOperations::CreateGroup
80 (Handle(GEOM_Object) theMainShape, TopAbs_ShapeEnum theShapeType)
84 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
85 anArray->SetValue(1, -1);
87 //Add a new Sub-shape object
88 Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theMainShape, anArray);
91 aGroup->SetType(GEOM_GROUP);
93 //Set a sub shape type
94 TDF_Label aFreeLabel = aGroup->GetFreeLabel();
95 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType);
97 //Make a Python command
98 Handle(GEOM_Function) aFunction = aGroup->GetFunction(1);
100 GEOM::TPythonDump(aFunction) << aGroup
101 << " = geompy.CreateGroup(" << theMainShape << ", " << theShapeType << ")";
107 //=============================================================================
111 //=============================================================================
112 void GEOMImpl_IGroupOperations::AddObject(Handle(GEOM_Object) theGroup, int theSubShapeID)
115 if(theGroup.IsNull()) return;
117 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
118 if(aFunction.IsNull()) return;
120 GEOM_ISubShape aSSI (aFunction);
122 // Check sub-shape index validity
123 TDF_Label aLabel = aSSI.GetMainShape()->GetOwnerEntry();
124 if (aLabel.IsRoot()) return;
125 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
126 if (aMainObj.IsNull()) return;
127 TopoDS_Shape aMainShape = aMainObj->GetValue();
128 if (aMainShape.IsNull()) return;
130 TopTools_IndexedMapOfShape aMapOfShapes;
131 TopExp::MapShapes(aMainShape, aMapOfShapes);
133 if (theSubShapeID < 1 || aMapOfShapes.Extent() < theSubShapeID) {
134 SetErrorCode("Invalid sub-shape index: out of range");
138 // Add sub-shape index
139 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
140 if(aSeq.IsNull()) return;
141 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
142 aSeq->SetValue(1, theSubShapeID);
145 Standard_Integer aLength = aSeq->Length();
146 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength+1);
147 for(Standard_Integer i = 1; i<=aLength; i++) {
148 aNewSeq->SetValue(i, aSeq->Value(i));
149 if(aSeq->Value(i) == theSubShapeID) {
150 SetErrorCode(ALREADY_PRESENT);
154 aNewSeq->SetValue(aLength+1, theSubShapeID);
155 aSSI.SetIndices(aNewSeq);
158 // As we do not recompute here our group, lets mark it as Modified
159 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
160 theGroup->SetTic(aTic - 1);
162 //Make a Python command
163 GEOM::TPythonDump(aFunction, /*append=*/true)
164 << "geompy.AddObject(" << theGroup << ", " << theSubShapeID << ")";
170 //=============================================================================
174 //=============================================================================
175 void GEOMImpl_IGroupOperations::RemoveObject (Handle(GEOM_Object) theGroup, int theSubShapeID)
178 if(theGroup.IsNull()) return;
180 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
181 if(aFunction.IsNull()) return;
183 GEOM_ISubShape aSSI(aFunction);
184 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
185 if(aSeq.IsNull()) return;
187 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {
188 SetErrorCode(NOT_EXISTS);
192 Handle(TColStd_HArray1OfInteger) aNewSeq;
193 Standard_Integer aLength = aSeq->Length();
195 if(aSeq->Value(1) != theSubShapeID) {
196 SetErrorCode(NOT_EXISTS);
199 aNewSeq = new TColStd_HArray1OfInteger(1,1);
200 aNewSeq->SetValue(1, -1);
203 aNewSeq = new TColStd_HArray1OfInteger(1, aLength-1);
204 Standard_Boolean isFound = Standard_False;
205 for (Standard_Integer i = 1, k = 1; i <= aLength; i++) {
206 if (aSeq->Value(i) == theSubShapeID) {
207 isFound = Standard_True;
209 if (k < aLength) { // this check is to avoid sequence <aNewSeq> overflow
210 aNewSeq->SetValue(k, aSeq->Value(i));
217 SetErrorCode(NOT_EXISTS);
222 aSSI.SetIndices(aNewSeq);
224 // As we do not recompute here our group, lets mark it as Modified
225 TDF_Label aLabel = aSSI.GetMainShape()->GetOwnerEntry();
226 if (aLabel.IsRoot()) return;
227 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
228 if (aMainObj.IsNull()) return;
229 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
230 theGroup->SetTic(aTic - 1);
232 //Make a Python command
233 GEOM::TPythonDump(aFunction, /*append=*/true)
234 << "geompy.RemoveObject(" << theGroup << ", " << theSubShapeID << ")";
240 //=============================================================================
244 //=============================================================================
245 void GEOMImpl_IGroupOperations::UnionList (Handle(GEOM_Object) theGroup,
246 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
249 if (theGroup.IsNull()) return;
251 Standard_Integer aLen = theSubShapes->Length();
253 //SetErrorCode("The list is empty");
258 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
259 if (aFunction.IsNull()) return;
261 GEOM_ISubShape aSSI (aFunction);
263 // New contents of the group
264 TColStd_ListOfInteger aNewIDs;
265 TColStd_MapOfInteger mapIDs;
267 // Add current IDs to the list
268 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
269 if (aSeq.IsNull()) return;
270 Standard_Integer val_j, aLength = aSeq->Length();
272 for (Standard_Integer j = 1; j <= aLength; j++) {
273 val_j = aSeq->Value(j);
274 if (val_j > 0 && mapIDs.Add(val_j)) {
275 aNewIDs.Append(val_j);
280 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
281 if (aMainShapeFunc.IsNull()) return;
282 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
283 if (aLabel.IsRoot()) return;
284 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
285 if (aMainObj.IsNull()) return;
286 TopoDS_Shape aMainShape = aMainObj->GetValue();
287 if (aMainShape.IsNull()) return;
289 TopTools_IndexedMapOfShape mapIndices;
290 TopExp::MapShapes(aMainShape, mapIndices);
293 TopAbs_ShapeEnum aType = GetType(theGroup);
295 // Get IDs of sub-shapes to add
296 Standard_Integer i, new_id;
297 for (i = 1; i <= aLen; i++) {
298 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
300 TopoDS_Shape aShape_i = anObj_i->GetValue();
301 TopAbs_ShapeEnum aType_i = aShape_i.ShapeType();
303 // 1. If aShape_i is sub-shape of aMainShape - add it
304 if (anObj_i->IsMainShape()) {
305 if (aType_i != aType && aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
306 SetErrorCode("Operation aborted: one of given objects has a wrong type");
309 if (!mapIndices.Contains(aShape_i)) {
310 SetErrorCode("Operation aborted: not a sub-shape given");
313 new_id = mapIndices.FindIndex(aShape_i);
314 if (mapIDs.Add(new_id)) {
315 aNewIDs.Append(new_id);
318 // 2. If type of group is not defined - add all sub-shapes of aShape_i
319 else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
320 TopTools_IndexedMapOfShape mapIndices_i;
321 TopExp::MapShapes(aShape_i, mapIndices_i);
322 Standard_Integer ii = 1, nbSubSh = mapIndices_i.Extent();
323 Standard_Boolean someGood = Standard_False;
324 for (; ii <= nbSubSh; ii++) {
325 TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
326 if (mapIndices.Contains(aSubShape_i)) {
327 someGood = Standard_True;
328 new_id = mapIndices.FindIndex(aSubShape_i);
329 if (mapIDs.Add(new_id)) {
330 aNewIDs.Append(new_id);
335 SetErrorCode("Operation aborted: not a sub-shape given");
339 // 3. If type of group is defined - add all sub-shapes of aShape_i of that type
341 TopExp_Explorer aSubShapes_i (aShape_i, aType);
342 for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
343 TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
344 if (!mapIndices.Contains(aSubShape_i)) {
345 SetErrorCode("Operation aborted: not a sub-shape given");
348 new_id = mapIndices.FindIndex(aSubShape_i);
349 if (mapIDs.Add(new_id)) {
350 aNewIDs.Append(new_id);
356 if (aNewIDs.Extent() > 0) {
357 Standard_Integer k = 1;
358 TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
359 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
360 for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
361 aNewSeq->SetValue(k, aNewIDsIter.Value());
364 aSSI.SetIndices(aNewSeq);
366 // As we do not recompute here our group, lets mark it as Modified
367 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
368 theGroup->SetTic(aTic - 1);
371 //Make a Python command
372 Handle(GEOM_Object) aLatest = GEOM::GetCreatedLast(theSubShapes);
373 aLatest = GEOM::GetCreatedLast(aLatest, theGroup);
374 Handle(GEOM_Function) aLastFunc = aLatest->GetLastFunction();
376 GEOM::TPythonDump pd (aLastFunc, /*append=*/true);
377 pd << "geompy.UnionList(" << theGroup << ", [";
379 for (i = 1; i <= aLen; i++) {
380 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
381 pd << anObj_i << (( i < aLen ) ? ", " : "])");
387 //=============================================================================
391 //=============================================================================
392 void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
393 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
396 if (theGroup.IsNull()) return;
398 Standard_Integer aLen = theSubShapes->Length();
400 SetErrorCode("The list is empty");
404 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
405 if (aFunction.IsNull()) return;
407 GEOM_ISubShape aSSI (aFunction);
409 // Map of IDs to be removed
410 TColStd_MapOfInteger mapIDsToRemove;
412 // Map of current IDs
413 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
414 if (aSeq.IsNull()) return;
415 Standard_Integer aLength = aSeq->Length();
417 if (aLength == 1 && aSeq->Value(1) == -1) // empty group
420 TColStd_MapOfInteger mapIDsCurrent;
421 Standard_Integer j = 1;
422 for (; j <= aLength; j++) {
423 mapIDsCurrent.Add(aSeq->Value(j));
427 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
428 if (aMainShapeFunc.IsNull()) return;
429 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
430 if (aLabel.IsRoot()) return;
431 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
432 if (aMainObj.IsNull()) return;
433 TopoDS_Shape aMainShape = aMainObj->GetValue();
434 if (aMainShape.IsNull()) return;
436 TopTools_IndexedMapOfShape mapIndices;
437 TopExp::MapShapes(aMainShape, mapIndices);
440 TopAbs_ShapeEnum aType = GetType(theGroup);
442 // Get IDs of sub-shapes to be removed
443 Standard_Integer i, rem_id;
444 for (i = 1; i <= aLen; i++) {
445 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
447 TopoDS_Shape aShape_i = anObj_i->GetValue();
449 // 1. If aShape_i is sub-shape of aMainShape - remove it
450 if (mapIndices.Contains(aShape_i)) {
451 rem_id = mapIndices.FindIndex(aShape_i);
452 if (mapIDsCurrent.Contains(rem_id)) {
453 mapIDsToRemove.Add(rem_id);
456 // 2. If type of group is not defined - remove all sub-shapes of aShape_i
457 else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
458 TopTools_IndexedMapOfShape mapIndices_i;
459 TopExp::MapShapes(aShape_i, mapIndices_i);
460 Standard_Integer nbSubSh = mapIndices_i.Extent();
461 Standard_Integer ii = 1;
462 for (; ii <= nbSubSh; ii++) {
463 TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
464 if (mapIndices.Contains(aSubShape_i)) {
465 rem_id = mapIndices.FindIndex(aSubShape_i);
466 if (mapIDsCurrent.Contains(rem_id)) {
467 mapIDsToRemove.Add(rem_id);
472 // 3. If type of group is defined - remove all sub-shapes of aShape_i of that type
474 TopExp_Explorer aSubShapes_i (aShape_i, aType);
475 for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
476 TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
477 if (mapIndices.Contains(aSubShape_i)) {
478 rem_id = mapIndices.FindIndex(aSubShape_i);
479 if (mapIDsCurrent.Contains(rem_id)) {
480 mapIDsToRemove.Add(rem_id);
487 if (mapIDsToRemove.Extent() > 0) {
488 Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
489 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
491 for (j = 1; j <= aLength; j++) {
492 if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
493 aNewSeq->SetValue(k, aSeq->Value(j));
498 aSSI.SetIndices(aNewSeq);
500 // As we do not recompute here our group, lets mark it as Modified
501 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
502 theGroup->SetTic(aTic - 1);
505 //Make a Python command
506 Handle(GEOM_Object) aLatest = GEOM::GetCreatedLast(theSubShapes);
507 aLatest = GEOM::GetCreatedLast(aLatest, theGroup);
508 Handle(GEOM_Function) aLastFunc = aLatest->GetLastFunction();
510 GEOM::TPythonDump pd (aLastFunc, /*append=*/true);
511 pd << "geompy.DifferenceList(" << theGroup << ", [";
513 for (i = 1; i <= aLen; i++) {
514 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
515 pd << anObj_i << (( i < aLen ) ? ", " : "])");
521 //=============================================================================
525 //=============================================================================
526 void GEOMImpl_IGroupOperations::UnionIDs (Handle(GEOM_Object) theGroup,
527 const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
530 if (theGroup.IsNull()) return;
532 Standard_Integer aLen = theSubShapes->Length();
534 SetErrorCode("The list is empty");
538 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
539 if (aFunction.IsNull()) return;
541 GEOM_ISubShape aSSI (aFunction);
543 // New contents of the group
544 TColStd_ListOfInteger aNewIDs;
545 TColStd_MapOfInteger mapIDs;
547 // Add current IDs to the list
548 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
549 if (aSeq.IsNull()) return;
550 Standard_Integer val_j, aLength = aSeq->Length();
552 for (Standard_Integer j = 1; j <= aLength; j++) {
553 val_j = aSeq->Value(j);
554 if (val_j > 0 && mapIDs.Add(val_j)) {
555 aNewIDs.Append(val_j);
560 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
561 if (aMainShapeFunc.IsNull()) return;
562 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
563 if (aLabel.IsRoot()) return;
564 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
565 if (aMainObj.IsNull()) return;
566 TopoDS_Shape aMainShape = aMainObj->GetValue();
567 if (aMainShape.IsNull()) return;
569 TopTools_IndexedMapOfShape mapIndices;
570 TopExp::MapShapes(aMainShape, mapIndices);
573 TopAbs_ShapeEnum aType = GetType(theGroup);
575 // Get IDs of sub-shapes to add
576 Standard_Integer i, new_id;
577 for (i = 1; i <= aLen; i++) {
578 new_id = theSubShapes->Value(i);
580 if (0 < new_id && new_id <= mapIndices.Extent()) {
581 //if (mapIDs.Add(new_id)) { IPAL21297. Why we ignore invalid ids silently?
582 if (mapIDs.Add(new_id) && mapIndices(new_id).ShapeType()==aType ) {
583 aNewIDs.Append(new_id);
588 if (aNewIDs.Extent() > 0) {
589 Standard_Integer k = 1;
590 TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
591 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
592 for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
593 aNewSeq->SetValue(k, aNewIDsIter.Value());
596 aSSI.SetIndices(aNewSeq);
598 // As we do not recompute here our group, lets mark it as Modified
599 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
600 theGroup->SetTic(aTic - 1);
603 //Make a Python command
604 GEOM::TPythonDump pd (aFunction, /*append=*/true);
605 pd << "geompy.UnionIDs(" << theGroup << ", [";
606 for (i = 1; i < aLen; i++)
607 pd << theSubShapes->Value(i) << ", ";
608 pd << theSubShapes->Value(aLen) << "])";
613 //=============================================================================
617 //=============================================================================
618 void GEOMImpl_IGroupOperations::DifferenceIDs (Handle(GEOM_Object) theGroup,
619 const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
622 if (theGroup.IsNull()) return;
624 Standard_Integer aLen = theSubShapes->Length();
626 SetErrorCode("The list is empty");
630 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
631 if (aFunction.IsNull()) return;
633 GEOM_ISubShape aSSI (aFunction);
635 // Map of IDs to be removed
636 TColStd_MapOfInteger mapIDsToRemove;
638 // Map of current IDs
639 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
640 if (aSeq.IsNull()) return;
641 Standard_Integer aLength = aSeq->Length();
643 if (aLength == 1 && aSeq->Value(1) == -1) // empty group
646 TColStd_MapOfInteger mapIDsCurrent;
647 Standard_Integer j = 1;
648 for (; j <= aLength; j++) {
649 mapIDsCurrent.Add(aSeq->Value(j));
653 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
654 if (aMainShapeFunc.IsNull()) return;
655 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
656 if (aLabel.IsRoot()) return;
657 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
658 if (aMainObj.IsNull()) return;
659 TopoDS_Shape aMainShape = aMainObj->GetValue();
660 if (aMainShape.IsNull()) return;
662 TopTools_IndexedMapOfShape mapIndices;
663 TopExp::MapShapes(aMainShape, mapIndices);
665 // Get IDs of sub-shapes to be removed
666 Standard_Integer i, rem_id;
667 for (i = 1; i <= aLen; i++) {
668 rem_id = theSubShapes->Value(i);
669 if (mapIDsCurrent.Contains(rem_id)) {
670 mapIDsToRemove.Add(rem_id);
674 if (mapIDsToRemove.Extent() > 0) {
675 Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
676 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
678 for (j = 1; j <= aLength; j++) {
679 if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
680 aNewSeq->SetValue(k, aSeq->Value(j));
685 aSSI.SetIndices(aNewSeq);
687 // As we do not recompute here our group, lets mark it as Modified
688 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
689 theGroup->SetTic(aTic - 1);
692 //Make a Python command
693 GEOM::TPythonDump pd (aFunction, /*append=*/true);
694 pd << "geompy.DifferenceIDs(" << theGroup << ", [";
695 for (i = 1; i < aLen; i++)
696 pd << theSubShapes->Value(i) << ", ";
697 pd << theSubShapes->Value(aLen) << "])";
702 //=============================================================================
706 //=============================================================================
707 TopAbs_ShapeEnum GEOMImpl_IGroupOperations::GetType(Handle(GEOM_Object) theGroup)
711 TDF_Label aFreeLabel = theGroup->GetFreeLabel();
712 Handle(TDataStd_Integer) anAttrib;
713 if(!aFreeLabel.FindAttribute(TDataStd_Integer::GetID(), anAttrib)) return TopAbs_SHAPE;
716 return (TopAbs_ShapeEnum) anAttrib->Get();
719 //=============================================================================
723 //=============================================================================
724 Handle(GEOM_Object) GEOMImpl_IGroupOperations::GetMainShape (Handle(GEOM_Object) theGroup)
728 if(theGroup.IsNull()) return NULL;
730 Handle(GEOM_Function) aGroupFunction = theGroup->GetFunction(1);
731 if (aGroupFunction.IsNull()) return NULL;
733 GEOM_ISubShape aSSI (aGroupFunction);
734 Handle(GEOM_Function) aMainShapeFunction = aSSI.GetMainShape();
735 if (aMainShapeFunction.IsNull()) return NULL;
737 TDF_Label aLabel = aMainShapeFunction->GetOwnerEntry();
738 Handle(GEOM_Object) aMainShape = GEOM_Object::GetObject(aLabel);
739 if (aMainShape.IsNull()) return NULL;
741 //Make a Python command
742 //GEOM::TPythonDump(aGroupFunction, /*append=*/true)
743 // << aMainShape << " = geompy.GetMainShape(" << theGroup << ")";
749 //=============================================================================
753 //=============================================================================
754 Handle(TColStd_HArray1OfInteger) GEOMImpl_IGroupOperations::GetObjects(Handle(GEOM_Object) theGroup)
758 if(theGroup.IsNull()) return NULL;
760 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
761 if(aFunction.IsNull()) return NULL;
763 GEOM_ISubShape aSSI(aFunction);
764 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
765 if(aSeq.IsNull()) return NULL;
767 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {