Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (c) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2011, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#define _SURFACE3D_C
37
#include "openaxiom-c-macros.h"
38
39
#include <string.h>
40
#include <math.h>
41
#include <stdlib.h>
42
43
#include "sockio.h"
44
#include "header.h"
45
#include "draw.h"
46
#include "mode.h" /* for #define components */
47
#include "com.h"
48
#include "XSpadFill.h"
49
#include "XShade.h"
50
#include "util.H1"
51
#include "Gfun.H1"
52
#include "all_3d.H1"
53
54
55
/**** useful defines ****/
56
57
#define precisionFactor 1024
58
59
/* depthChecker turns on the extensive depth checking mechanisms
60
for the depth sort algorithm. Without it, the hidden surface
61
removal is just a sort by z which works remarkably well, but,
62
is insufficient and, at times, may end up being incorrect */
63
#define depthChecker
64
65
66
pointInfo ptIA, ptIB, ptIC; /* global to this file */
67
68
/************************************
69
* void drawLineComponent(p,dFlag) *
70
************************************/
71
72
void
73
drawLineComponent (poly * p, int dFlag)
74
{
75
int i, hue;
76
int *anIndex;
77
RGB col_rgb;
78
79
/* If the polygon is clipped against the hither plane (clipPz) then
80
it is not drawn...or...if the clipStuff is set to true, and
81
the polygon is clipped against the user defined clip volume, it
82
is also not drawn. */
83
if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
84
/* This routine will eventually only be skipped if
85
p->totalClip is true and another routine would
86
handle the partialClip. this routine would handle
87
only those polygons without any clipped points */
88
for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
89
quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
90
quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
91
}
92
93
if (dFlag==Xoption) {
94
if (mono || viewport->monoOn)
95
GSetForeground(opaqueGC, (float)foregroundColor, dFlag);
96
else {
97
hue = hueValue(p->color);
98
GSetForeground(opaqueGC, (float)XSolidColor(hue,2), dFlag);
99
}
100
} else
101
GSetForeground(opaqueGC, psBlack, dFlag);
102
103
if (dFlag==PSoption && !mono && !viewport->monoOn) {
104
hue = getHue(p->color);
105
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
106
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts);
107
} else {
108
GDrawLines(opaqueGC, viewport->viewWindow, quadMesh, p->numpts,
109
CoordModeOrigin, dFlag);
110
}
111
if (dFlag == Xoption)
112
XMapWindow(dsply, viewport->viewWindow);
113
}
114
}
115
116
117
118
/**************************************************
119
* void drawOpaquePolygon(p,aGC,anotherGC) *
120
**************************************************/
121
122
void
123
drawOpaquePolygon (poly *p,GC aGC,GC anotherGC,int dFlag)
124
{
125
126
int *anIndex, i, hue, isNaN = 0;
127
RGB col_rgb;
128
129
if (mono || viewport->monoOn) {
130
GSetForeground(anotherGC, (float)foregroundColor, dFlag);
131
} else {
132
hue = hueValue(p->color);
133
GSetForeground(anotherGC, (float)XSolidColor(hue,2), dFlag);
134
}
135
136
/* If the polygon is clipped against the hither plane (clipPz) then
137
it is not drawn, or if the clipStuff is set to true, and
138
the polygon is clipped against the user defined clip volume, it
139
is also not drawn. */
140
141
if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
142
143
/* This routine should eventually only be skipped if
144
p->totalClip is true and another routine would
145
handle the partialClip. This routine would handle
146
only those polygons without any clipped points. */
147
148
for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
149
quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
150
quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
151
if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
152
}
153
154
quadMesh[i].x =refPt3D(viewData,*(p->indexPtr))->px;
155
quadMesh[i].y =refPt3D(viewData,*(p->indexPtr))->py;
156
if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
157
158
if (dFlag==PSoption && !mono && !viewport->monoOn && !isNaN) {
159
GSetForeground(GC9991, (float)backgroundColor, PSoption);
160
PSFillPolygon(GC9991, quadMesh, p->numpts+1);
161
hue = getHue(p->color);
162
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
163
if (viewport->diagonals)
164
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts+1);
165
else
166
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts);
167
} else {
168
if (mono || viewport->monoOn) {
169
GSetForeground(anotherGC, (float)foregroundColor, dFlag);
170
} else {
171
hue = hueValue(p->color);
172
GSetForeground(anotherGC, (float)XSolidColor(hue,2), dFlag);
173
}
174
GSetForeground(aGC,(float)backgroundColor,dFlag);
175
if (!isNaN) {
176
XFillPolygon(dsply, viewport->viewWindow, aGC, quadMesh, p->numpts,
177
Convex,CoordModeOrigin);
178
if (viewport->diagonals)
179
GDrawLines(anotherGC,viewport->viewWindow,quadMesh,p->numpts+1,
180
CoordModeOrigin, dFlag);
181
else
182
GDrawLines(anotherGC,viewport->viewWindow,quadMesh,p->numpts,
183
CoordModeOrigin, dFlag);
184
}
185
}
186
if (dFlag == Xoption) XMapWindow(dsply,viewport->viewWindow);
187
} /* if not totally clipped */
188
}
189
190
191
192
/*************************************
193
* poly *copyPolygons(polygonList) *
194
* *
195
* copies the given list of polygons *
196
* into a newly allocated list *
197
*************************************/
198
199
poly *
200
copyPolygons (poly *polygonList)
201
{
202
203
int i;
204
poly *aPoly,*retval,*prev;
205
206
prev = retval = aPoly = (poly *)saymem("surface.c",1,sizeof(poly));
207
aPoly->indexPtr = (int *)saymem("surface.c",
208
polygonList->numpts,sizeof(int));
209
aPoly->num = polygonList->num;
210
aPoly->sortNum = polygonList->sortNum;
211
aPoly->split = polygonList->split;
212
aPoly->numpts = polygonList->numpts;
213
for (i=0; i<aPoly->numpts; i++)
214
*((aPoly->indexPtr) + i) = *((polygonList->indexPtr) + i);
215
aPoly->N[0] = polygonList->N[0];
216
aPoly->N[1] = polygonList->N[1];
217
aPoly->N[2] = polygonList->N[2];
218
aPoly->planeConst = polygonList->planeConst;
219
aPoly->color = polygonList->color;
220
aPoly->moved = no;
221
aPoly->pxmin = polygonList->pxmin;
222
aPoly->pxmax = polygonList->pxmax;
223
aPoly->pymin = polygonList->pymin;
224
aPoly->pymax = polygonList->pymax;
225
aPoly->pzmin = polygonList->pzmin;
226
aPoly->pzmax = polygonList->pzmax;
227
aPoly->xmin = polygonList->xmin;
228
aPoly->xmax = polygonList->xmax;
229
aPoly->ymin = polygonList->ymin;
230
aPoly->ymax = polygonList->ymax;
231
aPoly->zmin = polygonList->zmin;
232
aPoly->zmax = polygonList->zmax;
233
aPoly->normalFacingOut = polygonList->normalFacingOut;
234
aPoly->primitiveType = polygonList->primitiveType;
235
for (polygonList = polygonList->next;
236
polygonList != NIL(poly);
237
polygonList = polygonList->next) {
238
prev->next = aPoly = (poly *)saymem("surface.c",1,sizeof(poly));
239
aPoly->indexPtr = (int *)saymem("surface.c",
240
polygonList->numpts,sizeof(int));
241
aPoly->num = polygonList->num;
242
aPoly->sortNum = polygonList->sortNum;
243
aPoly->numpts = polygonList->numpts;
244
aPoly->split = polygonList->split;
245
for (i=0; i<aPoly->numpts; i++)
246
*((aPoly->indexPtr) + i) = *((polygonList->indexPtr) + i);
247
aPoly->N[0] = polygonList->N[0];
248
aPoly->N[1] = polygonList->N[1];
249
aPoly->N[2] = polygonList->N[2];
250
aPoly->planeConst = polygonList->planeConst;
251
aPoly->color = polygonList->color;
252
aPoly->moved = no;
253
aPoly->pxmin = polygonList->pxmin;
254
aPoly->pxmax = polygonList->pxmax;
255
aPoly->pymin = polygonList->pymin;
256
aPoly->pymax = polygonList->pymax;
257
aPoly->pzmin = polygonList->pzmin;
258
aPoly->pzmax = polygonList->pzmax;
259
aPoly->xmin = polygonList->xmin;
260
aPoly->xmax = polygonList->xmax;
261
aPoly->ymin = polygonList->ymin;
262
aPoly->ymax = polygonList->ymax;
263
aPoly->zmin = polygonList->zmin;
264
aPoly->zmax = polygonList->zmax;
265
aPoly->normalFacingOut = polygonList->normalFacingOut;
266
aPoly->primitiveType = polygonList->primitiveType;
267
prev = aPoly;
268
}
269
aPoly->next = 0;
270
return(retval);
271
}
272
273
274
/******************************
275
* void minMaxPolygons(aPoly) *
276
* *
277
* sets up the xmin, *
278
* etc, for each polygon *
279
* for sorting and *
280
* extent checking. *
281
******************************/
282
283
void
284
minMaxPolygons (poly *aPoly)
285
{
286
287
int *anIndex;
288
int i;
289
290
for (; aPoly != NIL(poly); aPoly = aPoly->next) {
291
anIndex = aPoly->indexPtr;
292
aPoly->pxmin = aPoly->pxmax = refPt3D(viewData,*anIndex)->px;
293
aPoly->pymin = aPoly->pymax = refPt3D(viewData,*anIndex)->py;
294
aPoly->pzmin = aPoly->pzmax = refPt3D(viewData,*anIndex)->pz;
295
aPoly->xmin = aPoly->xmax = refPt3D(viewData,*anIndex)->x;
296
aPoly->ymin = aPoly->ymax = refPt3D(viewData,*anIndex)->y;
297
aPoly->zmin = aPoly->zmax = refPt3D(viewData,*anIndex)->z;
298
for (i=1,anIndex++; i<aPoly->numpts; i++,anIndex++) {
299
if (refPt3D(viewData,*anIndex)->px < aPoly->pxmin)
300
aPoly->pxmin = refPt3D(viewData,*anIndex)->px;
301
else if (refPt3D(viewData,*anIndex)->px > aPoly->pxmax)
302
aPoly->pxmax = refPt3D(viewData,*anIndex)->px;
303
if (refPt3D(viewData,*anIndex)->py < aPoly->pymin)
304
aPoly->pymin = refPt3D(viewData,*anIndex)->py;
305
else if (refPt3D(viewData,*anIndex)->py > aPoly->pymax)
306
aPoly->pymax = refPt3D(viewData,*anIndex)->py;
307
if (refPt3D(viewData,*anIndex)->pz < aPoly->pzmin)
308
aPoly->pzmin = refPt3D(viewData,*anIndex)->pz;
309
else if (refPt3D(viewData,*anIndex)->pz > aPoly->pzmax)
310
aPoly->pzmax = refPt3D(viewData,*anIndex)->pz;
311
312
if (refPt3D(viewData,*anIndex)->x < aPoly->xmin)
313
aPoly->xmin = refPt3D(viewData,*anIndex)->x;
314
else if (refPt3D(viewData,*anIndex)->x > aPoly->xmax)
315
aPoly->xmax = refPt3D(viewData,*anIndex)->x;
316
if (refPt3D(viewData,*anIndex)->y < aPoly->ymin)
317
aPoly->ymin = refPt3D(viewData,*anIndex)->y;
318
else if (refPt3D(viewData,*anIndex)->y > aPoly->ymax)
319
aPoly->ymax = refPt3D(viewData,*anIndex)->y;
320
if (refPt3D(viewData,*anIndex)->z < aPoly->zmin)
321
aPoly->zmin = refPt3D(viewData,*anIndex)->z;
322
else if (refPt3D(viewData,*anIndex)->z > aPoly->zmax)
323
aPoly->zmax = refPt3D(viewData,*anIndex)->z;
324
}
325
}
326
} /* minMaxPolygons */
327
328
329
330
/***********************************
331
* int polyCompare (p1,p2) *
332
* *
333
* returns -1 if p1 < p2 *
334
* 0 if p1 = p2 *
335
* 1 if p1 > p2 *
336
* note that this is the reverse *
337
* of what the msort requested. *
338
* this is so that the list will *
339
* be sorted from max to min. *
340
***********************************/
341
342
int
343
polyCompare (poly *p1,poly *p2)
344
{
345
346
if (p1->pzmax > p2->pzmax) return(-1);
347
else if (p1->pzmax < p2->pzmax) return(1);
348
else return(0);
349
}
350
351
/***********************
352
* void calcEyePoint() *
353
* *
354
* sets the global *
355
* variable eyePoint[] *
356
* to where the viewer *
357
* is pointed towards *
358
***********************/
359
360
void
361
calcEyePoint (void)
362
{
363
364
eyePoint[0] = sinPhi * (sinTheta);
365
eyePoint[1] = sinPhi * (-cosTheta);
366
eyePoint[2] = cosPhi;
367
368
}
369
370
371
372
/*
373
void drawPolygons()
374
A general routine for displaying a list of polygons
375
with the proper hidden surfaces removed. Assumes the
376
list of polygons is in viewData.polygons. Needs a
377
routine to split intersecting polygons in object space. *
378
*/
379
380
381
/**************************************
382
* void drawRenderedPolygon(p,dFlag) *
383
* *
384
* calculate the color for the *
385
* polygon p and draw it *
386
**************************************/
387
388
void
389
drawRenderedPolygon (poly *p,int dFlag)
390
{
391
392
int i,hue,shade, isNaN = 0;
393
float whichSide,H[3],P[3],LN,HN,diff,spec,tempLight,lumens,E[3],N[3];
394
int *anIndex, *indx;
395
RGB col_rgb;
396
397
if (!((p->partialClipPz) || (viewData.clipStuff && (p->partialClip)))) {
398
/* This routine should eventually only be skipped if
399
p->totalClip is true and another routine would
400
handle the partialClip. This routine would handle
401
only those polygons without any clipped points. */
402
403
for (i=0, anIndex=p->indexPtr; i<p->numpts; i++,anIndex++) {
404
quadMesh[i].x = refPt3D(viewData,*anIndex)->px;
405
quadMesh[i].y = refPt3D(viewData,*anIndex)->py;
406
if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
407
}
408
quadMesh[i].x = refPt3D(viewData,*(p->indexPtr))->px;
409
quadMesh[i].y = refPt3D(viewData,*(p->indexPtr))->py;
410
if (eqNANQ(quadMesh[i].x) || eqNANQ(quadMesh[i].y)) isNaN = 1;
411
412
if (!isNaN) {
413
/* calculate polygon illumination */
414
indx = p->indexPtr;
415
P[0] = (refPt3D(viewData,*(indx))->wx +
416
refPt3D(viewData,*(indx+1))->wx +
417
refPt3D(viewData,*(indx+2))->wx);
418
P[1] = (refPt3D(viewData,*(indx))->wy +
419
refPt3D(viewData,*(indx+1))->wy +
420
refPt3D(viewData,*(indx+2))->wy);
421
P[2] = (refPt3D(viewData,*(indx))->wz +
422
refPt3D(viewData,*(indx+1))->wz +
423
refPt3D(viewData,*(indx+2))->wz);
424
normalizeVector(P);
425
426
N[0] = p->N[0]; N[1] = p->N[1]; N[2] = p->N[2];
427
normalizeVector(eyePoint);
428
E[0] = 4.0*eyePoint[0] - P[0];
429
E[1] = 4.0*eyePoint[1] - P[1];
430
E[2] = 4.0*eyePoint[2] - P[2];
431
normalizeVector(E);
432
diff = 0.0; spec = 0.0;
433
LN = N[0]*viewport->lightVector[0] +
434
N[1]*viewport->lightVector[1] +
435
N[2]*viewport->lightVector[2];
436
if (LN < 0.0) LN = -LN;
437
diff = LN*Cdiff;
438
439
if (LN > 0.0) {
440
H[0] = E[0] + viewport->lightVector[0];
441
H[1] = E[1] + viewport->lightVector[1];
442
H[2] = E[2] + viewport->lightVector[2];
443
normalizeVector(H);
444
HN = dotProduct(N,H,3);
445
if (HN < 0.0) HN = -HN;
446
spec = pow((double)absolute(HN),coeff);
447
if (spec > 1.0) spec = 1.0;
448
}
449
450
lumens = ((Camb + 0.15) + diff + spec*Cspec);
451
if (lumens > 1.0) lumens = 1.0;
452
if (lumens < 0.0) lumens = 0.0;
453
if (dFlag==PSoption && !mono && !viewport->monoOn) {
454
hue = getHue(p->color);
455
col_rgb = hlsTOrgb((float)hue,lumens,0.8);
456
/* NTSC color to grey = .299 red + .587 green + .114 blue */
457
maxGreyShade = (int) psShadeMax;
458
whichSide = (.299*col_rgb.r + .587*col_rgb.g + .114*col_rgb.b) *
459
(maxGreyShade-1);
460
}
461
else {
462
if (mono || viewport->monoOn) {
463
hue = getHue(p->color);
464
col_rgb = hlsTOrgb((float)hue,lumens,0.8);
465
whichSide = (.299*col_rgb.r + .587*col_rgb.g + .114*col_rgb.b) *
466
(maxGreyShade-1);
467
} else
468
whichSide = lumens*(totalShades-1);
469
}
470
471
tempLight = lightIntensity;
472
if (lightIntensity < Camb) lightIntensity = Camb;
473
474
shade = floor(lightIntensity * absolute(whichSide));
475
lightIntensity = tempLight;
476
477
if (shade < totalShades) {
478
/* shade < totalShades is (temporarily) necessary here
479
because, currently, parameterizations for things like
480
the sphere would produce triangular shaped polygons
481
close to the poles which get triangularized leaving a
482
triangle with coincidental points. the normal for this
483
would be undefined (since coincidental points would create
484
a zero vector) and the shade would be large, hence,
485
the conditional. */
486
487
if (mono || viewport->monoOn) {
488
if (dFlag == Xoption) {
489
XChangeShade(dsply,maxGreyShade-shade-1);
490
XShadePolygon(dsply,viewport->viewWindow,quadMesh,p->numpts+1,
491
Convex,CoordModeOrigin);
492
}
493
else if (dFlag == PSoption) { /* renderGC has number 9991
494
(see main.c, header.h) */
495
GSetForeground(GC9991,
496
1.0-(float)(maxGreyShade-shade-1)*psShadeMul,PSoption);
497
PSFillPolygon(GC9991, quadMesh, p->numpts+1);
498
}
499
} else { /* not mono */
500
if (dFlag == Xoption) {
501
hue = hueValue(p->color);
502
XSpadFillPolygon(dsply, viewport->viewWindow, quadMesh,
503
p->numpts+1, Convex,CoordModeOrigin, hue, shade);
504
}
505
else if (dFlag == PSoption) /* draws it out in monochrome */
506
PSColorPolygon(col_rgb.r,col_rgb.g,col_rgb.b,quadMesh,p->numpts+1);
507
} /* if mono-else */
508
509
if (viewData.outlineRenderOn) {
510
if (viewport->diagonals) {
511
if (dFlag == PSoption) {
512
GSetForeground(renderGC,psBlack, dFlag);
513
GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts+1,
514
CoordModeOrigin,dFlag);
515
} else
516
GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts+1,
517
CoordModeOrigin,dFlag);
518
} else {
519
if (dFlag == PSoption) {
520
GSetForeground(renderGC,psBlack,PSoption);
521
GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts,
522
CoordModeOrigin,PSoption);
523
} else
524
GDrawLines(renderGC,viewport->viewWindow,quadMesh,p->numpts,
525
CoordModeOrigin,dFlag);
526
}
527
}
528
}
529
} /* if not NaN */
530
if (dFlag == Xoption) XMapWindow(dsply,viewport->viewWindow);
531
} /* if not clipped */
532
533
} /* drawRenderedPolygon */
534
535
536
void
537
freePointResevoir(void)
538
{
539
540
viewTriple *v;
541
542
while (splitPoints != NIL(viewTriple)) {
543
v = splitPoints;
544
splitPoints = splitPoints->next;
545
free(v);
546
}
547
548
} /* freePointResevoir */
549
550
/***********************************
551
* void freeListOfPolygons(pList); *
552
* *
553
* frees up a list of polygons. *
554
***********************************/
555
556
void
557
freeListOfPolygons (poly *pList)
558
{
559
560
poly *nextP;
561
562
for (; pList != NIL(poly); pList=nextP) {
563
nextP=pList->next;
564
free(pList->indexPtr);
565
free(pList);
566
}
567
} /* freeListOfPolygons() */
568
569
570
571
void
572
drawPolygons(int dFlag)
573
{
574
575
poly *p,*head;
576
poly *tempQuick=NULL;
577
int quickFirst=yes;
578
579
if (recalc) {
580
581
/* To get around multiple X Expose events the server tends
582
to send upon startup, leave negation of firstTime to the end. */
583
rotated = no;
584
zoomed = no;
585
translated = no;
586
switchedPerspective = no;
587
changedEyeDistance = no;
588
redoSmooth = yes;
589
590
if (keepDrawingViewport()) {
591
if (!firstTime) {
592
strcpy(control->message," Creating Polygons ");
593
writeControlMessage();
594
freeListOfPolygons(quickList);
595
freePointResevoir();
596
}
597
strcpy(control->message," Collecting Polygons ");
598
writeControlMessage();
599
quickList = copyPolygons(viewData.polygons);
600
601
if (keepDrawingViewport()) {
602
/* to get normal facing outside info */
603
strcpy(control->message," Projecting Polygons ");
604
writeControlMessage();
605
projectAllPolys(quickList);
606
if (keepDrawingViewport()) {
607
strcpy(control->message," Setting Extreme Values ");
608
writeControlMessage();
609
minMaxPolygons(quickList);
610
if (keepDrawingViewport()) {
611
strcpy(control->message," Sorting Polygons ");
612
writeControlMessage();
613
quickList = msort(quickList,0,viewData.numPolygons,polyCompare);
614
if (keepDrawingViewport()) {
615
calcEyePoint();
616
head = p = quickList;
617
618
clearControlMessage();
619
strcpy(control->message,viewport->title);
620
writeControlMessage();
621
622
if (viewData.scaleDown) {
623
if (keepDrawingViewport()) {
624
for (p=quickList;
625
keepDrawingViewport() && (p != NIL(poly));
626
p=p->next) {
627
switch (p->primitiveType) {
628
case pointComponent:
629
if (dFlag==Xoption) {
630
if (mono || viewport->monoOn)
631
GSetForeground(componentGC,
632
(float)foregroundColor, dFlag);
633
else
634
GSetForeground(componentGC,
635
(float)meshOutline, dFlag);
636
} else {
637
GSetForeground(componentGC, psBlack, dFlag);
638
GFillArc(componentGC, viewport->viewWindow,
639
(int)refPt3D(viewData,*(p->indexPtr))->px,
640
(int)refPt3D(viewData,*(p->indexPtr))->py,
641
viewData.pointSize,viewData.pointSize,0,
642
360*64, dFlag);
643
}
644
break;
645
case lineComponent:
646
drawLineComponent(p,dFlag);
647
break;
648
default:
649
if (viewData.style == opaqueMesh) {
650
GSetForeground(globGC,(float)backgroundColor,dFlag);
651
drawOpaquePolygon(p,globGC,opaqueGC,dFlag);
652
} else {
653
drawRenderedPolygon(p,dFlag);
654
}
655
} /* switch */
656
}
657
}
658
}
659
660
if (!quickFirst) {
661
/* append the rest of the polygons onto the list */
662
tempQuick->next = head;
663
/* but do not continue the drawing... */
664
if (head != NIL(poly)) head->doNotStopDraw = no;
665
} /* if !quickFirst */
666
finishedList = (p==NIL(poly));
667
} /* for various */
668
} /* steps */
669
} /* of */
670
} /* keepDrawingViewport() */
671
} /* *** */
672
/* May want to have a flag somewhere to stop the drawing yet
673
continue the freeing */
674
if (firstTime) firstTime = no;
675
} else { /* if recalc else if not recalc just draw stuff in list */
676
if (keepDrawingViewport()) {
677
for (p=quickList;
678
keepDrawingViewport() && p != NIL(poly) &&
679
(viewData.scaleDown || p->doNotStopDraw); p=p->next) {
680
projectAPoly(p);
681
switch (p->primitiveType) {
682
case pointComponent:
683
if (dFlag==Xoption) {
684
if (mono || viewport->monoOn)
685
GSetForeground(componentGC,(float)foregroundColor, dFlag);
686
else
687
GSetForeground(componentGC,(float)meshOutline, dFlag);
688
} else
689
GSetForeground(componentGC,psBlack, dFlag);
690
GFillArc(componentGC, viewport->viewWindow,
691
(int)refPt3D(viewData,*(p->indexPtr))->px,
692
(int)refPt3D(viewData,*(p->indexPtr))->py,
693
viewData.pointSize,viewData.pointSize,0,360*64,dFlag);
694
break;
695
case lineComponent:
696
drawLineComponent(p,dFlag);
697
break;
698
default:
699
if (viewData.style == opaqueMesh) {
700
GSetForeground(globGC,(float)backgroundColor,dFlag);
701
drawOpaquePolygon(p,globGC,opaqueGC,dFlag);
702
} else
703
drawRenderedPolygon(p,dFlag);
704
} /* switch */
705
}
706
}
707
}
708
} /* drawPolygons */
709
710
711
712
713
714
715
716
/**************************
717
* int lessThan(x,y) *
718
* int greaterThan(x,y) *
719
* int equal(x,y) *
720
* *
721
* Compares two floating *
722
* point numbers for *
723
* precision of up to one *
724
* place in a thousand. *
725
* returns *
726
* 1 if true *
727
* o otherwise *
728
**************************/
729
730
int
731
lessThan (float x,float y)
732
{
733
int xI,yI;
734
735
xI = x*precisionFactor;
736
yI = y*precisionFactor;
737
return(xI<yI);
738
}
739
740
int
741
greaterThan (float x,float y)
742
{
743
int xI,yI;
744
745
xI = x*precisionFactor;
746
yI = y*precisionFactor;
747
return(xI>yI);
748
}
749
750
int
751
isNaN (float v)
752
{
753
return (v != v);
754
}
755
756
757
int
758
isNaNPoint (float x,float y,float z)
759
{
760
return (isNaN(x) || isNaN(y) || isNaN(z));
761
}
762
763
int
764
equal (float x,float y)
765
{
766
int xI,yI;
767
768
xI = x*precisionFactor;
769
yI = y*precisionFactor;
770
return(xI==yI);
771
}
772
773
774