Hi Peter,

See attachment for the full source code. I changed based on the
'MyNode.cpp' ( the one that I got problem with SceneView_knob last time ).

To clear any unknown compilation problem, I made the build in command line
with:

C:\build > cl.exe /I"C:\Program Files\Nuke7.0v1\include" /EHsc MyNode.cpp
/link /dll /OUT:MyNode.dll "C:\Program Files\Nuke7.0v1\DDImage.lib"


I also tried to add "/Zi" and linker flag "/DEBUG" to get
the accessible calling stack.

 To replicate the crash:
- compiler MyNode.cpp
- create MyNode, type some letters in the 'file path'
- select some of the items in SceneView_knob, switch viewer to 3D --> crash

OR:
- create MyNode, connect to 'Scene', then connect to 'ScanlineRender', then
connect to 'viewer'
- press the 'calc hash' button in the panel --> crash

OR:
- create MyNode, connect to 'Scene', then connect to 'ScanlineRender', then
connect to 'viewer'
- save the scene
- launch Nuke 7 and load the scene --> crash

Here is the call stack:

> ntdll.dll!0000000077a932d0()
  [Frames below may be incorrect and/or missing, no symbols loaded for
ntdll.dll]
  kernel32.dll!00000000774d300a()
  MyNode.dll!free(void * pBlock)  Line 51 C
  MyNode.dll!std::allocator<unsigned int>::deallocate(unsigned int * _Ptr,
unsigned __int64 __formal)  Line 183 C++
  MyNode.dll!std::vector<unsigned int,std::allocator<unsigned int>
>::_Tidy()  Line 1309 C++
  MyNode.dll!std::vector<unsigned int,std::allocator<unsigned int>
>::~vector<unsigned int,std::allocator<unsigned int> >()  Line 705 + 0xa
bytes C++
  MyNode.dll!MyNode::calcHash()  Line 143 C++
  MyNode.dll!MyNode::knob_changed(DD::Image::Knob * k)  Line 207 C++
  Nuke7.0.exe!00000001405af0e4()
  Nuke7.0.exe!00000001405aea57()
  Nuke7.0.exe!000000014092f2c4()
  Nuke7.0.exe!0000000140930737()
  QtCore4.dll!000000007274af1f()
  QtGui4.dll!0000000071ae5f13()
  QtGui4.dll!00000000718a1c0f()
  QtGui4.dll!00000000718a3303()
  QtGui4.dll!00000000718a35ea()
  QtGui4.dll!00000000715dac05()
  QtGui4.dll!00000000715903b6()
  QtGui4.dll!000000007159210c()
  Nuke7.0.exe!0000000140615c2e()
  QtCore4.dll!0000000072737d92()
  QtGui4.dll!000000007159163e()
  QtGui4.dll!00000000715f2808()
  QtGui4.dll!00000000715f5146()
  user32.dll!00000000775e9bd1()
  user32.dll!00000000775e98da()
  QtCore4.dll!000000007275d05a()
  QtGui4.dll!00000000715f46e5()
  QtCore4.dll!000000007273734a()
  QtCore4.dll!000000007273b450()
  Nuke7.0.exe!0000000140603fe7()
  Nuke7.0.exe!0000000140cd1f29()
  Nuke7.0.exe!00000001410f3d16()
  Nuke7.0.exe!0000000140cee3f6()

I might use SceneView_knob in a wrong way.

Thanks a lot,
Shing

On Mon, Dec 17, 2012 at 10:49 PM, Chishing Yip <[email protected]>wrote:

