11#include <pxr/base/gf/vec2f.h>
12#include <pxr/imaging/hd/extComputationUtils.h>
22 output.reserve(primitiveParams.size());
23 const T &
input = value.Get<
T>();
25 for (
size_t i = 0;
i < primitiveParams.size(); ++
i) {
26 const int faceIndex = HdMeshUtil::DecodeFaceIndexFromCoarseFaceParam(primitiveParams[
i]);
35 const HdType valueType,
36 const VtIntArray &primitiveParams)
48 TF_RUNTIME_ERROR(
"Unsupported attribute type %d",
static_cast<int>(valueType));
54 const HdType valueType,
57 if (meshUtil.ComputeTriangulatedFaceVaryingPrimvar(
58 HdGetValueData(value), value.GetArraySize(), valueType, &value))
87 const SdfPath &instancerId
96 _util(&_topology, rprimId)
105 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals |
106 HdChangeTracker::DirtyPrimvar | HdChangeTracker::DirtyTopology |
107 HdChangeTracker::DirtyDisplayStyle | HdChangeTracker::DirtySubdivTags;
111HdDirtyBits HdCyclesMesh::_PropagateDirtyBits(HdDirtyBits bits)
const
113 if (bits & (HdChangeTracker::DirtyMaterialId)) {
115 bits |= HdChangeTracker::DirtyTopology;
118 if (bits & (HdChangeTracker::DirtyTopology | HdChangeTracker::DirtyDisplayStyle |
119 HdChangeTracker::DirtySubdivTags))
122 bits |= HdChangeTracker::DirtyTopology | HdChangeTracker::DirtyDisplayStyle |
123 HdChangeTracker::DirtySubdivTags;
126 if (bits & (HdChangeTracker::DirtyTopology)) {
128 bits |= HdChangeTracker::DirtyPoints | HdChangeTracker::DirtyNormals |
129 HdChangeTracker::DirtyPrimvar;
135void HdCyclesMesh::Populate(HdSceneDelegate *sceneDelegate, HdDirtyBits dirtyBits,
bool &rebuild)
137 if (HdChangeTracker::IsTopologyDirty(dirtyBits, GetId())) {
138 PopulateTopology(sceneDelegate);
141 if (dirtyBits & HdChangeTracker::DirtyPoints) {
142 PopulatePoints(sceneDelegate);
146 if (dirtyBits & HdChangeTracker::DirtyNormals) {
147 PopulateNormals(sceneDelegate);
151 if (dirtyBits & HdChangeTracker::DirtyPrimvar) {
152 PopulatePrimvars(sceneDelegate);
155 rebuild = (
_geom->triangles_is_modified()) || (
_geom->subd_start_corner_is_modified()) ||
156 (
_geom->subd_num_corners_is_modified()) || (
_geom->subd_shader_is_modified()) ||
157 (
_geom->subd_smooth_is_modified()) || (
_geom->subd_ptex_offset_is_modified()) ||
158 (
_geom->subd_face_corners_is_modified());
161void HdCyclesMesh::PopulatePoints(HdSceneDelegate *sceneDelegate)
165 for (
const HdExtComputationPrimvarDescriptor &desc :
166 sceneDelegate->GetExtComputationPrimvarDescriptors(GetId(), HdInterpolationVertex))
168 if (desc.name == HdTokens->points) {
169 auto valueStore = HdExtComputationUtils::GetComputedPrimvarValues({desc}, sceneDelegate);
170 const auto valueStoreIt = valueStore.find(desc.name);
171 if (valueStoreIt != valueStore.end()) {
172 value = std::move(valueStoreIt->second);
178 if (value.IsEmpty()) {
179 value = GetPoints(sceneDelegate);
182 if (!value.IsHolding<VtVec3fArray>()) {
183 TF_WARN(
"Invalid points data for %s", GetId().GetText());
187 const auto &points = value.UncheckedGet<VtVec3fArray>();
189 TF_VERIFY(points.size() >=
static_cast<size_t>(_topology.GetNumPoints()));
191 array<float3> pointsDataCycles;
192 pointsDataCycles.
reserve(points.size());
193 for (
const GfVec3f &point : points) {
197 _geom->set_verts(pointsDataCycles);
200void 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 else if (interpolation == HdInterpolationVertex || interpolation == HdInterpolationVarying) {
260 TF_VERIFY(
normals.size() ==
static_cast<size_t>(_topology.GetNumPoints()) &&
261 static_cast<size_t>(_topology.GetNumPoints()) ==
_geom->get_verts().size());
264 for (
size_t i = 0;
i <
_geom->get_verts().
size(); ++
i) {
268 else if (interpolation == HdInterpolationFaceVarying) {
269 TF_VERIFY(
normals.size() ==
static_cast<size_t>(_topology.GetNumFaceVaryings()));
273 if (!_util.ComputeTriangulatedFaceVaryingPrimvar(
279 const auto &normalsTriangulated = value.UncheckedGet<VtVec3fArray>();
284void HdCyclesMesh::PopulatePrimvars(HdSceneDelegate *sceneDelegate)
289 AttributeSet &attributes = subdivision ?
_geom->subd_attributes :
_geom->attributes;
291 const std::pair<HdInterpolation, AttributeElement> interpolations[] = {
299 for (
const auto &interpolation : interpolations) {
300 for (
const HdPrimvarDescriptor &desc :
301 GetPrimvarDescriptors(sceneDelegate, interpolation.first))
304 if (desc.name == HdTokens->points || desc.name == HdTokens->normals) {
308 VtValue value = GetPrimvar(sceneDelegate, desc.name);
309 if (value.IsEmpty()) {
313 const ustring
name(desc.name.GetString());
316 if (desc.role == HdPrimvarRoleTokens->textureCoordinate) {
319 else if (interpolation.first == HdInterpolationVertex) {
320 if (desc.name == HdTokens->displayColor || desc.role == HdPrimvarRoleTokens->color) {
323 else if (desc.name == HdTokens->normals) {
327 else if (desc.name == HdTokens->displayColor &&
328 interpolation.first == HdInterpolationConstant)
330 if (value.IsHolding<VtVec3fArray>() && value.GetArraySize() == 1) {
331 const GfVec3f color = value.UncheckedGet<VtVec3fArray>()[0];
340 const HdType valueType = HdGetValueTupleType(value).type;
344 if (interpolation.first == HdInterpolationUniform) {
346 if (value.IsEmpty()) {
350 else if (interpolation.first == HdInterpolationFaceVarying) {
352 if (value.IsEmpty()) {
364void HdCyclesMesh::PopulateTopology(HdSceneDelegate *sceneDelegate)
369 const HdDisplayStyle displayStyle = GetDisplayStyle(sceneDelegate);
370 _topology = HdMeshTopology(GetMeshTopology(sceneDelegate), displayStyle.refineLevel);
372 const TfToken subdivScheme = _topology.GetScheme();
373 if (subdivScheme == PxOsdOpenSubdivTokens->bilinear && _topology.GetRefineLevel() > 0) {
376 else if (subdivScheme == PxOsdOpenSubdivTokens->catmullClark && _topology.GetRefineLevel() > 0) {
383 const bool smooth = !displayStyle.flatShadingEnabled;
387 VtIntArray faceShaders(_topology.GetNumFaces(), 0);
389 const HdGeomSubsets &geomSubsets = _topology.GetGeomSubsets();
390 if (!geomSubsets.empty()) {
391 array<Node *> usedShaders = std::move(
_geom->get_used_shaders());
395 std::unordered_map<SdfPath, int, SdfPath::Hash> materials;
397 for (
const HdGeomSubset &geomSubset : geomSubsets) {
398 TF_VERIFY(geomSubset.type == HdGeomSubset::TypeFaceSet);
401 const auto it = materials.find(geomSubset.materialId);
402 if (it != materials.end()) {
406 const auto *
const material =
static_cast<const HdCyclesMaterial *
>(
407 sceneDelegate->GetRenderIndex().GetSprim(HdPrimTypeTokens->material,
408 geomSubset.materialId));
410 if (material && material->GetCyclesShader()) {
411 shader =
static_cast<int>(usedShaders.
size());
414 materials.emplace(geomSubset.materialId, shader);
418 for (
const int face : geomSubset.indices) {
419 faceShaders[face] = shader;
423 _geom->set_used_shaders(usedShaders);
426 const VtIntArray vertIndx = _topology.GetFaceVertexIndices();
427 const VtIntArray vertCounts = _topology.GetFaceVertexCounts();
430 VtVec3iArray triangles;
431 _util.ComputeTriangleIndices(&triangles, &_primitiveParams);
433 _geom->reserve_mesh(_topology.GetNumPoints(), triangles.size());
435 for (
size_t i = 0;
i < _primitiveParams.size(); ++
i) {
436 const int faceIndex = HdMeshUtil::DecodeFaceIndexFromCoarseFaceParam(_primitiveParams[
i]);
438 const GfVec3i triangle = triangles[
i];
439 _geom->add_triangle(triangle[0], triangle[1], triangle[2], faceShaders[faceIndex], smooth);
443 const PxOsdSubdivTags subdivTags = GetSubdivTags(sceneDelegate);
444 _topology.SetSubdivTags(subdivTags);
446 size_t numCorners = 0;
447 for (
const int vertCount : vertCounts) {
448 numCorners += vertCount;
451 _geom->reserve_subd_faces(_topology.GetNumFaces(), numCorners);
454 size_t faceIndex = 0;
455 size_t indexOffset = 0;
456 for (
const int vertCount : vertCounts) {
457 _geom->add_subd_face(&vertIndx[indexOffset], vertCount, faceShaders[faceIndex], smooth);
460 indexOffset += vertCount;
463 const VtIntArray creaseLengths = subdivTags.GetCreaseLengths();
464 if (!creaseLengths.empty()) {
465 size_t numCreases = 0;
466 for (
const int creaseLength : creaseLengths) {
467 numCreases += creaseLength - 1;
470 _geom->reserve_subd_creases(numCreases);
472 const VtIntArray creaseIndices = subdivTags.GetCreaseIndices();
473 const VtFloatArray creaseWeights = subdivTags.GetCreaseWeights();
476 size_t creaseLengthOffset = 0;
477 size_t createWeightOffset = 0;
478 for (
const int creaseLength : creaseLengths) {
479 for (
int j = 0; j < creaseLength - 1; ++j, ++createWeightOffset) {
480 const int v0 = creaseIndices[indexOffset + j];
481 const int v1 = creaseIndices[indexOffset + j + 1];
483 const float weight = creaseWeights.size() == creaseLengths.size() ?
484 creaseWeights[creaseLengthOffset] :
485 creaseWeights[createWeightOffset];
487 _geom->add_edge_crease(v0, v1, weight);
490 indexOffset += creaseLength;
491 creaseLengthOffset++;
494 const VtIntArray cornerIndices = subdivTags.GetCornerIndices();
495 const VtFloatArray cornerWeights = subdivTags.GetCornerWeights();
497 for (
size_t i = 0;
i < cornerIndices.size(); ++
i) {
498 _geom->add_vertex_crease(cornerIndices[
i], cornerWeights[
i]);
502 _geom->set_subd_dicing_rate(1.0f);
503 _geom->set_subd_max_level(_topology.GetRefineLevel());
510 _topology = HdMeshTopology();
511 _primitiveParams.clear();
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
HdCyclesGeometry(const PXR_NS::SdfPath &rprimId, const PXR_NS::SdfPath &instancerId)
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
void push_back_reserved(const T &t)
void reserve(const size_t newcapacity)
T * resize(const size_t newsize)
void push_back_slow(const T &t)
static float normals[][3]
VecBase< float, 3 > float3
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