Surface parameterization

I am trying to get a parameterized surface on a surface mesh (which is read from an STL file.). I have read some examples about parameterization provided by the CGAL examples directory. I learn that the seam line must be provided to get a parametric surface on an arbitrary surface. But still I don't understand how to make a seam line. Below is my code. So I want to know

1) When CGAL :: Parameterization_mesh_feature_extractor is used, how can I get the vertices on the feature curves and draw a seam line with the vertices?

2) Does CGAL provide a way to get the intersection curve of a given surface and the cutting plane so that I can get a parameterized surface on a portion of a given surface?

#include <cstdio>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include <CGAL/IO/io.h>
#include <CGAL/IO/STL_reader.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/polygon_soup_to_polyhedron_3.h>
#include <CGAL/Parameterization_polyhedron_adaptor_3.h>
#include <CGAL/Parameterization_mesh_patch_3.h>
#include <CGAL/parameterize.h>


int main(int argc, char* argv[]) {
  clock_t time1, time2;
  double read_time, write_time, build_time;
  if(argc == 1) {
    std::cout << "Please, give me a filename" << std::endl;
   return 0;
  }

  std::ifstream infile(argv[1]);

  if(infile.bad()) {
    std::cout << "Infile not found or file corrupt" << std::endl;
    return 1;
  }

  std::vector<CGAL::cpp11::array<double, 3> > points;
  std::vector<CGAL::cpp11::array<int, 3> > triangles;

  time1 = clock();
  if (!CGAL::read_STL(infile, points, triangles)) {
    std::cerr << "Error: invalid STL file" << std::endl;
    return 0;
  }
  time2 = clock();
  read_time = float(time2 - time1) / CLOCKS_PER_SEC;
  fprintf(stdout, "Read time  : %5.2f sec\n", read_time);

  // Write polyhedron in Tecplot format
  std::ofstream ofs("mesh.dat");
  CGAL::set_ascii_mode(ofs);
  time1 = clock();
  ofs << "TITLE=\"\"" << std::endl;
  ofs << "VARIABLES=\"X\" \"Y\" \"Z\"" << std::endl;
  ofs << "ZONE T=\"None\" N=" << points.size() << " E=" << triangles.size() << " F=FEPOINT ET=TRIANGLE" << std::endl; 

  ofs.setf(std::ios::fixed);
  ofs.precision(6);
  for(std::vector<CGAL::cpp11::array<double, 3> >::iterator i = points.begin(); i != points.end(); ++i) {
    ofs << (*i)[0] << " " << (*i)[1] << " " << (*i)[2] << std::endl;
  }

  for(std::vector<CGAL::cpp11::array<int, 3> >::iterator i = triangles.begin(); i != triangles.end(); ++i) {
    ofs << (*i)[0]+1 << " " << (*i)[1]+1 << " " << (*i)[2]+1 << std::endl;
  }
  time2 = clock();
  write_time = float(time2 - time1) / CLOCKS_PER_SEC;
  fprintf(stdout, "Write time : %5.2f sec\n", write_time);



  // build mesh

  typedef CGAL::Simple_cartesian<double>      Kernel;
  typedef CGAL::Polyhedron_3<Kernel>          Polyhedron;

  Polyhedron mesh;

  time1 = clock();
  try{
  // Try building a polyhedron
    CGAL::polygon_soup_to_polyhedron_3(mesh, points, triangles);

    if(! mesh.is_valid() || mesh.empty()){
      std::cerr << "Error: Invalid polyhedron" << std::endl;
    }
  }
  catch(...){}
  time2 = clock();
  build_time= float(time2 - time1) / CLOCKS_PER_SEC;
  fprintf(stdout, "Build time : %5.2f sec\n", build_time);


  // parameterization
  typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> Parameterization_polyhedron_adaptor;
  // Type describing a border or seam as a vertex list
  typedef std::list<Parameterization_polyhedron_adaptor::Vertex_handle> Seam;

  //Create a second adaptor that virtually "cuts" the mesh following the 'seam' path
  typedef CGAL::Parameterization_mesh_patch_3<Parameterization_polyhedron_adaptor> Mesh_patch_polyhedron; 

  Parameterization_polyhedron_adaptor mesh_adaptor(mesh);


  ////////////////////// cut graph ////////////////////////////////
  typedef CGAL::Parameterization_mesh_feature_extractor<Parameterization_polyhedron_adaptor>
      Mesh_feature_extractor;

  Seam seam;
  // Get reference to Polyhedron_3 mesh
  Polyhedron& mesh_ref = mesh_adaptor.get_adapted_mesh();

  // Extract mesh borders and compute genus
  Mesh_feature_extractor feature_extractor(mesh_adaptor);
  int nb_borders = feature_extractor.get_nb_borders();
  int genus = feature_extractor.get_genus(); // genus means a hole inside a surface

  std::cout << "# borders: " << nb_borders << " # holes: " << genus << std::endl;
  std::cout << feature_extractor.get_borders()[0] << std::endl;
  ///////////////////// end of cut graph //////////////////////////

  /*
  Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end());

  if (!mesh_patch.is_valid())
  {
      std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl;
      return EXIT_FAILURE;
  }

  typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron> Parameterizer; // Type that defines the error codes
  Parameterizer::Error_code err = CGAL::parameterize(mesh_patch);

  switch(err) {
      case Parameterizer::OK: // Success
          break;
      case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported
      case Parameterizer::ERROR_NON_TRIANGULAR_MESH:
      case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC:
      case Parameterizer::ERROR_BORDER_TOO_SHORT:
          std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl;
          return EXIT_FAILURE;
          break;
      default: // Error
          std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl;
          return EXIT_FAILURE;
          break;
  };


  // Raw output: dump (u,v) pairs
  Polyhedron::Vertex_const_iterator pVertex;
  for (pVertex = mesh.vertices_begin(); pVertex != mesh.vertices_end(); pVertex++)
  {
      // (u,v) pair is stored in any halfedge
      double u = mesh_adaptor.info(pVertex->halfedge())->uv().x();
      double v = mesh_adaptor.info(pVertex->halfedge())->uv().y();
      std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl;
  }
  */
  return 0;
}

      

+3


source to share





All Articles