1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_Arc.cpp
4 // Created: 26 Apr 2014
5 // Author: Artem ZHIDKOV
7 #include "SketchPlugin_Arc.h"
8 #include "SketchPlugin_Sketch.h"
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_ResultConstruction.h>
11 #include <ModelAPI_AttributeSelection.h>
12 #include <ModelAPI_Validator.h>
13 #include <ModelAPI_Session.h>
15 #include <GeomAPI_Circ2d.h>
16 #include <GeomAPI_Pnt2d.h>
17 #include <GeomDataAPI_Point2D.h>
18 #include <GeomDataAPI_Dir.h>
19 #include <GeomAlgoAPI_PointBuilder.h>
20 #include <GeomAlgoAPI_EdgeBuilder.h>
21 #include <GeomAlgoAPI_CompoundBuilder.h>
23 const double tolerance = 1e-7;
25 SketchPlugin_Arc::SketchPlugin_Arc()
26 : SketchPlugin_Feature()
28 myStartUpdate = false;
32 void SketchPlugin_Arc::initAttributes()
34 data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
35 data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
36 data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
37 data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
38 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
41 void SketchPlugin_Arc::execute()
43 SketchPlugin_Sketch* aSketch = sketch();
44 // result for the arc is set only when all obligatory attributes are initialized,
45 // otherwise AIS object is used to visualize the arc's preview
46 if (aSketch && isFeatureValid()) {
47 // compute a circle point in 3D view
48 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
49 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
50 // compute the arc start point
51 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
52 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
54 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
55 // make a visible point
56 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
57 std::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
59 aConstr1->setShape(aCenterPointShape);
60 aConstr1->setIsInHistory(false);
61 setResult(aConstr1, 0);
63 // make a visible circle
64 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
65 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
66 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
67 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
69 // compute and change the arc end point
70 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
71 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
72 /* must be automatically done in attributeChanged
73 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
74 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
75 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
76 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
77 anEndAttr->setValue(aProjection);
79 std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
81 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
82 aCenter, aStartPoint, aEndPoint, aNormal);
84 std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
86 aConstr2->setShape(aCircleShape);
87 aConstr2->setIsInHistory(false);
88 setResult(aConstr2, 1);
93 AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious)
95 SketchPlugin_Sketch* aSketch = sketch();
97 // if the feature is valid, the execute() method should be performed, AIS object is empty
98 if (!isFeatureValid()) {
99 // compute a circle point in 3D view
100 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
101 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
102 if (aCenterAttr->isInitialized()) {
103 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
105 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
106 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
107 if (aStartAttr->isInitialized()) {
108 // make a visible circle
109 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
110 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
111 bool aHasPlane = aNDir && !(aNDir->x() == 0 && aNDir->y() == 0 && aNDir->z() == 0);
113 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
114 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
115 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
116 aCenter, aStartPoint, aStartPoint, aNormal);
118 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
119 // make a visible point
120 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
121 aShapes.push_back(aCenterPointShape);
123 aShapes.push_back(aCircleShape);
124 if (!aShapes.empty())
126 std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
127 AISObjectPtr anAIS = thePrevious;
129 anAIS = AISObjectPtr(new GeomAPI_AISObject);
130 anAIS->createShape(aCompound);
140 return AISObjectPtr();
143 void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
145 std::shared_ptr<ModelAPI_Data> aData = data();
146 if (!aData->isValid())
149 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
150 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
151 aPoint1->move(theDeltaX, theDeltaY);
153 myStartUpdate = true;
155 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
156 aData->attribute(SketchPlugin_Arc::START_ID()));
157 aPoint2->move(theDeltaX, theDeltaY);
159 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
160 aData->attribute(SketchPlugin_Arc::END_ID()));
161 aPoint3->move(theDeltaX, theDeltaY);
162 myStartUpdate = false;
166 double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
169 std::shared_ptr<ModelAPI_Data> aData = data();
171 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
172 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
173 aDelta = aPoint1->pnt()->distance(thePoint);
175 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
176 aData->attribute(SketchPlugin_Arc::START_ID()));
177 double aDistance = aPoint2->pnt()->distance(thePoint);
178 if (aDelta < aDistance)
181 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
182 aData->attribute(SketchPlugin_Arc::END_ID()));
183 aDistance = aPoint3->pnt()->distance(thePoint);
184 if (aDelta < aDistance)
190 bool SketchPlugin_Arc::isFixed() {
191 return data()->selection(EXTERNAL_ID())->context().get();
194 bool SketchPlugin_Arc::isFeatureValid()
196 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
197 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID()));
198 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
199 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
200 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
201 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::END_ID()));
203 return aCenterAttr->isInitialized() && aStartAttr->isInitialized() && anEndAttr->isInitialized();
206 void SketchPlugin_Arc::attributeChanged(const std::string& theID)
208 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
209 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
210 if (!aCenterAttr->isInitialized())
212 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
213 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
214 if (!aStartAttr->isInitialized())
216 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
217 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
218 if (!anEndAttr->isInitialized())
221 // update the points in accordance to the changed point changes
222 if (theID == END_ID() && !myEndUpdate) {
224 // compute and change the arc end point
225 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
226 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
227 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
228 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
229 anEndAttr->setValue(aProjection);
231 } else if (theID == START_ID() && !myStartUpdate) {
232 myStartUpdate = true;
233 // compute and change the arc end point
234 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
235 new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt()));
236 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aStartAttr->pnt());
237 if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance)
238 aStartAttr->setValue(aProjection);
239 myStartUpdate = false;
240 } else if (theID == CENTER_ID() && !myEndUpdate) {
242 // compute and change the arc end point
243 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
244 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
245 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
246 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
247 anEndAttr->setValue(aProjection);