Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / PartSet / PartSet_OperationFeatureEditMulti.cpp
1 // File:        PartSet_OperationFeatureEditMulti.h
2 // Created:     05 May 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_OperationFeatureEditMulti.h>
6 #include <PartSet_Tools.h>
7 #include <PartSet_OperationSketch.h>
8
9 #include <ModuleBase_OperationDescription.h>
10 #include <ModuleBase_ViewerPrs.h>
11 #include <ModuleBase_IViewer.h>
12 #include <ModuleBase_ISelection.h>
13
14 #include <ModelAPI_Events.h>
15
16 #include <SketchPlugin_Feature.h>
17 #include <GeomDataAPI_Point2D.h>
18 #include <ModelAPI_Data.h>
19 #include <ModelAPI_Document.h>
20
21 #include <ModelAPI_Events.h>
22
23 #include <Events_Loop.h>
24
25 #include <SketchPlugin_Line.h>
26
27 #include <V3d_View.hxx>
28 #include <TopoDS_Vertex.hxx>
29 #include <TopoDS.hxx>
30 #include <BRep_Tool.hxx>
31
32 #include <QMouseEvent>
33 #ifdef _DEBUG
34 #include <QDebug>
35 #endif
36
37 //using namespace std;
38
39 PartSet_OperationFeatureEditMulti::PartSet_OperationFeatureEditMulti(const QString& theId,
40                                                                      QObject* theParent,
41                                                                      CompositeFeaturePtr theFeature)
42     : PartSet_OperationSketchBase(theId, theParent),
43       mySketch(theFeature),
44       myIsBlockedSelection(false)
45 {
46   myIsEditing = true;
47 }
48
49 PartSet_OperationFeatureEditMulti::~PartSet_OperationFeatureEditMulti()
50 {
51 }
52
53 void PartSet_OperationFeatureEditMulti::initSelection(ModuleBase_ISelection* theSelection,
54                                                       ModuleBase_IViewer* theViewer)
55 {
56   // 1. unite selected and hightlighted objects in order to have an opportunity to drag
57   // by the highlighted object
58   QList<ModuleBase_ViewerPrs> aFeatures;
59   aFeatures = theSelection->getSelected();
60   QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
61   // add highlighted elements if they are not selected
62   foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
63     if (!PartSet_Tools::isContainPresentation(aFeatures, aPrs))
64       aFeatures.append(aPrs);
65   }
66
67   // 1. find all features with skipping features with selected vertex shapes
68   myFeature2Attribute.clear();
69   // firstly, collect the features without local selection
70   foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
71     const TopoDS_Shape& aShape = aPrs.shape();
72     if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
73       const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
74       if (!aVertex.IsNull()) {
75         continue;
76       }
77     }
78     else {
79       ObjectPtr aObject = aPrs.object();
80       if (!aObject)
81         continue;
82       FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
83       if (aFeature && myFeature2Attribute.find(aFeature) == myFeature2Attribute.end()) {
84         std::list<std::string> aList;
85         // using an empty list as a sign, that this feature should be moved itself
86         myFeature2Attribute[aFeature] = aList;
87       }
88     }
89   }
90   // 2. collect the features with a local selection on them.
91   // if the list already has this feature, the local selection is skipped
92   // that means that if the selection contains a feature and a feature with local selected point,
93   // the edit is performed for a full feature
94   Handle(V3d_View) aView = theViewer->activeView();
95   foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
96     const TopoDS_Shape& aShape = aPrs.shape();
97     if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
98       const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
99       if (aVertex.IsNull())
100         continue;
101       ObjectPtr aObject = aPrs.object();
102       if (!aObject)
103         continue;
104       FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
105       if (!aFeature)
106         continue;
107       // if the feature is already moved, do nothing for this feature local selection
108       if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
109         continue;
110
111       // append the attribute of the vertex if it is found on the current feature
112       gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
113       double aVX, aVY;
114       PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aVX, aVY);
115       boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = PartSet_Tools::getFeaturePoint(
116                                                                     aFeature, aVX, aVY);
117       std::string anAttribute = aFeature->data()->id(aPoint2D);
118       std::list<std::string> aList;
119       if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
120         aList = myFeature2Attribute[aFeature];
121
122       aList.push_back(anAttribute);
123       myFeature2Attribute[aFeature] = aList;
124     }
125   }
126 }
127
128 CompositeFeaturePtr PartSet_OperationFeatureEditMulti::sketch() const
129 {
130   return mySketch;
131 }
132
133 //void PartSet_OperationFeatureEditMulti::mousePressed(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer, ModuleBase_ISelection* theSelection)
134 //{
135 //}
136
137 void PartSet_OperationFeatureEditMulti::mouseMoved(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer)
138 {
139   if (!(theEvent->buttons() & Qt::LeftButton))
140     return;
141
142   if (theViewer->isSelectionEnabled())
143     theViewer->enableSelection(false);
144
145   Handle(V3d_View) aView = theViewer->activeView();
146   gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);
147
148   //blockSelection(true);
149   if (myCurPoint.myIsInitialized) {
150     double aCurX, aCurY;
151     PartSet_Tools::convertTo2D(myCurPoint.myPoint, sketch(), aView, aCurX, aCurY);
152
153     double aX, anY;
154     PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
155
156     double aDeltaX = aX - aCurX;
157     double aDeltaY = anY - aCurY;
158
159     std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
160     while (aFeatIter != myFeature2Attribute.end()) {
161       FeaturePtr aFeature = aFeatIter->first;
162       std::list<std::string> anAttributes = aFeatIter->second;
163       // perform edit for the feature
164       if (anAttributes.empty()) {
165         boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
166                                        boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
167         if (aSketchFeature) {
168           aSketchFeature->move(aDeltaX, aDeltaY);
169         }
170       }
171       // perform edit for the feature's attribute
172       else {
173         std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
174                                                anAttrEnd = anAttributes.end();
175         for (; anAttrIter != anAttrEnd; anAttrIter++) {
176           boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr = boost::dynamic_pointer_cast<
177                            GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter));
178           if (aPointAttr) {
179             aPointAttr->move(aDeltaX, aDeltaY);
180           }
181         }      
182       }
183       aFeatIter++;
184     }
185   }
186   sendFeatures();
187
188   myCurPoint.setPoint(aPoint);
189 }
190
191 void PartSet_OperationFeatureEditMulti::mouseReleased(
192     QMouseEvent* theEvent, ModuleBase_IViewer* theViewer,
193     ModuleBase_ISelection* theSelection)
194 {
195   theViewer->enableSelection(true);
196   if (commit()) {
197     std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
198     while (aFeatIter != myFeature2Attribute.end()) {
199       FeaturePtr aFeature = aFeatIter->first;
200       if (aFeature) {
201         emit featureConstructed(aFeature, FM_Deactivation);
202       }
203       aFeatIter++;
204     }
205   }
206 }
207
208 void PartSet_OperationFeatureEditMulti::startOperation()
209 {
210   PartSet_OperationSketchBase::startOperation();
211   //emit multiSelectionEnabled(false);
212
213   //blockSelection(true);
214
215   myCurPoint.clear();
216 }
217
218 void PartSet_OperationFeatureEditMulti::stopOperation()
219 {
220   //emit multiSelectionEnabled(true);
221
222   //blockSelection(false, true);
223
224   myFeature2Attribute.clear();
225 }
226
227 //void PartSet_OperationFeatureEditMulti::blockSelection(bool isBlocked,
228 //                                                       const bool isRestoreSelection)
229 //{
230 //  if (myIsBlockedSelection == isBlocked)
231 //    return;
232 //
233 //  myIsBlockedSelection = isBlocked;
234 //  QList<ObjectPtr> aFeatureList;
235 ////  std::list<ModuleBase_ViewerPrs>::const_iterator anIt = myFeatures.begin(), aLast =
236 ////      myFeatures.end();
237 //  /*for(; anIt != aLast; anIt++)
238 //   aFeatureList.append((*anIt).feature());*/
239 //  //if (isBlocked) {
240 //  //  emit setSelection(QList<ObjectPtr>());
241 //  //  emit stopSelection(aFeatureList, true);
242 //  //} else {
243 //  //  emit stopSelection(aFeatureList, false);
244 //  //  if (isRestoreSelection) {
245 //  //    emit setSelection(aFeatureList);
246 //  //  }
247 //  //}
248 //}
249
250 void PartSet_OperationFeatureEditMulti::sendFeatures()
251 {
252   static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
253
254   std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
255   while (aFeatIter != myFeature2Attribute.end()) {
256     FeaturePtr aFeature = aFeatIter->first;
257     if (aFeature) {
258       ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
259     }
260     aFeatIter++;
261   }
262
263   Events_Loop::loop()->flush(anEvent);
264   flushUpdated();
265 }
266