[vtkusers] Slow rendering of derived class of vtkImplicitFunction

David.Pont at ForestResearch.co.nz David.Pont at ForestResearch.co.nz
Wed Oct 8 17:16:26 EDT 2003


Hi,
   My guess is that vtkSampleFunction is the part that takes the most time.
You use SetSampleDimensions to define the number of samples, for example
50*50*50 = 125,000 samples. Your implicit function EvaluateFunction will be
called for each of these, and I see your EvaluateFunction uses exp and
sqrt.
This volume is then contoured to produce a surface, the contouring
algorithms are relatively efficient, but this might be the next slowest
part.
If you use smaller SampleDimensions you will note a dramatic (exponential)
increase in speed, but you will also notice a poor representation of the
surface. The problem with vtkSampleFunction is that in order to sample the
surface at high resolution you have to sample a lot of dead space away from
the surface.

A basic design philosophy in vtk is to favour generality in algorithms, for
good reason. Producing a volume (structured points) from an implicit
function is smart because there are many vtk classes that can be used on
this type of data.
Check the literature and you will find examples of 'fast' algorithms for
creating implicit surfaces (Google 'implicit polygon'). I played around
with implicit polygonization by Velho (source code available off the
internet) some years back, but never had a real need for it.
The vtk philosophy would encourage you to implement a faster but more
specialised algorithm... (and would encourage you to contribute it back
;-P). Take a look at the documentation for vtkContourFilter and note the
'See also' for an example of a generic algorithm and its more specialised
friends.
So how are your C++ skills? they look just fine from your example code. You
could implement a new vtk class to do fast polygonization of implicit
surfaces in a few days... and have interactive blobs.

The only other way around might be to use vtkLODActor and feed it one (or
more) low resolution (low SampleDimensions) pipelines and one at the
desired resolution... ??

regards
   Dave P.



|---------+---------------------------->
|         |           "#LIM LAY NA#"   |
|         |           <wolken at pmail.ntu|
|         |           .edu.sg>         |
|         |           Sent by:         |
|         |           vtkusers-admin at vt|
|         |           k.org            |
|         |                            |
|         |                            |
|         |           08/10/2003 18:29 |
|         |                            |
|---------+---------------------------->
  >--------------------------------------------------------------------------------------------------------------------------------|
  |                                                                                                                                |
  |       To:       <vtkusers at vtk.org>                                                                                             |
  |       cc:                                                                                                                      |
  |       Subject:  [vtkusers] Slow rendering of derived class of vtkImplicitFunction                                              |
  >--------------------------------------------------------------------------------------------------------------------------------|




Hi all,
I'm having problems rendering my own derived class of vtkImplicitFunction.
I'm trying to construct a blobby from scattered 3d points using the
gaussian equation
f(x,y,z) = Sum to k(B*exp(-ar^2))+Threshold, where r^2 is the distance
to another pt and a, B are parameters to control the blobbiness.
The pipeline is
MyBlob->SampleFunction->ContourFilter->PolyDataNormals->PolyDataMapper->Actor.
It takes about 1.5min to render the surface which is too long. It's
supposed to be almost instant because
user interaction is needed. I've tried changing the contour filter to
vtkMarchingContourFilter but there
wasn't any improvement. Can anyone point out to me which part of the
pipeline is slowing it down or whether it
is anything to do with the code for the derived class. Thanks a lot.

// .NAME MyBlob - implicit function for blobby shape from 3D points
// .SECTION Description
// MyBlob computes the implicit function and/or gradient for a blobby shape
from a set of points.
// MyBlobis a concrete implementation of vtkImplicitFunction.

class MyBlob : public vtkImplicitFunction
{
public:
            vtkTypeMacro(MyBlob,vtkImplicitFunction);
            void PrintSelf(ostream& os, vtkIndent indent);

            // Description
            // Construct blob with scale factor = 0.6, exp factor = 25.0,
threshold = 0.5, delta = 0.0001
            static MyBlob *New();

            // Description
            // Evaluate blob equation
            float EvaluateFunction(float x[3]);
            float EvaluateFunction(float x, float y, float z)
                        {return
this->vtkImplicitFunction::EvaluateFunction(x,y,z); };

            // Description
            // Evaluate blob gradient
            void EvaluateGradient(float x[3], float n[3]);

            // Description
            // Set all points used in implicit function
            void SetPoints(vtkPoints *allPts);

            // Description:
            // Set / get the bounds
            vtkSetVectorMacro(Bounds, float, 6);
            vtkGetVectorMacro(Bounds, float, 6);

protected:
            MyBlob();
            ~MyBlob() {};

            vtkPoints *allPts;
            float ExponentFactor, ScaleFactor, Threshold, Bounds[6];
            int numPts;
            float *x, *y, *z;
};

vtkStandardNewMacro(MyBlob);

// Construct blob equation with default parameters
MyBlob::MyBlob()
{

            ExponentFactor = 25.0;
            ScaleFactor = 0.5;
            Threshold = 0.5;
}

// Input points needed to calculate the implicit function
void MyBlob::SetPoints(vtkPoints *allPts)
{
            float pt[3];

            if(!allPts)
                        return;

            this->allPts = allPts;
            this->numPts = allPts->GetNumberOfPoints();
            this->x = new float[this->numPts];
            this->y = new float[this->numPts];
            this->z = new float[this->numPts];
            for(int i = 0; i<this->numPts; i++)
            {
                        allPts->GetPoint(i,pt);
                        this->x[i] = pt[0];
                        this->y[i] = pt[1];
                        this->z[i] = pt[2];
            }

            this->SetBounds(allPts->GetBounds());
            for(i=0; i<6; i+=2)
            {
                        this->Bounds[i] -= 110;
            }
            for(i=1; i<6; i+=2)
            {
                        this->Bounds[i] += 110;
            }
}


// Evaluate blob equation
float MyBlob::EvaluateFunction(float xyz[3])
{
            float xx, yy, zz, distance;

            float sum = 0.0;
            float pt[3];

            if( this->allPts )
            {
                        for(int i=0; i<numPts; i++)
                        {
                                    xx = xyz[0] - x[i];
                                    yy = xyz[1] - y[i];
                                    zz = xyz[2] - z[i];

                                    distance = sqrt(xx*xx + yy*yy + zz*zz);

                                    sum = sum +
ScaleFactor*exp(-distance/ExponentFactor);
                        }
            }

            return sum-Threshold;
}


// Evaluate blob gradient
void MyBlob::EvaluateGradient(float xyz[3], float n[3])
{
 float xx, yy, zz, distance;


 n[0]=n[1]=n[2]=0;

 if( this->allPts )
 {
  for(int i=0; i<numPts; i++)
  {
   xx = xyz[0] - x[i];
   yy = xyz[1] - y[i];
   zz = xyz[2] - z[i];

   distance = sqrt(xx*xx + yy*yy + zz*zz);

   n[0] = n[0] -(ScaleFactor*xx*exp(-distance/ExponentFactor))/distance;
   n[1] = n[1] -(ScaleFactor*yy*exp(-distance/ExponentFactor))/distance;
   n[2] = n[2] -(ScaleFactor*zz*exp(-distance/ExponentFactor))/distance;
  }
 }

}








More information about the vtkusers mailing list