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-2010, 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 _COMPONENT3D_C
37
#include "openaxiom-c-macros.h"
38
39
#include "header.h"
40
#include "draw.h"
41
42
#include "Gfun.H1"
43
#include "util.H1"
44
#include "XSpadFill.h"
45
46
#include "all_3d.H1"
47
48
#define axisLength 1.0 /* use 100.0, if data is not to be normalized */
49
50
#define samePoint(a,b) ((refPt3D(viewData,a)->x == refPt3D(viewData,b)->x) &&\
51
(refPt3D(viewData,a)->y == refPt3D(viewData,b)->y) &&\
52
(refPt3D(viewData,a)->z == refPt3D(viewData,b)->z))
53
#define MAX_POINT 1000.0
54
#define MIN_POINT -1000.0
55
56
57
void
58
scaleComponents (void)
59
{
60
61
double xRange,yRange,zRange;
62
int i;
63
viewTriple *aPoint;
64
65
/* Temporary range limits until the three dimensional clipping
66
package is fully functional */
67
68
if (viewData.xmin < MIN_POINT) viewData.xmin = MIN_POINT;
69
if (viewData.xmax > MAX_POINT) viewData.xmax = MAX_POINT;
70
if (viewData.ymin < MIN_POINT) viewData.ymin = MIN_POINT;
71
if (viewData.ymax > MAX_POINT) viewData.ymax = MAX_POINT;
72
if (viewData.zmin < MIN_POINT) viewData.zmin = MIN_POINT;
73
if (viewData.zmax > MAX_POINT) viewData.zmax = MAX_POINT;
74
75
xRange = viewData.xmax - viewData.xmin;
76
yRange = viewData.ymax - viewData.ymin;
77
zRange = viewData.zmax - viewData.zmin;
78
79
/* We scale down, normalize the data, if it is coming from OpenAxiom
80
(handled by viewman). If the data is coming from a file (handled by
81
viewAlone) then it should already been scaled down.
82
*/
83
84
/* Find the coordinate axis with the larges range of data and scale
85
the others relative to it.
86
*/
87
/* compare x and y ranges */
88
if (xRange > yRange) {
89
if (xRange > zRange) {
90
if (absolute(viewData.xmax) >= absolute(viewData.xmin))
91
viewData.scaleToView = axisLength/(absolute(viewData.xmax));
92
else
93
viewData.scaleToView = axisLength/(absolute(viewData.xmin));
94
} else {
95
if (absolute(viewData.zmax) >= absolute(viewData.zmin))
96
viewData.scaleToView = axisLength/(absolute(viewData.zmax));
97
else
98
viewData.scaleToView = axisLength/(absolute(viewData.zmin));
99
}
100
} else {
101
if (yRange > zRange) {
102
if (absolute(viewData.ymax) >= absolute(viewData.ymin))
103
viewData.scaleToView = axisLength/(absolute(viewData.ymax));
104
else
105
viewData.scaleToView = axisLength/(absolute(viewData.ymin));
106
} else {
107
if (absolute(viewData.zmax) >= absolute(viewData.zmin))
108
viewData.scaleToView = axisLength/(absolute(viewData.zmax));
109
else
110
viewData.scaleToView = axisLength/(absolute(viewData.zmin));
111
}
112
}
113
114
/* We now normalize all the points in this program. The information
115
needed to link the normalized set of points back to the real object
116
space scale created in OpenAxiom is held in viewData.scaleToView. */
117
viewData.xmin *= viewData.scaleToView;
118
viewData.xmax *= viewData.scaleToView;
119
viewData.ymin *= viewData.scaleToView;
120
viewData.ymax *= viewData.scaleToView;
121
viewData.zmin *= viewData.scaleToView;
122
viewData.zmax *= viewData.scaleToView;
123
viewData.clipXmin = viewData.xmin;
124
viewData.clipXmax = viewData.xmax;
125
viewData.clipYmin = viewData.ymin;
126
viewData.clipYmax = viewData.ymax;
127
viewData.clipZmin = viewData.zmin;
128
viewData.clipZmax = viewData.zmax;
129
130
for (i=0, aPoint=viewData.points; i<viewData.numOfPoints; i++,aPoint++) {
131
aPoint->x *= viewData.scaleToView;
132
aPoint->y *= viewData.scaleToView;
133
aPoint->z *= viewData.scaleToView;
134
}
135
136
} /* scaleComponents() */
137
138
139
/*
140
void makeTriangle(a,b,c)
141
Given three indices to three points, a triangular polygon is created
142
and inserted into the polygon list of viewData. If two or more of the
143
points are coincidental, no polygon is created since that would be a
144
degenerate (collapsed) polygon.
145
*/
146
147
void
148
makeTriangle (int a, int b, int c)
149
{
150
poly *aPoly;
151
152
if (!(samePoint(a,b) || samePoint(b,c) || samePoint(c,a))) {
153
/* create triangle only if the three vertex points are distinct */
154
aPoly = (poly *)saymem("component.c",1,sizeof(poly));
155
aPoly->num = aPoly->sortNum = viewData.numPolygons++;
156
aPoly->split = aPoly->moved = no;
157
aPoly->numpts = 3;
158
aPoly->primitiveType = polygonComponent;
159
aPoly->indexPtr = (int *)saymem("component.c",3,sizeof(int));
160
*(aPoly->indexPtr) = a;
161
*(aPoly->indexPtr + 1) = b;
162
*(aPoly->indexPtr + 2) = c;
163
aPoly->doNotStopDraw = yes;
164
aPoly->next = viewData.polygons;
165
viewData.polygons = aPoly;
166
} /* if all points are unique */
167
168
} /* makeTriangle() */
169
170
171
172
173
/*
174
void triangulate()
175
176
Only if there is more than one list do we triangulate; a single list
177
is used for either a space curve or simply a point. Actually, in that
178
case, we now make "flat" *polygons, flagged by the primitiveType field
179
(pointComponent, etc. in tube.h). We need to examine two lists at a time
180
(and if the structure is closed, the last and first as well). For every
181
three points in the two lists, alternating between one in one and two in
182
the other, we construct triangles. If one list is shorter, then its last
183
point becomes the vertex for the remaining pairs of points from the other
184
list. It turns out that any distribution of points in the two lists
185
(preserving cyclic order) will produce the same desired polygon.
186
*/
187
188
void
189
triangulate (void)
190
{
191
192
int u,l;
193
int uBound,lBound;
194
int i,j,k;
195
LLPoint *anLLPoint;
196
LPoint *list1,*list2;
197
poly *aPoly;
198
199
anLLPoint = viewData.lllp.llp;
200
for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
201
if (anLLPoint->numOfLists > 1) {
202
list2 = anLLPoint->lp;
203
for (j=1; j<anLLPoint->numOfLists; j++) {
204
list1 = list2;
205
list2 = list1 + 1;
206
u = l = 0;
207
uBound = u+1 < list1->numOfPoints;
208
lBound = l+1 < list2->numOfPoints;
209
while (uBound || lBound) {
210
if (uBound) {
211
makeTriangle(*(list1->indices + u + 1),
212
*(list1->indices + u), *(list2->indices + l));
213
u++;
214
uBound = u+1 < list1->numOfPoints;
215
}
216
if (lBound) {
217
makeTriangle(*(list2->indices + l),
218
*(list2->indices + l + 1), *(list1->indices + u));
219
l++;
220
lBound = l+1 < list2->numOfPoints;
221
}
222
} /* while (uBound || lBound) */
223
} /* for j<anLLPoint->numOfLists */
224
} /* if anLLPoint->numOfLists > 1 */
225
else {
226
/* if anLLPoint->numOfLists <= 1...assume this means =1 */
227
/* Flat polygons are to be drawn when hidden
228
surface algorithm is used.*/
229
if (anLLPoint->numOfLists == 1) {
230
if (anLLPoint->lp->numOfPoints == 1) {
231
/* this graph is a single point */
232
aPoly = (poly *)saymem("component.c",1,sizeof(poly));
233
aPoly->num = aPoly->sortNum = viewData.numPolygons++;
234
aPoly->split = aPoly->moved = no;
235
aPoly->primitiveType = pointComponent;
236
aPoly->numpts = 1;
237
aPoly->indexPtr = (int *)saymem("component.c",1,intSize);
238
*(aPoly->indexPtr) = *(anLLPoint->lp->indices);
239
aPoly->doNotStopDraw = yes;
240
aPoly->next = viewData.polygons;
241
viewData.polygons = aPoly;
242
} else {
243
/* this graph is a curve */
244
for (k=0; k<anLLPoint->lp->numOfPoints-1; k++) {
245
aPoly = (poly *)saymem("component.c",1,sizeof(poly));
246
aPoly->num = aPoly->sortNum = viewData.numPolygons++;
247
aPoly->split = aPoly->moved = no;
248
aPoly->primitiveType = lineComponent; /* curveComponent */
249
aPoly->numpts = 2;
250
aPoly->indexPtr =
251
(int *)saymem("component.c",2,sizeof(int));
252
*(aPoly->indexPtr) = *(anLLPoint->lp->indices + k);
253
*(aPoly->indexPtr+1) = *(anLLPoint->lp->indices + k + 1);
254
aPoly->doNotStopDraw = yes;
255
aPoly->next = viewData.polygons;
256
viewData.polygons = aPoly;
257
} /* for k */
258
if (anLLPoint->lp->prop.closed) {
259
aPoly = (poly *)saymem("component.c",1,sizeof(poly));
260
aPoly->num = aPoly->sortNum = viewData.numPolygons++;
261
aPoly->split = aPoly->moved = no;
262
aPoly->primitiveType = lineComponent; /* curveComponent */
263
aPoly->numpts = 2;
264
aPoly->indexPtr =
265
(int *)saymem("component.c",2,sizeof(int));
266
*(aPoly->indexPtr) = *(anLLPoint->lp->indices + k);
267
*(aPoly->indexPtr+1) = *(anLLPoint->lp->indices);
268
aPoly->doNotStopDraw = yes;
269
aPoly->next = viewData.polygons;
270
viewData.polygons = aPoly;
271
} /* if list of points is closed */
272
} /* else */
273
} /* point, line, polygon, surface components are taken care of above */
274
} /* else anLLPoint->numOfLists <= 1 */
275
} /* for LLPoints in LLLPoints (i) */
276
277
} /* triangulate */
278
279
280
281
void
282
readComponentsFromViewman (void)
283
{
284
int i,j,k;
285
LLPoint *anLLPoint;
286
LPoint *anLPoint;
287
viewTriple *aPoint;
288
/* maxLength holds the max(llp,lp) figure regarding how large to
289
make the array of XPoints, i.e. quadMesh, for use in calling XDraw(). */
290
int maxLength=0;
291
292
int *anIndex;
293
294
readViewman(&(viewData.numOfPoints),intSize);
295
aPoint = viewData.points =
296
(viewTriple *)saymem("component.c",viewData.numOfPoints,
297
sizeof(viewTriple));
298
for (i=0; i<viewData.numOfPoints; i++, aPoint++) {
299
readViewman(&(aPoint->x),floatSize);
300
readViewman(&(aPoint->y),floatSize);
301
readViewman(&(aPoint->z),floatSize);
302
readViewman(&(aPoint->c),floatSize);
303
#ifdef NANQ_DEBUG
304
if (!(aPoint->z < 0) && !(aPoint->z > 0) && !(aPoint->z == 0))
305
fprintf(stderr,"%g\n", aPoint->z);
306
#endif
307
}
308
309
readViewman(&(viewData.lllp.numOfComponents),intSize);
310
anLLPoint = viewData.lllp.llp =
311
(LLPoint *)saymem("component.c, i",viewData.lllp.numOfComponents,
312
sizeof(LLPoint));
313
for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
314
readViewman(&(anLLPoint->prop.closed),intSize);
315
readViewman(&(anLLPoint->prop.solid),intSize);
316
readViewman(&(anLLPoint->numOfLists),intSize);
317
anLPoint = anLLPoint->lp =
318
(LPoint *)saymem("component.c, ii",anLLPoint->numOfLists,
319
sizeof(LPoint));
320
for (j=0; j<anLLPoint->numOfLists; j++,anLPoint++) {
321
if (anLLPoint->numOfLists > maxLength)
322
maxLength = anLLPoint->numOfLists;
323
readViewman(&(anLPoint->prop.closed),intSize);
324
readViewman(&(anLPoint->prop.solid),intSize);
325
readViewman(&(anLPoint->numOfPoints),intSize);
326
anIndex = anLPoint->indices =
327
(int *)saymem("component.c, index",anLPoint->numOfPoints,intSize);
328
if (anLPoint->numOfPoints > maxLength)
329
maxLength = anLPoint->numOfPoints;
330
for (k=0; k<anLPoint->numOfPoints; k++,anIndex++) {
331
readViewman(anIndex,intSize);
332
/* OpenAxiom arrays are one based, C arrays are zero based */
333
if (!viewAloned) (*anIndex)--;
334
}
335
} /* for LPoints in LLPoints (j) */
336
} /* for LLPoints in LLLPoints (i) */
337
338
quadMesh = (XPoint *)saymem("component.c",maxLength+2,sizeof(XPoint));
339
340
} /* readComponentsFromViewman() */
341
342
343
344
/*
345
void calcNormData() *
346
Calculates the surface normals for the polygons that make up the tube.
347
Also finds the fourth coefficient to the plane equation:
348
Ax + By + Cz + D = 0
349
A,B, and C are in the normal N[3] and D is the planeConst.
350
Figures out the color as well (from the average of the points) and
351
resets the moved flag
352
*/
353
354
void
355
calcNormData (void)
356
{
357
358
poly *aPoly;
359
int *index;
360
361
for (aPoly = viewData.polygons; aPoly != NIL(poly); aPoly = aPoly->next) {
362
index = aPoly->indexPtr;
363
switch (aPoly->primitiveType) {
364
case pointComponent:
365
case lineComponent:
366
aPoly->moved = 0;
367
aPoly->color = refPt3D(viewData,*index)->c;
368
break;
369
default:
370
/*
371
The following line takes 3 consecutive points and asks
372
for the normal vector defined by them. This assumes that
373
these do not contain co-linear points. For some reason,
374
co-linear points are allowed, this needs to be changed.
375
*/
376
getMeshNormal(refPt3D(viewData,*index)->x,
377
refPt3D(viewData,*index)->y,
378
refPt3D(viewData,*index)->z,
379
refPt3D(viewData,*(index+1))->x,
380
refPt3D(viewData,*(index+1))->y,
381
refPt3D(viewData,*(index+1))->z,
382
refPt3D(viewData,*(index+2))->x,
383
refPt3D(viewData,*(index+2))->y,
384
refPt3D(viewData,*(index+2))->z, 0.0, 1.0, aPoly->N);
385
386
/* calculate the constant term, D, for the plane equation */
387
aPoly->planeConst =
388
-(aPoly->N[0] * refPt3D(viewData,*index)->x +
389
aPoly->N[1] * refPt3D(viewData,*index)->y +
390
aPoly->N[2] * refPt3D(viewData,*index)->z);
391
aPoly->moved = 0;
392
aPoly->color = (refPt3D(viewData,*index)->c +
393
(refPt3D(viewData,*(index+1)))->c +
394
(refPt3D(viewData,*(index+2)))->c) / 3.0;
395
break;
396
} /* switch */
397
}
398
399
} /* calcNormData() */
400
401
402
403
/*
404
viewPoints *make3DComponents()
405
406
Read in all the 3D data from the viewport manager and construct the
407
model of it. The model is based upon a list of lists of lists of points.
408
Each top level list makes a component in 3-space. The interpretation
409
really begins at the level below that, where the list of lists of
410
points is. For 3D explicit equations of two variables, the closed
411
boolean for this level is False and the closed boolean for each sublist
412
is False as well. For 3D parameterized curves of one variable, the
413
closed boolean for this level is defined by the user from OpenAxiom ,
414
(which defaults to False) and the closed boolean for each sublist is True.
415
*/
416
417
viewPoints *
418
make3DComponents (void)
419
{
420
viewPoints *graphData;
421
422
readComponentsFromViewman();
423
424
/* The initial boundaries for the clipping region are set to those
425
of the boundaries of the data region. */
426
viewData.clipXmin = viewData.xmin; viewData.clipXmax = viewData.xmax;
427
viewData.clipYmin = viewData.ymin; viewData.clipYmax = viewData.ymax;
428
viewData.clipZmin = viewData.zmin; viewData.clipZmax = viewData.zmax;
429
430
/* normalize the data coordinates */
431
if (viewData.scaleDown) scaleComponents();
432
viewData.numPolygons = 0;
433
/* initially the list of polygons is empty */
434
viewData.polygons = NIL(poly);
435
/* create the polygons; (sets viewData.polygons and viewData.numPolygons) */
436
triangulate();
437
/* calculate the plane equations for all the polygons */
438
calcNormData();
439
440
graphData = makeViewport();
441
442
imageX = XCreateImage(/* display */ dsply,
443
/* visual */ DefaultVisual(dsply,scrn),
444
/* depth */ DefaultDepth(dsply,scrn),
445
/* format */ ZPixmap,
446
/* offset */ 0,
447
/* data */ NULL,
448
/* width */ vwInfo.width,
449
/* height */ 1,
450
/* bitmap_pad */ 32,
451
/* bytes_per_line */ 0);
452
imageX->data = NIL(char);
453
454
/* windowing displaying */
455
writeTitle();
456
postMakeViewport();
457
drawViewport(Xoption);
458
firstTime = yes;
459
XMapWindow(dsply, graphData->viewWindow);
460
XMapWindow(dsply, graphData->titleWindow);
461
XFlush(dsply);
462
463
return(graphData);
464
465
} /* make3DComponents */
466
467
468
469
470
471
void
472
draw3DComponents (int dFlag)
473
{
474
475
int i, j, k, hue, x1, y1, x2, y2;
476
LLPoint *anLLPoint;
477
LPoint *anLPoint;
478
int *anIndex;
479
int componentType; /* what the component is to be interpreted as */
480
int clip_a,clip_i; /* for use in wire mesh mode clipping */
481
XEvent peekEvent;
482
viewTriple *aLPt;
483
XPoint line[2];
484
RGB col_rgb;
485
486
calcEyePoint();
487
while ((XPending(dsply) > 0) && (scanline > 0))
488
XNextEvent(dsply,&peekEvent);
489
switch (viewData.style) {
490
491
case transparent:
492
GSetLineAttributes(componentGC,0,LineSolid,CapButt,JoinMiter,dFlag);
493
if (dFlag==Xoption) {
494
if (mono || viewport->monoOn)
495
GSetForeground(componentGC, (float)foregroundColor, dFlag);
496
else
497
GSetForeground(componentGC, (float) meshOutline, dFlag);
498
} else {
499
GSetForeground(componentGC, psBlack, dFlag);
500
}
501
/* no need to check "keep drawing" for ps */
502
if (dFlag == Xoption) drawMore = keepDrawingViewport();
503
504
/*
505
This is where we interpret the list of lists of lists of points struct.
506
We want to extract the following forms of data:
507
- individual points (drawn as filled points)
508
- lines (space curves)
509
- defined polygon primitives
510
- surfaces
511
the last one is the one that will replace the function of 2 variables,
512
tubes as well as 3D parameterized functions of 2 variables.
513
Since there could be many other ways of constructing L L L Pts - much
514
more than could be usefully interpreted - any other formats are
515
currently not allowed. When they are, this comment should be updated
516
appropriately.
517
518
************************************************************************
519
520
Traverse each component.
521
We decide here, before we begin traversing the
522
component what we want to interpret it as.
523
Here's the convention used to figure that out:
524
- points: #anLLPoint->numOfLists was 1
525
#anLPoint->numOfPoints is 1
526
- lines: #anLLPoint->numOfLists was 1
527
#anLPoint->numOfPoints > 1
528
- polygons: #anLLPoint->numOfLists was 2
529
#anLPoint->numOfPoints is 1
530
- surface: #anLLPoint->numOfLists was some m>1
531
#anLPoint->numOfPoints all point lists are the same.
532
533
*/
534
535
anLLPoint = viewData.lllp.llp;
536
for (i=0; i<viewData.lllp.numOfComponents; i++,anLLPoint++) {
537
/* initially, component type is unknown */
538
componentType = stillDontKnow;
539
if (anLLPoint->numOfLists == 1) {
540
if (anLLPoint->lp->numOfPoints == 1) componentType = pointComponent;
541
else componentType = lineComponent;
542
} else if (anLLPoint->numOfLists == 2) {
543
if ((anLLPoint->lp->numOfPoints == 1) &&
544
((anLLPoint->lp+1)->numOfPoints > 2))
545
componentType = polygonComponent;
546
}
547
/* Check for corrupt data and NaN data is made in OpenAxiom . */
548
if (componentType == stillDontKnow)
549
componentType = surfaceComponent;
550
551
anLPoint = anLLPoint->lp;
552
553
switch (componentType) {
554
555
case pointComponent:
556
/* anLLPoint->numOfLists == anLLPoint->lp->numOfPoints == 1 here */
557
aLPt = refPt3D(viewData,*(anLPoint->indices));
558
project(aLPt,quadMesh,0);
559
if (dFlag==Xoption) {
560
if (mono || viewport->monoOn)
561
GSetForeground(componentGC, (float)foregroundColor, dFlag);
562
else {
563
hue = hueValue(aLPt->c);
564
GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
565
}
566
} else GSetForeground(componentGC, psBlack, dFlag);
567
GFillArc(componentGC,viewport->viewWindow,quadMesh->x,quadMesh->y,
568
viewData.pointSize,viewData.pointSize,0,360*64,dFlag);
569
break;
570
571
case lineComponent:
572
/* anLLPoint->numOfLists == 1 here */
573
anIndex = anLPoint->indices;
574
aLPt = refPt3D(viewData,*anIndex);
575
project(aLPt,quadMesh,0);
576
x1 = quadMesh[0].x; y1 = quadMesh[0].y; anIndex++;
577
for (k=1; k<anLPoint->numOfPoints; k++,anIndex++) {
578
aLPt = refPt3D(viewData,*anIndex);
579
project(aLPt,quadMesh,k);
580
x2 = quadMesh[k].x; y2 = quadMesh[k].y;
581
if (dFlag==Xoption) {
582
if (mono || viewport->monoOn)
583
GSetForeground(componentGC, (float)foregroundColor, dFlag);
584
else {
585
hue = hueValue(aLPt->c);
586
GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
587
}
588
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
589
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
590
} else {
591
if (dFlag==PSoption && !mono && !viewport->monoOn) {
592
hue = getHue(aLPt->c);
593
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
594
line[0].x = x1; line[0].y = y1;
595
line[1].x = x2; line[1].y = y2;
596
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
597
} else {
598
if (foregroundColor == white)
599
GSetForeground(componentGC, 0.0, dFlag);
600
else
601
GSetForeground(componentGC, psBlack, dFlag);
602
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
603
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
604
}
605
}
606
x1 = x2; y1 = y2;
607
} /* for points in LPoints (k) */
608
if (anLPoint->prop.closed) {
609
project(refPt3D(viewData,*(anLPoint->indices)),quadMesh,
610
anLPoint->numOfPoints);
611
x2 = quadMesh[anLPoint->numOfPoints].x;
612
y2 = quadMesh[anLPoint->numOfPoints].y;
613
if (dFlag==Xoption) {
614
if (mono || viewport->monoOn)
615
GSetForeground(componentGC, (float)foregroundColor, dFlag);
616
else {
617
hue = hueValue(aLPt->c);
618
GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
619
}
620
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
621
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
622
}
623
else {
624
if (dFlag==PSoption && !mono && !viewport->monoOn) {
625
hue = getHue(aLPt->c);
626
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
627
line[0].x = x1; line[0].y = y1;
628
line[1].x = x2; line[1].y = y2;
629
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
630
}
631
else {
632
if (foregroundColor == white)
633
GSetForeground(componentGC, 0.0, dFlag);
634
else
635
GSetForeground(componentGC, psBlack, dFlag);
636
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
637
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
638
}
639
}
640
}
641
break;
642
643
case polygonComponent:
644
/* first pt of polygon is a single list */
645
project(refPt3D(viewData,*(anLPoint->indices)),quadMesh,0);
646
/* remaining points in the 2nd list (always of size 2 or greater) */
647
x1 = quadMesh[0].x; y1 = quadMesh[0].y;
648
anLPoint = anLLPoint->lp + 1;
649
anIndex = anLPoint->indices;
650
for (k=1; k<=anLPoint->numOfPoints; k++,anIndex++) {
651
aLPt = refPt3D(viewData,*anIndex);
652
project(aLPt,quadMesh,k);
653
x2 = quadMesh[k].x; y2 = quadMesh[k].y;
654
if (dFlag==Xoption) {
655
if (mono || viewport->monoOn)
656
GSetForeground(componentGC, (float)foregroundColor, dFlag);
657
else {
658
hue = hueValue(aLPt->c);
659
GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
660
}
661
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
662
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
663
}
664
else {
665
if (dFlag==PSoption && !mono && !viewport->monoOn) {
666
hue = getHue(aLPt->c);
667
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
668
line[0].x = x1; line[0].y = y1;
669
line[1].x = x2; line[1].y = y2;
670
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
671
}
672
else {
673
if (foregroundColor == white)
674
GSetForeground(componentGC, 0.0, dFlag);
675
else
676
GSetForeground(componentGC, psBlack, dFlag);
677
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
678
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
679
}
680
}
681
x1 = x2; y1 = y2;
682
} /* for points in LPoints (k) */
683
project(refPt3D(viewData,*(anLLPoint->lp->indices)),quadMesh,k);
684
x2 = quadMesh[k].x; y2 = quadMesh[k].y;
685
if (dFlag==Xoption) {
686
if (mono || viewport->monoOn)
687
GSetForeground(componentGC, (float)foregroundColor, dFlag);
688
else {
689
hue = hueValue(refPt3D(viewData,*anIndex)->c);
690
GSetForeground(componentGC, (float)XSolidColor(hue,2), dFlag);
691
}
692
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
693
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
694
} else {
695
if (dFlag==PSoption && !mono && !viewport->monoOn) {
696
hue = getHue(refPt3D(viewData,*anIndex)->c);
697
col_rgb = hlsTOrgb((float)hue,0.5,0.8);
698
line[0].x = x1; line[0].y = y1;
699
line[1].x = x2; line[1].y = y2;
700
PSDrawColor(col_rgb.r,col_rgb.g,col_rgb.b,line,2);
701
}
702
else {
703
if (foregroundColor == white)
704
GSetForeground(componentGC, 0.0, dFlag);
705
else
706
GSetForeground(componentGC, psBlack, dFlag);
707
if (!eqNANQ(x1) && !eqNANQ(y1) && !eqNANQ(x2) && !eqNANQ(y2))
708
GDrawLine(componentGC,viewport->viewWindow,x1,y1,x2,y2,dFlag);
709
}
710
}
711
/* close a polygon */
712
break;
713
714
case surfaceComponent:
715
if (dFlag==Xoption) {
716
if (mono || viewport->monoOn)
717
GSetForeground(componentGC, (float)foregroundColor, dFlag);
718
else
719
GSetForeground(componentGC, (float) meshOutline, dFlag);
720
}
721
else {
722
GSetForeground(componentGC, psBlack, dFlag);
723
}
724
725
/* traverse down one direction first (all points
726
in a list at a time) */
727
for (j=0; drawMore && j<anLLPoint->numOfLists; j++,anLPoint++) {
728
anIndex = anLPoint->indices;
729
clip_a = 0;
730
for (k=0, clip_i=0;
731
drawMore && k<anLPoint->numOfPoints;
732
k++, anIndex++, clip_i++) {
733
aLPt = refPt3D(viewData,*anIndex);
734
project(aLPt,quadMesh,k);
735
736
if (behindClipPlane(aLPt->pz) ||
737
(viewData.clipStuff &&
738
outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
739
if (clip_i - clip_a > 1) {
740
GDrawLines(componentGC,viewport->viewWindow,(quadMesh+clip_a),
741
clip_i-clip_a, CoordModeOrigin, dFlag );
742
}
743
clip_a = clip_i + 1;
744
}
745
746
drawMore = keepDrawingViewport();
747
} /* for points in LPoints (k) */
748
if (drawMore) {
749
/* if drawMore is true, then the above loop terminated with
750
clip_i incremented properly */
751
if (anLPoint->prop.closed) {
752
/* If closed, then do the first point again - no need to project
753
just copy over from the first one */
754
aLPt = refPt3D(viewData,*(anLPoint->indices));
755
project(aLPt,quadMesh, anLPoint->numOfPoints);
756
if (behindClipPlane(aLPt->pz) ||
757
(viewData.clipStuff &&
758
outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
759
if (clip_i - clip_a > 1) {
760
GDrawLines(componentGC, viewport->viewWindow,
761
(quadMesh+clip_a), clip_i-clip_a,
762
CoordModeOrigin, dFlag);
763
}
764
clip_a = clip_i + 1;
765
}
766
clip_i++;
767
} /* closed */
768
if (clip_i - clip_a > 1) {
769
GDrawLines(componentGC, viewport->viewWindow, (quadMesh+clip_a),
770
clip_i-clip_a, CoordModeOrigin, dFlag);
771
}
772
} /* drawMore */
773
} /* for LPoints in LLPoints (j) */
774
775
/* now traverse down the list in the other direction
776
(one point from each list at a time) */
777
for (j=0; drawMore && j<anLLPoint->lp->numOfPoints; j++) {
778
clip_a = 0;
779
for (k=0, clip_i=0;
780
drawMore && k<anLLPoint->numOfLists;
781
k++, clip_i++) {
782
aLPt = refPt3D(viewData,*((anLLPoint->lp + k)->indices + j));
783
project(aLPt, quadMesh,k);
784
785
if (behindClipPlane(aLPt->pz) ||
786
(viewData.clipStuff &&
787
outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
788
if (clip_i - clip_a > 1) {
789
GDrawLines(componentGC,viewport->viewWindow,quadMesh+clip_a,
790
clip_i-clip_a, CoordModeOrigin, dFlag );
791
}
792
clip_a = clip_i + 1;
793
}
794
drawMore = keepDrawingViewport();
795
} /* for points in LPoints (k) */
796
797
if (drawMore) {
798
/* if drawMore is true, then the above loop terminated with
799
clip_i incremented properly */
800
if (anLLPoint->prop.closed) {
801
/* if closed, do the first point again - no need to project
802
just copy over from the first one */
803
aLPt = refPt3D(viewData,*((anLLPoint->lp + 0)->indices + j));
804
project(aLPt, quadMesh, anLLPoint->numOfLists);
805
if (behindClipPlane(aLPt->pz) ||
806
(viewData.clipStuff &&
807
outsideClippedBoundary(aLPt->x, aLPt->y, aLPt->z))) {
808
if (clip_i - clip_a > 1) {
809
GDrawLines(componentGC, viewport->viewWindow,
810
quadMesh + clip_a, clip_i - clip_a,
811
CoordModeOrigin, dFlag);
812
}
813
clip_a = clip_i + 1;
814
}
815
clip_i++;
816
} /* closed */
817
if (clip_i - clip_a > 1) {
818
GDrawLines(componentGC, viewport->viewWindow, quadMesh+clip_a,
819
clip_i-clip_a, CoordModeOrigin, dFlag);
820
}
821
} /* drawMore */
822
} /* for a point in each LPoint (j) */
823
break;
824
} /* switch componentType */
825
} /* for LLPoints in LLLPoints (i) */
826
break;
827
828
case opaqueMesh:
829
if (dFlag==Xoption) {
830
GSetForeground(globGC, (float)opaqueForeground, dFlag);
831
GSetForeground(opaqueGC, (float)opaqueOutline, dFlag);
832
}
833
else {
834
GSetForeground(globGC, psBlack, dFlag);
835
GSetForeground(opaqueGC, psBlack, dFlag);
836
}
837
GSetLineAttributes(opaqueGC,0,LineSolid,CapButt,JoinRound,dFlag);
838
drawPolygons(dFlag);
839
break;
840
841
case render:
842
if (viewData.outlineRenderOn) {
843
GSetLineAttributes(renderGC,0,LineSolid,CapButt,JoinRound,dFlag);
844
if (dFlag==Xoption) GSetForeground(renderGC,(float)black, dFlag);
845
else GSetForeground(renderGC,psBlack, dFlag );
846
}
847
drawPolygons(dFlag);
848
break;
849
850
case smooth:
851
drawPhong(dFlag);
852
break;
853
854
} /* switch on style */
855
856
} /* draw3DComponents() */
857
858
859