Salome HOME
PAL11986. Add a new status to ErrorCode enum; thoroughly check if projection is needed
authoreap <eap@opencascade.com>
Mon, 27 Mar 2006 09:32:41 +0000 (09:32 +0000)
committereap <eap@opencascade.com>
Mon, 27 Mar 2006 09:32:41 +0000 (09:32 +0000)
src/SMESH/SMESH_Pattern.cxx

index f6090b1a839a8c70b3fa378f4a9acbc30cd90eb0..3cf7d2eb55eda9f44a63592574fb444e575491f9 100644 (file)
@@ -509,34 +509,53 @@ static gp_XY project (const SMDS_MeshNode* theNode,
 }
 
 //=======================================================================
-//function : isMeshBoundToShape
-//purpose  : return true if all 2d elements are bound to shape
+//function : areNodesBound
+//purpose  : true if all nodes of faces are bound to shapes
 //=======================================================================
 
-static bool isMeshBoundToShape(SMESH_Mesh* theMesh)
+template <class TFaceIterator> bool areNodesBound( TFaceIterator & faceItr )
 {
-  // check faces binding
-  SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
-  SMESHDS_SubMesh * aMainSubMesh = aMeshDS->MeshElements( aMeshDS->ShapeToMesh() );
-  if ( aMeshDS->NbFaces() != aMainSubMesh->NbElements() )
-    return false;
-
-  // check face nodes binding
-  SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
-  while ( fIt->more() )
+  while ( faceItr->more() )
   {
-    SMDS_ElemIteratorPtr nIt = fIt->next()->nodesIterator();
+    SMDS_ElemIteratorPtr nIt = faceItr->next()->nodesIterator();
     while ( nIt->more() )
     {
       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
       SMDS_PositionPtr pos = node->GetPosition();
-      if ( !pos || !pos->GetShapeId() )
+      if ( !pos || !pos->GetShapeId() ) {
         return false;
+      }
     }
   }
   return true;
 }
 
+//=======================================================================
+//function : isMeshBoundToShape
+//purpose  : return true if all 2d elements are bound to shape
+//           if aFaceSubmesh != NULL, then check faces bound to it
+//           else check all faces in aMeshDS
+//=======================================================================
+
+static bool isMeshBoundToShape(SMESHDS_Mesh *     aMeshDS,
+                               SMESHDS_SubMesh *  aFaceSubmesh,
+                               const bool         isMainShape)
+{
+  if ( isMainShape ) {
+    // check that all faces are bound to aFaceSubmesh
+    if ( aMeshDS->NbFaces() != aFaceSubmesh->NbElements() )
+      return false;
+  }
+
+  // check face nodes binding
+  if ( aFaceSubmesh ) {
+    SMDS_ElemIteratorPtr fIt = aFaceSubmesh->GetElements();
+    return areNodesBound( fIt );
+  }
+  SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
+  return areNodesBound( fIt );
+}
+
 //=======================================================================
 //function : Load
 //purpose  : Create a pattern from the mesh built on <theFace>.
@@ -573,32 +592,53 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
   for ( ; elIt != eList.end() ; elIt++ )
     if ( BRep_Tool::IsClosed( *elIt , face ))
       return setErrorCode( ERR_LOADF_CLOSED_FACE );
-  
+
+  // check that requested or needed projection is possible
+  bool isMainShape = theMesh->IsMainShape( face );
+  bool needProject = !isMeshBoundToShape( aMeshDS, fSubMesh, isMainShape );
+  bool canProject  = ( nbElems ? true : isMainShape );
+
+  if ( ( theProject || needProject ) && !canProject )
+    return setErrorCode( ERR_LOADF_CANT_PROJECT );
 
   Extrema_GenExtPS projector;
   GeomAdaptor_Surface aSurface( BRep_Tool::Surface( face ));
-  if ( theProject || nbElems == 0 )
+  if ( theProject || needProject )
     projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
 
   int iPoint = 0;
   TNodePointIDMap nodePointIDMap;
 
-  if ( nbElems == 0 || (theProject &&
-                        theMesh->IsMainShape( face ) &&
-                        !isMeshBoundToShape( theMesh )))
+  if ( needProject )
   {
-    MESSAGE("Project the whole mesh");
+    MESSAGE("Project the submesh");
     // ---------------------------------------------------------------
-    // The case where the whole mesh is projected to theFace
+    // The case where the submesh is projected to theFace
     // ---------------------------------------------------------------
 
-    // put nodes of all faces in the nodePointIDMap and fill myElemPointIDs
-    SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
-    while ( fIt->more() )
+    // get all faces
+    list< const SMDS_MeshElement* > faces;
+    if ( nbElems > 0 ) {
+      SMDS_ElemIteratorPtr fIt = fSubMesh->GetElements();
+      while ( fIt->more() ) {
+        const SMDS_MeshElement* f = fIt->next();
+        if ( f && f->GetType() == SMDSAbs_Face )
+          faces.push_back( f );
+      }
+    }
+    else {
+      SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
+      while ( fIt->more() )
+        faces.push_back( fIt->next() );
+    }
+
+    // put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
+    list< const SMDS_MeshElement* >::iterator fIt = faces.begin();
+    for ( ; fIt != faces.end(); ++fIt )
     {
       myElemPointIDs.push_back( TElemDef() );
       TElemDef& elemPoints = myElemPointIDs.back();
-      SMDS_ElemIteratorPtr nIt = fIt->next()->nodesIterator();
+      SMDS_ElemIteratorPtr nIt = (*fIt)->nodesIterator();
       while ( nIt->more() )
       {
         const SMDS_MeshElement* node = nIt->next();
@@ -837,7 +877,21 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
   double dU = maxU - minU, dV = maxV - minV;
   if ( dU <= DBL_MIN || dV <= DBL_MIN ) {
     Clear();
-    return setErrorCode( ERR_LOADF_NARROW_FACE );
+    bndBox.SetVoid();
+    // define where is the problem, in the face or in the mesh
+    TopExp_Explorer vExp( face, TopAbs_VERTEX );
+    for ( ; vExp.More(); vExp.Next() ) {
+      gp_Pnt2d uv = BRep_Tool::Parameters( TopoDS::Vertex( vExp.Current() ), face );
+      bndBox.Add( uv );
+    }
+    bndBox.Get( minU, minV, maxU, maxV );
+    dU = maxU - minU, dV = maxV - minV;
+    if ( dU <= DBL_MIN || dV <= DBL_MIN )
+      // face problem
+      return setErrorCode( ERR_LOADF_NARROW_FACE );
+    else
+      // mesh is projected onto a line, e.g.
+      return setErrorCode( ERR_LOADF_CANT_PROJECT );
   }
   double ratio = dU / dV, maxratio = 3, scale;
   int iCoord = 0;
@@ -4010,6 +4064,8 @@ bool SMESH_Pattern::findBoundaryPoints()
 
   MESSAGE(" findBoundaryPoints() ");
 
+  myNbKeyPntInBoundary.clear();
+
   if ( myIs2D )
   {
     set< TPoint* > pointsInElems;