1 // File: SketchPlugin_Arc.cpp
2 // Created: 26 Apr 2014
3 // Author: Artem ZHIDKOV
5 #include "SketchPlugin_Arc.h"
6 #include "SketchPlugin_Sketch.h"
7 #include <ModelAPI_Data.h>
8 #include <ModelAPI_ResultConstruction.h>
9 #include <ModelAPI_AttributeSelection.h>
10 #include <ModelAPI_Validator.h>
11 #include <ModelAPI_Session.h>
13 #include <GeomAPI_Circ2d.h>
14 #include <GeomAPI_Pnt2d.h>
15 #include <GeomDataAPI_Point2D.h>
16 #include <GeomDataAPI_Dir.h>
17 #include <GeomAlgoAPI_PointBuilder.h>
18 #include <GeomAlgoAPI_EdgeBuilder.h>
19 #include <GeomAlgoAPI_CompoundBuilder.h>
21 const double tolerance = 1e-7;
23 SketchPlugin_Arc::SketchPlugin_Arc()
24 : SketchPlugin_Feature()
26 myStartUpdate = false;
30 void SketchPlugin_Arc::initAttributes()
32 data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
33 data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
34 data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
35 data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
36 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
39 void SketchPlugin_Arc::execute()
41 SketchPlugin_Sketch* aSketch = sketch();
42 // result for the arc is set only when all obligatory attributes are initialized,
43 // otherwise AIS object is used to visualize the arc's preview
44 if (aSketch && isFeatureValid()) {
45 // compute a circle point in 3D view
46 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
47 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
48 // compute the arc start point
49 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
50 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
52 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
53 // make a visible point
54 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
55 std::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
57 aConstr1->setShape(aCenterPointShape);
58 aConstr1->setIsInHistory(false);
59 setResult(aConstr1, 0);
61 // make a visible circle
62 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
63 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
64 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
65 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
67 // compute and change the arc end point
68 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
69 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
70 /* must be automatically done in attributeChanged
71 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
72 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
73 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
74 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
75 anEndAttr->setValue(aProjection);
77 std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
79 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
80 aCenter, aStartPoint, aEndPoint, aNormal);
82 std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
84 aConstr2->setShape(aCircleShape);
85 aConstr2->setIsInHistory(false);
86 setResult(aConstr2, 1);
91 AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious)
93 SketchPlugin_Sketch* aSketch = sketch();
95 // if the feature is valid, the execute() method should be performed, AIS object is empty
96 if (!isFeatureValid()) {
97 // compute a circle point in 3D view
98 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
99 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
100 if (aCenterAttr->isInitialized()) {
101 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
103 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
104 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
105 if (aStartAttr->isInitialized()) {
106 // make a visible circle
107 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
108 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
109 bool aHasPlane = aNDir && !(aNDir->x() == 0 && aNDir->y() == 0 && aNDir->z() == 0);
111 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
112 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
113 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
114 aCenter, aStartPoint, aStartPoint, aNormal);
116 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
117 // make a visible point
118 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
119 aShapes.push_back(aCenterPointShape);
121 aShapes.push_back(aCircleShape);
122 if (!aShapes.empty())
124 std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
125 AISObjectPtr anAIS = thePrevious;
127 anAIS = AISObjectPtr(new GeomAPI_AISObject);
128 anAIS->createShape(aCompound);
137 return AISObjectPtr();
140 void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
142 std::shared_ptr<ModelAPI_Data> aData = data();
143 if (!aData->isValid())
146 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
147 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
148 aPoint1->move(theDeltaX, theDeltaY);
150 myStartUpdate = true;
152 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
153 aData->attribute(SketchPlugin_Arc::START_ID()));
154 aPoint2->move(theDeltaX, theDeltaY);
156 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
157 aData->attribute(SketchPlugin_Arc::END_ID()));
158 aPoint3->move(theDeltaX, theDeltaY);
159 myStartUpdate = false;
163 double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
166 std::shared_ptr<ModelAPI_Data> aData = data();
168 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
169 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
170 aDelta = aPoint1->pnt()->distance(thePoint);
172 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
173 aData->attribute(SketchPlugin_Arc::START_ID()));
174 double aDistance = aPoint2->pnt()->distance(thePoint);
175 if (aDelta < aDistance)
178 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
179 aData->attribute(SketchPlugin_Arc::END_ID()));
180 aDistance = aPoint3->pnt()->distance(thePoint);
181 if (aDelta < aDistance)
187 bool SketchPlugin_Arc::isFixed() {
188 return data()->selection(EXTERNAL_ID())->context();
191 bool SketchPlugin_Arc::isFeatureValid()
193 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
194 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID()));
195 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
196 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
197 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
198 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::END_ID()));
200 return aCenterAttr->isInitialized() && aStartAttr->isInitialized() && anEndAttr->isInitialized();
203 void SketchPlugin_Arc::attributeChanged(const std::string& theID)
205 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
206 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
207 if (!aCenterAttr->isInitialized())
209 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
210 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
211 if (!aStartAttr->isInitialized())
213 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
214 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
215 if (!anEndAttr->isInitialized())
218 // update the points in accordance to the changed point changes
219 if (theID == END_ID() && !myEndUpdate) {
221 // compute and change the arc end point
222 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
223 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
224 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
225 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
226 anEndAttr->setValue(aProjection);
228 } else if (theID == START_ID() && !myStartUpdate) {
229 myStartUpdate = true;
230 // compute and change the arc end point
231 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
232 new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt()));
233 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aStartAttr->pnt());
234 if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance)
235 aStartAttr->setValue(aProjection);
236 myStartUpdate = false;