Salome HOME
rectangle feature: complete rectangle type by center and end points
authorrraphael <raphael.raphael@c-s.fr>
Mon, 18 Jan 2021 16:10:03 +0000 (17:10 +0100)
committerrraphael <raphael.raphael@c-s.fr>
Mon, 18 Jan 2021 16:10:03 +0000 (17:10 +0100)
12 files changed:
src/PythonAPI/Test/TestAddRectangle.py [new file with mode: 0644]
src/SketchAPI/SketchAPI_MacroRectangle.cpp
src/SketchAPI/SketchAPI_MacroRectangle.h
src/SketchAPI/SketchAPI_Rectangle.cpp
src/SketchAPI/SketchAPI_Rectangle.h
src/SketchAPI/SketchAPI_Sketch.cpp
src/SketchAPI/SketchAPI_Sketch.h
src/SketchPlugin/SketchPlugin_MacroRectangle.cpp
src/SketchPlugin/SketchPlugin_MacroRectangle.h
src/SketchPlugin/SketchPlugin_Rectangle.cpp
src/SketchPlugin/SketchPlugin_Rectangle.h
src/SketchPlugin/plugin-Sketch.xml

diff --git a/src/PythonAPI/Test/TestAddRectangle.py b/src/PythonAPI/Test/TestAddRectangle.py
new file mode 100644 (file)
index 0000000..d22cc3a
--- /dev/null
@@ -0,0 +1,45 @@
+# Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+from salome.shaper import geom
+
+model.begin()
+partSet = model.moduleDocument()
+part = model.addPart(partSet).document()
+
+sketch = model.addSketch(part, model.defaultPlane("XOY"))
+
+# rectangles from start and end points
+rectangle_1 = sketch.addRectangle(0, 0, 50, 50)
+
+startPoint = geom.Pnt2d(50, 50)
+endPoint = geom.Pnt2d(100, 100)
+rectangle_2 = sketch.addRectangle(startPoint, endPoint)
+
+# rectangles from center and end points -> add a True argument
+centerPoint = geom.Pnt2d(100, 100)
+endPoint2 = geom.Pnt2d(120, 75)
+rectangle_3 = sketch.addRectangle(centerPoint, endPoint2, True)
+rectangle_4 = sketch.addRectangle(10, 5, 25, 75, True)
+
+model.end()
+
+
+assert(model.checkPythonDump())
index d2614f452ef1ec5fde223e6c8cd689cd41b121bc..a619aefd25244cc9caba71544c5a28188df8d0bb 100644 (file)
@@ -39,12 +39,12 @@ SketchAPI_MacroRectangle::SketchAPI_MacroRectangle(const std::shared_ptr<ModelAP
                                                    double theStartX,
                                                    double theStartY,
                                                    double theSecondX,
-                                                   double theSecondY, bool isSecondPointCenter):
+                                                   double theSecondY, bool isFirstPointCenter):
   SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
-    if(isSecondPointCenter)
-      setByStartAndCenterPoints(theStartX, theStartY, theSecondX, theSecondY);
+    if(isFirstPointCenter)
+      setByCenterAndEndPoints(theStartX, theStartY, theSecondX, theSecondY);
     else
       setByStartAndEndPoints(theStartX, theStartY, theSecondX, theSecondY);
   }
@@ -53,12 +53,12 @@ SketchAPI_MacroRectangle::SketchAPI_MacroRectangle(const std::shared_ptr<ModelAP
 //==================================================================================================
 SketchAPI_MacroRectangle::SketchAPI_MacroRectangle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                    const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint,
-                                                   const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint, bool isSecondPointCenter):
+                                                   const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint, bool isFirstPointCenter):
   SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
-    if(isSecondPointCenter)
-      setByStartAndCenterPoints(theStartPoint, theSecondPoint);
+    if(isFirstPointCenter)
+      setByCenterAndEndPoints(theStartPoint, theSecondPoint);
     else
       setByStartAndEndPoints(theStartPoint, theSecondPoint);
   }
@@ -91,20 +91,18 @@ void SketchAPI_MacroRectangle::setByStartAndEndPoints(const std::shared_ptr<Geom
 }
 
 //==================================================================================================
-void SketchAPI_MacroRectangle::setByStartAndCenterPoints(double theStartX, double theStartY,
-                                                         double theCenterX, double theCenterY)
+void SketchAPI_MacroRectangle::setByCenterAndEndPoints(double theCenterX, double theCenterY, double theEndX, double theEndY)
 {
-  fillAttribute(SketchPlugin_MacroRectangle::START_CENTER_POINT_TYPE_ID(), rectangleType());
-  fillAttribute(startPoint2(), theStartX, theStartY);
+  fillAttribute(SketchPlugin_MacroRectangle::CENTER_END_POINT_TYPE_ID(), rectangleType());
+  fillAttribute(endPoint2(), theEndX, theEndY);
   fillAttribute(centerPoint(), theCenterX, theCenterY);
   execute();
 }
 
 //==================================================================================================
-void SketchAPI_MacroRectangle::setByStartAndCenterPoints(const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint,
-                                                         const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint){
-  fillAttribute(SketchPlugin_MacroRectangle::START_END_POINT_TYPE_ID(), rectangleType());
-  fillAttribute(theStartPoint, startPoint2());
+void SketchAPI_MacroRectangle::setByCenterAndEndPoints(const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint, const std::shared_ptr<GeomAPI_Pnt2d>& theEndPoint){
+  fillAttribute(SketchPlugin_MacroRectangle::CENTER_END_POINT_TYPE_ID(), rectangleType());
+  fillAttribute(theEndPoint, endPoint2());
   fillAttribute(theCenterPoint, centerPoint());
 
   execute();
index 773c849d14ed3ad1cb6eeba0e2262832d961c656..c7d2c165e9057cc7944943ec8fe90536b9513884 100644 (file)
@@ -42,13 +42,13 @@ public:
                         double theStartX,
                         double theStartY,
                         double theSecondX,
-                        double theSecondY, bool isSecondPointCenter = false);
+                        double theSecondY, bool isFirstPointCenter = false);
 
   /// Constructor with values.
   SKETCHAPI_EXPORT
   SketchAPI_MacroRectangle(const std::shared_ptr<ModelAPI_Feature>& theFeature,
                         const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint,
-                        const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint, bool isSecondPointCenter = false);
+                        const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint, bool isFirstPointCenter = false);
 
 
   /// Destructor.
