Salome HOME
Merge with OCC-V2_1_0_deb
authoradmin <salome-admin@opencascade.com>
Fri, 17 Dec 2004 11:07:35 +0000 (11:07 +0000)
committeradmin <salome-admin@opencascade.com>
Fri, 17 Dec 2004 11:07:35 +0000 (11:07 +0000)
48 files changed:
Makefile.in
resources/SMESH_en.xml
resources/advanced_mesh_info.png [new file with mode: 0644]
resources/standard_mesh_info.png [new file with mode: 0644]
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/SMESH/Makefile.in
src/SMESH/SMESH_1D_Algo.cxx
src/SMESH/SMESH_2D_Algo.cxx
src/SMESH/SMESH_3D_Algo.cxx
src/SMESH/SMESH_Block.cxx [new file with mode: 0644]
src/SMESH/SMESH_Block.hxx [new file with mode: 0644]
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Hypothesis.cxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESHGUI/Makefile.in
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx
src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx
src/SMESHGUI/SMESHGUI_RotationDlg.cxx
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
src/SMESHGUI/SMESH_msg_en.po
src/SMESH_I/Makefile.in
src/SMESH_I/SMESH.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_Gen_i_1.cxx
src/SMESH_I/SMESH_MEDFamily_i.hxx
src/SMESH_I/SMESH_MEDMesh_i.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_SWIG/Makefile.in
src/SMESH_SWIG/SMESH_GroupFromGeom2.py [new file with mode: 0755]
src/SMESH_SWIG/SMESH_Sphere.py [new file with mode: 0644]
src/SMESH_SWIG/SMESH_box.py [new file with mode: 0755]
src/SMESH_SWIG/SMESH_demo_hexa2_upd.py [new file with mode: 0755]
src/SMESH_SWIG/SMESH_hexaedre.py [new file with mode: 0755]
src/SMESH_SWIG/meshpy.py
src/StdMeshers/Makefile.in
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Penta_3D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx

index cae80c1..7b95934 100644 (file)
@@ -38,6 +38,8 @@ mesh_hypo_length.png \
 mesh_hypo_segment.png \
 mesh_hypo_volume.png \
 mesh_info.png \
+advanced_mesh_info.png \
+standard_mesh_info.png \
 mesh_init.png \
 mesh_length.png \
 mesh_free_edges.png \
index 0fe9cf4..b574a7f 100644 (file)
@@ -67,7 +67,8 @@
      <separator pos-id=""/>
      <popup-item item-id="813" pos-id="" label-id="Delete Groups" icon-id="mesh_deleteGroups.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
      <separator pos-id=""/>
-     <popup-item item-id="900" pos-id="" label-id="Mesh Infos" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+     <popup-item item-id="900" pos-id="" label-id="Advanced Mesh Infos" icon-id="advanced_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+     <popup-item item-id="902" pos-id="" label-id="Standard Mesh Infos" icon-id="standard_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
 </menu-item>
 
 <!-- ************************** Control  (menubar)  ************************************ -->
    <separator pos-id=""/>
    <popup-item item-id="701" pos-id="" label-id="Compute" icon-id="mesh_compute.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
    <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
-   <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
+   <popup-item item-id="900" pos-id="" label-id="Show Advanced Info" icon-id="advanced_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
+   <popup-item item-id="902" pos-id="" label-id="Show Standard Info" icon-id="standard_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
    <separator pos-id=""/>
    <popup-item item-id="801" pos-id="" label-id="Create Group" icon-id="mesh_tree_group.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
    <separator pos-id=""/>
 
 <popupmenu label-id="Popup for Viewer" context-id="" parent-id="Viewer" object-id="Mesh">
    <popup-item item-id="214" pos-id="" label-id="Update" icon-id="mesh_update.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/> 
-   <popup-item item-id="900" pos-id="" label-id="Show Info" icon-id="mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
+   <popup-item item-id="900" pos-id="" label-id="Show Advanced Info" icon-id="advanced_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
+   <popup-item item-id="902" pos-id="" label-id="Show Standard Info" icon-id="standard_mesh_info.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
    <separator pos-id=""/>   
    <submenu label-id="Numbering" item-id="114" pos-id="">
      <popup-item item-id="9010" pos-id="" label-id="Display Nodes #" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
    <toolbutton-item item-id="802" pos-id="" label-id="Construct Group" icon-id="mesh_make_group.png" tooltip-id="Construct Group" accel-id="" toggle-id="" execute-action=""/>
    <toolbutton-item item-id="803" pos-id="" label-id="Edit Group" icon-id="mesh_edit_group.png" tooltip-id="Edit Group" accel-id="" toggle-id="" execute-action=""/>
    <separatorTB/>
-   <toolbutton-item item-id="900" pos-id="" label-id="Mesh Infos" icon-id="mesh_info.png" tooltip-id="Mesh Infos" accel-id="" toggle-id="" execute-action=""/>
+   <toolbutton-item item-id="900" pos-id="" label-id="Advanced Mesh Infos" icon-id="advanced_mesh_info.png" tooltip-id="Advanced Mesh Infos" accel-id="" toggle-id="" execute-action=""/>
+   <toolbutton-item item-id="902" pos-id="" label-id="Standard Mesh Infos" icon-id="standard_mesh_info.png" tooltip-id="Standard Mesh Infos" accel-id="" toggle-id="" execute-action=""/>    
 </toolbar>
 
 <toolbar label-id="Hypotheses Toolbar">
diff --git a/resources/advanced_mesh_info.png b/resources/advanced_mesh_info.png
new file mode 100644 (file)
index 0000000..01eaea2
Binary files /dev/null and b/resources/advanced_mesh_info.png differ
diff --git a/resources/standard_mesh_info.png b/resources/standard_mesh_info.png
new file mode 100644 (file)
index 0000000..0600087
Binary files /dev/null and b/resources/standard_mesh_info.png differ
index 69afde9..6bdfc09 100644 (file)
@@ -39,7 +39,7 @@
 #include "MED_Utilities.hxx"
 
 #define _EDF_NODE_IDS_
-#define _ELEMENTS_BY_DIM_
+//#define _ELEMENTS_BY_DIM_
 
 using namespace std;
 
@@ -234,9 +234,9 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        }
 
        double EPS = 1.0E-7;
-       anIsXDimension = (aBounds[1] - aBounds[0]) > EPS;
-       anIsYDimension = (aBounds[3] - aBounds[2]) > EPS;
-       anIsZDimension = (aBounds[5] - aBounds[4]) > EPS;
+       anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
+       anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
+       anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
 
        aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension;
        if(!aMeshDimension)
index 9d31f62..81c62ca 100644 (file)
@@ -45,6 +45,7 @@ EXPORT_HEADERS= \
        SMESH_3D_Algo.hxx \
        SMESH_Group.hxx \
        SMESH_MeshEditor.hxx \
+       SMESH_Block.hxx \
        SMESH_Pattern.hxx
 
 EXPORT_PYSCRIPTS =
@@ -61,6 +62,7 @@ LIB_SRC = SMESH_Gen.cxx SMESH_Mesh.cxx SMESH_subMesh.cxx \
          SMESH_3D_Algo.cxx \
          SMESH_Group.cxx \
          SMESH_MeshEditor.cxx \
+         SMESH_Block.cxx \
          SMESH_Pattern.cxx
 
 LIB_SERVER_IDL = 
@@ -73,10 +75,10 @@ BIN_SRC =
 
 # additionnal information to compile and link file
 CPPFLAGS+= $(OCC_INCLUDES) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
