1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_ConstraintRadius.cpp
4 // Created: 26 May 2014
5 // Author: Artem ZHIDKOV
7 #include "SketchPlugin_ConstraintRadius.h"
9 #include <SketchPlugin_Arc.h>
10 #include <SketchPlugin_Circle.h>
11 #include <SketchPlugin_Point.h>
13 #include <ModelAPI_AttributeDouble.h>
14 #include <ModelAPI_Data.h>
16 #include <GeomAPI_Pnt2d.h>
17 #include <GeomAPI_Circ.h>
18 #include <GeomAPI_Circ2d.h>
19 #include <GeomAPI_Dir.h>
20 #include <GeomAPI_XYZ.h>
21 #include <GeomDataAPI_Point2D.h>
22 #include <GeomDataAPI_Dir.h>
24 #include <Config_PropManager.h>
26 SketchPlugin_ConstraintRadius::SketchPlugin_ConstraintRadius()
30 void SketchPlugin_ConstraintRadius::initAttributes()
32 data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::type());
33 data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
34 data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::type());
37 void SketchPlugin_ConstraintRadius::execute()
39 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
40 ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
41 FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
44 std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
45 if (aFeature->getKind() == SketchPlugin_Circle::ID()) {
46 AttributeDoublePtr anAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
47 aData->attribute(SketchPlugin_Circle::RADIUS_ID()));
49 aRadius = anAttribute->value();
50 } else if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
51 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
52 GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Arc::CENTER_ID()));
53 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
54 GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Arc::START_ID()));
55 if (aCenterAttr && aStartAttr)
56 aRadius = aCenterAttr->pnt()->distance(aStartAttr->pnt());
58 //std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
59 // ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
60 //if(!aValueAttr->isInitialized()) {
61 // aValueAttr->setValue(aRadius);
66 double SketchPlugin_ConstraintRadius::circleRadius(std::shared_ptr<ModelAPI_Feature>& theCirc)
68 static const double kErrorResult = -1.;
72 std::shared_ptr<ModelAPI_Data> aData = data();
73 std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
74 ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
77 theCirc = ModelAPI_Feature::feature(anAttr->object());
78 std::string aKind = theCirc ? theCirc->getKind() : "";
79 if (aKind != SketchPlugin_Circle::ID() && aKind != SketchPlugin_Arc::ID())
82 DataPtr aCircData = theCirc->data();
83 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
84 if (aKind == SketchPlugin_Circle::ID()) {
85 AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
86 aCircData->attribute(SketchPlugin_Circle::RADIUS_ID()));
87 return aCircRadius->value();
89 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
90 aCircData->attribute(SketchPlugin_Arc::CENTER_ID()));
91 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
92 GeomDataAPI_Point2D>(aCircData->attribute(SketchPlugin_Arc::START_ID()));
93 return aCenterAttr->pnt()->distance(aStartAttr->pnt());
98 AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePrevious)
100 std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
101 double aRadius = circleRadius(aCyrcFeature);
103 return thePrevious; // can not create a good presentation
106 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
107 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
108 std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt;
109 if (aFlyoutAttr->isInitialized()) {
110 aFlyoutPnt = sketch()->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
114 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
115 if (aCyrcFeature->getKind() == SketchPlugin_Circle::ID()) { // circle
116 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
117 aCyrcFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID()));
119 double aShift = aRadius * 1.1;
120 std::shared_ptr<GeomAPI_Pnt2d> aPnt = aCenterAttr->pnt();
121 std::shared_ptr<GeomAPI_Pnt2d> aFPnt =
122 std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt->x() + aShift, aPnt->y() + aShift));
123 aFlyoutAttr->setValue(aFPnt);
124 aFlyoutPnt = sketch()->to3D(aFPnt->x(), aFPnt->y());
127 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
128 aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID()));
130 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
131 GeomDataAPI_Point2D>(aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID()));
132 aFlyoutAttr->setValue(aStartAttr->pnt());
133 aFlyoutPnt = sketch()->to3D(aStartAttr->pnt()->x(), aStartAttr->pnt()->y());
137 std::shared_ptr<GeomAPI_Pnt> aCenter = sketch()->to3D(aCenterAttr->x(), aCenterAttr->y());
138 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
139 sketch()->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
140 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
141 std::shared_ptr<GeomAPI_Circ> aCircle(new GeomAPI_Circ(aCenter, aNormal, aRadius));
144 std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
145 ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
146 if (aValueAttr->isInitialized())
147 aRadius = aValueAttr->value();
148 AISObjectPtr anAIS = thePrevious;
150 anAIS = AISObjectPtr(new GeomAPI_AISObject);
151 anAIS->createRadius(aCircle, aFlyoutPnt, aRadius);
153 // Set color from preferences
154 std::vector<int> aRGB = Config_PropManager::color("Visualization", "radius_color", RADIUS_COLOR);
155 anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]);
159 void SketchPlugin_ConstraintRadius::move(double theDeltaX, double theDeltaY)
161 std::shared_ptr<ModelAPI_Data> aData = data();
162 if (!aData->isValid())
165 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
166 ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
167 FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
170 std::string aCenterAttrName;
171 if (aFeature->getKind() == SketchPlugin_Circle::ID())
172 aCenterAttrName = SketchPlugin_Circle::CENTER_ID();
173 else if (aFeature->getKind() == SketchPlugin_Arc::ID())
174 aCenterAttrName = SketchPlugin_Arc::CENTER_ID();
175 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
176 GeomDataAPI_Point2D>(aFeature->data()->attribute(aCenterAttrName));
177 std::shared_ptr<GeomAPI_Pnt2d> aCenter = aCenterAttr->pnt();
179 // The specified delta applied on the circle curve,
180 // so it will be scaled due to distance between flyout and center points
181 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
182 GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
183 std::shared_ptr<GeomAPI_Pnt2d> aFlyout = aFlyoutAttr->pnt();
185 std::shared_ptr<ModelAPI_AttributeDouble> aRadius = std::dynamic_pointer_cast<
186 ModelAPI_AttributeDouble>(aData->attribute(SketchPlugin_Constraint::VALUE()));
187 double aScale = aFlyout->distance(aCenter) / aRadius->value();
189 std::shared_ptr<GeomAPI_Circ2d> aCircle(new GeomAPI_Circ2d(aCenter, aFlyout));
190 aFlyout->setX(aFlyout->x() + aScale * theDeltaX);
191 aFlyout->setY(aFlyout->y() + aScale * theDeltaY);
192 aFlyout = aCircle->project(aFlyout);
194 aFlyoutAttr->setValue(aFlyout->x(), aFlyout->y());
197 void SketchPlugin_ConstraintRadius::attributeChanged(const std::string& theID) {
198 if (theID == SketchPlugin_Constraint::ENTITY_A()) {
199 std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
200 ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
201 if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
202 std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
203 double aRadius = circleRadius(aCyrcFeature);
204 if (aRadius > 0) { // set as value the radius of updated reference to another circle
205 aValueAttr->setValue(aRadius);