From 6a74c9552a6deed91fa0f00eb4d1996d788b6bd3 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 17 Jun 2014 21:06:58 +0400 Subject: [PATCH 1/1] refs #80 - Sketch base GUI: create/draw point, circle and arc 1. The cross product for a line to find the constraint direction relatively to the source line feature --- src/GeomAPI/GeomAPI_Lin2d.cpp | 8 ++++ src/GeomAPI/GeomAPI_Lin2d.h | 2 + src/ModelAPI/ModelAPI_AttributeDouble.h | 3 ++ .../ModuleBase_WidgetDoubleValue.cpp | 4 +- src/PartSet/PartSet_FeatureLengthPrs.cpp | 41 ++++++++++++---- src/PartSet/PartSet_FeatureLinePrs.cpp | 25 +++++++--- src/PartSet/PartSet_FeatureLinePrs.h | 20 ++++---- src/PartSet/PartSet_OperationConstraint.cpp | 2 +- .../PartSet_OperationCreateConstraint.cpp | 47 ++++++++++++++----- src/PartSet/PartSet_OperationSketch.cpp | 2 +- src/PartSet/PartSet_Presentation.cpp | 7 +++ src/PartSet/PartSet_Tools.cpp | 4 +- src/SketchPlugin/SketchPlugin_Circle.cpp | 2 +- .../SketchSolver_ConstraintGroup.cpp | 6 +-- 14 files changed, 127 insertions(+), 46 deletions(-) diff --git a/src/GeomAPI/GeomAPI_Lin2d.cpp b/src/GeomAPI/GeomAPI_Lin2d.cpp index 8eb102ae5..1299c7503 100644 --- a/src/GeomAPI/GeomAPI_Lin2d.cpp +++ b/src/GeomAPI/GeomAPI_Lin2d.cpp @@ -60,3 +60,11 @@ const boost::shared_ptr GeomAPI_Lin2d::project(const boost::share return boost::shared_ptr(new GeomAPI_Pnt2d(aResult.X(), aResult.Y())); } +double GeomAPI_Lin2d::crossed(const boost::shared_ptr& thePoint) const +{ + const gp_XY& aDir = MY_LIN2D->Direction().XY(); + const gp_XY& aLoc = MY_LIN2D->Location().XY(); + const gp_XY& aPnt = thePoint->impl().XY(); + + return aDir.Crossed(aPnt - aLoc); +} diff --git a/src/GeomAPI/GeomAPI_Lin2d.h b/src/GeomAPI/GeomAPI_Lin2d.h index 32f55d3ed..2344648ea 100644 --- a/src/GeomAPI/GeomAPI_Lin2d.h +++ b/src/GeomAPI/GeomAPI_Lin2d.h @@ -31,6 +31,8 @@ public: const boost::shared_ptr intersect(const boost::shared_ptr& theLine) const; /// Project point on line const boost::shared_ptr project(const boost::shared_ptr& thePoint) const; + /// Computes the cross product of the line direction and a vector from the line start point to the point + double crossed(const boost::shared_ptr& thePoint) const; }; #endif diff --git a/src/ModelAPI/ModelAPI_AttributeDouble.h b/src/ModelAPI/ModelAPI_AttributeDouble.h index 81bdb6690..837757309 100644 --- a/src/ModelAPI/ModelAPI_AttributeDouble.h +++ b/src/ModelAPI/ModelAPI_AttributeDouble.h @@ -36,4 +36,7 @@ protected: {} }; +//! Pointer on double attribute +typedef boost::shared_ptr AttributeDoublePtr; + #endif diff --git a/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp b/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp index 9c02822e8..b17b98f11 100644 --- a/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp +++ b/src/ModuleBase/ModuleBase_WidgetDoubleValue.cpp @@ -89,7 +89,7 @@ ModuleBase_WidgetDoubleValue::~ModuleBase_WidgetDoubleValue() bool ModuleBase_WidgetDoubleValue::storeValue(FeaturePtr theFeature) const { DataPtr aData = theFeature->data(); - boost::shared_ptr aReal = aData->real(attributeID()); + AttributeDoublePtr aReal = aData->real(attributeID()); if (aReal->value() != mySpinBox->value()) { aReal->setValue(mySpinBox->value()); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED)); @@ -100,7 +100,7 @@ bool ModuleBase_WidgetDoubleValue::storeValue(FeaturePtr theFeature) const bool ModuleBase_WidgetDoubleValue::restoreValue(FeaturePtr theFeature) { DataPtr aData = theFeature->data(); - boost::shared_ptr aRef = aData->real(attributeID()); + AttributeDoublePtr aRef = aData->real(attributeID()); bool isBlocked = mySpinBox->blockSignals(true); mySpinBox->setValue(aRef->value()); diff --git a/src/PartSet/PartSet_FeatureLengthPrs.cpp b/src/PartSet/PartSet_FeatureLengthPrs.cpp index 944e7c51e..c8390f991 100644 --- a/src/PartSet/PartSet_FeatureLengthPrs.cpp +++ b/src/PartSet/PartSet_FeatureLengthPrs.cpp @@ -5,6 +5,8 @@ #include #include +#include + #include #include #include @@ -12,11 +14,13 @@ #include #include +#include #include #include #include #include +#include #include @@ -44,15 +48,34 @@ PartSet_SelectionMode PartSet_FeatureLengthPrs::setPoint(double theX, double the } break; case SM_SecondPoint: { - /*boost::shared_ptr aData = feature()->data(); - boost::shared_ptr aPoint = boost::dynamic_pointer_cast - (aData->attribute(CIRCLE_ATTR_CENTER)); - boost::shared_ptr aCoordPoint(new GeomAPI_Pnt2d(theX, theY)); - double aRadius = aCoordPoint->distance(aPoint->pnt()); - PartSet_Tools::setFeatureValue(feature(), aRadius, CIRCLE_ATTR_RADIUS); - - aMode = SM_DonePoint;*/ - } + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr anAttr = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_ENTITY_A)); + FeaturePtr aFeature; + if (anAttr) { + aFeature = anAttr->feature(); + if (aFeature->getKind() != SKETCH_LINE_KIND) { + aFeature = FeaturePtr(); + } + } + boost::shared_ptr aPoint = boost::shared_ptr + (new GeomAPI_Pnt2d(theX, theY)); + boost::shared_ptr aFeatureLin = PartSet_FeatureLinePrs::createLin2d(aFeature); + boost::shared_ptr aResult = aFeatureLin->project(aPoint); + double aDistance = aPoint->distance(aResult); + + double aStartX, aStartY; + PartSet_FeatureLinePrs::getLinePoint(aFeature, LINE_ATTR_START, aStartX, aStartY); + + if (aFeatureLin->crossed(aPoint) < 0) + aDistance = -aDistance; + + AttributeDoublePtr aFlyoutAttr = + boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE)); + aFlyoutAttr->setValue(aDistance); + + aMode = SM_DonePoint; + } break; default: break; diff --git a/src/PartSet/PartSet_FeatureLinePrs.cpp b/src/PartSet/PartSet_FeatureLinePrs.cpp index ae85a3d88..bc7e2d144 100644 --- a/src/PartSet/PartSet_FeatureLinePrs.cpp +++ b/src/PartSet/PartSet_FeatureLinePrs.cpp @@ -125,15 +125,13 @@ void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature, double& theX, double& theY) { if (theFeature && theFeature->getKind() == getKind()) { - double X0, X1, X2, X3; - double Y0, Y1, Y2, Y3; - getLinePoint(theFeature, LINE_ATTR_START, X2, Y2); - getLinePoint(theFeature, LINE_ATTR_END, X3, Y3); + double X0, X1; + double Y0, Y1; PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1); boost::shared_ptr aPoint = boost::shared_ptr(new GeomAPI_Pnt2d(X1, Y1)); - boost::shared_ptr aFeatureLin = boost::shared_ptr - (new GeomAPI_Lin2d(X2, Y2, X3, Y3)); + boost::shared_ptr aFeatureLin = PartSet_FeatureLinePrs::createLin2d(theFeature); + switch (theMode) { case SM_FirstPoint: { boost::shared_ptr aResult = aFeatureLin->project(aPoint); @@ -211,6 +209,21 @@ boost::shared_ptr PartSet_FeatureLinePrs::findPoint(Feature return aPoint2D; } +boost::shared_ptr PartSet_FeatureLinePrs::createLin2d(FeaturePtr theFeature) +{ + boost::shared_ptr aFeatureLin; + if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind()) + return aFeatureLin; + + double aStartX, aStartY, anEndX, anEndY; + getLinePoint(theFeature, LINE_ATTR_START, aStartX, aStartY); + getLinePoint(theFeature, LINE_ATTR_END, anEndX, anEndY); + + aFeatureLin = boost::shared_ptr + (new GeomAPI_Lin2d(aStartX, aStartY, anEndX, anEndY)); + return aFeatureLin; +} + boost::shared_ptr PartSet_FeatureLinePrs::featurePoint (const PartSet_SelectionMode& theMode) { diff --git a/src/PartSet/PartSet_FeatureLinePrs.h b/src/PartSet/PartSet_FeatureLinePrs.h index 08ccc3837..0f6fb051f 100644 --- a/src/PartSet/PartSet_FeatureLinePrs.h +++ b/src/PartSet/PartSet_FeatureLinePrs.h @@ -13,6 +13,7 @@ #include class GeomDataAPI_Point2D; +class GeomAPI_Lin2d; class Handle_V3d_View; /*! @@ -80,6 +81,17 @@ public: virtual boost::shared_ptr findPoint(FeaturePtr theFeature, double theX, double theY); + /// Creates a lin 2d object on a base of the line feature + /// \param theFeature the line feature + static boost::shared_ptr createLin2d(FeaturePtr theFeature); + /// \brief Get the line point 2d coordinates. + /// \param theFeature the line feature + /// \param theAttribute the start or end attribute of the line + /// \param theX the horizontal coordinate + /// \param theY the vertical coordinate + static void getLinePoint(FeaturePtr theFeature, const std::string& theAttribute, + double& theX, double& theY); + protected: /// Initializes current feature by the given /// \param theSourceFeature the feature, which attributes are used to initialize the current feature @@ -88,14 +100,6 @@ protected: /// Returns the feature point in the selection mode position. /// \param theMode the current operation selection mode. The feature attribute depends on the mode virtual boost::shared_ptr featurePoint(const PartSet_SelectionMode& theMode); - - /// \brief Get the line point 2d coordinates. - /// \param theFeature the line feature - /// \param theAttribute the start or end attribute of the line - /// \param theX the horizontal coordinate - /// \param theY the vertical coordinate - static void getLinePoint(FeaturePtr theFeature, const std::string& theAttribute, - double& theX, double& theY); }; #endif diff --git a/src/PartSet/PartSet_OperationConstraint.cpp b/src/PartSet/PartSet_OperationConstraint.cpp index 3a96b309a..e810cf390 100644 --- a/src/PartSet/PartSet_OperationConstraint.cpp +++ b/src/PartSet/PartSet_OperationConstraint.cpp @@ -162,7 +162,7 @@ void PartSet_OperationConstraint::setValue(const double theValue) { boost::shared_ptr aData = feature()->data(); - boost::shared_ptr anAttr = + AttributeDoublePtr anAttr = boost::dynamic_pointer_cast(aData->attribute(CONSTRAINT_ATTR_VALUE)); anAttr->setValue(theValue); diff --git a/src/PartSet/PartSet_OperationCreateConstraint.cpp b/src/PartSet/PartSet_OperationCreateConstraint.cpp index a648c82a0..78d0fe251 100644 --- a/src/PartSet/PartSet_OperationCreateConstraint.cpp +++ b/src/PartSet/PartSet_OperationCreateConstraint.cpp @@ -53,8 +53,8 @@ PartSet_OperationCreateConstraint::~PartSet_OperationCreateConstraint() bool PartSet_OperationCreateConstraint::canProcessKind(const std::string& theId) { - return /*theId == SKETCH_LINE_KIND || theId == SKETCH_POINT_KIND || theId == SKETCH_CIRCLE_KIND || - theId == SKETCH_ARC_KIND || */theId == SKETCH_CONSTRAINT_LENGTH_KIND; + // changed + return theId == SKETCH_CONSTRAINT_LENGTH_KIND; } bool PartSet_OperationCreateConstraint::canBeCommitted() const @@ -79,7 +79,8 @@ void PartSet_OperationCreateConstraint::init(FeaturePtr theFeature, const std::list& /*theSelected*/, const std::list& /*theHighlighted*/) { - if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND) + // changed + if (!theFeature/* || theFeature->getKind() != SKETCH_LINE_KIND*/) return; myInitFeature = theFeature; } @@ -93,25 +94,45 @@ void PartSet_OperationCreateConstraint::mouseReleased(QMouseEvent* theEvent, Han const std::list& theSelected, const std::list& /*theHighlighted*/) { - if (theSelected.empty()) { - - } - else { - XGUI_ViewerPrs aPrs = theSelected.front(); - FeaturePtr aFeature = aPrs.feature(); + switch (myPointSelectionMode) + { + case SM_FirstPoint: { + if (!theSelected.empty()) { + XGUI_ViewerPrs aPrs = theSelected.front(); + FeaturePtr aFeature = aPrs.feature(); + + myFeaturePrs->init(feature(), aFeature); + flushUpdated(); + setPointSelectionMode(SM_SecondPoint); + } + } + break; + case SM_SecondPoint: { + double aX, anY; + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); + PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); - myFeaturePrs->init(feature(), aFeature); - flushUpdated(); + PartSet_SelectionMode aMode = myFeaturePrs->setPoint(aX, anY, myPointSelectionMode); + flushUpdated(); + // show value edit dialog + //setPointSelectionMode(aMode); + commit(); + restartOperation(feature()->getKind(), FeaturePtr()); + } + break; + default: + break; } } void PartSet_OperationCreateConstraint::mouseMoved(QMouseEvent* theEvent, Handle(V3d_View) theView) { + // changed switch (myPointSelectionMode) { - case SM_FirstPoint: + //case SM_FirstPoint: case SM_SecondPoint: - case SM_ThirdPoint: + //case SM_ThirdPoint: { double aX, anY; gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); diff --git a/src/PartSet/PartSet_OperationSketch.cpp b/src/PartSet/PartSet_OperationSketch.cpp index 7966e9ed1..bc57e5068 100644 --- a/src/PartSet/PartSet_OperationSketch.cpp +++ b/src/PartSet/PartSet_OperationSketch.cpp @@ -194,7 +194,7 @@ bool PartSet_OperationSketch::hasSketchPlane() const if (feature()) { boost::shared_ptr aData = feature()->data(); - boost::shared_ptr anAttr; + AttributeDoublePtr anAttr; boost::shared_ptr aNormal = boost::dynamic_pointer_cast(aData->attribute(SKETCH_ATTR_NORM)); aHasPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0); diff --git a/src/PartSet/PartSet_Presentation.cpp b/src/PartSet/PartSet_Presentation.cpp index 18fcce5f8..84dc7e3fe 100644 --- a/src/PartSet/PartSet_Presentation.cpp +++ b/src/PartSet/PartSet_Presentation.cpp @@ -122,6 +122,11 @@ Handle(AIS_InteractiveObject) PartSet_Presentation::createSketchConstraintLength //Build dimension here gp_Pnt aP1 = aPoint1; gp_Pnt aP2 = aPoint2; + if (aFlyout < 0) { + aP1 = aPoint2; + aP2 = aPoint1; + } + Handle(AIS_InteractiveObject) anAIS = thePrevPrs; if (anAIS.IsNull()) @@ -148,6 +153,8 @@ Handle(AIS_InteractiveObject) PartSet_Presentation::createSketchConstraintLength Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS); if (!aDimAIS.IsNull()) { aDimAIS->SetMeasuredGeometry(aPoint1, aPoint2, aPlane); + aDimAIS->SetFlyout(aFlyout); + aDimAIS->Redisplay(Standard_True); } } diff --git a/src/PartSet/PartSet_Tools.cpp b/src/PartSet/PartSet_Tools.cpp index 615f79a28..451971a16 100644 --- a/src/PartSet/PartSet_Tools.cpp +++ b/src/PartSet/PartSet_Tools.cpp @@ -73,7 +73,7 @@ void PartSet_Tools::convertTo2D(const gp_Pnt& thePoint, FeaturePtr theSketch, if (!theSketch) return; - boost::shared_ptr anAttr; + AttributeDoublePtr anAttr; boost::shared_ptr aData = theSketch->data(); boost::shared_ptr anOrigin = @@ -237,7 +237,7 @@ void PartSet_Tools::setFeatureValue(FeaturePtr theFeature, double theValue, if (!theFeature) return; boost::shared_ptr aData = theFeature->data(); - boost::shared_ptr anAttribute = + AttributeDoublePtr anAttribute = boost::dynamic_pointer_cast(aData->attribute(theAttribute)); if (anAttribute) anAttribute->setValue(theValue); diff --git a/src/SketchPlugin/SketchPlugin_Circle.cpp b/src/SketchPlugin/SketchPlugin_Circle.cpp index d58a58dd7..eaa284d08 100644 --- a/src/SketchPlugin/SketchPlugin_Circle.cpp +++ b/src/SketchPlugin/SketchPlugin_Circle.cpp @@ -51,7 +51,7 @@ const boost::shared_ptr& SketchPlugin_Circle::preview() if (aHasPlane) { boost::shared_ptr aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z())); // compute the circle radius - boost::shared_ptr aRadiusAttr = + AttributeDoublePtr aRadiusAttr = boost::dynamic_pointer_cast(data()->attribute(CIRCLE_ATTR_RADIUS)); double aRadius = aRadiusAttr->value(); diff --git a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp index 186e80505..6ee9f2e42 100644 --- a/src/SketchSolver/SketchSolver_ConstraintGroup.cpp +++ b/src/SketchSolver/SketchSolver_ConstraintGroup.cpp @@ -162,7 +162,7 @@ bool SketchSolver_ConstraintGroup::changeConstraint( // Create constraint parameters double aDistance = 0.0; // scalar value of the constraint - boost::shared_ptr aDistAttr = + AttributeDoublePtr aDistAttr = boost::dynamic_pointer_cast(theConstraint->data()->attribute(CONSTRAINT_ATTR_VALUE)); if (aDistAttr) { @@ -288,7 +288,7 @@ Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity( } // Scalar value (used for the distance entities) - boost::shared_ptr aScalar = + AttributeDoublePtr aScalar = boost::dynamic_pointer_cast(theEntity); if (aScalar) { @@ -810,7 +810,7 @@ void SketchSolver_ConstraintGroup::updateAttribute( } // Scalar value - boost::shared_ptr aScalar = + AttributeDoublePtr aScalar = boost::dynamic_pointer_cast(theAttribute); if (aScalar) { -- 2.30.2