X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelection.cpp;h=53c04b6863ad4cb7fd7eb1dea4ce00907a292e21;hb=694482299ca580d780c221cc6a3e7574e59fd2c3;hp=f610b3dbefb7161ab8e292fcfac57b0dfd7e6539;hpb=a73784ec83ca10e12b2832c681ce3bf38f8550c9;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index f610b3dbe..53c04b686 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -8,6 +8,7 @@ #include "Model_Application.h" #include "Model_Events.h" #include "Model_Data.h" +#include "Model_Document.h" #include #include #include @@ -26,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -40,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -48,9 +52,15 @@ #include #include using namespace std; +//#define DEB_NAMING 1 +#ifdef DEB_NAMING +#include +#endif /// adeed to the index in the packed map to signalize that the vertex of edge is seleted /// (multiplied by the index of the edge) static const int kSTART_VERTEX_DELTA = 1000000; +// identifier that there is simple reference: selection equals to context +Standard_GUID kSIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb29"); // on this label is stored: // TNaming_NamedShape - selected shape @@ -58,7 +68,7 @@ static const int kSTART_VERTEX_DELTA = 1000000; // TDataStd_IntPackedMap - indexes of edges in composite element (for construction) // TDataStd_Integer - type of the selected shape (for construction) // TDF_Reference - from ReferenceAttribute, the context - +#define DDDD 1 void Model_AttributeSelection::setValue(const ResultPtr& theContext, const std::shared_ptr& theSubShape) { @@ -68,19 +78,37 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, if (isOldShape) return; // shape is the same, so context is also unchanged // update the referenced object if needed bool isOldContext = theContext == myRef.value(); + + if (!isOldContext) myRef.setValue(theContext); - if (theContext->groupName() == ModelAPI_ResultBody::group()) - selectBody(theContext, theSubShape); - else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) + // do noth use naming if selected shape is result shape itself, but not sub-shape + TDF_Label aSelLab = selectionLabel(); + aSelLab.ForgetAttribute(kSIMPLE_REF_ID); + if (theContext->groupName() == ModelAPI_ResultBody::group()) { + // do not select the whole shape for body:it is already must be in the data framework + if (theContext->shape().get() && theContext->shape()->isEqual(theSubShape)) { + aSelLab.ForgetAllAttributes(true); + TDataStd_UAttribute::Set(aSelLab, kSIMPLE_REF_ID); + } else { + selectBody(theContext, theSubShape); + } + } else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) { selectConstruction(theContext, theSubShape); + } + myIsInitialized = true; std::string aSelName = namingName(); if(!aSelName.empty()) TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name - - myIsInitialized = true; +#ifdef DDDD + //#### + //selectSubShape("FACE", "Extrusion_1/LateralFace_3"); + //selectSubShape("FACE", "Extrusion_1/TopFace"); + //selectSubShape("EDGE", "Extrusion_1/TopFace|Extrusion_1/LateralFace_1"); + //selectSubShape("EDGE", "Sketch_1/Edge_6"); +#endif owner()->data()->sendAttributeUpdated(this); } @@ -88,6 +116,14 @@ std::shared_ptr Model_AttributeSelection::value() { std::shared_ptr aResult; if (myIsInitialized) { + TDF_Label aSelLab = selectionLabel(); + if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape + ResultPtr aContext = context(); + if (!aContext.get()) + return aResult; // empty result + return aContext->shape(); + } + Handle(TNaming_NamedShape) aSelection; if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) { TopoDS_Shape aSelShape = aSelection->Get(); @@ -147,10 +183,15 @@ TDF_LabelMap& Model_AttributeSelection::scope() bool Model_AttributeSelection::update() { ResultPtr aContext = context(); - if (!aContext) return false; + if (!aContext.get()) return false; + TDF_Label aSelLab = selectionLabel(); + if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape + return aContext->shape() && !aContext->shape()->isNull(); + } + if (aContext->groupName() == ModelAPI_ResultBody::group()) { // body: just a named shape, use selection mechanism from OCCT - TNaming_Selector aSelector(selectionLabel()); + TNaming_Selector aSelector(aSelLab); bool aResult = aSelector.Solve(scope()) == Standard_True; owner()->data()->sendAttributeUpdated(this); return aResult; @@ -275,7 +316,9 @@ bool Model_AttributeSelection::update() for(int a = 0; a < aSubNum; a++) { // if aSubIds take any, the first appropriate int aFeatureID = aComposite->subFeatureId(a); - if (aSubIds->IsEmpty() || aSubIds->Contains(aFeatureID)) { + 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; @@ -312,6 +355,7 @@ bool Model_AttributeSelection::update() } } } else { // simple construction element: the selected is that needed + selectConstruction(aContext, aContext->shape()); owner()->data()->sendAttributeUpdated(this); return true; } @@ -340,22 +384,61 @@ void Model_AttributeSelection::selectBody( return; } } - aSel.Select(aNewShape, aContext); + //BRepTools::Write(aNewShape, "Selection0.brep"); + aSel.Select(aNewShape, aContext); +} + +/// registers the name of the shape in the label (theID == 0) of sub label (theID is a tag) +/// if theID is zero, +static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, + const int theID, const FeaturePtr& theContextFeature, std::shared_ptr theDoc, + std::string theAdditionalName, + Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)()) +{ + TDF_Label aLab = theID == 0 ? theMainLabel : theMainLabel.FindChild(theID); + TNaming_Builder aBuilder(aLab); + aBuilder.Generated(theShape); + std::stringstream aName; + aName<name()<<"/"; + if (!theAdditionalName.empty()) + aName<GetMap()); + for(; aRef.More(); aRef.Next()) { + aName<<"-"<addNamingName(aLab, aName.str()); + TDataStd_Name::Set(aLab, aName.str().c_str()); } void Model_AttributeSelection::selectConstruction( const ResultPtr& theContext, const std::shared_ptr& theSubShape) { + std::shared_ptr aMyDoc = + std::dynamic_pointer_cast(owner()->document()); FeaturePtr aContextFeature = theContext->document()->feature(theContext); CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aContextFeature); + const TopoDS_Shape& aSubShape = theSubShape->impl(); if (!aComposite || aComposite->numberOfSubs() == 0) { - return; // saving of context is enough: result construction contains exactly the needed shape + // saving of context is enough: result construction contains exactly the needed shape + TNaming_Builder aBuilder(selectionLabel()); + aBuilder.Generated(aSubShape); + aMyDoc->addNamingName(selectionLabel(), theContext->data()->name()); + TDataStd_Name::Set(selectionLabel(), theContext->data()->name().c_str()); + return; } std::shared_ptr aData = std::dynamic_pointer_cast(owner()->data()); TDF_Label aLab = myRef.myRef->Label(); // identify the reuslts of sub-object of the composite by edges - const TopoDS_Shape& aSubShape = theSubShape->impl(); // save type of the selected shape in integer attribute TopAbs_ShapeEnum aShapeType = aSubShape.ShapeType(); TDataStd_Integer::Set(aLab, (int)aShapeType); @@ -371,7 +454,7 @@ void Model_AttributeSelection::selectConstruction( allCurves.Add(aCurve); } } - // iterate and store the result ids of sub-elements + // iterate and store the result ids of sub-elements and sub-elements to sub-labels Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); aRefs->Clear(); const int aSubNum = aComposite->numberOfSubs(); @@ -399,7 +482,6 @@ void Model_AttributeSelection::selectConstruction( for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current())); if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { - aRefs->Add(aComposite->subFeatureId(a)); aRefs->Add(aDelta + aComposite->subFeatureId(a)); break; } @@ -416,14 +498,27 @@ void Model_AttributeSelection::selectConstruction( if (allCurves.Contains(aCurve)) { int anID = aComposite->subFeatureId(a); aRefs->Add(anID); - // add edges to sub-label to support naming for edges selection - for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { - TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - if (aFaceCurve == aCurve) { - TNaming_Builder anEdgeBuilder(selectionLabel().FindChild(anID)); - anEdgeBuilder.Generated(anEdge); + if (aShapeType != TopAbs_EDGE) { // edge do not need the sub-edges on sub-labels + // add edges to sub-label to support naming for edges selection + TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); + for(; anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (aFaceCurve == aCurve) { + registerSubShape(selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, ""); + } + } + } else { // put vertices of the selected edge to sub-labels + // add edges to sub-label to support naming for edges selection + TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX); + int aTagIndex = anID + kSTART_VERTEX_DELTA; + for(; anEdgeExp.More(); anEdgeExp.Next(), aTagIndex += kSTART_VERTEX_DELTA) { + TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); + + std::stringstream anAdditionalName; + registerSubShape(selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, + ""); } } } @@ -435,6 +530,7 @@ void Model_AttributeSelection::selectConstruction( // store the selected as primitive TNaming_Builder aBuilder(selectionLabel()); aBuilder.Generated(aSubShape); + registerSubShape(selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", aRefs); } TDF_Label Model_AttributeSelection::selectionLabel() @@ -455,11 +551,12 @@ std::string GetShapeName(std::shared_ptr theDoc, const TopoDS_Sh 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("_"); @@ -501,16 +598,29 @@ bool isTrivial (const TopTools_ListOfShape& theAncestors, TopTools_IndexedMapOfS if(aNumber > 1) return false; return true; } -std::string Model_AttributeSelection::namingName()//std::shared_ptr theSubShape, - // const ResultPtr& theContext) +std::string Model_AttributeSelection::namingName() { + std::string aName(""); + if(!this->isInitialized()) return aName; + Handle(TDataStd_Name) anAtt; + if(selectionLabel().FindAttribute(TDataStd_Name::GetID(), anAtt)) { + aName = TCollection_AsciiString(anAtt->Get()).ToCString(); + return aName; + } + std::shared_ptr aSubSh = value(); ResultPtr aCont = context(); - std::string aName; + aName = "Undefined name"; if(!aSubSh.get() || aSubSh->isNull() || !aCont.get() || aCont->shape()->isNull()) return aName; TopoDS_Shape aSubShape = aSubSh->impl(); TopoDS_Shape aContext = aCont->shape()->impl(); +#ifdef DEB_NAMING + if(aSubShape.ShapeType() == TopAbs_COMPOUND) { + BRepTools::Write(aSubShape, "Selection.brep"); + BRepTools::Write(aContext, "Context.brep"); + } +#endif std::shared_ptr aDoc = std::dynamic_pointer_cast(aCont->document()); @@ -520,26 +630,35 @@ std::string Model_AttributeSelection::namingName()//std::shared_ptr to be dbugged + // 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_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape + // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces + if (BRep_Tool::Degenerated(TopoDS::Edge(aSubShape))) { + aName = "Degenerated_Edge"; + break; + } 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++) { +/* 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.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; @@ -579,6 +698,7 @@ std::string Model_AttributeSelection::namingName()//std::shared_ptr via edges + TopTools_IndexedDataMapOfShapeListOfShape aMap; + TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap); + const TopTools_ListOfShape& aList22 = aMap.FindFromKey(aSubShape); + if(aList22.Extent() >= 2) { // regular solution +#ifdef FIX_BUG1 + + // bug! duplication; fix is below + aFMap.Clear(); + TopTools_ListOfShape aListE; + TopTools_ListIteratorOfListOfShape itl2(aList22); + for (int i = 1;itl2.More();itl2.Next(),i++) { + if(aFMap.Add(itl2.Value())) + aListE.Append(itl2.Value()); + } + n = aListE.Extent(); +#endif + TopTools_ListIteratorOfListOfShape itl(aListE); + 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; + } + }//reg + else { // dangle vertex: if(aList22.Extent() == 1) + //it should be already in DF + } + } + 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; @@ -620,3 +774,315 @@ std::string Model_AttributeSelection::namingName()//std::shared_ptr theDoc) +{ + TopoDS_Shape aFace; + std::string::size_type n, nb = theSubShapeName.rfind('/'); + if (nb == std::string::npos) nb = 0; + 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; + } else + 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; + } + } + return aFace; +} + +int ParseName(const std::string& theSubShapeName, std::list& theList) +{ + std::string aName = theSubShapeName; + std::string aLastName; + 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); + } + if(!aLastName.empty()) + theList.push_back(aLastName); + return theList.size(); +} + +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); + } + if(theList.Extent() > 2) + aVec.push_back(aMap3); + if(theList.Extent() == 4) + aVec.push_back(aMap4); + + //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()); + } + } + } + //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(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(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; + } + } + } + return aShape; +} + +std::string getContextName(const std::string& theSubShapeName) +{ + std::string aName; + std::string::size_type n = theSubShapeName.find('/'); + if (n == std::string::npos) return aName; + aName = theSubShapeName.substr(0, n); + return aName; +} +// type ::= COMP | COMS | SOLD | SHEL | FACE | WIRE | EDGE | VERT +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::string aContName = getContextName(theSubShapeName); + if(aContName.empty()) return; + //ResultPtr aCont = context(); + ResultPtr aCont = aDoc->findByName(aContName); + if(!aCont.get() || aCont->shape()->isNull()) return; + TopoDS_Shape aContext = aCont->shape()->impl(); + TopAbs_ShapeEnum aContType = aContext.ShapeType(); + if(aType <= aContType) return; // not applicable + + + TopoDS_Shape aSelection; + switch (aType) + { + case TopAbs_COMPOUND: + break; + case TopAbs_COMPSOLID: + break; + case TopAbs_SOLID: + break; + case TopAbs_SHELL: + break; + case TopAbs_FACE: + { + 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); + } + } + break; + case TopAbs_WIRE: + break; + case TopAbs_EDGE: + { + 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()); + aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection)); + setValue(aCont, aShapeToBeSelected); + } + } + break; + case TopAbs_VERTEX: + { + 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()); + aShapeToBeSelected->setImpl(new TopoDS_Shape(aSelection)); + setValue(aCont, aShapeToBeSelected); + } + } + break; + default: //TopAbs_SHAPE + return; + } + +} + +int Model_AttributeSelection::Id() +{ + std::shared_ptr aSelection = value(); + std::shared_ptr aContext = context()->shape(); + const TopoDS_Shape& aMainShape = aContext->impl(); + const TopoDS_Shape& aSubShape = aSelection->impl(); + int anID = 0; + if (aSelection && !aSelection->isNull() && + aContext && !aContext->isNull()) + { + TopTools_IndexedMapOfShape aSubShapesMap; + TopExp::MapShapes(aMainShape, aSubShapesMap); + anID = aSubShapesMap.FindIndex(aSubShape); + } + return anID; +}