Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
authornds <natalia.donis@opencascade.com>
Wed, 1 Apr 2015 15:48:59 +0000 (18:48 +0300)
committernds <natalia.donis@opencascade.com>
Wed, 1 Apr 2015 15:48:59 +0000 (18:48 +0300)
25 files changed:
src/Config/Config_Prop.h
src/FeaturesPlugin/FeaturesPlugin_Extrusion.cpp
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Session.cpp
src/Model/Model_Update.cpp
src/ModuleBase/ModuleBase_IModule.h
src/ModuleBase/ModuleBase_PagedContainer.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_WidgetShapeSelector.cpp
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_Validators.h
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_ConstraintGroup.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.h
src/SketchSolver/SketchSolver_ConstraintManager.cpp
src/SketcherPrs/SketcherPrs_Coincident.cpp
src/SketcherPrs/SketcherPrs_Coincident.h
src/SketcherPrs/SketcherPrs_Radius.cpp
src/XGUI/XGUI_ContextMenuMgr.cpp

index 5e6cc4bc8576045bef9023694e7966a1c3121254..b24e422789cd86d197b76000dad3ccec783fae76 100644 (file)
@@ -4,8 +4,8 @@
 // Created:     12 Aug 2014
 // Author:      Vitaly SMETANNIKOV
 
-#ifndef Config_Prop_H
-#define Config_Prop_H
+#ifndef CONFIG_PROP_H
+#define CONFIG_PROP_H
 
 #include "Config_def.h"
 
