10 minute rewrite and it’s all working perfectly. Thanks for your info guys... 
huge informational leap.

-Nathan



From: Nathan Rusch 
Sent: Monday, October 31, 2011 4:10 PM
To: Nuke plug-in development discussion 
Subject: Re: [Nuke-dev] Altering only a specific ChannelSet in engine

Thanks for the quick replies guys. So currently the issue is that, even if I’m 
only getting a request for mask.a, if the op hash has been updated, I’m always 
get()-ing Mask_RGB in my single-threaded block no matter what. I’ll do some 
rewriting.

Much appreciated.

-Nathan



From: Jonathan Egstad 
Sent: Monday, October 31, 2011 3:54 PM
To: Nuke plug-in development discussion 
Subject: Re: [Nuke-dev] Altering only a specific ChannelSet in engine

  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 
listnuke-...@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



--------------------------------------------------------------------------------
_______________________________________________
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

Reply via email to