]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_Module.cpp
Salome HOME
d5f96e489e9d191e8fed9c98b59fe79e9642ca0c
[modules/shaper.git] / src / PartSet / PartSet_Module.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 #include "PartSet_Module.h"
4 #include <PartSet_WidgetSketchLabel.h>
5 #include <PartSet_Validators.h>
6 #include <PartSet_Tools.h>
7 #include <PartSet_WidgetPoint2d.h>
8 #include <PartSet_WidgetPoint2dDistance.h>
9 #include <PartSet_WidgetShapeSelector.h>
10 #include <PartSet_SketcherMgr.h>
11
12 #include <ModuleBase_Operation.h>
13 #include <ModuleBase_IViewer.h>
14 #include <ModuleBase_IViewWindow.h>
15 #include <ModuleBase_IPropertyPanel.h>
16 #include <ModuleBase_WidgetEditor.h>
17 #include <ModuleBase_FilterFactory.h>
18 #include <ModuleBase_FilterLinearEdge.h>
19 #include <ModuleBase_FilterFace.h>
20 #include <ModuleBase_FilterMulti.h>
21
22
23 #include <ModelAPI_Object.h>
24 #include <ModelAPI_Events.h>
25 #include <ModelAPI_Validator.h>
26 #include <ModelAPI_Data.h>
27 #include <ModelAPI_Session.h>
28
29 #include <GeomDataAPI_Point2D.h>
30 #include <GeomDataAPI_Point.h>
31 #include <GeomDataAPI_Dir.h>
32
33 #include <XGUI_Displayer.h>
34 #include <XGUI_Workshop.h>
35 #include <XGUI_OperationMgr.h>
36 #include <XGUI_PropertyPanel.h>
37 #include <XGUI_ModuleConnector.h>
38 #include <XGUI_Tools.h>
39
40 #include <SketchPlugin_Feature.h>
41 #include <SketchPlugin_Sketch.h>
42 #include <SketchPlugin_Line.h>
43 //#include <SketchPlugin_Arc.h>
44 //#include <SketchPlugin_Circle.h>
45 #include <SketchPlugin_ConstraintLength.h>
46 #include <SketchPlugin_ConstraintDistance.h>
47 #include <SketchPlugin_ConstraintParallel.h>
48 #include <SketchPlugin_ConstraintPerpendicular.h>
49 #include <SketchPlugin_ConstraintRadius.h>
50 //#include <SketchPlugin_ConstraintRigid.h>
51
52 #include <Events_Loop.h>
53
54 #include <StdSelect_TypeOfFace.hxx>
55 #include <TopoDS_Vertex.hxx>
56 #include <TopoDS.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <BRep_Tool.hxx>
59
60 #include <QObject>
61 #include <QMouseEvent>
62 #include <QString>
63 #include <QTimer>
64 #include <QApplication>
65
66 #include <GeomAlgoAPI_FaceBuilder.h>
67 #include <GeomDataAPI_Dir.h>
68
69 #ifdef _DEBUG
70 #include <QDebug>
71 #endif
72
73 /*!Create and return new instance of XGUI_Module*/
74 extern "C" PARTSET_EXPORT ModuleBase_IModule* createModule(ModuleBase_IWorkshop* theWshop)
75 {
76   return new PartSet_Module(theWshop);
77 }
78
79 PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop)
80   : ModuleBase_IModule(theWshop), 
81   myRestartingMode(RM_None)
82 {
83   //myWorkshop = dynamic_cast<XGUI_Workshop*>(theWshop);
84   mySketchMgr = new PartSet_SketcherMgr(this);
85
86   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWshop);
87   XGUI_Workshop* aWorkshop = aConnector->workshop();
88
89   XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr();
90   connect(anOpMgr, SIGNAL(keyEnterReleased()), this, SLOT(onEnterReleased()));
91   connect(anOpMgr, SIGNAL(operationActivatedByPreselection()),
92           this, SLOT(onOperationActivatedByPreselection()));
93
94   ModuleBase_IViewer* aViewer = theWshop->viewer();
95   connect(aViewer, SIGNAL(keyRelease(ModuleBase_IViewWindow*, QKeyEvent*)),
96           this, SLOT(onKeyRelease(ModuleBase_IViewWindow*, QKeyEvent*)));
97 }
98
99 PartSet_Module::~PartSet_Module()
100 {
101   if (!myDocumentShapeFilter.IsNull())
102     myDocumentShapeFilter.Nullify();
103 }
104
105 void PartSet_Module::registerValidators()
106 {
107   //Registering of validators
108   SessionPtr aMgr = ModelAPI_Session::get();
109   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
110   aFactory->registerValidator("PartSet_DistanceValidator", new PartSet_DistanceValidator);
111   aFactory->registerValidator("PartSet_LengthValidator", new PartSet_LengthValidator);
112   aFactory->registerValidator("PartSet_PerpendicularValidator", new PartSet_PerpendicularValidator);
113   aFactory->registerValidator("PartSet_ParallelValidator", new PartSet_ParallelValidator);
114   aFactory->registerValidator("PartSet_RadiusValidator", new PartSet_RadiusValidator);
115   aFactory->registerValidator("PartSet_RigidValidator", new PartSet_RigidValidator);
116   aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator);
117   aFactory->registerValidator("PartSet_SketchValidator", new PartSet_SketchValidator);
118 }
119
120 void PartSet_Module::registerFilters()
121 {
122   //Registering of selection filters
123   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
124   ModuleBase_FilterFactory* aFactory = aConnector->selectionFilters();
125
126   aFactory->registerFilter("EdgeFilter", new ModuleBase_FilterLinearEdge);
127   aFactory->registerFilter("FaceFilter", new ModuleBase_FilterFace);
128   aFactory->registerFilter("MultiFilter", new ModuleBase_FilterMulti);
129 }
130
131 void PartSet_Module::operationCommitted(ModuleBase_Operation* theOperation) 
132 {
133   if (theOperation->isEditOperation())
134     return;
135   // the selection is cleared after commit the create operation
136   // in order to do not use the same selected objects in the restarted operation
137   // for common behaviour, the selection is cleared even if the operation is not restarted
138   myWorkshop->viewer()->AISContext()->ClearSelected();
139
140   /// Restart sketcher operations automatically
141   FeaturePtr aFeature = theOperation->feature();
142   std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
143             std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
144   if (aSPFeature && (myRestartingMode == RM_LastFeatureUsed ||
145                      myRestartingMode == RM_EmptyFeatureUsed)) {
146     myLastOperationId = theOperation->id();
147     myLastFeature = myRestartingMode == RM_LastFeatureUsed ? theOperation->feature() : FeaturePtr();
148     
149     launchOperation(myLastOperationId);
150   }
151   breakOperationSequence();
152 }
153
154 void PartSet_Module::breakOperationSequence()
155 {
156   myLastOperationId = "";
157   myLastFeature = FeaturePtr();
158   myRestartingMode = RM_None;
159 }
160
161 void PartSet_Module::operationAborted(ModuleBase_Operation* theOperation)
162 {
163   breakOperationSequence();
164 }
165
166 void PartSet_Module::operationStarted(ModuleBase_Operation* theOperation)
167 {
168   if (theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) {
169     mySketchMgr->startSketch(theOperation);
170   }
171   if (myDocumentShapeFilter.IsNull())
172     myDocumentShapeFilter = new PartSet_GlobalFilter(myWorkshop);
173   myWorkshop->viewer()->addSelectionFilter(myDocumentShapeFilter);
174 }
175
176 void PartSet_Module::operationStopped(ModuleBase_Operation* theOperation)
177 {
178   if (theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) {
179     mySketchMgr->stopSketch(theOperation);
180   }
181   myWorkshop->viewer()->removeSelectionFilter(myDocumentShapeFilter);
182 }
183
184
185 void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation)
186 {
187   ModuleBase_IPropertyPanel* aPanel = theOperation->propertyPanel();
188   if ((theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) && 
189     (theOperation->isEditOperation())) {
190     // we have to manually activate the sketch label in edit mode
191       aPanel->activateWidget(aPanel->modelWidgets().first());
192       return;
193   }
194
195   // Restart last operation type 
196   if ((theOperation->id() == myLastOperationId) && myLastFeature) {
197     ModuleBase_ModelWidget* aWgt = aPanel->activeWidget();
198     if (theOperation->id().toStdString() == SketchPlugin_Line::ID()) {
199       // Initialise new line with first point equal to end of previous
200       PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast<PartSet_WidgetPoint2D*>(aWgt);
201       if (aPnt2dWgt) {
202         std::shared_ptr<ModelAPI_Data> aData = myLastFeature->data();
203         std::shared_ptr<GeomDataAPI_Point2D> aPoint = 
204           std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::END_ID()));
205         if (aPoint) {
206           aPnt2dWgt->setPoint(aPoint->x(), aPoint->y());
207           PartSet_Tools::setConstraints(mySketchMgr->activeSketch(), theOperation->feature(), 
208             aWgt->attributeID(), aPoint->x(), aPoint->y());
209           theOperation->propertyPanel()->activateNextWidget(aPnt2dWgt);
210         }
211       }
212     }
213   } else {
214     // Start editing constraint
215     if (theOperation->isEditOperation()) {
216       std::string aId = theOperation->id().toStdString();
217       if (PartSet_SketcherMgr::sketchOperationIdList().contains(QString(aId.c_str()))) {
218         if ((aId == SketchPlugin_ConstraintRadius::ID()) ||
219             (aId == SketchPlugin_ConstraintLength::ID()) || 
220             (aId == SketchPlugin_ConstraintDistance::ID())) {
221           // Find and activate widget for management of point for dimension line position
222           QList<ModuleBase_ModelWidget*> aWidgets = aPanel->modelWidgets();
223           foreach (ModuleBase_ModelWidget* aWgt, aWidgets) {
224             PartSet_WidgetPoint2D* aPntWgt = dynamic_cast<PartSet_WidgetPoint2D*>(aWgt);
225             if (aPntWgt) {
226               aPanel->activateWidget(aPntWgt);
227               return;
228             }
229           }
230         } 
231       }
232     }
233   }
234 }
235
236
237 void PartSet_Module::onSelectionChanged()
238 {
239   ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
240   if (!aOperation)
241     return;
242
243   bool isSketcherOp = false;
244   // An edit operation is enable only if the current opeation is the sketch operation
245   if (mySketchMgr->activeSketch()) {
246     if (PartSet_Tools::sketchPlane(mySketchMgr->activeSketch()))
247       isSketcherOp = (aOperation->id().toStdString() == SketchPlugin_Sketch::ID());
248   }
249   if (isSketcherOp) {
250     // Editing of constraints can be done on selection
251     ModuleBase_ISelection* aSelect = myWorkshop->selection();
252     QList<ModuleBase_ViewerPrs> aSelected = aSelect->getSelected();
253     if (aSelected.size() == 1) {
254       ModuleBase_ViewerPrs aPrs = aSelected.first();
255       ObjectPtr aObject = aPrs.object();
256       FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
257       if (aFeature) {
258         std::string aId = aFeature->getKind();
259         if ((aId == SketchPlugin_ConstraintRadius::ID()) ||
260             (aId == SketchPlugin_ConstraintLength::ID()) || 
261             (aId == SketchPlugin_ConstraintDistance::ID())) {
262           editFeature(aFeature);
263         }
264       }
265     }
266   } 
267 }
268
269 void PartSet_Module::onKeyRelease(ModuleBase_IViewWindow* theWnd, QKeyEvent* theEvent)
270 {
271   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
272   XGUI_OperationMgr* anOpMgr = aConnector->workshop()->operationMgr();
273   anOpMgr->onKeyReleased(theEvent);
274 }
275
276 void PartSet_Module::onEnterReleased()
277 {
278   myRestartingMode = RM_EmptyFeatureUsed;
279 }
280
281 void PartSet_Module::onOperationActivatedByPreselection()
282 {
283   ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
284   if (!aOperation)
285     return;
286
287   // Set final definitions if they are necessary
288   //propertyPanelDefined(aOperation);
289
290   /// Commit sketcher operations automatically
291   FeaturePtr aFeature = aOperation->feature();
292   std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
293             std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
294   if (aSPFeature) {
295     aOperation->commit();
296   }
297 }
298
299 void PartSet_Module::onNoMoreWidgets()
300 {
301   ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
302   if (aOperation) {
303     /// Restart sketcher operations automatically
304     FeaturePtr aFeature = aOperation->feature();
305     std::shared_ptr<SketchPlugin_Feature> aSPFeature = 
306               std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
307     if (aSPFeature) {
308       if (myRestartingMode != RM_Forbided)
309         myRestartingMode = RM_LastFeatureUsed;
310       aOperation->commit();
311     }
312   }
313 }
314
315 void PartSet_Module::onVertexSelected()
316 {
317   ModuleBase_Operation* aOperation = myWorkshop->currentOperation();
318   if (aOperation->id().toStdString() == SketchPlugin_Line::ID()) {
319     /// If last line finished on vertex the lines creation sequence has to be break
320     ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
321     const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
322     if (aWidgets.last() == aPanel->activeWidget()) {
323       myRestartingMode = RM_Forbided;
324     }
325   }
326 }
327
328 QWidget* PartSet_Module::createWidgetByType(const std::string& theType, QWidget* theParent,
329                                             Config_WidgetAPI* theWidgetApi, std::string theParentId,
330                                             QList<ModuleBase_ModelWidget*>& theModelWidgets)
331 {
332   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(workshop());
333   XGUI_Workshop* aWorkshop = aConnector->workshop();
334   if (theType == "sketch-start-label") {
335     PartSet_WidgetSketchLabel* aWgt = new PartSet_WidgetSketchLabel(theParent, theWidgetApi, theParentId);
336     aWgt->setWorkshop(aWorkshop);
337     connect(aWgt, SIGNAL(planeSelected(const std::shared_ptr<GeomAPI_Pln>&)), 
338       mySketchMgr, SLOT(onPlaneSelected(const std::shared_ptr<GeomAPI_Pln>&)));
339     theModelWidgets.append(aWgt);
340     return aWgt->getControl();
341
342   } else if (theType == "sketch-2dpoint_selector") {
343     PartSet_WidgetPoint2D* aWgt = new PartSet_WidgetPoint2D(theParent, theWidgetApi, theParentId);
344     aWgt->setWorkshop(aWorkshop);
345     aWgt->setSketch(mySketchMgr->activeSketch());
346
347     connect(aWgt, SIGNAL(vertexSelected()), this, SLOT(onVertexSelected()));
348
349     theModelWidgets.append(aWgt);
350     return aWgt->getControl();
351
352   } if (theType == "point2ddistance") {
353     PartSet_WidgetPoint2dDistance* aWgt = new PartSet_WidgetPoint2dDistance(theParent, theWidgetApi, theParentId);
354     aWgt->setWorkshop(aWorkshop);
355     aWgt->setSketch(mySketchMgr->activeSketch());
356
357     theModelWidgets.append(aWgt);
358     return aWgt->getControl();
359
360   } if (theType == "sketch_shape_selector") {
361     PartSet_WidgetShapeSelector* aWgt = 
362       new PartSet_WidgetShapeSelector(theParent, workshop(), theWidgetApi, theParentId);
363     aWgt->setSketcher(mySketchMgr->activeSketch());
364
365     theModelWidgets.append(aWgt);
366     return aWgt->getControl();
367
368   } if (theType == "sketch_constraint_shape_selector") {
369     PartSet_WidgetConstraintShapeSelector* aWgt = 
370       new PartSet_WidgetConstraintShapeSelector(theParent, workshop(), theWidgetApi, theParentId);
371     aWgt->setSketcher(mySketchMgr->activeSketch());
372
373     theModelWidgets.append(aWgt);
374     return aWgt->getControl();
375
376   } else
377     return 0;
378 }
379