@@ -26,7 +26,7 @@ class Config_Prop
   {
     Disabled,
     Space,
-    Bool,
+    Boolean,
     Color,
     String,
     Selector,
index 3d8c5bbc842d2fb14bebc33d78070df9bb22f284..3056c26826725267bb419994850fb66990db52ff 100644 (file)
@@ -72,8 +72,12 @@ void FeaturesPlugin_Extrusion::execute()
 
     for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
       ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
-      std::shared_ptr<GeomAPI_Shape> aFace = 
-        aFacesNum == -1 ? aValueFace : aConstruction->face(aFaceIndex);
+      std::shared_ptr<GeomAPI_Shape> aFace;
+      if (aFacesNum == -1) {
+        aFace = aValueFace;
+      } else {
+        aFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
+      }
       GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
       if(!aFeature.isDone()) {
         static const std::string aFeatureError = "Extrusion algorithm failed";  
index c2da1a4799feb204aad3cc3a15cf99127ad447a9..ee8cebc14c9d0274a1dd486a1638fca540450c17 100644 (file)
@@ -84,10 +84,15 @@ static TCollection_ExtendedString DocFileName(const char* theFileName, const std
   return aPath;
 }
 
+bool Model_Document::isRoot() const
+{
+  return this == Model_Session::get()->moduleDocument().get();
+}
+
 bool Model_Document::load(const char* theFileName)
 {
   Handle(Model_Application) anApp = Model_Application::getApplication();
-  if (this == Model_Session::get()->moduleDocument().get()) {
+  if (isRoot()) {
     anApp->setLoadPath(theFileName);
   }
   TCollection_ExtendedString aPath(DocFileName(theFileName, myID));
@@ -161,7 +166,7 @@ bool Model_Document::load(const char* theFileName)
       std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
     aSession->setActiveDocument(anApp->getDocument(myID), false);
     aSession->setCheckTransactions(false);
-    synchronizeFeatures(false, true);
+    synchronizeFeatures(false, true, true);
     aSession->setCheckTransactions(true);
     aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
     aSession->setActiveDocument(anApp->getDocument(myID), true);
@@ -173,7 +178,7 @@ bool Model_Document::save(const char* theFileName, std::list<std::string>& theRe
 {
   // create a directory in the root document if it is not yet exist
   Handle(Model_Application) anApp = Model_Application::getApplication();
-  if (this == Model_Session::get()->moduleDocument().get()) {
+  if (isRoot()) {
 #ifdef WIN32
     CreateDirectory(theFileName, NULL);
 #else
@@ -241,9 +246,9 @@ bool Model_Document::save(const char* theFileName, std::list<std::string>& theRe
 void Model_Document::close(const bool theForever)
 {
   std::shared_ptr<ModelAPI_Session> aPM = Model_Session::get();
-  if (this != aPM->moduleDocument().get() && this == aPM->activeDocument().get()) {
+  if (!isRoot() && this == aPM->activeDocument().get()) {
     aPM->setActiveDocument(aPM->moduleDocument());
-  } else if (this == aPM->moduleDocument().get()) {
+  } else if (isRoot()) {
     // erase the active document if root is closed
     aPM->setActiveDocument(DocumentPtr());
   }
@@ -341,7 +346,7 @@ bool Model_Document::finishOperation()
   // this must be here just after everything is finished but before real transaction stop
   // to avoid messages about modifications outside of the transaction
   // and to rebuild everything after all updates and creates
-  if (Model_Session::get()->moduleDocument().get() == this) { // once for root document
+  if (isRoot()) { // once for root document
     Events_Loop::loop()->autoFlush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
     static std::shared_ptr<Events_Message> aFinishMsg
       (new Events_Message(Events_Loop::eventByName("FinishOperation")));
@@ -371,7 +376,7 @@ bool Model_Document::finishOperation()
   if (!aResult && !myTransactions.empty() /* it can be for just created part document */)
     aResult = myTransactions.rbegin()->myOCAFNum != 0;
 
-  if (!aResult && Model_Session::get()->moduleDocument().get() == this) {
+  if (!aResult && isRoot()) {
     // nothing inside in all documents, so remove this transaction from the transactions list
     undoInternal(true, false);
     myDoc->ClearRedos();
@@ -398,7 +403,8 @@ void Model_Document::abortOperation()
       myDoc->Undo();
     myDoc->ClearRedos();
   }
-  synchronizeFeatures(true, false); // references were not changed since transaction start
+  // references were not changed since transaction start
+  synchronizeFeatures(true, false, isRoot());
   // abort for all subs
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
@@ -446,8 +452,6 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
   for(int a = 0; a < aNumTransactions; a++)
     myDoc->Undo();
 
-  if (theSynchronize)
-    synchronizeFeatures(true, true);
   if (theWithSubs) {
     // undo for all subs
     const std::set<std::string> aSubs = subDocuments(true);
@@ -455,6 +459,9 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
     for (; aSubIter != aSubs.end(); aSubIter++)
       subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
   }
+  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  if (theSynchronize)
+    synchronizeFeatures(true, true, isRoot());
 }
 
 void Model_Document::undo()
@@ -485,12 +492,14 @@ void Model_Document::redo()
   for(int a = 0; a < aNumRedos; a++)
     myDoc->Redo();
 
-  synchronizeFeatures(true, true);
   // redo for all subs
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
   for (; aSubIter != aSubs.end(); aSubIter++)
     subDoc(*aSubIter)->redo();
+
+  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  synchronizeFeatures(true, true, isRoot());
 }
 
 std::list<std::string> Model_Document::undoList() const
@@ -949,7 +958,8 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT
   theObj->initAttributes();
 }
 
-void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences)
+void Model_Document::synchronizeFeatures(
+  const bool theMarkUpdated, const bool theUpdateReferences, const bool theFlush)
 {
   std::shared_ptr<ModelAPI_Document> aThis = 
     Model_Application::getApplication()->getDocument(myID);
@@ -1040,11 +1050,13 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
   myExecuteFeatures = false;
   aLoop->activateFlushes(true);
 
-  aLoop->flush(aCreateEvent);
-  aLoop->flush(aDeleteEvent);
-  aLoop->flush(anUpdateEvent);
-  aLoop->flush(aRedispEvent);
-  aLoop->flush(aToHideEvent);
+  if (theFlush) {
+    aLoop->flush(aCreateEvent);
+    aLoop->flush(aDeleteEvent);
+    aLoop->flush(anUpdateEvent);
+    aLoop->flush(aRedispEvent);
+    aLoop->flush(aToHideEvent);
+  }
   myExecuteFeatures = true;
 }
 
index ef7c98a109f9f3d3113cce26cbd4cf2c6342af18..59631304e0ee4bf0bc51293e51d4212f5fedcca5 100644 (file)
@@ -170,7 +170,9 @@ class Model_Document : public ModelAPI_Document
   //! Synchronizes myFeatures list with the updated document
   //! \param theMarkUpdated causes the "update" event for all features
   //! \param theUpdateReferences causes the update of back-references
-  void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences);
+  //! \param theFlush makes flush all events in the end of all modifications of this method
+  void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences,
+    const bool theFlush);
   //! Synchronizes the BackReferences list in Data of Features and Results
   void synchronizeBackRefs();
 
@@ -219,6 +221,9 @@ class Model_Document : public ModelAPI_Document
   /// Internally makes document know that feature was removed or added in history after creation
   MODEL_EXPORT virtual void addToHistory(const std::shared_ptr<ModelAPI_Object> theObject);
 
+  /// Returns true if the document is root module document
+  bool isRoot() const;
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
index e7f21bf88a8470860d5c3bfba731f94b743dc564..8dcd0a11b0e04e008fc17b0d4f906fb9058be13e 100644 (file)
@@ -216,7 +216,7 @@ void Model_Session::setActiveDocument(
       if (aDoc.get()) {
         bool aWasChecked = myCheckTransactions;
         setCheckTransactions(false);
-        aDoc->synchronizeFeatures(false, true);
+        aDoc->synchronizeFeatures(false, true, true);
         if (aWasChecked)
             setCheckTransactions(true);
       }
@@ -266,7 +266,7 @@ std::shared_ptr<ModelAPI_Document> Model_Session::copy(
   aRT->SetRelocation(aSourceRoot, aTargetRoot);
   TDF_CopyTool::Copy(aDS, aRT);
 
-  aNew->synchronizeFeatures(false, true);
+  aNew->synchronizeFeatures(false, true, true);
   return aNew;
 }
 
index 2390df8268e737bb4e0038bd0df4e4e4e38f58d6..f1b4f50ff35fab60a0de7b867d3c56c9b14254ba 100644 (file)
@@ -50,7 +50,7 @@ Model_Update::Model_Update()
   aLoop->registerListener(this, kOpStartEvent);
 
   Config_PropManager::registerProp("Model update", "automatic_rebuild", "Rebuild immediately",
-                                   Config_Prop::Bool, "false");
+                                   Config_Prop::Boolean, "false");
   myIsAutomatic =
     Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
 }
index c7cd377cc26d7c778d5c7f7e15f980043aa4fb01..1d68372056ca961735560524bc0ada42b8c2c029 100644 (file)
@@ -10,6 +10,7 @@
 \r
 #include <QString>\r
 #include <QObject>\r
+#include <QMap>\r
 \r
 #include <string>\r
 #include <map>\r
@@ -75,7 +76,9 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject
 \r
   /// Add menu atems for viewer into the given menu\r
   /// \param theMenu a popup menu to be shown in the viewer\r
-  virtual void addViewerItems(QMenu* theMenu) const {}\r
+  /// \param theStdActions a map of standard actions\r
+  /// \return true if items are added and there is no necessity to provide standard menu\r
+  virtual bool addViewerItems(QMenu* theMenu, const QMap<QString, QAction*>& theStdActions) const { return false; }\r
 \r
   /// Add menu atems for object browser into the given menu\r
   /// \param theMenu a popup menu to be shown in the object browser\r
index 43fb4de2233308b7a25717dea526759092753668..b4e8b5690604a1e99bf607ec79cbb0a8b704d06d 100644 (file)
@@ -13,7 +13,7 @@
 #include <ModelAPI_AttributeString.h>
 
 #include <QWidget>
-#include <Qlist>
+#include <QList>
 #include <QVBoxLayout>
 
 
index 8b53074f961a4755a1cd02fc478c41e85979d420..9d74cc2fb48bb08f67d546bcf00611bf0389cf2b 100644 (file)
@@ -231,7 +231,7 @@ bool ModuleBase_WidgetMultiSelector::setSelection(const Handle_SelectMgr_EntityO
   AttributeSelectionListPtr aSelectionListAttr = 
     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
   if (aShape->isEqual(aResult->shape()))
-    aSelectionListAttr->append(aResult, NULL);
+    aSelectionListAttr->append(aResult, GeomShapePtr());
   else
     aSelectionListAttr->append(aResult, aShape);
 
index 36bbd0314e502d8324f1570127ec203f2367b36a..34eb3e189061b69be8b7fff28f62e7a3f76034b5 100644 (file)
@@ -377,7 +377,7 @@ void ModuleBase_WidgetShapeSelector::storeAttributeValue()
 
   myObject = GeomValidators_Tools::getObject(anAttribute);
   myShape = getShape();
-  myRefAttribute = NULL;
+  myRefAttribute = AttributePtr();
   myIsObject = false;
   AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
   if (aRefAttr) {
index 841387209216913943061197202e97cb03f22a97..4c685683578f2cd490d3964e314fca495da18414 100644 (file)
@@ -288,12 +288,12 @@ bool PartSet_Module::canDisplayObject(const ObjectPtr& theObject) const
   return aCanDisplay;
 }
 
-void PartSet_Module::addViewerItems(QMenu* theMenu) const
+bool PartSet_Module::addViewerItems(QMenu* theMenu, const QMap<QString, QAction*>& theStdActions) const
 {
   ModuleBase_Operation* anOperation = myWorkshop->currentOperation();
   if (!PartSet_SketcherMgr::isSketchOperation(anOperation) &&
       !PartSet_SketcherMgr::isNestedSketchOperation(anOperation))
-    return;
+    return false;
 
   ModuleBase_ISelection* aSelection = myWorkshop->selection();
   QObjectPtrList aObjects = aSelection->selectedPresentations();
@@ -307,10 +307,7 @@ void PartSet_Module::addViewerItems(QMenu* theMenu) const
       }
     }
     if (hasFeature) {
-      XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
-      XGUI_Workshop* aWorkshop = aConnector->workshop();
-      QAction* anAction = aWorkshop->contextMenuMgr()->action("DELETE_CMD");
-      theMenu->addAction(anAction);
+      theMenu->addAction(theStdActions["DELETE_CMD"]);
     }
   }
   bool isAuxiliary;
@@ -319,6 +316,7 @@ void PartSet_Module::addViewerItems(QMenu* theMenu) const
     theMenu->addAction(anAction);
     anAction->setChecked(isAuxiliary);
   }
+  return true;
 }
 
 void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
index 891759c36b34bb51dd9071fcc0bc70a7c449d280..5264352dc98b0563d12877f826f862cce2cd67dd 100644 (file)
@@ -103,7 +103,9 @@ public:
 
   /// Add menu atems for viewer into the given menu
   /// \param theMenu a popup menu to be shown in the viewer
-  virtual void addViewerItems(QMenu* theMenu) const;
+  /// \param theStdActions a map of standard actions
+  /// \return true if items are added and there is no necessity to provide standard menu
+  virtual bool addViewerItems(QMenu* theMenu, const QMap<QString, QAction*>& theStdActions) const;
 
 public slots:
   /// SLOT, that is called by no more widget signal emitted by property panel
index 8b18658297b86d0a1874a1357fd12856422c99a9..82c0479bd67ced814630e957d64583b71d6212e5 100644 (file)
@@ -136,6 +136,6 @@ void PartSet_WidgetShapeSelector::removeExternal()
       anIgnoredFeatures.insert(sketch());
       XGUI_Workshop::deleteFeatures(anObjects, anIgnoredFeatures);
     }
-    myExternalObject = NULL;
+    myExternalObject = ObjectPtr();
   }
 }
index fde907d815e9e9616819398e4e1263cd4b610fa1..5dc94ef4a28b5e38b00440fc1dc9daebeae646de 100644 (file)
@@ -79,8 +79,7 @@ void SketchPlugin_ConstraintMirror::execute()
         ResultConstructionPtr aRC =
             std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirrorIter);
         DocumentPtr aDoc = aRC ? aRC->document() : DocumentPtr();
