[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:26:02 EDT 2014
I should add: you actually have to re-initialize the voxelid at the
beginning of each row (i.e. at the beginning of each span of the
iterator).
On Wed, May 7, 2014 at 3:22 PM, David Gobbi <david.gobbi at gmail.com> wrote:
> 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