[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