Salome HOME
Implemented feature for constraint Mirror
authorazv <azv@opencascade.com>
Wed, 18 Mar 2015 04:12:43 +0000 (07:12 +0300)
committerazv <azv@opencascade.com>
Wed, 18 Mar 2015 12:01:34 +0000 (15:01 +0300)
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_ConstraintMirror.h [new file with mode: 0644]
src/SketchPlugin/SketchPlugin_Plugin.cpp
src/SketchPlugin/Test/TestConstraintMirror.py [new file with mode: 0644]
src/SketchPlugin/plugin-Sketch.xml

index e2fc7682907a66d296778b08b05c3209a0a6fe29..b8e644cc62c1fe9d702c8e6a3f87c57f44ac3b52 100644 (file)
@@ -26,6 +26,7 @@ SET(PROJECT_HEADERS
     SketchPlugin_ConstraintVertical.h
     SketchPlugin_ConstraintEqual.h
     SketchPlugin_ConstraintTangent.h
+    SketchPlugin_ConstraintMirror.h
     SketchPlugin_ShapeValidator.h
     SketchPlugin_Validators.h
     SketchPlugin_ResultValidators.h 
@@ -52,6 +53,7 @@ SET(PROJECT_SOURCES
     SketchPlugin_ConstraintVertical.cpp
     SketchPlugin_ConstraintEqual.cpp
     SketchPlugin_ConstraintTangent.cpp
+    SketchPlugin_ConstraintMirror.cpp
     SketchPlugin_ShapeValidator.cpp
     SketchPlugin_Validators.cpp
     SketchPlugin_ResultValidators.cpp
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp
new file mode 100644 (file)
index 0000000..633eed6
--- /dev/null
@@ -0,0 +1,112 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintMirror.cpp
+// Created: 17 Mar 2015
+// Author:  Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintMirror.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Session.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintMirror::SketchPlugin_ConstraintMirror()
+{
+}
+
+void SketchPlugin_ConstraintMirror::initAttributes()
+{
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::type());
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::type());
+}
+
+void SketchPlugin_ConstraintMirror::execute()
+{
+  // Objects to be mirrored will be created here
+  std::shared_ptr<ModelAPI_Data> aData = data();
+  AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
+  if (!aRefListOfShapes->isInitialized())
+    return ;
+
+  AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
+  // Check consistency of initial list and mirrored list
+  std::list<ObjectPtr> anInitialList =  aRefListOfShapes->list();
+  std::list<ObjectPtr> aMirroredList =  aRefListOfMirrored->list();
+  std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
+  std::list<ObjectPtr>::iterator aMirrorIter = aMirroredList.begin();
+  int indFirstWrong = 0; // index of element starts difference in the lists
+  std::set<int> anInvalidInd; // list of indices of removed features
+  std::shared_ptr<SketchPlugin_Feature> aFeatureIn, aFeatureOut;
+  for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) {
+    // Add features and store indices of objects to remove
+    aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
+    aFeatureOut = aMirrorIter != aMirroredList.end() ? 
+        std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirrorIter) :
+        std::shared_ptr<SketchPlugin_Feature>();
+    if (!aFeatureIn) {
+      if (aFeatureOut)
+        break; // the lists are inconsistent
+      continue;
+    }
+    if (!aFeatureOut) {
+      if (aMirrorIter != aMirroredList.end())
+        break; // the lists are inconsistent
+      // There is no mirrored object yet, create it
+      FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
+      aRefListOfMirrored->append(aNewFeature);
+      continue;
+    }
+    if (aFeatureIn->getKind() != aFeatureOut->getKind())
+      break; // the lists are inconsistent
+    if (!aFeatureIn->data()->isValid()) {
+      // initial feature was removed, delete it from lists
+      anInvalidInd.insert(indFirstWrong);
+    }
+    aMirrorIter++;
+  }
+  // Remove from the list objects already deleted before
+  std::set<int>::reverse_iterator anIt = anInvalidInd.rbegin();
+  for ( ; anIt != anInvalidInd.rend(); anIt++) {
+    if (*anIt < indFirstWrong) indFirstWrong--;
+    aRefListOfShapes->remove(aRefListOfShapes->object(*anIt));
+    aRefListOfMirrored->remove(aRefListOfMirrored->object(*anIt));
+  }
+  // If the lists inconsistent, remove all objects from mirrored list starting from indFirstWrong
+  if (anInitIter != anInitialList.end()) {
+    while (aRefListOfMirrored->size() > indFirstWrong)
+      aRefListOfMirrored->remove(aRefListOfMirrored->object(indFirstWrong));
+    // Create mirrored features instead of removed
+    anInitialList =  aRefListOfShapes->list();
+    anInitIter = anInitialList.begin();
+    for (int i = 0; i < indFirstWrong; i++) anInitIter++;
+    for ( ; anInitIter != anInitialList.end(); anInitIter++) {
+      aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
+      FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
+      aRefListOfMirrored->append(aNewFeature);
+    }
+  }
+}
+
+AISObjectPtr SketchPlugin_ConstraintMirror::getAISObject(AISObjectPtr thePrevious)
+{
+  if (!sketch())
+    return thePrevious;
+
+  AISObjectPtr anAIS = thePrevious;
+  /// TODO: Equal constraint presentation should be put here
+  return anAIS;
+}
+
+
diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.h b/src/SketchPlugin/SketchPlugin_ConstraintMirror.h
new file mode 100644 (file)
index 0000000..841f11a
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:    SketchPlugin_ConstraintMirror.h
+// Created: 17 Mar 2015
+// Author:  Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintMirror_H_
+#define SketchPlugin_ConstraintMirror_H_
+
+#include "SketchPlugin.h"
+#include <SketchPlugin_Sketch.h>
+#include "SketchPlugin_ConstraintBase.h"
+
+/** \class SketchPlugin_ConstraintMirror
+ *  \ingroup Plugins
+ *  \brief Feature for creation of a new constraint mirroring a list of objects regarding to a given line
+ *
+ *  This constraint has two attributes:
+ *  SketchPlugin_Constraint::ENTITY_A() for mirror line and
+ *  SketchPlugin_Constraint::ENTITY_B() for the list of objects
+ *
+ *  Also the constraint has attribute SketchPlugin_Constraint::ENTITY_C()
+ *  which contains list of mirrored objects
+ */
+class SketchPlugin_ConstraintMirror : public SketchPlugin_ConstraintBase
+{
+ public:
+  /// Mirror constraint kind
+  inline static const std::string& ID()
+  {
+    static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
+    return MY_CONSTRAINT_MIRROR_ID;
+  }
+  /// \brief Returns the kind of a feature
+  SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+  {
+    static std::string MY_KIND = SketchPlugin_ConstraintMirror::ID();
+    return MY_KIND;
+  }
+
+  /// \brief Creates a new part document if needed
+  SKETCHPLUGIN_EXPORT virtual void execute();
+
+  /// \brief Request for initialization of data model of the feature: adding all attributes
+  SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+  /// Returns the AIS preview
+  SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
+
+  /// \brief Use plugin manager for features creation
+  SketchPlugin_ConstraintMirror();
+};
+
+#endif
index fd9b04f8ac6331ea67e0bf9f130ae1f6c81d575a..fbf1235ce2e6e07616757b2d64f045a6614a0cf0 100644 (file)
@@ -11,6 +11,7 @@
 #include <SketchPlugin_ConstraintEqual.h>
 #include <SketchPlugin_ConstraintHorizontal.h>
 #include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintMirror.h>
 #include <SketchPlugin_ConstraintParallel.h>
 #include <SketchPlugin_ConstraintPerpendicular.h>
 #include <SketchPlugin_ConstraintRadius.h>
