From 4b2d12773c431cc89bdab69858bc5f0d47f12d84 Mon Sep 17 00:00:00 2001 From: rnv Date: Wed, 16 May 2012 14:34:00 +0000 Subject: [PATCH] Fix for the "0021561: EDF 2184 GEOM: Group with second shape restriction" issue. --- idl/GEOM_Gen.idl | 11 ++ src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 106 ++++++++++++++++++++ src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 9 ++ src/GEOM_I/GEOM_IShapesOperations_i.cc | 31 ++++++ src/GEOM_I/GEOM_IShapesOperations_i.hh | 3 + src/GEOM_SWIG/geompyDC.py | 25 +++++ src/GroupGUI/GroupGUI_GroupDlg.cxx | 29 ++++-- 7 files changed, 206 insertions(+), 8 deletions(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 905b1b6c7..783392170 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -2118,6 +2118,17 @@ module GEOM */ GEOM_Object GetSame (in GEOM_Object theShapeWhere, in GEOM_Object theShapeWhat); + + /*! + * \brief Get sub-shape Ids of theShapeWhere, which are + * coincident with \a theShapeWhat that can either SOLID, FACE, EDGE or VERTEX. + * \param theShapeWhere Shape to find sub-shapes of. + * \param theShapeWhat Shape, specifying what to find. + * \return found sub-shape Ids. + */ + ListOfLong GetSameIDs (in GEOM_Object theShapeWhere, + in GEOM_Object theShapeWhat); + }; // # GEOM_IBlocksOperations: diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index 8577ac995..b81b261ce 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -4914,3 +4914,109 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object return aResult; } + + +//======================================================================= +//function : GetSameIDs +//purpose : +//======================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs(const Handle(GEOM_Object)& theShapeWhere, + const Handle(GEOM_Object)& theShapeWhat) +{ + SetErrorCode(KO); + if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL; + + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + + if (aWhere.IsNull() || aWhat.IsNull()) return NULL; + + int anIndex = -1; + bool isFound = false; + TopTools_ListOfShape listShape; + TopTools_MapOfShape aMap; + + if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) { + TopoDS_Iterator It (aWhat, Standard_True, Standard_True); + if (It.More()) aWhat = It.Value(); + It.Next(); + if (It.More()) { + SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument"); + return NULL; + } + } + + switch (aWhat.ShapeType()) { + case TopAbs_VERTEX: { + gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat)); + TopExp_Explorer E(aWhere, TopAbs_VERTEX); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current())); + if(P.Distance(P2) <= MAX_TOLERANCE) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_EDGE: { + TopoDS_Edge anEdge = TopoDS::Edge(aWhat); + TopExp_Explorer E(aWhere, TopAbs_EDGE); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_FACE: { + TopoDS_Face aFace = TopoDS::Face(aWhat); + TopExp_Explorer E(aWhere, TopAbs_FACE); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameFace(aFace, TopoDS::Face(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + case TopAbs_SOLID: { + TopoDS_Solid aSolid = TopoDS::Solid(aWhat); + TopExp_Explorer E(aWhere, TopAbs_SOLID); + for(; E.More(); E.Next()) { + if(!aMap.Add(E.Current())) continue; + if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) { + listShape.Append(E.Current()); + } + } + break; + } + default: + return NULL; + } + + if ( !listShape.IsEmpty() ) { + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aWhere, anIndices); + TopTools_ListIteratorOfListOfShape itSub (listShape); + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + for (; itSub.More(); itSub.Next()) { + if (anIndices.Contains(itSub.Value())) + aSeq->Append(anIndices.FindIndex(itSub.Value())); + } + SetErrorCode(OK); + // The GetSameIDs() doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction(); + + // Make a Python command + GEOM::TPythonDump(aFunction) + << "listSameIDs = geompy.GetSameIDs(" + << theShapeWhere << ", " + << theShapeWhat << ")"; + return aSeq; + } else { + SetErrorCode(NOT_FOUND_ANY); + return NULL; + } +} diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 93971ff83..21885888a 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -305,6 +305,15 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations Standard_EXPORT Handle(GEOM_Object) GetSame(const Handle(GEOM_Object)& theShapeWhere, const Handle(GEOM_Object)& theShapeWhat); + /*! + * \brief Searches a shape equal to theWhat in the context of theWhere + * \param theShapeWhere - a context shap + * \param theShapeWhat - a sample shape + * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes + */ + Standard_EXPORT Handle(TColStd_HSequenceOfInteger) GetSameIDs(const Handle(GEOM_Object)& theShapeWhere, + const Handle(GEOM_Object)& theShapeWhat); + /*! * \brief Find IDs of sub-shapes complying with given status about surface * \param theBox - the box to check state of sub-shapes against diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index ca40dbf23..cee18553c 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -1832,3 +1832,34 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetSame return GetObject(anObject); } + +//============================================================================= +/*! + * GetSameIDs + */ +//============================================================================= +GEOM::ListOfLong* GEOM_IShapesOperations_i::GetSameIDs + (GEOM::GEOM_Object_ptr theShapeWhere, + GEOM::GEOM_Object_ptr theShapeWhat) { + GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong; + + //Get the reference objects + Handle(GEOM_Object) aShapeWhere = GetObjectImpl(theShapeWhere); + Handle(GEOM_Object) aShapeWhat = GetObjectImpl(theShapeWhat); + + if (aShapeWhere.IsNull() || + aShapeWhat.IsNull()) return aSeq._retn(); + + + Handle(TColStd_HSequenceOfInteger) aHSeq = + GetOperations()->GetSameIDs(aShapeWhere, aShapeWhat); + + if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = aHSeq->Value(i); + + return aSeq._retn(); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index cd1a5756e..c01b6317e 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -264,6 +264,9 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i : GEOM::GEOM_Object_ptr GetSame (GEOM::GEOM_Object_ptr theShapeWhere, GEOM::GEOM_Object_ptr theShapeWhat); + GEOM::ListOfLong* GetSameIDs (GEOM::GEOM_Object_ptr theShapeWhere, + GEOM::GEOM_Object_ptr theShapeWhat); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py index bfcb487b0..b072e7c73 100644 --- a/src/GEOM_SWIG/geompyDC.py +++ b/src/GEOM_SWIG/geompyDC.py @@ -3870,6 +3870,31 @@ class geompyDC(GEOM._objref_GEOM_Gen): RaiseIfFailed("GetSame", self.ShapesOp) return anObj + + ## Get sub-shape indices of theShapeWhere, which is + # equal to \a theShapeWhat. + # @param theShapeWhere Shape to find sub-shape of. + # @param theShapeWhat Shape, specifying what to find. + # @return List of all found sub-shapes indices. + # + # @ref swig_GetSame "Example" + def GetSameIDs(self,theShapeWhere, theShapeWhat): + """ + Get sub-shape indices of theShapeWhere, which is + equal to theShapeWhat. + + Parameters: + theShapeWhere Shape to find sub-shape of. + theShapeWhat Shape, specifying what to find. + + Returns: + List of all found sub-shapes indices. + """ + anObj = self.ShapesOp.GetSameIDs(theShapeWhere, theShapeWhat) + RaiseIfFailed("GetSameIDs", self.ShapesOp) + return anObj + + # end of l4_obtain ## @} diff --git a/src/GroupGUI/GroupGUI_GroupDlg.cxx b/src/GroupGUI/GroupGUI_GroupDlg.cxx index 45ce5dece..c34c6bb04 100644 --- a/src/GroupGUI/GroupGUI_GroupDlg.cxx +++ b/src/GroupGUI/GroupGUI_GroupDlg.cxx @@ -427,14 +427,27 @@ void GroupGUI_GroupDlg::setInPlaceObj(GEOM::GEOM_Object_var theObj, const bool i GEOM::GEOM_ILocalOperations_var aLocOp = getGeomEngine()->GetILocalOperations(getStudyId()); GEOM::ListOfGO_var aSubObjects = aShapesOp->MakeExplode(myInPlaceObj, getShapeType(), false); - for (int i = 0; i < aSubObjects->length(); i++) + for ( int i = 0; i < aSubObjects->length(); i++ ) { - GEOM::GEOM_Object_var aSS = aShapesOp->GetSame(myMainObj, aSubObjects[i]); - if (!CORBA::is_nil(aSS)) { - CORBA::Long aMainIndex = aLocOp->GetSubShapeIndex(myMainObj, aSS); - CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex(myInPlaceObj, aSubObjects[i]); - if (aMainIndex >= 0 && aPlaceIndex > 0) - myMain2InPlaceIndices.Bind(aMainIndex, aPlaceIndex); + GEOM::ListOfLong_var aCurrList = aShapesOp->GetSameIDs( myMainObj, aSubObjects[i] ); + if( aCurrList->length() > 1 ) { + //rnv : To Fix the 21561: EDF 2184 GEOM: Group with second shape restriction. + // In case if GetSameIDs(...) method return more then one ID use + // GetSharedShapes(...) method to get sub-shapes of the second shape. + GEOM::ListOfGO_var aSubObjects2 = aShapesOp->GetSharedShapes( myMainObj, aSubObjects[i], getShapeType() ); + for( int j = 0; j < aSubObjects2->length(); j++ ) { + CORBA::Long aMainIndex = aLocOp->GetSubShapeIndex( myMainObj, aSubObjects2[j] ); + CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i]); + if ( aMainIndex >= 0 && aPlaceIndex > 0 ) { + myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex ); + } + } + } else if(aCurrList->length() > 0 ) { + CORBA::Long aMainIndex = aCurrList[0]; + CORBA::Long aPlaceIndex = aLocOp->GetSubShapeIndex( myInPlaceObj, aSubObjects[i] ); + if ( aMainIndex >= 0 && aPlaceIndex > 0) { + myMain2InPlaceIndices.Bind( aMainIndex, aPlaceIndex ); + } } } } @@ -674,7 +687,7 @@ int GroupGUI_GroupDlg::getSelectedSubshapes (TColStd_IndexedMapOfInteger& theMap anEntry.remove(0, index+1); int anIndex = anEntry.toInt(); if (anIndex) - theMapIndex.Add(anIndex); + theMapIndex.Add(anIndex); } else // selection among published shapes { -- 2.39.2