Salome HOME
1. The incorrect behaviour fixed:
authornds <natalia.donis@opencascade.com>
Tue, 31 Mar 2015 09:35:06 +0000 (12:35 +0300)
committernds <natalia.donis@opencascade.com>
Tue, 31 Mar 2015 09:35:06 +0000 (12:35 +0300)
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.

src/InitializationPlugin/CMakeLists.txt
src/InitializationPlugin/InitializationPlugin_Plugin.cpp
src/InitializationPlugin/InitializationPlugin_Plugin.h
src/ModuleBase/ModuleBase_IModule.cpp
src/ModuleBase/ModuleBase_IModule.h
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_Validators.cpp
src/XGUI/XGUI_Workshop.cpp
src/XGUI/XGUI_Workshop.h

index 717e200abce89d6a9d0c14c8dcaa26d684da17cb..9f18bb6613661e6138dfdc92ad6c6d863b95b60d 100644 (file)
@@ -4,6 +4,7 @@ INCLUDE(Common)
 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
index 553d22608a543eeb2383630dd31fbda269e4cd18..ad707767504d2ef5379632a241af8b2f906762fe 100644 (file)
@@ -7,6 +7,7 @@
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Events.h>
+#include <ModelAPI_Result.h>
 
 #include <Events_Message.h>
 #include <Events_Error.h>
@@ -31,12 +32,29 @@ void InitializationPlugin_Plugin::processEvent(const std::shared_ptr<Events_Mess
     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: ")
@@ -44,10 +62,10 @@ void InitializationPlugin_Plugin::processEvent(const std::shared_ptr<Events_Mess
   }
 }
 
-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);
@@ -62,9 +80,15 @@ void InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theX, d
     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.);
@@ -72,4 +96,10 @@ void InitializationPlugin_Plugin::createPoint(DocumentPtr theDoc)
   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;
 }
index 4ddaf76098bdf0166b7e8c938090e550c7f3db2d..42d157703e7d9c46cd52a373e83229c11bbd4ac6 100644 (file)
@@ -32,10 +32,10 @@ class INITIALIZATIONPLUGIN_EXPORT InitializationPlugin_Plugin : public Events_Li
   /// \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
index 315be91780a0db0180dafdbfb6879b70d77ce351..1f759feb5b70a88fd16ccb21f74633a50c27ca23 100644 (file)
@@ -113,8 +113,7 @@ void ModuleBase_IModule::actionCreated(QAction* theFeature)
 
 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
index b29b4e51d97c4e383b40d0a2b422c1038f0c81d3..c7cd377cc26d7c778d5c7f7e15f980043aa4fb01 100644 (file)
@@ -109,8 +109,7 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
   //! 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
index 20cd411016fc4806e4f402843ee6926f4f03479e..da5860f6ccebf198f1d2f87093f708acd1160416 100644 (file)
@@ -275,36 +275,12 @@ bool PartSet_Module::canRedo() const
 
 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;
 }
index 2747c40040ff28e34ea3fe1b693fc19cef2f02fb..6a8c084db84ed0be24b157c488aaa3546e502622 100644 (file)
@@ -195,7 +195,8 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   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()
@@ -239,7 +240,8 @@ void PartSet_SketcherMgr::onValuesChangedInPropertyPanel()
   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)
@@ -375,7 +377,8 @@ void PartSet_SketcherMgr::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEve
     }
     // 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();
@@ -739,29 +742,46 @@ bool PartSet_SketcherMgr::canRedo() const
   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;
 }
 
index c5f7effe100641a20f6e164cf34eac5720d1fb65..dc68f283a36eae66389493b656241dca053e7876 100644 (file)
@@ -135,7 +135,7 @@ public:
   /// 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
index 6d17784f78dbcfc44b31410e0f8fa386089a33f6..04bcb3663fd2587b91666f37598aaf205cc9b04d 100644 (file)
@@ -247,8 +247,16 @@ bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
     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()) {
index 2997907c04b2d3853880af22aa1ee59d6c573653..3d7e3142e63577773d374a016e19acbaab6ab7e2 100644 (file)
 #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;
 
 
@@ -507,9 +526,20 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
 {
   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);
@@ -518,7 +548,14 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
     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();
@@ -526,11 +563,11 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
               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);
@@ -546,21 +583,28 @@ void XGUI_Workshop::onFeatureRedisplayMsg(const std::shared_ptr<ModelAPI_ObjectU
 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);
@@ -1573,8 +1617,11 @@ void XGUI_Workshop::closeDocument()
 }
 
 //**************************************************************
-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();
@@ -1583,6 +1630,8 @@ void XGUI_Workshop::displayObject(ObjectPtr theObj)
       viewer()->fitAll();
   } else 
     myDisplayer->display(theObj, false);
+
+  return true;
 }
 
 void XGUI_Workshop::addHistoryMenu(QObject* theObject, const char* theSignal, const char* theSlot)
index c2b067741db3bb8162dd48b7565ab87046036251..baeff44487730e7f95d5fa35b6693bf31deccc96 100644 (file)
@@ -391,7 +391,10 @@ signals:
   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,