1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkCompositePainter.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 "vtkCompositePainter.h"
16
17 #include "vtkColor.h"
18 #include "vtkCompositeDataDisplayAttributes.h"
19 #include "vtkCompositeDataIterator.h"
20 #include "vtkCompositeDataSet.h"
21 #include "vtkGarbageCollector.h"
22 #include "vtkHardwareSelector.h"
23 #include "vtkInformation.h"
24 #include "vtkInformationObjectBaseKey.h"
25 #include "vtkMultiBlockDataSet.h"
26 #include "vtkMultiPieceDataSet.h"
27 #include "vtkObjectFactory.h"
28 #include "vtkPolyData.h"
29 #include "vtkProperty.h"
30 #include "vtkRenderer.h"
31 #include "vtkRenderWindow.h"
32
33 #include <cassert>
34
35 // Return NULL if no override is supplied.
36 vtkAbstractObjectFactoryNewMacro(vtkCompositePainter)
37
38 vtkInformationKeyMacro(vtkCompositePainter, DISPLAY_ATTRIBUTES, ObjectBase);
39 vtkCxxSetObjectMacro(vtkCompositePainter, CompositeDataDisplayAttributes, vtkCompositeDataDisplayAttributes);
40 //----------------------------------------------------------------------------
vtkCompositePainter()41 vtkCompositePainter::vtkCompositePainter()
42 {
43 this->OutputData = 0;
44 this->CompositeDataDisplayAttributes = 0;
45 }
46
47 //----------------------------------------------------------------------------
~vtkCompositePainter()48 vtkCompositePainter::~vtkCompositePainter()
49 {
50 this->SetCompositeDataDisplayAttributes(0);
51 }
52
53 //----------------------------------------------------------------------------
GetOutput()54 vtkDataObject* vtkCompositePainter::GetOutput()
55 {
56 return this->OutputData? this->OutputData : this->GetInput();
57 }
58
59 //----------------------------------------------------------------------------
RenderInternal(vtkRenderer * renderer,vtkActor * actor,unsigned long typeflags,bool forceCompileOnly)60 void vtkCompositePainter::RenderInternal(vtkRenderer* renderer,
61 vtkActor* actor,
62 unsigned long typeflags,
63 bool forceCompileOnly)
64 {
65 vtkCompositeDataSet* input = vtkCompositeDataSet::SafeDownCast(this->GetInput());
66 if (!input || !this->DelegatePainter)
67 {
68 this->Superclass::RenderInternal(renderer, actor, typeflags,
69 forceCompileOnly);
70 return;
71 }
72
73 vtkHardwareSelector* selector = renderer->GetSelector();
74
75 if (this->CompositeDataDisplayAttributes &&
76 (this->CompositeDataDisplayAttributes->HasBlockOpacities() ||
77 this->CompositeDataDisplayAttributes->HasBlockVisibilities() ||
78 this->CompositeDataDisplayAttributes->HasBlockColors()))
79 {
80 vtkProperty* prop = actor->GetProperty();
81 RenderBlockState state;
82
83 // Push base-values on the state stack.
84 state.Visibility.push(true);
85 state.Opacity.push(prop->GetOpacity());
86 state.AmbientColor.push(vtkColor3d(prop->GetAmbientColor()));
87 state.DiffuseColor.push(vtkColor3d(prop->GetDiffuseColor()));
88 state.SpecularColor.push(vtkColor3d(prop->GetSpecularColor()));
89
90 // OpenGL currently knows how to render *this* state.
91 state.RenderedOpacity = state.Opacity.top();
92 state.RenderedAmbientColor = state.AmbientColor.top();
93 state.RenderedDiffuseColor = state.DiffuseColor.top();
94 state.RenderedSpecularColor = state.SpecularColor.top();
95
96 // render using the composite data attributes
97 unsigned int flat_index = 0;
98 this->RenderBlock(renderer,
99 actor,
100 typeflags,
101 forceCompileOnly,
102 input,
103 flat_index,
104 state);
105
106 // restore OpenGL state, if it was changed.
107 this->UpdateRenderingState(renderer->GetRenderWindow(), actor->GetProperty(), state);
108 }
109 else
110 {
111 // render using the multi-block structure itself
112 vtkCompositeDataIterator* iter = input->NewIterator();
113 for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
114 {
115 vtkDataObject* dobj = iter->GetCurrentDataObject();
116 if (dobj)
117 {
118 if (selector)
119 {
120 selector->BeginRenderProp();
121 // If hardware selection is in progress, we need to pass the composite
122 // index to the selection framework,
123 selector->RenderCompositeIndex(iter->GetCurrentFlatIndex());
124 }
125
126 this->DelegatePainter->SetInput(dobj);
127 this->OutputData = dobj;
128 this->Superclass::RenderInternal(renderer, actor, typeflags,
129 forceCompileOnly);
130 this->OutputData = 0;
131
132 if (selector)
133 {
134 selector->EndRenderProp();
135 }
136 }
137 }
138 iter->Delete();
139 }
140 }
141
142 //-----------------------------------------------------------------------------
RenderBlock(vtkRenderer * renderer,vtkActor * actor,unsigned long typeflags,bool forceCompileOnly,vtkDataObject * dobj,unsigned int & flat_index,vtkCompositePainter::RenderBlockState & state)143 void vtkCompositePainter::RenderBlock(vtkRenderer *renderer,
144 vtkActor *actor,
145 unsigned long typeflags,
146 bool forceCompileOnly,
147 vtkDataObject *dobj,
148 unsigned int &flat_index,
149 vtkCompositePainter::RenderBlockState &state)
150 {
151 assert("Sanity Check" &&
152 (state.Visibility.size() > 0) &&
153 (state.Opacity.size() > 0) &&
154 (state.AmbientColor.size() > 0) &&
155 (state.DiffuseColor.size() > 0) &&
156 (state.SpecularColor.size() > 0));
157
158 vtkHardwareSelector *selector = renderer->GetSelector();
159 vtkProperty *property = actor->GetProperty();
160 vtkCompositeDataDisplayAttributes* cda = this->CompositeDataDisplayAttributes;
161
162 // A block always *has* a visibility state, either explicitly set or
163 // inherited.
164 state.Visibility.push(
165 cda->HasBlockVisibility(flat_index) ?
166 cda->GetBlockVisibility(flat_index) : state.Visibility.top());
167
168 bool overrides_opacity = cda->HasBlockOpacity(flat_index);
169 if (overrides_opacity)
170 {
171 state.Opacity.push(cda->GetBlockOpacity(flat_index));
172 }
173
174 bool overrides_color = cda->HasBlockColor(flat_index);
175 if (overrides_color)
176 {
177 vtkColor3d color = cda->GetBlockColor(flat_index);
178 state.AmbientColor.push(color);
179 state.DiffuseColor.push(color);
180 state.SpecularColor.push(color);
181 }
182
183 unsigned int my_flat_index = flat_index;
184 // Advance flat-index. After this point, flat_index no longer points to this
185 // block.
186 flat_index++;
187
188 vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj);
189 vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj);
190 if (mbds || mpds)
191 {
192 unsigned int numChildren = mbds? mbds->GetNumberOfBlocks() :
193 mpds->GetNumberOfPieces();
194 for (unsigned int cc=0 ; cc < numChildren; cc++)
195 {
196 vtkDataObject* child = mbds ? mbds->GetBlock(cc) : mpds->GetPiece(cc);
197 if (child == NULL)
198 {
199 // speeds things up when dealing with NULL blocks (which is common with
200 // AMRs).
201 flat_index++;
202 continue;
203 }
204 this->RenderBlock(renderer, actor, typeflags, forceCompileOnly,
205 child, flat_index, state);
206 }
207 }
208 else if (dobj && state.Visibility.top() == true && state.Opacity.top() > 0.0)
209 {
210 // Implies that the block is a non-null leaf node.
211 // The top of the "stacks" have the state that this block must be rendered
212 // with.
213 if (selector)
214 {
215 selector->BeginRenderProp();
216 selector->RenderCompositeIndex(my_flat_index);
217 }
218 else
219 {
220 // Not selecting, render the colors and stuff correctly for this block.
221 // For that.
222 this->UpdateRenderingState(renderer->GetRenderWindow(), property, state);
223 }
224
225 this->DelegatePainter->SetInput(dobj);
226 this->OutputData = dobj;
227 this->Superclass::RenderInternal(renderer, actor, typeflags, forceCompileOnly);
228 this->OutputData = 0;
229 if (selector)
230 {
231 selector->EndRenderProp();
232 }
233 }
234
235 if (overrides_color)
236 {
237 state.AmbientColor.pop();
238 state.DiffuseColor.pop();
239 state.SpecularColor.pop();
240 }
241 if (overrides_opacity)
242 {
243 state.Opacity.pop();
244 }
245 state.Visibility.pop();
246 }
247
248 //-----------------------------------------------------------------------------
ReportReferences(vtkGarbageCollector * collector)249 void vtkCompositePainter::ReportReferences(vtkGarbageCollector *collector)
250 {
251 this->Superclass::ReportReferences(collector);
252
253 vtkGarbageCollectorReport(collector, this->OutputData, "Output");
254 }
255
256 //----------------------------------------------------------------------------
ProcessInformation(vtkInformation * info)257 void vtkCompositePainter::ProcessInformation(vtkInformation* info)
258 {
259 this->Superclass::ProcessInformation(info);
260
261 if (info->Has(DISPLAY_ATTRIBUTES()))
262 {
263 this->SetCompositeDataDisplayAttributes(
264 vtkCompositeDataDisplayAttributes::SafeDownCast(
265 info->Get(DISPLAY_ATTRIBUTES())));
266 }
267 }
268
269 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)270 void vtkCompositePainter::PrintSelf(ostream& os, vtkIndent indent)
271 {
272 this->Superclass::PrintSelf(os, indent);
273
274 os << indent << "CompositeDataDisplayAttributes: " ;
275 if (this->CompositeDataDisplayAttributes)
276 {
277 os << endl;
278 this->CompositeDataDisplayAttributes->PrintSelf(os, indent.GetNextIndent());
279 }
280 else
281 {
282 os << "(none)" << endl;
283 }
284 }
285