Nef_polyhedron build_axes() { Nef_nary_union unioner; { debug(LOG_DEBUG, DEBUG_LOG, 0, "add X-axis"); Polyhedron p; Build_Arrow b(point(-0.1, 0, 0), point(4.1, 0, 0), arrowdiameter, 16); p.delegate(b); unioner.add_polyhedron(p); } { debug(LOG_DEBUG, DEBUG_LOG, 0, "add Y-axis"); Polyhedron p; Build_Arrow b(point(0, -2, 0), point(0, 2, 0), arrowdiameter, 16); p.delegate(b); unioner.add_polyhedron(p); } { debug(LOG_DEBUG, DEBUG_LOG, 0, "add Z-axis"); Polyhedron p; Build_Arrow b(point(0, 0, -2), point(0, 0, 2), arrowdiameter, 16); p.delegate(b); unioner.add_polyhedron(p); } debug(LOG_DEBUG, DEBUG_LOG, 0, "extract axes union"); return unioner.get_union(); }
int main() { Polyhedron P; Build_triangle<HalfedgeDS> triangle; P.delegate( triangle); CGAL_assertion( P.is_triangle( P.halfedges_begin())); return 0; }
Polyhedron generate_polyhedron( const MatrixFr& vertices, const MatrixIr& faces) { Polyhedron P; PolyhedronBuilder<HalfedgeDS> triangle(vertices, faces); P.delegate(triangle); assert(vertices.rows() == P.size_of_vertices()); assert(faces.rows() == P.size_of_facets()); return P; }
Nef_polyhedron build_support(double thickness) { if (!yzslicing) { CartesianDomain domain(Interval(-2, 2), Interval(0, 1)); CharSupport support; Build_CartesianPointFunction s(support, domain, 4 * steps, 2, thickness); Polyhedron p; p.delegate(s); return Nef_polyhedron(p); } else { CartesianDomain domain(Interval(0, 4), Interval(0, 2)); SupportSheet support; Build_CartesianPointFunction s(support, domain, steps, steps, thickness); Polyhedron p; p.delegate(s); return Nef_polyhedron(p); } }
Nef_polyhedron polyhedron_to_cgal( const polyhedron &p ){ polyhedron tmp = p.triangulate(); Polyhedron P; polyhedron_builder<HalfedgeDS> builder( tmp ); P.delegate( builder ); if( P.is_closed() ) return Nef_polyhedron( P ); else std::cout << "input polyhedron is not closed!" << std::endl; return Nef_polyhedron(); }
int main() { std::stringstream ss; ss << "\ OFF\n6 4 0\n\ 0 1 0\n\ 0 0 0\n\ 1 0 0\n\ 1 1 0\n\ 2 1 0\n\ 2 0 0\n\ 3 0 1 2\n\ 3 0 2 3\n\ 3 2 5 3\n\ 3 5 4 3\n"; Polyhedron P; ss >> P; assert( P.size_of_vertices() == 6); assert( P.size_of_facets() == 4); assert( P.is_valid() ); //consider vertex 3 and set its halfedge to be on the border Polyhedron::Vertex_iterator vit=P.vertices_begin(); std::advance(vit, 3); assert( vit->point() == K::Point_3(1, 1, 0) ); Polyhedron::Halfedge_handle h=vit->halfedge(); while ( !h->is_border() ) h=h->next()->opposite(); vit->VBase::set_halfedge(h); assert( vit->halfedge()->vertex() == vit ); //consider vertex 4 and set its halfedge to be on the border ++vit; assert( vit->point() == K::Point_3(2, 1, 0) ); h=vit->halfedge(); while ( !h->is_border() ) h=h->next()->opposite(); vit->VBase::set_halfedge(h); assert( vit->halfedge()->vertex() == vit ); //try to append a facet Appender modifier; P.delegate(modifier); assert( P.size_of_vertices() == 7); assert( P.size_of_facets() == 5); assert( P.is_valid() ); }
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; }
// Constructeur : Charge l'obj et génère les Polyhedron_3 associés DegradeAnObject::DegradeAnObject(char const *input, char const *output) { this->output = output; // load the input file load_obj(input); if( coords.size() == 0 ) { std::cout << "Aucun objet n'a été chargé" << std::endl; } else { std::cout << "objet chargé" << std::endl; // build polyhedrons from the loaded arrays for(int i = 0 ; i < names.size() ; i++) { Polyhedron P; polyhedron_builder<HalfedgeDS> builder( coords[i], faces[i], minFacets[i] ); P.delegate( builder ); polys.push_back(P); } } }
scalarField calcCurvature(const triSurface& surf) { scalarField k(surf.points().size(), 0); Polyhedron P; buildCGALPolyhedron convert(surf); P.delegate(convert); // Info<< "Created CGAL Polyhedron with " << label(P.size_of_vertices()) // << " vertices and " << label(P.size_of_facets()) // << " facets. " << endl; // The rest of this function adapted from // CGAL-3.7/examples/Jet_fitting_3/Mesh_estimation.cpp //Vertex property map, with std::map typedef std::map<Vertex*, int> Vertex2int_map_type; typedef boost::associative_property_map< Vertex2int_map_type > Vertex_PM_type; typedef T_PolyhedralSurf_rings<Polyhedron, Vertex_PM_type > Poly_rings; typedef CGAL::Monge_via_jet_fitting<Kernel> Monge_via_jet_fitting; typedef Monge_via_jet_fitting::Monge_form Monge_form; std::vector<Point_3> in_points; //container for data points // default parameter values and global variables unsigned int d_fitting = 2; unsigned int d_monge = 2; unsigned int min_nb_points = (d_fitting + 1)*(d_fitting + 2)/2; //initialize the tag of all vertices to -1 Vertex_iterator vitb = P.vertices_begin(); Vertex_iterator vite = P.vertices_end(); Vertex2int_map_type vertex2props; Vertex_PM_type vpm(vertex2props); CGAL_For_all(vitb, vite) { put(vpm, &(*vitb), -1); }
/* * 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()); } }
TrianglesList meshSimplification(TrianglesList &triangles, int stopPredicate) { #ifdef MESHSIMPLIFICATION_LOG CGAL::Timer timer; timer.start(); #endif TrianglesList result; try { Polyhedron P; #ifdef MESHSIMPLIFICATION_LOG std::cout << "Start Building Polyhedron surface... " << std::endl; #endif Build_triangle_mesh_coherent_surface<HalfedgeDS> triangle(triangles); P.delegate(triangle); P.normalize_border(); #ifdef MESHSIMPLIFICATION_LOG std::cout << "Completed Building Polyhedron surface:" << std::endl; std::cout << "Polyhedron is_pure_triangle: " << P.is_pure_triangle() << std::endl; std::cout << "Polyhedron is_closed: " << P.is_closed() << std::endl; std::cout << "Polyhedron is_pure_bivalent : " << P.is_pure_bivalent () << std::endl; std::cout << "Polyhedron is_pure_trivalent: " << P.is_pure_trivalent() << std::endl; std::cout << "Polyhedron is_valid 0: " << P.is_valid(false, 0) << std::endl; std::cout << "Polyhedron is_valid 1: " << P.is_valid(false, 1) << std::endl; std::cout << "Polyhedron is_valid 2: " << P.is_valid(false, 2) << std::endl; std::cout << "Polyhedron is_valid 3: " << P.is_valid(false, 3) << std::endl; std::cout << "Polyhedron is_valid 4: " << P.is_valid(false, 4) << std::endl; std::cout << "Polyhedron normalized_border_is_valid : " << P.normalized_border_is_valid(false) << std::endl; #endif #ifdef MESHSIMPLIFICATION_LOG std::cout << "Start edge_collapse... " << std::endl; #endif SMS::Count_stop_predicate<Polyhedron> stop(stopPredicate); int removedEdges = SMS::edge_collapse(P, stop, CGAL::vertex_index_map(boost::get(CGAL::vertex_external_index, P)).edge_index_map(boost::get(CGAL::edge_external_index ,P)) ); #ifdef MESHSIMPLIFICATION_LOG std::cout << "Completed edge_collapse:" << std::endl; std::cout << "Finished with: " << removedEdges << " edges removed and " << (P.size_of_halfedges()/2) << " final edges." << std::endl; #endif //Build output result for ( Polyhedron::Facet_iterator fit( P.facets_begin() ), fend( P.facets_end() ); fit != fend; ++fit ) { if ( fit->is_triangle() ) { PointCGAL verts[3]; int tick = 0; Polyhedron::Halfedge_around_facet_circulator hit( fit->facet_begin() ), hend( hit ); do { if ( tick < 3 ) { verts[tick++] = PointCGAL( hit->vertex()->point().x(), hit->vertex()->point().y(), hit->vertex()->point().z() ); } else { std::cout << "meshSimplification: We've got facets with more than 3 vertices even though the facet reported to be triangular..." << std::endl; } } while( ++hit != hend ); result.push_back( Triangle(verts[0], verts[1], verts[2]) ); } else { std::cout << "meshSimplification: Skipping non-triangular facet" << std::endl; } } } catch (CGAL::Assertion_exception e) { std::cout << "ERROR: meshSimplification CGAL::Assertion_exception" << e.message() << std::endl; } #ifdef MESHSIMPLIFICATION_LOG timer.stop(); std::cout << "meshSimplification result with: " << result.size() << " triangles." << std::endl; std::cout << "Total meshSimplification time: " << timer.time() << std::endl; #endif return result; }
/** * \brief main function for example6 */ int main(int argc, char *argv[]) { int c; while (EOF != (c = getopt(argc, argv, "dSACIXNPFxp:"))) switch (c) { case 'd': if (debuglevel == LOG_DEBUG) { debuglevel++; } else { debuglevel = LOG_DEBUG; } break; case 'S': show_solution = !show_solution; break; case 'A': show_alternatives = !show_alternatives; break; case 'C': show_characteristics = !show_characteristics; break; case 'I': show_initial = !show_initial; break; case 'X': show_axes = !show_axes; break; case 'N': show_negative = !show_negative; break; case 'F': show_fcurve = !show_fcurve; break; case 'P': show_support = !show_support; break; case 'p': prefix = std::string(optarg); break; case 'x': yzslicing = false; break; } debug(LOG_DEBUG, DEBUG_LOG, 0, "nonuniqueness of solution of a " "partial differential equation"); // start building up the union of things to be restricted to a box Nef_nary_union unioner; // create a the solution surface try { if (show_solution) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding solution surface"); unioner.add_polyhedron(build_solution(sheetthickness)); debug(LOG_DEBUG, DEBUG_LOG, 0, "solution surface added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add solution: %s", x.what()); } // create an alternative solution surface try { if (show_alternatives) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding alternatives"); unioner.add_polyhedron(build_alternative(sheetthickness)); debug(LOG_DEBUG, DEBUG_LOG, 0, "alternatives added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add alternatives: %s", x.what()); } // add additional characteristics try { if (show_characteristics) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding characteristics"); unioner.add_polyhedron(build_characteristics()); debug(LOG_DEBUG, DEBUG_LOG, 0, "characteristics added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add characteristics: %s", x.what()); } // add negative characteristics try { if (show_negative) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding neg characteristics"); unioner.add_polyhedron(build_xcharacteristics()); debug(LOG_DEBUG, DEBUG_LOG, 0, "neg characteristics added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add negative characteristics: %s", x.what()); } // add the FCurve try { if (show_fcurve) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding fcurve"); unioner.add_polyhedron(build_fcurve()); debug(LOG_DEBUG, DEBUG_LOG, 0, "fcurve added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add fcurve: %s", x.what()); } // add the support sheet try { if (show_support) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding support"); unioner.add_polyhedron(build_support(sheetthickness)); debug(LOG_DEBUG, DEBUG_LOG, 0, "support added"); } } catch (std::exception& x) { debug(LOG_ERR, DEBUG_LOG, 0, "failed to add support: %s", x.what()); } // add the initial curve if (show_initial) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding initial curve"); unioner.add_polyhedron(build_initialcurve()); debug(LOG_DEBUG, DEBUG_LOG, 0, "initial curve added"); } // extract union debug(LOG_DEBUG, DEBUG_LOG, 0, "extract the image component union"); Nef_polyhedron image = unioner.get_union(); debug(LOG_DEBUG, DEBUG_LOG, 0, "base image constructed"); // restrict everything to a box debug(LOG_DEBUG, DEBUG_LOG, 0, "restrict to a box"); Build_Box box(point(-0.1, -2, -2), point(4, 2, 2)); Polyhedron boxp; boxp.delegate(box); image = image * boxp; debug(LOG_DEBUG, DEBUG_LOG, 0, "restriction complete"); // add axes if (show_axes) { debug(LOG_DEBUG, DEBUG_LOG, 0, "adding axes"); image = image + build_axes(); debug(LOG_DEBUG, DEBUG_LOG, 0, "axes added"); } // output Polyhedron P; debug(LOG_DEBUG, DEBUG_LOG, 0, "convert to polyhedron for output"); image.convert_to_polyhedron(P); std::cout << P; // write parts if (prefix.size() > 0) { PartWriter pw(prefix); pw(PartWriter::LEFT_PART, image); pw(PartWriter::RIGHT_PART, image); pw(PartWriter::FRONT_PART, image); pw(PartWriter::BACK_PART, image); } else { debug(LOG_DEBUG, DEBUG_LOG, 0, "part output suppressed"); } // that's it debug(LOG_DEBUG, DEBUG_LOG, 0, "output complete"); return EXIT_SUCCESS; }