Beispiel #1
0
//------------------------------------------------------------------------------
//	Initialize the dual center 
//------------------------------------------------------------------------------
void initAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    int vID = 0;
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->id()	= vID++;
	vi->label()	= DEFAULT_LABEL;
	vi->nCuts()	= 0;
    }
    cerr << "Total number of vertices = " << vID << endl;

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    int fID = 0;
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->id()	= fID++;
	// fi->label()	= DEFAULT_LABEL;
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
	// cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl;
    }
    cerr << "Total number of facets = " << fID << endl;

    // initialize the halfedge IDs
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->id() = NO_INDEX;
    }

    // assign the same IDs to the identical/ opposite halfedges
    int eID = 0;
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	if ( hi->id() == NO_INDEX ) {
	    assert( hi->opposite()->id() == NO_INDEX );
	    hi->id() = eID;
	    hi->opposite()->id() = eID;
	    eID++;
	    hi->label()		= hi->opposite()->label()	= DEFAULT_LABEL;
	    hi->match()		= hi->opposite()->match()	= DEFAULT_LABEL;
	    hi->cycle()		= hi->opposite()->cycle()	= NO_INDEX;
	    hi->weight()	= hi->opposite()->weight()	= 0.0;
	    hi->connect()	= hi->opposite()->connect()	= true;
	    hi->visit()		= hi->opposite()->visit()	= false;
	    // We individually handle hi->fixed
	}
    }
    cerr << "Total number of edges = " << eID << endl;
}
Beispiel #2
0
void initWeights( Polyhedron & poly )
{
    // assign the same IDs to the identical/ opposite halfedges
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->fixed()		= false;
    }
}
int main() {
    Polyhedron P;
    Build_triangle<HalfedgeDS> triangle;
    P.delegate( triangle);
    CGAL_assertion( P.is_triangle( P.halfedges_begin()));
    return 0;
}
Beispiel #4
0
void renewAttrs( Polyhedron & poly )
{
    // assign IDs to vertices
    for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) {
	vi->nCuts()	= 0;
    }

    // assign IDs to faces: the dual vertex and the dual coordinates-the center coordinates
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	fi->piece()	= NO_INDEX;
	Vector3 sum( 0.0, 0.0, 0.0 );
	Halfedge_facet_circulator hfc = fi->facet_begin();
	do {
	    sum = sum + ( hfc->vertex()->point() - CGAL::ORIGIN );
	} while ( ++hfc != fi->facet_begin() );
	sum = sum / ( double )CGAL::circulator_size( hfc );
	fi->center() = CGAL::ORIGIN + sum;
    }

    // assign the same IDs to the identical/ opposite halfedges
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	hi->label()		= DEFAULT_LABEL;
	hi->match()		= DEFAULT_LABEL;
	hi->cycle()		= NO_INDEX;
	hi->connect()		= true;
	hi->visit()		= false;
	hi->path()		= NO_INDEX;
	hi->orient()		= true;
	// We individually handle hi->fixed
    }
}
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;
}
/**
 * Set the label on all edges to be CHANNEL, RIDGE, or TRANSVERSE.
 */
void label_all_edges(Polyhedron& p)
{
    for (Halfedge_iterator i = p.halfedges_begin(); i != p.halfedges_end(); ++i)
    {
        // type is not initialized by the constructor, so we initialize it here.
        i->type = NO_TYPE;
        i->type = edge_type(i);
    }
}
void mergeCoplanar(Polyhedron& p,bool step2) {
	int facetsBefore =  p.size_of_facets();
	
	p.normalize_border();
	if(!p.size_of_border_halfedges()) {
		// Calculate normals only once in advace! so all tris should be coplanar with the original
		std::transform( p.facets_begin(), p.facets_end(),p.planes_begin(),Plane_equation());			// Calculate plane equations (only works on tri<- = bs)=true
		bool coplanarFound = true;
		std::vector<Polyhedron::Halfedge_handle> skipHEs;
		while (coplanarFound) {			
			coplanarFound = false;																		// Set coplanarFound false
			int percCount = 1;
			for (Polyhedron::Halfedge_iterator hit = p.halfedges_begin(); hit != p.halfedges_end(); ++hit,++percCount){ // Loop through all halfedges
				if (is_coplanar(hit,true)){																// If coplanar and equals semantics
					Polyhedron::Halfedge_handle removeMe = hit;
					while (CGAL::circulator_size(removeMe->vertex_begin()) < 3)							// Mover handle to beginning of linestring
						removeMe = removeMe->next();
					
					bool jcnh = false;
					if (!step2) jcnh = joinCreatesNoHole (hit);
					else		jcnh = joinCreatesNoHole2(hit);
					if (jcnh){														// If no holes will be created

						std::cout << "\rFacets   before/after: "<<facetsBefore<<" -> "<< p.size_of_facets()<<". ("<<100*percCount/p.size_of_halfedges()<<"%)";

						while (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)			// Join vertexes until at the other end of linestring
							if (removeMe->facet_degree()>3 && removeMe->opposite()->facet_degree()>3)
								removeMe = (p.join_vertex(removeMe))->next()->opposite();
							else																		// One of the faces turned into a triangle ->remove center vertex
								break;																	
						if (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)			// Remove remained of the border
							p.erase_center_vertex(removeMe->opposite());								// if two segments remain remove center point
						else
							p.join_facet(removeMe);														// if one segment remains join facets
						coplanarFound = true;
						break;
					} else { // simplify border, but how to do this safely? not optimal solution implemented. Should do: add inward offseted point of intersection etc.
						if (std::find(skipHEs.begin(), skipHEs.end(),hit)!=skipHEs.end()) {					// Skip if hit in skipList
							while (CGAL::circulator_size(removeMe->opposite()->vertex_begin()) < 3)	{		// Join vertexes until at the other end of linestring
								if (removeMe->facet_degree()>3 && removeMe->opposite()->facet_degree()>3)
									if (triDoesNotIntersectFacet(removeMe))									// if tri reMe,reME->prev does not intersect left or right facet
										removeMe = (p.join_vertex(removeMe))->next()->opposite();			// remove removeME
									else {
										skipHEs.push_back(removeMe);
										skipHEs.push_back(removeMe->opposite());
										removeMe = removeMe->prev();										// move removeME one halfedge back
									}
								else break;																	// stop if only a triangle remains or at other end																
							}	
							skipHEs.push_back(removeMe);
							skipHEs.push_back(removeMe->opposite());
	}	}	}	}	}	}
	//if (!step2) mergeCoplanar(p,true);
	//else 
		std::cout << "\rFacets   before/after: "<<facetsBefore<<" -> "<< p.size_of_facets()<<". (100%)"<<std::endl;
}
Beispiel #8
0
double shortest_edge(Polyhedron& p)
{
  double shortest = std::numeric_limits<double>::max();
  for (typename Polyhedron::Halfedge_iterator halfedge = p.halfedges_begin();
       halfedge != p.halfedges_end(); halfedge++)
  {
    const double length = get_edge_length<Polyhedron>(halfedge);
    shortest = std::min(shortest, length);
  }

  return shortest;
}
  /*
  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;
  }
Beispiel #10
0
//------------------------------------------------------------------------------
//	Compute and store the results of dual graphs into appropriate variables
//
//  computeDual( mesh, whole, bary, mid ); 
//------------------------------------------------------------------------------
void computeDual( Polyhedron & poly, Graph & dual,
		  vector< Point3 > & bary, vector< Point3 > & mid )
{
    // initialize the array of face barycenters: refer to the point at which the gravitational forces exerted by 2 objects are equal

    bary.clear();
    bary.resize( poly.size_of_facets() );

    // initialize the dual graph with dual vertices
    dual.clear();
    int fid = 0;
    for ( Facet_iterator fi = poly.facets_begin(); fi != poly.facets_end(); ++fi ) {
	// add a vertex: each face equals to each dual vertex
	add_vertex( dual );
	bary[ fid++ ] = fi->center(); 
	// cerr << " Barycenter No. " << fid-1 << " : " << bary[ fid-1 ] << endl;
    }

    int size_of_edges = poly.size_of_halfedges() / 2; //redundant

    // initialize the array of midpoints
    mid.clear();
    mid.resize( size_of_edges );

    // initialize the array of lengths
    // length.clear();
    // length.resize( size_of_edges );

    // construct the connecitivity of the dual graph
    for ( Halfedge_iterator hi = poly.halfedges_begin(); hi != poly.halfedges_end(); ++hi ) {
	int origID = hi->facet()->id(); // the face
	int destID = hi->opposite()->facet()->id(); // the neighbor face
	Point3 origCoord = hi->vertex()->point();
	Point3 destCoord = hi->opposite()->vertex()->point();
	Vector3 dispVec = origCoord - destCoord;
	Point3 midCoord = destCoord + 0.5 * dispVec;
	// double curLength = sqrt( dispVec.squared_length() ); // the length between two connected vertices
#ifdef DEBUG
	cerr << origID << " -- " << destID << endl;
#endif	// DEBUG	
	
	if ( origID < destID )
		add_edge( origID, destID, hi->id(), dual );  
		
	mid[ hi->id() ] = midCoord;
	hi->mid() = hi->opposite()->mid() = midCoord;
	hi->weight() = hi->opposite()->weight() = 1.0;
    }
}
int main() {
    Polyhedron P;
    Build_triangle<HalfedgeDS> triangle;
    P.delegate( triangle);
    CGAL_assertion( P.is_triangle( P.halfedges_begin()));
    
    CGAL::set_pretty_mode(std::cout);
    
    std::cout << "Success creating two triangles: "
                  << std::endl;
    
    std::cout << "The polyhedron created at this stage" << P << std::endl;
    
    running_iterators(P);

    return 0;
}
Beispiel #12
0
static void remove_short_edges(Polyhedron& p, const double threshold)
{
  while (true)
  {
    bool removed = false;
    for (typename Polyhedron::Halfedge_iterator halfedge = p.halfedges_begin();
	 halfedge != p.halfedges_end(); halfedge++)
    {
      if (get_edge_length<Polyhedron>(halfedge) < threshold)
      {
	remove_edge<Polyhedron>(p, halfedge);
	removed = true;
	break;
      }
    }

    if (!removed)
      break;
  }
}