Hey all, So I’m apparently still confused about what (not) to call in Iop::_validate, Iop::_request, and Iop::engine when I only need to do things to certain channels.
I’ve written a (theoretically) dead-simple Iop that averages the incoming RGB channels in place, and passes any other channels through. However, there’s either something wrong with my code, or I’m running into a Nuke bug I encountered a couple weeks ago with channel requests, because I keep getting viewer lock-ups and messages like 'Warning: [node name]: get(channels=0x7), but request(channels=0x2000)' in the terminal. I’d like to rule out the "bad user code" side of things and get any issues cleaned up on my side, so I’d appreciate it if someone could take a look and tell me if I’m doing something ass-backwards here. The rough summary of what the op should be doing is: 1) Only changing rgba.red, .green, and .blue. 2) In engine, aggregating each of those channels into a private double[3] array, dividing the aggregated values by the pixel count, and storing those averages in another private float[3] array. 3) Unlocking the engine threads and, for any channels not intersecting Mask_RGB, copying the input channel straight through; otherwise, writing the appropriate component of the average array to the entire output buffer. Like I said, I seem to still be overlooking something regarding what channels to set_out, request, and get(), so there may be some pretty stupid mistakes in here (on that note, it would be great if there were some better examples of how to use each of those steps somewhere). I’ve tried tweaking various ChannelSets and calls in different methods, and there are still a few code optimizations I think I could do, but right now I’m having no luck. CODE TIME: ---------------------------- void _validate(bool for_real) { _firstTime = true; copy_info(); set_out_channels(Mask_RGB); Iop::_validate(for_real); } void _request(int x, int y, int r, int t, ChannelMask channels, int count) { input0().request(x, y, r, t, channels, count); } void engine(int y, int x, int r, ChannelMask channels, Row& out) { ChannelSet opChannels = Mask_RGB; { Guard g(_engineLock); if (_firstTime) { // Reinitialize value containers for (int i = 0; i < 3; i++) { _avgPix[i] = _pixAggregate[i] = 0.0f; } Format format = input0().format(); const int fx = format.x(); const int fy = format.y(); const int fr = format.r(); const int ft = format.t(); const int height = ft - fy; const int width = fr - fx; const unsigned long int pixCount = width * height; // Allocate cache interest // If I uncomment these lines, I will get errors about // interest(channels=) instead of get(channels=) // Interest interest(input0(), fx, fy, fr, ft, opChannels, true); // interest.unlock(); for (int ry = fy; ry < ft; ry++) { // Set any progress bars progressFraction(ry, ft - fy); // Get the corresponding Mask_RGB row from the input Row row(fx, fr); row.get(input0(), ry, fx, fr, opChannels); if (aborted()) return; // Aggregate pixel values from Mask_RGB into container array int chan = 0; foreach(z, opChannels) { const float *CUR = row[z] + fx; const float *END = row[z] + fr; while (CUR < END) { _pixAggregate[chan] += (float)*CUR; CUR++; } chan++; } } // Calculate the average for each channel for (int c = 0; c < opChannels.size(); c++) { _avgPix[c] = _pixAggregate[c] / pixCount; } _firstTime = false; } } // Lock out of scope // Get the full row from the input Row in(x, r); in.get(input0(), y, x, r, channels); if (aborted()) return; // Fill all pixels in Mask_RGB from _avgPix int outChan = 0; foreach(z, channels) { if (!intersect(z, opChannels)) { // A channel we don't want to modify (may want to // change this to a straight memcpy eventually). out.copy(in, z, x, r); } else { float *CUR = out.writable(z) + x; const float *END = out[z] + r; while (CUR < END) { *CUR++ = _avgPix[outChan]; } outChan++; } } } -Nathan
_______________________________________________ Nuke-dev mailing list Nuke-dev@support.thefoundry.co.uk, http://forums.thefoundry.co.uk/ http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-dev