Ejemplo n.º 1
0
//Find the barycenter for each mesh and translate each mesh into the barycenter, returning mesh and barycenter
std::list<TranslatedMeshData> centerMeshesInBarycenter(std::list<MeshData> &listMeshData)
{

	std::list< std::pair<MeshData,PointCGAL> > result;
	std::list<MeshData>::iterator meshDataInter;
	for(meshDataInter = listMeshData.begin(); meshDataInter != listMeshData.end(); ++meshDataInter)
	{
		MeshData meshData = *meshDataInter;
		PointCGAL barycenter = getMeshBarycenter(meshData);
		MeshData meshDataTranslated = translateMesh(meshData, PointCGAL(-barycenter.x(), -barycenter.y(), -barycenter.z()));
		result.push_back(TranslatedMeshData(meshDataTranslated, barycenter));
	}

	return result;
}
Ejemplo n.º 2
0
cv::Point2d DelaunayTri::GetCircumcenter(const cv::Point2d &a, const cv::Point2d &b, const cv::Point2d &c) {
    PointCGAL p = dt.circumcenter(PointCGAL(a.x, a.y), PointCGAL(b.x, b.y), PointCGAL(c.x, c.y));
    return cv::Point2d(p.x(), p.y());
}
Ejemplo n.º 3
0
DelaunayTri::DelaunayTri(const std::vector<cv::Point2i> &XYpoints,
                         const int &width, const int &height, const int &size)
{

    this->width = width;
    this->height = height;

    img = cv::Mat::zeros(cv::Size(width, height), CV_8UC1);


    int i;
    points.resize(size);

    for(i = 0; i < size; ++i)
    {
        points[i] = std::make_pair(PointCGAL(XYpoints[i].x, XYpoints[i].y), i + 1);
    }

    dt.insert(points.begin(),points.end());

    int idxSize = 0;
    size_ = dt.number_of_faces();

    indices.resize(size_*3, -1);
    centers.resize(size_, cv::Point2d(0, 0));
    neighbors.resize(size_*3, 0.0);
    radii.resize(size_, 0.0);

    for(Delaunay::Finite_faces_iterator it = dt.finite_faces_begin(); it != dt.finite_faces_end(); it++) {

        cv::Point2d t[3];
        int idx[3];

        Delaunay::Face_handle face = it;

        int offset = idxSize * 3;
        for(i = 0; i < 3; i++) {
            t[i] = cv::Point2d(dt.triangle(face)[i].x(), dt.triangle(face)[i].y());
            *(idx + i) = face->vertex(i)->info();
            indices [offset + i] = face->vertex(i)->info();
        }

        this->insertMap(idx, idxSize);

        cv::Point2d circumCenter = this->GetCircumcenter(t[0], t[1], t[2]);

        centers[idxSize] = circumCenter;

        radii[idxSize] = distPoint2Point<double>(circumCenter.x, circumCenter.y,
                                                     t[1].x,  t[1].y);

        idxSize++;
    }

    //this->draw_subdiv();

    //cv::imwrite("delaunay.png", img);

    this->computeNeighbors();

}
Ejemplo n.º 4
0
PointCGAL converPointInexactToExact(KDPoint point)
{
	return PointCGAL(CGAL::to_double(point.x()), CGAL::to_double(point.y()), CGAL::to_double(point.z()));
}
Ejemplo n.º 5
0
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;
}
//The return values are the mass, the center of mass, and the inertia tensor relative to the
// center of mass. The code assumes that the rigid body has constant density 1. If the rigid body has constant
// density D, then you need to multiply the output mass by D and the output inertia tensor by D.
void calculateMassCenterInertia(TrianglesList &triangles, double &massReturn, PointCGAL &cmReturn, Vector &inertiaReturn)
{
    const REALD mult[10] = {1./6., 1./24., 1./24., 1./24., 1./60., 1./60., 1/60., 1./120., 1./120., 1./120.};
    REALD intg[10] = {0., 0., 0., 0., 0., 0., 0., 0., 0., 0.}; // order: 1, x, y, z, x^2, y^2, z^2, xy, yz, zx

    std::list<Triangle>::iterator triangleIter;
    for(triangleIter = triangles.begin(); triangleIter != triangles.end(); ++triangleIter)
    {
        Triangle t = *triangleIter;

        REALD x0 = CGAL::to_double(t.vertex(0).x());
        REALD y0 = CGAL::to_double(t.vertex(0).y());
        REALD z0 = CGAL::to_double(t.vertex(0).z());
        REALD x1 = CGAL::to_double(t.vertex(1).x());
        REALD y1 = CGAL::to_double(t.vertex(1).y());
        REALD z1 = CGAL::to_double(t.vertex(1).z());
        REALD x2 = CGAL::to_double(t.vertex(2).x());
        REALD y2 = CGAL::to_double(t.vertex(2).y());
        REALD z2 = CGAL::to_double(t.vertex(2).z());

        // get edges and cross product of edges
        REALD a1 = x1-x0;
        REALD b1 = y1-y0;
        REALD c1 = z1-z0;
        REALD a2 = x2-x0;
        REALD b2 = y2-y0;
        REALD c2 = z2-z0;
        REALD d0 = b1*c2-b2*c1;
        REALD d1 = a2*c1-a1*c2;
        REALD d2 = a1*b2-a2*b1;

        // compute integral terms
        REALD f1x, f2x, f3x, g0x, g1x, g2x, f1y, f2y, f3y, g0y, g1y, g2y, f1z, f2z, f3z, g0z, g1z, g2z;
        subexpressions_integral_terms(x0, x1, x2, f1x, f2x, f3x, g0x, g1x, g2x);
        subexpressions_integral_terms(y0, y1, y2, f1y, f2y, f3y, g0y, g1y, g2y);
        subexpressions_integral_terms(z0, z1, z2, f1z, f2z, f3z, g0z, g1z, g2z);

        // update integrals
        intg[0] += d0*f1x;
        intg[1] += d0*f2x;
        intg[2] += d1*f2y;
        intg[3] += d2*f2z;
        intg[4] += d0*f3x;
        intg[5] += d1*f3y;
        intg[6] += d2*f3z;
        intg[7] += d0*(y0*g0x+y1*g1x+y2*g2x);
        intg[8] += d1*(z0*g0y+z1*g1y+z2*g2y);
        intg[9] += d2*(x0*g0z+x1*g1z+x2*g2z);

    }

    //Multiple the coefficients
    for (int i = 0; i < 10; i++)
    {
        intg[i] *= mult[i];
    }

    //Mass of the body with a constant density 1
    REALD mass = intg[0];

    //Center of mass
    REALD cm_x = intg[1]/mass;
    REALD cm_y = intg[2]/mass;
    REALD cm_z = intg[3]/mass;

    //Inertia tensor relative to center of mass
    REALD inertia_xx = intg[5]+intg[6]-mass*(cm_y*cm_y+cm_z*cm_z);
    REALD inertia_yy = intg[4]+intg[6]-mass*(cm_z*cm_z+cm_x*cm_x);
    REALD inertia_zz = intg[4]+intg[5]-mass*(cm_x*cm_x+cm_y*cm_y);
    //REALD inertia_xy = -(intg[7]-mass*cm_x*cm_y);
    //REALD inertia_yz = -(intg[8]-mass*cm_y*cm_z);
    //REALD inertia_xz = -(intg[9]-mass*cm_z*cm_x);

    //Return the references values
    massReturn = fabs(mass);
    cmReturn = PointCGAL(cm_x, cm_y, cm_z);
    inertiaReturn = Vector(inertia_xx, inertia_yy, inertia_zz);

}