Salome HOME
Code correction: names of methods should start from a small letter.
[modules/shaper.git] / src / PartSet / PartSet_OperationSketch.cpp
1 // File:        PartSet_OperationSketch.h
2 // Created:     20 Apr 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_OperationSketch.h>
6
7 #include <PartSet_OperationEditLine.h>
8 #include <PartSet_Tools.h>
9
10 #include <SketchPlugin_Sketch.h>
11
12 #include <ModelAPI_Data.h>
13 #include <ModelAPI_AttributeDouble.h>
14 #include <ModelAPI_AttributeRefList.h>
15
16 #include <GeomAlgoAPI_FaceBuilder.h>
17 #include <GeomDataAPI_Point.h>
18 #include <GeomDataAPI_Dir.h>
19
20 #include <XGUI_ViewerPrs.h>
21
22 #include <AIS_Shape.hxx>
23 #include <AIS_ListOfInteractive.hxx>
24 #include <AIS_InteractiveObject.hxx>
25 #include <AIS_DimensionOwner.hxx>
26 #include <AIS_LengthDimension.hxx>
27 #include <V3d_View.hxx>
28
29 #ifdef _DEBUG
30 #include <QDebug>
31 #endif
32
33 #include <QMouseEvent>
34
35 using namespace std;
36
37 PartSet_OperationSketch::PartSet_OperationSketch(const QString& theId,
38                                                      QObject* theParent)
39 : PartSet_OperationSketchBase(theId, theParent)
40 {
41 }
42
43 PartSet_OperationSketch::~PartSet_OperationSketch()
44 {
45 }
46
47 std::list<int> PartSet_OperationSketch::getSelectionModes(boost::shared_ptr<ModelAPI_Feature> theFeature) const
48 {
49   std::list<int> aModes;
50   if (!hasSketchPlane())
51     aModes.push_back(TopAbs_FACE);
52   else
53     aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature);
54
55   return aModes;
56 }
57
58 void PartSet_OperationSketch::init(boost::shared_ptr<ModelAPI_Feature> theFeature,
59                                    const std::list<XGUI_ViewerPrs>& /*theSelected*/,
60                                    const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
61 {
62   setFeature(theFeature);
63 }
64
65 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketch::sketch() const
66 {
67   return feature();
68 }
69
70 void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, Handle_V3d_View theView,
71                                            const std::list<XGUI_ViewerPrs>& theSelected,
72                                            const std::list<XGUI_ViewerPrs>& theHighlighted)
73 {
74   if (!hasSketchPlane()) {
75     if (!theHighlighted.empty()) {
76       XGUI_ViewerPrs aPrs = theHighlighted.front();
77       const TopoDS_Shape& aShape = aPrs.shape();
78       if (!aShape.IsNull())
79         setSketchPlane(aShape);
80     }
81   }
82   else {
83     // if shift button is pressed and there are some already selected objects, the operation should
84     // not be started. We just want to combine some selected objects.
85     bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
86     if (aHasShift && theSelected.size() > 0)
87       return;
88
89     if (theHighlighted.size() == 1) {
90       boost::shared_ptr<ModelAPI_Feature> aFeature = theHighlighted.front().feature();
91       if (aFeature)
92         restartOperation(PartSet_OperationEditLine::Type(), aFeature);
93     }
94     else
95       myFeatures = theHighlighted;
96   }
97 }
98
99 #include <QLineEdit>
100 void PartSet_OperationSketch::mouseReleased(QMouseEvent* theEvent, Handle_V3d_View theView,
101                                             const std::list<XGUI_ViewerPrs>& theSelected,
102                                             const std::list<XGUI_ViewerPrs>& theHighlighted)
103 {
104   if (!hasSketchPlane()) {
105   }
106   else {
107     if (!theSelected.empty()) {
108       XGUI_ViewerPrs aPrs = theSelected.front();
109       if (!aPrs.owner().IsNull()) {
110         Handle(AIS_DimensionOwner) anOwner = Handle(AIS_DimensionOwner)::DownCast(aPrs.owner());
111         if (!anOwner.IsNull() && anOwner->SelectionMode() == AIS_DSM_Text) {
112           Handle(SelectMgr_SelectableObject) anObject = anOwner->Selectable();
113           double aValue = 0;
114           if (!anObject.IsNull()) {
115             Handle(AIS_LengthDimension) aLenDim = Handle(AIS_LengthDimension)::DownCast(anObject);
116             if (!aLenDim.IsNull())
117               aValue = aLenDim->GetValue();
118           }
119
120           QLineEdit* aLine = new QLineEdit();
121           QPoint aViewPos = theEvent->globalPos();
122           QPoint aLinePos(aViewPos.x(), aViewPos.y());
123           aLine->move(aLinePos);
124           aLine->setText(QString::number(aValue));
125           aLine->show();
126         }
127       }
128     }
129   }
130 }
131
132 void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView)
133 {
134   if (!hasSketchPlane() || !(theEvent->buttons() &  Qt::LeftButton) || myFeatures.empty())
135     return;
136
137   if (myFeatures.size() != 1) {
138     boost::shared_ptr<ModelAPI_Feature> aFeature = PartSet_Tools::nearestFeature(theEvent->pos(),
139                                                                 theView, feature(), myFeatures);
140     if (aFeature)
141       restartOperation(PartSet_OperationEditLine::Type(), aFeature);
142   }
143 }
144
145 std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
146                                                         PartSet_OperationSketch::subPreview() const
147 {
148   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > aPreviewMap;
149
150   boost::shared_ptr<SketchPlugin_Feature> aFeature;
151
152   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
153   if (!aData->isValid())
154     return aPreviewMap;
155   boost::shared_ptr<ModelAPI_AttributeRefList> aRefList =
156         boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aData->attribute(SKETCH_ATTR_FEATURES));
157
158   std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures = aRefList->list();
159   std::list<boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = aFeatures.begin(),
160                                                                   aLast = aFeatures.end();
161   for (; anIt != aLast; anIt++) {
162     aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
163     boost::shared_ptr<GeomAPI_Shape> aPreview = aFeature->preview();
164     if (aPreview)
165       aPreviewMap[aFeature] = aPreview;
166   }
167   return aPreviewMap;
168 }
169
170 void PartSet_OperationSketch::stopOperation()
171 {
172   PartSet_OperationSketchBase::stopOperation();
173   emit featureConstructed(feature(), FM_Hide);
174   emit closeLocalContext();
175 }
176
177 bool PartSet_OperationSketch::isNestedOperationsEnabled() const
178 {
179   return hasSketchPlane();
180 }
181
182 void PartSet_OperationSketch::startOperation()
183 {
184   if (!feature()) {
185     setFeature(createFeature());
186     emit fitAllView();
187   }
188 }
189
190 bool PartSet_OperationSketch::hasSketchPlane() const
191 {
192   bool aHasPlane = false;
193
194   if (feature()) {
195     boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
196     boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
197     boost::shared_ptr<GeomDataAPI_Dir> aNormal = 
198       boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
199     aHasPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
200   }
201   return aHasPlane;
202 }
203
204 void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
205 {
206   if (theShape.IsNull())
207     return;
208
209   // get selected shape
210   boost::shared_ptr<GeomAPI_Shape> aGShape(new GeomAPI_Shape);
211   aGShape->setImpl(new TopoDS_Shape(theShape));
212
213   // get plane parameters
214   boost::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aGShape);
215
216   // set plane parameters to feature
217   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
218   double anA, aB, aC, aD;
219   aPlane->coefficients(anA, aB, aC, aD);
220
221   boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
222   // temporary solution for main planes only
223   boost::shared_ptr<GeomDataAPI_Point> anOrigin = 
224     boost::dynamic_pointer_cast<GeomDataAPI_Point>(aData->attribute(SKETCH_ATTR_ORIGIN));
225   anOrigin->setValue(0, 0, 0);
226   boost::shared_ptr<GeomDataAPI_Dir> aNormal = 
227     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
228   aNormal->setValue(anA, aB, aC);
229   boost::shared_ptr<GeomDataAPI_Dir> aDirX = 
230     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRX));
231   aDirX->setValue(aB, aC, anA);
232   boost::shared_ptr<GeomDataAPI_Dir> aDirY = 
233     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRY));
234   aDirY->setValue(aC, anA, aB);
235   boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
236
237   flushUpdated();
238
239   emit featureConstructed(feature(), FM_Hide);
240   emit closeLocalContext();
241   emit planeSelected(aDir->x(), aDir->y(), aDir->z());
242 }