Salome HOME
PAL13330( When mesh generation does not success, trace where )
authoreap <eap@opencascade.com>
Tue, 10 Apr 2007 14:19:13 +0000 (14:19 +0000)
committereap <eap@opencascade.com>
Tue, 10 Apr 2007 14:19:13 +0000 (14:19 +0000)
   describe problems using SMESH_ComputeError

18 files changed:
src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.hxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_1D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Propagation.cxx
src/StdMeshers/StdMeshers_Propagation.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx

index 8baf9846a6794d7dafaebac7331752845c03d03a..7c949c52718a159cec0f88e6592438936f2ac60e 100644 (file)
@@ -36,6 +36,7 @@
 #include "SMESH_HypoFilter.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -58,6 +59,8 @@
 #include <Standard_ErrorHandler.hxx>
 #include <Standard_Failure.hxx>
 
+typedef SMESH_Comment TComm;
+
 using namespace std;
 
 
@@ -164,7 +167,7 @@ namespace {
                       const int          eventType,
                       SMESH_subMesh*     subMesh,
                       EventListenerData* data,
-                      SMESH_Hypothesis*  /*hyp*/)
+                      const SMESH_Hypothesis*  /*hyp*/)
     {
       bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT &&
                           subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK );
@@ -175,32 +178,35 @@ namespace {
         {
           if ( SMESH_subMesh* sm = *smIt ) {
             sm->SetIsAlwaysComputed( false );
-            if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
-                sm->GetFather()->GetGen()->Compute( *sm );
-            else  // edge
-              sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+            sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
           }
         }
       }
       // at study restoration:
       // check if edge submesh must have _alwaysComputed flag
-      else if ( eventType == SMESH_subMesh::COMPUTE_EVENT &&
-                event     == SMESH_subMesh::SUBMESH_RESTORED )
+      else if ( event     == SMESH_subMesh::SUBMESH_RESTORED &&
+                eventType == SMESH_subMesh::COMPUTE_EVENT )
       {
         if ( !subMesh->GetEventListenerData( this )) { // not yet checked
           SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
-          TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() );
-          TopoDS_Vertex V1, V2;
-          TopExp::Vertices( edge, V1, V2 );
-          bool noVertexNode1 = ( !SMESH_Algo::VertexNode( V1, meshDS ));
-          bool noVertexNode2 = ( !SMESH_Algo::VertexNode( V2, meshDS ));
-          if ( noVertexNode1 || noVertexNode2 ) {
-            TopoDS_Face face;
-            auto_ptr< StdMeshers_FaceSide > side
-              ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),
-                                                            edge, face, false ));
-            if ( side->NbSegments() )
-              careOfSubMeshes( *side, this );
+          if ( meshDS->NbNodes() > 0 ) {
+            // check if there are nodes on all vertices
+            bool hasNodesOnVerext = true;
+            SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+            while ( hasNodesOnVerext && smIt->more() ) {
+              SMESH_subMesh* sm = smIt->next();
+              hasNodesOnVerext = ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbNodes() );
+            }
+            if ( !hasNodesOnVerext ) {
+              // check if an edge is a part of a complex side
+              TopoDS_Face face;
+              TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() );
+              auto_ptr< StdMeshers_FaceSide > side
+                ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),
+                                                              edge, face, false ));
+              if ( side->NbEdges() > 1 && side->NbSegments() )
+                careOfSubMeshes( *side, this );
+            }
           }
         }
       }
@@ -343,15 +349,14 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh &         aMesh,
   // Create mesh
 
   const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
-  if (!nFirst) {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
-  const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS );
-  if (!nLast) {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
+  const SMDS_MeshNode * nLast  = SMESH_Algo::VertexNode( VLast, meshDS );
+  if (!nFirst) 
+    return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+                 <<meshDS->ShapeToIndex(VFirst));
+  if (!nLast)
+    return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+                 <<meshDS->ShapeToIndex(VLast));
+
   vector<const SMDS_MeshNode*> nodes( nbNodes, (const SMDS_MeshNode*)0 );
   nodes.front() = nFirst;
   nodes.back()  = nLast;
@@ -397,9 +402,9 @@ bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh &         aMesh,
   }
 
   // remove nodes on internal vertices
-  for ( int iE = 0; iE < side->NbEdges()-1; ++iE )
+  for ( int iE = 1; iE < side->NbEdges(); ++iE )
   {
-    TopoDS_Vertex V = side->LastVertex( iE );
+    TopoDS_Vertex V = side->FirstVertex( iE );
     while ( const SMDS_MeshNode * n = SMESH_Algo::VertexNode( V, meshDS ))
       meshDS->RemoveNode( n );
   }
index 21490011ba186f324281a6d78e42206cd134bb3f..80cd6caeb1973e8e309f56e9a914a13586655980 100644 (file)
@@ -36,6 +36,7 @@
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-//#include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 
 #include <BRep_Tool.hxx>
 #include <Geom_Surface.hxx>
-// #include <Geom_Curve.hxx>
-// #include <Geom2d_Curve.hxx>
-// #include <Handle_Geom2d_Curve.hxx>
-// #include <Handle_Geom_Curve.hxx>
 #include <gp_Pnt2d.hxx>
 
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
 
+typedef SMESH_Comment TComm;
+
 using namespace std;
 
-static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
 
 //=============================================================================
 /*!
@@ -71,8 +69,8 @@ static bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aSha
  */
 //=============================================================================
 
-StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
-                                       SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_3D_Algo(hypId, studyId, gen)
 {
   MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
   _name = "Hexa_3D";
@@ -175,8 +173,8 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int&
  */
 //=============================================================================
 
-bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
-       const TopoDS_Shape & aShape)throw(SALOME_Exception)
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
+                                 const TopoDS_Shape & aShape) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   MESSAGE("StdMeshers_Hexa_3D::Compute");
@@ -184,7 +182,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
   
   // 0.  - shape and face mesh verification
   // 0.1 - shape must be a solid (or a shell) with 6 faces
-  //MESSAGE("---");
 
   vector < SMESH_subMesh * >meshFaces;
   for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
@@ -192,13 +189,10 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
     ASSERT(aSubMesh);
     meshFaces.push_back(aSubMesh);
   }
-  if (meshFaces.size() != 6) {
-    SCRUTE(meshFaces.size());
-    return false;
-  }
+  if (meshFaces.size() != 6)
+    return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in block");
 
   // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
-  //MESSAGE("---");
 
   // tool for working with quadratic elements
   SMESH_MesherHelper aTool (aMesh);
@@ -231,7 +225,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
   for (int i = 0; i < 6; i++)
     aQuads[i] = 0;
 
-  for (int i = 0; i < 6; i++) {
+  for (int i = 0; i < 6; i++)
+  {
     TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
     SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
     string algoName = algo->GetName();
@@ -248,9 +243,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       }
     }
     if ( ! isAllQuad ) {
-      //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
-      bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, bIsOk );
+      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+      return ClearAndReturn( aQuads, error(err));
     }
     StdMeshers_Quadrangle_2D *quadAlgo =
       dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
@@ -259,7 +253,9 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh);
     }
     catch(SALOME_Exception & S_ex) {
-      return ClearAndReturn( aQuads, false );
+      return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) <<
+                                           " Raised by StdMeshers_Quadrangle_2D "
+                                           " on face #" << meshDS->ShapeToIndex( aFace )));
     }
 
     // 0.2.1 - number of points on the opposite edges must be the same
@@ -270,58 +266,30 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
         aQuads[i]->side[2]->NbEdges() != 1 ||
         aQuads[i]->side[3]->NbEdges() != 1*/) {
       MESSAGE("different number of points on the opposite edges of face " << i);
-      //                  ASSERT(0);
-      // \begin{E.A.}
       // Try to go into penta algorithm 'cause it has been improved.
-      // return ClearAndReturn( aQuads, false );
-      bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, bIsOk );
-      // \end{E.A.}
+      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+      return ClearAndReturn( aQuads, error(err));
     }
   }
 
   // 1.  - identify faces and vertices of the "cube"
   // 1.1 - ancestor maps vertex->edges in the cube
-  //MESSAGE("---");
 
   TopTools_IndexedDataMapOfShapeListOfShape MS;
   TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
 
   // 1.2 - first face is choosen as face Y=0 of the unit cube
-  //MESSAGE("---");
 
   const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
   const TopoDS_Face & F = TopoDS::Face(aFace);
 
   // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
-  //MESSAGE("---");
 
   aCube.V000 = aQuads[0]->side[0]->FirstVertex(); // will be (0,0,0) on the unit cube
   aCube.V100 = aQuads[0]->side[0]->LastVertex();  // will be (1,0,0) on the unit cube
   aCube.V001 = aQuads[0]->side[2]->FirstVertex(); // will be (0,0,1) on the unit cube
   aCube.V101 = aQuads[0]->side[2]->LastVertex();  // will be (1,0,1) on the unit cube
 
-  // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
-  //     - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
-  //     - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) 
-  //     - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
-  //MESSAGE("---");
-
-//   TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V000, MS);
-//   ASSERT(!E_0Y0.IsNull());
-
-//   TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V100, MS);
-//   ASSERT(!E_1Y0.IsNull());
-
-//   TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V101, MS);
-//   ASSERT(!E_1Y1.IsNull());
-
-//   TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V001, MS);
-//   ASSERT(!E_0Y1.IsNull());
-
-  // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
-  //MESSAGE("---");
-
   TopTools_IndexedMapOfShape MV0;
   TopExp::MapShapes(F, TopAbs_VERTEX, MV0);
 
@@ -330,33 +298,7 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
   aCube.V011 = OppositeVertex( aCube.V001, MV0, aQuads);
   aCube.V111 = OppositeVertex( aCube.V101, MV0, aQuads);
 
-//   TopoDS_Vertex VFirst, VLast;
-//   TopExp::Vertices(E_0Y0, VFirst, VLast);
-//   if (VFirst.IsSame(aCube.V000))
-//     aCube.V010 = VLast;
-//   else
-//     aCube.V010 = VFirst;
-
-//   TopExp::Vertices(E_1Y0, VFirst, VLast);
-//   if (VFirst.IsSame(aCube.V100))
-//     aCube.V110 = VLast;
-//   else
-//     aCube.V110 = VFirst;
-
-//   TopExp::Vertices(E_1Y1, VFirst, VLast);
-//   if (VFirst.IsSame(aCube.V101))
-//     aCube.V111 = VLast;
-//   else
-//     aCube.V111 = VFirst;
-
-//   TopExp::Vertices(E_0Y1, VFirst, VLast);
-//   if (VFirst.IsSame(aCube.V001))
-//     aCube.V011 = VLast;
-//   else
-//     aCube.V011 = VFirst;
-
   // 1.6 - find remaining faces given 4 vertices
-  //MESSAGE("---");
 
   int _indY0 = 0;
   aCube.quad_Y0 = aQuads[_indY0];
@@ -381,8 +323,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
                             aCube.V100, aCube.V101, aCube.V110, aCube.V111);
   aCube.quad_X1 = aQuads[_indX1];
 
-  //MESSAGE("---");
-
   // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
 
   Conv2DStruct cx0;                    // for face X=0
@@ -407,7 +347,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
   // 1.8 - create a 3D structure for normalized values
   
-  //MESSAGE("---");
   int nbx = aCube.quad_Z0->side[0]->NbPoints();
   if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints();
  
@@ -734,20 +673,12 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
         SMDS_MeshVolume * elt;
         if ( isForw ) {
-          //elt = meshDS->AddVolume(np[n1].node, np[n2].node,
-          //                        np[n3].node, np[n4].node,
-          //                        np[n5].node, np[n6].node,
-          //                        np[n7].node, np[n8].node);
           elt = aTool.AddVolume(np[n1].node, np[n2].node,
                                 np[n3].node, np[n4].node,
                                 np[n5].node, np[n6].node,
                                 np[n7].node, np[n8].node);
         }
         else {
-          //elt = meshDS->AddVolume(np[n1].node, np[n4].node,
-          //                        np[n3].node, np[n2].node,
-          //                        np[n5].node, np[n8].node,
-          //                        np[n7].node, np[n6].node);
           elt = aTool.AddVolume(np[n1].node, np[n4].node,
                                 np[n3].node, np[n2].node,
                                 np[n5].node, np[n8].node,
@@ -759,7 +690,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
     }
   }
   if ( np ) delete [] np;
-  //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
   return ClearAndReturn( aQuads, true );
 }
 
@@ -769,8 +699,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
  */
 //=============================================================================
 
-void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby,
-       int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS)
+void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, int nbz,
+                                  Point3DStruct * np, const SMESHDS_Mesh * meshDS)
 {
        int ijk = k * nbx * nby + j * nbx + i;
        const SMDS_MeshNode * node = np[ijk].node;
@@ -1050,16 +980,21 @@ TopoDS_Vertex StdMeshers_Hexa_3D::OppositeVertex(const TopoDS_Vertex& aVertex,
 //function : ComputePentahedralMesh
 //purpose  : 
 //=======================================================================
-bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aShape)
+
+SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
+                                             const TopoDS_Shape & aShape)
 {
   //printf(" ComputePentahedralMesh HERE\n");
   //
   bool bOK;
+  SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
   //int iErr;
   StdMeshers_Penta_3D anAlgo;
   //
   bOK=anAlgo.Compute(aMesh, aShape);
   //
+  err = anAlgo.GetComputeError();
+  //
   if ( !bOK && anAlgo.ErrorStatus() == 5 )
   {
     static StdMeshers_Prism_3D * aPrism3D = 0;
@@ -1068,10 +1003,12 @@ bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
       aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
     }
     SMESH_Hypothesis::Hypothesis_Status aStatus;
-    if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) )
+    if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
       bOK = aPrism3D->Compute( aMesh, aShape );
+      err = aPrism3D->GetComputeError();
+    }
   }
-  return bOK;
+  return err;
 }
 
 
index b08d352f2fdf22d074d4a84491f2dd25bc138c19..cb4e61fc161b2a9531355add902b62fcc010982a 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_Block.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "StdMeshers_FaceSide.hxx"
 #include "StdMeshers_MaxElementArea.hxx"
@@ -180,8 +181,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
 
   // helper builds quadratic mesh if necessary
-  myTool = new SMESH_MesherHelper(aMesh);
-  auto_ptr<SMESH_MesherHelper> helperDeleter( myTool );
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
   _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
   const bool ignoreMediumNodes = _quadraticMesh;
 
@@ -209,10 +210,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     {
       wireEdges.splice(wireEdges.end(), wireEdges,
                        wireEdges.begin(), ++wireEdges.begin());
-      if ( from->IsSame( wireEdges.front() )) {
-        MESSAGE( "No nodes on vertices on wire " << iW+1);
-        return false;
-      }
+      if ( from->IsSame( wireEdges.front() ))
+        return error(COMPERR_BAD_INPUT_MESH,"No nodes on vertices");
     }
     StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh,
                                                          true, ignoreMediumNodes);
@@ -222,7 +221,8 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     from = to;
   }
   if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
-    return false;
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Too few segments")<<wires[0]->NbSegments());
 
   if (_hypLengthFromEdges && _edgeLength < DBL_MIN )
     _edgeLength = 100;
@@ -283,7 +283,7 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     }
     else
     {
-      MESSAGE("Error in Triangulation");
+      error(ierr,"Error in Triangulation (aptrte())");
     }
   }
   if (nudslf != NULL) delete[]nudslf;
@@ -512,12 +512,12 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
   {
     const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
     if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
-      MESSAGE("Wrong nb UVPtStruct: "<<uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
-      return false;
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
+                   << iW << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
     }
     if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
       MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
-      return false;
+      return error(dfltErr(),"Internal error");
     }
 
     vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
index 51b33214fadc17d02597a094a397f46650cba7a2..6359f2905524033ab8a1ba86ead3f187e9be7551 100644 (file)
@@ -38,6 +38,7 @@
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
@@ -71,7 +72,7 @@ enum { NB_WALL_FACES = 4 };
 //purpose  : 
 //=======================================================================
 StdMeshers_Penta_3D::StdMeshers_Penta_3D()
-: myErrorStatus(1)
+: myErrorStatus(SMESH_ComputeError::New())
 {
   myTol3D=0.1;
   myWallNodesMaps.resize( SMESH_Block::NbFaces() );
@@ -86,8 +87,6 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D()
 
 StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
 {
-  if ( myTool )
-    delete myTool;
 }
 
 //=======================================================================
@@ -99,51 +98,45 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
 {
   MESSAGE("StdMeshers_Penta_3D::Compute()");
   //
-  myErrorStatus=0;
-  //
   bool bOK=false;
   //
   myShape=aShape;
   SetMesh(aMesh);
   //
   CheckData();
-  if (myErrorStatus){
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
 
-  myTool = new SMESH_MesherHelper(aMesh);
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
   myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
 
   //
   MakeBlock();
-  if (myErrorStatus){
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   ClearMeshOnFxy1();
-  if (myErrorStatus) {
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeNodes();
-  if (myErrorStatus){
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeConnectingMap();
   //
   MakeMeshOnFxy1();
-  if (myErrorStatus) {
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeVolumeMesh();
   //
-  delete myTool; myTool = 0;
   return !bOK;
 }
 
@@ -153,8 +146,6 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
 //=======================================================================
 void StdMeshers_Penta_3D::MakeNodes()
 {
-  myErrorStatus=0;
-  //
   const int aNbSIDs=9;
   int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
   double aX, aY, aZ;
@@ -258,7 +249,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       if (iErr) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
                 "SMESHBlock: ComputeParameters operation failed");
-        myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+        myErrorStatus=myBlock.GetError();
         return;
       }
       aTNode.SetNormCoord(aCoords);
@@ -284,8 +275,10 @@ void StdMeshers_Penta_3D::MakeNodes()
                            TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )),
                            pMesh->GetMeshDS());
     if ( !ok ) {
-      myErrorStatus = i + 1;
-      MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus );
+      myErrorStatus->myName = COMPERR_BAD_INPUT_MESH;
+      myErrorStatus->myComment = SMESH_Comment() <<
+        "Can't find regular quadrangle mesh on a side face #" <<
+        pMesh->GetMeshDS()->ShapeToIndex( myBlock.Shape( wallFaceID[ i ]));
       return;
     }
   }
@@ -430,7 +423,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       //
       //   suporting shape ID
       ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
        return;
       }
@@ -477,7 +470,7 @@ void StdMeshers_Penta_3D::MakeNodes()
           meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
         }
       }
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
        return;
       }