-           $(BOOST_CPPFLAGS)
-CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome
-
-LDFLAGS+= -L${KERNEL_ROOT_DIR}/lib/salome -lSMESHDS -lMeshDriverDAT -lMeshDriverSTL -lMeshDriverMED -lMeshDriverUNV
+           -I${GEOM_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
+CXXFLAGS+= $(OCC_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+           -I${GEOM_ROOT_DIR}/include/salome
+LDFLAGS+= -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome -lNMTTools -lSMESHDS -lMeshDriverDAT -lMeshDriverSTL -lMeshDriverMED -lMeshDriverUNV
 
 @CONCLUDE@
 
index 846f28f..37567a5 100644 (file)
@@ -29,6 +29,7 @@
 using namespace std;
 #include "SMESH_1D_Algo.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_subMesh.hxx"
 
 //=============================================================================
 /*!
index c84a353..d1084f7 100644 (file)
@@ -29,6 +29,7 @@
 using namespace std;
 #include "SMESH_2D_Algo.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_subMesh.hxx"
 
 #include "utilities.h"
 
index ce35f66..d42680f 100644 (file)
@@ -29,6 +29,7 @@
 using namespace std;
 #include "SMESH_3D_Algo.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_subMesh.hxx"
 
 #include "utilities.h"
 
diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx
new file mode 100644 (file)
index 0000000..6550a81
--- /dev/null
@@ -0,0 +1,1019 @@
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+// File      : SMESH_Pattern.hxx
+// Created   : Mon Aug  2 10:30:00 2004
+// Author    : Edward AGAPOV (eap)
+
+#include "SMESH_Block.hxx"
+
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <BRep_Tool.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopLoc_Location.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_Vec.hxx>
+#include <math_FunctionSetRoot.hxx>
+
+#include "utilities.h"
+
+#include <list>
+
+using namespace std;
+
+#define SQRT_FUNC 1
+
+//=======================================================================
+//function : SMESH_Block::TEdge::GetU
+//purpose  : 
+//=======================================================================
+
+double SMESH_Block::TEdge::GetU( const gp_XYZ& theParams ) const
+{
+  double u = theParams.Coord( myCoordInd );
+  return ( 1 - u ) * myFirst + u * myLast;
+}
+
+//=======================================================================
+//function : SMESH_Block::TEdge::Point
+//purpose  : 
+//=======================================================================
+
+gp_XYZ SMESH_Block::TEdge::Point( const gp_XYZ& theParams ) const
+{
+  gp_XYZ p = myC3d->Value( GetU( theParams )).XYZ();
+  if ( myTrsf.Form() != gp_Identity )
+    myTrsf.Transforms( p );
+  return p;
+}
+
+//=======================================================================
+//function : SMESH_Block::TFace::GetUV
+//purpose  : 
+//=======================================================================
+
+gp_XY SMESH_Block::TFace::GetUV( const gp_XYZ& theParams ) const
+{
+  gp_XY uv(0.,0.);
+  double dU = theParams.Coord( GetUInd() );
+  double dV = theParams.Coord( GetVInd() );
+  for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
+  {
+    double Ecoef = 0, Vcoef = 0;
+    switch ( iE ) {
+    case 0:
+      Ecoef = ( 1 - dV ); // u0
+      Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00
+    case 1:
+      Ecoef = dV; // u1
+      Vcoef = dU * ( 1 - dV ); break; // 10
+    case 2:
+      Ecoef = ( 1 - dU ); // 0v
+      Vcoef = dU * dV  ; break; // 11
+    case 3:
+      Ecoef = dU  ; // 1v
+      Vcoef = ( 1 - dU ) * dV  ; break; // 01
+    default:;
+    }
+    // edge addition
+    double u = theParams.Coord( myCoordInd[ iE ] );
+    u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ];
+    uv += Ecoef * myC2d[ iE ]->Value( u ).XY();
+    // corner addition
+    uv -= Vcoef * myCorner[ iE ];
+  }
+  return uv;
+}
+
+//=======================================================================
+//function : SMESH_Block::TFace::Point
+//purpose  : 
+//=======================================================================
+
+gp_XYZ SMESH_Block::TFace::Point( const gp_XYZ& theParams ) const
+{
+  gp_XY uv = GetUV( theParams );
+  gp_XYZ p = myS->Value( uv.X(), uv.Y() ).XYZ();
+  if ( myTrsf.Form() != gp_Identity )
+    myTrsf.Transforms( p );
+  return p;
+}
+
+//=======================================================================
+//function : GetShapeCoef
+//purpose  : 
+//=======================================================================
+
+double* SMESH_Block::GetShapeCoef (const int theShapeID)
+{
+  static double shapeCoef[][3] = {
+    //    V000,        V100,        V010,         V110
+    { -1,-1,-1 }, {  1,-1,-1 }, { -1, 1,-1 }, {  1, 1,-1 },
+    //    V001,        V101,        V011,         V111,
+    { -1,-1, 1 }, {  1,-1, 1 }, { -1, 1, 1 }, {  1, 1, 1 },
+    //    Ex00,        Ex10,        Ex01,         Ex11,
+    {  0,-1,-1 }, {  0, 1,-1 }, {  0,-1, 1 }, {  0, 1, 1 },
+    //    E0y0,        E1y0,        E0y1,         E1y1,
+    { -1, 0,-1 }, {  1, 0,-1 }, { -1, 0, 1 }, {  1, 0, 1 },
+    //    E00z,        E10z,        E01z,         E11z,
+    { -1,-1, 0 }, {  1,-1, 0 }, { -1, 1, 0 }, {  1, 1, 0 },
+    //    Fxy0,        Fxy1,        Fx0z,         Fx1z,         F0yz,           F1yz,
+    {  0, 0,-1 }, {  0, 0, 1 }, {  0,-1, 0 }, {  0, 1, 0 }, { -1, 0, 0 }, {  1, 0, 0 },
+    // ID_Shell
+    {  0, 0, 0 }
+  };
+  if ( theShapeID < ID_V000 || theShapeID > ID_F1yz )
+    return shapeCoef[ ID_Shell - 1 ];
+
+  return shapeCoef[ theShapeID - 1 ];
+}
+
+//=======================================================================
+//function : ShellPoint
+//purpose  : return coordinates of a point in shell
+//=======================================================================
+
+bool SMESH_Block::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const
+{
+  thePoint.SetCoord( 0., 0., 0. );
+  for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ )
+  {
+    // coef
+    double* coefs = GetShapeCoef( shapeID );
+    double k = 1;
+    for ( int iCoef = 0; iCoef < 3; iCoef++ ) {
+      if ( coefs[ iCoef ] != 0 ) {
+        if ( coefs[ iCoef ] < 0 )
+          k *= ( 1. - theParams.Coord( iCoef + 1 ));
+        else
+          k *= theParams.Coord( iCoef + 1 );
+      }
+    }
+    // point on a shape
+    gp_XYZ Ps;
+    if ( shapeID < ID_Ex00 ) // vertex
+      VertexPoint( shapeID, Ps );
+    else if ( shapeID < ID_Fxy0 ) { // edge
+      EdgePoint( shapeID, theParams, Ps );
+      k = -k;
+    } else // face
+      FacePoint( shapeID, theParams, Ps );
+
+    thePoint += k * Ps;
+  }
+  return true;
+}
+
+//=======================================================================
+//function : NbVariables
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::NbVariables() const
+{
+  return 3;
+}
+
+//=======================================================================
+//function : NbEquations
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::NbEquations() const
+{
+  return 1;
+}
+
+//=======================================================================
+//function : Value
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Value(const math_Vector& theXYZ, math_Vector& theFxyz) 
+{
+  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
+  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
+    theFxyz( 1 ) = myValues[ 0 ];
+  }
+  else {
+    ShellPoint( params, P );
+    gp_Vec dP( P - myPoint );
+    theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude();
+  }
+  return true;
+}
+
+//=======================================================================
+//function : Derivatives
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Derivatives(const math_Vector& XYZ,math_Matrix& Df) 
+{
+  MESSAGE( "SMESH_Block::Derivatives()");
+  math_Vector F(1,3);
+  return Values(XYZ,F,Df);
+}
+
+//=======================================================================
+//function : Values
+//purpose  : 
+//=======================================================================
+
+Standard_Boolean SMESH_Block::Values(const math_Vector& theXYZ,
+                                     math_Vector&       theFxyz,
+                                     math_Matrix&       theDf) 
+{
+//  MESSAGE( endl<<"SMESH_Block::Values( "<<theXYZ(1)<<", "<<theXYZ(2)<<", "<<theXYZ(3)<<")");
+
+  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
+  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
+    theFxyz( 1 ) = myValues[ 0 ];
+    theDf( 1,1 ) = myValues[ 1 ];
+    theDf( 1,2 ) = myValues[ 2 ];
+    theDf( 1,3 ) = myValues[ 3 ];
+    return true;
+  }
+
+  ShellPoint( params, P );
+  //myNbIterations++; // how many time call ShellPoint()
+
+  gp_Vec dP( P - myPoint );
+  theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude();
+  if ( theFxyz(1) < 1e-6 ) {
+    myParam      = params;
+    myValues[ 0 ]= 0;
+    theDf( 1,1 ) = 0;
+    theDf( 1,2 ) = 0;
+    theDf( 1,3 ) = 0;
+    return true;
+  }
+
+  if ( theFxyz(1) < myValues[0] )
+  {
+    // 3 partial derivatives
+    gp_Vec drv[ 3 ];
+    for ( int iP = 1; iP <= 3; iP++ ) {
+      gp_XYZ Pi;
+      params.SetCoord( iP, theXYZ( iP ) + 0.001 );
+      ShellPoint( params, Pi );
+      params.SetCoord( iP, theXYZ( iP ) ); // restore params
+      gp_Vec dPi ( P, Pi );
+      double mag = dPi.Magnitude();
+      if ( mag > DBL_MIN )
+        dPi /= mag;
+      drv[ iP - 1 ] = dPi;
+    }
+    for ( int iP = 0; iP < 3; iP++ ) {
+      if ( iP == myFaceIndex )
+        theDf( 1, iP + 1 ) = myFaceParam;
+      else {
+        // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P)
+        // where L is (P -> myPoint), P is defined by the 2 other derivative direction
+        int iPrev = ( iP ? iP - 1 : 2 );
+        int iNext = ( iP == 2 ? 0 : iP + 1 );
+        gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] );
+        double Direc = plnNorm * drv[ iP ];
+        if ( Abs(Direc) <= DBL_MIN )
+          theDf( 1, iP + 1 ) = dP * drv[ iP ];
+        else {
+          double Dis = plnNorm * P - plnNorm * myPoint;
+          theDf( 1, iP + 1 ) = Dis/Direc;
+        }
+      }
+    }
+    //myNbIterations +=3; // how many time call ShellPoint()
+
+    // store better values
+    myParam    = params;
+    myValues[0]= theFxyz(1);
+    myValues[1]= theDf(1,1);
+    myValues[2]= theDf(1,2);
+    myValues[3]= theDf(1,3);
+
+//     SCRUTE( theFxyz(1)  );
+//     SCRUTE( theDf( 1,1 ));
+//     SCRUTE( theDf( 1,2 ));
+//     SCRUTE( theDf( 1,3 ));
+  }
+
+  return true;
+}
+
+//=======================================================================
+//function : ComputeParameters
+//purpose  : compute point parameters in the block
+//=======================================================================
+
+bool SMESH_Block::ComputeParameters(const gp_Pnt& thePoint,
+                                    gp_XYZ&       theParams,
+                                    const int     theShapeID)
+{
+//   MESSAGE( endl<<"SMESH_Block::ComputeParameters( "
+//           <<thePoint.X()<<", "<<thePoint.Y()<<", "<<thePoint.Z()<<")");
+
+  myPoint = thePoint.XYZ();
+
+  myParam.SetCoord( -1,-1,-1 );
+  myValues[0] = 1e100;
+
+  const bool isOnFace = IsFaceID( theShapeID );
+  double * coef = GetShapeCoef( theShapeID );
+
+  // the first guess
+  math_Vector start( 1, 3, 0.0 );
+  if ( !myGridComputed )
+  {
+    // define the first guess by thePoint projection on lines
+    // connecting vertices
+    bool needGrid = false;
+    gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 );
+    double zero = DBL_MIN * DBL_MIN;
+    for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ )
+    {
+      if ( isOnFace && coef[ iParam - 1 ] != 0 ) {
+        iEdge += 4;
+        continue;
+      }
+      for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges
+        gp_Pnt p0 = myEdge[ iEdge ].Point( par000 );
+        gp_Pnt p1 = myEdge[ iEdge ].Point( par111 );
+        gp_Vec v01( p0, p1 ), v0P( p0, thePoint );
+        double len2 = v01.SquareMagnitude();
+        double par = 0;
+        if ( len2 > zero ) {
+          par = v0P.Dot( v01 ) / len2;
+          if ( par < 0 || par > 1 ) {
+            needGrid = true;
+            break;
+          }
+        }
+        start( iParam ) += par;
+      }
+      start( iParam ) /= 4.;
+    }
+    if ( needGrid ) {
+      // compute nodes of 3 x 3 x 3 grid
+      int iNode = 0;
+      for ( double x = 0.25; x < 0.9; x += 0.25 )
+        for ( double y = 0.25; y < 0.9; y += 0.25 )
+          for ( double z = 0.25; z < 0.9; z += 0.25 ) {
+            TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ];
+            prmPtn.first.SetCoord( x, y, z );
+            ShellPoint( prmPtn.first, prmPtn.second );
+          }
+      myGridComputed = true;
+    }
+  }
+  if ( myGridComputed ) {
+    double minDist = DBL_MAX;
+    gp_XYZ* bestParam = 0;
+    for ( int iNode = 0; iNode < 27; iNode++ ) {
+      TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ];
+      double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus();
+      if ( dist < minDist ) {
+        minDist = dist;
+        bestParam = & prmPtn.first;
+      }
+    }
+    start( 1 ) = bestParam->X();
+    start( 2 ) = bestParam->Y();
+    start( 3 ) = bestParam->Z();
+  }
+
+  int myFaceIndex = -1;
+  if ( isOnFace ) {
+    // put a point on the face
+    for ( int iCoord = 0; iCoord < 3; iCoord++ )
+      if ( coef[ iCoord ] ) {
+        myFaceIndex = iCoord;
+        myFaceParam = ( coef[ myFaceIndex ] < 0.5 ) ? 0.0 : 1.0;
+        start( iCoord + 1 ) = myFaceParam;
+      }
+  }
+  math_Vector low  ( 1, 3, 0.0 );
+  math_Vector up   ( 1, 3, 1.0 );
+  math_Vector tol  ( 1, 3, 1e-4 );
+  math_FunctionSetRoot paramSearch( *this, tol );
+
+  int nbLoops = 0;
+  while ( myValues[0] > 1e-1 && nbLoops++ < 10 ) {
+    paramSearch.Perform ( *this, start, low, up );
+    if ( !paramSearch.IsDone() ) {
+      //MESSAGE( " !paramSearch.IsDone() " );
+    }
+    else {
+      //MESSAGE( " NB ITERATIONS: " << paramSearch.NbIterations() );
+    }
+    start( 1 ) = myParam.X();
+    start( 2 ) = myParam.Y();
+    start( 3 ) = myParam.Z();
+    //MESSAGE( "Distance: " << ( SQRT_FUNC ? sqrt(myValues[0]) : myValues[0] ));
+  }
+//   MESSAGE( endl << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl);
+//   mySumDist += myValues[0];
+//   MESSAGE( " TOTAL NB ITERATIONS: " << myNbIterations <<
+//             " DIST: " << ( SQRT_FUNC ? sqrt(mySumDist) : mySumDist ));
+
+
+  theParams = myParam;
+
+  return true;
+}
+
+//=======================================================================
+//function : GetStateNumber
+//purpose  : 
+//=======================================================================
+
+Standard_Integer SMESH_Block::GetStateNumber ()
+{
+//   MESSAGE( endl<<"SMESH_Block::GetStateNumber( "<<myParam.X()<<", "<<
+//           myParam.Y()<<", "<<myParam.Z()<<") DISTANCE: " << myValues[0]);
+  return myValues[0] < 1e-1;
+}
+
+//=======================================================================
+//function : DumpShapeID
+//purpose  : debug an id of a block sub-shape
+//=======================================================================
+
+#define CASEDUMP(id,strm) case id: strm << #id; break;
+
+ostream& SMESH_Block::DumpShapeID (const int id, ostream& stream)
+{
+  switch ( id ) {
+  CASEDUMP( ID_V000, stream );
+  CASEDUMP( ID_V100, stream );
+  CASEDUMP( ID_V010, stream );
+  CASEDUMP( ID_V110, stream );
+  CASEDUMP( ID_V001, stream );
+  CASEDUMP( ID_V101, stream );
+  CASEDUMP( ID_V011, stream );
+  CASEDUMP( ID_V111, stream );
+  CASEDUMP( ID_Ex00, stream );
+  CASEDUMP( ID_Ex10, stream );
+  CASEDUMP( ID_Ex01, stream );
+  CASEDUMP( ID_Ex11, stream );
+  CASEDUMP( ID_E0y0, stream );
+  CASEDUMP( ID_E1y0, stream );
+  CASEDUMP( ID_E0y1, stream );
+  CASEDUMP( ID_E1y1, stream );
+  CASEDUMP( ID_E00z, stream );
+  CASEDUMP( ID_E10z, stream );
+  CASEDUMP( ID_E01z, stream );
+  CASEDUMP( ID_E11z, stream );
+  CASEDUMP( ID_Fxy0, stream );
+  CASEDUMP( ID_Fxy1, stream );
+  CASEDUMP( ID_Fx0z, stream );
+  CASEDUMP( ID_Fx1z, stream );
+  CASEDUMP( ID_F0yz, stream );
+  CASEDUMP( ID_F1yz, stream );
+  CASEDUMP( ID_Shell, stream );
+  default: stream << "ID_INVALID";
+  }
+  return stream;
+}
+
+//=======================================================================
+//function : GetShapeIDByParams
+//purpose  : define an id of the block sub-shape by normlized point coord
+//=======================================================================
+
+int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord )
+{
+  //   id ( 0 - 26 ) computation:
+
+  //   vertex     ( 0 - 7 )  : id = 1*x + 2*y + 4*z
+
+  //   edge || X  ( 8 - 11 ) : id = 8   + 1*y + 2*z
+  //   edge || Y  ( 12 - 15 ): id = 1*x + 12  + 2*z
+  //   edge || Z  ( 16 - 19 ): id = 1*x + 2*y + 16 
+
+  //   face || XY ( 20 - 21 ): id = 8   + 12  + 1*z - 0
+  //   face || XZ ( 22 - 23 ): id = 8   + 1*y + 16  - 2
+  //   face || YZ ( 24 - 25 ): id = 1*x + 12  + 16  - 4
+
+  static int iAddBnd[]    = { 1, 2, 4 };
+  static int iAddNotBnd[] = { 8, 12, 16 };
+  static int iFaceSubst[] = { 0, 2, 4 };
+
+  int id = 0;
+  int iOnBoundary = 0;
+  for ( int iCoord = 0; iCoord < 3; iCoord++ )
+  {
+    double val = theCoord.Coord( iCoord + 1 );
+    if ( val == 0.0 )
+      iOnBoundary++;
+    else if ( val == 1.0 )
+      id += iAddBnd[ iOnBoundary++ ];
+    else
+      id += iAddNotBnd[ iCoord ];
+  }
+  if ( iOnBoundary == 1 ) // face
+    id -= iFaceSubst[ (id - 20) / 4 ];
+  else if ( iOnBoundary == 0 ) // shell
+    id = 26;
+
+  if ( id > 26 || id < 0 ) {
+    MESSAGE( "GetShapeIDByParams() = " << id
+            <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() );
+  }
+
+  return id + 1; // shape ids start at 1
+}
+
+
+//=======================================================================
+//function : getOrderedEdges
+//purpose  : return nb wires and a list of oredered edges
+//=======================================================================
+
+static int getOrderedEdges (const TopoDS_Face&   theFace,
+                            const TopoDS_Vertex& theFirstVertex,
+                            list< TopoDS_Edge >& theEdges,
+                            list< int >  &       theNbVertexInWires)
+{
+  // put wires in a list, so that an outer wire comes first
+  list<TopoDS_Wire> aWireList;
+  TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace );
+  aWireList.push_back( anOuterWire );
+  for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() )
+    if ( !anOuterWire.IsSame( wIt.Value() ))
+      aWireList.push_back( TopoDS::Wire( wIt.Value() ));
+
+  // loop on edges of wires
+  theNbVertexInWires.clear();
+  list<TopoDS_Wire>::iterator wlIt = aWireList.begin();
+  for ( ; wlIt != aWireList.end(); wlIt++ )
+  {
+    int iE;
+    BRepTools_WireExplorer wExp( *wlIt, theFace );
+    for ( iE = 0; wExp.More(); wExp.Next(), iE++ )
+    {
+      TopoDS_Edge edge = wExp.Current();
+      edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
+      theEdges.push_back( edge );
+    }
+    theNbVertexInWires.push_back( iE );
+    iE = 0;
+    if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire
+      // orient closed edges
+      list< TopoDS_Edge >::iterator eIt, eIt2;
+      for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ )
+      {
+        TopoDS_Edge& edge = *eIt;
+        if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) ))
+        {
+          eIt2 = eIt;
+          bool isNext = ( eIt2 == theEdges.begin() );
+          TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2);
+          double f1,l1,f2,l2;
+          Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 );
+          Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 );
+          gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 );
+          gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 );
+          bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext );
+          gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 );
+          isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl ));
+          if ( isNext ? isFirst : !isFirst )
+            edge.Reverse();
+        }
+      }
+      // rotate theEdges until it begins from theFirstVertex
+      if ( ! theFirstVertex.IsNull() )
+        while ( !theFirstVertex.IsSame( TopExp::FirstVertex( theEdges.front(), true )))
+        {
+          theEdges.splice(theEdges.end(), theEdges,
+                          theEdges.begin(), ++ theEdges.begin());
+          if ( iE++ > theNbVertexInWires.back() ) 
+            break; // break infinite loop
+        }
+    }
+  }
+
+  return aWireList.size();
+}
+
+//=======================================================================
+//function : LoadBlockShapes
+//purpose  : add sub-shapes of theBlock to theShapeIDMap so that they get
+//           IDs acoording to enum TShapeID
+//=======================================================================
+
+bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell&         theShell,
+                                  const TopoDS_Vertex&        theVertex000,
+                                  const TopoDS_Vertex&        theVertex001,
+//                             TopTools_IndexedMapOfShape& theShapeIDMap
+                                  TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
+{
+  MESSAGE(" ::LoadBlockShapes()");
+
+  myShell = theShell;
+  myNbIterations = 0;
+  mySumDist = 0;
+  myGridComputed = false;
+
+  // 6 vertices
+  TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111;
+  // 12 edges
+  TopoDS_Shape Ex00, Ex10, Ex01, Ex11;
+  TopoDS_Shape E0y0, E1y0, E0y1, E1y1;
+  TopoDS_Shape E00z, E10z, E01z, E11z;
+  // 6 faces
+  TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz;
+
+  // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape
+  // filled by TopExp::MapShapesAndAncestors()
+  const int NB_FACES_BY_VERTEX = 6;
+
+  TopTools_IndexedDataMapOfShapeListOfShape vfMap;
+  TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_FACE, vfMap );
+  if ( vfMap.Extent() != 8 ) {
+    MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() );
+    return false;
+  }
+
+  V000 = theVertex000;
+  V001 = theVertex001;
+
+  if ( V000.IsNull() ) {
+    // find vertex 000 - the one with smallest coordinates
+    double minVal = DBL_MAX, minX, val;
+    for ( int i = 1; i <= 8; i++ ) {
+      const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i ));
+      gp_Pnt P = BRep_Tool::Pnt( v );
+      val = P.X() + P.Y() + P.Z();
+      if ( val < minVal || ( val == minVal && P.X() < minX )) {
+        V000 = v;
+        minVal = val;
+        minX = P.X();
+      }
+    }
+    // find vertex 001 - the one on the most vertical edge passing through V000
+    TopTools_IndexedDataMapOfShapeListOfShape veMap;
+    TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_EDGE, veMap );
+    gp_Vec dir001 = gp::DZ();
+    gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 ));
+    double maxVal = -DBL_MAX;
+    TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 ));
+    for (  ; eIt.More(); eIt.Next() ) {
+      const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() );
+      TopoDS_Vertex v = TopExp::FirstVertex( e );
+      if ( v.IsSame( V000 ))
+        v = TopExp::LastVertex( e );
+      val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized();
+      if ( val > maxVal ) {
+        V001 = v;
+        maxVal = val;
+      }
+    }
+  }
+
+  // find the bottom (Fxy0), Fx0z and F0yz faces
+
+  const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 );
+  const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 );
+  if (f000List.Extent() != NB_FACES_BY_VERTEX ||
+      f001List.Extent() != NB_FACES_BY_VERTEX ) {
+    MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent());
+    return false;
+  }
+  TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List );
+  int i, j, iFound1, iFound2;
+  for ( j = 0; f000It.More(); f000It.Next(), j++ )
+  {
+    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
+    const TopoDS_Shape& F = f000It.Value();
+    for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
+      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+      if ( F.IsSame( f001It.Value() ))
+        break;
+    }
+    if ( f001It.More() ) // Fx0z or F0yz found
+      if ( Fx0z.IsNull() ) {
+        Fx0z = F;
+        iFound1 = i;
+      } else {
+        F0yz = F;
+        iFound2 = i;
+      }
+    else // F is the bottom face
+      Fxy0 = F;
+  }
+  if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) {
+    MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() );
+    return false;
+  }
+
+  // choose the top face (Fxy1)
+  for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
+    if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+    if ( i != iFound1 && i != iFound2 )
+      break;
+  }
+  Fxy1 = f001It.Value();
+  if ( Fxy1.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // find bottom edges and veritices
+  list< TopoDS_Edge > eList;
+  list< int >         nbVertexInWires;
+  getOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires );
+  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  list< TopoDS_Edge >::iterator elIt = eList.begin();
+  for ( i = 0; elIt != eList.end(); elIt++, i++ )
+    switch ( i ) {
+    case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break;
+    case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break;
+    case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break;
+    case 3: Ex00 = *elIt; break;
+    default:;
+    }
+  if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
+    return false;
+  }
+
+
+  // find top edges and veritices
+  eList.clear();
+  getOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires );
+  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ )
+    switch ( i ) {
+    case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break;
+    case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break;
+    case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break;
+    case 3: E0y1 = *elIt; break;
+    default:;
+    }
+  if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
+    return false;
+  }
+
+  // swap Fx0z and F0yz if necessary
+  TopExp_Explorer exp( Fx0z, TopAbs_VERTEX );
+  for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100
+    if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() ))
+      break; // V101 or V100 found
+  if ( !exp.More() ) { // not found
+    TopoDS_Shape f = Fx0z; Fx0z = F0yz; F0yz = f;
+  }
+
+  // find Fx1z and F1yz faces
+  const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 );
+  const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 );
+  if (f111List.Extent() != NB_FACES_BY_VERTEX ||
+      f110List.Extent() != NB_FACES_BY_VERTEX ) {
+    MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent());
+    return false;
+  }
+  TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List);
+  for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) {
+    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
+    const TopoDS_Shape& F = f110It.Value();
+    for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) {
+      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
+      if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found
+        if ( Fx1z.IsNull() )
+          Fx1z = F;
+        else
+          F1yz = F;
+      }
+    }
+  }
+  if ( Fx1z.IsNull() || F1yz.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // swap Fx1z and F1yz if necessary
+  for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() )
+    if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() ))
+      break;
+  if ( !exp.More() ) {
+    TopoDS_Shape f = Fx1z; Fx1z = F1yz; F1yz = f;
+  }
+
+  // find vertical edges
+  for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
+    if ( vFirst.IsSame( V001 ))
+      E00z = edge;
+    else if ( vFirst.IsSame( V100 ))
+      E10z = edge;
+  }
+  if ( E00z.IsNull() || E10z.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+  for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
+    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
+    if ( vFirst.IsSame( V111 ))
+      E11z = edge;
+    else if ( vFirst.IsSame( V010 ))
+      E01z = edge;
+  }
+  if ( E01z.IsNull() || E11z.IsNull() ) {
+    MESSAGE(" LoadBlockShapes() error ");
+    return false;
+  }
+
+  // load shapes in theShapeIDMap
+
+  theShapeIDMap.Clear();
+  
+  theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD ));
+  theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD ));
+
+  theShapeIDMap.Add(Ex00);
+  theShapeIDMap.Add(Ex10);
+  theShapeIDMap.Add(Ex01);
+  theShapeIDMap.Add(Ex11);
+
+  theShapeIDMap.Add(E0y0);
+  theShapeIDMap.Add(E1y0);
+  theShapeIDMap.Add(E0y1);
+  theShapeIDMap.Add(E1y1);
+
+  theShapeIDMap.Add(E00z);
+  theShapeIDMap.Add(E10z);
+  theShapeIDMap.Add(E01z);
+  theShapeIDMap.Add(E11z);
+
+  theShapeIDMap.Add(Fxy0);
+  theShapeIDMap.Add(Fxy1);
+  theShapeIDMap.Add(Fx0z);
+  theShapeIDMap.Add(Fx1z);
+  theShapeIDMap.Add(F0yz);
+  theShapeIDMap.Add(F1yz);
+  
+  theShapeIDMap.Add(myShell);
+
+  if ( theShapeIDMap.Extent() != 27 ) {
+    MESSAGE("LoadBlockShapes() " << theShapeIDMap.Extent() );
+    return false;
+  }
+
+  // store shapes geometry
+  for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ )
+  {
+    const TopoDS_Shape& S = theShapeIDMap( shapeID );
+    switch ( S.ShapeType() )
+    {
+    case TopAbs_VERTEX: {
+
+      if ( shapeID > ID_V111 ) {
+        MESSAGE(" shapeID =" << shapeID );
+        return false;
+      }
+      myPnt[ shapeID - ID_V000 ] =
+        BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ();
+      break;
+    }
+    case TopAbs_EDGE: {
+
+      const TopoDS_Edge& edge = TopoDS::Edge( S );
+      if ( shapeID < ID_Ex00 || shapeID > ID_E11z || edge.IsNull() ) {
+        MESSAGE(" shapeID =" << shapeID );
+        return false;
+      }
+      TEdge& tEdge = myEdge[ shapeID - ID_Ex00 ];
+      tEdge.myCoordInd = GetCoordIndOnEdge( shapeID );
+      TopLoc_Location loc;
+      tEdge.myC3d = BRep_Tool::Curve( edge, loc, tEdge.myFirst, tEdge.myLast );
+      if ( !IsForwardEdge( edge, theShapeIDMap ))
+        Swap( tEdge.myFirst, tEdge.myLast );
+      tEdge.myTrsf = loc;
+      break;
+    }
+    case TopAbs_FACE: {
+
+      const TopoDS_Face& face = TopoDS::Face( S );
+      if ( shapeID < ID_Fxy0 || shapeID > ID_F1yz || face.IsNull() ) {
+        MESSAGE(" shapeID =" << shapeID );
+        return false;
+      }
+      TFace& tFace = myFace[ shapeID - ID_Fxy0 ];
+      // pcurves
+      vector< int > edgeIdVec(4, -1);
+      GetFaceEdgesIDs( shapeID, edgeIdVec );
+      for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
+      {
+        const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ]));
+        tFace.myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] );
+        tFace.myC2d[ iE ] =
+          BRep_Tool::CurveOnSurface( edge, face, tFace.myFirst[iE], tFace.myLast[iE] );
+        if ( !IsForwardEdge( edge, theShapeIDMap ))
+          Swap( tFace.myFirst[ iE ], tFace.myLast[ iE ] );
+      }
+      // 2d corners
+      tFace.myCorner[ 0 ] = tFace.myC2d[ 0 ]->Value( tFace.myFirst[0] ).XY();
+      tFace.myCorner[ 1 ] = tFace.myC2d[ 0 ]->Value( tFace.myLast[0] ).XY();
+      tFace.myCorner[ 2 ] = tFace.myC2d[ 1 ]->Value( tFace.myLast[1] ).XY();
+      tFace.myCorner[ 3 ] = tFace.myC2d[ 1 ]->Value( tFace.myFirst[1] ).XY();
+      // sufrace
+      TopLoc_Location loc;
+      tFace.myS = BRep_Tool::Surface( face, loc );
+      tFace.myTrsf = loc;
+      break;
+    }
+    default: break;
+    }
+  } // loop on shapes in theShapeIDMap
+
+  return true;
+}
+
+//=======================================================================
+//function : GetFaceEdgesIDs
+//purpose  : return edges IDs in the order u0, u1, 0v, 1v
+//           u0 means "|| u, v == 0"
+//=======================================================================
+
+void SMESH_Block::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec )
+{
+  switch ( faceID ) {
+  case ID_Fxy0:
+    edgeVec[ 0 ] = ID_Ex00;
+    edgeVec[ 1 ] = ID_Ex10;
+    edgeVec[ 2 ] = ID_E0y0;
+    edgeVec[ 3 ] = ID_E1y0;
+    break;
+  case ID_Fxy1:
+    edgeVec[ 0 ] = ID_Ex01;
+    edgeVec[ 1 ] = ID_Ex11;
+    edgeVec[ 2 ] = ID_E0y1;
+    edgeVec[ 3 ] = ID_E1y1;
+    break;
+  case ID_Fx0z:
+    edgeVec[ 0 ] = ID_Ex00;
+    edgeVec[ 1 ] = ID_Ex01;
+    edgeVec[ 2 ] = ID_E00z;
+    edgeVec[ 3 ] = ID_E10z;
+    break;
+  case ID_Fx1z:
+    edgeVec[ 0 ] = ID_Ex10;
+    edgeVec[ 1 ] = ID_Ex11;
+    edgeVec[ 2 ] = ID_E01z;
+    edgeVec[ 3 ] = ID_E11z;
+    break;
+  case ID_F0yz:
+    edgeVec[ 0 ] = ID_E0y0;
+    edgeVec[ 1 ] = ID_E0y1;
+    edgeVec[ 2 ] = ID_E00z;
+    edgeVec[ 3 ] = ID_E01z;
+    break;
+  case ID_F1yz:
+    edgeVec[ 0 ] = ID_E1y0;
+    edgeVec[ 1 ] = ID_E1y1;
+    edgeVec[ 2 ] = ID_E10z;
+    edgeVec[ 3 ] = ID_E11z;
+    break;
+  default:
+    MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID );
+  }
+}
diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx
new file mode 100644 (file)
index 0000000..d937aed
--- /dev/null
@@ -0,0 +1,209 @@
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+// File      : SMESH_Block.hxx
+// Created   : Tue Nov 30 12:42:18 2004
+// Author    : Edward AGAPOV (eap)
+
+
+#ifndef SMESH_Block_HeaderFile
+#define SMESH_Block_HeaderFile
+
+#include <Geom2d_Curve.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Surface.hxx>
+#include <TopExp.hxx>
+#include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Trsf.hxx>
+#include <gp_XY.hxx>
+#include <gp_XYZ.hxx>
+#include <math_FunctionSetWithDerivatives.hxx>
+#include <math_Matrix.hxx>
+#include <math_Vector.hxx>
+
+#include <ostream>
+#include <vector>
+
+// =========================================================
+// class calculating coordinates of 3D points by normalized
+// parameters inside the block and vice versa
+// =========================================================
+
+class SMESH_Block: public math_FunctionSetWithDerivatives
+{
+ public:
+  enum TShapeID { // ids of the block sub-shapes
+    ID_NONE = 0,
+
+    ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
+
+    ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
+    ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
+    ID_E00z, ID_E10z, ID_E01z, ID_E11z,
+
+    ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
+
+    ID_Shell
+    };
+  static inline bool IsVertexID( int theShapeID )
+  { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
+
+  static inline bool IsEdgeID( int theShapeID )
+  { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
+
+  static inline bool IsFaceID( int theShapeID )
+  { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
+
+
+  SMESH_Block (): myNbIterations(0), mySumDist(0.) {}
+
+  bool LoadBlockShapes(const TopoDS_Shell&         theShell,
+                       const TopoDS_Vertex&        theVertex000,
+                       const TopoDS_Vertex&        theVertex001,
+//                       TopTools_IndexedMapOfShape& theShapeIDMap
+                       TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
+  // add sub-shapes of theBlock to theShapeIDMap so that they get
+  // IDs acoording to enum TShapeID
+
+  static int GetShapeIDByParams ( const gp_XYZ& theParams );
+  // define an id of the block sub-shape by point parameters
+
+  bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
+    if ( !IsVertexID( theVertexID ))           return false;
+    thePoint = myPnt[ theVertexID - ID_V000 ]; return true;
+  }
+  // return vertex coordinates
+
+  bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
+    if ( !IsEdgeID( theEdgeID ))                                 return false;
+    thePoint = myEdge[ theEdgeID - ID_Ex00 ].Point( theParams ); return true;
+  }
+  // return coordinates of a point on edge
+
+  bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
+    if ( !IsFaceID ( theFaceID ))                                return false;
+    thePoint = myFace[ theFaceID - ID_Fxy0 ].Point( theParams ); return true;
+  }
+  // return coordinates of a point on face
+
+  bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
+  // return coordinates of a point in shell
+
+  bool ComputeParameters (const gp_Pnt& thePoint,
+                          gp_XYZ&       theParams,
+                          const int     theShapeID = ID_Shell);
+  // compute point parameters in the block
+
+  static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec );
+  // return edges IDs of a face in the order u0, u1, 0v, 1v
+
+  static int GetCoordIndOnEdge (const int theEdgeID)
+  { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
+  // return an index of a coordinate which varies along the edge
+
+  static double* GetShapeCoef (const int theShapeID);
+  // for theShapeID( TShapeID ), returns 3 coefficients used
+  // to compute an addition of an on-theShape point to coordinates
+  // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
+  // then the addition of a point P is computed as P*kx*ky*kz and ki is
+  // defined by the returned coef like this:
+  // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
+
+  static bool IsForwardEdge (const TopoDS_Edge &         theEdge, 
+                             //TopTools_IndexedMapOfShape& theShapeIDMap
+                             TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
+    int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
+    int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
+    return ( v1ID < v2ID );
+  }
+  // Return true if an in-block parameter increases along theEdge curve
+
+  static void Swap(double& a, double& b) { double tmp = a; a = b; b = tmp; }
+
+  // methods of math_FunctionSetWithDerivatives
+  Standard_Integer NbVariables() const;
+  Standard_Integer NbEquations() const;
+  Standard_Boolean Value(const math_Vector& X,math_Vector& F) ;
+  Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ;
+  Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ;
+  Standard_Integer GetStateNumber ();
+
+  static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream);
+  // DEBUG: dump an id of a block sub-shape
+
+ private:
+
+  struct TEdge {
+    int                myCoordInd;
+    double             myFirst;
+    double             myLast;
+    Handle(Geom_Curve) myC3d;
+    gp_Trsf            myTrsf;
+    double GetU( const gp_XYZ& theParams ) const;
+    gp_XYZ Point( const gp_XYZ& theParams ) const;
+  };
+
+  struct TFace {
+    // 4 edges in the order u0, u1, 0v, 1v
+    int                  myCoordInd[ 4 ];
+    double               myFirst   [ 4 ];
+    double               myLast    [ 4 ];
+    Handle(Geom2d_Curve) myC2d     [ 4 ];
+    // 4 corner points in the order 00, 10, 11, 01
+    gp_XY                myCorner  [ 4 ];
+    // surface
+    Handle(Geom_Surface) myS;
+    gp_Trsf              myTrsf;
+    gp_XY  GetUV( const gp_XYZ& theParams ) const;
+    gp_XYZ Point( const gp_XYZ& theParams ) const;
+    int GetUInd() const { return myCoordInd[ 0 ]; }
+    int GetVInd() const { return myCoordInd[ 2 ]; }
+  };
+
+  TopoDS_Shell myShell;
+  // geometry:
+  // 8 vertices
+  gp_XYZ myPnt[ 8 ];
+  // 12 edges
+  TEdge  myEdge[ 12 ];
+  // 6 faces
+  TFace  myFace[ 6 ];
+
+  // for param computation
+
+  int      myFaceIndex;
+  double   myFaceParam;
+  int      myNbIterations;
+  double   mySumDist;
+
+  gp_XYZ   myPoint; // the given point
+  gp_XYZ   myParam; // the best parameters guess
+  double   myValues[ 4 ]; // values computed at myParam
+
+  typedef pair<gp_XYZ,gp_XYZ> TxyzPair;
+  TxyzPair my3x3x3GridNodes[ 27 ];
+  bool     myGridComputed;
+};
+
+
+#endif
index 3a202a3..01d864c 100644 (file)
@@ -208,12 +208,21 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
   // mesh the rest subshapes starting from vertices
   // -----------------------------------------------
 
-  smToCompute = sm->GetFirstToCompute();
-  while (smToCompute)
+  int i, nbSub = smMap.size();
+  map<int, SMESH_subMesh*>::const_iterator itSub = smMap.begin();
+  for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus <sm>
   {
+    if ( itSub == smMap.end() )
+      smToCompute = sm;
+    else
+      smToCompute = (itSub++)->second;
+    if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) {
+      if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+        ret = false;
+      continue;
+    }
     TopoDS_Shape subShape = smToCompute->GetSubShape();
-    int dim = GetShapeDim(subShape);
-    if (dim > 0)
+    if ( subShape.ShapeType() != TopAbs_VERTEX )
     {
       if ( !smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE) )
         ret = false;
@@ -229,22 +238,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
         smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
       }
     }
-    smToCompute = sm->GetFirstToCompute();
   }
 
-  if (!ret) return false;
-
-  // JFA for PAL6524: if there are failed sub-meshes, return Standard_False
-  const map < int, SMESH_subMesh * >&subMeshes = sm->DependsOn();
-  map < int, SMESH_subMesh * >::const_iterator itsub;
-  for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++) {
-    SMESH_subMesh *smi = (*itsub).second;
-    if (smi->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) return false;
-  }
-  if (sm->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) return false;
-
-  MESSAGE( "VSR - SMESH_Gen::Compute() finished" );
-  return true;
+  MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
+  return ret;
 }
 
 
index dac1ee3..0107c3e 100644 (file)
@@ -30,6 +30,7 @@ using namespace std;
 using namespace std;
 #include "SMESH_Hypothesis.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_subMesh.hxx"
 #include "utilities.h"
 
 //=============================================================================
index 50c7932..0c05113 100644 (file)
 #include "DriverUNV_R_SMDS_Mesh.h"
 #include "DriverSTL_R_SMDS_Mesh.h"
 
+#include <BRepTools_WireExplorer.hxx>
+#include <BRep_Builder.hxx>
+#include <gp_Pnt.hxx>
+
 #include <TCollection_AsciiString.hxx>
-#include <memory>
-#include <TopTools_ListOfShape.hxx>
 #include <TopExp.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_Array1OfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+
+#include <memory>
+
 #include "Utils_ExceptHandlers.hxx"
 
 #ifdef _DEBUG_
@@ -254,8 +261,7 @@ SMESH_Hypothesis::Hypothesis_Status
   }
 
   SMESH_Hypothesis *anHyp = sc->mapHypothesis[anHypId];
-  if(MYDEBUG) SCRUTE( anHyp->GetName() );
-  int event;
+  MESSAGE( "SMESH_Mesh::AddHypothesis " << anHyp->GetName() );
 
   bool isGlobalHyp = IsMainShape( aSubShape );
 
@@ -272,6 +278,7 @@ SMESH_Hypothesis::Hypothesis_Status
 
   // shape 
 
+  int event;
   if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
     event = SMESH_subMesh::ADD_HYP;
   else
@@ -290,10 +297,26 @@ SMESH_Hypothesis::Hypothesis_Status
       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
     if (ret2 > ret)
       ret = ret2;
+
+    // check concurent hypotheses on ansestors
+    if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
+    {
+      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
+      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
+      for ( ; smIt != smMap.end(); smIt++ ) {
+        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
+          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+          if (ret2 > ret) {
+            ret = ret2;
+            break;
+          }
+        }
+      }
+    }
   }
 
-  subMesh->DumpAlgoState(true);
-  if(MYDEBUG) SCRUTE(ret);
+  if(MYDEBUG) subMesh->DumpAlgoState(true);
+  SCRUTE(ret);
   return ret;
 }
 
@@ -347,22 +370,44 @@ SMESH_Hypothesis::Hypothesis_Status
   else
     event = SMESH_subMesh::REMOVE_ALGO;
   SMESH_Hypothesis::Hypothesis_Status ret = subMesh->AlgoStateEngine(event, anHyp);
-  
+
+  // there may appear concurrent hyps that were covered by the removed hyp
+  if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
+      subMesh->IsApplicableHypotesis( anHyp ) &&
+      subMesh->CheckConcurentHypothesis( anHyp->GetType() ) != SMESH_Hypothesis::HYP_OK)
+    ret = SMESH_Hypothesis::HYP_CONCURENT;
+
   // subShapes
   if (!SMESH_Hypothesis::IsStatusFatal(ret) &&
       !subMesh->IsApplicableHypotesis( anHyp )) // is removed from father
+  {
+    if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
+      event = SMESH_subMesh::REMOVE_FATHER_HYP;
+    else
+      event = SMESH_subMesh::REMOVE_FATHER_ALGO;
+    SMESH_Hypothesis::Hypothesis_Status ret2 =
+      subMesh->SubMeshesAlgoStateEngine(event, anHyp);
+    if (ret2 > ret) // more severe
+      ret = ret2;
+
+    // check concurent hypotheses on ansestors
+    if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
     {
-      if (anHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO)
-       event = SMESH_subMesh::REMOVE_FATHER_HYP;
-      else
-       event = SMESH_subMesh::REMOVE_FATHER_ALGO;
-      SMESH_Hypothesis::Hypothesis_Status ret2 =
-       subMesh->SubMeshesAlgoStateEngine(event, anHyp);
-      if (ret2 > ret) // more severe
-       ret = ret2;
+      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
+      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
+      for ( ; smIt != smMap.end(); smIt++ ) {
+        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
+          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+          if (ret2 > ret) {
+            ret = ret2;
+            break;
+          }
+        }
+      }
     }
+  }
   
-  subMesh->DumpAlgoState(true);
+  if(MYDEBUG) subMesh->DumpAlgoState(true);
   if(MYDEBUG) SCRUTE(ret);
   return ret;
 }
@@ -864,6 +909,256 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID)
   delete _mapGroup[theGroupID];
 }
 
+//=============================================================================
+/*!
+ *  IsLocal1DHypothesis
+ *  Check, if there is 1D hypothesis assigned directly on <theEdge>
+ */
+//=============================================================================
+bool SMESH_Mesh::IsLocal1DHypothesis (const TopoDS_Shape& theEdge)
+{
+  const SMESHDS_Mesh* meshDS = GetMeshDS();
+  const list<const SMESHDS_Hypothesis*>& listHyp = meshDS->GetHypothesis(theEdge);
+  list<const SMESHDS_Hypothesis*>::const_iterator it = listHyp.begin();
+
+  for (; it != listHyp.end(); it++) {
+    const SMESH_Hypothesis * aHyp = static_cast<const SMESH_Hypothesis*>(*it);
+    if (aHyp->GetType() == SMESHDS_Hypothesis::PARAM_ALGO &&
+        aHyp->GetDim() == 1) { // 1D Hypothesis found
+      return true;
+    }
+  }
+  return false;
+}
+
+//=============================================================================
+/*!
+ *  IsPropagationHypothesis
+ */
+//=============================================================================
+bool SMESH_Mesh::IsPropagationHypothesis (const TopoDS_Shape& theEdge)
+{
+  return _mapPropagationChains.Contains(theEdge);
+}
+
+//=============================================================================
+/*!
+ *  IsPropagatedHypothesis
+ */
+//=============================================================================
+bool SMESH_Mesh::IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
+                                         TopoDS_Shape&       theMainEdge)
+{
+  int nbChains = _mapPropagationChains.Extent();
+  for (int i = 1; i <= nbChains; i++) {
+    const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromIndex(i);
+    if (aChain.Contains(theEdge)) {
+      theMainEdge = _mapPropagationChains.FindKey(i);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+//=============================================================================
+/*!
+ *  CleanMeshOnPropagationChain
+ */
+//=============================================================================
+void SMESH_Mesh::CleanMeshOnPropagationChain (const TopoDS_Shape& theMainEdge)
+{
+  const TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.FindFromKey(theMainEdge);
+  int i, nbEdges = aChain.Extent();
+  for (i = 1; i <= nbEdges; i++) {
+    TopoDS_Shape anEdge = aChain.FindKey(i);
+    SMESH_subMesh *subMesh = GetSubMesh(anEdge);
+    SMESHDS_SubMesh *subMeshDS = subMesh->GetSubMeshDS();
+    if (subMeshDS && subMeshDS->NbElements() > 0) {
+      subMesh->ComputeStateEngine(SMESH_subMesh::CLEANDEP);
+    }
+  }
+}
+
+//=============================================================================
+/*!
+ *  RebuildPropagationChains
+ *  Rebuild all existing propagation chains.
+ *  Have to be used, if 1D hypothesis have been assigned/removed to/from any edge
+ */
+//=============================================================================
+bool SMESH_Mesh::RebuildPropagationChains()
+{
+  bool ret = true;
+
+  // Clean all chains, because they can be not up-to-date
+  int i, nbChains = _mapPropagationChains.Extent();
+  for (i = 1; i <= nbChains; i++) {
+    TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
+    CleanMeshOnPropagationChain(aMainEdge);
+    _mapPropagationChains.ChangeFromIndex(i).Clear();
+  }
+
+  // Build all chains
+  for (i = 1; i <= nbChains; i++) {
+    TopoDS_Shape aMainEdge = _mapPropagationChains.FindKey(i);
+    if (!BuildPropagationChain(aMainEdge))
+      ret = false;
+    CleanMeshOnPropagationChain(aMainEdge);
+  }
+
+  return ret;
+}
+
+//=============================================================================
+/*!
+ *  RemovePropagationChain
+ *  Have to be used, if Propagation hypothesis is removed from <theMainEdge>
+ */
+//=============================================================================
+bool SMESH_Mesh::RemovePropagationChain (const TopoDS_Shape& theMainEdge)
+{
+  if (!_mapPropagationChains.Contains(theMainEdge))
+    return false;
+
+  // Clean mesh elements and nodes, built on the chain
+  CleanMeshOnPropagationChain(theMainEdge);
+
+  // Clean the chain
+  _mapPropagationChains.ChangeFromKey(theMainEdge).Clear();
+
+  // Remove the chain from the map
+  int i = _mapPropagationChains.FindIndex(theMainEdge);
+  TopoDS_Vertex anEmptyShape;
+  BRep_Builder BB;
+  BB.MakeVertex(anEmptyShape, gp_Pnt(0,0,0), 0.1);
+  TopTools_IndexedMapOfShape anEmptyMap;
+  _mapPropagationChains.Substitute(i, anEmptyShape, anEmptyMap);
+
+  return true;
+}
+
+//=============================================================================
+/*!
+ *  BuildPropagationChain
+ */
+//=============================================================================
+bool SMESH_Mesh::BuildPropagationChain (const TopoDS_Shape& theMainEdge)
+{
+  if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
+
+  // Add new chain, if there is no
+  if (!_mapPropagationChains.Contains(theMainEdge)) {
+    TopTools_IndexedMapOfShape aNewChain;
+    _mapPropagationChains.Add(theMainEdge, aNewChain);
+  }
+
+  // Check presence of 1D hypothesis to be propagated
+  if (!IsLocal1DHypothesis(theMainEdge)) {
+    MESSAGE("Warning: There is no 1D hypothesis to propagate. Please, assign.");
+    return true;
+  }
+
+  // Edges, on which the 1D hypothesis will be propagated from <theMainEdge>
+  TopTools_IndexedMapOfShape& aChain = _mapPropagationChains.ChangeFromKey(theMainEdge);
+  if (aChain.Extent() > 0) {
+    CleanMeshOnPropagationChain(theMainEdge);
+    aChain.Clear();
+  }
+
+  // At first put <theMainEdge> in the chain
+  aChain.Add(theMainEdge);
+
+  // List of edges, added to chain on the previous cycle pass
+  TopTools_ListOfShape listPrevEdges;
+  listPrevEdges.Append(theMainEdge);
+
+//   5____4____3____4____5____6
+//   |    |    |    |    |    |
+//   |    |    |    |    |    |
+//   4____3____2____3____4____5
+//   |    |    |    |    |    |      Number in the each knot of
+//   |    |    |    |    |    |      grid indicates cycle pass,
+//   3____2____1____2____3____4      on which corresponding edge
+//   |    |    |    |    |    |      (perpendicular to the plane
+//   |    |    |    |    |    |      of view) will be found.
+//   2____1____0____1____2____3
+//   |    |    |    |    |    |
+//   |    |    |    |    |    |
+//   3____2____1____2____3____4
+
+  // Collect all edges pass by pass
+  while (listPrevEdges.Extent() > 0) {
+    // List of edges, added to chain on this cycle pass
+    TopTools_ListOfShape listCurEdges;
+
+    // Find the next portion of edges
+    TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
+    for (; itE.More(); itE.Next()) {
+      TopoDS_Shape anE = itE.Value();
+
+      // Iterate on faces, having edge <anE>
+      TopTools_ListIteratorOfListOfShape itA (GetAncestors(anE));
+      for (; itA.More(); itA.Next()) {
+        TopoDS_Shape aW = itA.Value();
+
+        // There are objects of different type among the ancestors of edge
+        if (aW.ShapeType() == TopAbs_WIRE) {
+          TopoDS_Shape anOppE;
+
+          BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
+          Standard_Integer nb = 1, found = 0;
+          TopTools_Array1OfShape anEdges (1,4);
+          for (; aWE.More(); aWE.Next(), nb++) {
+            if (nb > 4) {
+              found = 0;
+              break;
+            }
+            anEdges(nb) = aWE.Current();
+            if (!_mapAncestors.Contains(anEdges(nb))) {
+              MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
+              break;
+            } else {
+              int ind = _mapAncestors.FindIndex(anEdges(nb));
+              anEdges(nb) = _mapAncestors.FindKey(ind);
+            }
+            if (anEdges(nb).IsSame(anE)) found = nb;
+          }
+
+          if (nb == 5 && found > 0) {
+            // Quadrangle face found, get an opposite edge
+            Standard_Integer opp = found + 2;
+            if (opp > 4) opp -= 4;
+            anOppE = anEdges(opp);
+
+            if (!aChain.Contains(anOppE)) {
+              if (!IsLocal1DHypothesis(anOppE)) {
+                TopoDS_Shape aMainEdgeForOppEdge;
+                if (IsPropagatedHypothesis(anOppE, aMainEdgeForOppEdge)) {
+                  // Collision!
+                  MESSAGE("Error: Collision between propagated hypotheses");
+                  CleanMeshOnPropagationChain(theMainEdge);
+                  aChain.Clear();
+                  return false;
+                } else {
+                  // Add found edge to the chain
+                  aChain.Add(anOppE);
+                  listCurEdges.Append(anOppE);
+                }
+              }
+            }
+          } // if (nb == 5 && found > 0)
+        } // if (aF.ShapeType() == TopAbs_WIRE)
+      } // for (; itF.More(); itF.Next())
+    } // for (; itE.More(); itE.Next())
+
+    listPrevEdges = listCurEdges;
+  } // while (listPrevEdges.Extent() > 0)
+
+  CleanMeshOnPropagationChain(theMainEdge);
+  return true;
+}
+
 //=======================================================================
 //function : GetAncestors
 //purpose  : return list of ancestors of theSubShape in the order
index d594b71..51f0853 100644 (file)
 #ifndef _SMESH_MESH_HXX_
 #define _SMESH_MESH_HXX_
 
+#include "SMESH_Hypothesis.hxx"
+//#include "SMESH_subMesh.hxx"
+
 #include "SMESHDS_Document.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_Command.hxx"
-#include "SMESH_Hypothesis.hxx"
-#include "SMESH_subMesh.hxx"
 #include "SMDSAbs_ElementType.hxx"
 
+#include "NMTTools_IndexedDataMapOfShapeIndexedMapOfShape.hxx"
+
+#include "Utils_SALOME_Exception.hxx"
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
@@ -62,6 +67,9 @@
 class SMESH_Gen;
 class SMESH_Group;
 class TopTools_ListOfShape;
+class SMESH_subMesh;
+
+typedef NMTTools_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain;
 
 class SMESH_Mesh
 {
@@ -167,10 +175,36 @@ public:
   list<int> GetGroupIds();
   
   void RemoveGroup (const int theGroupID);
+
+  // Propagation hypothesis management
+
+  bool IsLocal1DHypothesis (const TopoDS_Shape& theEdge);
+  // Returns true, if a local 1D hypothesis is set directly on <theEdge>
+
+  bool IsPropagationHypothesis (const TopoDS_Shape& theEdge);
+  // Returns true, if a local Propagation hypothesis is set directly on <theEdge>
+
+  bool IsPropagatedHypothesis (const TopoDS_Shape& theEdge,
+                               TopoDS_Shape&       theMainEdge);
+  // Returns true, if a local 1D hypothesis is
+  // propagated on <theEdge> from some other edge.
+  // Returns through <theMainEdge> the edge, from
+  // which the 1D hypothesis is propagated on <theEdge>
+
+  bool RebuildPropagationChains();
+  bool RemovePropagationChain (const TopoDS_Shape& theMainEdge);
+  bool BuildPropagationChain (const TopoDS_Shape& theMainEdge);
+
+  //
   
   ostream& Dump(ostream & save);
   
 private:
+  // Propagation hypothesis management
+  void CleanMeshOnPropagationChain(const TopoDS_Shape& theMainEdge);
+  //
+  
+private:
   int _id;                                     // id given by creator (unique within the creator instance)
   int _studyId;
   int _idDoc;                                  // id given by SMESHDS_Document
@@ -186,6 +220,8 @@ private:
   SMESH_Gen *_gen;
   
   TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
+
+  IndexedMapOfChain _mapPropagationChains; // Propagation hypothesis management
 };
 
 #endif
index 7f20a5c..0659567 100644 (file)
@@ -1,8 +1,25 @@
-// File      : SMESH_Pattern.cxx
-// Created   : Thu Aug  5 11:09:29 2004
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+// File      : SMESH_Pattern.hxx
+// Created   : Mon Aug  2 10:30:00 2004
 // Author    : Edward AGAPOV (eap)
-// Copyright : Open CASCADE
-
 
 #include "SMESH_Pattern.hxx"
 
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
 #include <gp_Lin2d.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Trsf.hxx>
 #include <gp_XY.hxx>
 #include <gp_XYZ.hxx>
-#include <math_FunctionSetRoot.hxx>
-#include <math_FunctionSetWithDerivatives.hxx>
-#include <math_Matrix.hxx>
-#include <math_Vector.hxx>
 #include <Extrema_GenExtPS.hxx>
 #include <Extrema_POnSurf.hxx>
 #include <GeomAdaptor_Surface.hxx>
@@ -47,6 +57,8 @@
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Mesh.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_subMesh.hxx"
 
 #include "utilities.h"
 
@@ -54,8 +66,6 @@ using namespace std;
 
 typedef map< const SMDS_MeshElement*, int > TNodePointIDMap;
 
-#define SQRT_FUNC 1
-
 //=======================================================================
 //function : SMESH_Pattern
 //purpose  : 
@@ -2431,164 +2441,6 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
   return setErrorCode( ERR_OK );
 }
 
-// =========================================================
-// class calculating coordinates of 3D points by normalized
-// parameters inside the block and vice versa
-// =========================================================
-
-class TBlock: public math_FunctionSetWithDerivatives
-{
- public:
-  enum TBlockShapeID { // ids of the block sub-shapes
-    ID_V000 = 1, ID_V100, ID_V010, ID_V110, ID_V001, ID_V101, ID_V011, ID_V111,
-
-    ID_Ex00, ID_Ex10, ID_Ex01, ID_Ex11,
-    ID_E0y0, ID_E1y0, ID_E0y1, ID_E1y1,
-    ID_E00z, ID_E10z, ID_E01z, ID_E11z,
-
-    ID_Fxy0, ID_Fxy1, ID_Fx0z, ID_Fx1z, ID_F0yz, ID_F1yz,
-
-    ID_Shell
-    };
-  static inline 
-bool IsVertexID( int theShapeID )
-  { return ( theShapeID >= ID_V000 && theShapeID <= ID_V111 ); }
-  static inline bool IsEdgeID( int theShapeID )
-  { return ( theShapeID >= ID_Ex00 && theShapeID <= ID_E11z ); }
-  static inline bool IsFaceID( int theShapeID )
-  { return ( theShapeID >= ID_Fxy0 && theShapeID <= ID_F1yz ); }
-
-
-  TBlock (const TopoDS_Shell& theBlock):
-    myShell( theBlock ), myNbIterations(0), mySumDist(0.) {}
-
-  bool LoadBlockShapes(const TopoDS_Vertex&        theVertex000,
-                       const TopoDS_Vertex&        theVertex001,
-//                       TopTools_IndexedMapOfShape& theShapeIDMap
-                       TopTools_IndexedMapOfOrientedShape& theShapeIDMap );
-  // add sub-shapes of theBlock to theShapeIDMap so that they get
-  // IDs acoording to enum TBlockShapeID
-
-  static int GetShapeIDByParams ( const gp_XYZ& theParams );
-  // define an id of the block sub-shape by point parameters
-
-  bool VertexPoint( const int theVertexID, gp_XYZ& thePoint ) const {
-    if ( !IsVertexID( theVertexID ))           return false;
-    thePoint = myPnt[ theVertexID - ID_V000 ]; return true;
-  }
-  // return vertex coordinates
-
-  bool EdgePoint( const int theEdgeID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
-    if ( !IsEdgeID( theEdgeID ))                                 return false;
-    thePoint = myEdge[ theEdgeID - ID_Ex00 ].Point( theParams ); return true;
-  }
-  // return coordinates of a point on edge
-
-  bool FacePoint( const int theFaceID, const gp_XYZ& theParams, gp_XYZ& thePoint ) const {
-    if ( !IsFaceID ( theFaceID ))                                return false;
-    thePoint = myFace[ theFaceID - ID_Fxy0 ].Point( theParams ); return true;
-  }
-  // return coordinates of a point on face
-
-  bool ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const;
-  // return coordinates of a point in shell
-
-  bool ComputeParameters (const gp_Pnt& thePoint,
-                          gp_XYZ&       theParams,
-                          const int     theShapeID = ID_Shell);
-  // compute point parameters in the block
-
-  static void GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec );
-  // return edges IDs of a face in the order u0, u1, 0v, 1v
-
-  static int GetCoordIndOnEdge (const int theEdgeID)
-  { return (theEdgeID < ID_E0y0) ? 1 : (theEdgeID < ID_E00z) ? 2 : 3; }
-  // return an index of a coordinate which varies along the edge
-
-  static double* GetShapeCoef (const int theShapeID);
-  // for theShapeID( TBlockShapeID ), returns 3 coefficients used
-  // to compute an addition of an on-theShape point to coordinates
-  // of an in-shell point. If an in-shell point has parameters (Px,Py,Pz),
-  // then the addition of a point P is computed as P*kx*ky*kz and ki is
-  // defined by the returned coef like this:
-  // ki = (coef[i] == 0) ? 1 : (coef[i] < 0) ? 1 - Pi : Pi
-
-  static bool IsForwardEdge (const TopoDS_Edge &         theEdge, 
-                             //TopTools_IndexedMapOfShape& theShapeIDMap
-                             TopTools_IndexedMapOfOrientedShape& theShapeIDMap) {
-    int v1ID = theShapeIDMap.FindIndex( TopExp::FirstVertex( theEdge ).Oriented( TopAbs_FORWARD ));
-    int v2ID = theShapeIDMap.FindIndex( TopExp::LastVertex( theEdge ).Oriented( TopAbs_FORWARD ));
-    return ( v1ID < v2ID );
-  }
-  // Return true if an in-block parameter increases along theEdge curve
-
-  static void Swap(double& a, double& b) { double tmp = a; a = b; b = tmp; }
-
-  // methods of math_FunctionSetWithDerivatives
-  Standard_Integer NbVariables() const;
-  Standard_Integer NbEquations() const;
-  Standard_Boolean Value(const math_Vector& X,math_Vector& F) ;
-  Standard_Boolean Derivatives(const math_Vector& X,math_Matrix& D) ;
-  Standard_Boolean Values(const math_Vector& X,math_Vector& F,math_Matrix& D) ;
-  Standard_Integer GetStateNumber ();
-
-  static ostream& DumpShapeID (const int theBlockShapeID, ostream& stream);
-  // DEBUG: dump an id of a block sub-shape
-
- private:
-
-  struct TEdge {
-    int                myCoordInd;
-    double             myFirst;
-    double             myLast;
-    Handle(Geom_Curve) myC3d;
-    gp_Trsf            myTrsf;
-    double GetU( const gp_XYZ& theParams ) const;
-    gp_XYZ Point( const gp_XYZ& theParams ) const;
-  };
-
-  struct TFace {
-    // 4 edges in the order u0, u1, 0v, 1v
-    int                  myCoordInd[ 4 ];
-    double               myFirst   [ 4 ];
-    double               myLast    [ 4 ];
-    Handle(Geom2d_Curve) myC2d     [ 4 ];
-    // 4 corner points in the order 00, 10, 11, 01
-    gp_XY                myCorner  [ 4 ];
-    // surface
-    Handle(Geom_Surface) myS;
-    gp_Trsf              myTrsf;
-    gp_XY  GetUV( const gp_XYZ& theParams ) const;
-    gp_XYZ Point( const gp_XYZ& theParams ) const;
-    int GetUInd() const { return myCoordInd[ 0 ]; }
-    int GetVInd() const { return myCoordInd[ 2 ]; }
-  };
-
-  TopoDS_Shell myShell;
-  // geometry:
-  // 8 vertices
-  gp_XYZ myPnt[ 8 ];
-  // 12 edges
-  TEdge  myEdge[ 12 ];
-  // 6 faces
-  TFace  myFace[ 6 ];
-
-  // for param computation
-
-  int      myFaceIndex;
-  double   myFaceParam;
-  int      myNbIterations;
-  double   mySumDist;
-
-  gp_XYZ   myPoint; // the given point
-  gp_XYZ   myParam; // the best parameters guess
-  double   myValues[ 4 ]; // values computed at myParam
-
-  typedef pair<gp_XYZ,gp_XYZ> TxyzPair;
-  TxyzPair my3x3x3GridNodes[ 27 ];
-  bool     myGridComputed;
-};
-
 //=======================================================================
 //function : Load
 //purpose  : Create a pattern from the mesh built on <theBlock>
@@ -2603,9 +2455,9 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
 
   // load shapes in myShapeIDMap
-  TBlock block( theBlock );
+  SMESH_Block block;
   TopoDS_Vertex v1, v2;
-  if ( !block.LoadBlockShapes( v1, v2, myShapeIDMap ))
+  if ( !block.LoadBlockShapes( theBlock, v1, v2, myShapeIDMap ))
     return setErrorCode( ERR_LOADV_BAD_SHAPE );
 
   // count nodes
@@ -2662,8 +2514,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
       const TopoDS_Edge& edge = TopoDS::Edge( S );
       double f,l;
       BRep_Tool::Range( edge, f, l );
-      int iCoord     = TBlock::GetCoordIndOnEdge( shapeID );
-      bool isForward = TBlock::IsForwardEdge( edge, myShapeIDMap );
+      int iCoord     = SMESH_Block::GetCoordIndOnEdge( shapeID );
+      bool isForward = SMESH_Block::IsForwardEdge( edge, myShapeIDMap );
       pIt = shapePoints.begin();
       nIt = aSubMesh->GetNodes();
       for ( ; nIt->more(); pIt++ )
@@ -2722,13 +2574,12 @@ bool SMESH_Pattern::Apply (const TopoDS_Shell&  theBlock,
 {
   MESSAGE(" ::Apply(volume) " );
 
-  TBlock block( theBlock );
-
   if (!findBoundaryPoints()     || // bind ID to points
       !setShapeToMesh( theBlock )) // check theBlock is a suitable shape
     return false;
 
-  if (!block.LoadBlockShapes( theVertex000, theVertex001, myShapeIDMap )) // bind ID to shape
+  SMESH_Block block;  // bind ID to shape
+  if (!block.LoadBlockShapes( theBlock, theVertex000, theVertex001, myShapeIDMap ))
     return setErrorCode( ERR_APPLV_BAD_SHAPE );
 
   // compute XYZ of points on shapes
@@ -3005,19 +2856,19 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList)
     }
     // vectors of boundary direction near <p>
     gp_Vec2d v1( pPrev->myInitUV, p->myInitUV ), v2( p->myInitUV, pNext->myInitUV );
-    // rotate vectors counterclockwise
-    v1.SetCoord( -v1.Y(), v1.X() );
-    v2.SetCoord( -v2.Y(), v2.X() );
-    // in-face direction
-    gp_Vec2d dirInFace = v1 + v2;
-    // for the outer boundary dirInFace should go to the right
-    bool reverse;
-    if ( bndIt == boundaryList.begin() ) // outer boundary
-      reverse = dirInFace.X() < 0;
-    else
-      reverse = dirInFace.X() > 0;
-    if ( reverse )
-      boundary.reverse();
+    double sqMag1 = v1.SquareMagnitude(), sqMag2 = v2.SquareMagnitude();
+    if ( sqMag1 > DBL_MIN && sqMag2 > DBL_MIN ) {
+      double yPrev = v1.Y() / sqrt( sqMag1 );
+      double yNext = v2.Y() / sqrt( sqMag2 );
+      double sumY = yPrev + yNext;
+      bool reverse;
+      if ( bndIt == boundaryList.begin() ) // outer boundary
+        reverse = sumY > 0;
+      else
+        reverse = sumY < 0;
+      if ( reverse )
+        boundary.reverse();
+    }
 
     // Put key-point IDs of a well-oriented boundary in myKeyPointIDs
     (*nbKpIt) = 0; // count nb of key-points again
@@ -3225,10 +3076,10 @@ bool SMESH_Pattern::findBoundaryPoints()
     vector< TPoint >::iterator pVecIt = myPoints.begin();
     for ( int i = 0; pVecIt != myPoints.end(); pVecIt++, i++ ) {
       TPoint* point = &(*pVecIt);
-      int shapeID = TBlock::GetShapeIDByParams( point->myInitXYZ );
+      int shapeID = SMESH_Block::GetShapeIDByParams( point->myInitXYZ );
       getShapePoints( shapeID ).push_back( point );
       // detect key-points
-      if ( TBlock::IsVertexID( shapeID ))
+      if ( SMESH_Block::IsVertexID( shapeID ))
         myKeyPointIDs.push_back( i );        
     }
   }
@@ -3415,896 +3266,3 @@ ostream & operator <<(ostream & OS, const SMESH_Pattern::TPoint& p)
   
   return OS;
 }
