--- /dev/null
+# 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())
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);
}
//==================================================================================================
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);
}
}
//==================================================================================================
-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();
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.
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 */)
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.
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);
}
}
//--------------------------------------------------------------------------------------
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);
}
//--------------------------------------------------------------------------------------
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());
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);
/// 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;
#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"
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,
class SketchAPI_Rectangle;
class SketchAPI_Rotation;
class SketchAPI_Translation;
-class SketchAPI_MacroRectangle;
+
//--------------------------------------------------------------------------------------
typedef std::pair<std::shared_ptr<GeomAPI_Pnt2d>, ModelHighAPI_RefAttr> PointOrReference;
//--------------------------------------------------------------------------------------
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(
#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>
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();
}
}
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());
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();
}
}
- 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);
return anAIS;
}
+
* \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
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;
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;
}
{
static const std::string ID("rectangle_start_point1");
return ID;
- }
+ }
+
/// 2D point - end point of the Rectangle
inline static const std::string& END1_ID()
{
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()
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
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();
#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;
{
}
+
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()
{
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++)
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);
}
}
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)
{
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++)
{
/// 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))
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);
}
return;
}
- // store results.
-
+ /// store results.
GeomShapePtr aRectangleShape;
ListOfShape aSubs;
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)
{
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();
#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
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;
}
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);
private:
/// \brief updateLines crates lines from start and en points
void updateLines();
+ void updateStartPoint();
};
+
#endif
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"