@@ -525,8 +518,6 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
                                           const int           z,
                                          StdMeshers_TNode&   aTN)
 {
-  myErrorStatus=0;
-  //
   double aX, aY, aZ, aD, aTol2, minD;
   gp_Pnt aP1, aP2;
   //
@@ -670,8 +661,6 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ&                  aBase
 //=======================================================================
 void StdMeshers_Penta_3D::MakeVolumeMesh()
 {
-  myErrorStatus=0;
-  //
   int i, j, ij, ik, i1, i2, aSSID; 
   //
   SMESH_Mesh*   pMesh = GetMesh();
@@ -724,7 +713,7 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
         continue;
       aID0 = pNode->GetID();
       aJ[k] = GetIndexOnLayer(aID0);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
        return;
       }
@@ -811,8 +800,6 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
 //=======================================================================
 void StdMeshers_Penta_3D::MakeMeshOnFxy1()
 {
-  myErrorStatus=0;
-  //
   int aID0, aJ, aLevel, ij, aNbNodes, k;
   //
   SMDS_NodeIteratorPtr itn;
@@ -859,14 +846,13 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     k = aNbNodes-1; // reverse a face
     aItNodes = pE0->nodesIterator();
     while (aItNodes->more()) {
-      //const SMDS_MeshElement* pNode = aItNodes->next();
       const SMDS_MeshNode* pNode =
         static_cast<const SMDS_MeshNode*> (aItNodes->next());
       if(myTool->IsMedium(pNode))
         continue;
       aID0 = pNode->GetID();
       aJ = GetIndexOnLayer(aID0);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
        return;
       }
@@ -908,8 +894,6 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
 //=======================================================================
 void StdMeshers_Penta_3D::ClearMeshOnFxy1()
 {
-  myErrorStatus=0;
-  //
   SMESH_subMesh* aSubMesh;
   SMESH_Mesh* pMesh=GetMesh();
   //
@@ -925,14 +909,13 @@ void StdMeshers_Penta_3D::ClearMeshOnFxy1()
 //=======================================================================
 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;
+    myErrorStatus->myName    = 200;
+    myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
     return j;
   }
   j=(*aMapIt).second;
@@ -962,9 +945,6 @@ 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;
@@ -1022,8 +1002,6 @@ 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;
@@ -1054,7 +1032,8 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
       break;   
     default:
       aSSID=SMESH_Block::ID_NONE;
-      myErrorStatus=10; // Can not find supporting shape ID
+      myErrorStatus->myName=10; // Can not find supporting shape ID
+      myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
       break;
   }
   return;
@@ -1065,8 +1044,6 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
 //=======================================================================
 void StdMeshers_Penta_3D::MakeBlock()
 {
-  myErrorStatus=0;
-  //
   bool bFound;
   int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
   //
@@ -1263,7 +1240,8 @@ void StdMeshers_Penta_3D::MakeBlock()
       }
     }
     if (!isOK) {
-      myErrorStatus=5; // more than one face has triangulation
+      myErrorStatus->myName=5; // more than one face has triangulation
+      myErrorStatus->myComment="Incorrect input mesh";
       return;
     }
   }
@@ -1278,7 +1256,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbE = aME.Extent();
   if (iNbE!= NB_WALL_FACES ){
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=7; // too few edges are in base face aFTr 
+    myErrorStatus->myName=7; // too few edges are in base face aFTr
+    myErrorStatus->myComment=SMESH_Comment("Not a quadrilateral face #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aFTr )<<": "<<iNbE<<" edges" ;
     return;
   }
   const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
@@ -1293,7 +1273,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbEV=aMEV.Extent();
   if (iNbEV!=3){
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=7; // too few edges meet in base vertex 
+    myErrorStatus->myName=7; // too few edges meet in base vertex 
+    myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<<iNbEV<<" edges";
     return;
   }
   //
@@ -1318,7 +1300,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   //
   if (!bFound) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=8; // can not find reper V001 
+    myErrorStatus->myName=8; // can not find reper V001
+    myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aV000 );
     return;
   }
   //DEB
@@ -1335,7 +1319,8 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbE=aME.Extent();
   if (iNbE!=1) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=9; // number of shells in source shape !=1 
+    myErrorStatus->myName=9; // number of shells in source shape !=1
+    myErrorStatus->myComment=SMESH_Comment("Unexpected nb of shells ")<<iNbE;
     return;
   }
   //
@@ -1345,7 +1330,7 @@ void StdMeshers_Penta_3D::MakeBlock()
   iErr = myBlock.ErrorStatus();
   if (iErr) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=100; // SMESHBlock: Load operation failed
+    myErrorStatus=myBlock.GetError(); // SMESHBlock: Load operation failed
     return;
   }
 }
@@ -1355,8 +1340,6 @@ void StdMeshers_Penta_3D::MakeBlock()
 //=======================================================================
 void StdMeshers_Penta_3D::CheckData()
 {
-  myErrorStatus=0;
-  //
   int i, iNb;
   int iNbEx[]={8, 12, 6};
   //
@@ -1368,14 +1351,16 @@ void StdMeshers_Penta_3D::CheckData()
   //
   if (myShape.IsNull()){
     MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-    myErrorStatus=2; // null shape
+    myErrorStatus->myName=2; // null shape
+    myErrorStatus->myComment="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
+    myErrorStatus->myName=3; // not compatible type of shape
+    myErrorStatus->myComment=SMESH_Comment("Wrong shape type (TopAbs_ShapeEnum) ")<<aST;
     return;
   }
   //
@@ -1385,7 +1370,8 @@ void StdMeshers_Penta_3D::CheckData()
     iNb=aM.Extent();
     if (iNb!=iNbEx[i]){
       MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-      myErrorStatus=4; // number of subshape is not compatible
+      myErrorStatus->myName=4; // number of subshape is not compatible
+      myErrorStatus->myComment="Wrong number of subshapes of a block";
       return;
     }
   }
@@ -1682,6 +1668,28 @@ int StdMeshers_SMESHBlock::ErrorStatus() const
   return myErrorStatus;
 }
 
+//================================================================================
+/*!
+ * \brief Return problem description
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const
+{
+  SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
+  string & text = err->myComment;
+  switch ( myErrorStatus ) {
+  case 2:
+  case 3: text = "Internal error of StdMeshers_Penta_3D"; break; 
+  case 4: text = "Can't compute normalized parameters of a point inside a block"; break;
+  case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break;
+  case 6: text = "Can't detect block subshapes. Not a block?"; break;
+  }
+  if (!text.empty())
+    err->myName = myErrorStatus;
+  return err;
+}
+
 //=======================================================================
 //function : Load
 //purpose  : 
@@ -1710,7 +1718,7 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
   myShapeIDMap.Clear();  
   bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
   if (!bOk) {
-    myErrorStatus=2;
+    myErrorStatus=6;
     return;
   }
 }
@@ -1824,7 +1832,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
     }
   }
   if (!bOk) {
-    myErrorStatus=4; // problems with point computation 
+    myErrorStatus=5; // problems with point computation 
     return;
   }
   aP3D.SetXYZ(aXYZ);
index a635a3828f5800a9bd321e0b27ac3df7e07dcdc8..667b500969c292c982c9ba8395162ae290afd150 100644 (file)
@@ -42,7 +42,7 @@
 #include <TColStd_MapOfInteger.hxx>
 
 #include "SMESH_Block.hxx"
-
+#include "SMESH_ComputeError.hxx"
 #include "SMESH_MesherHelper.hxx"
 
 typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
@@ -87,6 +87,8 @@ public:
 
   int  ErrorStatus() const;
 
+  SMESH_ComputeErrorPtr GetError() const;
+
 
 protected:
   TopoDS_Shell                       myShell;
@@ -173,6 +175,12 @@ class StdMeshers_Penta_3D {
     bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
     
     int ErrorStatus() const {
+      if (myErrorStatus->IsOK())
+        return 0;
+      return myErrorStatus->myName;
+    }
+
+    SMESH_ComputeErrorPtr GetComputeError() const {
       return myErrorStatus;
     }
    
@@ -244,7 +252,7 @@ class StdMeshers_Penta_3D {
     TopoDS_Shape              myShape;
     StdMeshers_SMESHBlock     myBlock;
     void *                    myMesh;
-    int                       myErrorStatus;
+    SMESH_ComputeErrorPtr     myErrorStatus;
     //
     vector <StdMeshers_TNode> myTNodes;
     int                       myISize;
index dd2c271d5992b6999e738384e4a00e88539ad942..8d87d043fdc1240af6c03ddc410ec71f8bf532a5 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_EdgePosition.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "utilities.h"
 
@@ -55,6 +56,7 @@ using namespace std;
 // }
 
 typedef StdMeshers_ProjectionUtils TAssocTool;
+typedef SMESH_Comment              TCom;
 
 enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0,
        ID_TOP_FACE = SMESH_Block::ID_Fxy1,
@@ -227,15 +229,14 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh&                          a
 
 bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
 {
-  myHelper = new SMESH_MesherHelper( theMesh );
-  // to delete helper at exit from Compute()
-  std::auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
+  SMESH_MesherHelper helper( theMesh );
+  myHelper = &helper;
 
   myHelper->IsQuadraticSubMesh( theShape );
 
   // Analyse mesh and geomerty to find block subshapes and submeshes
   if ( !myBlock.Init( myHelper, theShape ))
-    return false;
+    return error( myBlock.GetError());
 
   SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
 
@@ -282,7 +283,9 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
     myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() );
     gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ];
     if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the top face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << column.back()->GetID()
+                   << " on the face #"<< column.back()->GetPosition()->GetShapeId() );
 
     // vertical loop
     TNodeColumn::iterator columnNodes = column.begin();
@@ -308,7 +311,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       // compute coords for a new node
       gp_XYZ coords;
       if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords ))
-        RETURN_BAD_RESULT("SMESH_Block::ShellPoint() failed");
+        return error(dfltErr(),"Can't compute coordinates by normalized parameters");
 
       // create a node
       node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
@@ -320,7 +323,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
   // Create volumes
 
   SMESHDS_SubMesh* smDS = myBlock.SubMeshDS( ID_BOT_FACE );
-  if ( !smDS ) RETURN_BAD_RESULT("Null submesh");
+  if ( !smDS ) return error(COMPERR_BAD_INPUT_MESH, "Null submesh");
 
   // loop on bottom mesh faces
   SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
@@ -341,13 +344,13 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
         bot_column = myBotToColumnMap.find( n );
         if ( bot_column == myBotToColumnMap.end() )
-          RETURN_BAD_RESULT(" node column for a node not found");
+          return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
         columns[ i ] = & bot_column->second;
       }
       else {
         columns[ i ] = myBlock.GetNodeColumn( n );
         if ( !columns[ i ] )
-          RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+          return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
       }
     }
     // create prisms
@@ -459,7 +462,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
   SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
 
   if ( !botSMDS || botSMDS->NbElements() == 0 )
-    RETURN_BAD_RESULT("Empty horiz submesh");
+    return error(dfltErr(),TCom("No elememts on face #") << botSM->GetId());
 
   bool needProject = false;
   if ( !topSMDS || 
@@ -467,12 +470,15 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
        botSMDS->NbNodes()    != topSMDS->NbNodes())
   {
     if ( myBlock.HasNotQuadElemOnTop() )
-      RETURN_BAD_RESULT("Different triangles on 2 sides");
+      return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                   <<" and #"<< topSM->GetId() << " seems different" );
     needProject = true;
   }
 
   if ( 0/*needProject && !myProjectTriangles*/ )
