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);
64 // the value should to be computed here, not in the getAISObject in order to change the model value
65 // inside the object transaction. This is important for creating a constraint by preselection.
66 // The display of the presentation in this case happens after the transaction commit
67 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
68 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
69 if (!aFlyoutAttr->isInitialized())
70 compute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT());
74 bool SketchPlugin_ConstraintRadius::compute(const std::string& theAttributeId)
76 if (theAttributeId != SketchPlugin_Constraint::FLYOUT_VALUE_PNT())
79 std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
80 double aRadius = circleRadius(aCyrcFeature);
85 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
86 GeomDataAPI_Point2D>(data()->attribute(theAttributeId));
88 if (aCyrcFeature->getKind() == SketchPlugin_Circle::ID()) { // circle
89 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
90 aCyrcFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID()));
91 double aShift = aRadius * 1.1;
92 std::shared_ptr<GeomAPI_Pnt2d> aPnt = aCenterAttr->pnt();
93 std::shared_ptr<GeomAPI_Pnt2d> aFPnt =
94 std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt->x() + aShift, aPnt->y() + aShift));
95 aFlyoutAttr->setValue(aFPnt);
97 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
98 GeomDataAPI_Point2D>(aCyrcFeature->data()->attribute(SketchPlugin_Arc::START_ID()));
99 aFlyoutAttr->setValue(aStartAttr->pnt());
104 double SketchPlugin_ConstraintRadius::circleRadius(std::shared_ptr<ModelAPI_Feature>& theCirc)
106 static const double kErrorResult = -1.;
110 std::shared_ptr<ModelAPI_Data> aData = data();
111 std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
112 ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
115 theCirc = ModelAPI_Feature::feature(anAttr->object());
116 std::string aKind = theCirc ? theCirc->getKind() : "";
117 if (aKind != SketchPlugin_Circle::ID() && aKind != SketchPlugin_Arc::ID())
120 DataPtr aCircData = theCirc->data();
121 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
122 if (aKind == SketchPlugin_Circle::ID()) {
123 AttributeDoublePtr aCircRadius = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
124 aCircData->attribute(SketchPlugin_Circle::RADIUS_ID()));
125 return aCircRadius->value();
127 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
128 aCircData->attribute(SketchPlugin_Arc::CENTER_ID()));
129 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
130 GeomDataAPI_Point2D>(aCircData->attribute(SketchPlugin_Arc::START_ID()));
131 return aCenterAttr->pnt()->distance(aStartAttr->pnt());
136 AISObjectPtr SketchPlugin_ConstraintRadius::getAISObject(AISObjectPtr thePrevious)
138 std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
139 double aRadius = circleRadius(aCyrcFeature);
141 return thePrevious; // can not create a good presentation
144 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
145 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
146 if (!aFlyoutAttr->isInitialized())
147 return thePrevious; // can not create a good presentation
148 std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = sketch()->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
151 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr;
152 if (aCyrcFeature->getKind() == SketchPlugin_Circle::ID()) { // circle
153 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
154 aCyrcFeature->data()->attribute(SketchPlugin_Circle::CENTER_ID()));
156 aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
157 aCyrcFeature->data()->attribute(SketchPlugin_Arc::CENTER_ID()));
159 std::shared_ptr<GeomAPI_Pnt> aCenter = sketch()->to3D(aCenterAttr->x(), aCenterAttr->y());
160 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
161 sketch()->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
162 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
163 std::shared_ptr<GeomAPI_Circ> aCircle(new GeomAPI_Circ(aCenter, aNormal, aRadius));
166 std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
167 ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
168 if (aValueAttr->isInitialized())
169 aRadius = aValueAttr->value();
170 AISObjectPtr anAIS = thePrevious;
172 anAIS = AISObjectPtr(new GeomAPI_AISObject);
173 anAIS->createRadius(aCircle, aFlyoutPnt, aRadius);
175 // Set color from preferences
176 std::vector<int> aRGB = Config_PropManager::color("Visualization", "sketch_dimension_color",
177 SKETCH_DIMENSION_COLOR);
178 anAIS->setColor(aRGB[0], aRGB[1], aRGB[2]);
182 void SketchPlugin_ConstraintRadius::move(double theDeltaX, double theDeltaY)
184 std::shared_ptr<ModelAPI_Data> aData = data();
185 if (!aData->isValid())
188 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = std::dynamic_pointer_cast<
189 ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
190 FeaturePtr aFeature = ModelAPI_Feature::feature(aRef->object());
193 std::string aCenterAttrName;
194 if (aFeature->getKind() == SketchPlugin_Circle::ID())
195 aCenterAttrName = SketchPlugin_Circle::CENTER_ID();
196 else if (aFeature->getKind() == SketchPlugin_Arc::ID())
197 aCenterAttrName = SketchPlugin_Arc::CENTER_ID();
198 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
199 GeomDataAPI_Point2D>(aFeature->data()->attribute(aCenterAttrName));
200 std::shared_ptr<GeomAPI_Pnt2d> aCenter = aCenterAttr->pnt();
202 // The specified delta applied on the circle curve,
203 // so it will be scaled due to distance between flyout and center points
204 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = std::dynamic_pointer_cast<
205 GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
206 std::shared_ptr<GeomAPI_Pnt2d> aFlyout = aFlyoutAttr->pnt();
208 std::shared_ptr<ModelAPI_AttributeDouble> aRadius = std::dynamic_pointer_cast<
209 ModelAPI_AttributeDouble>(aData->attribute(SketchPlugin_Constraint::VALUE()));
210 double aScale = aFlyout->distance(aCenter) / aRadius->value();
212 std::shared_ptr<GeomAPI_Circ2d> aCircle(new GeomAPI_Circ2d(aCenter, aFlyout));
213 aFlyout->setX(aFlyout->x() + aScale * theDeltaX);
214 aFlyout->setY(aFlyout->y() + aScale * theDeltaY);
215 aFlyout = aCircle->project(aFlyout);
217 aFlyoutAttr->setValue(aFlyout->x(), aFlyout->y());
220 void SketchPlugin_ConstraintRadius::attributeChanged(const std::string& theID) {
221 if (theID == SketchPlugin_Constraint::ENTITY_A()) {
222 std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
223 ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()));
224 if (!aValueAttr->isInitialized()) { // only if it is not initialized, try to compute the current value
225 std::shared_ptr<ModelAPI_Feature> aCyrcFeature;
226 double aRadius = circleRadius(aCyrcFeature);
227 if (aRadius > 0) { // set as value the radius of updated reference to another circle
228 aValueAttr->setValue(aRadius);