From: dbv Date: Fri, 15 Jul 2016 17:03:16 +0000 (+0300) Subject: Issue #1650: Added option to create axis by two planes. X-Git-Tag: V_2.5.0~186 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=549088655a361679c68e5571d4e72d7661df5b3c;p=modules%2Fshaper.git Issue #1650: Added option to create axis by two planes. --- diff --git a/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp b/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp index 1dad21a93..6dc998e6f 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Axis.cpp @@ -10,6 +10,7 @@ #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include +#include #include #include #include @@ -31,6 +33,8 @@ using namespace std; +static const double defaultAxisSize = 50; + ConstructionPlugin_Axis::ConstructionPlugin_Axis() { } @@ -76,6 +80,16 @@ void ConstructionPlugin_Axis::initAttributes() /// Attributes for axis by plane and point. data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId()); data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId()); + + /// Attributes for axis by two planes. + data()->addAttribute(PLANE1(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(USE_OFFSET1(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(OFFSET1(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(REVERSE_OFFSET1(), ModelAPI_AttributeBoolean::typeId()); + data()->addAttribute(PLANE2(), ModelAPI_AttributeSelection::typeId()); + data()->addAttribute(USE_OFFSET2(), ModelAPI_AttributeString::typeId()); + data()->addAttribute(OFFSET2(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(REVERSE_OFFSET2(), ModelAPI_AttributeBoolean::typeId()); } void ConstructionPlugin_Axis::createAxisByTwoPoints() @@ -209,7 +223,7 @@ void ConstructionPlugin_Axis::createAxisByPlaneAndPoint() std::shared_ptr aProjPnt = aPln->project(aPnt); if(aProjPnt->isEqual(aPnt)) { - aPnt->translate(aPln->direction(), 10); + aPnt->translate(aPln->direction(), defaultAxisSize); } std::shared_ptr anEdge = GeomAlgoAPI_EdgeBuilder::line(aProjPnt, aPnt); @@ -220,6 +234,59 @@ void ConstructionPlugin_Axis::createAxisByPlaneAndPoint() setResult(aConstr); } +void ConstructionPlugin_Axis::createAxisByTwoPlanes() +{ + // Get face 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(); + + std::string useOffset1 = string(USE_OFFSET1())->value(); + if(!useOffset1.empty()) { + double anOffset1 = real(OFFSET1())->value(); + bool reverseOffset1 = boolean(REVERSE_OFFSET1())->value(); + if(reverseOffset1) { + anOffset1 = -anOffset1; + } + aPln1->translate(aPln1->direction(), anOffset1); + } + + // Get face 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(); + + std::string useOffset2 = string(USE_OFFSET2())->value(); + if(!useOffset2.empty()) { + double anOffset2 = real(OFFSET2())->value(); + bool reverseOffset2 = boolean(REVERSE_OFFSET2())->value(); + if(reverseOffset2) { + anOffset2 = -anOffset2; + } + aPln2->translate(aPln2->direction(), anOffset2); + } + + std::shared_ptr aLin = aPln1->intersect(aPln2); + std::shared_ptr aPnt1 = aLin->location(); + std::shared_ptr aPnt2 = aLin->location(); + aPnt2->translate(aLin->direction(), defaultAxisSize); + + std::shared_ptr anEdge = GeomAlgoAPI_EdgeBuilder::line(aPnt1, aPnt2); + + ResultConstructionPtr aConstr = document()->createConstruction(data()); + aConstr->setInfinite(true); + aConstr->setShape(anEdge); + setResult(aConstr); +} + void ConstructionPlugin_Axis::execute() { AttributeStringPtr aMethodTypeAttr = string(ConstructionPlugin_Axis::METHOD()); @@ -236,6 +303,8 @@ void ConstructionPlugin_Axis::execute() createAxisByLine(); } else if(aMethodType == CREATION_METHOD_BY_PLANE_AND_POINT()) { createAxisByPlaneAndPoint(); + } else if(aMethodType == CREATION_METHOD_BY_TWO_PLANES()) { + createAxisByTwoPlanes(); } } diff --git a/src/ConstructionPlugin/ConstructionPlugin_Axis.h b/src/ConstructionPlugin/ConstructionPlugin_Axis.h index 0a1eb5de8..438effd1f 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Axis.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Axis.h @@ -56,6 +56,13 @@ class ConstructionPlugin_Axis : public ModelAPI_Feature, public GeomAPI_ICustomP return METHOD_ATTR; } + /// Attribute name for creation method. + inline static const std::string& CREATION_METHOD_BY_TWO_PLANES() + { + static const std::string METHOD_ATTR("by_two_planes"); + return METHOD_ATTR; + } + /// attribute name for first point inline static const std::string& POINT_FIRST() { @@ -135,6 +142,62 @@ class ConstructionPlugin_Axis : public ModelAPI_Feature, public GeomAPI_ICustomP return ATTR_ID; } + /// Attribute name for plane 1. + inline static const std::string& PLANE1() + { + static const std::string ATTR_ID("plane1"); + return ATTR_ID; + } + + /// Attribute name for use offset for plane 1. + inline static const std::string& USE_OFFSET1() + { + static const std::string ATTR_ID("use_offset1"); + return ATTR_ID; + } + + /// Attribute name for offset for plane 1. + inline static const std::string& OFFSET1() + { + static const std::string ATTR_ID("offset1"); + return ATTR_ID; + } + + /// Attribute name for reverse offset for plane 1. + inline static const std::string& REVERSE_OFFSET1() + { + static const std::string ATTR_ID("reverse_offset1"); + return ATTR_ID; + } + + /// Attribute name for plane 2. + inline static const std::string& PLANE2() + { + static const std::string ATTR_ID("plane2"); + return ATTR_ID; + } + + /// Attribute name for use offset for plane 2. + inline static const std::string& USE_OFFSET2() + { + static const std::string ATTR_ID("use_offset2"); + return ATTR_ID; + } + + /// Attribute name for offset for plane 2. + inline static const std::string& OFFSET2() + { + static const std::string ATTR_ID("offset2"); + return ATTR_ID; + } + + /// Attribute name for reverse offset for plane 2. + inline static const std::string& REVERSE_OFFSET2() + { + static const std::string ATTR_ID("reverse_offset2"); + return ATTR_ID; + } + /// Returns a minimal length for axis inline static const double MINIMAL_LENGTH() { return 1.e-5; } @@ -165,6 +228,7 @@ class ConstructionPlugin_Axis : public ModelAPI_Feature, public GeomAPI_ICustomP void createAxisByPointAndDirection(); void createAxisByLine(); void createAxisByPlaneAndPoint(); + void createAxisByTwoPlanes(); }; diff --git a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp index 58b05df7f..dab24920d 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp @@ -30,6 +30,8 @@ ConstructionPlugin_Plugin::ConstructionPlugin_Plugin() new ConstructionPlugin_ValidatorPlaneLinePoint()); aFactory->registerValidator("ConstructionPlugin_ValidatorPlaneTwoParallelPlanes", new ConstructionPlugin_ValidatorPlaneTwoParallelPlanes()); + aFactory->registerValidator("ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes", + new ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes()); // register this plugin ModelAPI_Session::get()->registerPlugin(this); diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp index 3581fad92..5f90b9d44 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp @@ -304,6 +304,58 @@ bool ConstructionPlugin_ValidatorPlaneTwoParallelPlanes::isValid( return true; } +//================================================================================================== +bool ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes::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 are 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 f45a6a6b9..dbbe3d554 100644 --- a/src/ConstructionPlugin/ConstructionPlugin_Validators.h +++ b/src/ConstructionPlugin/ConstructionPlugin_Validators.h @@ -84,4 +84,19 @@ public: Events_InfoMessage& theError) const; }; +/// \class ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes +/// \ingroup Validators +/// \brief A validator for selection two parallel planes. +class ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes: 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/axis_widget.xml b/src/ConstructionPlugin/axis_widget.xml index e2e6ac47d..ac192ec6e 100644 --- a/src/ConstructionPlugin/axis_widget.xml +++ b/src/ConstructionPlugin/axis_widget.xml @@ -61,6 +61,32 @@ shape_types="vertex"> + + + + + + + + + + + + + + + + + + diff --git a/src/GeomAPI/GeomAPI_Pln.cpp b/src/GeomAPI/GeomAPI_Pln.cpp index b162e51f8..b562a0c41 100644 --- a/src/GeomAPI/GeomAPI_Pln.cpp +++ b/src/GeomAPI/GeomAPI_Pln.cpp @@ -13,6 +13,8 @@ #include +#include + using namespace std; GeomAPI_Pln::GeomAPI_Pln(const std::shared_ptr& theAxis) @@ -112,3 +114,44 @@ double GeomAPI_Pln::distance(const std::shared_ptr thePlane) const return aMyPln.Distance(anOtherPln); } + +void GeomAPI_Pln::translate(const std::shared_ptr theDir, double theDist) +{ + gp_Vec aVec(theDir->impl()); + aVec.Normalize(); + aVec.Multiply(theDist); + implPtr()->Translate(aVec); +} + +std::shared_ptr GeomAPI_Pln::intersect(const std::shared_ptr thePlane) const +{ + std::shared_ptr aRes; + + if(!thePlane.get()) { + return aRes; + } + + const gp_Pln& aMyPln = impl(); + const gp_Pln& anOtherPln = thePlane->impl(); + + IntAna_QuadQuadGeo aQuad(aMyPln, anOtherPln, Precision::Confusion(), Precision::Confusion()); + + if(aQuad.IsDone() != Standard_True) { + return aRes; + } + + if(aQuad.NbSolutions() != 1) { + return aRes; + } + + gp_Lin aLin = aQuad.Line(1); + gp_Pnt aLoc = aLin.Location(); + gp_Dir aDir = aLin.Direction(); + + std::shared_ptr aGeomLoc(new GeomAPI_Pnt(aLoc.X(), aLoc.Y(), aLoc.Z())); + std::shared_ptr aGeomDir(new GeomAPI_Dir(aDir.X(), aDir.Y(), aDir.Z())); + + aRes.reset(new GeomAPI_Lin(aGeomLoc, aGeomDir)); + + return aRes; +} diff --git a/src/GeomAPI/GeomAPI_Pln.h b/src/GeomAPI/GeomAPI_Pln.h index 6f0cb43db..d97fefc97 100644 --- a/src/GeomAPI/GeomAPI_Pln.h +++ b/src/GeomAPI/GeomAPI_Pln.h @@ -71,6 +71,14 @@ class GeomAPI_Pln : public GeomAPI_Interface /// \return distance between planes. GEOMAPI_EXPORT double distance(const std::shared_ptr thePlane) const; + + /// Translates the plane along direction theDir on distance theDist + GEOMAPI_EXPORT + void translate(const std::shared_ptr theDir, const double theDist); + + /// \return intersection line of two planes. Empty if they are parallel. + GEOMAPI_EXPORT + std::shared_ptr intersect(const std::shared_ptr thePlane) const; }; #endif