-
-//=======================================================================
-//function : TBlock::TEdge::GetU
-//purpose  : 
-//=======================================================================
-
-double TBlock::TEdge::GetU( const gp_XYZ& theParams ) const
-{
-  double u = theParams.Coord( myCoordInd );
-  return ( 1 - u ) * myFirst + u * myLast;
-}
-
-//=======================================================================
-//function : TBlock::TEdge::Point
-//purpose  : 
-//=======================================================================
-
-gp_XYZ TBlock::TEdge::Point( const gp_XYZ& theParams ) const
-{
-  gp_XYZ p = myC3d->Value( GetU( theParams )).XYZ();
-  if ( myTrsf.Form() != gp_Identity )
-    myTrsf.Transforms( p );
-  return p;
-}
-
-//=======================================================================
-//function : TBlock::TFace::GetUV
-//purpose  : 
-//=======================================================================
-
-gp_XY TBlock::TFace::GetUV( const gp_XYZ& theParams ) const
-{
-  gp_XY uv(0.,0.);
-  double dU = theParams.Coord( GetUInd() );
-  double dV = theParams.Coord( GetVInd() );
-  for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
-  {
-    double Ecoef = 0, Vcoef = 0;
-    switch ( iE ) {
-    case 0:
-      Ecoef = ( 1 - dV ); // u0
-      Vcoef = ( 1 - dU ) * ( 1 - dV ); break; // 00
-    case 1:
-      Ecoef = dV; // u1
-      Vcoef = dU * ( 1 - dV ); break; // 10
-    case 2:
-      Ecoef = ( 1 - dU ); // 0v
-      Vcoef = dU * dV  ; break; // 11
-    case 3:
-      Ecoef = dU  ; // 1v
-      Vcoef = ( 1 - dU ) * dV  ; break; // 01
-    default:;
-    }
-    // edge addition
-    double u = theParams.Coord( myCoordInd[ iE ] );
-    u = ( 1 - u ) * myFirst[ iE ] + u * myLast[ iE ];
-    uv += Ecoef * myC2d[ iE ]->Value( u ).XY();
-    // corner addition
-    uv -= Vcoef * myCorner[ iE ];
-  }
-  return uv;
-}
-
-//=======================================================================
-//function : TBlock::TFace::Point
-//purpose  : 
-//=======================================================================
-
-gp_XYZ TBlock::TFace::Point( const gp_XYZ& theParams ) const
-{
-  gp_XY uv = GetUV( theParams );
-  gp_XYZ p = myS->Value( uv.X(), uv.Y() ).XYZ();
-  if ( myTrsf.Form() != gp_Identity )
-    myTrsf.Transforms( p );
-  return p;
-}
-
-//=======================================================================
-//function : GetShapeCoef
-//purpose  : 
-//=======================================================================
-
-double* TBlock::GetShapeCoef (const int theShapeID)
-{
-  static double shapeCoef[][3] = {
-    //    V000,        V100,        V010,         V110
-    { -1,-1,-1 }, {  1,-1,-1 }, { -1, 1,-1 }, {  1, 1,-1 },
-    //    V001,        V101,        V011,         V111,
-    { -1,-1, 1 }, {  1,-1, 1 }, { -1, 1, 1 }, {  1, 1, 1 },
-    //    Ex00,        Ex10,        Ex01,         Ex11,
-    {  0,-1,-1 }, {  0, 1,-1 }, {  0,-1, 1 }, {  0, 1, 1 },
-    //    E0y0,        E1y0,        E0y1,         E1y1,
-    { -1, 0,-1 }, {  1, 0,-1 }, { -1, 0, 1 }, {  1, 0, 1 },
-    //    E00z,        E10z,        E01z,         E11z,
-    { -1,-1, 0 }, {  1,-1, 0 }, { -1, 1, 0 }, {  1, 1, 0 },
-    //    Fxy0,        Fxy1,        Fx0z,         Fx1z,         F0yz,           F1yz,
-    {  0, 0,-1 }, {  0, 0, 1 }, {  0,-1, 0 }, {  0, 1, 0 }, { -1, 0, 0 }, {  1, 0, 0 },
-    // ID_Shell
-    {  0, 0, 0 }
-  };
-  if ( theShapeID < ID_V000 || theShapeID > ID_F1yz )
-    return shapeCoef[ ID_Shell - 1 ];
-
-  return shapeCoef[ theShapeID - 1 ];
-}
-
-//=======================================================================
-//function : ShellPoint
-//purpose  : return coordinates of a point in shell
-//=======================================================================
-
-bool TBlock::ShellPoint( const gp_XYZ& theParams, gp_XYZ& thePoint ) const
-{
-  thePoint.SetCoord( 0., 0., 0. );
-  for ( int shapeID = ID_V000; shapeID < ID_Shell; shapeID++ )
-  {
-    // coef
-    double* coefs = GetShapeCoef( shapeID );
-    double k = 1;
-    for ( int iCoef = 0; iCoef < 3; iCoef++ ) {
-      if ( coefs[ iCoef ] != 0 ) {
-        if ( coefs[ iCoef ] < 0 )
-          k *= ( 1. - theParams.Coord( iCoef + 1 ));
-        else
-          k *= theParams.Coord( iCoef + 1 );
-      }
-    }
-    // point on a shape
-    gp_XYZ Ps;
-    if ( shapeID < ID_Ex00 ) // vertex
-      VertexPoint( shapeID, Ps );
-    else if ( shapeID < ID_Fxy0 ) { // edge
-      EdgePoint( shapeID, theParams, Ps );
-      k = -k;
-    } else // face
-      FacePoint( shapeID, theParams, Ps );
-
-    thePoint += k * Ps;
-  }
-  return true;
-}
-
-//=======================================================================
-//function : NbVariables
-//purpose  : 
-//=======================================================================
-
-Standard_Integer TBlock::NbVariables() const
-{
-  return 3;
-}
-
-//=======================================================================
-//function : NbEquations
-//purpose  : 
-//=======================================================================
-
-Standard_Integer TBlock::NbEquations() const
-{
-  return 1;
-}
-
-//=======================================================================
-//function : Value
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean TBlock::Value(const math_Vector& theXYZ, math_Vector& theFxyz) 
-{
-  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
-  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
-    theFxyz( 1 ) = myValues[ 0 ];
-  }
-  else {
-    ShellPoint( params, P );
-    gp_Vec dP( P - myPoint );
-    theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude();
-  }
-  return true;
-}
-
-//=======================================================================
-//function : Derivatives
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean TBlock::Derivatives(const math_Vector& XYZ,math_Matrix& Df) 
-{
-  MESSAGE( "TBlock::Derivatives()");
-  math_Vector F(1,3);
-  return Values(XYZ,F,Df);
-}
-
-//=======================================================================
-//function : Values
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean TBlock::Values(const math_Vector& theXYZ,
-                                math_Vector&       theFxyz,
-                                math_Matrix&       theDf) 
-{
-//  MESSAGE( endl<<"TBlock::Values( "<<theXYZ(1)<<", "<<theXYZ(2)<<", "<<theXYZ(3)<<")");
-
-  gp_XYZ P, params( theXYZ(1), theXYZ(2), theXYZ(3) );
-  if ( params.IsEqual( myParam, DBL_MIN )) { // same param
-    theFxyz( 1 ) = myValues[ 0 ];
-    theDf( 1,1 ) = myValues[ 1 ];
-    theDf( 1,2 ) = myValues[ 2 ];
-    theDf( 1,3 ) = myValues[ 3 ];
-    return true;
-  }
-
-  ShellPoint( params, P );
-  //myNbIterations++; // how many time call ShellPoint()
-
-  gp_Vec dP( P - myPoint );
-  theFxyz(1) = SQRT_FUNC ? dP.SquareMagnitude() : dP.Magnitude();
-  if ( theFxyz(1) < 1e-6 ) {
-    myParam      = params;
-    myValues[ 0 ]= 0;
-    theDf( 1,1 ) = 0;
-    theDf( 1,2 ) = 0;
-    theDf( 1,3 ) = 0;
-    return true;
-  }
-
-  if ( theFxyz(1) < myValues[0] )
-  {
-    // 3 partial derivatives
-    gp_Vec drv[ 3 ];
-    for ( int iP = 1; iP <= 3; iP++ ) {
-      gp_XYZ Pi;
-      params.SetCoord( iP, theXYZ( iP ) + 0.001 );
-      ShellPoint( params, Pi );
-      params.SetCoord( iP, theXYZ( iP ) ); // restore params
-      gp_Vec dPi ( P, Pi );
-      double mag = dPi.Magnitude();
-      if ( mag > DBL_MIN )
-        dPi /= mag;
-      drv[ iP - 1 ] = dPi;
-    }
-    for ( int iP = 0; iP < 3; iP++ ) {
-      if ( iP == myFaceIndex )
-        theDf( 1, iP + 1 ) = myFaceParam;
-      else {
-        // like IntAna_IntConicQuad::Perform (const gp_Lin& L, const gp_Pln& P)
-        // where L is (P -> myPoint), P is defined by the 2 other derivative direction
-        int iPrev = ( iP ? iP - 1 : 2 );
-        int iNext = ( iP == 2 ? 0 : iP + 1 );
-        gp_Vec plnNorm = drv[ iPrev ].Crossed( drv [ iNext ] );
-        double Direc = plnNorm * drv[ iP ];
-        if ( Abs(Direc) <= DBL_MIN )
-          theDf( 1, iP + 1 ) = dP * drv[ iP ];
-        else {
-          double Dis = plnNorm * P - plnNorm * myPoint;
-          theDf( 1, iP + 1 ) = Dis/Direc;
-        }
-      }
-    }
-    //myNbIterations +=3; // how many time call ShellPoint()
-
-    // store better values
-    myParam    = params;
-    myValues[0]= theFxyz(1);
-    myValues[1]= theDf(1,1);
-    myValues[2]= theDf(1,2);
-    myValues[3]= theDf(1,3);
-
-//     SCRUTE( theFxyz(1)  );
-//     SCRUTE( theDf( 1,1 ));
-//     SCRUTE( theDf( 1,2 ));
-//     SCRUTE( theDf( 1,3 ));
-  }
-
-  return true;
-}
-
-//=======================================================================
-//function : ComputeParameters
-//purpose  : compute point parameters in the block
-//=======================================================================
-
-bool TBlock::ComputeParameters(const gp_Pnt& thePoint,
-                               gp_XYZ&       theParams,
-                               const int     theShapeID)
-{
-//   MESSAGE( endl<<"TBlock::ComputeParameters( "
-//           <<thePoint.X()<<", "<<thePoint.Y()<<", "<<thePoint.Z()<<")");
-
-  myPoint = thePoint.XYZ();
-
-  myParam.SetCoord( -1,-1,-1 );
-  myValues[0] = 1e100;
-
-  const bool isOnFace = IsFaceID( theShapeID );
-  double * coef = GetShapeCoef( theShapeID );
-
-  // the first guess
-  math_Vector start( 1, 3, 0.0 );
-  if ( !myGridComputed )
-  {
-    // define the first guess by thePoint projection on lines
-    // connecting vertices
-    bool needGrid = false;
-    gp_XYZ par000( 0, 0, 0 ), par111( 1, 1, 1 );
-    double zero = DBL_MIN * DBL_MIN;
-    for ( int iEdge = 0, iParam = 1; iParam <= 3 && !needGrid; iParam++ )
-    {
-      if ( isOnFace && coef[ iParam - 1 ] != 0 ) {
-        iEdge += 4;
-        continue;
-      }
-      for ( int iE = 0; iE < 4; iE++, iEdge++ ) { // loop on 4 parallel edges
-        gp_Pnt p0 = myEdge[ iEdge ].Point( par000 );
-        gp_Pnt p1 = myEdge[ iEdge ].Point( par111 );
-        gp_Vec v01( p0, p1 ), v0P( p0, thePoint );
-        double len2 = v01.SquareMagnitude();
-        double par = 0;
-        if ( len2 > zero ) {
-          par = v0P.Dot( v01 ) / len2;
-          if ( par < 0 || par > 1 ) {
-            needGrid = true;
-            break;
-          }
-        }
-        start( iParam ) += par;
-      }
-      start( iParam ) /= 4.;
-    }
-    if ( needGrid ) {
-      // compute nodes of 3 x 3 x 3 grid
-      int iNode = 0;
-      for ( double x = 0.25; x < 0.9; x += 0.25 )
-        for ( double y = 0.25; y < 0.9; y += 0.25 )
-          for ( double z = 0.25; z < 0.9; z += 0.25 ) {
-            TxyzPair & prmPtn = my3x3x3GridNodes[ iNode++ ];
-            prmPtn.first.SetCoord( x, y, z );
-            ShellPoint( prmPtn.first, prmPtn.second );
-          }
-      myGridComputed = true;
-    }
-  }
-  if ( myGridComputed ) {
-    double minDist = DBL_MAX;
-    gp_XYZ* bestParam = 0;
-    for ( int iNode = 0; iNode < 27; iNode++ ) {
-      TxyzPair & prmPtn = my3x3x3GridNodes[ iNode ];
-      double dist = ( thePoint.XYZ() - prmPtn.second ).SquareModulus();
-      if ( dist < minDist ) {
-        minDist = dist;
-        bestParam = & prmPtn.first;
-      }
-    }
-    start( 1 ) = bestParam->X();
-    start( 2 ) = bestParam->Y();
-    start( 3 ) = bestParam->Z();
-  }
-
-  int myFaceIndex = -1;
-  if ( isOnFace ) {
-    // put a point on the face
-    for ( int iCoord = 0; iCoord < 3; iCoord++ )
-      if ( coef[ iCoord ] ) {
-        myFaceIndex = iCoord;
-        myFaceParam = ( coef[ myFaceIndex ] < 0.5 ) ? 0.0 : 1.0;
-        start( iCoord + 1 ) = myFaceParam;
-      }
-  }
-  math_Vector low  ( 1, 3, 0.0 );
-  math_Vector up   ( 1, 3, 1.0 );
-  math_Vector tol  ( 1, 3, 1e-4 );
-  math_FunctionSetRoot paramSearch( *this, tol );
-
-  int nbLoops = 0;
-  while ( myValues[0] > 1e-1 && nbLoops++ < 10 ) {
-    paramSearch.Perform ( *this, start, low, up );
-    if ( !paramSearch.IsDone() ) {
-      //MESSAGE( " !paramSearch.IsDone() " );
-    }
-    else {
-      //MESSAGE( " NB ITERATIONS: " << paramSearch.NbIterations() );
-    }
-    start( 1 ) = myParam.X();
-    start( 2 ) = myParam.Y();
-    start( 3 ) = myParam.Z();
-    //MESSAGE( "Distance: " << ( SQRT_FUNC ? sqrt(myValues[0]) : myValues[0] ));
-  }
-//   MESSAGE( endl << myParam.X() << " " << myParam.Y() << " " << myParam.Z() << endl);
-//   mySumDist += myValues[0];
-//   MESSAGE( " TOTAL NB ITERATIONS: " << myNbIterations <<
-//             " DIST: " << ( SQRT_FUNC ? sqrt(mySumDist) : mySumDist ));
-
-
-  theParams = myParam;
-
-  return true;
-}
-
-//=======================================================================
-//function : GetStateNumber
-//purpose  : 
-//=======================================================================
-
-Standard_Integer TBlock::GetStateNumber ()
-{
-//   MESSAGE( endl<<"TBlock::GetStateNumber( "<<myParam.X()<<", "<<
-//           myParam.Y()<<", "<<myParam.Z()<<") DISTANCE: " << myValues[0]);
-  return myValues[0] < 1e-1;
-}
-
-//=======================================================================
-//function : DumpShapeID
-//purpose  : debug an id of a block sub-shape
-//=======================================================================
-
-#define CASEDUMP(id,strm) case id: strm << #id; break;
-
-ostream& TBlock::DumpShapeID (const int id, ostream& stream)
-{
-  switch ( id ) {
-  CASEDUMP( ID_V000, stream );
-  CASEDUMP( ID_V100, stream );
-  CASEDUMP( ID_V010, stream );
-  CASEDUMP( ID_V110, stream );
-  CASEDUMP( ID_V001, stream );
-  CASEDUMP( ID_V101, stream );
-  CASEDUMP( ID_V011, stream );
-  CASEDUMP( ID_V111, stream );
-  CASEDUMP( ID_Ex00, stream );
-  CASEDUMP( ID_Ex10, stream );
-  CASEDUMP( ID_Ex01, stream );
-  CASEDUMP( ID_Ex11, stream );
-  CASEDUMP( ID_E0y0, stream );
-  CASEDUMP( ID_E1y0, stream );
-  CASEDUMP( ID_E0y1, stream );
-  CASEDUMP( ID_E1y1, stream );
-  CASEDUMP( ID_E00z, stream );
-  CASEDUMP( ID_E10z, stream );
-  CASEDUMP( ID_E01z, stream );
-  CASEDUMP( ID_E11z, stream );
-  CASEDUMP( ID_Fxy0, stream );
-  CASEDUMP( ID_Fxy1, stream );
-  CASEDUMP( ID_Fx0z, stream );
-  CASEDUMP( ID_Fx1z, stream );
-  CASEDUMP( ID_F0yz, stream );
-  CASEDUMP( ID_F1yz, stream );
-  CASEDUMP( ID_Shell, stream );
-  default: stream << "ID_INVALID";
-  }
-  return stream;
-}
-
-//=======================================================================
-//function : GetShapeIDByParams
-//purpose  : define an id of the block sub-shape by normlized point coord
-//=======================================================================
-
-int TBlock::GetShapeIDByParams ( const gp_XYZ& theCoord )
-{
-  //   id ( 0 - 26 ) computation:
-
-  //   vertex     ( 0 - 7 )  : id = 1*x + 2*y + 4*z
-
-  //   edge || X  ( 8 - 11 ) : id = 8   + 1*y + 2*z
-  //   edge || Y  ( 12 - 15 ): id = 1*x + 12  + 2*z
-  //   edge || Z  ( 16 - 19 ): id = 1*x + 2*y + 16 
-
-  //   face || XY ( 20 - 21 ): id = 8   + 12  + 1*z - 0
-  //   face || XZ ( 22 - 23 ): id = 8   + 1*y + 16  - 2
-  //   face || YZ ( 24 - 25 ): id = 1*x + 12  + 16  - 4
-
-  static int iAddBnd[]    = { 1, 2, 4 };
-  static int iAddNotBnd[] = { 8, 12, 16 };
-  static int iFaceSubst[] = { 0, 2, 4 };
-
-  int id = 0;
-  int iOnBoundary = 0;
-  for ( int iCoord = 0; iCoord < 3; iCoord++ )
-  {
-    double val = theCoord.Coord( iCoord + 1 );
-    if ( val == 0.0 )
-      iOnBoundary++;
-    else if ( val == 1.0 )
-      id += iAddBnd[ iOnBoundary++ ];
-    else
-      id += iAddNotBnd[ iCoord ];
-  }
-  if ( iOnBoundary == 1 ) // face
-    id -= iFaceSubst[ (id - 20) / 4 ];
-  else if ( iOnBoundary == 0 ) // shell
-    id = 26;
-
-  if ( id > 26 || id < 0 ) {
-    MESSAGE( "GetShapeIDByParams() = " << id
-            <<" "<< theCoord.X() <<" "<< theCoord.Y() <<" "<< theCoord.Z() );
-  }
-
-  return id + 1; // shape ids start at 1
-}
-
-//=======================================================================
-//function : LoadBlockShapes
-//purpose  : add sub-shapes of theBlock to theShapeIDMap so that they get
-//           IDs acoording to enum TBlockShapeID
-//=======================================================================
-
-bool TBlock::LoadBlockShapes(const TopoDS_Vertex&        theVertex000,
-                             const TopoDS_Vertex&        theVertex001,
-//                             TopTools_IndexedMapOfShape& theShapeIDMap
-                             TopTools_IndexedMapOfOrientedShape& theShapeIDMap )
-{
-  MESSAGE(" ::LoadBlockShapes()");
-  myGridComputed = false;
-
-  // 6 vertices
-  TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111;
-  // 12 edges
-  TopoDS_Shape Ex00, Ex10, Ex01, Ex11;
-  TopoDS_Shape E0y0, E1y0, E0y1, E1y1;
-  TopoDS_Shape E00z, E10z, E01z, E11z;
-  // 6 faces
-  TopoDS_Shape Fxy0, Fx0z, F0yz, Fxy1, Fx1z, F1yz;
-
-  // nb of faces bound to a vertex in TopTools_IndexedDataMapOfShapeListOfShape
-  // filled by TopExp::MapShapesAndAncestors()
-  const int NB_FACES_BY_VERTEX = 6;
-
-  TopTools_IndexedDataMapOfShapeListOfShape vfMap;
-  TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_FACE, vfMap );
-  if ( vfMap.Extent() != 8 ) {
-    MESSAGE(" Wrong nb of vertices in the block: " << vfMap.Extent() );
-    return false;
-  }
-
-  V000 = theVertex000;
-  V001 = theVertex001;
-
-  if ( V000.IsNull() ) {
-    // find vertex 000 - the one with smallest coordinates
-    double minVal = DBL_MAX, minX, val;
-    for ( int i = 1; i <= 8; i++ ) {
-      const TopoDS_Vertex& v = TopoDS::Vertex( vfMap.FindKey( i ));
-      gp_Pnt P = BRep_Tool::Pnt( v );
-      val = P.X() + P.Y() + P.Z();
-      if ( val < minVal || ( val == minVal && P.X() < minX )) {
-        V000 = v;
-        minVal = val;
-        minX = P.X();
-      }
-    }
-    // find vertex 001 - the one on the most vertical edge passing through V000
-    TopTools_IndexedDataMapOfShapeListOfShape veMap;
-    TopExp::MapShapesAndAncestors( myShell, TopAbs_VERTEX, TopAbs_EDGE, veMap );
-    gp_Vec dir001 = gp::DZ();
-    gp_Pnt p000 = BRep_Tool::Pnt( TopoDS::Vertex( V000 ));
-    double maxVal = -DBL_MAX;
-    TopTools_ListIteratorOfListOfShape eIt ( veMap.FindFromKey( V000 ));
-    for (  ; eIt.More(); eIt.Next() ) {
-      const TopoDS_Edge& e = TopoDS::Edge( eIt.Value() );
-      TopoDS_Vertex v = TopExp::FirstVertex( e );
-      if ( v.IsSame( V000 ))
-        v = TopExp::LastVertex( e );
-      val = dir001 * gp_Vec( p000, BRep_Tool::Pnt( v )).Normalized();
-      if ( val > maxVal ) {
-        V001 = v;
-        maxVal = val;
-      }
-    }
-  }
-
-  // find the bottom (Fxy0), Fx0z and F0yz faces
-
-  const TopTools_ListOfShape& f000List = vfMap.FindFromKey( V000 );
-  const TopTools_ListOfShape& f001List = vfMap.FindFromKey( V001 );
-  if (f000List.Extent() != NB_FACES_BY_VERTEX ||
-      f001List.Extent() != NB_FACES_BY_VERTEX ) {
-    MESSAGE(" LoadBlockShapes() " << f000List.Extent() << " " << f001List.Extent());
-    return false;
-  }
-  TopTools_ListIteratorOfListOfShape f001It, f000It ( f000List );
-  int i, j, iFound1, iFound2;
-  for ( j = 0; f000It.More(); f000It.Next(), j++ )
-  {
-    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
-    const TopoDS_Shape& F = f000It.Value();
-    for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
-      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-      if ( F.IsSame( f001It.Value() ))
-        break;
-    }
-    if ( f001It.More() ) // Fx0z or F0yz found
-      if ( Fx0z.IsNull() ) {
-        Fx0z = F;
-        iFound1 = i;
-      } else {
-        F0yz = F;
-        iFound2 = i;
-      }
-    else // F is the bottom face
-      Fxy0 = F;
-  }
-  if ( Fxy0.IsNull() || Fx0z.IsNull() || F0yz.IsNull() ) {
-    MESSAGE( Fxy0.IsNull() <<" "<< Fx0z.IsNull() <<" "<< F0yz.IsNull() );
-    return false;
-  }
-
-  // choose the top face (Fxy1)
-  for ( i = 0, f001It.Initialize( f001List ); f001It.More(); f001It.Next(), i++ ) {
-    if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-    if ( i != iFound1 && i != iFound2 )
-      break;
-  }
-  Fxy1 = f001It.Value();
-  if ( Fxy1.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // find bottom edges and veritices
-  list< TopoDS_Edge > eList;
-  list< int >         nbVertexInWires;
-  getOrderedEdges( TopoDS::Face( Fxy0 ), TopoDS::Vertex( V000 ), eList, nbVertexInWires );
-  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  list< TopoDS_Edge >::iterator elIt = eList.begin();
-  for ( i = 0; elIt != eList.end(); elIt++, i++ )
-    switch ( i ) {
-    case 0: E0y0 = *elIt; V010 = TopExp::LastVertex( *elIt, true ); break;
-    case 1: Ex10 = *elIt; V110 = TopExp::LastVertex( *elIt, true ); break;
-    case 2: E1y0 = *elIt; V100 = TopExp::LastVertex( *elIt, true ); break;
-    case 3: Ex00 = *elIt; break;
-    default:;
-    }
-  if ( i != 4 || E0y0.IsNull() || Ex10.IsNull() || E1y0.IsNull() || Ex00.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
-    return false;
-  }
-
-
-  // find top edges and veritices
-  eList.clear();
-  getOrderedEdges( TopoDS::Face( Fxy1 ), TopoDS::Vertex( V001 ), eList, nbVertexInWires );
-  if ( nbVertexInWires.size() != 1 || nbVertexInWires.front() != 4 ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  for ( i = 0, elIt = eList.begin(); elIt != eList.end(); elIt++, i++ )
-    switch ( i ) {
-    case 0: Ex01 = *elIt; V101 = TopExp::LastVertex( *elIt, true ); break;
-    case 1: E1y1 = *elIt; V111 = TopExp::LastVertex( *elIt, true ); break;
-    case 2: Ex11 = *elIt; V011 = TopExp::LastVertex( *elIt, true ); break;
-    case 3: E0y1 = *elIt; break;
-    default:;
-    }
-  if ( i != 4 || Ex01.IsNull() || E1y1.IsNull() || Ex11.IsNull() || E0y1.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error, eList.size()=" << eList.size());
-    return false;
-  }
-
-  // swap Fx0z and F0yz if necessary
-  TopExp_Explorer exp( Fx0z, TopAbs_VERTEX );
-  for ( ; exp.More(); exp.Next() ) // Fx0z shares V101 and V100
-    if ( V101.IsSame( exp.Current() ) || V100.IsSame( exp.Current() ))
-      break; // V101 or V100 found
-  if ( !exp.More() ) { // not found
-    TopoDS_Shape f = Fx0z; Fx0z = F0yz; F0yz = f;
-  }
-
-  // find Fx1z and F1yz faces
-  const TopTools_ListOfShape& f111List = vfMap.FindFromKey( V111 );
-  const TopTools_ListOfShape& f110List = vfMap.FindFromKey( V110 );
-  if (f111List.Extent() != NB_FACES_BY_VERTEX ||
-      f110List.Extent() != NB_FACES_BY_VERTEX ) {
-    MESSAGE(" LoadBlockShapes() " << f111List.Extent() << " " << f110List.Extent());
-    return false;
-  }
-  TopTools_ListIteratorOfListOfShape f111It, f110It ( f110List);
-  for ( j = 0 ; f110It.More(); f110It.Next(), j++ ) {
-    if ( NB_FACES_BY_VERTEX == 6 && j % 2 ) continue; // each face encounters twice
-    const TopoDS_Shape& F = f110It.Value();
-    for ( i = 0, f111It.Initialize( f111List ); f111It.More(); f111It.Next(), i++ ) {
-      if ( NB_FACES_BY_VERTEX == 6 && i % 2 ) continue; // each face encounters twice
-      if ( F.IsSame( f111It.Value() )) { // Fx1z or F1yz found
-        if ( Fx1z.IsNull() )
-          Fx1z = F;
-        else
-          F1yz = F;
-      }
-    }
-  }
-  if ( Fx1z.IsNull() || F1yz.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // swap Fx1z and F1yz if necessary
-  for ( exp.Init( Fx1z, TopAbs_VERTEX ); exp.More(); exp.Next() )
-    if ( V010.IsSame( exp.Current() ) || V011.IsSame( exp.Current() ))
-      break;
-  if ( !exp.More() ) {
-    TopoDS_Shape f = Fx1z; Fx1z = F1yz; F1yz = f;
-  }
-
-  // find vertical edges
-  for ( exp.Init( Fx0z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
-    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
-    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
-    if ( vFirst.IsSame( V001 ))
-      E00z = edge;
-    else if ( vFirst.IsSame( V100 ))
-      E10z = edge;
-  }
-  if ( E00z.IsNull() || E10z.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-  for ( exp.Init( Fx1z, TopAbs_EDGE ); exp.More(); exp.Next() ) {
-    const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
-    const TopoDS_Shape& vFirst = TopExp::FirstVertex( edge, true );
-    if ( vFirst.IsSame( V111 ))
-      E11z = edge;
-    else if ( vFirst.IsSame( V010 ))
-      E01z = edge;
-  }
-  if ( E01z.IsNull() || E11z.IsNull() ) {
-    MESSAGE(" LoadBlockShapes() error ");
-    return false;
-  }
-
-  // load shapes in theShapeIDMap
-
-  theShapeIDMap.Clear();
-  
-  theShapeIDMap.Add(V000.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V100.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V010.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V110.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V001.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V101.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V011.Oriented( TopAbs_FORWARD ));
-  theShapeIDMap.Add(V111.Oriented( TopAbs_FORWARD ));
-
-  theShapeIDMap.Add(Ex00);
-  theShapeIDMap.Add(Ex10);
-  theShapeIDMap.Add(Ex01);
-  theShapeIDMap.Add(Ex11);
-
-  theShapeIDMap.Add(E0y0);
-  theShapeIDMap.Add(E1y0);
-  theShapeIDMap.Add(E0y1);
-  theShapeIDMap.Add(E1y1);
-
-  theShapeIDMap.Add(E00z);
-  theShapeIDMap.Add(E10z);
-  theShapeIDMap.Add(E01z);
-  theShapeIDMap.Add(E11z);
-
-  theShapeIDMap.Add(Fxy0);
-  theShapeIDMap.Add(Fxy1);
-  theShapeIDMap.Add(Fx0z);
-  theShapeIDMap.Add(Fx1z);
-  theShapeIDMap.Add(F0yz);
-  theShapeIDMap.Add(F1yz);
-  
-  theShapeIDMap.Add(myShell);
-
-  if ( theShapeIDMap.Extent() != 27 ) {
-    MESSAGE("LoadBlockShapes() " << theShapeIDMap.Extent() );
-    return false;
-  }
-
-  // store shapes geometry
-  for ( int shapeID = 1; shapeID < theShapeIDMap.Extent(); shapeID++ )
-  {
-    const TopoDS_Shape& S = theShapeIDMap( shapeID );
-    switch ( S.ShapeType() )
-    {
-    case TopAbs_VERTEX: {
-
-      if ( shapeID > ID_V111 ) {
-        MESSAGE(" shapeID =" << shapeID );
-        return false;
-      }
-      myPnt[ shapeID - ID_V000 ] =
-        BRep_Tool::Pnt( TopoDS::Vertex( S )).XYZ();
-      break;
-    }
-    case TopAbs_EDGE: {
-
-      const TopoDS_Edge& edge = TopoDS::Edge( S );
-      if ( shapeID < ID_Ex00 || shapeID > ID_E11z || edge.IsNull() ) {
-        MESSAGE(" shapeID =" << shapeID );
-        return false;
-      }
-      TEdge& tEdge = myEdge[ shapeID - ID_Ex00 ];
-      tEdge.myCoordInd = GetCoordIndOnEdge( shapeID );
-      TopLoc_Location loc;
-      tEdge.myC3d = BRep_Tool::Curve( edge, loc, tEdge.myFirst, tEdge.myLast );
-      if ( !IsForwardEdge( edge, theShapeIDMap ))
-        Swap( tEdge.myFirst, tEdge.myLast );
-      tEdge.myTrsf = loc;
-      break;
-    }
-    case TopAbs_FACE: {
-
-      const TopoDS_Face& face = TopoDS::Face( S );
-      if ( shapeID < ID_Fxy0 || shapeID > ID_F1yz || face.IsNull() ) {
-        MESSAGE(" shapeID =" << shapeID );
-        return false;
-      }
-      TFace& tFace = myFace[ shapeID - ID_Fxy0 ];
-      // pcurves
-      vector< int > edgeIdVec(4, -1);
-      GetFaceEdgesIDs( shapeID, edgeIdVec );
-      for ( int iE = 0; iE < 4; iE++ ) // loop on 4 edges
-      {
-        const TopoDS_Edge& edge = TopoDS::Edge( theShapeIDMap( edgeIdVec[ iE ]));
-        tFace.myCoordInd[ iE ] = GetCoordIndOnEdge( edgeIdVec[ iE ] );
-        tFace.myC2d[ iE ] =
-          BRep_Tool::CurveOnSurface( edge, face, tFace.myFirst[iE], tFace.myLast[iE] );
-        if ( !IsForwardEdge( edge, theShapeIDMap ))
-          Swap( tFace.myFirst[ iE ], tFace.myLast[ iE ] );
-      }
-      // 2d corners
-      tFace.myCorner[ 0 ] = tFace.myC2d[ 0 ]->Value( tFace.myFirst[0] ).XY();
-      tFace.myCorner[ 1 ] = tFace.myC2d[ 0 ]->Value( tFace.myLast[0] ).XY();
-      tFace.myCorner[ 2 ] = tFace.myC2d[ 1 ]->Value( tFace.myLast[1] ).XY();
-      tFace.myCorner[ 3 ] = tFace.myC2d[ 1 ]->Value( tFace.myFirst[1] ).XY();
-      // sufrace
-      TopLoc_Location loc;
-      tFace.myS = BRep_Tool::Surface( face, loc );
-      tFace.myTrsf = loc;
-      break;
-    }
-    default: break;
-    }
-  } // loop on shapes in theShapeIDMap
-
-  return true;
-}
-
-//=======================================================================
-//function : GetFaceEdgesIDs
-//purpose  : return edges IDs in the order u0, u1, 0v, 1v
-//           u0 means "|| u, v == 0"
-//=======================================================================
-
-void TBlock::GetFaceEdgesIDs (const int faceID, vector< int >& edgeVec )
-{
-  switch ( faceID ) {
-  case ID_Fxy0:
-    edgeVec[ 0 ] = ID_Ex00;
-    edgeVec[ 1 ] = ID_Ex10;
-    edgeVec[ 2 ] = ID_E0y0;
-    edgeVec[ 3 ] = ID_E1y0;
-    break;
-  case ID_Fxy1:
-    edgeVec[ 0 ] = ID_Ex01;
-    edgeVec[ 1 ] = ID_Ex11;
-    edgeVec[ 2 ] = ID_E0y1;
-    edgeVec[ 3 ] = ID_E1y1;
-    break;
-  case ID_Fx0z:
-    edgeVec[ 0 ] = ID_Ex00;
-    edgeVec[ 1 ] = ID_Ex01;
-    edgeVec[ 2 ] = ID_E00z;
-    edgeVec[ 3 ] = ID_E10z;
-    break;
-  case ID_Fx1z:
-    edgeVec[ 0 ] = ID_Ex10;
-    edgeVec[ 1 ] = ID_Ex11;
-    edgeVec[ 2 ] = ID_E01z;
-    edgeVec[ 3 ] = ID_E11z;
-    break;
-  case ID_F0yz:
-    edgeVec[ 0 ] = ID_E0y0;
-    edgeVec[ 1 ] = ID_E0y1;
-    edgeVec[ 2 ] = ID_E00z;
-    edgeVec[ 3 ] = ID_E01z;
-    break;
-  case ID_F1yz:
-    edgeVec[ 0 ] = ID_E1y0;
-    edgeVec[ 1 ] = ID_E1y1;
-    edgeVec[ 2 ] = ID_E10z;
-    edgeVec[ 3 ] = ID_E11z;
-    break;
-  default:
-    MESSAGE(" GetFaceEdgesIDs(), wrong face ID: " << faceID );
-  }
-}
index b658a25..9358fae 100644 (file)
@@ -30,7 +30,6 @@
 #include <iostream>
 
 #include <TopoDS_Shape.hxx>
-//#include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_IndexedMapOfOrientedShape.hxx>
 #include <gp_XYZ.hxx>
 #include <gp_XY.hxx>
index 89e9e26..238bd22 100644 (file)
@@ -32,16 +32,20 @@ using namespace std;
 #include "SMESH_Mesh.hxx"
 #include "SMESH_Hypothesis.hxx"
 #include "SMESH_Algo.hxx"
+
 #include "utilities.h"
 #include "OpUtil.hxx"
 
+#include <BRep_Builder.hxx>
+
 #include <TopExp.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopoDS_Compound.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
-#include <TopoDS_Compound.hxx>
-#include <BRep_Builder.hxx>
 
 #ifdef _DEBUG_
 #include <gp_Pnt.hxx>
@@ -550,6 +554,43 @@ SMESH_Hypothesis::Hypothesis_Status
 
     if ( !_meshDS->AddHypothesis(_subShape, anHyp))
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
+
+    // Serve Propagation of 1D hypothesis
+    if (event == ADD_HYP) {
+      bool isPropagationOk = true;
+      string hypName = anHyp->GetName();
+
+      if (hypName == "Propagation") {
+        if (_subShape.ShapeType() == TopAbs_EDGE) {
+          isPropagationOk = _father->BuildPropagationChain(_subShape);
+        } else {
+          TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+          TopTools_MapOfShape aMap;
+          for (; exp.More(); exp.Next()) {
+            if (aMap.Add(exp.Current())) {
+              if (!_father->BuildPropagationChain(exp.Current())) {
+                isPropagationOk = false;
+              }
+            }
+          }
+        }
+      } else if (anHyp->GetDim() == 1) { // Only 1D hypothesis can be propagated
+        if (_subShape.ShapeType() == TopAbs_EDGE) {
+          TopoDS_Shape aMainEdge;
+          if (_father->IsPropagatedHypothesis(_subShape, aMainEdge)) {
+            isPropagationOk = _father->RebuildPropagationChains();
+          } else if (_father->IsPropagationHypothesis(_subShape)) {
+            isPropagationOk = _father->BuildPropagationChain(_subShape);
+          } else {
+          }
+        }
+      } else {
+      }
+
+      if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+        ret = SMESH_Hypothesis::HYP_CONCURENT;
+      }
+    } // Serve Propagation of 1D hypothesis
   }
 
   // --------------------------
@@ -559,6 +600,51 @@ SMESH_Hypothesis::Hypothesis_Status
   {
     if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
       return SMESH_Hypothesis::HYP_OK; // nothing changes
+
+    // Serve Propagation of 1D hypothesis
+    if (event == REMOVE_HYP) {
+      bool isPropagationOk = true;
+      string hypName = anHyp->GetName();
+
+      if (hypName == "Propagation") {
+        if (_subShape.ShapeType() == TopAbs_EDGE) {
+          if (!_father->RemovePropagationChain(_subShape)) {
+            return SMESH_Hypothesis::HYP_UNKNOWN_FATAL;
+          }
+          // rebuild propagation chains, because removing one
+          // chain can resolve concurention, existing before
+          isPropagationOk = _father->RebuildPropagationChains();
+        } else {
+          TopExp_Explorer exp (_subShape, TopAbs_EDGE);
+          TopTools_MapOfShape aMap;
+          for (; exp.More(); exp.Next()) {
+            if (aMap.Add(exp.Current())) {
+              if (!_father->RemovePropagationChain(exp.Current())) {
+                return SMESH_Hypothesis::HYP_UNKNOWN_FATAL;
+              }
+            }
+          }
+          // rebuild propagation chains, because removing one
+          // chain can resolve concurention, existing before
+          if (!_father->RebuildPropagationChains()) {
+            isPropagationOk = false;
+          }
+        }
+      } else { // if (hypName == "Propagation")
+        if (anHyp->GetDim() == 1) // Only 1D hypothesis can be propagated
+        {
+          if (_subShape.ShapeType() == TopAbs_EDGE) {
+            isPropagationOk = _father->RebuildPropagationChains();
+            if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT)
+              ret = SMESH_Hypothesis::HYP_CONCURENT;
+          }
+        }
+      }
+
+      if (!isPropagationOk && ret < SMESH_Hypothesis::HYP_CONCURENT) {
+        ret = SMESH_Hypothesis::HYP_CONCURENT;
+      }
+    } // Serve Propagation of 1D hypothesis
   }
 
   // ------------------
@@ -843,22 +929,9 @@ SMESH_Hypothesis::Hypothesis_Status
     ASSERT(0);
     break;
   }
-  // ----------------------------------------
-  // check concurent hypotheses on ansestors
-  // ----------------------------------------
-  if (ret < SMESH_Hypothesis::HYP_CONCURENT &&
-      (event == ADD_FATHER_HYP ||
-       event == ADD_FATHER_ALGO ||
-       event == REMOVE_FATHER_HYP ||
-       event == REMOVE_FATHER_ALGO ||
-       event == REMOVE_ALGO ||
-       event == REMOVE_HYP))
-  {
-    ret = CheckConcurentHypothesis( anHyp->GetType() );
-  }
 
   if ((_algoState != oldAlgoState) || modifiedHyp)
-    int retc = ComputeStateEngine(MODIF_ALGO_STATE);
+    ComputeStateEngine(MODIF_ALGO_STATE);
 
   return ret;
 }
index 307ddf2..8669c22 100644 (file)
@@ -123,6 +123,8 @@ class SMESH_subMesh
   // return true if theHypothesis can be used to mesh me:
   // its shape type is checked
   
+  SMESH_Hypothesis::Hypothesis_Status CheckConcurentHypothesis (const int theHypType);
+  // check if there are several applicable hypothesis on fathers
 
  protected:
   void InsertDependence(const TopoDS_Shape aSubShape);
@@ -150,9 +152,6 @@ class SMESH_subMesh
                           const TopoDS_Shape& theCollection);
   // Apply theAlgo to all subshapes in theCollection
 
