]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
NPAL14856: Get The Normal of a Face.
authorjfa <jfa@opencascade.com>
Wed, 24 Oct 2007 06:46:07 +0000 (06:46 +0000)
committerjfa <jfa@opencascade.com>
Wed, 24 Oct 2007 06:46:07 +0000 (06:46 +0000)
20 files changed:
Makefile.in
idl/GEOM_Gen.idl
resources/normale.png [new file with mode: 0644]
src/GEOMGUI/GEOM_images.po
src/GEOMGUI/GEOM_msg_en.po
src/GEOMGUI/GeometryGUI.cxx
src/GEOMImpl/GEOMImpl_IMeasure.hxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_I3DPrimOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_SWIG/GEOM_TestMeasures.py
src/GEOM_SWIG/geompy.py
src/MeasureGUI/Makefile.in
src/MeasureGUI/MeasureGUI.cxx
src/MeasureGUI/MeasureGUI_NormaleDlg.cxx [new file with mode: 0644]
src/MeasureGUI/MeasureGUI_NormaleDlg.h [new file with mode: 0644]

index d5d2bfb1e8fe68710efed2cdc8390adfc480caa7..4359b01f27fde022b469bc0d9bedd56bbdff78ce 100644 (file)
@@ -108,6 +108,7 @@ multirotationsimple.png \
 multitranslation.png \
 multitranslationdouble.png \
 multitranslationsimple.png \
+normale.png \
 offset.png \
 orientation.png \
 partition.png \
index 815775ff9b8e61a870f9c437da5a711ae83832eb..fa99c0db3d1e4f90a883c1f65d43952993d68a95 100644 (file)
@@ -918,8 +918,7 @@ module GEOM
      *  \return New GEOM_Object, containing the created solids.
      */
     GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases,
-                                          in ListOfGO theLocations );
-
+                                          in ListOfGO theLocations);
   };
 
   /*!
@@ -2344,6 +2343,17 @@ module GEOM
      */
     GEOM_Object GetCentreOfMass (in GEOM_Object theShape);
 
