1 // File: PartSet_OperationCreateFeature.h
2 // Created: 20 Apr 2014
3 // Author: Natalia ERMOLAEVA
5 #include <PartSet_OperationCreateFeature.h>
7 #include <PartSet_Tools.h>
8 #include <PartSet_OperationSketch.h>
9 #include <PartSet_FeaturePointPrs.h>
10 #include <PartSet_FeatureLinePrs.h>
11 #include <PartSet_FeatureCirclePrs.h>
12 #include <PartSet_FeatureArcPrs.h>
14 #include <SketchPlugin_Feature.h>
15 #include <SketchPlugin_Point.h>
16 #include <SketchPlugin_Line.h>
17 #include <SketchPlugin_Circle.h>
18 #include <SketchPlugin_Arc.h>
20 #include <ModuleBase_OperationDescription.h>
22 #include <XGUI_ViewerPrs.h>
23 #include <XGUI_Constants.h>
25 #include <V3d_View.hxx>
26 #include <TopoDS_Vertex.hxx>
28 #include <BRep_Tool.hxx>
34 #include <QMouseEvent>
38 PartSet_OperationCreateFeature::PartSet_OperationCreateFeature(const QString& theId,
40 FeaturePtr theFeature)
41 : PartSet_OperationSketchBase(theId, theParent),
42 myPointSelectionMode(SM_FirstPoint)
44 std::string aKind = theId.toStdString();
46 if (aKind == SKETCH_POINT_KIND) {
47 myFeaturePrs = new PartSet_FeaturePointPrs(theFeature);
49 if (aKind == SKETCH_LINE_KIND) {
50 myFeaturePrs = new PartSet_FeatureLinePrs(theFeature);
52 else if (aKind == SKETCH_CIRCLE_KIND) {
53 myFeaturePrs = new PartSet_FeatureCirclePrs(theFeature);
55 else if (aKind == SKETCH_ARC_KIND) {
56 myFeaturePrs = new PartSet_FeatureArcPrs(theFeature);
60 PartSet_OperationCreateFeature::~PartSet_OperationCreateFeature()
65 bool PartSet_OperationCreateFeature::canProcessKind(const std::string& theId)
67 return theId == SKETCH_LINE_KIND || theId == SKETCH_POINT_KIND || theId == SKETCH_CIRCLE_KIND ||
68 theId == SKETCH_ARC_KIND;
71 bool PartSet_OperationCreateFeature::canBeCommitted() const
73 return myPointSelectionMode == SM_DonePoint;
76 bool PartSet_OperationCreateFeature::isGranted(ModuleBase_IOperation* theOperation) const
78 return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type();
81 std::list<int> PartSet_OperationCreateFeature::getSelectionModes(FeaturePtr theFeature) const
83 std::list<int> aModes;
84 if (theFeature != feature())
85 aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature);
89 void PartSet_OperationCreateFeature::init(FeaturePtr theFeature,
90 const std::list<XGUI_ViewerPrs>& /*theSelected*/,
91 const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
93 if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND)
95 myInitFeature = theFeature;
98 FeaturePtr PartSet_OperationCreateFeature::sketch() const
100 return myFeaturePrs->sketch();
103 void PartSet_OperationCreateFeature::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView,
104 const std::list<XGUI_ViewerPrs>& theSelected,
105 const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
107 if (myPointSelectionMode == SM_DonePoint)
109 // if the point creation is finished, the next mouse release should commit the modification
110 // the next release can happens by double click in the viewer
112 restartOperation(feature()->getKind(), feature());
118 bool isFoundPoint = false;
119 gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView);
120 if (theSelected.empty()) {
121 PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY);
125 XGUI_ViewerPrs aPrs = theSelected.front();
126 const TopoDS_Shape& aShape = aPrs.shape();
127 if (!aShape.IsNull()) // the point is selected
129 if (aShape.ShapeType() == TopAbs_VERTEX) {
130 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
131 if (!aVertex.IsNull()) {
132 aPoint = BRep_Tool::Pnt(aVertex);
133 PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY);
136 myFeaturePrs->setConstraints(aX, anY, myPointSelectionMode);
139 else if (aShape.ShapeType() == TopAbs_EDGE) // the line is selected
141 PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY);
144 FeaturePtr aFeature = aPrs.feature();
146 double X0, X1, X2, X3;
147 double Y0, Y1, Y2, Y3;
148 PartSet_Tools::getLinePoint(aFeature, LINE_ATTR_START, X2, Y2);
149 PartSet_Tools::getLinePoint(aFeature, LINE_ATTR_END, X3, Y3);
150 PartSet_Tools::convertTo2D(aPoint, sketch(), theView, X1, Y1);
152 switch (myPointSelectionMode) {
154 PartSet_Tools::projectPointOnLine(X2, Y2, X3, Y3, X1, Y1, aX, anY);
156 case SM_SecondPoint: {
157 PartSet_Tools::getLinePoint(feature(), LINE_ATTR_START, X0, Y0);
158 PartSet_Tools::intersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, aX, anY);
171 switch (myPointSelectionMode)
174 case SM_SecondPoint: {
175 PartSet_SelectionMode aMode = myFeaturePrs->setPoint(aX, anY, myPointSelectionMode);
177 setPointSelectionMode(aMode);
185 void PartSet_OperationCreateFeature::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView)
187 switch (myPointSelectionMode)
193 gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView);
194 PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY);
195 myFeaturePrs->setPoint(aX, anY, myPointSelectionMode);
198 emit focusActivated(myFeaturePrs->getAttribute(myPointSelectionMode));
204 restartOperation(feature()->getKind(), feature());
211 void PartSet_OperationCreateFeature::keyReleased(std::string theName, QKeyEvent* theEvent)
213 int aKeyType = theEvent->key();
214 // the second point should be activated by any modification in the property panel
215 if (!theName.empty() /*&& aKeyType == Qt::Key_Return*/)
217 setPointSelectionMode(myFeaturePrs->getNextMode(theName), false);
219 keyReleased(theEvent->key());
222 void PartSet_OperationCreateFeature::keyReleased(const int theKey)
225 case Qt::Key_Return: {
226 if (myPointSelectionMode == SM_DonePoint)
229 // it start a new line creation at a free point
230 restartOperation(feature()->getKind(), FeaturePtr()/*feature()*/);
234 //restartOperation(feature()->getKind(), FeaturePtr());
237 case Qt::Key_Escape: {
238 if (myPointSelectionMode == SM_DonePoint)
252 void PartSet_OperationCreateFeature::startOperation()
254 PartSet_OperationSketchBase::startOperation();
255 setPointSelectionMode(!myInitFeature ? SM_FirstPoint : SM_SecondPoint);
257 emit multiSelectionEnabled(false);
260 void PartSet_OperationCreateFeature::abortOperation()
262 emit featureConstructed(feature(), FM_Hide);
263 PartSet_OperationSketchBase::abortOperation();
266 void PartSet_OperationCreateFeature::stopOperation()
268 PartSet_OperationSketchBase::stopOperation();
269 emit multiSelectionEnabled(true);
272 void PartSet_OperationCreateFeature::afterCommitOperation()
274 PartSet_OperationSketchBase::afterCommitOperation();
275 emit featureConstructed(feature(), FM_Deactivation);
278 FeaturePtr PartSet_OperationCreateFeature::createFeature(const bool theFlushMessage)
280 FeaturePtr aNewFeature = ModuleBase_Operation::createFeature(false);
282 boost::shared_ptr<SketchPlugin_Feature> aFeature =
283 boost::dynamic_pointer_cast<SketchPlugin_Feature>(sketch());
285 aFeature->addSub(aNewFeature);
287 myFeaturePrs->init(aNewFeature, myInitFeature);
289 emit featureConstructed(aNewFeature, FM_Activation);
295 void PartSet_OperationCreateFeature::setPointSelectionMode(const PartSet_SelectionMode& theMode,
296 const bool isToEmitSignal)
298 myPointSelectionMode = theMode;
299 if (isToEmitSignal) {
300 std::string aName = myFeaturePrs->getAttribute(theMode);
301 if (aName.empty() && theMode == SM_DonePoint) {
302 aName = XGUI::PROP_PANEL_OK;
304 emit focusActivated(aName);