| 1 | 
#ifndef lint | 
| 2 | 
static const char RCSid[] = "$Id: tmesh.c,v 2.5 2006/03/02 17:16:56 greg Exp $"; | 
| 3 | 
#endif | 
| 4 | 
/* | 
| 5 | 
 * Compute and print barycentric coordinates for triangle meshes | 
| 6 | 
 */ | 
| 7 | 
 | 
| 8 | 
#include <stdio.h> | 
| 9 | 
#include "fvect.h" | 
| 10 | 
#include "tmesh.h" | 
| 11 | 
 | 
| 12 | 
 | 
| 13 | 
int | 
| 14 | 
flat_tri(                       /* determine if triangle is flat */ | 
| 15 | 
        FVECT   v1, | 
| 16 | 
        FVECT   v2, | 
| 17 | 
        FVECT   v3, | 
| 18 | 
        FVECT   n1, | 
| 19 | 
        FVECT   n2, | 
| 20 | 
        FVECT   n3 | 
| 21 | 
) | 
| 22 | 
{ | 
| 23 | 
        double  d1, d2, d3; | 
| 24 | 
        FVECT   vt1, vt2, vn; | 
| 25 | 
                                        /* compute default normal */ | 
| 26 | 
        VSUB(vt1, v2, v1); | 
| 27 | 
        VSUB(vt2, v3, v2); | 
| 28 | 
        VCROSS(vn, vt1, vt2); | 
| 29 | 
        if (normalize(vn) == 0.0) | 
| 30 | 
                return(DEGEN); | 
| 31 | 
                                        /* compare to supplied normals */ | 
| 32 | 
        d1 = DOT(vn, n1); d2 = DOT(vn, n2); d3 = DOT(vn, n3); | 
| 33 | 
        if (d1 < 0 && d2 < 0 && d3 < 0) { | 
| 34 | 
                if (d1 > -COSTOL || d2 > -COSTOL || d3 > -COSTOL) | 
| 35 | 
                        return(RVBENT); | 
| 36 | 
                return(RVFLAT); | 
| 37 | 
        } | 
| 38 | 
        if (d1 < COSTOL || d2 < COSTOL || d3 < COSTOL) | 
| 39 | 
                return(ISBENT); | 
| 40 | 
        return(ISFLAT); | 
| 41 | 
} | 
| 42 | 
 | 
| 43 | 
 | 
| 44 | 
int | 
| 45 | 
comp_baryc(                     /* compute barycentric vectors */ | 
| 46 | 
        BARYCCM *bcm, | 
| 47 | 
        RREAL   *v1, | 
| 48 | 
        RREAL   *v2, | 
| 49 | 
        RREAL   *v3 | 
| 50 | 
) | 
| 51 | 
{ | 
| 52 | 
        RREAL   *vt; | 
| 53 | 
        FVECT   va, vab, vcb; | 
| 54 | 
        double  d; | 
| 55 | 
        int     ax0, ax1; | 
| 56 | 
        int     i; | 
| 57 | 
                                        /* compute major axis */ | 
| 58 | 
        VSUB(vab, v1, v2); | 
| 59 | 
        VSUB(vcb, v3, v2); | 
| 60 | 
        VCROSS(va, vab, vcb); | 
| 61 | 
        bcm->ax = (va[1]*va[1] > va[0]*va[0]); | 
| 62 | 
        if (va[2]*va[2] > va[bcm->ax]*va[bcm->ax]) bcm->ax = 2; | 
| 63 | 
        ax0 = (bcm->ax + 1)%3; | 
| 64 | 
        ax1 = (bcm->ax + 2)%3; | 
| 65 | 
        for (i = 0; i < 2; i++) { | 
| 66 | 
                vab[0] = v1[ax0] - v2[ax0]; | 
| 67 | 
                vcb[0] = v3[ax0] - v2[ax0]; | 
| 68 | 
                vab[1] = v1[ax1] - v2[ax1]; | 
| 69 | 
                vcb[1] = v3[ax1] - v2[ax1]; | 
| 70 | 
                d = vcb[0]*vcb[0] + vcb[1]*vcb[1]; | 
| 71 | 
                if (d <= FTINY*FTINY) | 
| 72 | 
                        return(-1); | 
| 73 | 
                d = (vcb[0]*vab[0] + vcb[1]*vab[1])/d; | 
| 74 | 
                va[0] = vab[0] - vcb[0]*d; | 
| 75 | 
                va[1] = vab[1] - vcb[1]*d; | 
| 76 | 
                d = va[0]*va[0] + va[1]*va[1]; | 
| 77 | 
                if (d <= FTINY*FTINY) | 
| 78 | 
                        return(-1); | 
| 79 | 
                d = 1.0/d; | 
| 80 | 
                bcm->tm[i][0] = va[0] *= d; | 
| 81 | 
                bcm->tm[i][1] = va[1] *= d; | 
| 82 | 
                bcm->tm[i][2] = -(v2[ax0]*va[0] + v2[ax1]*va[1]); | 
| 83 | 
                                        /* rotate vertices */ | 
| 84 | 
                vt = v1; | 
| 85 | 
                v1 = v2; | 
| 86 | 
                v2 = v3; | 
| 87 | 
                v3 = vt; | 
| 88 | 
        } | 
| 89 | 
        return(0); | 
| 90 | 
} | 
| 91 | 
 | 
