1 // Copyright (C) 2007-2011 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 if ( aShape_i.IsNull() ) continue;
302 TopAbs_ShapeEnum aType_i = aShape_i.ShapeType();
304 // 1. If aShape_i is sub-shape of aMainShape - add it
305 if (anObj_i->IsMainShape()) {
306 if (aType_i != aType && aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
307 SetErrorCode("Operation aborted: one of given objects has a wrong type");
310 if (!mapIndices.Contains(aShape_i)) {
311 SetErrorCode("Operation aborted: not a sub-shape given");
314 new_id = mapIndices.FindIndex(aShape_i);
315 if (mapIDs.Add(new_id)) {
316 aNewIDs.Append(new_id);
319 // 2. If type of group is not defined - add all sub-shapes of aShape_i
320 else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
321 TopTools_IndexedMapOfShape mapIndices_i;
322 TopExp::MapShapes(aShape_i, mapIndices_i);
323 Standard_Integer ii = 1, nbSubSh = mapIndices_i.Extent();
324 Standard_Boolean someGood = Standard_False;
325 for (; ii <= nbSubSh; ii++) {
326 TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
327 if (mapIndices.Contains(aSubShape_i)) {
328 someGood = Standard_True;
329 new_id = mapIndices.FindIndex(aSubShape_i);
330 if (mapIDs.Add(new_id)) {
331 aNewIDs.Append(new_id);
336 SetErrorCode("Operation aborted: not a sub-shape given");
340 // 3. If type of group is defined - add all sub-shapes of aShape_i of that type
342 TopExp_Explorer aSubShapes_i (aShape_i, aType);
343 for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
344 TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
345 if (!mapIndices.Contains(aSubShape_i)) {
346 SetErrorCode("Operation aborted: not a sub-shape given");
349 new_id = mapIndices.FindIndex(aSubShape_i);
350 if (mapIDs.Add(new_id)) {
351 aNewIDs.Append(new_id);
357 if (aNewIDs.Extent() > 0) {
358 Standard_Integer k = 1;
359 TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
360 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
361 for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
362 aNewSeq->SetValue(k, aNewIDsIter.Value());
365 aSSI.SetIndices(aNewSeq);
367 // As we do not recompute here our group, lets mark it as Modified
368 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
369 theGroup->SetTic(aTic - 1);
372 //Make a Python command
373 Handle(GEOM_Object) aLatest = GEOM::GetCreatedLast(theSubShapes);
374 aLatest = GEOM::GetCreatedLast(aLatest, theGroup);
375 Handle(GEOM_Function) aLastFunc = aLatest->GetLastFunction();
377 GEOM::TPythonDump pd (aLastFunc, /*append=*/true);
378 pd << "geompy.UnionList(" << theGroup << ", [";
380 for (i = 1; i <= aLen; i++) {
381 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
382 pd << anObj_i << (( i < aLen ) ? ", " : "])");
388 //=============================================================================
392 //=============================================================================
393 void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
394 const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
397 if (theGroup.IsNull()) return;
399 Standard_Integer aLen = theSubShapes->Length();
401 //SetErrorCode("The list is empty");
406 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
407 if (aFunction.IsNull()) return;
409 GEOM_ISubShape aSSI (aFunction);
411 // Map of IDs to be removed
412 TColStd_MapOfInteger mapIDsToRemove;
414 // Map of current IDs
415 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
416 if (aSeq.IsNull()) return;
417 Standard_Integer aLength = aSeq->Length();
419 // VSR 28/04/2011 commented to allow operation even for empty group
420 // if (aLength == 1 && aSeq->Value(1) == -1) // empty group
423 TColStd_MapOfInteger mapIDsCurrent;
424 Standard_Integer j = 1;
425 for (; j <= aLength; j++) {
426 mapIDsCurrent.Add(aSeq->Value(j));
430 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
431 if (aMainShapeFunc.IsNull()) return;
432 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
433 if (aLabel.IsRoot()) return;
434 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
435 if (aMainObj.IsNull()) return;
436 TopoDS_Shape aMainShape = aMainObj->GetValue();
437 if (aMainShape.IsNull()) return;
439 TopTools_IndexedMapOfShape mapIndices;
440 TopExp::MapShapes(aMainShape, mapIndices);
443 TopAbs_ShapeEnum aType = GetType(theGroup);
445 // Get IDs of sub-shapes to be removed
446 Standard_Integer i, rem_id;
447 for (i = 1; i <= aLen; i++) {
448 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
450 TopoDS_Shape aShape_i = anObj_i->GetValue();
452 // 1. If aShape_i is sub-shape of aMainShape - remove it
453 if (mapIndices.Contains(aShape_i)) {
454 rem_id = mapIndices.FindIndex(aShape_i);
455 if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
456 mapIDsToRemove.Add(rem_id);
459 // 2. If type of group is not defined - remove all sub-shapes of aShape_i
460 else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
461 TopTools_IndexedMapOfShape mapIndices_i;
462 TopExp::MapShapes(aShape_i, mapIndices_i);
463 Standard_Integer nbSubSh = mapIndices_i.Extent();
464 Standard_Integer ii = 1;
465 for (; ii <= nbSubSh; ii++) {
466 TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
467 if (mapIndices.Contains(aSubShape_i)) {
468 rem_id = mapIndices.FindIndex(aSubShape_i);
469 if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
470 mapIDsToRemove.Add(rem_id);
475 // 3. If type of group is defined - remove all sub-shapes of aShape_i of that type
477 TopExp_Explorer aSubShapes_i (aShape_i, aType);
478 for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
479 TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
480 if (mapIndices.Contains(aSubShape_i)) {
481 rem_id = mapIndices.FindIndex(aSubShape_i);
482 if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
483 mapIDsToRemove.Add(rem_id);
490 if (mapIDsToRemove.Extent() > 0) {
491 Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
492 Handle(TColStd_HArray1OfInteger) aNewSeq;
493 if ( aLength - aRemLength > 0 ) {
494 aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
495 for (j = 1; j <= aLength; j++) {
496 if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
497 aNewSeq->SetValue(k, aSeq->Value(j));
503 aNewSeq = new TColStd_HArray1OfInteger(1,1);
504 aNewSeq->SetValue(1, -1);
507 aSSI.SetIndices(aNewSeq);
509 // As we do not recompute here our group, lets mark it as Modified
510 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
511 theGroup->SetTic(aTic - 1);
514 //Make a Python command
515 Handle(GEOM_Object) aLatest = GEOM::GetCreatedLast(theSubShapes);
516 aLatest = GEOM::GetCreatedLast(aLatest, theGroup);
517 Handle(GEOM_Function) aLastFunc = aLatest->GetLastFunction();
519 GEOM::TPythonDump pd (aLastFunc, /*append=*/true);
520 pd << "geompy.DifferenceList(" << theGroup << ", [";
522 for (i = 1; i <= aLen; i++) {
523 Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
524 pd << anObj_i << (( i < aLen ) ? ", " : "])");
530 //=============================================================================
534 //=============================================================================
535 void GEOMImpl_IGroupOperations::UnionIDs (Handle(GEOM_Object) theGroup,
536 const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
539 if (theGroup.IsNull()) return;
541 Standard_Integer aLen = theSubShapes->Length();
543 //SetErrorCode("The list is empty");
548 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
549 if (aFunction.IsNull()) return;
551 GEOM_ISubShape aSSI (aFunction);
553 // New contents of the group
554 TColStd_ListOfInteger aNewIDs;
555 TColStd_MapOfInteger mapIDs;
557 // Add current IDs to the list
558 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
559 if (aSeq.IsNull()) return;
560 Standard_Integer val_j, aLength = aSeq->Length();
562 for (Standard_Integer j = 1; j <= aLength; j++) {
563 val_j = aSeq->Value(j);
564 if (val_j > 0 && mapIDs.Add(val_j)) {
565 aNewIDs.Append(val_j);
570 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
571 if (aMainShapeFunc.IsNull()) return;
572 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
573 if (aLabel.IsRoot()) return;
574 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
575 if (aMainObj.IsNull()) return;
576 TopoDS_Shape aMainShape = aMainObj->GetValue();
577 if (aMainShape.IsNull()) return;
579 TopTools_IndexedMapOfShape mapIndices;
580 TopExp::MapShapes(aMainShape, mapIndices);
583 TopAbs_ShapeEnum aType = GetType(theGroup);
585 // Get IDs of sub-shapes to add
586 Standard_Integer i, new_id;
587 for (i = 1; i <= aLen; i++) {
588 new_id = theSubShapes->Value(i);
590 if (0 < new_id && new_id <= mapIndices.Extent()) {
591 //if (mapIDs.Add(new_id)) { IPAL21297. Why we ignore invalid ids silently?
592 if (mapIDs.Add(new_id) && mapIndices(new_id).ShapeType()==aType ) {
593 aNewIDs.Append(new_id);
598 if (aNewIDs.Extent() > 0) {
599 Standard_Integer k = 1;
600 TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
601 Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
602 for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
603 aNewSeq->SetValue(k, aNewIDsIter.Value());
606 aSSI.SetIndices(aNewSeq);
608 // As we do not recompute here our group, lets mark it as Modified
609 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
610 theGroup->SetTic(aTic - 1);
613 //Make a Python command
614 GEOM::TPythonDump pd (aFunction, /*append=*/true);
615 pd << "geompy.UnionIDs(" << theGroup << ", [";
616 for (i = 1; i < aLen; i++)
617 pd << theSubShapes->Value(i) << ", ";
618 pd << theSubShapes->Value(aLen) << "])";
623 //=============================================================================
627 //=============================================================================
628 void GEOMImpl_IGroupOperations::DifferenceIDs (Handle(GEOM_Object) theGroup,
629 const Handle(TColStd_HSequenceOfInteger)& theSubShapes)
632 if (theGroup.IsNull()) return;
634 Standard_Integer aLen = theSubShapes->Length();
636 //SetErrorCode("The list is empty");
641 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
642 if (aFunction.IsNull()) return;
644 GEOM_ISubShape aSSI (aFunction);
646 // Map of IDs to be removed
647 TColStd_MapOfInteger mapIDsToRemove;
649 // Map of current IDs
650 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
651 if (aSeq.IsNull()) return;
652 Standard_Integer aLength = aSeq->Length();
654 // VSR 28/04/2011 commented to allow operation even for empty group
655 // if (aLength == 1 && aSeq->Value(1) == -1) // empty group
658 TColStd_MapOfInteger mapIDsCurrent;
659 Standard_Integer j = 1;
660 for (; j <= aLength; j++) {
661 mapIDsCurrent.Add(aSeq->Value(j));
665 Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
666 if (aMainShapeFunc.IsNull()) return;
667 TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
668 if (aLabel.IsRoot()) return;
669 Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
670 if (aMainObj.IsNull()) return;
671 TopoDS_Shape aMainShape = aMainObj->GetValue();
672 if (aMainShape.IsNull()) return;
674 TopTools_IndexedMapOfShape mapIndices;
675 TopExp::MapShapes(aMainShape, mapIndices);
677 // Get IDs of sub-shapes to be removed
678 Standard_Integer i, rem_id;
679 for (i = 1; i <= aLen; i++) {
680 rem_id = theSubShapes->Value(i);
681 if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
682 mapIDsToRemove.Add(rem_id);
686 if (mapIDsToRemove.Extent() > 0) {
687 Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();
688 Handle(TColStd_HArray1OfInteger) aNewSeq;
689 if ( aLength - aRemLength > 0 ) {
690 aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength);
691 for (j = 1; j <= aLength; j++) {
692 if (!mapIDsToRemove.Contains(aSeq->Value(j))) {
693 aNewSeq->SetValue(k, aSeq->Value(j));
699 aNewSeq = new TColStd_HArray1OfInteger(1,1);
700 aNewSeq->SetValue(1, -1);
703 aSSI.SetIndices(aNewSeq);
705 // As we do not recompute here our group, lets mark it as Modified
706 Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
707 theGroup->SetTic(aTic - 1);
710 //Make a Python command
711 GEOM::TPythonDump pd (aFunction, /*append=*/true);
712 pd << "geompy.DifferenceIDs(" << theGroup << ", [";
713 for (i = 1; i < aLen; i++)
714 pd << theSubShapes->Value(i) << ", ";
715 pd << theSubShapes->Value(aLen) << "])";
720 //=============================================================================
724 //=============================================================================
725 TopAbs_ShapeEnum GEOMImpl_IGroupOperations::GetType(Handle(GEOM_Object) theGroup)
729 TDF_Label aFreeLabel = theGroup->GetFreeLabel();
730 Handle(TDataStd_Integer) anAttrib;
731 if(!aFreeLabel.FindAttribute(TDataStd_Integer::GetID(), anAttrib)) return TopAbs_SHAPE;
734 return (TopAbs_ShapeEnum) anAttrib->Get();
737 //=============================================================================
741 //=============================================================================
742 Handle(GEOM_Object) GEOMImpl_IGroupOperations::GetMainShape (Handle(GEOM_Object) theGroup)
746 if(theGroup.IsNull()) return NULL;
748 Handle(GEOM_Function) aGroupFunction = theGroup->GetFunction(1);
749 if (aGroupFunction.IsNull()) return NULL;
751 GEOM_ISubShape aSSI (aGroupFunction);
752 Handle(GEOM_Function) aMainShapeFunction = aSSI.GetMainShape();
753 if (aMainShapeFunction.IsNull()) return NULL;
755 TDF_Label aLabel = aMainShapeFunction->GetOwnerEntry();
756 Handle(GEOM_Object) aMainShape = GEOM_Object::GetObject(aLabel);
757 if (aMainShape.IsNull()) return NULL;
759 //Make a Python command
760 //GEOM::TPythonDump(aGroupFunction, /*append=*/true)
761 // << aMainShape << " = geompy.GetMainShape(" << theGroup << ")";
767 //=============================================================================
771 //=============================================================================
772 Handle(TColStd_HArray1OfInteger) GEOMImpl_IGroupOperations::GetObjects(Handle(GEOM_Object) theGroup)
776 if(theGroup.IsNull()) return NULL;
778 Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
779 if(aFunction.IsNull()) return NULL;
781 GEOM_ISubShape aSSI(aFunction);
782 Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
783 if(aSeq.IsNull()) return NULL;
785 if(aSeq->Length() == 1 && aSeq->Value(1) == -1) {