From 9eca41cb14ef72ae9dfba15fce7c7b120ed23faf Mon Sep 17 00:00:00 2001 From: azv Date: Tue, 24 Mar 2015 12:56:46 +0300 Subject: [PATCH] Update Placement feature with flags Reverse and Centering --- .../FeaturesPlugin_Placement.cpp | 14 +++- src/FeaturesPlugin/FeaturesPlugin_Placement.h | 12 ++++ src/FeaturesPlugin/placement_widget.xml | 20 ++++-- src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp | 69 ++++++++++++++----- src/GeomAlgoAPI/GeomAlgoAPI_Placement.h | 29 +++++--- 5 files changed, 107 insertions(+), 37 deletions(-) diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp index 44ad7523e..fd59eb386 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,8 @@ void FeaturesPlugin_Placement::initAttributes() { data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::type()); data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::type()); + data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::type()); + data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::type()); } void FeaturesPlugin_Placement::execute() @@ -87,11 +90,16 @@ void FeaturesPlugin_Placement::execute() return; } - std::shared_ptr aBasePlane = aBaseFace1->getPlane(); - std::shared_ptr aSlavePlane = aSlaveFace1->getPlane(); + // Flags of the Placement + AttributeBooleanPtr aBoolAttr = std::dynamic_pointer_cast( + data()->attribute(FeaturesPlugin_Placement::REVERSE_ID())); + bool isReverse = aBoolAttr->value(); + aBoolAttr = std::dynamic_pointer_cast( + data()->attribute(FeaturesPlugin_Placement::CENTERING_ID())); + bool isCentering = aBoolAttr->value(); std::shared_ptr aResultBody = document()->createBody(data()); - GeomAlgoAPI_Placement aFeature(aSlaveObject, aSlavePlane, aBasePlane); + GeomAlgoAPI_Placement aFeature(aSlaveObject, aBaseFaceContext, aSlaveFace1, aBaseFace1, isReverse, isCentering); if(!aFeature.isDone()) { static const std::string aFeatureError = "Placement algorithm failed"; setError(aFeatureError); diff --git a/src/FeaturesPlugin/FeaturesPlugin_Placement.h b/src/FeaturesPlugin/FeaturesPlugin_Placement.h index e96541de3..bf74f1364 100644 --- a/src/FeaturesPlugin/FeaturesPlugin_Placement.h +++ b/src/FeaturesPlugin/FeaturesPlugin_Placement.h @@ -43,6 +43,18 @@ class FeaturesPlugin_Placement : public ModelAPI_Feature static const std::string MY_ATTRACT_FACE_ID("placement_attractable_face"); return MY_ATTRACT_FACE_ID; } + /// attribute name of flag of reverse direction + inline static const std::string& REVERSE_ID() + { + static const std::string MY_REVERSE_ID("placement_reverse_direction"); + return MY_REVERSE_ID; + } + /// attribute name of flag of centering position + inline static const std::string& CENTERING_ID() + { + static const std::string MY_CENTERING_ID("placement_centering"); + return MY_CENTERING_ID; + } /// Returns the kind of a feature FEATURESPLUGIN_EXPORT virtual const std::string& getKind() diff --git a/src/FeaturesPlugin/placement_widget.xml b/src/FeaturesPlugin/placement_widget.xml index fd4924fa0..4a8832004 100644 --- a/src/FeaturesPlugin/placement_widget.xml +++ b/src/FeaturesPlugin/placement_widget.xml @@ -8,11 +8,19 @@ shape_types="face" /> - + label="Select a face" + icon=":icons/cut_shape.png" + tooltip="Select a face of moved object" + shape_types="face" + concealment="true" > + + + diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp index 3cc4f85ae..e5714a22e 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.cpp @@ -8,52 +8,85 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include + #define DEB_PLACEMENT 1 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement( - std::shared_ptr theAttractiveFace, - std::shared_ptr theSourcePlane, - std::shared_ptr theDestPlane) + std::shared_ptr theSourceShape, + std::shared_ptr theDestShape, + std::shared_ptr theSourcePlane, + std::shared_ptr theDestPlane, + bool theIsReverse, + bool theIsCentering) : myDone(false), myShape(new GeomAPI_Shape()) { - build(theAttractiveFace, theSourcePlane, theDestPlane); + build(theSourceShape, theDestShape, theSourcePlane, theDestPlane, theIsReverse, theIsCentering); } void GeomAlgoAPI_Placement::build( - const std::shared_ptr& theAttractiveShape, - const std::shared_ptr& theSourcePlane, - const std::shared_ptr& theDestPlane) + const std::shared_ptr& theSourceShape, + const std::shared_ptr& theDestShape, + const std::shared_ptr& theSourcePlane, + const std::shared_ptr& theDestPlane, + bool theIsReverse, + bool theIsCentering) { - std::shared_ptr aSourceDir = theSourcePlane->direction(); - std::shared_ptr aSourceLoc = theSourcePlane->location(); - std::shared_ptr aDestDir = theDestPlane->direction(); - std::shared_ptr aDestLoc = theDestPlane->location(); + std::shared_ptr aSourcePlane = theSourcePlane->getPlane(); + std::shared_ptr aDestPlane = theDestPlane->getPlane(); + std::shared_ptr aSourceDir = aSourcePlane->direction(); + std::shared_ptr aSourceLoc = aSourcePlane->location(); + std::shared_ptr aDestDir = aDestPlane->direction(); + std::shared_ptr aDestLoc = aDestPlane->location(); + + // Initial shapes + const TopoDS_Shape& aSourceShape = theSourceShape->impl(); + const TopoDS_Shape& aDestShape = theDestShape->impl(); // Calculate transformation gp_Trsf aTrsf; gp_Vec aSrcDir(aSourceDir->x(), aSourceDir->y(), aSourceDir->z()); gp_Vec aDstDir(aDestDir->x(), aDestDir->y(), aDestDir->z()); + // Check the material of the solids to be on the correct side + BRepClass3d_SolidClassifier aClassifier; + aClassifier.Load(aSourceShape); + static const double aTransStep = 10. * Precision::Confusion(); + gp_Pnt aPoint(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z()); + aPoint.Translate(aSrcDir * aTransStep); + aClassifier.Perform(aPoint, Precision::Confusion()); + if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) || + (aClassifier.State() == TopAbs_IN && theIsReverse)) + aSrcDir.Reverse(); + aClassifier.Load(aDestShape); + aPoint.SetCoord(aDestLoc->x(), aDestLoc->y(), aDestLoc->z()); + aPoint.Translate(aDstDir * aTransStep); + aClassifier.Perform(aPoint, Precision::Confusion()); + if (aClassifier.State() == TopAbs_IN) + aDstDir.Reverse(); + // Calculate rotation gp_Quaternion aRot(aSrcDir, aDstDir); aTrsf.SetRotation(aRot); - gp_Vec aSrcCenter(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z()); - aSrcCenter.Transform(aTrsf); - gp_Vec aTrans(aDestLoc->x() - aSrcCenter.X(), - aDestLoc->y() - aSrcCenter.Y(), - aDestLoc->z() - aSrcCenter.Z()); + // Calculate translation + gp_Vec aSrcLoc(aSourceLoc->x(), aSourceLoc->y(), aSourceLoc->z()); + gp_Vec aDstLoc(aDestLoc->x(), aDestLoc->y(), aDestLoc->z()); + if (!theIsCentering) + aDstLoc = aSrcLoc + gp_Vec(aDstDir) * (aDstLoc-aSrcLoc).Dot(aDstDir); + aSrcLoc.Transform(aTrsf); + gp_Vec aTrans = aDstLoc - aSrcLoc; aTrsf.SetTransformation(aRot, aTrans); // Transform the shape with copying it - const TopoDS_Shape& aShape = theAttractiveShape->impl(); - BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aShape, aTrsf, true); + BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true); if(aBuilder) { setImpl(aBuilder); myDone = aBuilder->IsDone() == Standard_True; diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h index 7bebf97c9..703f609c1 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Placement.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,13 +24,19 @@ class GeomAlgoAPI_Placement : public GeomAPI_Interface public: /** \brief Creates an object which is obtained from current object by transformation calculated * as a movement of the source plane to be coincident with the destination plane - * \param[in] theAttractiveShape shape to be moved - * \param[in] theSourcePlane plane on the shape to be made coincident with destination plane - * \param[in] theDestPlane destination plane + * \param[in] theSourceShape shape to be moved + * \param[in] theDestShape invariabt shape + * \param[in] theSourcePlane plane on the shape to be made coincident with destination plane + * \param[in] theDestPlane destination plane + * \param[in] theIsReverse indicates that the solid materials should be on the same side against the destination plane + * \param[in] theIsCentering indicates the planes should be centered */ - GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr theAttractiveShape, - std::shared_ptr theSourcePlane, - std::shared_ptr theDestPlane); + GEOMALGOAPI_EXPORT GeomAlgoAPI_Placement(std::shared_ptr theSourceShape, + std::shared_ptr theDestShape, + std::shared_ptr theSourcePlane, + std::shared_ptr theDestPlane, + bool theIsReverse = false, + bool theIsCentering = false); /// Returns True if algorithm succeed GEOMALGOAPI_EXPORT const bool isDone() const @@ -56,9 +62,12 @@ public: private: /// builds resulting shape - void build(const std::shared_ptr& theAttractiveShape, - const std::shared_ptr& theSourcePlane, - const std::shared_ptr& theDestPlane); + void build(const std::shared_ptr& theSourceShape, + const std::shared_ptr& theDestShape, + const std::shared_ptr& theSourcePlane, + const std::shared_ptr& theDestPlane, + bool theIsReverse, + bool theIsCentering); /// fields bool myDone; -- 2.39.2