Salome HOME
PAL16567
authoreap <eap@opencascade.com>
Mon, 23 Jul 2007 09:20:51 +0000 (09:20 +0000)
committereap <eap@opencascade.com>
Mon, 23 Jul 2007 09:20:51 +0000 (09:20 +0000)
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx

index 44396d2afbd43cc0d247785edf3431f7148ea1a8..a3a9061ce81f24aa385c1c7128acc5e0a49255f0 100644 (file)
@@ -2659,6 +2659,162 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
   return setErrorCode( ERR_OK );
 }
 
+//=======================================================================
+//function : Apply
+//purpose  : Compute nodes coordinates applying
+//           the loaded pattern to <theFace>. The first key-point
+//           will be mapped into <theNodeIndexOnKeyPoint1>-th node
+//=======================================================================
+
+bool SMESH_Pattern::Apply (SMESH_Mesh*          theMesh,
+                           const SMDS_MeshFace* theFace,
+                           const TopoDS_Shape&  theSurface,
+                           const int            theNodeIndexOnKeyPoint1,
+                           const bool           theReverse)
+{
+//  MESSAGE(" ::Apply(MeshFace) " );
+  if ( theSurface.IsNull() || theSurface.ShapeType() != TopAbs_FACE ) {
+    return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse);
+  }
+  const TopoDS_Face& face = TopoDS::Face( theSurface );
+  TopLoc_Location loc;
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
+  const gp_Trsf & aTrsf = loc.Transformation();
+
+  if ( !IsLoaded() ) {
+    MESSAGE( "Pattern not loaded" );
+    return setErrorCode( ERR_APPL_NOT_LOADED );
+  }
+
+  // check nb of nodes
+  if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) {
+    MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() );
+    return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
+  }
+
+  // find points on edges, it fills myNbKeyPntInBoundary
+  if ( !findBoundaryPoints() )
+    return false;
+
+  // check that there are no holes in a pattern
+  if (myNbKeyPntInBoundary.size() > 1 ) {
+    return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
+  }
+
+  // Define the nodes order
+
+  list< const SMDS_MeshNode* > nodes;
+  list< const SMDS_MeshNode* >::iterator n = nodes.end();
+  SMDS_ElemIteratorPtr noIt = theFace->nodesIterator();
+  int iSub = 0;
+  while ( noIt->more() ) {
+    const SMDS_MeshNode* node = smdsNode( noIt->next() );
+    nodes.push_back( node );
+    if ( iSub++ == theNodeIndexOnKeyPoint1 )
+      n = --nodes.end();
+  }
+  if ( n != nodes.end() ) {
+    if ( theReverse ) {
+      if ( n != --nodes.end() )
+        nodes.splice( nodes.begin(), nodes, ++n, nodes.end() );
+      nodes.reverse();
+    }
+    else if ( n != nodes.begin() )
+      nodes.splice( nodes.end(), nodes, nodes.begin(), n );
+  }
+
+  // find a node not on a seam edge, if necessary
+  SMESH_MesherHelper helper( *theMesh );
+  helper.SetSubShape( theSurface );
+  const SMDS_MeshNode* inFaceNode = 0;
+  if ( helper.GetNodeUVneedInFaceNode() )
+  {
+    SMESH_MeshEditor editor( theMesh );
+    for ( n = nodes.begin(); ( !inFaceNode && n != nodes.end()); ++n ) {
+      int shapeID = editor.FindShape( *n );
+      if ( !shapeID )
+        return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse);
+      if ( !helper.IsSeamShape( shapeID ))
+        inFaceNode = *n;
+    }
+  }
+
+  // Set UV of key-points (i.e. of nodes of theFace )
+  vector< gp_XY > keyUV( theFace->NbNodes() );
+  myOrderedNodes.resize( theFace->NbNodes() );
+  for ( iSub = 1, n = nodes.begin(); n != nodes.end(); ++n, ++iSub )
+  {
+    TPoint* p = getShapePoints( iSub ).front();
+    p->myUV  = helper.GetNodeUV( face, *n, inFaceNode );
+    p->myXYZ = gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() );
+
+    keyUV[ iSub-1 ] = p->myUV;
+    myOrderedNodes[ iSub-1 ] = *n;
+  }
+
+  // points on edges to be used for UV computation of in-face points
+  list< list< TPoint* > > edgesPointsList;
+  edgesPointsList.push_back( list< TPoint* >() );
+  list< TPoint* > * edgesPoints = & edgesPointsList.back();
+  list< TPoint* >::iterator pIt;
+
+  // compute UV and XYZ of points on edges
+
+  for ( int i = 0; i < myOrderedNodes.size(); ++i, ++iSub )
+  {
+    gp_XY& uv1 = keyUV[ i ];
+    gp_XY& uv2 = ( i+1 < keyUV.size() ) ? keyUV[ i+1 ] : keyUV[ 0 ];
+
+    list< TPoint* > & ePoints = getShapePoints( iSub );
+    ePoints.back()->myInitU = 1.0;
+    list< TPoint* >::const_iterator pIt = ++ePoints.begin();
+    while ( *pIt != ePoints.back() )
+    {
+      TPoint* p = *pIt++;
+      p->myUV = uv1 * ( 1 - p->myInitU ) + uv2 * p->myInitU;
+      p->myXYZ = surface->Value( p->myUV.X(), p->myUV.Y() );
+      if ( !loc.IsIdentity() )
+        aTrsf.Transforms( p->myXYZ.ChangeCoord() );
+    }
+    // collect on-edge points (excluding the last one)
+    edgesPoints->insert( edgesPoints->end(), ePoints.begin(), --ePoints.end());
+  }
+
+  // Compute UV and XYZ of in-face points
+
+  // try to use a simple algo to compute UV
+  list< TPoint* > & fPoints = getShapePoints( iSub );
+  bool isDeformed = false;
+  for ( pIt = fPoints.begin(); !isDeformed && pIt != fPoints.end(); pIt++ )
+    if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
+                                  (*pIt)->myUV, isDeformed )) {
+      MESSAGE("cant Apply(face)");
+      return false;
+    }
+  // try to use a complex algo if it is a difficult case
+  if ( isDeformed && !compUVByElasticIsolines( edgesPointsList, fPoints ))
+  {
+    for ( ; pIt != fPoints.end(); pIt++ ) // continue with the simple algo
+      if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
+                                    (*pIt)->myUV, isDeformed )) {
+        MESSAGE("cant Apply(face)");
+        return false;
+      }
+  }
+
+  for ( pIt = fPoints.begin(); pIt != fPoints.end(); pIt++ )
+  {
+    TPoint * point = *pIt;
+    point->myXYZ = surface->Value( point->myUV.X(), point->myUV.Y() );
+    if ( !loc.IsIdentity() )
+      aTrsf.Transforms( point->myXYZ.ChangeCoord() );
+  }
+
+  myIsComputed = true;
+
+  return setErrorCode( ERR_OK );
+}
+
 //=======================================================================
 //function : undefinedXYZ
 //purpose  : 
