- don't store names of results in selection to avoid problem on rename of results
- update selection of bodies after something is added in the middle of history that changes the argument
- recompute selection context of the group if it is moved donw
return;
}
- std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
+ std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
+ GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
// Resize planes.
ListOfShape aTools;
GeomShapePtr aResultShape = aPartitionAlgo->shape();
int aResultIndex = 0;
- anObjects.insert(anObjects.end(), aPlanes.begin(), aPlanes.end());
if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
- storeResult(anObjects, anIt.current(), aMakeShapeList, aResultIndex);
+ storeResult(anObjects, aPlanes, anIt.current(), aMakeShapeList, aResultIndex);
++aResultIndex;
}
} else {
- storeResult(anObjects, aResultShape, aMakeShapeList, aResultIndex);
+ storeResult(anObjects, aPlanes, aResultShape, aMakeShapeList, aResultIndex);
++aResultIndex;
}
}
//=================================================================================================
-void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
- const GeomShapePtr theResultShape,
- const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
- const int theIndex)
+void FeaturesPlugin_Partition::storeResult(
+ ListOfShape& theObjects, ListOfShape& thePlanes,
+ const GeomShapePtr theResultShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
+ const int theIndex)
{
- // Find base.
+ // Find base. The most complicated is the real modified object (#1799 if box is partitioned by
+ // two planes the box is the base, not planes, independently on the order in the list).
GeomShapePtr aBaseShape;
for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
GeomShapePtr anObjectShape = *anIt;
- aBaseShape = findBase(anObjectShape, theResultShape, GeomAPI_Shape::VERTEX, theMakeShape);
- if(!aBaseShape.get()) {
- aBaseShape = findBase(anObjectShape, theResultShape, GeomAPI_Shape::EDGE, theMakeShape);
+ GeomShapePtr aCandidate =
+ findBase(anObjectShape, theResultShape, GeomAPI_Shape::VERTEX, theMakeShape);
+ if(!aCandidate.get()) {
+ aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::EDGE, theMakeShape);
}
- if(!aBaseShape.get()) {
- aBaseShape = findBase(anObjectShape, theResultShape, GeomAPI_Shape::FACE, theMakeShape);
- }
- if(aBaseShape.get()) {
- break;
+ if (!aCandidate.get())
+ aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::FACE, theMakeShape);
+
+ if(aCandidate.get()) {
+ if (!aBaseShape.get() || aBaseShape->shapeType() > aCandidate->shapeType()) {
+ aBaseShape = aCandidate;
+ }
}
}
aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
+ theObjects.insert(theObjects.end(), thePlanes.begin(), thePlanes.end());
int anIndex = 1;
for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
GeomShapePtr aShape = *anIt;
private:
/// Stores result of generation.
- void storeResult(const ListOfShape& theObjects,
+ void storeResult(ListOfShape& theObjects,
+ ListOfShape& thePlanes,
const GeomShapePtr theResultShape,
const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
const int theIndex = 0);
#include <TNaming_Tool.hxx>
#include <TNaming_Builder.hxx>
#include <TNaming_Localizer.hxx>
+#include <TNaming_SameShapeIterator.hxx>
+#include <TNaming_Iterator.hxx>
+#include <TNaming_NewShapeIterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <TDataStd_IntPackedMap.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRep_Builder.hxx>
-#include <TNaming_SameShapeIterator.hxx>
-#include <TNaming_Iterator.hxx>
using namespace std;
//#define DEB_NAMING 1
aBuilder.Generated(theContext->shape()->impl<TopoDS_Shape>());
std::shared_ptr<Model_Document> aMyDoc =
std::dynamic_pointer_cast<Model_Document>(owner()->document());
- std::string aName = contextName(theContext);
+ //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());
+ //aMyDoc->addNamingName(aSelLab, aName);
+ //TDataStd_Name::Set(aSelLab, aName.c_str());
} else { // for sketch the naming is needed in DS
BRep_Builder aCompoundBuilder;
TopoDS_Compound aComp;
aBuilder.Generated(aContext->shape()->impl<TopoDS_Shape>());
std::shared_ptr<Model_Document> aMyDoc =
std::dynamic_pointer_cast<Model_Document>(owner()->document());
- std::string aName = contextName(aContext);
- aMyDoc->addNamingName(aSelLab, aName);
- TDataStd_Name::Set(aSelLab, aName.c_str());
+ //std::string aName = contextName(aContext);
+ //aMyDoc->addNamingName(aSelLab, aName);
+ //TDataStd_Name::Set(aSelLab, aName.c_str());
}
return setInvalidIfFalse(aSelLab, aContext->shape() && !aContext->shape()->isNull());
}
if (aContext->groupName() == ModelAPI_ResultBody::group()) {
// body: just a named shape, use selection mechanism from OCCT
TNaming_Selector aSelector(aSelLab);
- TopoDS_Shape anOldShape = aSelector.NamedShape()->Get();
+ TopoDS_Shape anOldShape;
+ if (!aSelector.NamedShape().IsNull()) {
+ anOldShape = aSelector.NamedShape()->Get();
+ }
bool aResult = aSelector.Solve(scope()) == Standard_True;
aResult = setInvalidIfFalse(aSelLab, aResult); // must be before sending of updated attribute (1556)
- if (!anOldShape.IsEqual(aSelector.NamedShape()->Get())) // send updated if shape is changed
+ TopoDS_Shape aNewShape;
+ if (!aSelector.NamedShape().IsNull()) {
+ aNewShape = aSelector.NamedShape()->Get();
+ }
+ if (anOldShape.IsNull() || aNewShape.IsNull() ||
+ !anOldShape.IsEqual(aSelector.NamedShape()->Get())) // send updated if shape is changed
owner()->data()->sendAttributeUpdated(this);
return aResult;
} else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
/// -1 is out, 1 is in, 0 is not needed
static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape,
const int theID, const FeaturePtr& theContextFeature, std::shared_ptr<Model_Document> theDoc,
- std::string theAdditionalName, std::map<int, int>& theOrientations,
+ std::map<int, int>& theOrientations,
std::map<int, std::string>& theSubNames, // name of sub-elements by ID to be exported instead of indexes
Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(),
const int theOrientation = 0)
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();
+ // #1839 : do not store name of the feature in the tree, since this name could be changed
+ //aName<<theContextFeature->name();
if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction
- aName<<"/";
- if (!theAdditionalName.empty())
- aName<<theAdditionalName<<"/";
+ //aName<<"/";
if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face";
else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire";
else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge";
// saving of context is enough: result construction contains exactly the needed shape
TNaming_Builder aBuilder(selectionLabel());
aBuilder.Generated(aSubShape);
- std::string aName = contextName(theContext);
- aMyDoc->addNamingName(selectionLabel(), aName);
- TDataStd_Name::Set(selectionLabel(), aName.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());
int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
anOrientations[anID] = anOrient;
registerSubShape(
- selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, "", anOrientations,
+ selectionLabel(), anEdge, anID, aContextFeature, aMyDoc, anOrientations,
aSubNames, Handle(TDataStd_IntPackedMap)(), anOrient);
}
}
std::stringstream anAdditionalName;
registerSubShape(
- selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, "", anOrientations,
+ selectionLabel(), aV, aTagIndex, aContextFeature, aMyDoc, anOrientations,
aSubNames);
}
}
TNaming_Builder aBuilder(selectionLabel());
aBuilder.Generated(aSubShape);
registerSubShape(
- selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, "", anOrientations, aSubNames, aRefs);
+ selectionLabel(), aSubShape, 0, aContextFeature, aMyDoc, anOrientations, aSubNames, aRefs);
}
bool Model_AttributeSelection::selectPart(
aResult += theContext->data()->name();
return aResult;
}
+
+void Model_AttributeSelection::updateInHistory()
+{
+ ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
+ // only bodies may be modified later in the history, don't do anything otherwise
+ if (!aContext.get() || aContext->groupName() != ModelAPI_ResultBody::group())
+ return;
+ std::shared_ptr<Model_Data> aContData = std::dynamic_pointer_cast<Model_Data>(aContext->data());
+ if (!aContData.get() || !aContData->isValid())
+ return;
+ TDF_Label aContLab = aContData->label(); // named shape where the selected context is located
+ Handle(TNaming_NamedShape) aContNS;
+ if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS))
+ return;
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(aContext->document());
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ FeaturePtr aCurrentModifierFeat = aDoc->feature(aContext);
+ // iterate the context shape modifications in order to find a feature that is upper in history
+ // that this one and is really modifies the referenced result to refer to it
+ ResultPtr aModifierResFound;
+ TNaming_Iterator aPairIter(aContNS);
+ TopoDS_Shape aNewShape = aPairIter.NewShape();
+ bool anIterate = true;
+ // trying to update also the sub-shape selected
+ GeomShapePtr aSubShape = value();
+ if (aSubShape.get() && aSubShape->isEqual(aContext->shape()))
+ aSubShape.reset();
+
+ while(anIterate) {
+ anIterate = false;
+ TNaming_SameShapeIterator aModifIter(aNewShape, aContLab);
+ for(; aModifIter.More(); aModifIter.Next()) {
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (aDoc->objects()->object(aModifIter.Label().Father()));
+ if (!aModifierObj.get())
+ break;
+ FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
+ break;
+ if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ continue; // the modifier feature is later than this, so, should not be used
+ if (aCurrentModifierFeat == aModifierFeat || aDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
+ continue; // the current modifier is later than the found, so, useless
+ Handle(TNaming_NamedShape) aNewNS;
+ aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aModifierResFound = aModifierObj;
+ aCurrentModifierFeat = aModifierFeat;
+ TNaming_Iterator aPairIter(aNewNS);
+ aNewShape = aPairIter.NewShape();
+ /*
+ // searching for sub-shape equivalent on the sub-label of the new context result
+ TDF_ChildIDIterator aNSIter(aNewNS->Label(), TNaming_NamedShape::GetID());
+ for(; aNSIter.More(); aNSIter.Next()) {
+ TNaming_Iterator aPairsIter(aNSIter.Value()->Label());
+ for(; aPairsIter.More(); aPairsIter.Next()) {
+ if (aSubShape->impl<TopoDS_Shape>().IsEqual()
+ }
+ }*/
+ anIterate = true;
+ break;
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ } else { // not-precessed modification => don't support it
+ continue;
+ }
+ }
+
+ /*
+ TNaming_NewShapeIterator aModifIter(aPairIter.NewShape(), aContLab);
+ if (aModifIter.More()) aModifIter.Next(); // skip this shape result
+ for(; aModifIter.More(); aModifIter.Next()) {
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (aDoc->objects()->object(aModifIter.Label().Father()));
+ if (!aModifierObj.get())
+ break;
+ FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
+ break;
+ if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ break; // the modifier feature is later than this, so, should not be used
+ Handle(TNaming_NamedShape) aNewNS = aModifIter.NamedShape();
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aModifierResFound = aModifierObj;
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ } else { // not-precessed modification => don't support it
+ break;
+ }
+ }
+ // already found what is needed, don't iterate the next pair since normally
+ if (aModifierResFound.get()) // there must be only one pair in the result-shape
+ break;
+ */
+ }
+ if (aModifierResFound.get()) {
+ // update scope to reset to a new one
+ myScope.Clear();
+ myRef.setValue(aModifierResFound);
+ update(); // it must recompute a new sub-shape automatically
+ }
+ /*
+ if (aModifierResFound.get()) {
+ // update scope to reset to a new one
+ myScope.Clear();
+ if (!aSubShape.get() || aSubShape->isNull()) { // no sub-shape, so, just update a context
+ setValue(aModifierResFound, aSubShape);
+ return;
+ }
+ // seaching for the same sub-shape: the old topology stays the same
+ TopoDS_Shape anOldShape = aSubShape->impl<TopoDS_Shape>();
+ TopAbs_ShapeEnum aSubType = anOldShape.ShapeType();
+ TopoDS_Shape aNewContext = aModifierResFound->shape()->impl<TopoDS_Shape>();
+ TopExp_Explorer anExp(aNewContext, aSubType);
+ for(; anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsEqual(anOldShape))
+ break;
+ }
+ if (anExp.More()) { // found
+ setValue(aModifierResFound, aSubShape);
+ return;
+ }
+ // seaching for the same sub-shape: equal geometry
+ for(anExp.Init(aNewContext, aSubType); anExp.More(); anExp.Next()) {
+ if (aSubType == TopAbs_VERTEX) {
+
+ }
+ }
+ }*/
+ // if sub-shape selection exists, search also sub-shape new instance
+ /*
+ GeomShapePtr aSubShape = value();
+ if (aSubShape.get() && aSubShape != aContext->shape()) {
+
+ }*/
+}
/// Returns true if recomute of selection become impossible
MODEL_EXPORT virtual bool isInvalid();
+ /// Updates the arguments of selection if something was affected by creation
+ /// or reorder of features upper in the history line (issue #1757)
+ MODEL_EXPORT virtual void updateInHistory();
protected:
/// Objects are created for features automatically
// (if attribute is deleted and created, the abort updates attriute and makes the Attr invalid)
std::shared_ptr<Model_AttributeSelection> aNewAttr =
std::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aLabel));
+ aNewAttr->setID(id());
if (owner()) {
aNewAttr->setObject(owner());
}
friend class Model_AttributeSelection;
friend class Model_AttributeSelectionList;
friend class Model_ValidatorsFactory;
+ friend class Model_SelectionNaming;
public:
/// The simplest constructor. "setLabel" must be called just after to initialize correctly.
// update the feature and the history
clearHistory(theMoved);
// make sure all (selection) attributes of moved feature will be updated
- static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
- ModelAPI_EventCreator::get()->sendUpdated(theMoved, EVENT_UPD);
+ static Events_ID kUpdateSelection = Events_Loop::loop()->eventByName(EVENT_UPDATE_SELECTION);
+ ModelAPI_EventCreator::get()->sendUpdated(theMoved, kUpdateSelection, false);
ModelAPI_EventCreator::get()->sendReordered(theMoved);
}
friend class Model_AttributeReference;
friend class Model_AttributeRefAttr;
friend class Model_AttributeRefList;
+ friend class Model_AttributeSelection;
friend class Model_SelectionNaming;
};
#include "Model_SelectionNaming.h"
#include "Model_Document.h"
#include "Model_Objects.h"
+#include "Model_Data.h"
#include <ModelAPI_Feature.h>
#include <Events_InfoMessage.h>
#include <ModelAPI_Session.h>
std::string Model_SelectionNaming::getShapeName(
std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
- const bool theAddContextName)
+ ResultPtr& theContext, const bool theAnotherDoc, const bool theWholeContext)
{
std::string aName;
+ // add the result name to the name of the shape (it was in BodyBuilder, but did not work on Result rename)
+ bool isNeedContextName = theContext->shape().get() != NULL;// && !theContext->shape()->isEqual(theSubSh);
// check if the subShape is already in DF
Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(theShape, myLab);
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();
- // indexes are added to sub-shapes not primitives (primitives must not be located at the same label)
- if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && theAddContextName) {
- const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(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;
- }
- }
- }
- if (theAddContextName && aName.find("/") == std::string::npos) { // searching for the context object
- for(TDF_Label anObjL = aNS->Label(); anObjL.Depth() > 4; anObjL = anObjL.Father()) {
- int aDepth = anObjL.Depth();
- if (aDepth == 5 || aDepth == 7) {
- ObjectPtr anObj = theDoc->objects()->object(anObjL);
- if (anObj.get()) {
- ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(anObj);
- if (aRes.get()) {
- if (aRes && !aRes->shape()->impl<TopoDS_Shape>().IsEqual(theShape)) {
- aName = anObj->data()->name() + "/" + aName;
- }
- }
+ std::shared_ptr<Model_Data> aData =
+ std::dynamic_pointer_cast<Model_Data>(theContext->data());
+ if (isNeedContextName && aData && aData->label().IsEqual(aNS->Label())) {
+ // do nothing because this context name will be added later in this method
+ } else {
+ aName = TCollection_AsciiString(anAttr->Get()).ToCString();
+ // indexes are added to sub-shapes not primitives (primitives must not be located at the same label)
+ if(!aName.empty() && aNS->Evolution() != TNaming_PRIMITIVE && isNeedContextName) {
+ const TDF_Label& aLabel = aNS->Label();//theDoc->findNamingName(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;
}
}
}
}
}
}
+
+ // Name is empty and this is full context, it just add the whole context name that must be added
+ bool isEmptyName = aName.empty();
+ if (isNeedContextName && (!isEmptyName || theWholeContext)) {
+ aName = theContext->data()->name() + (isEmptyName ? "" : ("/" + aName));
+ if (theAnotherDoc)
+ aName = theContext->document()->kind() + "/" + aName; // PartSet
+ }
return aName;
}
BRepTools::Write(aContext, "Context.brep");
}
#endif
+ aName = getShapeName(aDoc, aSubShape, theContext, theAnotherDoc,
+ theContext->shape()->isEqual(theSubSh));
- // add the result name to the name of the shape (it was in BodyBuilder, but did not work on Result rename)
- bool isNeedContextName = theContext->shape().get() && !theContext->shape()->isEqual(theSubSh);
-
- // check if the subShape is already in DF
- aName = getShapeName(aDoc, aSubShape, isNeedContextName);
if(aName.empty() ) { // not in the document!
TopAbs_ShapeEnum aType = aSubShape.ShapeType();
switch (aType) {
// 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, isNeedContextName);
+ std::string aFaceName = getShapeName(aDoc, aFace, theContext, theAnotherDoc, false);
if(i == 1)
aName = aFaceName;
else
}
TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
for (;itl.More();itl.Next()) {
- std::string aFaceName = getShapeName(aDoc, itl.Value(), isNeedContextName);
+ std::string aFaceName = getShapeName(aDoc, itl.Value(), theContext, theAnotherDoc, false);
aName += "&" + aFaceName;
}
}
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, isNeedContextName);
+ std::string anEdgeName = getShapeName(aDoc, anEdge, theContext, theAnotherDoc, false);
if (anEdgeName.empty()) { // edge is not in DS, trying by faces anyway
isByFaces = true;
aName.clear();
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, isNeedContextName);
+ std::string aFaceName = getShapeName(aDoc, aFace, theContext, theAnotherDoc, false);
if(i == 1)
aName = aFaceName;
else
protected:
/// Gets the stored name from the document
std::string getShapeName(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape& theShape,
- const bool theAddContextName);
+ ResultPtr& theContext, const bool theAnotherDoc, const bool theWholeContext);
};
#endif
#include <Model_Document.h>
#include <Model_Data.h>
#include <Model_Objects.h>
+#include <Model_AttributeSelection.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
aLoop->registerListener(this, kPreviewRequestedEvent);
static const Events_ID kReorderEvent = aLoop->eventByName(EVENT_ORDER_UPDATED);
aLoop->registerListener(this, kReorderEvent);
+ static const Events_ID kUpdatedSel = aLoop->eventByName(EVENT_UPDATE_SELECTION);
+ aLoop->registerListener(this, kUpdatedSel);
// Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
myIsParamUpdated = false;
static const Events_ID kPreviewRequestedEvent = aLoop->eventByName(EVENT_PREVIEW_REQUESTED);
static const Events_ID kReorderEvent = aLoop->eventByName(EVENT_ORDER_UPDATED);
static const Events_ID kRedisplayEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const Events_ID kUpdatedSel = aLoop->eventByName(EVENT_UPDATE_SELECTION);
#ifdef DEB_UPDATE
std::cout<<"****** Event "<<theMessage->eventID().eventText()<<std::endl;
}
return;
}
+ if (theMessage->eventID() == kUpdatedSel) {
+ std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
+ std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
+ updateSelection(aMsg->objects());
+ }
// creation is added to "update" to avoid recomputation twice: on create and immediately after on update
if (theMessage->eventID() == kCreatedEvent) {
std::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
}
}
}
+
+void Model_Update::updateSelection(const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects)
+{
+ std::set<std::shared_ptr<ModelAPI_Object> >::iterator anObj = theObjects.begin();
+ for(; anObj != theObjects.end(); anObj++) {
+ list<AttributePtr> aRefs =
+ (*anObj)->data()->attributes(ModelAPI_AttributeSelection::typeId());
+ list<AttributePtr>::iterator aRefsIter = aRefs.begin();
+ for (; aRefsIter != aRefs.end(); aRefsIter++) {
+ std::shared_ptr<Model_AttributeSelection> aSel =
+ std::dynamic_pointer_cast<Model_AttributeSelection>(*aRefsIter);
+ aSel->updateInHistory();
+ }
+ // update the selection list attributes if any
+ aRefs = (*anObj)->data()->attributes(ModelAPI_AttributeSelectionList::typeId());
+ for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
+ std::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
+ for(int a = aSel->size() - 1; a >= 0; a--) {
+ std::shared_ptr<Model_AttributeSelection> aSelAttr =
+ std::dynamic_pointer_cast<Model_AttributeSelection>(aSel->value(a));
+ if (aSelAttr.get())
+ aSelAttr->updateInHistory();
+ }
+ }
+ }
+}
/// Returns true if theFeature modification was caused by theReason (may be feature of result of this feature)
bool isReason(
std::shared_ptr<ModelAPI_Feature>& theFeature, std::shared_ptr<ModelAPI_Object> theReason);
+
+ /// Updates a selection attributes for the features that possible were affected by creation
+ /// or reorder of features upper in the history line (issue #1757)
+ void updateSelection(const std::set<std::shared_ptr<ModelAPI_Object> >& theObjects);
+
};
#endif
static const char * EVENT_OBJECT_TO_REDISPLAY = "ObjectsToRedisplay";
/// Event ID that plugin is loaded (comes with ModelAPI_ObjectUpdatedMessage)
static const char * EVENT_PLUGIN_LOADED = "PluginLoaded";
-//
+/// The active document becomes another one
static const char * EVENT_DOCUMENT_CHANGED = "CurrentDocumentChanged";
+/// Event ID that order of objects in group is changed, so, tree must be fully rectreated (movement of feature)
+static const char * EVENT_ORDER_UPDATED = "OrderUpdated";
+/// Event ID that the sketch is prepared and all grouped messages for the solver may be flushed
+static const char * EVENT_UPDATE_SELECTION = "UpdateSelection";
+
+/// Request for the enabled/disabled actions behavior for some specific features
static const char * EVENT_FEATURE_STATE_REQUEST = "FeatureStateRequest";
+/// Reply for the enabled/disabled actions behavior for some specific features
static const char * EVENT_FEATURE_STATE_RESPONSE = "FeatureStateResponse";
-
+/// To block the viewer updates
static const char * EVENT_UPDATE_VIEWER_BLOCKED = "UpdateViewerBlocked";
+/// To unblock the viewer updates
static const char * EVENT_UPDATE_VIEWER_UNBLOCKED = "UpdateViewerUnblocked";
+/// To inform that there is an empty presentation in the viewer
static const char * EVENT_EMPTY_AIS_PRESENTATION = "EmptyAISPresentation";
+/// To inform that there is an empty operation for presentation in the viewer
static const char * EVENT_EMPTY_OPERATION_PRESENTATION = "EmptyOperationPresentation";
-
+/// To block preview
static const char * EVENT_PREVIEW_BLOCKED = "PreviewBlocked";
+/// To preview the current feature in the viewer (to compute the result)
static const char * EVENT_PREVIEW_REQUESTED = "PreviewRequested";
/// Event ID that solver has conflicting constraints (comes with ModelAPI_SolverFailedMessage)
/// Event ID that the problem in solver disappeared
static const char * EVENT_SOLVER_REPAIRED = "SolverRepaired";
-/// Event ID that order of objects in group is changed, so, tree must be fully rectreated (movement of feature)
-static const char * EVENT_ORDER_UPDATED = "OrderUpdated";
-
/// Event ID that informs that some object has changed the stability
static const char * EVENT_STABILITY_CHANGED = "StabilityChanged";
for(; aResIter != myResults.end(); aResIter++) {
(*aResIter)->setDisabled(*aResIter, false);
}
+ // update selection for the case something was updated higher in the history
+ // while this feature was disabled
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID kUpdatedSel = aLoop->eventByName(EVENT_UPDATE_SELECTION);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+ aECreator->sendUpdated(data()->owner(), kUpdatedSel, false);
}
return true;
}
{
if (myIsDisabled != theFlag) {
myIsDisabled = theFlag;
- data()->setIsDeleted(theFlag); // store it in data model (t oget back on undo/redo, etc)
+ data()->setIsDeleted(theFlag); // store it in data model (to get back on undo/redo, etc)
// this must be before "updated" message send to have history updated for OB update
document()->updateHistory(groupName()); // to update the history cash data in the document
// generate related events