+ aNewSeq = new TColStd_HArray1OfInteger(1, aLength-1);
+ Standard_Boolean isFound = Standard_False;
+ for (Standard_Integer i = 1, k = 1; i <= aLength; i++) {
+ if (aSeq->Value(i) == theSubShapeID) {
+ isFound = Standard_True;
+ } else {
+ if (k < aLength) { // this check is to avoid sequence <aNewSeq> overflow
+ aNewSeq->SetValue(k, aSeq->Value(i));
+ k++;
+ }
+ }
+ }
+
+ if (!isFound) {
+ SetErrorCode(NOT_EXISTS);
+ return;
+ }
+ }
+
+ aSSI.SetIndices(aNewSeq);
+
+ // As we do not recompute here our group, lets mark it as Modified
+ TDF_Label aLabel = aSSI.GetMainShape()->GetOwnerEntry();
+ if (aLabel.IsRoot()) return;
+ Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+ if (aMainObj.IsNull()) return;
+ Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
+ theGroup->SetTic(aTic - 1);
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "geompy.RemoveObject(" << theGroup << ", " << theSubShapeID << ")";
+
+ SetErrorCode(OK);
+ return;
+}
+
+//=============================================================================
+/*!
+ * UnionList
+ */
+//=============================================================================
+void GEOMImpl_IGroupOperations::UnionList (Handle(GEOM_Object) theGroup,
+ const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
+{
+ SetErrorCode(KO);
+ if (theGroup.IsNull()) return;
+
+ Standard_Integer aLen = theSubShapes->Length();
+ if (aLen < 1) {
+ //SetErrorCode("The list is empty");
+ SetErrorCode(OK);
+ return;
+ }
+
+ Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
+ if (aFunction.IsNull()) return;
+
+ GEOM_ISubShape aSSI (aFunction);
+
+ // New contents of the group
+ TColStd_ListOfInteger aNewIDs;
+ TColStd_MapOfInteger mapIDs;
+
+ // Add current IDs to the list
+ Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+ if (aSeq.IsNull()) return;
+ Standard_Integer val_j, aLength = aSeq->Length();
+
+ for (Standard_Integer j = 1; j <= aLength; j++) {
+ val_j = aSeq->Value(j);
+ if (val_j > 0 && mapIDs.Add(val_j)) {
+ aNewIDs.Append(val_j);
+ }
+ }
+
+ // Get Main Shape
+ Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+ if (aMainShapeFunc.IsNull()) return;
+ TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
+ if (aLabel.IsRoot()) return;
+ Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+ if (aMainObj.IsNull()) return;
+ TopoDS_Shape aMainShape = aMainObj->GetValue();
+ if (aMainShape.IsNull()) return;
+
+ TopTools_IndexedMapOfShape mapIndices;
+ TopExp::MapShapes(aMainShape, mapIndices);
+
+ // Get group type
+ TopAbs_ShapeEnum aType = GetType(theGroup);
+
+ // Get IDs of sub-shapes to add
+ Standard_Integer i, new_id;
+ for (i = 1; i <= aLen; i++) {
+ Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
+
+ TopoDS_Shape aShape_i = anObj_i->GetValue();
+ if ( aShape_i.IsNull() ) continue;
+ TopAbs_ShapeEnum aType_i = aShape_i.ShapeType();
+
+ // 1. If aShape_i is sub-shape of aMainShape - add it
+ if (anObj_i->IsMainShape()) {
+ if (aType_i != aType && aType != TopAbs_SHAPE && aType != TopAbs_COMPOUND) {
+ SetErrorCode("Operation aborted: one of given objects has a wrong type");
+ return;
+ }
+ if (!mapIndices.Contains(aShape_i)) {
+ SetErrorCode("Operation aborted: not a sub-shape given");
+ return;
+ }
+ new_id = mapIndices.FindIndex(aShape_i);
+ if (mapIDs.Add(new_id)) {
+ aNewIDs.Append(new_id);
+ }
+ }
+ // 2. If type of group is not defined - add all sub-shapes of aShape_i
+ else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
+ TopTools_IndexedMapOfShape mapIndices_i;
+ TopExp::MapShapes(aShape_i, mapIndices_i);
+ Standard_Integer ii = 1, nbSubSh = mapIndices_i.Extent();
+ Standard_Boolean someGood = Standard_False;
+ for (; ii <= nbSubSh; ii++) {
+ TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
+ if (mapIndices.Contains(aSubShape_i)) {
+ someGood = Standard_True;
+ new_id = mapIndices.FindIndex(aSubShape_i);
+ if (mapIDs.Add(new_id)) {
+ aNewIDs.Append(new_id);
+ }
+ }
+ }
+ if (!someGood) {
+ SetErrorCode("Operation aborted: not a sub-shape given");
+ return;
+ }
+ }
+ // 3. If type of group is defined - add all sub-shapes of aShape_i of that type
+ else {
+ TopExp_Explorer aSubShapes_i (aShape_i, aType);
+ for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
+ TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
+ if (!mapIndices.Contains(aSubShape_i)) {
+ SetErrorCode("Operation aborted: not a sub-shape given");
+ return;
+ }
+ new_id = mapIndices.FindIndex(aSubShape_i);
+ if (mapIDs.Add(new_id)) {
+ aNewIDs.Append(new_id);
+ }
+ }
+ }
+ }
+
+ if (aNewIDs.Extent() > 0) {
+ Standard_Integer k = 1;
+ TColStd_ListIteratorOfListOfInteger aNewIDsIter (aNewIDs);
+ Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aNewIDs.Extent());
+ for (; aNewIDsIter.More(); aNewIDsIter.Next(), k++) {
+ aNewSeq->SetValue(k, aNewIDsIter.Value());
+ }
+
+ aSSI.SetIndices(aNewSeq);
+
+ // As we do not recompute here our group, lets mark it as Modified
+ Standard_Integer aTic = aMainObj->GetTic(); // tic of main shape
+ theGroup->SetTic(aTic - 1);
+ }
+
+ //Make a Python command
+ Handle(GEOM_Object) aLatest = GEOM::GetCreatedLast(theSubShapes);
+ aLatest = GEOM::GetCreatedLast(aLatest, theGroup);
+ Handle(GEOM_Function) aLastFunc = aLatest->GetLastFunction();
+
+ GEOM::TPythonDump pd (aLastFunc, /*append=*/true);
+ pd << "geompy.UnionList(" << theGroup << ", [";
+
+ for (i = 1; i <= aLen; i++) {
+ Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
+ pd << anObj_i << (( i < aLen ) ? ", " : "])");
+ }
+
+ SetErrorCode(OK);
+}
+
+//=============================================================================
+/*!
+ * DifferenceList
+ */
+//=============================================================================
+void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup,
+ const Handle(TColStd_HSequenceOfTransient)& theSubShapes)
+{
+ SetErrorCode(KO);
+ if (theGroup.IsNull()) return;
+
+ Standard_Integer aLen = theSubShapes->Length();
+ if (aLen < 1) {
+ //SetErrorCode("The list is empty");
+ SetErrorCode(OK);
+ return;
+ }
+
+ Handle(GEOM_Function) aFunction = theGroup->GetFunction(1);
+ if (aFunction.IsNull()) return;
+
+ GEOM_ISubShape aSSI (aFunction);
+
+ // Map of IDs to be removed
+ TColStd_MapOfInteger mapIDsToRemove;
+
+ // Map of current IDs
+ Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices();
+ if (aSeq.IsNull()) return;
+ Standard_Integer aLength = aSeq->Length();
+
+ // VSR 28/04/2011 commented to allow operation even for empty group
+ // if (aLength == 1 && aSeq->Value(1) == -1) // empty group
+ // return;
+
+ TColStd_MapOfInteger mapIDsCurrent;
+ Standard_Integer j = 1;
+ for (; j <= aLength; j++) {
+ mapIDsCurrent.Add(aSeq->Value(j));
+ }
+
+ // Get Main Shape
+ Handle(GEOM_Function) aMainShapeFunc = aSSI.GetMainShape();
+ if (aMainShapeFunc.IsNull()) return;
+ TDF_Label aLabel = aMainShapeFunc->GetOwnerEntry();
+ if (aLabel.IsRoot()) return;
+ Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel);
+ if (aMainObj.IsNull()) return;
+ TopoDS_Shape aMainShape = aMainObj->GetValue();
+ if (aMainShape.IsNull()) return;
+
+ TopTools_IndexedMapOfShape mapIndices;
+ TopExp::MapShapes(aMainShape, mapIndices);
+
+ // Get group type
+ TopAbs_ShapeEnum aType = GetType(theGroup);
+
+ // Get IDs of sub-shapes to be removed
+ Standard_Integer i, rem_id;
+ for (i = 1; i <= aLen; i++) {
+ Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i));
+
+ TopoDS_Shape aShape_i = anObj_i->GetValue();
+
+ // 1. If aShape_i is sub-shape of aMainShape - remove it
+ if (mapIndices.Contains(aShape_i)) {
+ rem_id = mapIndices.FindIndex(aShape_i);
+ if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
+ mapIDsToRemove.Add(rem_id);
+ }
+ }
+ // 2. If type of group is not defined - remove all sub-shapes of aShape_i
+ else if (aType == TopAbs_SHAPE || aType == TopAbs_COMPOUND) {
+ TopTools_IndexedMapOfShape mapIndices_i;
+ TopExp::MapShapes(aShape_i, mapIndices_i);
+ Standard_Integer nbSubSh = mapIndices_i.Extent();
+ Standard_Integer ii = 1;
+ for (; ii <= nbSubSh; ii++) {
+ TopoDS_Shape aSubShape_i = mapIndices_i.FindKey(ii);
+ if (mapIndices.Contains(aSubShape_i)) {
+ rem_id = mapIndices.FindIndex(aSubShape_i);
+ if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
+ mapIDsToRemove.Add(rem_id);
+ }
+ }
+ }
+ }
+ // 3. If type of group is defined - remove all sub-shapes of aShape_i of that type
+ else {
+ TopExp_Explorer aSubShapes_i (aShape_i, aType);
+ for (; aSubShapes_i.More(); aSubShapes_i.Next()) {
+ TopoDS_Shape aSubShape_i = aSubShapes_i.Current();
+ if (mapIndices.Contains(aSubShape_i)) {
+ rem_id = mapIndices.FindIndex(aSubShape_i);
+ if (rem_id > 0 && mapIDsCurrent.Contains(rem_id)) {
+ mapIDsToRemove.Add(rem_id);
+ }
+ }
+ }
+ }
+ }
+
+ if (mapIDsToRemove.Extent() > 0) {
+ Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent();