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;
};
Example #2
0
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;
}