[vtkusers] OK so does ANYONE use the vtkImageTracerWidget?

Dean Inglis dean.inglis at sympatico.ca
Tue Nov 6 09:25:08 EST 2007


>I have the opposite issue with int/reinit of handles. I'd like to be
>able to turn on all the handles for all the points once a curve is
>closed ;-)

If you are tracing continuously, at the end of
the widget interaction you could turn all
the path points into handles with:

vtkPolyData* poly = vtkPolyData::New();
widget->GetPath(poly);
widget->InitializeHandles(poly->GetPoints());
poly->Delete();

The other problem of initializing only
one or two handles to control many
points (unambiguously) is not part of the API currently,
but if you have some modifications
I would be happy to take a look.  A
much faster way to edit a polyline with
points is to use vtkContourWidget.
Another approach I have used to
reduce the number of handles is to
delete intermediate points between
points where a change in curvature occurs.
This works particularly well when the
handles/points are all coincident with
voxel or pixel coordinates. See code below.

Dean



//--------------------------------------------------------------------------
-
// assumes a piecwise linear polyline with points at discrete locations
//
int vtkGeometryUtilities::ReducePolyData2D( vtkPolyData* inPoly,
	 vtkPolyData* outPoly, const int& closed )
{
  if ( !inPoly || !outPoly ){ return 0; }

  vtkPoints* inPts = inPoly->GetPoints();
  if ( !inPts ){ return 0; }
  int n = inPts->GetNumberOfPoints();
  if ( n < 3 ) { return 0; }

  double p0[3];
  inPts->GetPoint( 0, p0 );
  double p1[3];
  inPts->GetPoint( n - 1, p1 );
  bool minusNth = ( p0[0] == p1[0] && p0[1] == p1[1] && p0[2] == p1[2] );
  if ( minusNth && closed ) { --n; }

  struct frenet
    {
    double t[3];   // unit tangent vector
    bool   state; // state of kappa: zero or non-zero  T/F
    };

  frenet* f;
  f = new frenet[n];
  double tL;
  // calculate the tangent vector by forward differences
  for ( int i = 0; i < n; ++i )
    {
    inPts->GetPoint( i, p0 );
    inPts->GetPoint( ( i + 1 ) % n, p1 );
    tL = sqrt( vtkMath::Distance2BetweenPoints( p0, p1 ) );
    if ( tL == 0.0 ){ tL = 1.0; }
    for ( int j = 0 ; j < 3; ++j )
      {
      f[i].t[j] = (p1[j] - p0[j]) / tL;
      }
    }

  // calculate kappa from tangent vectors by forward differences
  // mark those points that have very low curvature
  double eps = 1.e-10;

  for ( int i = 0; i < n; ++i )
    {
    f[i].state = ( fabs( vtkMath::Dot( f[i].t, f[( i + 1 ) % n].t ) - 1.0 )
< eps );
    }

  vtkPoints* tempPts = vtkPoints::New();

  // mark keepers
  vtkIdTypeArray* ids = vtkIdTypeArray::New();

  // for now, insist on keeping the first point for closure
  ids->InsertNextValue( 0 );

  for ( int i = 1; i < n; ++i )
    {
    bool pre = f[( i - 1 + n ) % n].state; // means fik != 1
    bool cur = f[i].state;  // means fik = 1
    bool nex = f[( i + 1 ) % n].state;

   // possible vertex bend patterns for keep: pre cur nex
   // 0 0 1
   // 0 1 1
   // 0 0 0
   // 0 1 0

   // definite delete pattern
   // 1 1 1

   bool keep = false;

   if      (  pre &&  cur &&  nex ) { keep = false; }
   else if ( !pre && !cur &&  nex ) { keep = true; }
   else if ( !pre &&  cur &&  nex ) { keep = true; }
   else if ( !pre && !cur && !nex ) { keep = true; }
   else if ( !pre &&  cur && !nex ) { keep = true; }

   if ( keep  ) // not a current sure thing but the preceding delete was
      {
      ids->InsertNextValue( i );
      }
    }

  for ( int i = 0; i < ids->GetNumberOfTuples(); ++i )
    {
    tempPts->InsertNextPoint( inPts->GetPoint( ids->GetValue( i ) ) );
    }

  if ( closed )
    {
    tempPts->InsertNextPoint( inPts->GetPoint( ids->GetValue( 0 ) ) );
    }

  ConvertPointSequenceToPolyData( tempPts, closed, outPoly );

  ids->Delete();
  tempPts->Delete();
  delete [] f;
  return 1;
}




More information about the vtkusers mailing list