From: dbv Date: Fri, 15 Jul 2016 08:22:26 +0000 (+0300) Subject: Issue #1649: Added options to create plane by two parallel planes; X-Git-Tag: V_2.5.0~189 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=f21be85fd01ea53e646014cbc4ea78a2e9801944;p=modules%2Fshaper.git Issue #1649: Added options to create plane by two parallel planes; --- diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp b/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp index ff3030055..1e3e98ab5 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Plane.cpp @@ -70,6 +70,10 @@ void ConstructionPlugin_Plane::initAttributes() data()->addAttribute(COINCIDENT_POINT(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(AXIS(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(ANGLE(), ModelAPI_AttributeDouble::typeId()); + + // By two parallel planes. + data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId()); } //================================================================================================== @@ -93,6 +97,8 @@ void ConstructionPlugin_Plane::execute() } else if(aCreationMethodOption == CREATION_METHOD_BY_ROTATION()) { aShape = createByRotation(); } + } else if(aCreationMethod == CREATION_METHOD_BY_TWO_PARALLEL_PLANES()) { + aShape = createByTwoParallelPlanes(); } if(!aShape.get()) { @@ -100,7 +106,6 @@ void ConstructionPlugin_Plane::execute() return; } - removeResults(0); ResultConstructionPtr aConstr = document()->createConstruction(data()); aConstr->setInfinite(true); aConstr->setShape(aShape); @@ -314,6 +319,46 @@ std::shared_ptr ConstructionPlugin_Plane::createByRotation() return aRes; } +//================================================================================================== +std::shared_ptr ConstructionPlugin_Plane::createByTwoParallelPlanes() +{ + // Get plane 1. + AttributeSelectionPtr aFaceSelection1 = selection(PLANE1()); + GeomShapePtr aFaceShape1 = aFaceSelection1->value(); + if(!aFaceShape1.get()) { + aFaceShape1 = aFaceSelection1->context()->shape(); + } + std::shared_ptr aFace1(new GeomAPI_Face(aFaceShape1)); + std::shared_ptr aPln1 = aFace1->getPlane(); + + // Get plane 2. + AttributeSelectionPtr aFaceSelection2 = selection(PLANE2()); + GeomShapePtr aFaceShape2 = aFaceSelection2->value(); + if(!aFaceShape2.get()) { + aFaceShape2 = aFaceSelection2->context()->shape(); + } + std::shared_ptr aFace2(new GeomAPI_Face(aFaceShape2)); + std::shared_ptr aPln2 = aFace2->getPlane(); + + double aDist = aPln1->distance(aPln2) / 2.0; + + std::shared_ptr aOrig1 = aPln1->location(); + std::shared_ptr aDir1 = aPln1->direction(); + + aOrig1->translate(aDir1, aDist); + std::shared_ptr aNewPln(new GeomAPI_Pln(aOrig1, aDir1)); + + if((aNewPln->distance(aPln2) - aDist) > 1.e-7) { + aDir1->reverse(); + aOrig1->translate(aDir1, 2.0 * aDist); + aNewPln.reset(new GeomAPI_Pln(aOrig1, aDir1)); + } + + std::shared_ptr aRes = makeRectangularFace(aFace1, aNewPln); + + return aRes; +} + //================================================================================================== GeomShapePtr faceByThreeVertices(const std::shared_ptr theV1, const std::shared_ptr theV2, diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plane.h b/src/ConstructionPlugin/ConstructionPlugin_Plane.h index eb2ae37c4..999e6fa65 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plane.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Plane.h @@ -180,6 +180,19 @@ public: return ATTR_ID; } + inline static const std::string& PLANE1() + { + static const std::string ATTR_ID("plane1"); + return ATTR_ID; + } + + inline static const std::string& PLANE2() + { + static const std::string ATTR_ID("plane2"); + return ATTR_ID; + } + + /// Attribute name for a parameter for the general equation of a plane (ax+by+cz+d=0) inline static const std::string& A() { @@ -228,6 +241,7 @@ protected: std::shared_ptr createByLineAndPoint(); std::shared_ptr createByCoincidentPoint(); std::shared_ptr createByRotation(); + std::shared_ptr createByTwoParallelPlanes(); /// Creates a new plane by copy of face plane with translation along the normal /// to the specified distance. std::shared_ptr createByDistanceFromOther(); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp index 521873f11..58b05df7f 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp @@ -28,6 +28,8 @@ ConstructionPlugin_Plugin::ConstructionPlugin_Plugin() new ConstructionPlugin_ValidatorPlaneThreePoints()); aFactory->registerValidator("ConstructionPlugin_ValidatorPlaneLinePoint", new ConstructionPlugin_ValidatorPlaneLinePoint()); + aFactory->registerValidator("ConstructionPlugin_ValidatorPlaneTwoParallelPlanes", + new ConstructionPlugin_ValidatorPlaneTwoParallelPlanes()); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp index 9cf88ccd9..3581fad92 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp @@ -6,6 +6,7 @@ #include "ConstructionPlugin_Validators.h" +#include #include #include #include @@ -251,6 +252,58 @@ bool ConstructionPlugin_ValidatorPlaneLinePoint::isValid( return true; } +//================================================================================================== +bool ConstructionPlugin_ValidatorPlaneTwoParallelPlanes::isValid( + const AttributePtr& theAttribute, + const std::list& theArguments, + Events_InfoMessage& theError) const +{ + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + + AttributeSelectionPtr anAttribute1 = std::dynamic_pointer_cast(theAttribute); + AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front()); + + std::shared_ptr aPln1; + std::shared_ptr aPln2; + + GeomShapePtr aShape1 = anAttribute1->value(); + ResultPtr aContext1 = anAttribute1->context(); + if(!aContext1.get()) { + theError = "One of the attribute not initialized."; + return false; + } + if(!aShape1.get()) { + aShape1 = aContext1->shape(); + } + + GeomShapePtr aShape2 = anAttribute2->value(); + ResultPtr aContext2 = anAttribute2->context(); + if(!aContext2.get()) { + return true; + } + if(!aShape2.get()) { + aShape2 = aContext2->shape(); + } + + aPln1 = getPln(aShape1); + aPln2 = getPln(aShape2); + + if(!aPln1.get() || !aPln2.get()) { + theError = "Wrong shape types selected."; + return false; + } + + std::shared_ptr aDir1 = aPln1->direction(); + std::shared_ptr aDir2 = aPln2->direction(); + + if(!aDir1->isParallel(aDir2)) { + theError = "Planes not parallel."; + return false; + } + + return true; +} + std::shared_ptr getLin(const GeomShapePtr theShape) { std::shared_ptr aLin; diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.h b/src/ConstructionPlugin/ConstructionPlugin_Validators.h index 9bbb6f950..f45a6a6b9 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Validators.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.h @@ -69,4 +69,19 @@ public: Events_InfoMessage& theError) const; }; +/// \class ConstructionPlugin_ValidatorPlaneTwoParallelPlanes +/// \ingroup Validators +/// \brief A validator for selection two parallel planes. +class ConstructionPlugin_ValidatorPlaneTwoParallelPlanes: 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/plane_widget.xml b/src/ConstructionPlugin/plane_widget.xml index 4162ebfdd..fc85d1b26 100644 --- a/src/ConstructionPlugin/plane_widget.xml +++ b/src/ConstructionPlugin/plane_widget.xml @@ -104,21 +104,22 @@ title="By two parallel planes" tooltip="Plane equidistant from 2 parallel planes." icon="icons/Construction/plane_by_two_parallel_planes_32x32.png"> - - - - - + + + + + diff --git a/src/GeomAPI/GeomAPI_Dir.cpp b/src/GeomAPI/GeomAPI_Dir.cpp index 6f57e7681..d9963d46c 100644 --- a/src/GeomAPI/GeomAPI_Dir.cpp +++ b/src/GeomAPI/GeomAPI_Dir.cpp @@ -63,3 +63,7 @@ double GeomAPI_Dir::angle(const std::shared_ptr& theArg) const return MY_DIR->Angle(theArg->impl()); } +bool GeomAPI_Dir::isParallel(const std::shared_ptr theDir, const double theTolerance) const +{ + return MY_DIR->IsParallel(theDir->impl(), theTolerance) == Standard_True; +} diff --git a/src/GeomAPI/GeomAPI_Dir.h b/src/GeomAPI/GeomAPI_Dir.h index a3e49f907..9b9d4f354 100644 --- a/src/GeomAPI/GeomAPI_Dir.h +++ b/src/GeomAPI/GeomAPI_Dir.h @@ -54,6 +54,12 @@ class GeomAPI_Dir : public GeomAPI_Interface /// calculates angle between two directions GEOMAPI_EXPORT double angle(const std::shared_ptr& theArg) const; + + /// \return true if the angle between this unit vector and theDir unit vector is equal to 0 or to Pi. + GEOMAPI_EXPORT + bool isParallel(const std::shared_ptr theDir, const double theTolerance = 1.e-7) const; + + }; #endif diff --git a/src/GeomAPI/GeomAPI_Pln.cpp b/src/GeomAPI/GeomAPI_Pln.cpp index 4c26557cf..b162e51f8 100644 --- a/src/GeomAPI/GeomAPI_Pln.cpp +++ b/src/GeomAPI/GeomAPI_Pln.cpp @@ -104,3 +104,11 @@ std::shared_ptr GeomAPI_Pln::project(const std::shared_ptradded(aVec->decreased(aNormal->multiplied(aDot))); return std::shared_ptr(new GeomAPI_Pnt(aProjection)); } + +double GeomAPI_Pln::distance(const std::shared_ptr thePlane) const +{ + const gp_Pln& aMyPln = impl(); + const gp_Pln& anOtherPln = thePlane->impl(); + + return aMyPln.Distance(anOtherPln); +} diff --git a/src/GeomAPI/GeomAPI_Pln.h b/src/GeomAPI/GeomAPI_Pln.h index c3cd27e7f..6f0cb43db 100644 --- a/src/GeomAPI/GeomAPI_Pln.h +++ b/src/GeomAPI/GeomAPI_Pln.h @@ -67,6 +67,10 @@ class GeomAPI_Pln : public GeomAPI_Interface /// Returns projection of the given point onto the plane GEOMAPI_EXPORT std::shared_ptr project(const std::shared_ptr& thePoint) const; + + /// \return distance between planes. + GEOMAPI_EXPORT + double distance(const std::shared_ptr thePlane) const; }; #endif