Salome HOME
92caca86b9651cca674116966c3693b1c29c2305
[modules/shaper.git] / src / PartSet / PartSet_ConstraintRadiusPrs.cpp
1 // File:        PartSet_FeaturePrs.h
2 // Created:     16 Jun 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_ConstraintRadiusPrs.h>
6 #include <PartSet_Tools.h>
7
8 #include <PartSet_FeatureCirclePrs.h>
9 #include <PartSet_FeatureArcPrs.h>
10
11 #include <SketchPlugin_Feature.h>
12 #include <SketchPlugin_Sketch.h>
13 #include <SketchPlugin_Line.h>
14 #include <SketchPlugin_Circle.h>
15 #include <SketchPlugin_Arc.h>
16 #include <SketchPlugin_ConstraintRadius.h>
17
18 #include <GeomDataAPI_Point.h>
19 #include <GeomDataAPI_Point2D.h>
20 #include <GeomDataAPI_Dir.h>
21 #include <GeomAPI_Pnt2d.h>
22 #include <GeomAPI_Lin2d.h>
23 #include <GeomAPI_Pln.h>
24 #include <GeomAPI_Dir.h>
25
26 #include <GeomAlgoAPI_EdgeBuilder.h>
27
28 #include <ModelAPI_Data.h>
29 #include <ModelAPI_Document.h>
30 #include <ModelAPI_AttributeRefAttr.h>
31 #include <ModelAPI_AttributeRefList.h>
32 #include <ModelAPI_AttributeDouble.h>
33
34 #include <AIS_InteractiveObject.hxx>
35 #include <AIS_RadiusDimension.hxx>
36 #include <Precision.hxx>
37 #include <gp_Circ.hxx>
38 #include <V3d_View.hxx>
39
40 using namespace std;
41
42 PartSet_ConstraintRadiusPrs::PartSet_ConstraintRadiusPrs(FeaturePtr theSketch)
43 : PartSet_FeaturePrs(theSketch)
44 {
45 }
46
47 std::string PartSet_ConstraintRadiusPrs::getKind()
48 {
49   return SKETCH_CONSTRAINT_RADIUS_KIND;
50 }
51
52 PartSet_SelectionMode PartSet_ConstraintRadiusPrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
53 {
54   PartSet_SelectionMode aMode = theMode;
55   if (!feature() || theMode != SM_FirstPoint || !theFeature) {
56     return aMode;
57   }
58   std::string aKind = theFeature->getKind();
59   if (aKind == SKETCH_CIRCLE_KIND || aKind == SKETCH_ARC_KIND) {
60     // set length feature
61     boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
62     boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
63           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
64     aRef->setFeature(theFeature);
65
66     double aLength = 50;
67     bool isValid;
68     if (aKind == SKETCH_CIRCLE_KIND) {
69       aLength = PartSet_Tools::featureValue(theFeature, CIRCLE_ATTR_RADIUS, isValid);
70     }
71     else if (aKind == SKETCH_ARC_KIND) {
72       aLength = PartSet_FeatureArcPrs::radius(theFeature);
73     }
74
75     PartSet_Tools::setFeatureValue(feature(), aLength, CONSTRAINT_ATTR_VALUE);
76     aMode = SM_LastPoint;
77   }
78   return aMode;
79 }
80
81 PartSet_SelectionMode PartSet_ConstraintRadiusPrs::setPoint(double theX, double theY,
82                                                          const PartSet_SelectionMode& theMode)
83 {
84   PartSet_SelectionMode aMode = theMode;
85   switch (theMode)
86   {
87     case SM_LastPoint: {
88       boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
89
90       boost::shared_ptr<GeomAPI_Pnt2d> aPoint = boost::shared_ptr<GeomAPI_Pnt2d>
91                                                              (new GeomAPI_Pnt2d(theX, theY));
92
93       //PartSet_Tools::setFeaturePoint(feature(), theX, theY, SKETCH_CONSTRAINT_ATTR_CIRCLE_POINT);
94
95       //double aDistance = 40;
96       //AttributeDoublePtr aFlyoutAttr = 
97       //    boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE));
98       //aFlyoutAttr->setValue(aDistance);
99
100       aMode = SM_LastPoint;
101     }
102     break;
103     default:
104       break;
105   }
106   return aMode;
107 }
108
109 void PartSet_ConstraintRadiusPrs::projectPointOnFeature(FeaturePtr theFeature, FeaturePtr theSketch,
110                                                         gp_Pnt& thePoint, Handle(V3d_View) theView,
111                                                         double& theX, double& theY)
112 {
113   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
114   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
115           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
116   if (!anAttr)
117     return;
118   FeaturePtr aFeature = anAttr->feature();
119   if (!aFeature)
120     return;
121
122   gp_Circ aCircle;
123   gp_Pnt anAnchorPoint;
124   if (aFeature->getKind() == SKETCH_CIRCLE_KIND) {
125     PartSet_FeatureCirclePrs::projectPointOnFeature(aFeature, theSketch, thePoint, theView, theX, theY);
126   }
127   else if (aFeature->getKind() == SKETCH_ARC_KIND) {
128     PartSet_FeatureArcPrs::projectPointOnFeature(aFeature, theSketch, thePoint, theView, theX, theY);
129   }
130   // TODO: a bug in AIS_RadiusDimension:
131   // The anchor point can't be myCirc.Location() - an exception is raised.
132   // But we need exactly this case...
133   // We want to show a radius dimension starting from the circle centre and 
134   // ending at the user-defined point.
135   // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
136   double aDelta = 1/1000.0;
137   theX += aDelta;
138   theY += aDelta;
139 }
140
141 std::string PartSet_ConstraintRadiusPrs::getAttribute(const PartSet_SelectionMode& theMode) const
142 {
143   return "";
144 }
145
146 PartSet_SelectionMode PartSet_ConstraintRadiusPrs::getNextMode(const std::string& theAttribute) const
147 {
148   return SM_FirstPoint;
149 }
150
151 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintRadiusPrs::featurePoint
152                                                      (const PartSet_SelectionMode& theMode)
153 {
154   return boost::shared_ptr<GeomDataAPI_Point2D>();
155 }