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 (4 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
feat: added routine to triangulate .OBJ scene in memory

File Contents

# User Rev Content
1 greg 2.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     }