> Hi Peter,
>
> The suggested wrapper functions can be added to existing SceneView_KnobI
> interface without removing the STL version, my plugin runs fine on Linux
> and OSX with getSelectedItems() and getImportedItems() .
>
> I will dump the backtrace when I back to the office tomorrow ( GMT+8 ) and
> send the sample code to you asap.
>
> Best,
> Shing
>
>
>
> On Mon, Dec 17, 2012 at 10:11 PM, Peter Crossley <
> [email protected]> wrote:
>
>>  Hi Shing,
>>
>> The additions to the interface you've detailed seem like a reasonable
>> request, however we can't break NDK compatibility until the next major
>> release. I would suggest you contact [email protected] directly
>> with a feature request for this.
>>
>> I would also like to get to the bottom of your crashes. There shouldn't
>> be any problems calling these functions unless you're mixing crt versions.
>>
>> Would it be possible for you to send us a code sample that causes the
>> crash?
>>
>> Regards,
>>
>> Peter.
>>
>>
>> On 17/12/2012 13:12, Chishing Yip wrote:
>>
>> Hi Tom,
>>
>>  Thanks a lot for your reply.
>> We always make release build on windows, we have developed windows pluginfor 
>> two years without any
>> STL/compiler version problem in Nuke 6.3, this problem is new to us.
>>
>>  As I can see SceneView_knob is the only one that has this problem so
>> far in our plugins, is adding few wrappers an alternative? e.g. we are
>> using:
>> const std::vector< std::string >& SceneView_KnobI::menus() const;
>> const std::vector< std::string >& SceneView_KnobI::getItemNames() const;
>> void SceneView_KnobI::getImportedItems( std::vector< unsigned int >&
>> items ) const;
>> void SceneView_KnobI::getSelectedItems( std::vector< unsigned int >&
>> items ) const;
>>
>>  but we could also do the same thing without any STL interface if we
>> could have wrappers like these:
>>
>> unsigned int SceneView_KnobI::numOfMenus() const;
>> const char* SceneView_KnobI::getMenuItem( unsigned int menuIndex ) const;
>>
>> unsigned int SceneView_KnobI::numOfItemNames() const;
>> const char* SceneView_KnobI::getItemName( unsigned int itemIndex ) const;
>>
>> unsigned int SceneView_KnobI::numOfItems() const;
>> bool SceneView_KnobI::isImportedItem( unsigned int itemIndex ) const;
>> bool SceneView_KnobI::isSelectedItem( unsigned int itemIndex ) const;
>>
>> in the private implementation in SceneView_KnobI.cpp ( or any private .
>> cpp implementation inside Nuke ):
>>
>>  unsigned int SceneView_KnobI::numOfMenus() const
>> {
>> return menu.size();
>>  }
>> const char* SceneView_KnobI::getMenuItem( unsigned int menuIndex ) const
>> {
>>  return menu[ menuIndex ].c_str();
>>  }
>>
>> unsigned int SceneView_KnobI::numOfItemNames() const
>> {
>> return getItemNames.size();
>>  }
>> const char* SceneView_KnobI::getItemName( unsigned int itemIndex ) const
>> {
>> return getItemNames[ menuIndex ].c_str();
>>  }
>>
>> unsigned int SceneView_KnobI::numOfItems() const
>> {
>> return /* the total items scene view knob holds*/ ;
>>  }
>> bool SceneView_KnobI::isImportedItem( unsigned int itemIndex ) const
>> {
>> return /*if getImportedItems() contains the input itemIndex or not*/;
>>  }
>> bool SceneView_KnobI::isSelectedItem( unsigned int itemIndex ) const
>> {
>> return /*if getSelectedItems() contains the input itemIndex or not*/;
>>  }
>>
>> In this way, we don't need to deal with any STL interface but we could
>> construct the item list inside our plugin by ourselves, so there won't
>> be any STL compatibility issue between Nuke and any 3rd party plugins,
>> and since these are all wrappers I don't think that's difficult to
>> implement.
>>
>> We understand the API in Nuke 7.0 has been frozen, if above suggestion is
>> an acceptable alternative, we could wait until Nuke 7.1 release, what do
>> you think?
>>
>> Thanks again for your reply.
>> Best,
>> Shing
>> --
>> Zhicheng YE - Shing
>> the /*jupiter jazz*/ group - visual research
>> mercenaries of jupiter jazz limited - hong kong
>> www.jupiter-jazz.com
>>
>>
>> On Mon, Dec 17, 2012 at 6:58 AM, Tom Ward <[email protected]> wrote:
>>
>>> Hi Paolo,
>>>
>>>  The version of VS2010 that Nuke is compiled against is indeed
>>> 16.00.30319.01 and as far as I know there have been no breaking CRT
>>> changes in 2010 (unlike 2005) so don't think that would be the problem
>>>
>>>  Are you definitely always linking against the release version of the
>>> CRT? As we don't ship the debug versions of DDImage (or Nuke) you need to
>>> always build release versions of your plugins for Windows, not doing so
>>> usually results in STL problems like you're apparently seeing.
>>>
>>>  Hope that helps
>>>
>>>  Tom
>>>
>>>  On Sun, Dec 16, 2012 at 12:33 PM, Paolo Berto 
>>> <[email protected]>wrote:
>>>
>>>>  Hi Fellaz,
>>>>
>>>>  we mailed on nuke-dev but got no answers.
>>>>
>>>>  In a nutshell, we have a plugin which uses SceneView_knob in Nuke
>>>> 7.0, it always crashes after accessing SceneView_KnobI::getSelectedItems()
>>>> or SceneView_KnobI::getImportedItems(), to us this looks like a STL version
>>>> related problem.
>>>>
>>>>  Our compiler version:
>>>>
>>>>      > cl.exe
>>>>         Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for
>>>> x64
>>>>     > link.exe
>>>>         Microsoft (R) Incremental Linker Version 10.00.30319.01 for x64
>>>>
>>>>  We installed MSVC 2010, without SDK 7.1, without 2010 SP1.
>>>>
>>>>  How can we setup the correct development environment for Nuke 7.0 ?
>>>>  Which compiler ( and /exact/ version ) Nuke 7.0 was compiled against?
>>>>
>>>>  Best,
>>>>
>>>>
>>>>  --
>>>> pbd
>>>>
>>>> paolo berto durante
>>>> space cowboy // jupiter jazz ltd // hong kong
>>>> https://atomkraft.hk
>>>>   --
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>  --
>>> Tom Ward, Software Engineer
>>> The Foundry, 6th Floor, The Communications Building,
>>> 48 Leicester Square, London, UK, WC2H 7LT
>>> Tel: +44 (0)20 7434 0449 <%2B44%20%280%2920%207434%200449>   Web:
>>> www.thefoundry.co.uk
>>>
>>> The Foundry Visionmongers Ltd.
>>> Registered in England and Wales No: 4642027
>>>
>>>
>>
>>  --
>>
>>
>>
>>
>>
>
>
// Sphere.C
// Copyright (c) 2009 The Foundry Visionmongers Ltd.  All Rights Reserved.