-  SMESH_Hypothesis::Hypothesis_Status CheckConcurentHypothesis (const int theHypType);
-  // check if there are several applicable hypothesis on fathers
-
   const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape&      theShape,
                                              const SMESH_Hypothesis * theHyp,
                                              const int                theHypType = 0);
index 9730714..e3a1378 100644 (file)
@@ -66,6 +66,7 @@ LIB_SRC =     SMESHGUI.cxx \
                SMESHGUI_RemoveNodesDlg.cxx \
                SMESHGUI_RemoveElementsDlg.cxx \
                SMESHGUI_MeshInfosDlg.cxx \
+               SMESHGUI_StandardMeshInfosDlg.cxx \
                SMESHGUI_Preferences_ColorDlg.cxx \
                SMESHGUI_Preferences_ScalarBarDlg.cxx \
                SMESHGUI_Preferences_SelectionDlg.cxx \
@@ -119,6 +120,7 @@ LIB_MOC = \
                SMESHGUI_RemoveNodesDlg.h \
                SMESHGUI_RemoveElementsDlg.h \
                SMESHGUI_MeshInfosDlg.h \
+               SMESHGUI_StandardMeshInfosDlg.h \
                SMESHGUI_Preferences_ColorDlg.h \
                SMESHGUI_Preferences_ScalarBarDlg.h \
                SMESHGUI_Preferences_SelectionDlg.h \
index 49baea8..78f27d2 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESHGUI_RemoveNodesDlg.h"
 #include "SMESHGUI_RemoveElementsDlg.h"
 #include "SMESHGUI_MeshInfosDlg.h"
+#include "SMESHGUI_StandardMeshInfosDlg.h"
 #include "SMESHGUI_Preferences_ColorDlg.h"
 #include "SMESHGUI_Preferences_ScalarBarDlg.h"
 #include "SMESHGUI_Preferences_SelectionDlg.h"
@@ -626,6 +627,16 @@ namespace{
 
   void OnEditDelete()
   {
+    // VSR 17/11/04: check if all objects selected belong to SMESH component --> start
+    QString aParentComponent = ((SALOMEGUI_Desktop*)QAD_Application::getDesktop())->getComponentFromSelection();
+    if ( aParentComponent != QAD_Application::getDesktop()->getActiveComponent() )  {
+      QAD_MessageBox::warn1 ( QAD_Application::getDesktop(),
+                             QObject::tr("ERR_ERROR"), 
+                             QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg(QAD_Application::getDesktop()->getComponentUserName( "SMESH" )),
+                             QObject::tr("BUT_OK") );
+      return;
+    }
+    // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
     if (QAD_MessageBox::warn2
        (QAD_Application::getDesktop(),
         QObject::tr("SMESH_WRN_WARNING"),
@@ -712,32 +723,35 @@ namespace{
  *
  */
 //=============================================================================
-class CustomItem:public QCustomMenuItem
+class CustomItem : public QCustomMenuItem
 {
- public:
-  CustomItem(const QString & s, const QFont & f):string(s), font(f)
-  {
-  };
-  ~CustomItem()
+public:
+  CustomItem(const QString& s, const QFont& f) : myString(s), myFont(f) {}
+  ~CustomItem() {}
+
+  void paint(QPainter* p, const QColorGroup& cg, bool act, bool /*enabled*/, int x, int y, int w, int h)
   {
+    p->save();
+    p->fillRect( x, y, w, h, act ? cg.highlight() : cg.mid() );
+    p->setPen( act ? cg.highlightedText() : cg.buttonText() );
+    p->setFont( myFont );
+    p->drawText( x, y, w, h, AlignHCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, myString );
+    p->restore();
   }
 
-  void paint(QPainter * p, const QColorGroup & /*cg */ , bool /*act */ ,
-             bool /*enabled */ , int x, int y, int w, int h)
+  QSize sizeHint()
   {
-    p->setFont(font);
-    p->drawText(x, y, w, h,
-                AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
+    return QFontMetrics( myFont ).size( AlignHCenter | AlignVCenter | ShowPrefix | DontClip | SingleLine, myString );
   }
 
-  QSize sizeHint()
+  bool fullSpan() const
   {
-    return QFontMetrics(font).
-      size(AlignHCenter | AlignVCenter | ShowPrefix | DontClip, string);
+    return true;
   }
- private:
-  QString string;
-  QFont font;
+
+private:
+  QString myString;
+  QFont   myFont;
 };
 
 //=============================================================================
@@ -1542,6 +1556,29 @@ bool SMESHGUI::OnGUIEvent(int theCommandID, QAD_Desktop * parent)
       break;
     }
 
+  case 902:                                    // STANDARD MESH INFOS
+    {
+      EmitSignalDeactivateDialog();
+      SALOME_Selection *Sel =
+       SALOME_Selection::Selection(myActiveStudy->getSelection());
+      if ( Sel->IObjectCount() > 1 ) { // a dlg for each IO
+        SALOME_ListIO IOs; IOs = Sel->StoredIObjects(); // list copy
+        SALOME_ListIteratorOfListIO It (IOs);
+        for ( ; It.More(); It.Next() ) {
+          Sel->ClearIObjects();
+          Sel->AddIObject( It.Value() );
+          SMESHGUI_StandardMeshInfosDlg *aDlg = new SMESHGUI_StandardMeshInfosDlg(parent, "", false);
+        }
+        // restore selection
+        Sel->ClearIObjects();
+        for (It.Initialize( IOs ) ; It.More(); It.Next() )
+          Sel->AddIObject( It.Value() );
+      }
+      else
+        SMESHGUI_StandardMeshInfosDlg *aDlg = new SMESHGUI_StandardMeshInfosDlg(parent, "", false);
+      break;
+    } 
+    
   case 1001:                                   // AUTOMATIC UPDATE PREFERENCES
     {
       parent->menuBar()->setItemChecked(1001, !parent->menuBar()->isItemChecked(1001));
@@ -2246,7 +2283,7 @@ bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString
       if ( topItem >= 0 ) {
        if ( theParent == "Viewer" ) {
          // set bold font for popup menu's TopLabel item (Viewer popup)
-         QFont fnt = QApplication::font(); fnt.setBold( TRUE );
+         QFont fnt = popup->font(); fnt.setBold( TRUE );
          popup->removeItem( QAD_TopLabel_Popup_ID );
          popup->insertItem( new CustomItem( QString( IObject->getName() ), fnt ), QAD_TopLabel_Popup_ID, topItem );
        }
@@ -2438,7 +2475,7 @@ bool SMESHGUI::CustomPopup(QAD_Desktop* parent, QPopupMenu* popup, const QString
        int topItem = popup->indexOf( QAD_TopLabel_Popup_ID );
        if ( topItem >= 0 ) {
          // set bold font for popup menu's TopLabel item
-         QFont fnt = QApplication::font(); fnt.setBold( TRUE );
+         QFont fnt = popup->font(); fnt.setBold( TRUE );
          popup->removeItem( QAD_TopLabel_Popup_ID );
          popup->insertItem( new CustomItem( QString("%1 ").arg( nbSel ) + type + "(s) ", fnt ), QAD_TopLabel_Popup_ID, topItem );
        }
index d6f2e14..2d16299 100644 (file)
@@ -745,7 +745,8 @@ void SMESHGUI_EditHypothesesDlg::InitGeom()
   SALOMEDS::GenericAttribute_var    anAttr;
   SALOMEDS::AttributeName_var       aName;
   if ( !myGeomShape->_is_nil() && (!myMesh->_is_nil() || !mySubMesh->_is_nil()) ) {
-    SALOMEDS::SObject_var aSO = SMESH::GetActiveStudyDocument()->FindObjectIOR( myGeomShape->GetName() );
+    SALOMEDS::Study_var aStudy = SMESH::GetActiveStudyDocument();
+    SALOMEDS::SObject_var aSO = aStudy->FindObjectIOR( aStudy->ConvertObjectToIOR(myGeomShape) );
     if ( !aSO->_is_nil() ) {
       if (aSO->FindAttribute(anAttr, "AttributeName") ) {
        aName = SALOMEDS::AttributeName::_narrow(anAttr);
index 40837ec..dd130b2 100644 (file)
@@ -347,6 +347,8 @@ SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg( QWidget* parent,  const char* name
   this->move( x, y );
   this->show();
 
+  cout<<"----"<<this->height()<<endl;
+  cout<<"----"<<this->width()<<endl;
   // init dialog with current selection
   onSelectionChanged();
 }
index e8ae905..a060d03 100644 (file)
@@ -529,8 +529,11 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
   myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
   if(myMesh->_is_nil())
     return;
+
   myActor = SMESH::FindActorByObject(myMesh);
   if (!myActor)
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor)
     return;
   
   int aNbUnits = 0;
diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx
new file mode 100644 (file)
index 0000000..37dfbdf
--- /dev/null
@@ -0,0 +1,448 @@
+//  SMESH SMESHGUI : GUI for SMESH 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESHGUI_StandardMeshInfosDlg.cxx
+//  Author : Michael ZORIN
+//  Module : SMESH
+//  $Header$
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qtextbrowser.h>
+#include <qmap.h>
+#include <qpushbutton.h>
+
+#include "QAD_Application.h"
+#include "QAD_Desktop.h"
+#include "QAD_WaitCursor.h"
+
+#include "SMESHGUI_StandardMeshInfosDlg.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI.h"
+
+#include "SMESH.hxx"
+
+// IDL Headers
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+
+#include "utilities.h"
+
+using namespace std;
+
+
+//=================================================================================
+/*!
+ *  SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg
+ * 
+ *  Constructor
+ */
+//=================================================================================
+SMESHGUI_StandardMeshInfosDlg::SMESHGUI_StandardMeshInfosDlg( QWidget* parent,  const char* name, bool modal, WFlags fl )
+     : QDialog( parent, name, modal, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose )
+{
+  if ( !name )
+      setName( "SMESHGUI_StandardMeshInfosDlg" );
+  setCaption( tr( "SMESH_STANDARD_MESHINFO_TITLE"  ) );
+  setSizeGripEnabled( TRUE );
+
+  myStartSelection = true;
+  myIsActiveWindow = true;
+
+  // dialog layout
+  QGridLayout* aDlgLayout = new QGridLayout( this ); 
+  aDlgLayout->setSpacing( 6 );
+  aDlgLayout->setMargin( 11 );
+  
+  // mesh group box
+  myMeshGroup = new QGroupBox( this, "myMeshGroup" );
+  myMeshGroup->setTitle( tr( "SMESH_MESH" ) );
+  myMeshGroup->setColumnLayout(0, Qt::Vertical );
+  myMeshGroup->layout()->setSpacing( 0 );
+  myMeshGroup->layout()->setMargin( 0 );
+  QGridLayout* myMeshGroupLayout = new QGridLayout( myMeshGroup->layout() );
+  myMeshGroupLayout->setAlignment( Qt::AlignTop );
+  myMeshGroupLayout->setSpacing( 6 );
+  myMeshGroupLayout->setMargin( 11 );
+  
+  // select button, label and line edit with mesh name
+  myNameLab = new QLabel( myMeshGroup, "myNameLab" );
+  myNameLab->setText( tr( "SMESH_NAME"  ) );
+  myMeshGroupLayout->addWidget( myNameLab, 0, 0 );
+
+  QPixmap image0( QAD_Desktop::getResourceManager()->loadPixmap( "SMESH",tr( "ICON_SELECT" ) ) );
+  mySelectBtn = new QPushButton( myMeshGroup, "mySelectBtn" );
+  mySelectBtn->setPixmap( image0 );
+  mySelectBtn->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+  myMeshGroupLayout->addWidget( mySelectBtn, 0, 1 );
+  
+  myMeshLine = new QLineEdit( myMeshGroup, "myMeshLine" );
+  myMeshGroupLayout->addWidget( myMeshLine, 0, 2 );
+  
+  aDlgLayout->addWidget( myMeshGroup, 0, 0 );
+
+  // information group box
+  myInfoGroup  = new QGroupBox( this, "myInfoGroup" );
+  myInfoGroup->setTitle( tr( "SMESH_INFORMATION" ) );
+  myInfoGroup->setColumnLayout(0, Qt::Vertical );
+  myInfoGroup->layout()->setSpacing( 0 );
+  myInfoGroup->layout()->setMargin( 0 );
+  QGridLayout* myInfoGroupLayout = new QGridLayout( myInfoGroup->layout() );
+  myInfoGroupLayout->setAlignment( Qt::AlignTop );
+  myInfoGroupLayout->setSpacing( 6 );
+  myInfoGroupLayout->setMargin( 11 );
+  
+  // information text browser
+  myInfo = new QTextBrowser(myInfoGroup, "myInfo");
+  myInfoGroupLayout->addWidget( myInfo, 0, 0 );
+
+  aDlgLayout->addWidget( myInfoGroup, 1, 0 );
+
+  // buttons group
+  myButtonsGroup = new QGroupBox( this, "myButtonsGroup" );
+  myButtonsGroup->setColumnLayout(0, Qt::Vertical );
+  myButtonsGroup->layout()->setSpacing( 0 );  myButtonsGroup->layout()->setMargin( 0 );
+  QHBoxLayout* myButtonsGroupLayout = new QHBoxLayout( myButtonsGroup->layout() );
+  myButtonsGroupLayout->setAlignment( Qt::AlignTop );
+  myButtonsGroupLayout->setSpacing( 6 ); myButtonsGroupLayout->setMargin( 11 );
+  
+  // buttons --> OK button
+  myOkBtn = new QPushButton( tr( "SMESH_BUT_OK"  ), myButtonsGroup, "myOkBtn" );
+  myOkBtn->setAutoDefault( TRUE ); myOkBtn->setDefault( TRUE );
+  myButtonsGroupLayout->addStretch();
+  myButtonsGroupLayout->addWidget( myOkBtn );
+  myButtonsGroupLayout->addStretch();
+  
+  aDlgLayout->addWidget( myButtonsGroup, 2, 0 );
+  
+  mySelection = SALOME_Selection::Selection( SMESHGUI::GetSMESHGUI()->GetActiveStudy()->getSelection() );
+  SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ) ;
+
+  // connect signals
+  connect( myOkBtn,                  SIGNAL( clicked() ),                      this, SLOT( close() ) );
+  connect( mySelectBtn,              SIGNAL( clicked() ),                      this, SLOT( onStartSelection() ) );
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalCloseAllDialogs() ),        this, SLOT( close() ) ) ;
+  connect( SMESHGUI::GetSMESHGUI(),  SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( DeactivateActiveDialog() ) ) ;
+  connect( mySelection,              SIGNAL( currentSelectionChanged() ),      this, SLOT( onSelectionChanged() ) );
+
+  // resize and move dialog, then show
+  this->setMinimumSize(270, 428);
+  int x, y;
+  SMESHGUI::GetSMESHGUI()->DefineDlgPosition( this, x, y );
+  this->move( x, y );
+  this->show();
+  
+  // init dialog with current selection
+  myMeshFilter = new SMESH_TypeFilter( MESH );
+  mySelection->AddFilter( myMeshFilter );
+  onSelectionChanged();
+}
+
+//=================================================================================
+/*!
+ *  SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg
+ * 
+ *  Destructor
+ */
+//=================================================================================
+SMESHGUI_StandardMeshInfosDlg::~SMESHGUI_StandardMeshInfosDlg()
+{
+}
+
+//=================================================================================
+/*!
+ *  SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos
+ */
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::DumpMeshInfos()
+{
+  QAD_WaitCursor wc;
+  int nbSel = mySelection->IObjectCount();
+  myInfo->clear();
+  if ( nbSel == 1 ) {
+    myStartSelection = false;
+    myMeshLine->setText( "" );
+    SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
+    
+    if ( !aMesh->_is_nil() ) {
+      QString aName, anInfo;
+      SMESH::GetNameOfSelectedIObjects(mySelection, aName);
+      myMeshLine->setText( aName );
+      int aNbNodes =   (int)aMesh->NbNodes();
+      int aNbEdges =   (int)aMesh->NbEdges();
+      int aNbFaces =   (int)aMesh->NbFaces();
+      int aNbVolumes = (int)aMesh->NbVolumes();
+      
+      int aDimension = 0;
+      double aNbDimElements = 0;
+      if (aNbVolumes > 0) {
+       aNbDimElements = aNbVolumes;
+       aDimension = 3;
+      }
+      else if(aNbFaces > 0 ) {
+       aNbDimElements = aNbFaces;
+       aDimension = 2;
+      }
+      else if(aNbEdges > 0 ) {
+       aNbDimElements = aNbEdges;
+       aDimension = 1;
+      }
+      else if(aNbNodes > 0 ) {
+       aNbDimElements = aNbNodes;
+       aDimension = 0;
+      }
+      
+      // information about the mesh
+      anInfo.append(QString("Nb of element of dimension %1:<b> %2</b><br>").arg(aDimension).arg(aNbDimElements));
+      anInfo.append(QString("Nb of nodes: <b>%1</b><br><br>").arg(aNbNodes));
+
+      // information about the groups of the mesh
+      SALOMEDS::Study_var aStudy = SMESH::GetActiveStudyDocument();
+      SALOMEDS::SObject_var aMeshSO = aStudy->FindObjectIOR( aStudy->ConvertObjectToIOR(aMesh) ); 
+      SALOMEDS::SObject_var anObj;
+      
+      bool hasGroup = false;
+
+      // info about groups on nodes
+      aMeshSO->FindSubObject(Tag_NodeGroups , anObj);
+      if ( !anObj->_is_nil() )
+       {
+         SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj);
+         if (it->More())
+           {
+             anInfo.append(QString("Groups:<br><br>"));
+             hasGroup = true;
+           }
+         for(; it->More(); it->Next()){
+           SALOMEDS::SObject_var subObj = it->Value();
+           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() );
+           if ( !aGroup->_is_nil() )
+             {
+               anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
+               anInfo.append(QString("%1<br>").arg("on nodes"));
+               anInfo.append(QString("%1<br>").arg(aGroup->Size()));
+               // check if the group based on geometry
+               SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
+               if ( !aGroupOnGeom->_is_nil() )
+                 {
+                   GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
+                   QString aShapeName = "<unknown>";
+                   SALOMEDS::SObject_var aGeomObj, aRef;
+                   if ( subObj->FindSubObject( 1, aGeomObj ) &&  aGeomObj->ReferencedObject( aRef ))
+                     aShapeName = aRef->GetName();
+                   anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
+                 }
+               else
+                 anInfo.append(QString("<br>"));
+             }
+         }
+       }  
+      
+      // info about groups on edges
+      anObj = SALOMEDS::SObject::_nil();
+      aMeshSO->FindSubObject(Tag_EdgeGroups , anObj);
+      if ( !anObj->_is_nil() )
+       {
+         SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj);
+         if (!hasGroup && it->More())
+           {
+             anInfo.append(QString("Groups:<br><br>"));
+             hasGroup = true;
+           }
+         for(; it->More(); it->Next()){
+           SALOMEDS::SObject_var subObj = it->Value();
+           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() );
+           if ( !aGroup->_is_nil() )
+             {
+               anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
+               anInfo.append(QString("%1<br>").arg("on edges"));
+               anInfo.append(QString("%1<br>").arg(aGroup->Size()));
+               // check if the group based on geometry
+               SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
+               if ( !aGroupOnGeom->_is_nil() )
+                 {
+                   GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
+                   QString aShapeName = "<unknown>";
+                   SALOMEDS::SObject_var aGeomObj, aRef;
+                   if ( subObj->FindSubObject( 1, aGeomObj ) &&  aGeomObj->ReferencedObject( aRef ))
+                     aShapeName = aRef->GetName();
+                   anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
+                 }
+               else
+                 anInfo.append(QString("<br>"));
+             }
+         }
+       }
+      
+      // info about groups on faces
+      anObj = SALOMEDS::SObject::_nil();
+      aMeshSO->FindSubObject(Tag_FaceGroups , anObj);
+      if ( !anObj->_is_nil() )
+       {
+         SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj);
+         if (!hasGroup && it->More())
+           {
+             anInfo.append(QString("Groups:<br><br>"));
+             hasGroup = true;
+           }
+         for(; it->More(); it->Next()){
+           SALOMEDS::SObject_var subObj = it->Value();
+           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() );
+           if ( !aGroup->_is_nil() )
+             {
+               anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
+               anInfo.append(QString("%1<br>").arg("on faces"));
+               anInfo.append(QString("%1<br>").arg(aGroup->Size()));
+               // check if the group based on geometry
+               SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
+               if ( !aGroupOnGeom->_is_nil() )
+                 {
+                   GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
+                   QString aShapeName = "<unknown>";
+                   SALOMEDS::SObject_var aGeomObj, aRef;
+                   if ( subObj->FindSubObject( 1, aGeomObj ) &&  aGeomObj->ReferencedObject( aRef ))
+                     aShapeName = aRef->GetName();
+                   anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
+                 }
+               else
+                 anInfo.append(QString("<br>"));
+             }
+         }
+       }
+      
+      // info about groups on volumes
+      anObj = SALOMEDS::SObject::_nil();
+      aMeshSO->FindSubObject(Tag_VolumeGroups , anObj);
+      if ( !anObj->_is_nil() )
+       {
+         SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(anObj);
+         if (!hasGroup && it->More())
+           anInfo.append(QString("Groups:<br>"));
+         for(; it->More(); it->Next()){
+           SALOMEDS::SObject_var subObj = it->Value();
+           SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( subObj->GetObject() );
+           if ( !aGroup->_is_nil() )
+             {
+               anInfo.append(QString("-   <b>%1</b><br>").arg(aGroup->GetName()));
+               anInfo.append(QString("%1<br>").arg("on volumes"));
+               anInfo.append(QString("%1<br>").arg(aGroup->Size()));
+               // check if the group based on geometry
+               SMESH::SMESH_GroupOnGeom_var aGroupOnGeom = SMESH::SMESH_GroupOnGeom::_narrow(aGroup);
+               if ( !aGroupOnGeom->_is_nil() )
+                 {
+                   GEOM::GEOM_Object_var aGroupMainShape = aGroupOnGeom->GetShape();
+                   QString aShapeName = "<unknown>";
+                   SALOMEDS::SObject_var aGeomObj, aRef;
+                   if ( subObj->FindSubObject( 1, aGeomObj ) &&  aGeomObj->ReferencedObject( aRef ))
+                     aShapeName = aRef->GetName();
+                   anInfo.append(QString("based on <i>%1</i> geometry object<br><br>").arg(aShapeName));
+                 }
+               else
+                 anInfo.append(QString("<br>"));
+             }
+         }
+       }
+      
+      myInfo->setText(anInfo);
+      return;
+    }
+  }
+  
+  return;
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection has changed
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::onSelectionChanged()
+{
+  if ( myStartSelection )
+    DumpMeshInfos();
+}
+
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::closeEvent( QCloseEvent* e )
+{
+  mySelection->ClearFilters();
+  SMESHGUI::GetSMESHGUI()->ResetState();
+  QDialog::closeEvent( e );
+}
+
+
+//=================================================================================
+// function : windowActivationChange()
+// purpose  : called when window is activated/deactivated
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::windowActivationChange( bool oldActive )
+{
+  QDialog::windowActivationChange( oldActive );
+  if ( isActiveWindow() && myIsActiveWindow != isActiveWindow() )
+    ActivateThisDialog() ;
+  myIsActiveWindow = isActiveWindow();
+}
+
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::DeactivateActiveDialog()
+{
+  disconnect( mySelection, 0, this, 0 );
+}
+
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate any active dialog */
+  SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog() ;
+  connect( mySelection, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) );
+}
+
+//=================================================================================
+// function : onStartSelection()
+// purpose  : starts selection
+//=================================================================================
+void SMESHGUI_StandardMeshInfosDlg::onStartSelection()
+{
+  myStartSelection = true;
+  mySelection->AddFilter( myMeshFilter ) ;
+  myMeshLine->setText( tr( "Select a mesh" ) );
+  onSelectionChanged();
+  myStartSelection = true;
+}
diff --git a/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h b/src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h
new file mode 100644 (file)
index 0000000..04abee9
--- /dev/null
@@ -0,0 +1,83 @@
+//  SMESH SMESHGUI : GUI for SMESH 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESHGUI_StandardMeshInfosDlg.h
+//  Author : Michael ZORIN
+//  Module : SMESH
+//  $Header: 
+
+#ifndef SMESHGUI_STANDARDMESHINFOSDLG_H
+#define SMESHGUI_STANDARDMESHINFOSDLG_H
+
+#include "SMESH_TypeFilter.hxx"
+
+// QT Includes
+#include <qdialog.h>
+
+class QGroupBox;
+class QLabel;
+class QPushButton;
+class QLineEdit;
+class QTextBrowser;
+class SALOME_Selection;
+
+class SMESHGUI_StandardMeshInfosDlg : public QDialog
+{ 
+    Q_OBJECT
+
+public:
+    SMESHGUI_StandardMeshInfosDlg( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+    ~SMESHGUI_StandardMeshInfosDlg();
+
+protected:
+    void closeEvent( QCloseEvent* e );
+    void windowActivationChange( bool oldActive );
+    void DumpMeshInfos();
+
+private slots:
+    void onSelectionChanged();
+    void DeactivateActiveDialog() ;
+    void ActivateThisDialog();
+    void onStartSelection();
+
+private:
+    SALOME_Selection*     mySelection; 
+    bool                  myStartSelection;
+    bool                  myIsActiveWindow;
+    
+    Handle(SMESH_TypeFilter)      myMeshFilter;
+
+    QLabel*       myNameLab;
+    QPushButton*  mySelectBtn;
+    QLineEdit*    myMeshLine;
+    
+    QTextBrowser* myInfo;
+    
+    QGroupBox*    myMeshGroup;
+    QGroupBox*    myInfoGroup;
+    
+    QGroupBox*    myButtonsGroup;
+    QPushButton*  myOkBtn;
+};
+
+#endif // SMESHGUI_STANDARDMESHINFOSDLG_H
index d073f81..31a92ef 100644 (file)
@@ -592,8 +592,11 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
   myMesh = SMESH::GetMeshByIO( mySelection->firstIObject() );
   if(myMesh->_is_nil())
     return;
+
   myActor = SMESH::FindActorByObject(myMesh);
   if (!myActor)
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor)
     return;
   
   int aNbUnits = 0;
