From: mpv Date: Tue, 24 Mar 2015 07:54:26 +0000 (+0300) Subject: Fix for random order of faces in selection name (groups on extrusion after aborting). X-Git-Tag: V_1.0.2~5 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=4b07d0ae015bc7ed510f8795d9d57d408e0367eb;p=modules%2Fshaper.git Fix for random order of faces in selection name (groups on extrusion after aborting). --- diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 29c1b950f..a87cea536 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -51,6 +51,7 @@ #include #include #include +#include using namespace std; //#define DEB_NAMING 1 #ifdef DEB_NAMING @@ -101,7 +102,7 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, std::string aSelName = namingName(); if(!aSelName.empty()) - TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name + TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name #ifdef DDDD //#### //selectSubShape("FACE", "Extrusion_1/LateralFace_3"); @@ -317,40 +318,40 @@ bool Model_AttributeSelection::update() // if aSubIds take any, the first appropriate int aFeatureID = aComposite->subFeatureId(a); if (aSubIds->IsEmpty() || aSubIds->Contains(aFeatureID) || - aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA) || - aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) { - // searching for deltas - int aVertexNum = 0; - if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA)) aVertexNum = 1; - else if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) aVertexNum = 2; - // found the feature with appropriate edge - FeaturePtr aFeature = aComposite->subFeature(a); - std::list >::const_iterator aResIter = - aFeature->results().cbegin(); - for(;aResIter != aFeature->results().cend(); aResIter++) { - ResultConstructionPtr aRes = - std::dynamic_pointer_cast(*aResIter); - if (aRes && aRes->shape()) { - if (aRes->shape()->isVertex() && aVertexNum == 0) { // found! - selectConstruction(aContext, aRes->shape()); - owner()->data()->sendAttributeUpdated(this); - return true; - } else if (aRes->shape()->isEdge() && aVertexNum > 0) { - const TopoDS_Shape& anEdge = aRes->shape()->impl(); - int aVIndex = 1; - for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { - if (aVIndex == aVertexNum) { // found! - std::shared_ptr aVertex(new GeomAPI_Shape); - aVertex->setImpl(new TopoDS_Shape(aVExp.Current())); - selectConstruction(aContext, aVertex); - owner()->data()->sendAttributeUpdated(this); - return true; + aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA) || + aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) { + // searching for deltas + int aVertexNum = 0; + if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA)) aVertexNum = 1; + else if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) aVertexNum = 2; + // found the feature with appropriate edge + FeaturePtr aFeature = aComposite->subFeature(a); + std::list >::const_iterator aResIter = + aFeature->results().cbegin(); + for(;aResIter != aFeature->results().cend(); aResIter++) { + ResultConstructionPtr aRes = + std::dynamic_pointer_cast(*aResIter); + if (aRes && aRes->shape()) { + if (aRes->shape()->isVertex() && aVertexNum == 0) { // found! + selectConstruction(aContext, aRes->shape()); + owner()->data()->sendAttributeUpdated(this); + return true; + } else if (aRes->shape()->isEdge() && aVertexNum > 0) { + const TopoDS_Shape& anEdge = aRes->shape()->impl(); + int aVIndex = 1; + for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { + if (aVIndex == aVertexNum) { // found! + std::shared_ptr aVertex(new GeomAPI_Shape); + aVertex->setImpl(new TopoDS_Shape(aVExp.Current())); + selectConstruction(aContext, aVertex); + owner()->data()->sendAttributeUpdated(this); + return true; + } + aVIndex++; } - aVIndex++; } } } - } } } } @@ -365,7 +366,7 @@ bool Model_AttributeSelection::update() void Model_AttributeSelection::selectBody( - const ResultPtr& theContext, const std::shared_ptr& theSubShape) + const ResultPtr& theContext, const std::shared_ptr& theSubShape) { // perform the selection TNaming_Selector aSel(selectionLabel()); @@ -376,7 +377,8 @@ void Model_AttributeSelection::selectBody( if (aBody) { aContext = aBody->shape()->impl(); } else { - ResultConstructionPtr aConstr = std::dynamic_pointer_cast(myRef.value()); + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(myRef.value()); if (aConstr) { aContext = aConstr->shape()->impl(); } else { @@ -424,7 +426,7 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, } void Model_AttributeSelection::selectConstruction( - const ResultPtr& theContext, const std::shared_ptr& theSubShape) + const ResultPtr& theContext, const std::shared_ptr& theSubShape) { std::shared_ptr aMyDoc = std::dynamic_pointer_cast(owner()->document()); @@ -544,60 +546,72 @@ TDF_Label Model_AttributeSelection::selectionLabel() #define FIX_BUG1 1 std::string GetShapeName(std::shared_ptr theDoc, const TopoDS_Shape& theShape, - const TDF_Label& theLabel) + const TDF_Label& theLabel) { std::string aName; // check if the subShape is already in DF Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(theShape, theLabel); Handle(TDataStd_Name) anAttr; if(!aNS.IsNull() && !aNS->IsEmpty()) { // in the document - if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) { - aName = TCollection_AsciiString(anAttr->Get()).ToCString(); - if(!aName.empty()) { - const TDF_Label& aLabel = theDoc->findNamingName(aName); - /* MPV: the same shape with the same name may be duplicated on different labels (selection of the same construction object) - if(!aLabel.IsEqual(aNS->Label())) { - //aName.erase(); //something is wrong, to be checked!!! - aName += "_SomethingWrong"; - return aName; - }*/ - const TopoDS_Shape& aShape = aNS->Get(); - if(aShape.ShapeType() == TopAbs_COMPOUND) { - std::string aPostFix("_"); - TopoDS_Iterator it(aShape); - for (int i = 1;it.More();it.Next(), i++) { - if(it.Value() == theShape) { - aPostFix += TCollection_AsciiString (i).ToCString(); - aName += aPostFix; - break; - } - else continue; - } - } - } - } + if(aNS->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) { + aName = TCollection_AsciiString(anAttr->Get()).ToCString(); + if(!aName.empty()) { + const TDF_Label& aLabel = theDoc->findNamingName(aName); + /* MPV: the same shape with the same name may be duplicated on different labels (selection of the same construction object) + if(!aLabel.IsEqual(aNS->Label())) { + //aName.erase(); //something is wrong, to be checked!!! + aName += "_SomethingWrong"; + return aName; + }*/ + + static const std::string aPostFix("_"); + TNaming_Iterator anItL(aNS); + for(int i = 1; anItL.More(); anItL.Next(), i++) { + if(anItL.NewShape() == theShape) { + aName += aPostFix; + aName += TCollection_AsciiString (i).ToCString(); + break; + } + } + /* MPV: the code below does not work because of TNaming_Tool.cxx line 145: aNS->Get() uses maps + const TopoDS_Shape& aShape = aNS->Get(); + if(aShape.ShapeType() == TopAbs_COMPOUND) { + std::string aPostFix("_"); + TopoDS_Iterator it(aShape); + for (int i = 1;it.More();it.Next(), i++) { + if(it.Value() == theShape) { + aPostFix += TCollection_AsciiString (i).ToCString(); + aName += aPostFix; + break; + } + else continue; + } + } + */ + } + } } return aName; } bool isTrivial (const TopTools_ListOfShape& theAncestors, TopTools_IndexedMapOfShape& theSMap) { -// a trivial case: F1 & F2, aNumber = 1, i.e. intersection gives 1 edge. + // a trivial case: F1 & F2, aNumber = 1, i.e. intersection gives 1 edge. TopoDS_Compound aCmp; BRep_Builder BB; BB.MakeCompound(aCmp); TopTools_ListIteratorOfListOfShape it(theAncestors); for(;it.More();it.Next()) { - BB.Add(aCmp, it.Value()); - theSMap.Add(it.Value()); + BB.Add(aCmp, it.Value()); + theSMap.Add(it.Value()); } int aNumber(0); TopTools_IndexedDataMapOfShapeListOfShape aMap2; TopExp::MapShapesAndAncestors(aCmp, TopAbs_EDGE, TopAbs_FACE, aMap2); for (int i = 1; i <= aMap2.Extent(); i++) { - const TopoDS_Shape& aKey = aMap2.FindKey(i); - const TopTools_ListOfShape& anAncestors = aMap2.FindFromIndex(i); - if(anAncestors.Extent() > 1) aNumber++; + const TopoDS_Shape& aKey = aMap2.FindKey(i); + const TopTools_ListOfShape& anAncestors = aMap2.FindFromIndex(i); + if(anAncestors.Extent() > 1) aNumber++; } if(aNumber > 1) return false; return true; @@ -608,8 +622,8 @@ std::string Model_AttributeSelection::namingName() if(!this->isInitialized()) return aName; Handle(TDataStd_Name) anAtt; if(selectionLabel().FindAttribute(TDataStd_Name::GetID(), anAtt)) { - aName = TCollection_AsciiString(anAtt->Get()).ToCString(); - return aName; + aName = TCollection_AsciiString(anAtt->Get()).ToCString(); + return aName; } std::shared_ptr aSubSh = value(); @@ -630,130 +644,130 @@ std::string Model_AttributeSelection::namingName() aName = GetShapeName(aDoc, aSubShape, selectionLabel()); if(aName.empty() ) { // not in the document! TopAbs_ShapeEnum aType = aSubShape.ShapeType(); - switch (aType) { - case TopAbs_FACE: + switch (aType) { + case TopAbs_FACE: // the Face should be in DF. If it is not the case, it is an error ==> to be debugged - break; - case TopAbs_EDGE: - { - // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case - // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces - TopTools_IndexedDataMapOfShapeListOfShape aMap; - TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap); - TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape - bool isTrivialCase(true); -/* for (int i = 1; i <= aMap.Extent(); i++) { - const TopoDS_Shape& aKey = aMap.FindKey(i); - //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key - if (aKey.IsSame(aSubShape)) continue; - const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i); - // check that it is not a trivial case (F1 & F2: aNumber = 1) - isTrivialCase = isTrivial(anAncestors, aSMap); - break; - }*/ - if(aMap.Contains(aSubShape)) { - const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape); - // check that it is not a trivial case (F1 & F2: aNumber = 1) - isTrivialCase = isTrivial(anAncestors, aSMap); - } else - break; - TopTools_ListOfShape aListOfNbs; - if(!isTrivialCase) { // find Neighbors - TNaming_Localizer aLocalizer; - TopTools_MapOfShape aMap3; - aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3); - //int n = aMap3.Extent(); - TopTools_MapIteratorOfMapOfShape it(aMap3); - for(;it.More();it.Next()) { - const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge - //TopAbs_ShapeEnum aType = aNbShape.ShapeType(); - const TopTools_ListOfShape& aList = aMap.FindFromKey(aNbShape); - TopTools_ListIteratorOfListOfShape it2(aList); - for(;it2.More();it2.Next()) { - if(aSMap.Contains(it2.Value())) continue; // skip this Face - aListOfNbs.Append(it2.Value()); - } - } - } // else a trivial case - - // build name of the sub-shape Edge - for(int i=1; i <= aSMap.Extent(); i++) { - const TopoDS_Shape& aFace = aSMap.FindKey(i); - std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel()); - if(i == 1) - aName = aFaceName; - else - aName += "|" + aFaceName; - } - TopTools_ListIteratorOfListOfShape itl(aListOfNbs); - for (;itl.More();itl.Next()) { - std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel()); - aName += "|" + aFaceName; - } - } - break; + break; + case TopAbs_EDGE: + { + // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case + // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces + TopTools_IndexedDataMapOfShapeListOfShape aMap; + TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap); + TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape + bool isTrivialCase(true); + /* for (int i = 1; i <= aMap.Extent(); i++) { + const TopoDS_Shape& aKey = aMap.FindKey(i); + //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key + if (aKey.IsSame(aSubShape)) continue; + const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i); + // check that it is not a trivial case (F1 & F2: aNumber = 1) + isTrivialCase = isTrivial(anAncestors, aSMap); + break; + }*/ + if(aMap.Contains(aSubShape)) { + const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape); + // check that it is not a trivial case (F1 & F2: aNumber = 1) + isTrivialCase = isTrivial(anAncestors, aSMap); + } else + break; + TopTools_ListOfShape aListOfNbs; + if(!isTrivialCase) { // find Neighbors + TNaming_Localizer aLocalizer; + TopTools_MapOfShape aMap3; + aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3); + //int n = aMap3.Extent(); + TopTools_MapIteratorOfMapOfShape it(aMap3); + for(;it.More();it.Next()) { + const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge + //TopAbs_ShapeEnum aType = aNbShape.ShapeType(); + const TopTools_ListOfShape& aList = aMap.FindFromKey(aNbShape); + TopTools_ListIteratorOfListOfShape it2(aList); + for(;it2.More();it2.Next()) { + if(aSMap.Contains(it2.Value())) continue; // skip this Face + aListOfNbs.Append(it2.Value()); + } + } + } // else a trivial case - case TopAbs_VERTEX: - // name structure (Monifold Topology): - // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case. - // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation - // 2) F1 | F2 - intersection of 2 faces definses a vertex - applicable for case - // when 1 faces is cylindrical, conical, spherical or revolution and etc. - // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell - // or compound of 2 open faces. - // 4) E1 | E2 - intesection of 2 edges defines a vertex - when we have a case of - // two independent edges (wire or compound) - // implemented 2 first cases - { - TopTools_IndexedDataMapOfShapeListOfShape aMap; - TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap); - const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape); - TopTools_ListOfShape aList; - TopTools_MapOfShape aFMap; + // build name of the sub-shape Edge + for(int i=1; i <= aSMap.Extent(); i++) { + const TopoDS_Shape& aFace = aSMap.FindKey(i); + std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel()); + if(i == 1) + aName = aFaceName; + else + aName += "|" + aFaceName; + } + TopTools_ListIteratorOfListOfShape itl(aListOfNbs); + for (;itl.More();itl.Next()) { + std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel()); + aName += "|" + aFaceName; + } + } + break; + + case TopAbs_VERTEX: + // name structure (Monifold Topology): + // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case. + // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation + // 2) F1 | F2 - intersection of 2 faces definses a vertex - applicable for case + // when 1 faces is cylindrical, conical, spherical or revolution and etc. + // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell + // or compound of 2 open faces. + // 4) E1 | E2 - intesection of 2 edges defines a vertex - when we have a case of + // two independent edges (wire or compound) + // implemented 2 first cases + { + TopTools_IndexedDataMapOfShapeListOfShape aMap; + TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap); + const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape); + TopTools_ListOfShape aList; + TopTools_MapOfShape aFMap; #ifdef FIX_BUG1 - //int n = aList2.Extent(); //bug! duplication - // fix is below - TopTools_ListIteratorOfListOfShape itl2(aList2); - for (int i = 1;itl2.More();itl2.Next(),i++) { - if(aFMap.Add(itl2.Value())) - aList.Append(itl2.Value()); - } - //n = aList.Extent(); + //int n = aList2.Extent(); //bug! duplication + // fix is below + TopTools_ListIteratorOfListOfShape itl2(aList2); + for (int i = 1;itl2.More();itl2.Next(),i++) { + if(aFMap.Add(itl2.Value())) + aList.Append(itl2.Value()); + } + //n = aList.Extent(); #endif - int n = aList.Extent(); - if(n < 3) { // open topology case => via edges - TopTools_IndexedDataMapOfShapeListOfShape aMap; - TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap); - const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape); - if(aList2.Extent() >= 2) { // regular solution - TopTools_ListIteratorOfListOfShape itl(aList2); - for (int i = 1;itl.More();itl.Next(),i++) { - const TopoDS_Shape& anEdge = itl.Value(); - std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel()); - if(i == 1) - aName = anEdgeName; - else - aName += "|" + anEdgeName; - } - } - } - else { - TopTools_ListIteratorOfListOfShape itl(aList); - for (int i = 1;itl.More();itl.Next(),i++) { - const TopoDS_Shape& aFace = itl.Value(); - std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel()); - if(i == 1) - aName = aFaceName; - else - aName += "|" + aFaceName; - } - } - } - break; - } + int n = aList.Extent(); + if(n < 3) { // open topology case => via edges + TopTools_IndexedDataMapOfShapeListOfShape aMap; + TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap); + const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape); + if(aList2.Extent() >= 2) { // regular solution + TopTools_ListIteratorOfListOfShape itl(aList2); + for (int i = 1;itl.More();itl.Next(),i++) { + const TopoDS_Shape& anEdge = itl.Value(); + std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel()); + if(i == 1) + aName = anEdgeName; + else + aName += "|" + anEdgeName; + } + } + } + else { + TopTools_ListIteratorOfListOfShape itl(aList); + for (int i = 1;itl.More();itl.Next(),i++) { + const TopoDS_Shape& aFace = itl.Value(); + std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel()); + if(i == 1) + aName = aFaceName; + else + aName += "|" + aFaceName; + } + } + } + break; + } // register name // aDoc->addNamingName(selectionLabel(), aName); - // the selected sub-shape will not be shared and as result it will not require registration + // the selected sub-shape will not be shared and as result it will not require registration } return aName; } @@ -763,47 +777,49 @@ TopAbs_ShapeEnum translateType (const std::string& theType) TCollection_AsciiString aStr(theType.c_str()); aStr.UpperCase(); if(aStr.IsEqual("COMP")) - return TopAbs_COMPOUND; + return TopAbs_COMPOUND; else if(aStr.IsEqual("COMS")) - return TopAbs_COMPSOLID; + return TopAbs_COMPSOLID; else if(aStr.IsEqual("SOLD")) - return TopAbs_SOLID; + return TopAbs_SOLID; else if(aStr.IsEqual("SHEL")) - return TopAbs_SHELL; + return TopAbs_SHELL; else if(aStr.IsEqual("FACE")) - return TopAbs_FACE; + return TopAbs_FACE; else if(aStr.IsEqual("WIRE")) - return TopAbs_WIRE; + return TopAbs_WIRE; else if(aStr.IsEqual("EDGE")) - return TopAbs_EDGE; + return TopAbs_EDGE; else if(aStr.IsEqual("VERT")) - return TopAbs_VERTEX; + return TopAbs_VERTEX; return TopAbs_SHAPE; } -const TopoDS_Shape getShapeFromCompound(const std::string& theSubShapeName, const TopoDS_Shape& theCompound) +const TopoDS_Shape getShapeFromCompound( + const std::string& theSubShapeName, const TopoDS_Shape& theCompound) { TopoDS_Shape aSelection; std::string::size_type n = theSubShapeName.rfind('/'); if (n == std::string::npos) n = 0; - std::string aSubString = theSubShapeName.substr(n + 1); - n = aSubString.rfind('_'); - if (n == std::string::npos) return aSelection; - aSubString = aSubString.substr(n+1); - int indx = atoi(aSubString.c_str()); - TopoDS_Iterator it(theCompound); - for (int i = 1;it.More();it.Next(), i++) { - if(i == indx) { - aSelection = it.Value(); - break; - } - else continue; - } + std::string aSubString = theSubShapeName.substr(n + 1); + n = aSubString.rfind('_'); + if (n == std::string::npos) return aSelection; + aSubString = aSubString.substr(n+1); + int indx = atoi(aSubString.c_str()); + TopoDS_Iterator it(theCompound); + for (int i = 1;it.More();it.Next(), i++) { + if(i == indx) { + aSelection = it.Value(); + break; + } + else continue; + } return aSelection; } -const TopoDS_Shape findFaceByName(const std::string& theSubShapeName, std::shared_ptr theDoc) +const TopoDS_Shape findFaceByName( + const std::string& theSubShapeName, std::shared_ptr theDoc) { TopoDS_Shape aFace; std::string::size_type n, nb = theSubShapeName.rfind('/'); @@ -811,23 +827,23 @@ const TopoDS_Shape findFaceByName(const std::string& theSubShapeName, std::share std::string aSubString = theSubShapeName.substr(nb + 1); n = aSubString.rfind('_'); if (n != std::string::npos) { - std::string aSubStr2 = aSubString.substr(0, n); - aSubString = theSubShapeName.substr(0, nb + 1); - aSubString = aSubString + aSubStr2; + std::string aSubStr2 = aSubString.substr(0, n); + aSubString = theSubShapeName.substr(0, nb + 1); + aSubString = aSubString + aSubStr2; } else - aSubString = theSubShapeName; - + aSubString = theSubShapeName; + const TDF_Label& aLabel = theDoc->findNamingName(aSubString); if(aLabel.IsNull()) return aFace; Handle(TNaming_NamedShape) aNS; if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { - const TopoDS_Shape& aShape = aNS->Get(); - if(!aShape.IsNull()) { - if(aShape.ShapeType() == TopAbs_COMPOUND) - aFace = getShapeFromCompound(theSubShapeName, aShape); - else - aFace = aShape; - } + const TopoDS_Shape& aShape = aNS->Get(); + if(!aShape.IsNull()) { + if(aShape.ShapeType() == TopAbs_COMPOUND) + aFace = getShapeFromCompound(theSubShapeName, aShape); + else + aFace = aShape; + } } return aFace; } @@ -839,23 +855,24 @@ int ParseName(const std::string& theSubShapeName, std::list& theL int n1(0), n2(0); // n1 - start position, n2 - position of the delimiter while ((n2 = aName.find('|', n1)) != std::string::npos) { const std::string aName1 = aName.substr(n1, n2 - n1); //name of face - theList.push_back(aName1); - n1 = n2 + 1; - aLastName = aName.substr(n1); + theList.push_back(aName1); + n1 = n2 + 1; + aLastName = aName.substr(n1); } if(!aLastName.empty()) - theList.push_back(aLastName); + theList.push_back(aLastName); return theList.size(); } -const TopoDS_Shape findCommonShape(const TopAbs_ShapeEnum theType, const TopTools_ListOfShape& theList) +const TopoDS_Shape findCommonShape( + const TopAbs_ShapeEnum theType, const TopTools_ListOfShape& theList) { TopoDS_Shape aShape; std::vector aVec; TopTools_MapOfShape aMap1, aMap2, aMap3, aMap4; if(theList.Extent() > 1) { - aVec.push_back(aMap1); - aVec.push_back(aMap2); + aVec.push_back(aMap1); + aVec.push_back(aMap2); } if(theList.Extent() > 2) aVec.push_back(aMap3); @@ -865,66 +882,66 @@ const TopoDS_Shape findCommonShape(const TopAbs_ShapeEnum theType, const TopTool //fill maps TopTools_ListIteratorOfListOfShape it(theList); for(int i = 0;it.More();it.Next(),i++) { - const TopoDS_Shape& aFace = it.Value(); - if(i < 2) { - TopExp_Explorer anExp (aFace, theType); - for(;anExp.More();anExp.Next()) { - const TopoDS_Shape& anEdge = anExp.Current(); - if (!anEdge.IsNull()) - aVec[i].Add(anExp.Current()); - } - } else { - TopExp_Explorer anExp (aFace, TopAbs_VERTEX); - for(;anExp.More();anExp.Next()) { - const TopoDS_Shape& aVertex = anExp.Current(); - if (!aVertex.IsNull()) - aVec[i].Add(anExp.Current()); - } - } + const TopoDS_Shape& aFace = it.Value(); + if(i < 2) { + TopExp_Explorer anExp (aFace, theType); + for(;anExp.More();anExp.Next()) { + const TopoDS_Shape& anEdge = anExp.Current(); + if (!anEdge.IsNull()) + aVec[i].Add(anExp.Current()); + } + } else { + TopExp_Explorer anExp (aFace, TopAbs_VERTEX); + for(;anExp.More();anExp.Next()) { + const TopoDS_Shape& aVertex = anExp.Current(); + if (!aVertex.IsNull()) + aVec[i].Add(anExp.Current()); + } + } } //trivial case: 2 faces TopTools_ListOfShape aList; TopTools_MapIteratorOfMapOfShape it2(aVec[0]); for(;it2.More();it2.Next()) { - if(aVec[1].Contains(it2.Key())) { - aShape = it2.Key(); - if(theList.Extent() == 2) - break; - else - aList.Append(it2.Key()); - } + if(aVec[1].Contains(it2.Key())) { + aShape = it2.Key(); + if(theList.Extent() == 2) + break; + else + aList.Append(it2.Key()); + } } if(aList.Extent() && aVec.size() > 3) {// list of common edges ==> search ny neighbors - if(aVec[2].Extent() && aVec[3].Extent()) { - TopTools_ListIteratorOfListOfShape it(aList); - for(;it.More();it.Next()) { - const TopoDS_Shape& aCand = it.Value(); - // not yet completelly implemented, to be rechecked - TopoDS_Vertex aV1, aV2; - TopExp::Vertices(TopoDS::Edge(aCand), aV1, aV2); - int aNum(0); - if(aVec[2].Contains(aV1)) aNum++; - else if(aVec[2].Contains(aV2)) aNum++; - if(aVec[3].Contains(aV1)) aNum++; - else if(aVec[3].Contains(aV2)) aNum++; - if(aNum == 2) { - aShape = aCand; - break; - } - } - } + if(aVec[2].Extent() && aVec[3].Extent()) { + TopTools_ListIteratorOfListOfShape it(aList); + for(;it.More();it.Next()) { + const TopoDS_Shape& aCand = it.Value(); + // not yet completelly implemented, to be rechecked + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(TopoDS::Edge(aCand), aV1, aV2); + int aNum(0); + if(aVec[2].Contains(aV1)) aNum++; + else if(aVec[2].Contains(aV2)) aNum++; + if(aVec[3].Contains(aV1)) aNum++; + else if(aVec[3].Contains(aV2)) aNum++; + if(aNum == 2) { + aShape = aCand; + break; + } + } + } } if(aList.Extent() && aVec.size() == 3) { TopTools_ListIteratorOfListOfShape it(aList); - for(;it.More();it.Next()) { - const TopoDS_Shape& aCand = it.Value(); - if(aVec[2].Contains(aCand)) { - aShape = aCand; - break; - } - } + for(;it.More();it.Next()) { + const TopoDS_Shape& aCand = it.Value(); + if(aVec[2].Contains(aCand)) { + aShape = aCand; + break; + } + } } return aShape; } @@ -938,11 +955,13 @@ std::string getContextName(const std::string& theSubShapeName) return aName; } // type ::= COMP | COMS | SOLD | SHEL | FACE | WIRE | EDGE | VERT -void Model_AttributeSelection::selectSubShape(const std::string& theType, const std::string& theSubShapeName) +void Model_AttributeSelection::selectSubShape( + const std::string& theType, const std::string& theSubShapeName) { if(theSubShapeName.empty() || theType.empty()) return; TopAbs_ShapeEnum aType = translateType(theType); - std::shared_ptr aDoc = std::dynamic_pointer_cast(owner()->document());//std::dynamic_pointer_cast(aCont->document()); + std::shared_ptr aDoc = + std::dynamic_pointer_cast(owner()->document()); std::string aContName = getContextName(theSubShapeName); if(aContName.empty()) return; //ResultPtr aCont = context(); @@ -951,8 +970,8 @@ void Model_AttributeSelection::selectSubShape(const std::string& theType, const TopoDS_Shape aContext = aCont->shape()->impl(); TopAbs_ShapeEnum aContType = aContext.ShapeType(); if(aType <= aContType) return; // not applicable - - + + TopoDS_Shape aSelection; switch (aType) { @@ -966,89 +985,91 @@ void Model_AttributeSelection::selectSubShape(const std::string& theType, const break; case TopAbs_FACE: { - const TopoDS_Shape aSelection = findFaceByName(theSubShapeName, aDoc); - if(!aSelection.IsNull()) {// Select it - std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); + const TopoDS_Shape aSelection = findFaceByName(theSubShapeName, aDoc); + if(!aSelection.IsNull()) {// Select it + std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection)); - setValue(aCont, aShapeToBeSelected); - } - } + setValue(aCont, aShapeToBeSelected); + } + } break; case TopAbs_WIRE: - break; + break; case TopAbs_EDGE: - { - TopoDS_Shape aSelection;// = findFaceByName(theSubShapeName, aDoc); - const TDF_Label& aLabel = aDoc->findNamingName(theSubShapeName); + { + TopoDS_Shape aSelection;// = findFaceByName(theSubShapeName, aDoc); + const TDF_Label& aLabel = aDoc->findNamingName(theSubShapeName); if(!aLabel.IsNull()) { Handle(TNaming_NamedShape) aNS; if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { - const TopoDS_Shape& aShape = aNS->Get(); - if(!aShape.IsNull()) { - if(aShape.ShapeType() == TopAbs_COMPOUND) - aSelection = getShapeFromCompound(theSubShapeName, aShape); - else - aSelection = aShape; - } - } - } - if(aSelection.IsNull()) { - std::list aListofNames; - int n = ParseName(theSubShapeName, aListofNames); - if(n > 1 && n < 5) { - TopTools_ListOfShape aList; - for(std::list::iterator it =aListofNames.begin();it != aListofNames.end();it++){ - const TopoDS_Shape aFace = findFaceByName(*it, aDoc); - aList.Append(aFace); - } - aSelection = findCommonShape(TopAbs_EDGE, aList); - } - } - if(!aSelection.IsNull()) {// Select it - std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); + const TopoDS_Shape& aShape = aNS->Get(); + if(!aShape.IsNull()) { + if(aShape.ShapeType() == TopAbs_COMPOUND) + aSelection = getShapeFromCompound(theSubShapeName, aShape); + else + aSelection = aShape; + } + } + } + if(aSelection.IsNull()) { + std::list aListofNames; + int n = ParseName(theSubShapeName, aListofNames); + if(n > 1 && n < 5) { + TopTools_ListOfShape aList; + std::list::iterator it =aListofNames.begin(); + for(;it != aListofNames.end();it++){ + const TopoDS_Shape aFace = findFaceByName(*it, aDoc); + aList.Append(aFace); + } + aSelection = findCommonShape(TopAbs_EDGE, aList); + } + } + if(!aSelection.IsNull()) {// Select it + std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection)); - setValue(aCont, aShapeToBeSelected); - } - } + setValue(aCont, aShapeToBeSelected); + } + } break; case TopAbs_VERTEX: - { - TopoDS_Shape aSelection; - const TDF_Label& aLabel = aDoc->findNamingName(theSubShapeName); + { + TopoDS_Shape aSelection; + const TDF_Label& aLabel = aDoc->findNamingName(theSubShapeName); if(!aLabel.IsNull()) { Handle(TNaming_NamedShape) aNS; if(aLabel.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { - const TopoDS_Shape& aShape = aNS->Get(); - if(!aShape.IsNull()) { - if(aShape.ShapeType() == TopAbs_COMPOUND) - aSelection = getShapeFromCompound(theSubShapeName, aShape); - else - aSelection = aShape; - } - } - } - if(aSelection.IsNull()) { - std::list aListofNames; - int n = ParseName(theSubShapeName, aListofNames); - if(n > 1 && n < 4) { // 2 || 3 - TopTools_ListOfShape aList; - for(std::list::iterator it =aListofNames.begin();it != aListofNames.end();it++){ - const TopoDS_Shape aFace = findFaceByName(*it, aDoc); - if(!aFace.IsNull()) - aList.Append(aFace); - } - aSelection = findCommonShape(TopAbs_VERTEX, aList); - } - } - if(!aSelection.IsNull()) {// Select it - std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); + const TopoDS_Shape& aShape = aNS->Get(); + if(!aShape.IsNull()) { + if(aShape.ShapeType() == TopAbs_COMPOUND) + aSelection = getShapeFromCompound(theSubShapeName, aShape); + else + aSelection = aShape; + } + } + } + if(aSelection.IsNull()) { + std::list aListofNames; + int n = ParseName(theSubShapeName, aListofNames); + if(n > 1 && n < 4) { // 2 || 3 + TopTools_ListOfShape aList; + std::list::iterator it = aListofNames.begin(); + for(; it != aListofNames.end(); it++){ + const TopoDS_Shape aFace = findFaceByName(*it, aDoc); + if(!aFace.IsNull()) + aList.Append(aFace); + } + aSelection = findCommonShape(TopAbs_VERTEX, aList); + } + } + if(!aSelection.IsNull()) {// Select it + std::shared_ptr aShapeToBeSelected(new GeomAPI_Shape()); aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection)); - setValue(aCont, aShapeToBeSelected); - } - } - break; + setValue(aCont, aShapeToBeSelected); + } + } + break; default: //TopAbs_SHAPE - return; + return; } } @@ -1061,7 +1082,7 @@ int Model_AttributeSelection::Id() const TopoDS_Shape& aSubShape = aSelection->impl(); int anID = 0; if (aSelection && !aSelection->isNull() && - aContext && !aContext->isNull()) + aContext && !aContext->isNull()) { TopTools_IndexedMapOfShape aSubShapesMap; TopExp::MapShapes(aMainShape, aSubShapesMap);