Salome HOME
Merge branch 'master' of newgeom:newgeom.git
[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 <V3d_View.hxx>
25
26 #ifdef _DEBUG
27 #include <QDebug>
28 #endif
29
30 #include <QMouseEvent>
31
32 using namespace std;
33
34 PartSet_OperationSketch::PartSet_OperationSketch(const QString& theId,
35                                                      QObject* theParent)
36 : PartSet_OperationSketchBase(theId, theParent)
37 {
38 }
39
40 PartSet_OperationSketch::~PartSet_OperationSketch()
41 {
42 }
43
44 std::list<int> PartSet_OperationSketch::getSelectionModes(boost::shared_ptr<ModelAPI_Feature> theFeature) const
45 {
46   std::list<int> aModes;
47   if (!hasSketchPlane())
48     aModes.push_back(TopAbs_FACE);
49   else
50     aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature);
51   return aModes;
52 }
53
54 void PartSet_OperationSketch::init(boost::shared_ptr<ModelAPI_Feature> theFeature,
55                                    const std::list<XGUI_ViewerPrs>& thePresentations)
56 {
57   setFeature(theFeature);
58 }
59
60 boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketch::sketch() const
61 {
62   return feature();
63 }
64
65 void PartSet_OperationSketch::mousePressed(QMouseEvent* theEvent, Handle_V3d_View theView,
66                                            const std::list<XGUI_ViewerPrs>& theSelected,
67                                            const std::list<XGUI_ViewerPrs>& theHighlighted)
68 {
69   if (!hasSketchPlane()) {
70     if (!theHighlighted.empty()) {
71       XGUI_ViewerPrs aPrs = theHighlighted.front();
72       const TopoDS_Shape& aShape = aPrs.shape();
73       if (!aShape.IsNull())
74         setSketchPlane(aShape);
75     }
76   }
77   else {
78     // if shift button is pressed and there are some already selected objects, the operation should
79     // not be started. We just want to combine some selected objects.
80     bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
81     if (aHasShift && theSelected.size() > 0)
82       return;
83
84     if (theHighlighted.size() == 1) {
85       boost::shared_ptr<ModelAPI_Feature> aFeature = theHighlighted.front().feature();
86       if (aFeature)
87         emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
88     }
89     else
90       myFeatures = theHighlighted;
91   }
92 }
93
94 void PartSet_OperationSketch::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView)
95 {
96   if (!hasSketchPlane() || !(theEvent->buttons() &  Qt::LeftButton) || myFeatures.empty())
97     return;
98
99   if (myFeatures.size() != 1) {
100     boost::shared_ptr<ModelAPI_Feature> aFeature = PartSet_Tools::NearestFeature(theEvent->pos(),
101                                                                 theView, feature(), myFeatures);
102     if (aFeature)
103       emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
104   }
105 }
106
107 std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> >
108                                                         PartSet_OperationSketch::subPreview() const
109 {
110   std::map<boost::shared_ptr<ModelAPI_Feature>, boost::shared_ptr<GeomAPI_Shape> > aPreviewMap;
111
112   boost::shared_ptr<SketchPlugin_Feature> aFeature;
113
114   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
115   if (!aData->isValid())
116     return aPreviewMap;
117   boost::shared_ptr<ModelAPI_AttributeRefList> aRefList =
118         boost::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aData->attribute(SKETCH_ATTR_FEATURES));
119
120   std::list<boost::shared_ptr<ModelAPI_Feature> > aFeatures = aRefList->list();
121   std::list<boost::shared_ptr<ModelAPI_Feature> >::const_iterator anIt = aFeatures.begin(),
122                                                                   aLast = aFeatures.end();
123   for (; anIt != aLast; anIt++) {
124     aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
125     boost::shared_ptr<GeomAPI_Shape> aPreview = aFeature->preview();
126     if (aPreview)
127       aPreviewMap[aFeature] = aPreview;
128   }
129   return aPreviewMap;
130 }
131
132 void PartSet_OperationSketch::stopOperation()
133 {
134   PartSet_OperationSketchBase::stopOperation();
135   emit featureConstructed(feature(), FM_Hide);
136   emit closeLocalContext();
137 }
138
139 bool PartSet_OperationSketch::isNestedOperationsEnabled() const
140 {
141   return hasSketchPlane();
142 }
143
144 bool PartSet_OperationSketch::hasSketchPlane() const
145 {
146   bool aHasPlane = false;
147
148   if (feature()) {
149     // set plane parameters to feature
150     boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
151
152     boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
153     // temporary solution for main planes only
154     boost::shared_ptr<GeomDataAPI_Dir> aNormal = 
155       boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
156     double aX = aNormal->x(), anY = aNormal->y(), aZ = aNormal->z();
157
158     aHasPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
159   }
160   return aHasPlane;
161 }
162
163 void PartSet_OperationSketch::setSketchPlane(const TopoDS_Shape& theShape)
164 {
165   if (theShape.IsNull())
166     return;
167
168   // get selected shape
169   boost::shared_ptr<GeomAPI_Shape> aGShape(new GeomAPI_Shape);
170   aGShape->setImpl(new TopoDS_Shape(theShape));
171
172   // get plane parameters
173   boost::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aGShape);
174
175   // set plane parameters to feature
176   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
177   double anA, aB, aC, aD;
178   aPlane->coefficients(anA, aB, aC, aD);
179
180   boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
181   // temporary solution for main planes only
182   boost::shared_ptr<GeomDataAPI_Point> anOrigin = 
183     boost::dynamic_pointer_cast<GeomDataAPI_Point>(aData->attribute(SKETCH_ATTR_ORIGIN));
184   anOrigin->setValue(0, 0, 0);
185   boost::shared_ptr<GeomDataAPI_Dir> aNormal = 
186     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
187   aNormal->setValue(anA, aB, aC);
188   boost::shared_ptr<GeomDataAPI_Dir> aDirX = 
189     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRX));
190   aDirX->setValue(aB, aC, anA);
191   boost::shared_ptr<GeomDataAPI_Dir> aDirY = 
192     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_DIRY));
193   aDirY->setValue(aC, anA, aB);
194   boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
195
196   flushUpdated();
197
198   emit featureConstructed(feature(), FM_Hide);
199   emit closeLocalContext();
200   emit planeSelected(aDir->x(), aDir->y(), aDir->z());
201 }