#include "Model_AttributeDouble.h"
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
+#include <ModelAPI_Events.h>
#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
if (myText->Get() != aValue) {
myText->Set(aValue);
owner()->data()->sendAttributeUpdated(this);
+ // Send it to evaluator to convert into the double and store in the attribute
+ static Events_ID anId = ModelAPI_AttributeEvalMessage::eventId();
+ std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
+ std::shared_ptr<ModelAPI_AttributeEvalMessage>(new ModelAPI_AttributeEvalMessage(anId, this));
+ aMessage->setAttribute(owner()->data()->attribute(id())); // to get shared pointer to this
+ Events_Loop::loop()->send(aMessage);
}
}
bool Model_AttributeDouble::expressionInvalid()
{
- return myReal->Label().IsAttribute(kInvalidGUID);
+ return myReal->Label().IsAttribute(kInvalidGUID) == Standard_True;
}
owner()->data()->sendAttributeUpdated(this);
}
+void Model_AttributeRefList::clear()
+{
+ std::list<ObjectPtr> anOldList = list();
+ myRef->Clear();
+ std::list<ObjectPtr>::iterator anOldIter = anOldList.begin();
+ for(; anOldIter != anOldList.end(); anOldIter++) {
+ REMOVE_BACK_REF((*anOldIter));
+ }
+}
+
int Model_AttributeRefList::size() const
{
return myRef->Extent();
/// Returns number of features in the list
MODEL_EXPORT virtual int size() const;
+ /// Removes all references from the list
+ MODEL_EXPORT virtual void clear();
+
/// Returns the list of features
MODEL_EXPORT virtual std::list<ObjectPtr> list();
isOperationChanged = true;
}
if (isOperationChanged) {
- // remove all macros before clearing all created
+ // remove all macros before clearing all created and execute all not-previewed
std::set<ObjectPtr>::iterator aCreatedIter = myJustCreated.begin();
- for(; aCreatedIter != myJustCreated.end(); aCreatedIter++) {
- FeaturePtr aFeature =
- std::dynamic_pointer_cast<ModelAPI_Feature>(*aCreatedIter);
+ std::set<ObjectPtr>::iterator anUpdatedIter = myJustUpdated.begin();
+ for(; aCreatedIter != myJustCreated.end() || anUpdatedIter != myJustUpdated.end();
+ aCreatedIter == myJustCreated.end() ? anUpdatedIter++ : aCreatedIter++) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*
+ (aCreatedIter == myJustCreated.end() ? anUpdatedIter : aCreatedIter));
if (aFeature.get()) {
// execute not-previewed feature on "apply"
if (!aFeature->isPreviewNeeded() && (myJustCreated.find(aFeature) != myJustCreated.end() ||
for(; aDoubleIter != aDoubles.end(); aDoubleIter++) {
AttributeDoublePtr aDouble =
std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(*aDoubleIter);
- if (aDouble.get() && aDouble->expressionInvalid()) {
- aState = ModelAPI_StateInvalidArgument;
+ if (aDouble.get() && !aDouble->text().empty()) {
+ if (aDouble->expressionInvalid()) {
+ aState = ModelAPI_StateInvalidArgument;
+ }
}
}
//std::cout<<"Update feature "<<theFeature->getKind()<<" must be updated = "<<aMustbeUpdated<<std::endl;
// execute feature if it must be updated
if (aJustUpdated) {
- if ((std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
- !theFeature->isPersistentResult()) && theFeature->isPreviewNeeded()) {
- if (aFactory->validate(theFeature)) {
- if (myIsAutomatic || !theFeature->isPersistentResult() /* execute quick, not persistent results */
- || (isUpdated(theFeature) &&
- theFeature == theFeature->document()->currentFeature(false))) // currently edited
- {
- if (aState == ModelAPI_StateDone || aState == ModelAPI_StateMustBeUpdated) {
- executeFeature(theFeature);
- }
- } else { // must be updatet, but not updated yet
- theFeature->data()->execState(ModelAPI_StateMustBeUpdated);
- const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
- for (; aRIter != aResults.cend(); aRIter++) {
- std::shared_ptr<ModelAPI_Result> aRes = *aRIter;
- aRes->data()->execState(ModelAPI_StateMustBeUpdated);
+ if (theFeature->isPreviewNeeded()) {
+ if (std::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
+ !theFeature->isPersistentResult()) {
+ if (aFactory->validate(theFeature)) {
+ if (myIsAutomatic || !theFeature->isPersistentResult() /* execute quick, not persistent results */
+ || (isUpdated(theFeature) &&
+ theFeature == theFeature->document()->currentFeature(false))) // currently edited
+ {
+ if (aState == ModelAPI_StateDone || aState == ModelAPI_StateMustBeUpdated) {
+ executeFeature(theFeature);
+ }
+ } else { // must be updatet, but not updated yet
+ theFeature->data()->execState(ModelAPI_StateMustBeUpdated);
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = theFeature->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
+ for (; aRIter != aResults.cend(); aRIter++) {
+ std::shared_ptr<ModelAPI_Result> aRes = *aRIter;
+ aRes->data()->execState(ModelAPI_StateMustBeUpdated);
+ }
}
+ } else {
+ theFeature->eraseResults();
+ redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
}
- } else {
- theFeature->eraseResults();
- redisplayWithResults(theFeature, ModelAPI_StateInvalidArgument); // result also must be updated
+ } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
+ redisplayWithResults(theFeature, ModelAPI_StateNothing);
}
- } else { // for automatically updated features (on abort, etc) it is necessary to redisplay anyway
- redisplayWithResults(theFeature, ModelAPI_StateNothing);
+ } else { // preview is not needed => make state Done
+ if (theFeature->data()->execState() == ModelAPI_StateMustBeUpdated)
+ theFeature->data()->execState(ModelAPI_StateDone);
}
}
}
/// Erases the first meet of the feature in the list
MODELAPI_EXPORT virtual void remove(ObjectPtr theObject) = 0;
+ /// Removes all references from the list
+ MODELAPI_EXPORT virtual void clear() = 0;
+
/// Returns number of features in the list
MODELAPI_EXPORT virtual int size() const = 0;
return theResult->shape();
}
-bool findVariable(const std::string& theName, double& outValue)
+bool findVariable(const std::string& theName, double& outValue, ResultParameterPtr& theParam)
{
SessionPtr aSession = ModelAPI_Session::get();
std::list<DocumentPtr> aDocList;
}
for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
ObjectPtr aParamObj = (*it)->objectByName(ModelAPI_ResultParameter::group(), theName);
- ResultParameterPtr aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
- if(!aParam.get())
+ theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
+ if(!theParam.get())
continue;
- AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
+ AttributeDoublePtr aValueAttribute = theParam->data()->real(ModelAPI_ResultParameter::VALUE());
outValue = aValueAttribute->value();
return true;
}
#include "ModelAPI.h"
#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultParameter.h>
#include <GeomAPI_Shape.h>
#include <vector>
* in the root document (PartSet). If found, set it value in the \param outValue
* and returns true.
*/
-MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue);
+MODELAPI_EXPORT bool findVariable(const std::string& theName, double& outValue,
+ ResultParameterPtr& theParam);
/*!
* Returns the values of the next random color. The values are in range [0, 255]
bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
{
- QRegExp varNameMask("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
+ QRegExp varNameMask("[-+]?[0-9]*.?[0-9]+([eE][-+]?[0-9]+)?");
return !varNameMask.exactMatch(theText);
}
bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
double& outValue) const
{
-
- return ModelAPI_Tools::findVariable(theName.toStdString(), outValue);
+ ResultParameterPtr aParam;
+ return ModelAPI_Tools::findVariable(theName.toStdString(), outValue, aParam);
}
/*!
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Object.h>
-#include <ModelAPI_Events.h>
#include <ModuleBase_ParamSpinBox.h>
#include <ModuleBase_Tools.h>
// Here is a text of a real value or an expression.
std::string aText = mySpinBox->text().toStdString();
aReal->setText(aText);
- // Send it to evaluator to convert into the double and store in the attribute
- static Events_ID anId = ModelAPI_AttributeEvalMessage::eventId();
- std::shared_ptr<ModelAPI_AttributeEvalMessage> aMessage =
- std::shared_ptr<ModelAPI_AttributeEvalMessage>(new ModelAPI_AttributeEvalMessage(anId, this));
- aMessage->setAttribute(aData->attribute(attributeID()));
- Events_Loop::loop()->send(aMessage);
}
updateObject(myFeature);
return true;
std::list<std::string>::iterator it = anExprParams.begin();
for ( ; it != anExprParams.end(); it++) {
double aValue;
- if (!ModelAPI_Tools::findVariable(*it, aValue)) continue;
+ ResultParameterPtr aParamRes;
+ if (!ModelAPI_Tools::findVariable(*it, aValue, aParamRes)) continue;
std::ostringstream sstream;
sstream << aValue;
myInterp->clearLocalContext();
return result;
}
-
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_ResultParameter.h>
#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
#include <string>
#include <sstream>
void ParametersPlugin_Parameter::initAttributes()
{
- data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(),
- ModelAPI_AttributeString::typeId());
- data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(),
- ModelAPI_AttributeString::typeId());
+ data()->addAttribute(VARIABLE_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
+ data()->addAttribute(ARGUMENTS_ID(), ModelAPI_AttributeRefList::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ARGUMENTS_ID());
}
bool ParametersPlugin_Parameter::isInHistory()
return false;
}
-void ParametersPlugin_Parameter::attributeChanged(const std::string&)
+void ParametersPlugin_Parameter::attributeChanged(const std::string& theID)
{
- ResultParameterPtr aParam = document()->createParameter(data());
+ if (theID == EXPRESSION_ID()) { // recompute only on change of the expression
+ ResultParameterPtr aParam = document()->createParameter(data());
- std::string anExpression = string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
- if(anExpression.empty()) {
- // clear error/result if the expression is empty
- setError("", false);
- return;
+ std::string anExpression = string(EXPRESSION_ID())->value();
+ if(anExpression.empty()) {
+ // clear error/result if the expression is empty
+ setError("", false);
+ return;
+ }
+ std::string outErrorMessage;
+ double aValue = evaluate(anExpression, outErrorMessage);
+ // Name
+ std::string aName = string(VARIABLE_ID())->value();
+ std::ostringstream sstream;
+ sstream << aValue;
+ std::string aParamValue = sstream.str();
+ data()->setName(aName);
+ aParam->data()->setName(aName);
+ // Error
+ if (!outErrorMessage.empty()) {
+ std::string aStateMsg("Error: " + outErrorMessage);
+ data()->execState(ModelAPI_StateExecFailed);
+ setError(aStateMsg, false);
+ } else {
+ static const std::string anEmptyMsg(""); // it is checked in the validator by the empty message
+ setError(anEmptyMsg, false);
+ data()->execState(ModelAPI_StateDone);
+ }
+ // Value
+ AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
+ aValueAttribute->setValue(aValue);
+ setResult(aParam);
}
- std::string outErrorMessage;
- double aValue = evaluate(anExpression, outErrorMessage);
- // Name
- std::string aName = string(ParametersPlugin_Parameter::VARIABLE_ID())->value();
- std::ostringstream sstream;
- sstream << aValue;
- std::string aParamValue = sstream.str();
- data()->setName(aName);
- aParam->data()->setName(aName);
- // Error
- std::string aStateMsg;
- if (!outErrorMessage.empty()) {
- aStateMsg = "Error: " + outErrorMessage;
- data()->execState(ModelAPI_StateExecFailed);
- }
- setError(aStateMsg, false);
- // Value
- AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
- aValueAttribute->setValue(aValue);
- setResult(aParam);
}
void ParametersPlugin_Parameter::execute()
{
+ // just call recompute
+ attributeChanged(EXPRESSION_ID());
}
double ParametersPlugin_Parameter::evaluate(const std::string& theExpression, std::string& theError)
// find expression's params in the model
std::list<std::string> aContext;
std::list<std::string>::iterator it = anExprParams.begin();
+ std::list<ResultParameterPtr> aParamsList;
for ( ; it != anExprParams.end(); it++) {
double aValue;
- if (!ModelAPI_Tools::findVariable(*it, aValue)) continue;
+ ResultParameterPtr aParamRes;
+ if (!ModelAPI_Tools::findVariable(*it, aValue, aParamRes)) continue;
+ aParamsList.push_back(aParamRes);
std::ostringstream sstream;
sstream << aValue;
std::string aParamValue = sstream.str();
aContext.push_back(*it + "=" + aParamValue);
}
+ // compare the list of parameters to store if changed
+ AttributeRefListPtr aParams = reflist(ARGUMENTS_ID());
+ bool aDifferent = aParams->size() != aParamsList.size();
+ if (!aDifferent) {
+ std::list<ResultParameterPtr>::iterator aNewIter = aParamsList.begin();
+ std::list<ObjectPtr> anOldList = aParams->list();
+ std::list<ObjectPtr>::iterator anOldIter = anOldList.begin();
+ for(; !aDifferent && aNewIter != aParamsList.end(); aNewIter++, anOldIter++) {
+ if (*aNewIter != *anOldIter)
+ aDifferent = true;
+ }
+ }
+ if (aDifferent) {
+ aParams->clear();
+ std::list<ResultParameterPtr>::iterator aNewIter = aParamsList.begin();
+ for(; aNewIter != aParamsList.end(); aNewIter++) {
+ aParams->append(*aNewIter);
+ }
+ }
+
myInterp->extendLocalContext(aContext);
double result = myInterp->evaluate(theExpression, theError);
myInterp->clearLocalContext();
return result;
}
+
+bool ParametersPlugin_Parameter::isPreviewNeeded() const
+{
+ return false;
+}
return MY_EXPRESSION_ID;
}
+ /// list of references to the arguments of this expression
+ inline static const std::string& ARGUMENTS_ID()
+ {
+ static const std::string MY_VARIABLE_ID("arguments");
+ return MY_VARIABLE_ID;
+ }
+
/// Returns the kind of a feature
PARAMETERSPLUGIN_EXPORT virtual const std::string& getKind()
{
return MY_KIND;
}
+ /// Pre-execution is not needed for parameter
+ PARAMETERSPLUGIN_EXPORT virtual bool isPreviewNeeded() const;
+
/// Creates a new part document if needed
PARAMETERSPLUGIN_EXPORT virtual void execute();