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 _VIEWPORT3D_C
37
#include "openaxiom-c-macros.h"
38
39
#include <math.h>
40
#include <stdio.h>
41
#include <string.h>
42
#include <unistd.h>
43
#include <stdlib.h>
44
45
#include "spadBitmap.bitmap"
46
#include "spadMask.mask"
47
48
#include "header.h"
49
/*** definition for the axes and labels - this is the minimun that will be
50
drawn on the window - thus allowing the user some idea of the
51
orientation of the coordinate axes when rotating, etc. The
52
drawing of the mesh is aborted when an appropriate X event occurs.
53
The mesh should be scaled to the range of [-100..100] in all
54
directions. axisRange defines the range...change the stuff below
55
if that has changed. ***/
56
#include "static.h"
57
#include "draw.h"
58
#include "volume.h"
59
#include "mode.h"
60
61
#include "util.H1"
62
#include "Gfun.H1"
63
#include "XSpadFill.h"
64
#include "all_3d.H1"
65
66
#define axesOffset 5
67
68
Atom wm_delete_window;
69
70
71
/***************************
72
*** void writeTitle() ***
73
***************************/
74
75
void
76
writeTitle (void)
77
{
78
79
int strlength;
80
XWindowAttributes twInfo;
81
82
XGetWindowAttributes(dsply, viewport->titleWindow, &twInfo);
83
if (mono || viewport->monoOn)
84
GSetForeground(anotherGC, (float)foregroundColor, Xoption);
85
else
86
GSetForeground(anotherGC, (float)titleColor, Xoption);
87
XClearWindow(dsply, viewport->titleWindow);
88
89
strlength = strlen(viewport->title);
90
GDrawImageString(anotherGC, viewport->titleWindow,
91
centerX(anotherGC, viewport->title, strlength,
92
twInfo.width), 15,
93
viewport->title, strlength, Xoption);
94
95
}
96
97
98
/****************************
99
* void drawPreViewport() *
100
* *
101
* draws the axes and boxes *
102
* before the actual stuff. *
103
* all incoming signals *
104
* should be block and no *
105
* check for pending X *
106
* events are made. *
107
* *
108
****************************/
109
110
void
111
drawPreViewport (int dFlag)
112
{
113
114
int i, j, vPx0, vPy0, vPx1, vPy1;
115
/* for drawing the box */
116
float vPz, absTransX, absTransY;
117
XPoint blackbox[3], line[2];
118
RGB axes_rgb, clipbox_rgb, boundbox_rgb;
119
120
axes_rgb.r = 0.8; axes_rgb.g = 0.6; axes_rgb.b = 0.2;
121
clipbox_rgb.r = 0.4; clipbox_rgb.g = 0.5; clipbox_rgb.b = 0.9;
122
boundbox_rgb.r = 0.4; boundbox_rgb.g = 0.7; boundbox_rgb.b = 0.9;
123
124
XGetWindowAttributes(dsply, viewport->viewWindow, &vwInfo);
125
graphWindowAttrib = vwInfo;
126
127
/* Calculate various factors for use in projection */
128
/* Scale so that plot the scaling between the axes remains constant
129
and fits within the smaller of the two dimensions. */
130
131
xCenter = vwInfo.width / 2;
132
yCenter = vwInfo.height / 2;
133
134
if (vwInfo.height <= vwInfo.width) {
135
viewScale = viewport->scale * vwInfo.height / viewHeight;
136
}
137
else {
138
viewScale = viewport->scale * vwInfo.width / viewWidth;
139
}
140
141
/* Draw the projected image */
142
/** draw the axes without heeding to X interrupts, first **/
143
144
if (dFlag == Xoption) /* do this for X option only */
145
XClearWindow(dsply, viewport->viewWindow);
146
147
sinTheta = sin(-viewport->axestheta);
148
cosTheta = cos(-viewport->axestheta);
149
sinPhi = sin(viewport->axesphi);
150
cosPhi = cos(viewport->axesphi);
151
152
/* Create transformation matrices */
153
ROTATE(R); /* angles theta and phi are global */
154
SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
155
TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
156
157
/**** Pre Draw Routine ****/
158
159
if ((dFlag == PSoption) && (foregroundColor == white)) {
160
GSetForeground(globGC,(float)backgroundColor,dFlag);
161
blackbox[0].x = vwInfo.width; blackbox[0].y = vwInfo.height;
162
blackbox[1].x = 0; blackbox[1].y = 0;
163
blackbox[2].x = 0; blackbox[2].y = vwInfo.height;
164
if (viewport->monoOn || mono) {
165
PSFillPolygon(globGC, blackbox, 3);
166
} else {
167
PSColorPolygon(0.0,0.0,0.0,blackbox,4);
168
}
169
blackbox[0].x = vwInfo.width; blackbox[0].y = 0;
170
blackbox[1].x = 0; blackbox[1].y = 0;
171
blackbox[2].x = vwInfo.width; blackbox[2].y = vwInfo.height;
172
if (viewport->monoOn || mono) {
173
PSFillPolygon(globGC, blackbox, 3);
174
} else {
175
PSColorPolygon(0.0,0.0,0.0,blackbox,4);
176
}
177
}
178
179
/* axes */
180
181
for (i=0; i < 3; i++) {
182
projectStuff(axes[i][0],axes[i][1],axes[i][2],&vPx0,&vPy0,&vPz);
183
axesXY[i][0] = vPx0; axesXY[i][1] = vPy0; axesZ[i][0] = vPz;
184
projectStuff(axes[i][3],axes[i][4],axes[i][5],&vPx1,&vPy1,&vPz);
185
axesXY[i][2] = vPx1; axesXY[i][3] = vPy1; axesZ[i][1] = vPz;
186
if (viewport->axesOn) {
187
if (viewport->monoOn || mono) {
188
GSetForeground(globalGC1,(float)foregroundColor,dFlag);
189
GSetForeground(globGC,(float)foregroundColor,dFlag);
190
GDrawLine(globalGC1,viewport->viewWindow,vPx0,vPy0,vPx1,vPy1,dFlag);
191
} else {
192
if (dFlag == PSoption) {
193
GSetForeground(globGC,(float)foregroundColor,dFlag);
194
line[0].x = vPx0; line[0].y = vPy0;
195
line[1].x = vPx1; line[1].y = vPy1;
196
PSDrawColor(axes_rgb.r,axes_rgb.g,axes_rgb.b,line,2);
197
} else {
198
GSetForeground(globalGC1,(float)monoColor(axesColor),dFlag);
199
GSetForeground(globGC,(float)monoColor(labelColor),dFlag);
200
GDrawLine(globalGC1,viewport->viewWindow,vPx0,vPy0,vPx1,vPy1,dFlag);
201
}
202
}
203
if (i == 0) {
204
if (axesXY[0][2] < axesXY[0][0]) vPx1 -= axesOffset;
205
else vPx1 += axesOffset;
206
if (axesXY[0][3] < axesXY[0][1]) vPy1 -= axesOffset;
207
else vPy1 += axesOffset;
208
if (!viewport->yzOn)
209
GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"X",1,dFlag);
210
} else {
211
if (i == 1) {
212
if (axesXY[1][2] < axesXY[1][0]) vPx1 -= axesOffset;
213
else vPx1 += axesOffset;
214
if (axesXY[1][3] < axesXY[1][1]) vPy1 -= axesOffset;
215
else vPy1 += axesOffset;
216
if (!viewport->xzOn)
217
GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"Y",1,dFlag);
218
} else {
219
if (axesXY[2][2] < axesXY[2][0]) vPx1 -= axesOffset;
220
else vPx1 += axesOffset;
221
if (axesXY[2][3] < axesXY[2][1]) vPy1 -= axesOffset;
222
else vPy1 += axesOffset;
223
if (!viewport->xyOn)
224
GDrawString(globGC,viewport->viewWindow,vPx1,vPy1,"Z",1,dFlag);
225
}
226
}
227
GSetForeground(globalGC1,(float)monoColor(buttonColor),dFlag);
228
GSetForeground(globGC,(float)monoColor(buttonColor),dFlag);
229
} /* if viewport->axesOn */
230
}
231
232
viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
233
viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
234
viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
235
236
absTransX = absolute(viewport->transX);
237
absTransY = absolute(viewport->transY);
238
if ((absTransX > 0.5) || (absTransY > 0.5)) {
239
if (absTransX > absTransY)
240
reScale = 50.0 * absTransX / viewData.scaleToView;
241
else
242
reScale = 50.0 * absTransY / viewData.scaleToView;
243
if (reScale < 100.0) reScale = 100.0;
244
} else {
245
reScale = 100.0;
246
}
247
248
sinTheta = sin(-viewport->thetaObj);
249
cosTheta = cos(-viewport->thetaObj);
250
sinPhi = sin(viewport->phiObj);
251
cosPhi = cos(viewport->phiObj);
252
ROTATE1(R1);
253
254
if (viewport->originFlag) viewport->originFlag = no;
255
sinTheta = sin(-viewport->axestheta);
256
cosTheta = cos(-viewport->axestheta);
257
sinPhi = sin(viewport->axesphi);
258
cosPhi = cos(viewport->axesphi);
259
ROTATE(R);
260
261
/* region box */
262
if (viewData.clipbox) {
263
clipCorners[0].x = viewData.clipXmin;
264
clipCorners[0].y = viewData.clipYmin;
265
clipCorners[0].z = viewData.clipZmin;
266
clipCorners[1].x = viewData.clipXmax;
267
clipCorners[1].y = viewData.clipYmin;
268
clipCorners[1].z = viewData.clipZmin;
269
clipCorners[2].x = viewData.clipXmax;
270
clipCorners[2].y = viewData.clipYmin;
271
clipCorners[2].z = viewData.clipZmax;
272
clipCorners[3].x = viewData.clipXmin;
273
clipCorners[3].y = viewData.clipYmin;
274
clipCorners[3].z = viewData.clipZmax;
275
clipCorners[4].x = viewData.clipXmin;
276
clipCorners[4].y = viewData.clipYmax;
277
clipCorners[4].z = viewData.clipZmin;
278
clipCorners[5].x = viewData.clipXmax;
279
clipCorners[5].y = viewData.clipYmax;
280
clipCorners[5].z = viewData.clipZmin;
281
clipCorners[6].x = viewData.clipXmax;
282
clipCorners[6].y = viewData.clipYmax;
283
clipCorners[6].z = viewData.clipZmax;
284
clipCorners[7].x = viewData.clipXmin;
285
clipCorners[7].y = viewData.clipYmax;
286
clipCorners[7].z = viewData.clipZmax;
287
288
GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
289
290
/* project the 8 corners of the box */
291
for (i=0;i<8;i++) projectAPoint(&(clipCorners[i]));
292
293
for (i=0;i<6;i++) {
294
clipBox[i].inside = ((clipBox[i].pointsPtr[2]->px -
295
clipBox[i].pointsPtr[1]->px) *
296
(clipBox[i].pointsPtr[1]->py -
297
clipBox[i].pointsPtr[0]->py) -
298
(clipBox[i].pointsPtr[2]->py -
299
clipBox[i].pointsPtr[1]->py) *
300
(clipBox[i].pointsPtr[1]->px -
301
clipBox[i].pointsPtr[0]->px)) < 0;
302
if (clipBox[i].inside) {
303
for (j=0; j<3; j++) {
304
quadMesh[j].x = clipBox[i].pointsPtr[j]->px;
305
quadMesh[j].y = clipBox[i].pointsPtr[j]->py;
306
}
307
if (viewport->monoOn || mono) {
308
GSetForeground(trashGC,(float)foregroundColor,dFlag);
309
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
310
CoordModeOrigin, dFlag);
311
} else {
312
if (dFlag == PSoption) {
313
GSetForeground(trashGC,(float)clipBoxInline, dFlag);
314
line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
315
line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
316
PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
317
line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
318
line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
319
PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
320
} else {
321
GSetForeground(trashGC,(float)clipBoxInline, dFlag);
322
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
323
CoordModeOrigin, dFlag);
324
}
325
}
326
}
327
}
328
} /* if viewData.clipbox */
329
330
/* VOLUME panel stuff */
331
if ((doingPanel == VOLUMEpanel) || viewData.box) {
332
333
GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
334
335
for (i=0;i<8;i++) {
336
/* project the 8 corners of the box */
337
projectAPoint(&(corners[i]));
338
if (i) {
339
if (corners[i].pz > pzMax) pzMax = corners[i].pz;
340
else if (corners[i].pz < pzMin) pzMin = corners[i].pz;
341
} else
342
pzMax = pzMin = corners[i].pz;
343
}
344
345
for (i=0;i<6;i++) {
346
/* Process the 6 sides of the boxes.
347
Here, we calculate, for each side (defined by two segments)
348
whether it is facing towards or away from the viewer. if
349
facing, away, we draw them first. later we draw the ones
350
facing the viewer. (this is a sort of backface removal
351
scheme. */
352
/* We define the normal vector for the box as vA X vB where
353
vA=p2-p0 and vB=p1-p0. All we really care about, though,
354
is what sign the normal is (whether it is towards or away
355
from the viewer - so we just take the triple product of
356
it against the eye vector, which is, conveniently enough,
357
simply [0 0 1]. Hence, only the Z component of the
358
cross product is calculated. (Actually, we are using the
359
projected normal - that's how we are able to use the
360
trick of just taking the Z component. */
361
box[i].inside = ((box[i].pointsPtr[2]->px -
362
box[i].pointsPtr[0]->px) * /* Ax * */
363
(box[i].pointsPtr[1]->py -
364
box[i].pointsPtr[0]->py) - /* By - */
365
(box[i].pointsPtr[2]->py -
366
box[i].pointsPtr[0]->py) * /* Ay * */
367
(box[i].pointsPtr[1]->px -
368
box[i].pointsPtr[0]->px)) /* Bx */
369
< 0;
370
if (box[i].inside) {
371
for (j=0; j<3; j++) {
372
quadMesh[j].x = box[i].pointsPtr[j]->px;
373
quadMesh[j].y = box[i].pointsPtr[j]->py;
374
}
375
if (viewport->monoOn || mono) {
376
GSetForeground(trashGC,(float)foregroundColor,dFlag);
377
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
378
CoordModeOrigin, dFlag);
379
} else {
380
if (dFlag == PSoption) {
381
GSetForeground(trashGC,(float)boxInline, dFlag );
382
line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
383
line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
384
PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
385
line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
386
line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
387
PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
388
} else {
389
GSetForeground(trashGC,(float)boxInline, dFlag );
390
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
391
CoordModeOrigin, dFlag);
392
}
393
}
394
}
395
}
396
} /* if viewData.box */
397
398
/* Write out view data */
399
if (dFlag == Xoption) { /* do this only for X option */
400
writeControlMessage();
401
XFlush(dsply);
402
}
403
}
404
405
406
/********************************/
407
/*** void drawTheViewport() ***/
408
/********************************/
409
410
void
411
drawTheViewport (int dFlag)
412
{
413
414
int i,j;
415
XPoint line[2];
416
RGB clipbox_rgb, boundbox_rgb;
417
418
clipbox_rgb.r = 0.4; clipbox_rgb.g = 0.5; clipbox_rgb.b = 0.9;
419
boundbox_rgb.r = 0.4; boundbox_rgb.g = 0.7; boundbox_rgb.b = 0.9;
420
421
/**** Draw Routine ****/
422
423
if (viewport->allowDraw && (doingPanel != VOLUMEpanel)) {
424
/* Do not draw the mesh stuff if we're in the process of changing
425
the viewing volume; we just want to see the volume */
426
427
/* drawMore allows the drawing to continue if no relevant XEvent occurs */
428
drawMore = yes;
429
drawMore = keepDrawingViewport();
430
draw3DComponents(dFlag);
431
432
} /*if viewport->allowDraw */
433
434
/**** Post Draw Routine ****/
435
if (viewData.clipbox) { /* draw the front 3 lines of region box */
436
GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
437
for (i=0; i<6; i++) {
438
if (!(clipBox[i].inside)) {
439
for (j=0; j<4; j++) {
440
quadMesh[j].x = clipBox[i].pointsPtr[j]->px;
441
quadMesh[j].y = clipBox[i].pointsPtr[j]->py;
442
}
443
if (viewport->monoOn || mono) {
444
GSetForeground(trashGC,(float)foregroundColor,dFlag);
445
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
446
CoordModeOrigin, dFlag);
447
} else {
448
if (dFlag == PSoption) {
449
GSetForeground(trashGC,(float)boxInline, dFlag );
450
line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
451
line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
452
PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
453
line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
454
line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
455
PSDrawColor(clipbox_rgb.r,clipbox_rgb.g,clipbox_rgb.b,line,2);
456
} else {
457
GSetForeground(trashGC,(float)boxInline, dFlag );
458
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
459
CoordModeOrigin, dFlag);
460
}
461
}
462
}
463
}
464
}
465
466
if ((doingPanel==VOLUMEpanel) || viewData.box) {
467
GSetLineAttributes(trashGC,0,LineSolid,CapButt,JoinMiter,dFlag);
468
for (i=0; i<6; i++) {
469
if (!(box[i].inside)) {
470
for (j=0; j<4; j++) {
471
quadMesh[j].x = box[i].pointsPtr[j]->px;
472
quadMesh[j].y = box[i].pointsPtr[j]->py;
473
}
474
if (viewport->monoOn || mono) {
475
GSetForeground(trashGC,(float)foregroundColor,dFlag);
476
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
477
CoordModeOrigin, dFlag);
478
} else {
479
if (dFlag == PSoption) {
480
GSetForeground(trashGC,(float)boxInline, dFlag );
481
line[0].x = quadMesh[0].x; line[0].y = quadMesh[0].y;
482
line[1].x = quadMesh[1].x; line[1].y = quadMesh[1].y;
483
PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
484
line[0].x = quadMesh[1].x; line[0].y = quadMesh[1].y;
485
line[1].x = quadMesh[2].x; line[1].y = quadMesh[2].y;
486
PSDrawColor(boundbox_rgb.r,boundbox_rgb.g,boundbox_rgb.b,line,2);
487
} else {
488
GSetForeground(trashGC,(float)boxInline, dFlag );
489
GDrawLines(trashGC, viewport->viewWindow, quadMesh, 3,
490
CoordModeOrigin, dFlag);
491
}
492
}
493
}
494
}
495
}
496
497
if (dFlag == Xoption) /* do this for X option only */
498
XFlush(dsply);
499
500
if (smoothError) {
501
strcpy(control->message,"Cannot alloc more smooth shades.");
502
writeControlMessage();
503
smoothError = no;
504
}
505
506
} /* drawTheViewport */
507
508
/************************************
509
*** viewPoints *makeViewport() ***
510
************************************/
511
512
viewPoints *
513
makeViewport (void)
514
{
515
516
Pixmap spadbits,spadmask;
517
XSetWindowAttributes viewAttrib;
518
XSizeHints titleSizeHints;
519
Window viewTitleWindow, viewGraphWindow;
520
XColor foreColor, backColor;
521
522
/**** create a viewport ****/
523
524
if (!(viewport = (viewPoints *)saymem("viewport3D.c",
525
1,sizeof(viewPoints)))) {
526
fprintf(stderr,"Ran out of memory trying to create a viewport.\n");
527
exitWithAck(RootWindow(dsply,scrn),Window,-1);
528
}
529
/* Definition of the 4x4 identity matrix. */
530
I[0][0] = 1.0; I[0][1] = 0.0; I[0][2] = 0.0; I[0][3] = 0.0;
531
I[1][0] = 0.0; I[1][1] = 1.0; I[1][2] = 0.0; I[1][3] = 0.0;
532
I[2][0] = 0.0; I[2][1] = 0.0; I[2][2] = 1.0; I[2][3] = 0.0;
533
I[3][0] = 0.0; I[3][1] = 0.0; I[3][2] = 0.0; I[3][3] = 1.0;
534
535
viewport->viewportKey = viewportKeyNum++;
536
viewport->nextViewport = 0;
537
viewport->prevViewport = 0;
538
viewport->deltaX = viewport->deltaX0 = viewData.deltaX;
539
viewport->deltaY = viewport->deltaY0 = viewData.deltaY;
540
viewport->deltaZ = viewport->deltaZ0 = viewData.deltaZ;
541
viewport->scale = viewport->scale0 = viewData.scale;
542
viewport->scaleX = viewData.scaleX;
543
viewport->scaleY = viewData.scaleY;
544
viewport->scaleZ = viewData.scaleZ;
545
viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
546
viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
547
viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
548
549
viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
550
viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
551
viewport->thetaObj = 0.0;
552
viewport->phiObj = 0.0;
553
554
strcpy(viewport->title,viewData.title);
555
556
viewport->axesOn = yes;
557
viewport->regionOn = no;
558
viewport->monoOn = no;
559
viewport->zoomXOn = yes;
560
viewport->zoomYOn = yes;
561
viewport->zoomZOn = yes;
562
563
viewport->originrOn = yes;
564
viewport->objectrOn = no;
565
viewport->originFlag = no;
566
567
viewport->xyOn = no;
568
viewport->xzOn = no;
569
viewport->yzOn = no;
570
571
viewport->closing = no;
572
viewport->allowDraw = yes; /*if no, just draw axes the first time */
573
viewport->needNorm = yes;
574
575
viewport->lightVector[0] = -0.5;
576
viewport->lightVector[1] = 0.5;
577
viewport->lightVector[2] = 0.5;
578
viewport->translucency = viewData.translucency;
579
580
viewport->hueOffset = viewData.hueOff;
581
viewport->numberOfHues = viewData.numOfHues;
582
viewport->hueTop = viewData.hueOff + viewData.numOfHues;
583
if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;
584
viewport->diagonals = viewData.diagonals;
585
586
/* make theta in [0..2pi) and phi in (-pi..pi] */
587
while (viewport->theta >= two_pi) {
588
viewport->theta -= two_pi;
589
}
590
while (viewport->theta < 0.0) {
591
viewport->theta += two_pi;
592
}
593
while (viewport->phi > pi) {
594
viewport->phi -= two_pi;
595
}
596
while (viewport->phi <= -pi) {
597
viewport->phi += two_pi;
598
}
599
600
while (viewport->axestheta >= two_pi) {
601
viewport->axestheta -= two_pi;
602
}
603
while (viewport->axestheta < 0.0) {
604
viewport->axestheta += two_pi;
605
}
606
while (viewport->axesphi > pi) {
607
viewport->axesphi -= two_pi;
608
}
609
while (viewport->axesphi <= -pi) {
610
viewport->axesphi += two_pi;
611
}
612
613
/* Initialize the rotation matrix about the origin. */
614
sinTheta = sin(-viewport->theta);
615
cosTheta = cos(-viewport->theta);
616
sinPhi = sin(viewport->phi);
617
cosPhi = cos(viewport->phi);
618
ROTATE(R); /* angles theta and phi are global */
619
620
/* Initialize the rotation matrix about the object's center of volume. */
621
sinTheta = sin(-viewport->thetaObj);
622
cosTheta = cos(-viewport->thetaObj);
623
sinPhi = sin(viewport->phiObj);
624
cosPhi = cos(viewport->phiObj);
625
ROTATE1(R1); /* angles theta and phi are global */
626
627
628
/* Initialize the non-uniform scaling matrix. */
629
SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
630
/* Initialize the translation matrix. */
631
TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
632
/**** make the windows for the viewport ****/
633
spadbits = XCreateBitmapFromData(dsply,rtWindow,
634
(const char*) spadBitmap_bits,
635
spadBitmap_width,spadBitmap_height);
636
spadmask = XCreateBitmapFromData(dsply,rtWindow,
637
(const char*) spadMask_bits,
638
spadMask_width,spadMask_height);
639
viewAttrib.background_pixel = backgroundColor;
640
viewAttrib.border_pixel = foregroundColor;
641
642
viewAttrib.override_redirect = overrideManager;
643
644
viewAttrib.colormap = colorMap;
645
foreColor.pixel = foregroundColor;
646
backColor.pixel = backgroundColor;
647
/*
648
foreColor.pixel = viewCursorForeground;
649
backColor.pixel = viewCursorBackground;
650
*/
651
XQueryColor(dsply,colorMap,&foreColor);
652
XQueryColor(dsply,colorMap,&backColor);
653
viewAttrib.cursor = XCreatePixmapCursor(dsply,spadbits,spadmask,
654
&foreColor,&backColor,spadBitmap_x_hot,spadBitmap_y_hot);
655
viewAttrib.event_mask = titleMASK;
656
if (viewData.vW) {
657
titleSizeHints.flags = PPosition | PSize;
658
titleSizeHints.x = viewData.vX;
659
titleSizeHints.y = viewData.vY;
660
titleSizeHints.width = viewData.vW;
661
titleSizeHints.height = viewData.vH;
662
} else { /* ain't gonna allow this for now... */
663
titleSizeHints.flags = PSize;
664
titleSizeHints.width = viewWidth;
665
titleSizeHints.height = viewHeight;
666
}
667
668
viewTitleWindow = XCreateWindow(dsply /* display */,
669
rtWindow, /* parent */
670
viewData.vX, /* x */
671
viewData.vY, /* y */
672
viewData.vW, /* width */
673
viewData.vH, /* height */
674
/* viewBorderWidth+3*/ 0, /* border width */
675
CopyFromParent, /* depth */
676
InputOutput, /* class */
677
CopyFromParent, /* visual */
678
viewportTitleCreateMASK,/* valuemask */
679
&viewAttrib /* attributes */);
680
681
wm_delete_window = XInternAtom(dsply, "WM_DELETE_WINDOW", False);
682
(void) XSetWMProtocols(dsply, viewTitleWindow, &wm_delete_window, 1);
683
684
XSetNormalHints(dsply,viewTitleWindow,&titleSizeHints);
685
if (strlen(viewport->title) < 30)
686
XSetStandardProperties(dsply,viewTitleWindow,"OpenAxiom 3D",viewport->title,
687
None,NULL,0,&titleSizeHints);
688
else
689
XSetStandardProperties(dsply,viewTitleWindow,"OpenAxiom 3D","3D OpenAxiom Graph",
690
None,NULL,0,&titleSizeHints);
691
viewport->titleWindow = viewTitleWindow;
692
693
viewAttrib.event_mask = viewportMASK;
694
viewSizeHints.flags = PPosition | PSize;
695
viewSizeHints.x = -(viewBorderWidth+3);
696
viewSizeHints.x = 0; /* lose this */
697
viewSizeHints.y = titleHeight;
698
viewSizeHints.width = titleSizeHints.width;
699
viewSizeHints.height = titleSizeHints.height-(titleHeight+appendixHeight);
700
701
viewGraphWindow = XCreateWindow(dsply, /* display */
702
viewTitleWindow, /* parent */
703
viewSizeHints.x, /* x */
704
viewSizeHints.y, /* y */
705
viewSizeHints.width, /* width */
706
viewSizeHints.height, /* height */
707
/* viewBorderWidth+3*/0, /* border width */
708
CopyFromParent, /* depth */
709
InputOutput, /* class */
710
CopyFromParent, /* visual */
711
viewportCreateMASK, /* valuemask */
712
&viewAttrib /* attributes */);
713
XSetNormalHints(dsply,viewGraphWindow,&viewSizeHints);
714
XSetStandardProperties(dsply,viewGraphWindow,"","",None,NULL,0,
715
&viewSizeHints);
716
viewport->viewWindow = viewGraphWindow;
717
graphWindowAttrib.width = viewSizeHints.width;
718
graphWindowAttrib.height = viewSizeHints.height;
719
720
if (viewport->hueOffset != viewport->hueTop) {
721
multiColorFlag = yes;
722
redoColor = no;
723
} else {
724
if (viewport->hueTop < 11)
725
smoothHue = viewport->hueTop*6;
726
else {
727
if (viewport->hueTop > 10 && viewport->hueTop < 16)
728
smoothHue = viewport->hueTop*20 - 140;
729
else smoothHue = viewport->hueTop*12 - 12;
730
}
731
redoColor = yes;
732
}
733
734
/**** Make the control panel for the viewport. ****/
735
736
XSync(dsply,0);
737
738
control = viewport->controlPanel = makeControlPanel();
739
makeLightingPanel();
740
makeVolumePanel();
741
makeSavePanel();
742
makeQuitPanel();
743
744
if ((viewport->haveControl = viewData.showCP))
745
putControlPanelSomewhere(anywhere);
746
747
firstTime = yes;
748
return(viewport);
749
750
} /* makeViewport() */
751
752
753
/*****************************
754
* void postMakeViewport() *
755
* *
756
* post processing when *
757
* creating a viewport. *
758
* 1) assign min,max values *
759
* for the box volume *
760
*****************************/
761
762
void
763
postMakeViewport (void)
764
{
765
766
corners[0].x = viewData.xmin; corners[0].y = viewData.ymin;
767
corners[0].z = viewData.zmin;
768
corners[1].x = viewData.xmax; corners[1].y = viewData.ymin;
769
corners[1].z = viewData.zmin;
770
corners[2].x = viewData.xmax; corners[2].y = viewData.ymin;
771
corners[2].z = viewData.zmax;
772
corners[3].x = viewData.xmin; corners[3].y = viewData.ymin;
773
corners[3].z = viewData.zmax;
774
corners[4].x = viewData.xmin; corners[4].y = viewData.ymax;
775
corners[4].z = viewData.zmin;
776
corners[5].x = viewData.xmax; corners[5].y = viewData.ymax;
777
corners[5].z = viewData.zmin;
778
corners[6].x = viewData.xmax; corners[6].y = viewData.ymax;
779
corners[6].z = viewData.zmax;
780
corners[7].x = viewData.xmin; corners[7].y = viewData.ymax;
781
corners[7].z = viewData.zmax;
782
783
box[2].pointsPtr[0] = &(corners[0]);
784
box[2].pointsPtr[1] = &(corners[1]);
785
box[2].pointsPtr[2] = &(corners[2]);
786
box[2].pointsPtr[3] = &(corners[3]);
787
788
box[3].pointsPtr[0] = &(corners[1]);
789
box[3].pointsPtr[1] = &(corners[5]);
790
box[3].pointsPtr[2] = &(corners[6]);
791
box[3].pointsPtr[3] = &(corners[2]);
792
793
box[0].pointsPtr[0] = &(corners[4]);
794
box[0].pointsPtr[1] = &(corners[7]);
795
box[0].pointsPtr[2] = &(corners[6]);
796
box[0].pointsPtr[3] = &(corners[5]);
797
798
box[1].pointsPtr[0] = &(corners[0]);
799
box[1].pointsPtr[1] = &(corners[3]);
800
box[1].pointsPtr[2] = &(corners[7]);
801
box[1].pointsPtr[3] = &(corners[4]);
802
803
box[5].pointsPtr[0] = &(corners[3]);
804
box[5].pointsPtr[1] = &(corners[2]);
805
box[5].pointsPtr[2] = &(corners[6]);
806
box[5].pointsPtr[3] = &(corners[7]);
807
808
box[4].pointsPtr[0] = &(corners[0]);
809
box[4].pointsPtr[1] = &(corners[4]);
810
box[4].pointsPtr[2] = &(corners[5]);
811
box[4].pointsPtr[3] = &(corners[1]);
812
813
/* clip box */
814
815
clipBox[0].pointsPtr[0] = &(clipCorners[0]);
816
clipBox[0].pointsPtr[1] = &(clipCorners[1]);
817
clipBox[0].pointsPtr[2] = &(clipCorners[2]);
818
clipBox[0].pointsPtr[3] = &(clipCorners[3]);
819
820
clipBox[1].pointsPtr[0] = &(clipCorners[1]);
821
clipBox[1].pointsPtr[1] = &(clipCorners[5]);
822
clipBox[1].pointsPtr[2] = &(clipCorners[6]);
823
clipBox[1].pointsPtr[3] = &(clipCorners[2]);
824
825
clipBox[2].pointsPtr[0] = &(clipCorners[4]);
826
clipBox[2].pointsPtr[1] = &(clipCorners[7]);
827
clipBox[2].pointsPtr[2] = &(clipCorners[6]);
828
clipBox[2].pointsPtr[3] = &(clipCorners[5]);
829
830
clipBox[3].pointsPtr[0] = &(clipCorners[0]);
831
clipBox[3].pointsPtr[1] = &(clipCorners[3]);
832
clipBox[3].pointsPtr[2] = &(clipCorners[7]);
833
clipBox[3].pointsPtr[3] = &(clipCorners[4]);
834
835
clipBox[4].pointsPtr[0] = &(clipCorners[3]);
836
clipBox[4].pointsPtr[1] = &(clipCorners[2]);
837
clipBox[4].pointsPtr[2] = &(clipCorners[6]);
838
clipBox[4].pointsPtr[3] = &(clipCorners[7]);
839
840
clipBox[5].pointsPtr[0] = &(clipCorners[0]);
841
clipBox[5].pointsPtr[1] = &(clipCorners[4]);
842
clipBox[5].pointsPtr[2] = &(clipCorners[5]);
843
clipBox[5].pointsPtr[3] = &(clipCorners[1]);
844
845
846
}
847
848
849
/*****************************************
850
*** int keepDrawingViewport() ***
851
*****************************************/
852
853
854
855
856
int
857
keepDrawingViewport(void)
858
{
859
860
XEvent peekEvent;
861
int retVal;
862
863
if (XPending(dsply)) {
864
XPeekEvent(dsply,&peekEvent);
865
if (((peekEvent.type == Expose) &&
866
((peekEvent.xany).window == viewport->viewWindow)) ||
867
((peekEvent.type == Expose) &&
868
((peekEvent.xany).window == viewport->titleWindow)) ||
869
((peekEvent.type == Expose) &&
870
((peekEvent.xany).window == control->controlWindow))) {
871
retVal = firstTime;
872
} else if ((peekEvent.xbutton.type == ButtonRelease) ||
873
((peekEvent.type == LeaveNotify) && !(followMouse)) ||
874
((peekEvent.type == MotionNotify) && !(followMouse)) ||
875
(peekEvent.type == ResizeRequest)) {
876
XNextEvent(dsply,&peekEvent);
877
followMouse = no;
878
retVal = yes;
879
} else if ((peekEvent.xany).window == (control->buttonQueue[hideControl]).self) {
880
viewport->haveControl = no;
881
XUnmapWindow(dsply,control->controlWindow);
882
retVal = yes;
883
} else {
884
retVal = no;
885
}
886
} else {
887
retVal = !followMouse;
888
}
889
890
if (writeImage) retVal = yes;
891
drawMore = no;
892
return(retVal);
893
894
}
895
896