]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
NPAL14856: Get The Normal of a Face. And merge MakePipeShellsWithoutPath from 3.2.X.
authorjfa <jfa@opencascade.com>
Wed, 24 Oct 2007 06:48:22 +0000 (06:48 +0000)
committerjfa <jfa@opencascade.com>
Wed, 24 Oct 2007 06:48:22 +0000 (06:48 +0000)
27 files changed:
idl/GEOM_Gen.idl
idl/GEOM_Superv.idl
resources/Makefile.am
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_I3DPrimOperations.cxx
src/GEOMImpl/GEOMImpl_I3DPrimOperations.hxx
src/GEOMImpl/GEOMImpl_IMeasure.hxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
src/GEOMImpl/GEOMImpl_PipeDriver.cxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOM_I/GEOM_I3DPrimOperations_i.cc
src/GEOM_I/GEOM_I3DPrimOperations_i.hh
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_I_Superv/GEOM_Superv_i.cc
src/GEOM_I_Superv/GEOM_Superv_i.hh
src/GEOM_SWIG/GEOM_TestMeasures.py
src/GEOM_SWIG/geompyDC.py
src/MeasureGUI/Makefile.am
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 9c161c2e3951dd576a59203af9a1d41287ef33ad..fa99c0db3d1e4f90a883c1f65d43952993d68a95 100644 (file)
@@ -910,7 +910,15 @@ module GEOM
                                           in GEOM_Object thePath,
                                           in boolean theWithContact ,
                                           in boolean theWithCorrection );
