]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1649: Added options to create plane by two parallel planes;
authordbv <dbv@opencascade.com>
Fri, 15 Jul 2016 08:22:26 +0000 (11:22 +0300)
committerdbv <dbv@opencascade.com>
Fri, 15 Jul 2016 08:22:26 +0000 (11:22 +0300)
src/ConstructionPlugin/ConstructionPlugin_Plane.cpp
src/ConstructionPlugin/ConstructionPlugin_Plane.h
src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp
src/ConstructionPlugin/ConstructionPlugin_Validators.cpp
src/ConstructionPlugin/ConstructionPlugin_Validators.h
src/ConstructionPlugin/plane_widget.xml
src/GeomAPI/GeomAPI_Dir.cpp
src/GeomAPI/GeomAPI_Dir.h
src/GeomAPI/GeomAPI_Pln.cpp
src/GeomAPI/GeomAPI_Pln.h

index ff3030055983dfbccfbeb00ca625b6145ea16dac..1e3e98ab54e81fdbc241b85ff02e128d9015cb30 100644 (file)
@@ -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<GeomAPI_Shape> ConstructionPlugin_Plane::createByRotation()
   return aRes;
 }
 
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> ConstructionPlugin_Plane::createByTwoParallelPlanes()
+{
+  // Get plane 1.
+  AttributeSelectionPtr aFaceSelection1 = selection(PLANE1());
+  GeomShapePtr aFaceShape1 = aFaceSelection1->value();
+  if(!aFaceShape1.get()) {
+    aFaceShape1 = aFaceSelection1->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Face> aFace1(new GeomAPI_Face(aFaceShape1));
+  std::shared_ptr<GeomAPI_Pln> aPln1 = aFace1->getPlane();
+
+  // Get plane 2.
+  AttributeSelectionPtr aFaceSelection2 = selection(PLANE2());
+  GeomShapePtr aFaceShape2 = aFaceSelection2->value();
+  if(!aFaceShape2.get()) {
+    aFaceShape2 = aFaceSelection2->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Face> aFace2(new GeomAPI_Face(aFaceShape2));
+  std::shared_ptr<GeomAPI_Pln> aPln2 = aFace2->getPlane();
+
+  double aDist = aPln1->distance(aPln2) / 2.0;
+
+  std::shared_ptr<GeomAPI_Pnt> aOrig1 = aPln1->location();
+  std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
+
+  aOrig1->translate(aDir1, aDist);
+  std::shared_ptr<GeomAPI_Pln> 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<GeomAPI_Face> aRes = makeRectangularFace(aFace1, aNewPln);
+
+  return aRes;
+}
+
 //==================================================================================================
 GeomShapePtr faceByThreeVertices(const std::shared_ptr<GeomAPI_Vertex> theV1,
                                  const std::shared_ptr<GeomAPI_Vertex> theV2,
index eb2ae37c4dcead206ad35afbb7eb21418e5cbb83..999e6fa65fd49f69b06127590e0a0a9083485869 100644 (file)
@@ -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<GeomAPI_Shape> createByLineAndPoint();
   std::shared_ptr<GeomAPI_Shape> createByCoincidentPoint();
   std::shared_ptr<GeomAPI_Shape> createByRotation();
+  std::shared_ptr<GeomAPI_Shape> createByTwoParallelPlanes();
   /// Creates a new plane by copy of face plane with translation along the normal
   /// to the specified distance.
   std::shared_ptr<GeomAPI_Shape> createByDistanceFromOther();
index 521873f11424443df74a1481c02f3f575eace3ce..58b05df7f0aa33758830ad411d0b8cdcc79618bb 100644 (file)
@@ -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);
index 9cf88ccd9b1a4e4bc2091c763d6fb8c00bb01bc5..3581fad92c84c095b8ac6e0aa7fa79be574ad32f 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "ConstructionPlugin_Validators.h"
 
+#include <GeomAPI_Dir.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Face.h>
 #include <GeomAPI_Lin.h>
@@ -251,6 +252,58 @@ bool ConstructionPlugin_ValidatorPlaneLinePoint::isValid(
   return true;
 }
 
+//==================================================================================================
+bool ConstructionPlugin_ValidatorPlaneTwoParallelPlanes::isValid(
+    const AttributePtr& theAttribute,
+    const std::list<std::string>& theArguments,
+    Events_InfoMessage& theError) const
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+
+  AttributeSelectionPtr anAttribute1 = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+  AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
+
+  std::shared_ptr<GeomAPI_Pln> aPln1;
+  std::shared_ptr<GeomAPI_Pln> 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<GeomAPI_Dir> aDir1 = aPln1->direction();
+  std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
+
+  if(!aDir1->isParallel(aDir2)) {
+    theError = "Planes not parallel.";
+    return false;
+  }
+
+  return true;
+}
+
 std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape)
 {
   std::shared_ptr<GeomAPI_Lin> aLin;
index 9bbb6f950b0d797f71fe27a402d79892c988ffe1..f45a6a6b97e8ccd104100eb42b8d9612909538d9 100644 (file)
@@ -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<std::string>& theArguments,
+                        Events_InfoMessage& theError) const;
+};
+
 #endif