@@ -56,13 +56,13 @@ public:
   virtual ~SketchAPI_MacroRectangle();
 
   INTERFACE_5(SketchPlugin_MacroRectangle::ID(),
-              rectangleType, SketchPlugin_MacroRectangle::TYPE_ID(),
+              rectangleType, SketchPlugin_MacroRectangle::RECTANGLE_TYPE_ID(),
               ModelAPI_AttributeString, /** Rectangle type */,
               startPoint1, SketchPlugin_MacroRectangle::START1_ID(),
               GeomDataAPI_Point2D, /** Start point 1 */,
               endPoint1, SketchPlugin_MacroRectangle::END1_ID(),
               GeomDataAPI_Point2D, /** End point 1 */,
-              startPoint2, SketchPlugin_MacroRectangle::START2_ID(),
+              endPoint2, SketchPlugin_MacroRectangle::END2_ID(),
               GeomDataAPI_Point2D, /** First point 2 */,
               centerPoint, SketchPlugin_MacroRectangle::CENTER_ID(),
               GeomDataAPI_Point2D, /** Center point */)
@@ -80,12 +80,12 @@ private:
                                   const std::shared_ptr<GeomAPI_Pnt2d>& theEndPoint);
 
   /// Set by start  and center points.
-  void setByStartAndCenterPoints(double theStartX, double theStartY,
-                                  double theCenterX, double theCenterY);
+  void setByCenterAndEndPoints(double theCenterX, double theCenterY,
+                                  double theEndX, double theEndY);
 
   /// Set by start and center points.
-  void setByStartAndCenterPoints(const std::shared_ptr<GeomAPI_Pnt2d>& theStartPoint,
-                                  const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint);
+  void setByCenterAndEndPoints(const std::shared_ptr<GeomAPI_Pnt2d>& theCenterPoint,
+                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndPoint);
 };
 
 /// Pointer on Rectangle object.
index f9ee374e5b93cdf0fc2eaa2da1874b85fdd8b378..e40b501d2d4478014b83950ba2f9a4aa0d70d980 100644 (file)
@@ -33,24 +33,22 @@ SketchAPI_Rectangle::SketchAPI_Rectangle(
   initialize();
 }
 
-SketchAPI_Rectangle::SketchAPI_Rectangle(
-    const std::shared_ptr<ModelAPI_Feature> & theFeature,
-    double theX1, double theY1, double theX2, double theY2)
+SketchAPI_Rectangle::SketchAPI_Rectangle(const std::shared_ptr<ModelAPI_Feature> & theFeature,
+                                         double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter)
   : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
-    setByCoordinates(theX1, theY1, theX2, theY2);
+    setByCoordinates(theX1, theY1, theX2, theY2, isFirstPointCenter);
   }
 }
 
-SketchAPI_Rectangle::SketchAPI_Rectangle(
-    const std::shared_ptr<ModelAPI_Feature> & theFeature,
-    const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-    const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
+SketchAPI_Rectangle::SketchAPI_Rectangle(const std::shared_ptr<ModelAPI_Feature> & theFeature,
+                                         const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+                                         const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint, bool isFirstPointCenter)
   : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
-    setByPoints(theStartPoint, theEndPoint);
+    setByPoints(theFirstPoint, theEndPoint, isFirstPointCenter);
   }
 }
 
@@ -60,22 +58,37 @@ SketchAPI_Rectangle::~SketchAPI_Rectangle()
 
 //--------------------------------------------------------------------------------------
 void SketchAPI_Rectangle::setByCoordinates(
-    double theX1, double theY1, double theX2, double theY2)
-{
-  fillAttribute(startPoint(), theX1, theY1);
-  fillAttribute(endPoint(), theX2, theY2);
+    double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter)
+{  
+  if(isFirstPointCenter){
+    fillAttribute(centerPoint(), theX1, theY1);
+    double xStart = 2.0*theX1 - theX2;
+    double yStart = 2.0*theY1 - theY2;
+    fillAttribute(startPoint(), xStart, yStart);
+  }
+  else
+    fillAttribute(startPoint(), theX1, theY1);
 
-  execute();
+  fillAttribute(endPoint(), theX2, theY2);
+  execute(true);
 }
 
-void SketchAPI_Rectangle::setByPoints(
-    const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-    const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint)
-{
-  fillAttribute(theStartPoint, startPoint());
-  fillAttribute(theEndPoint, endPoint());
+void SketchAPI_Rectangle::setByPoints(const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+                                      const std::shared_ptr<GeomAPI_Pnt2d> & theSecondPoint, bool isFirstPointCenter)
+{  
+  if(isFirstPointCenter){
+    fillAttribute(theFirstPoint, centerPoint());
+    double xStart = 2.0*theFirstPoint->x() - theSecondPoint->x();
+    double yStart = 2.0*theFirstPoint->y() - theSecondPoint->y();
 
-  execute();
+    std::shared_ptr<GeomAPI_Pnt2d> theStartPoint = std::make_shared<GeomAPI_Pnt2d>(xStart, yStart);
+    fillAttribute(theStartPoint, startPoint());
+  }
+  else
+    fillAttribute(theFirstPoint, startPoint());
+
+  fillAttribute(theSecondPoint, endPoint());
+  execute(true);
 }
 
 //--------------------------------------------------------------------------------------
@@ -94,7 +107,7 @@ std::list<std::shared_ptr<SketchAPI_SketchEntity> > SketchAPI_Rectangle::lines()
 void SketchAPI_Rectangle::dump(ModelHighAPI_Dumper& theDumper) const
 {
 
- FeaturePtr aBase = feature();
 FeaturePtr aBase = feature();
 
   /// do not dump sub-features eg: lines and lines constraints
   AttributeRefListPtr noToDumpList =  aBase->reflist(SketchPlugin_Rectangle::NOT_TO_DUMP_LIST_ID());
@@ -107,15 +120,17 @@ void SketchAPI_Rectangle::dump(ModelHighAPI_Dumper& theDumper) const
 
   const std::string& aSketchName = theDumper.parentName(aBase);
 
-  AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
-  if (anExternal->context()) {
-    // rectangle is external
-    theDumper << aBase << " = " << aSketchName << ".addRectangle(" << anExternal << ")" << std::endl;
-  } else {
+  FeaturePtr aCenterPointFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aBase->refattr(SketchPlugin_Rectangle::CENTER_REF_ID())->object());
+  if(aCenterPointFeature){
+    // rectangle has center
+    theDumper << aBase << " = " << aSketchName << ".addRectangle("
+              << startPoint() << ", " << centerPoint() << ", 1)" << std::endl;
+  }
+  else
     // rectangle given by start and end points
     theDumper << aBase << " = " << aSketchName << ".addRectangle("
               << startPoint() << ", " << endPoint() << ")" << std::endl;
-  }
+
   // dump "auxiliary" flag if necessary
   SketchAPI_SketchEntity::dump(theDumper);
 
index a1e6fea6b18c8e51c4ca118e5f6ebe3e7a2aaeb5..b2fd70670ca23e477ccb321a8ea32596d0db384c 100644 (file)
@@ -42,30 +42,31 @@ public:
   /// Constructor with values
   SKETCHAPI_EXPORT
   SketchAPI_Rectangle(const std::shared_ptr<ModelAPI_Feature> & theFeature,
-                      double theX1, double theY1, double theX2, double theY2);
+                      double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter = false);
   /// Constructor with values
   SKETCHAPI_EXPORT
   SketchAPI_Rectangle(const std::shared_ptr<ModelAPI_Feature> & theFeature,
-                      const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-                      const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint);
+                      const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+                      const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint, bool isFirstPointCenter = false);
   /// Destructor
   SKETCHAPI_EXPORT
   virtual ~SketchAPI_Rectangle();
 