-    RETURN_BAD_RESULT("Need to project but not allowed");
+    return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
+  ///RETURN_BAD_RESULT("Need to project but not allowed");
 
   if ( needProject )
   {
@@ -486,14 +492,16 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
   if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(),
                                              topFace, myBlock.Mesh(),
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(dfltErr(),TCom("Topology of faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
 
   // Find matching nodes of top and bottom faces
   TNodeNodeMap n2nMap;
   if ( ! TAssocTool::FindMatchingNodesOnFaces( botFace, myBlock.Mesh(),
                                                topFace, myBlock.Mesh(),
                                                shape2ShapeMap, n2nMap ))
-    RETURN_BAD_RESULT("Different mesh on top and bottom faces");
+    return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
 
   // Fill myBotToColumnMap
 
@@ -508,7 +516,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
     // compute bottom node params
     TNode bN( botNode );
     if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
     // create node column
     TNode2ColumnMap::iterator bN_col = 
       myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
@@ -555,12 +564,14 @@ bool StdMeshers_Prism_3D::projectBottomToTop()
     // compute bottom node params
     TNode bN( botNode );
     if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
     // compute top node coords
     gp_XYZ topXYZ; gp_XY topUV;
     if ( !myBlock.FacePoint( ID_TOP_FACE, bN.GetParams(), topXYZ ) ||
          !myBlock.FaceUV   ( ID_TOP_FACE, bN.GetParams(), topUV ))
-      RETURN_BAD_RESULT("SMESH_Block::FacePoint() on the top face failed");
+      return error(dfltErr(),TCom("Can't compute coordinates ")
+                   << "by normalized parameters on the face #"<< topSM->GetId() );
     SMDS_MeshNode * topNode = meshDS->AddNode( topXYZ.X(),topXYZ.Y(),topXYZ.Z() );
     meshDS->SetNodeOnFace( topNode, topFaceID, topUV.X(), topUV.Y() );
     // create node column
@@ -593,13 +604,13 @@ bool StdMeshers_Prism_3D::projectBottomToTop()
       if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
         TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n );
         if ( bot_column == myBotToColumnMap.end() )
-          RETURN_BAD_RESULT(" node column for a node not found");
+          return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
         nodes[ i ] = bot_column->second.back();
       }
       else {
         const TNodeColumn* column = myBlock.GetNodeColumn( n );
         if ( !column )
-          RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+          return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
         nodes[ i ] = column->back();
       }
     }
@@ -711,6 +722,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     SMESH_Block::ID_Fx1z, SMESH_Block::ID_F0yz
   };
 
+  myError = SMESH_ComputeError::New();
+
   // -------------------------------------------------------------
   // Look for top and bottom faces: not quadrangle ones or meshed
   // with not quadrangle elements
@@ -721,14 +734,13 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   int nbFaces = 0;
   //
   SMESH_subMesh* mainSubMesh = myHelper->GetMesh()->GetSubMeshContaining( shape3D );
-  if ( !mainSubMesh ) RETURN_BAD_RESULT("Null submesh of shape3D");
+  if ( !mainSubMesh ) return error(COMPERR_BAD_INPUT_MESH,"Null submesh of shape3D");
 
   // analyse face submeshes
-  const map< int, SMESH_subMesh * >& subSM = mainSubMesh->DependsOn();
-  map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
-  for ( ; i_subSM != subSM.end(); ++i_subSM )
+  SMESH_subMeshIteratorPtr smIt = mainSubMesh->getDependsOnIterator(false,false);
+  while ( smIt->more() )
   {
-    SMESH_subMesh* sm = i_subSM->second;
+    SMESH_subMesh* sm = smIt->next();
     const TopoDS_Shape& face = sm->GetSubShape();
     if ( face.ShapeType() != TopAbs_FACE )
       continue;
@@ -760,7 +772,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
         notQuadElemSubMesh.push_back( sm );
     }
     else {
-      RETURN_BAD_RESULT("not meshed face");
+      return error(COMPERR_BAD_INPUT_MESH,TCom("Not meshed face #")<<sm->GetId());
     }
     // check if a quadrangle face is meshed with a quadranglar grid
     if ( notQuadGeomSubMesh.back() != sm &&
@@ -800,9 +812,13 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
   // detect bad cases
   if ( nbNotQuad > 0 && nbNotQuad != 2 )
-    RETURN_BAD_RESULT("Wrong shape geometry");
+    return error(COMPERR_BAD_SHAPE,
+                 TCom("More than 2 not quadrilateral faces")
+                 <<nbNotQuad);
   if ( nbNotQuadMeshed > 2 )
-    RETURN_BAD_RESULT("More then 2 faces meshed with not quadrangle elements");
+    return error(COMPERR_BAD_INPUT_MESH,
+                 TCom("More then 2 faces meshed with not quadrangle elements")
+                 <<nbNotQuadMeshed);
 
   // get found submeshes
   if ( hasNotQuad )
@@ -821,11 +837,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     else
       ok = ( notQuadGeomSubMesh == notQuadElemSubMesh );
     if ( !ok )
-      RETURN_BAD_RESULT("Side face meshed with not quadrangle elements");
+      return error(COMPERR_BAD_INPUT_MESH, "Side face meshed with not quadrangle elements");
   }
 
   myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
-    
   // ----------------------------------------------------------
 
   if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ?
@@ -873,7 +889,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     // Load geometry in SMESH_Block
     if ( !SMESH_Block::FindBlockShapes( shell, Vbot, Vtop, myShapeIDMap )) {
       if ( !hasNotQuad )
-        RETURN_BAD_RESULT("Can not detect top and bottom");
+        return error(COMPERR_BAD_SHAPE, "Can't detect top and bottom of a prism");
     }
     else {
       if ( !botSM ) botSM = Mesh()->GetSubMeshContaining( myShapeIDMap( ID_BOT_FACE ));
@@ -927,7 +943,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   // Get Wall faces corresponding to the ordered bottom edges
   list< TopoDS_Face > wallFaces;
   if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces))
-    RETURN_BAD_RESULT("GetWallFaces() failed");
+    return error(COMPERR_BAD_SHAPE, "Can't find side faces");
 
   // Find columns of wall nodes and calculate edges' lengths
   // --------------------------------------------------------
@@ -945,7 +961,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   {
     TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
     if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
-      RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+      return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+                   << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
 
     SHOWYXZ("\np1 F "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
     SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
@@ -957,7 +974,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     {
       SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edgeIt);
       if ( !smDS )
-        RETURN_BAD_RESULT("Null submesh on a bottom edge");
+        return error(COMPERR_BAD_INPUT_MESH, TCom("Null submesh on the edge #")
+                     << MeshDS()->ShapeToIndex( *edgeIt ));
       // assure length uniqueness
       edgeLength[ iE ] *= smDS->NbNodes() + edgeLength[ iE ] / ( 1000 + iE );
       len2edgeMap[ edgeLength[ iE ]] = iE;
@@ -970,7 +988,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   {
     TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
     if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
-      RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+      return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+                   << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
     // edge columns
     int id = MeshDS()->ShapeToIndex( *edgeIt );
     bool isForward = true; // meaningless for intenal wires
index e4e12eb833b854aa024909ce01aa296485cddd3f..55a2495707e4b9e6c72e9b304a054f9f9b884e5b 100644 (file)
@@ -35,6 +35,7 @@
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <vector.h>
 #include <map.h>
@@ -114,6 +115,11 @@ public:
    */
   bool Init(SMESH_MesherHelper* helper, const TopoDS_Shape& shape3D);
 
+  /*!
+   * \brief Return problem description
+   */
+  SMESH_ComputeErrorPtr GetError() const { return myError; }
+
   /*!
    * \brief Return number of nodes on every vertical edge
     * \retval int - number of nodes including end nodes
@@ -342,7 +348,14 @@ private:
   // to find a column for a node by edge SMESHDS Index
   map< int, pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap;
 
-  
+  SMESH_ComputeErrorPtr myError;
+  /*!
+   * \brief store error and comment and then return ( error == COMPERR_OK )
+   */
+  bool error(int error, const SMESH_Comment& comment = "") {
+    myError = SMESH_ComputeError::New(error,comment);
+    return myError->IsOK();
+  }
   //vector< SMESH_subMesh* >           mySubMeshesVec; // submesh by in-block id
 };
 
index d9c58e9d7aa42d3c1f0b5350fa192db7ef3e24b3..c276b3afa70705ebc049ab19c2630874c39b7d21 100644 (file)
@@ -1238,7 +1238,7 @@ namespace {
     HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh
 
     void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
-                      EventListenerData*, SMESH_Hypothesis*)
+                      EventListenerData*, const SMESH_Hypothesis*)
     {
       if ( event     == SMESH_subMesh::MODIF_HYP &&
            eventType == SMESH_subMesh::ALGO_EVENT)
index 571d3990abea306913a576210fe37055a52a5d3c..1bfdc41c5a3db5df1be7bbeb0f09afcc6b4584c5 100644 (file)
@@ -41,6 +41,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRep_Tool.hxx>
@@ -190,7 +191,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(dfltErr(),SMESH_Comment("Vertices association failed" ));
 
   // ----------------------------------------------
   // Assure that mesh on a source edge is computed
@@ -201,11 +202,11 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   if ( tgtMesh == srcMesh ) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   // -----------------------------------------------
   // Find out nodes distribution on the source edge
@@ -216,7 +217,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   
   vector< double > params; // sorted parameters of nodes on the source edge
   if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
-    RETURN_BAD_RESULT("Bad node params on the source edge");
+    return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
 
   int i, nbNodes = params.size();
 
@@ -248,20 +249,10 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   vector< const SMDS_MeshNode* > nodes ( nbNodes );
 
   // Get the first and last nodes
-  // -----------------------------
-
-  SMESHDS_SubMesh* smV0 = meshDS->MeshElements( tgtV[0] );
-  SMESHDS_SubMesh* smV1 = meshDS->MeshElements( tgtV[1] );
-  if ( !smV0 || !smV1 )
-    RETURN_BAD_RESULT("No submeshes on vertices");
-
-  SMDS_NodeIteratorPtr nItV0 = smV0->GetNodes();
-  SMDS_NodeIteratorPtr nItV1 = smV1->GetNodes();
-  if ( !nItV0->more() || !nItV1->more() )
-    RETURN_BAD_RESULT("No nodes on vertices");
-
-  nodes.front() = nItV0->next();
-  nodes.back()  = nItV1->next();
+  nodes.front() = VertexNode( tgtV[0], meshDS );
+  nodes.back()  = VertexNode( tgtV[1], meshDS );
+  if ( !nodes.front() || !nodes.back() )
+    return error(COMPERR_BAD_INPUT_MESH,"No node on vertex");
 
   // Compute parameters on the target edge and make internal nodes
   // --------------------------------------------------------------
@@ -284,7 +275,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       // from the point at given parameter.
       GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] );
       if ( !Discret.IsDone() )
