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.4 by greg, Thu Apr 15 23:51:04 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 +        RREAL           ncoor[3][3];
75 +        int             i;
76 +
77 +        if (f->nv != 3)
78 +                return(0);                      /* should never happen */
79 +        if (sizeof(sc->vert[0].p) != sizeof(FVECT))
80 +                error(INTERNAL, "Code error in trismooth()");
81 +        if (comp_baryc(&bcm, sc->vert[f->v[0].vid].p, sc->vert[f->v[1].vid].p,
82 +                        sc->vert[f->v[2].vid].p) < 0)
83 +                return(0);                      /* degenerate?? */
84 +
85 +        for (i = 3; i--; ) {                    /* assign BC normals */
86 +                float   *tnrm = sc->norm[f->v[i].nid];
87 +                ncoor[0][i] = tnrm[0];
88 +                ncoor[1][i] = tnrm[1];
89 +                ncoor[2][i] = tnrm[2];
90 +        }                                       /* print texture */
91 +        fprintf(fp, "\n%s texfunc %s\n4 dx dy dz %s\n0\n",
92 +                        sc->matname[f->mat], TEXNAME, TCALNAME);
93 +        fput_baryc(&bcm, ncoor, 3, fp);         /* with BC normals */
94 +        fprintf(fp, "\n%s polygon %s.%d\n0\n0\n9\n",
95 +                        TEXNAME, sc->grpname[f->grp], ++fcnt);
96 +        for (i = 0; i < 3; i++) {               /* then triangle */
97 +                double  *v = sc->vert[f->v[i].vid].p;
98 +                fprintf(fp, "\t%18.12g %18.12g %18.12g\n", v[0], v[1], v[2]);
99 +        }
100 +        return(1);
101 + }
102 +
103   /* Callback to convert face to Radiance */
104   static int
105   radface(Scene *sc, Face *f, void *ptr)
106   {
20        static int      fcnt = 0;
107          FILE            *fp = (FILE *)ptr;
108          int             i;
109          
24        if (f->flags & FACE_DEGENERATE)
25                return(0);
110          fprintf(fp, "\n%s polygon %s.%d\n0\n0\n%d\n", sc->matname[f->mat],
111                                  sc->grpname[f->grp], ++fcnt, 3*f->nv);
112          for (i = 0; i < f->nv; i++) {
# Line 41 | Line 125 | toRadiance(Scene *sc, FILE *fp, int flreq, int flexc)
125  
126          if (sc == NULL || sc->nfaces <= 0 || fp == NULL)
127                  return(0);
128 +                                                /* not passing empties */
129 +        flexc |= FACE_DEGENERATE;
130 +                                                /* reset counter if not stdout */
131 +        fcnt *= (fp == stdout);
132                                                  /* write comments */
133          for (n = 0; n < sc->ndescr; n++)
134                  fprintf(fp, "# %s\n", sc->descr[n]);
135 <                                                /* write faces */
136 <        n = foreachFace(sc, radface, flreq, flexc, (void *)fp);
135 >                                                /* flag faces to smooth */
136 >        n = foreachFace(sc, checksmooth, flreq, flexc, NULL);
137 >        if (n > 0) {                            /* write smooth faces */
138 >                Scene   *smoothies = dupScene(sc, flreq|FACE_RESERVED, flexc);
139 >                if (!smoothies)
140 >                        return(-1);
141 >                n = triangulateScene(smoothies);
142 >                if (n >= 0)
143 >                        n = foreachFace(smoothies, trismooth, 0, 0, fp);
144 >                freeScene(smoothies);
145 >        }
146 >        if (n < 0)
147 >                return(-1);
148 >                                                /* write flat faces */
149 >        n += foreachFace(sc, radface, flreq, flexc|FACE_RESERVED, fp);
150 >
151          if (fflush(fp) < 0) {
152                  error(SYSTEM, "Error writing Radiance scene data");
153                  return(-1);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines