1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11 #if defined(HAVE_STRING_H)
12 #include <string.h>
13 #endif
14
15 #if defined(HAVE_STRINGS_H)
16 #include <strings.h>
17 #endif
18
19 #include "hwDeclarations.h"
20 #include "hwXfield.h"
21 #include "hwMatrix.h"
22 #include "hwMemory.h"
23 #include "hwPortLayer.h"
24 #include "hwWindow.h"
25 #include "hwObjectHash.h"
26
27 #define String dxString
28 #define Object dxObject
29 #define Angle dxAngle
30 #define Matrix dxMatrix
31 #define Screen dxScreen
32 #define Boolean dxBoolean
33 #include "../libdx/internals.h"
34 #undef String
35 #undef Object
36 #undef Angle
37 #undef Matrix
38 #undef Screen
39 #undef Boolean
40
41 #include "hwDebug.h"
42
43 static Error _gammaCorrectColors(xfieldP xf, double gamma, int isLit);
44
45 #define CAT(x,y) x##y
46
47 #define CHECK_CONST_ARRAY(name) \
48 if(DXQueryConstantArray(xf->CAT(name,_array),NULL,NULL)) \
49 xf->CAT(name,Dep) = dep_field;
50
51 /*
52 * get a component array
53 */
54
55 #define array(array, name, required) { \
56 xf->array = (Array) DXGetComponentValue(f, name); \
57 if (!xf->array) { \
58 if (required) { \
59 DXSetError(ERROR_MISSING_DATA, "#10240", name); \
60 EXIT(("ERROR: missing data")); \
61 return ERROR; \
62 } \
63 EXIT(("OK")); \
64 return OK; \
65 } \
66 else \
67 DXReference((dxObject)xf->array); \
68 }
69
70
71 /*
72 * check the type of a component
73 */
74
75 #define check(comp, name, t, dim) { \
76 if (dim==0 || dim==1) { \
77 if (!DXTypeCheck(xf->CAT(comp,_array), t, CATEGORY_REAL, 0) && \
78 !DXTypeCheck(xf->CAT(comp,_array), t, CATEGORY_REAL, 1, 1)) { \
79 DXSetError(ERROR_DATA_INVALID, "#11829", name); \
80 EXIT(("ERROR: invalid data")); \
81 return ERROR; \
82 } \
83 } else { \
84 if (!DXTypeCheck(xf->CAT(comp,_array), t, CATEGORY_REAL, 1, dim)) \
85 { \
86 DXSetError(ERROR_DATA_INVALID, "#11829", name); \
87 EXIT(("ERROR: invalid data")); \
88 return ERROR; \
89 } \
90 } \
91 }
92
93
94 /*
95 * get the component data and number of items
96 */
97
98 #define get(comp) { \
99 xf->comp = DXCreateArrayHandle(xf->CAT(comp,_array)); \
100 if (!xf->comp) { \
101 EXIT(("returning NULL")); \
102 return ERROR; \
103 } \
104 DXGetArrayInfo(xf->CAT(comp,_array),&xf->CAT(n,comp), NULL,NULL,NULL,NULL); \
105 }
106
107 /*
108 * Get the component data, and check its number of items
109 * against another component. Note - we only consider it a mismatch
110 * if xf->count is non-zero; this for example allows _XOpacities to
111 * work even if we haven't done _XColors (as for example in _Survey).
112 */
113
114 #define compare(comp, name, count) { \
115 int n; \
116 get(comp); \
117 n = xf->CAT(n,comp); \
118 if (n!=count && count!=0) { \
119 DXSetError(ERROR_DATA_INVALID,"#13050", \
120 name, n, count); \
121 EXIT(("ERROR: invalid data")); \
122 return ERROR; \
123 } \
124 }
125
126 /*=====================================================================*\
127 Xfield component functions
128 \*=====================================================================*/
129 extern Error _dxfTriangulateField(Field);
130 extern Error _dxf_XNeighbors(Field f, xfieldT *xf, enum xr required, enum xd xd);
131 extern Error _dxf_linesToPlines (xfieldT *xf);
132 extern Error _dxf_linesToPlines (xfieldT *xf);
133 extern Error _dxf_trisToTmesh (xfieldT *xf, tdmChildGlobalP globals);
134 extern Error _dxf_quadsToQmesh (xfieldT *xf, void *globals);
135
136 /*
137 * box, points, connections
138 */
139
140 static Error
_XBox(Field f,xfieldT * xf,enum xr required)141 _XBox(Field f, xfieldT* xf, enum xr required)
142 {
143 ENTRY(("_XBox(0x%x, 0x%x, %d)", f, xf, required));
144
145 if(DXBoundingBox((dxObject)f,(Point *) xf->box))
146 {
147 float xMin = DXD_MAX_FLOAT, xMax = -DXD_MAX_FLOAT;
148 float yMin = DXD_MAX_FLOAT, yMax = -DXD_MAX_FLOAT;
149 float zMin = DXD_MAX_FLOAT, zMax = -DXD_MAX_FLOAT;
150 int i;
151 Point *p = (Point *)xf->box;
152
153 for (i = 0; i < 8; i++, p++)
154 {
155 if (xMin > p->x) xMin = p->x;
156 if (yMin > p->y) yMin = p->y;
157 if (zMin > p->z) zMin = p->z;
158 if (xMax < p->x) xMax = p->x;
159 if (yMax < p->y) yMax = p->y;
160 if (zMax < p->z) zMax = p->z;
161 }
162
163 p = (Point *)xf->box;
164
165 p->x = xMin; p->y = yMin; p->z = zMin; p++;
166 p->x = xMin; p->y = yMin; p->z = zMax; p++;
167 p->x = xMin; p->y = yMax; p->z = zMin; p++;
168 p->x = xMin; p->y = yMax; p->z = zMax; p++;
169 p->x = xMax; p->y = yMin; p->z = zMin; p++;
170 p->x = xMax; p->y = yMin; p->z = zMax; p++;
171 p->x = xMax; p->y = yMax; p->z = zMin; p++;
172 p->x = xMax; p->y = yMax; p->z = zMax;
173
174 EXIT(("OK"));
175 return OK;
176 } else {
177 EXIT(("ERROR"));
178 return ERROR;
179 }
180 }
181
182 static Error
_XPositions(Field f,xfieldT * xf,enum xr required)183 _XPositions(Field f, xfieldT* xf, enum xr required)
184 {
185 ENTRY(("_XPositions(0x%x, 0x%x, %d)", f, xf, required));
186
187 array(positions_array, POSITIONS, required);
188 get(positions);
189 DXGetArrayInfo(xf->positions_array,NULL,NULL,NULL,NULL,&xf->shape);
190
191 if (DXGetComponentValue(f, INVALID_POSITIONS)) {
192 /* This also creates DXReference() */
193 if((xf->invPositions = DXCreateInvalidComponentHandle((dxObject)f,
194 NULL,
195 POSITIONS))) {
196 } else {
197 EXIT(("ERROR"));
198 return ERROR;
199 }
200 }
201
202 EXIT(("OK"));
203 return OK;
204 }
205
206 static Error
_XPolylines(Field f,xfieldT * xf,enum xr required)207 _XPolylines(Field f, xfieldT *xf, enum xr required)
208 {
209 array(polylines_array, POLYLINES, required);
210 check(polylines, "polylines", TYPE_INT, 0);
211
212 xf->polylines = (int *)DXGetArrayData(xf->polylines_array);
213 DXGetArrayInfo(xf->polylines_array,
214 &xf->npolylines, NULL, NULL, NULL, NULL);
215
216 /* edges required if polylines present */
217 array(edges_array, "edges", required);
218 check(edges, "edges", TYPE_INT, 0);
219
220 xf->edges = (int *)DXGetArrayData(xf->edges_array);
221 DXGetArrayInfo(xf->edges_array,
222 &xf->nedges, NULL, NULL, NULL, NULL);
223
224 xf->connectionType = ct_polylines;
225 xf->nconnections = xf->npolylines;
226
227 if (DXGetComponentValue(f, "invalid polylines"))
228 {
229 if (NULL == (xf->invCntns = DXCreateInvalidComponentHandle((dxObject)f,
230 NULL, "polylines")))
231 return ERROR;
232 }
233
234 return OK;
235 }
236
237 static Error
_XConnections(Field f,xfieldT * xf,enum xr required)238 _XConnections(Field f, xfieldT* xf, enum xr required)
239 {
240 static struct info {
241 char *name; /* element type attribute */
242 connectionTypeT ct; /* corresponding ct */
243 int n; /* ints per item */
244 int volume; /* whether these are volume connections */
245 int posPerConn; /* positions per connection */
246 } info[] = {
247 { "lines", ct_lines, 2, 0, 2 },
248 { "triangles", ct_triangles, 3, 0, 3 },
249 { "quads", ct_quads, 4, 0, 4 },
250 { "tetrahedra", ct_tetrahedra, 4, 1, 3 },
251 { "cubes", ct_cubes, 8, 1, 4} ,
252 { NULL }
253 };
254 struct info *i;
255 dxObject cto;
256 char *s;
257
258 ENTRY(("_XConnections(0x%x, 0x%x, %d)", f, xf, required));
259
260 xf->connectionType = ct_none;
261 array(connections_array, CONNECTIONS, required);
262 cto = DXGetAttribute((dxObject)xf->connections_array, ELEMENT_TYPE);
263 s = DXGetString((dxString)cto);
264
265 if (!s) {
266 EXIT(("ERROR"));
267 DXErrorReturn(ERROR_BAD_PARAMETER, "#13070");
268 }
269
270 /* try to find it */
271 for (i=info; i->name; i++) {
272 if (strcmp(s, i->name)==0) {
273 check(connections, "connections", TYPE_INT, i->n);
274 get(connections);
275 DXGetArrayInfo(xf->connections_array, &xf->nconnections,
276 NULL,NULL,NULL,NULL);
277 xf->connectionType = i->ct;
278 xf->posPerConn = i->posPerConn;
279 if(i->volume)
280 _dxf_setFlags(_dxf_attributeFlags(_dxf_xfieldAttributes(xf)),
281 CONTAINS_VOLUME);
282 if (DXGetComponentValue(f, INVALID_CONNECTIONS)) {
283 /* This also creates DXReference() */
284 if((xf->invCntns = DXCreateInvalidComponentHandle((dxObject)f,
285 NULL,
286 CONNECTIONS))){
287 } else {
288 EXIT(("ERROR"));
289 return ERROR;
290 }
291 }
292 EXIT(("OK"));
293 return OK;
294 }
295 }
296
297 DXSetError(ERROR_BAD_PARAMETER, "#10410", i->ct);
298 EXIT(("ERROR"));
299 return ERROR;
300 }
301
302
303 static Error
_XNeighbors(Field f,xfieldT * xf,enum xr required)304 _XNeighbors(Field f, xfieldT* xf, enum xr required)
305 {
306 int n;
307
308 ENTRY(("_XNeighbors(0x%x, 0x%x, %d)", f, xf, required));
309
310 if (xf->neighbors_array) {
311 EXIT(("OK: xf->neighbors_array != NULL"));
312 return OK;
313 }
314
315 /* If a regular connections_array */
316 if (DXQueryGridConnections(xf->connections_array, &n, xf->k)) {
317 if( xf->connectionType==ct_cubes && n != 3) {
318 DXSetError(ERROR_DATA_INVALID,
319 "#13155","cubes",3);
320 goto error;
321 } else if( xf->connectionType==ct_quads && n != 2) {
322 DXSetError(ERROR_DATA_INVALID,
323 "#13155","quads",2);
324 goto error;
325 } else if( xf->connectionType==ct_lines && n != 1) {
326 DXSetError(ERROR_DATA_INVALID,
327 "#13155","lines",1);
328 goto error;
329 }
330 EXIT(("OK"));
331 return OK;
332 } else {
333 xf->neighbors_array = (Array) DXGetComponentValue(f, NEIGHBORS);
334 if(!xf->neighbors_array) {
335 xf->neighbors_array = DXNeighbors(f);
336 if (!xf->neighbors_array) {
337 if (required) {
338 DXSetError(ERROR_MISSING_DATA, "#10240", NEIGHBORS);
339 EXIT(("ERROR"));
340 return ERROR;
341 } else {
342 EXIT(("OK"));
343 return OK;
344 }
345 }
346 }
347 DXReference((dxObject)xf->neighbors_array);
348 check(neighbors, "neighbors", TYPE_INT,
349 DXGetItemSize((Array)xf->connections_array)/DXTypeSize(TYPE_INT));
350 compare(neighbors, "neighbors", xf->nconnections);
351 }
352
353 EXIT(("OK"));
354 return OK;
355
356 error:
357
358 EXIT(("ERROR"));
359 return ERROR;
360 }
361
362
363 /*
364 *
365 */
366
367 static Error
_XColors(Field f,xfieldT * xf,enum xr required)368 _XColors(Field f, xfieldT* xf,
369 enum xr required)
370 {
371 Array colors_array;
372 char *fs, *bs, *s = NULL;
373 dependencyT color_dep;
374 int ncolors;
375
376 ENTRY(("_XColors(0x%x, 0x%x, %d)", f, xf, required));
377
378 color_dep = dep_none;
379
380 /* get front/back colors arrays */
381 #if 0 /* we currently don't support back colors in HW */
382 colors_array = (Array) DXGetComponentValue(f, COLORS);
383 xf->fcolors_array = (Array) DXGetComponentValue(f, FRONT_COLORS);
384 xf->bcolors_array = (Array) DXGetComponentValue(f, BACK_COLORS);
385 if (!xf->fcolors_array) xf->fcolors_array = colors_array;
386 if (!xf->bcolors_array) xf->bcolors_array = colors_array;
387 #else
388 xf->fcolors_array = (Array) DXGetComponentValue(f, COLORS);
389 if(!xf->fcolors_array)
390 xf->fcolors_array = (Array) DXGetComponentValue(f, FRONT_COLORS);
391 if(!xf->fcolors_array)
392 xf->fcolors_array = (Array) DXGetComponentValue(f, BACK_COLORS);
393 colors_array = xf->bcolors_array = xf->fcolors_array;
394 #endif
395 if (!xf->fcolors_array && !xf->bcolors_array) {
396 if (required==XR_REQUIRED) {
397 DXSetError(ERROR_MISSING_DATA, "#13060","colors");
398 EXIT(("ERROR"));
399 return ERROR;
400 } else {
401 EXIT(("OK"));
402 return OK;
403 }
404 } else {
405 DXReference((dxObject)xf->fcolors_array);
406 DXReference((dxObject)xf->bcolors_array);
407 }
408
409 /* find dependency */
410 if(color_dep != dep_field) {
411 fs =DXGetString((dxString)DXGetAttribute((dxObject)xf->fcolors_array, DEP));
412 bs =DXGetString((dxString)DXGetAttribute((dxObject)xf->bcolors_array, DEP));
413 if (!fs || !bs)
414 s = DXGetString((dxString)DXGetAttribute((dxObject)colors_array, DEP));
415 if (!fs) fs = s;
416 if (!bs) bs = s;
417 if (fs && bs && strcmp(fs,bs)!=0) {
418 DXSetError(ERROR_BAD_PARAMETER,
419 "#10256","colors, front colors or back colors","dep");
420 EXIT(("ERROR"));
421 return ERROR;
422 }
423
424 s = fs? fs : bs;
425 if (!s) {
426 DXSetError(ERROR_MISSING_DATA, "#10255","colors","dep");
427 EXIT(("ERROR"));
428 return ERROR;
429 }
430 if (strcmp(s,"positions")==0) color_dep = dep_positions;
431 else if (strcmp(s,"connections")==0) color_dep = dep_connections;
432 else if (strcmp(s,"polylines")==0) color_dep = dep_polylines;
433 else {
434 DXSetError(ERROR_MISSING_DATA, "#10256",
435 "colors, front colors or back colors","dep");
436 EXIT(("ERROR"));
437 return ERROR;
438 }
439 xf->fcolorsDep = color_dep;
440 }
441
442 /* number of colors */
443 DXGetArrayInfo(xf->fcolors_array? xf->fcolors_array : xf->bcolors_array,
444 &ncolors, NULL, NULL, NULL, NULL);
445
446 if (xf->fcolors_array) {
447 Type type;
448 DXGetArrayInfo(xf->fcolors_array, NULL, &type, NULL, NULL, NULL);
449 if (type==TYPE_UBYTE) {
450 /* FIXME: Software rendering knows how to deal with ubyte[3] colors */
451 /* but hardware rendering doesn't. See also back colors below. */
452 check(fcolors, "colors", TYPE_UBYTE, 1);
453 array(cmap_array, "color map", 1);
454 check(cmap, "color map", TYPE_FLOAT, 3);
455 compare(cmap, "color map", 256);
456 } else {
457 check(fcolors, "colors", TYPE_FLOAT, 3);
458 }
459 compare(fcolors, "colors", ncolors);
460 }
461
462 if (xf->bcolors_array) {
463 Type type;
464 DXGetArrayInfo(xf->bcolors_array, NULL, &type, NULL, NULL, NULL);
465 if (type==TYPE_UBYTE) {
466 check(bcolors, "colors", TYPE_UBYTE, 1);
467 if (!xf->cmap_array) {
468 if (xf->fcolors_array) {
469 EXIT(("ERROR"));
470 DXErrorReturn(ERROR_BAD_PARAMETER,"#11812");
471 }
472 array(cmap_array, "color map", 1);
473 compare(cmap, "color map", 256);
474 }
475 } else {
476 if (xf->cmap_array) {
477 EXIT(("ERROR"));
478 DXErrorReturn(ERROR_BAD_PARAMETER,"#11812");
479 }
480 check(bcolors, "colors", TYPE_FLOAT, 3);
481 }
482 compare(bcolors, "colors", ncolors);
483 }
484
485 CHECK_CONST_ARRAY(fcolors);
486 xf->colorsDep = xf->fcolorsDep;
487
488 EXIT(("OK"));
489 return OK;
490 }
491
492
493 /*
494 * Normals
495 */
496 static Error
_XNormals(Field f,xfieldT * xf,enum xr required)497 _XNormals(Field f, xfieldT* xf,
498 enum xr required)
499 {
500 char *s;
501 dependencyT normal_dep;
502
503 ENTRY(("_XNormals(0x%x, 0x%x, %d)", f, xf, required));
504
505 normal_dep = dep_none;
506 array(normals_array, NORMALS, required);
507 if (xf->normals_array && DXGetComponentValue(f, "binormals")) {
508 /* not surface normals */
509 xf->normals_array = NULL;
510 EXIT(("not surface normals"));
511 return OK;
512 }
513 check(normals, "normals", TYPE_FLOAT, 3);
514 if(normal_dep != dep_field) {
515 s = DXGetString((dxString)DXGetAttribute((dxObject)xf->normals_array, DEP));
516 if (strcmp(s,"positions")==0) normal_dep = dep_positions;
517 else if (strcmp(s,"connections")==0) normal_dep = dep_connections;
518 else if (strcmp(s,"polylines")==0) normal_dep = dep_polylines;
519 #if 0
520 else if (strcmp(s,"faces")==0) normal_dep = dep_faces;
521 #endif
522 else {
523 DXSetError(ERROR_MISSING_DATA, "#10256","normals","dep");
524 EXIT(("ERROR"));
525 return ERROR;
526 }
527 if (normal_dep==dep_positions) {
528 compare(normals, "normals", xf->npositions);
529 } else if (normal_dep==dep_connections) {
530 compare(normals, "normals", xf->nconnections);
531 } else if (normal_dep==dep_polylines) {
532 compare(normals, "normals", xf->npolylines);
533 } else {
534 DXSetError(ERROR_DATA_INVALID, "#10256","normals","dep");
535 EXIT(("ERROR"));
536 return ERROR;
537 }
538 }
539 _dxf_setFlags(_dxf_attributeFlags(_dxf_xfieldAttributes(xf)),
540 CONTAINS_NORMALS);
541 xf->normalsDep = normal_dep;
542 CHECK_CONST_ARRAY(normals);
543
544 EXIT(("OK"));
545 return OK;
546 }
547
548
549 static Error
_XOpacities(Field f,xfieldT * xf,enum xr required)550 _XOpacities(Field f, xfieldT* xf,
551 enum xr required)
552 {
553 Type type;
554 dependencyT opacity_dep;
555
556 ENTRY(("_XOpacities(0x%x, 0x%x, %d)", f, xf, required));
557
558 opacity_dep = dep_none; /* Should Be Replaced ... (:Q= */
559
560 array(opacities_array, OPACITIES, required);
561 if (xf->opacities_array)
562 {
563 if (xf->fcolors_array)
564 {
565 dxObject o;
566 char *s;
567
568 if(opacity_dep != dep_field)
569 {
570 o = DXGetComponentAttribute(f, OPACITIES, DEP);
571 if (! o)
572 {
573 DXSetError(ERROR_DATA_INVALID, "#10255","opacities","dep");
574 EXIT(("ERROR"));
575 return ERROR;
576 }
577 }
578
579 s = DXGetString((dxString)o);
580 if (! s)
581 {
582 DXSetError(ERROR_DATA_INVALID, "#10256","opacities","dep");
583 EXIT(("ERROR"));
584 return ERROR;
585 }
586
587 if (strcmp(s,"positions")==0) opacity_dep = dep_positions;
588 else if (strcmp(s,"connections")==0) opacity_dep = dep_connections;
589 else if (strcmp(s,"polylines")==0) opacity_dep = dep_polylines;
590 else
591 {
592 DXSetError(ERROR_MISSING_DATA,"#10256","opacities","dep");
593 EXIT(("ERROR"));
594 return ERROR;
595 }
596
597 if (opacity_dep==dep_positions)
598 {
599 compare(opacities, "opacities", xf->npositions);
600 }
601 else if (opacity_dep==dep_connections)
602 {
603 compare(opacities, "opacities", xf->nconnections);
604 }
605 else if (opacity_dep==dep_polylines)
606 {
607 compare(opacities, "opacities", xf->npolylines);
608 }
609 xf->opacitiesDep= opacity_dep;
610 }
611
612 DXGetArrayInfo(xf->opacities_array, NULL, &type, NULL, NULL, NULL);
613
614 if (type==TYPE_UBYTE)
615 {
616 check(opacities, "opacities", TYPE_UBYTE, 1);
617 array(omap_array, "opacity map", 1);
618 compare(omap, "opacity map", 256);
619 }
620 else
621 {
622 check(opacities, "opacities", TYPE_FLOAT, 1);
623 }
624
625 CHECK_CONST_ARRAY(opacities);
626
627 _dxf_setFlags(_dxf_attributeFlags(_dxf_xfieldAttributes(xf)),
628 CONTAINS_TRANSPARENT);
629 }
630 else
631 {
632 xf->opacities = NULL;
633 xf->nopacities = 0;
634 xf->opacitiesDep = dep_none;
635 }
636
637 EXIT(("OK"));
638 return OK;
639 }
640
641
642 /*
643 static Error
644 _XFreeLocal(xfieldT* xf)
645 {
646 ENTRY(("_XFreeLocal(0x%x)", xf));
647 EXIT(("stub function"));
648 return OK;
649 }
650 */
651
652
653 /*=====================================================================*\
654 Xfield functions
655 \*=====================================================================*/
656
657 Error
_dxf_deleteXfield(xfieldP xf)658 _dxf_deleteXfield(xfieldP xf)
659 {
660 ENTRY(("_dxf_deleteXfield(0x%x)", xf));
661
662 if (xf->clipPts)
663 DXFree((Pointer)xf->clipPts), xf->clipPts = NULL;
664
665 if (xf->clipVecs)
666 DXFree((Pointer)xf->clipVecs), xf->clipVecs = NULL;
667
668 if (xf->texture_field)
669 { DXDelete((dxObject)xf->texture_field); xf->texture_field = NULL; }
670
671 if (xf->texture)
672 {
673 if (xf->myTextureData)
674 DXFree((Pointer)xf->texture);
675 xf->texture = NULL;
676 xf->myTextureData = 0;
677 }
678
679 if ((xf->glObject || xf->FlatGridTexture.Address) && xf->deletePrivate)
680 {
681 (*xf->deletePrivate)((struct xfieldS *)xf);
682 xf->glObject = 0;
683 }
684
685
686 if (xf->uv_array)
687 { DXDelete((dxObject)xf->uv_array); xf->uv_array = NULL; }
688
689 if (xf->uv)
690 { DXFreeArrayHandle(xf->uv); xf->uv = NULL; }
691
692 if (xf->connections)
693 { DXFreeArrayHandle(xf->connections); xf->connections = NULL; }
694
695 if(xf->connections_array)
696 { DXDelete((dxObject)xf->connections_array);xf->connections_array = NULL; }
697
698 if(xf->origConnections_array)
699 { DXDelete((dxObject)xf->origConnections_array);xf->origConnections_array = NULL; }
700
701 if(xf->polylines_array)
702 { DXDelete((dxObject)xf->polylines_array);xf->polylines_array = NULL; }
703
704 if(xf->edges_array)
705 { DXDelete((dxObject)xf->edges_array);xf->edges_array = NULL; }
706
707 if (xf->invCntns)
708 { DXFreeInvalidComponentHandle(xf->invCntns); xf->invCntns = NULL; }
709
710 if (xf->positions){ DXFreeArrayHandle(xf->positions); xf->positions = NULL; }
711
712 if(xf->positions_array)
713 { DXDelete((dxObject)xf->positions_array); xf->positions_array = NULL; }
714
715 if (xf->invPositions)
716 { DXFreeInvalidComponentHandle(xf->invPositions); xf->invPositions = NULL;}
717
718 if (xf->normals) { DXFreeArrayHandle(xf->normals); xf->normals = NULL; }
719
720 if(xf->normals_array)
721 { DXDelete((dxObject)xf->normals_array); xf->normals_array = NULL; }
722
723 if (xf->fcolors) { DXFreeArrayHandle(xf->fcolors); xf->fcolors = NULL; }
724
725 if(xf->fcolors_array)
726 { DXDelete((dxObject)xf->fcolors_array); xf->fcolors_array = NULL; }
727
728 if (xf->bcolors) { DXFreeArrayHandle(xf->bcolors); xf->bcolors = NULL; }
729
730 if(xf->bcolors_array)
731 { DXDelete((dxObject)xf->bcolors_array); xf->bcolors_array = NULL; }
732
733 if (xf->cmap) { DXFreeArrayHandle(xf->cmap); xf->cmap = NULL; }
734
735 if(xf->cmap_array)
736 { DXDelete((dxObject)xf->cmap_array); xf->cmap_array = NULL; }
737
738 if (xf->opacities){ DXFreeArrayHandle(xf->opacities); xf->opacities = NULL; }
739
740 if(xf->opacities_array)
741 { DXDelete((dxObject)xf->opacities_array); xf->opacities_array = NULL; }
742
743 if (xf->omap) { DXFreeArrayHandle(xf->omap); xf->omap = NULL; }
744
745 if(xf->omap_array)
746 { DXDelete((dxObject)xf->omap_array); xf->omap_array = NULL; }
747
748 if (xf->neighbors){ DXFreeArrayHandle(xf->neighbors); xf->neighbors = NULL; }
749
750 if(xf->neighbors_array)
751 { DXDelete((dxObject)xf->neighbors_array); xf->neighbors_array = NULL; }
752
753 if(xf->meshes)
754 { DXDelete((dxObject)xf->meshes); xf->meshes = NULL; }
755
756 if(xf->meshObject)
757 { DXDelete((dxObject)xf->meshObject); xf->meshObject = NULL; }
758
759 if (xf->field)
760 { DXDelete((dxObject)xf->field); xf->field = NULL; }
761
762
763 tdmFree(xf);
764
765 EXIT((""));
766 return OK;
767 }
768
769
770 #define ABS(x) ((x)<0)?-(x):(x)
771
772 extern Error _XTexture(Field, xfieldT*, void *globals);
773
774 xfieldP
_dxf_newXfieldP(Field f,attributeP attributes,void * globals)775 _dxf_newXfieldP(Field f, attributeP attributes, void *globals)
776 {
777 DEFGLOBALDATA(globals);
778 DEFPORT(PORT_HANDLE);
779 xfieldT *xf;
780 hwFlags attFlags;
781 hwFlags servicesFlags;
782
783 ENTRY(("_dxf_newXfield(0x%x, 0x%x, 0x%x)", f, attributes, globals));
784
785 if (!(xf = (xfieldT*)tdmAllocateZero(sizeof(xfieldT)))) {
786 EXIT(("alloc failed"));
787 return NULL;
788 }
789
790 xf->field = (Field)DXReference((dxObject)f);
791
792 /* SGI Specific FlatGrid Texturing */
793 xf->FlatGridTexture.Address = NULL;
794 xf->FlatGridTexture.Index = 0;
795
796 if(attributes)
797 *_dxf_xfieldAttributes(xf) = *attributes;
798
799 attFlags = _dxf_attributeFlags(_dxf_xfieldAttributes(xf));
800 servicesFlags = _dxf_SERVICES_FLAGS();
801
802 /*
803 XXX Currently no effort is made to make these arrays local
804 this means access to them is going to be into global memory,
805 this could be really slow for the cmap and omap (and perhaps others)
806 on an MP machine.
807 */
808
809 if (DXGetComponentValue (f, "faces") ||
810 DXGetComponentValue (f, INVALID_POSITIONS)) {
811 /* XXX How do I get rid of this allocated header ? */
812 f = (Field)DXCopy((dxObject)f,COPY_HEADER);
813 if (DXGetComponentValue (f, "faces"))
814 if(!_dxfTriangulateField(f))
815 goto error;
816 if (DXGetComponentValue (f, INVALID_POSITIONS))
817 /*
818 * This is an appropriate place to propagate invalid positions,
819 * if any, to invalid connections. Don't do this in _dxfDraw()
820 * itself. That routine is also called by the direct
821 * interactors, which update only the view transform; validity
822 * state should remain constant.
823 */
824 if (!DXInvalidateConnections((dxObject)f))
825 /* unable to propagate invalid positions to connections */
826 DXErrorGoto (ERROR_INTERNAL, "#13850") ;
827 }
828
829 if(_dxf_isFlagsSet(_dxf_attributeFlags(_dxf_xfieldAttributes(xf)),
830 IN_CLIP_OBJECT)) {
831
832 if (!_XPositions(f, xf, XR_REQUIRED)) goto error;
833 /*
834 XXX we should allow only surface type connections here
835 */
836 if (!_XConnections(f, xf,XR_REQUIRED)) goto error;
837 } else {
838
839
840 if (!_XPositions(f, xf, XR_REQUIRED)) goto error;
841 if (!_XBox(f, xf, XR_REQUIRED)) goto error;
842 if (!_XColors(f, xf, XR_REQUIRED)) goto error;
843 if (!_XOpacities(f, xf, XR_OPTIONAL)) goto error;
844 if (!_XConnections(f, xf, XR_OPTIONAL)) goto error;
845 if (!_XPolylines(f, xf,XR_OPTIONAL)) goto error;
846
847 if (!_XTexture(f, xf, globals)) goto error;
848
849 /* sanity check for fcolors = bcolors for volumes */
850 /* and for position-dependent */
851 /* XXX - xf->volume? */
852 if (_dxf_isFlagsSet(attFlags, CONTAINS_VOLUME)) {
853 if (!_dxf_XNeighbors(f, xf, XR_REQUIRED, XD_GLOBAL)) {
854 /* Warning!!!!!! no ERROR is set here!!!!! */
855 EXIT(("ERROR"));
856 return ERROR;
857 }
858 if (xf->fcolors_array != xf->bcolors_array) {
859 EXIT(("ERROR"));
860 DXErrorReturn(ERROR_DATA_INVALID,
861 "#13165");
862 }
863 }
864
865 /*
866 * If we are not in a screen or clip object and we are supposed to shade
867 * get the normals
868 */
869 if(!(_dxf_isFlagsSet(attFlags,(IN_SCREEN_OBJECT | IN_CLIP_OBJECT)))
870 && _dxf_xfieldAttributes(xf)->shade)
871 if (!_XNormals(f, xf, XR_OPTIONAL)) goto error;
872
873 if(_dxf_isFlagsSet(servicesFlags,SF_TEXTURE_MAP))
874 {
875 int n,counts[3];
876 float origin[3];
877 float deltas[9];
878
879 if(xf->connectionType == ct_quads &&
880 xf->normalsDep == dep_none &&
881 xf->colorsDep == dep_positions &&
882 !xf->invCntns &&
883 !xf->invPositions &&
884 DXQueryGridPositions(xf->positions_array,&n,
885 counts, origin, deltas) &&
886 (n == 2))
887 {
888
889 xf->image = (Field)f;
890 xf->connectionType = ct_flatGrid;
891 }
892 }
893
894
895 if(_dxf_isFlagsSet(servicesFlags,SF_POLYLINES) &&
896 xf->connectionType == ct_lines &&
897 xf->opacitiesDep == dep_none &&
898 !(xf->colorsDep == dep_connections) &&
899 !(xf->normalsDep == dep_connections)) {
900 TIMER("> _dxf_linesToPlines");
901 if(!_dxf_linesToPlines(xf)) goto error;
902 TIMER("< _dxf_lineToPlines");
903 }
904
905 #if 0
906 if(_dxf_isFlagsSet(servicesFlags,SF_POLYLINES) &&
907 xf->connectionType == ct_polylines &&
908 !(xf->colorsDep == dep_polylines) &&
909 !(xf->normalsDep == dep_polylines)) {
910 TIMER("> _dxf_linesToPlines");
911 if(!_dxf_polylinesToPlines(xf)) goto error;
912 TIMER("< _dxf_lineToPlines");
913 }
914 #endif
915
916 /* Don't mesh translucent primitives; they're depth sorted for rendering */
917 if(
918 (_dxf_isFlagsSet(servicesFlags, SF_DOES_TRANS) &&
919 (xf->opacitiesDep == dep_none) &&
920 !(xf->texture && xf->textureIsRGBA))
921 ||
922 (!_dxf_isFlagsSet(servicesFlags, SF_DOES_TRANS))
923 )
924 {
925 if(_dxf_isFlagsSet(servicesFlags,SF_TMESH) &&
926 xf->connectionType == ct_triangles &&
927 !(xf->colorsDep == dep_connections) &&
928 !(xf->normalsDep == dep_connections)) {
929 if (!_XNeighbors(f, xf, XR_REQUIRED)) goto error;
930 TIMER("> _dxf_trisToTmesh");
931 if(!(_dxf_trisToTmesh(xf, globals))) goto error;
932 TIMER("< _dxf_trisToTmesh");
933 }
934
935 if(_dxf_isFlagsSet(servicesFlags,SF_QMESH) &&
936 xf->connectionType == ct_quads &&
937 !(xf->colorsDep == dep_connections) &&
938 !(xf->normalsDep == dep_connections)) {
939 if (!_XNeighbors(f, xf, XR_REQUIRED)) goto error;
940 TIMER("> _dxf_quadsToQmesh");
941 if(!_dxf_quadsToQmesh(xf, globals)) goto error;
942 TIMER("< _dxf_quadsToQmesh");
943 }
944 }
945
946 if(_dxf_isFlagsSet(servicesFlags,SF_GAMMA_CORRECT_COLORS)) {
947 float gamma = 2.0;
948 char* gammaStr;
949
950
951 if ( (gammaStr = (char*)getenv("DXHWGAMMA")) ) {
952 gamma = atof(gammaStr);
953 if (gamma < 0.0) gamma = 0.0;
954 }
955
956 TIMER("> gammaCorrectColors");
957 if(xf->normalsDep != dep_none)
958 _gammaCorrectColors(xf, gamma, 0);
959 else
960 _gammaCorrectColors(xf, gamma, 1);
961 TIMER("< gammaCorrectColors");
962 }
963
964 xf->glObject = 0;
965 }
966
967 EXIT(("xf = 0x%x", xf));
968 return xf;
969
970 error:
971
972 if(xf)
973 tdmFree(xf);
974
975 EXIT(("xf = NULL"));
976 return NULL;
977 }
978
979 xfieldO
_dxf_newXfieldO(Field f,attributeP attributes,void * globals)980 _dxf_newXfieldO(Field f, attributeP attributes, void *globals)
981 {
982 xfieldO xfo = NULL;
983 xfieldP xf = _dxf_newXfieldP(f, attributes, globals);
984
985 if (xf)
986 xfo = (xfieldO)_dxf_newHwObject(HW_CLASS_XFIELD, (Pointer)xf, _dxf_deleteXfield);
987
988 EXIT(("xfo = 0x%x", xfo));
989 return xfo;
990 }
991
992 xfieldP
_dxf_getXfieldData(xfieldO obj)993 _dxf_getXfieldData(xfieldO obj)
994 {
995 return (xfieldP)_dxf_getHwObjectData((dxObject)obj);
996 }
997
998 /*=====================================================================*\
999 Attribute handling stuff
1000 \*=====================================================================*/
1001
1002 /*
1003 * Parameters
1004 */
1005 #define PARAMETER(parm, name, type, get) { \
1006 type p; \
1007 dxObject a; \
1008 a = DXGetAttribute(o, name); \
1009 if (a) { \
1010 if (!get(a, &p)) { \
1011 DXSetError(ERROR_BAD_PARAMETER, "#10020", name " attribute"); \
1012 EXIT(("ERROR")); \
1013 return ERROR; \
1014 } \
1015 new->parm = p; \
1016 } \
1017 }
1018
1019 #define PARAMETER1(parm, name, type, get, rhs, msg) { \
1020 type p; \
1021 dxObject a; \
1022 a = DXGetAttribute(o, name); \
1023 if (a) { \
1024 if (!get(a, &p)) { \
1025 DXSetError(ERROR_BAD_PARAMETER, msg, name " attribute"); \
1026 EXIT(("ERROR")); \
1027 return ERROR; \
1028 } \
1029 new->parm = rhs; \
1030 } \
1031 }
1032
1033
1034 #define PARAMETER2(parm, name, type, get, msg) { \
1035 type p; \
1036 dxObject a; \
1037 a = DXGetAttribute(o, name); \
1038 if (a) { \
1039 if (!get(DXGetAttribute(o, name), &p)) { \
1040 DXSetError(ERROR_BAD_PARAMETER, msg, name " attribute"); \
1041 EXIT(("ERROR")); \
1042 return ERROR; \
1043 } \
1044 new->front.parm = new->back.parm = p; \
1045 } \
1046 a = DXGetAttribute(o, "front " name); \
1047 if (a && !get(a, &(new->front.parm))) { \
1048 DXSetError(ERROR_BAD_PARAMETER, \
1049 msg,"front " name " attribute"); \
1050 EXIT(("ERROR")); \
1051 return ERROR; \
1052 } \
1053 a = DXGetAttribute(o, "back " name); \
1054 if (a && !get(a, &(new->back.parm))) { \
1055 DXSetError(ERROR_BAD_PARAMETER, \
1056 msg, "back " name " attribute"); \
1057 EXIT(("ERROR")); \
1058 return ERROR; \
1059 } \
1060 }
1061
1062
1063 #define MULTIPLIER(parm, name, type, get) { \
1064 type p; \
1065 dxObject a; \
1066 a = DXGetAttribute(o, name); \
1067 if (a) { \
1068 if (!get(a, &p)) { \
1069 DXSetError(ERROR_BAD_PARAMETER, "#10080", name " attribute"); \
1070 EXIT(("ERROR")); \
1071 return ERROR; \
1072 } \
1073 new->parm *= p; \
1074 } \
1075 }
1076
1077
1078 attributeP
_dxf_parameters(dxObject o,attributeP old)1079 _dxf_parameters(dxObject o, attributeP old)
1080 {
1081 static struct
1082 { char *str; textureFilterE val; }
1083 filter_to_str[] = {
1084 { "nearest", tf_nearest },
1085 { "linear", tf_linear },
1086 { "nearest_mipmap_nearest",tf_nearest_mipmap_nearest },
1087 { "nearest_mipmap_linear", tf_nearest_mipmap_linear },
1088 { "linear_mipmap_nearest", tf_linear_mipmap_nearest },
1089 { "linear_mipmap_linear", tf_linear_mipmap_linear },
1090 { 0, (textureFilterE) 0 } };
1091
1092 dxObject options;
1093 int density;
1094 char *densityString;
1095 char optionsString[201];
1096 attributeP new;
1097 dxObject obj;
1098 Class class;
1099
1100 ENTRY(("_dxf_parameters(0x%x, 0x%x)", o, old));
1101
1102 new = _dxf_newAttribute(old);
1103
1104 if (!(new->flags & IGNORE_PARAMS)) {
1105 PARAMETER2(ambient, "ambient", float, DXExtractFloat, "#10080");
1106 PARAMETER2(specular, "specular", float, DXExtractFloat, "#10080");
1107 PARAMETER2(diffuse, "diffuse", float, DXExtractFloat, "#10080");
1108 PARAMETER2(shininess, "shininess", float, DXExtractFloat, "#10020");
1109 PARAMETER1(fuzz, "fuzz", float, DXExtractFloat, new->fuzz+p, "#10080");
1110 PARAMETER(shade, "shade", int, DXExtractInteger);
1111 PARAMETER(flat_z, "flat z", int, DXExtractInteger);
1112 PARAMETER(skip, "skip", int, DXExtractInteger);
1113 PARAMETER(linewidth, "line width", float, DXExtractFloat);
1114 MULTIPLIER(color_multiplier ,"color multiplier" ,float,DXExtractFloat);
1115 MULTIPLIER(opacity_multiplier,"opacity multiplier",float,DXExtractFloat);
1116 }
1117
1118 /*
1119 * get texture map if there is one
1120 */
1121 class = DXGetObjectClass(o);
1122 if (class == CLASS_FIELD && (obj = DXGetAttribute(o, "texture")) != NULL)
1123 {
1124 if (new->texture)
1125 DXDelete(new->texture);
1126 new->texture = DXReference(obj);
1127
1128 /* get texture wrap options */
1129 if ((options = DXGetAttribute(o, "texture wrap s"))) {
1130 char *wrap_s;
1131 if(!(DXExtractString(options, &wrap_s))) {
1132 DXSetError(ERROR_BAD_PARAMETER,"#13384");
1133 EXIT(("ERROR"));
1134 return ERROR;
1135 }
1136 if (!strcmp(wrap_s,"clamp" )) new->texture_wrap_s = tw_clamp;
1137 else if(!strcmp(wrap_s,"repeat")) new->texture_wrap_s = tw_repeat;
1138 else if(!strcmp(wrap_s,"clamp to edge"))
1139 new->texture_wrap_s = tw_clamp_to_edge;
1140 else if(!strcmp(wrap_s,"clamp to border"))
1141 new->texture_wrap_s = tw_clamp_to_border;
1142 else {
1143 DXSetError(ERROR_BAD_PARAMETER,"#13384");
1144 EXIT(("ERROR"));
1145 return ERROR;
1146 }
1147 }
1148 if ((options = DXGetAttribute(o, "texture wrap t"))) {
1149 char *wrap_t;
1150 if(!(DXExtractString(options, &wrap_t))) {
1151 DXSetError(ERROR_BAD_PARAMETER,"#13384");
1152 EXIT(("ERROR"));
1153 return ERROR;
1154 }
1155 if (!strcmp(wrap_t,"clamp" )) new->texture_wrap_t = tw_clamp;
1156 else if(!strcmp(wrap_t,"repeat")) new->texture_wrap_t = tw_repeat;
1157 else if(!strcmp(wrap_t,"clamp to edge"))
1158 new->texture_wrap_t = tw_clamp_to_edge;
1159 else if(!strcmp(wrap_t,"clamp to border"))
1160 new->texture_wrap_t = tw_clamp_to_border;
1161 else {
1162 DXSetError(ERROR_BAD_PARAMETER,"#13384");
1163 EXIT(("ERROR"));
1164 return ERROR;
1165 }
1166 }
1167
1168 /* get texture filter options */
1169 if ((options = DXGetAttribute(o, "texture min filter"))) {
1170 char *str;
1171 int i;
1172 if(!(DXExtractString(options, &str))) {
1173 DXSetError(ERROR_BAD_PARAMETER,"#13386");
1174 EXIT(("ERROR"));
1175 return ERROR;
1176 }
1177 for ( i = 0; filter_to_str[i].str != 0; i++ )
1178 if (!strcmp(str,filter_to_str[i].str))
1179 break;
1180 if ( filter_to_str[i].str == 0 ) {
1181 DXSetError(ERROR_BAD_PARAMETER,"#13386");
1182 EXIT(("ERROR"));
1183 return ERROR;
1184 }
1185 new->texture_min_filter = filter_to_str[i].val;
1186 }
1187 if ((options = DXGetAttribute(o, "texture mag filter"))) {
1188 char *str;
1189 int i;
1190 if(!(DXExtractString(options, &str))) {
1191 DXSetError(ERROR_BAD_PARAMETER,"#13386");
1192 EXIT(("ERROR"));
1193 return ERROR;
1194 }
1195 for ( i = 0; i < 2; i++ )
1196 if (!strcmp(str,filter_to_str[i].str))
1197 break;
1198 if ( i >= 2 ) {
1199 DXSetError(ERROR_BAD_PARAMETER,"#13386");
1200 EXIT(("ERROR"));
1201 return ERROR;
1202 }
1203 new->texture_mag_filter = filter_to_str[i].val;
1204 }
1205
1206 /* get texture function options */
1207 if ((options = DXGetAttribute(o, "texture function"))) {
1208 char *str;
1209 if(!(DXExtractString(options, &str))) {
1210 DXSetError(ERROR_BAD_PARAMETER,"#13388");
1211 EXIT(("ERROR"));
1212 return ERROR;
1213 }
1214 if (!strcmp(str,"decal")) new->texture_function = tfn_decal;
1215 else if(!strcmp(str,"replace")) new->texture_function = tfn_replace;
1216 else if(!strcmp(str,"modulate")) new->texture_function = tfn_modulate;
1217 else if(!strcmp(str,"blend")) new->texture_function = tfn_blend;
1218 else {
1219 DXSetError(ERROR_BAD_PARAMETER,"#13388");
1220 EXIT(("ERROR"));
1221 return ERROR;
1222 }
1223 }
1224 }
1225
1226 /* get culling options */
1227 if ((options = DXGetAttribute(o, "cull face"))) {
1228 char *cull;
1229 if(!(DXExtractString(options, &cull))) {
1230 DXSetError(ERROR_BAD_PARAMETER,"#13389");
1231 EXIT(("ERROR"));
1232 return ERROR;
1233 }
1234 if (!strcmp(cull,"off" )) new->cull_face = cf_off;
1235 else if(!strcmp(cull,"front" )) new->cull_face = cf_front;
1236 else if(!strcmp(cull,"back" )) new->cull_face = cf_back;
1237 else if(!strcmp(cull,"front and back")) new->cull_face = cf_front_and_back;
1238 else {
1239 DXSetError(ERROR_BAD_PARAMETER,"#13389");
1240 EXIT(("ERROR"));
1241 return ERROR;
1242 }
1243 }
1244
1245 /* get lighting model options */
1246 if ((options = DXGetAttribute(o, "light model"))) {
1247 char *lmodel;
1248 if(!(DXExtractString(options, &lmodel))) {
1249 DXSetError(ERROR_BAD_PARAMETER,"#13387");
1250 EXIT(("ERROR"));
1251 return ERROR;
1252 }
1253 if (!strcmp(lmodel,"one side" )) new->light_model = lm_one_side;
1254 else if (!strcmp(lmodel,"two side" )) new->light_model = lm_two_side;
1255 else {
1256 DXSetError(ERROR_BAD_PARAMETER,"#13387");
1257 EXIT(("ERROR"));
1258 return ERROR;
1259 }
1260 }
1261
1262 /* get anti-aliasing options */
1263 if ((options = DXGetAttribute(o, "antialias"))) {
1264 char *aaoptions;
1265 if(!(DXExtractString(options, &aaoptions))) {
1266 DXSetError(ERROR_BAD_PARAMETER,"#13382");
1267 EXIT(("ERROR"));
1268 return ERROR;
1269 }
1270 if(!strcmp(aaoptions,"lines")) new->aalines = 1;
1271 }
1272
1273 /* get rendering approximation options */
1274 if ((options = DXGetAttribute(o, "rendering approximation"))) {
1275 char *down,*up;
1276
1277 if(!(DXExtractString(options, &down))) {
1278 DXSetError(ERROR_BAD_PARAMETER,"#13380",down);
1279 EXIT(("ERROR"));
1280 return ERROR;
1281 }
1282 strncpy(optionsString,down,200);
1283 down = up = optionsString;
1284 while(*up && *up != ',') up++;
1285 if (*up == ',') *up++ = '\0';
1286 if(!strlen(up)) up = down;
1287 if(!strcmp(down,"none")) new->buttonDown.approx = approx_none;
1288 else if(!strcmp(down,"dots")) new->buttonDown.approx = approx_dots;
1289 else if(!strcmp(down,"box")) new->buttonDown.approx = approx_box;
1290 else if(!strcmp(down,"wireframe")) new->buttonDown.approx = approx_lines;
1291 else {
1292 DXSetError(ERROR_BAD_PARAMETER,"#13380",down);
1293 EXIT(("ERROR"));
1294 return ERROR;
1295 }
1296
1297 if(!strcmp(up,"none")) new->buttonUp.approx = approx_none;
1298 else if(!strcmp(up,"dots")) new->buttonUp.approx = approx_dots;
1299 else if(!strcmp(up,"box")) new->buttonUp.approx = approx_box;
1300 else if(!strcmp(up,"wireframe")) new->buttonUp.approx = approx_lines;
1301 else {
1302 DXSetError(ERROR_BAD_PARAMETER,"#13380",up);
1303 EXIT(("ERROR"));
1304 return ERROR;
1305 }
1306
1307 }
1308
1309 /* get approximation density */
1310 if ((options = DXGetAttribute(o, "render every"))) {
1311 if (DXExtractInteger (options, &density)) {
1312 new->buttonDown.density = density;
1313 new->buttonUp.density = density;
1314 } else if(DXExtractString (options, &densityString)) {
1315 new->buttonDown.density = new->buttonUp.density = -1;
1316 sscanf(densityString,"%d,%d",
1317 &new->buttonDown.density,&new->buttonUp.density);
1318 if(new->buttonUp.density == -1)
1319 new->buttonUp.density = new->buttonDown.density;
1320 } else {
1321 EXIT(("ERROR"));
1322 DXErrorReturn(ERROR_BAD_PARAMETER,"#13360");
1323 }
1324 }
1325
1326 EXIT(("new = 0x%x", new));
1327 return new;
1328 }
1329
1330 /*=====================================================================*\
1331 Xfield attribute functions
1332 \*=====================================================================*/
1333
1334 static attributeT defAttribute = {
1335 /* flags */ 0,
1336 /* flat_z */ 0,
1337 /* skip */ 1,
1338 /* color_multiplier */ 1.0,
1339 /* opacity_multiplier */ 1.0,
1340 /* shade */ 1,
1341 /* buttonDown */ {approx_none, 1},
1342 /* buttonUp */ {approx_none, 1},
1343 /* fuzz */ 0.0,
1344 /* ff */ 1.0,
1345 /* linewidth */ 1.0,
1346 /* aalines */ 0,
1347 /* front */ {1.0, 0.7, 0.5, 10},
1348 /* back */ {1.0, 0.7, 0.5, 10},
1349 /* mm */ {
1350 {1.0, 0.0, 0.0, 0.0},
1351 {0.0, 1.0, 0.0, 0.0},
1352 {0.0, 0.0, 1.0, 0.0},
1353 {0.0, 0.0, 0.0, 1.0}
1354 },
1355 /* vm */ {
1356 {1.0, 0.0, 0.0, 0.0},
1357 {0.0, 1.0, 0.0, 0.0},
1358 {0.0, 0.0, 1.0, 0.0},
1359 {0.0, 0.0, 0.0, 1.0}
1360 },
1361 /* texture */ NULL,
1362
1363 /* texture_wrap_s */ tw_clamp,
1364 /* texture_wrap_t */ tw_clamp,
1365 /* texture_min_filter */ tf_nearest,
1366 /* texture_mag_filter */ tf_nearest,
1367 /* texture_function */ tfn_modulate,
1368
1369 /* cull_face */ cf_off,
1370 /* light_model */ lm_one_side
1371 };
1372
1373
1374
1375 float *
_dxf_attributeFuzz(attributeP att,double * ff)1376 _dxf_attributeFuzz(attributeP att, double *ff)
1377 {
1378 ENTRY(("_dxf_attributeFuzz(0x%x, 0x%x)", att, ff));
1379
1380 if (ff)
1381 *ff = att->ff;
1382
1383 EXIT((""));
1384 return &att->fuzz;
1385 }
1386
1387 hwFlags
_dxf_attributeFlags(attributeP att)1388 _dxf_attributeFlags(attributeP att)
1389 {
1390 ENTRY(("_dxf_attributeFlags(0x%x)", att));
1391
1392 EXIT((""));
1393 return &att->flags;
1394 }
1395
1396 materialAttrP
_dxf_attributeFrontMaterial(attributeP att)1397 _dxf_attributeFrontMaterial(attributeP att)
1398 {
1399 ENTRY(("_dxf_attributeFrontMaterial(0x%x)", att));
1400
1401 EXIT((""));
1402 return &att->front;
1403 }
1404
1405 void
_dxf_attributeMatrix(attributeP att,float matrix[4][4])1406 _dxf_attributeMatrix(attributeP att, float matrix[4][4])
1407 {
1408 ENTRY(("_dxf_attributeMatrix(0x%x, 0x%x)", att, matrix));
1409
1410 COPYMATRIX(matrix,att->mm);
1411
1412 EXIT((""));
1413 }
1414
1415 void
_dxf_setAttributeMatrix(attributeP att,float matrix[4][4])1416 _dxf_setAttributeMatrix(attributeP att, float matrix[4][4])
1417 {
1418 ENTRY(("_dxf_setAttributeMatrix(0x%x, 0x%x)", att, matrix));
1419
1420 COPYMATRIX(att->mm,matrix);
1421
1422 EXIT((""));
1423 }
1424
1425 Error
_dxf_deleteAttribute(attributeP att)1426 _dxf_deleteAttribute(attributeP att)
1427 {
1428 ENTRY(("_dxf_deleteAttribute(0x%x)", att));
1429
1430 if (att->texture) {
1431 DXDelete(att->texture);
1432 att->texture = NULL;
1433 }
1434
1435 /* !!!!! should check for non-null */
1436 tdmFree(att);
1437
1438 EXIT((""));
1439 return OK;
1440 }
1441
1442 attributeP
_dxf_newAttribute(attributeP from)1443 _dxf_newAttribute(attributeP from)
1444 {
1445 attributeP ret;
1446
1447 ENTRY(("_dxf_newAttribute(0x%x)", from));
1448
1449 if(!(ret = (attributeP)tdmAllocate(sizeof(attributeT)))) {
1450 EXIT(("alloc errror"));
1451 DXErrorReturn(ERROR_NO_MEMORY,"");
1452 }
1453
1454 if(from)
1455 *ret = *from;
1456 else {
1457 *ret = defAttribute;
1458 COPYMATRIX(ret->mm,identity);
1459 }
1460
1461 if (ret->texture)
1462 DXReference(ret->texture);
1463
1464 EXIT(("ret = 0x%x", ret));
1465 return ret;
1466 }
1467
1468
1469 int
_dxf_xfieldNconnections(xfieldP xf)1470 _dxf_xfieldNconnections(xfieldP xf)
1471 {
1472 ENTRY(("_dxf_xfieldNconnections(0x%x)", xf));
1473
1474 EXIT((""));
1475 return xf->nconnections;
1476 }
1477
1478 attributeP
_dxf_xfieldAttributes(xfieldP xf)1479 _dxf_xfieldAttributes(xfieldP xf)
1480 {
1481 ENTRY(("_dxf_xfieldAttributes(0x%x)", xf));
1482
1483 EXIT((""));
1484 return &xf->attributes;
1485 }
1486
1487 int
_dxf_xfieldSidesPerConnection(xfieldP xf)1488 _dxf_xfieldSidesPerConnection(xfieldP xf)
1489 {
1490 ENTRY(("_dxf_xfieldSidesPerConnection(0x%x)", xf));
1491
1492 switch (xf->connectionType) {
1493 case ct_cubes:
1494 EXIT(("6"));
1495 return 6;
1496 break;
1497 case ct_tetrahedra:
1498 EXIT(("4"));
1499 return 4;
1500 break;
1501 default:
1502 EXIT(("1"));
1503 return 1;
1504 break;
1505 }
1506 }
1507
1508
1509
1510 /*
1511 * XXX For gl 3.2 we can't do back colors so we always set front colors
1512 * equal to back colors in newXfield. This allows us to optimize and use
1513 * a single ambient-diffuse color for the surface by multiplying the
1514 * diffuse into the surface color and using kamb/kdiff*AmbientLightColor
1515 * for the ambient light.
1516 *
1517 * This won't work if the front and back material properties are different.
1518 * We'll revisit this when we have back colors
1519 *
1520 * Each port needs to apply the surface properties in one of three places
1521 * A global surface property. (If the port allows, this is how xgl,starbase
1522 * are done).
1523 * Apply the inverse of the coefs to the lights before each field.
1524 * Apply the coefs to the colors once (in this function) before coloring
1525 * surface.
1526 */
1527 static Error
_computeOnArray(double diffuse,double invertGamma,Array array,int items,Array * retArray,ArrayHandle * retHandle)1528 _computeOnArray(double diffuse, double invertGamma,
1529 Array array, int items,
1530 Array *retArray, ArrayHandle *retHandle)
1531 {
1532 float *data = NULL, *dataPtr = NULL, *retData = NULL;
1533 RGBColor scratch;
1534 int i;
1535
1536 ENTRY(("_computeOnArray(%f, %f, 0x%x, %d, 0x%x, 0x%x)",
1537 diffuse, invertGamma, array, items, retArray, retHandle));
1538
1539 *retArray = NULL;
1540 *retHandle = NULL;
1541
1542 if(DXGetArrayClass(array) == CLASS_CONSTANTARRAY) {
1543 if (!(*retArray = (Array)DXNewConstantArray(items, (Pointer)&scratch,
1544 TYPE_FLOAT, CATEGORY_REAL,
1545 1, 3)))
1546 goto error;
1547
1548
1549 if(!(data = (float *)DXGetConstantArrayData(array))) goto error;
1550 if(!(retData = (float *)DXGetConstantArrayData(*retArray))) goto error;
1551
1552 for(i=0 ; i < 3 ; i++) {
1553 retData[i] = ((*data <= 0.0 || diffuse <= 0.0) ? 0.0
1554 : pow(*data * diffuse, invertGamma));
1555 data++;
1556 }
1557 } else {
1558 if (!(*retArray = DXNewArray(TYPE_FLOAT, CATEGORY_REAL, 1, 3)))
1559 goto error;
1560 if (!DXAddArrayData(*retArray, 0, items, NULL))
1561 goto error;
1562
1563 if(!(retData = (float *) DXGetArrayData(*retArray))) goto error;
1564 if(diffuse <= 0)
1565 bzero(retData,sizeof(float) * 3 * items);
1566 else {
1567 if(!(dataPtr = data = (float *) DXGetArrayData(array))) goto error;
1568
1569 /* XXX
1570 * since all attempts at correcting GAMMA by using lighting is flawed
1571 * (incorrect if multiple lights, low light colors, intense colors for
1572 * different correction factors) we will only do the expensive pow function
1573 * for the constant color case, because this is both cheap and corrects
1574 * the more noticeable problems when a low intensity single color is picked.
1575 */
1576 #ifndef APPLY_GAMMA_TO_COLORS
1577 if(!diffuse)
1578 diffuse = pow(1./10000.,invertGamma);
1579 else
1580 diffuse = pow(diffuse,invertGamma);
1581
1582 invertGamma = 1.0;
1583 #endif
1584
1585 /* if the gamma is aprox 1.0, avoid the pow() function */
1586 if(invertGamma > .9 && invertGamma < 1.1) {
1587 for(i=0 ; i < 3 * items; i++) {
1588 *retData++ = ((*data <= 0.) ? 0.
1589 : (*data * diffuse));
1590 data++;
1591 }
1592 } else {
1593 for(i=0 ; i < 3 * items; i++) {
1594 *retData++ = ((*data <= 0.) ? 0.
1595 : pow(*data * diffuse, invertGamma));
1596 data++;
1597 }
1598 }
1599 if(DXGetArrayClass(array) != CLASS_ARRAY) {
1600 DXFree(dataPtr);
1601 dataPtr = NULL;
1602 }
1603 }
1604 }
1605 if(!(*retHandle = DXCreateArrayHandle(*retArray))) goto error;
1606 DXReference((dxObject)*retArray);
1607
1608 EXIT(("OK"));
1609 return OK;
1610
1611 error:
1612 if(DXGetArrayClass(array) != CLASS_ARRAY &&
1613 DXGetArrayClass(array) != CLASS_CONSTANTARRAY){
1614 if(dataPtr) DXFree(dataPtr);
1615 if(retData) DXFree(retData);
1616 }
1617 if(*retArray) DXDelete((dxObject)*retArray);
1618 if(*retHandle) DXFreeArrayHandle(*retHandle);
1619 *retArray = NULL;
1620 *retHandle = NULL;
1621
1622 EXIT(("ERROR"));
1623 return ERROR;
1624 }
1625
1626 static Error
_gammaCorrectColors(xfieldP xf,double gamma,int isLit)1627 _gammaCorrectColors(xfieldP xf, double gamma, int isLit)
1628 {
1629 hwFlags flags = _dxf_attributeFlags(_dxf_xfieldAttributes(xf));
1630 materialAttrP material = _dxf_attributeFrontMaterial(
1631 _dxf_xfieldAttributes(xf));
1632 float diffuse = material->diffuse;
1633 Array array;
1634 ArrayHandle arrayHandle;
1635
1636 ENTRY(("_gammaCorrectColors(0x%x, %f, %d)", xf, gamma, isLit));
1637
1638 TIMER("> _gammaCorrectColors ");
1639
1640 if(_dxf_isFlagsSet(flags,CORRECTED_COLORS)) {
1641 EXIT(("OK: CORRECTED_COLORS flag set"));
1642 return OK;
1643 }
1644
1645 if(_dxf_isFlagsSet(flags,SF_CONST_COEF_HELP))
1646 diffuse = 1.0;
1647
1648 if(gamma > .9 && gamma < 1.1 && diffuse > .9 && diffuse < 1.1) {
1649 EXIT(("gamma > .9 etc."));
1650 return OK;
1651 }
1652
1653 material->specular = ((material->specular <= 0.0) ? 0.0
1654 : pow(material->specular,1./gamma));
1655
1656 /* These have already been type checked in hwXfield.c:_XColors */
1657 if(xf->cmap_array) {
1658 if(! isLit)
1659 _computeOnArray(1.0,1./gamma,xf->cmap_array,xf->ncmap,
1660 &array,&arrayHandle);
1661 else if(diffuse)
1662 _computeOnArray(diffuse,1./gamma,xf->cmap_array,xf->ncmap,
1663 &array,&arrayHandle);
1664 else
1665 _computeOnArray(1./10000.,1./gamma,xf->cmap_array,xf->ncmap,
1666 &array,&arrayHandle);
1667 DXDelete((dxObject)xf->cmap_array);
1668 DXFreeArrayHandle(xf->cmap);
1669 xf->cmap_array = array;
1670 xf->cmap = arrayHandle;
1671 } else {
1672 if(! isLit)
1673 _computeOnArray(1.0,1./gamma,xf->fcolors_array,xf->nfcolors,
1674 &array,&arrayHandle);
1675 if(diffuse)
1676 _computeOnArray(diffuse,1./gamma,xf->fcolors_array,xf->nfcolors,
1677 &array,&arrayHandle);
1678 else
1679 _computeOnArray(1./10000.,1./gamma,xf->fcolors_array,xf->nfcolors,
1680 &array,&arrayHandle);
1681 /*
1682 * assume front and back colors are equal,
1683 * (see comment before this function)
1684 */
1685 DXDelete((dxObject)xf->fcolors_array);
1686 DXDelete((dxObject)xf->bcolors_array);
1687 DXFreeArrayHandle(xf->fcolors);
1688 DXFreeArrayHandle(xf->bcolors);
1689 xf->fcolors_array = array;
1690 xf->bcolors_array = array;
1691 xf->fcolors = arrayHandle;
1692 if(!(xf->bcolors = DXCreateArrayHandle(xf->bcolors_array))) goto error;
1693 DXReference((dxObject)xf->fcolors_array);
1694 DXReference((dxObject)xf->bcolors_array);
1695 }
1696
1697 _dxf_setFlags(flags,CORRECTED_COLORS);
1698
1699 TIMER("< _gammaCorrectColors ");
1700
1701 EXIT(("OK"));
1702 return OK;
1703 error:
1704
1705 TIMER("< _gammaCorrectColors ");
1706
1707 EXIT(("ERROR"));
1708 return ERROR;
1709 }
1710
1711 Error
_dxf_getHwXfieldClipPlanes(xfieldO xo,int * nClips,Point ** pts,Vector ** vecs)1712 _dxf_getHwXfieldClipPlanes(xfieldO xo, int *nClips, Point **pts, Vector **vecs)
1713 {
1714 xfieldP xf = (xfieldP)_dxf_getHwObjectData((dxObject)xo);
1715 if (! xf)
1716 return ERROR;
1717
1718 *nClips = xf->nClips;
1719 *pts = xf->clipPts;
1720 *vecs = xf->clipVecs;
1721
1722 return OK;
1723 }
1724
1725 Error
_dxf_setHwXfieldClipPlanes(xfieldO xo,int nClips,Point * pts,Vector * vecs)1726 _dxf_setHwXfieldClipPlanes(xfieldO xo, int nClips, Point *pts, Vector *vecs)
1727 {
1728 int i;
1729 xfieldP xf = (xfieldP)_dxf_getHwObjectData((dxObject)xo);
1730 if (! xf)
1731 return ERROR;
1732
1733 if (! nClips)
1734 {
1735 xf->nClips = 0;
1736 xf->clipPts = NULL;
1737 xf->clipVecs = NULL;
1738 }
1739
1740 xf->clipPts = (Point *)DXAllocate(nClips * sizeof(Point));
1741 xf->clipVecs = (Vector *)DXAllocate(nClips * sizeof(Vector));
1742 if (! xf->clipPts || ! xf->clipVecs)
1743 return ERROR;
1744
1745 xf->nClips = nClips;
1746
1747 for (i = 0; i < nClips; i++)
1748 {
1749 xf->clipPts[i] = pts[i];
1750 xf->clipVecs[i] = vecs[i];
1751 }
1752
1753 return OK;
1754 }
1755
1756