static const char* const CLASS = "MyNode";
static const char* const HELP = "Generates a 3D sphere";

#include <DDImage/SourceGeo.h>
#include <DDImage/Scene.h>
#include <DDImage/Triangle.h>
#include <DDImage/Knobs.h>
#include <DDImage/Knob.h>
#include <DDImage/SceneView_KnobI.h>
#include <DDImage/Channel3D.h>
#include <assert.h>

using namespace DD::Image;

#ifndef mFnStringize
#define mFnStringize2(A) # A
#define mFnStringize(A) mFnStringize2(A)
#endif

#define MAX_SPHERE_TESSELATION 512

class MyNode : public SourceGeo
{
private:
  const char* filename;
  SceneView_KnobI* mySceneViewKnob;
  int initvalue;
  double radius;
  int columns, rows;
  double my_u_extent, my_v_extent;
  bool close_top, close_bottom;
  // local matrix that Axis_Knob fills in
  Matrix4 _local;
  bool fix;
  Knob* _pAxisKnob;
  Hash sceneViewHash_;

protected:
  void _validate(bool for_real)
  {
    // Clamp the mesh size to reasonable numbers:
    columns = MIN(MAX(columns, 3), MAX_SPHERE_TESSELATION);
    rows    = MIN(MAX(rows,    3), MAX_SPHERE_TESSELATION);
    my_u_extent = clamp( my_u_extent, 0.001, 360.0 );
    my_v_extent = clamp( my_v_extent, 0.001, 180.0 );
    SourceGeo::_validate(for_real);
  }

public:
  static const Description description;
  const char* Class() const { return CLASS; }
  const char* node_help() const { return HELP; }

  MyNode(Node* node) : SourceGeo(node)
  {
    filename = "";
    mySceneViewKnob = NULL;
    int initvalue = 0;
    radius = 1.0;
    rows = columns = 30;
    close_top = close_bottom = true;
    my_u_extent = 360.0;
    my_v_extent = 180.0;
    _local.makeIdentity();
    fix = false;
    _pAxisKnob = NULL;
	sceneViewHash_.reset( 0 ); 
  }

