[vtk-developers] vtkGlyph3D & range clamping

John Platt jcplatt at lineone.net
Wed May 18 16:28:54 EDT 2005


Hi Will,

 

For geometric scales, I have made changes to

 

            vtkWarpScalar

            vtkWarpVector

            vtkGlyph3D

            vtkTensorGlyph

 

For vtkMapper, I have a programmable vtkMergeDataObjectFilter which sets
the range of the lookup table used by the mapper each time the filter
executes. A new method, say, vtkMapper::AutoRangeOn() which mapped the
input to [0,1] would presumably remove the need for the LUT range update
(provided UseLookupTableScalarRangeOff()).

 

On the implementation side, maybe you could consider some transform
switches for vtkDataArray like NormalizeOn()/Off(), ClampOn()/Off()
which could be used by GetTuple(), GetComponent(), GetValue() to
transform the data on the fly. The original scalars do need to be
preserved so they can be used for, say, labeling.

 

Thanks for your interest.

 

John.

 

 

 

-----Original Message-----
From: Will Schroeder [mailto:will.schroeder at kitware.com] 
Sent: 18 May 2005 11:38
To: John Platt; vtk-developers at vtk.org
Subject: Re: [vtk-developers] vtkGlyph3D & range clamping

 

John-

I apologize if I've missed something here: for which classes are you
proposing these changes? vtkGlyph3D, vtkWarpScalar, and ?? How many
classes are involved? Your ideas have merit but I'm wondering if it
should be done class-by-class or somehow encapsulated in a helper
class...

Will

At 06:20 PM 5/11/2005, John Platt wrote:



Hi,
 
Maybe I've missed something but I seem to spend a lot of time modifying
filters to normalise the input data at the time of execution. Here's an
example of bodging the scale factor so the warp is always shown a fixed
size.
 
void vtkWarpScalarEx::Execute()
{
    vtkDataArray* inScalars =
this->GetInput()->GetPointData()->GetScalars(
this->InputScalarsSelection );
    double scaleFactor = this->ScaleFactor;
    if ( inScalars )
      {
      double maxNorm = inScalars->GetMaxNorm();
      if ( maxNorm > 0.0 )
        this->SetScaleFactor( scaleFactor/maxNorm );
      }
    vtkWarpScalar::Execute();
    this->SetScaleFactor( scaleFactor );
}
 
Mapping attribute data to the range to [0,1] doesn't always solve the
problem either, particularly when computing a scale factor for sizing
glyphs. For example, suppose there are sphere glyphs representing masses
M1 < M2 and M2 is to be displayed a fixed size. Normalising scalars
(say) to [0, 1] will leave M1 zero size. Provision for this kind of
functionality requires independent access to the attribute data limits.
Here is a solution for the mass problem using UpperClampToMaxNormOn().
 
vtkGlyph3D.h
==========
 
Replace 
 
  // Description:
  // Specify range to map scalar values into.
  vtkSetVector2Macro(Range,double);
  vtkGetVectorMacro(Range,double,2);
 
By
 
  // Description:
  // Specify the range for clamping the scalar values (or vector
magnitude if
  // ScaleByVector() is enabled). Scalars outside this range are set to
the
  // end points and then normalised to [0-1]. Glyphs for points with
scalars
  // less than or equal to Range[0] with therefore not be visible. This
range is
  // only used with ClampingOn()
  vtkSetVector2Macro(Range,double);
  vtkGetVectorMacro(Range,double,2);
 
  vtkSetMacro(LowerClampToMinNorm,int);
  vtkBooleanMacro(LowerClampToMinNorm,int);
  vtkGetMacro(LowerClampToMinNorm,int);
 
  vtkSetMacro(UpperClampToMaxNorm,int);
  vtkBooleanMacro(UpperClampToMaxNorm,int);
  vtkGetMacro(UpperClampToMaxNorm,int);
 
Insert
 
  int LowerClampToMinNorm; // Use the min norm of the attribute data as
the lower clamp
  int UpperClampToMaxNorm; // Use the max norm of the attribute data as
the upper clamp
 
 
vtkGlyph3D.cxx (Revision: 1.112)
========================
 
vtkGlyph3D::vtkGlyph3D()
 
Insert
 
  this->LowerClampToMinNorm = 0;
  this->UpperClampToMaxNorm = 0;
 
vtkGlyph3D::Execute()
 
Remove
 
  // Check input for consistency
  //
  if ( (den = this->Range[1] - this->Range[0]) == 0.0 )
    {
    den = 1.0;
    }
 
After 
 
  else
    {
    haveVectors = 0;
    }
 
Insert
 
  // Set the range for clamping the data scale factors.
  if ( this->Clamping && ( this->LowerClampToMinNorm ||
this->UpperClampToMaxNorm ) )
    {
    double* inRange = NULL;
    if ( inScalars && this->ScaleMode == VTK_SCALE_BY_SCALAR )
      {
      inRange = inScalars->GetRange();
      }
    else if ( haveVectors )
      {
      if ( this->VectorMode == VTK_USE_NORMAL )
        {
        inRange = inNormals->GetRange( -1 );
        }
      else
        {
        inRange = inVectors->GetRange( -1 );
        }
      }
    if ( inRange && LowerClampToMinNorm ) this->Range[0] = inRange[0];
    if ( inRange && UpperClampToMaxNorm ) this->Range[1] = inRange[1];
    }
 
  if ( (den = this->Range[1] - this->Range[0]) == 0.0 ) den = 1.0;
 
 
vtkGlyph3D::PrintSelf()
 
Replace 
 
  os << indent << "Range: (" << this->Range[0] << ", " << this->Range[1]
<< ")\n";
 
By
 
  os << indent << "Range: (";
  this->LowerClampToMinNorm ? os << "Min norm,"   : os << this->Range[0]
<< ",";
  this->UpperClampToMaxNorm ? os << "Max norm)\n" : os << this->Range[1]
<< ")\n";
 
If this kind of functionality is useful I will add it to bug tracker as
a feature request.
 
Where the clamping and normalisation are not combined, it would be
useful to have methods like
 
            ScaleByMinNorm()/ScaleByMaxNorm()
            SetLowerClamp( lower )/SetUpperClamp( upper )
            MapToRange( lower, upper )
 
Using MapToRange( 0, 1 ) on vtkMapper would allow scalars of any range
to be colour mapped red through blue without having to call SetRange()
with actual attribute values. This would go some way to lessening the
assumption that the data range is known in advance.
 
Thanks for your consideration.
 
John Platt.
 
_______________________________________________
vtk-developers mailing list
vtk-developers at vtk.org
http://www.vtk.org/mailman/listinfo/vtk-developers

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtk-developers/attachments/20050518/77718653/attachment.html>


More information about the vtk-developers mailing list