-        RETURN_BAD_RESULT(" GCPnts_AbscissaPoint failed");
+        return error(dfltErr(),"GCPnts_AbscissaPoint failed");
       tgtParams[ i ] = Discret.Parameter();
     }
     // make internal nodes 
@@ -324,7 +315,8 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
   // enough nodes to make all edges quadratic?
   if ( quadratic && ( nbNodes < 3 || ( nbNodes % 2 != 1 )))
-    RETURN_BAD_RESULT("Wrong nb nodes to make quadratic mesh");
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Wrong number of nodes to make quadratic mesh: ")<<nbNodes);
 
   // Create edges
   // -------------
index 510589f9005d6cebf5d6839e101d2b5ba8c5d198..4aa83bdd0c30c2482d9e7385284911119602d00b 100644 (file)
@@ -41,6 +41,7 @@
 #include "SMESH_Pattern.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMDS_EdgePosition.hxx"
 
 #include "utilities.h"
@@ -223,10 +224,9 @@ namespace {
         // do not break but iterate over DependsOn()
       }
       default:
-        const map< int, SMESH_subMesh * >& subSM = sm->DependsOn();
-        map< int, SMESH_subMesh * >::const_iterator i_sm = subSM.begin();
-        for ( ; i_sm != subSM.end(); ++i_sm )
-          Clean( i_sm->second );
+        SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false);
+        while ( smIt->more() )
+          Clean( smIt->next() );
       }
     }
   };
@@ -386,7 +386,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcFace, srcMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
 
   // ----------------------------------------------
   // Assure that mesh on a source Face is computed
@@ -397,11 +397,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   if ( tgtMesh == srcMesh ) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
 
   // --------------------
@@ -412,7 +412,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   SMESH_Pattern mapper;
   mapper.Load( srcMesh, srcFace );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::Load() failed");
+    return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
 
   // Find the first target vertex corresponding to first vertex of the <mapper>
   // and <theReverse> flag needed to call mapper.Apply()
@@ -463,14 +463,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   mapper.Apply( tgtFace, tgtV1, reverse );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::Apply() failed");
+    return error(dfltErr(),"Can't apply source mesh pattern to the face");
 
   // Create the mesh
 
   const bool toCreatePolygons = false, toCreatePolyedrs = false;
   mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::MakeMesh() failed");
+    return error(dfltErr(),"Can't make mesh by source mesh pattern");
 
   // it will remove mesh built by pattern mapper on edges and vertices
   // in failure case
@@ -487,11 +487,10 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // Make groups of nodes to merge
 
   // loop on edge and vertex submeshes of a target face
-  const map< int, SMESH_subMesh * >& subSM = tgtSubMesh->DependsOn();
-  map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
-  for ( ; i_subSM != subSM.end(); ++i_subSM )
+  SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false);
+  while ( smIt->more() )
   {
-    SMESH_subMesh*     sm = i_subSM->second;
+    SMESH_subMesh*     sm = smIt->next();
     SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
 
     // Sort new and old nodes of a submesh separately
index 1d8bce6d82ec8402d72b856c7338d499e8e04d80..68eda5d6593ea297364697efd0f8b1d9b276a54b 100644 (file)
@@ -42,6 +42,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 
@@ -204,13 +205,15 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
     srcShell = TopoDS::Shell( exp.Current() );
   if ( nbShell != 1 )
-    RETURN_BAD_RESULT("There must be 1 shell in the source shape");
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Shape must have 1 shell but not") << nbShell);
 
   exp.Init( aShape, TopAbs_SHELL );
   for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
     tgtShell = TopoDS::Shell( exp.Current() );
   if ( nbShell != 1 )
-    RETURN_BAD_RESULT("There must be 1 shell in the target shape");
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Shape must have 1 shell but not") << nbShell);
 
   // Assure that mesh on a source shape is computed
 
@@ -219,11 +222,11 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
 
   if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
 
   // Find 2 pairs of corresponding vertices
@@ -242,18 +245,18 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   {
     if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh,
                                                shape2ShapeMap) )
-      RETURN_BAD_RESULT("FindSubShapeAssociation() failed");
+      return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" );
 
     exp.Init( tgtShell, TopAbs_EDGE );
     TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );
 
     if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
-      RETURN_BAD_RESULT("Shape associating not done");
+      return error(dfltErr(),"Association of subshapes failed" );
     srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
     srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
     if ( !TAssocTool::IsSubShape( srcV000, srcShell ) ||
          !TAssocTool::IsSubShape( srcV100, srcShell ))
-      RETURN_BAD_RESULT("Wrong target vertices");
+      return error(dfltErr(),"Incorrect association of subshapes" );
   }
 
   // Load 2 SMESH_Block's with src and tgt shells
@@ -261,10 +264,10 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   SMESH_Block srcBlock, tgtBlock;
   TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
   if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
-    RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(tgtShell) failed");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
 
   if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
-    RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(srcShell) failed");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
 
   // Find matching nodes of src and tgt shells
 
@@ -293,9 +296,9 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     TNodeNodeMap faceMatchingNodes;
     if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, 
                                                  shape2ShapeMap, faceMatchingNodes ))
-      RETURN_BAD_RESULT("Different mesh on corresponding src and tgt faces: "
-                        << srcMeshDS->ShapeToIndex( srcFace ) << " and "
-                        << tgtMeshDS->ShapeToIndex( tgtFace ));
+    return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+                 << srcMeshDS->ShapeToIndex( srcFace ) << " and "
+                 << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
 
     // put found matching nodes of 2 faces to the global map
     src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
@@ -339,11 +342,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
         gp_Pnt srcCoord = gpXYZ( srcNode );
         gp_XYZ srcParam;
         if ( !srcBlock.ComputeParameters( srcCoord, srcParam ))
-          RETURN_BAD_RESULT("srcBlock.ComputeParameters() failed");
+          return error(dfltErr(),SMESH_Comment("Can't compute normalized parameters ")
+                       << "for source node " << srcNode->GetID());
         // compute coordinates of target node by srcParam
         gp_XYZ tgtXYZ;
         if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ ))
-          RETURN_BAD_RESULT("tgtBlock.ShellPoint() failed");
+          return error(dfltErr(),"Can't compute coordinates by normalized parameters");
         // add node
         SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() );
         tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() );
@@ -356,20 +360,21 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     // Create a new volume
 
     SMDS_MeshVolume * tgtVol = 0;
+    int id = 0, force3d = false;
     switch ( volType ) {
     case SMDS_VolumeTool::TETRA     :
     case SMDS_VolumeTool::QUAD_TETRA:
       tgtVol = helper.AddVolume( nodes[0],
                                  nodes[1],
                                  nodes[2],
-                                 nodes[3]); break;
+                                 nodes[3], id, force3d); break;
     case SMDS_VolumeTool::PYRAM     :
     case SMDS_VolumeTool::QUAD_PYRAM:
       tgtVol = helper.AddVolume( nodes[0],
                                  nodes[1],
                                  nodes[2],
                                  nodes[3],
-                                 nodes[4]); break;
+                                 nodes[4], id, force3d); break;
     case SMDS_VolumeTool::PENTA     :
     case SMDS_VolumeTool::QUAD_PENTA:
       tgtVol = helper.AddVolume( nodes[0],
@@ -377,7 +382,7 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[2],
                                  nodes[3],
                                  nodes[4],
-                                 nodes[5]); break;
+                                 nodes[5], id, force3d); break;
     case SMDS_VolumeTool::HEXA      :
     case SMDS_VolumeTool::QUAD_HEXA :
       tgtVol = helper.AddVolume( nodes[0],
@@ -387,16 +392,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[4],
                                  nodes[5],
                                  nodes[6],
-                                 nodes[7]); break;
+                                 nodes[7], id, force3d); break;
     default: // polyhedron
       const SMDS_PolyhedralVolumeOfNodes * poly =
         dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
       if ( !poly )
         RETURN_BAD_RESULT("Unexpected volume type");
