Skip to content

Commit c873d92

Browse files
committed
Merge branch 'RB-10.3' into main
2 parents 7d1c9c4 + af4cc45 commit c873d92

File tree

7 files changed

+111
-10
lines changed

7 files changed

+111
-10
lines changed

Changes

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ Breaking Changes
9595
- IECoreGL : Removed `PerspectiveCamera.h` header. The implementation was already removed in a Cortex 10.1.0.0 (#1241).
9696
- StringAlgo : Removed `join()` (#1221).
9797

98+
10.3.7.0 (relative to 10.3.6.1)
99+
========
100+
101+
Improvements
102+
------------
103+
104+
- IECoreGL :
105+
- Buffer : Added `buffer()` method, which returns the OpenGL buffer handle (#1272).
106+
- Primitive : Added `getVertexBuffer()` and `getVertexCount()` methods (#1272).
107+
108+
Fixes
109+
-----
110+
111+
- IECoreUSD :
112+
- SceneCacheFileFormat : Added support for `IECore::Object` references when determining primvar type (#1280).
113+
98114
10.3.6.1 (relative to 10.3.6.0)
99115
========
100116

contrib/IECoreUSD/src/IECoreUSD/SceneCacheData.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ void SceneCacheData::loadPrimVars( const SceneInterface::Path& currentPath, TfTo
662662
// variables
663663
SceneInterface::Path variablesPath;
664664
variablesPath.push_back( g_ioRoot );
665-
for ( auto& p : currentPath )
665+
for ( const auto& p : currentPath )
666666
{
667667
// avoid injecting the internal root because
668668
// the path would be invalid in the IndexedIO hierarchy
@@ -676,20 +676,21 @@ void SceneCacheData::loadPrimVars( const SceneInterface::Path& currentPath, TfTo
676676

677677
variablesPath.insert( variablesPath.end(), g_staticIoVariablesPath.begin(), g_staticIoVariablesPath.end() );
678678

679-
if ( auto variables = m_sceneio->directory( variablesPath, IndexedIO::MissingBehaviour::NullIfMissing ) )
679+
if ( const auto variables = m_sceneio->directory( variablesPath, IndexedIO::MissingBehaviour::NullIfMissing ) )
680680
{
681681
IndexedIO::EntryIDList variableLists;
682682
variables->entryIds( variableLists );
683-
for( auto& var: variableLists )
683+
684+
for( const auto& var: variableLists )
684685
{
685-
auto it = find( g_defaultPrimVars.cbegin(), g_defaultPrimVars.cend(), var.value() );
686+
const auto it = find( g_defaultPrimVars.cbegin(), g_defaultPrimVars.cend(), var.value() );
686687
if( it != g_defaultPrimVars.cend() )
687688
{
688689
continue;
689690
}
690691

691692
// interpolation
692-
auto variableIO = variables->subdirectory( var, IndexedIO::MissingBehaviour::NullIfMissing );
693+
const auto variableIO = variables->subdirectory( var, IndexedIO::MissingBehaviour::NullIfMissing );
693694
int interpolationValue = 0;
694695
TfToken usdInterpolation;
695696
if ( !variableIO || !variableIO->hasEntry( g_ioInterpolation ) )
@@ -702,17 +703,45 @@ void SceneCacheData::loadPrimVars( const SceneInterface::Path& currentPath, TfTo
702703
usdInterpolation = PrimitiveAlgo::toUSD( static_cast<PrimitiveVariable::Interpolation>( interpolationValue ) );
703704

704705
// data type
705-
auto dataType = variableIO->subdirectory( g_ioData, IndexedIO::MissingBehaviour::NullIfMissing );
706-
std::string dataTypeValue;
707-
if( !dataType || !dataType->hasEntry( g_ioType ) )
706+
if( !variableIO->hasEntry( g_ioData ) )
707+
{
708+
IECore::msg( IECore::Msg::Warning, "SceneCacheData::loadPrimVars", boost::format( "Unable to find data for Primitive Variable \"%s\" at location \"%s\"." ) % var % primPath );
709+
continue;
710+
}
711+
712+
ConstIndexedIOPtr dataIO;
713+
const IndexedIO::Entry dataEntry = variableIO->entry( g_ioData );
714+
if( dataEntry.entryType() == IndexedIO::File)
715+
{
716+
if( dataEntry.dataType() != IndexedIO::InternedStringArray )
717+
{
718+
IECore::msg( IECore::Msg::Warning, "SceneCacheData::loadPrimVars", boost::format( "Unable to find reference to data for Primitive Variable \"%s\" at location \"%s\"." ) % var % primPath );
719+
continue;
720+
}
721+
// IECore::Object has saved a reference to the data, so we need to follow the link to the referenced
722+
// directory in order to find the dataType
723+
IndexedIO::EntryIDList referencedPath( dataEntry.arrayLength() );
724+
InternedString *p = referencedPath.data();
725+
variableIO->read( g_ioData, p, dataEntry.arrayLength() );
726+
dataIO = variableIO->directory( referencedPath, IndexedIO::MissingBehaviour::NullIfMissing );
727+
}
728+
else
729+
{
730+
// Get the data subdirectory
731+
dataIO = variableIO->subdirectory( g_ioData, IndexedIO::MissingBehaviour::NullIfMissing );
732+
}
733+
734+
if( !dataIO || !dataIO->hasEntry( g_ioType ) )
708735
{
709736
IECore::msg( IECore::Msg::Warning, "SceneCacheData::loadPrimVars", boost::format( "Unable to find data type for Primitive Variable \"%s\" at location \"%s\"." ) % var % primPath );
710737
continue;
711738
}
712-
dataType->read( g_ioType, dataTypeValue );
739+
740+
std::string dataTypeValue;
741+
dataIO->read( g_ioType, dataTypeValue );
713742

714743
// interpretation
715-
auto interpretationData = dataType->subdirectory( g_ioData, IndexedIO::MissingBehaviour::NullIfMissing );
744+
const auto interpretationData = dataIO->subdirectory( g_ioData, IndexedIO::MissingBehaviour::NullIfMissing );
716745
IntDataPtr interpretationValue = nullptr;
717746
if ( interpretationData && interpretationData->hasEntry( g_interpretation ) )
718747
{

contrib/IECoreUSD/test/IECoreUSD/SceneCacheFileFormatTest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ def testCustomPrimvars( self ):
527527
mesh["customPoint"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, v )
528528
mesh["customIndexedInt"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Uniform, IECore.IntVectorData( [12] ), IECore.IntVectorData( [ 0 ] * vertexSize ) )
529529

530+
# Test a shallow copy of a primvar which causes IECore.Object to write a reference into the IndexedIO file
531+
mesh["Pref"] = mesh["P"]
532+
530533
box.writeObject( mesh, 1.0 )
531534
del m, box
532535

@@ -557,6 +560,14 @@ def testCustomPrimvars( self ):
557560
customIndexedInt = prim.GetAttribute( "primvars:customIndexedInt" )
558561
self.assertEqual( customIndexedInt.GetMetadata( "interpolation" ), pxr.UsdGeom.Tokens.uniform )
559562

563+
# Pref
564+
Pref = prim.GetAttribute( "primvars:Pref" )
565+
self.assertIsNotNone( Pref )
566+
self.assertFalse( Pref.GetMetadata( "custom" ) )
567+
self.assertEqual( Pref.GetMetadata( "typeName" ), pxr.Sdf.ValueTypeNames.Point3fArray )
568+
self.assertEqual( Pref.Get( 24.0 ), pxr.UsdGeom.Mesh( prim ).GetPointsAttr().Get( 24.0 ) )
569+
self.assertEqual( Pref.GetMetadata( "interpolation" ), pxr.UsdGeom.Tokens.vertex )
570+
560571
# round trip
561572
exportPath = os.path.join( self.temporaryDirectory(), "testUSDExportCustomPrimVar.scc" )
562573
stage.Export( exportPath )
@@ -581,6 +592,9 @@ def testCustomPrimvars( self ):
581592
# indices
582593
self.assertEqual( mesh["customIndexedInt"].indices, IECore.IntVectorData( [0] * vertexSize ) )
583594

595+
# copy
596+
self.assertEqual( mesh["Pref"], mesh["P"] )
597+
584598
def testCornersAndCreases( self ):
585599
fileName = os.path.join( self.temporaryDirectory(), "testUSDCornerAndCreases.scc" )
586600
m = IECoreScene.SceneCache( fileName, IECore.IndexedIO.OpenMode.Write )

include/IECoreGL/Buffer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ class IECOREGL_API Buffer : public IECore::RunTimeTyped
6262
/// Deletes the buffer with glDeleteBuffers().
6363
~Buffer() override;
6464

65+
/// Returns the GL handle for the buffer. Note that this is
66+
/// owned by the Buffer class and will be destroyed in the
67+
/// destructor - you must therefore not call glDeleteBuffers()
68+
/// yourself.
69+
GLuint buffer() const;
70+
6571
/// Returns the size of the buffer in bytes.
6672
size_t size() const;
6773

include/IECoreGL/Primitive.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include "IECoreGL/Export.h"
3939
#include "IECoreGL/GL.h"
40+
#include "IECoreGL/Buffer.h"
4041
#include "IECoreGL/Renderable.h"
4142
#include "IECoreGL/Shader.h"
4243
#include "IECoreGL/TypedStateComponent.h"
@@ -165,6 +166,12 @@ class IECOREGL_API Primitive : public Renderable
165166
IE_CORE_DECLAREPTR( TransparencySort );
166167
//@}
167168

169+
/// Call to retrieve the buffer for a previously registered vertex attribute.
170+
ConstBufferPtr getVertexBuffer( const std::string &name ) const;
171+
172+
/// Call to determine the number of vertices in each registered vertex attribute.
173+
size_t getVertexCount() const;
174+
168175
protected :
169176

170177
/// Called by derived classes to register a uniform attribute. There are no type or length checks on this call.

src/IECoreGL/Buffer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ Buffer::~Buffer()
9494
glDeleteBuffers( 1, &m_buffer );
9595
}
9696

97+
GLuint Buffer::buffer() const
98+
{
99+
return m_buffer;
100+
}
101+
97102
size_t Buffer::size() const
98103
{
99104
ScopedBinding binding( *this, GL_ARRAY_BUFFER );

src/IECoreGL/Primitive.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ const Shader::Setup *flatConstantShaderSetup( State *state, bool forIDRender )
153153
return shaderSetup.get();
154154
}
155155

156+
const std::string g_P( "P" );
157+
156158
} // namespace
157159

158160
//////////////////////////////////////////////////////////////////////////
@@ -380,6 +382,28 @@ void Primitive::addVertexAttribute( const std::string &name, IECore::ConstDataPt
380382
m_vertexAttributes[name] = data->copy();
381383
}
382384

385+
ConstBufferPtr Primitive::getVertexBuffer( const std::string &name ) const
386+
{
387+
const AttributeMap::const_iterator it = m_vertexAttributes.find( name );
388+
return ( it != m_vertexAttributes.end() )
389+
? IECore::runTimeCast< const Buffer >( CachedConverter::defaultCachedConverter()->convert( it->second.get() ) )
390+
: ConstBufferPtr();
391+
}
392+
393+
size_t Primitive::getVertexCount() const
394+
{
395+
// NOTE : It would perhaps be better if the vertex count was stored as a member variable, then we could
396+
// check the size of each registered vertex attribute as it is added. Derived classes would need
397+
// to set this value perhaps as an argument to the constructor. However that would break ABI so for
398+
// now determine the vertex count by inspecting the size of the "P" attribute which ALL primitives
399+
// should have registered.
400+
401+
const AttributeMap::const_iterator it = m_vertexAttributes.find( g_P );
402+
return ( ( it != m_vertexAttributes.end() ) && ( IECore::runTimeCast< const IECore::V3fVectorData >( it->second ) ) )
403+
? static_cast< size_t >( IECore::assertedStaticCast< const IECore::V3fVectorData >( it->second )->readable().size() )
404+
: static_cast< size_t >( 0 );
405+
}
406+
383407
bool Primitive::depthSortRequested( const State * state ) const
384408
{
385409
return state->get<Primitive::TransparencySort>()->value() &&

0 commit comments

Comments
 (0)