|
40 | 40 |
|
41 | 41 | #include "IECore/SimpleTypedData.h" |
42 | 42 |
|
| 43 | +#include "boost/algorithm/string/predicate.hpp" |
| 44 | + |
43 | 45 | IECORE_PUSH_DEFAULT_VISIBILITY |
44 | 46 | #include "pxr/usd/usdGeom/points.h" |
| 47 | +#if PXR_VERSION >= 2603 |
| 48 | +#include "pxr/usd/usdVol/particleField3DGaussianSplat.h" |
| 49 | +#endif |
45 | 50 | IECORE_POP_DEFAULT_VISIBILITY |
46 | 51 |
|
47 | 52 | using namespace IECore; |
@@ -94,6 +99,104 @@ namespace |
94 | 99 |
|
95 | 100 | bool writePoints( const IECoreScene::PointsPrimitive *points, const pxr::UsdStagePtr &stage, const pxr::SdfPath &path, pxr::UsdTimeCode time ) |
96 | 101 | { |
| 102 | +#if PXR_VERSION >= 2603 |
| 103 | + auto type = points->variableData<const StringData>( "type", PrimitiveVariable::Constant ); |
| 104 | + if( type && type->readable() == "gaussianSplat" ) |
| 105 | + { |
| 106 | + auto usdSplats = pxr::UsdVolParticleField3DGaussianSplat::Define( stage, path ); |
| 107 | + |
| 108 | + int maxCoefficientsIndex = -1; |
| 109 | + std::unordered_map<int, const V3fVectorData *> coefficientsMap; |
| 110 | + |
| 111 | + for( const auto &p : points->variables ) |
| 112 | + { |
| 113 | + if( p.first == "P" ) |
| 114 | + { |
| 115 | + usdSplats.CreatePositionsAttr().Set( PrimitiveAlgo::toUSDExpanded( p.second ), time ); |
| 116 | + } |
| 117 | + else if( p.first == "orientations" ) |
| 118 | + { |
| 119 | + usdSplats.CreateOrientationsAttr().Set( PrimitiveAlgo::toUSDExpanded( p.second ), time ); |
| 120 | + } |
| 121 | + else if( p.first == "scales" ) |
| 122 | + { |
| 123 | + usdSplats.CreateScalesAttr().Set( PrimitiveAlgo::toUSDExpanded( p.second ), time ); |
| 124 | + } |
| 125 | + else if( p.first == "opacities" ) |
| 126 | + { |
| 127 | + usdSplats.CreateOpacitiesAttr().Set( PrimitiveAlgo::toUSDExpanded( p.second ), time ); |
| 128 | + } |
| 129 | + else if( p.first == "radiance:sphericalHarmonicsDegree" ) |
| 130 | + { |
| 131 | + usdSplats.CreateRadianceSphericalHarmonicsDegreeAttr().Set( DataAlgo::toUSD( p.second.data.get() ), time ); |
| 132 | + } |
| 133 | + else if( p.first == "projectionModeHint" ) |
| 134 | + { |
| 135 | + usdSplats.CreateProjectionModeHintAttr().Set( DataAlgo::toUSD( p.second.data.get() ), time ); |
| 136 | + } |
| 137 | + else if( p.first == "sortingModeHint" ) |
| 138 | + { |
| 139 | + usdSplats.CreateSortingModeHintAttr().Set( DataAlgo::toUSD( p.second.data.get() ), time ); |
| 140 | + } |
| 141 | + else if( boost::starts_with( p.first, "radiance:sphericalHarmonicsCoefficients:" ) ) |
| 142 | + { |
| 143 | + try |
| 144 | + { |
| 145 | + const int coefficientsIndex = std::stoi( p.first.substr( 40 ) ); // 40 = length of `radiance:...` prefix |
| 146 | + |
| 147 | + if( p.second.data->typeId() != V3fVectorDataTypeId || p.second.interpolation != PrimitiveVariable::Interpolation::Vertex ) |
| 148 | + { |
| 149 | + IECore::msg( |
| 150 | + IECore::Msg::Warning, |
| 151 | + "PointsAlgo::writePoints", |
| 152 | + "Invalid primitive variable \"{}\" on location \"{}\". Spherical harmonics coefficients must be of type V3fVectorData with Vertex interpolation.", |
| 153 | + p.first, path.GetAsString() |
| 154 | + ); |
| 155 | + continue; |
| 156 | + } |
| 157 | + |
| 158 | + coefficientsMap[coefficientsIndex] = static_cast<const V3fVectorData *>( p.second.data.get() ); |
| 159 | + maxCoefficientsIndex = std::max( maxCoefficientsIndex, coefficientsIndex ); |
| 160 | + } |
| 161 | + catch( ... ) |
| 162 | + { |
| 163 | + PrimitiveAlgo::writePrimitiveVariable( p.first, p.second, usdSplats, time ); |
| 164 | + } |
| 165 | + } |
| 166 | + else if( p.first == "type" ) |
| 167 | + { |
| 168 | + // This is intrinsic to `UsdVolParticleField3DGaussianSplat` |
| 169 | + continue; |
| 170 | + } |
| 171 | + else |
| 172 | + { |
| 173 | + PrimitiveAlgo::writePrimitiveVariable( p.first, p.second, usdSplats, time ); |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + if( !coefficientsMap.empty() ) |
| 178 | + { |
| 179 | + const int coefficientsCount = maxCoefficientsIndex + 1; |
| 180 | + pxr::VtArray<pxr::GfVec3f> allCoefficients( coefficientsCount * points->getNumPoints() ); |
| 181 | + |
| 182 | + for( const auto &[i, coefficientsData] : coefficientsMap ) |
| 183 | + { |
| 184 | + const std::vector<Imath::V3f> &coefficients = coefficientsData->readable(); |
| 185 | + |
| 186 | + for( size_t j = 0, eJ = points->getNumPoints(); j < eJ; ++j ) |
| 187 | + { |
| 188 | + allCoefficients[j * coefficientsCount + i] = DataAlgo::toUSD( coefficients[j] ); |
| 189 | + } |
| 190 | + } |
| 191 | + |
| 192 | + usdSplats.CreateRadianceSphericalHarmonicsCoefficientsAttr().Set( allCoefficients, time ); |
| 193 | + } |
| 194 | + |
| 195 | + return true; |
| 196 | + } |
| 197 | + |
| 198 | +#endif |
| 199 | + |
97 | 200 | auto usdPoints = pxr::UsdGeomPoints::Define( stage, path ); |
98 | 201 | for( const auto &p : points->variables ) |
99 | 202 | { |
|
0 commit comments