+    /*!
+     *  Get a vector, representing the normal of theFace.
+     *  If the face is not planar, theOptionalPoint is obligatory.
+     *  \param theFace Shape (face) to define the normal of.
+     *  \param theOptionalPoint Shape (point) to define the normal at.
+     *                          Can be NULL in case of planar face.
+     *  \return New GEOM_Object, containing the created normal vector.
+     */
+    GEOM_Object GetNormal (in GEOM_Object theFace,
+                          in GEOM_Object theOptionalPoint);
+
     /*!
      *  Get inertia matrix and moments of inertia of theShape.
      *  \param theShape Shape to calculate inertia of.
diff --git a/resources/normale.png b/resources/normale.png
new file mode 100644 (file)
index 0000000..7db7fb2
Binary files /dev/null and b/resources/normale.png differ
index f968ecac8d35917dfd6695cf9c37d3a01eab90fd..157ec0807755cca7298b670427a128cf0d661dcc 100644 (file)
@@ -209,6 +209,10 @@ msgstr "partitionplane.png"
 msgid "ICON_DLG_CENTERMASS"
 msgstr "centergravity.png"
 
+#NormaleDlg
+msgid "ICON_DLG_NORMALE"
+msgstr "normale.png"
+
 #BoundingBoxDlg
 msgid "ICON_DLG_BOUNDING_BOX"
 msgstr "bounding.png"
@@ -738,8 +742,8 @@ msgstr "point_coord.png"
 msgid "ICO_BASIC_PROPS"
 msgstr "basicproperties.png"
 
-msgid "ICO_MASS_CENTER"
-msgstr "centergravity.png"
+msgid "ICO_NORMALE"
+msgstr "normale.png"
 
 msgid "ICO_INERTIA"
 msgstr "axisinertia.png"
index 958384b10d6b7c8d172cf9177cb7e12215c2fc86..8db6a7dc93738eb851c8bfc0ec11e097a37519e0 100644 (file)
@@ -588,6 +588,13 @@ msgstr "Bounding Box"
 msgid "GEOM_CMASS"
 msgstr "Center Of Mass"
 
+#Normale
+msgid "GEOM_NORMALE"
+msgstr "Normale To A Face"
+
+msgid "GEOM_VECTOR_NORMALE"
+msgstr "Vector_Normale"
+
 #Basic Properties
 msgid "GEOM_PROPERTIES"
 msgstr "Basic Properties"
@@ -862,6 +869,10 @@ msgstr "Circle Construction"
 msgid "GEOM_CMASS_TITLE"
 msgstr "Center Of Mass Construction"
 
+#: GeometryGUI_NormaleDlg.cxx:57
+msgid "GEOM_NORMALE_TITLE"
+msgstr "Create Normale To A Face"
+
 msgid "GEOM_PLANE_SIZE"
 msgstr "Size of plane :"
 
@@ -2727,6 +2738,15 @@ msgstr "Center of mass"
 msgid "STB_MASS_CENTER"
 msgstr "Compute center of mass"
 
+msgid "TOP_NORMALE"
+msgstr "Compute normale to a face"
+
+msgid "MEN_NORMALE"
+msgstr "Normale to a face"
+
+msgid "STB_NORMALE"
+msgstr "Compute normale to a face in a point (optional)"
+
 msgid "TOP_INERTIA"
 msgstr "Compute intertia"
 
index f57fd8e52b740bac42f5b1b4e2edb54b3c59468a..cfecf056a4c02743cdf0d49175b8503900902fed 100644 (file)
@@ -524,6 +524,7 @@ void GeometryGUI::OnGUIEvent( int id )
   else if( id == 701   ||  // MENU MEASURE - PROPERTIES
           id == 702   ||  // MENU MEASURE - CDG
           id == 703   ||  // MENU MEASURE - INERTIA
+          id == 704   ||  // MENU MEASURE - NORMALE
           id == 7041  ||  // MENU MEASURE - BOUNDING BOX
           id == 7042  ||  // MENU MEASURE - MIN DISTANCE
           id == 7043  ||  // MENU MEASURE - ANGLE
@@ -847,6 +848,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createGeomAction( 701, "BASIC_PROPS" );
   createGeomAction( 702, "MASS_CENTER" );
   createGeomAction( 703, "INERTIA" );
+  createGeomAction( 704, "NORMALE" );
   createGeomAction( 7041, "BND_BOX" );
   createGeomAction( 7042, "MIN_DIST" );
   createGeomAction( 7043, "MEASURE_ANGLE" );
@@ -1002,6 +1004,7 @@ void GeometryGUI::initialize( CAM_Application* app )
   createMenu( separator(), measurId, -1 );
   createMenu( 702, measurId, -1 );
   createMenu( 703, measurId, -1 );
+  createMenu( 704, measurId, -1 );
   // NPAL16572: move "Check free boundaries" and "Check free faces" from "Repair" to "Measure"
   createMenu( separator(), measurId, -1 );
   createMenu( 609, measurId, -1 );
index 80915550b6c19724489ad2eaa5f31a697b7f2f9a..db615f1f309e4100cbdb2ece9fee860f1eea779d 100644 (file)
 
 #include "GEOM_Function.hxx"
 
-#define MEASURE_ARG_BASE 1
+//#define MEASURE_ARG_BASE  1
+//#define MEASURE_ARG_POINT 2
 
 class GEOMImpl_IMeasure
 {
+  enum {
+    MEASURE_ARG_BASE  = 1,
+    MEASURE_ARG_POINT = 2
+  };
  public:
 
   GEOMImpl_IMeasure(Handle(GEOM_Function) theFunction): _func(theFunction) {}
@@ -35,6 +40,11 @@ class GEOMImpl_IMeasure
 
   Handle(GEOM_Function) GetBase() { return _func->GetReference(MEASURE_ARG_BASE); }
 
+  void SetPoint(Handle(GEOM_Function) thePnt)
+  { _func->SetReference(MEASURE_ARG_POINT, thePnt); }
+
+  Handle(GEOM_Function) GetPoint() { return _func->GetReference(MEASURE_ARG_POINT); }
+
  private:
 
   Handle(GEOM_Function) _func;
index 5925ea6d438023aa229ae0cf69af57eb1cf7929d..67e26c014cc29827521856b05b77f591594396f0 100644 (file)
@@ -878,6 +878,70 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
   return aCDG;
 }
 
+//=============================================================================
+/*!
+ *  GetNormal
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
+                                         (Handle(GEOM_Object) theFace,
+                                          Handle(GEOM_Object) theOptionalPoint)
+{
+  SetErrorCode(KO);
+
+  if (theFace.IsNull()) return NULL;
+
+  //Add a new Normale object
+  Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
+
+  //Add a new Normale function
+  Handle(GEOM_Function) aFunction =
+    aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
+  if (aFunction.IsNull()) return NULL;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
+
+  GEOMImpl_IMeasure aCI (aFunction);
+
+  Handle(GEOM_Function) aFace = theFace->GetLastFunction();
+  if (aFace.IsNull()) return NULL;
+
+  aCI.SetBase(aFace);
+
+  if (!theOptionalPoint.IsNull()) {
+    Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
+    aCI.SetPoint(anOptPnt);
+  }
+
+  //Compute the Normale value
+  try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Measure driver failed to compute normake of face");
+      return NULL;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return NULL;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump pd (aFunction);
+  pd << aNorm << " = geompy.GetNormal(" << theFace;
+  if (!theOptionalPoint.IsNull()) {
+    pd << ", " << theOptionalPoint;
+  }
+  pd << ")";
+
+  SetErrorCode(OK);
+  return aNorm;
+}
+
 //=============================================================================
 /*!
  *  GetBasicProperties
index 2c221f3f32fa523fb2b32c2682d3399a72438f97..24f6e52537e682ecdb602c6e918bd698cf505fb8 100644 (file)
@@ -90,6 +90,9 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
 
   Standard_EXPORT Handle(GEOM_Object) GetCentreOfMass (Handle(GEOM_Object) theShape);
 
+  Standard_EXPORT Handle(GEOM_Object) GetNormal (Handle(GEOM_Object) theFace,
+                                                 Handle(GEOM_Object) theOptionalPoint);
+
   Standard_EXPORT void GetBasicProperties (Handle(GEOM_Object) theShape,
                                            Standard_Real& theLength,
                                            Standard_Real& theSurfArea,
index 52fdd93ceb5ccd9f49f192209272c2a8b377993b..69ffeabd874f4aa2a154569c45a43785ba6ed031 100644 (file)
 #include <BRep_Tool.hxx>
 #include <BRepGProp.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
 
 #include <TopAbs.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Shape.hxx>
 
 #include <GProp_GProps.hxx>
+#include <GeomLProp_SLProps.hxx>
+#include <Geom_Surface.hxx>
+
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <ShapeAnalysis_Surface.hxx>
 
 #include <gp_Pnt.hxx>
 #include <Precision.hxx>
@@ -73,7 +81,8 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
 
   TopoDS_Shape aShape;
 
-  if (aType == CDG_MEASURE) {
+  if (aType == CDG_MEASURE)
+  {
     Handle(GEOM_Function) aRefBase = aCI.GetBase();
     TopoDS_Shape aShapeBase = aRefBase->GetValue();
     if (aShapeBase.IsNull()) {
@@ -97,8 +106,99 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
     }
 
     aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
+  }
+  else if (aType == VECTOR_FACE_NORMALE)
+  {
+    // Face
+    Handle(GEOM_Function) aRefBase = aCI.GetBase();
+    TopoDS_Shape aShapeBase = aRefBase->GetValue();
+    if (aShapeBase.IsNull()) {
+      Standard_NullObject::Raise("Face for normale calculation is null");
+    }
+    if (aShapeBase.ShapeType() != TopAbs_FACE) {
+      Standard_NullObject::Raise("Shape for normale calculation is not a face");
+    }
+    TopoDS_Face aFace = TopoDS::Face(aShapeBase);
+
+    // Point
+    gp_Pnt p1 (0,0,0);
+
+    Handle(GEOM_Function) aPntFunc = aCI.GetPoint();
+    if (!aPntFunc.IsNull())
+    {
+      TopoDS_Shape anOptPnt = aPntFunc->GetValue();
+      if (anOptPnt.IsNull())
+        Standard_NullObject::Raise("Invalid shape given for point argument");
+      p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt));
+    }
+    else
+    {
+      gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace);
+      p1 = aPos.Location();
+    }
 
-  } else {
+    // Point parameters on surface
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+    Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf);
+    gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion());
+
+    // Normal direction
+    gp_Vec Vec1,Vec2;
+    BRepAdaptor_Surface SF (aFace);
+    SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2);
+    gp_Vec V = Vec1.Crossed(Vec2);
+    Standard_Real mod = V.Magnitude();
+    if (mod < Precision::Confusion())
+      Standard_NullObject::Raise("Normal vector of a face has null magnitude");
+
+    // Set length of normal vector to average radius of curvature
+    Standard_Real radius = 0.0;
+    GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion());
+    if (aProperties.IsCurvatureDefined()) {
+      Standard_Real radius1 = Abs(aProperties.MinCurvature());
+      Standard_Real radius2 = Abs(aProperties.MaxCurvature());
+      if (Abs(radius1) > Precision::Confusion()) {
+       radius = 1.0 / radius1;
+        if (Abs(radius2) > Precision::Confusion()) {
+          radius = (radius + 1.0 / radius2) / 2.0;
+        }
+      }
+      else {
+        if (Abs(radius2) > Precision::Confusion()) {
+          radius = 1.0 / radius2;
+        }
+      }
+    }
+
+    // Set length of normal vector to average dimension of the face
+    // (only if average radius of curvature is not appropriate)
+    if (radius < Precision::Confusion()) {
+        Bnd_Box B;
+        Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
+        BRepBndLib::Add(aFace, B);
+        B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+        radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0;
+    }
+
+    if (radius < Precision::Confusion())
+      radius = 1.0;
+
+    V *= radius / mod;
+
+    // consider the face orientation
+    if (aFace.Orientation() == TopAbs_REVERSED ||
+        aFace.Orientation() == TopAbs_INTERNAL) {
+      V = - V;
+    }
+
+    // Edge
+    gp_Pnt p2 = p1.Translated(V);
+    BRepBuilderAPI_MakeEdge aBuilder (p1, p2);
+    if (!aBuilder.IsDone())
+      Standard_NullObject::Raise("Vector construction failed");
+    aShape = aBuilder.Shape();
+  }
+  else {
   }
 
   if (aShape.IsNull()) return 0;
@@ -107,7 +207,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
 
   log.SetTouched(Label()); 
 
-  return 1;    
+  return 1;
 }
 
 
index 23b93efd56bd3a5bb1beb626d7a5ca1137abfe71..c33d81b14d7f3609fa5ef23362254b4f38632289 100755 (executable)
@@ -97,6 +97,7 @@
 #define VECTOR_TWO_PNT  1
 #define VECTOR_DX_DY_DZ 2
 #define VECTOR_TANGENT_CURVE_PAR 3
+#define VECTOR_FACE_NORMALE 4
 
 #define PLANE_PNT_VEC   1
 #define PLANE_FACE      2
index 2ae7c4a919f0b19ad26b40e8a47cab746c71049a..e730e0e0302df5827e339b6463a90785939633ac 100644 (file)
@@ -663,7 +663,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
 
 //=============================================================================
 /*!
- *  MakePipeWithShellSections
+ *  MakePipeShellsWithoutPath
  */
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
index 7be30405664d6ece01d23a17357ef47f0f4e8596..d4e8c6a8e67fc9bf8d9c74c332c330794d5b48f6 100644 (file)
@@ -141,7 +141,7 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetCentreOfMass
   //Set a not done flag
   GetOperations()->SetNotDone();
 
