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