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