-  INTERFACE_3(SketchPlugin_Rectangle::ID(),
+  INTERFACE_4(SketchPlugin_Rectangle::ID(),
               startPoint, SketchPlugin_Rectangle::START_ID(), GeomDataAPI_Point2D, /** Start point */,
-              endPoint,  SketchPlugin_Rectangle::END_ID(), GeomDataAPI_Point2D, /** End point */,
-              linesList,  SketchPlugin_Rectangle::LINES_LIST_ID(), ModelAPI_AttributeRefList, /** Lines list */
+              endPoint, SketchPlugin_Rectangle::END_ID(), GeomDataAPI_Point2D, /** End point */,
+              centerPoint, SketchPlugin_Rectangle::CENTER_ID(), GeomDataAPI_Point2D, /** Center point */,
+              linesList, SketchPlugin_Rectangle::LINES_LIST_ID(), ModelAPI_AttributeRefList, /** Lines list */
   )
 
   /// Set by coordinates
   SKETCHAPI_EXPORT
-  void setByCoordinates(double theX1, double theY1, double theX2, double theY2);
+  void setByCoordinates(double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter);
 
   /// Set by points
   SKETCHAPI_EXPORT
-  void setByPoints(const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-                   const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint);
+  void setByPoints(const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+                   const std::shared_ptr<GeomAPI_Pnt2d> & theSecondPoint, bool isFirstPointCenter);
 
   /// List of lines composing rectangle
   SKETCHAPI_EXPORT std::list<std::shared_ptr<SketchAPI_SketchEntity> > lines() const;
index db60b1826a13c00bb7341525c158dc8be3679ea9..910beca82e82eac7e4dbdb3b87777a908777936c 100644 (file)
@@ -67,7 +67,6 @@
 #include "SketchAPI_MacroCircle.h"
 #include "SketchAPI_MacroEllipse.h"
 #include "SketchAPI_MacroEllipticArc.h"
-#include "SketchAPI_MacroRectangle.h"
 #include "SketchAPI_Mirror.h"
 #include "SketchAPI_Offset.h"
 #include "SketchAPI_Point.h"
@@ -425,23 +424,23 @@ std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
     compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
   return RectanglePtr(new SketchAPI_Rectangle(aFeature, theStartPoint, theEndPoint));
 }
-/*
-std::shared_ptr<SketchAPI_MacroRectangle> SketchAPI_Sketch::addRectangle(
-    double theX1, double theY1, double theX2, double theY2, bool thePoint2IsCenter)
+
+std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
+    double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
-    compositeFeature()->addFeature(SketchAPI_MacroRectangle::ID());
-  return MacroRectanglePtr(new SketchAPI_MacroRectangle(aFeature, theX1, theY1, theX2, theY2, thePoint2IsCenter));
+    compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
+  return RectanglePtr(new SketchAPI_Rectangle(aFeature, theX1, theY1, theX2, theY2, isFirstPointCenter));
 }
-std::shared_ptr<SketchAPI_MacroRectangle> SketchAPI_Sketch::addRectangle(
-    const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-    const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint,  bool theEndPointIsCenter)
+std::shared_ptr<SketchAPI_Rectangle> SketchAPI_Sketch::addRectangle(
+    const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+    const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint,  bool isFirstPointCenter)
 {
   std::shared_ptr<ModelAPI_Feature> aFeature =
-    compositeFeature()->addFeature(SketchAPI_MacroRectangle::ID());
-  return MacroRectanglePtr(new SketchAPI_MacroRectangle(aFeature, theStartPoint, theEndPoint, theEndPointIsCenter));
+    compositeFeature()->addFeature(SketchAPI_Rectangle::ID());
+  return RectanglePtr(new SketchAPI_Rectangle(aFeature, theFirstPoint, theEndPoint, isFirstPointCenter));
 }
-*/
+
 //--------------------------------------------------------------------------------------
 std::shared_ptr<SketchAPI_Circle> SketchAPI_Sketch::addCircle(double theCenterX,
                                                               double theCenterY,
index d26472f28520f66f42b443b41c9dd98ee5aae231..3f77ba084436c0afeaefd27af859123405ebbf83 100644 (file)
@@ -56,7 +56,7 @@ class SketchAPI_Projection;
 class SketchAPI_Rectangle;
 class SketchAPI_Rotation;
 class SketchAPI_Translation;
-class SketchAPI_MacroRectangle;
+
 //--------------------------------------------------------------------------------------
 typedef std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> PointOrReference;
 //--------------------------------------------------------------------------------------
@@ -180,15 +180,15 @@ public:
       const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
       const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint);
   /// Add rectangle