-        FeaturePtr aFeature =  aDoc ? std::dynamic_pointer_cast<SketchPlugin_Feature>(
-              aDoc->feature(aRC)) : FeaturePtr();
+        FeaturePtr aFeature =  aDoc ? aDoc->feature(aRC) : FeaturePtr();
         if (aFeature)
           aDoc->removeFeature(aFeature);
       }
index c7ee95fcc32070a00d6564cbb37effd8ad1f9870..e92cdb8c47472ae37d3726b24434f64d4743ca87 100644 (file)
@@ -55,6 +55,10 @@ SketchPlugin_Plugin::SketchPlugin_Plugin()
                               new SketchPlugin_ExternalValidator);
   aFactory->registerValidator("SketchPlugin_TangentAttr",
                               new SketchPlugin_TangentAttrValidator);
+  aFactory->registerValidator("SketchPlugin_NotFixed",
+                              new SketchPlugin_NotFixedValidator);
+  aFactory->registerValidator("SketchPlugin_EqualAttr",
+                              new SketchPlugin_EqualAttrValidator);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
index 358c82c1b4982e73bf8875c5e31b952798c55d16..95da79b9513deced964b1fd618ad7cab8ef9f6d2 100644 (file)
@@ -7,8 +7,10 @@
 #include "SketchPlugin_Validators.h"
 #include "SketchPlugin_ConstraintDistance.h"
 #include "SketchPlugin_ConstraintCoincidence.h"