@@ -2687,7 +2843,8 @@ inline static bool isDefined(const gp_XYZ& theXYZ)
 //           will be mapped into <theNodeIndexOnKeyPoint1>-th node
 //=======================================================================
 
-bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& theFaces,
+bool SMESH_Pattern::Apply (SMESH_Mesh*                     theMesh,
+                           std::set<const SMDS_MeshFace*>& theFaces,
                            const int                       theNodeIndexOnKeyPoint1,
                            const bool                      theReverse)
 {
@@ -2725,11 +2882,29 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& theFaces,
 
   int ind1 = 0; // lowest point index for a face
 
+  // meshed geometry
+  TopoDS_Shape shape;
+//   int          shapeID = 0;
+//   SMESH_MeshEditor editor( theMesh ); 
+
   // apply to each face in theFaces set
   set<const SMDS_MeshFace*>::iterator face = theFaces.begin();
   for ( ; face != theFaces.end(); ++face )
   {
-    if ( !Apply( *face, theNodeIndexOnKeyPoint1, theReverse )) {
+//     int curShapeId = editor.FindShape( *face );
+//     if ( curShapeId != shapeID ) {
+//       if ( curShapeId )
+//         shape = theMesh->GetMeshDS()->IndexToShape( curShapeId );
+//       else
+//         shape.Nullify();
+//       shapeID = curShapeId;
+//     }
+    bool ok;
+    if ( shape.IsNull() )
+      ok = Apply( *face, theNodeIndexOnKeyPoint1, theReverse );
+    else
+      ok = Apply( theMesh, *face, shape, theNodeIndexOnKeyPoint1, theReverse );
+    if ( !ok ) {
       MESSAGE( "Failed on " << *face );
       continue;
     }
index 76b592c3f934b3424674d4ea9bae3debab53a6c1..a2ee3050da6f78b98419795292def1603b87f96f 100644 (file)
@@ -101,7 +101,17 @@ class SMESH_Pattern {
   // the loaded pattern to <theFace>. The first key-point
   // will be mapped into <theNodeIndexOnKeyPoint1>-th node
 
-  bool Apply (std::set<const SMDS_MeshFace*>& theFaces,
+  bool Apply (SMESH_Mesh*          theMesh,
+              const SMDS_MeshFace* theFace,
+              const TopoDS_Shape&  theSurface,
+              const int            theNodeIndexOnKeyPoint1,
+              const bool           theReverse);
+  // Compute nodes coordinates applying
+  // the loaded pattern to <theFace>. The first key-point
+  // will be mapped into <theNodeIndexOnKeyPoint1>-th node
+
+  bool Apply (SMESH_Mesh*                     theMesh,
+              std::set<const SMDS_MeshFace*>& theFaces,
               const int                       theNodeIndexOnKeyPoint1,
               const bool                      theReverse);
   // Compute nodes coordinates applying