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_SketchEntity()
28 myStartUpdate = false;
32 void SketchPlugin_Arc::initAttributes()
34 SketchPlugin_SketchEntity::initAttributes();
36 data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
37 data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
38 data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
39 data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
40 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
43 void SketchPlugin_Arc::execute()
45 SketchPlugin_Sketch* aSketch = sketch();
46 // result for the arc is set only when all obligatory attributes are initialized,
47 // otherwise AIS object is used to visualize the arc's preview
48 if (aSketch && isFeatureValid()) {
49 // compute a circle point in 3D view
50 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
51 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
52 // compute the arc start point
53 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
54 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
56 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
57 // make a visible point
58 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
59 std::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
61 aConstr1->setShape(aCenterPointShape);
62 aConstr1->setIsInHistory(false);
63 setResult(aConstr1, 0);
65 // make a visible circle
66 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
67 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
68 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
69 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
71 // compute and change the arc end point
72 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
73 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
74 /* must be automatically done in attributeChanged
75 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
76 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
77 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
78 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
79 anEndAttr->setValue(aProjection);
81 std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
83 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
84 aCenter, aStartPoint, aEndPoint, aNormal);
86 std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
88 aConstr2->setShape(aCircleShape);
89 aConstr2->setIsInHistory(false);
90 setResult(aConstr2, 1);
95 AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious)
97 SketchPlugin_Sketch* aSketch = sketch();
99 // if the feature is valid, the execute() method should be performed, AIS object is empty
100 if (!isFeatureValid()) {
101 // compute a circle point in 3D view
102 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
103 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
104 if (aCenterAttr->isInitialized()) {
105 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
107 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
108 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
109 if (aStartAttr->isInitialized()) {
110 // make a visible circle
111 std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
112 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
113 bool aHasPlane = aNDir && !(aNDir->x() == 0 && aNDir->y() == 0 && aNDir->z() == 0);
115 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
116 std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
117 std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
118 aCenter, aStartPoint, aStartPoint, aNormal);
120 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
121 // make a visible point
122 std::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
123 aShapes.push_back(aCenterPointShape);
125 aShapes.push_back(aCircleShape);
126 if (!aShapes.empty())
128 std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
129 AISObjectPtr anAIS = thePrevious;
131 anAIS = AISObjectPtr(new GeomAPI_AISObject);
132 anAIS->createShape(aCompound);
142 return AISObjectPtr();
145 void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
147 std::shared_ptr<ModelAPI_Data> aData = data();
148 if (!aData->isValid())
151 myStartUpdate = true;
153 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
154 aData->attribute(SketchPlugin_Arc::START_ID()));
155 aPoint2->move(theDeltaX, theDeltaY);
157 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
158 aData->attribute(SketchPlugin_Arc::END_ID()));
159 aPoint3->move(theDeltaX, theDeltaY);
160 myStartUpdate = false;
163 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
164 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
165 aPoint1->move(theDeltaX, theDeltaY);
168 double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
171 std::shared_ptr<ModelAPI_Data> aData = data();
173 std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
174 aData->attribute(SketchPlugin_Arc::CENTER_ID()));
175 aDelta = aPoint1->pnt()->distance(thePoint);
177 std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
178 aData->attribute(SketchPlugin_Arc::START_ID()));
179 double aDistance = aPoint2->pnt()->distance(thePoint);
180 if (aDelta < aDistance)
183 std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
184 aData->attribute(SketchPlugin_Arc::END_ID()));
185 aDistance = aPoint3->pnt()->distance(thePoint);
186 if (aDelta < aDistance)
192 bool SketchPlugin_Arc::isFixed() {
193 return data()->selection(EXTERNAL_ID())->context().get() != NULL;
196 bool SketchPlugin_Arc::isFeatureValid()
198 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
199 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID()));
200 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
201 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
202 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
203 GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::END_ID()));
205 return aCenterAttr->isInitialized() && aStartAttr->isInitialized() && anEndAttr->isInitialized();
208 void SketchPlugin_Arc::attributeChanged(const std::string& theID)
210 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
211 GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
212 if (!aCenterAttr->isInitialized())
214 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
215 GeomDataAPI_Point2D>(data()->attribute(START_ID()));
216 if (!aStartAttr->isInitialized())
218 std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
219 GeomDataAPI_Point2D>(data()->attribute(END_ID()));
220 if (!anEndAttr->isInitialized())
223 // update the points in accordance to the changed point changes
224 if (theID == END_ID() && !myEndUpdate) {
226 // compute and change the arc end point
227 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
228 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
229 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
230 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
231 anEndAttr->setValue(aProjection);
233 } else if (theID == START_ID() && !myStartUpdate) {
234 myStartUpdate = true;
235 // compute and change the arc end point
236 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
237 new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt()));
238 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aStartAttr->pnt());
239 if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance)
240 aStartAttr->setValue(aProjection);
241 myStartUpdate = false;
242 } else if (theID == CENTER_ID() && !myEndUpdate) {
244 // compute and change the arc end point
245 std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
246 new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
247 std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
248 if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
249 anEndAttr->setValue(aProjection);