#include "Model_Data.h"
#include "Model_Document.h"
#include "Model_SelectionNaming.h"
+#include <Model_Objects.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_Tools.h>
#include <GeomAPI_Shape.h>
+#include <ModelAPI_Session.h>
#include <GeomAPI_PlanarEdges.h>
#include <Events_InfoMessage.h>
#include <TDataStd_Name.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Iterator.hxx>
-#include <TNaming_Iterator.hxx>
#include <BRep_Builder.hxx>
+#include <TNaming_SameShapeIterator.hxx>
+#include <TNaming_Iterator.hxx>
+
using namespace std;
//#define DEB_NAMING 1
#ifdef DEB_NAMING
aBuilder.Generated(theContext->shape()->impl<TopoDS_Shape>());
std::shared_ptr<Model_Document> aMyDoc =
std::dynamic_pointer_cast<Model_Document>(owner()->document());
- std::string aName = theContext->data()->name();
+ std::string aName = contextName(theContext);
+ // for selection in different document, add the document name
aMyDoc->addNamingName(aSelLab, aName);
TDataStd_Name::Set(aSelLab, aName.c_str());
} else { // for sketch the naming is needed in DS
//myIsInitialized = true;
owner()->data()->sendAttributeUpdated(this);
-
- std::string aSelName = namingName();
- if(!aSelName.empty())
- TDataStd_Name::Set(selectionLabel(), aSelName.c_str()); //set name
}
std::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
aBuilder.Generated(aContext->shape()->impl<TopoDS_Shape>());
std::shared_ptr<Model_Document> aMyDoc =
std::dynamic_pointer_cast<Model_Document>(owner()->document());
- std::string aName = aContext->data()->name();
+ std::string aName = contextName(aContext);
aMyDoc->addNamingName(aSelLab, aName);
TDataStd_Name::Set(aSelLab, aName.c_str());
}
}
}
}
- aNewSelected = Model_SelectionNaming::findAppropriateFace(aContext, allCurves);
+ aNewSelected = Model_SelectionNaming::findAppropriateFace(
+ aContext, allCurves, aShapeType == TopAbs_WIRE);
}
if (aNewSelected) { // store this new selection
- if (aShapeType == TopAbs_WIRE) { // just get a wire from face to have wire
- TopExp_Explorer aWireExp(aNewSelected->impl<TopoDS_Shape>(), TopAbs_WIRE);
- if (aWireExp.More()) {
- aNewSelected.reset(new GeomAPI_Shape);
- aNewSelected->setImpl<TopoDS_Shape>(new TopoDS_Shape(aWireExp.Current()));
- }
- }
selectConstruction(aContext, aNewSelected);
setInvalidIfFalse(aSelLab, true);
owner()->data()->sendAttributeUpdated(this);
return setInvalidIfFalse(aSelLab, false); // unknown case
}
-
void Model_AttributeSelection::selectBody(
const ResultPtr& theContext, const std::shared_ptr<GeomAPI_Shape>& theSubShape)
{
return;
}
}
- TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl<TopoDS_Shape>() : aContext;
+
+ // with "recover" feature the selected context may be not up to date (issue 1710)
+ Handle(TNaming_NamedShape) aResult;
+ TDF_Label aSelLab = selectionLabel();
+ TopoDS_Shape aNewContext = aContext;
+ bool isUpdated = true;
+ while(!aNewContext.IsNull() && isUpdated) { // searching for the very last shape that was produced from this one
+ isUpdated = false;
+ if (!TNaming_Tool::HasLabel(aSelLab, aNewContext)) // to avoid crash of TNaming_SameShapeIterator if pure shape does not exists
+ break;
+ for(TNaming_SameShapeIterator anIter(aNewContext, aSelLab); anIter.More(); anIter.Next()) {
+ TDF_Label aNSLab = anIter.Label();
+ if (!scope().Contains(aNSLab))
+ continue;
+ Handle(TNaming_NamedShape) aNS;
+ if (aNSLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ for(TNaming_Iterator aShapesIter(aNS); aShapesIter.More(); aShapesIter.Next()) {
+ if (aShapesIter.Evolution() == TNaming_SELECTED)
+ continue; // don't use the selection evolution
+ if (!aShapesIter.OldShape().IsNull() && aShapesIter.OldShape().IsSame(aNewContext)) {
+ // found the original shape
+ aNewContext = aShapesIter.NewShape(); // go to the newer shape
+ isUpdated = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (aNewContext.IsNull()) { // a context is already deleted
+ setInvalidIfFalse(aSelLab, false);
+ Events_InfoMessage("Model_AttributeSelection", "Failed to select shape already deleted").send();
+ return;
+ }
+
+ TopoDS_Shape aNewSub = theSubShape ? theSubShape->impl<TopoDS_Shape>() : aContext;
+ if (!aNewSub.IsEqual(aContext)) { // searching for subshape in the new context
+ bool isFound = false;
+ TopExp_Explorer anExp(aNewContext, aNewSub.ShapeType());
+ for(; anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsEqual(aNewSub)) {
+ isFound = true;
+ break;
+ }
+ }
+ if (!isFound) { // sub-shape is not found in the up-to-date instance of the context shape
+ setInvalidIfFalse(aSelLab, false);
+ Events_InfoMessage("Model_AttributeSelection", "Failed to select sub-shape already modified").send();
+ return;
+ }
+ }
+
+
/// fix for issue 411: result modified shapes must not participate in this selection mechanism
FeaturePtr aFeatureOwner = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
if (aFeatureOwner.get())
aFeatureOwner->eraseResults();
if (!aContext.IsNull()) {
- aSel.Select(aNewShape, aContext);
+ aSel.Select(aNewSub, aNewContext);
}
}
TNaming_Builder aBuilder(aLab);
aBuilder.Generated(theShape);
std::stringstream aName;
+ // add the part name if the selected object is located in other part
+ if (theDoc != theContextFeature->document()) {
+ if (theContextFeature->document() == ModelAPI_Session::get()->moduleDocument()) {
+ aName<<theContextFeature->document()->kind()<<"/";
+ } else {
+ ResultPtr aDocRes = ModelAPI_Tools::findPartResult(
+ ModelAPI_Session::get()->moduleDocument(), theContextFeature->document());
+ if (aDocRes.get()) {
+ aName<<aDocRes->data()->name()<<"/";
+ }
+ }
+ }
aName<<theContextFeature->name();
if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction
aName<<"/";
// 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());
+ std::string aName = contextName(theContext);
+ aMyDoc->addNamingName(selectionLabel(), aName);
+ TDataStd_Name::Set(selectionLabel(), aName.c_str());
return;
}
std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(owner()->data());
std::string aName("");
if(!this->isInitialized())
return !theDefaultName.empty() ? theDefaultName : aName;
- Handle(TDataStd_Name) anAtt;
- if(selectionLabel().FindAttribute(TDataStd_Name::GetID(), anAtt)) {
- aName = TCollection_AsciiString(anAtt->Get()).ToCString();
- return aName;
- }
std::shared_ptr<GeomAPI_Shape> aSubSh = value();
ResultPtr aCont = context();
Model_SelectionNaming aSelNaming(selectionLabel());
- return aSelNaming.namingName(aCont, aSubSh, theDefaultName);
+ return aSelNaming.namingName(
+ aCont, aSubSh, theDefaultName, owner()->document() != aCont->document());
}
// type ::= COMP | COMS | SOLD | SHEL | FACE | WIRE | EDGE | VERT
std::shared_ptr<GeomAPI_Shape> aShapeToBeSelected;
ResultPtr aCont;
if (aSelNaming.selectSubShape(theType, theSubShapeName, aDoc, aShapeToBeSelected, aCont)) {
+ // try to find the last context to find the up to dat shape
+ if (aCont->shape().get() && !aCont->shape()->isNull() &&
+ aCont->groupName() == ModelAPI_ResultBody::group() && aDoc == owner()->document()) {
+ const TopoDS_Shape aConShape = aCont->shape()->impl<TopoDS_Shape>();
+ if (!aConShape.IsNull()) {
+ Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel());
+ if (!aNS.IsNull()) {
+ aNS = TNaming_Tool::CurrentNamedShape(aNS);
+ if (!aNS.IsNull()) {
+ TDF_Label aLab = aNS->Label();
+ while(aLab.Depth() != 7 && aLab.Depth() > 5)
+ aLab = aLab.Father();
+ ObjectPtr anObj = aDoc->objects()->object(aLab);
+ if (anObj.get()) {
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
+ if (aRes)
+ aCont = aRes;
+ }
+ }
+ }
+ }
+ }
setValue(aCont, aShapeToBeSelected);
}
}
setValue(aContext, aSelection);
}
+std::string Model_AttributeSelection::contextName(const ResultPtr& theContext) const
+{
+ std::string aResult;
+ if (owner()->document() != theContext->document()) {
+ if (theContext->document() == ModelAPI_Session::get()->moduleDocument()) {
+ aResult = theContext->document()->kind() + "/";
+ } else {
+ ResultPtr aDocRes = ModelAPI_Tools::findPartResult(
+ ModelAPI_Session::get()->moduleDocument(), theContext->document());
+ if (aDocRes.get()) {
+ aResult = aDocRes->data()->name() + "/";
+ }
+ }
+ }
+ aResult += theContext->data()->name();
+ return aResult;
+}