diff --git a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc
index ff70d793a..7091e0d4b 100644
--- a/doc/salome/gui/GEOM/input/tui_measurement_tools.doc
+++ b/doc/salome/gui/GEOM/input/tui_measurement_tools.doc
@@ -71,6 +71,35 @@ else:
print "But must be (50, 15, 50)"
\endcode
+
Get vertex by index
+
+\code
+import geompy
+
+# Create auxiliary objects
+Vertex_1 = geompy.MakeVertex(0, 0, 0)
+Vertex_2 = geompy.MakeVertex(10, 20, 0)
+Vertex_3 = geompy.MakeVertex(0, 40, 0)
+Vertex_4 = geompy.MakeVertex(-10, 60, 0)
+Vertex_5 = geompy.MakeVertex(0, 80, 0)
+Curve_1 = geompy.MakeInterpol([Vertex_1, Vertex_2, Vertex_3])
+Curve_2 = geompy.MakeInterpol([Vertex_5, Vertex_4, Vertex_3])
+Wire_1 = geompy.MakeWire([Curve_1, Curve_2])
+Reversed_Wire = geompy.ChangeOrientationShellCopy(Wire_1)
+
+# Get The vertexes from Reversed Wire by different functions
+vertex_0 = geompy.GetFirstVertex(Reversed_Wire)
+vertex_1 = geompy.GetVertexByIndex(Reversed_Wire, 1)
+vertex_2 = geompy.GetLastVertex(Reversed_Wire)
+
+# Publish objects in study
+geompy.addToStudy( Wire_1, "Wire_1" )
+geompy.addToStudy( Reversed_Wire, "Reversed_Wire" )
+geompy.addToStudy( vertex_0, "vertex_0" )
+geompy.addToStudy( vertex_1, "vertex_1" )
+geompy.addToStudy( vertex_2, "vertex_2" )
+\endcode
+
Inertia
\code
diff --git a/doc/salome/gui/GEOM/input/using_measurement_tools.doc b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
index 068a94716..13765941c 100644
--- a/doc/salome/gui/GEOM/input/using_measurement_tools.doc
+++ b/doc/salome/gui/GEOM/input/using_measurement_tools.doc
@@ -8,7 +8,8 @@ concerning created or imported geometrical objects. They are:
- \ref point_coord_anchor "Point coordinates"
- \ref basic_prop_anchor "Basic properties"
-- \ref center_mass_anchor "Center of mass"
+- \ref center_mass_anchor "Center of mass"
+- \ref vertex_by_index "Get Vertex By Index"
- \ref inertia_anchor "Inertia"
- \ref normale_anchor "Normal to a Face"
- \ref boundaries_anchor "Check Free Boundaries"
@@ -53,39 +54,51 @@ Python Tuple.
\em Shape is a shape whose properties are inquired.
\image html neo-basicprop.png
-
-\anchor center_mass_anchor
-
Center of mass
-
-\n Calculates and returns the coordinates of the gravity center for
-the selected geometrical object.
-
-\n Result: GEOM_Object (vertex).
-\n TUI Command: geompy.MakeCDG(Shape), where \em Shape is
-the shape for which a center of gravity is computed.
-
-\image html measures3.png
-
-\anchor inertia_anchor
-
Inertia
-
-Returns the axial moments of inertia for the selected geometrical object.
-
-\n Result: Displays the matrix of the own moments of inertia and
-the relative moments of inertia in the form of Python Tuple
- (I11, I12, I13,
- I21, I22, I23,
- I31, I32, I33,
- Ix, Iy, Iz).
-\n TUI Command: geompy.Inertia(Shape), where \em Shape is
-a shape for which the own matrix of inertia and the relative moments of inertia are
-returned.
-
-\image html measures4.png
-
-\anchor normale_anchor
-
Normal to a Face
-
+
+\anchor center_mass_anchor
+
Center of mass
+
+\n Calculates and returns the coordinates of the gravity center for
+the selected geometrical object.
+
+\n Result: GEOM_Object (vertex).
+\n TUI Command: geompy.MakeCDG(Shape), where \em Shape is
+the shape for which a center of gravity is computed.
+
+\image html measures3.png
+
+\anchor vertex_by_index
+
Get Vertex by Index
+
+\n It is possible to get the first or the last vertex from an edge or a wire, depending on
+its direction (orientation), or to find the vertex by the index inside the wire.
+The numeration of vertexes starts from 0. This function has only a TUI implementation)
+
+\n Result: GEOM_Object (vertex).
+\n TUI Command: geompy.GetVertexByIndex(Shape, Index),
+ geompy.GetFirstVertex(Shape),
+ geompy.GetLastVertex(Shape), where \em Shape must be Wire or Edge.
+
+\anchor inertia_anchor
+
Inertia
+
+Returns the axial moments of inertia for the selected geometrical object.
+
+\n Result: Displays the matrix of the own moments of inertia and
+the relative moments of inertia in the form of Python Tuple
+ (I11, I12, I13,
+ I21, I22, I23,
+ I31, I32, I33,
+ Ix, Iy, Iz).
+\n TUI Command: geompy.Inertia(Shape), where \em Shape is
+a shape for which the own matrix of inertia and the relative moments of inertia are
+returned.
+
+\image html measures4.png
+
+\anchor normale_anchor
+
Normal to a Face
+
\n Calculates the normal vector to the selected \b Face. The \b Point
is a point of the \b Face, where the Normal should be calculated.
diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl
index 795212497..62a229e4a 100644
--- a/idl/GEOM_Gen.idl
+++ b/idl/GEOM_Gen.idl
@@ -2885,6 +2885,15 @@ module GEOM
* \return New GEOM_Object, containing the created point.
*/
GEOM_Object GetCentreOfMass (in GEOM_Object theShape);
+
+
+ /*
+ * Get the vertex by index for 1D objects depends the edge/wire orientation
+ * \param theShape Shape (wire or edge) to find the vertex on it
+ * \param theIndex Index of vertex subshape
+ * \return New GEOM_Object, vertex.
+ */
+ GEOM_Object GetVertexByIndex( in GEOM_Object theShape, in long index );
/*!
* Get a vector, representing the normal of theFace.
diff --git a/src/GEOMImpl/GEOMImpl_IMeasure.hxx b/src/GEOMImpl/GEOMImpl_IMeasure.hxx
index c6c8ab74e..1b4583e78 100644
--- a/src/GEOMImpl/GEOMImpl_IMeasure.hxx
+++ b/src/GEOMImpl/GEOMImpl_IMeasure.hxx
@@ -30,7 +30,8 @@ class GEOMImpl_IMeasure
{
enum {
MEASURE_ARG_BASE = 1,
- MEASURE_ARG_POINT = 2
+ MEASURE_ARG_POINT = 2,
+ MEASURE_INDEX = 3
};
public:
@@ -45,6 +46,10 @@ class GEOMImpl_IMeasure
{ _func->SetReference(MEASURE_ARG_POINT, thePnt); }
Handle(GEOM_Function) GetPoint() { return _func->GetReference(MEASURE_ARG_POINT); }
+
+ void SetIndex(int theIndex) { _func->SetInteger(MEASURE_INDEX, theIndex); }
+
+ int GetIndex() { return _func->GetInteger(MEASURE_INDEX); }
private:
diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
index cbb229be6..cb04f5776 100644
--- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
+++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
@@ -895,6 +895,60 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
return aCDG;
}
+//=============================================================================
+/*!
+ * GetVertexByIndex
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
+ (Handle(GEOM_Object) theShape,
+ Standard_Integer theIndex)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ //Add a new Vertex object
+ Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT);
+
+ //Add a function
+ Handle(GEOM_Function) aFunction =
+ aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
+
+ GEOMImpl_IMeasure aCI (aFunction);
+ aCI.SetBase(aRefShape);
+ aCI.SetIndex(theIndex);
+
+ //Compute
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Vertex by index driver failed.");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex(" << theShape << ", " << theIndex << ")";
+
+ SetErrorCode(OK);
+ return aVertex;
+}
+
//=============================================================================
/*!
* GetNormal
diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
index 8d484b716..286c83423 100644
--- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
+++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
@@ -92,6 +92,9 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
Standard_EXPORT Handle(GEOM_Object) GetCentreOfMass (Handle(GEOM_Object) theShape);
+ Standard_EXPORT Handle(GEOM_Object) GetVertexByIndex (Handle(GEOM_Object) theShape,
+ Standard_Integer theIndex);
+
Standard_EXPORT Handle(GEOM_Object) GetNormal (Handle(GEOM_Object) theFace,
Handle(GEOM_Object) theOptionalPoint);
diff --git a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
index f2a61f778..75c1b8eab 100644
--- a/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
+++ b/src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
@@ -35,6 +35,11 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
#include
#include
@@ -108,6 +113,69 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
}
+ else if (aType == VERTEX_BY_INDEX)
+ {
+ Handle(GEOM_Function) aRefBase = aCI.GetBase();
+ TopoDS_Shape aShapeBase = aRefBase->GetValue();
+ if (aShapeBase.IsNull()) {
+ Standard_NullObject::Raise("Shape for centre of mass calculation is null");
+ }
+
+ int index = aCI.GetIndex();
+ gp_Pnt aVertex;
+
+ if (aShapeBase.ShapeType() == TopAbs_VERTEX) {
+ if ( index != 1 )
+ Standard_NullObject::Raise("Vertex index is out of range");
+ else
+ aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase));
+ } else if (aShapeBase.ShapeType() == TopAbs_EDGE) {
+ TopoDS_Vertex aV1, aV2;
+ TopoDS_Edge anEdgeE = TopoDS::Edge(aShapeBase);
+
+ TopExp::Vertices(anEdgeE, aV1, aV2);
+ gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
+ gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
+
+ if (index < 0 || index > 1)
+ Standard_NullObject::Raise("Vertex index is out of range");
+
+ if ( anEdgeE.Orientation() == TopAbs_FORWARD && index == 0 ||
+ anEdgeE.Orientation() == TopAbs_REVERSED && index == 1 )
+ aVertex = aP1;
+ else
+ aVertex = aP2;
+ } else if (aShapeBase.ShapeType() == TopAbs_WIRE) {
+ TopTools_IndexedMapOfShape anEdgeShapes;
+ TopTools_IndexedMapOfShape aVertexShapes;
+ TopoDS_Vertex aV1, aV2;
+ TopoDS_Wire aWire = TopoDS::Wire(aShapeBase);
+ TopExp_Explorer exp (aWire, TopAbs_EDGE);
+ for (; exp.More(); exp.Next()) {
+ anEdgeShapes.Add(exp.Current());
+ TopoDS_Edge E = TopoDS::Edge(exp.Current());
+ TopExp::Vertices(E, aV1, aV2);
+ if ( aVertexShapes.Extent() == 0)
+ aVertexShapes.Add(aV1);
+ if ( !aV1.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
+ aVertexShapes.Add(aV1);
+ if ( !aV2.IsSame( aVertexShapes(aVertexShapes.Extent()) ) )
+ aVertexShapes.Add(aV2);
+ }
+
+ if (index < 0 || index > aVertexShapes.Extent())
+ Standard_NullObject::Raise("Vertex index is out of range");
+
+ if (aWire.Orientation() == TopAbs_FORWARD)
+ aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(index+1)));
+ else
+ aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(aVertexShapes.Extent() - index)));
+ } else {
+ Standard_NullObject::Raise("Shape for vertex calculation is not an edge or wire");
+ }
+
+ aShape = BRepBuilderAPI_MakeVertex(aVertex).Shape();
+ }
else if (aType == VECTOR_FACE_NORMALE)
{
// Face
diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx
index b6b753451..bab5e2de2 100755
--- a/src/GEOMImpl/GEOMImpl_Types.hxx
+++ b/src/GEOMImpl/GEOMImpl_Types.hxx
@@ -113,6 +113,7 @@
#define VECTOR_DX_DY_DZ 2
#define VECTOR_TANGENT_CURVE_PAR 3
#define VECTOR_FACE_NORMALE 4
+#define VERTEX_BY_INDEX 5
#define PLANE_PNT_VEC 1
#define PLANE_FACE 2
diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.cc b/src/GEOM_I/GEOM_IMeasureOperations_i.cc
index f3e332365..0508b7945 100644
--- a/src/GEOM_I/GEOM_IMeasureOperations_i.cc
+++ b/src/GEOM_I/GEOM_IMeasureOperations_i.cc
@@ -149,6 +149,31 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetCentreOfMass
return GetObject(anObject);
}
+//=============================================================================
+/*!
+ * GetVertexByIndex
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetVertexByIndex
+ (GEOM::GEOM_Object_ptr theShape, CORBA::Long theIndex)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Set a not done flag
+ GetOperations()->SetNotDone();
+
+ //Get the reference shape
+ Handle(GEOM_Object) aShape = GetObjectImpl(theShape);
+ if ( aShape.IsNull() ) return aGEOMObject._retn();
+
+ // Get vertex by index
+ Handle(GEOM_Object) anObject = GetOperations()->GetVertexByIndex(aShape, theIndex);
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
//=============================================================================
/*!
* GetNormal
diff --git a/src/GEOM_I/GEOM_IMeasureOperations_i.hh b/src/GEOM_I/GEOM_IMeasureOperations_i.hh
index 1aace732a..51a1ec8f0 100644
--- a/src/GEOM_I/GEOM_IMeasureOperations_i.hh
+++ b/src/GEOM_I/GEOM_IMeasureOperations_i.hh
@@ -60,6 +60,9 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
GEOM::GEOM_Object_ptr GetNormal (GEOM::GEOM_Object_ptr theFace,
GEOM::GEOM_Object_ptr theOptionalPoint);
+ GEOM::GEOM_Object_ptr GetVertexByIndex (GEOM::GEOM_Object_ptr theObject,
+ CORBA::Long theIndex);
+
void GetInertia (GEOM::GEOM_Object_ptr theShape,
CORBA::Double& I11, CORBA::Double& I12, CORBA::Double& I13,
CORBA::Double& I21, CORBA::Double& I22, CORBA::Double& I23,
diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py
index 13a4c5ef6..d118084b9 100644
--- a/src/GEOM_SWIG/geompyDC.py
+++ b/src/GEOM_SWIG/geompyDC.py
@@ -3231,6 +3231,41 @@ class geompyDC(GEOM._objref_GEOM_Gen):
RaiseIfFailed("GetCentreOfMass", self.MeasuOp)
return anObj
+ ## Get a vertex subshape by index depended with orientation.
+ # @param theShape Shape to find subshape.
+ # @param theIndex Index to find vertex by this index.
+ # @return New GEOM_Object, containing the created vertex.
+ #
+ # @ref tui_measurement_tools_page "Example"
+ def GetVertexByIndex(self,theShape, theIndex):
+ # Example: see GEOM_TestMeasures.py
+ anObj = self.MeasuOp.GetVertexByIndex(theShape, theIndex)
+ RaiseIfFailed("GetVertexByIndex", self.MeasuOp)
+ return anObj
+
+ ## Get the first vertex of wire/edge depended orientation.
+ # @param theShape Shape to find first vertex.
+ # @return New GEOM_Object, containing the created vertex.
+ #
+ # @ref tui_measurement_tools_page "Example"
+ def GetFirstVertex(self,theShape):
+ # Example: see GEOM_TestMeasures.py
+ anObj = self.GetVertexByIndex(theShape, 0)
+ RaiseIfFailed("GetFirstVertex", self.MeasuOp)
+ return anObj
+
+ ## Get the last vertex of wire/edge depended orientation.
+ # @param theShape Shape to find last vertex.
+ # @return New GEOM_Object, containing the created vertex.
+ #
+ # @ref tui_measurement_tools_page "Example"
+ def GetLastVertex(self,theShape):
+ # Example: see GEOM_TestMeasures.py
+ nb_vert = self.ShapesOp.NumberOfSubShapes(theShape, ShapeType["VERTEX"])
+ anObj = self.GetVertexByIndex(theShape, (nb_vert-1))
+ RaiseIfFailed("GetLastVertex", self.MeasuOp)
+ return anObj
+
## Get a normale to the given face. If the point is not given,
# the normale is calculated at the center of mass.
# @param theFace Face to define normale of.