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]);
30 return VtValue(output);
34 const HdType valueType,
35 const VtIntArray &primitiveParams)
39 return ComputeTriangulatedUniformPrimvar<VtFloatArray>(value, primitiveParams);
41 return ComputeTriangulatedUniformPrimvar<VtVec2fArray>(value, primitiveParams);
43 return ComputeTriangulatedUniformPrimvar<VtVec3fArray>(value, primitiveParams);
45 return ComputeTriangulatedUniformPrimvar<VtVec4fArray>(value, 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()));
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]);
262 N[i] =
make_float3(normals[faceIndex][0], normals[faceIndex][1], normals[faceIndex][2]);
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) {
271 N[i] =
make_float3(normals[i][0], normals[i][1], normals[i][2]);
274 else if (interpolation == HdInterpolationFaceVarying) {
275 TF_VERIFY(normals.size() ==
static_cast<size_t>(_topology.GetNumFaceVaryings()));
277 if (!_util.ComputeTriangulatedFaceVaryingPrimvar(
278 normals.data(), normals.size(), HdTypeFloatVec3, &value))
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)
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()) {
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()) {
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();
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
list< Attribute > attributes
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)
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