Salome HOME
Merge remote-tracking branch 'remotes/origin/master' into SketchSolver
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_ConstraintDistance.cpp
1 // File:    SketchPlugin_ConstraintDistance.cpp
2 // Created: 23 May 2014
3 // Author:  Artem ZHIDKOV
4
5 #include "SketchPlugin_ConstraintDistance.h"
6 #include <SketchPlugin_Point.h>
7
8 #include <GeomAPI_Lin2D.h>
9 #include <GeomAPI_Pnt2D.h>
10 #include <GeomDataAPI_Point2D.h>
11
12 #include <ModelAPI_AttributeDouble.h>
13 #include <ModelAPI_Data.h>
14
15 #include <AIS_LengthDimension.hxx>
16 #include <gp_Pnt.hxx>
17 #include <gp_Pln.hxx>
18
19 /// Obtain the point object from specified constraint parameter
20 static boost::shared_ptr<GeomDataAPI_Point2D> getFeaturePoint(
21             DataPtr             theData,
22             const std::string&  theAttribute);
23
24
25 SketchPlugin_ConstraintDistance::SketchPlugin_ConstraintDistance()
26 {
27 }
28
29 void SketchPlugin_ConstraintDistance::initAttributes()
30 {
31   data()->addAttribute(CONSTRAINT_ATTR_VALUE,    ModelAPI_AttributeDouble::type());
32   data()->addAttribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT, GeomDataAPI_Point2D::type());
33   data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
34   data()->addAttribute(CONSTRAINT_ATTR_ENTITY_B, ModelAPI_AttributeRefAttr::type());
35 }
36
37 void SketchPlugin_ConstraintDistance::execute()
38 {
39   boost::shared_ptr<ModelAPI_Data> aData = data();
40
41   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr_A = 
42           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
43   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr_B = 
44           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_B));
45
46   AttributeDoublePtr anAttribute =
47       boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_VALUE));
48
49   if (anAttr_A && anAttr_B && anAttribute->value() == 0)
50   {
51     FeaturePtr aFeature_A = anAttr_A->feature();
52     FeaturePtr aFeature_B = anAttr_B->feature();
53
54     double aValue = 40; // TODO
55     anAttribute->setValue(aValue);
56   }
57 }
58
59 Handle(AIS_InteractiveObject) SketchPlugin_ConstraintDistance::getAISShape(
60   Handle_AIS_InteractiveObject thePrevious)
61 {
62   if (!sketch())
63     return thePrevious;
64
65   boost::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
66
67   DataPtr aData = data();
68   boost::shared_ptr<GeomDataAPI_Point2D> aPoint_A = getFeaturePoint(aData, CONSTRAINT_ATTR_ENTITY_A);
69   boost::shared_ptr<GeomDataAPI_Point2D> aPoint_B = getFeaturePoint(aData, CONSTRAINT_ATTR_ENTITY_B);
70   if (!aPoint_A || !aPoint_B)
71     return thePrevious;
72
73   // fly out calculation
74   boost::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = 
75     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT));
76   boost::shared_ptr<GeomAPI_Pnt2d> aFlyOutPnt = aFlyOutAttr->pnt();
77
78   boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin = 
79     boost::shared_ptr<GeomAPI_Lin2d>(new GeomAPI_Lin2d(aPoint_A->x(), aPoint_A->y(),
80                                                        aPoint_B->x(), aPoint_B->y()));
81   boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->project(aFlyOutPnt);
82   double aDistance = aFlyOutPnt->distance(aResult);
83
84   if (!aFeatureLin->isRight(aFlyOutPnt))
85     aDistance = -aDistance;
86   double aFlyout = aDistance;
87
88   //Build dimension here
89   boost::shared_ptr<GeomAPI_Pnt> aPoint1 = sketch()->to3D(aPoint_A->x(), aPoint_A->y());
90   boost::shared_ptr<GeomAPI_Pnt> aPoint2 = sketch()->to3D(aPoint_B->x(), aPoint_B->y());
91   if (aFlyout < 0)
92     aPoint1.swap(aPoint2);
93
94   // value calculation
95   boost::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = 
96     boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_VALUE));
97   double aValue = aValueAttr->value();
98   if (aValue == 0) { // TODO! the default value
99     aValue = aPoint1->distance(aPoint2);
100   }
101
102   Handle(AIS_InteractiveObject) anAIS = thePrevious;
103   if (anAIS.IsNull())
104   {
105     Handle(AIS_LengthDimension) aDimAIS = 
106       new AIS_LengthDimension(aPoint1->impl<gp_Pnt>(), aPoint2->impl<gp_Pnt>(), aPlane->impl<gp_Pln>());
107     aDimAIS->SetCustomValue(aValue);
108
109     Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
110     anAspect->MakeArrows3d (Standard_False);
111     anAspect->MakeText3d(false);
112     anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
113     anAspect->MakeTextShaded(false);
114     aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
115     aDimAIS->SetDimensionAspect (anAspect);
116     aDimAIS->SetFlyout(aFlyout);
117     aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
118
119     anAIS = aDimAIS;
120   }
121   else {
122     // update presentation
123     Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
124     if (!aDimAIS.IsNull()) {
125       aDimAIS->SetMeasuredGeometry(aPoint1->impl<gp_Pnt>(), aPoint2->impl<gp_Pnt>(), aPlane->impl<gp_Pln>());
126       aDimAIS->SetCustomValue(aValue);
127       aDimAIS->SetFlyout(aFlyout);
128
129       aDimAIS->Redisplay(Standard_True);
130     }
131   }
132   return anAIS;
133 }
134
135
136 boost::shared_ptr<GeomDataAPI_Point2D> getFeaturePoint(DataPtr theData,
137                                                        const std::string& theAttribute)
138 {
139   boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
140
141   if (!theData)
142     return aPointAttr;
143
144   FeaturePtr aFeature;
145   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
146     boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theData->attribute(theAttribute));
147   if (anAttr)
148     aFeature = anAttr->feature();
149
150   if (aFeature && aFeature->getKind() == SKETCH_POINT_KIND)
151     aPointAttr = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
152                                            (aFeature->data()->attribute(POINT_ATTR_COORD));
153   return aPointAttr;
154 }
155