-    
+
+    /*!
+     * Create solids between given sections
+     *  \param theSeqBases - list of sections (shell or face).
+     *  \param theLocations - list of corresponding vertexes
+     *  \return New GEOM_Object, containing the created solids.
+     */
+    GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases,
+                                          in ListOfGO theLocations);
   };
 
   /*!
@@ -1792,7 +1800,7 @@ module GEOM
     GEOM_Object MakeCircleThreePnt (in GEOM_Object thePnt1,
                                    in GEOM_Object thePnt2,
                                    in GEOM_Object thePnt3);
-/*!
+    /*!
      *  Create a circle with given center, with a radius equals the distance from center to Point1
      *  and on a plane defined by all of three points.
      *  \param thePnt1,thePnt2,thePnt3 Points, defining the circle.
@@ -1938,6 +1946,7 @@ module GEOM
                                     in double      theR1,
                                     in double      theR2,
                                     in ListOfLong  theEdges);
+
     /*!
      *  Perform a fillet on all edges of the specified faces of the given shape.
      *  \param theShape Shape, to perform fillet on.
@@ -1954,6 +1963,7 @@ module GEOM
                                     in double      theR1,
                                     in double      theR2,
                                     in ListOfLong  theFaces);
+
     /*!
      *  Perform a symmetric chamfer on all edges of the given shape.
      *  \param theShape Shape, to perform chamfer on.
@@ -1984,6 +1994,7 @@ module GEOM
     GEOM_Object MakeChamferEdgeAD (in GEOM_Object theShape,
                                   in double theD, in double theAngle,
                                   in long theFace1, in long theFace2);
+
     /*!
      *  Perform a chamfer on all edges of the specified faces.
      *  with distance D1 on the first specified face (if several for one edge)
@@ -2026,6 +2037,7 @@ module GEOM
     GEOM_Object MakeChamferEdgesAD (in GEOM_Object theShape,
                                    in double theD, in double theAngle,
                                    in ListOfLong theEdges);
+
     /*!
      *  Perform an Archimde operation on the given shape with given parameters.
      *                    The object presenting the resulting face is returned
@@ -2331,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.
index 7eaab4b6c81a5654b50aeadc0441a0396011dc3e..e217d4077d9a2a51ff7ca82eaf19a94e3835f97e 100644 (file)
@@ -184,6 +184,9 @@ module GEOM
                                           in boolean theWithContact ,
                                           in boolean theWithCorrection );
     
+    GEOM_Object MakePipeShellsWithoutPath (in ListOfGO theSeqBases,
+                                          in ListOfGO theLocations );
+
     //-----------------------------------------------------------//
     // BooleanOperations                                         //
     //-----------------------------------------------------------//
index 9db0990858f7066f483f31d218646d7ff6ef2eb3..50a6231049a9f2b930aa64006d8790dc5ed223e9 100644 (file)
@@ -98,6 +98,7 @@ multirotationsimple.png \
 multitranslation.png \
 multitranslationdouble.png \
 multitranslationsimple.png \
+normale.png \
 offset.png \
 orientation.png \
 partition.png \
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 3bcaac2928e62d22747113eb6965014c95c44f18..f72ed036b6c511ff635a5b2560b1f9b9a8ce5cd5 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 de70f12593474c28353968098390da78e7401a07..2571cae0bcf3674515c4fd473f4b611caed9ef82 100644 (file)
@@ -1375,6 +1375,23 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
   
   pyDump<< "], [";
    
+  for(i =1 ; i <= nbSubBases; i++) {
+
+    Handle(Standard_Transient) anItem = theSubBases->Value(i);
+    if(anItem.IsNull())
+      continue;
+    
+    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
+    if(!anObj.IsNull()) {
+      pyDump<< anObj;
+      if(i < nbBases)
+       pyDump<<", ";
+    }
+    
+  }
+  
+  pyDump<< "], [";
+   
   for(i =1 ; i <= nbLocs; i++) {
 
     Handle(Standard_Transient) anItem = theLocations->Value(i);
@@ -1396,3 +1413,135 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeWithShellSections(
 
 }
 
+
+//=============================================================================
+/*!
+ *  MakePipeShellsWithoutPath
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakePipeShellsWithoutPath(
+               const Handle(TColStd_HSequenceOfTransient)& theBases,
+               const Handle(TColStd_HSequenceOfTransient)& theLocations)
+{
+  Handle(GEOM_Object) anObj;
+  SetErrorCode(KO);
+  if(theBases.IsNull())
+    return anObj;
+
+  Standard_Integer nbBases = theBases->Length();
+  
+  if (!nbBases)
+    return anObj;
+  
+  Standard_Integer nbLocs =  (theLocations.IsNull() ? 0 :theLocations->Length());
+
+  //Add a new Pipe object
+  Handle(GEOM_Object) aPipeDS = GetEngine()->AddObject(GetDocID(), GEOM_PIPE);
+  //Add a new Pipe function
+
+  Handle(GEOM_Function) aFunction =
+    aPipeDS->AddFunction(GEOMImpl_PipeDriver::GetID(), PIPE_SHELLS_WITHOUT_PATH);
+  if (aFunction.IsNull()) return anObj;
+
+  //Check if the function is set correctly
+  if (aFunction->GetDriverGUID() != GEOMImpl_PipeDriver::GetID()) return anObj;
+
+  GEOMImpl_IPipeShellSect aCI (aFunction);
+
+  Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aSeqLocs = new TColStd_HSequenceOfTransient;
+
+  Standard_Integer i =1;
+  for( ; i <= nbBases; i++) {
+
+    Handle(Standard_Transient) anItem = theBases->Value(i);
+    if(anItem.IsNull())
+      continue;
+    Handle(GEOM_Object) aBase = Handle(GEOM_Object)::DownCast(anItem);
+    if(aBase.IsNull())
+      continue;
+    Handle(GEOM_Function) aRefBase = aBase->GetLastFunction();
+    if(aRefBase.IsNull())
+      continue;
+
+    if(nbLocs) {
+      Handle(Standard_Transient) anItemLoc = theLocations->Value(i);
+      if(anItemLoc.IsNull())
+       continue;
+      Handle(GEOM_Object) aLoc = Handle(GEOM_Object)::DownCast(anItemLoc);
+      if(aLoc.IsNull())
+       continue;
+      Handle(GEOM_Function) aRefLoc = aLoc->GetLastFunction();
+      if(aRefLoc.IsNull())
+       continue;
+      aSeqLocs->Append(aRefLoc);
+    }
+
+    aSeqBases->Append(aRefBase);
+  }
+
+  if(!aSeqBases->Length())
+    return anObj;
+
+  aCI.SetBases(aSeqBases);
+  aCI.SetLocations(aSeqLocs);
+  
+  //Compute the Pipe value
+  try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+    OCC_CATCH_SIGNALS;
+#endif
+    if (!GetSolver()->ComputeFunction(aFunction)) {
+      SetErrorCode("Pipe with shell sections without path driver failed");
+      return anObj;
+    }
+  }
+  catch (Standard_Failure) {
+    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+    SetErrorCode(aFail->GetMessageString());
+    return anObj;
+  }
+
+  //Make a Python command
+  GEOM::TPythonDump pyDump(aFunction);
+  pyDump << aPipeDS << " = geompy.MakePipeShellsWithoutPath([";
+
+  for(i =1 ; i <= nbBases; i++) {
+
+    Handle(Standard_Transient) anItem = theBases->Value(i);
+    if(anItem.IsNull())
+      continue;
+    
+    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
+    if(!anObj.IsNull()) {
+      pyDump<< anObj;
+      if(i < nbBases)
+       pyDump<<", ";
+    }
+    
+  }
+  
+  pyDump<< "], [";
+   
+  for(i =1 ; i <= nbLocs; i++) {
+
+    Handle(Standard_Transient) anItem = theLocations->Value(i);
+    if(anItem.IsNull())
+      continue;
+    
+    Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(anItem);
+    if(!anObj.IsNull()) {
+      pyDump<< anObj;
+      if(i < nbLocs)
+       pyDump<<", ";
+    }
+  }  
+
+  pyDump<< "])";
+
+  SetErrorCode(OK);
+  return aPipeDS;
+
+}
+
index 5773f2f47f6dd5a8df88808d07a89558acc1f193..d3d7ba49caf426556a4f731f51c7ab7abcfc15ef 100644 (file)
@@ -94,6 +94,10 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
                bool theWithContact,
                bool theWithCorrections);
 
+  Standard_EXPORT Handle(GEOM_Object) MakePipeShellsWithoutPath(
+               const Handle(TColStd_HSequenceOfTransient)& theBases,
+               const Handle(TColStd_HSequenceOfTransient)& theLocations);
+
 };
 
 #endif
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 320debb037fbf2012a5febd1b89462c2929ed821..7bca5db26afc579953a1059d7cab7db6b7fb79eb 100644 (file)
@@ -31,6 +31,8 @@
 
 #include <ShapeAnalysis_FreeBounds.hxx>
 #include <ShapeAnalysis_Edge.hxx>
+#include <ShapeFix_Face.hxx>
+#include <ShapeFix_Shell.hxx>
 
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
@@ -41,6 +43,7 @@
 #include <BRepOffsetAPI_MakePipeShell.hxx>
 #include <GProp_GProps.hxx>
 #include <BRepGProp.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
 
 #include <TopAbs.hxx>
 #include <TopExp.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 
 #include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_Interpolate.hxx>
 #include <Geom_TrimmedCurve.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_BezierSurface.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_Conic.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_BSplineSurface.hxx>
+#include <GeomFill_BSplineCurves.hxx>
+#include <GeomConvert_ApproxCurve.hxx>
+#include <GeomConvert.hxx>
 
 #include <TColgp_SequenceOfPnt.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
+#include <TColgp_Array2OfPnt.hxx>
 #include <TColStd_HSequenceOfTransient.hxx>
 
 #include <Precision.hxx>
@@ -72,6 +88,8 @@
 #include "utilities.h"
 
 //#include "BRepTools.hxx"
+//#include "GeomTools.hxx"
+#include <GEOMAlgo_GlueAnalyser.hxx>
 
 
 //=======================================================================
@@ -108,6 +126,12 @@ static bool FillForOtherEdges(const TopoDS_Shape& F1,
   // creating map of vertex edges for both faces
   TopTools_IndexedDataMapOfShapeListOfShape aMapVertEdge1;
   TopExp::MapShapesAndAncestors(F1, TopAbs_VERTEX, TopAbs_EDGE, aMapVertEdge1);
+  if(!FF.Contains(F1))
+    cout<<"    FillForOtherEdges: map FF not contains key F1"<<endl;
+  if(!FF.Contains(E1))
+    cout<<"    FillForOtherEdges: map FF not contains key E1"<<endl;
+  if(!FF.Contains(V1))
+    cout<<"    FillForOtherEdges: map FF not contains key V1"<<endl;
   const TopoDS_Shape& F2 = FF.FindFromKey(F1);
   const TopoDS_Shape& E2 = FF.FindFromKey(E1);
   const TopoDS_Shape& V2 = FF.FindFromKey(V1);
@@ -121,6 +145,8 @@ static bool FillForOtherEdges(const TopoDS_Shape& F1,
 
   ShapeAnalysis_Edge sae;
   while(1) {
+    if(!aMapVertEdge1.Contains(VS1))
+      cout<<"    FillForOtherEdges: map aMapVertEdge1 not contains key VS1"<<endl;
     const TopTools_ListOfShape& aList1 = aMapVertEdge1.FindFromKey(VS1);
     //TopoDS_Shape E1next;
     TopTools_ListIteratorOfListOfShape anIter1(aList1);
@@ -128,6 +154,8 @@ static bool FillForOtherEdges(const TopoDS_Shape& F1,
       anIter1.Next();
     }
     //E1next = anIter1.Value();
+    if(!aMapVertEdge2.Contains(VS2))
+      cout<<"    FillForOtherEdges: map aMapVertEdge2 not contains key VS2"<<endl;
     const TopTools_ListOfShape& aList2 = aMapVertEdge2.FindFromKey(VS2);
     //TopoDS_Shape E2next;
     TopTools_ListIteratorOfListOfShape anIter2(aList2);
@@ -294,6 +322,109 @@ static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
 }
 
 
+//=======================================================================
+//function : FillCorrespondingEdges
+//purpose  : auxilary for CreatePipeShellsWithoutPath()
+//=======================================================================
+static bool FillCorrespondingEdges(const TopoDS_Shape& FS1,
+                                  const TopoDS_Shape& FS2,
+                                  const TopoDS_Vertex& aLoc1,
+                                  const TopoDS_Vertex& aLoc2,
+                                  TopTools_IndexedDataMapOfShapeShape& FF)
+{
+  //cout<<"FillCorrespondingEdges"<<endl;
+
+  gp_Pnt P1 = BRep_Tool::Pnt(aLoc1);
+  gp_Pnt P2 = BRep_Tool::Pnt(aLoc2);
+  gp_Vec aDir(P1,P2);
+
+  ShapeAnalysis_Edge sae;
+  double tol = Max( BRep_Tool::Tolerance(TopoDS::Face(FS1)),
+                   BRep_Tool::Tolerance(TopoDS::Face(FS2)) );
+  TopTools_MapOfShape Vs1,Vs2;
+
+  TopoDS_Vertex V11=aLoc1, V12=aLoc2, V21, V22;
+  TopoDS_Edge E1,E2;
+
+  TopExp_Explorer exp1;
+  for( exp1.Init(FS1,TopAbs_EDGE); exp1.More(); exp1.Next() ) {
+    E1 = TopoDS::Edge(exp1.Current());
+    TopoDS_Vertex V1 = sae.FirstVertex(E1);
+    TopoDS_Vertex V2 = sae.LastVertex(E1);
+    gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
+    gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
+    //cout<<"P11("<<P11.X()<<","<<P11.Y()<<","<<P11.Z()<<")"<<endl;
+    //cout<<"P21("<<P21.X()<<","<<P21.Y()<<","<<P21.Z()<<")"<<endl;
+    if(P1.Distance(Ptmp1)<tol) {
+      V21 = V2;
+      break;
+    }
+    if(P1.Distance(Ptmp2)<tol) {
+      V21 = V1;
+      break;
+    }
+  }
+
+  TopoDS_Edge E21,E22;
+  TopoDS_Vertex VE21,VE22;
+  int nbe=0;
+  for( exp1.Init(FS2,TopAbs_EDGE); exp1.More() && nbe<2; exp1.Next() ) {
+    TopoDS_Edge E = TopoDS::Edge(exp1.Current());
+    TopoDS_Vertex V1 = sae.FirstVertex(E);
+    TopoDS_Vertex V2 = sae.LastVertex(E);
+    gp_Pnt Ptmp1 = BRep_Tool::Pnt(V1);
+    gp_Pnt Ptmp2 = BRep_Tool::Pnt(V2);
+    if(P2.Distance(Ptmp1)<tol) {
+      if(nbe==0) {
+       E21 = E;
+       VE21 = V2;
+       nbe++;
+      }
+      else if(nbe==1) {
+       E22 = E;
+       VE22 = V2;
+       nbe++;
+      }
+    }
+    if(P2.Distance(Ptmp2)<tol) {
+      if(nbe==0) {
+       E21 = E;
+       VE21 = V1;
+       nbe++;
+      }
+      else if(nbe==1) {
+       E22 = E;
+       VE22 = V1;
+       nbe++;
+      }
+    }
+  }
+
+  gp_Pnt PV21 = BRep_Tool::Pnt(V21);
+  gp_Pnt PE21 = BRep_Tool::Pnt(VE21);
+  gp_Pnt PE22 = BRep_Tool::Pnt(VE22);
+  gp_Vec aDir1(PV21,PE21);
+  gp_Vec aDir2(PV21,PE22);
+  double ang1 = aDir.Angle(aDir1);
+  double ang2 = aDir.Angle(aDir2);
+  if(fabs(ang1)<fabs(ang2)) {
+    E2 = E21;
+    V22 = VE21;
+  }
+  else {
+    E2 = E22;
+    V22 = VE22;
+  }
+
+  FF.Add(V11,V12);
+  FF.Add(V21,V22);
+  FF.Add(E1,E2);
+
+  // find other pairs for vertexes and edges
+  return FillForOtherEdges(FS1,E1,V21,FF);
+}
+
+
 //=======================================================================
 //function : FindNextPairOfFaces
 //purpose  : auxilary for CreatePipeForShellSections()
@@ -312,6 +443,8 @@ static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
       if(aCI) delete aCI;
       Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find edge in map");
     }
+    if(!FF.Contains(E1))
+      cout<<"    FindNextPairOfFaces: map FF not contains key E1"<<endl;
     const TopoDS_Shape& E2 = FF.FindFromKey(E1);
     TopExp_Explorer anExpV;
     anExpV.Init( E1, TopAbs_VERTEX );
@@ -321,6 +454,8 @@ static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
       Standard_ConstructionError::Raise("FindNextPairOfFaces: Can not find vertex in map");
     }
 
+    if(!aMapEdgeFaces1.Contains(E1))
+      cout<<"    FindNextPairOfFaces: map aMapEdgeFaces1 not contains key E1"<<endl;
     const TopTools_ListOfShape& aList1 = aMapEdgeFaces1.FindFromKey(E1);
     if(aList1.Extent()<2)
       continue;
@@ -332,7 +467,11 @@ static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
     if(FF.Contains(F1other))
       continue;
 
+    if(!FF.Contains(aCurFace))
+      cout<<"    FindNextPairOfFaces: map FF not contains key aCurFace"<<endl;
     const TopoDS_Shape& F2 = FF.FindFromKey(aCurFace);
+    if(!aMapEdgeFaces2.Contains(E2))
+      cout<<"    FindNextPairOfFaces: map aMapEdgeFaces2 not contains key E2"<<endl;
     const TopTools_ListOfShape& aList2 = aMapEdgeFaces2.FindFromKey(E2);
     if(aList2.Extent()<2) {
       if(aCI) delete aCI;
@@ -357,6 +496,127 @@ static void FindNextPairOfFaces(const TopoDS_Shape& aCurFace,
 }
 
 
+//=======================================================================
+//function : FindFirstPairFaces
+//purpose  : auxilary for Execute()
+//=======================================================================
+static void FindFirstPairFaces(const TopoDS_Shape& S1, const TopoDS_Shape& S2,
+                              TopoDS_Vertex& V1, TopoDS_Vertex& V2,
+                              TopoDS_Shape& FS1, TopoDS_Shape& FS2)
+{
+  //cout<<"FindFirstPairFaces"<<endl;
+
+  // check if vertexes are subshapes of sections
+  gp_Pnt P1 = BRep_Tool::Pnt(V1);
+  gp_Pnt P2 = BRep_Tool::Pnt(V2);
+  TopoDS_Vertex V1new,V2new;
+  TopExp_Explorer exp;
+  double mindist = 1.e10;
+  for( exp.Init( S1, TopAbs_VERTEX ); exp.More(); exp.Next() ) {
+    TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
+    gp_Pnt P = BRep_Tool::Pnt(V);
+    double dist = P1.Distance(P);
+    if(dist<mindist) {
+      mindist = dist;
+      V1new = V;
+    }
+  }
+  mindist = 1.e10;
+  for( exp.Init( S2, TopAbs_VERTEX ); exp.More(); exp.Next() ) {
+    TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
+    gp_Pnt P = BRep_Tool::Pnt(V);
+    double dist = P2.Distance(P);
+    if(dist<mindist) {
+      mindist = dist;
+      V2new = V;
+    }
+  }
+
+  //gp_Pnt P1new = BRep_Tool::Pnt(V1new);
+  //gp_Pnt P2new = BRep_Tool::Pnt(V2new);
+  //cout<<"  P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
+  //cout<<"  P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
+  //cout<<"  P1new("<<P1new.X()<<","<<P1new.Y()<<","<<P1new.Z()<<")"<<endl;
+  //cout<<"  P2new("<<P2new.X()<<","<<P2new.Y()<<","<<P2new.Z()<<")"<<endl;
+
+  // replace vertexes if it is needed
+  if(!V1.IsSame(V1new)) {
+    V1 = V1new;
+    P1 = BRep_Tool::Pnt(V1);
+    cout<<"  replace V1"<<endl;
+  }
+  else
+    cout<<"  not replace V1"<<endl;
+  if(!V2.IsSame(V2new)) {
+    V2 = V2new;
+    P2 = BRep_Tool::Pnt(V2);
+    cout<<"  replace V2"<<endl;
+  }
+  else
+    cout<<"  not replace V2"<<endl;
+
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces1;
+  TopExp::MapShapesAndAncestors(S1, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces1);
+  TopTools_IndexedDataMapOfShapeListOfShape aMapVertFaces2;
+  TopExp::MapShapesAndAncestors(S2, TopAbs_VERTEX, TopAbs_FACE, aMapVertFaces2);
+
+  if(!aMapVertFaces1.Contains(V1))
+    cout<<"    FindFirstPairFaces: map aMapVertFaces1 not contains key V1"<<endl;
+  const TopTools_ListOfShape& aList1 = aMapVertFaces1.FindFromKey(V1);
+  TopTools_ListIteratorOfListOfShape anIter1(aList1);
+  FS1 = anIter1.Value();
+  // find middle point
+  double x1=0., y1=0., z1=0.;
+  int nbv1=0;
+  for( exp.Init( FS1, TopAbs_VERTEX ); exp.More(); exp.Next() ) {
+    TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
+    gp_Pnt P = BRep_Tool::Pnt(V);
+    x1 += P.X();
+    y1 += P.Y();
+    z1 += P.Z();
+    nbv1++;
+  }
+  gp_Pnt PM1(x1/nbv1, y1/nbv1, z1/nbv1);
+
+  TColgp_SequenceOfPnt Ps;
+  TopTools_SequenceOfShape Fs;
+  if(!aMapVertFaces2.Contains(V2))
+    cout<<"    FindFirstPairFaces: map aMapVertFaces2 not contains key V2"<<endl;
+  const TopTools_ListOfShape& aList2 = aMapVertFaces2.FindFromKey(V2);
+  TopTools_ListIteratorOfListOfShape anIter2(aList2);
+  for(; anIter2.More(); anIter2.Next()) {
+    TopoDS_Shape F = anIter2.Value();
+    double x2=0., y2=0., z2=0.;
+    int nbv2=0;
+    for( exp.Init( F, TopAbs_VERTEX ); exp.More(); exp.Next() ) {
+      TopoDS_Vertex V = TopoDS::Vertex(exp.Current());
+      gp_Pnt P = BRep_Tool::Pnt(V);
+      x2 += P.X();
+      y2 += P.Y();
+      z2 += P.Z();
+      nbv2++;
+    }
+    gp_Pnt PM(x2/nbv1, y2/nbv1, z2/nbv1);
+    Fs.Append(F);
+    Ps.Append(PM);
+  }
+
+  gp_Vec aDir(P1,P2);
+  int i=1;
+  double MinAng = PI;
+  int numface = 0;
+  for(; i<=Fs.Length(); i++) {
+    gp_Vec tmpDir(PM1,Ps(i));
+    double ang = fabs(aDir.Angle(tmpDir));
+    if(ang<MinAng) {
+      MinAng = ang;
+      numface = i;
+    }
+  }
+  FS2 = Fs(numface);
+}
+
+
 //=======================================================================
 //function : CreatePipeForShellSections
 //purpose  : auxilary for Execute()
@@ -413,120 +673,157 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
     TopoDS_Vertex V = TopoDS::Vertex(VLocs.Value(i));
     PLocs.Append(BRep_Tool::Pnt(V));
   }
+
   TopTools_SequenceOfShape Edges;
   TopTools_SequenceOfShape Wires;
-  TopExp_Explorer anExp;
-  for ( anExp.Init( aWirePath, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
-    Edges.Append(anExp.Current());
-  }
   ShapeAnalysis_Edge sae;
-  TopoDS_Edge edge = TopoDS::Edge(Edges.First());
-  double tol = BRep_Tool::Tolerance(edge);
-  TopoDS_Vertex VF = sae.FirstVertex(edge);
-  gp_Pnt PF = BRep_Tool::Pnt(VF);
-  //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
-  if( PF.Distance(PLocs.First()) > tol ) {
-    if(aCI) delete aCI;
-    Standard_ConstructionError::Raise
-      ("First location shapes is not coincided with first vertex of aWirePath");
-  }
-  VLocs.ChangeValue(1) = VF;
-  edge = TopoDS::Edge(Edges.Last());
-  tol = BRep_Tool::Tolerance(edge);
-  TopoDS_Vertex VL = sae.LastVertex(edge);
-  gp_Pnt PL = BRep_Tool::Pnt(VL);
-  if( PL.Distance(PLocs.Last()) > tol ) {
-    if(aCI) delete aCI;
-    Standard_ConstructionError::Raise
-      ("Last location shapes is not coincided with last vertex of aWirePath");
-  }
-  VLocs.ChangeValue(nbLocs) = VL;
-  int jcurr = 2;
-  TopTools_SequenceOfShape tmpEdges;
-  for(i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
-    TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
-    tol = BRep_Tool::Tolerance(E);
-    TopoDS_Vertex V1 = sae.FirstVertex(E);
-    TopoDS_Vertex V2 = sae.LastVertex(E);
-    gp_Pnt P1 = BRep_Tool::Pnt(V1);
-    gp_Pnt P2 = BRep_Tool::Pnt(V2);
-    if( P2.Distance(PLocs.Value(jcurr)) < tol ) {
-      // make wire from current edge and add created
-      // wire to Wires
+
+  if(nbLocs==2) {
+    TopExp_Explorer anExp;
+    for ( anExp.Init( aWirePath, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
+      Edges.Append(anExp.Current());
+    }
+    Standard_Integer Num1 = 0;
+    Standard_Integer Num2 = 0;
+    for(i=1; i<=Edges.Length(); i++) {
+      TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
+      double tol = BRep_Tool::Tolerance(E);
+      TopoDS_Vertex V1 = sae.FirstVertex(E);
+      TopoDS_Vertex V2 = sae.LastVertex(E);
+      gp_Pnt P1 = BRep_Tool::Pnt(V1);
+      gp_Pnt P2 = BRep_Tool::Pnt(V2);
+      if( P1.Distance(PLocs.First()) < tol ) {
+       Num1 = i;
+      }
+      if( P2.Distance(PLocs.Last()) < tol ) {
+       Num2 = i;
+      }
+    }
+    if( Num1>0 && Num2>0 ) {
       TopoDS_Wire W;
       B.MakeWire(W);
-      for(j=1; j<=tmpEdges.Length(); j++)
-       B.Add(W,tmpEdges.Value(j));
-      B.Add(W,E);
+      for(i=Num1; i<=Num2; i++) {
+       B.Add(W,Edges.Value(i));
+      }
       Wires.Append(W);
-      VLocs.ChangeValue(jcurr) = V2;
-      jcurr++;
-      tmpEdges.Clear();
     }
     else {
-      // find distance between E and aLocs(jcurr)
-      double fp,lp;
-      Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
-      GeomAPI_ProjectPointOnCurve PPC (PLocs.Value(jcurr),C);
-      if( PPC.NbPoints()>0 &&
-         PLocs.Value(jcurr).Distance(PPC.Point(1)) < tol ) {
-       double param = PPC.Parameter(1);
-       gp_Pnt PC1;
-       C->D0(param,PC1);
-       // split current edge
-       Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
-       Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
-       TopoDS_Edge E1,E2;
-       gp_Pnt Pfp;
-       C->D0(fp,Pfp);
-       if(Pfp.Distance(P1)<tol) {
-         B.MakeEdge(E1,tc1,tol);
-         B.Add(E1,V1);
-         TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
-         B.Add(E1,TopoDS::Vertex(tmpV));
-         tmpEdges.Append(E1);
-         B.MakeEdge(E2,tc2,tol);
-         tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
-         B.Add(E2,TopoDS::Vertex(tmpV));
-         B.Add(E2,V2);
-       }
-       else {
-         B.MakeEdge(E1,tc2,tol);
-         TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
-         B.Add(E1,TopoDS::Vertex(tmpV));
-         B.Add(E1,V1);
-         E1.Reverse();
-         tmpEdges.Append(E1);
-         B.MakeEdge(E2,tc1,tol);
-         B.Add(E2,V2);
-         tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
-         B.Add(E2,TopoDS::Vertex(tmpV));
-         E2.Reverse();
-       }
-       // create wire from tmpEdges
+      Wires.Append(aWirePath);
+    }
+  }
+  else {
+    TopExp_Explorer anExp;
+    for ( anExp.Init( aWirePath, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
+      Edges.Append(anExp.Current());
+    }
+    TopoDS_Edge edge = TopoDS::Edge(Edges.First());
+    double tol = BRep_Tool::Tolerance(edge);
+    TopoDS_Vertex VF = sae.FirstVertex(edge);
+    gp_Pnt PF = BRep_Tool::Pnt(VF);
+    //cout<<"PF("<<PF.X()<<","<<PF.Y()<<","<<PF.Z()<<")"<<endl;
+    if( PF.Distance(PLocs.First()) > tol ) {
+      if(aCI) delete aCI;
+      Standard_ConstructionError::Raise
+       ("First location shapes is not coincided with first vertex of aWirePath");
+    }
+    VLocs.ChangeValue(1) = VF;
+    edge = TopoDS::Edge(Edges.Last());
+    tol = BRep_Tool::Tolerance(edge);
+    TopoDS_Vertex VL = sae.LastVertex(edge);
+    gp_Pnt PL = BRep_Tool::Pnt(VL);
+    if( PL.Distance(PLocs.Last()) > tol ) {
+      if(aCI) delete aCI;
+      Standard_ConstructionError::Raise
+       ("Last location shapes is not coincided with last vertex of aWirePath");
+    }
+    VLocs.ChangeValue(nbLocs) = VL;
+    int jcurr = 2;
+    TopTools_SequenceOfShape tmpEdges;
+    for(i=1; i<=Edges.Length() && jcurr<nbLocs; i++) {
+      TopoDS_Edge E = TopoDS::Edge(Edges.Value(i));
+      tol = BRep_Tool::Tolerance(E);
+      TopoDS_Vertex V1 = sae.FirstVertex(E);
+      TopoDS_Vertex V2 = sae.LastVertex(E);
+      gp_Pnt P1 = BRep_Tool::Pnt(V1);
+      gp_Pnt P2 = BRep_Tool::Pnt(V2);
+      if( P2.Distance(PLocs.Value(jcurr)) < tol ) {
+       // make wire from current edge and add created
+       // wire to Wires
        TopoDS_Wire W;
        B.MakeWire(W);
        for(j=1; j<=tmpEdges.Length(); j++)
          B.Add(W,tmpEdges.Value(j));
+       B.Add(W,E);
        Wires.Append(W);
+       VLocs.ChangeValue(jcurr) = V2;
        jcurr++;
        tmpEdges.Clear();
-       Edges.Remove(i);
-       Edges.InsertAfter(i-1,E1);
-       Edges.InsertAfter(i,E2);
       }
       else {
-       tmpEdges.Append(E);
+       // find distance between E and aLocs(jcurr)
+       double fp,lp;
+       Handle(Geom_Curve) C = BRep_Tool::Curve(E,fp,lp);
+       GeomAPI_ProjectPointOnCurve PPC (PLocs.Value(jcurr),C);
+       if( PPC.NbPoints()>0 &&
+           PLocs.Value(jcurr).Distance(PPC.Point(1)) < tol ) {
+         double param = PPC.Parameter(1);
+         gp_Pnt PC1;
+         C->D0(param,PC1);
+         // split current edge
+         Handle(Geom_TrimmedCurve) tc1 = new Geom_TrimmedCurve(C,fp,param);
+         Handle(Geom_TrimmedCurve) tc2 = new Geom_TrimmedCurve(C,param,lp);
+         TopoDS_Edge E1,E2;
+         gp_Pnt Pfp;
+         C->D0(fp,Pfp);
+         if(Pfp.Distance(P1)<tol) {
+           B.MakeEdge(E1,tc1,tol);
+           B.Add(E1,V1);
+           TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
+           B.Add(E1,TopoDS::Vertex(tmpV));
+           tmpEdges.Append(E1);
+           B.MakeEdge(E2,tc2,tol);
+           tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
+           B.Add(E2,TopoDS::Vertex(tmpV));
+           B.Add(E2,V2);
+         }
+         else {
+           B.MakeEdge(E1,tc2,tol);
+           TopoDS_Shape tmpV = VLocs.Value(jcurr).Oriented(TopAbs_FORWARD);
+           B.Add(E1,TopoDS::Vertex(tmpV));
+           B.Add(E1,V1);
+           E1.Reverse();
+           tmpEdges.Append(E1);
+           B.MakeEdge(E2,tc1,tol);
+           B.Add(E2,V2);
+           tmpV = VLocs.Value(jcurr).Oriented(TopAbs_REVERSED);
+           B.Add(E2,TopoDS::Vertex(tmpV));
+           E2.Reverse();
+         }
+         // create wire from tmpEdges
+         TopoDS_Wire W;
+         B.MakeWire(W);
+         for(j=1; j<=tmpEdges.Length(); j++)
+           B.Add(W,tmpEdges.Value(j));
+         Wires.Append(W);
+         jcurr++;
+         tmpEdges.Clear();
+         Edges.Remove(i);
+         Edges.InsertAfter(i-1,E1);
+         Edges.InsertAfter(i,E2);
+       }
+       else {
+         tmpEdges.Append(E);
+       }
       }
     }
+    // create wire from other edges
+    TopoDS_Wire W;
+    B.MakeWire(W);
+    for(; i<=Edges.Length(); i++)
+      B.Add(W,Edges.Value(i));
+    Wires.Append(W);
+    //cout<<"Wires.Length()="<<Wires.Length()<<endl;
   }
-  // create wire from other edges
-  TopoDS_Wire W;
-  B.MakeWire(W);
-  for(; i<=Edges.Length(); i++)
-    B.Add(W,Edges.Value(i));
-  Wires.Append(W);
-  //cout<<"Wires.Length()="<<Wires.Length()<<endl;
 
   if( Wires.Length() != nbLocs-1 ) {
     if(aCI) delete aCI;
@@ -1083,12 +1380,485 @@ static TopoDS_Shape CreatePipeForShellSections(const TopoDS_Wire& aWirePath,
 }
 
 
+//=======================================================================
+//function : CreatePipeShellsWithoutPath
+//purpose  : auxilary for Execute()
+//=======================================================================
+static TopoDS_Shape CreatePipeShellsWithoutPath(GEOMImpl_IPipe* aCI)
+{
+  //cout<<"CreatePipeShellsWithoutPath"<<endl;
+  int i,j;
+  BRep_Builder B;
+
+  GEOMImpl_IPipeShellSect* aCIDS = (GEOMImpl_IPipeShellSect*)aCI;
+  // shell sections
+  Handle(TColStd_HSequenceOfTransient) aBasesObjs = aCIDS->GetBases();
+  // vertex for recognition
+  Handle(TColStd_HSequenceOfTransient) VObjs = aCIDS->GetLocations();
+
+  Standard_Integer nbBases = aBasesObjs->Length(), 
+    nbv = (VObjs.IsNull() ? 0 :VObjs->Length());
+    
+  if( nbv != nbBases ) {
+    if(aCI) delete aCI;
+    Standard_ConstructionError::Raise("Number of shapes for recognition is invalid");
+  }
+
+
+  TopTools_SequenceOfShape SecVs,Bases;
+  for(i=1; i<=nbBases; i++) {
+    // vertex
+    Handle(Standard_Transient) anItem = VObjs->Value(i);
+    if(anItem.IsNull())
+      continue;
+    Handle(GEOM_Function) aRef = Handle(GEOM_Function)::DownCast(anItem);
+    TopoDS_Shape V = aRef->GetValue();
+    if(V.IsNull() || V.ShapeType() != TopAbs_VERTEX)
+      continue;
+    SecVs.Append(V);
+    // section
+    anItem = aBasesObjs->Value(i);
+    if(anItem.IsNull())
+      continue;
+    aRef = Handle(GEOM_Function)::DownCast(anItem);
+    TopoDS_Shape aSh = aRef->GetValue();
+    if(aSh.IsNull())
+      continue;
+    Bases.Append(aSh);
+  }
+  nbv = SecVs.Length();
+  nbBases = Bases.Length();
+  if( nbv != nbBases ) {
+    if(aCI) delete aCI;
+    Standard_ConstructionError::Raise("One of shapes for recognition is not a vertex");
+  }
+
+  TopoDS_Compound aComp;
+  B.MakeCompound(aComp);
+
+  for(i=1 ; i<nbBases; i++) {
+    cout<<"Make pipe between sections "<<i<<" and "<<i+1<<endl;
+    TopoDS_Shape aShBase1 = Bases.Value(i);
+    TopoDS_Shape aShBase2 = Bases.Value(i+1);
+    TopExp_Explorer anExp;
+    Standard_Integer nbf1 = 0;
+    for ( anExp.Init( aShBase1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+      nbf1++;
+    }
+    Standard_Integer nbf2 = 0;
+    for ( anExp.Init( aShBase2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+      nbf2++;
+    }
+    //cout<<"nbf1="<<nbf1<<" nbf2="<<nbf2<<endl;
+    if(nbf1!=nbf2) {
+      if(aCI) delete aCI;
+      Standard_ConstructionError::Raise("Different number of faces in the sections");
+    }
+
+    TopTools_MapOfShape aFaces1,aFaces2;
+    for ( anExp.Init( aShBase1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+      aFaces1.Add(anExp.Current());
+    }
+    for ( anExp.Init( aShBase2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+      aFaces2.Add(anExp.Current());
+    }
+
+    // creating map of edge faces
+    TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces1;
+    TopExp::MapShapesAndAncestors(aShBase1, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces1);
+    TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces2;
+    TopExp::MapShapesAndAncestors(aShBase2, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces2);
+
+    // constuct map face->face (and subshapes)
+    TopTools_IndexedDataMapOfShapeShape FF;
+    //TopoDS_Shape FS1 = SecFs.Value(i), FS2 = SecFs.Value(i+1);
+    TopoDS_Shape FS1, FS2;
+    TopoDS_Vertex V1 = TopoDS::Vertex(SecVs(i));
+    TopoDS_Vertex V2 = TopoDS::Vertex(SecVs(i+1));
+    FindFirstPairFaces(aShBase1, aShBase2, V1, V2, FS1, FS2);
+
+    FF.Add(FS1,FS2);
+    cout<<"  first pair of corresponding faces is found"<<endl;
+
+    // add pairs of edges and vertexes to FF
+    bool stat =  FillCorrespondingEdges(FS1, FS2, V1, V2, FF);
+    if( !stat ) {
+      if(aCI) delete aCI;
+      Standard_ConstructionError::Raise("Can not create correct pipe");
+    }
+    cout<<"  correspondences for subshapes of first pair of faces is found"<<endl;
+
+    FindNextPairOfFaces(FS1, aMapEdgeFaces1, aMapEdgeFaces2, FF, aCI);
+    cout<<"  other correspondences is found, make pipe for all pairs of faces"<<endl;
+
+    // make pipe for each pair of faces
+    // auxilary map vertex->edge for created pipe edges
+    TopTools_IndexedDataMapOfShapeShape VPE;
+    ShapeAnalysis_Edge sae;
+    //cout<<"FF.Extent()="<<FF.Extent()<<endl;
+    int nbff = 0;
+    for(j=1; j<=FF.Extent(); j++) {
+      TopoDS_Shape F1 = FF.FindKey(j);
+      if( F1.ShapeType() != TopAbs_FACE )
+       continue;
+      TopoDS_Shape F2 = FF.FindFromIndex(j);
+      nbff++;
+
+      //if(nbff!=3) continue;
+
+      cout<<"    make pipe for "<<nbff<<" face"<<endl;
+
+      Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(F1));
+      if(S1->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
+       Handle(Geom_RectangularTrimmedSurface) RTS = 
+         Handle(Geom_RectangularTrimmedSurface)::DownCast(S1);
+       S1 = RTS->BasisSurface();
+      }
+      Handle(Geom_Plane) Pln1 = 
+         Handle(Geom_Plane)::DownCast(S1);
+      if( Pln1.IsNull() ) {
+       if(aCI) delete aCI;
+       Standard_ConstructionError::Raise("Surface from face is not plane");
+      }
+      gp_Vec aDir1(Pln1->Axis().Direction());
+
+      Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(F2));
+      if(S2->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
+       Handle(Geom_RectangularTrimmedSurface) RTS = 
+         Handle(Geom_RectangularTrimmedSurface)::DownCast(S2);
+       S2 = RTS->BasisSurface();
+      }
+      Handle(Geom_Plane) Pln2 = 
+         Handle(Geom_Plane)::DownCast(S2);
+      if( Pln2.IsNull() ) {
+       if(aCI) delete aCI;
+       Standard_ConstructionError::Raise("Surface from face is not plane");
+      }
+      gp_Vec aDir2(Pln2->Axis().Direction());
+
+      gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i)));
+      gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(SecVs(i+1)));
+      gp_Vec aDir(P1,P2);
+      if(fabs(aDir.Angle(aDir1))>PI/2.)
+       aDir1.Reverse();
+      if(fabs(aDir.Angle(aDir2))>PI/2.)
+       aDir2.Reverse();
+
+      TopExp_Explorer anExpE(F1,TopAbs_EDGE);
+      TopTools_SequenceOfShape aNewFs;
+      //int nbee=0;
+      for(; anExpE.More(); anExpE.Next()) {
+       TopoDS_Edge E1 = TopoDS::Edge(anExpE.Current());
+       //nbee++;
+       if(!FF.Contains(E1))
+         cout<<"map FF not contains key E1"<<endl;
+
+       if(VPE.Contains(E1)) {
+         aNewFs.Append(VPE.FindFromKey(E1));
+#ifdef _DEBUG_
+         cout<<"    using existed face"<<endl;
+#endif
+         continue;
+       }
+
+       TopoDS_Edge E3 = TopoDS::Edge(FF.FindFromKey(E1));
+       TopoDS_Vertex V1 = sae.FirstVertex(E1);
+       TopoDS_Vertex V2 = sae.LastVertex(E1);
+       if(!FF.Contains(V1))
+         cout<<"map FF not contains key V1"<<endl;
+       if(!FF.Contains(V2))
+         cout<<"map FF not contains key V2"<<endl;
+       TopoDS_Vertex V3 = TopoDS::Vertex(FF.FindFromKey(V2));
+       TopoDS_Vertex V4 = TopoDS::Vertex(FF.FindFromKey(V1));
+       TopoDS_Vertex Vtmp = sae.FirstVertex(E3);
+       if(Vtmp.IsSame(V4))
+         E3.Reverse();
+       gp_Pnt P1 = BRep_Tool::Pnt(V1);
+       gp_Pnt P2 = BRep_Tool::Pnt(V2);
+       gp_Pnt P3 = BRep_Tool::Pnt(V3);
+       gp_Pnt P4 = BRep_Tool::Pnt(V4);
+       // make E2
+       TopoDS_Edge E2;
+       Handle(Geom_BSplineCurve) C2;
+       if(VPE.Contains(V2)) {
+         E2 = TopoDS::Edge(VPE.FindFromKey(V2));
+         double fp,lp;
+         C2 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E2,fp,lp));
+       }
+       else {
+         Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
+         HAP->SetValue(1,P2);
+         HAP->SetValue(2,P3);
+         GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
+         anInt.Load(aDir1,aDir2);
+         anInt.Perform();
+         C2 = anInt.Curve();
+         B.MakeEdge(E2,C2,1.e-7);
+         B.Add(E2,TopoDS::Vertex(V2.Oriented(TopAbs_FORWARD)));
+         B.Add(E2,TopoDS::Vertex(V3.Oriented(TopAbs_REVERSED)));
+         VPE.Add(V2,E2);
+       }
+       // make E4
+       TopoDS_Edge E4;
+       Handle(Geom_BSplineCurve) C4;
+       if(VPE.Contains(V1)) {
+         E4 = TopoDS::Edge(VPE.FindFromKey(V1));
+         double fp,lp;
+         C4 = Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(E4,fp,lp));
+       }
+       else {
+         Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
+         HAP->SetValue(1,P1);
+         HAP->SetValue(2,P4);
+         GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
+         anInt.Load(aDir1,aDir2);
+         anInt.Perform();
+         C4 = anInt.Curve();
+         B.MakeEdge(E4,anInt.Curve(),1.e-7);
+         B.Add(E4,TopoDS::Vertex(V1.Oriented(TopAbs_FORWARD)));
+         B.Add(E4,TopoDS::Vertex(V4.Oriented(TopAbs_REVERSED)));
+         VPE.Add(V1,E4);
+       }
+
+       TopoDS_Wire W;
+       B.MakeWire(W);
+       B.Add(W,E1);
+       B.Add(W,E2);
+       B.Add(W,E3);
+       B.Add(W,E4.Reversed());
+       //cout<<"      wire for edge "<<nbee<<" is created"<<endl;
+       //BRepTools::Write(W,"/dn02/users_Linux/skl/work/Bugs/14857/w.brep");
+       
+       // make surface
+       
+       double fp,lp;
+       Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
+       //bool IsConicC1 = false;
+       //if( C1->IsKind(STANDARD_TYPE(Geom_Conic)) ) {
+       //  IsConicC1 = true;
+       //  cout<<"C1 - Geom_Conic"<<endl;
+       //}
+       if( C1->IsKind(STANDARD_TYPE(Geom_Line)) || C1->IsKind(STANDARD_TYPE(Geom_Conic)) ) {
+         C1 = new Geom_TrimmedCurve(C1,fp,lp);
+       }
+       //if(IsConicC1) {
+       //  double tol = BRep_Tool::Tolerance(E1);
+       //  GeomConvert_ApproxCurve ApxC1(C1,tol,GeomAbs_C1,10,5);
+       //  C1 = ApxC1.Curve();
+       //}
+       Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp,lp);
+       if( C3->IsKind(STANDARD_TYPE(Geom_Line)) || C3->IsKind(STANDARD_TYPE(Geom_Conic)) ) {
+         C3 = new Geom_TrimmedCurve(C3,fp,lp);
+       }
+       //filebuf fic;
+       //ostream os(&fic);
+       //os.precision(15);
+       Handle(Geom_BSplineCurve) CE1 =
+         GeomConvert::CurveToBSplineCurve(C1,Convert_RationalC1);
+       if(CE1->Degree()<3)
+         CE1->IncreaseDegree(3);
+       Handle(Geom_BSplineCurve) CE2 =
+         GeomConvert::CurveToBSplineCurve(C2,Convert_RationalC1);
+       if(CE2->Degree()<3)
+         CE2->IncreaseDegree(3);
+       Handle(Geom_BSplineCurve) CE3 =
+         GeomConvert::CurveToBSplineCurve(C3,Convert_RationalC1);
+       if(CE3->Degree()<3)
+         CE3->IncreaseDegree(3);
+       Handle(Geom_BSplineCurve) CE4 =
+         GeomConvert::CurveToBSplineCurve(C4,Convert_RationalC1);
+       if(CE4->Degree()<3)
+         CE4->IncreaseDegree(3);
+       //cout<<"CE1->Degree()="<<CE1->Degree()<<" CE2->Degree()="<<CE2->Degree()
+       //    <<" CE3->Degree()="<<CE3->Degree()<<" CE4->Degree()="<<CE4->Degree()<<endl;
+       //if(fic.open("/dn02/users_Linux/skl/work/Bugs/14857/ce1.brep",ios::out)) {
+       //  os<<"DrawTrSurf_BSplineCurve"<<endl;
+       //  GeomTools::Write(CE1,os);
+       //  fic.close();
+       //}
+
+       Handle(Geom_Surface) BS;
+       try {
+         GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_CoonsStyle);
+         //GeomFill_BSplineCurves GF(CE1,CE2,CE3,CE4,GeomFill_StretchStyle);
+         BS = GF.Surface();
+       }
+       catch(...) {
+         cout<<"      can not create BSplineSurface - create Bezier"<<endl;
+         int NbP=26;
+         TColgp_Array2OfPnt Points(1,NbP,1,NbP);
+         double fp1,lp1,fp2,lp2;
+         Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp1,lp1);
+         Handle(Geom_Curve) C3 = BRep_Tool::Curve(E3,fp2,lp2);
+         gp_Pnt P1C1,P2C1;
+         C1->D0(fp1,P1C1);
+         C1->D0(lp1,P2C1);
+         gp_Pnt P1C3,P2C3;
+         C3->D0(fp2,P1C3);
+         C3->D0(lp2,P2C3);
+         int n1,n2;
+         double fp,lp;
+         // get points from C1
+         if(P1.Distance(P1C1)<1.e-6) {
+           fp = fp1;
+           lp = lp1;
+         }
+         else {
+           fp = lp1;
+           lp = fp1;
+         }
+         double step = (lp-fp)/(NbP-1);
+         Points.SetValue(1,1,P1);
+         double par = fp;
+         for(n1=2; n1<NbP; n1++) {
+           gp_Pnt P;
+           par += step;
+           C1->D0(par,P);
+           Points.SetValue(1,n1,P);
+         }
+         Points.SetValue(1,NbP,P2);
+         // get points from C3
+         if(P4.Distance(P1C3)<1.e-6) {
+           fp = fp2;
+           lp = lp2;
+         }
+         else {
+           fp = lp2;
+           lp = fp2;
+         }
+         step = (lp-fp)/(NbP-1);
+         Points.SetValue(NbP,1,P4);
+         par = fp;
+         for(n1=2; n1<NbP; n1++) {
+           gp_Pnt P;
+           par += step;
+           C3->D0(par,P);
+           Points.SetValue(NbP,n1,P);
+         }
+         Points.SetValue(NbP,NbP,P3);
+         // create isolines and get points from them
+         for(n1=1; n1<=NbP; n1++) {
+           gp_Pnt PI1 = Points.Value(1,n1);
+           gp_Pnt PI2 = Points.Value(NbP,n1);
+           Handle(TColgp_HArray1OfPnt) HAP = new TColgp_HArray1OfPnt(1,2);
+           HAP->SetValue(1,PI1);
+           HAP->SetValue(2,PI2);
+           GeomAPI_Interpolate anInt(HAP,Standard_False,1.e-7);
+           anInt.Load(aDir1,aDir2);
+           anInt.Perform();
+           Handle(Geom_Curve) iso = anInt.Curve();
+           fp = iso->FirstParameter();
+           lp = iso->LastParameter();
+           step = (lp-fp)/(NbP-1);
+           par = fp;
+           TopoDS_Compound VComp;
+           B.MakeCompound(VComp);
+           for(n2=2; n2<NbP; n2++) {
+             gp_Pnt P;
+             par += step;
+             iso->D0(par,P);
+             Points.SetValue(n2,n1,P);
+           }
+         }
+         // create surface and face
+         //Handle(Geom_BezierSurface) BS = new Geom_BezierSurface(Points);
+         BS = new Geom_BezierSurface(Points);
+       }
+
+       BRepBuilderAPI_MakeFace BB(BS,W);
+       TopoDS_Face NewF = BB.Face();
+       Handle(ShapeFix_Face) sff = new ShapeFix_Face(NewF);
+       sff->Perform();
+       sff->FixOrientation();
+       TopoDS_Face FixedFace = sff->Face();
+       aNewFs.Append(FixedFace);
+       VPE.Add(E1,FixedFace);
+       //cout<<"      face for edge "<<nbee<<" is created"<<endl;
+       //BRepTools::Write(FixedFace,"/dn02/users_Linux/skl/work/Bugs/14857/f.brep");
+      }
+      // make shell
+      TopoDS_Shell aShell;
+      B.MakeShell(aShell);
+      for(int nf=1; nf<=aNewFs.Length(); nf++) {
+       B.Add(aShell,aNewFs(nf));
+      }
+      B.Add(aShell,F1);
+      B.Add(aShell,F2);
+      
+      // make sewing for this shell
+      Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
+      aSewing->SetTolerance(Precision::Confusion());
+      aSewing->SetFaceMode(Standard_True);
+      aSewing->SetFloatingEdgesMode(Standard_False);
+      aSewing->SetNonManifoldMode(Standard_False);
+      for ( anExp.Init( aShell, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+       aSewing->Add(anExp.Current());
+      }
+      aSewing->Perform();
+      cout<<"    shell for face "<<nbff<<" is created"<<endl;
+      const TopoDS_Shape aSewShape = aSewing->SewedShape();
+      //BRepTools::Write(aSewShape,"/dn02/users_Linux/skl/work/Bugs/14857/sew.brep");
+      if( aSewShape.ShapeType() == TopAbs_SHELL ) {
+       aShell = TopoDS::Shell(aSewShape);
+       GProp_GProps aSystem;
+       BRepGProp::VolumeProperties(aShell, aSystem);
+       if(aSystem.Mass()<0) {
+         //cout<<"aSewShape is reversed"<<endl;
+         aShell.Reverse();
+       }
+       if(BRep_Tool::IsClosed(aShell)) {
+         TopoDS_Solid aSolid;
+         B.MakeSolid(aSolid);
+         B.Add(aSolid,aShell);
+         B.Add(aComp,aSolid);
+         cout<<"    solid for face "<<nbff<<" is created"<<endl;
+       }
+       else {
+         B.Add(aComp,aShell);
+         cout<<"    solid for face "<<nbff<<" is not created"<<endl;
+       }
+      }
+      else {
+       B.Add(aComp,aShell);
+       cout<<"    solid for face "<<nbff<<" is not created"<<endl;
+      }
+      //cout<<"    solid for face "<<nbff<<" is created"<<endl;
+      
+      //Handle(ShapeFix_Shell) sfs = new ShapeFix_Shell(aShell);
+      //sfs->Perform();
+      //TopoDS_Shell FixedShell = sfs->Shell();
+      /*
+      GProp_GProps aSystem;
+      BRepGProp::VolumeProperties(FixedShell, aSystem);
+      if(aSystem.Mass()<0) {
+       //cout<<"aSewShape is reversed"<<endl;
+       FixedShell.Reverse();
+      }
+      if(BRep_Tool::IsClosed(FixedShell)) {
+       TopoDS_Solid aSolid;
+       B.MakeSolid(aSolid);
+       B.Add(aSolid,aShell);
+       B.Add(aComp,aSolid);
+      }
+      else {
+       B.Add(aComp,FixedShell);
+      }
+      */
+    }
+  }
+
+  //BRepTools::Write(aComp,"/dn02/users_Linux/skl/work/Bugs/14857/comp.brep");
+  return aComp;
+}
+
+
 //=======================================================================
 //function : Execute
 //purpose  :
 //=======================================================================
 Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
 {
+  //cout<<"PipeDriver::Execute"<<endl;
   if (Label().IsNull()) return 0;
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
   GEOMImpl_IPipe* aCI= 0;
@@ -1099,35 +1869,39 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
     aCI = new GEOMImpl_IPipeDiffSect(aFunction);
   else if(aType == PIPE_SHELL_SECTIONS)
     aCI = new GEOMImpl_IPipeShellSect(aFunction);
+  else if(aType == PIPE_SHELLS_WITHOUT_PATH)
+    aCI = new GEOMImpl_IPipeShellSect(aFunction);
   else
     return 0;
 
-  Handle(GEOM_Function) aRefPath = aCI->GetPath();
-  TopoDS_Shape aShapePath = aRefPath->GetValue();
-
+  TopoDS_Wire aWirePath;
+  if(aType != PIPE_SHELLS_WITHOUT_PATH) {
+    // working with path
+    Handle(GEOM_Function) aRefPath = aCI->GetPath();
+    TopoDS_Shape aShapePath = aRefPath->GetValue();
 
-  if (aShapePath.IsNull()) {
-    cout<<"Driver : path is null"<<endl;
-    if(aCI) delete aCI;
-    Standard_NullObject::Raise("MakePipe aborted : null path argument");
-  }
+    if (aShapePath.IsNull()) {
+      cout<<"Driver : path is null"<<endl;
+      if(aCI) delete aCI;
+      Standard_NullObject::Raise("MakePipe aborted : null path argument");
+    }
   
-  // Get path contour
-  TopoDS_Wire aWirePath;
-  if (aShapePath.ShapeType() == TopAbs_WIRE) {
-    aWirePath = TopoDS::Wire(aShapePath);
-  } 
-  else {
-    if (aShapePath.ShapeType() == TopAbs_EDGE) {
-      TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
-      aWirePath = BRepBuilderAPI_MakeWire(anEdge);
+    // Get path contour
+    if (aShapePath.ShapeType() == TopAbs_WIRE) {
+      aWirePath = TopoDS::Wire(aShapePath);
     } 
     else {
-      if(aCI) delete aCI;
-      Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
-    } 
+      if (aShapePath.ShapeType() == TopAbs_EDGE) {
+       TopoDS_Edge anEdge = TopoDS::Edge(aShapePath);
+       aWirePath = BRepBuilderAPI_MakeWire(anEdge);
+      } 
+      else {
+       if(aCI) delete aCI;
+       Standard_TypeMismatch::Raise("MakePipe aborted : path shape is neither a wire nor an edge");
+      } 
+    }
   }
-  
+
   TopoDS_Shape aShape;
 
   if (aType == PIPE_BASE_PATH) {
@@ -1146,8 +1920,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
   }
 
   //building pipe with different sections
-  else if (aType == PIPE_DIFFERENT_SECTIONS) 
-  {
+  else if (aType == PIPE_DIFFERENT_SECTIONS) {
     GEOMImpl_IPipeDiffSect* aCIDS = (GEOMImpl_IPipeDiffSect*)aCI;
     //GEOMImpl_IPipeDiffSect* aCIDS = static_cast<GEOMImpl_IPipeDiffSect*>(aCI);
     //BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
@@ -1159,16 +1932,14 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
     Standard_Integer i =1, nbBases = aBasesObjs->Length(), 
       nbLocs = (aLocObjs.IsNull() ? 0 :aLocObjs->Length());
     
-    if(nbLocs && nbLocs != nbBases)
-    {
+    if(nbLocs && nbLocs != nbBases) {
       if(aCI) delete aCI;
       Standard_ConstructionError::Raise("Number of sections is not equal to number of locations ");
     }
     TopTools_SequenceOfShape aSeqBases;
     TopTools_SequenceOfShape aSeqLocs;
     TopTools_SequenceOfShape aSeqFaces;
-    for( ; i <= nbBases; i++) 
-    {
+    for( ; i <= nbBases; i++) {
       Handle(Standard_Transient) anItem = aBasesObjs->Value(i);
       if(anItem.IsNull())
        continue;
@@ -1204,8 +1975,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
         aSeqFaces.Append(aShapeBase);
        aSeqBases.Append(aWire);
       }
-      else if(aTypeBase == TopAbs_FACE)
-      {
+      else if(aTypeBase == TopAbs_FACE) {
        NeedCreateSolid = Standard_True;
        //for case one path should be used other type function
         aSeqFaces.Append(aShapeBase);
@@ -1219,14 +1989,12 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       else if(aTypeBase == TopAbs_WIRE || aTypeBase == TopAbs_VERTEX) {
         aSeqBases.Append(aShapeBase);
       }
-      else if(aTypeBase == TopAbs_EDGE)
-      {
+      else if(aTypeBase == TopAbs_EDGE) {
         TopoDS_Edge anEdge = TopoDS::Edge(aShapeBase);
        TopoDS_Shape aWireProf = BRepBuilderAPI_MakeWire(anEdge);
        aSeqBases.Append(aWireProf);
       }
-      if(nbLocs) 
-      {
+      if(nbLocs) {
         Handle(Standard_Transient) anItemLoc = aLocObjs->Value(i);
        if(anItemLoc.IsNull())
          continue;
@@ -1241,6 +2009,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
     nbLocs = aSeqLocs.Length();
 
     // skl 02.05.2007
+    TopTools_SequenceOfShape Edges;
     if(nbLocs>0) {
       // we have to check that each location shape is a vertex from
       // path and update aSeqLocs if it is needed (and possible)
@@ -1249,7 +2018,7 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
        TopoDS_Vertex V = TopoDS::Vertex(aSeqLocs.Value(i));
        PLocs.Append(BRep_Tool::Pnt(V));
       }
-      TopTools_SequenceOfShape Edges;
+      //TopTools_SequenceOfShape Edges;
       TopExp_Explorer anExp;
       for ( anExp.Init( aWirePath, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
        Edges.Append(anExp.Current());
@@ -1347,39 +2116,153 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       }
     }
 
-    BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
+    // check curvature of wire for condition that
+    // max summary angle between directions along
+    // wire path must be < 4*PI. If not - split wire
+    // and seguences of shapes, perform pipe for each
+    // and make sewing after that
+    double fp,lp;
+    Handle(Geom_Curve) C = BRep_Tool::Curve(TopoDS::Edge(Edges.Value(1)),fp,lp);
+    gp_Pnt P1,P2;
+    gp_Vec Vec1,Vec2;
+    C->D1(fp,P1,Vec1);
+    C->D1(lp,P2,Vec2);
+    double SumAng = fabs(Vec1.Angle(Vec2));
+    Vec1 = Vec2;
+    P1 = P2;
+    TColStd_SequenceOfInteger SplitEdgeNums,SplitLocNums;
+    int LastLoc = 1;
+    //cout<<"Edges.Length()="<<Edges.Length()<<endl;
+    for(i=2; i<=Edges.Length(); i++) {
+      TopoDS_Edge edge = TopoDS::Edge(Edges.Value(i));
+      double tol = BRep_Tool::Tolerance(edge);
+      Handle(Geom_Curve) C = BRep_Tool::Curve(edge,fp,lp);
+      C->D1(lp,P2,Vec2);
+      double ang = fabs(Vec1.Angle(Vec2));
+      SumAng += ang;
+      if(SumAng>4*PI) {
+       SumAng = ang;
+       SplitEdgeNums.Append(i-1);
+       int j;
+       for(j=LastLoc+1; j<=aSeqLocs.Length(); j++) {
+         TopoDS_Vertex aVert = TopoDS::Vertex(aSeqLocs.Value(j));
+         gp_Pnt P = BRep_Tool::Pnt(aVert);
+         if( P1.Distance(P) < tol ) {
+           SplitLocNums.Append(j);
+           LastLoc = j;
+           break;
+         }
+       }
+      }
+      Vec1 = Vec2;
+      P1 = P2;
+    }
 
-    Standard_Integer nbShapes = aSeqBases.Length();
-    Standard_Integer step = nbShapes/nbBases;
-    
-    if(nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases))
-    {
-      if(aCI) delete aCI;
-      Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
+    //cout<<"SplitEdgeNums.Length()="<<SplitEdgeNums.Length()<<endl;
+    //cout<<"SplitLocNums.Length()="<<SplitLocNums.Length()<<endl;
+    if( SplitLocNums.Length()==SplitEdgeNums.Length() && SplitEdgeNums.Length()>0 ) {
+      TopTools_SequenceOfShape aSeqRes;
+      int nn, num1 = 1, num2 = 1;
+      for(nn=1; nn<=SplitEdgeNums.Length(); nn++) {
+       // create wirepath and sequences of shapes
+       BRep_Builder B;
+       TopoDS_Wire tmpW;
+       B.MakeWire(tmpW);
+       for(i=num1; i<=SplitEdgeNums.Value(nn); i++) {
+         B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
+       }
+       num1 = SplitEdgeNums.Value(nn) + 1;
+       TopTools_SequenceOfShape aTmpSeqBases;
+       TopTools_SequenceOfShape aTmpSeqLocs;
+       for(i=num2; i<=SplitLocNums.Value(nn); i++) {
+         aTmpSeqBases.Append(aSeqBases.Value(i));
+         aTmpSeqLocs.Append(aSeqLocs.Value(i));
+       }
+       num2 = SplitLocNums.Value(nn);
+       // make pipe
+       BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
+       Standard_Integer nbShapes = aTmpSeqBases.Length();
+       for(i=1; i<=nbShapes; i++) {
+         TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
+         TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
+         aBuilder.Add(aTmpSeqBases.Value(i), aVert, aWithContact, aWithCorrect);
+       }
+       if(!aBuilder.IsReady()) {
+         if(aCI) delete aCI;
+         Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
+       }
+       aBuilder.Build();
+       TopoDS_Shape resShape = aBuilder.Shape();
+       aSeqRes.Append(resShape);       
+      }
+      // create wirepath and sequences of shapes for last part
+      BRep_Builder B;
+      TopoDS_Wire tmpW;
+      B.MakeWire(tmpW);
+      for(i=num1; i<=Edges.Length(); i++) {
+       B.Add(tmpW,TopoDS::Edge(Edges.Value(i)));
+      }
+      TopTools_SequenceOfShape aTmpSeqBases;
+      TopTools_SequenceOfShape aTmpSeqLocs;
+      for(i=num2; i<=aSeqLocs.Length(); i++) {
+       aTmpSeqBases.Append(aSeqBases.Value(i));
+       aTmpSeqLocs.Append(aSeqLocs.Value(i));
+      }
+      // make pipe for last part
+      BRepOffsetAPI_MakePipeShell aBuilder(tmpW);
+      Standard_Integer nbShapes = aTmpSeqBases.Length();
+      for(i=1; i<=nbShapes; i++) {
+       TopoDS_Shape aShapeLoc = aTmpSeqLocs.Value(i);
+       TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
+       aBuilder.Add(aTmpSeqBases.Value(i), aVert, aWithContact, aWithCorrect);
+      }
+      if(!aBuilder.IsReady()) {
+       if(aCI) delete aCI;
+       Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
+      }
+      aBuilder.Build();
+      TopoDS_Shape resShape = aBuilder.Shape();
+      aSeqRes.Append(resShape);
+      // make sewing for result
+      Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
+      aSewing->SetTolerance(Precision::Confusion());
+      aSewing->SetFaceMode(Standard_True);
+      aSewing->SetFloatingEdgesMode(Standard_False);
+      aSewing->SetNonManifoldMode(Standard_False);
+      for(i=1; i<=aSeqRes.Length(); i++) {
+       aSewing->Add(aSeqRes.Value(i));
+      }
+      aSewing->Perform();
+      aShape = aSewing->SewedShape();
     }
-     
-    Standard_Integer ind =0;    
-    for( i=1; i  <= nbShapes && ind < nbShapes; i++) //i+nbBases <= nbShapes
-    {
-      TopTools_SequenceOfShape usedBases;
-      Standard_Integer j = 1;
-      for( ; j <= nbBases ; j++) 
-      {
-       ind = i + (j-1)*step;
-       
-        TopoDS_Shape aWireProf = aSeqBases.Value(ind);
-        usedBases.Append(aWireProf);
-        if(nbLocs) 
-        {
-          TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
-           TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
-           aBuilder.Add(aWireProf,aVert,aWithContact,aWithCorrect);
-        }
-        else
-           aBuilder.Add(aWireProf,aWithContact,aWithCorrect);
+    else {
+      // old implementation without splitting
+      BRepOffsetAPI_MakePipeShell aBuilder(aWirePath);
+
+      Standard_Integer nbShapes = aSeqBases.Length();
+      Standard_Integer step = nbShapes/nbBases;
+    
+      if(nbShapes < nbBases || fmod((double)nbShapes, (double)nbBases)) {
+       if(aCI) delete aCI;
+       Standard_ConstructionError::Raise("Invalid sections were specified for building pipe");
       }
-      if(!aBuilder.IsReady())
-      {
+      Standard_Integer ind =0;  
+      for( i=1; i  <= nbShapes && ind < nbShapes; i++) { //i+nbBases <= nbShapes
+       TopTools_SequenceOfShape usedBases;
+       Standard_Integer j = 1;
+       for( ; j <= nbBases ; j++) {
+         ind = i + (j-1)*step;
+         TopoDS_Shape aWireProf = aSeqBases.Value(ind);
+         usedBases.Append(aWireProf);
+         if(nbLocs) {
+           TopoDS_Shape aShapeLoc = aSeqLocs.Value(j);
+           TopoDS_Vertex aVert = TopoDS::Vertex(aShapeLoc);
+           aBuilder.Add(aWireProf,aVert,aWithContact,aWithCorrect);
+         }
+         else
+           aBuilder.Add(aWireProf,aWithContact,aWithCorrect);
+       }
+      if(!aBuilder.IsReady()) {
        if(aCI) delete aCI;
         Standard_ConstructionError::Raise("Invalid input data for building PIPE: bases are invalid");
       }
@@ -1388,17 +2271,17 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
       aSeqFaces.Append(aShape);        
       for( j = 1; j <=usedBases.Length(); j++)
         aBuilder.Delete(usedBases.Value(j));
-    }
+      }
        
-    //for case if section is face 
-    if(aSeqFaces.Length() >1)
-    {
-      BRep_Builder aB;
-      TopoDS_Compound aComp;
-      aB.MakeCompound(aComp);
-      for( i = 1; i <= aSeqFaces.Length(); i++)
-        aB.Add(aComp,aSeqFaces.Value(i));
-      aShape = aComp;
+      //for case if section is face 
+      if(aSeqFaces.Length() >1)        {
+       BRep_Builder aB;
+       TopoDS_Compound aComp;
+       aB.MakeCompound(aComp);
+       for( i = 1; i <= aSeqFaces.Length(); i++)
+         aB.Add(aComp,aSeqFaces.Value(i));
+       aShape = aComp;
+      }
     }
   }
 
@@ -1407,6 +2290,11 @@ Standard_Integer GEOMImpl_PipeDriver::Execute(TFunction_Logbook& log) const
     aShape = CreatePipeForShellSections(aWirePath,aCI);
   }
 
+  //building pipe shell sections without path
+  else if (aType == PIPE_SHELLS_WITHOUT_PATH) {
+    aShape = CreatePipeShellsWithoutPath(aCI);
+  }
+
   if (aShape.IsNull()) return 0;
 
   BRepCheck_Analyzer ana (aShape, Standard_False);
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 83a98e3a40a427682b8c71d7d40f389805f016ae..e730e0e0302df5827e339b6463a90785939633ac 100644 (file)
@@ -597,7 +597,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
                  CORBA::Boolean theWithContact,
                  CORBA::Boolean theWithCorrections)
 {
-   GEOM::GEOM_Object_var aGEOMObject;
+  GEOM::GEOM_Object_var aGEOMObject;
 
   //Set a not done flag
   GetOperations()->SetNotDone();
@@ -659,3 +659,57 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeWithShellSections
 
   return GetObject(anObject);
 }
+
+
+//=============================================================================
+/*!
+ *  MakePipeShellsWithoutPath
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakePipeShellsWithoutPath
+                 (const GEOM::ListOfGO& theBases,
+                 const GEOM::ListOfGO& theLocations)
+{
+  GEOM::GEOM_Object_var aGEOMObject;
+
+  //Set a not done flag
+  GetOperations()->SetNotDone();
+  Handle(TColStd_HSequenceOfTransient) aSeqBases = new TColStd_HSequenceOfTransient;
+  Handle(TColStd_HSequenceOfTransient) aSeqLocations = new TColStd_HSequenceOfTransient;
+  int ind=0, aNbBases=0, aNbLocs=0;
+  
+  //Get the shapes
+  aNbBases = theBases.length();
+  aNbLocs = theLocations.length();
+
+  if( aNbLocs &&  aNbBases != aNbLocs)
+    return aGEOMObject._retn();
+  
+  for (ind = 0; ind < aNbBases; ind++) {
+    if (theBases[ind] == NULL) continue;
+    Handle(GEOM_Object) aBase = GetOperations()->GetEngine()->
+      GetObject(theBases[ind]->GetStudyID(), theBases[ind]->GetEntry());
+    if(aBase.IsNull())
+      continue;
+    if(aNbLocs) {
+      Handle(GEOM_Object) aLoc = GetOperations()->GetEngine()->GetObject
+       (theLocations[ind]->GetStudyID(), theLocations[ind]->GetEntry());
+      if(aLoc.IsNull())
+       continue;
+      aSeqLocations->Append(aLoc);
+    }
+    aSeqBases->Append(aBase);
+  }
+
+  if(!aSeqBases->Length())
+    return aGEOMObject._retn();
+
+  // Make pipe
+  Handle(GEOM_Object) anObject =
+    GetOperations()->MakePipeShellsWithoutPath(aSeqBases,aSeqLocations);
+
+  if (!GetOperations()->IsDone() || anObject.IsNull())
+    return aGEOMObject._retn();
+
+  return GetObject(anObject);
+}
index fe86685a90e684077ad46e8919b04ae7d1bbdcdd..6c3febbc97261efb6f07a41efedd9a35c3236d59 100644 (file)
@@ -113,6 +113,9 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i :
                                                  CORBA::Boolean theWithContact,
                                                  CORBA::Boolean theWithCorrections);
 
+  GEOM::GEOM_Object_ptr MakePipeShellsWithoutPath(const GEOM::ListOfGO& theBases,
+                                                 const GEOM::ListOfGO& theLocations);
+
   ::GEOMImpl_I3DPrimOperations* GetOperations()
   { return (::GEOMImpl_I3DPrimOperations*)GetImpl(); }
 };
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 218a0bd7653e653b0e26477668671e3df7e5b11d..4db8a26d410dac87a029955a3ef29e1482207c14 100644 (file)
@@ -56,6 +56,9 @@ class GEOM_I_EXPORT 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 31c215150d7bd884917e92158a91d8d7827c5dcd..5694df6da40d7e711721340e27f2710214f50d51 100644 (file)
@@ -993,6 +993,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithDifferentSections
   return anObj;
 }
 
+
 //=============================================================================
 //  MakePipe:
 //=============================================================================
@@ -1015,6 +1016,24 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeWithShellSections
   return anObj;
 }
 
+
+//=============================================================================
+//  MakePipe:
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_Superv_i::MakePipeShellsWithoutPath
+                   (const GEOM::ListOfGO& theBases,
+                   const GEOM::ListOfGO& theLocations)
+{
+  beginService( " GEOM_Superv_i::MakePipeShellsWithoutPath" );
+  MESSAGE("GEOM_Superv_i::MakePipeShellsWithoutPath");
+  get3DPrimOp();
+  GEOM::GEOM_Object_ptr anObj =
+    my3DPrimOp->MakePipeShellsWithoutPath(theBases,theLocations);
+  endService( " GEOM_Superv_i::MakePipeShellsWithoutPath" );
+  return anObj;
+}
+
+
 //=============================================================================
 //  MakeFuse:
 //=============================================================================
index 6075d24051925f14e93c48470727789c9d27bf30..da845122221aa45d2da6d6d6128ab951ba76e789 100644 (file)
@@ -244,6 +244,9 @@ public:
                                                  CORBA::Boolean theWithContact,
                                                  CORBA::Boolean theWithCorrections);
 
+  GEOM::GEOM_Object_ptr MakePipeShellsWithoutPath(const GEOM::ListOfGO& theBases,
+                                                 const GEOM::ListOfGO& theLocations);
+  
   //-----------------------------------------------------------//
   // BooleanOperations                                         //
   //-----------------------------------------------------------//
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 011711d177f51f4f4d257cc79bbb3613b33543d2..ae478628ec51368bb7f9a082dd1094c193afb0bd 100644 (file)
@@ -731,9 +731,12 @@ class geompyDC(GEOM._objref_GEOM_Gen):
         #                            orthogonal to the spine tangent in the correspondent point
         #  @return New GEOM_Object, containing the created pipe.
         #
-        #  Example: see GEOM_TestAll.py
-        def MakePipeWithDifferentSections(self,theSeqBases, theLocations,thePath,theWithContact,theWithCorrection):
-            anObj = self.PrimOp.MakePipeWithDifferentSections(theSeqBases, theLocations,thePath,theWithContact,theWithCorrection)
+        def MakePipeWithDifferentSections(self, theSeqBases,
+                                          theLocations, thePath,
+                                          theWithContact, theWithCorrection):
+            anObj = self.PrimOp.MakePipeWithDifferentSections(theSeqBases,
+                                                              theLocations, thePath,
+                                                              theWithContact, theWithCorrection)
             if self.PrimOp.IsDone() == 0:
                 print "MakePipeWithDifferentSections : ", self.PrimOp.GetErrorCode()
             return anObj
@@ -755,7 +758,6 @@ class geompyDC(GEOM._objref_GEOM_Gen):
         #                            orthogonal to the spine tangent in the correspondent point
         #  @return New GEOM_Object, containing the created solids.
         #
-        #  Example: see GEOM_TestAll.py
         def MakePipeWithShellSections(self,theSeqBases, theSeqSubBases,
                                       theLocations, thePath,
                                       theWithContact, theWithCorrection):
@@ -765,7 +767,50 @@ class geompyDC(GEOM._objref_GEOM_Gen):
             if self.PrimOp.IsDone() == 0:
                 print "MakePipeWithShellSections : ", self.PrimOp.GetErrorCode()
             return anObj
-    
+
+        def MakePipeWithShellSectionsBySteps(self, theSeqBases, theSeqSubBases,
+                                             theLocations, thePath,
+                                             theWithContact, theWithCorrection):
+            res = []
+            nbsect = len(theSeqBases)
+            nbsubsect = len(theSeqSubBases)
+            #print "nbsect = ",nbsect
+            for i in range(1,nbsect):
+                #print "  i = ",i
+                tmpSeqBases = [ theSeqBases[i-1], theSeqBases[i] ]
+                tmpLocations = [ theLocations[i-1], theLocations[i] ]
+                tmpSeqSubBases = []
+                if nbsubsect>0: tmpSeqSubBases = [ theSeqSubBases[i-1], theSeqSubBases[i] ]
+                anObj = self.PrimOp.MakePipeWithShellSections(tmpSeqBases, tmpSeqSubBases,
+                                                              tmpLocations, thePath,
+                                                              theWithContact, theWithCorrection)
+                if self.PrimOp.IsDone() == 0:
+                    print "Problems with pipe creation between ",i," and ",i+1," sections"
+                    print "MakePipeWithShellSections : ", self.PrimOp.GetErrorCode()
+                    break
+                else:
+                    print "Pipe between ",i," and ",i+1," sections is OK"
+                    res.append(anObj)
+                    pass
+                pass
+            
+            resc = self.MakeCompound(res)
+            #resc = self.MakeSewing(res, 0.001)
+            #print "resc: ",resc
+            return resc
+        
+        ## Create solids between given sections
+        #  @param theSeqBases - list of sections (shell or face).
+        #  @param theLocations - list of corresponding vertexes
+        #  @return New GEOM_Object, containing the created solids.
+        #
+        def MakePipeShellsWithoutPath(self, theSeqBases, theLocations):
+            anObj = self.PrimOp.MakePipeShellsWithoutPath(theSeqBases, theLocations)
+            if self.PrimOp.IsDone() == 0:
+                print "MakePipeShellsWithoutPath : ", self.PrimOp.GetErrorCode()
+            return anObj
+        
+        
         # -----------------------------------------------------------------------------
         # Create base shapes
         # -----------------------------------------------------------------------------
@@ -2099,6 +2144,19 @@ class geompyDC(GEOM._objref_GEOM_Gen):
                 print "GetCentreOfMass : ", self.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(self, theFace, theOptionalPoint = None):
+            anObj = self.MeasuOp.GetNormal(theFace, theOptionalPoint)
+            if self.MeasuOp.IsDone() == 0:
+                print "GetNormal : ", self.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 bdd6b86e5972068cb70ed76a84e2712eebe2f9ba..e2462292fc323abc7f993b32d8017133de9add65 100644 (file)
@@ -47,6 +47,7 @@ dist_libMeasureGUI_la_SOURCES = \
        MeasureGUI_Skeleton.cxx \
        MeasureGUI_PropertiesDlg.cxx \
        MeasureGUI_CenterMassDlg.cxx \
+       MeasureGUI_NormaleDlg.cxx \
        MeasureGUI_InertiaDlg.cxx \
        MeasureGUI_BndBoxDlg.cxx \
        MeasureGUI_DistanceDlg.cxx \
@@ -68,6 +69,7 @@ MOC_FILES = \
        MeasureGUI_Skeleton_moc.cxx \
        MeasureGUI_PropertiesDlg_moc.cxx \
        MeasureGUI_CenterMassDlg_moc.cxx \
+       MeasureGUI_NormaleDlg_moc.cxx \
        MeasureGUI_InertiaDlg_moc.cxx \
        MeasureGUI_BndBoxDlg_moc.cxx \
        MeasureGUI_DistanceDlg_moc.cxx \
index ffd5a7e84f5af692b661af048c6041794e5be0a3..84571cf769f95d984818de17a00abdcb9cc80ceb 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..757c755
--- /dev/null
@@ -0,0 +1,74 @@
+//  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 "GEOM_MeasureGUI.hxx"
+
+#include "GEOMBase_Skeleton.h"
+#include "DlgRef_2Sel_QTD.h"
+
+//=================================================================================
+// class    : MeasureGUI_NormaleDlg
+// purpose  :
+//=================================================================================
+class GEOM_MEASUREGUI_EXPORT 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