예제 #1
0
  /*
  Simplificate a mesh using CGALs Triangulated Surface Mesh Simplification
  (http://doc.cgal.org/latest/Surface_mesh_simplification/index.html#Chapter_Triangulated_Surface_Mesh_Simplification)
  */
   const char* CGALSimplificateSurface(const char* inputMeshFile,
                        const char* outputMeshFile,
                        int stopnr,
                        std::vector<double> box = std::vector<double>()) {
      vtkSmartPointer<vtkPolyData> inputPoly = IOHelper::VTKReadPolyData(inputMeshFile);
	  Polyhedron polyhedron;
	  VTKPolydataToCGALPolyhedron_converter(inputPoly, &polyhedron);

	  //create stop predicate
	  CGAL::Surface_mesh_simplification::Count_stop_predicate<Polyhedron> stop(stopnr);

	  Constrains_map constrains_map ;
	  //if box contains exactly six values, use region inside box to mark non-removable edges
	  if(box.size()==6)
	  {
		  int totalEdges=0;
		  int constrainedEdges=0;
		  log_debug()<<"bounding box given"<<std::endl;
		  //iterate over all edges, edges inside box will be marked as non-removable
		  for(Polyhedron::Halfedge_iterator eb = polyhedron.halfedges_begin(),
											 ee = polyhedron.halfedges_end() ; eb != ee ; ++ eb )
		  {
			  Point currentPoint = eb->vertex()->point();
			   //test if edge vertex is within box
			   if( (currentPoint[0]>=box[0]) && (currentPoint[1]>=box[1]) && (currentPoint[2]>=box[2])
                            && (currentPoint[0]<=box[3]) && (currentPoint[1]<=box[4]) && (currentPoint[2]<=box[5]))
			   {    //add to map of non-removable edges
					constrains_map.set_is_constrained(eb,true);
				    constrainedEdges++;
			   }
			   totalEdges++;
		  }
		  log_debug()<<"total edges: "<<totalEdges<<" constrained: "<<constrainedEdges<<std::endl;
	  }


	  //simplificate mesh
	  int r = CGAL::Surface_mesh_simplification::edge_collapse
				(polyhedron,stop,
				CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index,polyhedron))
				.edge_index_map (boost::get(CGAL::edge_external_index ,polyhedron))
				.edge_is_border_map(constrains_map)
				);
	  log_debug()<<"Edges removed: "<<r<<std::endl;
	  //now create polydata-object
	  vtkSmartPointer<vtkPolyData> vtkpoly = vtkSmartPointer<vtkPolyData>::New();
	  //convert polyhedron to polydata
	  CGALPolyhedronToVTKPolydata_converter(&polyhedron, vtkpoly);

	  //write polydata to disk
	  bool result = IOHelper::VTKWritePolyData(outputMeshFile,vtkpoly);
	  return outputMeshFile;
  }
void mergeColinear(Polyhedron& p) {
	int vertBefore =  p.size_of_vertices();
	bool colinearFound = true;
	while (colinearFound) {
		colinearFound = false; // Set temporarily to false, if merge degments then set true

		int percCount = 1;
		for (Polyhedron::Halfedge_iterator hit = p.halfedges_begin(); hit != p.halfedges_end(); ++hit,++percCount){
			if (CGAL::circulator_size(hit->vertex_begin()) == 1) {
				std::cerr << "WARNING: Loose edge, but how??"<<std::endl;
				while (CGAL::circulator_size(hit->vertex_begin()) == 1)
					hit = p.join_vertex(hit->opposite());
				break;
			}

			if ((CGAL::circulator_size(hit->vertex_begin()) == 2) &&			// if only two he connected to vertex
				(hit->facet_degree()>3 && hit->opposite()->facet_degree()>3)) { // if faces are not triangles // prob faster

				Vector_3 cur(hit->prev()->vertex()->point(),hit->vertex()->point());
				Vector_3 nex(hit->vertex()->point(),hit->next()->vertex()->point());
				if ( is_colinear(cur,nex)) {									// check if colinear
					std::cout << "\rVertices before/after: "<<vertBefore<<" -> "<< p.size_of_vertices()<<". ("<<100*percCount/p.size_of_halfedges()<<"%)";
					p.join_vertex(hit->opposite());								// move cur to prev point
					colinearFound = true;
					break;
	}	}	}	}
	std::cout << "\rVertices before/after: "<<vertBefore<<" -> "<< p.size_of_vertices()<<". (100%)" << std::endl;
}