return Model_Application::getApplication()->getDocument(theDocID);
}
-ObjectPtr Model_Document::object(const std::string& theGroupID, const int theIndex)
+ObjectPtr Model_Document::object(const std::string& theGroupID,
+ const int theIndex, const bool theHidden)
{
if (theGroupID == ModelAPI_Feature::group()) {
- Handle(TDataStd_ReferenceArray) aRefs;
- if (!featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
- return ObjectPtr();
- if (aRefs->Lower() > theIndex || aRefs->Upper() < theIndex)
- return ObjectPtr();
- TDF_Label aFeatureLabel = aRefs->Value(theIndex);
- return feature(aFeatureLabel);
+ if (theHidden) {
+ int anIndex = 0;
+ TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID());
+ for(; aLabIter.More(); aLabIter.Next()) {
+ if (theIndex == anIndex) {
+ TDF_Label aFLabel = aLabIter.Value()->Label();
+ return feature(aFLabel);
+ }
+ anIndex++;
+ }
+ } else {
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (!featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return ObjectPtr();
+ if (aRefs->Lower() > theIndex || aRefs->Upper() < theIndex)
+ return ObjectPtr();
+ TDF_Label aFeatureLabel = aRefs->Value(theIndex);
+ return feature(aFeatureLabel);
+ }
} else {
// comment must be in any feature: it is kind
int anIndex = 0;
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
for(; aRIter != aResults.cend(); aRIter++) {
- if ((*aRIter)->isInHistory() && (*aRIter)->groupName() == theGroupID) {
+ if ((theHidden || (*aRIter)->isInHistory()) && (*aRIter)->groupName() == theGroupID) {
if (anIndex == theIndex)
return *aRIter;
anIndex++;
return ObjectPtr();
}
-int Model_Document::size(const std::string& theGroupID)
+int Model_Document::size(const std::string& theGroupID, const bool theHidden)
{
int aResult = 0;
if (theGroupID == ModelAPI_Feature::group()) {
- Handle(TDataStd_ReferenceArray) aRefs;
- if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
- return aRefs->Length();
+ if (theHidden) {
+ return myObjs.Size();
+ } else {
+ Handle(TDataStd_ReferenceArray) aRefs;
+ if (featuresLabel().FindAttribute(TDataStd_ReferenceArray::GetID(), aRefs))
+ return aRefs->Length();
+ }
} else {
// comment must be in any feature: it is kind
TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID());
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
for(; aRIter != aResults.cend(); aRIter++) {
- if ((*aRIter)->isInHistory() && (*aRIter)->groupName() == theGroupID) {
+ if ((theHidden || (*aRIter)->isInHistory()) && (*aRIter)->groupName() == theGroupID) {
aResult++;
}
}
boost::shared_ptr<ModelAPI_Document> aThis =
Model_Application::getApplication()->getDocument(myID);
// update all objects by checking are they of labels or not
- std::set<FeaturePtr> aCheckedFeatures;
+ std::set<FeaturePtr> aNewFeatures, aKeptFeatures;
TDF_ChildIDIterator aLabIter(featuresLabel(), TDataStd_Comment::GetID());
for(; aLabIter.More(); aLabIter.Next()) {
TDF_Label aFeatureLabel = aLabIter.Value()->Label();
.ToCString());
// this must be before "setData" to redo the sketch line correctly
myObjs.Bind(aFeatureLabel, aNewObj);
- aCheckedFeatures.insert(aNewObj);
+ aNewFeatures.insert(aNewObj);
initData(aNewObj, aFeatureLabel, TAG_FEATURE_ARGUMENTS);
- aNewObj->execute(); // to restore results list
// event: model is updated
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
ModelAPI_EventCreator::get()->sendUpdated(aNewObj, anEvent);
// feature for this label is added, so go to the next label
} else { // nothing is changed, both iterators are incremented
- aCheckedFeatures.insert(myObjs.Find(aFeatureLabel));
+ aKeptFeatures.insert(myObjs.Find(aFeatureLabel));
if (theMarkUpdated) {
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(myObjs.Find(aFeatureLabel), anEvent);
}
}
}
+ // execute new features to restore results: after features creation to make all references valid
+ /*std::set<FeaturePtr>::iterator aNewIter = aNewFeatures.begin();
+ for(; aNewIter != aNewFeatures.end(); aNewIter++) {
+ (*aNewIter)->execute();
+ }*/
// check all features are checked: if not => it was removed
NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFIter(myObjs);
while(aFIter.More()) {
- if (aCheckedFeatures.find(aFIter.Value()) == aCheckedFeatures.end()) {
+ if (aKeptFeatures.find(aFIter.Value()) == aKeptFeatures.end() &&
+ aNewFeatures.find(aFIter.Value()) == aNewFeatures.end()) {
FeaturePtr aFeature = aFIter.Value();
TDF_Label aLab = aFIter.Key();
aFIter.Next();
//! \param theGroupID group that contains a feature
//! \param theIndex zero-based index of feature in the group
//! \param isOperation if it is true, returns feature (not Object)
- MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID, const int theIndex);
+ //! \param theHidden if it is true, it counts also the features that are not in tree
+ MODEL_EXPORT virtual ObjectPtr object(const std::string& theGroupID, const int theIndex,
+ const bool theHidden = false);
//! Returns the number of features in the group
- MODEL_EXPORT virtual int size(const std::string& theGroupID);
+ //! If theHidden is true, it counts also the features that are not in tree
+ MODEL_EXPORT virtual int size(const std::string& theGroupID, const bool theHidden = false);
/// Creates a construction cresults
MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_ResultConstruction> createConstruction(
Model_Update::Model_Update()
{
+ Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
}
for(; aFIter != myInitial.end(); aFIter++) {
aDocs.insert((*aFIter)->document());
}
- // iterate all features of features-documents to update them
+ // iterate all features of features-documents to update them (including hidden)
set<boost::shared_ptr<ModelAPI_Document> >::iterator aDIter = aDocs.begin();
for(; aDIter != aDocs.end(); aDIter++) {
- int aNbFeatures = (*aDIter)->size(ModelAPI_Feature::group());
+ int aNbFeatures = (*aDIter)->size(ModelAPI_Feature::group(), true);
for(int aFIndex = 0; aFIndex < aNbFeatures; aFIndex++) {
- boost::shared_ptr<ModelAPI_Object> aFeature = boost::dynamic_pointer_cast<ModelAPI_Object>
- ((*aDIter)->object(ModelAPI_Feature::group(), aFIndex));
+ FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>
+ ((*aDIter)->object(ModelAPI_Feature::group(), aFIndex, true));
if (aFeature)
- updateObject(aFeature);
+ updateFeature(aFeature);
}
}
myUpdated.clear();
Events_Loop::loop()->flush(EVENT_DISP);
}
-bool Model_Update::updateObject(boost::shared_ptr<ModelAPI_Object> theObject)
+bool Model_Update::updateFeature(FeaturePtr theFeature)
{
// check it is already processed
- if (myUpdated.find(theObject) != myUpdated.end())
- return myUpdated[theObject];
+ if (myUpdated.find(theFeature) != myUpdated.end())
+ return myUpdated[theFeature];
// check all features this feature depended on (recursive call of updateFeature)
- bool anExecute = myInitial.find(theObject) != myInitial.end();
- bool aMustbeUpdated = myInitial.find(theObject) != myInitial.end();
- FeaturePtr aRealFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
- if (aRealFeature) { // only real feature contains references to other objects
+ bool aMustbeUpdated = myInitial.find(theFeature) != myInitial.end();
+ if (theFeature) { // only real feature contains references to other objects
// references
list<boost::shared_ptr<ModelAPI_Attribute> > aRefs =
- theObject->data()->attributes(ModelAPI_AttributeReference::type());
+ theFeature->data()->attributes(ModelAPI_AttributeReference::type());
list<boost::shared_ptr<ModelAPI_Attribute> >::iterator aRefsIter = aRefs.begin();
for(; aRefsIter != aRefs.end(); aRefsIter++) {
boost::shared_ptr<ModelAPI_Object> aSub =
boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(*aRefsIter)->value();
- if (aSub && aSub != theObject && updateObject(aSub))
+ if (updateObject(aSub)) {
aMustbeUpdated = true;
+ }
}
// lists of references
- aRefs = theObject->data()->attributes(ModelAPI_AttributeRefList::type());
+ aRefs = theFeature->data()->attributes(ModelAPI_AttributeRefList::type());
for(aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
list<ObjectPtr> aListRef =
boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*aRefsIter)->list();
list<ObjectPtr>::iterator aListIter = aListRef.begin();
for(; aListIter != aListRef.end(); aListIter++) {
boost::shared_ptr<ModelAPI_Object> aSub = *aListIter;
- if (aSub && updateObject(aSub))
+ if (updateObject(aSub)) {
aMustbeUpdated = true;
+ }
}
}
// execute feature if it must be updated
- anExecute = aMustbeUpdated || anExecute;
- if (anExecute) {
- aRealFeature->execute();
+ if (aMustbeUpdated) {
+ theFeature->execute();
// redisplay all results
static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
- const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aRealFeature->results();
+ const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
for(; aRIter != aResults.cend(); aRIter++) {
boost::shared_ptr<ModelAPI_Result> aRes = *aRIter;
+ myUpdated[aRes] = true;
ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
}
+ } else { // returns also true is results were updated: for sketch that refers to sub-features but results of sub-features were changed
+ const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
+ std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
+ for(; aRIter != aResults.cend(); aRIter++) {
+ if (myInitial.find(*aRIter) != myInitial.end()) {
+ aMustbeUpdated = true;
+ break;
+ }
+ }
+ }
+ }
+ myUpdated[theFeature] = aMustbeUpdated;
+ return aMustbeUpdated;
+}
+
+bool Model_Update::updateObject(boost::shared_ptr<ModelAPI_Object> theObject)
+{
+ if (!theObject)
+ return false;
+ FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
+ if (aFeature) { // for feature just call update Feature
+ return updateFeature(aFeature);
+ }
+ // check general object, possible just a result
+ if (myUpdated.find(theObject) != myUpdated.end())
+ return myUpdated[theObject]; // already processed
+ // check the feature of this object must be executed
+ ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ if (aResult) {
+ FeaturePtr aResFeature = aResult->document()->feature(aResult);
+ if (aResFeature) {
+ return updateFeature(aResFeature);
}
}
- myUpdated[theObject] = anExecute;
- return anExecute;
+ if (myInitial.find(theObject) != myInitial.end())
+ return true;
+ return false; // nothing is known
}
MODEL_EXPORT virtual void processEvent(const Events_Message* theMessage);
protected:
- /// Recoursively checks and updates the object if needed
+ /// Recoursively checks and updates the feature if needed (calls the execute method)
+ /// Returns true if feature was updated.
+ bool updateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
+ /// Recoursively checks and updates the object (result or feature) if needed (calls updateFeature)
/// Returns true if object was updated.
bool updateObject(boost::shared_ptr<ModelAPI_Object> theObject);
};
//! Returns the object in the group by the index (started from zero)
//! \param theGroupID group that contains an object
//! \param theIndex zero-based index of feature in the group
+ //! \param theHidden if it is true, it counts also the features that are not in tree
virtual boost::shared_ptr<ModelAPI_Object>
- object(const std::string& theGroupID, const int theIndex) = 0;
+ object(const std::string& theGroupID, const int theIndex, const bool theHidden = false) = 0;
//! Returns the number of objects in the group of objects
- virtual int size(const std::string& theGroupID) = 0;
+ //! If theHidden is true, it counts also the features that are not in tree
+ virtual int size(const std::string& theGroupID, const bool theHidden = false) = 0;
/// To virtually destroy the fields of successors
virtual ~ModelAPI_Document() {}
Events_Loop::loop()->flush(anEvent);
}
+void ModelAPI_Feature::setResult(
+ const boost::shared_ptr<ModelAPI_Result>& theResult, const int theIndex)
+{
+ std::list<boost::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
+ for(int anIndex = 0; anIndex < theIndex; anIndex++) {
+ aResIter++;
+ }
+ if (aResIter == myResults.end()) { // append
+ myResults.push_back(theResult);
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+ ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
+ // Create event for first Feature, send it to make "created" earlier than "updated"
+ Events_Loop::loop()->flush(anEvent);
+ } else { // update
+ *aResIter = theResult;
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent);
+ }
+}
+
boost::shared_ptr<ModelAPI_Document> ModelAPI_Feature::documentToAdd()
{
return ModelAPI_PluginManager::get()->currentDocument();
MODELAPI_EXPORT boost::shared_ptr<ModelAPI_Result> firstResult();
/// sets the alone result
MODELAPI_EXPORT void setResult(const boost::shared_ptr<ModelAPI_Result>& theResult);
+ /// sets the result by index (zero based), results before this must be set before
+ MODELAPI_EXPORT void setResult(
+ const boost::shared_ptr<ModelAPI_Result>& theResult, const int theIndex);
/// Returns true if this feature must not be created: this is just an action
/// that is not stored in the features history and data model (like "delete part").
boost::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
// make a visible point
boost::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
- aShapes.push_back(aCenterPointShape);
+ //aShapes.push_back(aCenterPointShape);
+ boost::shared_ptr<ModelAPI_ResultConstruction> aConstr1 =
+ document()->createConstruction(data());
+ aConstr1->setShape(aCenterPointShape);
+ aConstr1->setIsInHistory(false);
+ setResult(aConstr1, 0);
// make a visible circle
boost::shared_ptr<GeomDataAPI_Dir> aNDir =
boost::shared_ptr<GeomAPI_Shape> aCircleShape =
GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aRadius);
aShapes.push_back(aCircleShape);
+ boost::shared_ptr<ModelAPI_ResultConstruction> aConstr2 =
+ document()->createConstruction(data());
+ aConstr2->setShape(aCircleShape);
+ aConstr2->setIsInHistory(false);
+ setResult(aConstr2, 1);
}
}
+ /*
boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
// store the result
boost::shared_ptr<ModelAPI_ResultConstruction> aConstr =
aConstr->setShape(aCompound);
aConstr->setIsInHistory(false);
setResult(aConstr);
+ */
}
}