+#include "SketchPlugin_ConstraintRigid.h"
 #include "SketchPlugin_Line.h"
 #include "SketchPlugin_Arc.h"
+#include "SketchPlugin_Circle.h"
 
 #include "SketcherPrs_Tools.h"
 
@@ -93,7 +95,8 @@ bool SketchPlugin_TangentAttrValidator::isValid(
       if (aOtherFea->getKind() != SketchPlugin_Arc::ID())
         return false;
     } else if (aRefFea->getKind() == SketchPlugin_Arc::ID()) {
-      if (aOtherFea->getKind() != SketchPlugin_Line::ID())
+      if (aOtherFea->getKind() != SketchPlugin_Line::ID() &&
+          aOtherFea->getKind() != SketchPlugin_Arc::ID())
         return false;
     } else
       return false;
@@ -135,4 +138,76 @@ bool SketchPlugin_TangentAttrValidator::isValid(
   return false;
 }
 
+bool SketchPlugin_NotFixedValidator::isValid(
+    const AttributePtr& theAttribute, const std::list<std::string>& theArguments) const
+{
+  std::shared_ptr<SketchPlugin_Feature> aFeature =
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
+  if (!aFeature)
+    return true;
+
+  AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+  if (!aRefAttr)
+    return false;
+
+  SketchPlugin_Sketch* aSketch = aFeature->sketch();
+  int aNbFeatures = aSketch->numberOfSubs();
+  for (int anInd = 0; anInd < aNbFeatures; anInd++) {
+    FeaturePtr aSubFeature = aSketch->subFeature(anInd);
+    if (aSubFeature->getKind() != SketchPlugin_ConstraintRigid::ID() || aSubFeature == aFeature)
+      continue;
+    AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+        aSubFeature->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
+    if (aRefAttr->isObject()) {
+      if (aRefAttr->object() == aRAttr->object())
+        return false;
+    } else if (aRefAttr->attr() == aRAttr->attr())
+      return false;
+  }
+  return true;
+}
+
+bool SketchPlugin_EqualAttrValidator::isValid(
+  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
+{
+  std::string aParamA = theArguments.front();
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  AttributeRefAttrPtr aRefAttr[2];
+  aRefAttr[0] = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+  if (!aRefAttr)
+    return false;
+  aRefAttr[1] = aFeature->data()->refattr(aParamA);
+
+  if (!aRefAttr[0]->isObject() || !aRefAttr[1]->isObject())
+    return false;
+
+  int aType[2] = {0, 0}; // types of attributes: 0 - incorrect, 1 - line, 2 - circle, 3 - arc
+  std::list<std::string> anArguments;
+  for (int i = 0; i < 2; i++) {
+    ObjectPtr anObject = aRefAttr[i]->object();
+    aFeature = ModelAPI_Feature::feature(anObject);
+    if (!aFeature)
+      return false;
+
+    if (aFeature->getKind() == SketchPlugin_Line::ID()) {
+      aType[i] = 1;
+      continue;
+    }
+    if (aFeature->getKind() == SketchPlugin_Circle::ID()) {
+      aType[i] = 2;
+      continue;
+    }
+    if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
+      aType[i] = 3;
+      continue;
+    }
+    // wrong type of attribute
+    return false;
+  }
+
+  if ((aType[0] == 1 && aType[1] == 2) ||
+      (aType[0] == 2 && aType[1] == 1))
+    return false;
+  return true;
+}
 