-  /*SKETCHAPI_EXPORT
-  std::shared_ptr<SketchAPI_MacroRectangle> addRectangle(
-      double theX1, double theY1, double theX2, double theY2, bool thePoint2IsCenter);
+  SKETCHAPI_EXPORT
+  std::shared_ptr<SketchAPI_Rectangle> addRectangle(
+      double theX1, double theY1, double theX2, double theY2, bool isFirstPointCenter);
   /// Add rectangle
   SKETCHAPI_EXPORT
-  std::shared_ptr<SketchAPI_MacroRectangle> addRectangle(
-      const std::shared_ptr<GeomAPI_Pnt2d> & theStartPoint,
-      const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint,  bool theEndPointIsCenter);
-*/
+  std::shared_ptr<SketchAPI_Rectangle> addRectangle(
+      const std::shared_ptr<GeomAPI_Pnt2d> & theFirstPoint,
+      const std::shared_ptr<GeomAPI_Pnt2d> & theEndPoint,  bool isFirstPointCenter);
+
   /// Add circle
   SKETCHAPI_EXPORT
   std::shared_ptr<SketchAPI_Circle> addCircle(
index fae735f631beaf5151e54c4e44f90e10899bb7ec..cd3a06c26a628354089fc51364021f67bf0f9cad 100644 (file)
@@ -31,6 +31,8 @@
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_Events.h>
+
 #include <GeomAlgoAPI_CompoundBuilder.h>
 #include <GeomAlgoAPI_EdgeBuilder.h>
 #include <GeomAlgoAPI_PointBuilder.h>
@@ -43,65 +45,68 @@ const double tolerance = 1e-7;
 
 
 SketchPlugin_MacroRectangle::SketchPlugin_MacroRectangle()
-  : SketchPlugin_SketchEntity()
+  : SketchPlugin_SketchEntity(), myHasCenterPoint(false)
 {  
 }
 
 void SketchPlugin_MacroRectangle::initAttributes()
 {
   data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
-
   data()->addAttribute(START1_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(END1_ID(), GeomDataAPI_Point2D::typeId());
-
-  data()->addAttribute(START2_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(END2_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(RECTANGLE_TYPE_ID(), ModelAPI_AttributeString::typeId());
+  data()->addAttribute(EDIT_RECTANGLE_TYPE_ID(), ModelAPI_AttributeString::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_RECTANGLE_TYPE_ID());
 
-  data()->addAttribute(TYPE_ID(), ModelAPI_AttributeString::typeId());
-  data()->addAttribute(EDIT_TYPE_ID(), ModelAPI_AttributeString::typeId());
-
-  string(EDIT_TYPE_ID())->setValue("");
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EDIT_TYPE_ID());
+  string(EDIT_RECTANGLE_TYPE_ID())->setValue("");
 }
 
-void SketchPlugin_MacroRectangle::startPoint()
+void SketchPlugin_MacroRectangle::endPoint()
 {
-  std::shared_ptr<GeomDataAPI_Point2D> aStartPoint;
-  if(string(TYPE_ID())->value() == START_END_POINT_TYPE_ID())
-    aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START1_ID()));
+  std::shared_ptr<GeomDataAPI_Point2D> aEndPoint;
+  if(string(RECTANGLE_TYPE_ID())->value() == START_END_POINT_TYPE_ID())
+    aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END1_ID()));
   else
-    aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START2_ID()));
-  if(aStartPoint->isInitialized())
-    myStartPoint = std::make_shared<GeomAPI_Pnt2d>(aStartPoint->x(), aStartPoint->y());
+    aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END2_ID()));
+  if(aEndPoint->isInitialized())
+    myEndPoint = std::make_shared<GeomAPI_Pnt2d>(aEndPoint->x(), aEndPoint->y());
   else
-    myStartPoint.reset();
+    myEndPoint.reset();
 }
 
-void SketchPlugin_MacroRectangle::endPoint()
+void SketchPlugin_MacroRectangle::startPoint()
 {
-  if(string(TYPE_ID())->value() == START_END_POINT_TYPE_ID())
+  if(string(RECTANGLE_TYPE_ID())->value() == START_END_POINT_TYPE_ID())
   {
-    std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END1_ID()));
-    if(aEndPoint->isInitialized())
-      myEndPoint = std::make_shared<GeomAPI_Pnt2d>(aEndPoint->x(), aEndPoint->y());
+    std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START1_ID()));
+    if(aStartPoint->isInitialized())
+      myStartPoint = std::make_shared<GeomAPI_Pnt2d>(aStartPoint->x(), aStartPoint->y());
     else
-      myEndPoint.reset();
+      myStartPoint.reset();
   }
   else
   {
     /// Compute end point as the symmetric of start point w.r.t. center
-    std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START2_ID()));
+    std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END2_ID()));
     std::shared_ptr<GeomDataAPI_Point2D> aCenterPoint =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
-    double xEnd = 2.0*aCenterPoint->x() - aStartPoint->x();
-    double yEnd = 2.0*aCenterPoint->y() - aStartPoint->y();
 
-    if(aStartPoint ->isInitialized() && aCenterPoint->isInitialized())
-      myEndPoint =  std::make_shared<GeomAPI_Pnt2d>(xEnd, yEnd);
+    if(aCenterPoint->isInitialized())
+    {
+      myCenterPoint = std::make_shared<GeomAPI_Pnt2d>(aCenterPoint->x(), aCenterPoint->y());
+      myHasCenterPoint = true;
+    }
+    double xStart = 2.0*aCenterPoint->x() - aEndPoint->x();
+    double yStart = 2.0*aCenterPoint->y() - aEndPoint->y();
+
+    if(aEndPoint->isInitialized() && aCenterPoint->isInitialized())
+      myStartPoint =  std::make_shared<GeomAPI_Pnt2d>(xStart, yStart);
     else
-      myEndPoint.reset();
+      myStartPoint.reset();
   }
 }
 
@@ -112,12 +117,23 @@ void SketchPlugin_MacroRectangle::execute()
   if(!myStartPoint || !myEndPoint || !aSketch) {
     return ;
   }
