From cb65395939911675238e6b5668524c12d71ad9df Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 9 Jun 2014 17:20:27 +0400 Subject: [PATCH] refs #80 - Sketch base GUI: create/draw point, circle and arc Feature Arc creation. Project third point on the arc circle --- src/GeomAPI/CMakeLists.txt | 2 + src/GeomAPI/GeomAPI_Circ2d.cpp | 70 +++++++++++++++++++ src/GeomAPI/GeomAPI_Circ2d.h | 30 ++++++++ src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp | 11 ++- src/PartSet/PartSet_FeatureArcPrs.cpp | 33 ++++++++- src/PartSet/PartSet_FeatureArcPrs.h | 6 ++ .../PartSet_OperationCreateFeature.cpp | 14 ++++ 7 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 src/GeomAPI/GeomAPI_Circ2d.cpp create mode 100644 src/GeomAPI/GeomAPI_Circ2d.h diff --git a/src/GeomAPI/CMakeLists.txt b/src/GeomAPI/CMakeLists.txt index 2a2f3ed40..e14d63fe3 100644 --- a/src/GeomAPI/CMakeLists.txt +++ b/src/GeomAPI/CMakeLists.txt @@ -5,6 +5,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) SET(PROJECT_HEADERS GeomAPI.h + GeomAPI_Circ2d.h GeomAPI_Interface.h GeomAPI_XY.h GeomAPI_XYZ.h @@ -18,6 +19,7 @@ SET(PROJECT_HEADERS ) SET(PROJECT_SOURCES + GeomAPI_Circ2d.cpp GeomAPI_Interface.cpp GeomAPI_XY.cpp GeomAPI_XYZ.cpp diff --git a/src/GeomAPI/GeomAPI_Circ2d.cpp b/src/GeomAPI/GeomAPI_Circ2d.cpp new file mode 100644 index 000000000..4985ae3f4 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Circ2d.cpp @@ -0,0 +1,70 @@ +// File: GeomAPI_Circ2d.cpp +// Created: 29 May 2014 +// Author: Artem ZHIDKOV + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MY_CIRC2D static_cast(myImpl) + +static gp_Circ2d* newCirc2d(const double theCenterX, const double theCenterY, + const double thePointX, const double thePointY) +{ + gp_Pnt2d aCenter(theCenterX, theCenterY); + gp_Pnt2d aPoint(thePointX, thePointY); + + double aRadius = aCenter.Distance(aPoint); + + if (aCenter.IsEqual(aPoint, Precision::Confusion())) + return NULL; + + gp_Dir2d aDir(theCenterX - thePointX, theCenterY - thePointY); + return new gp_Circ2d(gp_Ax2d(aCenter, aDir), aRadius); +} + + +GeomAPI_Circ2d::GeomAPI_Circ2d(const boost::shared_ptr& theCenter, + const boost::shared_ptr& theCirclePoint) + : GeomAPI_Interface(newCirc2d(theCenter->x(), theCenter->y(), + theCirclePoint->x(), theCirclePoint->y())) +{} + +const boost::shared_ptr GeomAPI_Circ2d::project(const boost::shared_ptr& thePoint) const +{ + boost::shared_ptr aResult; + if (!MY_CIRC2D) + return aResult; + + Handle(Geom2d_Circle) aCircle = new Geom2d_Circle(MY_CIRC2D->Axis(), MY_CIRC2D->Radius());//(aCirc); + + const gp_Pnt2d& aPoint = thePoint->impl(); + + Geom2dAPI_ProjectPointOnCurve aProj(aPoint, aCircle); + Standard_Integer aNbPoint = aProj.NbPoints(); + double aX, anY; + if (aNbPoint > 0) { + double aMinDistance = 0, aDistance; + for (Standard_Integer j = 1; j <= aNbPoint; j++) { + gp_Pnt2d aNewPoint = aProj.Point(j); + aDistance = aNewPoint.Distance(aPoint); + if (!aMinDistance || aDistance < aMinDistance) { + aX = aNewPoint.X(); + anY = aNewPoint.Y(); + aMinDistance = aDistance; + aResult = boost::shared_ptr(new GeomAPI_Pnt2d(aX, anY)); + } + } + } + return aResult; +} + diff --git a/src/GeomAPI/GeomAPI_Circ2d.h b/src/GeomAPI/GeomAPI_Circ2d.h new file mode 100644 index 000000000..8b91d8332 --- /dev/null +++ b/src/GeomAPI/GeomAPI_Circ2d.h @@ -0,0 +1,30 @@ +// File: GeomAPI_Circ2d.h +// Created: 29 May 2014 +// Author: Artem ZHIDKOV + +#ifndef GeomAPI_Circ2d_HeaderFile +#define GeomAPI_Circ2d_HeaderFile + +#include +#include + +class GeomAPI_Pnt2d; + +/**\class GeomAPI_Circ2d + * \ingroup DataModel + * \brief Line in 2D + */ + +class GEOMAPI_EXPORT GeomAPI_Circ2d: public GeomAPI_Interface +{ +public: + /// Creation of circle defined by center point and circle radius + GeomAPI_Circ2d(const boost::shared_ptr& theCenter, + const boost::shared_ptr& theCirclePoint); + + /// Project point on line + const boost::shared_ptr project(const boost::shared_ptr& thePoint) const; +}; + +#endif + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp index 514374749..d12cbdd73 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp @@ -58,7 +58,16 @@ boost::shared_ptr GeomAlgoAPI_EdgeBuilder::lineCircleArc( double aRadius = theCenter->distance(theStartPoint); gp_Circ aCircle(gp_Ax2(aCenter, aDir), aRadius); - BRepBuilderAPI_MakeEdge anEdgeBuilder(aCircle); + const gp_Pnt& aStart = theStartPoint->impl(); + const gp_Pnt& anEnd = theEndPoint->impl(); + + BRepBuilderAPI_MakeEdge anEdgeBuilder; + if (aStart.IsEqual(anEnd, Precision::Confusion()) || + gp_Pnt(0, 0, 0).IsEqual(anEnd, Precision::Confusion())) + anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle); + else + anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle, aStart, anEnd); + boost::shared_ptr aRes(new GeomAPI_Shape); TopoDS_Edge anEdge = anEdgeBuilder.Edge(); aRes->setImpl(new TopoDS_Shape(anEdge)); diff --git a/src/PartSet/PartSet_FeatureArcPrs.cpp b/src/PartSet/PartSet_FeatureArcPrs.cpp index 4cc26f008..97af28864 100644 --- a/src/PartSet/PartSet_FeatureArcPrs.cpp +++ b/src/PartSet/PartSet_FeatureArcPrs.cpp @@ -10,12 +10,16 @@ #include #include +#include +#include #include #include #include #include +#include + #include using namespace std; @@ -42,8 +46,8 @@ PartSet_SelectionMode PartSet_FeatureArcPrs::setPoint(double theX, double theY, } break; case SM_ThirdPoint: { - PartSet_Tools::setFeaturePoint(feature(), theX, theY, ARC_ATTR_END); - aMode = SM_DonePoint; + PartSet_Tools::setFeaturePoint(feature(), theX, theY, ARC_ATTR_END); + aMode = SM_DonePoint; } break; default: @@ -85,6 +89,31 @@ PartSet_SelectionMode PartSet_FeatureArcPrs::getNextMode(const std::string& theA return aMode; } +void PartSet_FeatureArcPrs::projectPointOnArc(gp_Pnt& thePoint, Handle(V3d_View) theView, + double& theX, double& theY) +{ + FeaturePtr aSketch = sketch(); + if (aSketch) { + double aX, anY; + PartSet_Tools::convertTo2D(thePoint, aSketch, theView, aX, anY); + + // circle origin point and radius + boost::shared_ptr aData = feature()->data(); + boost::shared_ptr aCenter = boost::dynamic_pointer_cast + (aData->attribute(ARC_ATTR_CENTER)); + boost::shared_ptr aStart = boost::dynamic_pointer_cast + (aData->attribute(ARC_ATTR_START)); + + boost::shared_ptr aCirc(new GeomAPI_Circ2d(aCenter->pnt(), aStart->pnt())); + boost::shared_ptr aGeomPoint2d(new GeomAPI_Pnt2d(aX, anY)); + boost::shared_ptr aPnt2d = aCirc->project(aGeomPoint2d); + if (aPnt2d) { + theX = aPnt2d->x(); + theY = aPnt2d->y(); + } + } +} + boost::shared_ptr PartSet_FeatureArcPrs::featurePoint (const PartSet_SelectionMode& theMode) { diff --git a/src/PartSet/PartSet_FeatureArcPrs.h b/src/PartSet/PartSet_FeatureArcPrs.h index ea25b971f..a02029e7f 100644 --- a/src/PartSet/PartSet_FeatureArcPrs.h +++ b/src/PartSet/PartSet_FeatureArcPrs.h @@ -10,7 +10,10 @@ #include "PartSet_FeaturePrs.h" #include "PartSet_Constants.h" +#include + class GeomDataAPI_Point2D; +class Handle_V3d_View; /*! \class PartSet_FeatureArcPrs @@ -44,6 +47,9 @@ public: /// \return next attribute selection mode virtual PartSet_SelectionMode getNextMode(const std::string& theAttribute) const; + void projectPointOnArc(gp_Pnt& thePoint, Handle_V3d_View theView, + double& theX, double& theY); + protected: /// Returns the feature point in the selection mode position. /// \param theMode the current operation selection mode. The feature attribute depends on the mode diff --git a/src/PartSet/PartSet_OperationCreateFeature.cpp b/src/PartSet/PartSet_OperationCreateFeature.cpp index 4c117b3eb..e92571382 100644 --- a/src/PartSet/PartSet_OperationCreateFeature.cpp +++ b/src/PartSet/PartSet_OperationCreateFeature.cpp @@ -153,6 +153,12 @@ void PartSet_OperationCreateFeature::mouseReleased(QMouseEvent* theEvent, Handle case SM_FirstPoint: case SM_SecondPoint: case SM_ThirdPoint: { + if (feature()->getKind() == SKETCH_ARC_KIND) { + PartSet_FeatureArcPrs* anArcPrs = dynamic_cast(myFeaturePrs); + if (anArcPrs) { + anArcPrs->projectPointOnArc(aPoint, theView, aX, anY); + } + } PartSet_SelectionMode aMode = myFeaturePrs->setPoint(aX, anY, myPointSelectionMode); flushUpdated(); setPointSelectionMode(aMode); @@ -174,6 +180,14 @@ void PartSet_OperationCreateFeature::mouseMoved(QMouseEvent* theEvent, Handle(V3 double aX, anY; gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), theView); PartSet_Tools::convertTo2D(aPoint, sketch(), theView, aX, anY); + if (myPointSelectionMode == SM_ThirdPoint) { + if (feature()->getKind() == SKETCH_ARC_KIND) { + PartSet_FeatureArcPrs* anArcPrs = dynamic_cast(myFeaturePrs); + if (anArcPrs) { + anArcPrs->projectPointOnArc(aPoint, theView, aX, anY); + } + } + } myFeaturePrs->setPoint(aX, anY, myPointSelectionMode); flushUpdated(); -- 2.39.2