From 14b2f19dcba31d259343982c208daea43b407dc5 Mon Sep 17 00:00:00 2001 From: dbv Date: Thu, 7 Jul 2016 12:31:40 +0300 Subject: [PATCH 1/1] Added option to create Construction Point by intersection of two lines. --- src/ConstructionPlugin/CMakeLists.txt | 3 + .../ConstructionPlugin_Plugin.cpp | 6 ++ .../ConstructionPlugin_Point.cpp | 27 +++++++ .../ConstructionPlugin_Point.h | 22 ++++++ .../ConstructionPlugin_Validators.cpp | 70 ++++++++++++++++++ .../ConstructionPlugin_Validators.h | 27 +++++++ .../point_by_lines_intersection_32x32.png | Bin 0 -> 798 bytes .../icons/point_by_projection_32x32.png | Bin 955 -> 1071 bytes src/ConstructionPlugin/point_widget.xml | 21 ++++++ src/GeomAPI/GeomAPI_Lin.cpp | 13 ++++ src/GeomAPI/GeomAPI_Lin.h | 8 ++ src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp | 26 ++----- 12 files changed, 202 insertions(+), 21 deletions(-) create mode 100644 src/ConstructionPlugin/ConstructionPlugin_Validators.cpp create mode 100644 src/ConstructionPlugin/ConstructionPlugin_Validators.h create mode 100644 src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png diff --git a/src/ConstructionPlugin/CMakeLists.txt b/src/ConstructionPlugin/CMakeLists.txt index 4b5ca9ddb..f31b6e820 100644 --- a/src/ConstructionPlugin/CMakeLists.txt +++ b/src/ConstructionPlugin/CMakeLists.txt @@ -9,6 +9,7 @@ SET(PROJECT_HEADERS ConstructionPlugin_Point.h ConstructionPlugin_Axis.h ConstructionPlugin_Plane.h + ConstructionPlugin_Validators.h ) SET(PROJECT_SOURCES @@ -16,6 +17,7 @@ SET(PROJECT_SOURCES ConstructionPlugin_Point.cpp ConstructionPlugin_Axis.cpp ConstructionPlugin_Plane.cpp + ConstructionPlugin_Validators.cpp ) SET(XML_RESOURCES @@ -51,6 +53,7 @@ INCLUDE_DIRECTORIES( ../ModelAPI ../GeomAPI ../GeomAlgoAPI + ../Events ) diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp index c60c022b4..63d7308d2 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp @@ -4,6 +4,7 @@ #include "ConstructionPlugin_Point.h" #include "ConstructionPlugin_Axis.h" #include "ConstructionPlugin_Plane.h" +#include "ConstructionPlugin_Validators.h" #include @@ -17,6 +18,11 @@ static ConstructionPlugin_Plugin* MY_CONSTRUCTION_INSTANCE = new ConstructionPlu ConstructionPlugin_Plugin::ConstructionPlugin_Plugin() { + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + aFactory->registerValidator("ConstructionPlugin_ValidatorPointLines", + new ConstructionPlugin_ValidatorPointLines()); + // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Point.cpp b/src/ConstructionPlugin/ConstructionPlugin_Point.cpp index 380393db7..22f91d732 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Point.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Point.cpp @@ -46,6 +46,9 @@ void ConstructionPlugin_Point::initAttributes() data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId()); + + data()->addAttribute(FIRST_LINE(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(SECOND_LINE(), ModelAPI_AttributeSelection::typeId()); } //================================================================================================== @@ -60,6 +63,8 @@ void ConstructionPlugin_Point::execute() aShape = createByDistanceOnEdge(); } else if(aCreationMethod == CREATION_METHOD_BY_PROJECTION()) { aShape = createByProjection(); + } else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) { + aShape = createByIntersection(); } if(aShape.get()) { @@ -130,3 +135,25 @@ std::shared_ptr ConstructionPlugin_Point::createByProjection() return GeomAlgoAPI_PointBuilder::vertexByProjection(aVertex, aFace); } + +//================================================================================================== +std::shared_ptr ConstructionPlugin_Point::createByIntersection() +{ + // Get first line. + AttributeSelectionPtr aFirstLineSelection= selection(FIRST_LINE()); + GeomShapePtr aFirstLineShape = aFirstLineSelection->value(); + if(!aFirstLineShape.get()) { + aFirstLineShape = aFirstLineSelection->context()->shape(); + } + std::shared_ptr aFirstEdge(new GeomAPI_Edge(aFirstLineShape)); + + // Get first line. + AttributeSelectionPtr aSecondLineSelection= selection(SECOND_LINE()); + GeomShapePtr aSecondLineShape = aSecondLineSelection->value(); + if(!aSecondLineShape.get()) { + aSecondLineShape = aSecondLineSelection->context()->shape(); + } + std::shared_ptr aSecondEdge(new GeomAPI_Edge(aSecondLineShape)); + + return GeomAlgoAPI_PointBuilder::vertexByIntersection(aFirstEdge, aSecondEdge); +} diff --git a/src/ConstructionPlugin/ConstructionPlugin_Point.h b/src/ConstructionPlugin/ConstructionPlugin_Point.h index 65d17aef2..b5619e7be 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Point.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Point.h @@ -59,6 +59,13 @@ public: return MY_CREATION_METHOD_ID; } + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD_BY_LINES_INTERSECTION() + { + static const std::string MY_CREATION_METHOD_ID("by_lines_intersection"); + return MY_CREATION_METHOD_ID; + } + /// Attribute name for X coordinate. inline static const std::string& X() { @@ -122,6 +129,20 @@ public: return ATTR_ID; } + /// Attribute name for seleted first line. + inline static const std::string& FIRST_LINE() + { + static const std::string ATTR_ID("first_line"); + return ATTR_ID; + } + + /// Attribute name for seleted second line. + inline static const std::string& SECOND_LINE() + { + static const std::string ATTR_ID("second_line"); + return ATTR_ID; + } + /// Creates a new part document if needed. CONSTRUCTIONPLUGIN_EXPORT virtual void execute(); @@ -142,6 +163,7 @@ private: std::shared_ptr createByXYZ(); std::shared_ptr createByDistanceOnEdge(); std::shared_ptr createByProjection(); + std::shared_ptr createByIntersection(); }; diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp new file mode 100644 index 000000000..098485d0a --- /dev/null +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: ConstructionPlugin_Validators.cpp +// Created: 04 July 2016 +// Author: Dmitry Bobylev + +#include "ConstructionPlugin_Validators.h" + +#include +#include + +#include + +#include + +//================================================================================================== +bool ConstructionPlugin_ValidatorPointLines::isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + + AttributeSelectionPtr aLineAttribute1 = std::dynamic_pointer_cast(theAttribute); + AttributeSelectionPtr aLineAttribute2 = aFeature->selection(theArguments.front()); + + GeomShapePtr aLineShape1 = aLineAttribute1->value(); + ResultPtr aContext1 = aLineAttribute1->context(); + if(!aContext1.get()) { + theError = "One of the attribute not initialized."; + return false; + } + if(!aLineShape1.get()) { + aLineShape1 = aContext1->shape(); + } + if(!aLineShape1->isEdge()) { + theError = "One of the selected shapes not an edge."; + return false; + } + + GeomShapePtr aLineShape2 = aLineAttribute2->value(); + ResultPtr aContext2 = aLineAttribute2->context(); + if(!aContext2.get()) { + return true; + } + if(!aLineShape2.get()) { + aLineShape2 = aContext2->shape(); + } + if(!aLineShape2->isEdge()) { + theError = "One of the selected shapes not an edge."; + return false; + } + + std::shared_ptr aLineEdge1(new GeomAPI_Edge(aLineShape1)); + std::shared_ptr aLineEdge2(new GeomAPI_Edge(aLineShape2)); + + std::shared_ptr aLine1 = aLineEdge1->line(); + std::shared_ptr aLine2 = aLineEdge2->line(); + + if(!aLine1->isCoplanar(aLine2)) { + theError = "Selected lines not coplanar."; + return false; + } + + if(aLine1->isParallel(aLine2)) { + theError = "Selected lines are parallel."; + return false; + } + + return true; +} diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.h b/src/ConstructionPlugin/ConstructionPlugin_Validators.h new file mode 100644 index 000000000..85dc4a431 --- /dev/null +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.h @@ -0,0 +1,27 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> + +// File: ConstructionPlugin_Validators.h +// Created: 04 July 2016 +// Author: Dmitry Bobylev + +#ifndef ConstructionPlugin_Validators_H_ +#define ConstructionPlugin_Validators_H_ + +#include + +/// \class ConstructionPlugin_ValidatorPointLines +/// \ingroup Validators +/// \brief A validator for selection lines for point by intersection.. +class ConstructionPlugin_ValidatorPointLines: public ModelAPI_AttributeValidator +{ +public: + //! \return True if the attribute is valid. + //! \param[in] theAttribute the checked attribute. + //! \param[in] theArguments arguments of the attribute. + //! \param[out] theError error message. + virtual bool isValid(const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const; +}; + +#endif \ No newline at end of file diff --git a/src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png b/src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..d51c6ff421d1375a58fcec3886d96258fc22d85c GIT binary patch literal 798 zcmV+(1L6FMP)N2bZe?^J zG%heMIczh2P5=M`oJmAMR9HvFm$6P1Q51$Tp(HUT&MuGO16W!RhE9_ilC`n$87PdU zi4`Tafl5ms!P0lY#KK*piG+Zd7-I~`@PF5H<<9K6vMwW%eC(Zb{`3ELhMie_N)TAN`O4>ug#VnlU-Wbl zx0r%~8U5Zwu~t1S%6g*pM_^5jo@r(Z2e;S-Bk=;`BHTvR+hXPZaJj6Wz|ED>Fx1X( zW3(5BgImloD63ZrBH+6i6=k(MDC=F;ziR49^2&dSw&G+Q0{3P0e~^ zZ#IWp%pvp1u&kcyb)Ucv`_`LyvpL+NhkmZ<5|4F>cXZb8#W!945YC#KHn4*Rt>@w4 z7IScR*Y7^Kq1O!y4zQ+Xy?=8BKw*z`*6%Ek@I4*x#bbJCyxAOXF^59z%++(mb~N3`uU(-=OM%$Ahf1-{v6o!JUrZD7a4AuF#+Lo z9C)*(Z#a6ULAw>}f5I)MU}T1^@EmANJJTlIB50V$Zw%-8KJ!1TXl*8JLS!GyZjk}; zSD%7in6X(rvL8%S1%x&*cX)(Z^T=+Zb%4Nxmky8MVP5VgqKLoQf%qX1&h>9t4!q10 zZ!*YgeKDax6Ml-`!XtQ^cg#7U9-HYmqtEGJpWvP3w7wZ}?|u;oF1*+0#d63XYx;}H c)zd7T0iy8<)s?f)0000007*qoM6N<$g4qaijsO4v literal 0 HcmV?d00001 diff --git a/src/ConstructionPlugin/icons/point_by_projection_32x32.png b/src/ConstructionPlugin/icons/point_by_projection_32x32.png index e5a5510eaef5d304b4f26ad3b5eead60a50d16df..91900fe806e777b1f55c0797af479920a770e343 100644 GIT binary patch delta 993 zcmV<710MXl2d@Z_B#|)~3atPD8?6B$~7wK55d)cF;gn350(r`olY5-oBgA9JmL%!u%zUVXH0~AF=#0}D50XGKu!DaT zkP6a(155&w!4!}VZ2rt+z(>HJ*oW}MbP6|XiKgea@mVtG^L?2IjLca`wnb%>w5Xht z7q29H@hTcIV?GVfE+AV`x%MYf$(fY0WHrT4FQCzLiz$716=kfbCMU=&TTiaC4dg1{ zNbZ$28lKggDWRZ5HSkkvpp1*dU~+%_?n^rRsMVn6#APbjyhnSkyZJ=>5`EG#ZR8U5cb-$6Cto#C>}}3#{42`tq8&{)d?u%rtfkWr-e}K9Z#>o;m}=CI-Fiw{ zcw3cAOj=f<%o{<7*_i!)&PW9@QsVr4HtbTo2h@SJ5Pn%4j8$21H25i7p@z*p;vBI=GQ=H?*^`Lapt;h zJ`*K!*YBVOTlUlGhi_@guA@{@caBcpdqp`_wX}HqA)oQp^%s@-SJ2;Vt{Q0K0Yj$d zYe$dQbSU6F&XY%jv*yqsS1!e7=3vcpuuQY4uVWfEpNsgkL}C*%(J4t;)H~Hp(e^Au z@0H|K=1jJ?xoV)uG^j27#xeYb-=E+I_zw6jzkpBR184vXFOE;77wK{ zfmf3YHz^07J&`LsRDT9QzVPaD;U?war7-1j%QNjdnb&C481Fu|+Kg`1Sayc_UU8kai^jPvSp;U?uU@7r+U99TF9 z7S4frKL-{LqW}LO!WXYbf{^XV4kQ@aiR?mldxjeIcqao>NPh^TL{vy95{9Uea72S> z5gihNL?TfLjaSVk?uSeuB;bNVsRxBLr<6R;jVYe^Vx*rMwpx#XDkC34GYTLqvk=r- zMX)8|5NwXOfhxT~c!_sdG=ygtL*QN;1Rcl%{qagLhK4+`EpF8wyPg(b*;j){o!ljORUsd#Jaht7FzE<7GoYA zL+>EKlFAHZIg8VJ&v>g%(9}EVGFY2a3f<2}gy;6bR}KTQV*SdaHxPrfWigM4V`WUd z2U#Q)cSqh*F}?93cW_j0C6u=HKtfr)AVj^i1QZh|yMG3-r-D0{$UWD|#77VX=}HZ> zQ86Sf4|-mFb{R}LTHl-&JI0sUw(>--$#}>8@NZs#EJ%&fjp9{o8WN$dFXyV z3fax=P-edc*PeU?Yh@#3p1$PLU)9ma#J?eHq~gp#FEwn4O%=8tt?5RD;s8qutdH3b z>rBbuA8o}ox8gGGgH^gX{P|2kyTuECLc%9J21k4~X7EwRh + + + + + + + + + + diff --git a/src/GeomAPI/GeomAPI_Lin.cpp b/src/GeomAPI/GeomAPI_Lin.cpp index a9fe074d0..b76131aa3 100644 --- a/src/GeomAPI/GeomAPI_Lin.cpp +++ b/src/GeomAPI/GeomAPI_Lin.cpp @@ -105,3 +105,16 @@ const std::shared_ptr GeomAPI_Lin::project( return std::shared_ptr(new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z())); } +bool GeomAPI_Lin::isParallel(const std::shared_ptr theLin) const +{ + return MY_LIN->Direction().IsParallel(theLin->impl().Direction(), Precision::Confusion()) == Standard_True; +} + +bool GeomAPI_Lin::isCoplanar(const std::shared_ptr theLin) const +{ + if(MY_LIN->SquareDistance(theLin->impl()) > Precision::Confusion()) { + return false; + } + + return true; +} diff --git a/src/GeomAPI/GeomAPI_Lin.h b/src/GeomAPI/GeomAPI_Lin.h index 6f6710984..c62215bbc 100644 --- a/src/GeomAPI/GeomAPI_Lin.h +++ b/src/GeomAPI/GeomAPI_Lin.h @@ -53,6 +53,14 @@ class GeomAPI_Lin : public GeomAPI_Interface GEOMAPI_EXPORT const std::shared_ptr project( const std::shared_ptr& thePoint) const; + + /// \return true if lines are parallel. + GEOMAPI_EXPORT + bool isParallel(const std::shared_ptr theLin) const; + + /// \return true if lines are coplanar. + GEOMAPI_EXPORT + bool isCoplanar(const std::shared_ptr theLin) const; }; #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp index b5db2869b..1c7e51bb7 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp @@ -148,32 +148,16 @@ std::shared_ptr GeomAlgoAPI_PointBuilder::vertexByIntersection( return aVertex; } - gp_Lin aLin1 = theEdge1->line()->impl(); - gp_Lin aLin2 = theEdge2->line()->impl(); + std::shared_ptr aLin1 = theEdge1->line(); + std::shared_ptr aLin2 = theEdge2->line(); - if(aLin1.Distance(aLin2) > Precision::Confusion()) { - return aVertex; - } - - Handle(Geom_Line) aLine1 = new Geom_Line(aLin1); - Handle(Geom_Line) aLine2 = new Geom_Line(aLin2); - - GeomAPI_ExtremaCurveCurve anExtrema(aLine1, aLine2); + std::shared_ptr aPnt = aLin1->intersect(aLin2); - Standard_Integer aNbExtrema = anExtrema.NbExtrema(); - - if(aNbExtrema == 0) { + if(!aPnt.get()) { return aVertex; } - gp_Pnt aPnt1, aPnt2; - for(Standard_Integer anIndex = 1; anIndex <= aNbExtrema; ++anIndex) { - if(anExtrema.Distance(anIndex) <= Precision::Confusion()) { - anExtrema.Points(anIndex, aPnt1, aPnt2); - } - } - - aVertex.reset(new GeomAPI_Vertex(aPnt1.X(), aPnt1.Y(), aPnt1.Z())); + aVertex.reset(new GeomAPI_Vertex(aPnt->x(), aPnt->y(), aPnt->z())); return aVertex; } -- 2.39.2