ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/objtriangulate.c
Revision: 2.3
Committed: Tue Feb 13 21:06:00 2024 UTC (2 months, 2 weeks ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.2: +5 -3 lines
Log Message:
fix(robjutil): Mark bad faces as degenerate during triangulation

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: objtriangulate.c,v 2.2 2021/04/19 19:40:03 greg Exp $";
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 int rev;
20 } 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 if (sf->rev) { /* need to reverse triangle? */
31 int t = a;
32 a = c;
33 c = t;
34 }
35 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 mysf.rev = (polyArea(poly) < .0);
89 i = polyTriangulate(poly, addtriangle);
90 polyFree(poly);
91 if (i > 0) /* flag face */
92 f->flags |= FACE_DUPLICATE;
93 else
94 f->flags |= FACE_DEGENERATE;
95 return(i);
96 }
97
98 /* Convert all faces with > 3 vertices to triangles */
99 int
100 triangulateScene(Scene *sc)
101 {
102 int orig_nfaces = sc->nfaces;
103 int nc = foreachFace(sc, mktriangles,
104 0, FACE_DUPLICATE|FACE_DEGENERATE, NULL);
105
106 if (nc < 0) /* bad (memory) error? */
107 return(-1);
108 if (nc > 0) /* else remove faces we split up */
109 deleteFaces(sc, FACE_DUPLICATE, 0);
110
111 return(sc->nfaces - orig_nfaces);
112 }