Create a sketch(two circles), create an extrusion(use sketch in OB), edit sketch(create a new circle). The result is the extrusion is not redisplayed for the last circle.
2. Hide of the features from the initialization plugin after creation. There is a blinking in OCC viewer.
TODO: emit a signal about block/unblock the OCC viewer update to avoid this blinking.
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/Events
${PROJECT_SOURCE_DIR}/src/Config
${PROJECT_SOURCE_DIR}/src/ModelAPI
+ ${PROJECT_SOURCE_DIR}/src/GeomAPI
)
SET(PROJECT_HEADERS
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Events.h>
+#include <ModelAPI_Result.h>
#include <Events_Message.h>
#include <Events_Error.h>
std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage = std::dynamic_pointer_cast<
ModelAPI_DocumentCreatedMessage>(theMessage);
DocumentPtr aDoc = aMessage->document();
- createPoint(aDoc);
- createPlane(aDoc, 1., 0., 0.);
- createPlane(aDoc, 0., 1., 0.);
- createPlane(aDoc, 0., 0., 1.);
+ std::list<FeaturePtr> aFeatures;
+
+ aFeatures.push_back(createPoint(aDoc));
+ aFeatures.push_back(createPlane(aDoc, 1., 0., 0.));
+ aFeatures.push_back(createPlane(aDoc, 0., 1., 0.));
+ aFeatures.push_back(createPlane(aDoc, 0., 0., 1.));
// for PartSet it is done outside of the transaction, so explicitly flush this creation
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+
+ // hides the created features, the precondition is that the feature's results have been
+ // already built, so the createPlane/Points method calls the execute function for the planes
+ static Events_ID HIDE_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TOHIDE);
+ std::list<FeaturePtr >::const_iterator aFIter = aFeatures.begin();
+ for (; aFIter != aFeatures.cend(); aFIter++) {
+ FeaturePtr aPlane = *aFIter;
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aPlane->results();
+ std::list<ResultPtr >::const_iterator aRIter = aResults.begin();
+ for (; aRIter != aResults.cend(); aRIter++) {
+ ModelAPI_EventCreator::get()->sendUpdated(*aRIter, HIDE_DISP);
+ }
+ }
+ Events_Loop::loop()->flush(HIDE_DISP);
+
} else if (theMessage.get()) {
Events_Error::send(
std::string("InitializationPlugin_Plugin::processEvent: unhandled message caught: ")
}
}
-void InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theX, double theY,
- double theZ)
+FeaturePtr InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theX, double theY,
+ double theZ)
{
- std::shared_ptr<ModelAPI_Feature> aPlane = theDoc->addFeature("Plane");
+ FeaturePtr aPlane = theDoc->addFeature("Plane");
aPlane->string("CreationMethod")->setValue("PlaneByGeneralEquation");
aPlane->real("A")->setValue(theX);
aPlane->real("B")->setValue(theY);
aPlane->data()->setName("X0Y");
}
aPlane->setInHistory(aPlane, false); // don't show automatically created feature in the features history
+
+ // the plane should be executed in order to build the feature result immediatelly
+ // the results are to be hidden in the plugin
+ aPlane->execute();
+
+ return aPlane;
}
-void InitializationPlugin_Plugin::createPoint(DocumentPtr theDoc)
+FeaturePtr InitializationPlugin_Plugin::createPoint(DocumentPtr theDoc)
{
std::shared_ptr<ModelAPI_Feature> aPoint = theDoc->addFeature("Point");
aPoint->real("x")->setValue(0.);
aPoint->real("z")->setValue(0.);
aPoint->data()->setName("Origin");
aPoint->setInHistory(aPoint, false); // don't show automatically created feature in the features history
+
+ // the point should be executed in order to build the feature result immediatelly
+ // the results are to be hidden in the plugin
+ aPoint->execute();
+
+ return aPoint;
}
/// \param theX - determines if X is 0 or not
/// \param theY - determines if Y is 0 or not
/// \param theZ - determines if Z is 0 or not
- void createPlane(DocumentPtr theDoc, double theX, double theY, double theZ);
+ FeaturePtr createPlane(DocumentPtr theDoc, double theX, double theY, double theZ);
/// Creates the origin point in (0,0,0)
/// \param theDoc - document to contain a "point" feature
- void createPoint(DocumentPtr theDoc);
+ FeaturePtr createPoint(DocumentPtr theDoc);
};
#endif
bool ModuleBase_IModule::canDisplayObject(const ObjectPtr& theObject) const
{
- ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
- return anOperation && anOperation->hasObject(theObject);
+ return true;
}
bool ModuleBase_IModule::canUndo() const
//! Returns True if there are available Redos and there is not an active operation\r
virtual bool canRedo() const;\r
\r
- /// Returns whether the object can be displayed at the bounds of the active operation.\r
- /// Display only current operation results\r
+ /// Returns whether the object can be displayed. The default realization returns true.\r
/// \param theObject a model object\r
virtual bool canDisplayObject(const ObjectPtr& theObject) const;\r
\r
bool PartSet_Module::canDisplayObject(const ObjectPtr& theObject) const
{
- bool aCanDisplay = false;
- if (!mySketchMgr->canDisplayObject())
- return aCanDisplay;
- CompositeFeaturePtr aSketchFeature = mySketchMgr->activeSketch();
- if (aSketchFeature.get() != NULL) {
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
-
- // MPV: the second and third conditions to avoid crash on exit for application
- if (aFeature.get() != NULL && aFeature->data().get() && aFeature->data()->isValid()) {
- if (aFeature == aSketchFeature) {
- aCanDisplay = false;
- }
- else if (aSketchFeature.get() && aSketchFeature->data().get() &&
- aSketchFeature->data()->isValid()) {
- for (int i = 0; i < aSketchFeature->numberOfSubs() && !aCanDisplay; i++) {
- FeaturePtr aSubFeature = aSketchFeature->subFeature(i);
- std::list<ResultPtr> aResults = aSubFeature->results();
- std::list<ResultPtr>::const_iterator aIt;
- for (aIt = aResults.begin(); aIt != aResults.end() && !aCanDisplay; ++aIt) {
- if (theObject == (*aIt))
- aCanDisplay = true;
- }
- if (aSubFeature == theObject)
- aCanDisplay = true;
- }
- }
- }
- }
- else {
- aCanDisplay = ModuleBase_IModule::canDisplayObject(theObject);
+ // the display should be possible almost always, with exception of some specific cases
+
+ bool aCanDisplay = true;
+
+ if (mySketchMgr->activeSketch()) {
+ aCanDisplay = mySketchMgr->canDisplayObject(theObject);
}
return aCanDisplay;
}
myIsPropertyPanelValueChanged = false;
// the feature is to be erased here, but it is correct to call canDisplayObject because
// there can be additional check (e.g. editor widget in distance constraint)
- visualizeFeature(aOperation, canDisplayObject());
+ FeaturePtr aFeature = getCurrentOperation()->feature();
+ visualizeFeature(aOperation, canDisplayObject(aFeature));
}
void PartSet_SketcherMgr::onBeforeValuesChangedInPropertyPanel()
ModuleBase_Operation* aOperation = getCurrentOperation();
// the feature is to be erased here, but it is correct to call canDisplayObject because
// there can be additional check (e.g. editor widget in distance constraint)
- visualizeFeature(aOperation, canDisplayObject());
+ FeaturePtr aFeature = getCurrentOperation()->feature();
+ visualizeFeature(aOperation, canDisplayObject(aFeature));
}
void PartSet_SketcherMgr::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent)
}
// the feature is to be erased here, but it is correct to call canDisplayObject because
// there can be additional check (e.g. editor widget in distance constraint)
- visualizeFeature(aOperation, canDisplayObject());
+ FeaturePtr aFeature = getCurrentOperation()->feature();
+ visualizeFeature(aOperation, canDisplayObject(aFeature));
}
myClickedPoint.clear();
return isNestedCreateOperation(getCurrentOperation());
}
-bool PartSet_SketcherMgr::canDisplayObject() const
+bool PartSet_SketcherMgr::canDisplayObject(const ObjectPtr& theObject) const
{
bool aCanDisplay = true;
- if (!isNestedCreateOperation(getCurrentOperation()))
- return aCanDisplay;
-
- ModuleBase_Operation* aOperation = getCurrentOperation();
- ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
- ModuleBase_ModelWidget* anActiveWdg = aPanel ? aPanel->activeWidget() : 0;
- // the active widget editor should not influence here. The presentation should be visible always
- // when this widget is active.
- if (anActiveWdg) {
- ModuleBase_WidgetEditor* anEditorWdg = dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWdg);
- if (anEditorWdg) {
+ // 1. the sketch feature should not be displayed during the sketch active operation
+ // it is hidden by a sketch operation start and shown by a sketch stop, just the sketch
+ // nested features can be visualized
+ CompositeFeaturePtr aSketchFeature = activeSketch();
+ if (aSketchFeature.get() != NULL) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
+ if (aFeature.get() != NULL && aFeature == aSketchFeature)
+ aCanDisplay = false;
+ }
+ // 2. For created nested feature operation do not display the created feature if
+ // the mouse curstor leaves the OCC window.
+ // The correction cases, which ignores this condition:
+ // a. the property panel values modification
+ // b. the popup menu activated
+ // c. widget editor control
+ if (aCanDisplay) {
+ if (!isNestedCreateOperation(getCurrentOperation()))
return aCanDisplay;
+
+ ModuleBase_Operation* aOperation = getCurrentOperation();
+ ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+ ModuleBase_ModelWidget* anActiveWdg = aPanel ? aPanel->activeWidget() : 0;
+ // the active widget editor should not influence here. The presentation should be visible always
+ // when this widget is active.
+ if (anActiveWdg) {
+ ModuleBase_WidgetEditor* anEditorWdg = dynamic_cast<ModuleBase_WidgetEditor*>(anActiveWdg);
+ if (anEditorWdg) {
+ return aCanDisplay;
+ }
}
- }
- if (myIsPopupMenuActive)
- return aCanDisplay;
+ if (myIsPopupMenuActive)
+ return aCanDisplay;
- // during a nested create operation, the feature is redisplayed only if the mouse over view
- // of there was a value modified in the property panel after the mouse left the view
- aCanDisplay = myIsPropertyPanelValueChanged || myIsMouseOverWindow;
+ // during a nested create operation, the feature is redisplayed only if the mouse over view
+ // of there was a value modified in the property panel after the mouse left the view
+ aCanDisplay = myIsPropertyPanelValueChanged || myIsMouseOverWindow;
+ }
return aCanDisplay;
}
/// Display only current operation results for usual operation and ask the sketcher manager
/// if it is a sketch operation
/// \param theObject a model object
- bool canDisplayObject() const;
+ bool canDisplayObject(const ObjectPtr& theObject) const;
/// Returns true if the current operation is sketch entity create operation
/// \param theValue the current auxiliary value
for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
ObjectPtr anObject = aSelectAttr->context();
- FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
- isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+ // a context of the selection attribute is a feature result. It can be a case when the result
+ // of the feature is null, e.g. the feature is modified and has not been executed yet.
+ // The validator returns an invalid result here. The case is an extrusion built on a sketch
+ // feature. A new sketch element creation leads to an empty result.
+ if (!anObject.get())
+ isSketchEntities = false;
+ else {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+ }
}
}
if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
#include <dlfcn.h>
#endif
+//#define DEBUG_FEATURE_CREATED
+//#define DEBUG_FEATURE_REDISPLAY
+
+QString objectInfo(ObjectPtr theObj)
+{
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
+ QString aFeatureStr = "feature";
+ if(aRes.get()) {
+ aFeatureStr.append("(Result)");
+ aFeature = ModelAPI_Feature::feature(aRes);
+ }
+ if (aFeature.get()) {
+ aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
+ }
+ return aFeatureStr;
+}
+
+
QMap<QString, QString> XGUI_Workshop::myIcons;
{
std::set<ObjectPtr> aObjects = theMsg->objects();
std::set<ObjectPtr>::const_iterator aIt;
+
+#ifdef DEBUG_FEATURE_REDISPLAY
+ QStringList anInfo;
+ for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
+ anInfo.append(objectInfo((*aIt)));
+ }
+ QString anInfoStr = anInfo.join(", ");
+ qDebug(QString("onFeatureRedisplayMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
+#endif
+
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
ObjectPtr aObj = (*aIt);
+ // Hide the object if it is invalid or concealed one
bool aHide = !aObj->data() || !aObj->data()->isValid();
if (!aHide) { // check that this is not hidden result
ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
if (aHide)
myDisplayer->erase(aObj, false);
else {
- if (myDisplayer->isVisible(aObj)) {
+ // Redisplay the visible object or the object of the current operation
+ bool isVisibleObject = myDisplayer->isVisible(aObj);
+ #ifdef DEBUG_FEATURE_REDISPLAY
+ QString anObjInfo = objectInfo((aObj));
+ qDebug(QString("visible=%1 : display= %2").arg(isVisibleObject).arg(anObjInfo).toStdString().c_str());
+ #endif
+
+ if (isVisibleObject) { // redisplay visible object
displayObject(aObj); // In order to update presentation
if (myOperationMgr->hasOperation()) {
ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
aOperation->hasObject(aObj) && myDisplayer->isActive(aObj))
myDisplayer->deactivate(aObj);
}
- } else {
- if (myOperationMgr->hasOperation()) {
+ } else { // display object if the current operation has it
+ ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
+ if (aOperation && aOperation->hasObject(aObj)) {
ModuleBase_Operation* aOperation = myOperationMgr->currentOperation();
- if (myModule->canDisplayObject(aObj)) {
- displayObject(aObj);
+ if (displayObject(aObj)) {
// Deactivate object of current operation from selection
if (myDisplayer->isActive(aObj))
myDisplayer->deactivate(aObj);
void XGUI_Workshop::onFeatureCreatedMsg(const std::shared_ptr<ModelAPI_ObjectUpdatedMessage>& theMsg)
{
std::set<ObjectPtr> aObjects = theMsg->objects();
-
std::set<ObjectPtr>::const_iterator aIt;
- bool aHasPart = false;
+#ifdef DEBUG_FEATURE_CREATED
+ QStringList anInfo;
+ for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
+ anInfo.append(objectInfo((*aIt)));
+ }
+ QString anInfoStr = anInfo.join(", ");
+ qDebug(QString("onFeatureCreatedMsg: %1, %2").arg(aObjects.size()).arg(anInfoStr).toStdString().c_str());
+#endif
+
+ //bool aHasPart = false;
bool isDisplayed = false;
for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) {
- ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aIt);
- if (aPart) {
- aHasPart = true;
+ //ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aIt);
+ //if (aPart) {
+ //aHasPart = true;
// If a feature is created from the aplication's python console
// it doesn't stored in the operation mgr and doesn't displayed
- } else if (myModule->canDisplayObject(*aIt)) {
- displayObject(*aIt);
- isDisplayed = true;
- }
+ //} else {
+ isDisplayed = displayObject(*aIt);
+ //}
}
if (myObjectBrowser)
myObjectBrowser->processEvent(theMsg);
}
//**************************************************************
-void XGUI_Workshop::displayObject(ObjectPtr theObj)
+bool XGUI_Workshop::displayObject(ObjectPtr theObj)
{
+ if (!myModule->canDisplayObject(theObj))
+ return false;
+
ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theObj);
if (aBody.get() != NULL) {
int aNb = myDisplayer->objectsCount();
viewer()->fitAll();
} else
myDisplayer->display(theObj, false);
+
+ return true;
}
void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot)
void createDockWidgets();
/// Displaus object and fit all viewer if the object is first (update viewer will not be called)
- void displayObject(ObjectPtr theObj);
+ /// Asks the module whether the object can be displayed
+ /// \param theObj an object
+ /// \return true if the object is displayed
+ bool displayObject(ObjectPtr theObj);
//! Extends undo/redo toolbutton's with history menu
//! \param theObject - in the OpenParts it is a QToolButton by itself,