Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom.git into Dev_1.1.0
authorsbh <sergey.belash@opencascade.com>
Wed, 8 Apr 2015 18:00:36 +0000 (21:00 +0300)
committersbh <sergey.belash@opencascade.com>
Wed, 8 Apr 2015 18:00:36 +0000 (21:00 +0300)
46 files changed:
src/Model/Model_AttributeRefList.cpp
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_AttributeSelectionList.cpp
src/Model/Model_Document.cpp
src/ModelAPI/ModelAPI_Attribute.h
src/ModuleBase/ModuleBase_FilterValidated.cpp
src/PartSet/PartSet_MenuMgr.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_SketcherMgr.cpp
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_Validators.h
src/PartSet/PartSet_WidgetEditor.cpp
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/mirror.png [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/SketchPlugin_Sketch.cpp
src/SketchPlugin/SketchPlugin_Sketch.h
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_Validators.h
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_Constraint.cpp
src/SketchSolver/SketchSolver_ConstraintCoincidence.cpp
src/SketchSolver/SketchSolver_ConstraintRigid.cpp
src/SketchSolver/SketchSolver_FeatureStorage.cpp
src/SketchSolver/SketchSolver_Group.cpp
src/SketchSolver/SketchSolver_Storage.cpp
src/SketcherPrs/CMakeLists.txt
src/SketcherPrs/SketcherPrs_Coincident.cpp
src/SketcherPrs/SketcherPrs_Equal.cpp
src/SketcherPrs/SketcherPrs_Factory.cpp
src/SketcherPrs/SketcherPrs_Factory.h
src/SketcherPrs/SketcherPrs_Mirror.cpp [new file with mode: 0644]
src/SketcherPrs/SketcherPrs_Mirror.h [new file with mode: 0644]
src/SketcherPrs/SketcherPrs_Rigid.cpp
src/SketcherPrs/SketcherPrs_SymbolPrs.cpp
src/SketcherPrs/SketcherPrs_SymbolPrs.h
src/SketcherPrs/SketcherPrs_Tangent.cpp
src/SketcherPrs/SketcherPrs_Tools.cpp
src/SketcherPrs/icons/mirror.png [new file with mode: 0644]
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_Displayer.cpp

index c09190f3326da11cd0057ac0236d4397780762c9..13233fb9c4e0128becbf03d324014051ceb4539e 100644 (file)
@@ -29,6 +29,7 @@ void Model_AttributeRefList::remove(ObjectPtr theObject)
   if (theObject.get() != NULL) {
     aData = std::dynamic_pointer_cast<Model_Data>(theObject->data());
     myRef->Remove(aData->label().Father());
+    REMOVE_BACK_REF(theObject);
   }
   else { // in case of empty object remove, the first empty object is removed from the list
     std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(
index 3e23333451931c81706be68835312774179d2a04..b522b90a14129a9ab8c084943d5a69adce963db2 100644 (file)
@@ -171,6 +171,12 @@ Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel)
   myIsInitialized = myRef.isInitialized();
 }
 
+void Model_AttributeSelection::setID(const std::string theID)
+{
+  myRef.setID(theID);
+  ModelAPI_AttributeSelection::setID(theID);
+}
+
 ResultPtr Model_AttributeSelection::context() {
   return std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
 }
index 8708c136dc932defde1ecfba2c0761475841ee7f..22aaf8d9f9b831476ba6d1c63d47701f7570f6b3 100644 (file)
@@ -71,6 +71,9 @@ protected:
   /// Returns the prepared map of valid labels for naming selection solving (creates if not exists)
   TDF_LabelMap& scope();
 
+  /// Sets the ID of the attribute in Data (called from Data): here it is used for myRef ID setting
+  MODELAPI_EXPORT virtual void setID(const std::string theID);
+
   friend class Model_Data;
   friend class Model_AttributeSelectionList;
 };
index 24a9efca5308d5684d3030a0b55c6ac5d4fd8f54..79eb5c714e12ee2e5565c209dfb271f3d793b389 100644 (file)
@@ -39,6 +39,7 @@ void Model_AttributeSelectionList::append(
   if (owner()) {
     aNewAttr->setObject(owner());
   }
+  aNewAttr->setID(id());
   mySize->Set(aNewTag);
   aNewAttr->setValue(theContext, theSubShape);
   owner()->data()->sendAttributeUpdated(this);
index 24854af14fadc84360d1dd9799c0e90d4622e705..5ac695f1d094c93722b2c96e84992315c2bdcb76 100644 (file)
@@ -405,13 +405,13 @@ void Model_Document::abortOperation()
       myDoc->Undo();
     myDoc->ClearRedos();
   }
-  // references may be changed because they are set in attributes on the fly
-  synchronizeFeatures(true, true, isRoot());
-  // abort for all subs
+  // abort for all subs, flushes will be later, in the end of root abort
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
   for (; aSubIter != aSubs.end(); aSubIter++)
     subDoc(*aSubIter)->abortOperation();
+  // references may be changed because they are set in attributes on the fly
+  synchronizeFeatures(true, true, isRoot());
 }
 
 bool Model_Document::isOperation() const
index 1892b77bc8c5687367d091a559fc67a7451450b5..e3b1b056df9514052fe2bfebd6f256c5320b56e9 100644 (file)
@@ -77,7 +77,7 @@ class ModelAPI_Attribute
   MODELAPI_EXPORT ModelAPI_Attribute();
 
   /// Sets the ID of the attribute in Data (called from Data)
-  MODELAPI_EXPORT void setID(const std::string theID);
+  MODELAPI_EXPORT virtual void setID(const std::string theID);
 
   friend class Model_Data;
 };
