ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/objtriangulate.c
Revision: 2.2
Committed: Mon Apr 19 19:40:03 2021 UTC (3 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4
Changes since 2.1: +8 -1 lines
Log Message:
fix(genbox): Fixed issue with reversed triangles

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: objtriangulate.c,v 2.1 2021/03/12 03:59:25 greg Exp $";
3 greg 2.1 #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 greg 2.2 int rev;
20 greg 2.1 } SceneFace;
21    
22     /* Callback to create new triangle */
23     static int
24     addtriangle(const Vert2_list *tp, int a, int b, int c)
25     {
26     SceneFace *sf = (SceneFace *)tp->p;
27     Face *f = sf->f;
28     VNDX triv[3];
29    
30 greg 2.2 if (sf->rev) { /* need to reverse triangle? */
31     int t = a;
32     a = c;
33     c = t;
34     }
35 greg 2.1 triv[0][0] = f->v[a].vid;
36     triv[0][1] = f->v[a].tid;
37     triv[0][2] = f->v[a].nid;
38     triv[1][0] = f->v[b].vid;
39     triv[1][1] = f->v[b].tid;
40     triv[1][2] = f->v[b].nid;
41     triv[2][0] = f->v[c].vid;
42     triv[2][1] = f->v[c].tid;
43     triv[2][2] = f->v[c].nid;
44    
45     f = addFace(sf->sc, triv, 3);
46     if (f == NULL)
47     return(0);
48    
49     f->flags |= sf->f->flags;
50     f->grp = sf->f->grp;
51     f->mat = sf->f->mat;
52     return(1);
53     }
54    
55     /* Callback to convert face to triangles */
56     static int
57     mktriangles(Scene *sc, Face *f, void *p)
58     {
59     Normal nrm;
60     int i, ax, ay;
61     Vert2_list *poly;
62     SceneFace mysf;
63    
64     if (f->nv <= 3) /* already a triangle? */
65     return(0);
66    
67     if (faceArea(sc, f, nrm) == 0) /* hidden degenerate? */
68     return(0);
69     /* identify major axis from normal */
70     i = (nrm[1]*nrm[1] > nrm[0]*nrm[0]);
71     if (nrm[2]*nrm[2] > nrm[i]*nrm[i]) i = 2;
72     ax = (i+1)%3;
73     ay = (i+2)%3;
74     /* assign 2-D vertices */
75     poly = polyAlloc(f->nv);
76     if (poly == NULL) {
77     error(SYSTEM, "Out of memory in mktriangles");
78     return(-1);
79     }
80     mysf.sc = sc;
81     mysf.f = f;
82     poly->p = &mysf;
83     for (i = 0; i < f->nv; i++) {
84     double *pt = sc->vert[f->v[i].vid].p;
85     poly->v[i].mX = pt[ax];
86     poly->v[i].mY = pt[ay];
87     }
88 greg 2.2 mysf.rev = (polyArea(poly) < .0);
89 greg 2.1 i = polyTriangulate(poly, addtriangle);
90     polyFree(poly);
91     /* flag face if replaced */
92     f->flags |= (i > 0)*FACE_DUPLICATE;
93     return(i);
94     }
95    
96     /* Convert all faces with > 3 vertices to triangles */
97     int
98     triangulateScene(Scene *sc)
99     {
100     int orig_nfaces = sc->nfaces;
101     int nc = foreachFace(sc, mktriangles,
102     0, FACE_DUPLICATE|FACE_DEGENERATE, NULL);
103    
104     if (nc < 0) /* bad (memory) error? */
105     return(-1);
106     if (nc > 0) /* else remove faces we split up */
107     deleteFaces(sc, FACE_DUPLICATE, 0);
108    
109     return(sc->nfaces - orig_nfaces);
110     }