Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / PartSet / PartSet_OperationSketchLine.cpp
1 // File:        PartSet_OperationSketchLine.h
2 // Created:     20 Apr 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_OperationSketchLine.h>
6
7 #include <SketchPlugin_Feature.h>
8 #include <GeomDataAPI_Point2D.h>
9 #include <GeomDataAPI_Point.h>
10 #include <GeomDataAPI_Dir.h>
11 #include <ModelAPI_Data.h>
12 #include <ModelAPI_Document.h>
13
14 #include <SketchPlugin_Sketch.h>
15 #include <SketchPlugin_Line.h>
16
17 #ifdef _DEBUG
18 #include <QDebug>
19 #endif
20
21 using namespace std;
22
23 PartSet_OperationSketchLine::PartSet_OperationSketchLine(const QString& theId,
24                                                   QObject* theParent,
25                                               boost::shared_ptr<ModelAPI_Feature> theFeature)
26 : PartSet_OperationSketchBase(theId, theParent), mySketch(theFeature),
27   myPointSelectionMode(SM_FirstPoint)
28 {
29 }
30
31 PartSet_OperationSketchLine::~PartSet_OperationSketchLine()
32 {
33 }
34
35 bool PartSet_OperationSketchLine::isGranted() const
36 {
37   return true;
38 }
39
40 std::list<int> PartSet_OperationSketchLine::getSelectionModes(boost::shared_ptr<ModelAPI_Feature> theFeature) const
41 {
42   std::list<int> aModes;
43   if (theFeature != feature()) {
44     aModes.push_back(TopAbs_VERTEX);
45     aModes.push_back(TopAbs_EDGE);
46   }
47   return aModes;
48 }
49
50 void PartSet_OperationSketchLine::mouseReleased(const gp_Pnt& thePoint)
51 {
52   switch (myPointSelectionMode)
53   {
54     case SM_FirstPoint: {
55       setLinePoint(thePoint, LINE_ATTR_START);
56       myPointSelectionMode = SM_SecondPoint;
57     }
58     break;
59     case SM_SecondPoint: {
60       setLinePoint(thePoint, LINE_ATTR_END);
61       myPointSelectionMode = SM_None;
62     }
63     break;
64     case SM_None: {
65
66     }
67     break;
68     default:
69       break;
70   }
71 }
72
73 void PartSet_OperationSketchLine::mouseMoved(const gp_Pnt& thePoint)
74 {
75   switch (myPointSelectionMode)
76   {
77     case SM_SecondPoint:
78       setLinePoint(thePoint, LINE_ATTR_END);
79       break;
80     case SM_None: {
81       boost::shared_ptr<ModelAPI_Feature> aPrevFeature = feature();
82       // stop the last operation
83       commitOperation();
84       document()->finishOperation();
85       //emit changeSelectionMode(aPrevFeature, TopAbs_VERTEX);
86       // start a new operation
87       document()->startOperation();
88       startOperation();
89       // use the last point of the previous feature as the first of the new one
90       setLinePoint(aPrevFeature, LINE_ATTR_END, LINE_ATTR_START);
91       myPointSelectionMode = SM_SecondPoint;
92
93       emit featureConstructed(aPrevFeature, FM_Deactivation);
94     }
95     break;
96     default:
97       break;
98   }
99 }
100
101 void PartSet_OperationSketchLine::keyReleased(const int theKey)
102 {
103   switch (theKey) {
104     case Qt::Key_Escape: {
105       if (myPointSelectionMode != SM_None)
106         emit featureConstructed(feature(), FM_Abort);
107       abort();
108     }
109     break;
110     case Qt::Key_Return: {
111       if (myPointSelectionMode != SM_None) {
112         emit featureConstructed(feature(), FM_Abort);
113         myPointSelectionMode = SM_FirstPoint;
114         document()->abortOperation();
115       }
116       else
117         myPointSelectionMode = SM_FirstPoint;
118     }
119     break;
120     default:
121     break;
122   }
123 }
124
125 void PartSet_OperationSketchLine::startOperation()
126 {
127   PartSet_OperationSketchBase::startOperation();
128   myPointSelectionMode = SM_FirstPoint;
129 }
130
131 void PartSet_OperationSketchLine::stopOperation()
132 {
133   PartSet_OperationSketchBase::stopOperation();
134   myPointSelectionMode = SM_None;
135 }
136
137 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchLine::createFeature()
138 {
139   boost::shared_ptr<ModelAPI_Feature> aNewFeature = ModuleBase_Operation::createFeature();
140   if (mySketch) {
141     boost::shared_ptr<SketchPlugin_Feature> aFeature = 
142                            boost::dynamic_pointer_cast<SketchPlugin_Feature>(mySketch);
143
144     aFeature->addSub(aNewFeature);
145   }
146   emit featureConstructed(aNewFeature, FM_Activation);
147   return aNewFeature;
148 }
149
150 void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint,
151                                                const std::string& theAttribute)
152 {
153   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
154   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
155         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
156
157   double aX = 0;
158   double anY = 0;
159   convertTo2D(thePoint, aX, anY);
160   aPoint->setValue(aX, anY);
161 }
162
163 void PartSet_OperationSketchLine::setLinePoint(boost::shared_ptr<ModelAPI_Feature> theSourceFeature,
164                                                const std::string& theSourceAttribute,
165                                                const std::string& theAttribute)
166 {
167   boost::shared_ptr<ModelAPI_Data> aData = theSourceFeature->data();
168   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
169         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theSourceAttribute));
170   double aX = aPoint->x();
171   double anY = aPoint->y();
172
173   aData = feature()->data();
174   aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
175   aPoint->setValue(aX, anY);
176 }
177
178 void PartSet_OperationSketchLine::convertTo2D(const gp_Pnt& thePoint, double& theX, double& theY)
179 {
180   if (!mySketch)
181     return;
182
183   boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
184   boost::shared_ptr<ModelAPI_Data> aData = mySketch->data();
185
186   boost::shared_ptr<GeomDataAPI_Point> anOrigin = 
187     boost::dynamic_pointer_cast<GeomDataAPI_Point>(aData->attribute(SKETCH_ATTR_ORIGIN));
188
189   boost::shared_ptr<GeomDataAPI_Dir> aX = 
190     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRX));
191   boost::shared_ptr<GeomDataAPI_Dir> anY = 
192     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRY));
193
194   gp_Pnt aVec(thePoint.X() - anOrigin->x(), thePoint.Y() - anOrigin->y(), thePoint.Z() - anOrigin->z());
195   theX = aVec.X() * aX->x() + aVec.Y() * aX->y() + aVec.Z() * aX->z();
196   theY = aVec.X() * anY->x() + aVec.Y() * anY->y() + aVec.Z() * anY->z();
197 }