+  // Wait all constraints being created, then send update events
+  static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+  bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
+  if (isUpdateFlushed)
+    Events_Loop::loop()->setFlushed(anUpdateEvent, false);
 
   /// create a rectangle sketch
   FeaturePtr myRectangleFeature = aSketch->addFeature(SketchPlugin_Rectangle::ID());
   if(!myRectangleFeature)
     return;
 
+  if(myHasCenterPoint){
+    std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+          myRectangleFeature->attribute(SketchPlugin_Rectangle::CENTER_ID()))->setValue(myCenterPoint->x(),
+                                                                                       myCenterPoint->y());
+  }
+
   std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
         myRectangleFeature->attribute(SketchPlugin_Rectangle::START_ID()))->setValue(myStartPoint->x(),
                                                                                      myStartPoint->y());
@@ -128,18 +144,22 @@ void SketchPlugin_MacroRectangle::execute()
   myRectangleFeature->boolean(SketchPlugin_Rectangle::AUXILIARY_ID())
       ->setValue(boolean(AUXILIARY_ID())->value());
   myRectangleFeature->execute();
+
+  /// Send events to update the sub-features by the solver.
+  if (isUpdateFlushed)
+    Events_Loop::loop()->setFlushed(anUpdateEvent, true);  
 }
 
 void SketchPlugin_MacroRectangle::attributeChanged(const std::string& theID)
 {
-  if(theID == TYPE_ID()) {
+  if(theID == RECTANGLE_TYPE_ID()) {
     SketchPlugin_Tools::resetAttribute(this, START1_ID());
     SketchPlugin_Tools::resetAttribute(this, END1_ID());
     SketchPlugin_Tools::resetAttribute(this, CENTER_ID());
-    SketchPlugin_Tools::resetAttribute(this, START2_ID());
+    SketchPlugin_Tools::resetAttribute(this, END2_ID());
   }
   else if (theID == START1_ID() || theID == END1_ID() ||
-           theID == START2_ID() || theID == CENTER_ID())
+           theID == END2_ID() || theID == CENTER_ID())
   {
     // update points
     startPoint();
@@ -183,13 +203,13 @@ AISObjectPtr SketchPlugin_MacroRectangle::getAISObject(AISObjectPtr thePrevious)
     }
   }
 
-  if(string(TYPE_ID())->value() == START_CENTER_POINT_TYPE_ID()){
-    /// draw  a line start->center
+  if(string(RECTANGLE_TYPE_ID())->value() == CENTER_END_POINT_TYPE_ID()){
+    /// draw  a line center->end
     std::shared_ptr<GeomDataAPI_Point2D> aCenterPoint =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
 
-    std::shared_ptr<GeomAPI_Pnt> theStart(aSketch->to3D(myStartPoint->x(), myStartPoint->y()));
-    std::shared_ptr<GeomAPI_Pnt> theEnd(aSketch->to3D(aCenterPoint->x(), aCenterPoint->y()));
+    std::shared_ptr<GeomAPI_Pnt> theEnd(aSketch->to3D(myEndPoint->x(), myEndPoint->y()));
+    std::shared_ptr<GeomAPI_Pnt> theStart(aSketch->to3D(aCenterPoint->x(), aCenterPoint->y()));
     GeomShapePtr aLine = GeomAlgoAPI_EdgeBuilder::line(theStart, theEnd);
     if(aLine)
       aShapes.push_back(aLine);
@@ -209,3 +229,4 @@ AISObjectPtr SketchPlugin_MacroRectangle::getAISObject(AISObjectPtr thePrevious)
 
   return anAIS;
 }
+
index fc196f98f8f3efbecc2a1b18053a55e859e8e0d1..46208f862d709f229f41f6c8ea065001d0a2fb78 100644 (file)
@@ -30,7 +30,8 @@ class GeomAPI_Pnt2d;
  * \ingroup Plugins
  * \brief Feature for creation of the new Rectangle in Sketch.
  */
-class SketchPlugin_MacroRectangle: public SketchPlugin_SketchEntity,  public GeomAPI_IPresentable
+class SketchPlugin_MacroRectangle: public SketchPlugin_SketchEntity,
+    public GeomAPI_IPresentable
 {
 public:
   /// Rectangle feature kind
@@ -40,13 +41,13 @@ public:
     return ID;
   }
 
-  inline static const std::string& TYPE_ID()
+  inline static const std::string& RECTANGLE_TYPE_ID()
   {
     static const std::string ID("rectangle_type");
     return ID;
   }
 
-  inline static const std::string& EDIT_TYPE_ID()
+  inline static const std::string& EDIT_RECTANGLE_TYPE_ID()
   {
     static const std::string ID("edit_rectangle_type");
     return ID;
@@ -58,9 +59,9 @@ public:
     return ID;
   }
 
-  inline static const std::string& START_CENTER_POINT_TYPE_ID()
+  inline static const std::string& CENTER_END_POINT_TYPE_ID()
   {
-    static const std::string ID("rectangle_type_by_start_and_center_points");
+    static const std::string ID("rectangle_type_by_center_and_end_points");
     return ID;
   }
 
@@ -69,7 +70,8 @@ public:
   {
     static const std::string ID("rectangle_start_point1");
     return ID;
-  } 
+  }
+
   /// 2D point - end point of the Rectangle
   inline static const std::string& END1_ID()
   {
@@ -77,18 +79,18 @@ public:
     return ID;
   }
   /// 2D point - start point of the second Rectangle type
-  inline static const std::string& START2_ID()
+  inline static const std::string& END2_ID()
   {
-    static const std::string ID("rectangle_start_point2");
+    static const std::string ID("rectangle_end_point2");
     return ID;
   }
 
-   /// 2D point - center point of the second Rectangle type
+  /// 2D point - center point of the second Rectangle type
   inline static const std::string& CENTER_ID()
   {
     static const std::string ID("rectangle_center_point");
     return ID;
-  } 
+  }
 
   /// Returns the kind of a feature
   SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
@@ -97,7 +99,7 @@ public:
     return MY_KIND;
   }
 
-   /// Called on change of any argument-attribute of this object
+  /// Called on change of any argument-attribute of this object
   SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
 
   /// Creates a new part document if needed