index a6336d3533360bdf3c7c3f7e345ca44a297a4dfe..5bb26dac55ac995691f02fc411ba322317e6ba63 100644 (file)
@@ -18,8 +18,10 @@ IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_FilterValidated, SelectMgr_Filter);
 Standard_Boolean ModuleBase_FilterValidated::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const
 {
   ModuleBase_Operation* anOperation = myWorkshop->module()->currentOperation();
-  ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+  if (!anOperation)
+    return true;
 
+  ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
   ModuleBase_ModelWidget* anActiveWidget = aPanel->activeWidget();
   ModuleBase_WidgetValidated* aWidgetValidated = dynamic_cast<ModuleBase_WidgetValidated*>
                                                                           (anActiveWidget);
index 9b02aee05ecdbd39b3fba60be968560c08d644b6..7e0442d5157b35de44ef3bd628566f602b177672 100644 (file)
@@ -7,6 +7,7 @@
 #include "PartSet_MenuMgr.h"
 #include "PartSet_Module.h"
 #include "PartSet_SketcherMgr.h"
+#include "PartSet_Tools.h"
 
 #include <GeomAPI_Pnt2d.h>
 #include <GeomDataAPI_Point2D.h>
@@ -15,6 +16,7 @@
 #include <SketchPlugin_Line.h>
 #include <SketchPlugin_Circle.h>
 #include <SketchPlugin_Point.h>
+#include <SketchPlugin_Sketch.h>
 
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_Operation.h>
@@ -30,6 +32,9 @@
 #include <QAction>
 #include <QMenu>
 
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+
 PartSet_MenuMgr::PartSet_MenuMgr(PartSet_Module* theModule)
   : QObject(theModule), myModule(theModule), myPrevId(-1)
 {
@@ -117,7 +122,7 @@ void findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>& theList, std::
   if (!theList.contains(aObj)) {
     std::shared_ptr<GeomAPI_Pnt2d> aOrig = getPoint(theStartCoin, theAttr);
     theList.append(aObj);
-    const std::set<AttributePtr> aRefsList = aObj->data()->refsToMe();
+    const std::set<AttributePtr>& aRefsList = aObj->data()->refsToMe();
     std::set<AttributePtr>::const_iterator aIt;
     for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
@@ -143,43 +148,76 @@ bool PartSet_MenuMgr::addViewerItems(QMenu* theMenu, const QMap<QString, QAction
 
   myCoinsideLines.clear();
   ModuleBase_ISelection* aSelection = myModule->workshop()->selection();
-  QObjectPtrList aObjects = aSelection->selectedPresentations();
-  if (aObjects.size() > 0) {
+
+  NCollection_List<TopoDS_Shape> aShapeList;
+  std::list<ObjectPtr> aObjectsList;
+  aSelection->selectedShapes(aShapeList, aObjectsList);
+  bool aIsDetach = false;
+
+  if (aShapeList.Extent() == 1) {
+    TopoDS_Shape aShape = aShapeList.First();
+    if (aShape.ShapeType() == TopAbs_VERTEX) {
+      // Find 2d coordinates
+      FeaturePtr aSketchFea = myModule->sketchMgr()->activeSketch();
+      std::shared_ptr<SketchPlugin_Sketch> aSketch = 
+        std::dynamic_pointer_cast<SketchPlugin_Sketch>(aSketchFea);
+      gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
+      std::shared_ptr<GeomAPI_Pnt> aPnt3d(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
+      std::shared_ptr<GeomAPI_Pnt2d> aSelPnt = aSketch->to2D(aPnt3d);
+
+      // Find coincident in these coordinates
+      ObjectPtr aObj = aObjectsList.front();
+      FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
+      const std::set<AttributePtr>& aRefsList = aFeature->data()->refsToMe();
+      std::set<AttributePtr>::const_iterator aIt;
+      FeaturePtr aCoincident;
+      for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+        std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+        FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+        if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
+          std::shared_ptr<GeomAPI_Pnt2d> a2dPnt = getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A());
+          if (aSelPnt->isEqual(a2dPnt)) {
+            aCoincident = aConstrFeature;
+            break;
+          }
+        }
+      }
+      // If we have coincidence then add Detach menu
+      if (aCoincident.get() != NULL) {
+        mySelectedFeature = aCoincident;
+        findCoincidences(mySelectedFeature, myCoinsideLines, SketchPlugin_ConstraintCoincidence::ENTITY_A());
+        findCoincidences(mySelectedFeature, myCoinsideLines, SketchPlugin_ConstraintCoincidence::ENTITY_B());
+        if (myCoinsideLines.size() > 0) {
+          aIsDetach = true;
+          QMenu* aSubMenu = theMenu->addMenu(tr("Detach"));
+          QAction* aAction;
+          int i = 0;
+          foreach (FeaturePtr aCoins, myCoinsideLines) {
+            aAction = aSubMenu->addAction(aCoins->data()->name().c_str());
+            aAction->setData(QVariant(i));
+            i++;
+          }
+          connect(aSubMenu, SIGNAL(hovered(QAction*)), SLOT(onLineHighlighted(QAction*)));
+          connect(aSubMenu, SIGNAL(aboutToHide()), SLOT(onDetachMenuHide()));
+          connect(aSubMenu, SIGNAL(triggered(QAction*)), SLOT(onLineDetach(QAction*)));
+        } 
+      }
+    }
+  }
+  if ((!aIsDetach) && (aObjectsList.size() > 0)) {
     bool hasFeature = false;
     FeaturePtr aFeature;
-    foreach(ObjectPtr aObject, aObjects) {
+    std::list<ObjectPtr>::const_iterator aIt;
+    ObjectPtr aObject;
+    for (aIt = aObjectsList.cbegin(); aIt != aObjectsList.cend(); ++aIt) {
+      aObject = (*aIt);
       aFeature = ModelAPI_Feature::feature(aObject);
       if (aFeature.get() != NULL) {
         hasFeature = true;
       }
     }
-    if (hasFeature) {
-      bool aIsDetach = false;
-      if (aObjects.size() == 1) {
-        if (aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
-          /// If the feature is coincident then we use Detach command instead Delete
-          mySelectedFeature = aFeature;
-          findCoincidences(mySelectedFeature, myCoinsideLines, SketchPlugin_ConstraintCoincidence::ENTITY_A());
-          findCoincidences(mySelectedFeature, myCoinsideLines, SketchPlugin_ConstraintCoincidence::ENTITY_B());
-          if (myCoinsideLines.size() > 0) {
-            aIsDetach = true;
-            QMenu* aSubMenu = theMenu->addMenu(tr("Detach"));
-            QAction* aAction;
-            int i = 0;
-            foreach (FeaturePtr aCoins, myCoinsideLines) {
-              aAction = aSubMenu->addAction(aCoins->data()->name().c_str());
-              aAction->setData(QVariant(i));
-              i++;
-            }
-            connect(aSubMenu, SIGNAL(hovered(QAction*)), SLOT(onLineHighlighted(QAction*)));
-            connect(aSubMenu, SIGNAL(aboutToHide()), SLOT(onDetachMenuHide()));
-            connect(aSubMenu, SIGNAL(triggered(QAction*)), SLOT(onLineDetach(QAction*)));
-          } 
-        }
-      } 
-      if (!aIsDetach)
+    if (hasFeature)
         theMenu->addAction(theStdActions["DELETE_CMD"]);
-    }
   }
   bool isAuxiliary;
   if (canSetAuxiliary(isAuxiliary)) {
index 3d22b28a7bd9f3891ee04352bf40ea4d475fd6c3..b81a64bb3291fb07b2280883008df0594e201f99 100644 (file)
@@ -130,12 +130,17 @@ void PartSet_Module::registerValidators()
   //Registering of validators
   SessionPtr aMgr = ModelAPI_Session::get();
   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
-  aFactory->registerValidator("PartSet_DistanceValidator", new PartSet_DistanceValidator);
-  aFactory->registerValidator("PartSet_LengthValidator", new PartSet_LengthValidator);
-  aFactory->registerValidator("PartSet_PerpendicularValidator", new PartSet_PerpendicularValidator);
-  aFactory->registerValidator("PartSet_ParallelValidator", new PartSet_ParallelValidator);
-  aFactory->registerValidator("PartSet_RadiusValidator", new PartSet_RadiusValidator);
-  aFactory->registerValidator("PartSet_RigidValidator", new PartSet_RigidValidator);
+  aFactory->registerValidator("PartSet_DistanceSelection", new PartSet_DistanceSelection);
+  aFactory->registerValidator("PartSet_LengthSelection", new PartSet_LengthSelection);
+  aFactory->registerValidator("PartSet_PerpendicularSelection", new PartSet_PerpendicularSelection);
+  aFactory->registerValidator("PartSet_ParallelSelection", new PartSet_ParallelSelection);
+  aFactory->registerValidator("PartSet_RadiusSelection", new PartSet_RadiusSelection);
+  aFactory->registerValidator("PartSet_RigidSelection", new PartSet_RigidSelection);
+  aFactory->registerValidator("PartSet_CoincidentSelection", new PartSet_CoincidentSelection);
+  aFactory->registerValidator("PartSet_HVDirSelection", new PartSet_HVDirSelection);
+  aFactory->registerValidator("PartSet_TangentSelection", new PartSet_TangentSelection);
+  aFactory->registerValidator("PartSet_FilletSelection", new PartSet_FilletSelection);
+
   aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator);
   aFactory->registerValidator("PartSet_DifferentShapes", new ModelAPI_ShapeValidator);
 
index 359ee319e664327a795cd3f50fb7ba48ddc55763..40578fa8ad51a528d185926d14aefe0734784c9a 100644 (file)
@@ -157,18 +157,23 @@ PartSet_SketcherMgr::~PartSet_SketcherMgr()
 
 void PartSet_SketcherMgr::onEnterViewPort()
 {
-  if (!isNestedCreateOperation(getCurrentOperation()))
-    return;
   // 1. if the mouse over window, update the next flag. Do not perform update visibility of
   // created feature because it should be done in onMouseMove(). Some widgets watch
   // the mouse move and use the cursor position to update own values. If the presentaion is
   // redisplayed before this update, the feature presentation jumps from reset value to current.
   myIsMouseOverWindow = true;
   myIsPropertyPanelValueChanged = false;
+
+  if (!isNestedCreateOperation(getCurrentOperation()))
+    return;
 }
 
 void PartSet_SketcherMgr::onLeaveViewPort()
 {
+  myIsMouseOverViewProcessed = false;
+  myIsMouseOverWindow = false;
+  myIsPropertyPanelValueChanged = false;
+
   if (!isNestedCreateOperation(getCurrentOperation()))
     return;
   // the method should be performed if the popup menu is called,
@@ -176,9 +181,6 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   if (myIsPopupMenuActive)
     return;
 
-  myIsMouseOverViewProcessed = false;
-  myIsMouseOverWindow = false;
-
   // 2. if the mouse IS NOT over window, reset the active widget value and hide the presentation
   ModuleBase_IWorkshop* aWorkshop = myModule->workshop();
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(aWorkshop);
@@ -195,7 +197,7 @@ void PartSet_SketcherMgr::onLeaveViewPort()
   aDisplayer->enableUpdateViewer(isEnableUpdateViewer);
 
   // hides the presentation of the current operation feature
-  myIsPropertyPanelValueChanged = false;
+  //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)
   FeaturePtr aFeature = getCurrentOperation()->feature();
@@ -697,6 +699,7 @@ void PartSet_SketcherMgr::startSketch(ModuleBase_Operation* theOperation)
 void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
 {
   myIsMouseOverWindow = false;
+  myIsConstraintsShown = true;
 
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
   XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer();
@@ -740,8 +743,12 @@ void PartSet_SketcherMgr::stopSketch(ModuleBase_Operation* theOperation)
   aDisplayer->updateViewer();
 }
 
-void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* )
+void PartSet_SketcherMgr::startNestedSketch(ModuleBase_Operation* theOperation)
 {
+  if (constraintsIdList().contains(theOperation->id())) {
+    // Show constraints if a constraint was created
+    onShowConstraintsToggle(true);
+  }
   connectToPropertyPanel(true);
 }
 
@@ -757,10 +764,6 @@ void PartSet_SketcherMgr::commitNestedSketch(ModuleBase_Operation* theOperation)
   if (isNestedCreateOperation(theOperation))
     visualizeFeature(theOperation, true);
 
-  if (constraintsIdList().contains(theOperation->id())) {
-    // Show constraints if a constraint was created
-    onShowConstraintsToggle(true);
-  }
 }
 
 bool PartSet_SketcherMgr::canUndo() const
index 82675355b292f78aeec6255f5ac6ad880d81757a..b488201750a4866ff82aa1ff3d150af14b2a2223 100644 (file)
@@ -465,13 +465,16 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
       // Create line
       aMyFeature = theSketch->addFeature(SketchPlugin_Line::ID());
     } else if (aAdaptor.GetType() == GeomAbs_Circle) {
-      if (aAdaptor.IsClosed()) {
-        // Create circle
-        aMyFeature = theSketch->addFeature(SketchPlugin_Circle::ID());
-      } else {
+      std::shared_ptr<GeomAPI_Edge> anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge);
+      anEdge->setImpl(new TopoDS_Shape(theShape));
+      if (anEdge->isArc()) {
         // Create arc
         aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID());
       }
+      else {
+        // Create circle
+        aMyFeature = theSketch->addFeature(SketchPlugin_Circle::ID());
+      }
     }
     if (aMyFeature) {
       DataPtr aData = aMyFeature->data();
index 04bcb3663fd2587b91666f37598aaf205cc9b04d..55f0157b003a2ff8e9f36cdc1ec364f706b1d98f 100644 (file)
@@ -23,6 +23,7 @@
 #include <ModelAPI_Session.h>
 
 #include <SketchPlugin_Sketch.h>
+#include <GeomAPI_Edge.h>
 
 #include <list>
 #ifdef _DEBUG
@@ -63,31 +64,31 @@ int shapesNbLines(const ModuleBase_ISelection* theSelection)
   return aCount;
 }
 
-bool PartSet_DistanceValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
   return (aCount > 0) && (aCount < 3);
 }
 