  void knobs(Knob_Callback f)
  {
    File_knob( f, &filename, "file" );
    Divider( f);

    static const char* const initnames[] = { 0x0 };
    Knob* k = SceneView_knob( f, &initvalue, initnames, "my_scene_view", "" );
    SetFlags( f, Knob::SAVE_MENU | Knob::ALWAYS_SAVE | Knob::KNOB_CHANGED_RECURSIVE);

    mySceneViewKnob = k->sceneViewKnob();
	
	Button( f, "calc_hash", "calc hash" );

    Divider( f);

    BeginClosedGroup( f, "group" );

    SourceGeo::knobs(f);
    Int_knob(f, &rows, "rows", "rows/columns");
    Tooltip(f, "The maximum rows is "mFnStringize(MAX_SPHERE_TESSELATION));
    Int_knob(f, &columns, "columns", "");
    Tooltip(f, "The maximum columns is "mFnStringize(MAX_SPHERE_TESSELATION));
    Double_knob(f, &radius, "radius");
    Double_knob(f, &my_u_extent, "u_extent", "u extent" );
    Double_knob(f, &my_v_extent, "v_extent", "v extent" );
    Newline(f);
    Bool_knob(f, &close_top, "close_top", "close top");
    Bool_knob(f, &close_bottom, "close_bottom", "close bottom");
    Obsolete_knob(f, "create_uvs", 0);
    Obsolete_knob(f, "create_normals", 0);

    Divider( f);
    // transform knobs
    _pAxisKnob = Axis_knob(f, &_local, "transform");

    if (_pAxisKnob != NULL) {
      if (GeoOp::selectable() == true)
        _pAxisKnob->enable();
      else
        _pAxisKnob->disable();
    }

    // This knob is set by knob_default so that all new instances execute
    // the "fix" code, which rotates the sphere 180 degrees so that the
    // seam is on the far side from the default camera position.
    Bool_knob(f, &fix, "fix", INVISIBLE);

    EndGroup( f );
  }
  
    Hash calcHash() const
    {
        Hash myhash;

        if ( mySceneViewKnob ) {
            std::vector<unsigned int> selectedItems;
            mySceneViewKnob->getSelectedItems( selectedItems );

            std::size_t numItems = selectedItems.size();

            for ( std::size_t i = 0; i < numItems; ++i ) {
                myhash.append( selectedItems[ i ] );
            }
        }
        return myhash;
    }

  void resetMySceneViewKnob()
  {
    std::vector< std::string > items;
    if ( !filename || !strlen( filename ) ) {
        mySceneViewKnob->menu( items );
        return;
    }

    // FIXME: hard code all items, treat as loading from file
    items.push_back( "/root/group1/item1" );
    items.push_back( "/root/group1/item2" );
    items.push_back( "/root/group1/item3" );
    items.push_back( "/root/group2/item4" );
    items.push_back( "/root/group2/item5" );
    items.push_back( "/root/group2/item6" );
    items.push_back( "/root/group3/item7" );
    items.push_back( "/root/group3/item8" );
    items.push_back( "/root/group3/item9" );

    // set menu items
    mySceneViewKnob->menu( items );

    std::vector< unsigned int > selectedItems;
    mySceneViewKnob->getSelectedItems( selectedItems );
    std::cerr << "when script is loaded, size of previous selectedItems is " << selectedItems.size() << std::endl;

    std::vector< unsigned int > importedItems;
    for ( int i = 0; i < 9; ++i ) {
        importedItems.push_back( i );
    }

    // set imported items
    mySceneViewKnob->setImportedItems( importedItems );
    // Restore old selected items.
    mySceneViewKnob->setSelectedItems( selectedItems );
  }

  /*! The will handle the knob changes.
   */
  int knob_changed(Knob* k)
  {
    if (k != NULL) {
      if (strcmp(k->name(), "selectable") == 0) {
        if (GeoOp::selectable() == true)
          _pAxisKnob->enable();
        else
          _pAxisKnob->disable();
        return 1;
      }
	  
	  if ( k->is( "calc_hash" ) ) {
		Hash h = calcHash();
		if ( sceneViewHash_ != h ) {
			sceneViewHash_ = h;
		}
	  }

      if ( k->is( "file" ) ) {
        resetMySceneViewKnob();

        return 1;
      }

      if ( k == &Knob::showPanel ) {
        resetMySceneViewKnob();
      }
    }

    return SourceGeo::knob_changed(k);
  }