@@ -120,7 +122,8 @@ private:
 
   std::shared_ptr<GeomAPI_Pnt2d> myStartPoint;
   std::shared_ptr<GeomAPI_Pnt2d> myEndPoint;
-
+  std::shared_ptr<GeomAPI_Pnt2d> myCenterPoint;
+  bool myHasCenterPoint;
   void startPoint();
   void endPoint();
   FeaturePtr createRectangle();
index 3933f997c9d5d2a841dbaa55e3a64ea464ccfe7a..0518bdd33a224a48b6c859b0c34534eeb476bedb 100644 (file)
 
 #include "SketchPlugin_Rectangle.h"
 #include "SketchPlugin_Sketch.h"
-#include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_AttributeSelection.h>
 #include <ModelAPI_Validator.h>
-#include <ModelAPI_Session.h>
 #include <ModelAPI_AttributeRefList.h>
 #include <ModelAPI_AttributeRefAttr.h>
 #include <GeomDataAPI_Point2D.h>
 #include <GeomAlgoAPI_CompoundBuilder.h>
 
 #include <SketchPlugin_Line.h>
+#include <SketchPlugin_Point.h>
+#include <SketchPlugin_Tools.h>
 #include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketchPlugin_ConstraintHorizontal.h>
 #include <SketchPlugin_ConstraintVertical.h>
+#include <SketchPlugin_ConstraintCoincidenceInternal.h>
 
 #include <cmath>
 
+
 const double tolerance = 1e-7;
 
 
@@ -44,24 +46,35 @@ SketchPlugin_Rectangle::SketchPlugin_Rectangle()
 {
 }
 
+
 void SketchPlugin_Rectangle::initDerivedClassAttributes()
 {
+  data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
   data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
-  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
+  data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_ID());
+  data()->addAttribute(CENTER_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_REF_ID());
   data()->addAttribute(LINES_LIST_ID(), ModelAPI_AttributeRefList::typeId());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LINES_LIST_ID());
+  data()->addAttribute(DIAGONAL_LIST_ID(), ModelAPI_AttributeRefList::typeId());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), DIAGONAL_LIST_ID());
   data()->addAttribute(ISHV_LIST_ID(), ModelAPI_AttributeIntArray::typeId());
-
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), ISHV_LIST_ID());
   data()->addAttribute(NOT_TO_DUMP_LIST_ID(), ModelAPI_AttributeRefList::typeId());
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), NOT_TO_DUMP_LIST_ID());
+}
 
-  AttributeIntArrayPtr isHVList = intArray(ISHV_LIST_ID());
-  isHVList->setSize(4, false);
-  for(int i = 0; i< 4;)
-    isHVList->setValue(i++, 0, false);
- }
+namespace {
+  static const std::pair<unsigned, std::string> cornerToDiagonalLinePoints[4]
+  = {
+    {0, SketchPlugin_Line::START_ID()},
+    {1, SketchPlugin_Line::START_ID()},
+    {0, SketchPlugin_Line::END_ID()},
+    {1, SketchPlugin_Line::END_ID()}
+  };
+}
 
 void SketchPlugin_Rectangle::updateLines()
 {
@@ -73,14 +86,17 @@ void SketchPlugin_Rectangle::updateLines()
   std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END_ID()));
 
-  double xMin = std::min(aStartPoint->x(),  aEndPoint->x());
-  double xMax = std::max(aStartPoint->x(),  aEndPoint->x());
-  double yMin = std::min(aStartPoint->y(),  aEndPoint->y());
-  double yMax = std::max(aStartPoint->y(),  aEndPoint->y());
-  std::vector<double> aX = {xMin, xMax, xMax, xMin};
-  std::vector<double> aY = {yMin, yMin, yMax, yMax};
+  double aXStart = aStartPoint->x();
+  double aYStart = aStartPoint->y();
+  double aXEnd = aEndPoint->x();
+  double aYEnd = aEndPoint->y();
+
+  std::vector<double> aX = {aXStart, aXStart, aXEnd, aXEnd};
+  std::vector<double> aY = {aYStart, aYEnd, aYEnd, aYStart};
 
   bool anAuxiliary = data()->boolean(AUXILIARY_ID())->value();
+  AttributeRefListPtr aDiagonalList =  reflist(DIAGONAL_LIST_ID());
+
 
   /// Update coordinates of rectangle lines
   for(unsigned  i = 0; i < aNbLines; i++)
@@ -90,9 +106,37 @@ void SketchPlugin_Rectangle::updateLines()
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aLine->attribute(SketchPlugin_Line::START_ID()));
     std::shared_ptr<GeomDataAPI_Point2D> aLineEnd =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aLine->attribute(SketchPlugin_Line::END_ID()));
-       aLineStart->setValue(aX[i], aY[i]);
-    aLineEnd->setValue(aX[(i+1)%4], aY[(i+1)%4]);
+    aLineStart->setValue(aX[(i+3)%4], aY[(i+3)%4]);
+    aLineEnd->setValue(aX[i], aY[i]);
     aLine->data()->boolean(AUXILIARY_ID())->setValue(anAuxiliary);
+    /// Cooordinates of diagonals
+    if(aDiagonalList->size())
+    {
+      auto aDiagonalPoint = cornerToDiagonalLinePoints[i];
+      FeaturePtr aDiagonal = std::dynamic_pointer_cast<ModelAPI_Feature>(aDiagonalList->object(aDiagonalPoint.first));
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aDiagonal->attribute(aDiagonalPoint.second))->setValue(aX[(i+3)%4], aY[(i+3)%4]);
+    }
+  }
+}
+
+void SketchPlugin_Rectangle::updateStartPoint()
+{
+  /// Retrieving list of already created lines
+  AttributeRefListPtr aLinesList = reflist(LINES_LIST_ID());
+  unsigned  aNbLines = aLinesList->size();
+  std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START_ID()));
+
+  double aXStart = aStartPoint->x();
+  double aYStart = aStartPoint->y();
+
+  /// Update coordinates of rectangle lines
+  for(unsigned  i = 0; i < aNbLines; i++)
+  {
+    FeaturePtr aLine = std::dynamic_pointer_cast<ModelAPI_Feature>(aLinesList->object(i));
+    std::shared_ptr<GeomDataAPI_Point2D> aLineStart =
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aLine->attribute(SketchPlugin_Line::END_ID()));
+    aLineStart->setValue(aXStart, aYStart);
   }
 }
 