-bool PartSet_LengthValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   int aCount = shapesNbLines(theSelection);
-  return (aCount > 0) && (aCount < 2);
+  return (aCount == 1);
 }
 
-bool PartSet_PerpendicularValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   int aCount = shapesNbLines(theSelection);
   return (aCount > 0) && (aCount < 3);
 }
 
-bool PartSet_ParallelValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   int aCount = shapesNbLines(theSelection);
   return (aCount > 0) && (aCount < 3);
 }
 
-bool PartSet_RadiusValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
   ModuleBase_ViewerPrs aPrs;
@@ -105,15 +106,79 @@ bool PartSet_RadiusValidator::isValid(const ModuleBase_ISelection* theSelection)
       }
     }
   }
-  return (aCount > 0) && (aCount < 2);
+  return (aCount == 1);
 }
 
-bool PartSet_RigidValidator::isValid(const ModuleBase_ISelection* theSelection) const
+bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection) const
+{
+  QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();  
+  return (aList.count() == 1);
+}
+
+
+bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection) const
+{
+  int aCount = shapesNbPoints(theSelection);
+  return (aCount > 0) && (aCount < 3);
+}
+
+bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection) const
+{
+  int aCount = shapesNbLines(theSelection);
+  return (aCount == 1);
+}
+
+bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection) const
 {
   int aCount = shapesNbLines(theSelection);
-  return (aCount > 0) && (aCount < 2);
+  return (aCount > 0) && (aCount < 3);
+}
+
+bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection) const
+{
+  QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
+  if ((aList.size() == 0) || (aList.size() > 2))
+    return false;
+
+  ModuleBase_ViewerPrs aPrs = aList.first();
+  const TopoDS_Shape& aShape = aPrs.shape();
+  if (aShape.IsNull())
+    return false;
+
+  if (aShape.ShapeType() != TopAbs_EDGE)
+    return false;
+
+  std::shared_ptr<GeomAPI_Shape> aShapePtr(new GeomAPI_Shape);
+  aShapePtr->setImpl(new TopoDS_Shape(aShape));
+  GeomAPI_Edge aEdge1(aShapePtr);
+
+  if (aEdge1.isLine() || aEdge1.isArc()) {
+    if (aList.size() == 2) {
+      // Check second selection
+      aPrs = aList.last();
+      const TopoDS_Shape& aShape2 = aPrs.shape();
+      if (aShape2.IsNull())
+        return false;
+
+      if (aShape2.ShapeType() != TopAbs_EDGE)
+        return false;
+
+      std::shared_ptr<GeomAPI_Shape> aShapePtr2(new GeomAPI_Shape);
+      aShapePtr2->setImpl(new TopoDS_Shape(aShape2));
+      GeomAPI_Edge aEdge2(aShapePtr2);
+      if (aEdge1.isLine() && aEdge2.isArc())
+        return true;
+      else if (aEdge1.isArc() && aEdge2.isLine())
+        return true;
+      else
+        return false;
+    } else
+      return true;
+  }
+  return false;
 }
 
+
 bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, 
                                                 const std::list<std::string>& theArguments) const
 {
index 7a7f2333c04bc740469e930e2f939843579a854d..7d78aeb10a7f2e879ef26261605d81ae8dda8f1a 100644 (file)
@@ -19,7 +19,7 @@
 
 //! \ingroup Validators
 //! A class to validate a selection for Distance constraint operation
-class PartSet_DistanceValidator : public ModuleBase_SelectionValidator
+class PartSet_DistanceSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
@@ -27,7 +27,7 @@ class PartSet_DistanceValidator : public ModuleBase_SelectionValidator
 
 //! \ingroup Validators
 //! A class to validate a selection for Length constraint operation
-class PartSet_LengthValidator : public ModuleBase_SelectionValidator
+class PartSet_LengthSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
@@ -35,36 +35,72 @@ class PartSet_LengthValidator : public ModuleBase_SelectionValidator
 
 //! \ingroup Validators
 //! A class to validate a selection for Perpendicular constraint operation
-class PartSet_PerpendicularValidator : public ModuleBase_SelectionValidator
+class PartSet_PerpendicularSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
 };
 
 //! \ingroup Validators
-//! A class to validate a selection for Perpendicular constraint operation
-class PartSet_ParallelValidator : public ModuleBase_SelectionValidator
+//! A class to validate a selection for Parallel constraint operation
+class PartSet_ParallelSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
 };
 
 //! \ingroup Validators
-//! A class to validate a selection for Perpendicular constraint operation
-class PartSet_RadiusValidator : public ModuleBase_SelectionValidator
+//! A class to validate a selection for Radius constraint operation
+class PartSet_RadiusSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
 };
 
 //! \ingroup Validators
-//! A class to validate a selection for Perpendicular constraint operation
-class PartSet_RigidValidator : public ModuleBase_SelectionValidator
+//! A class to validate a selection for Rigid constraint operation
+class PartSet_RigidSelection : public ModuleBase_SelectionValidator
+{
+ public:
+  PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
+};
+
+
+//! \ingroup Validators
+//! A class to validate a selection for coincedence constraint operation
+class PartSet_CoincidentSelection : public ModuleBase_SelectionValidator
+{
+ public:
+  PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
+};
+
+//! \ingroup Validators
+//! A class to validate a selection for Horizontal and Vertical constraints operation
+class PartSet_HVDirSelection : public ModuleBase_SelectionValidator
+{
+ public:
+  PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
+};
+
+//! \ingroup Validators
+//! A class to validate a selection for Tangential constraints operation
+class PartSet_TangentSelection : public ModuleBase_SelectionValidator
 {
  public:
   PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
 };
 