index de761dd..641ec5c 100644 (file)
@@ -560,8 +560,11 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
   myMesh = SMESH::GetMeshByIO(IO);
   if(myMesh->_is_nil())
     return;
+  
   myActor = SMESH::FindActorByObject(myMesh);
   if (!myActor)
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor)
     return;
     
   int aNbUnits = 0;
index c1187f3..8a0a416 100644 (file)
@@ -722,6 +722,10 @@ msgstr "Rotation"
 msgid "SMESH_MESHINFO_TITLE"
 msgstr "Mesh Infos"
 
+#Standard Mesh Infos
+msgid "SMESH_STANDARD_MESHINFO_TITLE"
+msgstr "Standard Mesh Infos"
+
 #Mesh Infos
 msgid "SMESH_MESHINFO_NAME"
 msgstr "Name"
@@ -790,6 +794,10 @@ msgstr "Heterogenous"
 msgid "SMESH_BAD_SELECTION"
 msgstr "No valid selection"
 
+#Information :
+msgid "SMESH_INFORMATION"
+msgstr "Information"
+
 # --------- Create hypotheses/algorithms ---------
 
 msgid "SMESH_CREATE_HYPOTHESES"
@@ -1665,8 +1673,8 @@ msgstr "Number of digits after point"
 msgid "SMESHGUI_PrecisionDlg::NOT_USE"
 msgstr "Do not use"
 
-
-
+msgid "NON_SMESH_OBJECTS_SELECTED"
+msgstr "There are objects selected which do not belong to %1 component."
 
 
 
index a2b64c5..2517d10 100644 (file)
@@ -44,7 +44,8 @@ EXPORT_HEADERS= \
        SMESH_3D_Algo_i.hxx \
        SMESH_subMesh_i.hxx \
        SMESH_Mesh_i.hxx \
-       SMESH_Hypothesis_i.hxx
+       SMESH_Hypothesis_i.hxx \
+       SMESH.hxx
 
 EXPORT_PYSCRIPTS = smeshpy.py SMESH_test.py
 
diff --git a/src/SMESH_I/SMESH.hxx b/src/SMESH_I/SMESH.hxx
new file mode 100644 (file)
index 0000000..ea68b04
--- /dev/null
@@ -0,0 +1,56 @@
+//  SMESH SMESH_I :
+//
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH.hxx
+//  Author : Michael ZORIN
+//  Module : SMESH
+//  $Header: 
+
+#ifndef _SMESH_SMESH_HXX_
+#define _SMESH_SMESH_HXX_
+
+// Tags definition
+enum {
+  // Top level
+  Tag_HypothesisRoot         = 1, // hypotheses root
+  Tag_AlgorithmsRoot         = 2, // algorithms root
+  // Mesh/Submesh
+  Tag_RefOnShape             = 1, // references to shape
+  Tag_RefOnAppliedHypothesis = 2, // applied hypotheses root
+  Tag_RefOnAppliedAlgorithms = 3, // applied algorithms root
+  // Mesh only
+  Tag_SubMeshOnVertex        = 4, // sub-meshes roots by type
+  Tag_SubMeshOnEdge          = 5, // ...
+  Tag_SubMeshOnWire          = 6, // ...
+  Tag_SubMeshOnFace          = 7, // ...
+  Tag_SubMeshOnShell         = 8, // ...
+  Tag_SubMeshOnSolid         = 9, // ...
+  Tag_SubMeshOnCompound      = 10, // ...
+  Tag_NodeGroups             = 11, // Group roots by type
+  Tag_EdgeGroups             = 12, // ...
+  Tag_FaceGroups             = 13, // ...
+  Tag_VolumeGroups           = 14 // ... 
+};
+
+#endif
+
index dd9c389..4e50171 100644 (file)
@@ -33,6 +33,8 @@
 #include "SMESH_Algo_i.hxx"
 #include "SMESH_Group_i.hxx"
 
+#include "SMESH.hxx"
+
 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
 
 #include "utilities.h"
@@ -46,28 +48,6 @@ static int MYDEBUG = 0;
 static int MYDEBUG = 0;
 #endif
 