\ No newline at end of file
index 4162ebfdd55cb7254618556c4f995a04f5ff3cd8..fc85d1b26b5f00f1b0f2a58544fb76344a82a27d 100644 (file)
          title="By two parallel planes"
          tooltip="Plane equidistant from 2 parallel planes."
          icon="icons/Construction/plane_by_two_parallel_planes_32x32.png">
-    </box>
-
-
-    <!--<box id="PlaneByFaceAndDistance" title="On some distance from a face">
-      <shape_selector id="planeFace"
-                      label="Plane face"
-                      tooltip="Select a planar face"
+      <shape_selector id="plane1"
+                      label="1st plane"
+                      tooltip="Select a planar face."
+                      icon="icons/Construction/face.png"
                       shape_types="face">
         <validator id="GeomValidators_Face" parameters="plane"/>
+        <validator id="ConstructionPlugin_ValidatorPlaneTwoParallelPlanes" parameters="plane2"/>
       </shape_selector>
-      <doublevalue id="distance" 
-                   label="Distance" 
-                   tooltip="Distance from selected face to plane" 
-               default="0" />
-    </box>-->
-
+      <shape_selector id="plane2"
+                      label="2nd plane"
+                      tooltip="Select a planar face."
+                      icon="icons/Construction/face.png"
+                      shape_types="face">
+        <validator id="GeomValidators_Face" parameters="plane"/>
+        <validator id="ConstructionPlugin_ValidatorPlaneTwoParallelPlanes" parameters="plane1"/>
+      </shape_selector>
+    </box>
   </toolbox>
 </source>
index 6f57e76815be685afaf7de7fdd399aaceead0348..d9963d46cdd1c7d84dc59fc2fbfd033cd64bba7f 100644 (file)
@@ -63,3 +63,7 @@ double GeomAPI_Dir::angle(const std::shared_ptr<GeomAPI_Dir>& theArg) const
   return MY_DIR->Angle(theArg->impl<gp_Dir>());
 }
 
+bool GeomAPI_Dir::isParallel(const std::shared_ptr<GeomAPI_Dir> theDir, const double theTolerance) const
+{
+  return MY_DIR->IsParallel(theDir->impl<gp_Dir>(), theTolerance) == Standard_True;
+}
index a3e49f90760d12dca01f62e7ffeb3443d81375b4..9b9d4f354facae598c966060af591be57614145b 100644 (file)
@@ -54,6 +54,12 @@ class GeomAPI_Dir : public GeomAPI_Interface
   /// calculates angle between two directions
   GEOMAPI_EXPORT 
   double angle(const std::shared_ptr<GeomAPI_Dir>& 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<GeomAPI_Dir> theDir, const double theTolerance = 1.e-7) const;
+
+
 };
 
 #endif
index 4c26557cfe13d693aeb49dfe28dbf25b80e9efa4..b162e51f8253139ce455121ae8f006b1aa93f6ea 100644 (file)
@@ -104,3 +104,11 @@ std::shared_ptr<GeomAPI_Pnt> GeomAPI_Pln::project(const std::shared_ptr<GeomAPI_
       aLocation->added(aVec->decreased(aNormal->multiplied(aDot)));
   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aProjection));
 }
+
+double GeomAPI_Pln::distance(const std::shared_ptr<GeomAPI_Pln> thePlane) const
+{
+  const gp_Pln& aMyPln = impl<gp_Pln>();
+  const gp_Pln& anOtherPln = thePlane->impl<gp_Pln>();
+
+  return aMyPln.Distance(anOtherPln);
+}
index c3cd27e7fa6b5d467e399f8adc28556b75f7b3d4..6f0cb43dbf1b74aef2ffc5afc6b019687c00e57d 100644 (file)
@@ -67,6 +67,10 @@ class GeomAPI_Pln : public GeomAPI_Interface
   /// Returns projection of the given point onto the plane
   GEOMAPI_EXPORT
   std::shared_ptr<GeomAPI_Pnt> project(const std::shared_ptr<GeomAPI_Pnt>& thePoint) const;
+
+  /// \return distance between planes.
+  GEOMAPI_EXPORT
+  double distance(const std::shared_ptr<GeomAPI_Pln> thePlane) const;
 };
 
 #endif