@@ -118,6 +162,7 @@ void SketchPlugin_Rectangle::execute()
   unsigned aNbLines = aLinesList->size();
   AttributeIntArrayPtr isHVList = intArray(ISHV_LIST_ID());
   AttributeRefListPtr aNotToDumpList = reflist(NOT_TO_DUMP_LIST_ID());
+  AttributeRefListPtr aDiagonalList =  reflist(DIAGONAL_LIST_ID());
 
   if(aNbLines == 1)
   {
@@ -128,8 +173,35 @@ void SketchPlugin_Rectangle::execute()
       aLinesList->append(aLine);
       aNotToDumpList->append(aLine);
     }
+
     updateLines();
+
     aNbLines = aLinesList->size();
+    FeaturePtr aCenterPointFeature;
+
+    if(aDiagonalList->size())
+    {
+      /// compute diagonals intersection point
+      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+
+      aCenterPointFeature = aSketch->addFeature(SketchPlugin_Point::ID());
+      aNotToDumpList->append(aCenterPointFeature);
+      AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+            aCenterPointFeature->attribute(SketchPlugin_Point::COORD_ID()));
+      aCoord->setValue(aCenterAttr->x(), aCenterAttr->y());
+      aCenterPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
+      refattr(CENTER_REF_ID())->setObject(aCenterPointFeature);
+
+      for(int i = 0; i < 2; i++)
+      {
+        FeaturePtr aDiagonal = std::dynamic_pointer_cast<ModelAPI_Feature>(aDiagonalList->object(i));
+        FeaturePtr aConstraint = SketchPlugin_Tools::createConstraintAttrObject(aSketch, SketchPlugin_ConstraintCoincidenceInternal::ID(),
+                                                                                aCoord, aDiagonal);
+        aNotToDumpList->append(aConstraint);
+      }
+    }
+
     /// Create constraints to keep the rectangle
     for( unsigned i = 0; i < aNbLines; i++)
     {
@@ -137,19 +209,34 @@ void SketchPlugin_Rectangle::execute()
       /// connect neighbor lines by coincidence
       unsigned iPrev = (i+3)%4;
       FeaturePtr aPrevLine = std::dynamic_pointer_cast<ModelAPI_Feature>(aLinesList->object(iPrev));
-      FeaturePtr aCoincidence = aSketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
-      aNotToDumpList->append(aCoincidence);
-      AttributeRefAttrPtr aRefAttrA = aCoincidence->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_A());
-      AttributeRefAttrPtr aRefAttrB = aCoincidence->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_B());
-      aRefAttrA->setAttr(aPrevLine->attribute(SketchPlugin_Line::END_ID()));
-      aRefAttrB->setAttr(aLine->attribute(SketchPlugin_Line::START_ID()));
+      FeaturePtr aConstraint = SketchPlugin_Tools::createConstraintAttrAttr(aSketch, SketchPlugin_ConstraintCoincidence::ID(),
+                                                                            aPrevLine->attribute(SketchPlugin_Line::END_ID()),
+                                                                            aLine->attribute(SketchPlugin_Line::START_ID()));
+      aNotToDumpList->append(aConstraint);
+
+      /// case of  rectangle created from its center
+      if(aDiagonalList->size())
+      {
+        auto aDiagonalPoint = cornerToDiagonalLinePoints[i];
+        FeaturePtr aDiagonal = std::dynamic_pointer_cast<ModelAPI_Feature>(aDiagonalList->object(aDiagonalPoint.first));
+        FeaturePtr aConstraint = SketchPlugin_Tools::createConstraintAttrAttr(aSketch, SketchPlugin_ConstraintCoincidenceInternal::ID(),
+                                                                              aDiagonal->attribute(aDiagonalPoint.second),
+                                                                              aLine->attribute(SketchPlugin_Line::START_ID()));
+        aNotToDumpList->append(aConstraint);
+      }
     }
-
     /// Update coordinates of created lines
     updateLines();
   }
 
   /// Add horizontal and vertical constraint for the lines which already have result
+  if(isHVList->size() == 0)
+  {
+    isHVList->setSize(4, false);
+    for(int i = 0; i< 4;)
+      isHVList->setValue(i++, 0, false);
+  }
+
   for(unsigned i = 0; i< aNbLines; i++)
   {
     if(isHVList->value(i))
@@ -163,7 +250,7 @@ void SketchPlugin_Rectangle::execute()
       aHVName = SketchPlugin_ConstraintVertical::ID();
     FeaturePtr aHVConstraint = aSketch->addFeature(aHVName);
     aNotToDumpList->append(aHVConstraint);
-    AttributeRefAttrPtr aRefAttrA = aHVConstraint->refattr(SketchPlugin_ConstraintCoincidence::ENTITY_A());
+    AttributeRefAttrPtr aRefAttrA = aHVConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
     aRefAttrA->setObject(aLine->lastResult());
     isHVList->setValue(i, 1, false);
   }
@@ -175,8 +262,7 @@ void SketchPlugin_Rectangle::execute()
     return;
   }
 
-  // store results.
-
+  /// store results.
   GeomShapePtr aRectangleShape;
   ListOfShape aSubs;
 
@@ -189,25 +275,36 @@ void SketchPlugin_Rectangle::execute()
     aSubs.push_back(aLineResult->shape());
   }
 
-  aRectangleShape = aSubs.empty() ? GeomShapePtr() : GeomAlgoAPI_CompoundBuilder::compound(aSubs);
+  for(int i = 0; i< aDiagonalList->size(); i++)
+  {
+    FeaturePtr aDiagonal = std::dynamic_pointer_cast<ModelAPI_Feature>(aDiagonalList->object(i));
+    ResultPtr aDiagonalResult = aDiagonal->lastResult();
+    if(!aDiagonalResult.get())
+      continue;
+    aSubs.push_back(aDiagonalResult->shape());
+  }
 
