From 0079777a600195a8b5c18a7006d106c56289ce08 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Wed, 24 Aug 2005 14:32:56 +0000 Subject: [PATCH] *** empty log message *** --- Common/GmshMatrix.h | 3 + Mesh/BDS.cpp | 359 ++++++++++++++++++++------------------- Mesh/BDS.h | 11 +- Mesh/DiscreteSurface.cpp | 4 +- 4 files changed, 195 insertions(+), 182 deletions(-) diff --git a/Common/GmshMatrix.h b/Common/GmshMatrix.h index 9f4857092a..1f5dc2e547 100644 --- a/Common/GmshMatrix.h +++ b/Common/GmshMatrix.h @@ -183,9 +183,12 @@ public: assert (result.size() == c); GSL_Matrix *ls = new GSL_Matrix(c, c); GSL_Vector *ls_rhs = new GSL_Vector(c); + //GSL_Vector *test = new GSL_Vector(c); gsl_blas_dgemm (CblasTrans,CblasNoTrans, 1.0, data, data, 1.0, ls->data); gsl_blas_dgemv (CblasTrans, 1.0, data, rhs.data, 1.0, ls_rhs->data); ls->lu_solve (*ls_rhs,result); + + delete ls; delete ls_rhs; } diff --git a/Mesh/BDS.cpp b/Mesh/BDS.cpp index 661fac8f09..f70d2e573c 100644 --- a/Mesh/BDS.cpp +++ b/Mesh/BDS.cpp @@ -13,6 +13,27 @@ */ +void outputScalarField ( std::list<BDS_Triangle*>t , const char *iii) +{ + FILE * f = fopen (iii,"w"); + fprintf(f,"View \"scalar\" {\n"); + std::list<BDS_Triangle *>::iterator tit = t.begin(); + std::list<BDS_Triangle *>::iterator tite = t.end(); + while (tit!=tite) + { + BDS_Point *pts[3]; + (*tit)->getNodes (pts); + fprintf(f,"ST(%g,%g,%g,%g,%g,%g,%g,%g,%g){%g,%g,%g};\n", + pts[0]->X, pts[0]->Y, pts[0]->Z, + pts[1]->X, pts[1]->Y, pts[1]->Z, + pts[2]->X, pts[2]->Y, pts[2]->Z, + pts[0]->radius_of_curvature, pts[1]->radius_of_curvature, pts[2]->radius_of_curvature); + ++tit; + } + fprintf(f,"};\n"); + fclose(f); +} + double BDS_Quadric:: normalCurv ( double x, double y, double z ) const { // K = div n = div ( Grad(f) / ||Grad(f)||) @@ -91,7 +112,8 @@ void BDS_Quadric::projection ( double xa, double ya, double za, } void BDS_GeomEntity::getClosestTriangles ( double x, double y, double z, - std::list<BDS_Triangle*> &l ) + std::list<BDS_Triangle*> &l , + double &radius) { #ifdef HAVE_ANN_ @@ -106,6 +128,7 @@ void BDS_GeomEntity::getClosestTriangles ( double x, double y, double z, queryPt[0] = x; queryPt[1] = y; queryPt[2] = z; + double eps; kdTree->annkSearch( // search queryPt, // query point @@ -114,41 +137,19 @@ void BDS_GeomEntity::getClosestTriangles ( double x, double y, double z, dists, // distance (returned) eps); // error bound + std::list<BDS_Triangle*>l1,l2,l3; + + radius = sR[nnIdx[0]]; + for (int K=0;K<nbK;K++) { - if (nnIdx[K] < sP.size()) - { - std::list<BDS_Triangle *> l1; - sP[nnIdx[K]]->getTriangles (l1); - l.insert(l.begin(),l1.begin(),l1.end()); - } - else if (nnIdx[K] < sP.size() + sE.size() ) - { - - BDS_Edge *e = sE[nnIdx[K]- sP.size()]; - std::list<BDS_Triangle *> l1,l2; - e->p1->getTriangles (l1); - e->p2->getTriangles (l2); - l.insert(l.begin(),l1.begin(),l1.end()); - l.insert(l.begin(),l2.begin(),l2.end()); - // for (int i=0;i<e->numfaces();i++) - // { - // app.push_back(e->faces(i)); - // } - } - else - { - std::list<BDS_Triangle *> l1,l2,l3; - BDS_Point *pts[3]; - sT[nnIdx[K] - sP.size() - sE.size()]->getNodes (pts); - pts[0]->getTriangles (l1); - pts[0]->getTriangles (l2); - pts[0]->getTriangles (l3); - l.insert(l.begin(),l1.begin(),l1.end()); - l.insert(l.begin(),l2.begin(),l2.end()); - l.insert(l.begin(),l3.begin(),l3.end()); - // l.push_back( sT[nnIdx[0] - sP.size() - sE.size()]); - } + BDS_Edge *e = sE[nnIdx[K]]; + e->p1->getTriangles (l1); + e->p2->getTriangles (l2); + l.insert(l.begin(),l1.begin(),l1.end()); + l.insert(l.begin(),l2.begin(),l2.end()); + l.sort(); + l.unique(); } #else @@ -193,7 +194,7 @@ double dist_droites_gauches(BDS_Point *p1, BDS_Point *p2, // les droites sont paralleles if (x == 0) { - throw; + return 1.e18; } // les droites sont gauches else @@ -681,81 +682,78 @@ void BDS_Mesh :: createSearchStructures ( ) #ifdef HAVE_ANN_ printf("creating the ANN search structure\n"); + + const double LC_SEARCH = LC *3.e-3; - for (std::set<BDS_GeomEntity*,GeomLessThan>::iterator it = geom.begin(); - it != geom.end(); - ++it) + for (std::set<BDS_GeomEntity*,GeomLessThan>::iterator it = geom.begin(); + it != geom.end(); + ++it) { - if ((*it)->classif_degree == 2) + if ((*it)->classif_degree == 2 && !(*it)->surf) { - std::set<BDS_Point*> pts; - std::set<BDS_Edge*> eds; - - if ((*it)->t.size() > 10) - { - std::list<BDS_Triangle*>::iterator tit = (*it)->t.begin(); - std::list<BDS_Triangle*>::iterator tite = (*it)->t.end(); - while (tit!=tite) - { - BDS_Point *nod[3]; - (*tit)->getNodes (nod); - pts.insert (nod[0]); - pts.insert (nod[1]); - pts.insert (nod[2]); - eds.insert((*tit)->e1); - eds.insert((*tit)->e2); - eds.insert((*tit)->e3); - tit++; - } - - printf("copying %d nodes %d edges and %d triangles\n",pts.size(),eds.size(),(*it)->t.size()); - (*it)->sT.resize((*it)->t.size()); - (*it)->sE.resize(eds.size()); - (*it)->sP.resize(pts.size()); - std::copy ( (*it)->t.begin(), (*it)->t.end(), (*it)->sT.begin() ); - std::copy ( pts.begin(), pts.end(), (*it)->sP.begin() ); - std::copy ( eds.begin(), eds.end(), (*it)->sE.begin() ); - - int maxPts = (*it)->sT.size() + (*it)->sE.size() + (*it)->sP.size(); - - printf("%d pts found\n",maxPts); - - const int dim = 3; - (*it)->queryPt = annAllocPt(dim); // allocate query point - (*it)->dataPts = annAllocPts(maxPts, dim); // allocate data points - (*it)->nnIdx = new ANNidx[(*it)->nbK]; // allocate near neigh indices - (*it)->dists = new ANNdist[(*it)->nbK]; // allocate near neighbor dists - - int I = 0; - - for (int i=0;i<(*it)->sP.size();i++) - { - (*it)->dataPts[I][0] = (*it)->sP[i]->X; - (*it)->dataPts[I][1] = (*it)->sP[i]->Y; - (*it)->dataPts[I][2] = (*it)->sP[i]->Z; - I++; - } - for (int i=0;i<(*it)->sE.size();i++) - { - (*it)->dataPts[I][0] = 0.5 * ((*it)->sE[i]->p1->X+(*it)->sE[i]->p2->X); - (*it)->dataPts[I][1] = 0.5 * ((*it)->sE[i]->p1->Y+(*it)->sE[i]->p2->Y); - (*it)->dataPts[I][2] = 0.5 * ((*it)->sE[i]->p1->Z+(*it)->sE[i]->p2->Z); - I++; - } - for (int i=0;i<(*it)->sT.size();i++) - { - const BDS_Vector cog = (*it)->sT[i]->cog(); - (*it)->dataPts[I][0] = cog.x; - (*it)->dataPts[I][1] = cog.y; - (*it)->dataPts[I][2] = cog.z; - I++; - } - printf("building kd Tree for surface %d -- %d points\n",(*it)->classif_tag,maxPts); - (*it)->kdTree = new ANNkd_tree( // build search structure - (*it)->dataPts, // the data points - maxPts, // number of points - dim); - } + if ((*it)->t.size() > 5) + { + int maxPts = 0; + + std::set<BDS_Edge *> edg; + + std::list<BDS_Triangle*>::iterator tit = (*it)->t.begin(); + std::list<BDS_Triangle*>::iterator tite = (*it)->t.end(); + + while (tit!=tite) + { + edg.insert ((*tit)->e1); + edg.insert ((*tit)->e2); + edg.insert ((*tit)->e3); + tit++; + } + + std::set<BDS_Edge*>::iterator eit = edg.begin(); + std::set<BDS_Edge*>::iterator eite = edg.end(); + while (eit!=eite) + { + double l = (*eit)->length(); + maxPts += (int)(l / (LC_SEARCH) + 2); + eit++; + } + + printf("%d pts found\n",maxPts); + + const int dim = 3; + (*it)->queryPt = annAllocPt(dim); // allocate query point + (*it)->dataPts = annAllocPts(maxPts, dim); // allocate data points + (*it)->nnIdx = new ANNidx[(*it)->nbK]; // allocate near neigh indices + (*it)->dists = new ANNdist[(*it)->nbK]; // allocate near neighbor dists + (*it)->sE.resize (maxPts); + (*it)->sR.resize (maxPts); + int I = 0; + + eit = edg.begin(); + eite = edg.end(); + while (eit!=eite) + { + double l = (*eit)->length(); + int N = (int)(l / (LC_SEARCH) + 2); + BDS_Point *p1= (*eit)->p1; + BDS_Point *p2= (*eit)->p2; + for (int i=0;i<N;i++) + { + double u = (double)i/(N-1); + (*it)->dataPts[I][0] = p1->X + (p2->X-p1->X) * (u); + (*it)->dataPts[I][1] = p1->Y + (p2->Y-p1->Y) * (u); + (*it)->dataPts[I][2] = p1->Z + (p2->Z-p1->Z) * (u); + (*it)->sE[I] = (*eit); + (*it)->sR[I] = p1->radius_of_curvature + (p2->radius_of_curvature-p1->radius_of_curvature) * (u);; + I++; + } + eit++; + } + printf("building kd Tree for surface %d -- %d points\n",(*it)->classif_tag,maxPts); + (*it)->kdTree = new ANNkd_tree( // build search structure + (*it)->dataPts, // the data points + maxPts, // number of points + dim); + } } } #endif @@ -768,6 +766,12 @@ void BDS_Point :: compute_curvature ( ) // printf("curvature using %d triangles\n",t.size()); + if (g && g->classif_degree != 2) + { + radius_of_curvature = 1.e22; + return; + } + if (t.size() > 4) { Double_Matrix M ( t.size() , 4 ); @@ -801,16 +805,44 @@ void BDS_Point :: compute_curvature ( ) // curvature = divergence of n - double curvature = Cx(0) + Cy(1) + Cz(2); + double curvature = fabs(Cx(0)) + fabs(Cy(1)) + fabs(Cz(2)); if (curvature != 0.0) - radius_of_curvature = fabs(1/curvature); + radius_of_curvature = fabs(1./curvature); else radius_of_curvature = 1.e22; - // printf(" R = %g\n",radius_of_curvature); + printf(" R = %g\n",radius_of_curvature); } } +int compute_curvatures (std::list<BDS_Edge*> &edges) +{ + std::list<BDS_Edge*>::iterator it = edges.begin(); + std::list<BDS_Edge*>::iterator ite = edges.end(); + while (it != ite) + { + if ((*it)->numfaces() == 2) + { + if ((*it)->faces(0)->g == (*it)->faces(1)->g) + { + BDS_Vector N1=(*it)->faces(0)->N(); + BDS_Vector N2=(*it)->faces(1)->N(); + BDS_Vector C1=(*it)->faces(0)->cog(); + BDS_Vector C2=(*it)->faces(1)->cog(); + BDS_Vector DIFFN = N2-N1; + BDS_Vector DIST = C2-C1; + double crv = 1./sqrt((DIFFN*DIFFN)/(DIST*DIST)); + if ((*it)->p1->radius_of_curvature > crv) + (*it)->p1->radius_of_curvature = crv; + if ((*it)->p2->radius_of_curvature > crv) + (*it)->p2->radius_of_curvature = crv; + } + } + ++it; + } +} + + void recur_color_plane_surf ( const double eps, BDS_Triangle *t , const BDS_Vector &n, @@ -901,23 +933,6 @@ void BDS_Mesh :: classify ( double angle, int NB_T ) } geom.clear(); } - - - { - std::set<BDS_Point*,PointLessThan>::iterator it = points.begin(); - std::set<BDS_Point*,PointLessThan>::iterator ite = points.end(); - while (it != ite) - { - (*it)-> compute_curvature ( ); - ++it; - } - } - - // color plane surfaces - - // if (NB_T > 0)color_plane_surf (1.e-4, NB_T); - - { std::list<BDS_Edge*>::iterator it = edges.begin(); std::list<BDS_Edge*>::iterator ite = edges.end(); @@ -1144,11 +1159,14 @@ void BDS_Mesh :: classify ( double angle, int NB_T ) ++it; } } + printf(" computing curvatures\n"); + compute_curvatures (edges); printf(" reverse engineering surfaces\n"); reverseEngineerCAD ( ) ; printf(" creating search structures\n"); createSearchStructures ( ) ; printf(" end classifying %d edgetags %d vertextags\n",edgetag-1,vertextag-1); + outputScalarField (triangles,"R_curvature.pos"); } double PointLessThanLexicographic::t = 0; double BDS_Vector::t = 0; @@ -1816,7 +1834,6 @@ bool BDS_Mesh ::split_edge ( BDS_Edge *e, double coord, BDS_Mesh *geom ) snap_point (mid, geom); - return true; } @@ -1852,6 +1869,7 @@ bool BDS_Mesh ::swap_edge ( BDS_Edge *e) BDS_Point *p1 = e->p1; BDS_Point *p2 = e->p2; e->oppositeof (op); + BDS_GeomEntity *g1=0,*g2=0,*ge=e->g; BDS_Point *pts1[3]; @@ -2088,43 +2106,43 @@ bool project_point_on_a_list_of_triangles ( BDS_Point *p , void BDS_Mesh :: snap_point ( BDS_Point *p , BDS_Mesh *geom_mesh ) { - if (p->g->surf) + if (p->g->surf) { - p->g->surf->projection ( p->X,p->Y,p->Z,p->X,p->Y,p->Z); + p->g->surf->projection ( p->X,p->Y,p->Z,p->X,p->Y,p->Z); } - else if (p->g && p->g->classif_degree == 2 && geom_mesh) + else if (p->g && p->g->classif_degree == 2 && geom_mesh) + { + std::list<BDS_Triangle*> l; + BDS_GeomEntity *gg = geom_mesh->get_geom(p->g->classif_tag,p->g->classif_degree); + gg->getClosestTriangles (p->X,p->Y,p->Z,l,p->radius_of_curvature); + bool ok = project_point_on_a_list_of_triangles ( p , l, p->X,p->Y,p->Z); + + if (!ok) { - std::list<BDS_Triangle*> l; - BDS_GeomEntity *gg = geom_mesh->get_geom(p->g->classif_tag,p->g->classif_degree); - gg->getClosestTriangles (p->X,p->Y,p->Z,l); - bool ok = project_point_on_a_list_of_triangles ( p , l, p->X,p->Y,p->Z); - - if (!ok) - { - SNAP_FAILURE++; - } - else - { - SNAP_SUCCESS++; - } - + SNAP_FAILURE++; } - else - { - return; - } - - { - std::list<BDS_Triangle *> t; - p->getTriangles (t); - std::list<BDS_Triangle *>::iterator tit = t.begin(); - std::list<BDS_Triangle *>::iterator tite = t.end(); - while (tit!=tite) + else { - (*tit)->_update(); - ++tit; - } + SNAP_SUCCESS++; + } + + } + else + { + return; } + + { + std::list<BDS_Triangle *> t; + p->getTriangles (t); + std::list<BDS_Triangle *>::iterator tit = t.begin(); + std::list<BDS_Triangle *>::iterator tite = t.end(); + while (tit!=tite) + { + (*tit)->_update(); + ++tit; + } + } } bool BDS_Mesh ::smooth_point ( BDS_Point *p , BDS_Mesh *geom_mesh ) @@ -2178,18 +2196,6 @@ void BDS_Mesh :: compute_metric_edge_lengths (const BDS_Metric & metric) ++it; } } - // printf("computation of curvatures\n"); - { - std::set<BDS_Point*, PointLessThan>::iterator it = points.begin(); - std::set<BDS_Point*, PointLessThan>::iterator ite = points.end(); - while (it != ite) - { - if ((*it)->g && !(*it)->g->surf) - (*it)->compute_curvature (); - ++it; - } - } - { std::list<BDS_Edge*>::iterator it = edges.begin(); @@ -2204,15 +2210,15 @@ void BDS_Mesh :: compute_metric_edge_lengths (const BDS_Metric & metric) 0.5*(e->p1->Y+e->p2->Y), 0.5*(e->p1->Z+e->p2->Z)); double radius = 1./curvature; - double target = radius / 5.0; + double target = 3.14159 *radius / 3.0; e->target_length = metric.update_target_length (target,e->target_length); // printf("e1 radius %g target %g length %g mlp %g ml %g\n",radius, target,e->length(),e->length()/target,e->metric_length); } else { - double radius = 1/(0.5*(1/e->p1->radius_of_curvature+1/e->p2->radius_of_curvature)); - double target = radius / 5.0; - e->target_length = metric.update_target_length (target,e->target_length); + double radius = 0.5*(e->p1->radius_of_curvature+e->p2->radius_of_curvature); + double target = 3.14159 * radius / 3.0; + e->target_length = metric.update_target_length (target,e->target_length); } ++it; @@ -2252,6 +2258,7 @@ void BDS_Mesh :: compute_metric_edge_lengths (const BDS_Metric & metric) // printf("end computation of metric lengths\n"); } + int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh) { int nb_modif = 0; @@ -2403,7 +2410,7 @@ int BDS_Mesh :: adapt_mesh ( double l, bool smooth, BDS_Mesh *geom_mesh) } printf("%d snaps have succeeded , %d have failed\n",SNAP_SUCCESS,SNAP_FAILURE); - + outputScalarField (triangles,"b.pos"); return nb_modif; } diff --git a/Mesh/BDS.h b/Mesh/BDS.h index 4cc3660598..5e17455aa5 100644 --- a/Mesh/BDS.h +++ b/Mesh/BDS.h @@ -72,16 +72,15 @@ public: ANNidxArray nnIdx; // near neighbor indices ANNdistArray dists; // near neighbor distances ANNkd_tree* kdTree; // search structure - std::vector<BDS_Triangle *> sT; std::vector<BDS_Edge *> sE; - std::vector<BDS_Point *> sP; + std::vector<double> sR; #endif std::list<BDS_Triangle *> t; std::list<BDS_Edge *> e; BDS_Point *p; BDS_Surface *surf; void getClosestTriangles ( double x, double y, double z, - std::list<BDS_Triangle*> &l ); + std::list<BDS_Triangle*> &l , double &radius); inline bool operator < ( const BDS_GeomEntity & other ) const { if (classif_degree < other.classif_degree)return true; @@ -92,7 +91,7 @@ public: BDS_GeomEntity (int a, int b) : classif_tag (a),classif_degree(b),p(0),surf(0) { - nbK=3; + nbK=1; #ifdef HAVE_ANN_ kdTree = 0; #endif @@ -131,6 +130,10 @@ public: { return BDS_Vector (x+v.x,y+v.y,z+v.z); } + BDS_Vector operator - (const BDS_Vector &v) + { + return BDS_Vector (x-v.x,y-v.y,z-v.z); + } inline BDS_Vector operator % (const BDS_Vector &other) const { return BDS_Vector(y*other.z-z*other.y, diff --git a/Mesh/DiscreteSurface.cpp b/Mesh/DiscreteSurface.cpp index 35d7ade82d..0f2ef6f65c 100644 --- a/Mesh/DiscreteSurface.cpp +++ b/Mesh/DiscreteSurface.cpp @@ -1,4 +1,4 @@ -// $Id: DiscreteSurface.cpp,v 1.21 2005-08-19 14:07:34 remacle Exp $ +// $Id: DiscreteSurface.cpp,v 1.22 2005-08-24 14:32:56 remacle Exp $ // // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle // @@ -179,7 +179,7 @@ void BDS_To_Mesh(Mesh *m) int MeshDiscreteSurface(Surface *s) { - const int NITER = 20; + const int NITER = 10; if(s->bds){ Msg(STATUS2, "Discrete Surface Mesh Generator..."); // s->bds is the discrete surface that defines the geometry -- GitLab