[vtkusers] double vtkDataArray::GetTuple1(vtkIdType i) vs void vtkDataArray::GetTuple(vtkIdType i, double *tuple)
David Gobbi
david.gobbi at gmail.com
Wed May 7 17:22:23 EDT 2014
Hi Maarten,
Since you know it's a vtkUnsignedCharArray, you shouldn't be using
the SetTuple/GetTuple methods. Use the SetTupleValue and
GetTupleValue methods, they're much faster because 1) they aren't
virtual methods and 2) they don't have to convert to/from double.
Or even better, if you know that your array only has one component,
you can use SetValue/GetValue.
Your math for voxelid is too simplistic. Depending on how the update
extent is divided amongst the threads, it might give you a location
that is totally wrong. To see why, draw a square on a piece of paper.
That square represents the total extent of the output. Then divide
that square into quadrants, and imagine that each quadrant goes
to a different Execute method. Then think about how each thread
is going to march through the data.
David
On Wed, May 7, 2014 at 2:20 PM, Maarten Beek <beekmaarten at yahoo.com> wrote:
> Hi all,
>
> I experienced a crash in my algorithm derived from
> vtkThreadedImageAlgorithm, that (I think) I solved, but that I don't
> understand. Is there some one who can shed some light on the following?
>
> What I am trying to do is adding a flag identifying the input(s) that
> contribute to the value of each pixel in the output image
>
> //----------------------------------------------------------------------------
> // This templated function executes the filter for any type of data.
> template <class OT>
> void cmvtkTemplatedExecute(cmvtkDRRGenerator2* self,
> vtkDataSetCollection* inputs, vtkImageData*
> output,
> int extent[6], int threadId, OT*)
> {
> vtkUnsignedCharArray* uchararray =
> vtkUnsignedCharArray::SafeDownCast(output->GetPointData()->GetScalars("input_flag"));
>
> int numinputs = inputs->GetNumberOfItems();
> for( int input_i = 0; input_i < numinputs; ++input_i )
> {
> vtkImageData* input =
> vtkImageData::SafeDownCast(inputs->GetItem(input_i));
> if( 0 == input )
> {
> // should not happen
> continue;
> }
> const int* dims= output->GetDimensions();
>
> vtkImageProgressIterator<OT> outIt(output, extent, self, threadId);
> vtkIdType voxelid = extent[0] + size[0]*extent[2] +
> size[0]*size[1]*extent[4];
>
> // Loop through output pixels
> while( !outIt.IsAtEnd() )
> {
> OT* outSI = outIt.BeginSpan();
> OT* outSIEnd = outIt.EndSpan();
>
> while( outSI != outSIEnd )
> {
> // start with setting pixel to 0.0
> if( input_i == 0 )
> {
> *outSI = 0.0;
> }
>
> OT result = 0.0;
>
> //.... some math resulting in a value for result....
>
> *outSI += result;
>
> // this input image participates in voxel values; adjust bit
> if( 0.0 < result && 0 != uchararray )
> {
> // The commented code crashes...
>
> //unsigned char oldvalue =
> uchararray->GetTuple1(voxelid);
> //unsigned char newvalue = oldvalue | (1<<input_i);
> //uchararray->SetTuple1(voxelid, newvalue);
>
> double dOldValue;
> uchararray->GetTuple(voxelid, &dOldValue);
> unsigned char chOldValue = static_cast<unsigned
> char>(dOldValue);
> unsigned char chNewValue = chOldValue | (1<<input_i);
> double dNewValue = static_cast<double>(chNewValue);
> uchararray->SetTuple(voxelid, &dNewValue);
> }
>
> ++outSI;
> ++voxelid;
> }
> outIt.NextSpan();
> }
> } // input_i < numinputs
> }
More information about the vtkusers
mailing list