+  FeaturePtr aCenterPointFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(refattr(CENTER_REF_ID())->object());
+  if(aCenterPointFeature)
+  {
+    ResultPtr aCenterResult = aCenterPointFeature->lastResult();
+    if(aCenterResult.get())
+      aSubs.push_back(aCenterResult->shape());
+  }
+
+  aRectangleShape = aSubs.empty() ? GeomShapePtr() : GeomAlgoAPI_CompoundBuilder::compound(aSubs);
   std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 0);
   aResult->setShape(aRectangleShape);
   aResult->setIsInHistory(false);
   setResult(aResult, 1);
 }
 
-
-bool SketchPlugin_Rectangle::isFixed() {
-  return data()->selection(EXTERNAL_ID())->context().get() != NULL;
-}
-
 void SketchPlugin_Rectangle::attributeChanged(const std::string& theID)
 {
   if (theID == START_ID() || theID == END_ID())
   {
     AttributeRefListPtr aLinesList = reflist(LINES_LIST_ID());
-    AttributeRefListPtr aNotToDumpList =  reflist(NOT_TO_DUMP_LIST_ID());
+    AttributeRefListPtr aNotToDumpList = reflist(NOT_TO_DUMP_LIST_ID());
     unsigned  aNbLines = aLinesList->size();
     if(aNbLines == 0)
     {
@@ -219,16 +316,33 @@ void SketchPlugin_Rectangle::attributeChanged(const std::string& theID)
       FeaturePtr aLine = aSketch->addFeature(SketchPlugin_Line::ID());
       aLinesList->append(aLine);
       aNotToDumpList->append(aLine);
-    }
 
+      /// if rectangle has center, add 2 iagonals
+      std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+      if(aCenterAttr->isInitialized())
+      {
+        AttributeRefListPtr aDiagonalList = reflist(DIAGONAL_LIST_ID());
+        for(int i = 0; i < 2; i++)
+        {
+          FeaturePtr aDiagonalLine = aSketch->addFeature(SketchPlugin_Line::ID());
+          aDiagonalLine->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
+          aDiagonalList->append(aDiagonalLine);
+          aNotToDumpList->append(aDiagonalLine);
+        }
+      }
+    }
     std::shared_ptr<GeomDataAPI_Point2D> aStartPoint =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(START_ID()));
     std::shared_ptr<GeomDataAPI_Point2D> aEndPoint =
         std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(END_ID()));
 
     if (aStartPoint->isInitialized() && aEndPoint->isInitialized())
-      updateLines();    
+      updateLines();
+    else
+      updateStartPoint();
   }
+
   if (theID == AUXILIARY_ID())
   {
     bool anAuxiliary = data()->boolean(AUXILIARY_ID())->value();
index 7d3e2f4649886c11194c83ef7d21a3584e70b98c..72bef0d6a88c3bf16609b16585928032254185c2 100644 (file)
 
 #include "SketchPlugin.h"
 #include "SketchPlugin_SketchEntity.h"
-#include "SketchPlugin_Sketch.h"
 
 /**\class SketchPlugin_Rectangle
  * \ingroup Plugins
  * \brief Feature for creation of the new Rectangle in Sketch.
  */
 class SketchPlugin_Rectangle: public SketchPlugin_SketchEntity
-
 {
  public:
   /// Rectangle feature kind
@@ -53,10 +51,31 @@ class SketchPlugin_Rectangle: public SketchPlugin_SketchEntity
     return ID;
   }
 
+  /// 2D point - center point of the Rectangle
+  inline static const std::string& CENTER_ID()
+  {
+    static const std::string ID("rectangle_center_point");
+    return ID;
+  }
+
+  /// 2D point - center point of the Rectangle
+  inline static const std::string& CENTER_REF_ID()
+  {
+    static const std::string ID("rectangle_center_point_ref");
+    return ID;
+  }
+
   /// 2D point - list of Rectangle lines
   inline static const std::string& LINES_LIST_ID()
   {
-    static const std::string ID("RectangleList");
+    static const std::string ID("RectangleLinesList");
+    return ID;
+  }
+
+  /// 2D point - list of Diagonal lines
+  inline static const std::string& DIAGONAL_LIST_ID()
+  {
+    static const std::string ID("RectangleDiagonalLinesList");
     return ID;
   }
 
@@ -79,8 +98,8 @@ class SketchPlugin_Rectangle: public SketchPlugin_SketchEntity
     return MY_KIND;
   }
 
-  /// Returns true is sketch element is under the rigid constraint
-  SKETCHPLUGIN_EXPORT virtual bool isFixed();
+  SKETCHPLUGIN_EXPORT virtual bool isMacro() const
+  { return true;}
 
   /// Called on change of any argument-attribute of this object
   SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
@@ -98,6 +117,8 @@ protected:
 private:
   /// \brief updateLines crates lines from start and en points
   void updateLines(); 
+  void updateStartPoint(); 
 };
 
+
 #endif
index ea64ddfe7c7b168128bc3b27532024848e98a69e..813607e5112b7f31239523d043d26dfd15761ab2 100644 (file)
                                      enable_value="enable_by_preferences"/>
             <validator id="GeomValidators_Different" parameters="rectangle_start_point1,rectangle_end_point1"/>
          </box>
-         <box id="rectangle_type_by_start_and_center_points"
+         <box id="rectangle_type_by_center_and_end_points"
               icon="icons/Sketch/rectangle_pt_rad_32x32.png"
-              title="Start and center points">
-           <sketch-2dpoint_selector id="rectangle_start_point2"
-                                    accept_expressions="0"
-                                    title="Rectangle start point"
-                                    tooltip="Start point coordinates"
-                                    enable_value="enable_by_preferences"/>
+              title="Center and end points">
            <sketch-2dpoint_selector id="rectangle_center_point"
                                     accept_expressions="0"
                                     title="Rectangle center point"
                                     tooltip="Center point coordinates"
                                     enable_value="enable_by_preferences"/>
-           <validator id="GeomValidators_Different" parameters="rectangle_start_point2,rectangle_center_point"/>
+           <sketch-2dpoint_selector id="rectangle_end_point2"
+                                    accept_expressions="0"
+                                    title="Rectangle end point"
+                                    tooltip="End point coordinates"
+                                    enable_value="enable_by_preferences"/>
+           <validator id="GeomValidators_Different" parameters="rectangle_end_point2,rectangle_center_point"/>
         </box>
        </toolbox>
        <boolvalue id="Auxiliary"