Salome HOME
Added option to create Construction Point by intersection of two lines.
authordbv <dbv@opencascade.com>
Thu, 7 Jul 2016 09:31:40 +0000 (12:31 +0300)
committerdbv <dbv@opencascade.com>
Thu, 7 Jul 2016 09:31:57 +0000 (12:31 +0300)
12 files changed:
src/ConstructionPlugin/CMakeLists.txt
src/ConstructionPlugin/ConstructionPlugin_Plugin.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.cpp
src/ConstructionPlugin/ConstructionPlugin_Point.h
src/ConstructionPlugin/ConstructionPlugin_Validators.cpp [new file with mode: 0644]
src/ConstructionPlugin/ConstructionPlugin_Validators.h [new file with mode: 0644]
src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png [new file with mode: 0644]
src/ConstructionPlugin/icons/point_by_projection_32x32.png
src/ConstructionPlugin/point_widget.xml
src/GeomAPI/GeomAPI_Lin.cpp
src/GeomAPI/GeomAPI_Lin.h
src/GeomAlgoAPI/GeomAlgoAPI_PointBuilder.cpp

index 4b5ca9ddb246badcdc13b74002b795ba2b7755e2..f31b6e820118e8e0478297a0741f84ff325f674c 100644 (file)
@@ -9,6 +9,7 @@ SET(PROJECT_HEADERS
     ConstructionPlugin_Point.h
     ConstructionPlugin_Axis.h
     ConstructionPlugin_Plane.h
+    ConstructionPlugin_Validators.h
 )
 
 SET(PROJECT_SOURCES
@@ -16,6 +17,7 @@ SET(PROJECT_SOURCES
     ConstructionPlugin_Point.cpp
     ConstructionPlugin_Axis.cpp
     ConstructionPlugin_Plane.cpp
+    ConstructionPlugin_Validators.cpp
 )
 
 SET(XML_RESOURCES
@@ -51,6 +53,7 @@ INCLUDE_DIRECTORIES(
   ../ModelAPI
   ../GeomAPI
   ../GeomAlgoAPI
+  ../Events
 )
 
 
index c60c022b4311028afd31a9c801159ed0d1158822..63d7308d204bc4008f7c0de549daafce1ebb6491 100644 (file)
@@ -4,6 +4,7 @@
 #include "ConstructionPlugin_Point.h"
 #include "ConstructionPlugin_Axis.h"
 #include "ConstructionPlugin_Plane.h"
+#include "ConstructionPlugin_Validators.h"
 
 #include <Config_PropManager.h>
 
@@ -17,6 +18,11 @@ static ConstructionPlugin_Plugin* MY_CONSTRUCTION_INSTANCE = new ConstructionPlu
 
 ConstructionPlugin_Plugin::ConstructionPlugin_Plugin()
 {
+  SessionPtr aMgr = ModelAPI_Session::get();
+  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+  aFactory->registerValidator("ConstructionPlugin_ValidatorPointLines",
+                              new ConstructionPlugin_ValidatorPointLines());
+
   // register this plugin
   ModelAPI_Session::get()->registerPlugin(this);
 
index 380393db703ea60e5feb37ac5c474aacea46f967..22f91d732f9e2cb0d6677cb379eb1b3b8ef3c9d8 100644 (file)
@@ -46,6 +46,9 @@ void ConstructionPlugin_Point::initAttributes()
 
   data()->addAttribute(POINT(), ModelAPI_AttributeSelection::typeId());
   data()->addAttribute(PLANE(), ModelAPI_AttributeSelection::typeId());
+
+  data()->addAttribute(FIRST_LINE(), ModelAPI_AttributeSelection::typeId());
+  data()->addAttribute(SECOND_LINE(), ModelAPI_AttributeSelection::typeId());
 }
 
 //==================================================================================================
@@ -60,6 +63,8 @@ void ConstructionPlugin_Point::execute()
     aShape = createByDistanceOnEdge();
   } else if(aCreationMethod == CREATION_METHOD_BY_PROJECTION()) {
     aShape = createByProjection();
+  } else if(aCreationMethod == CREATION_METHOD_BY_LINES_INTERSECTION()) {
+    aShape = createByIntersection();
   }
 
   if(aShape.get()) {
@@ -130,3 +135,25 @@ std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByProjection()
 
   return GeomAlgoAPI_PointBuilder::vertexByProjection(aVertex, aFace);
 }
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Vertex> ConstructionPlugin_Point::createByIntersection()
+{
+  // Get first line.
+  AttributeSelectionPtr aFirstLineSelection= selection(FIRST_LINE());
+  GeomShapePtr aFirstLineShape = aFirstLineSelection->value();
+  if(!aFirstLineShape.get()) {
+    aFirstLineShape = aFirstLineSelection->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Edge> aFirstEdge(new GeomAPI_Edge(aFirstLineShape));
+
+  // Get first line.
+  AttributeSelectionPtr aSecondLineSelection= selection(SECOND_LINE());
+  GeomShapePtr aSecondLineShape = aSecondLineSelection->value();
+  if(!aSecondLineShape.get()) {
+    aSecondLineShape = aSecondLineSelection->context()->shape();
+  }
+  std::shared_ptr<GeomAPI_Edge> aSecondEdge(new GeomAPI_Edge(aSecondLineShape));
+
+  return GeomAlgoAPI_PointBuilder::vertexByIntersection(aFirstEdge, aSecondEdge);
+}
index 65d17aef2e878f03880a095a7e797257ef718b07..b5619e7becfb34f6d6a402ef596be94ee87a4c92 100644 (file)
@@ -59,6 +59,13 @@ public:
     return MY_CREATION_METHOD_ID;
   }
 
+  /// Attribute name for creation method.
+  inline static const std::string& CREATION_METHOD_BY_LINES_INTERSECTION()
+  {
+    static const std::string MY_CREATION_METHOD_ID("by_lines_intersection");
+    return MY_CREATION_METHOD_ID;
+  }
+
   /// Attribute name for X coordinate.
   inline static const std::string& X()
   {
@@ -122,6 +129,20 @@ public:
     return ATTR_ID;
   }
 
+  /// Attribute name for seleted first line.
+  inline static const std::string& FIRST_LINE()
+  {
+    static const std::string ATTR_ID("first_line");
+    return ATTR_ID;
+  }
+
+  /// Attribute name for seleted second line.
+  inline static const std::string& SECOND_LINE()
+  {
+    static const std::string ATTR_ID("second_line");
+    return ATTR_ID;
+  }
+
   /// Creates a new part document if needed.
   CONSTRUCTIONPLUGIN_EXPORT virtual void execute();
 
@@ -142,6 +163,7 @@ private:
   std::shared_ptr<GeomAPI_Vertex> createByXYZ();
   std::shared_ptr<GeomAPI_Vertex> createByDistanceOnEdge();
   std::shared_ptr<GeomAPI_Vertex> createByProjection();
+  std::shared_ptr<GeomAPI_Vertex> createByIntersection();
 
 };
 
diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp b/src/ConstructionPlugin/ConstructionPlugin_Validators.cpp
new file mode 100644 (file)
index 0000000..098485d
--- /dev/null
@@ -0,0 +1,70 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        ConstructionPlugin_Validators.cpp
+// Created:     04 July 2016
+// Author:      Dmitry Bobylev
+
+#include "ConstructionPlugin_Validators.h"
+
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Lin.h>
+
+#include <ModelAPI_AttributeSelection.h>
+
+#include <Events_InfoMessage.h>
+
+//==================================================================================================
+bool ConstructionPlugin_ValidatorPointLines::isValid(const AttributePtr& theAttribute,
+                                                     const std::list<std::string>& theArguments,
+                                                     Events_InfoMessage& theError) const
+{
+  FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
+
+  AttributeSelectionPtr aLineAttribute1 = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+  AttributeSelectionPtr aLineAttribute2 = aFeature->selection(theArguments.front());
+
+  GeomShapePtr aLineShape1 = aLineAttribute1->value();
+  ResultPtr aContext1 = aLineAttribute1->context();
+  if(!aContext1.get()) {
+    theError = "One of the attribute not initialized.";
+    return false;
+  }
+  if(!aLineShape1.get()) {
+    aLineShape1 = aContext1->shape();
+  }
+  if(!aLineShape1->isEdge()) {
+    theError = "One of the selected shapes not an edge.";
+    return false;
+  }
+
+  GeomShapePtr aLineShape2 = aLineAttribute2->value();
+  ResultPtr aContext2 = aLineAttribute2->context();
+  if(!aContext2.get()) {
+    return true;
+  }
+  if(!aLineShape2.get()) {
+    aLineShape2 = aContext2->shape();
+  }
+  if(!aLineShape2->isEdge()) {
+    theError = "One of the selected shapes not an edge.";
+    return false;
+  }
+
+  std::shared_ptr<GeomAPI_Edge> aLineEdge1(new GeomAPI_Edge(aLineShape1));
+  std::shared_ptr<GeomAPI_Edge> aLineEdge2(new GeomAPI_Edge(aLineShape2));
+
+  std::shared_ptr<GeomAPI_Lin> aLine1 = aLineEdge1->line();
+  std::shared_ptr<GeomAPI_Lin> aLine2 = aLineEdge2->line();
+
+  if(!aLine1->isCoplanar(aLine2)) {
+    theError = "Selected lines not coplanar.";
+    return false;
+  }
+
+  if(aLine1->isParallel(aLine2)) {
+    theError = "Selected lines are parallel.";
+    return false;
+  }
+
+  return true;
+}
diff --git a/src/ConstructionPlugin/ConstructionPlugin_Validators.h b/src/ConstructionPlugin/ConstructionPlugin_Validators.h
new file mode 100644 (file)
index 0000000..85dc4a4
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        ConstructionPlugin_Validators.h
+// Created:     04 July 2016
+// Author:      Dmitry Bobylev
+
+#ifndef ConstructionPlugin_Validators_H_
+#define ConstructionPlugin_Validators_H_
+
+#include <ModelAPI_AttributeValidator.h>
+
+/// \class ConstructionPlugin_ValidatorPointLines
+/// \ingroup Validators
+/// \brief A validator for selection lines for point by intersection..
+class ConstructionPlugin_ValidatorPointLines: 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
diff --git a/src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png b/src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png
new file mode 100644 (file)
index 0000000..d51c6ff
Binary files /dev/null and b/src/ConstructionPlugin/icons/point_by_lines_intersection_32x32.png differ
index e5a5510eaef5d304b4f26ad3b5eead60a50d16df..91900fe806e777b1f55c0797af479920a770e343 100644 (file)
Binary files a/src/ConstructionPlugin/icons/point_by_projection_32x32.png and b/src/ConstructionPlugin/icons/point_by_projection_32x32.png differ
index 230aac45a3f728b9f939617709f0080a9287dab7..c489daaad365e99417a4811f3760672e8970ebf1 100644 (file)
         <validator id="GeomValidators_Face" parameters="plane"/>
       </shape_selector>
     </box>
