X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_OperationSketchLine.cpp;h=ddd9bd7281857bdf1ab1d34ac2ebc7adb9e60068;hb=9dbc7bb239ec73b8af08652a2560e53bc211f2a4;hp=25bc7667366bf59dfe07ccc3fb285caee2ac82c3;hpb=950f8c3ca4de26c84757fe06698d8ea5a527757a;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_OperationSketchLine.cpp b/src/PartSet/PartSet_OperationSketchLine.cpp index 25bc76673..ddd9bd728 100644 --- a/src/PartSet/PartSet_OperationSketchLine.cpp +++ b/src/PartSet/PartSet_OperationSketchLine.cpp @@ -5,18 +5,41 @@ #include #include +#include #include +#include + #include + +#include + #include #include +#include +#include + +#include + +#include +#include + +#include +#include #include +#include +#include +#include +#include + #ifdef _DEBUG #include #endif +#include + using namespace std; PartSet_OperationSketchLine::PartSet_OperationSketchLine(const QString& theId, @@ -31,90 +54,185 @@ PartSet_OperationSketchLine::~PartSet_OperationSketchLine() { } -bool PartSet_OperationSketchLine::isGranted() const +bool PartSet_OperationSketchLine::isGranted(ModuleBase_IOperation* theOperation) const { - return true; + return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type(); } std::list PartSet_OperationSketchLine::getSelectionModes(boost::shared_ptr theFeature) const { std::list aModes; - if (theFeature != feature()) { - aModes.push_back(TopAbs_VERTEX); - aModes.push_back(TopAbs_EDGE); - } + if (theFeature != feature()) + aModes = PartSet_OperationSketchBase::getSelectionModes(theFeature); return aModes; } -void PartSet_OperationSketchLine::mouseReleased(const gp_Pnt& thePoint, QMouseEvent* /*theEvent*/) +void PartSet_OperationSketchLine::init(boost::shared_ptr theFeature, + const std::list& /*theSelected*/, + const std::list& /*theHighlighted*/) +{ + if (!theFeature || theFeature->getKind() != "SketchLine") + return; + // use the last point of the previous feature as the first of the new one + boost::shared_ptr aData = theFeature->data(); + myInitPoint = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); +} + +boost::shared_ptr PartSet_OperationSketchLine::sketch() const { + return mySketch; +} + +void PartSet_OperationSketchLine::mouseReleased(QMouseEvent* theEvent, Handle(V3d_View) theView, + const std::list& theSelected, + const std::list& /*theHighlighted*/) +{ + double aX, anY; + + bool isFoundPoint = false; + gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView); + if (theSelected.empty()) { + PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY); + isFoundPoint = true; + } + else { + XGUI_ViewerPrs aPrs = theSelected.front(); + const TopoDS_Shape& aShape = aPrs.shape(); + if (!aShape.IsNull()) // the point is selected + { + if (aShape.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape); + if (!aVertex.IsNull()) { + aPoint = BRep_Tool::Pnt(aVertex); + PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY); + isFoundPoint = true; + + setConstraints(aX, anY); + } + } + else if (aShape.ShapeType() == TopAbs_EDGE) // the line is selected + { + boost::shared_ptr aFeature = aPrs.feature(); + if (aFeature) { + double X0, X1, X2, X3; + double Y0, Y1, Y2, Y3; + getLinePoint(aFeature, LINE_ATTR_START, X2, Y2); + getLinePoint(aFeature, LINE_ATTR_END, X3, Y3); + PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, X1, Y1); + + switch (myPointSelectionMode) { + case SM_FirstPoint: + PartSet_Tools::ProjectPointOnLine(X2, Y2, X3, Y3, X1, Y1, aX, anY); + break; + case SM_SecondPoint: { + getLinePoint(feature(), LINE_ATTR_START, X0, Y0); + PartSet_Tools::IntersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, aX, anY); + } + break; + default: + break; + } + isFoundPoint = true; + } + } + } + } + //if (!isFoundPoint) + // return; + switch (myPointSelectionMode) { case SM_FirstPoint: { - setLinePoint(thePoint, LINE_ATTR_START); - myPointSelectionMode = SM_SecondPoint; + setLinePoint(feature(), aX, anY, LINE_ATTR_START); + setLinePoint(feature(), aX, anY, LINE_ATTR_END); + flushUpdated(); + + setPointSelectionMode(SM_SecondPoint); } break; case SM_SecondPoint: { - setLinePoint(thePoint, LINE_ATTR_END); - myPointSelectionMode = SM_None; - } - break; - case SM_None: { - } + setLinePoint(feature(), aX, anY, LINE_ATTR_END); + flushUpdated(); + + setPointSelectionMode(SM_DonePoint); + } break; default: break; } } -void PartSet_OperationSketchLine::mouseMoved(const gp_Pnt& thePoint, QMouseEvent* /*theEvent*/) +void PartSet_OperationSketchLine::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) { switch (myPointSelectionMode) { + case SM_FirstPoint: { + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView); + PartSet_Tools::ConvertTo2D(aPoint, sketch(), theView, aX, anY); + setLinePoint(feature(), aX, anY, LINE_ATTR_START); + setLinePoint(feature(), aX, anY, LINE_ATTR_END); + flushUpdated(); + emit focusActivated(LINE_ATTR_START); + } + break; case SM_SecondPoint: - setLinePoint(thePoint, LINE_ATTR_END); - break; - case SM_None: { - boost::shared_ptr aPrevFeature = feature(); - // stop the last operation - commitOperation(); - document()->finishOperation(); - //emit changeSelectionMode(aPrevFeature, TopAbs_VERTEX); - // start a new operation - document()->startOperation(); - startOperation(); - // use the last point of the previous feature as the first of the new one - setLinePoint(aPrevFeature, LINE_ATTR_END, LINE_ATTR_START); - myPointSelectionMode = SM_SecondPoint; - - emit featureConstructed(aPrevFeature, FM_Deactivation); + { + gp_Pnt aPoint = PartSet_Tools::ConvertClickToPoint(theEvent->pos(), theView); + setLinePoint(aPoint, theView, LINE_ATTR_END); + flushUpdated(); + emit focusActivated(LINE_ATTR_END); } break; + case SM_DonePoint: + { + commit(); + emit featureConstructed(feature(), FM_Deactivation); + emit launchOperation(PartSet_OperationSketchLine::Type(), feature()); + } default: break; } } +void PartSet_OperationSketchLine::keyReleased(std::string theName, QKeyEvent* theEvent) +{ + int aKeyType = theEvent->key(); + if (!theName.empty() && aKeyType == Qt::Key_Return) { + if (theName == LINE_ATTR_START) { + setPointSelectionMode(SM_SecondPoint, false); + } + else if (theName == LINE_ATTR_END) { + setPointSelectionMode(SM_DonePoint, false); + } + } + keyReleased(theEvent->key()); +} + void PartSet_OperationSketchLine::keyReleased(const int theKey) { switch (theKey) { - case Qt::Key_Escape: { - if (myPointSelectionMode != SM_None) - emit featureConstructed(feature(), FM_Abort); - abort(); + case Qt::Key_Return: { + if (myPointSelectionMode == SM_DonePoint) + { + commit(); + emit featureConstructed(feature(), FM_Deactivation); + emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr()); + } + //else + // abort(); + //emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr()); } break; - case Qt::Key_Return: { - if (myPointSelectionMode != SM_None) { - emit featureConstructed(feature(), FM_Abort); - myPointSelectionMode = SM_FirstPoint; - document()->abortOperation(); + case Qt::Key_Escape: { + if (myPointSelectionMode == SM_DonePoint) + { + commit(); + emit featureConstructed(feature(), FM_Deactivation); } else - myPointSelectionMode = SM_FirstPoint; + abort(); } - break; default: break; } @@ -123,51 +241,182 @@ void PartSet_OperationSketchLine::keyReleased(const int theKey) void PartSet_OperationSketchLine::startOperation() { PartSet_OperationSketchBase::startOperation(); - myPointSelectionMode = SM_FirstPoint; + setPointSelectionMode(!myInitPoint ? SM_FirstPoint : SM_SecondPoint); + + emit multiSelectionEnabled(false); +} + +void PartSet_OperationSketchLine::abortOperation() +{ + emit featureConstructed(feature(), FM_Hide); + PartSet_OperationSketchBase::abortOperation(); } void PartSet_OperationSketchLine::stopOperation() { PartSet_OperationSketchBase::stopOperation(); - myPointSelectionMode = SM_None; + emit multiSelectionEnabled(true); } -boost::shared_ptr PartSet_OperationSketchLine::createFeature() +boost::shared_ptr PartSet_OperationSketchLine::createFeature(const bool theFlushMessage) { - boost::shared_ptr aNewFeature = ModuleBase_Operation::createFeature(); - if (mySketch) { + boost::shared_ptr aNewFeature = ModuleBase_Operation::createFeature(false); + if (sketch()) { boost::shared_ptr aFeature = - boost::dynamic_pointer_cast(mySketch); + boost::dynamic_pointer_cast(sketch()); aFeature->addSub(aNewFeature); } + if (myInitPoint) { + setLinePoint(aNewFeature, myInitPoint->x(), myInitPoint->y(), LINE_ATTR_START); + setLinePoint(aNewFeature, myInitPoint->x(), myInitPoint->y(), LINE_ATTR_END); + + boost::shared_ptr aData = aNewFeature->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(LINE_ATTR_START)); + createConstraint(myInitPoint, aPoint); + } + emit featureConstructed(aNewFeature, FM_Activation); + if (theFlushMessage) + flushCreated(); return aNewFeature; } -void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint, - const std::string& theAttribute) +void PartSet_OperationSketchLine::createConstraint(boost::shared_ptr thePoint1, + boost::shared_ptr thePoint2) +{ + boost::shared_ptr aDoc = document(); + boost::shared_ptr aFeature = aDoc->addFeature("SketchConstraintCoincidence"); + + if (sketch()) { + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(sketch()); + aSketch->addSub(aFeature); + } + + boost::shared_ptr aData = aFeature->data(); + + boost::shared_ptr aRef1 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); + aRef1->setAttr(thePoint1); + + boost::shared_ptr aRef2 = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_B)); + aRef2->setAttr(thePoint2); + + if (aFeature) // TODO: generate an error if feature was not created + aFeature->execute(); +} + +void PartSet_OperationSketchLine::setConstraints(double theX, double theY) { + std::string aPointArg; + switch (myPointSelectionMode) + { + case SM_FirstPoint: + aPointArg = LINE_ATTR_START; + break; + case SM_SecondPoint: + aPointArg = LINE_ATTR_END; + break; + } + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aPoint = boost::dynamic_pointer_cast + (aData->attribute(aPointArg)); + aData = sketch()->data(); + boost::shared_ptr aRefList = + boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_FEATURES)); + + std::list > aFeatures = aRefList->list(); + std::list >::const_iterator anIt = aFeatures.begin(), + aLast = aFeatures.end(); + for (; anIt != aLast; anIt++) { + boost::shared_ptr aFeature = *anIt; + boost::shared_ptr aFPoint = findLinePoint(aFeature, theX, theY); + if (aFPoint) + createConstraint(aFPoint, aPoint); + } +} + +void PartSet_OperationSketchLine::getLinePoint(boost::shared_ptr theFeature, + const std::string& theAttribute, + double& theX, double& theY) +{ + if (!theFeature || theFeature->getKind() != "SketchLine") + return; + boost::shared_ptr aData = theFeature->data(); boost::shared_ptr aPoint = boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + theX = aPoint->x(); + theY = aPoint->y(); +} - double aX, anY; - PartSet_Tools::ConvertTo2D(thePoint, mySketch, aX, anY); - aPoint->setValue(aX, anY); +boost::shared_ptr PartSet_OperationSketchLine::findLinePoint( + boost::shared_ptr theFeature, + double theX, double theY) +{ + boost::shared_ptr aPoint2D; + if (!theFeature || theFeature->getKind() != "SketchLine") + return aPoint2D; + boost::shared_ptr aData = theFeature->data(); + + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_START)); + if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) + aPoint2D = aPoint; + else { + aPoint = boost::dynamic_pointer_cast(aData->attribute(LINE_ATTR_END)); + if (fabs(aPoint->x() - theX) < Precision::Confusion() && fabs(aPoint->y() - theY) < Precision::Confusion() ) + aPoint2D = aPoint; + } + return aPoint2D; } -void PartSet_OperationSketchLine::setLinePoint(boost::shared_ptr theSourceFeature, - const std::string& theSourceAttribute, +void PartSet_OperationSketchLine::setLinePoint(boost::shared_ptr theFeature, + double theX, double theY, const std::string& theAttribute) { - boost::shared_ptr aData = theSourceFeature->data(); + if (!theFeature) + return; + boost::shared_ptr aData = theFeature->data(); boost::shared_ptr aPoint = - boost::dynamic_pointer_cast(aData->attribute(theSourceAttribute)); - double aX = aPoint->x(); - double anY = aPoint->y(); + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); + aPoint->setValue(theX, theY); +} - aData = feature()->data(); - aPoint = boost::dynamic_pointer_cast(aData->attribute(theAttribute)); +void PartSet_OperationSketchLine::setLinePoint(const gp_Pnt& thePoint, + Handle(V3d_View) theView, + const std::string& theAttribute) +{ + double aX, anY; + PartSet_Tools::ConvertTo2D(thePoint, sketch(), theView, aX, anY); + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aPoint = + boost::dynamic_pointer_cast(aData->attribute(theAttribute)); aPoint->setValue(aX, anY); } + +void PartSet_OperationSketchLine::setPointSelectionMode(const PointSelectionMode& theMode, + const bool isToEmitSignal) +{ + myPointSelectionMode = theMode; + if (isToEmitSignal) { + std::string aName; + switch (theMode) { + case SM_FirstPoint: + aName = LINE_ATTR_START; + break; + case SM_SecondPoint: + aName = LINE_ATTR_END; + break; + case SM_DonePoint: + aName = XGUI::PROP_PANEL_OK; + break; + default: + break; + } + emit focusActivated(aName); + } +}