+//! \ingroup Validators
+//! A class to validate a selection for Fillet constraints operation
+class PartSet_FilletSelection : public ModuleBase_SelectionValidator
+{
+ public:
+  PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const;
+};
+
+////////////// Attribute validators ////////////////
+
+
 /**
 * \ingroup Validators
 * A validator which checks that objects selected for feature attributes are different (not the same)
index 66ed150b86e2c2947c633598f781bd79c0a97e1e..4857863b5ea31d1f905187ffcb0a67fad13d6ac7 100644 (file)
@@ -24,8 +24,8 @@ bool PartSet_WidgetEditor::focusTo()
 {
   PartSet_Module* aModule = dynamic_cast<PartSet_Module*>(myWorkshop->module());
   if (aModule->isMouseOverWindow())
-    return ModuleBase_WidgetDoubleValue::focusTo();
+    return ModuleBase_WidgetEditor::focusTo();
   else {
-    ModuleBase_WidgetEditor::focusTo();
+    return ModuleBase_WidgetDoubleValue::focusTo();
   }
 }
index 6be038d19d803a84cf839d7dc1e6e7e97e6e7f7f..af8e9d56af5061f563fe2ca5a854b61e09b39307 100644 (file)
@@ -245,6 +245,7 @@ void PartSet_WidgetSketchLabel::deactivate()
   //XGUI_Displayer* aDisp = myWorkshop->displayer();
   //aDisp->closeLocalContexts();
   erasePreviewPlanes();
+  activateFilters(myWorkshop->module()->workshop(), false);
 }
 
 void PartSet_WidgetSketchLabel::erasePreviewPlanes()
index 62cefad4869b312719b4c8aa186014b9af079174..b37f9e71a15296dd4da7597fd00aa8dc52b30285 100644 (file)
@@ -36,5 +36,6 @@
      <file>icons/tangent.png</file>
      <file>icons/fillet.png</file>
      <file>icons/coincedence.png</file>
+     <file>icons/mirror.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/mirror.png b/src/PartSet/icons/mirror.png
new file mode 100644 (file)
index 0000000..1c12a71
Binary files /dev/null and b/src/PartSet/icons/mirror.png differ
index fd765dec9fb452fbc9e13b89f07a32b7e43fe460..f28a09516757ff59a05cbe8966e34693cfeb4fd4 100644 (file)
@@ -187,7 +187,9 @@ AISObjectPtr SketchPlugin_ConstraintMirror::getAISObject(AISObjectPtr thePreviou
     return thePrevious;
 
   AISObjectPtr anAIS = thePrevious;
-  /// TODO: Equal constraint presentation should be put here
+  if (!anAIS) {
+    anAIS = SketcherPrs_Factory::mirrorConstraint(this, sketch()->coordinatePlane());
+  }
   return anAIS;
 }
 
index e92cdb8c47472ae37d3726b24434f64d4743ca87..91a92ce7b2f89dd8498c70cd8c2b9066af0a7e37 100644 (file)
@@ -59,6 +59,8 @@ SketchPlugin_Plugin::SketchPlugin_Plugin()
                               new SketchPlugin_NotFixedValidator);
   aFactory->registerValidator("SketchPlugin_EqualAttr",
                               new SketchPlugin_EqualAttrValidator);
+  aFactory->registerValidator("SketchPlugin_MirrorAttr",
+                              new SketchPlugin_MirrorAttrValidator);
 
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
index 377fc0beddf6fc491423951a2417c3ca474e0a2e..64b0c09f6f36f39ddaa0dd51a6c0f9071ec65e01 100644 (file)
 #include <GeomAPI_AISObject.h>
 #include <GeomAPI_Dir.h>
 #include <GeomAPI_PlanarEdges.h>
-#include <GeomAPI_XYZ.h>
 
-#include <GeomDataAPI_Dir.h>
-#include <GeomDataAPI_Point.h>
 #include <GeomAlgoAPI_FaceBuilder.h>
 
 #include <ModelAPI_AttributeRefList.h>
@@ -188,69 +185,6 @@ bool SketchPlugin_Sketch::isSub(ObjectPtr theObject) const
   return false;
 }
 
-std::shared_ptr<GeomAPI_Pnt> SketchPlugin_Sketch::to3D(const double theX, const double theY)
-{
-  std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-      data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-  std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
-
-  std::shared_ptr<GeomAPI_XYZ> aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX))
-      ->added(aY->xyz()->multiplied(theY));
-
-  return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aSum));
-}
-
-std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Sketch::to2D(
-  const std::shared_ptr<GeomAPI_Pnt>& thePnt)
-{
-  std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-      data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
-  std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
-  return thePnt->to2D(aC->pnt(), aX->dir(), aY);
-}
-
-
-bool SketchPlugin_Sketch::isPlaneSet()
-{
-  std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-
-  return aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
-}
-
-std::shared_ptr<GeomAPI_Pln> SketchPlugin_Sketch::plane()
-{
-  std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-      data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-      data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-
-  if (!anOrigin || !aNorm)
-    return std::shared_ptr<GeomAPI_Pln>();
-
-  return std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(anOrigin->pnt(), aNorm->dir()));
-}
-
-std::shared_ptr<GeomAPI_Ax3> SketchPlugin_Sketch::coordinatePlane() const
-{
-  DataPtr aData = data();
-  std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
-    aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-    aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
-  std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
-    aData->attribute(SketchPlugin_Sketch::NORM_ID()));
-
-  return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(aC->pnt(), aX->dir(), aNorm->dir()));
-}
 
 void SketchPlugin_Sketch::erase()
 {
index 0c88f0d8f097c59f2dff814f9344ac942f343de9..d7e65d5486ff8bcc8bbf6a0b08c4573e2c0e79ed 100644 (file)
@@ -13,6 +13,9 @@
 #include <GeomAPI_Pln.h>
 #include <GeomAPI_IPresentable.h>
 #include <GeomAPI_Ax3.h>
+#include <GeomAPI_XYZ.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Dir.h>
 #include <list>
 
 #define YZ_PLANE_COLOR "#ff0000"
@@ -85,7 +88,37 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature//, public GeomAPI_I
   }
 
   /// Converts a 2D sketch space point into point in 3D space
-  SKETCHPLUGIN_EXPORT std::shared_ptr<GeomAPI_Pnt> to3D(const double theX, const double theY);
+  /// \param theX an X coordinate
+  /// \param theY an Y coordinate
+  std::shared_ptr<GeomAPI_Pnt> to3D(const double theX, const double theY) const
+  {
+    std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        data()->attribute(ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(NORM_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(DIRX_ID()));
+    std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
+
+    std::shared_ptr<GeomAPI_XYZ> aSum = aC->pnt()->xyz()->added(aX->dir()->xyz()->multiplied(theX))
+        ->added(aY->xyz()->multiplied(theY));
+
+    return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aSum));
+  }
+  
+  /// Returns the point projected into the sketch plane
+  /// \param thePnt a source 3d point
+  std::shared_ptr<GeomAPI_Pnt2d> to2D(const std::shared_ptr<GeomAPI_Pnt>& thePnt) const
+  {
+    std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        data()->attribute(ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(NORM_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(DIRX_ID()));
+    std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
+    return thePnt->to2D(aC->pnt(), aX->dir(), aY);
+  }
 
   /// Returns true if this feature must be displayed in the history (top level of Part tree)
   SKETCHPLUGIN_EXPORT virtual bool isInHistory()
@@ -97,11 +130,43 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature//, public GeomAPI_I
   SketchPlugin_Sketch();
 
   /// Returns the basis plane for the sketch
-  std::shared_ptr<GeomAPI_Pln> plane();
+  std::shared_ptr<GeomAPI_Pln> plane() const
+  {
+    std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+        data()->attribute(ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(NORM_ID()));
 
-  SKETCHPLUGIN_EXPORT std::shared_ptr<GeomAPI_Ax3> coordinatePlane() const;
+    if (!anOrigin || !aNorm)
+      return std::shared_ptr<GeomAPI_Pln>();
+
+    return std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(anOrigin->pnt(), aNorm->dir()));
+  }
+
+  /// Returns currently defined plane as an object of Ax3
+  std::shared_ptr<GeomAPI_Ax3> coordinatePlane() const
+  {
+    DataPtr aData = data();
+    std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
+      aData->attribute(ORIGIN_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+      aData->attribute(DIRX_ID()));
+    std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+      aData->attribute(NORM_ID()));
+
+    return std::shared_ptr<GeomAPI_Ax3>(new GeomAPI_Ax3(aC->pnt(), aX->dir(), aNorm->dir()));
+  }
+
+  /// Checks whether the plane is set in the sketch.
+  /// \returns the boolean state
+  bool isPlaneSet() const
+  {
+    std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
+        data()->attribute(NORM_ID()));
+
+    return aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
+  }
 
-  //virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
 
   /// removes also all sub-sketch elements
   SKETCHPLUGIN_EXPORT virtual void erase();
@@ -128,14 +193,7 @@ class SketchPlugin_Sketch : public ModelAPI_CompositeFeature//, public GeomAPI_I
   /// Construction result is allways recomuted on the fly
   SKETCHPLUGIN_EXPORT virtual bool isPersistentResult() {return false;}
 
-  /// Returns the point projected into the sketch plane
-  std::shared_ptr<GeomAPI_Pnt2d> to2D(const std::shared_ptr<GeomAPI_Pnt>& thePnt);
-
   SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
-protected:
-  /// Checks whether the plane is set in the sketch.
-  /// \returns the boolean state
-  bool isPlaneSet();
 };
 
 #endif
index 95da79b9513deced964b1fd618ad7cab8ef9f6d2..72f0b61d1cb6872e656d70b75d631b8353ab22c1 100644 (file)
@@ -18,6 +18,8 @@
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_Session.h>
 
 #include <GeomValidators_Edge.h>
@@ -211,3 +213,26 @@ bool SketchPlugin_EqualAttrValidator::isValid(
   return true;
 }
 
+bool SketchPlugin_MirrorAttrValidator::isValid(
+  const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
+{
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  AttributeSelectionListPtr aSelAttr = 
+    std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+  if (!aSelAttr)
+    return false;
+
+  AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      aFeature->attribute(SketchPlugin_Constraint::ENTITY_C()));
+  std::list<ObjectPtr> aMirroredObjects = aRefListOfMirrored->list();
+
+  for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
+    std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aSelAttr->value(anInd);
+    std::list<ObjectPtr>::iterator aMirIter = aMirroredObjects.begin();
+    for (; aMirIter != aMirroredObjects.end(); aMirIter++)
+      if (aSelect->context() == *aMirIter)
+        return false;
+  }
+  return true;
+}
+
index 47df3706156129b4cfacac9f4891d6bc0b733bc9..e4f6d36d6904eefabf32e44a0b30e4f9ade5e169 100644 (file)
@@ -76,5 +76,21 @@ class SketchPlugin_EqualAttrValidator : public ModelAPI_AttributeValidator
                        const std::list<std::string>& theArguments) const;
 };
 
+/**\class SketchPlugin_MirrorAttrValidator
+ * \ingroup Validators
+ * \brief Validator for the mirror constraint input.
+ *
+ * It checks that attributes of the Mirror constraint are correct.
+ */
+class SketchPlugin_MirrorAttrValidator : public ModelAPI_AttributeValidator
+{
+ public:
+  //! returns true if attribute is valid
+  //! \param theAttribute the checked attribute
+  //! \param theArguments arguments of the attribute (not used)
+  virtual bool isValid(const AttributePtr& theAttribute,
+                       const std::list<std::string>& theArguments) const;
+};
+
 
 #endif
