Skip to content

Commit 90c07ae

Browse files
authored
Merge from internal changes (#8)
* Katana: USD PointInstancer support. It is creating a walter procedural location with its prim path starting at the point instancer. Arnold Procedural: Force scan of "/materials" location before anything else in order to support location starting at a PointInstancer prim (for Katana support). Add support for USD constant attibuts in Arnold (fixing error on usd kitchen set). MtoA extension: jsoncpp library not needed anymore.
1 parent 9baff9a commit 90c07ae

53 files changed

Lines changed: 2209 additions & 621 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,28 @@
1-
Open Walter
2-
===========================
1+
![Open Walter](https://www.rodeofx.com/uploads/images/tech/Walter_logo_mini-01.png)
32

4-
Walter is an open source suite of plugins using USD for various DCCs and renderer.
3+
Walter is suite of plugins using USD for various DCCs and renderer.
4+
5+
It's main goal is to stay as much as possible in the [*USD Stage*](http://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-Stage)
6+
loaded through a DCC in order to increase the interactivity and limit the import/export time.
7+
8+
The DCC communicate with the *USD Stage* to access or modify specific [*USD prim*](http://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-Prim)
9+
or properties. Modifications are stored in specific [*session layers*](http://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-SessionLayer)
10+
like for example transform, variant or visibility layers.
11+
12+
The [*Hydra Renderer*](http://graphics.pixar.com/usd/docs/USD-Glossary.html#USDGlossary-HydraRenderer) is used to display the stage in DCC like Houdini or Maya.
13+
14+
Walter provide a portable lookdev workflow. From Maya, artists can assign Arnold shaders directly on the *USD prims*
15+
of the loaded stage. Those *lookdev edits* can then be exported as Alembic layers to be loaded
16+
in Houdini or Katana.
17+
18+
Walter let you interact with prims transforms directly from Maya. It is *connecting* Maya locator(s) to the expose prim(s), in order
19+
to push any static or animated transforms to the *USD stage*. This is the way to exchange layout and rigid animations between DCCs using Walter.
20+
21+
Walter include a modified version of the Embree raytracer for Hydra. It is able to blend any rendered prims with native Maya or Houdini objects displayed in the viewport.
22+
This raytracer is dedicated to fast display. On scenes with millions of polygons, it will be much faster that the default Hydra renderer plugin (called *Stream*).
23+
You can mix Walter nodes using *Embree* and *Stream* in the same scene. For example, the main character could be displayed using *Stream* and the environment using *Embree*.
24+
25+
Finally Walter extend USD itself by providing additional schemas (like WalterVolume or Expression), file format plugin (Arnold Scene Sources) and resolver (Alembic 1.7 CoreLayer allowing to load more than one *main file* in the stage).
526

627

728
Supported Platforms
@@ -31,6 +52,15 @@ Finally, the walterViewer application is a standalone viewer that can load Walte
3152
It is mostly used for development purpose, as it let you load layers without launching a DCC.
3253

3354

55+
Trying Walter
56+
------------
57+
58+
Compiled versions for Centos7 can be downloaded from (https://github.com/rodeofx/OpenWalter/releases).
59+
You will need to add the plugins to your application environment.
60+
Take a look at the Houdini, Katana, Kick and Maya wrappers in (https://github.com/rodeofx/OpenWalter/tree/dev/walter/utils)
61+
to see how to get a proper configuration to load Walter plugins.
62+
63+
3464
Building Walter
3565
------------
3666

@@ -65,13 +95,11 @@ For example to build only the Houdini plugin:
6595

6696
##### Arnold Procedural
6797

68-
*walter* node:
69-
7098
Render a list of USD or Alembic files.
71-
Walter **materials** and **assignations** can be loaded directly, including assignations using Walter Expression.
99+
**Materials** and **assignations** can be loaded directly, including assignations using **expressions**.
72100
Session layers like transforms, variants, purposes, etc... can be passed as parameters too.
73101

74-
You must set the Arnold install path in your environment.
102+
You must set the Arnold root path in your environment.
75103

76104
| Variable Name | Description | Version |
77105
| ----------------- | ----------------------------------- | --------- |
@@ -80,16 +108,15 @@ You must set the Arnold install path in your environment.
80108

81109
##### Houdini Plugin
82110

83-
*Walter SOP* node:
84-
85-
It is using an **Hydra** display to visualise a stack of USD/Alembic layers in the viewport as **Packed Walter** primitives.
111+
* *Walter SOP* node:
112+
It is using an **Hydra** display to visualize a stack of USD/Alembic layers in the viewport as **Packed Walter** primitives.
86113
You can unpack them using standard Houdini Unpack node.
87114

88-
*Walter Procedural OBJ* node:
115+
* *Walter Procedural OBJ* node:
89116
Create a Walter procedural node in Arnold (via HtoA) to render USD/Alembic layers.
90-
It is supporting layers comming from Walter for Maya (like materials, assignations, overrides or transforms).
117+
It is supporting layers coming from Walter for Maya (like materials, assignations, overrides or transforms).
91118

92-
You must set the Houdini and HtoA install paths in your environment.
119+
You must set the Houdini and HtoA root paths in your environment.
93120

94121
| Variable Name | Description | Version |
95122
| ----------------- | ----------------------------------- | --------- |
@@ -99,12 +126,11 @@ You must set the Houdini and HtoA install paths in your environment.
99126

100127
##### Katana Plugin
101128

102-
*Walter_In* node:
129+
* *Walter_In* node:
130+
Create a Katana scene graph from a stack of USD/Alembic/Arnold Scene Sources layers.
131+
It is supporting materials, assignations, overrides and transforms layers coming from Walter for Maya.
103132

104-
Create a Katana scene graph from a stack of USD/Alembic layers.
105-
It is supporting materials, assignations, overrides and transforms layers comming from Walter for Maya.
106-
107-
You must set the Maya and MtoA install paths in your environment.
133+
You must set the Maya and MtoA root paths in your environment.
108134

109135
| Variable Name | Description | Version |
110136
| ----------------- | ----------------------------------- | --------- |
@@ -113,13 +139,27 @@ You must set the Maya and MtoA install paths in your environment.
113139

114140
##### Maya Plugin
115141

116-
*Walter Standin* node:
142+
* *Walter Standin* node:
143+
144+
From the WalterStandin Attribute Editor you can:
145+
* open the Walter Tree Widget
146+
* select any variants available in the stage.
147+
* select the purpose to use in the viewport (proxy or render)
148+
* switch between bounding box and full representatin (disabled in the open source version for the moment)
149+
* choose the Hydra Renderer plugin
150+
151+
You can select *USD prims* directly from the viewport like a standard Maya object or from the Walter Tree Widget (aka the *Walter outliner*).
152+
You can drag and drop materials from the Hypershader directly on any prims in the Walter Tree Widget and override Arnold attributes.
153+
Shader drag and drop can be done on Walter Expression items in the Tree Widget (using regular expression to assign shaders to prims).
154+
155+
By righ clicking on a prim in the Walter Tree Widget you can:
156+
* show or hide prims
157+
* expose prims transforms as Maya locators
158+
* override prim purpose.
159+
160+
161+
Finally edits can be saved on disk as specific layers.
117162

118-
It is using an **Hydra** display to visualise a stack of USD/Alembic layers in the viewport as one Maya shape node.
119-
You can select USD prims from the viewport or from the Walter tree widget.
120-
You can modify the loaded USD stage, like adding materials, assignations or attributes. You can animate USD prims
121-
by exposing their transforms to Maya as locator objects. You can select any variants available in the composed stage.
122-
Finally all those edits can be saved on disk in specific layers.
123163

124164
*Walter Translator* for MtoA:
125165

@@ -167,3 +207,12 @@ If you run ```make clean && make``` it will re-build only Walter (and so it will
167207
##### Build Options
168208

169209
Run ```make help``` for more info on the various targets available.
210+
211+
212+
Contributing
213+
------------
214+
215+
Since the open source version of Walter is in its early days, we did not yet created any forum or documentation pages.
216+
217+
[![Join the chat at https://gitter.im/OpenWalter/Lobby](https://badges.gitter.im/OpenWalter/Lobby.svg)](https://gitter.im/OpenWalter/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
218+

walter/arnold/procedural/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ if(BUILD_TESTS)
113113
arnold_test(09-b365c58f35b1-broken-regex.ass)
114114
arnold_test(10-6722c1d-aiComposite.ass)
115115
arnold_test(11-matrix-param_support.ass)
116+
arnold_test(12-point-instancer.ass)
116117
endif()
117118
118119
install(TARGETS ${PROC} DESTINATION ${CMAKE_INSTALL_PREFIX}/arnold)

walter/arnold/procedural/delegate.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ RendererDelegate::RendererDelegate(
2323
void RendererDelegate::populate(const UsdPrim& root)
2424
{
2525
const SdfPath rootPath = root.GetPath();
26-
27-
2826
bool childrenKnown = mIndex.isChildrenKnown(rootPath);
2927

3028
// This accessor will freeze if there is another accessor in different
@@ -49,15 +47,25 @@ void RendererDelegate::populate(const UsdPrim& root)
4947

5048
const SdfPath primPath = prim.GetPath();
5149

50+
// This will check if, in the hierarchy of the root path, a parent prim
51+
// of primPath has already been added to the index.
52+
// If it's the case, it means that a walter procedural will be created
53+
// for it (the parent) and so children will be populate at this time.
54+
if (mIndex.isParentKnown(rootPath, primPath))
55+
{
56+
continue;
57+
}
58+
5259
// In some cases like a bbox generated from a "point instance" a path could
53-
// already by added to the index, but not from the same parent. In this case
60+
// already be added to the index, but not from the same parent. In this case
5461
// we can't skip to early.
5562
bool skipLater = false;
56-
// Skip it it's already cached. In USD it's possible to have several
63+
64+
// Skip if it's already cached. In USD it's possible to have several
5765
// parents. We need to be sure that we output the object only once.
5866
if (rootPath != primPath && mIndex.isProcessed(primPath))
5967
{
60-
if(childrenKnown)
68+
if (childrenKnown)
6169
{
6270
continue;
6371
}
@@ -76,7 +84,7 @@ void RendererDelegate::populate(const UsdPrim& root)
7684
mIndex.insertPrim(rootPath, primPath);
7785
}
7886

79-
if(skipLater)
87+
if (skipLater)
8088
{
8189
continue;
8290
}
@@ -148,6 +156,24 @@ void RendererDelegate::populate(const UsdPrim& root)
148156
}
149157
}
150158

159+
// If the locations '/' or '/materials' were not already "scanned" we don't
160+
// want to check for expression and assignment as materials may not be
161+
// retrieved to do it properly. So skip the Expression scan until
162+
// '/materials' has been scanned in the loop above.
163+
//
164+
// If materials are retrieved and the check for expression and assignment
165+
// are already done there is nothing else to do and we can skip the last
166+
// loop on WalterExpression.
167+
if (!mIndex.hasGlobalMaterials() || mIndex.isAssignmentDone())
168+
{
169+
return;
170+
}
171+
172+
// Always check assignment from the pseudo root "/" whatever the given
173+
// root prim was as material are usually under "/" directly.
174+
UsdPrim pseudoRoot = root.GetStage()->GetPseudoRoot();
175+
range = UsdPrimRange(pseudoRoot);
176+
151177
for (const UsdPrim& prim : range)
152178
{
153179
// We already processed everything and since all the materials are
@@ -161,8 +187,9 @@ void RendererDelegate::populate(const UsdPrim& root)
161187
WalterExpression expression(prim);
162188
std::string expressionText = expression.GetExpression();
163189
WalterExpression::AssignmentLayers layers = expression.GetLayers();
190+
164191
// Insert them into a cache.
165192
mIndex.insertExpression(
166-
prim.GetPath(), rootPath, expressionText, layers);
193+
prim.GetPath(), pseudoRoot.GetPath(), expressionText, layers);
167194
}
168195
}

walter/arnold/procedural/engine.cpp

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ int RendererEngine::getNumNodes(
130130
const UsdPrim prim = mStage->GetPrimAtPath(path);
131131
if (prim)
132132
{
133+
// If the given path is not the root path or a children of /materials
134+
// and if global materials are not already found we need to force
135+
// the check of materials location, which will produce one more
136+
// procedural node set to the '/materials' location.
137+
int numNodes = 0;
138+
if (path != SdfPath("/") &&
139+
!boost::starts_with(path.GetString(), "/materials") &&
140+
!mIndex.hasGlobalMaterials())
141+
{
142+
numNodes = 1;
143+
}
144+
133145
if (prim.IsA<UsdGeomPointInstancer>())
134146
{
135147
UsdGeomPointInstancer instancer(prim);
@@ -144,13 +156,15 @@ int RendererEngine::getNumNodes(
144156
VtVec3fArray positions;
145157
positionsAttr.Get(&positions, static_cast<double>(averageTime));
146158

147-
return static_cast<int>(positions.size());
159+
int pointInstancerNumNodes = static_cast<int>(positions.size());
160+
mIndex.insertNumNodes(prim.GetPath(), pointInstancerNumNodes);
161+
return numNodes + pointInstancerNumNodes;
148162
}
149163

150164
prepare(prim);
151165
// 2x because we need to output a reference and an inctance for each
152166
// object.
153-
return 2 * mIndex.getNumNodes(path);
167+
return numNodes + 2 * mIndex.getNumNodes(path);
154168
}
155169
return 0;
156170
}
@@ -161,22 +175,46 @@ void* RendererEngine::render(
161175
const std::vector<float>& times,
162176
const void* userData)
163177
{
178+
// If the locations '/' or '/materials' are not in the hierarchy map,
179+
// create a walter procedural for /materials. This happend when the first
180+
// "objectPath" given to the procedural was a children of '/'.
181+
//
182+
// If '/materials' need to be scanned we force it to be the first
183+
// thing done.
184+
if (!mIndex.hasGlobalMaterials() && id == 0)
185+
{
186+
SdfPath materialPath("/materials");
187+
UsdPrim materialPrim = mStage->GetPrimAtPath(materialPath);
188+
if (materialPrim)
189+
{
190+
return mPlugin.output(materialPrim, times, userData);
191+
}
192+
}
193+
164194
const UsdPrim parentPrim = mStage->GetPrimAtPath(path);
165195
if (parentPrim.IsA<UsdGeomPointInstancer>())
166196
{
197+
int realID = id % mIndex.getNumNodes(path);
198+
167199
return mPlugin.outputBBoxFromPoint(
168-
parentPrim, id, times, userData, mIndex);
200+
parentPrim, realID, times, userData, mIndex);
169201
}
170202

171-
// TODO: Can be slow.
172203
int numNodes = mIndex.getNumNodes(path);
204+
173205
// It's impossible that numNodes is 0 at this point because render() is
174206
// called from arnoldProceduralGetNode. And arnoldProceduralGetNode is
175207
// called after arnoldProceduralNumNodes. If the number of nodes is 0,
176208
// render() should never be called.
177209
assert(numNodes > 0);
178210

179-
// Since we output a reference and an inctance for each object, the real id
211+
// This is to ensure the id we get is independant of whether material
212+
// were forced to be scanned or not. In any other case than point instancer
213+
// the number of nodes returned to arnold was multiply by 2, that explain
214+
// the manipulation bellow.
215+
id = id % (numNodes * 2);
216+
217+
// Since we output a reference and an instance for each object, the real id
180218
// is id % numNodes. With this we can use variants if variant is 0, we need
181219
// to output a reference object. Otherwise we need to output an instance. We
182220
// use following terminology: a reference is an invisible object that

0 commit comments

Comments
 (0)