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 
12 #include "hwDeclarations.h"
13 #include "hwXfield.h"
14 #include "hwSort.h"
15 
16 SortList
_dxf_newSortList()17 _dxf_newSortList()
18 {
19     SortListP sl = DXAllocate(sizeof(struct sortList));
20     if (sl)
21     {
22 	sl->sortBlockList = NULL;
23 	sl->sortList = NULL;
24 	sl->itemCount = 0;
25 	sl->sortListLength = 0;
26     }
27 
28     return (SortList)sl;
29 }
30 
31 void
_dxf_clearSortList(SortList sl)32 _dxf_clearSortList(SortList sl)
33 {
34     SortListP slp = (SortListP)sl;
35     SortBlock tmp = slp->sortBlockList;
36 
37     while (tmp)
38     {
39 	SortBlock bye = tmp;
40 	tmp = tmp->next;
41 	DXFree(bye);
42     }
43 
44     slp->sortBlockList = NULL;
45     slp->itemCount = 0;
46 }
47 
_dxf_deleteSortList(SortList sl)48 void _dxf_deleteSortList(SortList sl)
49 {
50     SortListP slp = (SortListP)sl;
51     _dxf_clearSortList(sl);
52     if (slp->sortList)
53 	DXFree((Pointer)slp->sortList);
54     DXFree((Pointer)sl);
55 }
56 
57 int
_dxf_Insert_Translucent(SortList sl,void * xfp,int i)58 _dxf_Insert_Translucent(SortList sl, void *xfp, int i)
59 {
60     SortListP slp = (SortListP)sl;
61     Sort next;
62 
63     if (!slp->sortBlockList || slp->sortBlockList->numUsed == DXHW_TLIST_BLOCKSIZE)
64     {
65 	SortBlock tmp = DXAllocate(sizeof(struct sortBlock));
66 	if (! tmp)
67 	    return 0;
68 
69 	tmp->next = slp->sortBlockList;
70 	tmp->numUsed = 0;
71 	slp->sortBlockList = tmp;
72     }
73 
74     next = slp->sortBlockList->list + slp->sortBlockList->numUsed++;
75     next->xfp = xfp;
76     next->poly = i;
77 
78     slp->itemCount ++;
79 
80     return 1;
81 }
82 
83 #define LT(a,b)         ((a)->depth < (b)->depth)
84 #define GT(a,b)         ((a)->depth > (b)->depth)
85 #define TYPE            struct sortD
86 #define QUICKSORT       _dxf_DepthSort
87 #define QUICKSORT_LOCAL _dxf_DepthSortLocal
88 #include "../libdx/qsort.c"
89 #undef LT
90 #undef GT
91 #undef TYPE
92 #undef QUICKSORT
93 #undef QUICKSORT_LOCAL
94 
95 #define Apply_Z(poi, mat, res) \
96   res = mat[0][2]*poi[0] + mat[1][2]*poi[1] + mat[2][2]*poi[2] + mat[3][2];
97 
98 int
_dxf_Sort_Translucent(SortList sl)99 _dxf_Sort_Translucent(SortList sl)
100 {
101     SortListP slp = (SortListP)sl;
102     int       j;
103     SortBlock sbp;
104     SortD     sdp;
105     Sort      sp;
106 
107     if (slp->itemCount <= 0)
108 	return OK;
109 
110     if (!slp->sortList || slp->sortListLength < slp->itemCount)
111     {
112 	if (slp->sortList)
113 	    DXFree((Pointer)slp->sortList);
114 
115 	slp->sortList = DXAllocate(slp->itemCount * sizeof(struct sortD));
116 	if (! slp->sortList)
117 	    return ERROR;
118 
119 	slp->sortListLength = slp->itemCount;
120     }
121 
122     for (sdp = slp->sortList, sbp = slp->sortBlockList; sbp; sbp = sbp->next)
123     {
124         for (j = 0, sp = sbp->list; j < sbp->numUsed; j++, sdp++, sp++)
125 	{
126 	    int     cs[8];
127 	    int     *conn;
128 	    float   *vertex, center[3];
129 	    float   *vs[3];
130 	    int     k;
131 	    xfieldT *xf = (xfieldT *)sp->xfp;
132 
133 	    if (xf->connections)
134 	    {
135 		conn = (int *)DXGetArrayEntry(xf->connections,
136 				sp->poly, (Pointer)cs);
137 
138 		center[0] = center[1] = center[2] = 0.0;
139 		for (k = 0; k < xf->posPerConn; k++)
140 		{
141 		    vertex = (float *)DXGetArrayEntry(xf->positions,
142 					    conn[k], (Pointer)vs);
143 		    center[0] += vertex[0];
144 		    center[1] += vertex[1];
145 		    center[2] += vertex[2];
146 		}
147 
148 		switch(xf->posPerConn)
149 		{
150 		    case 0:
151 			DXSetError(ERROR_INTERNAL, "zero posPerConn??");
152 			return ERROR;
153 
154 		    case 1:
155 			break;
156 
157 		    case 2:
158 			center[0] *= 0.5;
159 			center[1] *= 0.5;
160 			center[2] *= 0.5;
161 			break;
162 
163 		    case 3:
164 			center[0] *= 0.33333333;
165 			center[1] *= 0.33333333;
166 			center[2] *= 0.33333333;
167 			break;
168 
169 		    case 4:
170 			center[0] *= 0.25;
171 			center[1] *= 0.25;
172 			center[2] *= 0.25;
173 			break;
174 
175 		    default:
176 			{
177 			    int   l;
178 			    float denom = 1.0 / xf->posPerConn;
179 			    for (l = 0; l < xf->posPerConn; l++)
180 			    {
181 				center[0] *= denom;
182 				center[1] *= denom;
183 				center[2] *= denom;
184 			    }
185 			}
186 			break;
187 		}
188 
189 		Apply_Z(center, xf->attributes.vm, sdp->depth);
190 	    }
191 	    else
192 	    {
193 		vertex = (float *)DXGetArrayEntry(xf->positions,
194 		                                     sp->poly, (Pointer)vs);
195 
196 		Apply_Z(vertex, xf->attributes.vm, sdp->depth);
197 	    }
198 
199 	    sdp->xfp   = sp->xfp;
200 	    sdp->poly  = sp->poly;
201 	}
202     }
203 
204     _dxf_DepthSort(slp->sortList, slp->itemCount);
205 
206     return OK;
207 }
208