int CTriangleObj::saveSTLFile(const char *fname, const double* pmatrix) { Vector3d p0, p1, p2; FILE *fp=fopen(fname, _WA_); if (fp==NULL) return 0; Vector3i*& m_pTriangle = (Vector3i*&)m_pPolygon; fprintf(fp, "solid Object01\n"); for (int i=0; i<m_nPolygonCount; i++){ const Vector3i tri = m_pTriangle[i]; const Vector3d& _p0=m_pVertex[tri.x]; const Vector3d& _p1=m_pVertex[tri.y]; const Vector3d& _p2=m_pVertex[tri.z]; TransformVertex3dToVertex3d(_p0, pmatrix, &p0.x); TransformVertex3dToVertex3d(_p1, pmatrix, &p1.x); TransformVertex3dToVertex3d(_p2, pmatrix, &p2.x); const Vector3f p0f(p0.x, p0.y, p0.z); const Vector3f p1f(p1.x, p1.y, p1.z); const Vector3f p2f(p2.x, p2.y, p2.z); Vector3f norm = compute_triangle_normal(p0f,p1f,p2f); fprintf(fp, "facet normal %f %f %f\n", norm.x, norm.y, norm.z); fprintf(fp, "outer loop\n"); const Vector3d *p=&p0; fprintf(fp, "vertex %.12lG %.12lG %.12lG\n", p->x, p->y, p->z); p=&p1; fprintf(fp, "vertex %.12lG %.12lG %.12lG\n", p->x, p->y, p->z); p=&p2; fprintf(fp, "vertex %.12lG %.12lG %.12lG\n", p->x, p->y, p->z); fprintf(fp, "endloop\n"); fprintf(fp, "endfacet\n"); } fprintf(fp, "endsolid Object01\n"); fclose(fp); return 1; }
void mesh_set_average_vertex_normals(struct mesh *m) { int i, j, k; struct vertex *vn, **v; v = malloc(sizeof(*v) * m->nvertices); vn = malloc(sizeof(*vn) * m->nvertices); /* Use w as a counter of how many triangles use a vertex, init to 0 */ for (i = 0; i < m->nvertices; i++) m->v[i].w = 0.0; k = 0; for (i = 0; i < m->ntriangles; i++) { union vec3 normal; normal = compute_triangle_normal(&m->t[i]); m->t[i].n.x = normal.v.x; m->t[i].n.y = normal.v.y; m->t[i].n.z = normal.v.z; for (j = 0; j < 3; j++) { /* First time we've encountered this vertex? */ if (m->t[i].v[j]->w < 0.5) { v[k] = m->t[i].v[j]; vn[k].x = normal.v.x; vn[k].y = normal.v.y; vn[k].z = normal.v.z; vn[k].w = 1.0; m->t[i].v[j]->w = 1.0; k++; } else { int fv = find_vertex(v, m->t[i].v[j], m->nvertices); assert(fv >= 0); vn[fv].x += normal.v.x; vn[fv].y += normal.v.y; vn[fv].z += normal.v.z; vn[fv].w += 1.0; m->t[i].v[j]->w += 1.0; } } } for (i = 0; i < m->ntriangles; i++) { for (j = 0; j < 3; j++) { k = find_vertex(v, m->t[i].v[j], m->nvertices); assert(k >= 0); /* Average the normals... */ m->t[i].vnormal[j].x = vn[k].x / m->t[i].v[j]->w; m->t[i].vnormal[j].y = vn[k].y / m->t[i].v[j]->w; m->t[i].vnormal[j].z = vn[k].z / m->t[i].v[j]->w; } } /* set w's back to 1.0 */ for (i = 0; i < m->nvertices; i++) m->v[i].w = 1.0; free(vn); free(v); }
inline void CMarchingTet::_getMidTrianglePointAttr(const int v0, const int v1, const int v2, const Vector3f &p0, const Vector3f &p1, const Vector3f &p2, CVertexInfo *pVertInfo, int &f, Vector3f &norm) { f = VERTEX_AT_FREE; const Vector3i *ptri = _lsearchDynamicTri(v0, v1, v2, pVertInfo); if (ptri!=NULL || _lsearchStaticTri(v0, v1, v2, pVertInfo)!=NULL){ f = VERTEX_AT_BOUNDARY_PLANE; norm = compute_triangle_normal(p0, p1, p2); } }
int SurfaceEdgeCollapse::check_new_triangles(float x0, float y0, float z0, pair *link, int num_link) { // checks whether the newly computed position of the point the edge collapses // into guarantees a correct triangulation (no overlappings of triangles) int convex = 1; int i; fl_triple n1, n2; compute_triangle_normal(link[num_link - 1][0], link[num_link - 1][1], x0, y0, z0, n1); for (i = 0; i < num_link; i++) { compute_triangle_normal(link[i][0], link[i][1], x0, y0, z0, n2); if (!angle[link[i][0]]) if (n1[0] * n2[0] + n1[1] * n2[1] + n1[2] * n2[2] < 0) convex = 0; n1[0] = n2[0]; n1[1] = n2[1]; n1[2] = n2[2]; } return (convex); }
void mesh_set_flat_shading_vertex_normals(struct mesh *m) { int i, j; for (i = 0; i < m->ntriangles; i++) { union vec3 normal; normal = compute_triangle_normal(&m->t[i]); m->t[i].n.x = normal.v.x; m->t[i].n.y = normal.v.y; m->t[i].n.z = normal.v.z; for (j = 0; j < 3; j++) m->t[i].vnormal[j] = m->t[i].n; } }
void mesh_set_spherical_vertex_normals(struct mesh *m) { int i, j; for (i = 0; i < m->ntriangles; i++) { union vec3 normal; normal = compute_triangle_normal(&m->t[i]); m->t[i].n.x = normal.v.x; m->t[i].n.y = normal.v.y; m->t[i].n.z = normal.v.z; for (j = 0; j < 3; j++) { union vec3 normal = { { m->t[i].v[j]->x, m->t[i].v[j]->y, m->t[i].v[j]->z } }; vec3_normalize_self(&normal); m->t[i].vnormal[j].x = normal.v.x; m->t[i].vnormal[j].y = normal.v.y; m->t[i].vnormal[j].z = normal.v.z; } } }
int CSphere16::_initSphereMesh(void) { const Vector3f zerovec(0,0,0); for (int i=0; i<NV; ++i) m_normals[i] = zerovec; const Vector3i *ptri = (const Vector3i*)tris; const Vector3f *pvert = (const Vector3f*)vert; for (int i=0; i<NT; ++i){ const Vector3i t = ptri[i]; const int a=t.x, b=t.y, c=t.z; const Vector3f n = compute_triangle_normal(pvert[a], pvert[b], pvert[c]); m_normals[a]+=n, m_normals[b]+=n, m_normals[c]+=n; } for (int i=0; i<NV; ++i){ m_normals[i].normalize(); m_normals_inv[i] = -m_normals[i]; } return 1; }
int CTriangleMesh::copyTriangleMesh(int vertex_num, Vector3D vertex[], int triangle_num, Vector3I *triangle) { int i; Vector3D n; // m_nVerticesNumber = vertex_num; m_Vertice = new Vector3D[vertex_num]; assert(m_Vertice!=NULL); for (i=0; i<vertex_num; i++) m_Vertice[i]=vertex[i]; // m_nTriangleNumber = triangle_num; m_Triangles = new Vector3I[triangle_num]; for (i=0; i<triangle_num; i++) m_Triangles[i]=triangle[i]; //normal m_pVertexNorm = new Vector3D[vertex_num]; assert(m_pVertexNorm!=NULL); for (i=0; i<vertex_num; i++) m_pVertexNorm[i]=Vector3D(0,0,0); for (i=0; i<m_nTriangleNumber; i++){ int a, b, c; a = m_Triangles[i][0], b = m_Triangles[i][1], c = m_Triangles[i][2]; n= compute_triangle_normal(m_Vertice[a], m_Vertice[b], m_Vertice[c]); m_pVertexNorm[a]+=n; m_pVertexNorm[b]+=n; m_pVertexNorm[c]+=n; } for (i=0; i<m_nVerticesNumber; i++){ m_pVertexNorm[i].normalize(); } // m_nVerticeFieldNumber=2; m_pPrintFunc = NULL; m_ppEdgeTable = NULL; return 1; }
/* fabricate a tube of length h, radius r, with nfaces, parallel to x axis */ struct mesh *mesh_tube(float h, float r, float nfaces) { struct mesh *m; int ntris = nfaces * 2; int nvertices = nfaces * 2; int i, j; float angle, da; float l = h / 2.0; m = allocate_mesh_for_copy(ntris, nvertices, 0, 1); if (!m) return m; m->geometry_mode = MESH_GEOMETRY_TRIANGLES; da = 2 * M_PI / (float) nfaces; angle = 0.0; for (i = 0; i < nvertices; i += 2) { m->v[i].x = -l; m->v[i].y = r * cos(angle); m->v[i].z = r * -sin(angle); m->v[i + 1].x = l; m->v[i + 1].y = m->v[i].y; m->v[i + 1].z = m->v[i].z; angle += da; } m->nvertices = nvertices; for (i = 0; i < ntris; i += 2) { m->t[i].v[2] = &m->v[i % nvertices]; m->t[i].v[1] = &m->v[(i + 1) % nvertices]; m->t[i].v[0] = &m->v[(i + 2) % nvertices]; m->t[i + 1].v[2] = &m->v[(i + 2) % nvertices]; m->t[i + 1].v[1] = &m->v[(i + 1) % nvertices]; m->t[i + 1].v[0] = &m->v[(i + 3) % nvertices]; } m->ntriangles = ntris; for (i = 0; i < ntris; i++) { union vec3 normal; normal = compute_triangle_normal(&m->t[i]); m->t[i].n.x = normal.v.x; m->t[i].n.y = normal.v.y; m->t[i].n.z = normal.v.z; for (j = 0; j < 3; j++) { union vec3 normal = { { 0, -m->t[i].v[j]->y, -m->t[i].v[j]->z } }; vec3_normalize_self(&normal); m->t[i].vnormal[j].x = normal.v.x; m->t[i].vnormal[j].y = normal.v.y; m->t[i].vnormal[j].z = normal.v.z; } } mesh_set_flat_shading_vertex_normals(m); for (i = 0; i < ntris; i += 2) { mesh_set_triangle_texture_coords(m, i, 0.0, (float) ((int) ((i + 2) / 2)) * 1.0 / (float) nfaces, 1.0, (float) ((int) (i / 2)) / (float) nfaces, 0.0, (float) ((int) (i / 2)) / (float) nfaces); mesh_set_triangle_texture_coords(m, i + 1, 1.0, (float) ((int) ((i + 2) / 2)) / (float) nfaces, 1.0, (float) ((int) (i / 2)) / (float) nfaces, 0.0, (float) ((int) ((i + 2) / 2)) / (float) nfaces); } m->nlines = 0; m->radius = mesh_compute_radius(m); mesh_graph_dev_init(m); return m; }