]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_Module.cpp
Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / PartSet / PartSet_Module.cpp
1 #include <PartSet_Module.h>
2 #include <PartSet_OperationSketch.h>
3 #include <PartSet_OperationSketchLine.h>
4 #include <PartSet_OperationEditLine.h>
5 #include <ModuleBase_Operation.h>
6 #include <ModuleBase_OperationDescription.h>
7 #include <PartSet_Listener.h>
8 #include <PartSet_TestOCC.h>
9
10 #include <ModuleBase_Operation.h>
11 #include <ModelAPI_Object.h>
12
13 #include <XGUI_MainWindow.h>
14 #include <XGUI_Displayer.h>
15 #include <XGUI_Viewer.h>
16 #include <XGUI_Workshop.h>
17 #include <XGUI_OperationMgr.h>
18 #include <XGUI_SelectionMgr.h>
19 #include <XGUI_ViewPort.h>
20 #include <XGUI_ActionsMgr.h>
21 #include <XGUI_ViewerProxy.h>
22 #include <XGUI_ContextMenuMgr.h>
23 #include <XGUI_PropertyPanel.h>
24 #include <XGUI_Tools.h>
25
26 #include <Config_PointerMessage.h>
27 #include <Config_ModuleReader.h>
28 #include <Config_WidgetReader.h>
29 #include <Events_Loop.h>
30 #include <Events_Message.h>
31 #include <Events_Error.h>
32
33 #include <GeomAPI_Shape.h>
34
35 #include <AIS_ListOfInteractive.hxx>
36
37 #include <QObject>
38 #include <QMouseEvent>
39 #include <QString>
40
41 #ifdef _DEBUG
42 #include <QDebug>
43 #endif
44
45 /*!Create and return new instance of XGUI_Module*/
46 extern "C" PARTSET_EXPORT XGUI_Module* createModule(XGUI_Workshop* theWshop)
47 {
48   return new PartSet_Module(theWshop);
49 }
50
51 PartSet_Module::PartSet_Module(XGUI_Workshop* theWshop)
52 {
53   myWorkshop = theWshop;
54   myListener = new PartSet_Listener(this);
55
56   XGUI_OperationMgr* anOperationMgr = myWorkshop->operationMgr();
57
58   connect(anOperationMgr, SIGNAL(operationStarted()),
59           this, SLOT(onOperationStarted()));
60
61   connect(anOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
62           this, SLOT(onOperationStopped(ModuleBase_Operation*)));
63
64   XGUI_ContextMenuMgr* aContextMenuMgr = myWorkshop->contextMenuMgr();
65   connect(aContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), 
66           this, SLOT(onContextMenuCommand(const QString&, bool)));
67
68   connect(myWorkshop->viewer(), SIGNAL(mousePress(QMouseEvent*)),
69           this, SLOT(onMousePressed(QMouseEvent*)));
70   connect(myWorkshop->viewer(), SIGNAL(mouseRelease(QMouseEvent*)),
71           this, SLOT(onMouseReleased(QMouseEvent*)));
72   connect(myWorkshop->viewer(), SIGNAL(mouseMove(QMouseEvent*)),
73           this, SLOT(onMouseMoved(QMouseEvent*)));
74   connect(myWorkshop->viewer(), SIGNAL(keyRelease(QKeyEvent*)),
75           this, SLOT(onKeyRelease(QKeyEvent*)));
76 }
77
78 PartSet_Module::~PartSet_Module()
79 {
80 }
81
82 XGUI_Workshop* PartSet_Module::workshop() const
83 {
84   return myWorkshop;
85 }
86
87 void PartSet_Module::createFeatures()
88 {
89   Config_ModuleReader aXMLReader = Config_ModuleReader();
90   aXMLReader.readAll();
91   myFeaturesInFiles = aXMLReader.featuresInFiles();
92 }
93
94 void PartSet_Module::featureCreated(QAction* theFeature)
95 {
96   connect(theFeature, SIGNAL(triggered(bool)), this, SLOT(onFeatureTriggered()));
97 }
98
99 QStringList PartSet_Module::nestedFeatures(QString)
100 {
101   return QStringList();
102 }
103
104 std::string PartSet_Module::featureFile(const std::string& theFeatureId)
105 {
106   return myFeaturesInFiles[theFeatureId];
107 }
108
109 /*
110  *
111  */
112 void PartSet_Module::onFeatureTriggered()
113 {
114   //PartSet_TestOCC::local_selection_change_shape(myWorkshop->viewer()->AISContext(),
115   //                                   myWorkshop->viewer()->activeView());
116
117   //PartSet_TestOCC::local_selection_erase(myWorkshop->viewer()->AISContext(),
118   //                                       myWorkshop->viewer()->activeView());
119   QAction* aCmd = dynamic_cast<QAction*>(sender());
120   //Do nothing on uncheck
121   if(aCmd->isCheckable() && !aCmd->isChecked())
122     return;
123   launchOperation(aCmd->data().toString());
124 }
125   
126 void PartSet_Module::launchOperation(const QString& theCmdId)
127 {
128   ModuleBase_Operation* anOperation = createOperation(theCmdId.toStdString());
129   sendOperation(anOperation);
130 }
131
132 void PartSet_Module::onOperationStarted()
133 {
134   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
135                                        myWorkshop->operationMgr()->currentOperation());
136   if (aPreviewOp) {
137     XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
138     connect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
139             aPropPanel, SLOT(onFocusActivated(const std::string&)));
140   }
141 }
142
143 void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation)
144 {
145   if (!theOperation)
146     return;
147   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(theOperation);
148   if (aPreviewOp) {
149     XGUI_PropertyPanel* aPropPanel = myWorkshop->propertyPanel();
150     disconnect(aPreviewOp, SIGNAL(focusActivated(const std::string&)),
151                aPropPanel, SLOT(onFocusActivated(const std::string&)));
152   }
153 }
154
155 void PartSet_Module::onContextMenuCommand(const QString& theId, bool isChecked)
156 {
157   QFeatureList aFeatures = myWorkshop->selector()->selectedFeatures();
158   if (theId == "EDIT_CMD" && (aFeatures.size() > 0)) {
159     editFeature(aFeatures.first());
160   }
161 }
162
163 void PartSet_Module::onMousePressed(QMouseEvent* theEvent)
164 {
165   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
166                                        myWorkshop->operationMgr()->currentOperation());
167   if (aPreviewOp)
168   {
169     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
170     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected();
171     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted();
172
173     aPreviewOp->mousePressed(theEvent, myWorkshop->viewer()->activeView(), aSelected, aHighlighted);
174   }
175 }
176
177 void PartSet_Module::onMouseReleased(QMouseEvent* theEvent)
178 {
179   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
180                                        myWorkshop->operationMgr()->currentOperation());
181   if (aPreviewOp)
182   {
183     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
184     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected();
185     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted();
186
187     aPreviewOp->mouseReleased(theEvent, myWorkshop->viewer()->activeView(), aSelected, aHighlighted);
188   }
189 }
190
191 void PartSet_Module::onMouseMoved(QMouseEvent* theEvent)
192 {
193   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(
194                                        myWorkshop->operationMgr()->currentOperation());
195   if (aPreviewOp)
196     aPreviewOp->mouseMoved(theEvent, myWorkshop->viewer()->activeView());
197 }
198
199 void PartSet_Module::onKeyRelease(QKeyEvent* theEvent)
200 {
201   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
202   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
203   if (aPreviewOp) {
204     aPreviewOp->keyReleased(theEvent->key());
205   }
206 }
207
208 void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ)
209 {
210   myWorkshop->viewer()->setViewProjection(theX, theY, theZ);
211   myWorkshop->actionsMgr()->update();
212
213   //PartSet_TestOCC::testSelection(myWorkshop);
214 }
215
216 void PartSet_Module::onFitAllView()
217 {
218   myWorkshop->viewer()->fitAll();
219 }
220
221 void PartSet_Module::onLaunchOperation(std::string theName, boost::shared_ptr<ModelAPI_Feature> theFeature)
222 {
223   ModuleBase_Operation* anOperation = createOperation(theName.c_str());
224   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
225   if (aPreviewOp)
226   {
227     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
228       // refill the features list with avoiding of the features, obtained only by vertex shape (TODO)
229     std::list<XGUI_ViewerPrs> aSelected = aDisplayer->GetSelected(TopAbs_VERTEX);
230     std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted(TopAbs_VERTEX);
231     aPreviewOp->init(theFeature, aSelected, aHighlighted);
232   }
233   sendOperation(anOperation);
234   myWorkshop->actionsMgr()->updateCheckState();
235 }
236
237 void PartSet_Module::onMultiSelectionEnabled(bool theEnabled)
238 {
239   XGUI_ViewerProxy* aViewer = myWorkshop->viewer();
240   aViewer->enableMultiselection(theEnabled);
241 }
242
243 void PartSet_Module::onStopSelection(const std::list<XGUI_ViewerPrs>& theFeatures, const bool isStop)
244 {
245   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
246   if (!isStop) {
247     std::list<XGUI_ViewerPrs>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
248     boost::shared_ptr<ModelAPI_Feature> aFeature;
249     for (; anIt != aLast; anIt++) {
250       activateFeature((*anIt).feature(), false);
251     }
252   }
253   aDisplayer->StopSelection(theFeatures, isStop, false);
254
255   XGUI_ViewerProxy* aViewer = myWorkshop->viewer();
256   aViewer->enableSelection(!isStop);
257
258   aDisplayer->UpdateViewer();
259 }
260
261 void PartSet_Module::onSetSelection(const std::list<XGUI_ViewerPrs>& theFeatures)
262 {
263   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
264   aDisplayer->SetSelected(theFeatures, false);
265   aDisplayer->UpdateViewer();
266 }
267
268 void PartSet_Module::onCloseLocalContext()
269 {
270   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
271   aDisplayer->CloseLocalContexts();
272 }
273
274 void PartSet_Module::onFeatureConstructed(boost::shared_ptr<ModelAPI_Feature> theFeature,
275                                           int theMode)
276 {
277   bool isDisplay = theMode != PartSet_OperationSketchBase::FM_Hide;
278   visualizePreview(theFeature, isDisplay, false);
279   if (!isDisplay) {
280     ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation();
281     boost::shared_ptr<ModelAPI_Feature> aSketch;
282     PartSet_OperationSketchBase* aPrevOp = dynamic_cast<PartSet_OperationSketchBase*>(aCurOperation);
283     if (aPrevOp) {
284       std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
285                                                                          aList = aPrevOp->subPreview();
286       XGUI_Displayer* aDisplayer = myWorkshop->displayer();
287       std::list<int> aModes = aPrevOp->getSelectionModes(aPrevOp->feature());
288
289       std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
290                                                              anIt = aList.begin(), aLast = aList.end();
291       for (; anIt != aLast; anIt++) {
292         boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
293         visualizePreview(aFeature, false, false);
294       }
295       aDisplayer->UpdateViewer();
296     }
297   }
298
299   if (theMode == PartSet_OperationSketchBase::FM_Activation ||
300       theMode == PartSet_OperationSketchBase::FM_Deactivation)
301     activateFeature(theFeature, true);
302 }
303
304 ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdId)
305 {
306   // get operation xml description
307   std::string aStdCmdId = theCmdId;
308   if (aStdCmdId == PartSet_OperationEditLine::Type())
309     aStdCmdId = PartSet_OperationSketchLine::Type();
310   std::string aPluginFileName = featureFile(aStdCmdId);
311   Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName);
312   aWdgReader.readAll();
313   std::string aXmlCfg = aWdgReader.featureWidgetCfg(aStdCmdId);
314   std::string aDescription = aWdgReader.featureDescription(aStdCmdId);
315
316   // create the operation
317   ModuleBase_Operation* anOperation;
318   if (theCmdId == PartSet_OperationSketch::Type()) {
319     anOperation = new PartSet_OperationSketch(theCmdId.c_str(), this);
320   }
321   else if(theCmdId == PartSet_OperationSketchLine::Type() ||
322           theCmdId == PartSet_OperationEditLine::Type()) {
323     ModuleBase_Operation* aCurOperation = myWorkshop->operationMgr()->currentOperation();
324     boost::shared_ptr<ModelAPI_Feature> aSketch;
325     PartSet_OperationSketchBase* aPrevOp = dynamic_cast<PartSet_OperationSketchBase*>(aCurOperation);
326     if (aPrevOp)
327       aSketch = aPrevOp->sketch();
328     if (theCmdId == PartSet_OperationSketchLine::Type())
329       anOperation = new PartSet_OperationSketchLine(theCmdId.c_str(), this, aSketch);
330     else
331       anOperation = new PartSet_OperationEditLine(theCmdId.c_str(), this, aSketch);
332   }
333   else {
334     anOperation = new ModuleBase_Operation(theCmdId.c_str(), this);
335   }
336   anOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg));
337   anOperation->getDescription()->setDescription(QString::fromStdString(aDescription));
338
339   // connect the operation
340   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
341   if (aPreviewOp) {
342     connect(aPreviewOp, SIGNAL(featureConstructed(boost::shared_ptr<ModelAPI_Feature>, int)),
343             this, SLOT(onFeatureConstructed(boost::shared_ptr<ModelAPI_Feature>, int)));
344     connect(aPreviewOp, SIGNAL(launchOperation(std::string, boost::shared_ptr<ModelAPI_Feature>)),
345             this, SLOT(onLaunchOperation(std::string, boost::shared_ptr<ModelAPI_Feature>)));
346     connect(aPreviewOp, SIGNAL(multiSelectionEnabled(bool)),
347             this, SLOT(onMultiSelectionEnabled(bool)));
348
349     connect(aPreviewOp, SIGNAL(multiSelectionEnabled(bool)),
350             this, SLOT(onMultiSelectionEnabled(bool)));
351     connect(aPreviewOp, SIGNAL(stopSelection(const std::list<XGUI_ViewerPrs>&, const bool)),
352             this, SLOT(onStopSelection(const std::list<XGUI_ViewerPrs>&, const bool)));
353     connect(aPreviewOp, SIGNAL(setSelection(const std::list<XGUI_ViewerPrs>&)),
354             this, SLOT(onSetSelection(const std::list<XGUI_ViewerPrs>&)));
355
356      connect(aPreviewOp, SIGNAL(closeLocalContext()),
357              this, SLOT(onCloseLocalContext()));
358
359     PartSet_OperationSketch* aSketchOp = dynamic_cast<PartSet_OperationSketch*>(aPreviewOp);
360     if (aSketchOp) {
361       connect(aSketchOp, SIGNAL(planeSelected(double, double, double)),
362               this, SLOT(onPlaneSelected(double, double, double)));
363       connect(aSketchOp, SIGNAL(fitAllView()),
364               this, SLOT(onFitAllView()));
365     }
366   }
367
368   return anOperation;
369 }
370
371 void PartSet_Module::sendOperation(ModuleBase_Operation* theOperation)
372 {
373   //TODO(sbh): Implement static method to extract event id [SEID]
374   static Events_ID aModuleEvent = Events_Loop::eventByName("PartSetModuleEvent");
375   Config_PointerMessage aMessage(aModuleEvent, this);
376   aMessage.setPointer(theOperation);
377   Events_Loop::loop()->send(aMessage);
378 }
379
380 void PartSet_Module::visualizePreview(boost::shared_ptr<ModelAPI_Feature> theFeature, bool isDisplay,
381                                       const bool isUpdateViewer)
382 {
383   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
384   if (!anOperation)
385     return;
386
387   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
388   if (!aPreviewOp)
389     return;
390
391   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
392   if (isDisplay) {
393     boost::shared_ptr<GeomAPI_Shape> aPreview = aPreviewOp->preview(theFeature);
394     bool isAISCreated = aDisplayer->Redisplay(theFeature, aPreview ?
395                                            aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
396     if (isAISCreated) {
397       PartSet_OperationSketch* aSketchOp = dynamic_cast<PartSet_OperationSketch*>(aPreviewOp);
398       if (aSketchOp) {
399         Handle(AIS_InteractiveObject) anAIS = aDisplayer->GetAISObject(theFeature);
400         aSketchOp->correctPresentation(anAIS);
401       }
402     }
403   }
404   else
405     aDisplayer->Erase(theFeature, false);
406
407   if (isUpdateViewer)
408     aDisplayer->UpdateViewer();
409 }
410
411 void PartSet_Module::activateFeature(boost::shared_ptr<ModelAPI_Feature> theFeature,
412                                      const bool isUpdateViewer)
413 {
414   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
415   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
416   if (aPreviewOp) {
417     XGUI_Displayer* aDisplayer = myWorkshop->displayer();
418     aDisplayer->ActivateInLocalContext(theFeature, aPreviewOp->getSelectionModes(theFeature),
419                                        isUpdateViewer);
420   }
421 }
422
423 void PartSet_Module::updateCurrentPreview(const std::string& theCmdId)
424 {
425   ModuleBase_Operation* anOperation = myWorkshop->operationMgr()->currentOperation();
426   if (!anOperation)
427     return;
428
429   PartSet_OperationSketchBase* aPreviewOp = dynamic_cast<PartSet_OperationSketchBase*>(anOperation);
430   if (!aPreviewOp)
431     return;
432
433   boost::shared_ptr<ModelAPI_Feature> aFeature = aPreviewOp->feature();
434   if (!aFeature || aFeature->getKind() != theCmdId)
435     return;
436
437   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
438                                                                      aList = aPreviewOp->subPreview();
439   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
440   std::list<int> aModes = aPreviewOp->getSelectionModes(aPreviewOp->feature());
441
442   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >::const_iterator
443                                                          anIt = aList.begin(), aLast = aList.end();
444   for (; anIt != aLast; anIt++) {
445     boost::shared_ptr<ModelAPI_Feature> aFeature = (*anIt).first;
446     boost::shared_ptr<GeomAPI_Shape> aPreview = (*anIt).second;
447     aDisplayer->Redisplay(aFeature,
448                           aPreview ? aPreview->impl<TopoDS_Shape>() : TopoDS_Shape(), false);
449     aDisplayer->ActivateInLocalContext(aFeature, aModes, false);
450   }
451   aDisplayer->UpdateViewer();
452 }
453
454 void PartSet_Module::editFeature(FeaturePtr theFeature)
455 {
456   if (!theFeature)
457     return;
458
459   if (theFeature->getKind() == "Sketch") {
460     FeaturePtr aFeature = theFeature;
461     if (XGUI_Tools::isModelObject(aFeature)) {
462       ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
463       aFeature = aObject->featureRef();
464     }
465
466     if (aFeature) {
467       onLaunchOperation(aFeature->getKind(), aFeature);
468       updateCurrentPreview(aFeature->getKind());
469     }
470   }
471 }