1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_MacroCircle.cpp
4 // Created: 26 May 2014
5 // Author: Artem ZHIDKOV
7 #include "SketchPlugin_MacroCircle.h"
9 #include "SketchPlugin_Circle.h"
10 #include "SketchPlugin_ConstraintCoincidence.h"
11 #include "SketchPlugin_Tools.h"
13 #include <ModelAPI_Data.h>
14 #include <ModelAPI_Events.h>
15 #include <ModelAPI_ResultConstruction.h>
16 #include <ModelAPI_AttributeSelection.h>
17 #include <ModelAPI_Validator.h>
18 #include <ModelAPI_AttributeDouble.h>
19 #include <ModelAPI_AttributeRefAttr.h>
20 #include <ModelAPI_AttributeString.h>
21 #include <ModelAPI_Session.h>
23 #include <GeomAPI_Pnt2d.h>
24 #include <GeomAPI_Circ.h>
25 #include <GeomAPI_Circ2d.h>
26 #include <GeomAPI_Vertex.h>
27 #include <GeomAPI_XY.h>
28 #include <GeomDataAPI_Point2D.h>
29 #include <GeomDataAPI_Dir.h>
30 #include <GeomAlgoAPI_PointBuilder.h>
31 #include <GeomAlgoAPI_EdgeBuilder.h>
32 #include <GeomAlgoAPI_CompoundBuilder.h>
35 const double tolerance = 1e-7;
38 static const std::string& POINT_ID(int theIndex)
41 case 1: return SketchPlugin_MacroCircle::FIRST_POINT_ID();
42 case 2: return SketchPlugin_MacroCircle::SECOND_POINT_ID();
43 case 3: return SketchPlugin_MacroCircle::THIRD_POINT_ID();
46 static const std::string DUMMY;
52 SketchPlugin_MacroCircle::SketchPlugin_MacroCircle()
53 : SketchPlugin_SketchEntity(),
58 void SketchPlugin_MacroCircle::initAttributes()
60 data()->addAttribute(CIRCLE_TYPE(), ModelAPI_AttributeString::typeId());
62 data()->addAttribute(CENTER_POINT_ID(), GeomDataAPI_Point2D::typeId());
63 data()->addAttribute(CENTER_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
64 data()->addAttribute(PASSED_POINT_ID(), GeomDataAPI_Point2D::typeId());
65 data()->addAttribute(PASSED_POINT_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
67 data()->addAttribute(FIRST_POINT_ID(), GeomDataAPI_Point2D::typeId());
68 data()->addAttribute(SECOND_POINT_ID(), GeomDataAPI_Point2D::typeId());
69 data()->addAttribute(THIRD_POINT_ID(), GeomDataAPI_Point2D::typeId());
71 data()->addAttribute(CIRCLE_RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
72 data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
74 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_POINT_REF_ID());
75 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PASSED_POINT_REF_ID());
78 void SketchPlugin_MacroCircle::execute()
80 // Create circle feature.
81 FeaturePtr aCircleFeature = sketch()->addFeature(SketchPlugin_Circle::ID());
82 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
83 aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()))->setValue(myCenter->x(),
85 aCircleFeature->real(SketchPlugin_Circle::RADIUS_ID())->setValue(myRadius);
86 aCircleFeature->boolean(SketchPlugin_Circle::AUXILIARY_ID())
87 ->setValue(boolean(AUXILIARY_ID())->value());
88 aCircleFeature->execute();
93 // Create constraints.
94 SketchPlugin_Tools::createConstraint(this,
95 CENTER_POINT_REF_ID(),
96 aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
99 SketchPlugin_Tools::createConstraint(this,
100 PASSED_POINT_REF_ID(),
102 aCircleFeature->lastResult(),
106 AISObjectPtr SketchPlugin_MacroCircle::getAISObject(AISObjectPtr thePrevious)
108 if(!myCenter.get() || myRadius < tolerance) {
109 return AISObjectPtr();
112 SketchPlugin_Sketch* aSketch = sketch();
114 return AISObjectPtr();
117 // Compute a circle in 3D view.
118 std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(myCenter->x(), myCenter->y()));
119 std::shared_ptr<GeomDataAPI_Dir> aNDir =
120 std::dynamic_pointer_cast<GeomDataAPI_Dir>(
121 aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
122 std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
123 GeomShapePtr aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, myRadius);
124 GeomShapePtr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter);
125 if(!aCircleShape.get() || !aCenterPointShape.get()) {
126 return AISObjectPtr();
129 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
130 aShapes.push_back(aCircleShape);
131 aShapes.push_back(aCenterPointShape);
133 std::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
134 AISObjectPtr anAIS = thePrevious;
136 anAIS.reset(new GeomAPI_AISObject());
138 anAIS->createShape(aCompound);
142 void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) {
143 // If circle type switched reset according attributes.
144 if(theID == CIRCLE_TYPE()) {
145 std::string aType = string(CIRCLE_TYPE())->value();
146 if(aType == CIRCLE_TYPE_BY_CENTER_AND_PASSED_POINTS()) {
147 resetAttribute(CENTER_POINT_ID());
148 resetAttribute(PASSED_POINT_ID());
149 } else if(aType == CIRCLE_TYPE_BY_THREE_POINTS()) {
150 resetAttribute(FIRST_POINT_ID());
151 resetAttribute(SECOND_POINT_ID());
152 resetAttribute(THIRD_POINT_ID());
156 } else if(theID == CENTER_POINT_ID() || theID == PASSED_POINT_ID()) {
157 std::shared_ptr<GeomDataAPI_Point2D> aCenterPointAttr =
158 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()));
159 if(!aCenterPointAttr->isInitialized()) {
162 std::shared_ptr<GeomDataAPI_Point2D> aPassedPointAttr =
163 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(PASSED_POINT_ID()));
164 if(!aPassedPointAttr->isInitialized()) {
168 myCenter = aCenterPointAttr->pnt();
169 myRadius = myCenter->distance(aPassedPointAttr->pnt());
170 } else if(theID == FIRST_POINT_ID() || theID == SECOND_POINT_ID() || theID == THIRD_POINT_ID()) {
171 std::shared_ptr<GeomAPI_Pnt2d> aPoints[3];
172 int aNbInitialized = 0;
173 for(int i = 1; i <= 3; ++i) {
174 std::shared_ptr<GeomDataAPI_Point2D> aCurPnt =
175 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(POINT_ID(i)));
176 if(aCurPnt->isInitialized())
177 aPoints[aNbInitialized++] = aCurPnt->pnt();
180 if(aNbInitialized == 1) {
182 } else if(aNbInitialized == 2) {
183 std::shared_ptr<GeomAPI_XY> aCenterXY =
184 aPoints[0]->xy()->added(aPoints[1]->xy())->multiplied(0.5);
185 myCenter.reset(new GeomAPI_Pnt2d(aCenterXY->x(), aCenterXY->y()));
186 myRadius = aPoints[0]->distance(aPoints[1]) * 0.5;
188 std::shared_ptr<GeomAPI_Circ2d> aCircle(
189 new GeomAPI_Circ2d(aPoints[0], aPoints[1], aPoints[2]));
190 myCenter = aCircle->center();
192 myRadius = aCircle->radius();
197 AttributeDoublePtr aRadiusAttr = real(CIRCLE_RADIUS_ID());
198 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
199 aRadiusAttr->setValue(myRadius);
200 data()->blockSendAttributeUpdated(aWasBlocked, false);
203 void SketchPlugin_MacroCircle::resetAttribute(const std::string& theId)
205 AttributePtr anAttr = attribute(theId);