boost::shared_ptr<Model_Document> aDoc =
boost::dynamic_pointer_cast<Model_Document>(owner()->document());
- if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label()));
+ if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get()));
myRef->Set(aData->label().Father()); // references to the feature label
boost::shared_dynamic_cast<Model_Document>(owner()->document())->objectIsReferenced(theObject);
if (!myIsInitialized) {
myRef = TDF_Reference::Set(theLabel, theLabel); // not initialized references to itself
} else {
+ if (owner()) {
+ boost::shared_ptr<Model_Document> aDoc =
+ boost::dynamic_pointer_cast<Model_Document>(owner()->document());
+ if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get()));
+ }
+ }
+}
+
+void Model_AttributeReference::setObject(const boost::shared_ptr<ModelAPI_Object>& theObject)
+{
+ if (owner() != theObject) {
+ ModelAPI_AttributeReference::setObject(theObject);
boost::shared_ptr<Model_Document> aDoc =
boost::dynamic_pointer_cast<Model_Document>(owner()->document());
- if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Label()));
+ if (aDoc) aDoc->objectIsReferenced(aDoc->object(myRef->Get()));
}
}
{
boost::shared_ptr<Model_Document> aDoc =
boost::dynamic_pointer_cast<Model_Document>(owner()->document());
- if (aDoc) aDoc->objectIsNotReferenced(aDoc->object(myRef->Label()));
+ TDF_Label aLab = myRef->Get();
+ if (aDoc && !aLab.IsNull()) aDoc->objectIsNotReferenced(aDoc->object(myRef->Get()));
}
MODEL_EXPORT ~Model_AttributeReference();
+ MODEL_EXPORT virtual void setObject(const boost::shared_ptr<ModelAPI_Object>& theObject);
+
protected:
/// Objects are created for features automatically
MODEL_EXPORT Model_AttributeReference(TDF_Label& theLabel);
void Model_Document::removeFeature(FeaturePtr theFeature)
{
+ // check the feature: it must have no depended objects on it
+ std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
+ for(; aResIter != theFeature->results().cend(); aResIter++) {
+ if (myConcealedResults.find(*aResIter) != myConcealedResults.end()) {
+ Events_Error::send("Feature '" + theFeature->data()->name() + "' is used and can not be deleted");
+ return;
+ }
+ }
boost::shared_ptr<Model_Data> aData = boost::static_pointer_cast<Model_Data>(theFeature->data());
TDF_Label aFeatureLabel = aData->label().Father();
if (myObjs.IsBound(aFeatureLabel))
myObjs.UnBind(aFeatureLabel);
else
return; // not found feature => do not remove
-
+ // erase fields
+ theFeature->erase();
// erase all attributes under the label of feature
aFeatureLabel.ForgetAllAttributes();
// remove it from the references array
// event: feature is deleted
ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group());
+ /* this is in "erase"
// results of this feature must be redisplayed
static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), aRes->groupName());
}
+ */
}
FeaturePtr Model_Document::feature(TDF_Label& theLabel)
static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
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++) {
boost::shared_ptr<ModelAPI_Result> aRes = *aRIter;
//aRes->setData(boost::shared_ptr<ModelAPI_Data>()); // deleted flag
ModelAPI_EventCreator::get()->sendUpdated(aRes, EVENT_DISP);
ModelAPI_EventCreator::get()->sendDeleted(aThis, aRes->groupName());
}
+ */
// redisplay also removed feature (used for sketch and AISObject)
ModelAPI_EventCreator::get()->sendUpdated(aFeature, EVENT_DISP);
+ aFeature->erase();
} else
aFIter.Next();
}
boost::shared_ptr<ModelAPI_Document> aThis =
Model_Application::getApplication()->getDocument(myID);
ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_ResultBody::group());
+
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+ aECreator->sendUpdated(aResult, EVENT_DISP);
}
}
}
if (aResult) {
std::set<ResultPtr>::iterator aFind = myConcealedResults.find(aResult);
if (aFind != myConcealedResults.end()) {
+ ResultPtr aFeature = *aFind;
myConcealedResults.erase(aFind);
boost::shared_ptr<ModelAPI_Document> aThis =
Model_Application::getApplication()->getDocument(myID);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
- ModelAPI_EventCreator::get()->sendUpdated(*aFind, anEvent, false);
+ ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent, false);
} else {
Events_Error::send(std::string("The object '") + aResult->data()->name() +
"' was not referenced '");
myObjects.insert(theObject);
}
-std::set<ObjectPtr> Model_ObjectUpdatedMessage::objects() const
+const std::set<ObjectPtr>& Model_ObjectUpdatedMessage::objects() const
{
return myObjects;
}
public:
/// Returns the feature that has been updated
- virtual std::set<ObjectPtr> objects() const;
+ virtual const std::set<ObjectPtr>& objects() const;
//! Creates a new empty group (to store it in the loop before flush)
virtual boost::shared_ptr<Events_MessageGroup> newEmpty();
void Model_Session::finishOperation()
{
ROOT_DOC->finishOperation();
+ static boost::shared_ptr<Events_Message> aFinishMsg
+ (new Events_Message(Events_Loop::eventByName("FinishOperation")));
+ Events_Loop::loop()->send(aFinishMsg);
}
void Model_Session::abortOperation()
{
ROOT_DOC->abortOperation();
+ static boost::shared_ptr<Events_Message> anAbortMsg
+ (new Events_Message(Events_Loop::eventByName("AbortOperation")));
+ Events_Loop::loop()->send(anAbortMsg);
}
bool Model_Session::isOperation()
Model_Update MY_INSTANCE; /// the only one instance initialized on load of the library
-Model_Update::Model_Update() : isCreated(false)
+Model_Update::Model_Update()
{
- static const Events_ID kChangedEvent = Events_Loop::loop()->eventByName("PreferenceChanged");
- Events_Loop::loop()->registerListener(this, kChangedEvent);
- static const Events_ID kRebuildEvent = Events_Loop::loop()->eventByName("Rebuild");
- Events_Loop::loop()->registerListener(this, kRebuildEvent);
- Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED));
- Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+ Events_Loop* aLoop = Events_Loop::loop();
+ static const Events_ID kChangedEvent = aLoop->eventByName("PreferenceChanged");
+ aLoop->registerListener(this, kChangedEvent);
+ static const Events_ID kRebuildEvent = aLoop->eventByName("Rebuild");
+ aLoop->registerListener(this, kRebuildEvent);
+ static const Events_ID kCreatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED);
+ aLoop->registerListener(this, kCreatedEvent);
+ static const Events_ID kUpdatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
+ aLoop->registerListener(this, kUpdatedEvent);
+ static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
+ aLoop->registerListener(this, kOpFinishEvent);
+ static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
+ aLoop->registerListener(this, kOpAbortEvent);
+
Config_PropManager::registerProp("Model update", "automatic_rebuild", "Rebuild automatically",
Config_Prop::Bool, "false");
isAutomatic = Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
void Model_Update::processEvent(const boost::shared_ptr<Events_Message>& theMessage)
{
- static const Events_ID kChangedEvent = Events_Loop::loop()->eventByName("PreferenceChanged");
- static const Events_ID kRebuildEvent = Events_Loop::loop()->eventByName("Rebuild");
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static const Events_ID kChangedEvent = aLoop->eventByName("PreferenceChanged");
+ static const Events_ID kRebuildEvent = aLoop->eventByName("Rebuild");
+ static const Events_ID kCreatedEvent = aLoop->eventByName(EVENT_OBJECT_CREATED);
+ static const Events_ID kUpdatedEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED);
+ static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
+ static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
bool isAutomaticChanged = false;
if (theMessage->eventID() == kChangedEvent) { // automatic and manual rebuild flag is changed
isAutomatic =
isAutomaticChanged = true;
isAutomatic = true;
}
+ } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent) {
+ boost::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
+ boost::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
+ const std::set<ObjectPtr>& anObjs = aMsg->objects();
+ std::set<ObjectPtr>::const_iterator anObjIter = anObjs.cbegin();
+ for(; anObjIter != anObjs.cend(); anObjIter++)
+ myJustCreatedOrUpdated.insert(*anObjIter);
+ } else if (theMessage->eventID() == kOpFinishEvent || theMessage->eventID() == kOpAbortEvent) {
+ myJustCreatedOrUpdated.clear();
+ return;
}
if (isExecuted)
return; // nothing to do: it is executed now
- // execute just created features anyway
- isCreated = theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_CREATED);
//Events_LongOp::start(this);
isExecuted = true;
}
myUpdated.clear();
// flush
- static Events_ID EVENT_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
- Events_Loop::loop()->flush(EVENT_DISP);
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ aLoop->flush(EVENT_DISP);
//Events_LongOp::end(this);
if (isAutomaticChanged) isAutomatic = false;
- isCreated = false;
isExecuted = false;
}
!theFeature->isPersistentResult()) {
ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
if (aFactory->validate(theFeature)) {
- if (isAutomatic || (isCreated && myInitial.find(theFeature) != myInitial.end()) ||
+ if (isAutomatic || (myJustCreatedOrUpdated.find(theFeature) != myJustCreatedOrUpdated.end()) ||
!theFeature->isPersistentResult() /* execute quick, not persistent results */) {
try {
theFeature->execute();
- theFeature->data()->mustBeUpdated(false);
} catch(...) {
Events_Error::send(
"Feature " + theFeature->getKind() + " has failed during the execution");
theFeature->eraseResults();
}
+ theFeature->data()->mustBeUpdated(false);
+ 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;
+ aRes->data()->mustBeUpdated(false);
+ }
} else {
theFeature->data()->mustBeUpdated(true);
+ 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;
+ aRes->data()->mustBeUpdated(true);
+ }
aMustbeUpdated = false;
}
} else {
bool isExecuted;
/// to know execute or not automatically all update
bool isAutomatic;
- /// execute just created features for sure
- bool isCreated;
+ /// just created features: they must be updated immideately even in not-automatic mode for
+ /// preview; cleared on commit operations
+ std::set<boost::shared_ptr<ModelAPI_Object> > myJustCreatedOrUpdated;
public:
/// Is called only once, on startup of the application
}
/// Sets the owner of this attribute
- MODELAPI_EXPORT void setObject(const boost::shared_ptr<ModelAPI_Object>& theObject)
+ MODELAPI_EXPORT virtual void setObject(const boost::shared_ptr<ModelAPI_Object>& theObject)
{
myObject = theObject;
}
public:
/// Returns the feature that has been updated
- virtual std::set<ObjectPtr> objects() const = 0;
+ virtual const std::set<ObjectPtr>& objects() const = 0;
//! Creates a new empty group (to store it in the loop before flush)
virtual boost::shared_ptr<Events_MessageGroup> newEmpty() = 0;
{
std::list<boost::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
for(; aResIter != myResults.end(); aResIter++) {
- if (*aResIter == theResult) {
- std::string aGroup = (*aResIter)->groupName();
- (*aResIter)->data()->erase();
+ ResultPtr aRes = *aResIter;
+ if (aRes == theResult) {
+ std::string aGroup = aRes->groupName();
+ aRes->data()->erase();
myResults.erase(aResIter);
+
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
ModelAPI_EventCreator::get()->sendDeleted(document(), aGroup);
+ aECreator->sendUpdated(aRes, EVENT_DISP);
break;
}
}
void ModelAPI_Feature::eraseResults()
{
if (!myResults.empty()) {
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+
std::list<boost::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
for(; aResIter != myResults.end(); aResIter++) {
- (*aResIter)->data()->erase();
- ModelAPI_EventCreator::get()->sendDeleted(document(), (*aResIter)->groupName());
+ (*aResIter)->data()->erase();
+ ModelAPI_EventCreator::get()->sendDeleted(document(), (*aResIter)->groupName());
+ aECreator->sendUpdated(*aResIter, EVENT_DISP);
}
myResults.clear();
// flush it to avoid left presentations after input of invalid arguments (radius=0)
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
Events_Loop::loop()->flush(anEvent);
}
}
return ModelAPI_Session::get()->activeDocument();
}
-ModelAPI_Feature::~ModelAPI_Feature()
+void ModelAPI_Feature::erase()
{
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+
while (!myResults.empty()) { // remove one by one with messages
boost::shared_ptr<ModelAPI_Result> aRes = *(myResults.begin());
myResults.erase(myResults.begin());
- ModelAPI_EventCreator::get()->sendDeleted(aRes->document(), aRes->groupName());
+ aECreator->sendDeleted(aRes->document(), aRes->groupName());
+ aECreator->sendUpdated(aRes, EVENT_DISP);
}
+ ModelAPI_Object::erase();
+}
+
+ModelAPI_Feature::~ModelAPI_Feature()
+{
+ erase();
}
FeaturePtr ModelAPI_Feature::feature(ObjectPtr theObject)
MODELAPI_EXPORT void removeResult(const boost::shared_ptr<ModelAPI_Result>& theResult);
/// removes all results from the feature
MODELAPI_EXPORT void eraseResults();
+ /// removes all fields from this feature: results, data, etc
+ MODELAPI_EXPORT virtual void erase();
/// Returns true if result is persistent (stored in document) and on undo-redo, save-open
/// it is not needed to recompute it.
#define ModelAPI_Object_H_
#include "ModelAPI.h"
+#include "ModelAPI_Data.h"
#include <boost/shared_ptr.hpp>
myDoc = theDoc;
}
+ /// removes all fields from this feature
+ MODELAPI_EXPORT virtual void erase() {
+ if (myData) myData->erase();
+ setData(DataPtr());
+ }
+
friend class Model_Document;
+
};
typedef boost::shared_ptr<ModelAPI_Object> ObjectPtr;
bool isAllValid = true;
bool isCCRemoved = false; // indicates that at least one of coincidence constraints was removed
while (isAllValid && aConstrIter != myConstraintMap.rend()) {
- if (!aConstrIter->first->data()->isValid()) {
+ if (!aConstrIter->first->data() || !aConstrIter->first->data()->isValid()) {
if (aConstrIter->first->getKind().compare(SketchPlugin_ConstraintCoincidence::ID()) == 0)
isCCRemoved = true;
std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>::reverse_iterator aCopyIter =
/// \brief Check for valid sketch data
inline bool isWorkplaneValid() const
{
- return mySketch->data()->isValid();
+ return mySketch->data() && mySketch->data()->isValid();
}
/** \brief Adds or updates a constraint in the group
{
//Get operation feature to validate
FeaturePtr aFeature = theOperation->feature();
+ if (!aFeature) return true; // rename operation
//Get validators for the Id
SessionPtr aMgr = ModelAPI_Session::get();
ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
case ConstructFolder:
return QIcon(":pictures/constr_folder.png");
case ConstructObject:
- case BodiesObject:
+ case BodiesObject: {
+ DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+ std::string aGroup = theIndex.internalId() == ConstructObject ?
+ ModelAPI_ResultConstruction::group() : ModelAPI_ResultBody::group();
+ ObjectPtr anObject = aRootDoc->object(aGroup, theIndex.row());
+ if (anObject && anObject->data() && anObject->data()->mustBeUpdated()) {
+ return QIcon(":pictures/constr_object_modified.png");
+ }
return QIcon(":pictures/constr_object.png");
+ }
}
break;
case BodiesFolder:
return QIcon(":pictures/constr_folder.png");
case ConstructObject:
- case BodiesObject:
+ case BodiesObject: {
+ std::string aGroup = theIndex.internalId() == ConstructObject ?
+ ModelAPI_ResultConstruction::group() : ModelAPI_ResultBody::group();
+ ObjectPtr anObject = partDocument()->object(aGroup, theIndex.row());
+ if (anObject && anObject->data() && anObject->data()->mustBeUpdated()) {
+ return QIcon(":pictures/constr_object_modified.png");
+ }
return QIcon(":pictures/constr_object.png");
+ }
case HistoryObject: {
ObjectPtr aObject = partDocument()->object(ModelAPI_Feature::group(), theIndex.row() - 3);
FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(aObject);
<file>pictures/params_folder.png</file>
<file>pictures/constr_folder.png</file>
<file>pictures/constr_object.png</file>
+ <file>pictures/constr_object_modified.png</file>
<file>pictures/part_ico.png</file>
<file>pictures/properties.png</file>
<file>pictures/features.png</file>