1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkProp.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 "vtkProp.h"
16 #include "vtkObjectFactory.h"
17 #include "vtkAssemblyPaths.h"
18 #include "vtkCommand.h"
19 #include "vtkInformation.h"
20 #include "vtkInformationIterator.h"
21 #include "vtkInformationKey.h"
22 #include "vtkInformationIntegerKey.h"
23 #include "vtkInformationDoubleVectorKey.h"
24 #include <cassert>
25 
26 vtkCxxSetObjectMacro(vtkProp,PropertyKeys,vtkInformation);
27 
28 vtkInformationKeyMacro(vtkProp,GeneralTextureUnit,Integer);
29 vtkInformationKeyMacro(vtkProp,GeneralTextureTransform,DoubleVector);
30 
31 //----------------------------------------------------------------------------
32 // Creates an Prop with the following defaults: visibility on.
vtkProp()33 vtkProp::vtkProp()
34 {
35   this->Visibility = 1;  // ON
36 
37   this->Pickable   = 1;
38   this->Dragable   = 1;
39 
40   this->UseBounds=true;
41 
42   this->AllocatedRenderTime = 10.0;
43   this->EstimatedRenderTime = 0.0;
44   this->RenderTimeMultiplier = 1.0;
45 
46   this->Paths = nullptr;
47 
48   this->NumberOfConsumers = 0;
49   this->Consumers = nullptr;
50 
51   this->PropertyKeys=nullptr;
52 }
53 
54 //----------------------------------------------------------------------------
~vtkProp()55 vtkProp::~vtkProp()
56 {
57   if ( this->Paths )
58   {
59     this->Paths->Delete();
60   }
61 
62   delete [] this->Consumers;
63 
64   if(this->PropertyKeys!=nullptr)
65   {
66     this->PropertyKeys->Delete();
67   }
68 }
69 
70 //----------------------------------------------------------------------------
71 // This method is invoked if the prop is picked.
Pick()72 void vtkProp::Pick()
73 {
74   this->InvokeEvent(vtkCommand::PickEvent,nullptr);
75 }
76 
77 //----------------------------------------------------------------------------
78 // Shallow copy of vtkProp.
ShallowCopy(vtkProp * prop)79 void vtkProp::ShallowCopy(vtkProp *prop)
80 {
81   this->Visibility = prop->GetVisibility();
82   this->Pickable   = prop->GetPickable();
83   this->Dragable   = prop->GetDragable();
84 }
85 
86 //----------------------------------------------------------------------------
InitPathTraversal()87 void vtkProp::InitPathTraversal()
88 {
89   if ( this->Paths == nullptr )
90   {
91     this->Paths = vtkAssemblyPaths::New();
92     vtkAssemblyPath *path = vtkAssemblyPath::New();
93     path->AddNode(this,nullptr);
94     this->BuildPaths(this->Paths,path);
95     path->Delete();
96   }
97   this->Paths->InitTraversal();
98 }
99 
100 //----------------------------------------------------------------------------
GetNextPath()101 vtkAssemblyPath *vtkProp::GetNextPath()
102 {
103   if ( ! this->Paths)
104   {
105     return nullptr;
106   }
107   return this->Paths->GetNextItem();
108 }
109 
110 //----------------------------------------------------------------------------
111 // This method is used in conjunction with the assembly object to build a copy
112 // of the assembly hierarchy. This hierarchy can then be traversed for
113 // rendering, picking or other operations.
BuildPaths(vtkAssemblyPaths * paths,vtkAssemblyPath * path)114 void vtkProp::BuildPaths(vtkAssemblyPaths *paths, vtkAssemblyPath *path)
115 {
116   // This is a leaf node in the assembly hierarchy so we
117   // copy the path in preparation to assingning it to paths.
118   vtkAssemblyPath *childPath = vtkAssemblyPath::New();
119   childPath->ShallowCopy(path);
120 
121   // We can add this path to the list of paths
122   paths->AddItem(childPath);
123   childPath->Delete(); //okay, reference counting
124 }
125 
126 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)127 void vtkProp::PrintSelf(ostream& os, vtkIndent indent)
128 {
129   this->Superclass::PrintSelf(os,indent);
130 
131   os << indent << "Dragable: " << (this->Dragable ? "On\n" : "Off\n");
132   os << indent << "Pickable: " << (this->Pickable ? "On\n" : "Off\n");
133 
134   os << indent << "AllocatedRenderTime: "
135      << this->AllocatedRenderTime << endl;
136   os << indent << "EstimatedRenderTime: "
137      << this->EstimatedRenderTime << endl;
138   os << indent << "NumberOfConsumers: " << this->NumberOfConsumers << endl;
139   os << indent << "RenderTimeMultiplier: "
140      << this->RenderTimeMultiplier << endl;
141   os << indent << "Visibility: " << (this->Visibility ? "On\n" : "Off\n");
142 
143   os << indent << "PropertyKeys: ";
144   if(this->PropertyKeys!=nullptr)
145   {
146     this->PropertyKeys->PrintSelf(os,indent);
147     os << endl;
148   }
149   else
150   {
151     os << "none." << endl;
152   }
153 
154   os << indent << "useBounds: " << this->UseBounds <<endl;
155 }
156 
157 
158 //----------------------------------------------------------------------------
AddConsumer(vtkObject * c)159 void vtkProp::AddConsumer(vtkObject *c)
160 {
161   // make sure it isn't already there
162   if (this->IsConsumer(c))
163   {
164     return;
165   }
166   // add it to the list, reallocate memory
167   vtkObject **tmp = this->Consumers;
168   this->NumberOfConsumers++;
169   this->Consumers = new vtkObject* [this->NumberOfConsumers];
170   for (int i = 0; i < (this->NumberOfConsumers-1); i++)
171   {
172     this->Consumers[i] = tmp[i];
173   }
174   this->Consumers[this->NumberOfConsumers-1] = c;
175   // free old memory
176   delete [] tmp;
177 }
178 
179 //----------------------------------------------------------------------------
RemoveConsumer(vtkObject * c)180 void vtkProp::RemoveConsumer(vtkObject *c)
181 {
182   // make sure it is already there
183   if (!this->IsConsumer(c))
184   {
185     return;
186   }
187   // remove it from the list, reallocate memory
188   vtkObject **tmp = this->Consumers;
189   this->NumberOfConsumers--;
190   this->Consumers = new vtkObject* [this->NumberOfConsumers];
191   int cnt = 0;
192   int i;
193   for (i = 0; i <= this->NumberOfConsumers; i++)
194   {
195     if (tmp[i] != c)
196     {
197       this->Consumers[cnt] = tmp[i];
198       cnt++;
199     }
200   }
201   // free old memory
202   delete [] tmp;
203 }
204 
205 //----------------------------------------------------------------------------
IsConsumer(vtkObject * c)206 int vtkProp::IsConsumer(vtkObject *c)
207 {
208   int i;
209   for (i = 0; i < this->NumberOfConsumers; i++)
210   {
211     if (this->Consumers[i] == c)
212     {
213       return 1;
214     }
215   }
216   return 0;
217 }
218 
219 //----------------------------------------------------------------------------
GetConsumer(int i)220 vtkObject *vtkProp::GetConsumer(int i)
221 {
222   if (i >= this->NumberOfConsumers)
223   {
224     return nullptr;
225   }
226   return this->Consumers[i];
227 }
228 
229 // ----------------------------------------------------------------------------
230 // Description:
231 // Tells if the prop has all the required keys.
232 // \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
HasKeys(vtkInformation * requiredKeys)233 bool vtkProp::HasKeys(vtkInformation *requiredKeys)
234 {
235   bool result=requiredKeys==nullptr;
236   if(!result)
237   {
238     vtkInformationIterator *it=vtkInformationIterator::New();
239     it->SetInformation(requiredKeys);
240     it->GoToFirstItem();
241     result=true;
242     while(result && !it->IsDoneWithTraversal())
243     {
244       vtkInformationKey *k=it->GetCurrentKey();
245       result=this->PropertyKeys!=nullptr && this->PropertyKeys->Has(k);
246       it->GoToNextItem();
247     }
248     it->Delete();
249   }
250   return result;
251 }
252 
253 // ----------------------------------------------------------------------------
254 // Description:
255 // Render the opaque geometry only if the prop has all the requiredKeys.
256 // This is recursive for composite props like vtkAssembly.
257 // An implementation is provided in vtkProp but each composite prop
258 // must override it.
259 // It returns if the rendering was performed.
260 // \pre v_exists: v!=0
261 // \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
RenderFilteredOpaqueGeometry(vtkViewport * v,vtkInformation * requiredKeys)262 bool vtkProp::RenderFilteredOpaqueGeometry(vtkViewport *v,
263                                            vtkInformation *requiredKeys)
264 {
265   assert("pre: v_exists" && v!=nullptr);
266   bool result;
267   if(this->HasKeys(requiredKeys))
268   {
269     result=this->RenderOpaqueGeometry(v)==1;
270   }
271   else
272   {
273     result=false;
274   }
275   return result;
276 }
277 
278 // ----------------------------------------------------------------------------
279 // Description:
280 // Render the translucent polygonal geometry only if the prop has all the
281 // requiredKeys.
282 // This is recursive for composite props like vtkAssembly.
283 // An implementation is provided in vtkProp but each composite prop
284 // must override it.
285 // It returns if the rendering was performed.
286 // \pre v_exists: v!=0
287 // \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
RenderFilteredTranslucentPolygonalGeometry(vtkViewport * v,vtkInformation * requiredKeys)288 bool vtkProp::RenderFilteredTranslucentPolygonalGeometry(
289   vtkViewport *v,
290   vtkInformation *requiredKeys)
291 {
292   assert("pre: v_exists" && v!=nullptr);
293   bool result;
294   if(this->HasKeys(requiredKeys))
295   {
296     result=this->RenderTranslucentPolygonalGeometry(v)==1;
297   }
298   else
299   {
300     result=false;
301   }
302   return result;
303 }
304 
305 // ----------------------------------------------------------------------------
306 // Description:
307 // Render the volumetric geometry only if the prop has all the
308 // requiredKeys.
309 // This is recursive for composite props like vtkAssembly.
310 // An implementation is provided in vtkProp but each composite prop
311 // must override it.
312 // It returns if the rendering was performed.
313 // \pre v_exists: v!=0
314 // \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
RenderFilteredVolumetricGeometry(vtkViewport * v,vtkInformation * requiredKeys)315 bool vtkProp::RenderFilteredVolumetricGeometry(vtkViewport *v,
316                                                vtkInformation *requiredKeys)
317 {
318   assert("pre: v_exists" && v!=nullptr);
319   bool result;
320   if(this->HasKeys(requiredKeys))
321   {
322     result=this->RenderVolumetricGeometry(v)==1;
323   }
324   else
325   {
326     result=false;
327   }
328   return result;
329 }
330 
331 // ----------------------------------------------------------------------------
332 // Description:
333 // Render in the overlay of the viewport only if the prop has all the
334 // requiredKeys.
335 // This is recursive for composite props like vtkAssembly.
336 // An implementation is provided in vtkProp but each composite prop
337 // must override it.
338 // It returns if the rendering was performed.
339 // \pre v_exists: v!=0
340 // \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
RenderFilteredOverlay(vtkViewport * v,vtkInformation * requiredKeys)341 bool vtkProp::RenderFilteredOverlay(vtkViewport *v,
342                                     vtkInformation *requiredKeys)
343 {
344   assert("pre: v_exists" && v!=nullptr);
345   bool result;
346   if(this->HasKeys(requiredKeys))
347   {
348     result=this->RenderOverlay(v)==1;
349   }
350   else
351   {
352     result=false;
353   }
354   return result;
355 }
356