1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkChooserPainter.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 #include "vtkChooserPainter.h"
16 
17 #include "vtkCommand.h"
18 #include "vtkConfigure.h"
19 #include "vtkGarbageCollector.h"
20 #include "vtkInformation.h"
21 #include "vtkLinesPainter.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPointData.h"
24 #include "vtkPointsPainter.h"
25 #include "vtkPolyData.h"
26 #include "vtkPolygonsPainter.h"
27 #include "vtkProperty.h"
28 #include "vtkRenderer.h"
29 #include "vtkStandardPolyDataPainter.h"
30 #include "vtkTStripsPainter.h"
31 
32 vtkStandardNewMacro(vtkChooserPainter);
33 
34 vtkCxxSetObjectMacro(vtkChooserPainter, VertPainter, vtkPolyDataPainter);
35 vtkCxxSetObjectMacro(vtkChooserPainter, LinePainter, vtkPolyDataPainter);
36 vtkCxxSetObjectMacro(vtkChooserPainter, PolyPainter, vtkPolyDataPainter);
37 vtkCxxSetObjectMacro(vtkChooserPainter, StripPainter, vtkPolyDataPainter);
38 
39 //-----------------------------------------------------------------------------
vtkChooserPainter()40 vtkChooserPainter::vtkChooserPainter()
41 {
42   this->VertPainter = NULL;
43   this->LinePainter = NULL;
44   this->PolyPainter = NULL;
45   this->StripPainter = NULL;
46   this->LastRenderer = NULL;
47   this->UseLinesPainterForWireframes = 0;
48 #if defined(__APPLE__) && (defined(VTK_USE_CARBON) || defined(VTK_USE_COCOA))
49   /*
50    * On some Macs, glPolygonMode(*,GL_LINE) does not render anything
51    * for polys. To fix this, we use the GL_LINE_LOOP to render the polygons.
52    */
53 //  this->UseLinesPainterForWireframes = 1;
54 #endif
55 }
56 
57 //-----------------------------------------------------------------------------
~vtkChooserPainter()58 vtkChooserPainter::~vtkChooserPainter()
59 {
60 
61   if (this->VertPainter) this->VertPainter->Delete();
62   if (this->LinePainter) this->LinePainter->Delete();
63   if (this->PolyPainter) this->PolyPainter->Delete();
64   if (this->StripPainter) this->StripPainter->Delete();
65 }
66 
67 /*
68 //-----------------------------------------------------------------------------
69 void vtkChooserPainter::ReleaseGraphicsResources(vtkWindow* w)
70 {
71   if (this->VertPainter)
72     {
73     this->VertPainter->ReleaseGraphicsResources(w);
74     }
75   if (this->LinePainter)
76     {
77     this->LinePainter->ReleaseGraphicsResources(w);
78     }
79   if (this->PolyPainter)
80     {
81     this->PolyPainter->ReleaseGraphicsResources(w);
82     }
83   if (this->StripPainter)
84     {
85     this->StripPainter->ReleaseGraphicsResources(w);
86     }
87   this->Superclass::ReleaseGraphicsResources(w);
88 }
89 */
90 //-----------------------------------------------------------------------------
ReportReferences(vtkGarbageCollector * collector)91 void vtkChooserPainter::ReportReferences(vtkGarbageCollector *collector)
92 {
93   this->Superclass::ReportReferences(collector);
94 
95   vtkGarbageCollectorReport(collector, this->VertPainter, "Vert Painter");
96   vtkGarbageCollectorReport(collector, this->LinePainter, "Line Painter");
97   vtkGarbageCollectorReport(collector, this->PolyPainter, "Poly Painter");
98   vtkGarbageCollectorReport(collector, this->StripPainter, "Strip Painter");
99 }
100 
101 //-----------------------------------------------------------------------------
PrepareForRendering(vtkRenderer * ren,vtkActor * actor)102 void vtkChooserPainter::PrepareForRendering(vtkRenderer* ren, vtkActor* actor)
103 {
104   // Ensure that the renderer chain is up-to-date.
105   if (this->PaintersChoiceTime < this->MTime ||
106     this->PaintersChoiceTime < this->Information->GetMTime() ||
107     this->LastRenderer != ren ||
108     this->PaintersChoiceTime < this->GetInput()->GetMTime())
109     {
110     this->LastRenderer = ren;
111     // Choose the painters.
112     this->ChoosePainters(ren, actor);
113     // Pass them the information and poly data we have.
114     this->UpdateChoosenPainters();
115     this->PaintersChoiceTime.Modified();
116     }
117   this->Superclass::PrepareForRendering(ren, actor);
118 }
119 
120 //-----------------------------------------------------------------------------
UpdateChoosenPainters()121 void vtkChooserPainter::UpdateChoosenPainters()
122 {
123   if (this->VertPainter)
124     {
125     this->PassInformation(this->VertPainter);
126     }
127   if (this->LinePainter)
128     {
129     this->PassInformation(this->LinePainter);
130     }
131   if (this->PolyPainter)
132     {
133     this->PassInformation(this->PolyPainter);
134     }
135   if (this->StripPainter)
136     {
137     this->PassInformation(this->StripPainter);
138     }
139 }
140 
141 //-----------------------------------------------------------------------------
ChoosePainters(vtkRenderer * renderer,vtkActor * actor)142 void vtkChooserPainter::ChoosePainters(vtkRenderer *renderer, vtkActor* actor)
143 {
144   const char *vertpaintertype;
145   const char *linepaintertype;
146   const char *polypaintertype;
147   const char *strippaintertype;
148 
149   vtkPolyDataPainter* painter;
150 
151   this->SelectPainters(renderer, actor, vertpaintertype, linepaintertype,
152                        polypaintertype, strippaintertype);
153   vtkDebugMacro(<< "Selected " << vertpaintertype << ", "
154                 << linepaintertype << ", " << polypaintertype << ", "
155                 << strippaintertype);
156 
157   if (!this->VertPainter || !this->VertPainter->IsA(vertpaintertype))
158     {
159     painter = this->CreatePainter(vertpaintertype);
160     if (painter)
161       {
162       this->SetVertPainter(painter);
163       painter->Delete();
164       vtkStandardPolyDataPainter* sp = vtkStandardPolyDataPainter::New();
165       painter->SetDelegatePainter(sp);
166       sp->Delete();
167       }
168     }
169 
170   if (!this->LinePainter || !this->LinePainter->IsA(linepaintertype))
171     {
172     if (strcmp(vertpaintertype, linepaintertype) == 0)
173       {
174       this->SetLinePainter(this->VertPainter);
175       }
176     else
177       {
178       painter = this->CreatePainter(linepaintertype);
179       if (painter)
180         {
181         this->SetLinePainter(painter);
182         painter->Delete();
183         vtkStandardPolyDataPainter* sp = vtkStandardPolyDataPainter::New();
184         painter->SetDelegatePainter(sp);
185         sp->Delete();
186         }
187       }
188     }
189 
190   if (!this->PolyPainter || !this->PolyPainter->IsA(polypaintertype))
191     {
192     if (strcmp(vertpaintertype, polypaintertype) == 0)
193       {
194       this->SetPolyPainter(this->VertPainter);
195       }
196     else if (strcmp(linepaintertype, polypaintertype) == 0)
197       {
198       this->SetPolyPainter(this->LinePainter);
199       }
200     else
201       {
202       painter = this->CreatePainter(polypaintertype);
203       if (painter)
204         {
205         this->SetPolyPainter(painter);
206         painter->Delete();
207         vtkStandardPolyDataPainter* sp = vtkStandardPolyDataPainter::New();
208         painter->SetDelegatePainter(sp);
209         sp->Delete();
210         }
211       }
212     }
213 
214   if (!this->StripPainter || !this->StripPainter->IsA(strippaintertype))
215     {
216     if (strcmp(vertpaintertype, strippaintertype) == 0)
217       {
218       this->SetStripPainter(this->VertPainter);
219       }
220     else if (strcmp(linepaintertype, strippaintertype) == 0)
221       {
222       this->SetStripPainter(this->LinePainter);
223       }
224     else if (strcmp(polypaintertype, strippaintertype) == 0)
225       {
226       this->SetStripPainter(this->PolyPainter);
227       }
228     else
229       {
230       painter = this->CreatePainter(strippaintertype);
231       if (painter)
232         {
233         this->SetStripPainter(painter);
234         painter->Delete();
235         vtkStandardPolyDataPainter* sp = vtkStandardPolyDataPainter::New();
236         painter->SetDelegatePainter(sp);
237         sp->Delete();
238         }
239       }
240     }
241 }
242 
243 //-----------------------------------------------------------------------------
SelectPainters(vtkRenderer * vtkNotUsed (renderer),vtkActor * vtkNotUsed (actor),const char * & vertptype,const char * & lineptype,const char * & polyptype,const char * & stripptype)244 void vtkChooserPainter::SelectPainters(vtkRenderer *vtkNotUsed(renderer),
245     vtkActor* vtkNotUsed(actor), const char *&vertptype, const char *&lineptype,
246     const char *&polyptype, const char *&stripptype)
247 {
248   vertptype = "vtkPointsPainter";
249   lineptype = "vtkLinesPainter";
250   polyptype = "vtkPolygonsPainter";
251   stripptype = "vtkTStripsPainter";
252 }
253 
254 //-----------------------------------------------------------------------------
CreatePainter(const char * paintertype)255 vtkPolyDataPainter* vtkChooserPainter::CreatePainter(const char *paintertype)
256 {
257   vtkPolyDataPainter* p = 0;
258   if (strcmp(paintertype, "vtkPointsPainter") == 0)
259     {
260     p = vtkPointsPainter::New();
261     }
262   else if (strcmp(paintertype, "vtkLinesPainter") == 0)
263     {
264     p = vtkLinesPainter::New();
265     }
266   else if (strcmp(paintertype, "vtkPolygonsPainter") == 0)
267     {
268     p = vtkPolygonsPainter::New();
269     }
270   else if (strcmp(paintertype, "vtkTStripsPainter") == 0)
271     {
272     p = vtkTStripsPainter::New();
273     }
274   else
275     {
276     vtkErrorMacro("Cannot create painter " << paintertype);
277     return 0;
278     }
279   this->ObserverPainterProgress(p);
280   return p;
281 }
282 
283 //-----------------------------------------------------------------------------
RenderInternal(vtkRenderer * renderer,vtkActor * actor,unsigned long typeflags,bool forceCompileOnly)284 void vtkChooserPainter::RenderInternal(vtkRenderer* renderer, vtkActor* actor,
285                                        unsigned long typeflags,
286                                        bool forceCompileOnly)
287 {
288   vtkPolyData* pdInput = this->GetInputAsPolyData();
289   vtkIdType numVerts = pdInput->GetNumberOfVerts();
290   vtkIdType numLines = pdInput->GetNumberOfLines();
291   vtkIdType numPolys = pdInput->GetNumberOfPolys();
292   vtkIdType numStrips = pdInput->GetNumberOfStrips();
293 
294   vtkIdType total_cells = (typeflags & vtkPainter::VERTS)?
295     pdInput->GetNumberOfVerts() : 0;
296   total_cells += (typeflags & vtkPainter::LINES)?
297     pdInput->GetNumberOfLines() : 0;
298   total_cells += (typeflags & vtkPainter::POLYS)?
299     pdInput->GetNumberOfPolys() : 0;
300   total_cells += (typeflags & vtkPainter::STRIPS)?
301     pdInput->GetNumberOfStrips() : 0;
302 
303   if (total_cells == 0)
304     {
305     // nothing to render.
306     return;
307     }
308 
309   this->ProgressOffset = 0.0;
310   this->TimeToDraw = 0.0;
311   if ((typeflags & vtkPainter::VERTS) && numVerts>0 )
312     {
313     //cout << this << "Verts" << endl;
314     this->ProgressScaleFactor = static_cast<double>(numVerts)/total_cells;
315     this->VertPainter->Render(renderer, actor, vtkPainter::VERTS,
316                               forceCompileOnly);
317     this->TimeToDraw += this->VertPainter->GetTimeToDraw();
318     this->ProgressOffset += this->ProgressScaleFactor;
319     }
320 
321   if ((typeflags & vtkPainter::LINES) && numLines>0 )
322     {
323     //cout << this << "Lines" << endl;
324     this->ProgressScaleFactor = static_cast<double>(numLines)/total_cells;
325     this->LinePainter->Render(renderer, actor, vtkPainter::LINES,
326                               forceCompileOnly);
327     this->TimeToDraw += this->LinePainter->GetTimeToDraw();
328     this->ProgressOffset += this->ProgressScaleFactor;
329     }
330 
331 
332   if ((typeflags & vtkPainter::POLYS) && numPolys>0 )
333     {
334     //cout << this << "Polys" << endl;
335     this->ProgressScaleFactor = static_cast<double>(numPolys)/total_cells;
336     if (   this->UseLinesPainterForWireframes
337         && (actor->GetProperty()->GetRepresentation() == VTK_WIREFRAME)
338         && !actor->GetProperty()->GetBackfaceCulling()
339         && !actor->GetProperty()->GetFrontfaceCulling()
340         && !this->GetInputAsPolyData()->GetPointData()->GetAttribute(
341                                                vtkDataSetAttributes::EDGEFLAG) )
342       {
343       this->LinePainter->Render(renderer, actor, vtkPainter::POLYS,
344         forceCompileOnly);
345       this->TimeToDraw += this->LinePainter->GetTimeToDraw();
346       }
347     else
348       {
349       this->PolyPainter->Render(renderer, actor, vtkPainter::POLYS,
350         forceCompileOnly);
351       this->TimeToDraw += this->PolyPainter->GetTimeToDraw();
352       }
353     this->ProgressOffset += this->ProgressScaleFactor;
354     }
355 
356   if ((typeflags & vtkPainter::STRIPS) && numStrips>0 )
357     {
358     //cout << this << "Strips" << endl;
359     this->ProgressScaleFactor = static_cast<double>(numStrips)/total_cells;
360     this->StripPainter->Render(renderer, actor, vtkPainter::STRIPS,
361                                forceCompileOnly);
362     this->TimeToDraw += this->StripPainter->GetTimeToDraw();
363     }
364   this->Superclass::RenderInternal(renderer, actor, typeflags,forceCompileOnly);
365 }
366 
367 //-----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)368 void vtkChooserPainter::PrintSelf(ostream &os, vtkIndent indent)
369 {
370   this->Superclass::PrintSelf(os, indent);
371 
372   os << indent << "VertPainter: " << this->VertPainter << endl;
373   os << indent << "LinePainter: " << this->LinePainter << endl;
374   os << indent << "PolyPainter: " << this->PolyPainter << endl;
375   os << indent << "StripPainter: " << this->StripPainter << endl;
376   os << indent << "UseLinesPainterForWireframes: "
377     << this->UseLinesPainterForWireframes << endl;
378 }
379