1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4 
5   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6   All rights reserved.
7   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8 
9      This software is distributed WITHOUT ANY WARRANTY; without even
10      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11      PURPOSE.  See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #include "vtkSurfaceLICInterface.h"
15 
16 #include "vtkFloatArray.h"
17 #include "vtkOpenGLFramebufferObject.h"
18 #include "vtkImageData.h"
19 #include "vtkLineIntegralConvolution2D.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkOpenGLError.h"
22 #include "vtkOpenGLRenderWindow.h"
23 #include "vtkOpenGLShaderCache.h"
24 #include "vtkOpenGLState.h"
25 #include "vtkPainterCommunicator.h"
26 #include "vtkPixelBufferObject.h"
27 #include "vtkPointData.h"
28 #include "vtkPolyData.h"
29 #include "vtkProperty.h"
30 #include "vtkRenderer.h"
31 #include "vtkScalarsToColors.h"
32 #include "vtkShaderProgram.h"
33 #include "vtkSurfaceLICComposite.h"
34 #include "vtkTextureObjectVS.h"
35 
36 #include "vtkOpenGLVertexBufferObject.h"
37 #include "vtkOpenGLVertexArrayObject.h"
38 #include "vtkOpenGLIndexBufferObject.h"
39 
40 #include "vtkLICNoiseHelper.h"
41 #include "vtkSurfaceLICHelper.h"
42 
43 #include <cstring>
44 #include <algorithm>
45 #include <limits>
46 #include <vector>
47 #include <deque>
48 #include <cstdlib>
49 
50 #include "vtkSurfaceLICInterface_SC.h"
51 #include "vtkSurfaceLICInterface_CE.h"
52 #include "vtkSurfaceLICInterface_DCpy.h"
53 #include "vtkTextureObjectVS.h"
54 
55 typedef vtkLineIntegralConvolution2D vtkLIC2D;
56 
57 // write intermediate results to disk for debugging
58 #define vtkSurfaceLICInterfaceDEBUG 0
59 #if vtkSurfaceLICInterfaceDEBUG >= 2
60 #include "vtkTextureIO.h"
61 #include <sstream>
62 using std::ostringstream;
63 //----------------------------------------------------------------------------
64 static
mpifn(vtkPainterCommunicator * comm,const char * fn)65 std::string mpifn(vtkPainterCommunicator *comm, const char *fn)
66 {
67   ostringstream oss;
68   oss << comm->GetRank() << "_" << fn;
69   return oss.str();
70 }
71 #endif
72 
73 vtkObjectFactoryNewMacro(vtkSurfaceLICInterface);
74 
75 //----------------------------------------------------------------------------
vtkSurfaceLICInterface()76 vtkSurfaceLICInterface::vtkSurfaceLICInterface()
77 {
78   this->Internals = new vtkSurfaceLICHelper();
79 
80   this->Enable = 1;
81   this->AlwaysUpdate = 0;
82 
83   this->StepSize = 1;
84   this->NumberOfSteps = 20;
85   this->NormalizeVectors = 1;
86 
87   this->EnhancedLIC = 1;
88 
89   this->EnhanceContrast = 0;
90   this->LowLICContrastEnhancementFactor = 0.0;
91   this->HighLICContrastEnhancementFactor = 0.0;
92   this->LowColorContrastEnhancementFactor = 0.0;
93   this->HighColorContrastEnhancementFactor = 0.0;
94   this->AntiAlias = 0;
95   this->ColorMode = COLOR_MODE_BLEND;
96   this->LICIntensity = 0.8;
97   this->MapModeBias = 0.0;
98 
99   this->GenerateNoiseTexture = 0;
100   this->NoiseType = NOISE_TYPE_GAUSSIAN;
101   this->NoiseTextureSize = 200;
102   this->MinNoiseValue = 0.0;
103   this->MaxNoiseValue = 0.8;
104   this->NoiseGrainSize = 1;
105   this->NumberOfNoiseLevels = 256;
106   this->ImpulseNoiseProbability = 1.0;
107   this->ImpulseNoiseBackgroundValue = 0.0;
108   this->NoiseGeneratorSeed = 1;
109 
110   this->MaskOnSurface = 0;
111   this->MaskThreshold = 0.0;
112   this->MaskIntensity = 0.0;
113   this->MaskColor[0] = 0.5;
114   this->MaskColor[1] = 0.5;
115   this->MaskColor[2] = 0.5;
116 
117   this->CompositeStrategy = COMPOSITE_AUTO;
118 }
119 
120 //----------------------------------------------------------------------------
~vtkSurfaceLICInterface()121 vtkSurfaceLICInterface::~vtkSurfaceLICInterface()
122 {
123   #if vtkSurfaceLICInterfaceDEBUG >= 1
124   cerr << "=====vtkSurfaceLICInterface::~vtkSurfaceLICInterface" << endl;
125   #endif
126   this->ReleaseGraphicsResources(this->Internals->Context);
127   delete this->Internals;
128 }
129 
ShallowCopy(vtkSurfaceLICInterface * m)130 void vtkSurfaceLICInterface::ShallowCopy(vtkSurfaceLICInterface *m)
131 {
132   this->SetNumberOfSteps(m->GetNumberOfSteps());
133   this->SetStepSize(m->GetStepSize());
134   this->SetEnhancedLIC(m->GetEnhancedLIC());
135   this->SetGenerateNoiseTexture(m->GetGenerateNoiseTexture());
136   this->SetNoiseType(m->GetNoiseType());
137   this->SetNormalizeVectors(m->GetNormalizeVectors());
138   this->SetNoiseTextureSize(m->GetNoiseTextureSize());
139   this->SetNoiseGrainSize(m->GetNoiseGrainSize());
140   this->SetMinNoiseValue(m->GetMinNoiseValue());
141   this->SetMaxNoiseValue(m->GetMaxNoiseValue());
142   this->SetNumberOfNoiseLevels(m->GetNumberOfNoiseLevels());
143   this->SetImpulseNoiseProbability(m->GetImpulseNoiseProbability());
144   this->SetImpulseNoiseBackgroundValue(m->GetImpulseNoiseBackgroundValue());
145   this->SetNoiseGeneratorSeed(m->GetNoiseGeneratorSeed());
146   this->SetEnhanceContrast(m->GetEnhanceContrast());
147   this->SetLowLICContrastEnhancementFactor(
148     m->GetLowLICContrastEnhancementFactor());
149   this->SetHighLICContrastEnhancementFactor(
150     m->GetHighLICContrastEnhancementFactor());
151   this->SetLowColorContrastEnhancementFactor(
152     m->GetLowColorContrastEnhancementFactor());
153   this->SetHighColorContrastEnhancementFactor(
154     m->GetHighColorContrastEnhancementFactor());
155   this->SetAntiAlias(m->GetAntiAlias());
156   this->SetColorMode(m->GetColorMode());
157   this->SetLICIntensity(m->GetLICIntensity());
158   this->SetMapModeBias(m->GetMapModeBias());
159   this->SetMaskOnSurface(m->GetMaskOnSurface());
160   this->SetMaskThreshold(m->GetMaskThreshold());
161   this->SetMaskIntensity(m->GetMaskIntensity());
162   this->SetMaskColor(m->GetMaskColor());
163   this->SetEnable(m->GetEnable());
164 }
165 
UpdateCommunicator(vtkRenderer * renderer,vtkActor * actor,vtkDataObject * input)166 void vtkSurfaceLICInterface::UpdateCommunicator(
167   vtkRenderer *renderer, vtkActor *actor, vtkDataObject *input)
168 {
169     // commented out as camera and data changes also
170     // require a communicator update, currently the
171     // test does not include these
172 //  if (this->NeedToUpdateCommunicator())
173   {
174     // create a communicator that contains only ranks
175     // that have visible data. In parallel this is a
176     // collective operation across all ranks. In
177     // serial this is a no-op.
178     this->CreateCommunicator(renderer,actor, input);
179   }
180 }
181 
PrepareForGeometry()182 void vtkSurfaceLICInterface::PrepareForGeometry()
183 {
184   vtkOpenGLState *ostate = this->Internals->Context->GetState();
185 
186   // save the active fbo and its draw buffer
187   this->PrevDrawBuf = 0;
188   glGetIntegerv(GL_DRAW_BUFFER, &this->PrevDrawBuf);
189 
190   this->PrevFbo = 0;
191   glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &this->PrevFbo);
192 
193   // ------------------------------------------- render geometry, project vectors onto screen, etc
194   // setup our fbo
195   vtkOpenGLFramebufferObject *fbo = this->Internals->FBO;
196   fbo->SaveCurrentBindings();
197   fbo->Bind(GL_FRAMEBUFFER);
198   fbo->AddDepthAttachment(GL_DRAW_FRAMEBUFFER, this->Internals->DepthImage);
199   fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 0U, this->Internals->GeometryImage);
200   fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 1U, this->Internals->VectorImage);
201   fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 2U, this->Internals->MaskVectorImage);
202   fbo->ActivateDrawBuffers(3);
203   vtkCheckFrameBufferStatusMacro(GL_FRAMEBUFFER);
204 
205   // clear internal color and depth buffers
206   // the LIC'er requires *all* fragments in the vector
207   // texture to be initialized to 0
208   ostate->vtkglDisable(GL_BLEND);
209   ostate->vtkglEnable(GL_DEPTH_TEST);
210   ostate->vtkglDisable(GL_SCISSOR_TEST);
211   ostate->vtkglClearColor(0.0, 0.0, 0.0, 0.0);
212   ostate->vtkglClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
213 }
214 
CompletedGeometry()215 void vtkSurfaceLICInterface::CompletedGeometry()
216 {
217   vtkOpenGLFramebufferObject *fbo = this->Internals->FBO;
218   fbo->RemoveRenDepthAttachment(GL_DRAW_FRAMEBUFFER);
219   fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 0U);
220   fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 1U);
221   fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 2U);
222   fbo->DeactivateDrawBuffers();
223   fbo->UnBind(GL_FRAMEBUFFER);
224 
225   #if vtkSurfaceLICInterfaceDEBUG >= 2
226   vtkPainterCommunicator *comm = this->GetCommunicator();
227 
228   vtkTextureIO::Write(
229         mpifn(comm,"slicp_geometry_image.vtm"),
230         this->Internals->GeometryImage,
231         this->Internals->BlockExts);
232   vtkTextureIO::Write(
233         mpifn(comm,"slicp_vector_image.vtm"),
234         this->Internals->VectorImage,
235         this->Internals->BlockExts);
236   vtkTextureIO::Write(
237         mpifn(comm,"slicp_mask_vector_image.vtm"),
238         this->Internals->MaskVectorImage,
239         this->Internals->BlockExts);
240   vtkTextureIO::Write(
241         mpifn(comm,"slicp_depth_image.vtm"),
242         this->Internals->DepthImage,
243         this->Internals->BlockExts);
244   #endif
245 }
246 
247 
GatherVectors()248 void vtkSurfaceLICInterface::GatherVectors()
249 {
250   vtkPixelExtent viewExt(
251         this->Internals->Viewsize[0],
252         this->Internals->Viewsize[1]);
253 
254   vtkPainterCommunicator *comm = this->GetCommunicator();
255 
256   // get tight screen space bounds to reduce communication/computation
257   vtkPixelBufferObject *vecPBO = this->Internals->VectorImage->Download();
258   void *pVecPBO = vecPBO->MapPackedBuffer();
259 
260   this->Internals->GetPixelBounds(
261           (float*)pVecPBO,
262           this->Internals->Viewsize[0],
263           this->Internals->BlockExts);
264 
265   // initialize compositor
266   this->Internals->Compositor->Initialize(
267         viewExt,
268         this->Internals->BlockExts,
269         this->CompositeStrategy,
270         this->StepSize,
271         this->NumberOfSteps,
272         this->NormalizeVectors,
273         this->EnhancedLIC,
274         this->AntiAlias);
275 
276   if (comm->GetMPIInitialized())
277   {
278     // parallel run
279     // need to use the communicator provided by the rendering engine
280     this->Internals->Compositor->SetCommunicator(comm);
281 
282     // build compositing program and set up the screen space decomp
283     // with guard pixels
284     int iErr = 0;
285     iErr = this->Internals->Compositor->BuildProgram((float*)pVecPBO);
286     if (iErr)
287     {
288       vtkErrorMacro("Failed to construct program, reason " << iErr);
289     }
290 
291     // composite vectors
292     vtkTextureObject *compositeVectors = this->Internals->CompositeVectorImage;
293     iErr = this->Internals->Compositor->Gather(
294             pVecPBO,
295             VTK_FLOAT,
296             4,
297             compositeVectors);
298     if (iErr)
299     {
300       vtkErrorMacro("Failed to composite vectors, reason  " << iErr);
301     }
302 
303     // composite mask vectors
304     vtkTextureObject *compositeMaskVectors = this->Internals->CompositeMaskVectorImage;
305     vtkPixelBufferObject *maskVecPBO = this->Internals->MaskVectorImage->Download();
306     void *pMaskVecPBO = maskVecPBO->MapPackedBuffer();
307     iErr = this->Internals->Compositor->Gather(
308             pMaskVecPBO,
309             VTK_FLOAT,
310             4,
311             compositeMaskVectors);
312     if (iErr)
313     {
314       vtkErrorMacro("Failed to composite mask vectors, reason " << iErr);
315     }
316     maskVecPBO->UnmapPackedBuffer();
317     maskVecPBO->Delete();
318 
319     // restore the default communicator
320     this->Internals->Compositor->RestoreDefaultCommunicator();
321 
322     #if vtkSurfaceLICInterfaceDEBUG >= 2
323     vtkTextureIO::Write(
324            mpifn(comm,"slicp_new_vector_image.vtm"),
325            this->Internals->CompositeVectorImage,
326            this->Internals->Compositor->GetDisjointGuardExtents());
327 
328     vtkTextureIO::Write(
329            mpifn(comm,"slicp_new_mask_vector_image.vtm"),
330            this->Internals->CompositeMaskVectorImage,
331            this->Internals->Compositor->GetDisjointGuardExtents());
332     #endif
333   }
334   else
335   {
336     // serial run
337     // make the decomposition disjoint and add guard pixels
338     this->Internals->Compositor->InitializeCompositeExtents((float*)pVecPBO);
339 
340     // use the lic decomp from here on out, in serial we have this
341     // flexibility because we don't need to worry about ordered compositing
342     // or IceT's scissor boxes
343     this->Internals->BlockExts
344        = this->Internals->Compositor->GetCompositeExtents();
345 
346     // pass through without compositing
347     this->Internals->CompositeVectorImage = this->Internals->VectorImage;
348     this->Internals->CompositeMaskVectorImage = this->Internals->MaskVectorImage;
349   }
350 
351  vecPBO->UnmapPackedBuffer();
352  vecPBO->Delete();
353 }
354 
ApplyLIC()355 void vtkSurfaceLICInterface::ApplyLIC()
356 {
357   vtkPainterCommunicator *comm = this->GetCommunicator();
358 
359   vtkPixelExtent viewExt(
360         this->Internals->Viewsize[0],
361         this->Internals->Viewsize[1]);
362 
363   #if vtkSurfaceLICInterfaceDEBUG >= 2
364   ostringstream oss;
365   if ( this->GenerateNoiseTexture )
366   {
367     const char *noiseType[3]={"unif","gauss","perl"};
368     oss
369      << "slicp_noise_"
370      << noiseType[this->NoiseType]
371      << "_size_" << this->NoiseTextureSize
372      << "_grain_" << this->NoiseGrainSize
373      << "_minval_" << this->MinNoiseValue
374      << "_maxval_" << this->MaxNoiseValue
375      << "_nlevels_" << this->NumberOfNoiseLevels
376      << "_impulseprob_" << this->ImpulseNoiseProbability
377      << "_impulseprob_" << this->ImpulseNoiseBackgroundValue
378      << ".vtk";
379   }
380   else
381   {
382     oss << "slicp_noise_default.vtk";
383   }
384   vtkTextureIO::Write(
385         mpifn(comm, oss.str().c_str()),
386         this->Internals->NoiseImage);
387   #endif
388 
389   // TODO -- this means that the steps size is a function
390   // of aspect ratio which is pretty insane...
391   // convert from window units to texture units
392   // this isn't correct since there's no way to account
393   // for anisotropy in the trasnform to texture space
394   double tcScale[2] = {
395         1.0/this->Internals->Viewsize[0],
396         1.0/this->Internals->Viewsize[1]};
397 
398   double stepSize
399     = this->StepSize*sqrt(tcScale[0]*tcScale[0]+tcScale[1]*tcScale[1]);
400 
401   stepSize = stepSize <= 0.0 ? 1.0e-10 : stepSize;
402 
403   // configure image lic
404   vtkLineIntegralConvolution2D *LICer = this->Internals->LICer;
405 
406   LICer->SetStepSize(stepSize);
407   LICer->SetNumberOfSteps(this->NumberOfSteps);
408   LICer->SetEnhancedLIC(this->EnhancedLIC);
409   switch (this->EnhanceContrast)
410   {
411     case ENHANCE_CONTRAST_LIC:
412     case ENHANCE_CONTRAST_BOTH:
413       LICer->SetEnhanceContrast(vtkLIC2D::ENHANCE_CONTRAST_ON);
414       break;
415     default:
416       LICer->SetEnhanceContrast(vtkLIC2D::ENHANCE_CONTRAST_OFF);
417   }
418   LICer->SetLowContrastEnhancementFactor(this->LowLICContrastEnhancementFactor);
419   LICer->SetHighContrastEnhancementFactor(this->HighLICContrastEnhancementFactor);
420   LICer->SetAntiAlias(this->AntiAlias);
421   LICer->SetComponentIds(0, 1);
422   LICer->SetNormalizeVectors(this->NormalizeVectors);
423   LICer->SetMaskThreshold(this->MaskThreshold);
424   LICer->SetCommunicator(comm);
425 
426   // loop over composited extents
427   const std::deque<vtkPixelExtent> &compositeExts
428     = this->Internals->Compositor->GetCompositeExtents();
429 
430   const std::deque<vtkPixelExtent> &disjointGuardExts
431     = this->Internals->Compositor->GetDisjointGuardExtents();
432 
433   this->Internals->LICImage.TakeReference(
434        LICer->Execute(
435             viewExt,            // screen extent
436             disjointGuardExts,  // disjoint extent of valid vectors
437             compositeExts,      // disjoint extent where lic is needed
438             this->Internals->CompositeVectorImage,
439             this->Internals->CompositeMaskVectorImage,
440             this->Internals->NoiseImage));
441 
442   if (!this->Internals->LICImage)
443   {
444     vtkErrorMacro("Failed to compute image LIC");
445     return;
446   }
447 
448   #if vtkSurfaceLICInterfaceDEBUG >= 2
449   vtkTextureIO::Write(
450         mpifn(comm,"slicp_lic.vtm"),
451         this->Internals->LICImage,
452         compositeExts);
453   #endif
454 
455   // ------------------------------------------- move from LIC decomp back to geometry decomp
456   if ( comm->GetMPIInitialized()
457     && (this->Internals->Compositor->GetStrategy()!=COMPOSITE_INPLACE ) )
458   {
459     #ifdef vtkSurfaceLICMapperTIME
460     this->StartTimerEvent("vtkSurfaceLICMapper::ScatterLIC");
461     #endif
462 
463     // parallel run
464     // need to use the communicator provided by the rendering engine
465     this->Internals->Compositor->SetCommunicator(comm);
466 
467     vtkPixelBufferObject *licPBO = this->Internals->LICImage->Download();
468     void *pLicPBO = licPBO->MapPackedBuffer();
469     vtkTextureObject *newLicImage = nullptr;
470     int iErr = this->Internals->Compositor->Scatter(pLicPBO, VTK_FLOAT, 4, newLicImage);
471     if (iErr)
472     {
473       vtkErrorMacro("Failed to scatter lic");
474     }
475     licPBO->UnmapPackedBuffer();
476     licPBO->Delete();
477     this->Internals->LICImage = nullptr;
478     this->Internals->LICImage = newLicImage;
479     newLicImage->Delete();
480 
481     // restore the default communicator
482     this->Internals->Compositor->RestoreDefaultCommunicator();
483 
484     #ifdef vtkSurfaceLICMapperTIME
485     this->EndTimerEvent("vtkSurfaceLICMapper::ScatterLIC");
486     #endif
487     #if vtkSurfaceLICMapperDEBUG >= 2
488     vtkTextureIO::Write(
489           mpifn(comm,"slicp_new_lic.vtm"),
490           this->Internals->LICImage,
491           this->Internals->BlockExts);
492     #endif
493   }
494 }
495 
CombineColorsAndLIC()496 void vtkSurfaceLICInterface::CombineColorsAndLIC()
497 {
498   vtkOpenGLRenderWindow *renWin = this->Internals->Context;
499   vtkOpenGLState *ostate = renWin->GetState();
500 
501   vtkPainterCommunicator *comm = this->GetCommunicator();
502 
503   vtkPixelExtent viewExt(
504         this->Internals->Viewsize[0],
505         this->Internals->Viewsize[1]);
506 
507   vtkOpenGLFramebufferObject *fbo = this->Internals->FBO;
508   fbo->SaveCurrentBindings();
509   fbo->Bind(GL_FRAMEBUFFER);
510   fbo->InitializeViewport(this->Internals->Viewsize[0], this->Internals->Viewsize[1]);
511   fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 0U, this->Internals->RGBColorImage);
512   fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 1U, this->Internals->HSLColorImage);
513   fbo->ActivateDrawBuffers(2U);
514   vtkCheckFrameBufferStatusMacro(GL_FRAMEBUFFER);
515 
516   // clear the parts of the screen which we will modify
517   ostate->vtkglEnable(GL_SCISSOR_TEST);
518   ostate->vtkglClearColor(0.0, 0.0, 0.0, 0.0);
519   size_t nBlocks = this->Internals->BlockExts.size();
520   for (size_t e=0; e<nBlocks; ++e)
521   {
522     vtkPixelExtent ext = this->Internals->BlockExts[e];
523     ext.Grow(2); // halo for linear filtering
524     ext &= viewExt;
525 
526     unsigned int extSize[2];
527     ext.Size(extSize);
528 
529     ostate->vtkglScissor(ext[0], ext[2], extSize[0], extSize[1]);
530     ostate->vtkglClear(GL_COLOR_BUFFER_BIT);
531   }
532   ostate->vtkglDisable(GL_SCISSOR_TEST);
533 
534   this->Internals->VectorImage->Activate();
535   this->Internals->GeometryImage->Activate();
536   this->Internals->LICImage->Activate();
537 
538   if (!this->Internals->ColorPass->Program)
539   {
540     this->InitializeResources();
541   }
542   vtkShaderProgram *colorPass = this->Internals->ColorPass->Program;
543   renWin->GetShaderCache()->ReadyShaderProgram(colorPass);
544 
545   colorPass->SetUniformi("texVectors",
546     this->Internals->VectorImage->GetTextureUnit());
547   colorPass->SetUniformi("texGeomColors",
548     this->Internals->GeometryImage->GetTextureUnit());
549   colorPass->SetUniformi("texLIC",
550     this->Internals->LICImage->GetTextureUnit());
551   colorPass->SetUniformi("uScalarColorMode", this->ColorMode);
552   colorPass->SetUniformf("uLICIntensity", this->LICIntensity);
553   colorPass->SetUniformf("uMapBias", this->MapModeBias);
554   colorPass->SetUniformf("uMaskIntensity", this->MaskIntensity);
555   float fMaskColor[3];
556   fMaskColor[0] = this->MaskColor[0];
557   fMaskColor[1] = this->MaskColor[1];
558   fMaskColor[2] = this->MaskColor[2];
559   colorPass->SetUniform3f("uMaskColor", fMaskColor);
560 
561   for (size_t e=0; e<nBlocks; ++e)
562   {
563     this->Internals->RenderQuad(viewExt, this->Internals->BlockExts[e],
564       this->Internals->ColorPass);
565   }
566 
567   this->Internals->VectorImage->Deactivate();
568   this->Internals->GeometryImage->Deactivate();
569   this->Internals->LICImage->Deactivate();
570 
571   // --------------------------------------------- color contrast enhance
572   if ( ( this->EnhanceContrast == ENHANCE_CONTRAST_COLOR )
573     || ( this->EnhanceContrast == ENHANCE_CONTRAST_BOTH ) )
574   {
575     #if vtkSurfaceLICInterfaceDEBUG >= 2
576     vtkTextureIO::Write(
577           mpifn(comm,"slic_color_rgb_in.vtm"),
578           this->Internals->RGBColorImage,
579           this->Internals->BlockExts);
580     vtkTextureIO::Write(
581           mpifn(comm,"slic_color_hsl_in.vtm"),
582           this->Internals->HSLColorImage,
583           this->Internals->BlockExts);
584     #endif
585 
586     // find min/max lighness value for color contrast enhancement.
587     float LMin = VTK_FLOAT_MAX;
588     float LMax = -VTK_FLOAT_MAX;
589     float LMaxMinDiff = VTK_FLOAT_MAX;
590 
591     vtkSurfaceLICHelper::StreamingFindMinMax(fbo, this->Internals->BlockExts, LMin, LMax);
592 
593     if ( this->Internals->BlockExts.size()
594       && ((LMax <= LMin) || (LMin < 0.0f) || (LMax > 1.0f)) )
595     {
596       vtkErrorMacro(
597         << comm->GetRank()
598         << ": Invalid range " << LMin << ", " << LMax
599         << " for color contrast enhancement");
600       LMin = 0.0;
601       LMax = 1.0;
602       LMaxMinDiff = 1.0;
603     }
604 
605     // global collective reduction for parallel operation
606     this->GetGlobalMinMax(comm, LMin, LMax);
607 
608     // set M and m as a fraction of the range.
609     LMaxMinDiff = LMax-LMin;
610     LMin += LMaxMinDiff*this->LowColorContrastEnhancementFactor;
611     LMax -= LMaxMinDiff*this->HighColorContrastEnhancementFactor;
612     LMaxMinDiff = LMax-LMin;
613 
614     // normalize shader
615     fbo->AddColorAttachment(GL_DRAW_FRAMEBUFFER, 0U, this->Internals->RGBColorImage);
616     fbo->ActivateDrawBuffer(0U);
617     vtkCheckFrameBufferStatusMacro(GL_DRAW_FRAMEBUFFER);
618 
619     this->Internals->GeometryImage->Activate();
620     this->Internals->HSLColorImage->Activate();
621     this->Internals->LICImage->Activate();
622 
623     if (!this->Internals->ColorEnhancePass->Program)
624     {
625       this->InitializeResources();
626     }
627     vtkShaderProgram *colorEnhancePass =
628       this->Internals->ColorEnhancePass->Program;
629     renWin->GetShaderCache()->ReadyShaderProgram(colorEnhancePass);
630     colorEnhancePass->SetUniformi("texGeomColors",
631       this->Internals->GeometryImage->GetTextureUnit());
632     colorEnhancePass->SetUniformi("texHSLColors",
633       this->Internals->HSLColorImage->GetTextureUnit());
634     colorEnhancePass->SetUniformi("texLIC",
635       this->Internals->LICImage->GetTextureUnit());
636     colorEnhancePass->SetUniformf("uLMin", LMin);
637     colorEnhancePass->SetUniformf("uLMaxMinDiff", LMaxMinDiff);
638 
639     for (size_t e=0; e<nBlocks; ++e)
640     {
641       this->Internals->RenderQuad(viewExt, this->Internals->BlockExts[e],
642         this->Internals->ColorEnhancePass);
643     }
644 
645     this->Internals->GeometryImage->Deactivate();
646     this->Internals->HSLColorImage->Deactivate();
647     this->Internals->LICImage->Deactivate();
648 
649     fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 0U);
650     fbo->DeactivateDrawBuffers();
651   }
652   else
653   {
654     fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 0U);
655     fbo->RemoveTexColorAttachment(GL_DRAW_FRAMEBUFFER, 1U);
656     fbo->DeactivateDrawBuffers();
657   }
658 
659   fbo->UnBind(GL_FRAMEBUFFER);
660 
661   #if vtkSurfaceLICInterfaceDEBUG >= 2
662   vtkTextureIO::Write(
663          mpifn(comm,"slicp_new_rgb.vtm"),
664          this->Internals->RGBColorImage,
665          this->Internals->BlockExts);
666   #endif
667 }
668 
CopyToScreen()669 void vtkSurfaceLICInterface::CopyToScreen()
670 {
671   vtkOpenGLRenderWindow *renWin = this->Internals->Context;
672   vtkOpenGLState *ostate = renWin->GetState();
673 
674   vtkPixelExtent viewExt(
675       this->Internals->Viewsize[0],
676       this->Internals->Viewsize[1]);
677 
678   glBindFramebuffer(GL_FRAMEBUFFER, this->PrevFbo);
679   glDrawBuffer(this->PrevDrawBuf);
680 
681 
682   ostate->vtkglDisable(GL_BLEND);
683   ostate->vtkglDisable(GL_SCISSOR_TEST);
684   ostate->vtkglEnable(GL_DEPTH_TEST);
685 
686   // Viewport transformation for 1:1 'pixel=texel=data' mapping.
687   // Note this is not enough for 1:1 mapping, because depending on the
688   // primitive displayed (point,line,polygon), the rasterization rules
689   // are different.
690   ostate->vtkglViewport(0, 0, this->Internals->Viewsize[0],
691         this->Internals->Viewsize[1]);
692 
693   this->Internals->DepthImage->Activate();
694   this->Internals->RGBColorImage->Activate();
695 
696   if (!this->Internals->CopyPass->Program)
697   {
698     this->InitializeResources();
699   }
700   vtkShaderProgram *copyPass =
701     this->Internals->CopyPass->Program;
702   renWin->GetShaderCache()->ReadyShaderProgram(copyPass);
703   copyPass->SetUniformi("texDepth",
704     this->Internals->DepthImage->GetTextureUnit());
705   copyPass->SetUniformi("texRGBColors",
706     this->Internals->RGBColorImage->GetTextureUnit());
707 
708   size_t nBlocks = this->Internals->BlockExts.size();
709   for (size_t e=0; e<nBlocks; ++e)
710   {
711     this->Internals->RenderQuad(viewExt, this->Internals->BlockExts[e],
712       this->Internals->CopyPass);
713   }
714 
715   this->Internals->DepthImage->Deactivate();
716   this->Internals->RGBColorImage->Deactivate();
717 
718   #ifdef vtkSurfaceLICMapperTIME
719   this->EndTimerEvent("vtkSurfaceLICMapper::DepthCopy");
720   #endif
721 
722   //
723   this->Internals->Updated();
724 }
725 
726 //----------------------------------------------------------------------------
ReleaseGraphicsResources(vtkWindow * win)727 void vtkSurfaceLICInterface::ReleaseGraphicsResources(vtkWindow* win)
728 {
729   this->Internals->ReleaseGraphicsResources(win);
730   this->Internals->Context = nullptr;
731 }
732 
733 //----------------------------------------------------------------------------
734 #define vtkSetMonitoredParameterMacro(_name, _type, _code)  \
735 void vtkSurfaceLICInterface::Set##_name (_type val)           \
736 {                                                           \
737   if (val == this->_name)                                   \
738   {                                                       \
739     return;                                                 \
740   }                                                       \
741   _code                                                     \
742   this->_name = val;                                        \
743   this->Modified();                                         \
744 }
745 // lic
746 vtkSetMonitoredParameterMacro(
747       GenerateNoiseTexture,
748       int,
749       this->Internals->Noise = nullptr;
750       this->Internals->NoiseImage = nullptr;)
751 
752 vtkSetMonitoredParameterMacro(
753       NoiseType,
754       int,
755       this->Internals->Noise = nullptr;
756       this->Internals->NoiseImage = nullptr;)
757 
758 vtkSetMonitoredParameterMacro(
759       NoiseTextureSize,
760       int,
761       this->Internals->Noise = nullptr;
762       this->Internals->NoiseImage = nullptr;)
763 
764 vtkSetMonitoredParameterMacro(
765       NoiseGrainSize,
766       int,
767       this->Internals->Noise = nullptr;
768       this->Internals->NoiseImage = nullptr;)
769 
vtkSetMonitoredParameterMacro(MinNoiseValue,double,val=val<0.0?0.0:val;val=val>1.0?1.0:val;this->Internals->Noise=nullptr;this->Internals->NoiseImage=nullptr;)770 vtkSetMonitoredParameterMacro(
771       MinNoiseValue,
772       double,
773       val = val < 0.0 ? 0.0 : val;
774       val = val > 1.0 ? 1.0 : val;
775       this->Internals->Noise = nullptr;
776       this->Internals->NoiseImage = nullptr;)
777 
778 vtkSetMonitoredParameterMacro(
779       MaxNoiseValue,
780       double,
781       val = val < 0.0 ? 0.0 : val;
782       val = val > 1.0 ? 1.0 : val;
783       this->Internals->Noise = nullptr;
784       this->Internals->NoiseImage = nullptr;)
785 
786 vtkSetMonitoredParameterMacro(
787       NumberOfNoiseLevels,
788       int,
789       this->Internals->Noise = nullptr;
790       this->Internals->NoiseImage = nullptr;)
791 
792 vtkSetMonitoredParameterMacro(
793       ImpulseNoiseProbability,
794       double,
795       val = val < 0.0 ? 0.0 : val;
796       val = val > 1.0 ? 1.0 : val;
797       this->Internals->Noise = nullptr;
798       this->Internals->NoiseImage = nullptr;)
799 
800 vtkSetMonitoredParameterMacro(
801       ImpulseNoiseBackgroundValue,
802       double,
803       val = val < 0.0 ? 0.0 : val;
804       val = val > 1.0 ? 1.0 : val;
805       this->Internals->Noise = nullptr;
806       this->Internals->NoiseImage = nullptr;)
807 
808 vtkSetMonitoredParameterMacro(
809       NoiseGeneratorSeed,
810       int,
811       this->Internals->Noise = nullptr;
812       this->Internals->NoiseImage = nullptr;)
813 
814 // compositor
815 vtkSetMonitoredParameterMacro(
816       CompositeStrategy,
817       int,)
818 
819 // lic/compositor
820 vtkSetMonitoredParameterMacro(
821       NumberOfSteps,
822       int,)
823 
824 vtkSetMonitoredParameterMacro(
825       StepSize,
826       double,)
827 
828 vtkSetMonitoredParameterMacro(
829       NormalizeVectors,
830       int,
831       val = val < 0 ? 0 : val;
832       val = val > 1 ? 1 : val;)
833 
834 vtkSetMonitoredParameterMacro(
835       MaskThreshold,
836       double,)
837 
838 vtkSetMonitoredParameterMacro(
839       EnhancedLIC,
840       int,)
841 
842 // lic
843 vtkSetMonitoredParameterMacro(
844       LowLICContrastEnhancementFactor,
845       double,
846       val = val < 0.0 ? 0.0 : val;
847       val = val > 1.0 ? 1.0 : val;)
848 
849 vtkSetMonitoredParameterMacro(
850       HighLICContrastEnhancementFactor,
851       double,
852       val = val < 0.0 ? 0.0 : val;
853       val = val > 1.0 ? 1.0 : val;)
854 
855 vtkSetMonitoredParameterMacro(
856       AntiAlias,
857       int,
858       val = val < 0 ? 0 : val;)
859 
860 // geometry
861 vtkSetMonitoredParameterMacro(
862       MaskOnSurface,
863       int,
864       val = val < 0 ? 0 : val;
865       val = val > 1 ? 1 : val;)
866 
867 // colors
868 vtkSetMonitoredParameterMacro(
869       ColorMode,
870       int,)
871 
872 vtkSetMonitoredParameterMacro(
873       LICIntensity,
874       double,
875       val = val < 0.0 ? 0.0 : val;
876       val = val > 1.0 ? 1.0 : val;)
877 
878 vtkSetMonitoredParameterMacro(
879       MaskIntensity,
880       double,
881       val = val < 0.0 ? 0.0 : val;
882       val = val > 1.0 ? 1.0 : val;)
883 
884 vtkSetMonitoredParameterMacro(
885       MapModeBias,
886       double,
887       val = val <-1.0 ? -1.0 : val;
888       val = val > 1.0 ?  1.0 : val;)
889 
890 vtkSetMonitoredParameterMacro(
891       LowColorContrastEnhancementFactor,
892       double,
893       val = val < 0.0 ? 0.0 : val;
894       val = val > 1.0 ? 1.0 : val;)
895 
896 vtkSetMonitoredParameterMacro(
897       HighColorContrastEnhancementFactor,
898       double,
899       val = val < 0.0 ? 0.0 : val;
900       val = val > 1.0 ? 1.0 : val;)
901 
902 //----------------------------------------------------------------------------
903 void vtkSurfaceLICInterface::SetMaskColor(double *val)
904 {
905   double rgb[3];
906   for (int q=0; q<3; ++q)
907   {
908     rgb[q] = val[q];
909     rgb[q] = rgb[q] < 0.0 ? 0.0 : rgb[q];
910     rgb[q] = rgb[q] > 1.0 ? 1.0 : rgb[q];
911   }
912   if ( (rgb[0] == this->MaskColor[0])
913     && (rgb[1] == this->MaskColor[1])
914     && (rgb[2] == this->MaskColor[2]) )
915   {
916     return;
917   }
918   for (int q=0; q<3; ++q)
919   {
920     this->MaskColor[q] = rgb[q];
921   }
922   this->Modified();
923 }
924 
925 //----------------------------------------------------------------------------
SetEnhanceContrast(int val)926 void vtkSurfaceLICInterface::SetEnhanceContrast(int val)
927 {
928   val = val < ENHANCE_CONTRAST_OFF ? ENHANCE_CONTRAST_OFF : val;
929   val = val > ENHANCE_CONTRAST_BOTH ? ENHANCE_CONTRAST_BOTH : val;
930   if (val == this->EnhanceContrast)
931   {
932     return;
933   }
934 
935   this->EnhanceContrast = val;
936   this->Modified();
937 }
938 
939 //----------------------------------------------------------------------------
SetNoiseDataSet(vtkImageData * data)940 void vtkSurfaceLICInterface::SetNoiseDataSet(vtkImageData *data)
941 {
942   if (data == this->Internals->Noise)
943   {
944     return;
945   }
946   this->Internals->Noise = data;
947   this->Internals->NoiseImage = nullptr;
948   this->Modified();
949 }
950 
951 //----------------------------------------------------------------------------
GetNoiseDataSet()952 vtkImageData *vtkSurfaceLICInterface::GetNoiseDataSet()
953 {
954   if (this->Internals->Noise == nullptr)
955   {
956     vtkImageData *noise = nullptr;
957     if ( this->GenerateNoiseTexture )
958     {
959       // report potential issues
960       if ( this->NoiseGrainSize >= this->NoiseTextureSize )
961       {
962         vtkErrorMacro(
963           "NoiseGrainSize must be smaller than NoiseTextureSize");
964       }
965       if ( this->MinNoiseValue >= this->MaxNoiseValue )
966       {
967         vtkErrorMacro(
968           "MinNoiseValue must be smaller than MaxNoiseValue");
969       }
970       if ( (this->ImpulseNoiseProbability == 1.0)
971         && (this->NumberOfNoiseLevels < 2) )
972       {
973         vtkErrorMacro(
974           "NumberOfNoiseLevels must be greater than 1 "
975           "when not generating impulse noise");
976       }
977 
978       // generate a custom noise texture based on the
979       // current settings.
980       int noiseTextureSize = this->NoiseTextureSize;
981       int noiseGrainSize = this->NoiseGrainSize;
982       vtkLICRandomNoise2D noiseGen;
983       float *noiseValues = noiseGen.Generate(
984             this->NoiseType,
985             noiseTextureSize,
986             noiseGrainSize,
987             static_cast<float>(this->MinNoiseValue),
988             static_cast<float>(this->MaxNoiseValue),
989             this->NumberOfNoiseLevels,
990             this->ImpulseNoiseProbability,
991             static_cast<float>(this->ImpulseNoiseBackgroundValue),
992             this->NoiseGeneratorSeed);
993       if ( noiseValues == nullptr )
994       {
995         vtkErrorMacro("Failed to generate noise.");
996       }
997 
998       vtkFloatArray *noiseArray = vtkFloatArray::New();
999       noiseArray->SetNumberOfComponents(2);
1000       noiseArray->SetName("noise");
1001       vtkIdType arraySize = 2*noiseTextureSize*noiseTextureSize;
1002       noiseArray->SetArray(noiseValues, arraySize, 0);
1003 
1004       noise = vtkImageData::New();
1005       noise->SetSpacing(1.0, 1.0, 1.0);
1006       noise->SetOrigin(0.0, 0.0, 0.0);
1007       noise->SetDimensions(noiseTextureSize, noiseTextureSize, 1);
1008       noise->GetPointData()->SetScalars(noiseArray);
1009 
1010       noiseArray->Delete();
1011     }
1012     else
1013     {
1014       // load a predefined noise texture.
1015       noise = vtkLICRandomNoise2D::GetNoiseResource();
1016     }
1017 
1018     this->Internals->Noise = noise;
1019     this->Internals->NoiseImage = nullptr;
1020     noise->Delete();
1021     noise = nullptr;
1022   }
1023 
1024   return this->Internals->Noise;
1025 }
1026 
1027 //----------------------------------------------------------------------------
UpdateNoiseImage(vtkRenderWindow * renWin)1028 void vtkSurfaceLICInterface::UpdateNoiseImage(vtkRenderWindow *renWin)
1029 {
1030   vtkOpenGLRenderWindow *rw = vtkOpenGLRenderWindow::SafeDownCast(renWin);
1031   vtkImageData *noiseDataSet = this->GetNoiseDataSet();
1032 
1033   int ext[6];
1034   noiseDataSet->GetExtent(ext);
1035   unsigned int dataWidth = ext[1]-ext[0]+1;
1036   unsigned int dataHeight = ext[3]-ext[2]+1;
1037 
1038   vtkDataArray *noiseArray = noiseDataSet->GetPointData()->GetScalars();
1039   int dataType = noiseArray->GetDataType();
1040   void *data = noiseArray->GetVoidPointer(0);
1041   int dataComps = noiseArray->GetNumberOfComponents();
1042   unsigned int dataSize = noiseArray->GetNumberOfTuples()*dataComps;
1043 
1044   vtkPixelBufferObject *pbo = vtkPixelBufferObject::New();
1045   pbo->SetContext(renWin);
1046   pbo->Upload1D(dataType, data, dataSize, 1, 0);
1047 
1048   vtkTextureObject *tex = vtkTextureObject::New();
1049   tex->SetContext(rw);
1050   tex->SetBaseLevel(0);
1051   tex->SetMaxLevel(0);
1052   tex->SetWrapS(vtkTextureObject::Repeat);
1053   tex->SetWrapT(vtkTextureObject::Repeat);
1054   tex->SetMinificationFilter(vtkTextureObject::Nearest);
1055   tex->SetMagnificationFilter(vtkTextureObject::Nearest);
1056   tex->Create2D(dataWidth, dataHeight, dataComps, pbo, false);
1057   tex->SetAutoParameters(0);
1058   pbo->Delete();
1059 
1060   this->Internals->NoiseImage = tex;
1061   tex->Delete();
1062 }
1063 
1064 
1065 //----------------------------------------------------------------------------
IsSupported(vtkRenderWindow * renWin)1066 bool vtkSurfaceLICInterface::IsSupported(vtkRenderWindow *renWin)
1067 {
1068   vtkOpenGLRenderWindow *context
1069     = vtkOpenGLRenderWindow::SafeDownCast(renWin);
1070 
1071   return vtkSurfaceLICHelper::IsSupported(context);
1072 }
1073 
1074 //----------------------------------------------------------------------------
CanRenderSurfaceLIC(vtkActor * actor)1075 bool vtkSurfaceLICInterface::CanRenderSurfaceLIC(vtkActor *actor)
1076 {
1077   // check the render context for GL feature support
1078   // note this also handles non-opengl render window
1079   if ( this->Internals->ContextNeedsUpdate
1080     && !vtkSurfaceLICInterface::IsSupported(this->Internals->Context) )
1081   {
1082     vtkErrorMacro("SurfaceLIC is not supported");
1083     return false;
1084   }
1085 
1086   bool canRender = false;
1087 
1088   int rep = actor->GetProperty()->GetRepresentation();
1089 
1090   if (this->Enable &&
1091     this->Internals->HasVectors
1092     && (rep == VTK_SURFACE))
1093   {
1094     canRender = true;
1095   }
1096 
1097   #if vtkSurfaceLICInterfaceDEBUG >= 1
1098   cerr
1099     << this->Internals->Communicator->GetWorldRank()
1100     << " CanRender " << canRender << endl;
1101   #endif
1102 
1103   return canRender;
1104 }
1105 
1106 namespace {
BuildAShader(vtkOpenGLRenderWindow * renWin,vtkOpenGLHelper ** cbor,const char * vert,const char * frag)1107   void BuildAShader(vtkOpenGLRenderWindow *renWin,
1108     vtkOpenGLHelper **cbor, const char * vert,
1109     const char *frag)
1110   {
1111   if (*cbor == nullptr)
1112   {
1113     *cbor = new vtkOpenGLHelper;
1114   }
1115   if (!(*cbor)->Program)
1116   {
1117     (*cbor)->Program =
1118         renWin->GetShaderCache()->ReadyShaderProgram(vert,
1119                                               frag,
1120                                               "");
1121   }
1122   else
1123   {
1124     renWin->GetShaderCache()->ReadyShaderProgram((*cbor)->Program);
1125   }
1126   }
1127 }
1128 
1129 //----------------------------------------------------------------------------
InitializeResources()1130 void vtkSurfaceLICInterface::InitializeResources()
1131 {
1132   bool initialized = true;
1133 
1134   // noise image
1135   if (!this->Internals->NoiseImage)
1136   {
1137     initialized = false;
1138 
1139     this->UpdateNoiseImage(this->Internals->Context);
1140   }
1141 
1142   // compositer for parallel operation
1143   if (!this->Internals->Compositor)
1144   {
1145     this->Internals->UpdateAll();
1146     vtkSurfaceLICComposite *compositor = vtkSurfaceLICComposite::New();
1147     compositor->SetContext(this->Internals->Context);
1148     this->Internals->Compositor = compositor;
1149     compositor->Delete();
1150   }
1151 
1152   // image LIC
1153   if (!this->Internals->LICer)
1154   {
1155     initialized = false;
1156 
1157     vtkLineIntegralConvolution2D *LICer = vtkLineIntegralConvolution2D::New();
1158     LICer->SetContext(this->Internals->Context);
1159     this->Internals->LICer = LICer;
1160     LICer->Delete();
1161   }
1162 
1163   // frame buffers
1164   if (!this->Internals->FBO)
1165   {
1166     initialized = false;
1167 
1168     vtkOpenGLFramebufferObject * fbo = vtkOpenGLFramebufferObject::New();
1169     fbo->SetContext(this->Internals->Context);
1170     this->Internals->FBO = fbo;
1171     fbo->Delete();
1172   }
1173 
1174   // load shader codes
1175   vtkOpenGLRenderWindow *renWin = this->Internals->Context;
1176 
1177   if (!this->Internals->ColorPass || !this->Internals->ColorPass->Program)
1178   {
1179     initialized = false;
1180     BuildAShader(renWin, &this->Internals->ColorPass,
1181       vtkTextureObjectVS, vtkSurfaceLICInterface_SC);
1182   }
1183 
1184   if (!this->Internals->ColorEnhancePass || !this->Internals->ColorEnhancePass->Program)
1185   {
1186     initialized = false;
1187     BuildAShader(renWin, &this->Internals->ColorEnhancePass,
1188       vtkTextureObjectVS, vtkSurfaceLICInterface_CE);
1189   }
1190 
1191   if (!this->Internals->CopyPass || !this->Internals->CopyPass->Program)
1192   {
1193     initialized = false;
1194     BuildAShader(renWin, &this->Internals->CopyPass,
1195       vtkTextureObjectVS, vtkSurfaceLICInterface_DCpy);
1196   }
1197 
1198   // if any of the above were not already initialized
1199   // then execute all stages
1200   if (!initialized)
1201   {
1202     this->Internals->UpdateAll();
1203   }
1204 }
1205 
1206 //----------------------------------------------------------------------------
NeedToUpdateCommunicator()1207 bool vtkSurfaceLICInterface::NeedToUpdateCommunicator()
1208 {
1209   // no comm or externally modified parameters
1210   if ( this->Internals->CommunicatorNeedsUpdate
1211     || this->Internals->ContextNeedsUpdate
1212     || !this->Internals->Communicator
1213     || this->AlwaysUpdate )
1214   {
1215     this->Internals->CommunicatorNeedsUpdate = true;
1216     this->Internals->UpdateAll();
1217   }
1218 
1219   #if vtkSurfaceLICInterfaceDEBUG >= 1
1220   cerr
1221     << this->Internals->Communicator->GetWorldRank()
1222     << " NeedToUpdateCommunicator "
1223     << this->Internals->CommunicatorNeedsUpdate << endl;
1224   #endif
1225 
1226   return this->Internals->CommunicatorNeedsUpdate;
1227 }
1228 
1229 //----------------------------------------------------------------------------
ValidateContext(vtkRenderer * renderer)1230 void vtkSurfaceLICInterface::ValidateContext(vtkRenderer *renderer)
1231 {
1232   bool modified = false;
1233 
1234   vtkOpenGLRenderWindow *context
1235     = vtkOpenGLRenderWindow::SafeDownCast(renderer->GetRenderWindow());
1236 
1237   // context changed
1238   if (this->Internals->Context != context)
1239   {
1240     modified = true;
1241     if (this->Internals->Context)
1242     {
1243       this->ReleaseGraphicsResources(this->Internals->Context);
1244     }
1245     this->Internals->Context = context;
1246   }
1247 
1248   // viewport size changed
1249   int viewsize[2];
1250   renderer->GetTiledSize(&viewsize[0], &viewsize[1]);
1251   if ( this->Internals->Viewsize[0] != viewsize[0]
1252     || this->Internals->Viewsize[1] != viewsize[1] )
1253   {
1254     modified = true;
1255 
1256     // update view size
1257     this->Internals->Viewsize[0] = viewsize[0];
1258     this->Internals->Viewsize[1] = viewsize[1];
1259 
1260     // resize textures
1261     this->Internals->ClearTextures();
1262     this->Internals->AllocateTextures(context, viewsize);
1263   }
1264 
1265   // if anything changed execute all stages
1266   if (modified)
1267   {
1268     this->Internals->UpdateAll();
1269   }
1270 
1271   #if vtkSurfaceLICInterfaceDEBUG >= 1
1272   cerr
1273     << this->Internals->Communicator->GetWorldRank()
1274     << " NeedToUpdatContext " << modified << endl;
1275   #endif
1276 }
1277 
SetHasVectors(bool v)1278 void vtkSurfaceLICInterface::SetHasVectors(bool v)
1279 {
1280   this->Internals->HasVectors = v;
1281 }
1282 
GetHasVectors()1283 bool vtkSurfaceLICInterface::GetHasVectors()
1284 {
1285   return this->Internals->HasVectors;
1286 }
1287 
1288 //----------------------------------------------------------------------------
GetCommunicator()1289 vtkPainterCommunicator *vtkSurfaceLICInterface::GetCommunicator()
1290 {
1291   return this->Internals->Communicator;
1292 }
1293 
1294 //----------------------------------------------------------------------------
CreateCommunicator(int)1295 vtkPainterCommunicator *vtkSurfaceLICInterface::CreateCommunicator(int)
1296 {
1297   return new vtkPainterCommunicator;
1298 }
1299 
1300 //----------------------------------------------------------------------------
CreateCommunicator(vtkRenderer * ren,vtkActor * act,vtkDataObject * input)1301 void vtkSurfaceLICInterface::CreateCommunicator(
1302   vtkRenderer *ren,
1303   vtkActor *act,
1304   vtkDataObject *input)
1305 {
1306   // compute screen space pixel extent of local blocks and
1307   // union of local blocks. only blocks that pass view frustum
1308   // visibility test are used in the computation.
1309   this->Internals->DataSetExt.Clear();
1310   this->Internals->BlockExts.clear();
1311 
1312   int includeRank = this->Internals->ProjectBounds(
1313           ren, act, input,
1314           this->Internals->Viewsize,
1315           this->Internals->DataSetExt,
1316           this->Internals->BlockExts);
1317 
1318   delete this->Internals->Communicator;
1319   this->Internals->Communicator = this->CreateCommunicator(includeRank);
1320 
1321   #if vtkSurfaceLICInterfaceDEBUG >= 1
1322   cerr
1323     << this->Internals->Communicator->GetWorldRank()
1324     << " is rendering " << includeRank << endl;
1325   #endif
1326 }
1327 
1328 //----------------------------------------------------------------------------
SetUpdateAll()1329 void vtkSurfaceLICInterface::SetUpdateAll()
1330 {
1331   this->Internals->UpdateAll();
1332 }
1333 
1334 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)1335 void vtkSurfaceLICInterface::PrintSelf(ostream & os, vtkIndent indent)
1336 {
1337   this->Superclass::PrintSelf(os, indent);
1338   os
1339     << indent << "NumberOfSteps=" << this->NumberOfSteps << endl
1340     << indent << "StepSize=" << this->StepSize << endl
1341     << indent << "NormalizeVectors=" << this->NormalizeVectors << endl
1342     << indent << "EnhancedLIC=" << this->EnhancedLIC << endl
1343     << indent << "EnhanceContrast=" << this->EnhanceContrast << endl
1344     << indent << "LowLICContrastEnhancementFactor=" << this->LowLICContrastEnhancementFactor << endl
1345     << indent << "HighLICContrastEnhancementFactor=" << this->HighLICContrastEnhancementFactor << endl
1346     << indent << "LowColorContrastEnhancementFactor=" << this->LowColorContrastEnhancementFactor << endl
1347     << indent << "HighColorContrastEnhancementFactor=" << this->HighColorContrastEnhancementFactor << endl
1348     << indent << "AntiAlias=" << this->AntiAlias << endl
1349     << indent << "MaskOnSurface=" << this->MaskOnSurface << endl
1350     << indent << "MaskThreshold=" << this->MaskThreshold << endl
1351     << indent << "MaskIntensity=" << this->MaskIntensity << endl
1352     << indent << "MaskColor=" << this->MaskColor[0] << ", " << this->MaskColor[1] << ", " << this->MaskColor[2] << endl
1353     << indent << "ColorMode=" << this->ColorMode << endl
1354     << indent << "LICIntensity=" << this->LICIntensity << endl
1355     << indent << "MapModeBias=" << this->MapModeBias << endl
1356     << indent << "GenerateNoiseTexture=" << this->GenerateNoiseTexture << endl
1357     << indent << "NoiseType=" << this->NoiseType << endl
1358     << indent << "NoiseTextureSize=" << this->NoiseTextureSize << endl
1359     << indent << "NoiseGrainSize=" << this->NoiseGrainSize << endl
1360     << indent << "MinNoiseValue=" << this->MinNoiseValue << endl
1361     << indent << "MaxNoiseValue=" << this->MaxNoiseValue << endl
1362     << indent << "NumberOfNoiseLevels=" << this->NumberOfNoiseLevels << endl
1363     << indent << "ImpulseNoiseProbablity=" << this->ImpulseNoiseProbability << endl
1364     << indent << "ImpulseNoiseBackgroundValue=" << this->ImpulseNoiseBackgroundValue << endl
1365     << indent << "NoiseGeneratorSeed=" << this->NoiseGeneratorSeed << endl
1366     << indent << "AlwaysUpdate=" << this->AlwaysUpdate << endl
1367     << indent << "CompositeStrategy=" << this->CompositeStrategy << endl;
1368 }
1369