From 3866ec3a969f5cc1801d535eab97e4115d9d4564 Mon Sep 17 00:00:00 2001 From: jfa Date: Fri, 4 Feb 2005 06:55:40 +0000 Subject: [PATCH] PAL7968. Two new functions implemented: UnionList() and DifferenceList(). --- idl/GEOM_Gen.idl | 16 +- src/GEOMImpl/GEOMImpl_IGroupOperations.cxx | 300 ++++++++++++++++++++- src/GEOMImpl/GEOMImpl_IGroupOperations.hxx | 6 + src/GEOM_I/GEOM_IGroupOperations_i.cc | 70 +++++ src/GEOM_I/GEOM_IGroupOperations_i.hh | 4 + src/GEOM_SWIG/GEOM_TestOthers.py | 15 +- src/GEOM_SWIG/batchmode_geompy.py | 10 + src/GEOM_SWIG/geompy.py | 24 ++ 8 files changed, 428 insertions(+), 17 deletions(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 6ed153980..891f401e0 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -1860,12 +1860,26 @@ module GEOM /*! * Removes a sub object with ID \a theSubShapeId from the group - * \param theGroup is a GEOM group from which the new sub shape is removed + * \param theGroup is a GEOM group from which the sub shape is removed. * \param theSubShapeId is a sub shape ID in the main object. * \note Use method ILocalOperations.GetSubShapeIndex() to get an ID by the sub shape */ void RemoveObject (in GEOM_Object theGroup, in long theSubShapeId); + /*! + * Adds to the group all the given shapes. No errors, if some shapes are alredy included. + * \param theGroup is a GEOM group to which the new sub shapes are added. + * \param theSubShapes is a list of sub shapes to be added. + */ + void UnionList (in GEOM_Object theGroup, in ListOfGO theSubShapes); + + /*! + * Removes from the group all the given shapes. No errors, if some shapes are not included. + * \param theGroup is a GEOM group from which the sub-shapes are removed. + * \param theSubShapes is a list of sub-shapes to be removed. + */ + void DifferenceList (in GEOM_Object theGroup, in ListOfGO theSubShapes); + /*! * Returns a type of sub objects stored in the group * \param theGroup is a GEOM group which type is returned. diff --git a/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx b/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx index ce66c20d6..f4bedb504 100644 --- a/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IGroupOperations.cxx @@ -2,6 +2,11 @@ using namespace std; #include "GEOMImpl_IGroupOperations.hxx" +#include "GEOMImpl_Types.hxx" + +#include "GEOM_Function.hxx" +#include "GEOM_ISubShape.hxx" + #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" @@ -12,13 +17,13 @@ using namespace std; #include #include -#include "GEOM_Function.hxx" -#include "GEOMImpl_Types.hxx" -#include "GEOM_ISubShape.hxx" - #include #include + #include +#include +#include +#include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC @@ -89,11 +94,11 @@ Handle(GEOM_Object) GEOMImpl_IGroupOperations::CreateGroup(Handle(GEOM_Object) t void GEOMImpl_IGroupOperations::AddObject(Handle(GEOM_Object) theGroup, int theSubShapeID) { SetErrorCode(KO); - if(theGroup.IsNull()) return; + if(theGroup.IsNull()) return; Handle(GEOM_Function) aFunction = theGroup->GetFunction(1); if(aFunction.IsNull()) return; - + GEOM_ISubShape aSSI(aFunction); Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices(); if(aSeq.IsNull()) return; @@ -126,13 +131,11 @@ void GEOMImpl_IGroupOperations::AddObject(Handle(GEOM_Object) theGroup, int theS void GEOMImpl_IGroupOperations::RemoveObject(Handle(GEOM_Object) theGroup, int theSubShapeID) { SetErrorCode(KO); - if(theGroup.IsNull()) return; - + if(theGroup.IsNull()) return; - Handle(GEOM_Function) aFunction = theGroup->GetFunction(1); + Handle(GEOM_Function) aFunction = theGroup->GetFunction(1); if(aFunction.IsNull()) return; - - + GEOM_ISubShape aSSI(aFunction); Handle(TColStd_HArray1OfInteger) aSeq = aSSI.GetIndices(); if(aSeq.IsNull()) return; @@ -176,11 +179,284 @@ void GEOMImpl_IGroupOperations::RemoveObject(Handle(GEOM_Object) theGroup, int t aSSI.SetIndices(aNewSeq); } - SetErrorCode(OK); return; } +//============================================================================= +/*! + * UnionList + */ +//============================================================================= +void GEOMImpl_IGroupOperations::UnionList (Handle(GEOM_Object) theGroup, + const Handle(TColStd_HSequenceOfTransient)& theSubShapes) +{ + SetErrorCode(KO); + if (theGroup.IsNull()) 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 IDs of sub-shapes to add + Standard_Integer i, new_id, aLen = theSubShapes->Length(); + for (i = 1; i <= aLen; i++) { + Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i)); + + if (anObj_i->IsMainShape()) { + TopoDS_Shape aShape_i = anObj_i->GetValue(); + if (mapIndices.Contains(aShape_i)) { + new_id = mapIndices.FindIndex(aShape_i); + if (mapIDs.Add(new_id)) { + aNewIDs.Append(new_id); + } + } else { + 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"); + return; + } + } else { + // Check main shape of sub-shape to add + Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1); + if (aFunc_i.IsNull()) return; + + GEOM_ISubShape aSSI_i (aFunc_i); + + Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape(); + if (aMainShapeFunc_i.IsNull()) return; + TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry(); + if (aLabel_i.IsRoot()) return; + Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel); + if (aMainObj_i.IsNull()) return; + TopoDS_Shape aMainShape_i = aMainObj_i->GetValue(); + if (aMainShape_i.IsNull()) return; + + if (aMainShape_i.IsSame(aMainShape)) { + // add all sub-shape IDs to the list + + // Get IDs + Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices(); + if (aSeq_i.IsNull()) return; + Standard_Integer aLength_i = aSeq_i->Length(); + + for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) { + new_id = aSeq_i->Value(i_j); + if (new_id > 0) { + if (mapIDs.Add(new_id)) { + aNewIDs.Append(new_id); + } + } + } + + } else if (mapIndices.Contains(aMainShape_i)) { + // compute new IDs and add them to the list + TopTools_IndexedMapOfShape mapIndices_i; + TopExp::MapShapes(aMainShape_i, mapIndices_i); + + // Get IDs + Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices(); + if (aSeq_i.IsNull()) return; + Standard_Integer aLength_i = aSeq_i->Length(); + + for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) { + if (aSeq_i->Value(i_j) > 0) { + TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j); + new_id = mapIndices.FindIndex(aShape_i_j); + if (mapIDs.Add(new_id)) { + aNewIDs.Append(new_id); + } + } + } + + } else { + 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"); + return; + } + } + } + + 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); + } + + SetErrorCode(OK); +} + +//============================================================================= +/*! + * DifferenceList + */ +//============================================================================= +void GEOMImpl_IGroupOperations::DifferenceList (Handle(GEOM_Object) theGroup, + const Handle(TColStd_HSequenceOfTransient)& theSubShapes) +{ + SetErrorCode(KO); + if (theGroup.IsNull()) 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(); + + 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 IDs of sub-shapes to be removed + Standard_Integer i, rem_id, aLen = theSubShapes->Length(); + for (i = 1; i <= aLen; i++) { + Handle(GEOM_Object) anObj_i = Handle(GEOM_Object)::DownCast(theSubShapes->Value(i)); + + if (anObj_i->IsMainShape()) { + TopoDS_Shape aShape_i = anObj_i->GetValue(); + if (mapIndices.Contains(aShape_i)) { + rem_id = mapIndices.FindIndex(aShape_i); + if (mapIDsCurrent.Contains(rem_id)) { + mapIDsToRemove.Add(rem_id); + } + } else { + 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"); + return; + } + } else { + // Check main shape of sub-shape to be removed + Handle(GEOM_Function) aFunc_i = anObj_i->GetFunction(1); + if (aFunc_i.IsNull()) return; + + GEOM_ISubShape aSSI_i (aFunc_i); + + Handle(GEOM_Function) aMainShapeFunc_i = aSSI_i.GetMainShape(); + if (aMainShapeFunc_i.IsNull()) return; + TDF_Label aLabel_i = aMainShapeFunc_i->GetOwnerEntry(); + if (aLabel_i.IsRoot()) return; + Handle(GEOM_Object) aMainObj_i = GEOM_Object::GetObject(aLabel); + if (aMainObj_i.IsNull()) return; + TopoDS_Shape aMainShape_i = aMainObj_i->GetValue(); + if (aMainShape_i.IsNull()) return; + + if (aMainShape_i.IsSame(aMainShape)) { + // remove all sub-shapes + + // Get IDs + Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices(); + if (aSeq_i.IsNull()) return; + Standard_Integer aLength_i = aSeq_i->Length(); + + for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) { + rem_id = aSeq_i->Value(i_j); + if (rem_id > 0) { + if (mapIDsCurrent.Contains(rem_id)) { + mapIDsToRemove.Add(rem_id); + } + } + } + + } else if (mapIndices.Contains(aMainShape_i)) { + // compute new IDs and add them to the map of ids to be removed + TopTools_IndexedMapOfShape mapIndices_i; + TopExp::MapShapes(aMainShape_i, mapIndices_i); + + // Get IDs + Handle(TColStd_HArray1OfInteger) aSeq_i = aSSI_i.GetIndices(); + if (aSeq_i.IsNull()) return; + Standard_Integer aLength_i = aSeq_i->Length(); + + for (Standard_Integer i_j = 1; i_j <= aLength_i; i_j++) { + if (aSeq_i->Value(i_j) > 0) { + TopoDS_Shape aShape_i_j = mapIndices_i.FindKey(i_j); + rem_id = mapIndices.FindIndex(aShape_i_j); + if (mapIDsCurrent.Contains(rem_id)) { + mapIDsToRemove.Add(rem_id); + } + } + } + + } else { + 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"); + return; + } + } + } + + if (mapIDsToRemove.Extent() > 0) { + Standard_Integer k = 1, aRemLength = mapIDsToRemove.Extent(); + Handle(TColStd_HArray1OfInteger) aNewSeq = new TColStd_HArray1OfInteger(1, aLength - aRemLength); + + for (j = 1; j <= aLength; j++) { + if (!mapIDsToRemove.Contains(aSeq->Value(j))) { + aNewSeq->SetValue(k, aSeq->Value(j)); + k++; + } + } + + aSSI.SetIndices(aNewSeq); + } + + SetErrorCode(OK); +} + //============================================================================= /*! * GetType diff --git a/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx b/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx index c17db5f17..ea9075844 100644 --- a/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IGroupOperations.hxx @@ -21,6 +21,12 @@ class GEOMImpl_IGroupOperations : public GEOM_IOperations { void RemoveObject(Handle(GEOM_Object) theGroup, int theSubShapeID); + void UnionList (Handle(GEOM_Object) theGroup, + const Handle(TColStd_HSequenceOfTransient)& theSubShapes); + + void DifferenceList (Handle(GEOM_Object) theGroup, + const Handle(TColStd_HSequenceOfTransient)& theSubShapes); + TopAbs_ShapeEnum GetType(Handle(GEOM_Object) theGroup); Handle(GEOM_Object) GetMainShape(Handle(GEOM_Object) theGroup); diff --git a/src/GEOM_I/GEOM_IGroupOperations_i.cc b/src/GEOM_I/GEOM_IGroupOperations_i.cc index 3ff5c9bb6..b0689d0dd 100644 --- a/src/GEOM_I/GEOM_IGroupOperations_i.cc +++ b/src/GEOM_I/GEOM_IGroupOperations_i.cc @@ -104,6 +104,76 @@ void GEOM_IGroupOperations_i::RemoveObject(GEOM::GEOM_Object_ptr theGroup, CORBA return; } +//============================================================================= +/*! + * UnionList + */ +//============================================================================= +void GEOM_IGroupOperations_i::UnionList (GEOM::GEOM_Object_ptr theGroup, + const GEOM::ListOfGO& theSubShapes) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theGroup == NULL) return; + + //Get the reference group + Handle(GEOM_Object) aGroupRef = GetOperations()->GetEngine()->GetObject + (theGroup->GetStudyID(), theGroup->GetEntry()); + if (aGroupRef.IsNull()) return; + + //Get sub-shape to add + Handle(TColStd_HSequenceOfTransient) aSubShapes = new TColStd_HSequenceOfTransient; + + int ind, aLen = theSubShapes.length(); + for (ind = 0; ind < aLen; ind++) { + if (theSubShapes[ind] == NULL) return; + Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject + (theSubShapes[ind]->GetStudyID(), theSubShapes[ind]->GetEntry()); + if (aSh.IsNull()) return; + aSubShapes->Append(aSh); + } + + //Perform the operation + GetOperations()->UnionList(aGroupRef, aSubShapes); + return; +} + +//============================================================================= +/*! + * DifferenceList + */ +//============================================================================= +void GEOM_IGroupOperations_i::DifferenceList (GEOM::GEOM_Object_ptr theGroup, + const GEOM::ListOfGO& theSubShapes) +{ + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theGroup == NULL) return; + + //Get the reference group + Handle(GEOM_Object) aGroupRef = GetOperations()->GetEngine()->GetObject + (theGroup->GetStudyID(), theGroup->GetEntry()); + if (aGroupRef.IsNull()) return; + + //Get sub-shape to remove + Handle(TColStd_HSequenceOfTransient) aSubShapes = new TColStd_HSequenceOfTransient; + + int ind, aLen = theSubShapes.length(); + for (ind = 0; ind < aLen; ind++) { + if (theSubShapes[ind] == NULL) return; + Handle(GEOM_Object) aSh = GetOperations()->GetEngine()->GetObject + (theSubShapes[ind]->GetStudyID(), theSubShapes[ind]->GetEntry()); + if (aSh.IsNull()) return; + aSubShapes->Append(aSh); + } + + //Perform the operation + GetOperations()->DifferenceList(aGroupRef, aSubShapes); + return; +} + //============================================================================= /*! * GetType diff --git a/src/GEOM_I/GEOM_IGroupOperations_i.hh b/src/GEOM_I/GEOM_IGroupOperations_i.hh index 14ccec8aa..068f0916d 100644 --- a/src/GEOM_I/GEOM_IGroupOperations_i.hh +++ b/src/GEOM_I/GEOM_IGroupOperations_i.hh @@ -26,6 +26,10 @@ class GEOM_IGroupOperations_i : void RemoveObject (GEOM::GEOM_Object_ptr theGroup, CORBA::Long theSubShapeId); + void UnionList (GEOM::GEOM_Object_ptr theGroup, const GEOM::ListOfGO& theSubShapes); + + void DifferenceList (GEOM::GEOM_Object_ptr theGroup, const GEOM::ListOfGO& theSubShapes); + CORBA::Long GetType (GEOM::GEOM_Object_ptr theGroup); GEOM::GEOM_Object_ptr GetMainShape (GEOM::GEOM_Object_ptr theGroup); diff --git a/src/GEOM_SWIG/GEOM_TestOthers.py b/src/GEOM_SWIG/GEOM_TestOthers.py index 55429a96b..d9354e838 100644 --- a/src/GEOM_SWIG/GEOM_TestOthers.py +++ b/src/GEOM_SWIG/GEOM_TestOthers.py @@ -194,17 +194,24 @@ def TestOtherOperations (geompy, math): f_ind_5 = geompy.GetSubShapeID(Box, box_faces[4]) f_ind_6 = geompy.GetSubShapeID(Box, box_faces[5]) - geompy.AddObject(CreateGroup, f_ind_6) - geompy.AddObject(CreateGroup, f_ind_1) - geompy.AddObject(CreateGroup, f_ind_4) + geompy.AddObject(CreateGroup, f_ind_6) # box_faces[5] + geompy.AddObject(CreateGroup, f_ind_1) # box_faces[0] + geompy.AddObject(CreateGroup, f_ind_4) # box_faces[3] + + # UnionList + geompy.UnionList(CreateGroup, [box_faces[2], box_faces[4], box_faces[5]]) # RemoveObject(theGroup, theSubShapeID) - geompy.RemoveObject(CreateGroup, f_ind_1) + geompy.RemoveObject(CreateGroup, f_ind_1) # box_faces[0] + + # DifferenceList + geompy.DifferenceList(CreateGroup, [box_faces[1], box_faces[0], box_faces[3]]) # GetObjectIDs GetObjectIDs = geompy.GetObjectIDs(CreateGroup) print "Group of Box's faces includes the following IDs:" + print "(must be ", f_ind_6, ", ", f_ind_3, " and ", f_ind_5, ")" for ObjectID in GetObjectIDs: print " ", ObjectID diff --git a/src/GEOM_SWIG/batchmode_geompy.py b/src/GEOM_SWIG/batchmode_geompy.py index 0e8f1b0a1..452023fcf 100644 --- a/src/GEOM_SWIG/batchmode_geompy.py +++ b/src/GEOM_SWIG/batchmode_geompy.py @@ -1033,6 +1033,16 @@ def RemoveObject(Group, SubShapeID): if GroupOp.IsDone() == 0: print "RemoveObject : ", GroupOp.GetErrorCode() +def UnionList (theGroup, theSubShapes): + GroupOp.UnionList(theGroup, theSubShapes) + if GroupOp.IsDone() == 0: + print "UnionList : ", GroupOp.GetErrorCode() + +def DifferenceList (theGroup, theSubShapes): + GroupOp.DifferenceList(theGroup, theSubShapes) + if GroupOp.IsDone() == 0: + print "DifferenceList : ", GroupOp.GetErrorCode() + def GetObjectIDs(Group): ListIDs = GroupOp.GetObjects(Group) if GroupOp.IsDone() == 0: diff --git a/src/GEOM_SWIG/geompy.py b/src/GEOM_SWIG/geompy.py index 656c22bae..60c341f82 100644 --- a/src/GEOM_SWIG/geompy.py +++ b/src/GEOM_SWIG/geompy.py @@ -2331,6 +2331,30 @@ def RemoveObject(theGroup, theSubShapeID): if GroupOp.IsDone() == 0: print "RemoveObject : ", GroupOp.GetErrorCode() +def UnionList (theGroup, theSubShapes): + """ + * Adds to the group all the given shapes. No errors, if some shapes are alredy included. + * \param theGroup is a GEOM group to which the new sub shapes are added. + * \param theSubShapes is a list of sub shapes to be added. + + * Example: see GEOM_TestOthers.py + """ + GroupOp.UnionList(theGroup, theSubShapes) + if GroupOp.IsDone() == 0: + print "UnionList : ", GroupOp.GetErrorCode() + +def DifferenceList (theGroup, theSubShapes): + """ + * Removes from the group all the given shapes. No errors, if some shapes are not included. + * \param theGroup is a GEOM group from which the sub-shapes are removed. + * \param theSubShapes is a list of sub-shapes to be removed. + + * Example: see GEOM_TestOthers.py + """ + GroupOp.DifferenceList(theGroup, theSubShapes) + if GroupOp.IsDone() == 0: + print "DifferenceList : ", GroupOp.GetErrorCode() + def GetObjectIDs(theGroup): """ * Returns a list of sub objects ID stored in the group -- 2.39.2