index f2bce5f32c89d4c47fcb6adccf7b9319ddf56be4..6657008fd201a8a6294a6af54fc5fed5660803e6 100644 (file)
@@ -71,7 +71,7 @@
           <validator id="GeomValidators_Positive"/>
         </doublevalue_editor>
         
-        <validator id="PartSet_DistanceValidator"/>
+        <validator id="PartSet_DistanceSelection"/>
       </feature>
       
     <!--  SketchConstraintLength  -->      
@@ -85,7 +85,7 @@
         <doublevalue_editor label="Value" tooltip="Length" id="ConstraintValue" default="computed">
           <validator id="GeomValidators_Positive"/>
         </doublevalue_editor>
-        <validator id="PartSet_LengthValidator"/>
+        <validator id="PartSet_LengthSelection"/>
       </feature>
       
     <!--  SketchConstraintRadius  -->
@@ -97,7 +97,7 @@
         </shape_selector>
         <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt"  default="computed" internal="1" obligatory="0"/>
         <doublevalue_editor label="Value" tooltip="Radius" id="ConstraintValue" default="computed"/>
-        <validator id="PartSet_RadiusValidator"/>
+        <validator id="PartSet_RadiusSelection"/>
       </feature>
       
     <!--  SketchConstraintParallel  -->
             <validator id="PartSet_DifferentObjects"/>
             <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
         </sketch_constraint_shape_selector>
-        <validator id="PartSet_ParallelValidator"/>
+        <validator id="PartSet_ParallelSelection"/>
       </feature>
       
     <!--  SketchConstraintPerpendicular  -->
           <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
             <validator id="GeomValidators_Edge" parameters="line"/>
         </sketch_constraint_shape_selector>
-        <validator id="PartSet_PerpendicularValidator"/>
+        <validator id="PartSet_PerpendicularSelection"/>
       </feature>
 
       <!--  SketchConstraintCoincedence  -->
         <sketch_shape_selector id="ConstraintEntityB" label="Second point" tooltip="Select a second point" shape_types="vertex">
           <validator id="PartSet_DifferentObjects"/>
         </sketch_shape_selector>
+        <validator id="PartSet_CoincidentSelection"/>
       </feature>
 
       <!--  SketchConstraintRigid  -->
           <validator id="PartSet_SketchEntityValidator" parameters="SketchPoint,SketchLine,SketchCircle,SketchArc"/>
           <validator id="SketchPlugin_NotFixed"/>
         </shape_selector>
-        <validator id="PartSet_RigidValidator"/>
+        <validator id="PartSet_RigidSelection"/>
       </feature>
       
     <!--  SketchConstraintHorizontal  -->
             label="Line" tooltip="Select a line" shape_types="edge">
             <validator id="GeomValidators_Edge" parameters="line"/>
         </sketch_constraint_shape_selector>
+        <validator id="PartSet_HVDirSelection"/>
       </feature>
       
     <!--  SketchConstraintVertical  -->
             label="Line" tooltip="Select a line" shape_types="edge">
             <validator id="GeomValidators_Edge" parameters="line"/>
         </sketch_constraint_shape_selector>
+        <validator id="PartSet_HVDirSelection"/>
       </feature>
       
     <!--  SketchConstraintEqual  -->
         <sketch_constraint_shape_selector id="ConstraintEntityB"
             label="Last object" tooltip="Select line or arc" shape_types="edge">
         <validator id="SketchPlugin_TangentAttr" parameters="ConstraintEntityA"/>
+        <validator id="PartSet_DifferentObjects"/>
         </sketch_constraint_shape_selector>
+        <validator id="PartSet_TangentSelection"/>
       </feature>
       
-    <!--  SketchConstraintMirror  -->
-      <feature
-        id="SketchConstraintMirror"
-        title="Mirror"
-        tooltip="Create constraint, mirroring group of objects">
-        <sketch_constraint_shape_selector id="ConstraintEntityA" 
-            label="Mirror line" tooltip="Select mirror line" shape_types="edge">
-            <validator id="GeomValidators_Edge" parameters="line"/>
-        </sketch_constraint_shape_selector>
-        <multi_selector id="ConstraintMirrorList" 
-            label="List of objects"
-            tooltip="Select list of mirroring objects"
-            type_choice="Edges">
-        </multi_selector>
-      </feature>
+         
     </group>
     
     <group id="Edit">
         <doublevalue_editor label="Value" tooltip="Fillet radius" id="ConstraintValue" min="0">
           <validator id="GeomValidators_Positive"/>
         </doublevalue_editor>
+        <validator id="PartSet_FilletSelection"/>
+      </feature>
+      
+      <!--  SketchConstraintMirror  -->
+      <feature
+        id="SketchConstraintMirror"
+        title="Mirror" icon=":icons/mirror.png"
+        tooltip="Create constraint, mirroring group of objects">
+        <sketch_constraint_shape_selector id="ConstraintEntityA"
+            label="Mirror line" tooltip="Select mirror line" shape_types="edge">
+            <validator id="GeomValidators_Edge" parameters="line"/>
+        </sketch_constraint_shape_selector>
+        <multi_selector id="ConstraintMirrorList"
+            label="List of objects"
+            tooltip="Select list of mirroring objects"
+            type_choice="Edges">
+            <validator id="SketchPlugin_MirrorAttr" />
+        </multi_selector>
       </feature>
     </group>
   </workbench>
index 370bdce0d4e4962f6ac7f2d8635e077c91769383..b86ce1a28073d4caa0cecf85827bc7e4b4b517b8 100644 (file)
@@ -282,7 +282,7 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributeRefAttrPtr theAttrib
 Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int& theType)
 {
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
-  if (!isInitialized(theEntity))
+  if (!theEntity || !isInitialized(theEntity))
     return SLVS_E_UNKNOWN;
 
   // If the entity is already in the group, try to find it
@@ -378,7 +378,7 @@ Slvs_hEntity SketchSolver_Constraint::changeEntity(AttributePtr theEntity, int&
 Slvs_hEntity SketchSolver_Constraint::changeEntity(FeaturePtr theEntity, int& theType)
 {
   Slvs_hEntity aResult = SLVS_E_UNKNOWN;
-  if (!theEntity->data() || !theEntity->data()->isValid())
+  if (!theEntity || !theEntity->data() || !theEntity->data()->isValid())
     return SLVS_E_UNKNOWN;
   // If the entity is already in the group, try to find it
   std::map<FeaturePtr, Slvs_hEntity>::const_iterator anEntIter = myFeatureMap.find(theEntity);
index 1172988cba921d4ba5e83eab6c9d0627ca88789f..2ae6bf381b4922a07398f41495e7f3254fc3fd12 100644 (file)
@@ -202,6 +202,6 @@ bool SketchSolver_ConstraintCoincidence::remove(ConstraintPtr theConstraint)
     }
     anExtraIt++;
   }
-  return isFullyRemoved;
+  return mySlvsConstraints.empty();
 }
 
index a1deb96ccd44516b25004ebf166363b615ae6554..6c1875ccb062394d2df1312fad8271c1aeb43626 100644 (file)
@@ -117,6 +117,11 @@ void SketchSolver_ConstraintRigid::getAttributes(
       myFeatureMap[myBaseFeature] = anEntityID;
   }
 
