Developer documentation | Axl-2.5.1

axlRenderer.cpp
Go to the documentation of this file.
1 /* axlRenderer.cpp ---
2  *
3  * Author: Meriadeg Perrinel
4  * Copyright (C) 2008 - Meriadeg Perrinel, Inria.
5  * Created: Tue Nov 9 16:58:59 2010 (+0100)
6  * Version: $Id$
7  * Last-Updated: Tue Nov 9 17:09:38 2010 (+0100)
8  * By: Meriadeg Perrinel
9  * Update #: 19
10  */
11 
12 /* Commentary:
13  *
14  */
15 
16 /* Change log:
17  *
18  */
19 
20 
21 #include "axlRenderer.h"
22 
23 
24 #include <vtkObjectFactory.h>
25 
26 #include "vtkCamera.h"
27 #include "vtkCommand.h"
28 #include "vtkGraphicsFactory.h"
29 #include "vtkHardwareSelector.h"
30 #include "vtkMath.h"
31 #include "vtkRendererDelegate.h"
32 #include "vtkRenderPass.h"
33 #include "vtkRenderState.h"
34 #include "vtkRenderWindow.h"
35 #include "vtkTexture.h"
36 
37 #include <QtGui>
38 
39 
40 //----------------------------------------------------------------------------
41 // Needed when we don't use the vtkStandardNewMacro.
42 //vtkStandardNewMacro(axlRenderer);
43 //----------------------------------------------------------------------------
44 
45 //vtkStandardNewMacro(axlRenderer);
46 
47 
48 class axlRendererPrivate
49 {
50 public:
51 
52  bool isGrid;
53 };
54 
55 axlRenderer::axlRenderer() : d(new axlRendererPrivate)
56 {
57  qDebug()<<"axlRenderer::New()";
58  d->isGrid = false;
59 }
61 {
62 
63 }
64 
65 void axlRenderer::useGrid(bool use)
66 {
67  d->isGrid = use;
68 }
69 
71 {
72  return d->isGrid;
73 }
74 void axlRenderer::PrintSelf(ostream& os, vtkIndent indent)
75 {
76  this->Superclass::PrintSelf(os,indent);
77 }
78 
79 
87 //void vtkRenderer::ResetCamera(double bounds[6])
88 //{
89 // qDebug()<< "axlRenderer::ResetCamera ";
90 // double center[3];
91 // double distance;
92 // double vn[3], *vup;
93 
94 // this->GetActiveCamera();
95 // if ( this->ActiveCamera != NULL )
96 // {
97 // this->ActiveCamera->GetViewPlaneNormal(vn);
98 // }
99 // else
100 // {
101 // vtkErrorMacro(<< "Trying to reset non-existant camera");
102 // return;
103 // }
104 
105 // center[0] = (bounds[0] + bounds[1])/2.0;
106 // center[1] = (bounds[2] + bounds[3])/2.0;
107 // center[2] = (bounds[4] + bounds[5])/2.0;
108 
109 // double w1 = bounds[1] - bounds[0];
110 // double w2 = bounds[3] - bounds[2];
111 // double w3 = bounds[5] - bounds[4];
112 // w1 *= w1;
113 // w2 *= w2;
114 // w3 *= w3;
115 // double radius = w1 + w2 + w3;
116 
117 // // If we have just a single point, pick a radius of 1.0
118 // radius = (radius==0)?(1.0):(radius);
119 
120 // // compute the radius of the enclosing sphere
121 // radius = sqrt(radius)*0.5;
122 
123 // // default so that the bounding sphere fits within the view fustrum
124 
125 // // compute the distance from the intersection of the view frustum with the
126 // // bounding sphere. Basically in 2D draw a circle representing the bounding
127 // // sphere in 2D then draw a horizontal line going out from the center of
128 // // the circle. That is the camera view. Then draw a line from the camera
129 // // position to the point where it intersects the circle. (it will be tangent
130 // // to the circle at this point, this is important, only go to the tangent
131 // // point, do not draw all the way to the view plane). Then draw the radius
132 // // from the tangent point to the center of the circle. You will note that
133 // // this forms a right triangle with one side being the radius, another being
134 // // the target distance for the camera, then just find the target dist using
135 // // a sin.
136 // double angle=vtkMath::RadiansFromDegrees(this->ActiveCamera->GetViewAngle());
137 // double parallelScale=radius;
138 
139 // this->ComputeAspect();
140 // double aspect[2];
141 // this->GetAspect(aspect);
142 
143 // if(aspect[0]>=1.0) // horizontal window, deal with vertical angle|scale
144 // {
145 // if(this->ActiveCamera->GetUseHorizontalViewAngle())
146 // {
147 // angle=2.0*atan(tan(angle*0.5)/aspect[0]);
148 // }
149 // }
150 // else // vertical window, deal with horizontal angle|scale
151 // {
152 // if(!this->ActiveCamera->GetUseHorizontalViewAngle())
153 // {
154 // angle=2.0*atan(tan(angle*0.5)*aspect[0]);
155 // }
156 
157 // parallelScale=parallelScale/aspect[0];
158 // }
159 
160 // distance =radius/sin(angle*0.5);
161 
162 // // check view-up vector against view plane normal
163 // vup = this->ActiveCamera->GetViewUp();
164 // if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 )
165 // {
166 // vtkWarningMacro(<<"Resetting view-up since view plane normal is parallel");
167 // this->ActiveCamera->SetViewUp(-vup[2], vup[0], vup[1]);
168 // }
169 
170 // // update the camera
171 // this->ActiveCamera->SetFocalPoint(center[0],center[1],center[2]);
172 // this->ActiveCamera->SetPosition(center[0]+distance*vn[0],
173 // center[1]+distance*vn[1],
174 // center[2]+distance*vn[2]);
175 // bounds[0] = -500;
176 // bounds[1] = +500;
177 // bounds[2] = -500;
178 // bounds[3] = +500;
179 // bounds[4] = -500;
180 // bounds[5] = +500;
181 // this->ResetCameraClippingRange( bounds );
182 
183 // // setup default parallel scale
184 // this->ActiveCamera->SetParallelScale(parallelScale);
185 //}
186 
187 
195 
197 
199 
208 
213 
214 
221 
228 
231 
232 
240 
246 
253 
261 
265 
279 
285 
289 
292 
308 
316 
319 
322 //void vtkRenderer::ResetCameraClippingRange()
323 //{
324 // double allBounds[6];
325 
326 // this->ComputeVisiblePropBounds( allBounds );
327 
328 // allBounds[0] = -500;
329 // allBounds[1] = +500;
330 // allBounds[2] = -500;
331 // allBounds[3] = +500;
332 // allBounds[4] = -500;
333 // allBounds[5] = +500;
334 
335 // if (!vtkMath::AreBoundsInitialized(allBounds))
336 // {
337 // vtkDebugMacro( << "Cannot reset camera clipping range!" );
338 // }
339 // else
340 // {
341 // this->ResetCameraClippingRange(allBounds);
342 // }
343 
344 // // Here to let parallel/distributed compositing intercept
345 // // and do the right thing.
346 // this->InvokeEvent(vtkCommand::ResetCameraClippingRangeEvent,this);
347 //}
348 
350 
351 
352 
353 // Automatically set up the camera based on a specified bounding box
354 // (xmin,xmax, ymin,ymax, zmin,zmax). Camera will reposition itself so
355 // that its focal point is the center of the bounding box, and adjust its
356 // distance and position to preserve its initial view plane normal
357 // (i.e., vector defined from camera position to focal point). Note: if
358 // the view plane is parallel to the view up axis, the view up axis will
359 // be reset to one of the three coordinate axes.
360 void axlRenderer::ResetCamera(double bounds[6])
361 {
362  qDebug()<< "axlRenderer::ResetCamera ";
363  double center[3];
364  double distance;
365  double vn[3], *vup;
366 
367  this->GetActiveCamera();
368  if ( this->ActiveCamera != NULL )
369  {
370  this->ActiveCamera->GetViewPlaneNormal(vn);
371  }
372  else
373  {
374  vtkErrorMacro(<< "Trying to reset non-existant camera");
375  return;
376  }
377 
378  center[0] = (bounds[0] + bounds[1])/2.0;
379  center[1] = (bounds[2] + bounds[3])/2.0;
380  center[2] = (bounds[4] + bounds[5])/2.0;
381 
382  double w1 = bounds[1] - bounds[0];
383  double w2 = bounds[3] - bounds[2];
384  double w3 = bounds[5] - bounds[4];
385  w1 *= w1;
386  w2 *= w2;
387  w3 *= w3;
388  double radius = w1 + w2 + w3;
389 
390  // If we have just a single point, pick a radius of 1.0
391  radius = (radius==0)?(1.0):(radius);
392 
393  // compute the radius of the enclosing sphere
394  radius = sqrt(radius)*0.5;
395 
396  // default so that the bounding sphere fits within the view fustrum
397 
398  // compute the distance from the intersection of the view frustum with the
399  // bounding sphere. Basically in 2D draw a circle representing the bounding
400  // sphere in 2D then draw a horizontal line going out from the center of
401  // the circle. That is the camera view. Then draw a line from the camera
402  // position to the point where it intersects the circle. (it will be tangent
403  // to the circle at this point, this is important, only go to the tangent
404  // point, do not draw all the way to the view plane). Then draw the radius
405  // from the tangent point to the center of the circle. You will note that
406  // this forms a right triangle with one side being the radius, another being
407  // the target distance for the camera, then just find the target dist using
408  // a sin.
409  double angle=vtkMath::RadiansFromDegrees(this->ActiveCamera->GetViewAngle());
410  double parallelScale=radius;
411 
412  this->ComputeAspect();
413  double aspect[2];
414  this->GetAspect(aspect);
415 
416  if(aspect[0]>=1.0) // horizontal window, deal with vertical angle|scale
417  {
418  if(this->ActiveCamera->GetUseHorizontalViewAngle())
419  {
420  angle=2.0*atan(tan(angle*0.5)/aspect[0]);
421  }
422  }
423  else // vertical window, deal with horizontal angle|scale
424  {
425  if(!this->ActiveCamera->GetUseHorizontalViewAngle())
426  {
427  angle=2.0*atan(tan(angle*0.5)*aspect[0]);
428  }
429 
430  parallelScale=parallelScale/aspect[0];
431  }
432 
433  distance =radius/sin(angle*0.5);
434 
435  // check view-up vector against view plane normal
436  vup = this->ActiveCamera->GetViewUp();
437  if ( fabs(vtkMath::Dot(vup,vn)) > 0.999 )
438  {
439  vtkWarningMacro(<<"Resetting view-up since view plane normal is parallel");
440  this->ActiveCamera->SetViewUp(-vup[2], vup[0], vup[1]);
441  }
442 
443  // update the camera
444  this->ActiveCamera->SetFocalPoint(center[0],center[1],center[2]);
445  this->ActiveCamera->SetPosition(center[0]+distance*vn[0],
446  center[1]+distance*vn[1],
447  center[2]+distance*vn[2]);
448 
449  if(d->isGrid)
450  {
451  bounds[0] = -500;
452  bounds[1] = +500;
453  bounds[2] = -500;
454  bounds[3] = +500;
455  bounds[4] = -500;
456  bounds[5] = +500;
457  }
458 
459  this->ResetCameraClippingRange( bounds );
460 
461  // setup default parallel scale
462  this->ActiveCamera->SetParallelScale(parallelScale);
463 }
464 
465 
466 // Automatically set up the camera based on the visible actors.
467 // The camera will reposition itself to view the center point of the actors,
468 // and move along its initial view plane normal (i.e., vector defined from
469 // camera position to focal point) so that all of the actors can be seen.
471 {
472  qDebug()<< "axlRenderer::ResetCamera 2 ";
473 
474  double allBounds[6];
475 
476  this->ComputeVisiblePropBounds( allBounds );
477 
478  if (!vtkMath::AreBoundsInitialized(allBounds))
479  {
480  vtkDebugMacro( << "Cannot reset camera!" );
481  }
482  else
483  {
484  this->ResetCamera(allBounds);
485  }
486 
487  // Here to let parallel/distributed compositing intercept
488  // and do the right thing.
489  this->InvokeEvent(vtkCommand::ResetCameraEvent,this);
490 }
491 
492 
493 // Alternative version of ResetCamera(bounds[6]);
494 void axlRenderer::ResetCamera(double xmin, double xmax,
495  double ymin, double ymax,
496  double zmin, double zmax)
497 {
498  double bounds[6];
499 
500  bounds[0] = xmin;
501  bounds[1] = xmax;
502  bounds[2] = ymin;
503  bounds[3] = ymax;
504  bounds[4] = zmin;
505  bounds[5] = zmax;
506 
507  this->ResetCamera(bounds);
508 }
509 
510 
511 // Reset the camera clipping ranger to include this entire bounding box
513 {
514  std::cout<< " reset vtk Camera"<<std::endl;
515  double vn[3], position[3], a, b, c, d;
516  double range[2], dist;
517  int i, j, k;
518 
519  // Don't reset the clipping range when we don't have any 3D visible props
520  if (!vtkMath::AreBoundsInitialized(bounds))
521  {
522  return;
523  }
524 
525  this->GetActiveCameraAndResetIfCreated();
526  if ( this->ActiveCamera == NULL )
527  {
528  vtkErrorMacro(<< "Trying to reset clipping range of non-existant camera");
529  return;
530  }
531 
532  // Find the plane equation for the camera view plane
533  this->ActiveCamera->GetViewPlaneNormal(vn);
534  this->ActiveCamera->GetPosition(position);
535  a = -vn[0];
536  b = -vn[1];
537  c = -vn[2];
538  d = -(a*position[0] + b*position[1] + c*position[2]);
539 
540  // Set the max near clipping plane and the min far clipping plane
541  range[0] = a*bounds[0] + b*bounds[2] + c*bounds[4] + d;
542  range[1] = 1e-18;
543 
544  // Find the closest / farthest bounding box vertex
545  for ( k = 0; k < 2; k++ )
546  {
547  for ( j = 0; j < 2; j++ )
548  {
549  for ( i = 0; i < 2; i++ )
550  {
551  dist = a*bounds[i] + b*bounds[2+j] + c*bounds[4+k] + d;
552  range[0] = (dist<range[0])?(dist):(range[0]);
553  range[1] = (dist>range[1])?(dist):(range[1]);
554  }
555  }
556  }
557 
558  // Do not let the range behind the camera throw off the calculation.
559  if (range[0] < 0.0)
560  {
561  range[0] = 0.0;
562  }
563 
564  // Give ourselves a little breathing room
565  range[0] = 0.99*range[0] - (range[1] - range[0])*0.5;
566  range[1] = 1.01*range[1] + (range[1] - range[0])*0.5;
567 
568  // Make sure near is not bigger than far
569  range[0] = (range[0] >= range[1])?(0.01*range[1]):(range[0]);
570 
571  // Make sure near is at least some fraction of far - this prevents near
572  // from being behind the camera or too close in front. How close is too
573  // close depends on the resolution of the depth buffer
574  if (!this->NearClippingPlaneTolerance)
575  {
576  this->NearClippingPlaneTolerance = 0.01;
577  if (this->RenderWindow)
578  {
579  int ZBufferDepth = this->RenderWindow->GetDepthBufferSize();
580  if ( ZBufferDepth > 16 )
581  {
582  this->NearClippingPlaneTolerance = 0.001;
583  }
584  }
585  }
586 
587  // make sure the front clipping range is not too far from the far clippnig
588  // range, this is to make sure that the zbuffer resolution is effectively
589  // used
590  if (range[0] < this->NearClippingPlaneTolerance*range[1])
591  {
592  range[0] = this->NearClippingPlaneTolerance*range[1];
593  }
594 
595  this->ActiveCamera->SetClippingRange( range );
596 }
597 
598 // Automatically set the clipping range of the camera based on the
599 // visible actors
601 {
602  double allBounds[6];
603 
604  this->ComputeVisiblePropBounds( allBounds );
605 
606  if(d->isGrid)
607  {
608  allBounds[0] = -500;
609  allBounds[1] = +500;
610  allBounds[2] = -500;
611  allBounds[3] = +500;
612  allBounds[4] = -500;
613  allBounds[5] = +500;
614  }
615 
616  if (!vtkMath::AreBoundsInitialized(allBounds))
617  {
618  vtkDebugMacro( << "Cannot reset camera clipping range!" );
619  }
620  else
621  {
622  this->ResetCameraClippingRange(allBounds);
623  }
624 
625  // Here to let parallel/distributed compositing intercept
626  // and do the right thing.
627  this->InvokeEvent(vtkCommand::ResetCameraClippingRangeEvent,this);
628 }
629 
630 
631 
632 
634 //axlRenderer *axlRenderer::New()
635 //{
636 // // First try to create the object from the vtkObjectFactory
637 // //vtkObject* ret = vtkObjectFactory::CreateInstance("axlRenderer");
638 // return new axlRenderer;//static_cast<axlRenderer *>(ret);
639 //}
void useGrid(bool use)
Definition: axlRenderer.cpp:65
void PrintSelf(ostream &os, vtkIndent indent)
Definition: axlRenderer.cpp:74
bool grid(void)
Definition: axlRenderer.cpp:70
void ResetCameraClippingRange()
void ResetCamera()
double angle(axlPoint vCompute, axlPoint vRef, axlPoint normal)