1 /**********
2 *
3 * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
4 * University of Manchester, UK. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 *
9 * . Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * . Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * . Neither the name of the University of Manchester nor the names of its
17 * contributors may be used to endorse or promote products derived from this
18 * software without specific prior written permission.
19 *
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 **********
34 *
35 * Program : TINA
36 * File : $Source: /home/tina/cvs/tina-tools/tinatool/draw/drawPaint_tri.c,v $
37 * Date : $Date: 2003/10/01 16:02:47 $
38 * Version : $Revision: 1.2 $
39 * CVS Id : $Id: drawPaint_tri.c,v 1.2 2003/10/01 16:02:47 tony Exp $
40 *
41 * Author : Legacy TINA
42 *
43 * Notes :
44 *
45 *********
46 */
47
48 #include "drawPaint_tri.h"
49
50 #if HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53
54 #include <math.h>
55 #include <float.h>
56 #include <tina/sys/sysDef.h>
57 #include <tina/sys/sysPro.h>
58 #include <tina/math/mathDef.h>
59 #include <tina/math/mathPro.h>
60 #include <tina/geometry/geomDef.h>
61 #include <tinatool/draw/draw_TvDef.h>
62 #include <tinatool/draw/draw_TvPro.h>
63 #include <tinatool/draw/draw_PaintDef.h>
64 #include <tinatool/draw/draw_PaintPro.h>
65
66 void draw_triangle3(Tv * tv, Vec3 * tri)
67
68 /* a 3 vector of VEC3 */
69 {
70 if (tv == NULL)
71 return;
72
73 tv_line3(tv, tri[0], tri[1]);
74 tv_line3(tv, tri[1], tri[2]);
75 tv_line3(tv, tri[2], tri[0]);
76 }
77
78 void draw_triangle3_fill(Tv * tv, Vec3 * tri, int col)
79
80 /* a 3 vector of VEC3 */
81
82 {
83 Ipos p[3] = {{Ipos_id}, {Ipos_id}, {Ipos_id}};
84 Ipos dif[3] = {{Ipos_id}, {Ipos_id}, {Ipos_id}};
85 int lx, ux, ly, uy;
86 int width, height;
87 int i, j;
88
89 if (tv == NULL)
90 return;
91
92 width = tv_get_width(tv);
93 height = tv_get_height(tv);
94 tv_set_color(tv, col);
95 draw_triangle3(tv, tri);
96 for (i = 0; i < 3; ++i)
97 p[i] = tv_proj3(tv, tri[i]);
98
99 for (i = 0; i < 3; ++i)
100 {
101 j = (i + 1) % 3;
102 dif[i] = ipos_diff(p[j], p[i]);
103 }
104
105 ly = MIN3(ipos_y(p[0]), ipos_y(p[1]), ipos_y(p[2]));
106 if (ly < 0)
107 ly = 0;
108 uy = MAX3(ipos_y(p[0]), ipos_y(p[1]), ipos_y(p[2]));
109 if (uy >= height)
110 uy = height - 1;
111
112 for (i = ly; i < uy; ++i)
113 {
114 lx = width;
115 ux = 0;
116 for (j = 0; j < 3; ++j)
117 {
118 if (i == ipos_y(p[j]) || i == ipos_y(p[(j + 1) % 3]) ||
119 BETWEEN(i, ipos_y(p[j]), ipos_y(p[(j + 1) % 3])))
120 {
121 int x;
122
123 if (ipos_y(dif[j]) == 0)
124 { /* horizontal line */
125 x = MIN(ipos_x(p[j]), ipos_x(p[(j + 1) % 3]));
126 if (x < lx)
127 lx = x;
128 x = MAX(ipos_x(p[j]), ipos_x(p[(j + 1) % 3]));
129 if (x > ux)
130 ux = x;
131 continue;
132 }
133 x = i - ipos_y(p[j]); /* bottom of the pixel */
134 x = ipos_x(p[j]) + x * ipos_x(dif[j]) / ipos_y(dif[j]);
135 if (x < lx)
136 lx = x;
137 if (x > ux)
138 ux = x;
139 } else
140 continue;
141
142 if (i + 1 == ipos_y(p[j]) || i + 1 == ipos_y(p[(j + 1) % 3]) ||
143 BETWEEN(i + 1, ipos_y(p[j]), ipos_y(p[(j + 1) % 3])))
144 {
145 int x;
146
147 x = i + 1 - ipos_y(p[j]); /* top of the pixel */
148 x = ipos_x(p[j]) + x * ipos_x(dif[j]) / ipos_y(dif[j]);
149 if (x < lx)
150 lx = x;
151 if (x > ux)
152 ux = x;
153 }
154 }
155 if (lx < ux)
156 tv_linexy(tv, lx - 1, i, ux + 1, i);
157 }
158 }
159
160 void shade_triangle3(Tv * tv, Vec3 * tri)
161
162 /* a 3 vector of VEC3 */
163 {
164 Vec3 n = {Vec3_id};
165 Vec3 dif[3] = {{Vec3_id}, {Vec3_id}, {Vec3_id}};
166 int gl, i, j;
167 double min_dp = FLT_MAX;
168
169 if (tv == NULL)
170 return;
171
172 for (i = 0; i < 3; ++i)
173 {
174 j = (i + 1) % 3;
175 dif[i] = vec3_diff(tri[j], tri[i]);
176 }
177
178 for (i = 0; i < 3; ++i)
179 for (j = i + 1; j < 3; ++j)
180 {
181 double dp = fabs(vec3_dot(dif[i], dif[j]));
182
183 if ((i == 0 && j == 1) || dp < min_dp)
184 {
185 min_dp = dp;
186 n = vec3_cross(dif[i], dif[j]);
187 }
188 }
189
190 n = vec3_unit(n);
191 gl = (int)(64.0 + 191.0 * fabs(vec3_dot(n, tv->ez3)));
192 if (gl > 255)
193 gl = 255;
194 if (gl < 0)
195 gl = 0;
196 draw_triangle3_fill(tv, tri, (int) tv->cmap_data_visible->std_lut[gl]);
197 }
198
199 /* ARGSUSED quieten lint */
200 static double tri_closest_along_tv_ez3(Vec3 * tri, int type, Tv * tv)
201 {
202 int i;
203 double max = FLT_MIN;
204
205 for (i = 0; i < 3; ++i)
206 {
207 double dp = -vec3_dot(vec3_diff(tri[i], tv->centre3), tv->ez3);
208
209 if (i == 0 || dp > max)
210 max = dp;
211 }
212 return (max);
213 }
214
215 void draw_ordered_tris3_list(Tv * tv, List * tris)
216 {
217 if (tv == NULL)
218 return;
219
220 tris = list_copy(tris, (void *(*) ()) NULL, NULL);
221 tris = sort_list(tris, tri_closest_along_tv_ez3, (void *) tv);
222 reclist_list_draw(tv, tris, TRIANGLE3, shade_triangle3, NULL);
223 }
224
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.