]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #1649: Added options to create plane by coincident point;
authordbv <dbv@opencascade.com>
Wed, 13 Jul 2016 15:49:17 +0000 (18:49 +0300)
committerdbv <dbv@opencascade.com>
Thu, 14 Jul 2016 09:20:34 +0000 (12:20 +0300)
src/ConstructionPlugin/ConstructionPlugin_Plane.cpp
src/ConstructionPlugin/ConstructionPlugin_Plane.h
src/ConstructionPlugin/plane_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_FaceBuilder.cpp
src/GeomAlgoAPI/GeomAlgoAPI_FaceBuilder.h

index 40529c0c9e23998ced6a4851620ddf7422091af6..368bc32368a5d6e9c261f9ab8a5a455b4aa42a3e 100644 (file)
@@ -28,6 +28,8 @@
 static GeomShapePtr faceByThreeVertices(const std::shared_ptr<GeomAPI_Vertex> theV1,
                                         const std::shared_ptr<GeomAPI_Vertex> theV2,
                                         const std::shared_ptr<GeomAPI_Vertex> theV3);
+static std::shared_ptr<GeomAPI_Face> makeRectangularFace(const std::shared_ptr<GeomAPI_Face> theFace,
+                                                         const std::shared_ptr<GeomAPI_Pln> thePln);
 
 //==================================================================================================
 ConstructionPlugin_Plane::ConstructionPlugin_Plane()
@@ -62,6 +64,7 @@ void ConstructionPlugin_Plane::initAttributes()
   data()->addAttribute(CREATION_METHOD_BY_OTHER_PLANE_OPTION(), ModelAPI_AttributeString::typeId());
   data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(DISTANCE(), ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(COINCIDENT_POINT(), ModelAPI_AttributeSelection::typeId());
 }
 
 //==================================================================================================
@@ -80,14 +83,17 @@ void ConstructionPlugin_Plane::execute()
     std::string aCreationMethodOption = string(CREATION_METHOD_BY_OTHER_PLANE_OPTION())->value();
     if(aCreationMethodOption == CREATION_METHOD_BY_DISTANCE_FROM_OTHER()) {
       aShape = createByDistanceFromOther();
+    } else if(aCreationMethodOption == CREATION_METHOD_BY_COINCIDENT_TO_POINT()) {
+      aShape = createByCoincidentPoint();
     }
   }
 
-
   if(!aShape.get()) {
+    setError("Error: Could not create a plane.");
     return;
   }
 
+  removeResults(0);
   ResultConstructionPtr aConstr = document()->createConstruction(data());
   aConstr->setInfinite(true);
   aConstr->setShape(aShape);
@@ -205,7 +211,7 @@ std::shared_ptr<GeomAPI_Shape> ConstructionPlugin_Plane::createByLineAndPoint()
 }
 
 //==================================================================================================
-std::shared_ptr<GeomAPI_Shape>  ConstructionPlugin_Plane::createByDistanceFromOther()
+std::shared_ptr<GeomAPI_Shape> ConstructionPlugin_Plane::createByDistanceFromOther()
 {
   AttributeSelectionPtr aFaceAttr = data()->selection(ConstructionPlugin_Plane::PLANE());
   AttributeDoublePtr aDistAttr = data()->real(ConstructionPlugin_Plane::DISTANCE());
@@ -233,41 +239,39 @@ std::shared_ptr<GeomAPI_Shape>  ConstructionPlugin_Plane::createByDistanceFromOt
     aOrig->translate(aDir, aDist);
     std::shared_ptr<GeomAPI_Pln> aNewPln(new GeomAPI_Pln(aOrig, aDir));
 
-    // Create rectangular face close to the selected
-    double aXmin, aYmin, Zmin, aXmax, aYmax, Zmax;
-    aFace->computeSize(aXmin, aYmin, Zmin, aXmax, aYmax, Zmax);
-
-    // use all 8 points of the bounding box to find the 2D bounds
-    bool isFirst = true;
-    double aMinX2d, aMaxX2d, aMinY2d, aMaxY2d;
-    for(int aXIsMin = 0; aXIsMin < 2; aXIsMin++) {
-      for(int aYIsMin = 0; aYIsMin < 2; aYIsMin++) {
-        for(int aZIsMin = 0; aZIsMin < 2; aZIsMin++) {
-          std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(
-            aXIsMin ? aXmin : aXmax, aYIsMin ? aYmin : aYmax, aZIsMin ? Zmin : Zmax));
-          std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = aPnt->to2D(aNewPln);
-          if (isFirst || aPnt2d->x() < aMinX2d)
-            aMinX2d = aPnt2d->x();
-          if (isFirst || aPnt2d->y() < aMinY2d)
-            aMinY2d = aPnt2d->y();
-          if (isFirst || aPnt2d->x() > aMaxX2d)
-            aMaxX2d = aPnt2d->x();
-          if (isFirst || aPnt2d->y() > aMaxY2d)
-            aMaxY2d = aPnt2d->y();
-          if (isFirst)
-            isFirst = !isFirst;
-        }
-      }
-    }
-    double aWgap = (aMaxX2d - aMinX2d) * 0.1;
-    double aHgap = (aMaxY2d - aMinY2d) * 0.1;
-    aPlane = GeomAlgoAPI_FaceBuilder::planarFace(aNewPln,
-      aMinX2d - aWgap, aMinY2d - aHgap, aMaxX2d - aMinX2d + 2. * aWgap, aMaxY2d - aMinY2d + 2. * aHgap);
-
+    aPlane = makeRectangularFace(aFace, aNewPln);
   }
   return aPlane;
 }
 
+//==================================================================================================
+std::shared_ptr<GeomAPI_Shape> ConstructionPlugin_Plane::createByCoincidentPoint()
+{
+  // Get face.
+  AttributeSelectionPtr aFaceSelection = selection(PLANE());
+  GeomShapePtr aFaceShape = aFaceSelection->value();
+  if(!aFaceShape.get()) {
+    aFaceShape = aFaceSelection->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(aFaceShape));
+
+  // Get point.
+  AttributeSelectionPtr aPointSelection = selection(COINCIDENT_POINT());
+  GeomShapePtr aPointShape = aPointSelection->value();
+  if(!aPointShape.get()) {
+    aPointShape = aPointSelection->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(aPointShape));
+
+  std::shared_ptr<GeomAPI_Pnt> anOrig = aVertex->point();
+  std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
+  std::shared_ptr<GeomAPI_Dir> aDir = aPln->direction();
+
+  std::shared_ptr<GeomAPI_Pln> aNewPln(new GeomAPI_Pln(anOrig, aDir));
+
+  return makeRectangularFace(aFace, aNewPln);
+}
+
 //==================================================================================================
 GeomShapePtr faceByThreeVertices(const std::shared_ptr<GeomAPI_Vertex> theV1,
                                  const std::shared_ptr<GeomAPI_Vertex> theV2,
@@ -284,3 +288,41 @@ GeomShapePtr faceByThreeVertices(const std::shared_ptr<GeomAPI_Vertex> theV1,
 
   return aRes;
 }
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Face> makeRectangularFace(const std::shared_ptr<GeomAPI_Face> theFace,
+                                                  const std::shared_ptr<GeomAPI_Pln> thePln)
+{
+  // Create rectangular face close to the selected
+  double aXmin, aYmin, Zmin, aXmax, aYmax, Zmax;
+  theFace->computeSize(aXmin, aYmin, Zmin, aXmax, aYmax, Zmax);
+
+  // use all 8 points of the bounding box to find the 2D bounds
+  bool isFirst = true;
+  double aMinX2d, aMaxX2d, aMinY2d, aMaxY2d;
+  for(int aXIsMin = 0; aXIsMin < 2; aXIsMin++) {
+    for(int aYIsMin = 0; aYIsMin < 2; aYIsMin++) {
+      for(int aZIsMin = 0; aZIsMin < 2; aZIsMin++) {
+        std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(
+          aXIsMin ? aXmin : aXmax, aYIsMin ? aYmin : aYmax, aZIsMin ? Zmin : Zmax));
+        std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = aPnt->to2D(thePln);
+        if (isFirst || aPnt2d->x() < aMinX2d)
+          aMinX2d = aPnt2d->x();
+        if (isFirst || aPnt2d->y() < aMinY2d)
+          aMinY2d = aPnt2d->y();
+        if (isFirst || aPnt2d->x() > aMaxX2d)
+          aMaxX2d = aPnt2d->x();
+        if (isFirst || aPnt2d->y() > aMaxY2d)
+          aMaxY2d = aPnt2d->y();
+        if (isFirst)
+          isFirst = !isFirst;
+      }
+    }
+  }
+  double aWgap = (aMaxX2d - aMinX2d) * 0.1;
+  double aHgap = (aMaxY2d - aMinY2d) * 0.1;
+  std::shared_ptr<GeomAPI_Face> aResFace = GeomAlgoAPI_FaceBuilder::planarFace(thePln,
+    aMinX2d - aWgap, aMinY2d - aHgap, aMaxX2d - aMinX2d + 2. * aWgap, aMaxY2d - aMinY2d + 2. * aHgap);
+
+  return aResFace;
+}
index 3bfecc7a71a526afd1097e6c9baf804b42b30cb7..d92f00811d0f4b7468ce8c7343c22d773cae63ee 100644 (file)
@@ -159,6 +159,13 @@ public:
     return ATTR_ID;
   }
 
