#include <SketchPlugin_Line.h>
#include <V3d_View.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
#include <QMouseEvent>
#ifdef _DEBUG
}
-void PartSet_OperationFeatureEditMulti::initSelection(ModuleBase_ISelection* theSelection)
+void PartSet_OperationFeatureEditMulti::initSelection(ModuleBase_ISelection* theSelection,
+ ModuleBase_IViewer* theViewer)
{
- //if (!theHighlighted.empty()) {
- // // if there is highlighted object, we check whether it is in the list of selected objects
- // // in that case this object is a handle of the moved lines. If there no such object in the selection,
- // // the hightlighted object should moved and the selection is skipped. The skipped selection will be
- // // deselected in the viewer by blockSelection signal in the startOperation method.
- // bool isSelected = false;
- // std::list<ModuleBase_ViewerPrs>::const_iterator anIt = theSelected.begin(),
- // aLast = theSelected.end();
- // for (; anIt != aLast && !isSelected; anIt++) {
- // isSelected = ModelAPI_Feature::feature((*anIt).object()) == feature();
- // }
- // if (!isSelected)
- // myFeatures = theHighlighted;
- // else
- // myFeatures = theSelected;
- //} else
- myFeatures = theSelection->getSelected();
+ QList<ModuleBase_ViewerPrs> aFeatures;
+ aFeatures = theSelection->getSelected();
QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
// add highlighted elements if they are not selected
foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
- if (!isContains(myFeatures, aPrs))
- myFeatures.append(aPrs);
+ if (!isContains(aFeatures, aPrs))
+ aFeatures.append(aPrs);
}
- // Remove current feature if it is in the list (it will be moved as main feature)
- foreach (ModuleBase_ViewerPrs aPrs, myFeatures) {
- FeaturePtr aF = ModelAPI_Feature::feature(aPrs.object());
- if (ModelAPI_Feature::feature(aPrs.object()) == feature()) {
- myFeatures.removeOne(aPrs);
- break;
+
+ // firstly iterate the operation presentations and move all features
+ // if there is no selected vertex shape for it. Create a set of moved features
+ myFeature2Attribute.clear();
+ // firstly, collect the features without local selection
+ std::set<FeaturePtr> aMovedFeatures;
+ foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
+ const TopoDS_Shape& aShape = aPrs.shape();
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
+ if (!aVertex.IsNull()) {
+ continue;
+ }
+ }
+ else {
+ ObjectPtr aObject = aPrs.object();
+ if (!aObject)
+ continue;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
+ if (aFeature && myFeature2Attribute.find(aFeature) == myFeature2Attribute.end()) {
+ std::list<std::string> aList;
+ myFeature2Attribute[aFeature] = aList;
+ }
+ }
+ }
+ // secondly, collect the features with a local selection on them
+ // if the list already has this feature, the local selection is skipped
+ Handle(V3d_View) aView = theViewer->activeView();
+ foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
+ const TopoDS_Shape& aShape = aPrs.shape();
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
+ if (aVertex.IsNull())
+ continue;
+ ObjectPtr aObject = aPrs.object();
+ if (!aObject)
+ continue;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
+ if (!aFeature)
+ continue;
+ // if the feature is already moved, do nothing for this feature local selection
+
+ if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
+ continue;
+
+ gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
+ double aVX, aVY;
+ PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aVX, aVY);
+
+ boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = PartSet_Tools::getFeaturePoint(
+ aFeature, aVX, aVY);
+ std::string anAttribute = aFeature->data()->id(aPoint2D);
+ std::list<std::string> aList;
+ if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
+ aList = myFeature2Attribute[aFeature];
+
+ aList.push_back(anAttribute);
+ myFeature2Attribute[aFeature] = aList;
}
}
}
double aDeltaX = aX - aCurX;
double aDeltaY = anY - aCurY;
- boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
- SketchPlugin_Feature>(feature());
- aSketchFeature->move(aDeltaX, aDeltaY);
-
- foreach (ModuleBase_ViewerPrs aPrs, myFeatures) {
- ObjectPtr aObject = aPrs.object();
- if (!aObject || aObject == feature())
- continue;
- FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
- if (aFeature) {
- aSketchFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- if (aSketchFeature)
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+ while (aFeatIter != myFeature2Attribute.end()) {
+ FeaturePtr aFeature = aFeatIter->first;
+ std::list<std::string> anAttributes = aFeatIter->second;
+ if (anAttributes.empty()) {
+ boost::shared_ptr<SketchPlugin_Feature> aSketchFeature =
+ boost::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
+ if (aSketchFeature) {
aSketchFeature->move(aDeltaX, aDeltaY);
+ }
+ }
+ else {
+ std::list<std::string>::const_iterator anAttrIter = anAttributes.begin(),
+ anAttrEnd = anAttributes.end();
+ for (; anAttrIter != anAttrEnd; anAttrIter++) {
+ boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr = boost::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(aFeature->data()->attribute(*anAttrIter));
+ if (aPointAttr) {
+ aPointAttr->move(aDeltaX, aDeltaY);
+ }
+ }
}
+ aFeatIter++;
}
}
sendFeatures();
{
theViewer->enableSelection(true);
if (commit()) {
- foreach (ModuleBase_ViewerPrs aPrs, myFeatures) {
- ObjectPtr aFeature = aPrs.object();
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+ while (aFeatIter != myFeature2Attribute.end()) {
+ FeaturePtr aFeature = aFeatIter->first;
if (aFeature) {
emit featureConstructed(aFeature, FM_Deactivation);
}
+ aFeatIter++;
}
}
}
//blockSelection(false, true);
- myFeatures.clear();
+ myFeature2Attribute.clear();
}
//void PartSet_OperationFeatureEditMulti::blockSelection(bool isBlocked,
{
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
- foreach (ModuleBase_ViewerPrs aPrs, myFeatures) {
- ObjectPtr aFeature = aPrs.object();
- if (!aFeature)
- continue;
-
- ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
+ while (aFeatIter != myFeature2Attribute.end()) {
+ FeaturePtr aFeature = aFeatIter->first;
+ if (aFeature) {
+ ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
+ }
+ aFeatIter++;
}
+
Events_Loop::loop()->flush(anEvent);
flushUpdated();
}
return ModelAPI_Session::get()->moduleDocument();
}
-void PartSet_Tools::setFeaturePoint(FeaturePtr theFeature, double theX, double theY,
- const std::string& theAttribute)
+boost::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::getFeaturePoint(FeaturePtr theFeature,
+ double theX, double theY)
{
- if (!theFeature)
- return;
- boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(theAttribute));
- if (aPoint)
- aPoint->setValue(theX, theY);
+ boost::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = boost::shared_ptr<GeomAPI_Pnt2d>(
+ new GeomAPI_Pnt2d(theX, theY));
+ std::list<boost::shared_ptr<ModelAPI_Attribute> > anAttiributes =
+ theFeature->data()->attributes(GeomDataAPI_Point2D::type());
+ std::list<boost::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
+ aLast = anAttiributes.end();
+ boost::shared_ptr<GeomDataAPI_Point2D> aFPoint;
+ for (; anIt != aLast && !aFPoint; anIt++) {
+ boost::shared_ptr<GeomDataAPI_Point2D> aCurPoint = boost::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(*anIt);
+ if (aCurPoint && aCurPoint->pnt()->distance(aClickedPoint) < Precision::Confusion())
+ aFPoint = aCurPoint;
+ }
+
+ return aFPoint;
}
void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue,