Skip to content

Commit

Permalink
Adding Hydra Generative Procedural Example of a simple Triangle
Browse files Browse the repository at this point in the history
Signed-off-by: Infernalspawn <sebastian.h.schmidt@gmail.com>
  • Loading branch information
infernalspawn committed Jul 28, 2024
1 parent 6ea28a1 commit 3573db0
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 2 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

A collection of example plugins for [Pixar's USD](https://github.com/PixarAnimationStudios/USD) (Universal Scene Description).

This project also aims to provide a set of CMake utilities for building USD plugins outside of the USD project source tree. The utilities are heavily based on the build logic prescribed by the USD project itself.
This project also aims to provide a set of CMake utilities for building USD plugins outside of the USD project source tree. The utilities are heavily based on the build logic prescribed by the USD project itself.

We hope the minimal examples and surrounding build infrastructure can be useful to USD community developers interested in building and deploying their own plugin(s).
We hope the minimal examples and surrounding build infrastructure can be useful to USD community developers interested in building and deploying their own plugin(s).

Huge thanks to Pixar's USD team for providing a highly extensible platform!

Expand All @@ -25,6 +25,7 @@ Huge thanks to Pixar's USD team for providing a highly extensible platform!
- [usdTriImaging](./src/usdTriImaging): A prim adapter which images the **Triangle** prim type.
- [usdTriFileFormat](./src/usdTriFileFormat): A file format plugin which authors a triangular mesh for a `.triangle` payload.
- [hdTri](./src/hdTri): A hydra renderer plugin which images a triangle (in the most direct sense).
- [hdGpTri](./src/hdGpTri): A generative procedural plugin which creates a triangle (in the most direct sense).
- [usdviewTri](./src/usdviewTri): An usdview plugin providing a menu command to define child Triangle prim(s) under selected paths.

There are many other USD plugins available online - check out [USD Working Group: Projects & Resources](https://wiki.aswf.io/display/WGUSD/USD+Projects+and+Resources) for more!
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_subdirectory(usdviewTri)
add_subdirectory(usdTriImaging)
add_subdirectory(usdTriFileFormat)
add_subdirectory(hdTri)
add_subdirectory(hdGpTri)

# Install top-level plugInfo for including per-library plugInfo(s).
install(
Expand Down
41 changes: 41 additions & 0 deletions src/hdGpTri/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
usd_plugin(hdGpTri

PUBLIC_HEADERS_INSTALL_PREFIX
${ORGANIZATION}

PYTHON_INSTALL_PREFIX
${ORGANIZATION}

LIBRARIES
js
plug
tf
sdf
vt
gf
hdGp
arch

CPPFILES
triGenerative.cpp

RESOURCE_FILES
plugInfo.json
)


#add_subdirectory(tests)

#usd_test(usdTriGenerative_testTriangle

# CPPFILES
# tests/testUsdImagingGLHdGp.cpp

# LIBRARIES
# tf
# sdf
# usd
# usdGeom
# hdGp
# usdImagingGL
#)
22 changes: 22 additions & 0 deletions src/hdGpTri/plugInfo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"Plugins": [
{
"Info": {
"Types": {
"TriProceduralPlugin": {
"bases": [
"HdGpGenerativeProceduralPlugin"
],
"displayName": "triangle",
"priority" : 0
}
}
},
"LibraryPath": "../../hdGpTri.so",
"Name": "hdGpTri",
"ResourcePath": "resources",
"Root": "..",
"Type": "library"
}
]
}
27 changes: 27 additions & 0 deletions src/hdGpTri/scenes/triangle.usda
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#usda 1.0
(
startFrame = 1
endFrame = 2
)

def Scope "World"
{
def GenerativeProcedural "myGenerativeProc" (
prepend apiSchemas = ["HydraGenerativeProceduralAPI"]
)
{
token primvars:hdGp:proceduralType = "triangle"
double primvars:sideLength = 1.0
}

def GenerativeProcedural "myGenerativeProTransformed" (
prepend apiSchemas = ["HydraGenerativeProceduralAPI"]
)
{
token primvars:hdGp:proceduralType = "triangle"
double primvars:sideLength = 1.0

matrix4d xformOp:transform:transform1 = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (15, 15, 15, 1) )
uniform token[] xformOpOrder = ["xformOp:transform:transform1"]
}
}
193 changes: 193 additions & 0 deletions src/hdGpTri/triGenerative.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
//
// Copyright © 2024 Weta FX Limited
//
// SPDX-License-Identifier: Apache-2.0
//

#include "./triGenerative.h"

#include <pxr/imaging/hd/retainedDataSource.h>
#include <pxr/imaging/hd/primvarsSchema.h>
#include <pxr/imaging/hd/meshSchema.h>
#include <pxr/imaging/hd/tokens.h>

PXR_NAMESPACE_USING_DIRECTIVE

namespace {
TF_DEFINE_PRIVATE_TOKENS(_makeSomeStuffTokens, (sideLength)(myTriangle));
}

class _PointsFromSideLengthDataSource : public HdVec3fArrayDataSource
{
public:
HD_DECLARE_DATASOURCE(_PointsFromSideLengthDataSource);

bool GetContributingSampleTimesForInterval(
Time startTime,
Time endTime,
std::vector<Time>* outSampleTimes) override
{
return _sideLengthDs->GetContributingSampleTimesForInterval(
startTime, endTime, outSampleTimes);
}

VtValue GetValue(Time shutterOffset)
{
return VtValue(GetTypedValue(shutterOffset));
}

VtArray<GfVec3f> GetTypedValue(Time shutterOffset)
{
double sideLength =
_sideLengthDs->GetValue(shutterOffset).UncheckedGet<double>();

VtVec3fArray points{
GfVec3f(0.0f, 0.57735027f * sideLength, 0.0f),
GfVec3f(-0.5f * sideLength, -0.28867513f * sideLength, 0.0f),
GfVec3f(0.5f * sideLength, -0.28867513f * sideLength, 0.0f)
};
return points;
}

private:
_PointsFromSideLengthDataSource(HdSampledDataSourceHandle sideLengthDs)
: _sideLengthDs(sideLengthDs)
{
}

HdSampledDataSourceHandle _sideLengthDs;
};

_MakeTriGenerativeProcedural::_MakeTriGenerativeProcedural(
const SdfPath& i_primPath)
: HdGpGenerativeProcedural(i_primPath)
{
}

HdGpGenerativeProcedural*
_MakeTriGenerativeProcedural::New(const SdfPath& i_primPath)
{
return new _MakeTriGenerativeProcedural(i_primPath);
}

HdGpGenerativeProcedural::DependencyMap
_MakeTriGenerativeProcedural::UpdateDependencies(
const HdSceneIndexBaseRefPtr& i_inputScene)
{
HdGpGenerativeProcedural::DependencyMap result;
return result;
}

HdGpGenerativeProcedural::ChildPrimTypeMap
_MakeTriGenerativeProcedural::Update(
const HdSceneIndexBaseRefPtr& i_inputScene,
const HdGpGenerativeProcedural::ChildPrimTypeMap& i_previousResult,
const HdGpGenerativeProcedural::DependencyMap& i_dirtiedDependencies,
HdSceneIndexObserver::DirtiedPrimEntries* o_outputDirtiedPrims)
{
ChildPrimTypeMap result;
HdSceneIndexPrim myPrim = i_inputScene->GetPrim(_GetProceduralPrimPath());

double sideLength = 1.0f;
if (HdSampledDataSourceHandle sideLengthDS =
HdPrimvarsSchema::GetFromParent(myPrim.dataSource)
.GetPrimvar(_makeSomeStuffTokens->sideLength)
.GetPrimvarValue()) {

VtValue v = sideLengthDS->GetValue(0.0f);
if (v.IsHolding<double>()) {
sideLength = v.UncheckedGet<double>();
_sideLengthDs = sideLengthDS;
}
}

const bool lengthChanged = sideLength != _sideLength;
if (lengthChanged) {
// new
SdfPath tPath = _GetProceduralPrimPath();
tPath.AppendChild(_makeSomeStuffTokens->myTriangle);
o_outputDirtiedPrims->emplace_back(
tPath, HdPrimvarsSchema::GetPointsLocator());
}

// new
SdfPath tpath = _GetProceduralPrimPath();
tpath = tpath.AppendChild(_makeSomeStuffTokens->myTriangle);
result[tpath] = HdPrimTypeTokens->mesh;

return result;
}

HdContainerDataSourceHandle
_MakeTriGenerativeProcedural::_GetChildPrimvarsDs()
{
HdContainerDataSourceHandle primvarsDs = HdRetainedContainerDataSource::New(
HdPrimvarsSchemaTokens->points,
HdPrimvarSchema::Builder()
.SetPrimvarValue(
_PointsFromSideLengthDataSource::New(_sideLengthDs))
.SetInterpolation(HdPrimvarSchema::BuildInterpolationDataSource(
HdPrimvarSchemaTokens->vertex))
.SetRole(HdPrimvarSchema::BuildRoleDataSource(
HdPrimvarSchemaTokens->point))
.Build());

return primvarsDs;
}

HdContainerDataSourceHandle
_MakeTriGenerativeProcedural::_GetChildMeshDs()
{
static const VtIntArray faceVertexCounts = { 3 };

static const VtIntArray faceVertexIndices = { 0, 1, 2 };

using _IntArrayDs = HdRetainedTypedSampledDataSource<VtIntArray>;

static const _IntArrayDs::Handle fvcDs = _IntArrayDs::New(faceVertexCounts);

static const _IntArrayDs::Handle fviDs =
_IntArrayDs::New(faceVertexIndices);

static const HdContainerDataSourceHandle meshDs =
HdMeshSchema::Builder()
.SetTopology(HdMeshTopologySchema::Builder()
.SetFaceVertexCounts(fvcDs)
.SetFaceVertexIndices(fviDs)
.Build())
.Build();

return meshDs;
}

HdSceneIndexPrim
_MakeTriGenerativeProcedural::GetChildPrim(
const HdSceneIndexBaseRefPtr& i_inputScene,
const SdfPath& i_childPrimPath)
{

HdSceneIndexPrim result;

if (i_childPrimPath == _GetProceduralPrimPath().AppendChild(
_makeSomeStuffTokens->myTriangle)) {
result.primType = HdPrimTypeTokens->mesh;
result.dataSource =
HdRetainedContainerDataSource::New(HdPrimvarsSchemaTokens->primvars,
_GetChildPrimvarsDs(),
HdPrimTypeTokens->mesh,
_GetChildMeshDs());
}
return result;
}

HdGpGenerativeProcedural*
TriProceduralPlugin::Construct(const SdfPath& i_proceduralPrimPath)
{
return _MakeTriGenerativeProcedural::New(i_proceduralPrimPath);
}

TF_REGISTRY_FUNCTION(TfType)
{
HdGpGenerativeProceduralPluginRegistry::
Define<TriProceduralPlugin, HdGpGenerativeProceduralPlugin>();
}
52 changes: 52 additions & 0 deletions src/hdGpTri/triGenerative.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Copyright © 2024 Weta FX Limited
//
// SPDX-License-Identifier: Apache-2.0
//

#include <pxr/imaging/hdGp/sceneIndexPlugin.h>
#include <pxr/imaging/hdGp/generativeProcedural.h>
#include <pxr/imaging/hdGp/generativeProceduralPlugin.h>
#include <pxr/imaging/hdGp/generativeProceduralPluginRegistry.h>

PXR_NAMESPACE_OPEN_SCOPE

class _MakeTriGenerativeProcedural : public HdGpGenerativeProcedural
{

public:
_MakeTriGenerativeProcedural(const SdfPath& i_primPath);

static HdGpGenerativeProcedural* New(const SdfPath& i_primPath);

HdGpGenerativeProcedural::DependencyMap UpdateDependencies(
const HdSceneIndexBaseRefPtr& i_inputScene) override;

ChildPrimTypeMap Update(const HdSceneIndexBaseRefPtr& i_inputScene,
const ChildPrimTypeMap& i_previousResult,
const DependencyMap& i_dirtiedDependencies,
HdSceneIndexObserver::DirtiedPrimEntries*
o_outputDirtiedPrims) override;

HdSceneIndexPrim GetChildPrim(const HdSceneIndexBaseRefPtr& i_inputScene,
const SdfPath& i_childPrimPath) override;

private:
HdContainerDataSourceHandle _GetChildMeshDs();
HdContainerDataSourceHandle _GetChildPrimvarsDs();

double _sideLength = 1.0f;
HdSampledDataSourceHandle _displayColorDs;
HdSampledDataSourceHandle _sideLengthDs;
};

class TriProceduralPlugin : public HdGpGenerativeProceduralPlugin
{
public:
TriProceduralPlugin() = default;

HdGpGenerativeProcedural* Construct(
const SdfPath& i_proceduralPrimPath) override;
};

PXR_NAMESPACE_CLOSE_SCOPE

0 comments on commit 3573db0

Please sign in to comment.