index 11721fbd1dfd654190b980d2ea91f650b62943dc..47df3706156129b4cfacac9f4891d6bc0b733bc9 100644 (file)
@@ -44,4 +44,37 @@ class SketchPlugin_TangentAttrValidator : public ModelAPI_AttributeValidator
 };
 
 
+/**\class SketchPlugin_NotFixed
+ * \ingroup Validators
+ * \brief Validator for the rigid constraint input.
+ *
+ * It just checks there is no rigid constraint for the current feature.
+ */
+class SketchPlugin_NotFixedValidator : public ModelAPI_AttributeValidator
+{
+ public:
+  //! returns true if attribute is not used in another rigid constraint
+  //! \param theAttribute the checked attribute
+  //! \param theArguments arguments of the attribute
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments) const;
+};
+
+/**\class SketchPlugin_EqualAttrValidator
+ * \ingroup Validators
+ * \brief Validator for the equal constraint input.
+ *
+ * It checks that attributes of the Equal constraint are correct.
+ */
+class SketchPlugin_EqualAttrValidator : public ModelAPI_AttributeValidator
+{
+ public:
+  //! returns true if attribute is valid
+  //! \param theAttribute the checked attribute
+  //! \param theArguments arguments of the attribute
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments) const;
+};
+
+
 #endif
index 7274cc18dab72adb9939c9da12a5904ad506d7d5..04730f8fc9538824ba28a4e04c60c4e574f6cf0b 100644 (file)
         <shape_selector id="ConstraintEntityA" label="Object" tooltip="Select an object" 
             shape_types="edge vertex">
           <validator id="PartSet_SketchEntityValidator" parameters="SketchPoint,SketchLine,SketchCircle,SketchArc"/>
+          <validator id="SketchPlugin_NotFixed"/>
         </shape_selector>
         <validator id="PartSet_RigidValidator"/>
       </feature>
         
         <sketch_constraint_shape_selector id="ConstraintEntityB"
             label="Last object" tooltip="Select line, circle or arc" shape_types="edge">
-          <validator id="PartSet_SameTypeAttr" parameters="ConstraintEntityA"/>
+          <validator id="SketchPlugin_EqualAttr" parameters="ConstraintEntityA"/>
           <validator id="PartSet_DifferentObjects"/>
         </sketch_constraint_shape_selector>
       </feature>
index 9b0ae4325756fb0ae42fef3ff50a45b56a89aeb7..f54067afa647d3c20c62e7a9d85a5bff5a328ade 100644 (file)
@@ -687,10 +687,10 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
   for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) {
     aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
     aBaseFeature = aRC ? aRC->document()->feature(aRC) :
-        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
+        std::dynamic_pointer_cast<ModelAPI_Feature>(*aBaseIter);
     aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirIter);
     aMirrorFeature = aRC ? aRC->document()->feature(aRC) :
-        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirIter);
+        std::dynamic_pointer_cast<ModelAPI_Feature>(*aMirIter);
 
     if (!aBaseFeature || !aMirrorFeature || 
         aBaseFeature->getKind() != aMirrorFeature->getKind())
@@ -745,6 +745,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
           Slvs_hParam v = changeParameter(y, aParamIter);
           Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v);
           myEntities.push_back(aPoint);
+          myEntOfConstr.push_back(true);
           aBothMiddlePoints[i] = aPoint.h;
           // additional constraint point-on-curve
           Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint(
@@ -752,6 +753,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
               aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN);
           myConstraints.push_back(aPonCircConstr);
           myConstraintMap[theConstraint].push_back(aPonCircConstr.h);
+          aNewConstraints.push_back(aPonCircConstr.h);
         }
 
         aBaseArcPoints[2] = aBothMiddlePoints[0];