+  if (anEntityID == SLVS_E_UNKNOWN) {
+    myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
+    return;
+  }
+
   // Check the entity is complex
   Slvs_Entity anEntity = myStorage->getEntity(anEntityID);
   if (anEntity.point[0] != SLVS_E_UNKNOWN) {
index 610993a74eb5ede2eb4f1e7a634577d43da5a945..d647d075b6f1cca79b74cf3d17e4dd20bd5e21b2 100644 (file)
@@ -91,14 +91,10 @@ void SketchSolver_FeatureStorage::removeConstraint(ConstraintPtr theConstraint)
     while (aFeatIter != myFeatures.end()) {
       aCIter = aFeatIter->second.find(theConstraint);
       if (aCIter != aFeatIter->second.end()) {
-        aFeatIter->second.erase(aCIter);
-        if (aFeatIter->second.empty()) {
-          MapFeatureConstraint::iterator aTmpIter = aFeatIter; // stores iterator for the next element, while the current is deleting
-          aTmpIter++;
-          myFeatures.erase(aFeatIter);
-          aFeatIter = aTmpIter;
-          continue;
-        }
+        FeaturePtr aFeature = aFeatIter->first;
+        aFeatIter++;
+        removeFeature(aFeature, theConstraint);
+        continue;
       }
       aFeatIter++;
     }
@@ -200,7 +196,7 @@ void SketchSolver_FeatureStorage::changeFeature(FeaturePtr theFeature, Constrain
 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
 {
   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
-  if (aFeatIter != myFeatures.end())
+  if (aFeatIter == myFeatures.end())
     return; // no such feature
 
   std::set<ConstraintPtr> aConstraints = aFeatIter->second;
@@ -212,19 +208,35 @@ void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature)
 void SketchSolver_FeatureStorage::removeFeature(FeaturePtr theFeature, ConstraintPtr theConstraint)
 {
   MapFeatureConstraint::iterator aFeatIter = myFeatures.find(theFeature);
-  if (aFeatIter != myFeatures.end())
+  if (aFeatIter == myFeatures.end())
     return; // no such feature
 
-  std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
-  std::list<AttributePtr>::iterator anIter = anAttributes.begin();
-  for (; anIter != anAttributes.end(); anIter++) {
-    AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
-    if (aRefAttr) {
-      if (!aRefAttr->isObject())
-        removeAttribute(aRefAttr->attr(), theFeature);
-      continue;
+  if (theFeature->data()) {
+    std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
+    std::list<AttributePtr>::iterator anIter = anAttributes.begin();
+    for (; anIter != anAttributes.end(); anIter++) {
+      AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIter);
+      if (aRefAttr) {
+        if (!aRefAttr->isObject())
+          removeAttribute(aRefAttr->attr(), theFeature);
+        continue;
+      }
+      removeAttribute(*anIter, theFeature);
+    }
+  } else {
+    // iterate on attributes to find items refered to theFeature
+    MapAttributeFeature::iterator anIter = myAttributes.begin();
+    while (anIter != myAttributes.end()) {
+      if (anIter->second.find(theFeature) != anIter->second.end()) {
+        anIter->second.erase(theFeature);
+        if (anIter->second.empty()) {
+          MapAttributeFeature::iterator aDeadIter = anIter++;
+          myAttributes.erase(aDeadIter);
+          continue;
+        }
+      }
+      anIter++;
     }
-    removeAttribute(*anIter, theFeature);
   }
 
   aFeatIter->second.erase(theConstraint);
@@ -287,7 +299,7 @@ void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute)
 void SketchSolver_FeatureStorage::removeAttribute(AttributePtr theAttribute, FeaturePtr theFeature)
 {
   MapAttributeFeature::iterator anAttrIter = myAttributes.find(theAttribute);
-  if (anAttrIter != myAttributes.end())
+  if (anAttrIter == myAttributes.end())
     return; // no such attribute
 
   anAttrIter->second.erase(theFeature);
index 2c6d8f5763627c0d5c012814ce687a4d463d6741..b51828ba9d0eb78e560f1d934f11f9801a4642a3 100644 (file)
@@ -439,8 +439,20 @@ void SketchSolver_Group::splitGroup(std::vector<SketchSolver_Group*>& theCuts)
         anUnusedConstraints.push_back(*anIter);
   }
 
-  std::vector<SketchSolver_Group*>::iterator aCutsIter;
+  // Check the unused constraints once again, because they may become interacted with new storage since adding constraints
   std::vector<ConstraintPtr>::iterator aUnuseIt = anUnusedConstraints.begin();
+  while (aUnuseIt != anUnusedConstraints.end()) {
+    if (aNewFeatStorage->isInteract(*aUnuseIt)) {
+      size_t aShift = aUnuseIt - anUnusedConstraints.begin();
+      anUnusedConstraints.erase(aUnuseIt);
+      aUnuseIt = anUnusedConstraints.begin() + aShift;
+      continue;
+    }
+    aUnuseIt++;
+  }
+
+  std::vector<SketchSolver_Group*>::iterator aCutsIter;
+  aUnuseIt = anUnusedConstraints.begin();
   for ( ; aUnuseIt != anUnusedConstraints.end(); aUnuseIt++) {
     // Remove unused constraints
     removeConstraint(*aUnuseIt);
index d4a5171322ad5701bd990264cbe94c8185c8c901..1690d7d561d37b5a4040b46b3ba2583fe7522168 100644 (file)
@@ -151,13 +151,19 @@ bool SketchSolver_Storage::removeEntity(const Slvs_hEntity& theEntityID)
       if (anEntIter->distance == theEntityID)
         return false;
     }
+    std::set<Slvs_hEntity> anEntAndSubs;
+    anEntAndSubs.insert(theEntityID);
+    for (int i = 0; i < 4; i++)
+      if (myEntities[aPos].point[i] != SLVS_E_UNKNOWN)
+        anEntAndSubs.insert(myEntities[aPos].point[i]);
+
     std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
     for (; aConstrIter != myConstraints.end(); aConstrIter++) {
       Slvs_hEntity anEntIDs[6] = {aConstrIter->ptA, aConstrIter->ptB,
           aConstrIter->entityA, aConstrIter->entityB,
           aConstrIter->entityC, aConstrIter->entityD};
       for (int i = 0; i < 6; i++)
-        if (anEntIDs[i] == theEntityID)
+        if (anEntAndSubs.find(anEntIDs[i]) != anEntAndSubs.end())
           return false;
     }
     // The entity is not used, remove it and its parameters
index be597690dc06f4a92d56770896d94c5823ea341b..963c7e54244d171e682de90299662e95c52283bf 100644 (file)
@@ -16,6 +16,7 @@ SET(PROJECT_HEADERS
        SketcherPrs_SensitivePoint.h
        SketcherPrs_Radius.h
        SketcherPrs_LengthDimension.h
+       SketcherPrs_Mirror.h
 )
 
 SET(PROJECT_SOURCES
@@ -33,6 +34,7 @@ SET(PROJECT_SOURCES
        SketcherPrs_SensitivePoint.cpp
        SketcherPrs_Radius.cpp
        SketcherPrs_LengthDimension.cpp
+       SketcherPrs_Mirror.cpp
 )
 
 SET(PROJECT_LIBRARIES
@@ -62,6 +64,7 @@ SET(PROJECT_PICTURES
        icons/vertical.png
        icons/equal.png
        icons/tangent.png
+       icons/mirror.png
 )
 
 ADD_DEFINITIONS(-DSKETCHERPRS_EXPORTS ${CAS_DEFINITIONS})
index 3520df99884db5881a6d22137b95cf51e6b08dca..b85d018b361da4502cfa8bbbc51b465261de0799 100644 (file)
@@ -70,11 +70,11 @@ void SketcherPrs_Coincident::Compute(const Handle(PrsMgr_PresentationManager3d)&
 void SketcherPrs_Coincident::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
                                             const Standard_Integer aMode)
 {
-  if ((aMode == 0) || (aMode == SketcherPrs_Tools::Sel_Constraint)) {
-    Handle(SelectMgr_EntityOwner) aOwn = new SelectMgr_EntityOwner(this, 10);
-    Handle(Select3D_SensitivePoint) aSp = new Select3D_SensitivePoint(aOwn, myPoint);
-    aSelection->Add(aSp);
-  }
+//  if ((aMode == 0) || (aMode == SketcherPrs_Tools::Sel_Constraint)) {
+//    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 f26682c3cae4603bccf4c216fc3f7c54691fc9a7..90f705fd8512e2c9692145ef1d20c0a7e1c36e1d 100644 (file)
@@ -52,7 +52,16 @@ void SketcherPrs_Equal::drawLines(const Handle(Prs3d_Presentation)& thePrs, Quan
   Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);
   aGroup->SetPrimitivesAspect(aLineAspect);
 
-  addLine(aGroup, SketchPlugin_Constraint::ENTITY_A());
-  addLine(aGroup, SketchPlugin_Constraint::ENTITY_B());
+  ObjectPtr aObj = SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_A());
+  std::shared_ptr<GeomAPI_Shape> aLine = SketcherPrs_Tools::getShape(aObj);
+  if (aLine.get() == NULL)
+    return;
+  drawShape(aLine, thePrs);
+
+  aObj = SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_B());
+  aLine = SketcherPrs_Tools::getShape(aObj);
+  if (aLine.get() == NULL)
+    return;
+  drawShape(aLine, thePrs);
 }
 
index 7ef2368621dbf5a651055fc64e24a71af6b2fb83..39ce4d6e0ce01385eba019c200cec8431ea4c742 100644 (file)
@@ -15,6 +15,7 @@
 #include "SketcherPrs_Tangent.h"
 #include "SketcherPrs_Radius.h"
 #include "SketcherPrs_LengthDimension.h"
+#include "SketcherPrs_Mirror.h"
 
 #define CONSTRAINT_PRS_IMPL(NAME, CLASS) \
 AISObjectPtr SketcherPrs_Factory::NAME(ModelAPI_Feature* theConstraint, \
@@ -34,6 +35,7 @@ CONSTRAINT_PRS_IMPL(equalConstraint, SketcherPrs_Equal);
 CONSTRAINT_PRS_IMPL(tangentConstraint, SketcherPrs_Tangent);
 CONSTRAINT_PRS_IMPL(radiusConstraint, SketcherPrs_Radius);
 CONSTRAINT_PRS_IMPL(lengthDimensionConstraint, SketcherPrs_LengthDimension);
+CONSTRAINT_PRS_IMPL(mirrorConstraint, SketcherPrs_Mirror);
 
 
 AISObjectPtr SketcherPrs_Factory::horisontalConstraint(ModelAPI_Feature* theConstraint,
index c43fb948fed15389e49ed56601f858331dbdb61b..9b627b940650c0d30720e5c5b2a7e807621a43a8 100644 (file)
@@ -74,6 +74,11 @@ public:
   /// \param theConstraint the constraint
   /// \param thePlane the current sketch plane
   GET_CONSTRAINT_PRS(lengthDimensionConstraint)
+
+  /// Creates coincedent perpendicular presentation
+  /// \param theConstraint the constraint
+  /// \param thePlane the current sketch plane
+  GET_CONSTRAINT_PRS(mirrorConstraint)
 };
 
 #endif
diff --git a/src/SketcherPrs/SketcherPrs_Mirror.cpp b/src/SketcherPrs/SketcherPrs_Mirror.cpp
new file mode 100644 (file)
index 0000000..2c05d22
--- /dev/null
@@ -0,0 +1,109 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        SketcherPrs_Mirror.cpp
+// Created:     6 April 2015
+// Author:      Vitaly SMETANNIKOV
+
+#include "SketcherPrs_Mirror.h"
+#include "SketcherPrs_Tools.h"
+#include "SketcherPrs_PositionMgr.h"
+
+#include <SketchPlugin_Constraint.h>
+
+#include <ModelAPI_AttributeRefList.h>
+
+#include <Graphic3d_AspectLine3d.hxx>
+#include <Prs3d_Root.hxx>
+
+
+
+IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Mirror, SketcherPrs_SymbolPrs);
+IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Mirror, SketcherPrs_SymbolPrs);
+
+static Handle(Image_AlienPixMap) MyPixMap;
+
+SketcherPrs_Mirror::SketcherPrs_Mirror(ModelAPI_Feature* theConstraint, 
+                                           const std::shared_ptr<GeomAPI_Ax3>& thePlane) 
+ : SketcherPrs_SymbolPrs(theConstraint, thePlane)
+{
+}  
+
+
+bool SketcherPrs_Mirror::updatePoints(double theStep) const
+{
+  ObjectPtr aAxisObj = SketcherPrs_Tools::getResult(myConstraint, SketchPlugin_Constraint::ENTITY_A());
+  if (SketcherPrs_Tools::getShape(aAxisObj).get() == NULL)
+    return false;
+
+  std::shared_ptr<ModelAPI_Data> aData = myConstraint->data();
+  std::shared_ptr<ModelAPI_AttributeRefList> anAttrB = aData->reflist(SketchPlugin_Constraint::ENTITY_B());
+  if (anAttrB.get() == NULL)
+    return false;
+  std::shared_ptr<ModelAPI_AttributeRefList> anAttrC = aData->reflist(SketchPlugin_Constraint::ENTITY_C());
+  if (anAttrC.get() == NULL)
+    return false;
+
+  SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
+  int aNb = anAttrB->size();
+  if (aNb != anAttrC->size())
+    return false;
+
+  myPntArray = new Graphic3d_ArrayOfPoints(2 * aNb);
+  int i;
+  ObjectPtr aObj;
+  gp_Pnt aP1;
+  for (i = 0; i < aNb; i++) {
+    aObj = anAttrB->object(i);
+    aP1 = aMgr->getPosition(aObj, this, theStep);
+    myPntArray->SetVertice(i + 1, aP1);
+  }  
+  for (i = 0; i < aNb; i++) {
+    aObj = anAttrC->object(i);
+    aP1 = aMgr->getPosition(aObj, this, theStep);
+    myPntArray->SetVertice(aNb + i + 1, aP1);
+  }  
+  return true;
+}
+
+
+void SketcherPrs_Mirror::drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const
+{
+  std::shared_ptr<ModelAPI_Data> aData = myConstraint->data();
+  std::shared_ptr<ModelAPI_AttributeRefList> anAttrB = aData->reflist(SketchPlugin_Constraint::ENTITY_B());
+  if (anAttrB.get() == NULL)
+    return;
+  std::shared_ptr<ModelAPI_AttributeRefList> anAttrC = aData->reflist(SketchPlugin_Constraint::ENTITY_C());
+  if (anAttrC.get() == NULL)
+    return;
+
+  SketcherPrs_PositionMgr* aMgr = SketcherPrs_PositionMgr::get();
+  int aNb = anAttrB->size();
+  if (aNb != anAttrC->size())
+    return;
+
+  Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup(thePrs);
+
+  Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);
+  aGroup->SetPrimitivesAspect(aLineAspect);
+
+  // Draw axis line
+  addLine(aGroup, SketchPlugin_Constraint::ENTITY_A());
+
+  // Draw source objects
+  int i;
+  ObjectPtr aObj;
+  for (i = 0; i < aNb; i++) {
+    aObj = anAttrB->object(i);
+    std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(aObj);
+    if (aShape.get() != NULL)
+      drawShape(aShape, thePrs);
+  }
+  // draw mirrored objects
+  for (i = 0; i < aNb; i++) {
+    aObj = anAttrC->object(i);
+    std::shared_ptr<GeomAPI_Shape> aShape = SketcherPrs_Tools::getShape(aObj);
+    if (aShape.get() != NULL)
+      drawShape(aShape, thePrs);
+  }
+}
+
diff --git a/src/SketcherPrs/SketcherPrs_Mirror.h b/src/SketcherPrs/SketcherPrs_Mirror.h
new file mode 100644 (file)
index 0000000..69e9494
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:        SketcherPrs_Mirror.h
+// Created:     6 April 2015
+// Author:      Vitaly SMETANNIKOV
+
+#ifndef SketcherPrs_Mirror_H
+#define SketcherPrs_Mirror_H
+
+#include "SketcherPrs_SymbolPrs.h"
+
+
+DEFINE_STANDARD_HANDLE(SketcherPrs_Mirror, SketcherPrs_SymbolPrs)
+
+/**
+* \ingroup GUI
+* A redefinition of standard AIS Interactive Object in order to provide  
+* presentation of mirror constraint
+*/
+class SketcherPrs_Mirror: public SketcherPrs_SymbolPrs
+{
+public:
+  /// Constructor
+  /// \param theConstraint a constraint feature
+  /// \param thePlane a coordinate plane of current sketch
+  Standard_EXPORT SketcherPrs_Mirror(ModelAPI_Feature* theConstraint, 
+                                       const std::shared_ptr<GeomAPI_Ax3>& thePlane);
+  DEFINE_STANDARD_RTTI(SketcherPrs_Mirror)
+protected:
+  virtual const char* iconName() const { return "mirror.png"; }
+
+  virtual void drawLines(const Handle(Prs3d_Presentation)& thePrs, Quantity_Color theColor) const;
+
+  /// Update myPntArray according to presentation positions
+  /// \return true in case of success
+  virtual bool updatePoints(double theStep) const;
+};
+
+#endif
\ No newline at end of file
index 2a7245e1dfc809d1f91407c2a691f97d4153d632..73963b7fed11d3dce7c4356effe22da7981756d3 100644 (file)
@@ -66,25 +66,11 @@ void SketcherPrs_Rigid::drawLines(const Handle(Prs3d_Presentation)& thePrs, Quan
     return;
 
   Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup(thePrs);
-  if (aShape->isEdge()) {
-    Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);
-    aGroup->SetPrimitivesAspect(aLineAspect);
-    std::shared_ptr<GeomAPI_Curve> aCurve = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape));
-    if (aCurve->isLine()) {
-      addLine(aGroup, SketchPlugin_Constraint::ENTITY_A());
-    } else {
-      GeomAdaptor_Curve aAdaptor(aCurve->impl<Handle(Geom_Curve)>(), aCurve->startParam(), aCurve->endParam());
-      StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
-    }
-  } else {
-    // This is a point
-    Handle(Prs3d_PointAspect) aPntAspect = new Prs3d_PointAspect(Aspect_TOM_PLUS, theColor, 1);
-    myDrawer->SetPointAspect(aPntAspect);
-
-    std::shared_ptr<GeomAPI_Vertex> aVertex = std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
-    std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
-    Handle(Geom_CartesianPoint) aPoint = new Geom_CartesianPoint(aPnt->impl<gp_Pnt>());
-    StdPrs_Point::Add(thePrs, aPoint, myDrawer);
-  }
+  Handle(Graphic3d_AspectLine3d) aLineAspect = new Graphic3d_AspectLine3d(theColor, Aspect_TOL_SOLID, 2);
+  aGroup->SetPrimitivesAspect(aLineAspect);
+
+  Handle(Prs3d_PointAspect) aPntAspect = new Prs3d_PointAspect(Aspect_TOM_PLUS, theColor, 1);
+  myDrawer->SetPointAspect(aPntAspect);
+  drawShape(aShape, thePrs);
 }
 
