1 // File: PartSet_OperationFeatureEdit.h
2 // Created: 05 May 2014
3 // Author: Natalia ERMOLAEVA
5 #include <PartSet_OperationFeatureEdit.h>
6 #include <PartSet_Tools.h>
7 #include <PartSet_OperationSketch.h>
8 #include <PartSet_OperationFeatureEditMulti.h>
10 #include <SketchPlugin_Constraint.h>
12 #include <ModuleBase_OperationDescription.h>
13 #include <ModuleBase_WidgetEditor.h>
14 #include <ModuleBase_ViewerPrs.h>
15 #include <ModuleBase_IPropertyPanel.h>
16 #include <ModuleBase_ISelection.h>
17 #include <ModuleBase_IViewer.h>
19 #include <ModelAPI_Events.h>
21 #include <SketchPlugin_Feature.h>
22 #include <GeomDataAPI_Point2D.h>
24 #include <ModelAPI_Data.h>
25 #include <ModelAPI_Document.h>
26 #include <ModelAPI_Events.h>
28 #include <Events_Loop.h>
30 #include <SketchPlugin_Line.h>
32 #include <V3d_View.hxx>
33 #include <TopoDS_Vertex.hxx>
35 #include <BRep_Tool.hxx>
36 #include <AIS_DimensionOwner.hxx>
37 #include <AIS_DimensionSelectionMode.hxx>
43 #include <QMouseEvent>
47 PartSet_OperationFeatureEdit::PartSet_OperationFeatureEdit(const QString& theId,
49 CompositeFeaturePtr theFeature)
50 : PartSet_OperationFeatureBase(theId, theParent, theFeature),
51 myIsBlockedSelection(false)
56 PartSet_OperationFeatureEdit::~PartSet_OperationFeatureEdit()
60 void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelection,
61 ModuleBase_IViewer* theViewer)
63 PartSet_OperationFeatureBase::initSelection(theSelection, theViewer);
64 // 1. unite selected and hightlighted objects in order to have an opportunity to drag
65 // by the highlighted object
66 QList<ModuleBase_ViewerPrs> aFeatures = theSelection->getSelected();
67 QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
68 // add highlighted elements if they are not selected
69 foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
70 if (!PartSet_Tools::isContainPresentation(aFeatures, aPrs))
71 aFeatures.append(aPrs);
74 // 1. find all features with skipping features with selected vertex shapes
75 myFeature2Attribute.clear();
76 // firstly, collect the features without local selection
77 /*foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
78 const TopoDS_Shape& aShape = aPrs.shape();
79 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
80 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
81 if (!aVertex.IsNull()) {
86 ObjectPtr aObject = aPrs.object();
89 FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
90 if (aFeature && myFeature2Attribute.find(aFeature) == myFeature2Attribute.end()) {
91 std::list<std::string> aList;
92 // using an empty list as a sign, that this feature should be moved itself
93 myFeature2Attribute[aFeature] = aList;
97 // 2. collect the features with a local selection on them.
98 // if the list already has this feature, the local selection is skipped
99 // that means that if the selection contains a feature and a feature with local selected point,
100 // the edit is performed for a full feature
101 Handle(V3d_View) aView = theViewer->activeView();
102 foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
103 const TopoDS_Shape& aShape = aPrs.shape();
104 if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
105 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
106 if (aVertex.IsNull())
108 ObjectPtr aObject = aPrs.object();
111 FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
114 // if the feature is already moved, do nothing for this feature local selection
115 if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
118 // append the attribute of the vertex if it is found on the current feature
119 gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
121 PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aVX, aVY);
122 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = PartSet_Tools::getFeaturePoint(
124 std::string anAttribute = aFeature->data()->id(aPoint2D);
125 std::list<std::string> aList;
126 if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
127 aList = myFeature2Attribute[aFeature];
129 aList.push_back(anAttribute);
130 myFeature2Attribute[aFeature] = aList;
135 void PartSet_OperationFeatureEdit::mousePressed(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer, ModuleBase_ISelection* theSelection)
137 ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
138 if(aActiveWgt && aActiveWgt->isViewerSelector()) {
139 // Almost do nothing, all stuff in on PartSet_OperationFeatureBase::mouseReleased
140 PartSet_OperationFeatureBase::mousePressed(theEvent, theViewer, theSelection);
143 QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
144 QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
145 bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
146 if (aHasShift && !aHighlighted.empty()) {
147 foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
148 aSelected.append(aPrs);
152 if (!aSelected.empty()) {
153 aObject = aSelected.first().object();
155 if (!aHighlighted.empty())
156 aObject = aHighlighted.first().object();
158 //if (!theHighlighted.empty())
159 // aObject = theHighlighted.front().object();
160 //if (!aObject && !theSelected.empty()) // changed for a constrain
161 // aObject = theSelected.front().object();
163 FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
164 if (!aFeature || aFeature != feature() || (aSelected.size() > 1)) {
166 theViewer->enableSelection(true);
167 emit featureConstructed(feature(), FM_Deactivation);
169 // If we have selection and prehilighting with shift pressed
170 // Then we have to select all these objects and restart as multi edit operfation
171 //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
172 //if (aHasShift && !theHighlighted.empty()) {
173 // QList<ObjectPtr> aSelected;
174 // std::list<ModuleBase_ViewerPrs>::const_iterator aIt;
175 // for (aIt = theSelected.cbegin(); aIt != theSelected.cend(); ++aIt)
176 // aSelected.append((*aIt).object());
178 // for (aIt = theHighlighted.cbegin(); aIt != theHighlighted.cend(); ++aIt) {
179 // if (!aSelected.contains((*aIt).object()))
180 // aSelected.append((*aIt).object());
182 // emit setSelection(aSelected);
185 std::string anOperationType =
186 (aSelected.size() > 1) ?
187 PartSet_OperationFeatureEditMulti::Type() : PartSet_OperationFeatureEdit::Type();
188 restartOperation(anOperationType, aFeature);
195 void PartSet_OperationFeatureEdit::mouseMoved(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer)
197 if (!(theEvent->buttons() & Qt::LeftButton))
199 Handle(V3d_View) aView = theViewer->activeView();
200 gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView);
202 theViewer->enableSelection(false);
204 //blockSelection(true);
205 if (myCurPoint.myIsInitialized) {
207 PartSet_Tools::convertTo2D(myCurPoint.myPoint, sketch(), aView, aCurX, aCurY);
210 PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
212 double aDeltaX = aX - aCurX;
213 double aDeltaY = anY - aCurY;
215 boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
216 SketchPlugin_Feature>(feature());
218 bool isMoved = false;
219 // the functionality to move the feature attribute if it exists in the internal map
220 std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
221 while (aFeatIter != myFeature2Attribute.end()) {
222 FeaturePtr aFeature = aFeatIter->first;
223 std::list<std::string> anAttributes = aFeatIter->second;
224 // perform edit for the feature
225 /*if (anAttributes.empty()) {
226 boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
227 boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
228 if (aSketchFeature) {
229 aSketchFeature->move(aDeltaX, aDeltaY);
232 // perform edit for the feature's attribute
234 if (!anAttributes.empty()) {
235 std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
236 anAttrEnd = anAttributes.end();
237 for (; anAttrIter != anAttrEnd; anAttrIter++) {
238 boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr = boost::dynamic_pointer_cast<
239 GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter));
241 aPointAttr->move(aDeltaX, aDeltaY);
249 // the feature is moved only if there is no a local selection on this feature
251 // MPV: added condition because it could be external edge of some object, not sketch
252 if (aSketchFeature && aSketchFeature->sketch() == sketch().get()) {
253 aSketchFeature->move(aDeltaX, aDeltaY);
254 static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY);
255 ModelAPI_EventCreator::get()->sendUpdated(feature(), anEvent);
261 myCurPoint.setPoint(aPoint);
264 void PartSet_OperationFeatureEdit::mouseReleased(
265 QMouseEvent* theEvent, ModuleBase_IViewer* theViewer,
266 ModuleBase_ISelection* theSelection)
268 theViewer->enableSelection(true);
269 ModuleBase_ModelWidget* aActiveWgt = 0;
271 aActiveWgt = myPropertyPanel->activeWidget();
272 if(aActiveWgt && aActiveWgt->isViewerSelector()) {
273 // Almost do nothing, all stuff in on PartSet_OperationFeatureBase::mouseReleased
274 PartSet_OperationFeatureBase::mouseReleased(theEvent, theViewer, theSelection);
276 //blockSelection(false);
280 void PartSet_OperationFeatureEdit::mouseDoubleClick(
281 QMouseEvent* theEvent, Handle_V3d_View theView,
282 ModuleBase_ISelection* theSelection)
284 // TODO the functionality is important only for constraint feature. Should be moved in another place
285 QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
286 if (!aSelected.empty()) {
287 ModuleBase_ViewerPrs aFeaturePrs = aSelected.first();
288 if (!aFeaturePrs.owner().IsNull()) {
289 Handle(AIS_DimensionOwner) anOwner = Handle(AIS_DimensionOwner)::DownCast(
290 aFeaturePrs.owner());
291 if (!anOwner.IsNull() && anOwner->SelectionMode() == AIS_DSM_Text) {
293 double aValue = PartSet_Tools::featureValue(feature(), SketchPlugin_Constraint::VALUE(),
296 ModuleBase_WidgetEditor::editFeatureValue(feature(), SketchPlugin_Constraint::VALUE());
304 void PartSet_OperationFeatureEdit::startOperation()
306 PartSet_OperationSketchBase::startOperation();
307 //emit multiSelectionEnabled(false);
312 void PartSet_OperationFeatureEdit::stopOperation()
314 //emit multiSelectionEnabled(true);
316 //blockSelection(false, false);
319 //void PartSet_OperationFeatureEdit::blockSelection(bool isBlocked, const bool isRestoreSelection)
321 // if (myIsBlockedSelection == isBlocked)
324 // myIsBlockedSelection = isBlocked;
325 // QList<ObjectPtr> aFeatureList;
326 // aFeatureList.append(feature());
328 // //if (isBlocked) {
329 // // emit setSelection(QList<ObjectPtr>());
330 // // emit stopSelection(aFeatureList, true);
332 // // emit stopSelection(aFeatureList, false);
333 // // if (isRestoreSelection)
334 // // emit setSelection(aFeatureList);
338 FeaturePtr PartSet_OperationFeatureEdit::createFeature(const bool theFlushMessage,
339 CompositeFeaturePtr theCompositeFeature)
341 // do nothing in order to do not create a new feature
345 void PartSet_OperationFeatureEdit::sendFeatures()
347 static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
349 FeaturePtr aFeature = feature();
350 ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
352 Events_Loop::loop()->flush(anEvent);