Salome HOME
Merge branch 'Dev_0.6' of newgeom:newgeom into Dev_0.6
[modules/shaper.git] / src / PartSet / PartSet_WidgetSketchLabel.cpp
1 // File:        PartSet_WidgetSketchLabel.cpp
2 // Created:     07 July 2014
3 // Author:      Vitaly SMETANNIKOV
4
5 #include "PartSet_WidgetSketchLabel.h"
6 #include "PartSet_Tools.h"
7
8 #include <XGUI_Workshop.h>
9 #include <XGUI_Displayer.h>
10 #include <XGUI_SelectionMgr.h>
11 #include <XGUI_Selection.h>
12 #include <XGUI_ViewerProxy.h>
13 #include <XGUI_ActionsMgr.h>
14
15 #include <ModuleBase_Operation.h>
16 #include <ModuleBase_ViewerPrs.h>
17
18 #include <GeomAlgoAPI_FaceBuilder.h>
19 #include <GeomDataAPI_Point.h>
20 #include <GeomDataAPI_Dir.h>
21 #include <GeomAPI_XYZ.h>
22
23 #include <SketchPlugin_Sketch.h>
24
25 #include <Precision.hxx>
26 #include <gp_Pln.hxx>
27 #include <gp_Pnt.hxx>
28 #include <gp_Dir.hxx>
29 #include <AIS_Shape.hxx>
30 #include <AIS_DimensionSelectionMode.hxx>
31
32 #include <Config_WidgetAPI.h>
33 #include <Config_PropManager.h>
34
35 #include <QLabel>
36
37 #define PLANE_SIZE          "200"     
38 #define SKETCH_WIDTH        "4"
39
40
41 PartSet_WidgetSketchLabel::PartSet_WidgetSketchLabel(QWidget* theParent,
42                                                      const Config_WidgetAPI* theData,
43                                                      const std::string& theParentId)
44     : ModuleBase_ModelWidget(theParent, theData, theParentId), myPreviewDisplayed(false)
45 {
46   myText = QString::fromStdString(theData->getProperty("title"));
47   myLabel = new QLabel("", theParent);
48   myLabel->setWordWrap(true);
49   myTooltip = QString::fromStdString(theData->getProperty("tooltip"));
50   myLabel->setToolTip("");
51   myLabel->setIndent(5);
52 }
53
54 PartSet_WidgetSketchLabel::~PartSet_WidgetSketchLabel()
55 {
56   erasePreviewPlanes();
57 }
58
59 QList<QWidget*> PartSet_WidgetSketchLabel::getControls() const
60 {
61   return QList<QWidget*>();
62 }
63
64 QWidget* PartSet_WidgetSketchLabel::getControl() const
65 {
66   return myLabel;
67 }
68
69 void PartSet_WidgetSketchLabel::onPlaneSelected()
70 {
71   XGUI_Selection* aSelection = myWorkshop->selector()->selection();
72   QList<ModuleBase_ViewerPrs> aSelected = aSelection->getSelected();
73   if (!aSelected.empty()) {
74     ModuleBase_ViewerPrs aPrs = aSelected.first();
75     TopoDS_Shape aShape = aPrs.shape();
76     if (!aShape.IsNull()) {
77       std::shared_ptr<GeomAPI_Dir> aDir = setSketchPlane(aShape);
78       if (aDir) {
79         erasePreviewPlanes();
80
81         if (aPrs.object() && (feature() != aPrs.object())) {
82           DataPtr aData = feature()->data();
83           AttributeSelectionPtr aSelAttr = 
84             std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
85             (aData->attribute(SketchPlugin_Feature::EXTERNAL_ID()));
86           if (aSelAttr) {
87             ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aPrs.object());
88             if (aRes) {
89               GeomShapePtr aShapePtr(new GeomAPI_Shape());
90               aShapePtr->setImpl(new TopoDS_Shape(aShape));
91               aSelAttr->setValue(aRes, aShapePtr);
92             }
93           }
94         } else
95           myWorkshop->viewer()->setViewProjection(aDir->x(), aDir->y(), aDir->z());
96
97         // Clear text in the label
98         myLabel->setText("");
99         myLabel->setToolTip("");
100         disconnect(myWorkshop->selector(), SIGNAL(selectionChanged()), 
101                    this, SLOT(onPlaneSelected()));
102
103         // Clear selection mode and define sketching mode
104         XGUI_Displayer* aDisp = myWorkshop->displayer();
105         aDisp->removeSelectionFilter(myPlaneFilter);
106         aDisp->closeLocalContexts();
107         setSketchingMode();
108         XGUI_ActionsMgr* anActMgr = myWorkshop->actionsMgr();
109         anActMgr->update();
110       }
111     }
112   }
113 }
114
115 std::shared_ptr<GeomAPI_Pln> PartSet_WidgetSketchLabel::plane() const
116 {
117   CompositeFeaturePtr aSketch = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
118   return PartSet_Tools::sketchPlane(aSketch);
119
120 }
121
122 void PartSet_WidgetSketchLabel::activate()
123 {
124   std::shared_ptr<GeomAPI_Pln> aPlane = plane();
125   if (aPlane) {
126     setSketchingMode();
127   } else {
128     // We have to select a plane before any operation
129     showPreviewPlanes();
130
131     XGUI_Displayer* aDisp = myWorkshop->displayer();
132     aDisp->openLocalContext();
133     aDisp->activateObjectsOutOfContext(QIntList());
134     if (myPlaneFilter.IsNull())
135       myPlaneFilter = new StdSelect_FaceFilter(StdSelect_Plane);
136     aDisp->addSelectionFilter(myPlaneFilter);
137     QIntList aModes;
138     aModes << TopAbs_FACE;
139     aDisp->setSelectionModes(aModes);
140
141     myLabel->setText(myText);
142     myLabel->setToolTip(myTooltip);
143
144     connect(myWorkshop->selector(), SIGNAL(selectionChanged()), this, SLOT(onPlaneSelected()));
145     aDisp->updateViewer();
146   }
147 }
148
149 void PartSet_WidgetSketchLabel::deactivate()
150 {
151
152   XGUI_Displayer* aDisp = myWorkshop->displayer();
153   aDisp->removeSelectionFilter(myPlaneFilter);
154   //aDisp->removeSelectionFilter(mySketchFilter);
155   aDisp->closeLocalContexts();
156   erasePreviewPlanes();
157 }
158
159 void PartSet_WidgetSketchLabel::erasePreviewPlanes()
160 {
161   if (myPreviewDisplayed) {
162     XGUI_Displayer* aDisp = myWorkshop->displayer();
163     aDisp->eraseAIS(myYZPlane, false);
164     aDisp->eraseAIS(myXZPlane, false);
165     aDisp->eraseAIS(myXYPlane, false);
166     myPreviewDisplayed = false;
167   }
168 }
169
170 void PartSet_WidgetSketchLabel::showPreviewPlanes()
171 {
172   if (myPreviewDisplayed)
173     return;
174
175   if (!myYZPlane) { // If planes are not created
176     // Create Preview
177     std::shared_ptr<GeomAPI_Pnt> anOrigin(new GeomAPI_Pnt(0, 0, 0));
178     std::shared_ptr<GeomAPI_Dir> aYZDir(new GeomAPI_Dir(1, 0, 0));
179     std::shared_ptr<GeomAPI_Dir> aXZDir(new GeomAPI_Dir(0, 1, 0));
180     std::shared_ptr<GeomAPI_Dir> aXYDir(new GeomAPI_Dir(0, 0, 1));
181
182     int aR[] = {255, 0, 0};
183     int aG[] = {0, 255, 0};
184     int aB[] = {0, 0, 255};
185
186     myYZPlane = createPreviewPlane(anOrigin, aYZDir, aR);
187     myXZPlane = createPreviewPlane(anOrigin, aXZDir, aG);
188     myXYPlane = createPreviewPlane(anOrigin, aXYDir, aB);
189   }
190   XGUI_Displayer* aDisp = myWorkshop->displayer();
191   aDisp->displayAIS(myYZPlane, false);
192   aDisp->displayAIS(myXZPlane, false);
193   aDisp->displayAIS(myXYPlane, false);
194   myPreviewDisplayed = true;
195 }
196
197
198 AISObjectPtr PartSet_WidgetSketchLabel::createPreviewPlane(std::shared_ptr<GeomAPI_Pnt> theOrigin, 
199                                                            std::shared_ptr<GeomAPI_Dir> theNorm, 
200                                                            const int theRGB[3])
201 {
202   double aSize = Config_PropManager::integer("Sketch planes", "Size of planes", PLANE_SIZE);
203   std::shared_ptr<GeomAPI_Shape> aFace = GeomAlgoAPI_FaceBuilder::square(theOrigin, theNorm, aSize);
204   AISObjectPtr aAIS = AISObjectPtr(new GeomAPI_AISObject());
205   aAIS->createShape(aFace);
206   aAIS->setWidth(Config_PropManager::integer("Sketch planes", "planes_thickness", SKETCH_WIDTH));
207   aAIS->setColor(theRGB[0], theRGB[1], theRGB[2]);
208   return aAIS;
209 }
210
211
212 std::shared_ptr<GeomAPI_Dir> PartSet_WidgetSketchLabel::setSketchPlane(const TopoDS_Shape& theShape)
213 {
214   if (theShape.IsNull())
215     return std::shared_ptr<GeomAPI_Dir>();
216
217   // get selected shape
218   std::shared_ptr<GeomAPI_Shape> aGShape(new GeomAPI_Shape);
219   aGShape->setImpl(new TopoDS_Shape(theShape));
220
221   // get plane parameters
222   std::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aGShape);
223
224   // set plane parameters to feature
225   std::shared_ptr<ModelAPI_Data> aData = feature()->data();
226   double anA, aB, aC, aD;
227   aPlane->coefficients(anA, aB, aC, aD);
228
229   // calculate attributes of the sketch
230   std::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
231   std::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
232   std::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
233   aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
234   std::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
235   // X axis is preferable to be dirX on the sketch
236   const double tol = Precision::Confusion();
237   bool isX = fabs(anA - 1.0) < tol && fabs(aB) < tol && fabs(aC) < tol;
238   std::shared_ptr<GeomAPI_Dir> aTempDir(
239       isX ? new GeomAPI_Dir(0, 1, 0) : new GeomAPI_Dir(1, 0, 0));
240   std::shared_ptr<GeomAPI_Dir> aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir)));
241   std::shared_ptr<GeomAPI_Dir> aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir)));
242
243   std::shared_ptr<GeomDataAPI_Point> anOrigin = std::dynamic_pointer_cast<GeomDataAPI_Point>(
244       aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
245   anOrigin->setValue(anOrigPnt);
246   std::shared_ptr<GeomDataAPI_Dir> aNormal = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
247       aData->attribute(SketchPlugin_Sketch::NORM_ID()));
248   aNormal->setValue(aNormDir);
249   std::shared_ptr<GeomDataAPI_Dir> aDirX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
250       aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
251   aDirX->setValue(aXDir);
252   std::shared_ptr<GeomDataAPI_Dir> aDirY = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
253       aData->attribute(SketchPlugin_Sketch::DIRY_ID()));
254   aDirY->setValue(aYDir);
255   std::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
256   return aDir;
257 }
258
259
260 void PartSet_WidgetSketchLabel::setSketchingMode()
261 {
262   XGUI_Displayer* aDisp = myWorkshop->displayer();
263   QIntList aModes;
264   // Clear standard selection modes if they are defined
265   aDisp->setSelectionModes(aModes);
266   aDisp->openLocalContext();
267
268   // Set filter
269   std::shared_ptr<GeomAPI_Pln> aPlane = plane();
270   double aA, aB, aC, aD;
271   aPlane->coefficients(aA, aB, aC, aD);
272   gp_Pln aPln(aA, aB, aC, aD);
273   // No selection of external objects
274   //mySketchFilter = new ModuleBase_ShapeInPlaneFilter(aPln);
275   //aDisp->addSelectionFilter(mySketchFilter);
276
277   // Get default selection modes
278   aModes.append(AIS_DSM_Text);
279   aModes.append(AIS_DSM_Line);
280   aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_VERTEX));
281   aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_EDGE));
282
283   aDisp->activateObjectsOutOfContext(aModes);
284 }