index 20fc780a705d564a603b0e8dde375b97e2975123..b4e646709886c7f327bb81be9f1a16afe0d7c578 100644 (file)
@@ -9,6 +9,8 @@
 #include "SketcherPrs_PositionMgr.h"
 
 #include <GeomAPI_Edge.h>
+#include <GeomAPI_Vertex.h>
+#include <GeomAPI_Curve.h>
 
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_BndBox4f.hxx>
 #include <AIS_InteractiveContext.hxx>
 #include <V3d_Viewer.hxx>
 #include <Prs3d_Root.hxx>
+#include <Geom_CartesianPoint.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <StdPrs_DeflectionCurve.hxx>
+#include <StdPrs_Point.hxx>
+#include <StdPrs_Curve.hxx>
 
 #include <OpenGl_Element.hxx>
 #include <OpenGl_GraphicDriver.hxx>
@@ -437,3 +444,24 @@ void SketcherPrs_SymbolPrs::Release (OpenGl_Context* theContext)
   }
 }
 
+void SketcherPrs_SymbolPrs::drawShape(const std::shared_ptr<GeomAPI_Shape>& theShape, 
+                                      const Handle(Prs3d_Presentation)& thePrs) const
+{
+  if (theShape->isEdge()) {
+    std::shared_ptr<GeomAPI_Curve> aCurve = 
+      std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(theShape));
+    if (aCurve->isLine()) {
+      GeomAdaptor_Curve aCurv(aCurve->impl<Handle(Geom_Curve)>(), aCurve->startParam(), aCurve->endParam());
+      StdPrs_Curve::Add(thePrs, aCurv, myDrawer);
+    } else {
+      GeomAdaptor_Curve aAdaptor(aCurve->impl<Handle(Geom_Curve)>(), aCurve->startParam(), aCurve->endParam());
+      StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
+    }
+  } else if (theShape->isVertex()) {
+    std::shared_ptr<GeomAPI_Vertex> aVertex = 
+      std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(theShape));
+    std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
+    Handle(Geom_CartesianPoint) aPoint = new Geom_CartesianPoint(aPnt->impl<gp_Pnt>());
+    StdPrs_Point::Add(thePrs, aPoint, myDrawer);
+  }
+}
index 446cedabcd6fb9ad28a0d6c11bf2dadae315579b..91b2323ac5e74f7dfcfd1c8696f625877c69ca9e 100644 (file)
@@ -103,6 +103,10 @@ protected:
   /// \return true in case of success
   virtual bool updatePoints(double theStep) const { return true; }
 
