> You must not make ANY assumptions about what channels are being requested of > you. Your code crashes because you blindly request row[z] from opChannels > which is Mask_RGB, but what happens if a downstream node asks for Alpha (or > Z-Depth, or anything other than RGB)? You will blindly do a row[Chan_Alpha], > and that will return NULL because that channel isn’t in your input row > because you never requested it, and will immediately crash Nuke. You should > ‘erase’ the output of all requested channels for which you do not wish to > provide data.
Usually it's easiest to call get() on the input and pass the channel mask the engine is getting so at least the add'l channels get filled in, then you simply modify the ones you want. Or better yet you remove the channels you're going to modify from the get() channel mask so the channels aren't processed twice for no reason (unless you need the channel data as source.) input(0)->get(y, x, r, channels, row); // fill my writable channels or ChannelSet c1(channels); c1 -= my_writable_channels; input(0)->get(y, x, r, c1, row); // fill my writable channels -jonathan > From: nuke-dev-boun...@support.thefoundry.co.uk > [mailto:nuke-dev-boun...@support.thefoundry.co.uk] On Behalf Of Nathan Rusch > Sent: Monday, October 31, 2011 3:17 PM > To: Nuke-Dev > Subject: [Nuke-dev] Altering only a specific ChannelSet in engine > > 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 > > (CONFIDENTIALITY NOTICE: The information contained in this email may be > confidential and/or privileged. This email is intended to be reviewed by only > the individual or organization named above. If you are not the intended > recipient, or an authorized representative of the intended recipient, you are > hereby notified that any review, dissemination or copying of this email, or > the information contained herein is strictly prohibited. If you have received > this communication in error, please notify the sender by return email and > delete this email from your system. Thank You.) > > _______________________________________________ > 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
_______________________________________________ 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