ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/convertobj.c
(Generate patch)

Comparing ray/src/common/convertobj.c (file contents):
Revision 2.3 by greg, Thu Apr 23 22:35:27 2020 UTC vs.
Revision 2.6 by greg, Sat Apr 17 14:51:33 2021 UTC

# Line 10 | Line 10 | static const char RCSid[] = "$Id$";
10   */
11  
12   #include "paths.h"
13 + #include "fvect.h"
14 + #include "tmesh.h"
15   #include "rterror.h"
16   #include "objutil.h"
17  
18 + #define TEXNAME         "T-nor"
19 +
20 + static int      fcnt = 0;                       /* face output counter */
21 +
22 + /* Callback for face smoothing detection */
23 + static int
24 + checksmooth(Scene *sc, Face *f, void *ptr)
25 + {
26 +        int     nrev = 0;
27 +        Normal  fnrm;
28 +        int     i;
29 +
30 +        f->flags &= ~FACE_RESERVED;             /* using reserved flag */
31 +
32 +        for (i = f->nv; i--; )
33 +                if (f->v[i].nid < 0)
34 +                        return(0);              /* missing normal */
35 +
36 +        if (faceArea(sc, f, fnrm) == 0)         /* degenerate?? */
37 +                return(0);
38 +                                                /* check each normal */
39 +        for (i = f->nv; i--; ) {
40 +                float   *tnrm = sc->norm[f->v[i].nid];
41 +                double  dprod = DOT(tnrm, fnrm);
42 +                if (dprod >= COSTOL)            /* this one agrees? */
43 +                        continue;
44 +                if (dprod > -COSTOL)            /* active smoothing? */
45 +                        break;
46 +                ++nrev;                         /* count opposite face normal */
47 +        }
48 +        if ((i < 0) & !nrev)                    /* all normals agree w/ face? */
49 +                return(0);
50 +        if (nrev == f->nv) {                    /* all reversed? */
51 +                for (i = f->nv/2; i--; ) {      /* swap vertices around */
52 +                        int     j = f->nv-1 - i;
53 +                        VertEnt tve = f->v[i];
54 +                        f->v[i] = f->v[j];
55 +                        f->v[j] = tve;
56 +                }
57 +                return(0);
58 +        }
59 +        f->flags |= FACE_RESERVED;              /* else we got one to smooth */
60 +        return(1);
61 + }
62 +
63 + /* Callback to write out smoothed Radiance triangle */
64 + static int
65 + trismooth(Scene *sc, Face *f, void *ptr)
66 + {
67 +        FILE            *fp = (FILE *)ptr;
68 +        BARYCCM         bcm;
69 +        FVECT           coor[3];
70 +        int             i;
71 +
72 +        if (f->nv != 3)
73 +                return(0);                      /* should never happen */
74 + #ifdef  SMLFLT
75 +        for (i = 3; i--; ) {
76 +                double  *v = sc->vert[f->v[i].vid].p;
77 +                VCOPY(coor[i], v);
78 +        }
79 +        if (comp_baryc(&bcm, coor[0], coor[1], coor[2]) < 0)
80 +                return(0);                      /* degenerate?? */
81 + #else
82 +        if (comp_baryc(&bcm, sc->vert[f->v[0].vid].p,
83 +                        sc->vert[f->v[1].vid].p, sc->vert[f->v[2].vid].p) < 0)
84 +                return(0);                      /* degenerate?? */
85 + #endif
86 +        for (i = 3; i--; ) {                    /* assign BC normals */
87 +                float   *tnrm = sc->norm[f->v[i].nid];
88 +                coor[0][i] = tnrm[0];
89 +                coor[1][i] = tnrm[1];
90 +                coor[2][i] = tnrm[2];
91 +        }                                       /* print texture */
92 +        fprintf(fp, "\n%s texfunc %s\n4 dx dy dz %s\n0\n",
93 +                        sc->matname[f->mat], TEXNAME, TCALNAME);
94 +        fput_baryc(&bcm, coor, 3, fp);          /* with BC normals */
95 +        fprintf(fp, "\n%s polygon %s.%d\n0\n0\n9\n",
96 +                        TEXNAME, sc->grpname[f->grp], ++fcnt);
97 +        for (i = 0; i < 3; i++) {               /* then triangle */
98 +                double  *v = sc->vert[f->v[i].vid].p;
99 +                fprintf(fp, "\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
100 +        }
101 +        return(1);
102 + }
103 +
104   /* Callback to convert face to Radiance */
105   static int
106   radface(Scene *sc, Face *f, void *ptr)
107   {
20        static int      fcnt = 0;
108          FILE            *fp = (FILE *)ptr;
109          int             i;
110          
24        if (f->flags & FACE_DEGENERATE)
25                return(0);
111          fprintf(fp, "\n%s polygon %s.%d\n0\n0\n%d\n", sc->matname[f->mat],
112                                  sc->grpname[f->grp], ++fcnt, 3*f->nv);
113          for (i = 0; i < f->nv; i++) {
# Line 41 | Line 126 | toRadiance(Scene *sc, FILE *fp, int flreq, int flexc)
126  
127          if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
128                  return(0);
129 +                                                /* not passing empties */
130 +        flexc |= FACE_DEGENERATE;
131 +                                                /* reset counter if not stdout */
132 +        fcnt *= (fp == stdout);
133                                                  /* write comments */
134          for (n = 0; n < sc->ndescr; n++)
135                  fprintf(fp, "# %s\n", sc->descr[n]);
136 <                                                /* write faces */
137 <        n = foreachFace(sc, radface, flreq, flexc, (void *)fp);
136 >                                                /* flag faces to smooth */
137 >        n = foreachFace(sc, checksmooth, flreq, flexc, NULL);
138 >        if (n > 0) {                            /* write smooth faces */
139 >                Scene   *smoothies = dupScene(sc, flreq|FACE_RESERVED, flexc);
140 >                if (!smoothies)
141 >                        return(-1);
142 >                n = triangulateScene(smoothies);
143 >                if (n >= 0)
144 >                        n = foreachFace(smoothies, trismooth, 0, 0, fp);
145 >                freeScene(smoothies);
146 >        }
147 >        if (n < 0)
148 >                return(-1);
149 >                                                /* write flat faces */
150 >        n += foreachFace(sc, radface, flreq, flexc|FACE_RESERVED, fp);
151 >
152          if (fflush(fp) < 0) {
153                  error(SYSTEM, "Error writing Radiance scene data");
154                  return(-1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines