Skip to content

Commit e6e4626

Browse files
Merge pull request #1468 from johnhaddon/usdArnoldProcedural
USD : Add loading of Arnold procedural prims
2 parents 827a09a + f3e79fa commit e6e4626

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

Changes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
10.5.x.x (relative to 10.5.14.1)
22
========
33

4+
Improvements
5+
------------
46

7+
- USDScene : Added loading of ArnoldAlembic, ArnoldUsd and ArnoldProceduralCustom prims as Cortex ExternalProcedural objects.
58

69
10.5.14.1 (relative to 10.5.14.0)
710
=========
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//////////////////////////////////////////////////////////////////////////
2+
//
3+
// Copyright (c) 2025, Cinesite VFX Ltd. All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are
7+
// met:
8+
//
9+
// * Redistributions of source code must retain the above copyright
10+
// notice, this list of conditions and the following disclaimer.
11+
//
12+
// * Redistributions in binary form must reproduce the above copyright
13+
// notice, this list of conditions and the following disclaimer in the
14+
// documentation and/or other materials provided with the distribution.
15+
//
16+
// * Neither the name of Image Engine Design nor the names of any
17+
// other contributors to this software may be used to endorse or
18+
// promote products derived from this software without specific prior
19+
// written permission.
20+
//
21+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22+
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23+
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24+
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25+
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26+
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27+
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28+
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29+
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30+
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
//
33+
//////////////////////////////////////////////////////////////////////////
34+
35+
#include "IECoreUSD/DataAlgo.h"
36+
#include "IECoreUSD/ObjectAlgo.h"
37+
38+
#include "IECoreScene/ExternalProcedural.h"
39+
40+
IECORE_PUSH_DEFAULT_VISIBILITY
41+
#include "pxr/usd/usdGeom/gprim.h"
42+
IECORE_POP_DEFAULT_VISIBILITY
43+
44+
using namespace IECore;
45+
using namespace IECoreScene;
46+
using namespace IECoreUSD;
47+
48+
//////////////////////////////////////////////////////////////////////////
49+
// Reading
50+
//////////////////////////////////////////////////////////////////////////
51+
52+
namespace
53+
{
54+
55+
const pxr::TfToken g_arnold( "arnold" );
56+
const pxr::TfToken g_arnoldAlembic( "ArnoldAlembic" );
57+
const pxr::TfToken g_arnoldNodeEntry( "arnold:node_entry" );
58+
const pxr::TfToken g_arnoldProceduralCustom( "ArnoldProceduralCustom" );
59+
const pxr::TfToken g_arnoldUsd( "ArnoldUsd" );
60+
61+
// Arnold's procedural schemas are a mishmash of parameters specific to the procedural
62+
// and generic Arnold-specific node parameters that have no place in USD because
63+
// they have USD equivalents already. There is no way of querying which is which, so
64+
// we manually list the ones we need to ignore.
65+
const std::unordered_set<std::string> g_parameterSkipList = {
66+
"visibility", "sidedness", "receive_shadows", "self_shadows", "invert_normals",
67+
"ray_bias", "matrix", "transform_type", "shader", "opaque", "matte", "use_light_group",
68+
"light_group", "use_shadow_group", "shadow_group", "trace_sets", "motion_start", "motion_end",
69+
"id", "override_nodes", "operator", "name", "node_entry"
70+
};
71+
72+
IECore::ObjectPtr readArnoldProcedural( pxr::UsdGeomGprim &gprim, pxr::UsdTimeCode time, const Canceller *canceller )
73+
{
74+
ExternalProceduralPtr result = new ExternalProcedural();
75+
76+
// Get procedural type.
77+
78+
if( gprim.GetPrim().IsA( g_arnoldAlembic ) )
79+
{
80+
// For historical reasonss, the "filename" is actually the Arnold node
81+
// type.
82+
result->setFileName( "alembic" );
83+
}
84+
else if( gprim.GetPrim().IsA( g_arnoldProceduralCustom ) )
85+
{
86+
std::string nodeEntry;
87+
gprim.GetPrim().GetAttribute( g_arnoldNodeEntry ).Get( &nodeEntry, time );
88+
result->setFileName( nodeEntry );
89+
}
90+
else if( gprim.GetPrim().IsA( g_arnoldUsd ) )
91+
{
92+
result->setFileName( "usd" );
93+
}
94+
95+
// Get bound.
96+
97+
pxr::VtVec3fArray extent;
98+
gprim.ComputeExtent( time, &extent );
99+
if( extent.size() == 2 )
100+
{
101+
result->setBound(
102+
Imath::Box3f( DataAlgo::fromUSD( extent[0] ), DataAlgo::fromUSD( extent[1] ) )
103+
);
104+
}
105+
106+
// Get parameters.
107+
108+
for( const auto &attribute : gprim.GetPrim().GetAuthoredAttributes() )
109+
{
110+
if( attribute.GetNamespace() != g_arnold )
111+
{
112+
continue;
113+
}
114+
115+
const std::string parameterName = attribute.GetBaseName().GetString();
116+
if( g_parameterSkipList.count( parameterName ) )
117+
{
118+
continue;
119+
}
120+
121+
if( auto data = DataAlgo::fromUSD( attribute, time ) )
122+
{
123+
result->parameters()->writable()[parameterName] = data;
124+
}
125+
}
126+
127+
return result;
128+
}
129+
130+
bool arnoldProceduralMightBeTimeVarying( pxr::UsdGeomGprim &gprim )
131+
{
132+
if( gprim.GetExtentAttr().ValueMightBeTimeVarying() )
133+
{
134+
return true;
135+
}
136+
137+
for( const auto &attribute : gprim.GetPrim().GetAuthoredAttributes() )
138+
{
139+
if( attribute.GetNamespace() != g_arnold )
140+
{
141+
continue;
142+
}
143+
144+
const std::string parameterName = attribute.GetBaseName().GetString();
145+
if( g_parameterSkipList.count( parameterName ) )
146+
{
147+
continue;
148+
}
149+
150+
if( attribute.ValueMightBeTimeVarying() )
151+
{
152+
return true;
153+
}
154+
}
155+
156+
return false;
157+
}
158+
159+
ObjectAlgo::ReaderDescription<pxr::UsdGeomGprim> g_arnoldAlembicReaderDescription( g_arnoldAlembic, readArnoldProcedural, arnoldProceduralMightBeTimeVarying );
160+
ObjectAlgo::ReaderDescription<pxr::UsdGeomGprim> g_arnoldProceduralCustomReaderDescription( g_arnoldProceduralCustom, readArnoldProcedural, arnoldProceduralMightBeTimeVarying );
161+
ObjectAlgo::ReaderDescription<pxr::UsdGeomGprim> g_arnoldUsdReaderDescription( g_arnoldUsd, readArnoldProcedural, arnoldProceduralMightBeTimeVarying );
162+
163+
} // namespace

0 commit comments

Comments
 (0)