@@ -121,6 +122,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID)
     return FeaturePtr(new SketchPlugin_ConstraintEqual);
   } else if (theFeatureID == SketchPlugin_ConstraintTangent::ID()) {
     return FeaturePtr(new SketchPlugin_ConstraintTangent);
+  } else if (theFeatureID == SketchPlugin_ConstraintMirror::ID()) {
+    return FeaturePtr(new SketchPlugin_ConstraintMirror);
   }
   // feature of such kind is not found
   return FeaturePtr();
@@ -169,6 +172,7 @@ std::shared_ptr<ModelAPI_FeatureStateMessage> SketchPlugin_Plugin
       aMsg->setState(SketchPlugin_ConstraintVertical::ID(), aHasSketchPlane);
       aMsg->setState(SketchPlugin_ConstraintEqual::ID(), aHasSketchPlane);
       aMsg->setState(SketchPlugin_ConstraintTangent::ID(), aHasSketchPlane);
+      aMsg->setState(SketchPlugin_ConstraintMirror::ID(), aHasSketchPlane);
     }
   }
   return aMsg;
diff --git a/src/SketchPlugin/Test/TestConstraintMirror.py b/src/SketchPlugin/Test/TestConstraintMirror.py
new file mode 100644 (file)
index 0000000..de1c087
--- /dev/null
@@ -0,0 +1,126 @@
+"""
+    TestConstraintMirror.py
+    Unit test of SketchPlugin_ConstraintMirror class
+        
+    SketchPlugin_ConstraintMirror
+        static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::type());
+        data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::type());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-17"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Creation of an arc and two lines
+#=========================================================================
+# Arc
+aSession.startOperation()
+aSketchArc1 = aSketchFeature.addFeature("SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# Line 1
+aSession.startOperation()
+aSketchLine1 = aSketchFeature.addFeature("SketchLine")
+aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
+aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
+aLine1StartPoint.setValue(0., 50.)
+aLine1EndPoint.setValue(0., 100.)
+aSession.finishOperation()
+# Line 2
+aSession.startOperation()
+aSketchLine2 = aSketchFeature.addFeature("SketchLine")
+aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
+aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
+aLine2StartPoint.setValue(50., 0.)
+aLine2EndPoint.setValue(100., 0.)
+aSession.finishOperation()
+#=========================================================================
+# Link arc points and lines points by the coincidence constraint
+#=========================================================================
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcStartPoint)
+reflistB.setAttr(aLine1StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcEndPoint)
+reflistB.setAttr(aLine2StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+#=========================================================================
+# Add tangency constraint and check correctness
+#=========================================================================
+aSession.startOperation()
+aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
+aRefObjectA = aTangency.refattr("ConstraintEntityA")
+aRefObjectB = aTangency.refattr("ConstraintEntityB")
+anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
+anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+#=========================================================================
+# Create mirror line
+#=========================================================================
+aSession.startOperation()
+aMirrorLine = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
+aLineStartPoint.setValue(100., 0.)
+aLineEndPoint.setValue(100., 100.)
+aSession.finishOperation()
+#=========================================================================
+# Make mirror for objects created above
+#=========================================================================
+aSession.startOperation()
+aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
+aRefObjectA = aMirror.refattr("ConstraintEntityA")
+aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
+aRefListB = aMirror.reflist("ConstraintEntityB")
+aRefListB.append(aSketchArc1)
+aRefListB.append(aSketchLine1)
+aRefListB.append(aSketchLine2)
+aMirror.execute()
+aSession.finishOperation()
+#=========================================================================
+# End of test
+#=========================================================================
index 3bbfbfead5ede7681d3377d7523da86fe28b7454..b4a7ab35b24d03bc609a1e3a0ea7581719d2b886 100644 (file)
             label="Last object" tooltip="Select line or arc" shape_types="edge">
         </sketch_constraint_shape_selector>
       </feature>
+    <!--  SketchConstraintMirror  -->
+      <feature
+        id="SketchConstraintMirror"
+        title="Mirror"
+        tooltip="Create constraint mirroring group of objects"
+        internal="1" />
     </group>
   </workbench>
 </plugin>