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.5 by greg, Fri Apr 16 15:18: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; i--; )          /* remove normal indices */
52 +                        f->v[i].nid = -1;
53 +                for (i = f->nv/2; i--; ) {      /* and swap others around */
54 +                        int     j = f->nv-1 - i;
55 +                        int     vi = f->v[i].vid;
56 +                        int     ti = f->v[i].tid;
57 +                        f->v[i].vid = f->v[j].vid;
58 +                        f->v[i].tid = f->v[j].tid;
59 +                        f->v[j].vid = vi;
60 +                        f->v[j].tid = ti;
61 +                }
62 +                return(0);
63 +        }
64 +        f->flags |= FACE_RESERVED;              /* else we got one to smooth */
65 +        return(1);
66 + }
67 +
68 + /* Callback to write out smoothed Radiance triangle */
69 + static int
70 + trismooth(Scene *sc, Face *f, void *ptr)
71 + {
72 +        FILE            *fp = (FILE *)ptr;
73 +        BARYCCM         bcm;
74 +        FVECT           coor[3];
75 +        int             i;
76 +
77 +        if (f->nv != 3)
78 +                return(0);                      /* should never happen */
79 + #ifdef  SMLFLT
80 +        for (i = 3; i--; ) {
81 +                double  *v = sc->vert[f->v[i].vid].p;
82 +                VCOPY(coor[i], v);
83 +        }
84 +        if (comp_baryc(&bcm, coor[0], coor[1], coor[2]) < 0)
85 +                return(0);                      /* degenerate?? */
86 + #else
87 +        if (comp_baryc(&bcm, sc->vert[f->v[0].vid].p,
88 +                        sc->vert[f->v[1].vid].p, sc->vert[f->v[2].vid].p) < 0)
89 +                return(0);                      /* degenerate?? */
90 + #endif
91 +        for (i = 3; i--; ) {                    /* assign BC normals */
92 +                float   *tnrm = sc->norm[f->v[i].nid];
93 +                coor[0][i] = tnrm[0];
94 +                coor[1][i] = tnrm[1];
95 +                coor[2][i] = tnrm[2];
96 +        }                                       /* print texture */
97 +        fprintf(fp, "\n%s texfunc %s\n4 dx dy dz %s\n0\n",
98 +                        sc->matname[f->mat], TEXNAME, TCALNAME);
99 +        fput_baryc(&bcm, coor, 3, fp);          /* with BC normals */
100 +        fprintf(fp, "\n%s polygon %s.%d\n0\n0\n9\n",
101 +                        TEXNAME, sc->grpname[f->grp], ++fcnt);
102 +        for (i = 0; i < 3; i++) {               /* then triangle */
103 +                double  *v = sc->vert[f->v[i].vid].p;
104 +                fprintf(fp, "\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
105 +        }
106 +        return(1);
107 + }
108 +
109   /* Callback to convert face to Radiance */
110   static int
111   radface(Scene *sc, Face *f, void *ptr)
112   {
20        static int      fcnt = 0;
113          FILE            *fp = (FILE *)ptr;
114          int             i;
115          
24        if (f->flags & FACE_DEGENERATE)
25                return(0);
116          fprintf(fp, "\n%s polygon %s.%d\n0\n0\n%d\n", sc->matname[f->mat],
117                                  sc->grpname[f->grp], ++fcnt, 3*f->nv);
118          for (i = 0; i < f->nv; i++) {
# Line 41 | Line 131 | toRadiance(Scene *sc, FILE *fp, int flreq, int flexc)
131  
132          if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
133                  return(0);
134 +                                                /* not passing empties */
135 +        flexc |= FACE_DEGENERATE;
136 +                                                /* reset counter if not stdout */
137 +        fcnt *= (fp == stdout);
138                                                  /* write comments */
139          for (n = 0; n < sc->ndescr; n++)
140                  fprintf(fp, "# %s\n", sc->descr[n]);
141 <                                                /* write faces */
142 <        n = foreachFace(sc, radface, flreq, flexc, (void *)fp);
141 >                                                /* flag faces to smooth */
142 >        n = foreachFace(sc, checksmooth, flreq, flexc, NULL);
143 >        if (n > 0) {                            /* write smooth faces */
144 >                Scene   *smoothies = dupScene(sc, flreq|FACE_RESERVED, flexc);
145 >                if (!smoothies)
146 >                        return(-1);
147 >                n = triangulateScene(smoothies);
148 >                if (n >= 0)
149 >                        n = foreachFace(smoothies, trismooth, 0, 0, fp);
150 >                freeScene(smoothies);
151 >        }
152 >        if (n < 0)
153 >                return(-1);
154 >                                                /* write flat faces */
155 >        n += foreachFace(sc, radface, flreq, flexc|FACE_RESERVED, fp);
156 >
157          if (fflush(fp) < 0) {
158                  error(SYSTEM, "Error writing Radiance scene data");
159                  return(-1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines