ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/objtriangulate.c
Revision: 2.1
Committed: Fri Mar 12 03:59:25 2021 UTC (3 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
feat: added routine to triangulate .OBJ scene in memory

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * Turn all faces with > 3 sides to triangles in Wavefront .OBJ scene
6 */
7
8 #include "copyright.h"
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include "rterror.h"
13 #include "objutil.h"
14 #include "triangulate.h"
15
16 typedef struct {
17 Scene *sc;
18 Face *f;
19 } SceneFace;
20
21 /* Callback to create new triangle */
22 static int
23 addtriangle(const Vert2_list *tp, int a, int b, int c)
24 {
25 SceneFace *sf = (SceneFace *)tp->p;
26 Face *f = sf->f;
27 VNDX triv[3];
28
29 triv[0][0] = f->v[a].vid;
30 triv[0][1] = f->v[a].tid;
31 triv[0][2] = f->v[a].nid;
32 triv[1][0] = f->v[b].vid;
33 triv[1][1] = f->v[b].tid;
34 triv[1][2] = f->v[b].nid;
35 triv[2][0] = f->v[c].vid;
36 triv[2][1] = f->v[c].tid;
37 triv[2][2] = f->v[c].nid;
38
39 f = addFace(sf->sc, triv, 3);
40 if (f == NULL)
41 return(0);
42
43 f->flags |= sf->f->flags;
44 f->grp = sf->f->grp;
45 f->mat = sf->f->mat;
46 return(1);
47 }
48
49 /* Callback to convert face to triangles */
50 static int
51 mktriangles(Scene *sc, Face *f, void *p)
52 {
53 Normal nrm;
54 int i, ax, ay;
55 Vert2_list *poly;
56 SceneFace mysf;
57
58 if (f->nv <= 3) /* already a triangle? */
59 return(0);
60
61 if (faceArea(sc, f, nrm) == 0) /* hidden degenerate? */
62 return(0);
63 /* identify major axis from normal */
64 i = (nrm[1]*nrm[1] > nrm[0]*nrm[0]);
65 if (nrm[2]*nrm[2] > nrm[i]*nrm[i]) i = 2;
66 ax = (i+1)%3;
67 ay = (i+2)%3;
68 /* assign 2-D vertices */
69 poly = polyAlloc(f->nv);
70 if (poly == NULL) {
71 error(SYSTEM, "Out of memory in mktriangles");
72 return(-1);
73 }
74 mysf.sc = sc;
75 mysf.f = f;
76 poly->p = &mysf;
77 for (i = 0; i < f->nv; i++) {
78 double *pt = sc->vert[f->v[i].vid].p;
79 poly->v[i].mX = pt[ax];
80 poly->v[i].mY = pt[ay];
81 }
82 i = polyTriangulate(poly, addtriangle);
83 polyFree(poly);
84 /* flag face if replaced */
85 f->flags |= (i > 0)*FACE_DUPLICATE;
86 return(i);
87 }
88
89 /* Convert all faces with > 3 vertices to triangles */
90 int
91 triangulateScene(Scene *sc)
92 {
93 int orig_nfaces = sc->nfaces;
94 int nc = foreachFace(sc, mktriangles,
95 0, FACE_DUPLICATE|FACE_DEGENERATE, NULL);
96
97 if (nc < 0) /* bad (memory) error? */
98 return(-1);
99 if (nc > 0) /* else remove faces we split up */
100 deleteFaces(sc, FACE_DUPLICATE, 0);
101
102 return(sc->nfaces - orig_nfaces);
103 }