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