bool rtree_callback_3D(MVertex *neighbour, void *w) { Wrapper3D *wrapper; wrapper = static_cast<Wrapper3D *>(w); const MVertex *individual = wrapper->get_individual(); const MVertex *parent = wrapper->get_parent(); if(parent == neighbour) return true; // frameFieldBackgroundMesh3D* bgm = wrapper->bgm(); // const MVertex *closest = bgm->get_nearest_neighbor(individual); // const double h = bgm->size(closest);// get approximate size, closest // vertex, faster ?! STensor3 crossfield; // bgm->eval_approximate_crossfield(closest, crossfield); double *h = wrapper->get_size(); STensor3 *crossfield = wrapper->get_crossfield(); const double distance = infinity_distance_3D(individual, neighbour, (*crossfield)); if(distance < k1 * (*h)) { wrapper->set_ok(false); return false; } return true; };
bool Filler3D::treat_region(GRegion *gr) { BGMManager::set_use_cross_field(true); bool use_vectorial_smoothness; bool use_fifo; string algo; // readValue("param.dat","SMOOTHNESSALGO",algo); algo.assign("SCALAR"); if (!algo.compare("SCALAR")){ use_vectorial_smoothness = false; use_fifo = false; } else if (!algo.compare("FIFO")){ use_vectorial_smoothness = false; use_fifo = true; } else{ cout << "unknown SMOOTHNESSALGO !" << endl; throw; } const bool debug=false; const bool export_stuff=true; double a; cout << "ENTERING POINTINSERTION3D" << endl; // acquire background mesh cout << "pointInsertion3D: recover BGM" << endl; a = Cpu(); frameFieldBackgroundMesh3D *bgm = dynamic_cast<frameFieldBackgroundMesh3D*>(BGMManager::get(gr)); time_smoothing += (Cpu() - a); if (!bgm){ cout << "pointInsertion3D:: BGM dynamic cast failed ! " << endl; throw; } // export BGM fields if(export_stuff){ cout << "pointInsertion3D: export size field " << endl; stringstream ss; ss << "bg3D_sizefield_" << gr->tag() << ".pos"; bgm->exportSizeField(ss.str()); cout << "pointInsertion3D : export crossfield " << endl; stringstream sscf; sscf << "bg3D_crossfield_" << gr->tag() << ".pos"; bgm->exportCrossField(sscf.str()); cout << "pointInsertion3D : export smoothness " << endl; stringstream sss; sss << "bg3D_smoothness_" << gr->tag() << ".pos"; bgm->exportSmoothness(sss.str()); if (use_vectorial_smoothness){ cout << "pointInsertion3D : export vectorial smoothness " << endl; stringstream ssvs; ssvs << "bg3D_vectorial_smoothness_" << gr->tag() << ".pos"; bgm->exportVectorialSmoothness(ssvs.str()); } } // ---------------- START FILLING NEW POINTS ---------------- cout << "pointInsertion3D : inserting points in region " << gr->tag() << endl; //ProfilerStart("/home/bernard/profile"); a = Cpu(); // ----- initialize fifo list ----- RTree<MVertex*,double,3,double> rtree; listOfPoints *fifo; if (use_fifo) fifo = new listOfPointsFifo(); else if (use_vectorial_smoothness) fifo = new listOfPointsVectorialSmoothness(); else fifo = new listOfPointsScalarSmoothness(); set<MVertex*> temp; vector<MVertex*> boundary_vertices; map<MVertex*,int> vert_priority; map<MVertex*,double> smoothness_forplot; MElement *element; MVertex *vertex; list<GFace*> faces = gr->faces(); for(list<GFace*>::iterator it=faces.begin();it!=faces.end();it++){// for all faces GFace *gf = *it; // int limit = code_kesskessai(gf->tag()); for(unsigned int i=0;i<gf->getNumMeshElements();i++){ element = gf->getMeshElement(i); for(int j=0;j<element->getNumVertices();j++){// for all vertices vertex = element->getVertex(j); temp.insert(vertex); // limits.insert(make_pair(vertex,limit)); } } } int geodim; for(set<MVertex*>::iterator it=temp.begin();it!=temp.end();it++){ geodim = (*it)->onWhat()->dim(); if ((geodim==0) || (geodim==1) || (geodim==2)) boundary_vertices.push_back(*it); } double min[3],max[3],x,y,z,h; for(unsigned int i=0;i<boundary_vertices.size();i++){ x = boundary_vertices[i]->x(); y = boundary_vertices[i]->y(); z = boundary_vertices[i]->z(); // "on boundary since working on boundary_vertices ... MVertex *closest = bgm->get_nearest_neighbor_on_boundary(boundary_vertices[i]); h = bgm->size(closest);// get approximate size, closest vertex, faster ?! fill_min_max(x,y,z,h,min,max); rtree.Insert(min,max,boundary_vertices[i]); if (!use_vectorial_smoothness){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_smoothness(x,y,z); svp->dir = 0; svp->layer = 0; svp->size = h; bgm->eval_approximate_crossfield(closest, svp->cf); fifo->insert(svp); if (debug){ smoothness_forplot[svp->v] = svp->rank; } } else{ STensor3 temp; bgm->eval_approximate_crossfield(closest, temp); for (int idir=0;idir<3;idir++){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = boundary_vertices[i]; svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z); svp->dir = idir; svp->layer = 0; svp->size = h; svp->cf = temp; for (int k=0;k<3;k++) svp->direction(k) = temp(k,idir); // cout << "fifo size=" << fifo->size() << " inserting " ; fifo->insert(svp); // cout << " -> fifo size=" << fifo->size() << endl; } } } // TODO: si fifo était list of *PTR -> pas de copies, gain temps ? Wrapper3D wrapper; wrapper.set_bgm(bgm); MVertex *parent,*individual; new_vertices.clear(); bool spawn_created; int priority_counter=0; STensor3 crossfield; int parent_layer; while(!fifo->empty()){ parent = fifo->get_first_vertex(); // parent_limit = fifo->get_first_limit(); parent_layer = fifo->get_first_layer(); // if(parent_limit!=-1 && parent_layer>=parent_limit()){ // continue; // } vector<MVertex*> spawns; if (!use_vectorial_smoothness){ spawns.resize(6); computeSixNeighbors(bgm,parent,spawns,fifo->get_first_crossfield(), fifo->get_first_size()); } else{ spawns.resize(2); computeTwoNeighbors(bgm,parent,spawns,fifo->get_first_direction(), fifo->get_first_size()); } fifo->erase_first(); // cout << "while, fifo->size()=" << fifo->size() << " parent=(" << // parent->x() << "," << parent->y() << "," << parent->z() << ")" << // endl; for(unsigned int i=0;i<spawns.size();i++){ spawn_created = false; individual = spawns[i]; x = individual->x(); y = individual->y(); z = individual->z(); // cout << " working on candidate " << "(" << individual->x() << "," // << individual->y() << "," << individual->z() << ")" << endl; if(bgm->inDomain(x,y,z)){ // cout << " spawn " << i << " in domain" << endl; MVertex *closest = bgm->get_nearest_neighbor(individual); h = bgm->size(closest);// get approximate size, closest vertex, faster ?! if(far_from_boundary_3D(bgm,individual,h)){ // cout << " spawn " << i << " far from bnd" << endl; bgm->eval_approximate_crossfield(closest, crossfield); wrapper.set_ok(true); wrapper.set_individual(individual); wrapper.set_parent(parent); wrapper.set_size(&h); wrapper.set_crossfield(&crossfield); fill_min_max(x,y,z,h,min,max); rtree.Search(min,max,rtree_callback_3D,&wrapper); if(wrapper.get_ok()){ // cout << " spawn " << i << " wrapper OK" << endl; if (!use_vectorial_smoothness){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank=bgm->get_smoothness(individual->x(),individual->y(),individual->z()); svp->dir = 0; svp->layer = parent_layer+1; svp->size = h; svp->cf = crossfield; fifo->insert(svp); if (debug){ smoothness_forplot[svp->v] = svp->rank; vert_priority[individual] = priority_counter++; } } else{ if (debug) vert_priority[individual] = priority_counter++; for (int idir=0;idir<3;idir++){ smoothness_vertex_pair *svp = new smoothness_vertex_pair(); svp->v = individual; svp->rank = bgm->get_vectorial_smoothness(idir,x,y,z); svp->dir = idir; svp->layer = parent_layer+1; svp->size = h; for (int k=0;k<3;k++) svp->direction(k) = crossfield(k,idir); svp->cf = crossfield; fifo->insert(svp); } } rtree.Insert(min,max,individual); new_vertices.push_back(individual); spawn_created = true; } } } if(!spawn_created){ delete individual; } }// end loop on spawns } //ProfilerStop(); time_insert_points += (Cpu() - a); // --- output --- if (debug){ stringstream ss; ss << "priority_3D_" << gr->tag() << ".pos"; print_nodal_info(ss.str().c_str(),vert_priority); ss.clear(); stringstream sss; sss << "smoothness_3D_" << gr->tag() << ".pos"; print_nodal_info(sss.str().c_str(),smoothness_forplot); sss.clear(); } // ------- meshing using new points cout << "tets in gr before= " << gr->tetrahedra.size() << endl; cout << "nb new vertices= " << new_vertices.size() << endl; a=Cpu(); int option = CTX::instance()->mesh.algo3d; CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY; deMeshGRegion deleter; deleter(gr); std::vector<GRegion*> regions; regions.push_back(gr); meshGRegion mesher(regions); //? mesher(gr); //? MeshDelaunayVolume(regions); time_meshing += (Cpu() - a); cout << "tets in gr after= " << gr->tetrahedra.size() << endl; cout << "gr tag=" << gr->tag() << endl; CTX::instance()->mesh.algo3d = option; delete fifo; for(unsigned int i=0;i<new_vertices.size();i++) delete new_vertices[i]; new_vertices.clear(); rtree.RemoveAll(); return true; }