+  void drawShape(const std::shared_ptr<GeomAPI_Shape>& theShape, 
+    const Handle(Prs3d_Presentation)& thePrs) const;
+
+
 protected:
   /// Constraint feature
   ModelAPI_Feature* myConstraint;
index 45f32049425091c54120cc4d9426ca5457d3d15e..199eb782f8161ff7123909e695805e648292752e 100644 (file)
@@ -64,23 +64,7 @@ void SketcherPrs_Tangent::drawLines(const Handle(Prs3d_Presentation)& thePrs, Qu
 
   if ((aShape1.get() == NULL) || (aShape2.get() == NULL))
     return;
-
-  std::shared_ptr<GeomAPI_Curve> aCurve1 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape1));
-  std::shared_ptr<GeomAPI_Curve> aCurve2 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape2));
-  if (aCurve1->isCircle() && aCurve2->isLine()) {
-    addLine(aGroup, SketchPlugin_Constraint::ENTITY_B());
-    GeomAdaptor_Curve aAdaptor(aCurve1->impl<Handle(Geom_Curve)>(), aCurve1->startParam(), aCurve1->endParam());
-    StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
-  } else if (aCurve1->isLine() && aCurve2->isCircle()) {
-    addLine(aGroup, SketchPlugin_Constraint::ENTITY_A());
-    GeomAdaptor_Curve aAdaptor(aCurve2->impl<Handle(Geom_Curve)>(), aCurve2->startParam(), aCurve2->endParam());
-    StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
-  } else {
-    // Both curves are arcs
-    GeomAdaptor_Curve aAdaptor1(aCurve1->impl<Handle(Geom_Curve)>(), aCurve1->startParam(), aCurve1->endParam());
-    StdPrs_DeflectionCurve::Add(thePrs, aAdaptor1, myDrawer);
-    GeomAdaptor_Curve aAdaptor2(aCurve2->impl<Handle(Geom_Curve)>(), aCurve2->startParam(), aCurve2->endParam());
-    StdPrs_DeflectionCurve::Add(thePrs, aAdaptor2, myDrawer);
-  }
+  drawShape(aShape1, thePrs);
+  drawShape(aShape2, thePrs);
 }
 
index 47468899ec7d2d7685b561f1277707b93d5c7bd8..8c28de0b09ff9888dff66e7313c3a7f637fa6a6d 100644 (file)
@@ -23,9 +23,7 @@ namespace SketcherPrs_Tools {
 ObjectPtr getResult(ModelAPI_Feature* theFeature, const std::string& theAttrName)
 {
   std::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
-    std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(theAttrName));
-
+  std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = aData->refattr(theAttrName);
   return anAttr->object();
 }
 
diff --git a/src/SketcherPrs/icons/mirror.png b/src/SketcherPrs/icons/mirror.png
new file mode 100644 (file)
index 0000000..3197cf3
Binary files /dev/null and b/src/SketcherPrs/icons/mirror.png differ
index 9e7ce02ae348cfb50ee3f37950e607beb4bfd377..129fdb2cfd9db0b6c6fe493c8034fc8dc2ce25f9 100644 (file)
@@ -131,35 +131,41 @@ void XGUI_ActionsMgr::updateOnViewSelection()
   if (!myOperationMgr->hasOperation())
     return;
 
-  ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
-  FeaturePtr anActiveFeature = anOperation->feature();
-  if(!anActiveFeature.get())
+  QStringList aIdList = myOperationMgr->operationList();
+  //ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
+  //FeaturePtr anActiveFeature = anOperation->feature();
+  //if(!anActiveFeature.get())
+  if (aIdList.isEmpty())
     return;
 
-  QString aFeatureId = QString::fromStdString(anActiveFeature->getKind());
+  //QString aFeatureId = QString::fromStdString(anActiveFeature->getKind());
   XGUI_Selection* aSelection = myWorkshop->selector()->selection();
   if (aSelection->getSelected().size() == 0) {
-    foreach(QString aId, nestedCommands(aFeatureId)) {
-      setActionEnabled(aId, true);
+    foreach(QString aFeatureId, aIdList) {
+      foreach(QString aId, nestedCommands(aFeatureId)) {
+        setActionEnabled(aId, true);
+      }
     }
   } else { 
     SessionPtr aMgr = ModelAPI_Session::get();
     ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
-    foreach(QString aId, nestedCommands(aFeatureId)) {
-      std::list<ModelAPI_Validator*> aValidators;
-      std::list<std::list<std::string> > anArguments;
-      aFactory->validators(aId.toStdString(), aValidators, anArguments);
-      std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
-      std::list<std::list<std::string> >::iterator aValidatorArgs = anArguments.begin();
-      for (; aValidator != aValidators.end(); aValidator++, aValidatorArgs++) {
-        if (!(*aValidator))
-          continue;
-        const ModuleBase_SelectionValidator* aSelValidator =
-            dynamic_cast<const ModuleBase_SelectionValidator*>(*aValidator);
-        if (!aSelValidator)
-          continue;
-        setActionEnabled(aId, aSelValidator->isValid(aSelection, *aValidatorArgs));
+    foreach(QString aFeatureId, aIdList) {
+      foreach(QString aId, nestedCommands(aFeatureId)) {
+        std::list<ModelAPI_Validator*> aValidators;
+        std::list<std::list<std::string> > anArguments;
+        aFactory->validators(aId.toStdString(), aValidators, anArguments);
+        std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
+        std::list<std::list<std::string> >::iterator aValidatorArgs = anArguments.begin();
+        for (; aValidator != aValidators.end(); aValidator++, aValidatorArgs++) {
+          if (!(*aValidator))
+            continue;
+          const ModuleBase_SelectionValidator* aSelValidator =
+              dynamic_cast<const ModuleBase_SelectionValidator*>(*aValidator);
+          if (!aSelValidator)
+            continue;
+          setActionEnabled(aId, aSelValidator->isValid(aSelection, *aValidatorArgs));
 
+        }
       }
     }
   }
index 91d5c2f7cc99c9831aea1cf8e7e85844c6e57d5a..1051298f4b9bdb2765a919e517b7fa117f29a790 100644 (file)
@@ -265,10 +265,10 @@ void XGUI_ContextMenuMgr::addViewerItems(QMenu* theMenu) const
         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->canChangeColor())
+      theMenu->addAction(action("COLOR_CMD"));
   }
   if (!myWorkshop->isSalomeMode()) {
     theMenu->addSeparator();
index cbe4bb8fe0235dcd4033d554b039711c6eae0132..57cb4980184dcd53395de57db0d13164a03e1cc5 100644 (file)
@@ -706,7 +706,9 @@ void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFi
   Handle(AIS_InteractiveContext) aContext = AISContext();
   if (aContext.IsNull())
     return;
-  GetFilter()->Remove(theFilter);
+  Handle(SelectMgr_AndFilter) aCompositeFilter = GetFilter();
+  if (aCompositeFilter->IsIn(theFilter))
+    aCompositeFilter->Remove(theFilter);
 }
 
 void XGUI_Displayer::removeFilters()