@@ -806,16 +808,51 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
     for (aBaseIter = aBaseList.begin(); aBaseIter != aBaseList.end(); aBaseIter++) {
       aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
       aBaseFeature = aRC ? aRC->document()->feature(aRC) :
-          std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
+          std::dynamic_pointer_cast<ModelAPI_Feature>(*aBaseIter);
       if (!aBaseFeature) continue;
       std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-      std::list<AttributePtr>::iterator anIt = aPoints.begin();
-      for ( ; anIt != aPoints.end(); anIt++) {
+      if (aBaseFeature->getKind() != SketchPlugin_Arc::ID()) {
+        std::list<AttributePtr>::iterator anIt = aPoints.begin();
+        for ( ; anIt != aPoints.end(); anIt++) {
+          addTemporaryConstraintWhereDragged(*anIt);
+        }
+      } else {
         // Arcs are fixed by center and start points only (to avoid solving errors in SolveSpace)
-        if (aBaseFeature->getKind() == SketchPlugin_Arc::ID() &&
-            (*anIt)->id() == SketchPlugin_Arc::END_ID())
-          continue;
-        addTemporaryConstraintWhereDragged(*anIt);
+        AttributePtr aCenterAttr = aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID());
+        std::map<AttributePtr, Slvs_hEntity>::iterator aFound = myEntityAttrMap.find(aCenterAttr);
+        Slvs_hEntity anArcPoints[3] = {aFound->second, 0, 0};
+        AttributePtr aStartAttr = aBaseFeature->attribute(SketchPlugin_Arc::START_ID());
+        aFound = myEntityAttrMap.find(aStartAttr);
+        anArcPoints[1] = aFound->second;
+        AttributePtr aEndAttr = aBaseFeature->attribute(SketchPlugin_Arc::END_ID());
+        aFound = myEntityAttrMap.find(aEndAttr);
+        anArcPoints[2] = aFound->second;
+
+        bool isFixed[3] = {false, false, false};
+        int aNbFixed = 0; // number of already fixed points on the arc
+        for (int i = 0; i < 3; i++) {
+          std::vector<std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+          for (; aCoPtIter != myCoincidentPoints.end() && !isFixed[i]; aCoPtIter++) {
+            if (aCoPtIter->find(anArcPoints[i]) == aCoPtIter->end())
+              continue;  // the entity was not found in current set
+
+            // Find one of already created SLVS_C_WHERE_DRAGGED constraints in current set of coincident points
+            std::vector<Slvs_Constraint>::iterator aConstrIter = myConstraints.begin();
+            for (; aConstrIter != myConstraints.end(); aConstrIter++)
+              if (aConstrIter->type == SLVS_C_WHERE_DRAGGED && 
+                  aCoPtIter->find(aConstrIter->ptA) != aCoPtIter->end()) {
+                isFixed[i] = true;
+                aNbFixed++;
+                break;  // the SLVS_C_WHERE_DRAGGED constraint already exists
+              }
+          }
+        }
+        if (aNbFixed < 2) { // append constraints
+          if (!isFixed[0])
+            addTemporaryConstraintWhereDragged(aCenterAttr);
+          if (!isFixed[1] && (isFixed[0] || aNbFixed == 0))
+            addTemporaryConstraintWhereDragged(aStartAttr);
+        }
       }
     }
   }
@@ -921,7 +958,7 @@ bool SketchSolver_ConstraintGroup::changeFilletConstraint(
   for (int indEnt = 0; aFilIter != aFilletList.end(); aFilIter++, indEnt++) {
     aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aFilIter);
     aFilletFeature = aRC ? aRC->document()->feature(aRC) :
-        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFilIter);
+        std::dynamic_pointer_cast<ModelAPI_Feature>(*aFilIter);
     if (!aFilletFeature)
       return false;
     aFilletEnt[indEnt] = changeEntityFeature(aFilletFeature);
@@ -1080,7 +1117,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
   std::map<std::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator aEntIter =
       myEntityAttrMap.find(theEntity);
   int aEntPos;