+    <box id="by_lines_intersection"
+         title="By intersection"
+         tooltip="Point by intersection of two coplanar lines."
+         icon="icons/Construction/point_by_lines_intersection_32x32.png">
+      <shape_selector id="first_line"
+                      label="First line"
+                      tooltip="First line."
+                      icon="icons/Construction/point.png"
+                      shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+        <validator id="ConstructionPlugin_ValidatorPointLines" parameters="second_line"/>
+      </shape_selector>
+      <shape_selector id="second_line"
+                      label="Second line"
+                      tooltip="Second line."
+                      icon="icons/Construction/point.png"
+                      shape_types="edge">
+        <validator id="GeomValidators_ShapeType" parameters="line"/>
+        <validator id="ConstructionPlugin_ValidatorPointLines" parameters="first_line"/>
+      </shape_selector>
+    </box>
   </toolbox>
 </source>
index a9fe074d086af9cb2df9e840bde3c8aa070163bb..b76131aa32695a01c70e5b2f54010de1b78dc173 100644 (file)
@@ -105,3 +105,16 @@ const std::shared_ptr<GeomAPI_Pnt> GeomAPI_Lin::project(
   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aResult.X(), aResult.Y(), aResult.Z()));
 }
 
+bool GeomAPI_Lin::isParallel(const std::shared_ptr<GeomAPI_Lin> theLin) const
+{
+  return MY_LIN->Direction().IsParallel(theLin->impl<gp_Lin>().Direction(), Precision::Confusion()) == Standard_True;
+}
+
+bool GeomAPI_Lin::isCoplanar(const std::shared_ptr<GeomAPI_Lin> theLin) const
+{
+  if(MY_LIN->SquareDistance(theLin->impl<gp_Lin>()) > Precision::Confusion()) {
+    return false;
+  }
+
+  return true;
+}
index 6f67109848906352f76a302c25ed893476b80653..c62215bbcc0a32fc0fbe357e365b314e74dae4e6 100644 (file)
@@ -53,6 +53,14 @@ class GeomAPI_Lin : public GeomAPI_Interface
   GEOMAPI_EXPORT 
   const std::shared_ptr<GeomAPI_Pnt> project(
       const std::shared_ptr<GeomAPI_Pnt>& thePoint) const;
+
+  /// \return true if lines are parallel.
+  GEOMAPI_EXPORT
+  bool isParallel(const std::shared_ptr<GeomAPI_Lin> theLin) const;
+
+  /// \return true if lines are coplanar.
+  GEOMAPI_EXPORT
+  bool isCoplanar(const std::shared_ptr<GeomAPI_Lin> theLin) const;
 };
 
 #endif
index b5db2869b32a40415f0e8b317c584bd4f51f40af..1c7e51bb733736e6a38729c46e5475da71890640 100644 (file)
@@ -148,32 +148,16 @@ std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertexByIntersection(
     return aVertex;
   }
 
-  gp_Lin aLin1 = theEdge1->line()->impl<gp_Lin>();
-  gp_Lin aLin2 = theEdge2->line()->impl<gp_Lin>();
+  std::shared_ptr<GeomAPI_Lin> aLin1 = theEdge1->line();
+  std::shared_ptr<GeomAPI_Lin> aLin2 = theEdge2->line();
 
-  if(aLin1.Distance(aLin2) > Precision::Confusion()) {
-    return aVertex;
-  }
-
-  Handle(Geom_Line) aLine1 = new Geom_Line(aLin1);
-  Handle(Geom_Line) aLine2 = new Geom_Line(aLin2);
-
-  GeomAPI_ExtremaCurveCurve anExtrema(aLine1, aLine2);
+  std::shared_ptr<GeomAPI_Pnt> aPnt = aLin1->intersect(aLin2);
 
-  Standard_Integer aNbExtrema = anExtrema.NbExtrema();
-
-  if(aNbExtrema == 0) {
+  if(!aPnt.get()) {
     return aVertex;
   }
 
-  gp_Pnt aPnt1, aPnt2;
-  for(Standard_Integer anIndex = 1; anIndex <= aNbExtrema; ++anIndex) {
-    if(anExtrema.Distance(anIndex) <= Precision::Confusion()) {
-      anExtrema.Points(anIndex, aPnt1, aPnt2);
-    }
-  }
-
-  aVertex.reset(new GeomAPI_Vertex(aPnt1.X(), aPnt1.Y(), aPnt1.Z()));
+  aVertex.reset(new GeomAPI_Vertex(aPnt->x(), aPnt->y(), aPnt->z()));
 
   return aVertex;
 }