void CGALPolyhedronToVTKPolydata_converter(Polyhedron *polyhedron, vtkSmartPointer<vtkPolyData> polydata) { //convert from cgal polyhedron to vtk poly data //first the points vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> faces = vtkSmartPointer<vtkCellArray>::New(); //iterator over all vertices in polyhedron, add them as points std::map<Vertex_handle, vtkIdType> V; vtkIdType inum = 0; for ( Vertex_iterator v = polyhedron->vertices_begin(); v != polyhedron->vertices_end(); ++v) { points->InsertNextPoint(v->point()[0],v->point()[1],v->point()[2]); V[v] = inum++; } //now iterate over all faces in polyhedron for ( Facet_iterator i = polyhedron->facets_begin(); i != polyhedron->facets_end(); ++i) { Halfedge_around_facet_circulator j = i->facet_begin(); faces->InsertNextCell(CGAL::circulator_size(j)); do { //get indice of vertex, insert new cell point into faces faces->InsertCellPoint(V[j->vertex()]); } while(++j != i->facet_begin()); } // Set the points and faces of the polydata polydata->SetPoints(points); polydata->SetPolys(faces); }
void geometryUtils::renderPolyhedron(Polyhedron * pmesh) { glBegin(GL_TRIANGLES); for (Facet_iterator i = pmesh->facets_begin(); i != pmesh->facets_end(); i++) { Halfedge_around_facet_circulator j = i->facet_begin(); glColor3d(i->color[0].R, i->color[0].G, i->color[0].B); glVertex3d(CGAL::to_double(j->vertex()->point().x()), CGAL::to_double(j->vertex()->point().y()), CGAL::to_double(j->vertex()->point().z())); glColor3d(i->color[1].R, i->color[1].G, i->color[1].B); glVertex3d(CGAL::to_double(j->next()->vertex()->point().x()), CGAL::to_double(j->next()->vertex()->point().y()), CGAL::to_double(j->next()->vertex()->point().z())); glColor3d(i->color[2].R, i->color[2].G, i->color[2].B); glVertex3d(CGAL::to_double(j->next()->next()->vertex()->point().x()), CGAL::to_double(j->next()->next()->vertex()->point().y()), CGAL::to_double(j->next()->next()->vertex()->point().z())); } glEnd(); }
double AreaFacetTriangleSeg(Facet_iterator &f) { Halfedge_around_facet_circulator pHalfedge = f->facet_begin(); Point3d P = pHalfedge->vertex()->point(); Point3d Q = pHalfedge->next()->vertex()->point(); Point3d R = pHalfedge->next()->next()->vertex()->point(); Vector PQ=Q-P; //Vector PR=R-P; // MT Vector QR=R-Q; Vector normal = CGAL::cross_product(PQ,QR); double area=0.5*sqrt(normal*normal); return area; }
void geometryUtils::computeGaussCurvature(Polyhedron* P) { for (Facet_iterator i = P->facets_begin(); i != P->facets_end(); i++) { int e = 0; Halfedge_around_facet_circulator edge = i->facet_begin(); do { i->kappa[e] = computeLocalGaussCurvature(edge->vertex()); int H = floor(i->kappa[e] * geometryUtils::kappaMax + 180); // std::cout << H; // std::cout << " "; i->color[e] = HSVtoRGB(H, 1.0, 1.0); e++; } while (++edge != i->facet_begin()); // std::cout << edge->kappa; // std::cout << " "; } };
void Scene_textured_polyhedron_item::compute_normals_and_vertices(void) { positions_facets.resize(0); positions_lines.resize(0); textures_map_facets.resize(0); textures_map_lines.resize(0); normals.resize(0); typedef ::EPIC_kernel Kernel; typedef CGAL::Textured_items Items; typedef Kernel::Point_3 Point; typedef Kernel::Vector_3 Vector; typedef CGAL::Polyhedron_3<Kernel,Items> Base; typedef Base::Halfedge_around_facet_circulator Halfedge_around_facet_circulator; typedef Base::Edge_iterator Edge_iterator; typedef Base::Facet Facet; typedef Base::Facet_iterator Facet_iterator; //Facets Facet_iterator f = poly->facets_begin(); for(f = poly->facets_begin(); f != poly->facets_end(); f++) { Halfedge_around_facet_circulator he = f->facet_begin(); Halfedge_around_facet_circulator end = he; CGAL_For_all(he,end) { // If Flat shading:1 normal per polygon added once per vertex if (cur_shading == Flat || cur_shading == FlatPlusEdges) { Vector n = CGAL::Polygon_mesh_processing:: compute_face_normal(f, static_cast<Base&>(*poly)); normals.push_back(n[0]); normals.push_back(n[1]); normals.push_back(n[2]); } // If Gouraud shading: 1 normal per vertex else if(cur_shading == Gouraud) { const Facet::Normal_3& n = he->vertex()->normal(); normals.push_back(n[0]); normals.push_back(n[1]); normals.push_back(n[2]); } //position const Point& p = he->vertex()->point(); positions_facets.push_back(p.x()); positions_facets.push_back(p.y()); positions_facets.push_back(p.z()); positions_facets.push_back(1.0); const double u = he->vertex()->u(); const double v = he->vertex()->v(); textures_map_facets.push_back(u); textures_map_facets.push_back(v); } } //Lines typedef Kernel::Point_3 Point; typedef Base::Edge_iterator Edge_iterator; Edge_iterator he; for(he = poly->edges_begin(); he != poly->edges_end(); he++) { const Point& a = he->vertex()->point(); const Point& b = he->opposite()->vertex()->point(); positions_lines.push_back(a.x()); positions_lines.push_back(a.y()); positions_lines.push_back(a.z()); positions_lines.push_back(1.0); const double u = he->vertex()->u(); const double v = he->vertex()->v(); textures_map_lines.push_back(u); textures_map_lines.push_back(v); positions_lines.push_back(b.x()); positions_lines.push_back(b.y()); positions_lines.push_back(b.z()); positions_lines.push_back(1.0); const double ou = he->opposite()->vertex()->u(); const double ov = he->opposite()->vertex()->v(); textures_map_lines.push_back(ou); textures_map_lines.push_back(ov); } }
void Boolean_Operations_Component::SubdiviserPolyedre(PolyhedronPtr pMesh) { //Each facet must be triangular if(!pMesh->is_pure_triangle()) { pMesh->triangulate(); return; } Facet_iterator pFacet; Vector Vcenter; //Initialization of the tags for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++) { Halfedge_around_facet_circulator pHEcirc = pFacet->facet_begin(); pFacet->Issub = false; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; pHEcirc++; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; pHEcirc++; pHEcirc->Isnew = false; pHEcirc->vertex()->Isnew = false; } //For each facet of the polyhedron for (pFacet = pMesh->facets_begin(); pFacet != pMesh->facets_end(); pFacet++) { //We subdivide the facet if it is not already done if(!(pFacet->Issub)) { Halfedge_handle pHE = pFacet->facet_begin(); for(unsigned int i = 0;i!=5;i++) { if(!pHE->Isnew) { //each edge is splited in its center Vcenter = Vector(0.0, 0.0, 0.0); Vcenter = ( (pHE->vertex()->point() - CGAL::ORIGIN) + (pHE->opposite()->vertex()->point() - CGAL::ORIGIN) ) / 2; pHE = pMesh->split_edge(pHE); pHE->vertex()->point() = CGAL::ORIGIN + Vcenter; //update of the tags (the new vertex and the four new halfedges pHE->vertex()->Isnew = true; pHE->Isnew = true; pHE->opposite()->Isnew = true; pHE->next()->Isnew = true; pHE->next()->opposite()->Isnew = true; } pHE = pHE->next(); } //Three new edges are build between the three new vertices, and the tags of the facets are updated if(!pHE->vertex()->Isnew) pHE = pHE->next(); pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE = pMesh->split_facet(pHE, pHE->next()->next()); pHE->opposite()->facet()->Issub = true; pHE->facet()->Issub = true; } } }
void VSA_Component::Flooding() { m_Poly->NbFaceLabel=m_NbProxy; typedef std::multiset<FacetToIntegrate,CompFacet> ListFacet_model; typedef std::multiset<FacetToIntegrate,CompFacet>::iterator ListFacet_iterator; for(Facet_iterator pface = m_Poly->facets_begin(); pface != m_Poly->facets_end(); pface++) { pface->LabelVSA=-1; } ListFacet_model ListFacet; for(int i=0;i<m_NbProxy;i++)//For each proxy we select triangles that could grow { m_Table_Proxy[i].TabAdj.clear(); Facet_iterator f=m_Table_Proxy[i].Seed; f->LabelVSA=i; //we extract the three triangles Facet_iterator ff1, ff2, ff3; FacetToIntegrate f1, f2, f3; Halfedge_around_facet_circulator pHalfedge = f->facet_begin(); if(!pHalfedge->opposite()->is_border()) { ff1 = pHalfedge->opposite()->facet(); f1.Facet=ff1; f1.PossibleCluster=i; f1.DistanceLLoyd=DistorsionError(f1.Facet,m_Table_Proxy[i]); ListFacet.insert(f1); } if(!pHalfedge->next()->opposite()->is_border()) { ff2 = pHalfedge->next()->opposite()->facet(); f2.Facet=ff2; f2.PossibleCluster=i; f2.DistanceLLoyd=DistorsionError(f2.Facet,m_Table_Proxy[i]); ListFacet.insert(f2); } if(!pHalfedge->next()->next()->opposite()->is_border()) { ff3 = pHalfedge->next()->next()->opposite()->facet(); f3.Facet=ff3; f3.PossibleCluster=i; f3.DistanceLLoyd=DistorsionError(f3.Facet,m_Table_Proxy[i]); ListFacet.insert(f3); } } ListFacet_iterator it; for(it=ListFacet.begin();it!=ListFacet.end();) { if(it->Facet->LabelVSA==-1) { it->Facet->LabelVSA=it->PossibleCluster; //we add adjacent triangles to the queue //we extract the three triangles Facet_iterator ff1, ff2, ff3; Halfedge_around_facet_circulator pHalfedge = it->Facet->facet_begin(); FacetToIntegrate f1, f2, f3; if(!pHalfedge->opposite()->is_border()) { ff1 = pHalfedge->opposite()->facet(); if(ff1->LabelVSA==-1 ) { f1.Facet=ff1; f1.PossibleCluster=it->PossibleCluster; f1.DistanceLLoyd=DistorsionError(f1.Facet,m_Table_Proxy[it->PossibleCluster]); ListFacet.insert(f1); } } if(!pHalfedge->next()->opposite()->is_border()) { ff2 = pHalfedge->next()->opposite()->facet(); if(ff2->LabelVSA==-1) { f2.Facet=ff2; f2.PossibleCluster=it->PossibleCluster; f2.DistanceLLoyd=DistorsionError(f2.Facet,m_Table_Proxy[it->PossibleCluster]); ListFacet.insert(f2); } } if(!pHalfedge->next()->next()->opposite()->is_border()) { ff3 = pHalfedge->next()->next()->opposite()->facet(); if(ff3->LabelVSA==-1) { f3.Facet=ff3; f3.PossibleCluster=it->PossibleCluster; f3.DistanceLLoyd=DistorsionError(f3.Facet,m_Table_Proxy[it->PossibleCluster]); ListFacet.insert(f3); } } } ListFacet.erase(it); it=ListFacet.begin(); } //integration of the adjacency information between proxies /* for(Halfedge_iterator pHalfedge = m_Poly->halfedges_begin(); pHalfedge != m_Poly->halfedges_end(); pHalfedge++) { if(pHalfedge->is_border()||pHalfedge->opposite()->is_border()) continue; int Label1=pHalfedge->facet()->LabelVSA; int Label2=pHalfedge->opposite()->facet()->LabelVSA; if(Label1!=Label2) { bool IsFound=false; for(unsigned int i=0;i<m_Table_Proxy[Label1].TabAdj.size();i++) if(m_Table_Proxy[Label1].TabAdj[i]==Label2) IsFound=true; if(IsFound==false) { m_Table_Proxy[Label1].TabAdj.push_back(Label2); m_Table_Proxy[Label2].TabAdj.push_back(Label1); } } }*/ }
/* * mexFunction(): entry point for the mex function */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // interface to deal with input arguments from Matlab enum InputIndexType {IN_TRI, IN_X, IN_METHOD, IN_ITER, InputIndexType_MAX}; MatlabImportFilter::Pointer matlabImport = MatlabImportFilter::New(); matlabImport->ConnectToMatlabFunctionInput(nrhs, prhs); // check that we have all input arguments matlabImport->CheckNumberOfArguments(2, InputIndexType_MAX); // register the inputs for this function at the import filter MatlabInputPointer inTRI = matlabImport->RegisterInput(IN_TRI, "TRI"); MatlabInputPointer inX = matlabImport->RegisterInput(IN_X, "X"); MatlabInputPointer inMETHOD = matlabImport->RegisterInput(IN_METHOD, "METHOD"); MatlabInputPointer inITER = matlabImport->RegisterInput(IN_ITER, "ITER"); // interface to deal with outputs to Matlab enum OutputIndexType {OUT_TRI, OUT_N, OutputIndexType_MAX}; MatlabExportFilter::Pointer matlabExport = MatlabExportFilter::New(); matlabExport->ConnectToMatlabFunctionOutput(nlhs, plhs); // check number of outputs the user is asking for matlabExport->CheckNumberOfArguments(0, OutputIndexType_MAX); // register the outputs for this function at the export filter typedef MatlabExportFilter::MatlabOutputPointer MatlabOutputPointer; MatlabOutputPointer outTRI = matlabExport->RegisterOutput(OUT_TRI, "TRI"); MatlabOutputPointer outN = matlabExport->RegisterOutput(OUT_N, "N"); // if any of the inputs is empty, the output is empty too if (mxIsEmpty(prhs[IN_TRI]) || mxIsEmpty(prhs[IN_X])) { matlabExport->CopyEmptyArrayToMatlab(outTRI); matlabExport->CopyEmptyArrayToMatlab(outN); return; } // polyhedron to contain the input mesh Polyhedron mesh; PolyhedronBuilder<Polyhedron> builder(matlabImport, inTRI, inX); mesh.delegate(builder); // get size of input matrix with the points mwSize nrowsTri = mxGetM(inTRI->pm); mwSize nrowsX = mxGetM(inX->pm); #ifdef DEBUG std::cout << "Number of facets read = " << mesh.size_of_facets() << std::endl; std::cout << "Number of vertices read = " << mesh.size_of_vertices() << std::endl; #endif if (nrowsTri != mesh.size_of_facets()) { mexErrMsgTxt(("Input " + inTRI->name + ": Number of triangles read into mesh different from triangles provided at the input").c_str()); } if (nrowsX != mesh.size_of_vertices()) { mexErrMsgTxt(("Input " + inX->name + ": Number of vertices read into mesh different from vertices provided at the input").c_str()); } // sort halfedges such that the non-border edges precede the // border edges. We need to do this before any halfedge iterator // operations are valid mesh.normalize_border(); #ifdef DEBUG std::cout << "Number of border halfedges = " << mesh.size_of_border_halfedges() << std::endl; #endif // number of holes we have filled mwIndex n = 0; // a closed mesh with no holes will have no border edges. What we do // is grab a border halfedge and close the associated hole. This // makes the rest of the iterators invalid, so we have to normalize // the mesh again. Then we iterate, looking for a new border // halfedge, filling the hole, etc. // // Note that confusingly, mesh.border_halfedges_begin() gives a // pointer to the halfedge that is NOT a border in a border // edge. The border halfedge is instead // mesh.border_halfedges_begin()->opposite() while (!mesh.is_closed()) { // exit if user pressed Ctrl+C ctrlcCheckPoint(__FILE__, __LINE__); // get the first hole we can find, and close it mesh.fill_hole(mesh.border_halfedges_begin()->opposite()); // increase the counter of number of holes we have filled n++; // renormalize mesh so that halfedge iterators are again valid mesh.normalize_border(); } // split all facets to triangles CGAL::triangulate_polyhedron<Polyhedron>(mesh); // copy output with number of holes filled std::vector<double> nout(1, n); matlabExport->CopyVectorOfScalarsToMatlab<double, std::vector<double> >(outN, nout, 1); // allocate memory for Matlab outputs double *tri = matlabExport->AllocateMatrixInMatlab<double>(outTRI, mesh.size_of_facets(), 3); // extract the triangles of the solution // snippet adapted from CgalMeshSegmentation.cpp // vertices coordinates. Assign indices to the vertices by defining // a map between their handles and the index std::map<Vertex_handle, int> V; int inum = 0; for(Vertex_iterator vit = mesh.vertices_begin(); vit != mesh.vertices_end(); ++vit) { // save to internal list of vertices V[vit] = inum++; } // triangles given as (i,j,k), where each index corresponds to a vertex in x mwIndex row = 0; for (Facet_iterator fit = mesh.facets_begin(); fit != mesh.facets_end(); ++fit, ++row) { if (fit->facet_degree() != 3) { std::cerr << "Facet has " << fit->facet_degree() << " edges" << std::endl; mexErrMsgTxt("Facet does not have 3 edges"); } // go around the half-edges of the facet, to extract the vertices Halfedge_around_facet_circulator heit = fit->facet_begin(); int idx = 0; do { // extract triangle indices and save to Matlab output // note that Matlab indices go like 1, 2, 3..., while C++ indices go like 0, 1, 2... tri[row + idx * mesh.size_of_facets()] = 1 + V[heit->vertex()]; idx++; } while (++heit != fit->facet_begin()); } }