-// Tags definition ===========================================================
-// Top level
-long Tag_HypothesisRoot         = 1; // hypotheses root
-long Tag_AlgorithmsRoot         = 2; // algorithms root
-// Mesh/Submesh
-long Tag_RefOnShape             = 1; // references to shape
-long Tag_RefOnAppliedHypothesis = 2; // applied hypotheses root
-long Tag_RefOnAppliedAlgorithms = 3; // applied algorithms root
-// Mesh only
-long Tag_SubMeshOnVertex        = 4; // sub-meshes roots by type
-long Tag_SubMeshOnEdge          = 5; // ...
-long Tag_SubMeshOnWire          = 6; // ...
-long Tag_SubMeshOnFace          = 7; // ...
-long Tag_SubMeshOnShell         = 8; // ...
-long Tag_SubMeshOnSolid         = 9; // ...
-long Tag_SubMeshOnCompound      = 10; // ...
-long Tag_NodeGroups             = 11; // Group roots by type
-long Tag_EdgeGroups             = 12; // ...
-long Tag_FaceGroups             = 13; // ...
-long Tag_VolumeGroups           = 14; // ...
-// ===========================================================================
-
 //=============================================================================
 /*!
  *  Get...Tag [ static ]
index a5a8a52..e48a496 100644 (file)
@@ -57,13 +57,13 @@ public :
   SMESH_MEDFamily_i(int identifier, SMESH_subMesh_i* sm,
                    string name, string description, SALOME_MED::medEntityMesh entity );
   SMESH_MEDFamily_i(const SMESH_MEDFamily_i & f);
-
-        // IDL Methods
-        void setProtocol(SALOME::TypeOfCommunication typ) {}
-        void release() {}
-        SALOME::Sender_ptr getSenderForNumber(long int) {return SALOME::Sender::_nil();}
-        SALOME::Sender_ptr getSenderForNumberIndex() {return SALOME::Sender::_nil();}
-
+  
+  // IDL Methods
+  void setProtocol(SALOME::TypeOfCommunication typ) {}
+  void release() {}
+  SALOME::Sender_ptr getSenderForNumber(long int) {return SALOME::Sender::_nil();}
+  SALOME::Sender_ptr getSenderForNumberIndex() {return SALOME::Sender::_nil();}
+  
   CORBA::Long            getIdentifier()      
     throw (SALOME::SALOME_Exception);
   CORBA::Long            getNumberOfAttributes() 
index 1c9308e..e8e82f1 100644 (file)
@@ -74,12 +74,12 @@ class SMESH_MEDMesh_i:
        SMESH_MEDMesh_i(SMESH_Mesh_i * m);
        ~SMESH_MEDMesh_i();
 
-       // IDL Methods 
+       // IDL Methods
        void setProtocol(SALOME::TypeOfCommunication typ) {}
        void release() {}
        SALOME::Sender_ptr getSenderForCoordinates(long int) {return SALOME::Sender::_nil();}
        SALOME::Sender_ptr getSenderForConnectivity(long int, long int, long int, long int) {return SALOME::Sender::_nil();}
-
+       
        char *getName() throw(SALOME::SALOME_Exception);
        CORBA::Long getSpaceDimension() throw(SALOME::SALOME_Exception);
 
index 8cdfa30..c18cd7d 100644 (file)
@@ -252,7 +252,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  Reorient(anElementsId);
+  return Reorient(anElementsId);
 }
 
 //=============================================================================
@@ -298,7 +298,7 @@ CORBA::Boolean
                                       CORBA::Double               MaxAngle)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  TriToQuad(anElementsId, Criterion, MaxAngle);
+  return TriToQuad(anElementsId, Criterion, MaxAngle);
 }
 
 //=============================================================================
@@ -365,7 +365,7 @@ CORBA::Boolean
                                      CORBA::Boolean            Diag13)
 {
   SMESH::long_array_var anElementsId = theObject->GetIDs();
-  SplitQuad(anElementsId, Diag13);
+  return SplitQuad(anElementsId, Diag13);
 }
 
 //=============================================================================
index bf85736..c6c8c04 100644 (file)
@@ -74,6 +74,12 @@ EXPORT_PYSCRIPTS = libSMESH_Swig.py \
                   SMESH_controls.py \
                   SMESH_freebord.py \
                   SMESH_blocks.py \
+                  SMESH_BelongToGeom.py \
+                  SMESH_GroupFromGeom2.py \
+                  SMESH_box.py \
+                  SMESH_demo_hexa2_upd.py \
+                  SMESH_hexaedre.py \
+                  SMESH_Sphere.py \
                   SMESH_GroupFromGeom.py
 
 LIB_CLIENT_IDL = SALOMEDS.idl \
diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py
new file mode 100755 (executable)
index 0000000..37f333d
--- /dev/null
@@ -0,0 +1,53 @@
+#==============================================================================
+#  Info.
+#  Bug (from script, bug)   : SMESH_GroupFromGeom.py, PAL6945
+#  Modified                 : 25/11/2004
+#  Author                   : Kovaltchuk Alexey
+#  Project                  : PAL/SALOME
+#============================================================================== 
+from SMESH_test1 import *
+import SMESH
+
+# Compute the mesh created in SMESH_test1
+
+smesh.Compute(mesh, box)
+
+# Create geometry groups on plane:
+aGeomGroup1 = geompy.CreateGroup(face , geompy.ShapeType["FACE"])
+geompy.AddObject(aGeomGroup1, 1)
+
+aGeomGroup2 = geompy.CreateGroup(face , geompy.ShapeType["EDGE"])
+
+geompy.AddObject(aGeomGroup2, 3)
+geompy.AddObject(aGeomGroup2, 6)
+geompy.AddObject(aGeomGroup2, 8)
+geompy.AddObject(aGeomGroup2, 10)
+
+geompy.addToStudy(aGeomGroup1, "Group on Faces")
+geompy.addToStudy(aGeomGroup2, "Group on Edges")
+
+aSmeshGroup1 = mesh.CreateGroupFromGEOM(SMESH.FACE, "SMESHGroup1", aGeomGroup1)
+aSmeshGroup2 = mesh.CreateGroupFromGEOM(SMESH.EDGE, "SMESHGroup2", aGeomGroup2)
+
+print "Create aGroupOnShell - a group linked to a shell"
+aGroupOnShell = mesh.CreateGroupFromGEOM(SMESH.EDGE, "GroupOnShell", shell)
+print "aGroupOnShell type =", aGroupOnShell.GetType()
+print "aGroupOnShell size =", aGroupOnShell.Size()
+print "aGroupOnShell ids :", aGroupOnShell.GetListOfID()
+
+print " "
+
+print "Modify <LocalLength> hypothesis: 100 -> 50"
+hypLen1.SetLength(50)
+print "Contents of aGroupOnShell changes:"
+print "aGroupOnShell size =", aGroupOnShell.Size()
+print "aGroupOnShell ids :", aGroupOnShell.GetListOfID()
+
+print " "
+
+print "Re-compute mesh, contents of aGroupOnShell changes again:"
+smesh.Compute(mesh, box)
+print "aGroupOnShell size =", aGroupOnShell.Size()
+print "aGroupOnShell ids :", aGroupOnShell.GetListOfID()
+
+salome.sg.updateObjBrowser(1);
diff --git a/src/SMESH_SWIG/SMESH_Sphere.py b/src/SMESH_SWIG/SMESH_Sphere.py
new file mode 100644 (file)
index 0000000..9c6bc42
--- /dev/null
@@ -0,0 +1,107 @@
+#  GEOM GEOM_SWIG : binding of C++ omplementaion with Python
+#
+#  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : GEOM_Sphere.py
+#  Author : Damien COQUERET, Open CASCADE
+#  Module : GEOM
+#  $Header: 
+
+from geompy import *
+from math import *
+
+from meshpy import *
+
+# It is an example of creating a hexahedrical mesh on a sphere.
+#
+# Used approach allows to avoid problems with degenerated and
+# seam edges without special processing of geometrical shapes
+
+#-----------------------------------------------------------------------
+#Variables
+Radius  = 100.
+Dist    = Radius / 2.
+Factor  = 2.5
+Angle90 = pi / 2.
+NbSeg   = 10
+
+PointsList = []
+ShapesList = []
+
+#Basic Elements
+P0 = MakeVertex(0., 0., 0.)
+P1 = MakeVertex(-Dist, -Dist, -Dist)
+P2 = MakeVertex(-Dist, -Dist, Dist)
+P3 = MakeVertex(-Dist, Dist, Dist)
+P4 = MakeVertex(-Dist, Dist, -Dist)
+
+VZ = MakeVectorDXDYDZ(0., 0., 1.)
+
+#Construction Elements
+PointsList.append(P1)
+PointsList.append(P2)
+PointsList.append(P3)
+PointsList.append(P4)
+PointsList.append(P1)
+
+PolyLine = MakePolyline(PointsList)
+
+Face1 = MakeFace(PolyLine, 1)
+Face2 = MakeScaleTransform(Face1, P0, Factor)
+Face3 = MakeScaleTransform(Face1, P0, -1.)
+
+#Models
+Sphere = MakeSphereR(Radius)
+
+Block = MakeHexa2Faces(Face1, Face2)
+Cube  = MakeHexa2Faces(Face1, Face3)
+
+Common1 = MakeBoolean(Sphere, Block, 1)
+Common2 = MakeRotation(Common1, VZ, Angle90)
+
+MultiBlock1 = MakeMultiTransformation1D(Common1, 21, -1, 3)
+MultiBlock2 = MakeMultiTransformation1D(Common2, 31, -1, 3)
+
+#Reconstruct sphere from several blocks
+ShapesList.append(Cube)
+ShapesList.append(MultiBlock1)
+ShapesList.append(MultiBlock2)
+Compound = MakeCompound(ShapesList)
+
+Result = MakeGlueFaces(Compound, 0.1)
+
+#addToStudy
+Id_Sphere      = addToStudy(Sphere, "Sphere")
+Id_Cube        = addToStudy(Cube, "Cube")
+
+Id_Common1     = addToStudy(Common1, "Common1")
+Id_Common2     = addToStudy(Common2, "Common2")
+
+Id_MultiBlock1 = addToStudy(MultiBlock1, "MultiBlock1")
+Id_MultiBlock2 = addToStudy(MultiBlock2, "MultiBlock2")
+
+Id_Result      = addToStudy(Result, "Result")
+
+#-----------------------------------------------------------------------
+#Meshing
+my_hexa = MeshHexa(Result, NbSeg, "Sphere_Mesh")
+my_hexa.Compute()
diff --git a/src/SMESH_SWIG/SMESH_box.py b/src/SMESH_SWIG/SMESH_box.py
new file mode 100755 (executable)
index 0000000..2902c73
--- /dev/null
@@ -0,0 +1,73 @@
+#==============================================================================
+#  Info.
+#  Bug (from script, bug)   : box.py, PAL5223
+#  Modified                 : 25/11/2004
+#  Author                   : Kovaltchuk Alexey
+#  Project                  : PAL/SALOME
+#==============================================================================
+#
+# Salome geometry and meshing for a box
+#
+import salome
+from salome import sg
+import geompy
+
+import StdMeshers
+
+# ---- launch GEOM
+
+geom          = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+meshgenerator = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+###geom.GetCurrentStudy(salome.myStudy._get_StudyId())
+meshgenerator.SetCurrentStudy(salome.myStudy)
+
+# Plate
+
+box    = geompy.MakeBox(0.,0.,0.,1.,1.,1.)
+boxId  = geompy.addToStudy(box,"box")
+
+# ---- launch SMESH
+
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId)
+# meshgenerator=smeshpy.smeshpy()
+
+
+# Hypothesis
+
+hypL1=meshgenerator.CreateHypothesis("LocalLength","libStdMeshersEngine.so")
+hypL1.SetLength(0.25)
+hypL1Id = salome.ObjectToID(hypL1) 
+smeshgui.SetName(hypL1Id, "LocalLength")
+
+# Algorithm
+
+alg1D=meshgenerator.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+alg1DId = salome.ObjectToID(alg1D) 
+smeshgui.SetName(alg1DId, "algo1D")
+
+alg2D=meshgenerator.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so")
+alg2DId = salome.ObjectToID(alg2D) 
+smeshgui.SetName(alg2DId, "algo2D")
+
+alg3D=meshgenerator.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so")
+alg3DId = salome.ObjectToID(alg3D) 
+smeshgui.SetName(alg3DId, "algo3D")
+# ---- init a Mesh
+
+box_mesh=meshgenerator.CreateMesh(box)
+box_meshId = salome.ObjectToID(box_mesh)
+smeshgui.SetName(box_meshId, "box_mesh")
+
+# ---- set Hypothesis & Algorithm
+
+box_mesh.AddHypothesis(box,alg1D)
+box_mesh.AddHypothesis(box,alg2D)
+box_mesh.AddHypothesis(box,alg3D)
+box_mesh.AddHypothesis(box,hypL1)
+
+meshgenerator.Compute(box_mesh,box)
+
+sg.updateObjBrowser(1)
diff --git a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py
new file mode 100755 (executable)
index 0000000..755214a
--- /dev/null
@@ -0,0 +1,210 @@
+#==============================================================================
+#  Info.
+#  Bug (from script, bug)   : SMESH_demo_hexa2_upd.py, PAL6781
+#  Modified                 : 25/11/2004
+#  Author                   : Kovaltchuk Alexey
+#  Project                  : PAL/SALOME
+#==============================================================================
+# Tetrahedrization of a geometry (box minus a inner cylinder).
+# Hypothesis and algorithms for the mesh generation are not global:
+# the mesh of some edges is thinner
+#
+
+import salome
+import geompy
+
+import StdMeshers
+import NETGENPlugin
+
+geom  = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+
+smeshgui = salome.ImportComponentGUI("SMESH")
+smeshgui.Init(salome.myStudyId);
+
+import math
+
+# -----------------------------------------------------------------------------
+
+ShapeTypeShell     = 3
+ShapeTypeFace      = 4
+ShapeTypeEdge      = 6
+
+a = math.sqrt(2.)/4.
+ma = - a
+zero = 0.
+un = 1.
+mun= - un
+demi = 1./2.
+
+Orig = geompy.MakeVertex(zero,zero,zero)
+P0 = geompy.MakeVertex(a,a,zero)
+P1 = geompy.MakeVertex(zero,demi,zero)
+P2 = geompy.MakeVertex(ma,a,zero)
+P3 = geompy.MakeVertex(mun,un,zero)
+P4 = geompy.MakeVertex(un,un,zero)
+P5 = geompy.MakeVertex(zero,zero,un)
+
+arc = geompy.MakeArc(P0,P1,P2)
+e1 = geompy.MakeEdge(P2,P3)
+e2 = geompy.MakeEdge(P3,P4)
+e3 = geompy.MakeEdge(P4,P0)
+
+list = []
+list.append(arc)
+list.append(e1)
+list.append(e2)
+list.append(e3)
+
+wire = geompy.MakeWire(list)
+face = geompy.MakeFace(wire,1)
+
+dir = geompy.MakeVector(Orig,P5)
+vol1 = geompy.MakePipe(face,dir)
+
+angle = math.pi/2.
+#dir = geom.MakeVector(Orig,P5)
+vol2 = geompy.MakeRotation(vol1,dir,angle)
+
+vol3 = geompy.MakeRotation(vol2,dir,angle)
+
+vol4 = geompy.MakeRotation(vol3,dir,angle)
+
+list = []
+list.append(vol1)
+list.append(vol2)
+list.append(vol3)
+list.append(vol4)
+
+volComp = geompy.MakeCompound(list)
+
+tol3d = 1.e-3
+vol = geompy.MakeGlueFaces(volComp,tol3d)
+idVol = geompy.addToStudy(vol,"volume")
+
+print "Analysis of the final volume:"
+subShellList = geompy.SubShapeAllSorted(vol,ShapeTypeShell)
+subFaceList = geompy.SubShapeAllSorted(vol,ShapeTypeFace)
+subEdgeList = geompy.SubShapeAllSorted(vol,ShapeTypeEdge)
+
+print "number of Shells in the volume : ",len(subShellList)
+print "number of Faces in the volume : ",len(subFaceList)
+print "number of Edges in the volume : ",len(subEdgeList)
+
+idSubEdge = []
+for k in range(len(subEdgeList)):
+    idSubEdge.append(geompy.addToStudyInFather(vol,subEdgeList[k],"SubEdge"+str(k)))
+
+edgeZ = []
+edgeZ.append(subEdgeList[0])
+edgeZ.append(subEdgeList[3])
+edgeZ.append(subEdgeList[10])
+edgeZ.append(subEdgeList[11])
+edgeZ.append(subEdgeList[20])
+edgeZ.append(subEdgeList[21])
+edgeZ.append(subEdgeList[28])
+edgeZ.append(subEdgeList[31])
+
+idEdgeZ = []
+for i in range(8):
+    idEdgeZ.append(geompy.addToStudyInFather(vol,edgeZ[i],"EdgeZ"+str(i+1)))
+
+### ---------------------------- SMESH --------------------------------------
+
+# ---- create Hypothesis
+
+print "-------------------------- create Hypothesis"
+
+print "-------------------------- NumberOfSegments the global one"
+
+numberOfSegments = 10
+
+hypNbSeg=smesh.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so")
+hypNbSeg.SetNumberOfSegments(numberOfSegments)
+hypNbSegID = hypNbSeg.GetId()
+print hypNbSeg.GetName()
+print hypNbSegID
+print hypNbSeg.GetNumberOfSegments()
+
+smeshgui.SetName(salome.ObjectToID(hypNbSeg), "NumberOfSegments")
+
+print "-------------------------- NumberOfSegments in the Z direction"
+
+numberOfSegmentsZ = 40
+
+hypNbSegZ=smesh.CreateHypothesis("NumberOfSegments","libStdMeshersEngine.so")
+hypNbSegZ.SetNumberOfSegments(numberOfSegmentsZ)
+hypNbSegZID = hypNbSegZ.GetId()
+print hypNbSegZ.GetName()
+print hypNbSegZID
+print hypNbSegZ.GetNumberOfSegments()
+
+smeshgui.SetName(salome.ObjectToID(hypNbSegZ), "NumberOfSegmentsZ")
+
+# ---- create Algorithms
+
+print "-------------------------- create Algorithms"
+
+print "-------------------------- Regular_1D"
+
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(regular1D), "Wire Discretisation")
+
+print "-------------------------- Quadrangle_2D"
+
+quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(quad2D), "Quadrangle_2D")
+
+print "-------------------------- Hexa_3D"
+
+hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so")
+smeshgui.SetName(salome.ObjectToID(hexa3D), "Hexa_3D")
+
+# ---- init a Mesh with the volume
+
+mesh = smesh.CreateMesh(vol)
+smeshgui.SetName(salome.ObjectToID(mesh), "meshVolume")
+
+# ---- add hypothesis to the volume
+
+print "-------------------------- add hypothesis to the volume"
+
+ret=mesh.AddHypothesis(vol,regular1D)
+print ret
+ret=mesh.AddHypothesis(vol,hypNbSeg)
+print ret
+ret=mesh.AddHypothesis(vol,quad2D)
+print ret
+ret=mesh.AddHypothesis(vol,hexa3D)
+print ret
+
+for i in range(8):
+    print "-------------------------- add hypothesis to edge in the Z directions", (i+1)
+
+    subMeshEdgeZ = mesh.GetSubMesh(edgeZ[i],"SubMeshEdgeZ_"+str(i+1))
+
+    retZ = mesh.AddHypothesis(edgeZ[i],hypNbSegZ)
+    print " add hyp Z ", retZ
+
+salome.sg.updateObjBrowser(1)
+
+print "-------------------------- compute the mesh of the volume"
+
+ret=smesh.Compute(mesh,vol)
+
+print ret
+if ret != 0:
+##    log=mesh.GetLog(0) # no erase trace
+##    for linelog in log:
+##        print linelog
+    print "Information about the MeshBox :"
+    print "Number of nodes       : ", mesh.NbNodes()
+    print "Number of edges       : ", mesh.NbEdges()
+    print "Number of faces       : ", mesh.NbFaces()
+    print "Number of triangles   : ", mesh.NbTriangles()
+    print "Number of volumes     : ", mesh.NbVolumes()
+    print "Number of tetrahedrons: ", mesh.NbTetras()
+else:
+    print "problem when Computing the mesh"
+
+salome.sg.updateObjBrowser(1)
diff --git a/src/SMESH_SWIG/SMESH_hexaedre.py b/src/SMESH_SWIG/SMESH_hexaedre.py
new file mode 100755 (executable)
index 0000000..1b93e1c
--- /dev/null
@@ -0,0 +1,148 @@
+#==============================================================================
+#  Info.
+#  Bug (from script, bug)   : hexaedre_modified.py, PAL6194, PAL7153
+#  Modified                 : 25/11/2004
+#  Author                   : Kovaltchuk Alexey
+#  Project                  : PAL/SALOME
+#==============================================================================
+
+import salome
+from salome import sg
+
+import geompy
+
+import math
+
+# -----------------------------------------------------------------------------
+
+geom = salome.lcc.FindOrLoadComponent("FactoryServer", "GEOM")
+myBuilder = salome.myStudy.NewBuilder()
+gg = salome.ImportComponentGUI("GEOM")
+from salome import sg
+
+ShapeTypeCompSolid = 1
+ShapeTypeSolid     = 2
+ShapeTypeShell     = 3
+ShapeTypeFace      = 4
+ShapeTypeWire      = 5
+ShapeTypeEdge      = 6
+ShapeTypeVertex    = 7
+
+Boolop_common = 1
+Boolop_cut = 2
+Boolop_fuse = 3
+Boolop_section = 4
+
+p0 = geompy.MakeVertex(0., 0., 0.)
+px = geompy.MakeVertex(100., 0., 0.)
+py = geompy.MakeVertex(0., 100., 0.)
+pz = geompy.MakeVertex(0., 0., 100.)
+vx = geompy.MakeVector(p0, px)
+vy = geompy.MakeVector(p0, py)
+vz = geompy.MakeVector(p0, pz)
+
+sphereExt = geompy.MakeSphere(    0.,  0.,  0., 400.)
+sphereInt = geompy.MakeSphere(    0.,-50.,  0., 350.)
+sphereA   = geompy.MakeSphere( -400., 50., 50., 400.)
+sphereB   = geompy.MakeSphere(  350.,-50.,-50., 350.)
+ptcyle    = geompy.MakeVertex(0., -300., -450.)
+cylindre  = geompy.MakeCylinder(ptcyle,vz,500.,900.)
+
+vol1=geompy.MakeCut(sphereExt,sphereA)
+vol2=geompy.MakeCut(vol1,sphereB)
+vol3=geompy.MakeCut(vol2,cylindre)
+blob=geompy.MakeCut(vol3,sphereInt)
+
+idblob = geompy.addToStudy(blob,"blob")
+
+aretes = []
+aretes = geompy.SubShapeAllSorted(blob, ShapeTypeEdge)
+eid=0
+
+# -------------------------------
+# --- numerotation des aretes
+##for edge in aretes:
+##    edname="arete%d"%eid
+##    idedge=geompy.addToStudy(edge,edname)
+##    eid=eid+1
+
+salome.sg.updateObjBrowser(1)
+
+# --- epaisseur 0 2 8 10
+# --- hauteur   1 3 9 11
+# --- largeur   4 5 6 7
+
+# -----------------------------------------------------------------------------
+
+print "-------------------------- mesh"
+
+import SMESH
+import StdMeshers
+smesh = salome.lcc.FindOrLoadComponent("FactoryServer", "SMESH")
+smesh.SetCurrentStudy(salome.myStudy)
+
+# ---- create Hypothesis
+print "-------------------------- create Hypothesis"
+numberOfSegments = 4
+hypNbSegA=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hypNbSegA.SetNumberOfSegments(numberOfSegments)
+numberOfSegments = 10
+hypNbSegB=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hypNbSegB.SetNumberOfSegments(numberOfSegments)
+numberOfSegments = 15
+hypNbSegC=smesh.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hypNbSegC.SetNumberOfSegments(numberOfSegments)
+
+# ---- create Algorithms
+print "-------------------------- create Algorithms"
+regular1D=smesh.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+quad2D=smesh.CreateHypothesis("Quadrangle_2D", "libStdMeshersEngine.so")
+hexa3D=smesh.CreateHypothesis("Hexa_3D", "libStdMeshersEngine.so")
+
+# ---- init a Mesh with the geom shape
+shape_mesh = blob
+myMesh=smesh.CreateMesh(shape_mesh)
+
+# ---- add hypothesis and algorithms to mesh
+print "-------------------------- add hypothesis to mesh"
+myMesh.AddHypothesis(shape_mesh,regular1D)
+myMesh.AddHypothesis(shape_mesh,quad2D)
+myMesh.AddHypothesis(shape_mesh,hexa3D)
+
+#myMesh.AddHypothesis(shape_mesh,hypNbSeg)
+
+myMesh.AddHypothesis(aretes[0],hypNbSegA)
+myMesh.AddHypothesis(aretes[2],hypNbSegA)
+myMesh.AddHypothesis(aretes[8],hypNbSegA)
+myMesh.AddHypothesis(aretes[10],hypNbSegA)
+
+myMesh.AddHypothesis(aretes[1],hypNbSegC)
+myMesh.AddHypothesis(aretes[3],hypNbSegC)
+myMesh.AddHypothesis(aretes[9],hypNbSegC)
+myMesh.AddHypothesis(aretes[11],hypNbSegC)
+
+myMesh.AddHypothesis(aretes[4],hypNbSegB)
+myMesh.AddHypothesis(aretes[5],hypNbSegB)
+myMesh.AddHypothesis(aretes[6],hypNbSegB)
+myMesh.AddHypothesis(aretes[7],hypNbSegB)
+
+# ---- compute mesh
+
+print "-------------------------- compute mesh"
+ret=smesh.Compute(myMesh, shape_mesh)
+print ret
+if ret != 0:
+    #log=myMesh.GetLog(0) # no erase trace
+    #for linelog in log:
+    #    print linelog
+    print "Information about the Mesh:"
+    print "Number of nodes       : ", myMesh.NbNodes()
+    print "Number of edges       : ", myMesh.NbEdges()
+    print "Number of faces       : ", myMesh.NbFaces()
+    print "Number of quadrangles : ", myMesh.NbQuadrangles()
+    print "Number of volumes     : ", myMesh.NbVolumes()
+    print "Number of hexahedrons : ", myMesh.NbHexas()
+else:
+    print "problem when Computing the mesh"
+
+salome.sg.updateObjBrowser(1)
index 757a6fe..effc62d 100644 (file)
@@ -10,6 +10,8 @@ import salome
 
 import StdMeshers
 
+import SMESH
+
 # Variables
 # ---------
 
@@ -98,4 +100,27 @@ class MeshHexaImpl:
         smesh.Compute(self.mesh, self.piece)
         salome.sg.updateObjBrowser(1)
 
+    # Creates mesh group based on a geometric group
+    # --------------------
+
+    def Group(self, grp, name=""):
+        if name == "":
+            name = grp.GetName()
+        tgeo = geompy.GroupOp.GetType(grp)
+        if tgeo == geompy.ShapeType["VERTEX"]:
+            type = SMESH.NODE
+        elif tgeo == geompy.ShapeType["EDGE"]:
+            type = SMESH.EDGE
+        elif tgeo == geompy.ShapeType["FACE"]:
+            type = SMESH.FACE
+        elif tgeo == geompy.ShapeType["SOLID"]:
+            type = SMESH.VOLUME
+        return self.mesh.CreateGroupFromGEOM(type, name, grp)
+
+    # Export mesh in a MED file
+    # --------------------
+
+    def ExportMED(self, filename, groups=1):
+        self.mesh.ExportMED(filename, groups)
+
 MeshHexa = MeshHexaImpl
index 92e94c1..caa8333 100644 (file)
@@ -70,6 +70,7 @@ LIB_SRC = \
        StdMeshers_Regular_1D.cxx \
        StdMeshers_Quadrangle_2D.cxx \
        StdMeshers_MEFISTO_2D.cxx \
+       StdMeshers_Penta_3D.cxx \
        StdMeshers_Hexa_3D.cxx
 
 LIB_SERVER_IDL = 
@@ -82,8 +83,8 @@ BIN_SRC =
 
 # additionnal information to compil and link file
 CPPFLAGS+= $(OCC_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome $(BOOST_CPPFLAGS)
-CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome
+CXXFLAGS+= $(OCC_CXXFLAGS) -I${KERNEL_ROOT_DIR}/include/salome -I${GEOM_ROOT_DIR}/include/salome
 
-LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome
+LDFLAGS+= -lSMESHimpl -lMEFISTO2D -L${KERNEL_ROOT_DIR}/lib/salome -L${GEOM_ROOT_DIR}/lib/salome
 
 @CONCLUDE@
index 580c48e..f80cd53 100644 (file)
@@ -55,6 +55,11 @@ using namespace std;
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
 
+//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f
+#include <StdMeshers_Penta_3D.hxx>
+
+static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t
 
 //=============================================================================
 /*!
@@ -155,15 +160,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 {
   Unexpect aCatch(SalomeException);
        MESSAGE("StdMeshers_Hexa_3D::Compute");
-
-       bool isOk = false;
+       //bool isOk = false;
        SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-       SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+       //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
        //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
 
        // 0.  - shape and face mesh verification
        // 0.1 - shape must be a solid (or a shell) with 6 faces
-       //MESSAGE("---");
+       MESSAGE("---");
 
        vector < SMESH_subMesh * >meshFaces;
        for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
@@ -184,40 +188,56 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
        for (int i = 0; i < 6; i++)
        {
-               TopoDS_Shape aShape = meshFaces[i]->GetSubShape();
-               SMESH_Algo *algo = _gen->GetAlgo(aMesh, aShape);
-               string algoName = algo->GetName();
-               if (algoName != "Quadrangle_2D")
-               {
-                       // *** delete _quads
-                       SCRUTE(algoName);
-//                     ASSERT(0);
-                       return false;
-               }
-               StdMeshers_Quadrangle_2D *quadAlgo =
-                       dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
-               ASSERT(quadAlgo);
-               try
-               {
-                       _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aShape);
-                       // *** to delete after usage
-               }
-               catch(SALOME_Exception & S_ex)
-               {
-                       // *** delete _quads
-                       // *** throw exception
-//                     ASSERT(0);
-                        return false;
-               }
-
-                // 0.2.1 - number of points on the opposite edges must be the same
-                if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
-                    _quads[i]->nbPts[1] != _quads[i]->nbPts[3])
-                {
-                  MESSAGE("different number of points on the opposite edges of face " << i);
-//                  ASSERT(0);
-                  return false;
-                }
+         TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+         SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+         string algoName = algo->GetName();
+          bool isAllQuad = false;
+         if (algoName == "Quadrangle_2D") {
+            SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
+            if ( sm ) {
+              isAllQuad = true;
+              SMDS_ElemIteratorPtr eIt = sm->GetElements();
+              while ( isAllQuad && eIt->more() )
+                isAllQuad = ( eIt->next()->NbNodes() == 4 );
+            }
+          }
+          if ( ! isAllQuad ) {
+           //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
+            bool bIsOk;
+            //
+            bIsOk=ComputePentahedralMesh(aMesh, aShape);
+            if (bIsOk) {
+              return true;
+            }
+           //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t
+           SCRUTE(algoName);
+           //                  ASSERT(0);
+           return false;
+         }
+         StdMeshers_Quadrangle_2D *quadAlgo =
+           dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
+         ASSERT(quadAlgo);
+         try
+           {
+             _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace);
+             // *** to delete after usage
+           }
+         catch(SALOME_Exception & S_ex)
+           {
+             // *** delete _quads
+             // *** throw exception
+             //                        ASSERT(0);
+             return false;
+           }
+
+         // 0.2.1 - number of points on the opposite edges must be the same
+         if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
+             _quads[i]->nbPts[1] != _quads[i]->nbPts[3])
+           {
+             MESSAGE("different number of points on the opposite edges of face " << i);
+             //                  ASSERT(0);
+             return false;
+           }
        }
 
        // 1.  - identify faces and vertices of the "cube"
@@ -1023,3 +1043,35 @@ istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
 {
   return hyp.LoadFrom( load );
 }
+
+//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f
+///////////////////////////////////////////////////////////////////////////////
+//ZZ
+//#include <stdio.h>
+
+//=======================================================================
+//function : ComputePentahedralMesh
+//purpose  : 
+//=======================================================================
+bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aShape)
+{
+  //printf(" ComputePentahedralMesh HERE\n");
+  //
+  bool bOK;
+  int iErr;
+  StdMeshers_Penta_3D anAlgo;
+  //
+  bOK=anAlgo.Compute(aMesh, aShape);
+  /*
+  iErr=anAlgo.ErrorStatus();
+  
+  if (iErr) {
+    printf("  *** Error# %d\n", iErr);
+  }
+  else {
+    printf("  *** No errors# %d\n", iErr);
+  }
+  */
+  return bOK;
+}
+
diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx
new file mode 100644 (file)
index 0000000..30362f4
--- /dev/null
@@ -0,0 +1,1106 @@
+//  SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions
+//
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Penta_3D.cxx
+//  Module : SMESH
+
+using namespace std;
+
+#include <StdMeshers_Penta_3D.hxx>
+
+#include <stdio.h>
+
+#include <algorithm>
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopExp.hxx>
+#include <SMESH_Mesh.hxx>
+#include <SMESH_subMesh.hxx>
+#include <SMESHDS_SubMesh.hxx>
+
+#include <SMDS_MeshElement.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <gp_Pnt.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Shell.hxx>
+
+typedef map < int, int, less<int> >::iterator   \
+  StdMeshers_IteratorOfDataMapOfIntegerInteger;
+
+//=======================================================================
+//
+//           StdMeshers_Penta_3D 
+//
+//=======================================================================
+//function : StdMeshers_Penta_3D
+//purpose  : 
+//=======================================================================
+StdMeshers_Penta_3D::StdMeshers_Penta_3D()
+: myErrorStatus(1)
+{
+  myTol3D=0.1;
+}
+//=======================================================================
+//function : Compute
+//purpose  : 
+//=======================================================================
+bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, 
+                                 const TopoDS_Shape& aShape)
+{
+  myErrorStatus=0;
+  //
+  bool bOK=false;
+  //
+  myShape=aShape;
+  SetMesh(aMesh);
+  //
+  CheckData();
+  if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeBlock();
+    if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeNodes();
+  if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeConnectingMap();
+  //
+  ClearMeshOnFxy1();
+  if (myErrorStatus) {
+    return bOK;
+  }
+  //
+  MakeMeshOnFxy1();
+  if (myErrorStatus) {
+    return bOK;
+  }
+  //
+  MakeVolumeMesh();
+  //
+  return !bOK;
+}
+//=======================================================================
+//function : MakeNodes
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeNodes()
+{
+  myErrorStatus=0;
+  //
+  const int aNbSIDs=9;
+  int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
+  double aX, aY, aZ;
+  SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={
+    SMESH_Block::ID_V000, SMESH_Block::ID_V100, 
+    SMESH_Block::ID_V110, SMESH_Block::ID_V010,
+    SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0, 
+    SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0,
+    SMESH_Block::ID_Fxy0
+  }; 
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  // 1. Define the sizes of mesh
+  //
+  // 1.1 Horizontal size
+  myJSize=0;
+  for (i=0; i<aNbSIDs; ++i) {
+    const TopoDS_Shape& aS=myBlock.Shape(aSIDs[i]);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    iNbN=aSM->NbNodes();
+    myJSize+=iNbN;
+  }
+  //printf("***  Horizontal: number of nodes summary=%d\n", myJSize);
+  //
+  // 1.2 Vertical size
+  myISize=2;
+  {
+    const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    iNbN=aSM->NbNodes();
+    myISize+=iNbN;
+  }
+  //printf("***  Vertical: number of nodes on edges and vertices=%d\n", myISize);
+  //
+  aSize=myISize*myJSize;
+  myTNodes.resize(aSize);
+  //
+  StdMeshers_TNode aTNode;
+  gp_XYZ aCoords;
+  gp_Pnt aP3D;
+  //
+  // 2. Fill the repers on base face (Z=0)
+  i=0; j=0;
+  // vertices
+  for (k=0; k<aNbSIDs; ++k) {
+    aSID=aSIDs[k];
+    const TopoDS_Shape& aS=myBlock.Shape(aSID);
+    SMDS_NodeIteratorPtr ite =pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+    while(ite->more()) {
+      const SMDS_MeshNode* aNode = ite->next();
+      aNodeID=aNode->GetID();
+      //
+      aTNode.SetNode(aNode);
+      aTNode.SetShapeSupportID(aSID);
+      aTNode.SetBaseNodeID(aNodeID);
+      //
+      switch (aSID){
+        case SMESH_Block::ID_V000:
+         aCoords.SetCoord(0., 0., 0.);
+         break;
+       case SMESH_Block::ID_V100:
+         aCoords.SetCoord(1., 0., 0.);
+         break; 
+       case SMESH_Block::ID_V110:
+         aCoords.SetCoord(1., 1., 0.);
+         break; 
+       case SMESH_Block::ID_V010:
+         aCoords.SetCoord(0., 1., 0.);
+         break;
+       case SMESH_Block::ID_Ex00:  
+       case SMESH_Block::ID_E1y0:
+       case SMESH_Block::ID_Ex10:
+       case SMESH_Block::ID_E0y0:
+       case SMESH_Block::ID_Fxy0:{
+         aX=aNode->X();
+         aY=aNode->Y();
+         aZ=aNode->Z();
+         aP3D.SetCoord(aX, aY, aZ);
+         myBlock.ComputeParameters(aP3D, aS, aCoords);
+         iErr=myBlock.ErrorStatus();
+         if (iErr) {
+            MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
+                    "SMESHBlock: ComputeParameters operation failed");
+           myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+           return;
+         }
+       }
+         break;
+       default:
+         break;
+      }
+      aTNode.SetNormCoord(aCoords);
+      ij=i*myJSize+j;
+      myTNodes[ij]=aTNode;
+      ++j;
+    }
+  }
+  /*
+  //DEB
+  {
+    int iShapeSupportID, iBaseNodeID;
+    //
+    //printf("\n\n*** Base Face\n");
+    i=0;
+    for (j=0; j<myJSize; ++j) {
+      ij=i*myJSize+j;
+      const StdMeshers_TNode& aTNode=myTNodes[ij];
+      iShapeSupportID=aTNode.ShapeSupportID();
+      iBaseNodeID=aTNode.BaseNodeID();
+      const gp_XYZ& aXYZ=aTNode.NormCoord();
+      printf("*** j:%d bID#%d iSS:%d { %lf %lf %lf }\n",
+            j,  iBaseNodeID, iShapeSupportID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z());
+    }
+  }
+  */
+  //DEB
+  //return; //zz
+  //
+  // 3. Finding of Z-layers
+  vector<double> aZL(myISize);
+  vector<double>::iterator aItZL1, aItZL2 ;
+  //
+  const TopoDS_Shape& aE00z=myBlock.Shape(SMESH_Block::ID_E00z);
+  SMDS_NodeIteratorPtr aItaE00z =
+    pMesh->GetSubMeshContaining(aE00z)->GetSubMeshDS()->GetNodes();
+  //
+  aZL[0]=0.;
+  i=1;
+  while (aItaE00z->more()) {
+    const SMDS_MeshNode* aNode=aItaE00z->next();
+    aX=aNode->X(); aY=aNode->Y(); aZ=aNode->Z();
+    aP3D.SetCoord(aX, aY, aZ);
+    myBlock.ComputeParameters(aP3D, aE00z, aCoords);
+    iErr=myBlock.ErrorStatus();
+    if (iErr) {
+      MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
+              "SMESHBlock: ComputeParameters operation failed");
+      myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+      return;
+    }
+    aZL[i]=aCoords.Z();
+    ++i;
+  }
+  aZL[i]=1.;
+  //
+  aItZL1=aZL.begin();
+  aItZL2=aZL.end();
+  //
+  // Sorting the layers
+  sort(aItZL1, aItZL2);
+  //DEB
+  /*
+  printf("** \n\n Layers begin\n");
+  for(i=0, aItZL=aItZL1; aItZL!=aItZL2; ++aItZL, ++i) {
+    printf(" #%d : %lf\n", i, *aItZL);
+  } 
+  printf("** Layers end\n");
+  */
+  //DEB
+  //
+  //
+  // 4. Fill the rest repers
+  bool bIsUpperLayer;
+  int iBNID;
+  SMESH_Block::TShapeID aSSID, aBNSSID;
+  StdMeshers_TNode aTN;
+  //
+  for (j=0; j<myJSize; ++j) {
+    for (i=1; i<myISize; ++i) {
+      //
+      // base node info
+      const StdMeshers_TNode& aBN=myTNodes[j];
+      aBNSSID=(SMESH_Block::TShapeID)aBN.ShapeSupportID();
+      iBNID=aBN.BaseNodeID();
+      const gp_XYZ& aBNXYZ=aBN.NormCoord();
+      //
+      // fill current node info
+      //   -index in aTNodes
+      ij=i*myJSize+j; 
+      //   -normalized coordinates  
+      aX=aBNXYZ.X();  
+      aY=aBNXYZ.Y();
+      aZ=aZL[i];
+      aCoords.SetCoord(aX, aY, aZ); 
+      //
+      //   suporting shape ID
+      bIsUpperLayer=(i==(myISize-1));
+      ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
+       return;
+      }
+      //
+      aTN.SetShapeSupportID(aSSID);
+      aTN.SetNormCoord(aCoords);
+      aTN.SetBaseNodeID(iBNID);
+      //
+      if (aSSID!=SMESH_Block::ID_NONE){
+       // try to find the node
+       const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
+       FindNodeOnShape(aS, aCoords, aTN);
+      }
+      else{
+       // create node and get it id
+       CreateNode (bIsUpperLayer, aCoords, aTN);
+      }
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
+       return;
+      }
+      //
+      myTNodes[ij]=aTN;
+    }
+  }
+  //DEB
+  /*
+  {
+    int iSSID, iBNID, aID;
+    //
+    for (i=0; i<myISize; ++i) {
+      printf(" Layer# %d\n", i);
+      for (j=0; j<myJSize; ++j) {
+       ij=i*myJSize+j; 
+       const StdMeshers_TNode& aTN=myTNodes[ij];
+       //const StdMeshers_TNode& aTN=aTNodes[ij];
+       const gp_XYZ& aXYZ=aTN.NormCoord();
+       iSSID=aTN.ShapeSupportID();
+       iBNID=aTN.BaseNodeID();
+       //
+       const SMDS_MeshNode* aNode=aTN.Node();
+       aID=aNode->GetID(); 
+       aX=aNode->X();
+       aY=aNode->Y();
+       aZ=aNode->Z();
+       printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf },  { %lf %lf %lf }\n",
+              j,  iBNID, iSSID, aID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z(), aX, aY, aZ);
+      }
+    }
+  }
+  */
+  //DEB t
+}
+//=======================================================================
+//function : FindNodeOnShape
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
+                                         const gp_XYZ& aParams,
+                                         StdMeshers_TNode& aTN)
+{
+  myErrorStatus=0;
+  //
+  double aX, aY, aZ, aD, aTol2;
+  gp_Pnt aP1, aP2;
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  aTol2=myTol3D*myTol3D;
+  SMDS_MeshNode* pNode=NULL;
+  //
+  myBlock.Point(aParams, aS, aP1);
+  //
+  SMDS_NodeIteratorPtr ite=
+    pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+  while(ite->more()) {
+    const SMDS_MeshNode* aNode = ite->next();
+    aX=aNode->X();
+    aY=aNode->Y();
+    aZ=aNode->Z();
+    aP2.SetCoord(aX, aY, aZ);
+    aD=(double)aP1.SquareDistance(aP2);
+    //printf("** D=%lf ", aD, aTol2);
+    if (aD<aTol2) {
+      pNode=(SMDS_MeshNode*)aNode;
+      aTN.SetNode(pNode);
+      //printf(" Ok\n");
+      return; 
+    }
+  }
+  //
+  //printf(" KO\n");
+  aTN.SetNode(pNode);
+  MESSAGE("StdMeshers_Penta_3D::FindNodeOnShape(), can not find the node");
+  myErrorStatus=11; // can not find the node;
+}
+
+//=======================================================================
+//function : MakeVolumeMesh
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeVolumeMesh()
+{
+  myErrorStatus=0;
+  //
+  int i, j, ij, ik, i1, i2, aSSID; 
+  //
+  TopoDS_Shell aShell;
+  TopExp_Explorer aExp;
+  //
+  SMESH_Mesh*   pMesh =GetMesh();
+  SMESHDS_Mesh* meshDS=pMesh->GetMeshDS();
+  //
+  aExp.Init(myShape, TopAbs_SHELL);
+  for (; aExp.More(); aExp.Next()){
+    aShell=TopoDS::Shell(aExp.Current());
+    break;
+  }
+  //
+  // 1. Set Node In Volume
+  ik=myISize-1;
+  for (i=1; i<ik; ++i){
+    for (j=0; j<myJSize; ++j){
+      ij=i*myJSize+j;
+      const StdMeshers_TNode& aTN=myTNodes[ij];
+      aSSID=aTN.ShapeSupportID();
+      if (aSSID==SMESH_Block::ID_NONE) {
+       SMDS_MeshNode* aNode=(SMDS_MeshNode*)aTN.Node();
+       meshDS->SetNodeInVolume(aNode, aShell);
+      }
+    }
+  }
+  //
+  // 2. Make pentahedrons
+  int aID0, k , aJ[3];
+  vector<const SMDS_MeshNode*> aN;
+  //
+  SMDS_ElemIteratorPtr itf, aItNodes;
+  //
+  const TopoDS_Face& aFxy0=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
+  SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
+  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  //
+  itf=aSM0->GetElements();
+  while(itf->more()) {
+    const SMDS_MeshElement* pE0=itf->next();
+    //
+    int nbFaceNodes = pE0->NbNodes();
+    if ( aN.size() < nbFaceNodes * 2 )
+      aN.resize( nbFaceNodes * 2 );
+    //
+    k=0;
+    aItNodes=pE0->nodesIterator();
+    while (aItNodes->more()) {
+      const SMDS_MeshElement* pNode=aItNodes->next();
+      aID0=pNode->GetID();
+      aJ[k]=GetIndexOnLayer(aID0);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
+       return;
+      }
+      //
+      ++k;
+    }
+    //
+    for (i=0; i<ik; ++i){
+      i1=i;
+      i2=i+1;
+      for(j=0; j<nbFaceNodes; ++j) {
+       ij=i1*myJSize+aJ[j];
+       const StdMeshers_TNode& aTN1=myTNodes[ij];
+       const SMDS_MeshNode* aN1=aTN1.Node();
+       aN[j]=aN1;
+       //
+       ij=i2*myJSize+aJ[j];
+       const StdMeshers_TNode& aTN2=myTNodes[ij];
+       const SMDS_MeshNode* aN2=aTN2.Node();
+       aN[j+nbFaceNodes]=aN2;
+      }
+      //
+      SMDS_MeshVolume* aV = 0;
+      switch ( nbFaceNodes ) {
+      case 3:
+       aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
+                               aN[3], aN[4], aN[5]);
+        break;
+      case 4:
+       aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+                               aN[4], aN[5], aN[6], aN[7]);
+        break;
+      default:
+        continue;
+      }
+      meshDS->SetMeshElementOnShape(aV, aShell);
+    }
+  }
+}
+
+//=======================================================================
+//function : MakeMeshOnFxy1
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeMeshOnFxy1()
+{
+  myErrorStatus=0;
+  //
+  int aID0, aJ, aLevel, ij, aNbNodes, k;
+  //
+  SMDS_NodeIteratorPtr itn;
+  SMDS_ElemIteratorPtr itf, aItNodes;
+  SMDSAbs_ElementType aElementType;
+  //
+  const TopoDS_Face& aFxy0=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
+  const TopoDS_Face& aFxy1=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
+  //
+  SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
+  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  //
+  // set nodes on aFxy1
+  aLevel=myISize-1;
+  itn=aSM0->GetNodes();
+  aNbNodes=aSM0->NbNodes();
+  //printf("** aNbNodes=%d\n", aNbNodes);
+  while(itn->more()) {
+    const SMDS_MeshNode* aN0=itn->next();
+    aID0=aN0->GetID();
+    aJ=GetIndexOnLayer(aID0);
+    if (myErrorStatus) {
+      MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
+      return;
+    }
+    //
+    ij=aLevel*myJSize+aJ;
+    const StdMeshers_TNode& aTN1=myTNodes[ij];
+    SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node();
+    //
+    meshDS->SetNodeOnFace(aN1, aFxy1);
+  }
+  //
+  // set elements on aFxy1
+  vector<const SMDS_MeshNode*> aNodes1;
+  //
+  itf=aSM0->GetElements();
+  while(itf->more()) {
+    const SMDS_MeshElement * pE0=itf->next();
+    aElementType=pE0->GetType();
+    if (!aElementType==SMDSAbs_Face) {
+      continue;
+    }
+    aNbNodes=pE0->NbNodes();
+//     if (aNbNodes!=3) {
+//       continue;
+//     }
+    if ( aNodes1.size() < aNbNodes )
+      aNodes1.resize( aNbNodes );
+    //
+    k=aNbNodes-1; // reverse a face
+    aItNodes=pE0->nodesIterator();
+    while (aItNodes->more()) {
+      const SMDS_MeshElement* pNode=aItNodes->next();
+      aID0=pNode->GetID();
+      aJ=GetIndexOnLayer(aID0);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
+       return;
+      }
+      //
+      ij=aLevel*myJSize+aJ;
+      const StdMeshers_TNode& aTN1=myTNodes[ij];
+      const SMDS_MeshNode* aN1=aTN1.Node();
+      aNodes1[k]=aN1;
+      --k;
+    }
+    SMDS_MeshFace * face = 0;
+    switch ( aNbNodes ) {
+    case 3:
+      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+      break;
+    case 4:
+      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+      break;
+    default:
+      continue;
+    }
+    meshDS->SetMeshElementOnShape(face, aFxy1);
+  }
+}
+//=======================================================================
+//function : ClearMeshOnFxy1
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::ClearMeshOnFxy1()
+{
+  myErrorStatus=0;
+  //
+  SMESH_subMesh* aSubMesh;
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1);
+  aSubMesh = pMesh->GetSubMeshContaining(aFxy1);
+  if (aSubMesh)
+    aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
+}
+
+//=======================================================================
+//function : GetIndexOnLayer
+//purpose  : 
+//=======================================================================
+int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
+{
+  myErrorStatus=0;
+  //
+  int j=-1;
+  StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
+  //
+  aMapIt=myConnectingMap.find(aID);
+  if (aMapIt==myConnectingMap.end()) {
+    myErrorStatus=200;
+    return j;
+  }
+  j=(*aMapIt).second;
+  return j;
+}
+//=======================================================================
+//function : MakeConnectingMap
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeConnectingMap()
+{
+  int j, aBNID;
+  //
+  for (j=0; j<myJSize; ++j) {
+    const StdMeshers_TNode& aBN=myTNodes[j];
+    aBNID=aBN.BaseNodeID();
+    myConnectingMap[aBNID]=j;
+  }
+}
+//=======================================================================
+//function : CreateNode
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
+                                    const gp_XYZ& aParams,
+                                    StdMeshers_TNode& aTN)
+{
+  myErrorStatus=0;
+  //
+  int iErr;
+  double aX, aY, aZ;
+  //
+  gp_Pnt aP;
+  //
+  SMDS_MeshNode* pNode=NULL; 
+  aTN.SetNode(pNode);  
+  //
+  if (bIsUpperLayer) {
+    // point on face Fxy1
+    const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1);
+    myBlock.Point(aParams, aS, aP);
+  }
+  else {
+    // point inside solid
+    myBlock.Point(aParams, aP);
+  }
+  //
+  iErr=myBlock.ErrorStatus();
+  if (iErr) {
+    myErrorStatus=12; // can not find the node point;
+    return;
+  }
+  //
+  aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); 
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS();
+  //
+  pNode = pMeshDS->AddNode(aX, aY, aZ);
+  aTN.SetNode(pNode);
+}
+//=======================================================================
+//function : ShapeSupportID
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
+                                        const SMESH_Block::TShapeID aBNSSID,
+                                        SMESH_Block::TShapeID& aSSID)
+{
+  myErrorStatus=0;
+  //
+  switch (aBNSSID) {
+    case SMESH_Block::ID_V000:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
+      break;
+    case SMESH_Block::ID_V100:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
+      break; 
+    case SMESH_Block::ID_V110:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
+      break;
+    case SMESH_Block::ID_V010:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
+      break;
+    case SMESH_Block::ID_Ex00:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
+      break;
+    case SMESH_Block::ID_Ex10:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
+      break; 
+    case SMESH_Block::ID_E0y0:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
+      break; 
+    case SMESH_Block::ID_E1y0:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
+      break; 
+    case SMESH_Block::ID_Fxy0:
+      aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ?  Shape_ID_Fxy1 : Shape_ID_NONE;
+      break;   
+    default:
+      aSSID=SMESH_Block::ID_NONE;
+      myErrorStatus=10; // Can not find supporting shape ID
+      break;
+  }
+  return;
+}
+//=======================================================================
+//function : MakeBlock
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeBlock()
+{
+  myErrorStatus=0;
+  //
+  bool bFound;
+  int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
+  //
+  TopoDS_Vertex aV000, aV001;
+  TopoDS_Shape aFTr;
+  TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+  TopTools_IndexedMapOfShape aME ,aMEV, aM;
+  TopTools_ListIteratorOfListOfShape aIt;
+  //
+  TopExp::MapShapes(myShape, TopAbs_FACE, aM);
+  //
+  // 0. Find triangulated face aFTr
+  SMDSAbs_ElementType aElementType;
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  iCnt=0;
+  iNbF=aM.Extent();
+  for (i=1; i<=iNbF; ++i) {
+    const TopoDS_Shape& aF=aM(i);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    SMDS_ElemIteratorPtr itf=aSM->GetElements();
+    while(itf->more()) {
+      const SMDS_MeshElement * pElement=itf->next();
+      aElementType=pElement->GetType();
+      if (aElementType==SMDSAbs_Face) {
+       iNbNodes=pElement->NbNodes();
+       if (iNbNodes==3) {
+         aFTr=aF;
+         ++iCnt;
+         if (iCnt>1) {
+            MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+           myErrorStatus=5; // more than one face has triangulation
+           return;
+         }
+         break; // next face
+       }
+      }
+    }
+  }
+  // 
+  // 1. Vetrices V00, V001;
+  //
+  TopExp::MapShapes(aFTr, TopAbs_EDGE, aME);
+  TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+  //
+  // 1.1 Base vertex V000
+  iNbE=aME.Extent();
+  if (iNbE!=4){
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=7; // too few edges are in base face aFTr 
+    return;
+  }
+  const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
+  aV000=TopExp::FirstVertex(aE1);
+  //
+  const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000);
+  aIt.Initialize(aLE);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aEx=aIt.Value();
+    aMEV.Add(aEx);
+  }
+  iNbEV=aMEV.Extent();
+  if (iNbEV!=3){
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=7; // too few edges meet in base vertex 
+    return;
+  }
+  //
+  // 1.2 Vertex V001
+  bFound=false;
+  for (j=1; j<=iNbEV; ++j) {
+    const TopoDS_Shape& aEx=aMEV(j);
+    if (!aME.Contains(aEx)) {
+      TopoDS_Vertex aV[2];
+      //
+      const TopoDS_Edge& aE=TopoDS::Edge(aEx);
+      TopExp::Vertices(aE, aV[0], aV[1]);
+      for (i=0; i<2; ++i) {
+       if (!aV[i].IsSame(aV000)) {
+         aV001=aV[i];
+         bFound=!bFound;
+         break;
+       }
+      }
+    }
+  }
+  //
+  if (!bFound) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=8; // can not find reper V001 
+    return;
+  }
+  //DEB
+  //gp_Pnt aP000, aP001;
+  //
+  //aP000=BRep_Tool::Pnt(TopoDS::Vertex(aV000));
+  //printf("*** aP000 { %lf, %lf, %lf }\n", aP000.X(), aP000.Y(), aP000.Z());
+  //aP001=BRep_Tool::Pnt(TopoDS::Vertex(aV001));
+  //printf("*** aP001 { %lf, %lf, %lf }\n", aP001.X(), aP001.Y(), aP001.Z());
+  //DEB
+  //
+  aME.Clear();
+  TopExp::MapShapes(myShape, TopAbs_SHELL, aME);
+  iNbE=aME.Extent();
+  if (iNbE!=1) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=9; // number of shells in source shape !=1 
+    return;
+  }
+  //
+  // 2. Load Block
+  const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
+  myBlock.Load(aShell, aV000, aV001);
+  iErr=myBlock.ErrorStatus();
+  if (iErr) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=100; // SMESHBlock: Load operation failed
+    return;
+  }
+}
+//=======================================================================
+//function : CheckData
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::CheckData()
+{
+  myErrorStatus=0;
+  //
+  int i, iNb;
+  int iNbEx[]={8, 12, 6};
+  //
+  TopAbs_ShapeEnum aST;
+  TopAbs_ShapeEnum aSTEx[]={
+    TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE
+  }; 
+  TopTools_IndexedMapOfShape aM;
+  //
+  if (myShape.IsNull()){
+    MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+    myErrorStatus=2; // null shape
+    return;
+  }
+  //
+  aST=myShape.ShapeType();
+  if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
+    MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+    myErrorStatus=3; // not compatible type of shape
+    return;
+  }
+  //
+  for (i=0; i<3; ++i) {
+    aM.Clear();
+    TopExp::MapShapes(myShape, aSTEx[i], aM);
+    iNb=aM.Extent();
+    if (iNb!=iNbEx[i]){
+      MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+      myErrorStatus=4; // number of subshape is not compatible
+      return;
+    }
+  }
+}
+//////////////////////////////////////////////////////////////////////////
+//
+//   StdMeshers_SMESHBlock
+//
+//
+#include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TopoDS_Vertex.hxx>
+
+//=======================================================================
+//function : StdMeshers_SMESHBlock
+//purpose  : 
+//=======================================================================
+StdMeshers_SMESHBlock::StdMeshers_SMESHBlock()
+{
+  myErrorStatus=1;
+}
+//=======================================================================
+//function : ErrorStatus
+//purpose  : 
+//=======================================================================
+int StdMeshers_SMESHBlock::ErrorStatus() const
+{
+  return myErrorStatus;
+}
+//=======================================================================
+//function : Load
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
+{
+  
+  TopoDS_Vertex aV000, aV001;
+  //
+  Load(theShell, aV000, aV001);
+}
+//=======================================================================
+//function : Load
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
+                                const TopoDS_Vertex& theV000,
+                                const TopoDS_Vertex& theV001)
+{
+  myErrorStatus=0;
+  //
+  myShell=theShell;
+  //
+  bool bOk;
+  //
+  myShapeIDMap.Clear();  
+  bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
+  if (!bOk) {
+    myErrorStatus=2;
+    return;
+  }
+}
+//=======================================================================
+//function : ComputeParameters
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, 
+                                             gp_XYZ& theXYZ)
+{
+  ComputeParameters(thePnt, myShell, theXYZ);
+}
+//=======================================================================
+//function : ComputeParameters
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
+                                             const TopoDS_Shape& theShape,
+                                             gp_XYZ& theXYZ)
+{
+  myErrorStatus=0;
+  //
+  int aID;
+  bool bOk;
+  //
+  aID=ShapeID(theShape);
+  if (myErrorStatus) {
+    return;
+  }
+  bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID);
+  if (!bOk) {
+    myErrorStatus=4; // problems with computation Parameters 
+    return;
+  }
+}
+//=======================================================================
+//function : Point
+//purpose  : 
+//=======================================================================
+ void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
+                                  gp_Pnt& aP3D)
+{
+  TopoDS_Shape aS;
+  //
+  Point(theParams, aS, aP3D);
+}
+//=======================================================================
+//function : Point
+//purpose  : 
+//=======================================================================
+ void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
+                                  const TopoDS_Shape& theShape,
+                                  gp_Pnt& aP3D)
+{
+  myErrorStatus=0;
+  //
+  int aID;
+  bool bOk=false;
+  gp_XYZ aXYZ(99.,99.,99.);
+  aP3D.SetXYZ(aXYZ);
+  //
+  if (theShape.IsNull()) {
+    bOk=myTBlock.ShellPoint(theParams, aXYZ);
+  }
+  //
+  else {
+    aID=ShapeID(theShape);
+    if (myErrorStatus) {
+      return;
+    }
+    //
+    if (SMESH_Block::IsVertexID(aID)) {
+      bOk=myTBlock.VertexPoint(aID, aXYZ);
+    }
+    else if (SMESH_Block::IsEdgeID(aID)) {
+      bOk=myTBlock.EdgePoint(aID, theParams, aXYZ);
+    }
+    //
+    else if (SMESH_Block::IsFaceID(aID)) {
+      bOk=myTBlock.FacePoint(aID, theParams, aXYZ);
+    }
+  }
+  if (!bOk) {
+    myErrorStatus=4; // problems with point computation 
+    return;
+  }
+  aP3D.SetXYZ(aXYZ);
+}
+//=======================================================================
+//function : ShapeID
+//purpose  : 
+//=======================================================================
+int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape)
+{
+  myErrorStatus=0;
+  //
+  int aID=-1;
+  TopoDS_Shape aSF, aSR;
+  //
+  aSF=theShape;
+  aSF.Orientation(TopAbs_FORWARD);
+  aSR=theShape;
+  aSR.Orientation(TopAbs_REVERSED);
+  //
+  if (myShapeIDMap.Contains(aSF)) {
+    aID=myShapeIDMap.FindIndex(aSF);
+    return aID;
+  }
+  if (myShapeIDMap.Contains(aSR)) {
+    aID=myShapeIDMap.FindIndex(aSR);
+    return aID;
+  }
+  myErrorStatus=2; // unknown shape;
+  return aID;
+}
+//=======================================================================
+//function : Shape
+//purpose  : 
+//=======================================================================
+const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
+{
+  myErrorStatus=0;
+  //
+  int aNb;
+  //
+  aNb=myShapeIDMap.Extent();
+  if (theID<1 || theID>aNb) {
+    myErrorStatus=3; // ID is out of range
+    return myEmptyShape;
+  }
+  //
+  const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
+  return aS;
+}
diff --git a/src/StdMeshers/StdMeshers_Penta_3D.hxx b/src/StdMeshers/StdMeshers_Penta_3D.hxx
new file mode 100644 (file)
index 0000000..aac472e
--- /dev/null
@@ -0,0 +1,225 @@
+//  SMESH StdMeshers : implementaion of SMESH idl descriptions
+//
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Penta_3D.hxx
+//  Module : SMESH
+
+#ifndef StdMeshers_Penta_3D_HeaderFile
+#define StdMeshers_Penta_3D_HeaderFile
+
+#include <map>
+
+typedef std::map < int, int > StdMeshers_DataMapOfIntegerInteger;
+
+////////////////////////////////////////////////////////////////////////
+//
+//  class StdMeshers_SMESHBlock
+//
+#include <gp_Pnt.hxx>
+#include <gp_XYZ.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopTools_IndexedMapOfOrientedShape.hxx>
+
+#include "SMESH_Block.hxx"
+
+class StdMeshers_SMESHBlock {
+public:
+  //
+  StdMeshers_SMESHBlock();
+  
+  void Load (const TopoDS_Shell& theShell);
+  
+  void Load (const TopoDS_Shell& theShell,
+            const TopoDS_Vertex& theV000,
+            const TopoDS_Vertex& theV001);
+  
+  void ComputeParameters(const gp_Pnt& thePnt, 
+                        gp_XYZ& theXYZ);
+  
+  void ComputeParameters(const gp_Pnt& thePnt,
+                        const TopoDS_Shape& theShape,
+                        gp_XYZ& theXYZ);
+  
+  void Point(const gp_XYZ& theParams, 
+            gp_Pnt& thePnt);
+  
+  void Point(const gp_XYZ& theParams,
+            const TopoDS_Shape& theShape, 
+            gp_Pnt& thePnt);
+  
+  int ShapeID(const TopoDS_Shape& theShape); 
+  
+  const TopoDS_Shape& Shape(const int theID);
+  
+  
+  int  ErrorStatus() const;
+
+
+protected:
+  TopoDS_Shell                       myShell;
+  TopTools_IndexedMapOfOrientedShape myShapeIDMap;
+  SMESH_Block                        myTBlock;
+  TopoDS_Shape                       myEmptyShape;
+  //
+  int myErrorStatus;
+};
+////////////////////////////////////////////////////////////////////////
+//
+//  class StdMeshers_TNode
+//
+#include "SMDS_MeshNode.hxx"
+
+class StdMeshers_TNode {
+
+public:
+  
+  StdMeshers_TNode(){
+    myNode=NULL;
+    myXYZ.SetCoord(99., 99., 99.);
+    myShapeSupportID=-1;
+    myBaseNodeID=-1;
+  }
+  
+  void SetNode(const SMDS_MeshNode* theNode) {
+    myNode=(SMDS_MeshNode*) theNode;
+  }
+  
+  const SMDS_MeshNode* Node()const {
+    return myNode;
+  }
+
+  void SetShapeSupportID (const int theID) {
+    myShapeSupportID=theID;
+  }
+  
+  int ShapeSupportID()const {
+    return myShapeSupportID;
+  }
+  
+  void SetNormCoord (const gp_XYZ& theXYZ) {
+    myXYZ=theXYZ;
+  }
+
+  const gp_XYZ& NormCoord ()const{
+    return myXYZ;
+  }
+  
+  void SetBaseNodeID (const int theID) {
+    myBaseNodeID=theID;
+  }
+  
+  int BaseNodeID ()const{
+    return myBaseNodeID;
+  }
+
+private:
+  SMDS_MeshNode* myNode;
+  int  myShapeSupportID;
+  gp_XYZ         myXYZ;
+  int            myBaseNodeID;
+};
+
+////////////////////////////////////////////////////////////////////////
+//
+//  class StdMeshers_Penta_3D
+//
+#include "SMESH_Mesh.hxx"
+#include <TopoDS_Shape.hxx>
+//
+class StdMeshers_Penta_3D {
+//
+  public: // methods
+    StdMeshers_Penta_3D();
+    
+    //~StdMeshers_Penta_3D();
+    
+    bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
+    
+    int ErrorStatus() const {
+      return myErrorStatus;
+    }
+   
+    void SetTolerance(const double theTol3D) {
+      myTol3D=theTol3D;
+    }
+    
+    double Tolerance() const {
+      return myTol3D;
+    }
+    
+
+  protected: // methods
+    
+    void CheckData();
+    
+    void MakeBlock();
+
+    void MakeNodes();
+
+    void ShapeSupportID(const bool theIsUpperLayer,
+                       const SMESH_Block::TShapeID theBNSSID,
+                       SMESH_Block::TShapeID& theSSID);
+
+    void FindNodeOnShape(const TopoDS_Shape& aS,
+                        const gp_XYZ& aParams,
+                        StdMeshers_TNode& aTN);
+
+    void CreateNode(const bool theIsUpperLayer,
+                   const gp_XYZ& aParams,
+                   StdMeshers_TNode& aTN);
+
+    void ClearMeshOnFxy1();
+
+    void MakeMeshOnFxy1();
+
+    void MakeConnectingMap();
+
+    int GetIndexOnLayer(const int aID);
+
+    void MakeVolumeMesh();
+  
+    void SetMesh(SMESH_Mesh& theMesh) {
+      myMesh=(void *)&theMesh;
+    }
+    
+    SMESH_Mesh* GetMesh()const {
+      return (SMESH_Mesh*)myMesh;
+    }
+    
+  protected: // fields
+    TopoDS_Shape myShape;
+    StdMeshers_SMESHBlock myBlock;
+    void *       myMesh;
+    int          myErrorStatus;
+    //
+    vector <StdMeshers_TNode> myTNodes;
+    int myISize;
+    int myJSize;
+    double   myTol3D;        // Tolerance value     
+    StdMeshers_DataMapOfIntegerInteger myConnectingMap;
+
+};
+
+#endif
index 6a6f92a..d7d2e84 100644 (file)
@@ -1,23 +1,23 @@
 //  SMESH SMESH : implementaion of SMESH idl descriptions
 //
 //  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
 //
 //
 //
@@ -38,7 +38,6 @@ using namespace std;
 #include "StdMeshers_Arithmetic1D.hxx"
 #include "StdMeshers_StartEndLength.hxx"
 #include "StdMeshers_Deflection1D.hxx"
-#include "StdMeshers_Propagation.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -48,18 +47,13 @@ using namespace std;
 #include "utilities.h"
 
 #include <BRep_Tool.hxx>
-#include <BRepTools_WireExplorer.hxx>
-
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Shape.hxx>
-#include <TopTools_Array1OfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-
 #include <GeomAdaptor_Curve.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <GCPnts_UniformDeflection.hxx>
-
 #include <Standard_ErrorHandler.hxx>
 #include <Precision.hxx>
 
@@ -68,7 +62,7 @@ using namespace std;
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -88,7 +82,7 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -98,7 +92,7 @@ StdMeshers_Regular_1D::~StdMeshers_Regular_1D()
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -186,7 +180,7 @@ bool StdMeshers_Regular_1D::CheckHypothesis
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge,
@@ -316,7 +310,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
       theParams.push_back( param );
     }
     return true;
-
+    
   }
 
   case ARITHMETIC_1D: {
@@ -363,7 +357,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -419,7 +413,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     // only internal nodes receive an edge position with param on curve
 
     const SMDS_MeshNode * idPrev = idFirst;
-
+    
     for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++)
     {
       double param = *itU;
@@ -429,7 +423,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
       SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
       meshDS->SetNodeOnEdge(node, E);
 
-      // **** edgePosition associe au point = param.
+      // **** edgePosition associe au point = param. 
       SMDS_EdgePosition* epos =
         dynamic_cast<SMDS_EdgePosition *>(node->GetPosition().get());
       epos->SetUParameter(param);
@@ -476,130 +470,48 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
 
 //=============================================================================
 /*!
- *  GetUsedHypothesis
+ *  See comments in SMESH_Algo.cxx
  */
 //=============================================================================
 
-const list <const SMESHDS_Hypothesis *> & StdMeshers_Regular_1D::GetUsedHypothesis
-  (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+const list <const SMESHDS_Hypothesis *> & StdMeshers_Regular_1D::GetUsedHypothesis(
+       SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
   _usedHypList.clear();
-  _usedHypList = GetAppliedHypothesis(aMesh, aShape); // copy
+  _usedHypList = GetAppliedHypothesis(aMesh, aShape);  // copy
   int nbHyp = _usedHypList.size();
-
-  // try to find being propagated hypothesis
-  string propName = StdMeshers_Propagation::GetName();
-  if (nbHyp == 0) {
-    // Get all opposite edges
-    TopTools_ListOfShape anOppositeEdges;
-    TopoDS_Shape mainShape = aMesh.GetMeshDS()->ShapeToMesh();
-    GetOppositeEdges(mainShape, aShape, anOppositeEdges);
-    TopTools_ListIteratorOfListOfShape oppIt (anOppositeEdges);
-    for (; oppIt.More(); oppIt.Next()) {
-      const TopoDS_Shape& oppE = oppIt.Value();
-
-      // Find Propagation hypothesis on the opposite edge
-      if (IsPropagated(aMesh, oppE)) {
-
-        // Get hypothesis, used by the opposite edge
-        _usedHypList = SMESH_Algo::GetUsedHypothesis(aMesh, oppE);
-        nbHyp = _usedHypList.size();
-        if (nbHyp == 1)
-          break;
-      }
+  if (nbHyp == 0)
+  {
+    // Check, if propagated from some other edge
+    TopoDS_Shape aMainEdge;
+    if (aShape.ShapeType() == TopAbs_EDGE &&
+        aMesh.IsPropagatedHypothesis(aShape, aMainEdge))
+    {
+      // Propagation of 1D hypothesis from <aMainEdge> on this edge
+      _usedHypList = GetAppliedHypothesis(aMesh, aMainEdge);   // copy
+      nbHyp = _usedHypList.size();
     }
   }
-
-  // try to find relevant 1D hypothesis on ancestors
-  if (nbHyp == 0) {
-    TopTools_ListIteratorOfListOfShape ancIt (aMesh.GetAncestors(aShape));
-    for (; ancIt.More(); ancIt.Next()) {
+  if (nbHyp == 0)
+  {
+    TopTools_ListIteratorOfListOfShape ancIt( aMesh.GetAncestors( aShape ));
+    for (; ancIt.More(); ancIt.Next())
+    {
       const TopoDS_Shape& ancestor = ancIt.Value();
-      _usedHypList = GetAppliedHypothesis(aMesh, ancestor); // copy
+      _usedHypList = GetAppliedHypothesis(aMesh, ancestor);    // copy
       nbHyp = _usedHypList.size();
       if (nbHyp == 1)
         break;
     }
   }
-
   if (nbHyp > 1)
-    _usedHypList.clear(); //only one compatible hypothesis allowed
+    _usedHypList.clear();      //only one compatible hypothesis allowed
   return _usedHypList;
 }
 
 //=============================================================================
 /*!
- *  Is Propagation hypothesis assigned to theShape or its ancestors
- */
-//=============================================================================
-Standard_Boolean StdMeshers_Regular_1D::IsPropagated (SMESH_Mesh         & theMesh,
-                                                      const TopoDS_Shape & theShape)
-{
-  const SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
-
-  // try to find Propagation hypothesis on theShape
-  const list<const SMESHDS_Hypothesis*> & listHyp = meshDS->GetHypothesis(theShape);
-
-  list<const SMESHDS_Hypothesis*>::const_iterator it = listHyp.begin();
-  for (; it != listHyp.end(); it++) {
-    const SMESHDS_Hypothesis *anHyp = *it;
-    if (anHyp->GetName() == StdMeshers_Propagation::GetName())
-      return Standard_True;
-  }
-
-  // try to find Propagation hypothesis on ancestors
-  TopTools_ListIteratorOfListOfShape ancIt (theMesh.GetAncestors(theShape));
-  for (; ancIt.More(); ancIt.Next()) {
-    const TopoDS_Shape& ancestor = ancIt.Value();
-    const list<const SMESHDS_Hypothesis*> & listAncHyp = meshDS->GetHypothesis(ancestor);
-
-    list<const SMESHDS_Hypothesis*>::const_iterator itAnc = listAncHyp.begin();
-    for (; itAnc != listAncHyp.end(); itAnc++) {
-      const SMESHDS_Hypothesis *anHyp = *itAnc;
-      if (anHyp->GetName() == StdMeshers_Propagation::GetName())
-        return Standard_True;
-    }
-  }
-
-  return Standard_False;
-}
-
-//=============================================================================
-/*!
- * GetOppositeEdges() - get all edges of theShape,
- * laying on any quadrangle face in front of theEdge
- */
-//=============================================================================
-void StdMeshers_Regular_1D::GetOppositeEdges (const TopoDS_Shape&   theShape,
-                                              const TopoDS_Shape&   theEdge,
-                                              TopTools_ListOfShape& theOppositeEdges) const
-{
-  TopExp_Explorer aWires (theShape, TopAbs_WIRE);
-  for (; aWires.More(); aWires.Next()) {
-    const TopoDS_Shape& aWire = aWires.Current();
-    BRepTools_WireExplorer aWE (TopoDS::Wire(aWire));
-    Standard_Integer nb = 1, found = 0;
-    TopTools_Array1OfShape anEdges (1,4);
-    for (; aWE.More(); aWE.Next(), nb++) {
-      if (nb > 4) {
-        found = 0;
-        break;
-      }
-      anEdges(nb) = aWE.Current();
-      if (anEdges(nb).IsSame(theEdge))
-        found = nb;
-    }
-    if (nb == 5 && found > 0) {
-      Standard_Integer opp = found + 2;
-      if (opp > 4) opp -= 4;
-      theOppositeEdges.Append(anEdges(opp));
-    }
-  }
-}
-
-//=============================================================================
-/*!
- *
+ *  
  */
 //=============================================================================
 
@@ -610,7 +522,7 @@ ostream & StdMeshers_Regular_1D::SaveTo(ostream & save)
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -621,7 +533,7 @@ istream & StdMeshers_Regular_1D::LoadFrom(istream & load)
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
@@ -632,7 +544,7 @@ ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp)
 
 //=============================================================================
 /*!
- *
+ *  
  */
 //=============================================================================
 
index b038a91..548d598 100644 (file)
@@ -32,9 +32,6 @@
 
 #include "SMESH_1D_Algo.hxx"
 
-#include <TopoDS_Shape.hxx>
-#include <TopTools_ListOfShape.hxx>
-
 class TopoDS_Edge;
 
 class StdMeshers_Regular_1D:
@@ -52,7 +49,7 @@ public:
                       const TopoDS_Shape& aShape);
 
   virtual const std::list <const SMESHDS_Hypothesis *> &
-          GetUsedHypothesis (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+    GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
 
   ostream & SaveTo(ostream & save);
   istream & LoadFrom(istream & load);
@@ -61,13 +58,6 @@ public:
 
 protected:
 
-  Standard_Boolean IsPropagated (SMESH_Mesh         & theMesh,
-                                 const TopoDS_Shape & theShape);
-
-  void GetOppositeEdges (const TopoDS_Shape&   theShape,
-                         const TopoDS_Shape&   theEdge,
-                         TopTools_ListOfShape& theOppositeEdges) const;
-
   bool computeInternalParameters (const TopoDS_Edge&    theEdge,
                                   std::list< double > & theParameters ) const;