-      vector<int> quantities( poly->NbFaces(), 0 );
-      for ( int i = 0; i < quantities.size(); ++i )
-        quantities[ i ] = poly->NbFaceNodes( i + 1 );
-      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, quantities );
+      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
     }
     if ( tgtVol ) {
       tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
index 2591d309d49f73e2a62f2fdf5e6709517a536950..2b701a07ace79d8d21b4caf305e25eed1c610d02 100644 (file)
 
 #include "utilities.h"
 
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMDS_SetIterator.hxx"
+
 using namespace std;
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId,
-                                                SMESH_Gen * gen)
-     : SMESH_Hypothesis(hypId, studyId, gen)
-{
-  _name = GetName();
-  _param_algo_dim = -1; // 1D auxiliary
-}
+namespace {
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::~StdMeshers_Propagation()
-{
+  // =======================================================================
+  /*!
+   * \brief Listener managing propagation of 1D hypotheses
+   */
+  // =======================================================================
+
+  class PropagationMgr: public SMESH_subMeshEventListener
+  {
+  public:
+    static PropagationMgr* GetListener();
+    /*!
+     * \brief Set listener on edge submesh
+     */
+    static void Set(SMESH_subMesh * submesh);
+    /*!
+     * \brief Return an edge from which hypotheses are propagated from
+     */
+    static TopoDS_Edge GetSource(SMESH_subMesh * submesh);
+    /*!
+     * \brief Does it's main job
+     */
+    void ProcessEvent(const int          event,
+                      const int          eventType,
+                      SMESH_subMesh*     subMesh,
+                      SMESH_subMeshEventListenerData* data,
+                      const SMESH_Hypothesis*         hyp = 0);
+  private:
+    PropagationMgr();
+  };
 }
 
 //=============================================================================
 /*!
- *
+ * StdMeshers_Propagation Implementation
  */
 //=============================================================================
 
-ostream & StdMeshers_Propagation::SaveTo (ostream & save)
+StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Gen * gen)
+  : SMESH_Hypothesis(hypId, studyId, gen)
 {
-  return save;
+  _name = GetName();
+  _param_algo_dim = -1; // 1D auxiliary
 }
-
-//=============================================================================
+StdMeshers_Propagation::~StdMeshers_Propagation()                      {}
+string StdMeshers_Propagation::GetName ()                              { return "Propagation"; }
+ostream & StdMeshers_Propagation::SaveTo (ostream & save)              { return save; }
+istream & StdMeshers_Propagation::LoadFrom (istream & load)            { return load; }
+ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)   { return hyp.SaveTo(save); }
+istream & operator >> (istream & load, StdMeshers_Propagation & hyp)   { return hyp.LoadFrom(load); }
+bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*,
+                                                 const TopoDS_Shape& ) { return false; }
+void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); }
 /*!
- *
+ * \brief Return an edge from which hypotheses are propagated from
  */
-//=============================================================================
-istream & StdMeshers_Propagation::LoadFrom (istream & load)
+TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
+                                                         const TopoDS_Shape& theEdge)
 {
-  return load;
+  return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
 }
 
 //=============================================================================
-/*!
- *
- */
 //=============================================================================
-ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)
-{
-  return hyp.SaveTo(save);
-}
-
+// PROPAGATION MANAGEMENT
 //=============================================================================
-/*!
- *
- */
 //=============================================================================
-istream & operator >> (istream & load, StdMeshers_Propagation & hyp)
-{
-  return hyp.LoadFrom(load);
-}
 
-//=============================================================================
-/*!
- *  GetName
- */
-//=============================================================================
-std::string StdMeshers_Propagation::GetName ()
-{
-  return "Propagation";
-}
-//================================================================================
-/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as this hypothesis does not have parameters values
- */
-//================================================================================
+namespace {
 
-bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
-                                                 const TopoDS_Shape& /*theShape*/)
-{
-  return false;
-}
+  enum SubMeshState { WAIT_PROPAG_HYP, // no propagation hyp in chain
+                      HAS_PROPAG_HYP,  // propag hyp on this submesh
+                      IN_CHAIN,        // submesh is in propagation chain
+                      LAST_IN_CHAIN,   // submesh with local 1D hyp breaking a chain
+                      MEANINGLESS_LAST };          // meaningless
+
+  struct PropagationMgrData : public EventListenerData
+  {
+    bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge
+    PropagationMgrData( SubMeshState state ): EventListenerData(true) {
+      myType = state;
+    }
+    SubMeshState State() const {
+      return (SubMeshState) myType;
+    }
+    void SetSource(SMESH_subMesh* sm ) {
+      mySubMeshes.clear(); if ( sm ) mySubMeshes.push_back( sm );
+    }
+    void SetChain(list< SMESH_subMesh* >& chain ) {
+      mySubMeshes.clear(); mySubMeshes.splice( mySubMeshes.end(), chain );
+    }
+    SMESH_subMeshIteratorPtr GetChain() const;
+    SMESH_subMesh* GetSource() const;
+  };
+
+  //=============================================================================
+  /*!
+   * \brief return filter to find Propagation hypothesis
+   */
+  SMESH_HypoFilter & propagHypFilter()
+  {
+    static SMESH_HypoFilter propagHypFilter
+      ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ()));
+    return propagHypFilter;
+  }
+  //=============================================================================
+  /*!
+   * \brief return static PropagationMgr
+   */
+  PropagationMgr* PropagationMgr::GetListener()
+  {
+    static PropagationMgr theListener;
+    return &theListener;
+  }
+  PropagationMgr* getListener()
+  {
+    return PropagationMgr::GetListener();
+  }
+  //=============================================================================
+  /*!
+   * \brief return PropagationMgrData
+   */
+  PropagationMgrData* getData(SMESH_subMesh* sm)
+  {
+    if ( sm )
+      return static_cast< PropagationMgrData* >( sm->GetEventListenerData( getListener() ));
+    return 0;
+  }
+  //=============================================================================
+  /*!
+   * \brief return PropagationMgrData
+   */
+  PropagationMgrData* getData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge)
+  {
+    if ( theEdge.ShapeType() == TopAbs_EDGE )
+      return getData( theMesh.GetSubMeshContaining( theEdge ) );
+    return 0;
+  }
+  //================================================================================
+  /*!
+   * \brief Return an iterator on a chain
+   */
+  SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const
+  {
+    typedef SMESH_subMesh* TsubMesh;
+    typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator;
+    switch ( State() ) {
+    case HAS_PROPAG_HYP:
+      return SMESH_subMeshIteratorPtr
+        ( new TIterator( mySubMeshes.begin(), mySubMeshes.end() ));
+    case IN_CHAIN:
+    case LAST_IN_CHAIN:
+      if ( mySubMeshes.empty() ) break;
+      return getData( mySubMeshes.front() )->GetChain();
+    default:;
+    }
+    return SMESH_subMeshIteratorPtr
+      ( new TIterator( mySubMeshes.end(), mySubMeshes.end() ));
+  }
+  //================================================================================
+  /*!
+   * \brief Return a propagation source submesh
+   */
+  SMESH_subMesh* PropagationMgrData::GetSource() const
+  {
+    if ( myType == IN_CHAIN || myType == LAST_IN_CHAIN )
+      if ( !mySubMeshes.empty() ) 
+        return mySubMeshes.front();
+    return 0;
+  }
+  //=============================================================================
+  /*!
+   * \brief Returns a local 1D hypothesis used for theEdge
+   */
+  const SMESH_Hypothesis* isLocal1DHypothesis (SMESH_Mesh& theMesh,
+                                               const TopoDS_Shape& theEdge)
+  {
+    static SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 ));
+    hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() ));
+
+    return theMesh.GetHypothesis( theEdge, hypo, true );
+  }
+  //================================================================================
+  /*!
+   * \brief Build propagation chain
+    * \param theMainSubMesh - the submesh with Propagation hypothesis
+   */
+  bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh )
+  {
+  //   const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape();
+//     if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
+
+//     SMESH_Mesh* mesh = theMainSubMesh->GetFather();
+
+//     EventListenerData* chainData = new PropagationMgrData(HAS_PROPAG_HYP);
+//     theMainSubMesh->SetEventListener( getListener(), chainData, theMainSubMesh );
+
+//     // Edges submeshes, on which the 1D hypothesis will be propagated from <theMainEdge>
+//     list<SMESH_subMesh*> & chain = chainData->mySubMeshes;
+
+//     // List of edges, added to chain on the previous cycle pass
+//     TopTools_ListOfShape listPrevEdges;
+//     listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
+
+//     //   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 (mesh->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;
+//               }
+//               if (anEdges(nb).IsSame(anE)) found = nb;
+//             }
+
+//             if (nb == 5 && found > 0) {
+//               // Quadrangle face found, get an opposite edge
+//               Standard_Integer opp = ( found + 2 ) % 4;
+//               anOppE = anEdges(opp);
+
+//               // add anOppE to aChain if ...
+//               PropagationMgrData* data = getData( *mesh, anOppE );
+//               if ( !data || data->State() == WAIT_PROPAG_HYP ) { // ... anOppE is not in any chain
+//                 if ( !isLocal1DHypothesis( *mesh, anOppE )) { // ... no other 1d hyp on anOppE
+//                   // Add found edge to the chain oriented so that to
+//                   // have it co-directed with a forward MainEdge
+//                     TopAbs_Orientation ori = anE.Orientation();
+//                     if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
+//                       ori = TopAbs::Reverse( ori );
+//                     anOppE.Orientation( ori );
+//                     aChain.Add(anOppE);
+//                     listCurEdges.Append(anOppE);
+//                   }
+//                   else {
+//                     // Collision!
+//                     MESSAGE("Error: Collision between propagated hypotheses");
+//                     CleanMeshOnPropagationChain(theMainEdge);
+//                     aChain.Clear();
+//                     return ( aMainHyp == isLocal1DHypothesis(aMainEdgeForOppEdge) );
+//                   }
+//                 }
+//               }
+//             } // 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;
+  }
+  //================================================================================
+  /*!
+   * \brief Clear propagation chain
+   */
+  //================================================================================
+
+  bool clearPropagationChain( SMESH_subMesh* subMesh )
+  {
+    if ( PropagationMgrData* data = getData( subMesh )) {
+      if ( data->State() == IN_CHAIN )
+        return clearPropagationChain( data->GetSource() );
+      return true;
+    }
+    return false;
+  }  
+
+
+  //================================================================================
+  /*!
+   * \brief Constructor
+   */
+  PropagationMgr::PropagationMgr()
+    : SMESH_subMeshEventListener( false ) // won't be deleted by submesh
+  {}
+  //================================================================================
+  /*!
+   * \brief Set PropagationMgr on a submesh
+   */
+  void PropagationMgr::Set(SMESH_subMesh * submesh)
+  {
+    EventListenerData* data = EventListenerData::MakeData(submesh,WAIT_PROPAG_HYP);
+
+    submesh->SetEventListener( getListener(), data, submesh );
+
+    const SMESH_Hypothesis * propagHyp =
+      submesh->GetFather()->GetHypothesis( submesh->GetSubShape(), propagHypFilter(), true );
+    if ( propagHyp )
+      getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP,
+                                   SMESH_subMesh::ALGO_EVENT,
+                                   submesh,
+                                   data,
+                                   propagHyp);
+  }
+
+  //================================================================================
+  /*!
+   * \brief React on events on 1D submeshes
+   */
+  //================================================================================
+
+  void PropagationMgr::ProcessEvent(const int          event,
+                                    const int          eventType,
+                                    SMESH_subMesh*     subMesh,
+                                    SMESH_subMeshEventListenerData* data,
+                                    const SMESH_Hypothesis*         hyp)
+  {
+    if ( !data )
+      return;
+    if ( !hyp || hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO || hyp->GetDim() != 1 )
+      return;
+    if ( eventType != SMESH_subMesh::ALGO_EVENT )
+      return;
+
+    bool isPropagHyp = ( StdMeshers_Propagation::GetName() != hyp->GetName() );
+
+    switch ( data->myType ) {
+
+    case WAIT_PROPAG_HYP: { // no propagation hyp in chain
+      // --------------------------------------------------------
+      if ( !isPropagHyp )
+        return;
+      if ( !isLocal1DHypothesis( *subMesh->GetFather(), subMesh->GetSubShape()))
+        return;
+      if ( event == SMESH_subMesh::ADD_HYP ||
+           event == SMESH_subMesh::ADD_FATHER_HYP ) // add propagation hyp
+      {
+        // build propagation chain
+        clearPropagationChain( subMesh );
+        buildPropagationChain( subMesh );
+      }
+      return;
+    }
+    case HAS_PROPAG_HYP: {  // propag hyp on this submesh
+      // --------------------------------------------------------
+      switch ( event ) {
+      case SMESH_subMesh::REMOVE_HYP:
+      case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
+        if ( isPropagHyp )
+        {
+          // clear propagation chain
+        }
+        return;
+      case SMESH_subMesh::MODIF_HYP: // hyp modif
+        // clear mesh in a chain
+        return;
+      }
+      return;
+    }
+    case IN_CHAIN: {       // submesh is in propagation chain
+      // --------------------------------------------------------
+      if ( event == SMESH_subMesh::ADD_HYP ) // add local hypothesis
+        if ( isPropagHyp )
+          ; // collision
+        else
+          ; // rebuild propagation chain
+        return;
+    }
+    case LAST_IN_CHAIN: { // submesh with local 1D hyp, breaking a chain
+      // --------------------------------------------------------
+      if ( event == SMESH_subMesh::REMOVE_HYP ) // remove local hyp
+        ; // rebuild propagation chain
+      return;
+    }
+    } // switch by SubMeshState
+  }
+} // namespace
index 40bbdff2dd012ee1883df0c680d4bc6be497436d..fb350a7d2f06369fe9158e24ece87c2a92d8f888 100644 (file)
 #define _SMESH_PROPAGATION_HXX_
 
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMeshEventListener.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include <TopoDS_Edge.hxx>
+
+
+// =======================================================================
+/*!
+ * \brief Propagation hypothesis
+ */
+// =======================================================================
+
 class StdMeshers_Propagation:public SMESH_Hypothesis
 {
  public:
@@ -43,6 +53,22 @@ class StdMeshers_Propagation:public SMESH_Hypothesis
 
   static std::string GetName ();
 
+  /*!
+   * \brief Set EventListener managing propagation of hypotheses
+    * \param subMesh - edge submesh to set event listener on
+   * 
+   * 1D algo is expected to call this method from it's SetEventListener()
+   */
+  static void SetPropagationMgr(SMESH_subMesh* subMesh);
+
+  /*!
+   * \brief Return an edge from which hypotheses are propagated from
+    * \param theMesh - mesh
+    * \param theEdge - edge to which hypotheses are propagated
+    * \retval TopoDS_Edge - source edge, also passing orientation
+   */
+  static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge);
+
   /*!
    * \brief Initialize my parameter values by the mesh built on the geometry
     * \param theMesh - the built mesh
@@ -53,5 +79,4 @@ class StdMeshers_Propagation:public SMESH_Hypothesis
    */
   virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
 };