+  /// Attribute name for coincident point.
+  inline static const std::string& COINCIDENT_POINT()
+  {
+    static const std::string ATTR_ID("coincident_point");
+    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()
   {
@@ -205,6 +212,7 @@ protected:
   std::shared_ptr<GeomAPI_Shape> createByGeneralEquation();
   std::shared_ptr<GeomAPI_Shape> createByThreePoints();
   std::shared_ptr<GeomAPI_Shape> createByLineAndPoint();
+  std::shared_ptr<GeomAPI_Shape> createByCoincidentPoint();
   /// 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 299e6ae358c3edca5193db7f6e9003a31c071026..6c8e2f9667d54a4c90145257b3968406d4b8b1e5 100644 (file)
              title="By coincident to point"
              tooltip="Plane by coincident to point."
              icon="icons/Construction/plane_by_coincident_to_point_32x32.png">
+          <shape_selector id="coincident_point"
+                          label="Point"
+                          tooltip="Select point."
+                          icon="icons/Construction/point.png"
+                          shape_types="vertex">
+          </shape_selector>
         </box>
         <box id="by_rotation"
              title="By rotation"
index 7a625131054247ae5fa6778a66ccb5b391de4929..b5c5a4aa771ee07e166c12ae0243d080480766d8 100644 (file)
@@ -104,6 +104,26 @@ std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::planarFaceByThreeVertices
   return aFace;
 }
 
+//==================================================================================================
+std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::planarFaceByFaceAndVertex(
+    const std::shared_ptr<GeomAPI_Face> theFace,
+    const std::shared_ptr<GeomAPI_Vertex> theVertex)
+{
+  gp_Pln aPln = theFace->getPlane()->impl<gp_Pln>();
+  gp_Pnt aPnt = theVertex->point()->impl<gp_Pnt>();
+
+  std::shared_ptr<GeomAPI_Face> aFace;
+  GC_MakePlane aMakePlane(aPln, aPnt);
+  if(!aMakePlane.IsDone()) {
+    return aFace;
+  }
+
+  BRepBuilderAPI_MakeFace aMakeFace(aMakePlane.Value()->Pln());
+  aFace.reset(new GeomAPI_Face());
+  aFace->setImpl(new TopoDS_Face(aMakeFace.Face()));
+  return aFace;
+}
+
 //==================================================================================================
 std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_FaceBuilder::plane(const std::shared_ptr<GeomAPI_Face> theFace)
 {
index 603ed4620f3aa8d353bb98a5b7cbccad51bc368f..c33013f02e51d5c102396fcffc3068296b4af604 100644 (file)
@@ -47,6 +47,10 @@ class GEOMALGOAPI_EXPORT GeomAlgoAPI_FaceBuilder
                                                                  const std::shared_ptr<GeomAPI_Vertex> theVertex2,
                                                                  const std::shared_ptr<GeomAPI_Vertex> theVertex3);
 
+  /// Creates a planar face parallel to theFace and passing through theVertex.
+  static std::shared_ptr<GeomAPI_Face> planarFaceByFaceAndVertex(const std::shared_ptr<GeomAPI_Face> theFace,
+                                                                 const std::shared_ptr<GeomAPI_Vertex> theVertex);
+
   /// Returns the plane of the planar face. If it is not planar, returns empty ptr.
   static std::shared_ptr<GeomAPI_Pln> plane(const std::shared_ptr<GeomAPI_Face> theFace);
 };