  // Hash up knobs that affect the Sphere:
  void get_geometry_hash()
  {
    SourceGeo::get_geometry_hash();   // Get all hashes up-to-date

    // Knobs that change the geometry structure:
    geo_hash[Group_Primitives].append(columns);
    geo_hash[Group_Primitives].append(rows);
    geo_hash[Group_Primitives].append(close_top);
    geo_hash[Group_Primitives].append(close_bottom);

    // Knobs that change the point locations:
    geo_hash[Group_Points].append(radius);
    geo_hash[Group_Points].append(columns);
    geo_hash[Group_Points].append(rows);
    geo_hash[Group_Points].append(close_top);
    geo_hash[Group_Points].append(close_bottom);

    // Knobs that change the vertex attributes:
    geo_hash[Group_Attributes].append(my_u_extent);
    geo_hash[Group_Attributes].append(my_v_extent);

    geo_hash[Group_Matrix].append(_local.a00);
    geo_hash[Group_Matrix].append(_local.a01);
    geo_hash[Group_Matrix].append(_local.a02);
    geo_hash[Group_Matrix].append(_local.a03);

    geo_hash[Group_Matrix].append(_local.a10);
    geo_hash[Group_Matrix].append(_local.a11);
    geo_hash[Group_Matrix].append(_local.a12);
    geo_hash[Group_Matrix].append(_local.a13);

    geo_hash[Group_Matrix].append(_local.a20);
    geo_hash[Group_Matrix].append(_local.a21);
    geo_hash[Group_Matrix].append(_local.a22);
    geo_hash[Group_Matrix].append(_local.a23);

    geo_hash[Group_Matrix].append(_local.a30);
    geo_hash[Group_Matrix].append(_local.a31);
    geo_hash[Group_Matrix].append(_local.a32);
    geo_hash[Group_Matrix].append(_local.a33);

    // append to hash
    geo_hash[Group_Primitives].append(filename);

    SceneView_KnobI* p( knob( "my_scene_view" )->sceneViewKnob() );
    const std::vector<std::string>& items( p->getItemNames() );
    for ( unsigned int i = 0; i < items.size(); ++i ) {
        geo_hash[Group_Primitives].append( items[i] );
    }

    std::vector<unsigned int> selectedItems;
    p->getSelectedItems( selectedItems );
    for ( std::size_t i = 0; i < selectedItems.size(); ++i ) {
        geo_hash[Group_Primitives].append( selectedItems[ i ] );
    }

	geo_hash[Group_Primitives].append( calcHash() );

  }

  // Apply the concat matrix to all the GeoInfos.
  void geometry_engine(Scene& scene, GeometryList& out)
  {
    SourceGeo::geometry_engine(scene, out);

    // multiply the node matrix
    for (unsigned i = 0; i < out.size(); i++)
      out[i].matrix = _local * out[i].matrix;
  }

