Пример #1
0
	void operator() (const TriMesh *themesh, int v0, vec &c,
			 float w, int v) const
	{
		vec ncurv;
		proj_curv(themesh->pdir1[v], themesh->pdir2[v],
			  themesh->curv1[v], 0, themesh->curv2[v],
			  themesh->pdir1[v0], themesh->pdir2[v0],
			  ncurv[0], ncurv[1], ncurv[2]);
		c += w * ncurv;
	}
Пример #2
0
void Curvature::computePrincipalCurvatures( Surface_mesh * src_mesh )
{
	computePointAreas(src_mesh);

	uint nv = src_mesh->n_vertices(), nf = src_mesh->n_faces();

	curv1.resize(nv);
	curv2.resize(nv);

	pdir1.resize(nv);
	pdir2.resize(nv);

	std::vector<double> curv12(nv);
	
	Surface_mesh::Vertex_property<Point> points = src_mesh->vertex_property<Point>("v:point");
	Surface_mesh::Vertex_property<Normal> normals = src_mesh->vertex_property<Normal>("v:normal");
	Surface_mesh::Face_iterator fit, fend = src_mesh->faces_end();
	Surface_mesh::Vertex_around_face_circulator fvit, fvend;
	Surface_mesh::Vertex_iterator vit, vend = src_mesh->vertices_end();

	//#pragma omp parallel for
	for (fit = src_mesh->faces_begin(); fit != fend; ++fit) 
	{
		fvit = src_mesh->vertices(fit);

		uint vi0 = ((Vertex)fvit).idx();  Point v0 = points[fvit]; ++fvit;
		uint vi1 = ((Vertex)fvit).idx();  Point v1 = points[fvit]; ++fvit;
		uint vi2 = ((Vertex)fvit).idx();  Point v2 = points[fvit];

		pdir1[vi0] = v1 - v0;
		pdir1[vi1] = v2 - v1;
		pdir1[vi2] = v0 - v2;
	}

	//#pragma omp parallel for
	for (vit = src_mesh->vertices_begin(); vit != vend; ++vit) 
	{
		uint vi = ((Vertex)vit).idx();

		pdir1[vi] = cross(pdir1[vi], normals[vit]);
		pdir1[vi].normalize();
		pdir2[vi] = cross(normals[vit], pdir1[vi]);
	}

	// Compute curvature per-face
	//#pragma omp parallel for
	for (fit = src_mesh->faces_begin(); fit != fend; ++fit) 
	{
		uint i = ((Surface_mesh::Face)fit).idx(); // face index

		uint vi[3];	Normal vn[3];
		fvit = src_mesh->vertices(fit);
		
		vi[0] = ((Vertex)fvit).idx(); Point v0 = points[fvit]; vn[0] = normals[fvit]; ++fvit;
		vi[1]  = ((Vertex)fvit).idx(); Point v1 = points[fvit]; vn[1] = normals[fvit]; ++fvit;
		vi[2]  = ((Vertex)fvit).idx(); Point v2 = points[fvit]; vn[2] = normals[fvit]; ++fvit;

		// Edges
		Point e[3] = {v2 - v1,  v0 - v2,  v1 - v0};

		// N-T-B coordinate system per face
		Point t = e[0];
		t.normalize();
		Point n = cross(e[0], e[1]);
		Point b = cross(n, t);
		b.normalize();

		// Estimate curvature based on variation of normals
		// along edges
		double m[3] = { 0, 0, 0 };
		double w[3][3] = { {0,0,0}, {0,0,0}, {0,0,0} };
		for (int j = 0; j < 3; j++) {
			double u = dot(e[j], t);
			double v = dot(e[j], b);
			w[0][0] += u*u;
			w[0][1] += u*v;
			//w[1][1] += v*v + u*u; 
			//w[1][2] += u*v; 
			w[2][2] += v*v;
			Point dn = vn[PREV_Index(j)] - vn[NEXT_Index(j)];
			double dnu = dot(dn, t);
			double dnv = dot(dn, b);
			m[0] += dnu*u;
			m[1] += dnu*v + dnv*u;
			m[2] += dnv*v;
		}
		w[1][1] = w[0][0] + w[2][2];
		w[1][2] = w[0][1];

		// Least squares solution
		double diag[3];
		if (!ldltdc<double,3>(w, diag)) {
			//printf("ldltdc failed!\n");
			continue;
		}
		ldltsl<double,3>(w, diag, m, m);

		// Push it back out to the vertices
		for (uint j = 0; j < 3; j++) 
		{
			int vj = vi[j];
			double c1, c12, c2;
			proj_curv(t, b, m[0], m[1], m[2], pdir1[vj], pdir2[vj], c1, c12, c2);
			double wt = cornerareas[i][j] / pointareas[vj];

			//#pragma omp atomic
			curv1[vj] += wt * c1;

			//#pragma omp atomic
			curv12[vj] += wt * c12;

			//#pragma omp atomic
			curv2[vj] += wt * c2;
		}
	}

	// Store results into Surface_mesh object
	Surface_mesh::Vertex_property<double> my_curv1 = src_mesh->vertex_property<double>("v:curv1");
	Surface_mesh::Vertex_property<double> my_curv2 = src_mesh->vertex_property<double>("v:vurv2");
	Surface_mesh::Vertex_property<Vec3d> my_pdir1 = src_mesh->vertex_property<Vec3d>("v:pdir1");
	Surface_mesh::Vertex_property<Vec3d> my_pdir2 = src_mesh->vertex_property<Vec3d>("v:pdir2");

	// Compute principal directions and curvatures at each vertex
	//#pragma omp parallel for
	for (vit = src_mesh->vertices_begin(); vit != vend; ++vit) 
	{
		uint i = ((Surface_mesh::Vertex)vit).idx();
		diagonalize_curv(pdir1[i], pdir2[i],curv1[i], curv12[i], curv2[i], normals[vit], pdir1[i], pdir2[i],curv1[i], curv2[i]);

		my_curv1[vit] = curv1[i];
		my_curv2[vit] = curv2[i];

		my_pdir1[vit] = pdir1[i];
		my_pdir2[vit] = pdir2[i];
	}
}
Пример #3
0
// Compute derivatives of curvature
void Curvature::computeDerivativesCurvatures(Surface_mesh * src_mesh)
{
	// Compute principal curvatures and directions
	computePrincipalCurvatures(src_mesh);

	Surface_mesh::Vertex_property<Point> points = src_mesh->vertex_property<Point>("v:point");
	Surface_mesh::Vertex_property<Normal> normals = src_mesh->vertex_property<Normal>("v:normal");
	Surface_mesh::Face_iterator fit, fend = src_mesh->faces_end();
	Surface_mesh::Vertex_around_face_circulator fvit, fvend;

	// Resize the arrays we'll be using
	uint nv = src_mesh->n_vertices(), nf = src_mesh->n_faces();

	dcurv.resize(nv);

	// Compute derivatives of curvature per-face
	//#pragma omp parallel for
	for (fit = src_mesh->faces_begin(); fit != fend; ++fit) 
	{
		uint i = ((Surface_mesh::Face)fit).idx(); // face index

		uint vi[3];	Normal vn[3];
		fvit = src_mesh->vertices(fit);

		vi[0] = ((Vertex)fvit).idx(); Point v0 = points[fvit]; vn[0] = normals[fvit]; ++fvit;
		vi[1]  = ((Vertex)fvit).idx(); Point v1 = points[fvit]; vn[1] = normals[fvit]; ++fvit;
		vi[2]  = ((Vertex)fvit).idx(); Point v2 = points[fvit]; vn[2] = normals[fvit]; ++fvit;

		// Edges
		Point e[3] = {v2 - v1,  v0 - v2,  v1 - v0};

		// N-T-B coordinate system per face
		Point t = e[0];
		t.normalize();
		Point n = cross(e[0], e[1]);
		Point b = cross(n, t);
		b.normalize();

		// Project curvature tensor from each vertex into this
		// face's coordinate system
		Point fcurv[3];
		for (int j = 0; j < 3; j++) 
		{
			int vj = vi[j];
			proj_curv(pdir1[vj], pdir2[vj], curv1[vj], 0, curv2[vj],t, b, fcurv[j][0], fcurv[j][1], fcurv[j][2]);
		}

		// Estimate derivatives of curvature based on variation of curvature along edges
		double m[4] = {0,0,0,0};
		double w[4][4] = { {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0} };

		for (int j = 0; j < 3; j++) 
		{
			// Variation of curvature along each edge
			Point dfcurv = fcurv[PREV_Index(j)] - fcurv[NEXT_Index(j)];
			double u = dot(e[j], t);
			double v = dot(e[j], b);
			double u2 = u*u, v2 = v*v, uv = u*v;
			w[0][0] += u2;
			w[0][1] += uv;
			//w[1][1] += 2.0f*u2 + v2;
			//w[1][2] += 2.0f*uv;
			//w[2][2] += u2 + 2.0f*v2;
			//w[2][3] += uv;
			w[3][3] += v2;
			m[0] += u*dfcurv[0];
			m[1] += v*dfcurv[0] + 2.0f*u*dfcurv[1];
			m[2] += 2.0f*v*dfcurv[1] + u*dfcurv[2];
			m[3] += v*dfcurv[2];
		}

		w[1][1] = 2.0f * w[0][0] + w[3][3];
		w[1][2] = 2.0f * w[0][1];
		w[2][2] = w[0][0] + 2.0f * w[3][3];
		w[2][3] = w[0][1];

		// Least squares solution
		double d[4];

		if (!ldltdc<double,4>(w, d)) 
		{
			//printf("ldltdc failed!\n");
			continue;
		}

		ldltsl<double,4>(w, d, m, m);

		Vec4d face_dcurv(m[0], m[1], m[2], m[3]);

		// Push it back out to each vertex
		for (int j = 0; j < 3; j++) 
		{
			int vj = vi[j];

			Vec4d this_vert_dcurv;

			proj_dcurv(t, b, face_dcurv, pdir1[vj], pdir2[vj], this_vert_dcurv);

			double wt = cornerareas[i][j] / pointareas[vj];

			dcurv[vj] += wt * this_vert_dcurv;
		}
	}

	Surface_mesh::Vertex_property<Vec4d> my_dcurv = src_mesh->vertex_property<Vec4d>("v:dcurv");
	Surface_mesh::Vertex_iterator vit, vend = src_mesh->vertices_end();

	for (vit = src_mesh->vertices_begin(); vit != vend; ++vit){
		uint i = ((Vertex) vit).idx();
		my_dcurv[vit] = dcurv[i];
	}
}