10#include <pxr/base/gf/vec2f.h>
11#include <pxr/imaging/hd/extComputationUtils.h>
21 output.reserve(primitiveParams.size());
22 const T &input = value.Get<
T>();
24 for (
size_t i = 0; i < primitiveParams.size(); ++i) {
25 const int faceIndex = HdMeshUtil::DecodeFaceIndexFromCoarseFaceParam(primitiveParams[i]);
27 output.push_back(input[faceIndex]);
34 const HdType valueType,
35 const VtIntArray &primitiveParams)
47 TF_RUNTIME_ERROR(
"Unsupported attribute type %d",
static_cast<int>(valueType));
53 const HdType valueType,
56 if (meshUtil.ComputeTriangulatedFaceVaryingPrimvar(
57 HdGetValueData(value), value.GetArraySize(), valueType, &value))
86 const SdfPath &instancerId
95 _util(&_topology, rprimId)
104 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals |
105 HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyTopology |
106 HdChangeTracker::DirtyDisplayStyle | HdChangeTracker::DirtySubdivTags;
110HdDirtyBits HdCyclesMesh::_PropagateDirtyBits(HdDirtyBits bits)
const
112 if (bits & (HdChangeTracker::DirtyMaterialId)) {
114 bits |= HdChangeTracker::DirtyTopology;
117 if (bits & (HdChangeTracker::DirtyTopology | HdChangeTracker::DirtyDisplayStyle |
118 HdChangeTracker::DirtySubdivTags))
121 bits |= HdChangeTracker::DirtyTopology | HdChangeTracker::DirtyDisplayStyle |
122 HdChangeTracker::DirtySubdivTags;
125 if (bits & (HdChangeTracker::DirtyTopology)) {
127 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals |
128 HdChangeTracker::DirtyPrimvar;
134void HdCyclesMesh::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits,
bool &rebuild)
136 if (HdChangeTracker::IsTopologyDirty(dirtyBits, GetId())) {
137 PopulateTopology(sceneDelegate);
140 if (dirtyBits & HdChangeTracker::DirtyPoints) {
141 PopulatePoints(sceneDelegate);
145 if (dirtyBits & HdChangeTracker::DirtyNormals) {
146 PopulateNormals(sceneDelegate);
150 if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
151 PopulatePrimvars(sceneDelegate);
154 rebuild = (
_geom->triangles_is_modified()) || (
_geom->subd_start_corner_is_modified()) ||
155 (
_geom->subd_num_corners_is_modified()) || (
_geom->subd_shader_is_modified()) ||
156 (
_geom->subd_smooth_is_modified()) || (
_geom->subd_ptex_offset_is_modified()) ||
157 (
_geom->subd_face_corners_is_modified());
160void HdCyclesMesh::PopulatePoints(HdSceneDelegate *sceneDelegate)
164 for (
const HdExtComputationPrimvarDescriptor &desc :
165 sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex))
167 if (desc.name == HdTokens->points) {
168 auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
169 const auto valueStoreIt = valueStore.find(desc.name);
170 if (valueStoreIt != valueStore.end()) {
171 value = std::move(valueStoreIt->second);
177 if (value.IsEmpty()) {
178 value = GetPoints(sceneDelegate);
181 if (!value.IsHolding<VtVec3fArray>()) {
182 TF_WARN(
"Invalid points data for %s", GetId().GetText());
186 const auto &points = value.UncheckedGet<VtVec3fArray>();
188 TF_VERIFY(points.size() >=
static_cast<size_t>(_topology.GetNumPoints()));
190 array<float3> pointsDataCycles;
191 pointsDataCycles.
reserve(points.size());
192 for (
const GfVec3f &
point : points) {
196 _geom->set_verts(pointsDataCycles);
199void HdCyclesMesh::PopulateNormals(HdSceneDelegate *sceneDelegate)
210 HdInterpolation interpolation = HdInterpolationCount;
212 for (
int i = 0; i < HdInterpolationCount && interpolation == HdInterpolationCount; ++i) {
213 for (
const HdExtComputationPrimvarDescriptor &desc :
214 sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(),
215 static_cast<HdInterpolation
>(i)))
217 if (desc.name == HdTokens->normals) {
218 auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
219 const auto valueStoreIt = valueStore.find(desc.name);
220 if (valueStoreIt != valueStore.end()) {
221 value = std::move(valueStoreIt->second);
222 interpolation =
static_cast<HdInterpolation
>(i);
229 if (value.IsEmpty()) {
231 if (interpolation == HdInterpolationCount) {
235 value = GetNormals(sceneDelegate);
238 if (!value.IsHolding<VtVec3fArray>()) {
239 TF_WARN(
"Invalid normals data for %s", GetId().GetText());
243 const auto &
normals = value.UncheckedGet<VtVec3fArray>();
245 if (interpolation == HdInterpolationConstant) {
246 TF_VERIFY(
normals.size() == 1);
248 const GfVec3f constantNormal =
normals[0];
251 for (
size_t i = 0; i <
_geom->get_verts().
size(); ++i) {
252 N[i] =
make_float3(constantNormal[0], constantNormal[1], constantNormal[2]);
255 else if (interpolation == HdInterpolationUniform) {
256 TF_VERIFY(
normals.size() ==
static_cast<size_t>(_topology.GetNumFaces()));
259 for (
size_t i = 0; i <
_geom->num_triangles(); ++i) {
260 const int faceIndex = HdMeshUtil::DecodeFaceIndexFromCoarseFaceParam(_primitiveParams[i]);
265 else if (interpolation == HdInterpolationVertex || interpolation == HdInterpolationVarying) {
266 TF_VERIFY(
normals.size() ==
static_cast<size_t>(_topology.GetNumPoints()) &&
267 static_cast<size_t>(_topology.GetNumPoints()) ==
_geom->get_verts().size());
270 for (
size_t i = 0; i <
_geom->get_verts().
size(); ++i) {
274 else if (interpolation == HdInterpolationFaceVarying) {
275 TF_VERIFY(
normals.size() ==
static_cast<size_t>(_topology.GetNumFaceVaryings()));
277 if (!_util.ComputeTriangulatedFaceVaryingPrimvar(
283 const auto &normalsTriangulated = value.UncheckedGet<VtVec3fArray>();
287 for (
size_t i = 0; i <
_geom->num_triangles(); ++i) {
288 GfVec3f averageNormal = normalsTriangulated[i * 3] + normalsTriangulated[i * 3 + 1] +
289 normalsTriangulated[i * 3 + 2];
290 GfNormalize(&averageNormal);
292 N[i] =
make_float3(averageNormal[0], averageNormal[1], averageNormal[2]);
297void HdCyclesMesh::PopulatePrimvars(HdSceneDelegate *sceneDelegate)
302 AttributeSet &attributes = subdivision ?
_geom->subd_attributes :
_geom->attributes;
304 const std::pair<HdInterpolation, AttributeElement> interpolations[] = {
312 for (
const auto &interpolation : interpolations) {
313 for (
const HdPrimvarDescriptor &desc :
314 GetPrimvarDescriptors(sceneDelegate, interpolation.first))
317 if (desc.name == HdTokens->points || desc.name == HdTokens->normals) {
321 VtValue value = GetPrimvar(sceneDelegate, desc.name);
322 if (value.IsEmpty()) {
326 const ustring name(desc.name.GetString());
329 if (desc.role == HdPrimvarRoleTokens->textureCoordinate) {
332 else if (interpolation.first == HdInterpolationVertex) {
333 if (desc.name == HdTokens->displayColor || desc.role == HdPrimvarRoleTokens->color) {
336 else if (desc.name == HdTokens->normals) {
340 else if (desc.name == HdTokens->displayColor &&
341 interpolation.first == HdInterpolationConstant)
343 if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
344 const GfVec3f
color = value.UncheckedGet<VtVec3fArray>()[0];
351 _geom->need_attribute(scene, name))
353 const HdType valueType = HdGetValueTupleType(value).type;
357 if (interpolation.first == HdInterpolationUniform) {
359 if (value.IsEmpty()) {
363 else if (interpolation.first == HdInterpolationFaceVarying) {
365 if (value.IsEmpty()) {
371 ApplyPrimvars(attributes, name, value, interpolation.second, std);
377void HdCyclesMesh::PopulateTopology(HdSceneDelegate *sceneDelegate)
382 const HdDisplayStyle displayStyle = GetDisplayStyle(sceneDelegate);
383 _topology = HdMeshTopology(GetMeshTopology(sceneDelegate), displayStyle.refineLevel);
385 const TfToken subdivScheme = _topology.GetScheme();
386 if (subdivScheme == PxOsdOpenSubdivTokens->bilinear && _topology.GetRefineLevel() > 0) {
389 else if (subdivScheme == PxOsdOpenSubdivTokens->catmullClark && _topology.GetRefineLevel() > 0) {
396 const bool smooth = !displayStyle.flatShadingEnabled;
400 VtIntArray faceShaders(_topology.GetNumFaces(), 0);
402 HdGeomSubsets
const &geomSubsets = _topology.GetGeomSubsets();
403 if (!geomSubsets.empty()) {
404 array<Node *> usedShaders = std::move(
_geom->get_used_shaders());
408 std::unordered_map<SdfPath, int, SdfPath::Hash> materials;
410 for (
const HdGeomSubset &geomSubset : geomSubsets) {
411 TF_VERIFY(geomSubset.type == HdGeomSubset::TypeFaceSet);
414 const auto it = materials.find(geomSubset.materialId);
415 if (it != materials.end()) {
419 const auto material =
static_cast<const HdCyclesMaterial *
>(
420 sceneDelegate->GetRenderIndex().GetSprim(HdPrimTypeTokens->material,
421 geomSubset.materialId));
423 if (material && material->GetCyclesShader()) {
424 shader =
static_cast<int>(usedShaders.
size());
427 materials.emplace(geomSubset.materialId, shader);
431 for (
int face : geomSubset.indices) {
432 faceShaders[face] = shader;
436 _geom->set_used_shaders(usedShaders);
439 const VtIntArray vertIndx = _topology.GetFaceVertexIndices();
440 const VtIntArray vertCounts = _topology.GetFaceVertexCounts();
443 VtVec3iArray triangles;
444 _util.ComputeTriangleIndices(&triangles, &_primitiveParams);
446 _geom->reserve_mesh(_topology.GetNumPoints(), triangles.size());
448 for (
size_t i = 0; i < _primitiveParams.size(); ++i) {
449 const int faceIndex = HdMeshUtil::DecodeFaceIndexFromCoarseFaceParam(_primitiveParams[i]);
451 const GfVec3i triangle = triangles[i];
452 _geom->add_triangle(triangle[0], triangle[1], triangle[2], faceShaders[faceIndex],
smooth);
456 PxOsdSubdivTags subdivTags = GetSubdivTags(sceneDelegate);
457 _topology.SetSubdivTags(subdivTags);
460 size_t numCorners = 0;
461 for (
int vertCount : vertCounts) {
462 numNgons += (vertCount == 4) ? 0 : 1;
463 numCorners += vertCount;
466 _geom->reserve_subd_faces(_topology.GetNumFaces(), numNgons, numCorners);
469 size_t faceIndex = 0;
470 size_t indexOffset = 0;
471 for (
int vertCount : vertCounts) {
472 _geom->add_subd_face(&vertIndx[indexOffset], vertCount, faceShaders[faceIndex],
smooth);
475 indexOffset += vertCount;
478 const VtIntArray creaseLengths = subdivTags.GetCreaseLengths();
479 if (!creaseLengths.empty()) {
480 size_t numCreases = 0;
481 for (
int creaseLength : creaseLengths) {
482 numCreases += creaseLength - 1;
485 _geom->reserve_subd_creases(numCreases);
487 const VtIntArray creaseIndices = subdivTags.GetCreaseIndices();
488 const VtFloatArray creaseWeights = subdivTags.GetCreaseWeights();
491 size_t creaseLengthOffset = 0;
492 size_t createWeightOffset = 0;
493 for (
int creaseLength : creaseLengths) {
494 for (
int j = 0; j < creaseLength - 1; ++j, ++createWeightOffset) {
495 const int v0 = creaseIndices[indexOffset + j];
496 const int v1 = creaseIndices[indexOffset + j + 1];
498 float weight = creaseWeights.size() == creaseLengths.size() ?
499 creaseWeights[creaseLengthOffset] :
500 creaseWeights[createWeightOffset];
502 _geom->add_edge_crease(v0, v1, weight);
505 indexOffset += creaseLength;
506 creaseLengthOffset++;
509 const VtIntArray cornerIndices = subdivTags.GetCornerIndices();
510 const VtFloatArray cornerWeights = subdivTags.GetCornerWeights();
512 for (
size_t i = 0; i < cornerIndices.size(); ++i) {
513 _geom->add_vertex_crease(cornerIndices[i], cornerWeights[i]);
517 _geom->set_subd_dicing_rate(1.0f);
518 _geom->set_subd_max_level(_topology.GetRefineLevel());
525 _topology = HdMeshTopology();
526 _primitiveParams.clear();
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
VecBase< float, 3 > float3
HdCyclesGeometry(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId)
virtual void Finalize(PXR_NS::HdRenderParam *renderParam) override
PXR_NS::HdInterpolation GetPrimvarInterpolation(PXR_NS::HdSceneDelegate *sceneDelegate, const PXR_NS::TfToken &name) const
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
std::vector< CCL_NS::Object * > _instances
PXR_NS::HdDirtyBits GetInitialDirtyBitsMask() const override
HdCyclesMesh(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId={})
void Finalize(PXR_NS::HdRenderParam *renderParam) override
T * resize(size_t newsize)
void push_back_reserved(const T &t)
void reserve(size_t newcapacity)
void push_back_slow(const T &t)
smooth(Type::VEC3, "P") .flat(Type out_color storage_buf(0, Qualifier::READ, "Surfel", "surfels_buf[]") .push_constant(Type smooth(Type::VEC4, "interp_color")
static float normals[][3]
HDCYCLES_NAMESPACE_OPEN_SCOPE void ApplyPrimvars(AttributeSet &attributes, const ustring &name, VtValue value, AttributeElement elem, AttributeStandard std)
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
Transform convert_transform(const GfMatrix4d &matrix)
VtValue ComputeTriangulatedUniformPrimvar(VtValue value, const VtIntArray &primitiveParams)
VtValue ComputeTriangulatedFaceVaryingPrimvar(VtValue value, const HdType valueType, HdMeshUtil &meshUtil)
@ SUBDIVISION_CATMULL_CLARK