-  std::vector<Slvs_Param>::const_iterator aParamIter;  // looks at first parameter of already existent entity or at the end of vector otherwise
+  std::vector<Slvs_Param>::iterator aParamIter;  // looks at first parameter of already existent entity or at the end of vector otherwise
   if (aEntIter == myEntityAttrMap.end())  // no such entity => should be created
     aParamIter = myParams.end();
   else {  // the entity already exists
@@ -1297,7 +1334,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeNormal(
   // Try to find existent normal
   std::map<std::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator aEntIter =
       myEntityAttrMap.find(theNorm);
-  std::vector<Slvs_Param>::const_iterator aParamIter;  // looks to the first parameter of already existent entity or to the end of vector otherwise
+  std::vector<Slvs_Param>::iterator aParamIter;  // looks to the first parameter of already existent entity or to the end of vector otherwise
   if (aEntIter == myEntityAttrMap.end())  // no such entity => should be created
     aParamIter = myParams.end();
   else {  // the entity already exists, update it
@@ -1378,7 +1415,7 @@ bool SketchSolver_ConstraintGroup::updateWorkplane()
 //  Purpose:  create/update value of parameter
 // ============================================================================
 Slvs_hParam SketchSolver_ConstraintGroup::changeParameter(
-    const double& theParam, std::vector<Slvs_Param>::const_iterator& thePrmIter)
+    double theParam, std::vector<Slvs_Param>::iterator& thePrmIter)
 {
   if (thePrmIter != myParams.end()) {  // Parameter should be updated
     int aParamPos = thePrmIter - myParams.begin();
@@ -2143,9 +2180,16 @@ void SketchSolver_ConstraintGroup::makeMirrorEntity(const Slvs_hEntity& theBase,
   Slvs_Entity aBase = myEntities[Search(theBase, myEntities)];
   Slvs_Entity aMirror = myEntities[Search(theMirror, myEntities)];
   int i = 0;
-  while (aBase.point[i] != 0 && aMirror.point[i] != 0) {
-    makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine);
-    i++;
+  if (aBase.type != SLVS_E_ARC_OF_CIRCLE) {
+    while (aBase.point[i] != 0 && aMirror.point[i] != 0) {
+      makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine);
+      i++;
+    }
+  } else {
+    // swap mirroring first and last points of an arc
+    makeMirrorEntity(aBase.point[0], aMirror.point[0], theMirrorLine);
+    makeMirrorEntity(aBase.point[1], aMirror.point[2], theMirrorLine);
+    makeMirrorEntity(aBase.point[2], aMirror.point[1], theMirrorLine);
   }
   if (aBase.param[0] != 0 && aMirror.param[0] != 0) { // this is a point, copy it
     Slvs_Entity aMirrorLine = myEntities[Search(theMirrorLine, myEntities)];
@@ -2192,7 +2236,7 @@ Slvs_hConstraint SketchSolver_ConstraintGroup::changeMirrorPoints(
   std::map<Slvs_hEntity, Slvs_hEntity>::iterator aMapIter = thePrevMirror.find(theBasePoint);
   if (aMapIter != thePrevMirror.end()) {
     thePrevMirror.erase(aMapIter);
-    std::vector<Slvs_Constraint>::const_iterator anIter = thePrevConstr.begin();
+    std::vector<Slvs_Constraint>::iterator anIter = thePrevConstr.begin();
     for (; anIter != thePrevConstr.end(); anIter++)
       if (anIter->ptA == theBasePoint) {
         if (anIter->ptB != theMirrorPoint) {
index 73dc23d633c878c870d9fe8113f4d63c223af8f4..8ec26852fac14300c69639231ec902a1d470999f 100644 (file)
@@ -168,8 +168,8 @@ protected:
    *                        (the iterator will be increased if it does not reach the end of the list)
    *  \return identifier of changed parameter; when the parameter cannot be created, returned ID is 0
    */
-  Slvs_hParam changeParameter(const double& theParam,
-                              std::vector<Slvs_Param>::const_iterator& thePrmIter);
+  Slvs_hParam changeParameter(double theParam,
+                              std::vector<Slvs_Param>::iterator& thePrmIter);
 
   /** \brief Removes specified entities and their parameters
    *  \param[in] theEntities  list of IDs of the entities to be removed
index 1fafcf506b8e03cc5c2f5068d7e7f9febda211d1..bd346fb35fe35fac2343b7ff27b2600dae9c9544 100644 (file)
@@ -117,7 +117,7 @@ void SketchSolver_ConstraintManager::processEvent(
       for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
         std::shared_ptr<SketchPlugin_Feature> aFeature = 
           std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
-        if (!aFeature || aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
+        if (!aFeature /*|| aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()*/)
           continue;
         changeConstraintOrEntity(aFeature);
       }
index 60c2e451a1df0b7da64d621f447c292ec4c9bef0..86f1a1f3e53fee0ca76d99dfa9c9b1ab4ed8b056 100644 (file)
@@ -25,6 +25,9 @@
 #include <Graphic3d_ArrayOfPoints.hxx>
 #include <Prs3d_PointAspect.hxx>
 #include <Prs3d_Root.hxx>
+#include <SelectMgr_EntityOwner.hxx>
+#include <SelectMgr_Selection.hxx>
+#include <Select3D_SensitivePoint.hxx>
 
 
 IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Coincident, AIS_InteractiveObject);
@@ -34,6 +37,7 @@ SketcherPrs_Coincident::SketcherPrs_Coincident(SketchPlugin_Constraint* theConst
                                                const std::shared_ptr<GeomAPI_Ax3>& thePlane) 
  : AIS_InteractiveObject(), myConstraint(theConstraint), myPlane(thePlane)
 {
+  
 }  
 
 
@@ -48,11 +52,15 @@ void SketcherPrs_Coincident::Compute(const Handle(PrsMgr_PresentationManager3d)&
     return;
 
   std::shared_ptr<GeomAPI_Pnt> aPoint = myPlane->to3D(aPnt->x(), aPnt->y());
-
-  static Handle(Graphic3d_AspectMarker3d) aPtA = new Graphic3d_AspectMarker3d ();
-  aPtA->SetType(Aspect_TOM_RING1);
-  aPtA->SetScale(2.);
-  aPtA->SetColor(myOwnColor);
+  myPoint = aPoint->impl<gp_Pnt>();
+
+  static Handle(Graphic3d_AspectMarker3d) aPtA;
+  if (aPtA.IsNull()) {
+    aPtA = new Graphic3d_AspectMarker3d ();
+    aPtA->SetType(Aspect_TOM_RING1);
+    aPtA->SetScale(2.);
+    aPtA->SetColor(myOwnColor);
+  }
   Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup(thePresentation);
   aGroup->SetPrimitivesAspect(aPtA);
   Handle(Graphic3d_ArrayOfPoints) aPntArray = new Graphic3d_ArrayOfPoints(1);
@@ -64,6 +72,9 @@ void SketcherPrs_Coincident::Compute(const Handle(PrsMgr_PresentationManager3d)&
 void SketcherPrs_Coincident::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
                                             const Standard_Integer aMode)
 {
+  Handle(SelectMgr_EntityOwner) aOwn = new SelectMgr_EntityOwner(this, 10);
+  Handle(Select3D_SensitivePoint) aSp = new Select3D_SensitivePoint(aOwn, myPoint);
+  aSelection->Add(aSp);
 }
 
 void SketcherPrs_Coincident::SetColor(const Quantity_NameOfColor aCol)
index 9b9c4cd8acc347825b1e22fef1aebac86e6b6a7f..72c7ec5d01a9494ab707016fc3bc8fae66e0b9d0 100644 (file)
@@ -47,6 +47,7 @@ protected:
 private:
   SketchPlugin_Constraint* myConstraint;
   std::shared_ptr<GeomAPI_Ax3> myPlane;
+  gp_Pnt myPoint;
 };
 
 
index 07957c4dbb458f3c812a4e8aa551973c70e6ea0d..5e30f527fa95dd82ef66758e8b5b27c2e3aedfe6 100644 (file)
@@ -13,7 +13,7 @@
 #include <SketchPlugin_Arc.h>
 
 #include <GeomDataAPI_Point2D.h>
-#include <GeomAPI_Pnt2D.h>
+#include <GeomAPI_Pnt2d.h>
 #include <GeomAPI_Circ.h>
 #include <GeomAPI_XYZ.h>
 #include <ModelAPI_AttributeDouble.h>
index 282b1a31cce1b9206fab121f02b79a98005e5d38..91d5c2f7cc99c9831aea1cf8e7e85844c6e57d5a 100644 (file)
@@ -227,40 +227,49 @@ QMenu* XGUI_ContextMenuMgr::viewerMenu() const
 
 void XGUI_ContextMenuMgr::addViewerItems(QMenu* theMenu) const
 {
-  XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
-  QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
-  if (aObjects.size() > 0) {
-    //if (aObjects.size() == 1)
-    //  theMenu->addAction(action("EDIT_CMD"));
-    bool isVisible = false;
-    bool isShading = false;
-    bool canBeShaded = false;
-    foreach(ObjectPtr aObject, aObjects)
-    {
-      ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
-      if (aRes && myWorkshop->displayer()->isVisible(aRes)) {
-        isVisible = true;
-        canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
-        isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);      
-        break;
+  bool aIsDone = false;
+  ModuleBase_IModule* aModule = myWorkshop->module();
+  if (aModule) 
+    aIsDone = aModule->addViewerItems(theMenu, myActions);
+
+  if (!aIsDone) {
+    XGUI_SelectionMgr* aSelMgr = myWorkshop->selector();
+    QObjectPtrList aObjects = aSelMgr->selection()->selectedObjects();
+    if (aObjects.size() > 0) {
+      //if (aObjects.size() == 1)
+      //  theMenu->addAction(action("EDIT_CMD"));
+      bool isVisible = false;
+      bool isShading = false;
+      bool canBeShaded = false;
+      foreach(ObjectPtr aObject, aObjects)
+      {
+        ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
+        if (aRes && myWorkshop->displayer()->isVisible(aRes)) {
+          isVisible = true;
+          canBeShaded = myWorkshop->displayer()->canBeShaded(aObject);
+          isShading = (myWorkshop->displayer()->displayMode(aObject) == XGUI_Displayer::Shading);      
+          break;
+        }
       }
+      if (isVisible) {
+        if (canBeShaded) {
+          if (isShading)
+            theMenu->addAction(action("WIREFRAME_CMD"));
+          else
+            theMenu->addAction(action("SHADING_CMD"));
+        }
+        theMenu->addSeparator();
+        theMenu->addAction(action("SHOW_ONLY_CMD"));
+        theMenu->addAction(action("HIDE_CMD"));
+      } else
+        theMenu->addAction(action("SHOW_CMD"));
+      //theMenu->addAction(action("DELETE_CMD"));
     }
-    if (isVisible) {
-      if (canBeShaded) {
-        if (isShading)
-          theMenu->addAction(action("WIREFRAME_CMD"));
-        else
-          theMenu->addAction(action("SHADING_CMD"));
-      }
-      theMenu->addSeparator();
-      theMenu->addAction(action("SHOW_ONLY_CMD"));
-      theMenu->addAction(action("HIDE_CMD"));
-    } else
-      theMenu->addAction(action("SHOW_CMD"));
-    //theMenu->addAction(action("DELETE_CMD"));
+    if (myWorkshop->canChangeColor())
+      theMenu->addAction(action("COLOR_CMD"));
+    if (myWorkshop->displayer()->objectsCount() > 0)
+      theMenu->addAction(action("HIDEALL_CMD"));
   }
-  if (myWorkshop->displayer()->objectsCount() > 0)
-    theMenu->addAction(action("HIDEALL_CMD"));
   if (!myWorkshop->isSalomeMode()) {
     theMenu->addSeparator();
     QMdiArea* aMDI = myWorkshop->mainWindow()->mdiArea();
@@ -269,12 +278,7 @@ void XGUI_ContextMenuMgr::addViewerItems(QMenu* theMenu) const
       aSubMenu->addActions(aMDI->actions());
     }
   }
-  if (myWorkshop->canChangeColor())
-    theMenu->addAction(action("COLOR_CMD"));
 
-  ModuleBase_IModule* aModule = myWorkshop->module();
-  if (aModule)
-    aModule->addViewerItems(theMenu);
 }
 
 void XGUI_ContextMenuMgr::connectObjectBrowser() const