X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_AttributeSelection.cpp;h=c672ed47effb8b8299b90ef0563f4d561777d219;hb=383021cb51c4720904096ca851db5ee79255b402;hp=7bc7217dcfca8e0ca54dd9925cdd4771e066e29f;hpb=b8719c144ca530dc497fc4f60ac5cf862d05f97c;p=modules%2Fshaper.git diff --git a/src/Model/Model_AttributeSelection.cpp b/src/Model/Model_AttributeSelection.cpp index 7bc7217dc..c672ed47e 100644 --- a/src/Model/Model_AttributeSelection.cpp +++ b/src/Model/Model_AttributeSelection.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -61,7 +61,7 @@ using namespace std; #ifdef DEB_NAMING #include #endif -/// adeed to the index in the packed map to signalize that the vertex of edge is seleted +/// added to the index in the packed map to signalize that the vertex of edge is selected /// (multiplied by the index of the edge) static const int kSTART_VERTEX_DELTA = 1000000; // identifier that there is simple reference: selection equals to context @@ -98,8 +98,9 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape))); if (isOldShape) return; // shape is the same, so context is also unchanged // update the referenced object if needed - if (!isOldContext) - myRef.setValue(theContext); + if (!isOldContext) { + myRef.setValue(theContext); + } // do noth use naming if selected shape is result shape itself, but not sub-shape TDF_Label aSelLab = selectionLabel(); @@ -180,11 +181,16 @@ void Model_AttributeSelection::setValue(const ResultPtr& theContext, std::shared_ptr Model_AttributeSelection::value() { + GeomShapePtr aResult; if (myTmpContext.get() || myTmpSubShape.get()) { - return myTmpSubShape; + ResultConstructionPtr aResulConstruction = std::dynamic_pointer_cast(myTmpContext); + if(aResulConstruction.get()) { + // it is just reference to construction. + return myTmpSubShape; + } + return myTmpSubShape.get() ? myTmpSubShape : myTmpContext->shape(); } - std::shared_ptr aResult; TDF_Label aSelLab = selectionLabel(); if (aSelLab.IsAttribute(kINVALID_SELECTION)) return aResult; @@ -200,20 +206,27 @@ std::shared_ptr Model_AttributeSelection::value() return aResult; // empty result } if (aSelLab.IsAttribute(kPART_REF_ID)) { - /* TODO: implement used text here ResultPartPtr aPart = std::dynamic_pointer_cast(context()); if (!aPart.get() || !aPart->isActivated()) return std::shared_ptr(); // postponed naming needed Handle(TDataStd_Integer) anIndex; if (selectionLabel().FindAttribute(TDataStd_Integer::GetID(), anIndex)) { - return aPart->selectionValue(anIndex->Get()); - } - Handle(TDataStd_Name) aName; - if (!selectionLabel().FindAttribute(TDataStd_Name::GetID(), aName)) { - return std::shared_ptr(); // something is wrong + if (anIndex->Get()) { // special selection attribute was created, use it + return aPart->selectionValue(anIndex->Get()); + } else { // face with name is already in the data model, so try to take it by name + Handle(TDataStd_Name) aName; + if (selectionLabel().FindAttribute(TDataStd_Name::GetID(), aName)) { + std::string aSubShapeName(TCollection_AsciiString(aName->Get()).ToCString()); + std::size_t aPartEnd = aSubShapeName.find('/'); + if (aPartEnd != string::npos && aPartEnd != aSubShapeName.rfind('/')) { + string aNameInPart = aSubShapeName.substr(aPartEnd + 1); + int anIndex; + std::string aType; // to reuse already existing selection the type is not needed + return aPart->shapeInPart(aNameInPart, aType, anIndex); + } + } + } } - return aPart->shapeInPart(TCollection_AsciiString(aName).ToCString()); - */ } Handle(TNaming_NamedShape) aSelection; @@ -239,7 +252,7 @@ bool Model_AttributeSelection::isInvalid() bool Model_AttributeSelection::isInitialized() { - if (ModelAPI_AttributeSelection::isInitialized()) { // additional checkings if it is initialized + if (ModelAPI_AttributeSelection::isInitialized()) { // additional checks if it is initialized std::shared_ptr aResult; if (myRef.isInitialized()) { TDF_Label aSelLab = selectionLabel(); @@ -312,7 +325,7 @@ void Model_AttributeSelection::setObject(const std::shared_ptr& TDF_LabelMap& Model_AttributeSelection::scope() { if (myScope.IsEmpty()) { // create a new scope if not yet done - // gets all featueres with named shapes that are bofore this feature label (before in history) + // gets all features with named shapes that are before this feature label (before in history) DocumentPtr aMyDoc = owner()->document(); std::list > allFeatures = aMyDoc->allFeatures(); std::list >::iterator aFIter = allFeatures.begin(); @@ -327,11 +340,14 @@ TDF_LabelMap& Model_AttributeSelection::scope() aCompositeOwnerOwner = ModelAPI_Tools::compositeOwner(aCompositeOwner); } } + // for group Scope is not limitet: this is always up to date objects + bool isGroup = aFeature.get() && aFeature->getKind() == "Group"; for(; aFIter != allFeatures.end(); aFIter++) { if (*aFIter == owner()) { // the left features are created later (except subs of composite) aMePassed = true; continue; } + if (isGroup) aMePassed = false; bool isInScope = !aMePassed; if (!isInScope && aComposite.get()) { // try to add sub-elements of composite if this is composite if (aComposite->isSub(*aFIter)) @@ -405,21 +421,37 @@ bool Model_AttributeSelection::update() std::shared_ptr aShape(new GeomAPI_Shape); aShape->setImpl(new TopoDS_Shape(aComp)); selectConstruction(aContext, aShape); + } else { + // For correct naming selection, put the shape into the naming structure. + // It seems sub-shapes are not needed: only this shape is (and can be ) selected. + TNaming_Builder aBuilder(aSelLab); + aBuilder.Generated(aContext->shape()->impl()); + std::shared_ptr aMyDoc = + std::dynamic_pointer_cast(owner()->document()); + std::string aName = aContext->data()->name(); + aMyDoc->addNamingName(aSelLab, aName); + TDataStd_Name::Set(aSelLab, aName.c_str()); } return setInvalidIfFalse(aSelLab, aContext->shape() && !aContext->shape()->isNull()); } if (aSelLab.IsAttribute(kPART_REF_ID)) { // it is reference to the part object std::shared_ptr aNoSelection; - return setInvalidIfFalse(aSelLab, selectPart(aContext, aNoSelection, true)); + bool aResult = selectPart(aContext, aNoSelection, true); + aResult = setInvalidIfFalse(aSelLab, aResult); + if (aResult) { + owner()->data()->sendAttributeUpdated(this); + } + return aResult; } if (aContext->groupName() == ModelAPI_ResultBody::group()) { // body: just a named shape, use selection mechanism from OCCT TNaming_Selector aSelector(aSelLab); bool aResult = aSelector.Solve(scope()) == Standard_True; + aResult = setInvalidIfFalse(aSelLab, aResult); // must be before sending of updated attribute (1556) owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, aResult); + return aResult; } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) { // construction: identification by the results indexes, recompute faces and // take the face that more close by the indexes @@ -449,8 +481,8 @@ bool Model_AttributeSelection::update() return setInvalidIfFalse(aSelLab, false); } - if (aShapeType == TopAbs_FACE) { // compound is for the whole sketch selection - // If this is a wire with plane defined thin it is a sketch-like object + if (aShapeType == TopAbs_FACE || aShapeType == TopAbs_WIRE) { // compound is for the whole sketch selection + // If this is a wire with plane defined then it is a sketch-like object if (!aConstructionContext->facesNum()) // no faces, update can not work correctly return setInvalidIfFalse(aSelLab, false); // if there is no edges indexes, any face can be used: take the first @@ -458,7 +490,7 @@ bool Model_AttributeSelection::update() if (aNoIndexes) { aNewSelected = aConstructionContext->face(0); } else { // searching for most looks-like initial face by the indexes - // prepare edges of the current resut for the fast searching + // prepare edges of the current result for the fast searching NCollection_DataMap allCurves; // curves and orientations of edges const int aSubNum = aComposite->numberOfSubs(); for(int a = 0; a < aSubNum; a++) { @@ -527,9 +559,17 @@ bool Model_AttributeSelection::update() } } if (aNewSelected) { // store this new selection + if (aShapeType == TopAbs_WIRE) { // just get a wire from face to have wire + TopExp_Explorer aWireExp(aNewSelected->impl(), TopAbs_WIRE); + if (aWireExp.More()) { + aNewSelected.reset(new GeomAPI_Shape); + aNewSelected->setImpl(new TopoDS_Shape(aWireExp.Current())); + } + } selectConstruction(aContext, aNewSelected); + setInvalidIfFalse(aSelLab, true); owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, true); + return true; } else { // if the selection is not found, put the empty shape: it's better to have disappeared shape, than the old, the lost one TNaming_Builder anEmptyBuilder(selectionLabel()); return setInvalidIfFalse(aSelLab, false); @@ -549,8 +589,9 @@ bool Model_AttributeSelection::update() std::dynamic_pointer_cast(*aResIter); if (aRes && aRes->shape() && aRes->shape()->isEdge()) { // found! selectConstruction(aContext, aRes->shape()); + setInvalidIfFalse(aSelLab, true); owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, true); + return true; } } } @@ -578,8 +619,9 @@ bool Model_AttributeSelection::update() if (aRes && aRes->shape()) { if (aRes->shape()->isVertex() && aVertexNum == 0) { // found! selectConstruction(aContext, aRes->shape()); + setInvalidIfFalse(aSelLab, true); owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, true); + return true; } else if (aRes->shape()->isEdge() && aVertexNum > 0) { const TopoDS_Shape& anEdge = aRes->shape()->impl(); int aVIndex = 1; @@ -588,8 +630,9 @@ bool Model_AttributeSelection::update() std::shared_ptr aVertex(new GeomAPI_Shape); aVertex->setImpl(new TopoDS_Shape(aVExp.Current())); selectConstruction(aContext, aVertex); + setInvalidIfFalse(aSelLab, true); owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, true); + return true; } aVIndex++; } @@ -601,8 +644,9 @@ bool Model_AttributeSelection::update() } } else { // simple construction element: the selected is that needed selectConstruction(aContext, aContext->shape()); + setInvalidIfFalse(aSelLab, true); owner()->data()->sendAttributeUpdated(this); - return setInvalidIfFalse(aSelLab, true); + return true; } } return setInvalidIfFalse(aSelLab, false); // unknown case @@ -625,7 +669,7 @@ void Model_AttributeSelection::selectBody( if (aResult) { aContext = aResult->shape()->impl(); } else { - Events_Error::send("A result with shape is expected"); + Events_InfoMessage("Model_AttributeSelection", "A result with shape is expected").send(); return; } } @@ -661,6 +705,7 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, if (!theAdditionalName.empty()) aName<GetMap()); for(; aRef.More(); aRef.Next()) { aName<<"-"< aData = std::dynamic_pointer_cast(owner()->data()); TDF_Label aLab = myRef.myRef->Label(); - // identify the reuslts of sub-object of the composite by edges + // identify the results of sub-object of the composite by edges // save type of the selected shape in integer attribute TopAbs_ShapeEnum aShapeType = aSubShape.ShapeType(); TDataStd_Integer::Set(aLab, (int)aShapeType); @@ -826,7 +871,7 @@ bool Model_AttributeSelection::selectPart( } return true; // nothing to do, referencing just by name } - // store the shape (in case part is not loaded it should be usefull + // store the shape (in case part is not loaded it should be useful TopoDS_Shape aShape; std::string aName = theContext->data()->name(); if (!theSubShape.get() || theSubShape->isNull()) {// the whole part shape is selected @@ -873,6 +918,24 @@ void Model_AttributeSelection::selectSubShape( { if(theSubShapeName.empty() || theType.empty()) return; + // check this is Part-name: 2 delimiters in the name + std::size_t aPartEnd = theSubShapeName.find('/'); + if (aPartEnd != string::npos && aPartEnd != theSubShapeName.rfind('/')) { + std::string aPartName = theSubShapeName.substr(0, aPartEnd); + ObjectPtr aFound = owner()->document()->objectByName(ModelAPI_ResultPart::group(), aPartName); + if (aFound.get()) { // found such part, so asking it for the name + ResultPartPtr aPart = std::dynamic_pointer_cast(aFound); + string aNameInPart = theSubShapeName.substr(aPartEnd + 1); + int anIndex; + std::shared_ptr aSelected = aPart->shapeInPart(aNameInPart, theType, anIndex); + if (aSelected.get()) { + setValue(aPart, aSelected); + TDataStd_Integer::Set(selectionLabel(), anIndex); + return; + } + } + } + Model_SelectionNaming aSelNaming(selectionLabel()); std::shared_ptr aDoc = std::dynamic_pointer_cast(owner()->document()); @@ -885,14 +948,29 @@ void Model_AttributeSelection::selectSubShape( int Model_AttributeSelection::Id() { + int anID = 0; std::shared_ptr aSelection = value(); std::shared_ptr aContext = context()->shape(); - const TopoDS_Shape& aMainShape = aContext->impl(); + // support for compsolids: + if (context().get() && ModelAPI_Tools::compSolidOwner(context()).get()) + aContext = ModelAPI_Tools::compSolidOwner(context())->shape(); + + + TopoDS_Shape aMainShape = aContext->impl(); const TopoDS_Shape& aSubShape = aSelection->impl(); - int anID = 0; + // searching for the latest main shape if (aSelection && !aSelection->isNull() && aContext && !aContext->isNull()) { + std::shared_ptr aDoc = + std::dynamic_pointer_cast(context()->document()); + if (aDoc.get()) { + Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aMainShape, aDoc->generalLabel()); + if (!aNS.IsNull()) { + aMainShape = TNaming_Tool::CurrentShape(aNS); + } + } + TopTools_IndexedMapOfShape aSubShapesMap; TopExp::MapShapes(aMainShape, aSubShapesMap); anID = aSubShapesMap.FindIndex(aSubShape);