diff --git a/Mesh/2D_Mesh.cpp b/Mesh/2D_Mesh.cpp index 9ef24919d079f1290c411b3ea624d26751faeece..53e9aa51e4b7fc1ac84d20cc9206fe16f42f230a 100644 --- a/Mesh/2D_Mesh.cpp +++ b/Mesh/2D_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: 2D_Mesh.cpp,v 1.39 2002-02-01 14:34:05 remacle Exp $ +// $Id: 2D_Mesh.cpp,v 1.40 2002-02-12 20:11:34 geuzaine Exp $ /* Maillage Delaunay d'une surface (Point insertion Technique) @@ -145,7 +145,7 @@ void Calcule_Z (void *data, void *dum){ if (v->Frozen || v->Num < 0) return; - XYtoUV (THESUPPORT, &v->Pos.X, &v->Pos.Y, &U, &V, &Z); + XYtoUV (THESUPPORT, &v->Pos.X, &v->Pos.Y, &U, &V, &Z, 1.0); v->Pos.Z = Z; } diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp index a00df881c4490c31332102b25ebe88eeccc7298e..deac822e13c222f1b802a58937542af5de279656 100644 --- a/Mesh/SecondOrder.cpp +++ b/Mesh/SecondOrder.cpp @@ -1,4 +1,4 @@ -// $Id: SecondOrder.cpp,v 1.7 2001-10-29 08:52:20 geuzaine Exp $ +// $Id: SecondOrder.cpp,v 1.8 2002-02-12 20:11:34 geuzaine Exp $ #include "Gmsh.h" #include "Geo.h" @@ -45,8 +45,8 @@ Vertex *middleface (Vertex * v1, Vertex * v2){ if (THES->Typ == MSH_SURF_PLAN) return NULL; - XYZtoUV ( THES , v1->Pos.X , v1->Pos.Y , v1->Pos.Z, &U1 , &V1 ); - XYZtoUV ( THES , v2->Pos.X , v2->Pos.Y , v2->Pos.Z, &U2 , &V2 ); + XYZtoUV ( THES , v1->Pos.X , v1->Pos.Y , v1->Pos.Z, &U1 , &V1 , 1.0); + XYZtoUV ( THES , v2->Pos.X , v2->Pos.Y , v2->Pos.Z, &U2 , &V2 , 1.0); U = 0.5 *(U1+U2); V = 0.5 *(V1+V2); diff --git a/Mesh/Utils.cpp b/Mesh/Utils.cpp index 9799e73d40c5ce5c8be56c65d73a35eb750f8f06..6d7d3b2b6ba4c13bbecb10be33b7df605c450873 100644 --- a/Mesh/Utils.cpp +++ b/Mesh/Utils.cpp @@ -1,4 +1,4 @@ -// $Id: Utils.cpp,v 1.8 2001-12-16 05:16:37 remacle Exp $ +// $Id: Utils.cpp,v 1.9 2002-02-12 20:11:34 geuzaine Exp $ #include "Gmsh.h" #include "Numeric.h" @@ -178,7 +178,7 @@ end: #define Precision 1.e-10 -#define MaxIter 20 +#define MaxIter 50 void find_bestuv (Surface * s, double X, double Y, double *U, double *V, double *Z, int N){ @@ -253,11 +253,24 @@ void invert_singular_matrix(double **M, int n, double **I){ free_dvector(W,1,n); } -void XYZtoUV (Surface *s, double X, double Y, double Z, double *U, double *V) { +void XYZtoUV (Surface *s, double X, double Y, double Z, double *U, double *V, + double relax) { double Unew,Vnew,err; int iter; Vertex D_u,D_v,P; double **mat, **jac ; + double umin, umax, vmin, vmax; + + if (s->Typ == MSH_SURF_NURBS){ + umin = s->ku[0]; + umax = s->ku[s->OrderU + s->Nu]; + vmin = s->kv[0]; + vmax = s->kv[s->OrderV + s->Nv]; + } + else{ + umin = vmin = 0.0; + umax = vmax = 1.0; + } mat = dmatrix(1,3,1,3); jac = dmatrix(1,3,1,3); @@ -282,8 +295,10 @@ void XYZtoUV (Surface *s, double X, double Y, double Z, double *U, double *V) { mat[3][3] = 0.; invert_singular_matrix(mat,3,jac); - Unew = *U + jac[1][1] * (X-P.Pos.X) + jac[2][1] * (Y-P.Pos.Y) + jac[3][1] * (Z-P.Pos.Z) ; - Vnew = *V + jac[1][2] * (X-P.Pos.X) + jac[2][2] * (Y-P.Pos.Y) + jac[3][2] * (Z-P.Pos.Z) ; + Unew = *U + relax * (jac[1][1] * (X-P.Pos.X) + jac[2][1] * (Y-P.Pos.Y) + + jac[3][1] * (Z-P.Pos.Z)) ; + Vnew = *V + relax * (jac[1][2] * (X-P.Pos.X) + jac[2][2] * (Y-P.Pos.Y) + + jac[3][2] * (Z-P.Pos.Z)) ; err = DSQR(Unew - *U) + DSQR(Vnew - *V) ; @@ -292,18 +307,23 @@ void XYZtoUV (Surface *s, double X, double Y, double Z, double *U, double *V) { *V = Vnew; } - if(iter > 10){ - if(iter == MaxIter) Msg(WARNING, "Could not converge in XYZtoUV"); - else Msg(WARNING, "Many (%d) iterations in XYZtoUV", iter); - } - free_dmatrix(mat,1,3,1,3); free_dmatrix(jac,1,3,1,3); + if(iter == MaxIter || + (Unew > umax || Vnew > vmax || Unew < umin || Vnew < vmin)){ + if(relax < 1.e-12) + Msg(GERROR, "Could not converge: surface mesh will be wrong"); + else{ + Msg(INFO, "Relaxation factor = %g", 0.75*relax); + XYZtoUV (s, X, Y, Z, U, V, 0.75*relax); + } + } + } void XYtoUV (Surface * s, double *X, double *Y, - double *U, double *V, double *Z){ + double *U, double *V, double *Z, double relax){ double det, Unew, Vnew, err, mat[2][2], jac[2][2]; int iter; @@ -345,8 +365,8 @@ void XYtoUV (Surface * s, double *X, double *Y, jac[1][0] = -mat[1][0] / det; jac[1][1] = mat[0][0] / det; - Unew = *U + 1.0 * (jac[0][0] * (*X - P.Pos.X) + jac[1][0] * (*Y - P.Pos.Y)); - Vnew = *V + 1.0 * (jac[0][1] * (*X - P.Pos.X) + jac[1][1] * (*Y - P.Pos.Y)); + Unew = *U + relax * (jac[0][0] * (*X - P.Pos.X) + jac[1][0] * (*Y - P.Pos.Y)); + Vnew = *V + relax * (jac[0][1] * (*X - P.Pos.X) + jac[1][1] * (*Y - P.Pos.Y)); err = DSQR (Unew - *U) + DSQR (Vnew - *V); @@ -357,33 +377,30 @@ void XYtoUV (Surface * s, double *X, double *Y, *Z = P.Pos.Z; - if(iter > 10){ - if(iter == MaxIter) Msg(WARNING, "Could not converge in XYtoUV"); - else Msg(WARNING, "Many (%d) iterations in XYtoUV...", iter); - } - int thresh = Unew > umax || Vnew > vmax || Unew < umin || Vnew < vmin; - if (thresh){ - //Msg(WARNING, "(U,V) thresholded in XYtoUV (surface mesh may be wrong)"); - if(Unew > umax) *U = umax; - if(Vnew > vmax) *V = vmax; - if(Unew < umin) *U = umin; - if(Vnew < vmin) *V = vmin; + if(iter == MaxIter || thresh){ + if(relax < 1.e-6){ + Msg(GERROR, "Could not converge: surface mesh will probably be wrong"); + if(Unew > umax) *U = umax; + if(Vnew > vmax) *V = vmax; + if(Unew < umin) *U = umin; + if(Vnew < vmin) *V = vmin; + find_bestuv (s, *X, *Y, U, V, Z, 30); + P = InterpolateSurface (s, *U, *V, 0, 0); + *X = P.Pos.X; + *Y = P.Pos.Y; + *Z = P.Pos.Z; + } + else{ + Msg(INFO, "Relaxation factor = %g", 0.75*relax); + XYtoUV (s, X, Y, U, V, Z, 0.75*relax); + } } -#if 1 - if (iter == MaxIter || thresh){ - Msg(WARNING, "Entering rescue mode in XYtoUV: surface mesh may be wrong"); - find_bestuv (s, *X, *Y, U, V, Z, 30); - P = InterpolateSurface (s, *U, *V, 0, 0); - *X = P.Pos.X; - *Y = P.Pos.Y; - *Z = P.Pos.Z; - } -#endif } + int Oriente (List_T * cu, double n[3]){ int N, i, a, b, c; double cosa, sina, sum, v[3], w[3], u[3]; diff --git a/Mesh/Utils.h b/Mesh/Utils.h index 12c5a589c0b7dd4a2245427f1b6d2c647e0907af..0b71f07145363a2d7ced3d9ca118612695d62719 100644 --- a/Mesh/Utils.h +++ b/Mesh/Utils.h @@ -7,8 +7,9 @@ void MeanPlane(List_T *point, Surface *s); void find_bestuv (Surface * s, double X, double Y, double *U, double *V, double *Z, int N); void XYtoUV (Surface * s, double *X, double *Y, - double *U, double *V, double *Z); -void XYZtoUV (Surface *s, double X, double Y, double Z, double *U, double *V); + double *U, double *V, double *Z, double relax); +void XYZtoUV (Surface *s, double X, double Y, double Z, + double *U, double *V, double relax); int Oriente (List_T * cu, double n[3]); double angle_3p (Vertex * V, Vertex * P1, Vertex * P2); double angle_plan (Vertex * V, Vertex * P1, Vertex * P2, double n[3]);