-  if (theShape == NULL) return aGEOMObject._retn();
+  if (CORBA::is_nil(theShape)) return aGEOMObject._retn();
 
   //Get the reference shape
   Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject
@@ -157,6 +157,41 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetCentreOfMass
   return GetObject(anObject);
 }
 
+//=============================================================================
+/*!
+ *  GetNormal
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::GetNormal
+                                       (GEOM::GEOM_Object_ptr theFace,
+                                       GEOM::GEOM_Object_ptr theOptionalPoint)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+
+  if (CORBA::is_nil(theFace)) return aGEOMObject._retn();
+
+  //Get the reference shape
+  Handle(GEOM_Object) aFace = GetOperations()->GetEngine()->GetObject
+    (theFace->GetStudyID(), theFace->GetEntry());
+
+  if (aFace.IsNull()) return aGEOMObject._retn();
+
+  // Make Vector - normal to theFace (in point theOptionalPoint if the face is not planar)
+  Handle(GEOM_Object) anOptionalPoint;
+  if (!CORBA::is_nil(theOptionalPoint)) {
+    anOptionalPoint = GetOperations()->GetEngine()->GetObject
+      (theOptionalPoint->GetStudyID(), theOptionalPoint->GetEntry());
+  }
+  Handle(GEOM_Object) anObject = GetOperations()->GetNormal(aFace, anOptionalPoint);
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
+
 //=============================================================================
 /*!
  *  GetBasicProperties
index 702162edc82592875de2b6c75355fc3656c44a99..a0bfa76b38a8df769d1d9b214825968df5a06f33 100644 (file)
@@ -55,6 +55,9 @@ class GEOM_IMeasureOperations_i :
 
   GEOM::GEOM_Object_ptr GetCentreOfMass (GEOM::GEOM_Object_ptr theShape);
 
+  GEOM::GEOM_Object_ptr GetNormal (GEOM::GEOM_Object_ptr theFace,
+                                  GEOM::GEOM_Object_ptr theOptionalPoint);
+
   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,
index 1ca3cbccdd3f63b53ae0d1530bcf85ead5ed3519..d552abf06bbd65181a39bf9619f0058a2d93a22c 100644 (file)
@@ -109,6 +109,22 @@ def TestMeasureOperations (geompy, math):
     if Coords[0] != 5 or Coords[1] != 15 or Coords[2] != 35:
       print "But must be (5, 15, 35)"
 
+  ####### GetNormal #######
+
+  faces = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])
+  face0 = faces[0]
+  vnorm = geompy.GetNormal(face0)
+  if vnorm is None:
+    raise RuntimeError, "GetNormal(face0) failed"
+  else:
+    geompy.addToStudy(face0, "Face0")
+    geompy.addToStudy(vnorm, "Normale to Face0")
+    print "\nNormale of face has been successfully obtained:"
+    #Coords = geompy.PointCoordinates(pcdg)
+    #print "(", Coords[0], ", ", Coords[1], ", ", Coords[2], ")"
+    #if Coords[0] != 5 or Coords[1] != 15 or Coords[2] != 35:
+    #  print "But must be (5, 15, 35)"
+
   ####### MinDistance #######
 
   MinDist = geompy.MinDistance(box, cube)
index b634cb1411e7424bd93d0c2d599175d1693daaf5..72e3c6e6559e817730bbdf57c5ed203f4cb2396c 100644 (file)
@@ -746,7 +746,6 @@ def MakeThruSections(theSeqSections,theModeSolid,thePreci,theRuled):
 #                            orthogonal to the spine tangent in the correspondent point
 #  @return New GEOM_Object, containing the created pipe.
 #
-#  Example: see GEOM_TestAll.py
 def MakePipeWithDifferentSections(theSeqBases, theLocations,thePath,theWithContact,theWithCorrection):
     anObj = PrimOp.MakePipeWithDifferentSections(theSeqBases, theLocations,thePath,theWithContact,theWithCorrection)
     if PrimOp.IsDone() == 0:
@@ -770,7 +769,6 @@ def MakePipeWithDifferentSections(theSeqBases, theLocations,thePath,theWithConta
 #                            orthogonal to the spine tangent in the correspondent point
 #  @return New GEOM_Object, containing the created solids.
 #
-#  Example: see GEOM_TestAll.py
 def MakePipeWithShellSections(theSeqBases, theSeqSubBases,
                               theLocations, thePath,
                               theWithContact, theWithCorrection):
@@ -818,7 +816,6 @@ def MakePipeWithShellSectionsBySteps(theSeqBases, theSeqSubBases,
 #  @param theLocations - list of corresponding vertexes
 #  @return New GEOM_Object, containing the created solids.
 #
-#  Example: see GEOM_TestAll.py
 def MakePipeShellsWithoutPath(theSeqBases, theLocations):
     anObj = PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations)
     if PrimOp.IsDone() == 0:
@@ -2157,6 +2154,19 @@ def MakeCDG(theShape):
       print "GetCentreOfMass : ", MeasuOp.GetErrorCode()
     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.
+#  @param theOptionalPoint Point to compute the normale at.
+#  @return New GEOM_Object, containing the created vector.
+#
+#  Example: see GEOM_TestMeasures.py
+def GetNormal(theFace, theOptionalPoint = None):
+    anObj = MeasuOp.GetNormal(theFace, theOptionalPoint)
+    if MeasuOp.IsDone() == 0:
+      print "GetNormal : ", MeasuOp.GetErrorCode()
+    return anObj
+
 ## Check a topology of the given shape.
 #  @param theShape Shape to check validity of.
 #  @param theIsCheckGeom If FALSE, only the shape's topology will be checked,
index 8391f494e2c82bf043837e31ca2687ee432cf6dc..0a1e09cd936718cf74fb77b416c17a432ba832e0 100644 (file)
@@ -51,6 +51,7 @@ LIB_SRC =     MeasureGUI.cxx \
                MeasureGUI_Skeleton.cxx \
                MeasureGUI_PropertiesDlg.cxx \
                MeasureGUI_CenterMassDlg.cxx \
+               MeasureGUI_NormaleDlg.cxx \
                MeasureGUI_InertiaDlg.cxx \
                MeasureGUI_BndBoxDlg.cxx \
                MeasureGUI_DistanceDlg.cxx \
@@ -72,6 +73,7 @@ LIB_MOC = \
                MeasureGUI_Skeleton.h \
                MeasureGUI_PropertiesDlg.h \
                MeasureGUI_CenterMassDlg.h \
+               MeasureGUI_NormaleDlg.h \
                MeasureGUI_InertiaDlg.h \
                MeasureGUI_BndBoxDlg.h \
                MeasureGUI_DistanceDlg.h \
index b872ced4c3762d23d7a27ce43c74859ab6e5856b..ebd3dbaf694ed9e120f1deb3df6c96da571d8476 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "MeasureGUI_PropertiesDlg.h"    // Method PROPERTIES
 #include "MeasureGUI_CenterMassDlg.h"    // Method CENTER MASS
+#include "MeasureGUI_NormaleDlg.h"       // Method NORMALE
 #include "MeasureGUI_InertiaDlg.h"       // Method INERTIA
 #include "MeasureGUI_BndBoxDlg.h"        // Method BNDBOX
 #include "MeasureGUI_DistanceDlg.h"      // Method DISTANCE
@@ -78,6 +79,7 @@ bool MeasureGUI::OnGUIEvent( int theCommandID, SUIT_Desktop* parent )
     case 701 : new MeasureGUI_PropertiesDlg  (getGeometryGUI(), parent); break; // LENGTH, AREA AND VOLUME
     case 702 : new MeasureGUI_CenterMassDlg  (getGeometryGUI(), parent); break; // CENTER MASS
     case 703 : new MeasureGUI_InertiaDlg     (getGeometryGUI(), parent); break; // INERTIA
+    case 704 : new MeasureGUI_NormaleDlg     (getGeometryGUI(), parent); break; // NORMALE
     case 7041: new MeasureGUI_BndBoxDlg      (getGeometryGUI(), parent); break; // BOUNDING BOX
     case 7042: new MeasureGUI_DistanceDlg    (getGeometryGUI(), parent); break; // MIN DISTANCE
     case 7043: new MeasureGUI_AngleDlg       (getGeometryGUI(), parent); break; // ANGLE
diff --git a/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx b/src/MeasureGUI/MeasureGUI_NormaleDlg.cxx
new file mode 100644 (file)
index 0000000..32c6d9a
--- /dev/null
@@ -0,0 +1,281 @@
+//  GEOM GEOMGUI : GUI for Geometry component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+//  File   : MeasureGUI_NormaleDlg.cxx
+//  Author : Julia DOROVSKIKH
+//  Module : GEOM
+//  $Header$
+
+#include "MeasureGUI_NormaleDlg.h"
+
+#include "SUIT_Session.h"
+#include "SalomeApp_Application.h"
+#include "LightApp_SelectionMgr.h"
+
+#include <qlabel.h>
+
+#include "GEOMImpl_Types.hxx"
+
+#include "utilities.h"
+
+//=================================================================================
+// class    : MeasureGUI_NormaleDlg()
+// purpose  : Constructs a MeasureGUI_NormaleDlg which is a child of 'parent', with the
+//            name 'name' and widget flags set to 'f'.
+//            The dialog will by default be modeless, unless you set 'modal' to
+//            TRUE to construct a modal dialog.
+//=================================================================================
+MeasureGUI_NormaleDlg::MeasureGUI_NormaleDlg (GeometryGUI* theGeometryGUI, QWidget* parent,
+                                              const char* name, bool modal, WFlags fl)
+  :GEOMBase_Skeleton(theGeometryGUI, parent, name, modal, WStyle_Customize |
+                     WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+{
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_NORMALE")));
+  QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
+
+  setCaption(tr("GEOM_NORMALE_TITLE"));
+
+  /***************************************************************/
+  GroupConstructors->setTitle(tr("GEOM_NORMALE"));
+  RadioButton1->setPixmap(image0);
+  RadioButton2->close(TRUE);
+  RadioButton3->close(TRUE);
+
+  GroupArgs = new DlgRef_2Sel_QTD (this, "GroupArgs");
+  GroupArgs->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
+
+  GroupArgs->TextLabel1->setText(tr("GEOM_FACE"));
+  GroupArgs->TextLabel2->setText(tr("GEOM_POINT"));
+
+  GroupArgs->PushButton1->setPixmap(image1);
+  GroupArgs->PushButton2->setPixmap(image1);
+
+  Layout1->addWidget(GroupArgs, 2, 0);
+  /***************************************************************/
+
+  setHelpFileName("normale.htm");
+
+  Init();
+}
+
+//=================================================================================
+// function : ~MeasureGUI_NormaleDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+MeasureGUI_NormaleDlg::~MeasureGUI_NormaleDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::Init()
+{
+  /* init variables */
+  GroupArgs->LineEdit1->setReadOnly(true);
+  GroupArgs->LineEdit2->setReadOnly(true);
+
+  myFace = GEOM::GEOM_Object::_nil();
+  myPoint = GEOM::GEOM_Object::_nil();
+
+  myEditCurrentArgument = GroupArgs->LineEdit1;
+  globalSelection(GEOM_FACE);
+
+  /* signals and slots connections */
+  connect(buttonOk, SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+
+  connect(GroupArgs->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(GroupArgs->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+
+  connect(GroupArgs->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+  connect(GroupArgs->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+
+  connect(myGeomGUI->getApp()->selectionMgr(),
+         SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+
+  initName(tr("GEOM_VECTOR_NORMALE"));
+
+  //ConstructorsClicked(0);
+  SelectionIntoArgument();
+
+  /* displays Dialog */
+  GroupArgs->show();
+  this->show();
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::ClickOnOk()
+{
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool MeasureGUI_NormaleDlg::ClickOnApply()
+{
+  if (!onAccept())
+    return false;
+
+  initName();
+  return true;
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void MeasureGUI_NormaleDlg::SelectionIntoArgument()
+{
+  erasePreview();
+  myEditCurrentArgument->setText("");
+
+  if (myEditCurrentArgument == GroupArgs->LineEdit1) {
+    myFace = GEOM::GEOM_Object::_nil();
+  }
+  else if (myEditCurrentArgument == GroupArgs->LineEdit2) {
+    myPoint = GEOM::GEOM_Object::_nil();
+  }
+
+  if (IObjectCount() != 1)
+    return;
+
+  // nbSel == 1
+  Standard_Boolean testResult = Standard_False;
+  GEOM::GEOM_Object_var aSelectedObject =
+    GEOMBase::ConvertIOinGEOMObject(firstIObject(), testResult);
+
+  if (!testResult)
+    return;
+
+  if (myEditCurrentArgument == GroupArgs->LineEdit1) {
+    myFace = aSelectedObject;
+  }
+  else if (myEditCurrentArgument == GroupArgs->LineEdit2) {
+    myPoint = aSelectedObject;
+  }
+
+  myEditCurrentArgument->setText(GEOMBase::GetName(aSelectedObject));
+
+  displayPreview();
+}
+
+//=================================================================================
+// function : LineEditReturnPressed()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::LineEditReturnPressed()
+{
+  QLineEdit* send = (QLineEdit*)sender();
+  if (send == GroupArgs->LineEdit1 ||
+      send == GroupArgs->LineEdit2)
+  {
+    myEditCurrentArgument = send;
+    GEOMBase_Skeleton::LineEditReturnPressed();
+  }
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  if (send == GroupArgs->PushButton1) {
+    myEditCurrentArgument = GroupArgs->LineEdit1;
+    globalSelection(GEOM_FACE);
+  }
+  else if (send == GroupArgs->PushButton2) {
+    myEditCurrentArgument = GroupArgs->LineEdit2;
+    globalSelection(GEOM_POINT);
+  }
+
+  myEditCurrentArgument->setFocus();
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::ActivateThisDialog()
+{
+  GEOMBase_Skeleton::ActivateThisDialog();
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void MeasureGUI_NormaleDlg::enterEvent (QEvent* e)
+{
+  if (!GroupConstructors->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : createOperation
+// purpose  :
+//=================================================================================
+GEOM::GEOM_IOperations_ptr MeasureGUI_NormaleDlg::createOperation()
+{
+  return getGeomEngine()->GetIMeasureOperations(getStudyId());
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+bool MeasureGUI_NormaleDlg::isValid (QString&)
+{
+  //return !CORBA::is_nil(myFace) && !CORBA::is_nil(myPoint);
+  return !CORBA::is_nil(myFace);
+}
+
+//=================================================================================
+// function : execute
+// purpose  :
+//=================================================================================
+bool MeasureGUI_NormaleDlg::execute (ObjectList& objects)
+{
+  GEOM::GEOM_Object_var anObj =
+    GEOM::GEOM_IMeasureOperations::_narrow(getOperation())->GetNormal(myFace, myPoint);
+
+  if (!anObj->_is_nil())
+    objects.push_back(anObj._retn());
+
+  return true;
+}
diff --git a/src/MeasureGUI/MeasureGUI_NormaleDlg.h b/src/MeasureGUI/MeasureGUI_NormaleDlg.h
new file mode 100644 (file)
index 0000000..543914a
--- /dev/null
@@ -0,0 +1,72 @@
+//  GEOM GEOMGUI : GUI for Geometry component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//
+//
+//  File   : MeasureGUI_NormaleDlg.h
+//  Author : Julia DOROVSKIKH
+//  Module : GEOM
+
+#ifndef DIALOGBOX_NORMALE_H
+#define DIALOGBOX_NORMALE_H
+
+#include "GEOMBase_Skeleton.h"
+#include "DlgRef_2Sel_QTD.h"
+
+//=================================================================================
+// class    : MeasureGUI_NormaleDlg
+// purpose  :
+//=================================================================================
+class MeasureGUI_NormaleDlg : public GEOMBase_Skeleton
+{
+    Q_OBJECT
+
+public:
+    MeasureGUI_NormaleDlg (GeometryGUI* theGeometryGUI, QWidget* parent = 0,
+                          const char* name = 0, bool modal = FALSE, WFlags fl = 0);
+    ~MeasureGUI_NormaleDlg();
+
+protected:
+    // redefined from GEOMBase_Helper
+    virtual GEOM::GEOM_IOperations_ptr createOperation();
+    virtual bool isValid (QString& msg);
+    virtual bool execute (ObjectList& objects);
+
+private:
+    void Init();
+    void enterEvent (QEvent* e);
+
+    GEOM::GEOM_Object_var myFace;
+    GEOM::GEOM_Object_var myPoint;
+
+    DlgRef_2Sel_QTD* GroupArgs;
+
+private slots:
+    void ClickOnOk();
+    bool ClickOnApply();
+
+    void ActivateThisDialog();
+    void LineEditReturnPressed();
+    void SelectionIntoArgument();
+    void SetEditCurrentArgument();
+};
+
+#endif // DIALOGBOX_NORMALE_H