1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkTStripsPainter.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkTStripsPainter.h"
17
18 #include "vtkCellArray.h"
19 #include "vtkCellData.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPainterDeviceAdapter.h"
22 #include "vtkPoints.h"
23 #include "vtkPointData.h"
24 #include "vtkPolyData.h"
25 #include "vtkProperty.h"
26 #include "vtkRenderer.h"
27 #include "vtkRenderWindow.h"
28 #include "vtkTriangle.h"
29 #include "vtkUnsignedCharArray.h"
30
31 #include "vtkTimerLog.h"
32
33 vtkStandardNewMacro(vtkTStripsPainter);
34 //-----------------------------------------------------------------------------
vtkTStripsPainter()35 vtkTStripsPainter::vtkTStripsPainter()
36 {
37 this->SetSupportedPrimitive(vtkPainter::STRIPS);
38 }
39
40 //-----------------------------------------------------------------------------
~vtkTStripsPainter()41 vtkTStripsPainter::~vtkTStripsPainter()
42 {
43 }
44
45 //-----------------------------------------------------------------------------
46 #define vtkDrawPolysMacro(prim,glVertFuncs,glCellFuncs,glInitFuncs) \
47 { \
48 vtkIdType nPts; unsigned short count = 0; \
49 glInitFuncs \
50 while (ptIds < endPtIds) \
51 { \
52 nPts = *ptIds; \
53 ++ptIds; \
54 device->BeginPrimitive(prim);\
55 glCellFuncs \
56 while (nPts > 0) \
57 { \
58 glVertFuncs \
59 ++ptIds; \
60 --nPts; \
61 } \
62 if (++count == 10000) \
63 { \
64 cellNum += 10000; \
65 count = 0; \
66 this->UpdateProgress(static_cast<double>(cellNum-cellNumStart)/totalCells); \
67 if (ren->GetRenderWindow()->CheckAbortStatus()) \
68 { \
69 break; \
70 } \
71 } \
72 device->EndPrimitive(); \
73 } \
74 cellNum += count; \
75 }
76
77 //-----------------------------------------------------------------------------
78 // fix refs here
79 #define TStripNormal \
80 if ( vcount > 2) \
81 { \
82 if (vcount % 2) \
83 { \
84 normIdx[0] = ptIds[-2]; normIdx[1] = ptIds[0]; normIdx[2] = ptIds[-1]; \
85 vtkTriangle::ComputeNormal(p, 3, normIdx, polyNorm); \
86 } \
87 else \
88 { \
89 normIdx[0] = ptIds[-2]; normIdx[1] = ptIds[-1]; normIdx[2] = ptIds[0]; \
90 vtkTriangle::ComputeNormal(p, 3, normIdx, polyNorm); \
91 } \
92 device->SendAttribute(vtkPointData::NORMALS, 3,\
93 VTK_DOUBLE, polyNorm); \
94 } \
95 vcount++;
96
97 //-----------------------------------------------------------------------------
98 #define TStripNormalStart \
99 vtkTriangle::ComputeNormal(p, 3, ptIds, polyNorm); \
100 device->SendAttribute(vtkPointData::NORMALS, 3,\
101 VTK_DOUBLE, polyNorm); int vcount = 0;
102
103 //-----------------------------------------------------------------------------
RenderPrimitive(unsigned long idx,vtkDataArray * n,vtkUnsignedCharArray * c,vtkDataArray * t,vtkRenderer * ren)104 int vtkTStripsPainter::RenderPrimitive(unsigned long idx, vtkDataArray* n,
105 vtkUnsignedCharArray* c, vtkDataArray* t, vtkRenderer* ren)
106 {
107 vtkPolyData* pd = this->GetInputAsPolyData();
108 vtkPoints* p = pd->GetPoints();
109 vtkCellArray* ca = pd->GetStrips();
110 vtkIdType cellNum = pd->GetNumberOfVerts() +
111 pd->GetNumberOfLines() + pd->GetNumberOfPolys();
112 vtkIdType cellNumStart = cellNum;
113 vtkIdType totalCells = ca->GetNumberOfCells();
114
115 vtkPainterDeviceAdapter* device = ren->GetRenderWindow()->
116 GetPainterDeviceAdapter();
117 void *points = p->GetVoidPointer(0);
118 void *normals = 0;
119 void *tcoords = 0;
120 unsigned char *colors = 0;
121 double polyNorm[3];
122 vtkIdType normIdx[3];
123
124 int rep = VTK_TRIANGLE_STRIP;
125
126 if (ca->GetNumberOfCells() == 0)
127 {
128 return 1;
129 }
130 if (n)
131 {
132 normals = n->GetVoidPointer(0);
133 }
134 if (c)
135 {
136 colors = c->GetPointer(0);
137 }
138 if (t)
139 {
140 tcoords = t->GetVoidPointer(0);
141 }
142 vtkIdType *ptIds = ca->GetPointer();
143 vtkIdType *endPtIds = ptIds + ca->GetNumberOfConnectivityEntries();
144
145 int ptype = p->GetDataType();
146 int ntype = (n)? n->GetDataType() : 0;
147 int ttype = (t)? t->GetDataType() : 0;
148 int tcomps = (t)? t->GetNumberOfComponents() : 0;
149
150 // Ignore edge flags.
151 idx &= (~VTK_PDM_EDGEFLAGS);
152
153 // draw all the elements, use fast path if available
154 switch (idx)
155 {
156 case 0:
157 if (this->BuildNormals)
158 {
159 vtkDrawPolysMacro(rep,
160 TStripNormal;
161 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
162 ptype, points, 3**ptIds);,
163 TStripNormalStart,;);
164 }
165 else
166 {
167 vtkDrawPolysMacro(rep,
168 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
169 ptype, points, 3**ptIds);,
170 ;,;);
171 }
172 break;
173 case VTK_PDM_NORMALS:
174 vtkDrawPolysMacro(rep,
175 device->SendAttribute(vtkPointData::NORMALS, 3,
176 ntype, normals, 3**ptIds);
177 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
178 ptype, points, 3**ptIds);,;,;);
179 break;
180 case VTK_PDM_COLORS:
181 if (this->BuildNormals)
182 {
183 vtkDrawPolysMacro(rep,
184 TStripNormal
185 device->SendAttribute(vtkPointData::SCALARS, 4,
186 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
187 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
188 ptype, points, 3**ptIds);,
189 TStripNormalStart,;);
190 }
191 else
192 {
193 vtkDrawPolysMacro(rep,
194 device->SendAttribute(vtkPointData::SCALARS, 4,
195 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
196 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
197 ptype, points, 3**ptIds);,
198 ;,;);
199 }
200 break;
201 case VTK_PDM_COLORS | VTK_PDM_OPAQUE_COLORS:
202 if (this->BuildNormals)
203 {
204
205 vtkDrawPolysMacro(rep,
206 TStripNormal
207 device->SendAttribute(vtkPointData::SCALARS, 3,
208 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
209 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
210 ptype, points, 3**ptIds);,
211 TStripNormalStart,;);
212
213 }
214 else
215 {
216 vtkDrawPolysMacro(rep,
217 device->SendAttribute(vtkPointData::SCALARS, 3,
218 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
219 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
220 ptype, points, 3**ptIds);,
221 ;,;);
222 }
223 break;
224 case VTK_PDM_NORMALS | VTK_PDM_COLORS:
225 vtkDrawPolysMacro(rep,
226 device->SendAttribute(vtkPointData::NORMALS, 3,
227 ntype, normals, 3**ptIds);
228 device->SendAttribute(vtkPointData::SCALARS, 4,
229 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
230 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
231 ptype, points, 3**ptIds);,;,;);
232 break;
233 case VTK_PDM_NORMALS | VTK_PDM_COLORS | VTK_PDM_OPAQUE_COLORS:
234 vtkDrawPolysMacro(rep,
235 device->SendAttribute(vtkPointData::NORMALS, 3,
236 ntype, normals, 3**ptIds);
237 device->SendAttribute(vtkPointData::SCALARS, 3,
238 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
239 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
240 ptype, points, 3**ptIds);,;,;);
241 break;
242 case VTK_PDM_NORMALS | VTK_PDM_TCOORDS:
243 vtkDrawPolysMacro(rep,
244 device->SendAttribute(vtkPointData::NORMALS, 3,
245 ntype, normals, 3**ptIds);
246 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
247 ttype, tcoords, tcomps**ptIds);
248 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
249 ptype, points, 3**ptIds);,;,;);
250 break;
251 case VTK_PDM_COLORS | VTK_PDM_TCOORDS:
252 if (this->BuildNormals)
253 {
254 vtkDrawPolysMacro(rep,
255 TStripNormal
256 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
257 ttype, tcoords, tcomps**ptIds);
258 device->SendAttribute(vtkPointData::SCALARS, 4,
259 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
260 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
261 ptype, points, 3**ptIds);,
262 TStripNormalStart,;);
263 }
264 else
265 {
266 vtkDrawPolysMacro(rep,
267 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
268 ttype, tcoords, tcomps**ptIds);
269 device->SendAttribute(vtkPointData::SCALARS, 4,
270 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
271 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
272 ptype, points, 3**ptIds);,
273 ;,;);
274 }
275 break;
276 case VTK_PDM_COLORS | VTK_PDM_OPAQUE_COLORS | VTK_PDM_TCOORDS:
277 if (this->BuildNormals)
278 {
279 vtkDrawPolysMacro(rep,
280 TStripNormal
281 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
282 ttype, tcoords, tcomps**ptIds);
283 device->SendAttribute(vtkPointData::SCALARS, 3,
284 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
285 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
286 ptype, points, 3**ptIds);,
287 TStripNormalStart,;);
288 }
289 else
290 {
291 vtkDrawPolysMacro(rep,
292 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
293 ttype, tcoords, tcomps**ptIds);
294 device->SendAttribute(vtkPointData::SCALARS, 3,
295 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
296 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
297 ptype, points, 3**ptIds);,
298 ;,;);
299 }
300 break;
301 case VTK_PDM_NORMALS | VTK_PDM_COLORS | VTK_PDM_TCOORDS:
302 vtkDrawPolysMacro(rep,
303 device->SendAttribute(vtkPointData::NORMALS, 3,
304 ntype, normals, 3**ptIds);
305 device->SendAttribute(vtkPointData::SCALARS, 4,
306 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
307 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
308 ttype, tcoords, tcomps**ptIds);
309 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
310 ptype, points, 3**ptIds);,;,;);
311 break;
312 case VTK_PDM_NORMALS | VTK_PDM_COLORS | VTK_PDM_OPAQUE_COLORS |
313 VTK_PDM_TCOORDS:
314 vtkDrawPolysMacro(rep,
315 device->SendAttribute(vtkPointData::NORMALS, 3,
316 ntype, normals, 3**ptIds);
317 device->SendAttribute(vtkPointData::SCALARS, 3,
318 VTK_UNSIGNED_CHAR, colors + (*ptIds<<2));
319 device->SendAttribute(vtkPointData::TCOORDS, tcomps,
320 ttype, tcoords, tcomps**ptIds);
321 device->SendAttribute(vtkPointData::NUM_ATTRIBUTES, 3,
322 ptype, points, 3**ptIds);,;,;);
323 break;
324 default:
325 return 0; // let delegate painter process this render.
326 }
327 return 1;
328 }
329
330 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)331 void vtkTStripsPainter::PrintSelf(ostream& os, vtkIndent indent)
332 {
333 this->Superclass::PrintSelf(os, indent);
334
335 }
336