static void smooth_vertex (GtsVertex * v, gpointer * data) { GtsSurface * s = data[0]; if (!gts_vertex_is_boundary (v, s)) { gdouble * lambda = data[1]; GSList * vertices = gts_vertex_neighbors (v, NULL, s); GSList * i; GtsVector U0 = { 0., 0., 0.}; guint n = 0; i = vertices; while (i) { GtsPoint * p = i->data; U0[0] += p->x; U0[1] += p->y; U0[2] += p->z; n++; i = i->next; } g_slist_free (vertices); if (n > 0) { GTS_POINT (v)->x += (*lambda)*(U0[0]/n - GTS_POINT (v)->x); GTS_POINT (v)->y += (*lambda)*(U0[1]/n - GTS_POINT (v)->y); GTS_POINT (v)->z += (*lambda)*(U0[2]/n - GTS_POINT (v)->z); } } }
static PyObject* is_boundary(PygtsVertex* self, PyObject *args) { PyObject *s_; PygtsObject *s; SELF_CHECK /* Parse the args */ if(! PyArg_ParseTuple(args, "O", &s_) ) { return NULL; } /* Convert to PygtsObjects */ if(!pygts_surface_check(s_)) { PyErr_SetString(PyExc_TypeError,"expected a Surface"); return NULL; } s = PYGTS_OBJECT(s_); if( gts_vertex_is_boundary(PYGTS_VERTEX_AS_GTS_VERTEX(self), PYGTS_SURFACE_AS_GTS_SURFACE(s)) ) { Py_INCREF(Py_True); return Py_True; } else { Py_INCREF(Py_False); return Py_False; } }
/** * gts_vertex_gaussian_curvature: * @v: a #GtsVertex. * @s: a #GtsSurface. * @Kg: the Discrete Gaussian Curvature approximation at @v. * * Computes the Discrete Gaussian Curvature approximation at @v. * * This approximation is from the paper: * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr * VisMath '02, Berlin (Germany) * http://www-grail.usc.edu/pubs.html * * Returns: %TRUE if the operator could be evaluated, %FALSE if the * evaluation failed for some reason (@v is boundary or is the * endpoint of a non-manifold edge.) */ gboolean gts_vertex_gaussian_curvature (GtsVertex * v, GtsSurface * s, gdouble * Kg) { GSList * faces, * edges, * i; gdouble area = 0.0; gdouble angle_sum = 0.0; g_return_val_if_fail (v != NULL, FALSE); g_return_val_if_fail (s != NULL, FALSE); g_return_val_if_fail (Kg != NULL, FALSE); /* this operator is not defined for boundary edges */ if (gts_vertex_is_boundary (v, s)) return (FALSE); faces = gts_vertex_faces (v, s, NULL); g_return_val_if_fail (faces != NULL, FALSE); edges = gts_vertex_fan_oriented (v, s); if (edges == NULL) { g_slist_free (faces); return (FALSE); } i = faces; while (i) { GtsFace * f = i->data; area += region_area (v, f); i = i->next; } g_slist_free (faces); i = edges; while (i) { GtsEdge * e = i->data; GtsVertex * v1 = GTS_SEGMENT (e)->v1; GtsVertex * v2 = GTS_SEGMENT (e)->v2; angle_sum += angle_from_cotan (v, v1, v2); i = i->next; } g_slist_free (edges); *Kg = (2.0*M_PI - angle_sum)/area; return TRUE; }
/** * gts_vertex_mean_curvature_normal: * @v: a #GtsVertex. * @s: a #GtsSurface. * @Kh: the Mean Curvature Normal at @v. * * Computes the Discrete Mean Curvature Normal approximation at @v. * The mean curvature at @v is half the magnitude of the vector @Kh. * * Note: the normal computed is not unit length, and may point either * into or out of the surface, depending on the curvature at @v. It * is the responsibility of the caller of the function to use the mean * curvature normal appropriately. * * This approximation is from the paper: * Discrete Differential-Geometry Operators for Triangulated 2-Manifolds * Mark Meyer, Mathieu Desbrun, Peter Schroder, Alan H. Barr * VisMath '02, Berlin (Germany) * http://www-grail.usc.edu/pubs.html * * Returns: %TRUE if the operator could be evaluated, %FALSE if the * evaluation failed for some reason (@v is boundary or is the * endpoint of a non-manifold edge.) */ gboolean gts_vertex_mean_curvature_normal (GtsVertex * v, GtsSurface * s, GtsVector Kh) { GSList * faces, * edges, * i; gdouble area = 0.0; g_return_val_if_fail (v != NULL, FALSE); g_return_val_if_fail (s != NULL, FALSE); /* this operator is not defined for boundary edges */ if (gts_vertex_is_boundary (v, s)) return (FALSE); faces = gts_vertex_faces (v, s, NULL); g_return_val_if_fail (faces != NULL, FALSE); edges = gts_vertex_fan_oriented (v, s); if (edges == NULL) { g_slist_free (faces); return (FALSE); } i = faces; while (i) { GtsFace * f = i->data; area += region_area (v, f); i = i->next; } g_slist_free (faces); Kh[0] = Kh[1] = Kh[2] = 0.0; i = edges; while (i) { GtsEdge * e = i->data; GtsVertex * v1 = GTS_SEGMENT (e)->v1; GtsVertex * v2 = GTS_SEGMENT (e)->v2; gdouble temp; temp = cotan (v1, v, v2); Kh[0] += temp*(GTS_POINT (v2)->x - GTS_POINT (v)->x); Kh[1] += temp*(GTS_POINT (v2)->y - GTS_POINT (v)->y); Kh[2] += temp*(GTS_POINT (v2)->z - GTS_POINT (v)->z); temp = cotan (v2, v, v1); Kh[0] += temp*(GTS_POINT (v1)->x - GTS_POINT (v)->x); Kh[1] += temp*(GTS_POINT (v1)->y - GTS_POINT (v)->y); Kh[2] += temp*(GTS_POINT (v1)->z - GTS_POINT (v)->z); i = i->next; } g_slist_free (edges); if (area > 0.0) { Kh[0] /= 2*area; Kh[1] /= 2*area; Kh[2] /= 2*area; } else { return (FALSE); } return TRUE; }