  void create_geometry(Scene& scene, GeometryList& out)
  {
    int obj = 0;

    unsigned num_points = (close_bottom ? 1 : 0) + (rows - 1) * columns + (close_top ? 1 : 0);

    //=============================================================
    // Build the primitives:
    if (rebuild(Mask_Primitives)) {
      out.delete_objects();
      out.add_object(obj);

      // Create poly primitives:
      // Bottom endcap:
      if (close_bottom) {
        int j1 = 1;
        for (int i = 0; i < columns; i++) {
          int i0 = i % columns;
          int i1 = (i + 1) % columns;
          out.add_primitive(obj, new Triangle(0, i1 + j1, i0 + j1));
        }
      }

      // Create the center poly mesh:
      for (int j = 0; j < rows - 2; j++) {
        int j0 = j * columns + (close_bottom ? 1 : 0);
        int j1 = (j + 1) * columns + (close_bottom ? 1 : 0);
        for (int i = 0; i < columns; i++) {
          int i0 = i % columns;
          int i1 = (i + 1) % columns;
          // Create 2 triangles:
          out.add_primitive(obj, new Triangle(i0 + j0, i1 + j0, i0 + j1));
          out.add_primitive(obj, new Triangle(i0 + j1, i1 + j0, i1 + j1));
        }
      }

      // Top endcap:
      if (close_top) {
        int top_point = num_points - 1;
        int j0 = (close_bottom ? 1 : 0) + (rows - 2) * columns;
        for (int i = 0; i < columns; i++) {
          int i0 = i % columns;
          int i1 = (i + 1) % columns;
          out.add_primitive(obj, new Triangle(i0 + j0, i1 + j0, top_point));
        }
      }

      // Force points and attributes to update:
      set_rebuild(Mask_Points | Mask_Attributes);
    }

    //=============================================================
    // Create points and assign their coordinates:
    if (rebuild(Mask_Points)) {
      // Generate points:
      PointList* points = out.writable_points(obj);
      points->resize(num_points);

      // Assign the point locations:
      int p = 0;
      // Bottom center:
      if (close_bottom)
        (*points)[p++].set(0.0f, -radius, 0.0f);
      // Middle mesh:
      float drho = M_PI / rows;
      float dtheta = (2.0 * M_PI) / columns;
      float fix = this->fix ? -1 : 1;
      for (int j = 1; j < rows; j++) {
        float rho = j * drho;
        for (int i = 0; i < columns; i++) {
          float theta = i * dtheta;
          float x = fix * sinf(theta) * sinf(rho);
          float y = -cosf(rho);
          float z = fix * cosf(theta) * sinf(rho);
          (*points)[p].set(x * radius, y * radius, z * radius);
          ++p;
        }
      }
      // Top center:
      if (close_top)
        (*points)[p].set(0.0f, radius, 0.0f);
    }

    //=============================================================
    // Assign the normals and uvs:
    if (rebuild(Mask_Attributes)) {
      GeoInfo& info = out[obj];
      //---------------------------------------------
      // NORMALS:
      const Vector3* PNTS = info.point_array();
      Attribute* N = out.writable_attribute(obj, Group_Points, "N", NORMAL_ATTRIB);
      assert(N);
      for (unsigned p = 0; p < num_points; p++)
        N->normal(p) = PNTS[p] / radius;

      //---------------------------------------------
      // UVs:
      const Primitive** PRIMS = info.primitive_array();

      Attribute* uv = out.writable_attribute(obj, Group_Vertices, "uv", VECTOR4_ATTRIB);
      assert(uv);
      float ds = (360.0f / float(my_u_extent)) / float(columns); // U change per column
      float ss = 0.5f - (360.0f / float(my_u_extent)) / 2.0f;     // Starting U
      float dt = (180.0f / float(my_v_extent)) / float(rows);     // V change per row
      float st = 0.5 - (180.0 / my_v_extent) / 2.0;              // Starting V
      float s, t;                                             // Current UV
      t = st;
      // Bottom center:
      if (close_bottom) {
        s = ss;
        for (int i = 0; i < columns; i++) {
          unsigned v = (*PRIMS++)->vertex_offset();
          uv->vector4(v++).set(   s, 0.0f, 0.0f, 1.0f);
          uv->vector4(v++).set(s + ds, t + dt, 0.0f, 1.0f);
          uv->vector4(v++).set(   s, t + dt, 0.0f, 1.0f);
          s += ds;
        }
        t += dt;
      }

      // Create the poly mesh in center:
      for (int j = 0; j < rows - 2; j++) {
        s = ss;
        for (int i = 0; i < columns; i++) {
          unsigned v = (*PRIMS++)->vertex_offset();
          uv->vector4(v++).set(   s,    t, 0.0f, 1.0f);
          uv->vector4(v++).set(s + ds,    t, 0.0f, 1.0f);
          uv->vector4(v++).set(   s, t + dt, 0.0f, 1.0f);
          v = (*PRIMS++)->vertex_offset();
          uv->vector4(v++).set(   s, t + dt, 0.0f, 1.0f);
          uv->vector4(v++).set(s + ds,    t, 0.0f, 1.0f);
          uv->vector4(v++).set(s + ds, t + dt, 0.0f, 1.0f);
          s += ds;
        }
        t += dt;
      }

      // Top endcap:
      if (close_top) {
        s = ss;
        for (int i = 0; i < columns; i++) {
          unsigned v = (*PRIMS++)->vertex_offset();
          uv->vector4(v++).set(   s,    t, 0.0f, 1.0f);
          uv->vector4(v++).set(s + ds,    t, 0.0f, 1.0f);
          uv->vector4(v++).set(   s, 1.0f, 0.0f, 1.0f);
          s += ds;
        }
      }
    }
  }

  // virtual
  void build_handles(ViewerContext* ctx)
  {
    // call build_matrix_handle to multiply the context model matrix with the local matrix so the
    // nodes above it will display correctly
    build_matrix_handles(ctx, _local);
  }
};

static Op* build(Node* node) { return new MyNode(node); }
const Op::Description MyNode::description(CLASS, build);

// end of Sphere.C
_______________________________________________
Nuke-dev mailing list
[email protected], http://forums.thefoundry.co.uk/
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-dev

Reply via email to