| 92 | 
 | 
| 93 | 
void | 
| 94 | 
eval_baryc(                     /* evaluate barycentric weights at p */ | 
| 95 | 
        RREAL   wt[3], | 
| 96 | 
        FVECT   p, | 
| 97 | 
        BARYCCM *bcm | 
| 98 | 
) | 
| 99 | 
{ | 
| 100 | 
        double  u, v; | 
| 101 | 
        int     i; | 
| 102 | 
         | 
| 103 | 
        if ((i = bcm->ax + 1) >= 3) i -= 3; | 
| 104 | 
        u = p[i]; | 
| 105 | 
        if (++i >= 3) i -= 3; | 
| 106 | 
        v = p[i]; | 
| 107 | 
        wt[0] = u*bcm->tm[0][0] + v*bcm->tm[0][1] + bcm->tm[0][2]; | 
| 108 | 
        wt[1] = u*bcm->tm[1][0] + v*bcm->tm[1][1] + bcm->tm[1][2]; | 
| 109 | 
        wt[2] = 1. - wt[1] - wt[0]; | 
| 110 | 
} | 
| 111 | 
 | 
| 112 | 
 | 
| 113 | 
int | 
| 114 | 
get_baryc(              /* compute barycentric weights at p */ | 
| 115 | 
        RREAL   wt[3], | 
| 116 | 
        FVECT   p, | 
| 117 | 
        FVECT   v1, | 
| 118 | 
        FVECT   v2, | 
| 119 | 
        FVECT   v3 | 
| 120 | 
) | 
| 121 | 
{ | 
| 122 | 
        BARYCCM bcm; | 
| 123 | 
         | 
| 124 | 
        if (comp_baryc(&bcm, v1, v2, v3) < 0) | 
| 125 | 
                return(-1); | 
| 126 | 
        eval_baryc(wt, p, &bcm); | 
| 127 | 
        return(0); | 
| 128 | 
} | 
| 129 | 
 | 
| 130 | 
 | 
| 131 | 
#if 0 | 
| 132 | 
int | 
| 133 | 
get_baryc(wt, p, v1, v2, v3)    /* compute barycentric weights at p */ | 
| 134 | 
RREAL   wt[3]; | 
| 135 | 
FVECT   p; | 
| 136 | 
FVECT   v1, v2, v3; | 
| 137 | 
{ | 
| 138 | 
        FVECT   ac, bc, pc, cros; | 
| 139 | 
        double  normf; | 
| 140 | 
                                /* area formula w/o 2-D optimization */ | 
| 141 | 
        VSUB(ac, v1, v3); | 
| 142 | 
        VSUB(bc, v2, v3); | 
| 143 | 
        VSUB(pc, p, v3); | 
| 144 | 
        VCROSS(cros, ac, bc); | 
| 145 | 
        normf = DOT(cros,cros) | 
| 146 | 
        if (normf <= 0.0) | 
| 147 | 
                return(-1); | 
| 148 | 
        normf = 1./sqrt(normf); | 
| 149 | 
        VCROSS(cros, bc, pc); | 
| 150 | 
        wt[0] = VLEN(cros) * normf; | 
| 151 | 
        VCROSS(cros, ac, pc); | 
| 152 | 
        wt[1] = VLEN(cros) * normf; | 
| 153 | 
        wt[2] = 1. - wt[1] - wt[0]; | 
| 154 | 
        return(0); | 
| 155 | 
} | 
| 156 | 
#endif | 
| 157 | 
 | 
| 158 | 
 | 
| 159 | 
void | 
| 160 | 
fput_baryc(                     /* put barycentric coord. vectors */ | 
| 161 | 
        BARYCCM *bcm, | 
| 162 | 
        RREAL   com[][3], | 
| 163 | 
        int     n, | 
| 164 | 
        FILE    *fp | 
| 165 | 
) | 
| 166 | 
{ | 
| 167 | 
        double  a, b; | 
| 168 | 
        int     i; | 
| 169 | 
 | 
| 170 | 
        fprintf(fp, "%d\t%d\n", 1+3*n, bcm->ax); | 
| 171 | 
        for (i = 0; i < n; i++) { | 
| 172 | 
                a = com[i][0] - com[i][2]; | 
| 173 | 
                b = com[i][1] - com[i][2]; | 
| 174 | 
                fprintf(fp, "%14.8f %14.8f %14.8f\n", | 
| 175 | 
                        bcm->tm[0][0]*a + bcm->tm[1][0]*b, | 
| 176 | 
                        bcm->tm[0][1]*a + bcm->tm[1][1]*b, | 
| 177 | 
                        bcm->tm[0][2]*a + bcm->tm[1][2]*b + com[i][2]); | 
| 178 | 
        } | 
| 179 | 
} |