-
 #endif
index 589ca5267154eb5c1ee17ab5217ee835f5e54a02..0b0d057ed58edecc2ec47bb650894210a645514f 100644 (file)
@@ -36,6 +36,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -74,6 +75,7 @@ DEFINE_ARRAY2(StdMeshers_Array2OfNode,
 using namespace std;
 
 typedef gp_XY gp_UV;
+typedef SMESH_Comment TComm;
 
 //=============================================================================
 /*!
@@ -573,7 +575,7 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
   list< int > nbEdgesInWire;
   int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
   if (nbWire != 1) {
-    INFOS("only 1 wire by face (quadrangles)");
+    error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire);
     return 0;
   }
   FaceQuadStruct* quad = new FaceQuadStruct;
@@ -623,9 +625,8 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMes
       cout << ")";
     }
     cout << endl;
-#else
-    INFOS("face must have 4 edges / quadrangle");
 #endif
+    error(COMPERR_BAD_SHAPE, TComm("Face must have 4 side but not ") << nbSides);
     delete quad;
     quad = 0;
   }
@@ -668,7 +669,6 @@ faceQuadStruct::~faceQuadStruct()
 {
   for (int i = 0; i < side.size(); i++) {
     if (side[i])     delete side[i];
-    //if (uv_edges[i]) delete [] uv_edges[i];
   }
   if (uv_grid)       delete [] uv_grid;
 }
@@ -676,7 +676,7 @@ faceQuadStruct::~faceQuadStruct()
 namespace {
   inline const vector<UVPtStruct>& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg)
   {
-    bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE );
+    bool   isXConst   = ( i == BOTTOM_SIDE || i == TOP_SIDE );
     double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1;
     return
       quad->isEdgeOut[i] ?
@@ -735,10 +735,8 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
   const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 );
 
-  if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) {
-    MESSAGE("Nodes from edges not loaded");
-    return false;
-  }
+  if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
+    return error(dfltErr(), "Can't find nodes on sides");
 
   // nodes Id on "in" edges
   if (! quad->isEdgeOut[0]) {
@@ -876,25 +874,19 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1,
 
   uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
 
-  //cout<<"x0="<<x0<<" x1="<<x1<<" y0="<<y0<<" y1="<<y1<<endl;
-  //cout<<"x="<<x<<" y="<<y<<endl;
-  //cout<<"param_b="<<param_b<<" param_t="<<param_t<<" param_r="<<param_r<<" param_l="<<param_l<<endl;
-  //cout<<"u="<<u<<" v="<<v<<endl;
-
   return uv;
 }
 
-//=======================================================================
-//function : ComputeQuadPref
-//purpose  : 
 //=======================================================================
 /*!
- * Special function for creation only quandrangle faces
+ * Create only quandrangle faces
  */
-bool StdMeshers_Quadrangle_2D::ComputeQuadPref
-                          (SMESH_Mesh &        aMesh,
-                           const TopoDS_Shape& aShape,
-                           FaceQuadStruct*     quad) throw (SALOME_Exception)
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
+                                                const TopoDS_Shape& aShape,
+                                                FaceQuadStruct*     quad)
+  throw (SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
index 0b6a697cce73cda3cde8205209e004522b218f60..c83bff5250a62d5bf73eee982f1b4d511d9f5b41 100644 (file)
@@ -167,7 +167,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     if ( !outerShell.IsSame( It.Value() ))
       innerShell = It.Value();
   if ( nbShells != 2 )
-    RETURN_BAD_RESULT("Must be 2 shells");
+    return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not")<<nbShells);
 
   // ----------------------------------
   // Associate subshapes of the shells
@@ -177,7 +177,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
   if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
                                              innerShell, &aMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
 
   // ------------------
   // Make mesh
@@ -192,7 +192,8 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     TopoDS_Face outFace = TopoDS::Face( exp.Current() );
     TopoDS_Face inFace;
     if ( !shape2ShapeMap.IsBound( outFace )) {
-      RETURN_BAD_RESULT("Association not found for face " << meshDS->ShapeToIndex( outFace ));
+      return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" )
+                   << meshDS->ShapeToIndex( outFace ));
     } else {
       inFace = TopoDS::Face( shape2ShapeMap( outFace ));
     }
@@ -201,9 +202,10 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     TNodeNodeMap nodeIn2OutMap;
     if ( ! TAssocTool::FindMatchingNodesOnFaces( inFace, &aMesh, outFace, &aMesh,
                                                  shape2ShapeMap, nodeIn2OutMap ))
-      RETURN_BAD_RESULT("Different mesh on corresponding out and in faces: "
-                        << meshDS->ShapeToIndex( outFace ) << " and "
-                        << meshDS->ShapeToIndex( inFace ));
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+                   << meshDS->ShapeToIndex( outFace ) << " and "
+                   << meshDS->ShapeToIndex( inFace ) << " seems different" );
+
     // Create volumes
 
     SMDS_ElemIteratorPtr faceIt = meshDS->MeshElements( inFace )->GetElements();
@@ -252,9 +254,10 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap&     n2C
   SMESHDS_Mesh * meshDS = myHelper->GetMeshDS();
   int shapeID = myHelper->GetSubShapeID();
 
-  if ( myLayerPositions.empty() )
-    computeLayerPositions( gpXYZ( inNode ), gpXYZ( outNode ));
-
+  if ( myLayerPositions.empty() ) {
+    gp_Pnt pIn = gpXYZ( inNode ), pOut = gpXYZ( outNode );
+    computeLayerPositions( pIn, pOut );
+  }
   int nbSegments = myLayerPositions.size() + 1;
 
   TNode2ColumnMap::iterator n_col =
@@ -287,7 +290,7 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap&     n2C
 //================================================================================
 //================================================================================
 
-class TNodeDistributor: private StdMeshers_Regular_1D
+class TNodeDistributor: public StdMeshers_Regular_1D
 {
   list <const SMESHDS_Hypothesis *> myUsedHyps;
 public:
@@ -309,23 +312,24 @@ public:
                 const StdMeshers_LayerDistribution* hyp)
   {
     double len = pIn.Distance( pOut );
-    if ( len <= DBL_MIN ) RETURN_BAD_RESULT("Bad points");
+    if ( len <= DBL_MIN ) return error(dfltErr(),"Too close points of inner and outer shells");
 
     if ( !hyp || !hyp->GetLayerDistribution() )
-      RETURN_BAD_RESULT("Bad StdMeshers_LayerDistribution hypothesis");
+      return error(dfltErr(), "Invalid LayerDistribution hypothesis");
     myUsedHyps.clear();
     myUsedHyps.push_back( hyp->GetLayerDistribution() );
 
     TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut );
     SMESH_Hypothesis::Hypothesis_Status aStatus;
     if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus ))
-      RETURN_BAD_RESULT("StdMeshers_Regular_1D::CheckHypothesis() failed with status "<<aStatus);
+      return error(dfltErr(), "StdMeshers_Regular_1D::CheckHypothesis() failed"
+                   "with LayerDistribution hypothesis");
 
     BRepAdaptor_Curve C3D(edge);
     double f = C3D.FirstParameter(), l = C3D.LastParameter();
     list< double > params;
     if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false ))
-      RETURN_BAD_RESULT("StdMeshers_Regular_1D::computeInternalParameters() failed");
+      return error(dfltErr(),"StdMeshers_Regular_1D failed to compute layers distribution");
 
     positions.clear();
     positions.reserve( params.size() );
@@ -355,7 +359,8 @@ protected:
  */
 //================================================================================
 
-bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut)
+bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn,
+                                                      const gp_Pnt& pOut)
 {
   if ( myNbLayerHypo )
   {
@@ -367,8 +372,12 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut)
   }
   if ( myDistributionHypo ) {
     SMESH_Mesh * mesh = myHelper->GetMesh();
-    return TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
-                                                             *mesh, myDistributionHypo );
+    if ( !TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
+                                                            *mesh, myDistributionHypo ))
+    {
+      error( TNodeDistributor::GetDistributor(*mesh)->GetComputeError() );
+      return false;
+    }
   }
-  RETURN_BAD_RESULT("Bad hypothesis");  
+  RETURN_BAD_RESULT("Bad hypothesis");
 }
index 4c604ea32393238b0e26ff0eef987f59a32a150f..0bedb6a30f5b7aaa3514d5842458e693d12a6bf6 100644 (file)
@@ -36,6 +36,7 @@
 class StdMeshers_NumberOfLayers;
 class StdMeshers_LayerDistribution;
 class SMESH_MesherHelper;
+class gp_Pnt;
 
 class StdMeshers_RadialPrism_3D: public SMESH_3D_Algo
 {
@@ -58,7 +59,8 @@ protected:
                                const SMDS_MeshNode* outNode,
                                const SMDS_MeshNode* inNode);
 
-  bool computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut);
+  bool computeLayerPositions(const gp_Pnt& pIn,
+                             const gp_Pnt& pOut);
 
 
   const StdMeshers_NumberOfLayers*    myNbLayerHypo;
index 2f13e328307853a38d9e89fc4e3c1bae51d7df3e..9e59aa0c6b4a28c654a274a61fd9dee4265ad322 100644 (file)
@@ -43,6 +43,7 @@
 #include "SMESH_HypoFilter.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include <GCPnts_UniformDeflection.hxx>
 #include <Precision.hxx>
 
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
-
 #include <string>
-//#include <math.h>
 
 using namespace std;
 
@@ -376,25 +373,25 @@ static void compensateError(double a1, double an,
  */
 //================================================================================
 
-struct VertexEventListener : public SMESH_subMeshEventListener
-{
-  VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
-  {}
-  /*!
-   * \brief Clean mesh on edges
-   * \param event - algo_event or compute_event itself (of SMESH_subMesh)
-   * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
-   * \param subMesh - the submesh where the event occures
-   */
-  void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
-                    EventListenerData*, SMESH_Hypothesis*)
-  {
-    if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
-    {
-      subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
-    }
-  }
-}; // struct VertexEventListener
+// struct VertexEventListener : public SMESH_subMeshEventListener
+// {
+//   VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+//   {}
+//   /*!
+//    * \brief Clean mesh on edges
+//    * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+//    * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+//    * \param subMesh - the submesh where the event occures
+//    */
+//   void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+//                     EventListenerData*, const SMESH_Hypothesis*)
+//   {
+//     if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
+//     {
+//       subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
+//     }
+//   }
+// }; // struct VertexEventListener
 
 //=============================================================================
 /*!
@@ -408,13 +405,11 @@ struct VertexEventListener : public SMESH_subMeshEventListener
 
 void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh)
 {
-  static VertexEventListener listener;
-  const map < int, SMESH_subMesh * >& vSMs = subMesh->DependsOn();
-  map < int, SMESH_subMesh * >::const_iterator itsub;
-  for (itsub = vSMs.begin(); itsub != vSMs.end(); itsub++)
-  {
-    subMesh->SetEventListener( &listener, 0, itsub->second );
-  }
+//   static VertexEventListener listener;
+//   SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+//   while (smIt->more()) {
+//     subMesh->SetEventListener( &listener, 0, smIt->next() );
+//   }
 }
 
 //=============================================================================
@@ -440,9 +435,15 @@ const StdMeshers_SegmentLengthAroundVertex*
 StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh &          theMesh,
                                     const TopoDS_Vertex & theV)
 {
-  static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentLengthAroundVertex"));
-  const SMESH_Hypothesis * hyp = theMesh.GetHypothesis( theV, filter, true );
-  return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hyp );
+  static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D"));
+  if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true ))
+  {
+    SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h ));
+    const list <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
+    if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
+      return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
+  }
+  return 0;
 }
 
 //================================================================================
@@ -461,7 +462,7 @@ void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh &          theM
                                                       double                theLength,
                                                       std::list< double > & theParameters,
                                                       const TopoDS_Vertex & theVf,
-                                                      const TopoDS_Vertex & theVl) const
+                                                      const TopoDS_Vertex & theVl)
 {
   double f = theC3d.FirstParameter(), l = theC3d.LastParameter();
   int nPar = theParameters.size();
@@ -546,7 +547,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
                                                       double           theFirstU,
                                                       double           theLastU,
                                                       list<double> &   theParams,
-                                                      const bool       theReverse) const
+                                                      const bool       theReverse)
 {
   theParams.clear();
 
@@ -626,7 +627,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
     }
     GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l);
     if ( !Discret.IsDone() )
-      return false;
+      return error( dfltErr(), "GCPnts_UniformAbscissa failed");
 
     int NbPoints = Discret.NbPoints();
     for ( int i = 2; i < NbPoints; i++ )
@@ -731,8 +732,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
 
 bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
-  //MESSAGE("StdMeshers_Regular_1D::Compute");
-
   if ( _hypType == NONE )
     return false;
 
@@ -749,38 +748,25 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   TopExp::Vertices(E, VFirst, VLast);   // Vfirst corresponds to f and Vlast to l
 
   ASSERT(!VFirst.IsNull());
-  const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
-  if (!idFirst) {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
-
   ASSERT(!VLast.IsNull());
+  const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
   const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS );
-  if (!idLast) {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
+  if (!idFirst || !idLast)
+    return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
 
-  if (!Curve.IsNull()) {
+  if (!Curve.IsNull())
+  {
     list< double > params;
     bool reversed = false;
     if ( !_mainEdge.IsNull() )
       reversed = aMesh.IsReversedInChain( EE, _mainEdge );
+
     BRepAdaptor_Curve C3d( E );
     double length = EdgeLength( E );
-    try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-      OCC_CATCH_SIGNALS;
-#endif
-      if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
-        return false;
-      }
-      redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
-    }
-    catch ( Standard_Failure ) {
+    if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
       return false;
     }
+    redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
 
     // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
     // only internal nodes receive an edge position with param on curve
index f0e82262d87002a40e9050a8c6377b20f2f16220..b5bae58774482f263e422258f54ed995eecfeaf4 100644 (file)
@@ -76,14 +76,14 @@ protected:
                                           double                theFirstU,
                                           double                theLastU,
                                           std::list< double > & theParameters,
-                                          const bool            theReverse) const;
+                                          const bool            theReverse);
 
   virtual void redistributeNearVertices (SMESH_Mesh &          theMesh,
                                          Adaptor3d_Curve &     theC3d,
                                          double                theLength,
                                          std::list< double > & theParameters,
                                          const TopoDS_Vertex & theVf,
-                                         const TopoDS_Vertex & theVl) const;
+                                         const TopoDS_Vertex & theVl);
 
   /*!
    * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex