Exemplo n.º 1
0
void Filler::treat_region(GRegion* gr){

  int NumSmooth = CTX::instance()->mesh.smoothCrossField;
  std::cout << "NumSmooth = " << NumSmooth << std::endl ;
  if(NumSmooth && (gr->dim() == 3)){
    double scale = gr->bounds().diag()*1e-2;
    Frame_field::initRegion(gr,NumSmooth);
    Frame_field::saveCrossField("cross0.pos",scale);

    Frame_field::smoothRegion(gr,NumSmooth);
    Frame_field::saveCrossField("cross1.pos",scale);
  }

#if defined(HAVE_RTREE)
  unsigned int i;
  int j;
  int count;
  int limit;
  bool ok2;
  double x,y,z;
  SPoint3 point;
  Node *node,*individual,*parent;
  MVertex* vertex;
  MElement* element;
  MElementOctree* octree;
  deMeshGRegion deleter;
  Wrapper wrapper;
  GFace* gf;
  std::queue<Node*> fifo;
  std::vector<Node*> spawns;
  std::vector<Node*> garbage;
  std::vector<MVertex*> boundary_vertices;
  std::set<MVertex*> temp;
  std::list<GFace*> faces;
  std::map<MVertex*,int> limits;
  std::set<MVertex*>::iterator it;
  std::list<GFace*>::iterator it2;
  std::map<MVertex*,int>::iterator it3;
  RTree<Node*,double,3,double> rtree;
  
  Frame_field::init_region(gr);
  Size_field::init_region(gr);
  Size_field::solve(gr);
  octree = new MElementOctree(gr->model());
  garbage.clear();
  boundary_vertices.clear();
  temp.clear();
  new_vertices.clear();
  faces.clear();
  limits.clear();

  faces = gr->faces();	
  for(it2=faces.begin();it2!=faces.end();it2++){
    gf = *it2;
	limit = code(gf->tag());
	for(i=0;i<gf->getNumMeshElements();i++){
	  element = gf->getMeshElement(i);
      for(j=0;j<element->getNumVertices();j++){
	    vertex = element->getVertex(j);
		temp.insert(vertex);
		limits.insert(std::pair<MVertex*,int>(vertex,limit));
	  }
	}
  }
		
  /*for(i=0;i<gr->getNumMeshElements();i++){
    element = gr->getMeshElement(i);
    for(j=0;j<element->getNumVertices();j++){
      vertex = element->getVertex(j);
      temp.insert(vertex);
    }
  }*/

  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==0){
	  boundary_vertices.push_back(*it);
	}
  }
	
  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==1){
	  boundary_vertices.push_back(*it);
	}
  }
	
  for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()==2){
	  boundary_vertices.push_back(*it);
	}
  }
	
  /*for(it=temp.begin();it!=temp.end();it++){
    if((*it)->onWhat()->dim()<3){
      boundary_vertices.push_back(*it);
    }
  }*/
  //std::ofstream file("nodes.pos");
  //file << "View \"test\" {\n";	

  for(i=0;i<boundary_vertices.size();i++){
    x = boundary_vertices[i]->x();
    y = boundary_vertices[i]->y();
    z = boundary_vertices[i]->z();
    
    node = new Node(SPoint3(x,y,z));
    compute_parameters(node,gr);
	node->set_layer(0);
	
	it3 = limits.find(boundary_vertices[i]);
	node->set_limit(it3->second);
	
	rtree.Insert(node->min,node->max,node);
	fifo.push(node);
    //print_node(node,file);
  }
  
  count = 1;
  while(!fifo.empty()){
    parent = fifo.front();
	fifo.pop();
	garbage.push_back(parent);
	  
	if(parent->get_limit()!=-1 && parent->get_layer()>=parent->get_limit()){
	  continue;
	}
	  
	spawns.clear();
	spawns.resize(6);
	  
	for(i=0;i<6;i++){
	  spawns[i] = new Node();
	}
	
	create_spawns(gr,octree,parent,spawns);
	
	for(i=0;i<6;i++){
	  ok2 = 0;
	  individual = spawns[i];
	  point = individual->get_point();
	  x = point.x();
	  y = point.y();
	  z = point.z();
	  
	  if(inside_domain(octree,x,y,z)){
		compute_parameters(individual,gr);
		individual->set_layer(parent->get_layer()+1);
		individual->set_limit(parent->get_limit());
		
		if(far_from_boundary(octree,individual)){
		  wrapper.set_ok(1);
		  wrapper.set_individual(individual);
		  wrapper.set_parent(parent);
		  rtree.Search(individual->min,individual->max,rtree_callback,&wrapper);
			
		  if(wrapper.get_ok()){
		    fifo.push(individual);
		    rtree.Insert(individual->min,individual->max,individual);
			vertex = new MVertex(x,y,z,gr,0);
			new_vertices.push_back(vertex);
			ok2 = 1;
			//print_segment(individual->get_point(),parent->get_point(),file);
		  }
	    }
	  }
		
	  if(!ok2) delete individual;
	}
	
	if(count%100==0){
	  printf("%d\n",count);
	}
	count++;
  }
  
  //file << "};\n";

  int option = CTX::instance()->mesh.algo3d;
  CTX::instance()->mesh.algo3d = ALGO_3D_DELAUNAY;

  deleter(gr);
  std::vector<GRegion*> regions;
  regions.push_back(gr);
  meshGRegion mesher(regions); //?
  mesher(gr); //?
  MeshDelaunayVolume(regions);

  CTX::instance()->mesh.algo3d = option;
	
  for(i=0;i<garbage.size();i++) delete garbage[i];
  for(i=0;i<new_vertices.size();i++) delete new_vertices[i];
  new_vertices.clear();
  delete octree;
  rtree.RemoveAll();
  Size_field::clear();
  Frame_field::clear();
#endif
}
Exemplo n.º 2
0
bool Filler3D::treat_region(GRegion *gr)
{
  BGMManager::set_use_cross_field(true);

  bool use_vectorial_smoothness;
  bool use_fifo;
  std::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 {
    std::cout << "unknown SMOOTHNESSALGO !" << std::endl;
    throw;
  }

  const bool debug = false;
  const bool export_stuff = true;
  double a;

  std::cout << "ENTERING POINTINSERTION3D" << std::endl;

  // acquire background mesh
  std::cout << "pointInsertion3D: recover BGM" << std::endl;
  a = Cpu();
  frameFieldBackgroundMesh3D *bgm =
    dynamic_cast<frameFieldBackgroundMesh3D *>(BGMManager::get(gr));
  time_smoothing += (Cpu() - a);

  if(!bgm) {
    std::cout << "pointInsertion3D:: BGM dynamic cast failed ! " << std::endl;
    throw;
  }

  // export BGM fields
  if(export_stuff) {
    std::cout << "pointInsertion3D: export size field " << std::endl;
    std::stringstream ss;
    ss << "bg3D_sizefield_" << gr->tag() << ".pos";
    bgm->exportSizeField(ss.str());

    std::cout << "pointInsertion3D : export crossfield " << std::endl;
    std::stringstream sscf;
    sscf << "bg3D_crossfield_" << gr->tag() << ".pos";
    bgm->exportCrossField(sscf.str());

    std::cout << "pointInsertion3D : export smoothness " << std::endl;
    std::stringstream sss;
    sss << "bg3D_smoothness_" << gr->tag() << ".pos";
    bgm->exportSmoothness(sss.str());

    if(use_vectorial_smoothness) {
      std::cout << "pointInsertion3D : export vectorial smoothness "
                << std::endl;
      std::stringstream ssvs;
      ssvs << "bg3D_vectorial_smoothness_" << gr->tag() << ".pos";
      bgm->exportVectorialSmoothness(ssvs.str());
    }
  }

  // ---------------- START FILLING NEW POINTS ----------------
  std::cout << "pointInsertion3D : inserting points in region " << gr->tag()
            << std::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();

  std::set<MVertex *> temp;
  std::vector<MVertex *> boundary_vertices;
  std::map<MVertex *, int> vert_priority;
  std::map<MVertex *, double> smoothness_forplot;
  MElement *element;
  MVertex *vertex;
  std::vector<GFace *> faces = gr->faces();
  for(std::vector<GFace *>::iterator it = faces.begin(); it != faces.end();
      it++) {
    GFace *gf = *it;
    // int limit = code_kesskessai(gf->tag());
    for(unsigned int i = 0; i < gf->getNumMeshElements(); i++) {
      element = gf->getMeshElement(i);
      for(std::size_t 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(std::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);

        // std::cout << "fifo size=" << fifo->size() << " inserting   "  ;
        fifo->insert(svp);
        // std::cout << " ->  fifo size=" << fifo->size() << std::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;
    //    }

    std::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();

    //    std::cout << "while, fifo->size()=" << fifo->size() << " parent=(" <<
    //    parent->x() << "," << parent->y() << "," << parent->z() << ")" <<
    //    std::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();
      //      std::cout << " working on candidate " << "(" << individual->x() <<
      //      ","
      //      << individual->y() << "," << individual->z() << ")" << std::endl;

      if(bgm->inDomain(x, y, z)) {
        //        std::cout << "   spawn " << i << " in domain" << std::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)) {
          //        std::cout << "   spawn " << i << " far from bnd" <<
          //        std::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()) {
            //        std::cout << "   spawn " << i << " wrapper OK" <<
            //        std::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) {
    std::stringstream ss;
    ss << "priority_3D_" << gr->tag() << ".pos";
    print_nodal_info(ss.str().c_str(), vert_priority);
    ss.clear();

    std::stringstream sss;
    sss << "smoothness_3D_" << gr->tag() << ".pos";
    print_nodal_info(sss.str().c_str(), smoothness_forplot);
    sss.clear();
  }

  // ------- meshing using new points
  std::cout << "tets in gr before= " << gr->tetrahedra.size() << std::endl;
  std::cout << "nb new vertices= " << new_vertices.size() << std::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);

  std::cout << "tets in gr after= " << gr->tetrahedra.size() << std::endl;
  std::cout << "gr tag=" << gr->tag() << std::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;
}