7#include <pxr/base/gf/vec2f.h>
8#include <pxr/imaging/hd/light.h>
36 for (
auto &m_inst : mesh_instances_.values()) {
37 m_inst.data->remove();
39 if (!mesh_instances_.is_empty()) {
42 mesh_instances_.clear();
44 for (
auto &l_inst : nonmesh_instances_.values()) {
45 l_inst.transforms.clear();
46 update_nonmesh_instance(l_inst);
48 nonmesh_instances_.clear();
55 ID_LOG(
"%s", key.GetText());
56 if (key == pxr::HdInstancerTokens->instanceTransforms) {
57 return pxr::VtValue(mesh_transforms_);
59 return pxr::VtValue();
64 NonmeshInstance *nm_inst = nonmesh_instance(
id);
66 return nm_inst->transforms[nonmesh_prim_id_index(
id)];
70 return pxr::GfMatrix4d(1.0);
74 pxr::HdInterpolation interpolation)
const
76 pxr::HdPrimvarDescriptorVector primvars;
77 if (interpolation == pxr::HdInterpolationInstance) {
78 primvars.emplace_back(
79 pxr::HdInstancerTokens->instanceTransforms, interpolation, pxr::HdPrimvarRoleTokens->none);
86 return mesh_instance(
id)->indices;
91 MeshInstance *m_inst = mesh_instance(
id);
93 return m_inst->data.get();
95 NonmeshInstance *nm_inst = nonmesh_instance(
id);
97 return nm_inst->data.get();
104 pxr::SdfPathVector paths;
105 for (
const auto &m_inst : mesh_instances_.values()) {
106 for (
auto &p : m_inst.data->submesh_paths()) {
115 for (
const auto &m_inst : mesh_instances_.values()) {
116 m_inst.data->available_materials(paths);
118 for (
const auto &l_inst : nonmesh_instances_.values()) {
119 l_inst.data->available_materials(paths);
125 for (
auto &m_inst : mesh_instances_.values()) {
126 m_inst.data->update_double_sided(mat_data);
132 mesh_transforms_.clear();
133 for (
auto &m_inst : mesh_instances_.values()) {
134 m_inst.indices.clear();
136 for (
auto &l_inst : nonmesh_instances_.values()) {
137 l_inst.transforms.clear();
144 pxr::SdfPath p_id = object_prim_id(
object);
146 MeshInstance *m_inst = mesh_instance(p_id);
148 m_inst = &mesh_instances_.lookup_or_add_default(p_id);
149 m_inst->data = std::make_unique<MeshData>(
scene_delegate_,
object, p_id);
150 m_inst->data->init();
151 m_inst->data->insert();
154 m_inst->data->update();
156 ID_LOG(
"Mesh %s %d", m_inst->data->id->name,
int(mesh_transforms_.size()));
157 m_inst->indices.push_back(mesh_transforms_.size());
161 NonmeshInstance *nm_inst = nonmesh_instance(p_id);
163 nm_inst = &nonmesh_instances_.lookup_or_add_default(p_id);
166 ID_LOG(
"Nonmesh %s %d", nm_inst->data->id->name,
int(nm_inst->transforms.size()));
175 pxr::SdfPath h_id = hair_prim_id(
object, psys);
176 NonmeshInstance *nm_inst = nonmesh_instance(h_id);
178 nm_inst = &nonmesh_instances_.lookup_or_add_default(h_id);
179 nm_inst->data = std::make_unique<HairData>(
scene_delegate_,
object, h_id, psys);
180 nm_inst->data->init();
182 ID_LOG(
"Nonmesh %s %d", nm_inst->data->id->name,
int(nm_inst->transforms.size()));
192 mesh_instances_.remove_if([&](
auto item) {
193 bool res = item.value.indices.empty();
195 item.value.data->remove();
201 for (
auto &l_inst : nonmesh_instances_.values()) {
202 update_nonmesh_instance(l_inst);
204 nonmesh_instances_.remove_if([&](
auto item) {
return item.value.transforms.empty(); });
208 if (mesh_instances_.is_empty()) {
210 if (index.HasInstancer(
prim_id) && nonmesh_instances_.is_empty()) {
211 index.RemoveInstancer(
prim_id);
212 ID_LOG(
"Remove instancer");
216 if (index.HasInstancer(
prim_id)) {
217 index.GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
218 ID_LOG(
"Update instancer");
222 ID_LOG(
"Insert instancer");
227pxr::SdfPath InstancerData::object_prim_id(
Object *
object)
const
239 SNPRINTF(
name,
"%s_PS_%p", object_prim_id(parent_obj).GetName().c_str(), psys);
243pxr::SdfPath InstancerData::nonmesh_prim_id(pxr::SdfPath
const &prim_id,
int index)
const
250int InstancerData::nonmesh_prim_id_index(pxr::SdfPath
const &
id)
const
253 sscanf(
id.GetName().c_str(),
"NM_%d", &index);
257void InstancerData::update_nonmesh_instance(NonmeshInstance &nm_inst)
259 ObjectData *obj_data = nm_inst.data.get();
260 pxr::SdfPath prev_id = nm_inst.data->prim_id;
264 while (nm_inst.count > nm_inst.transforms.size()) {
266 obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
272 LightData *l_data =
dynamic_cast<LightData *
>(obj_data);
273 if (l_data && l_data->prim_type((
Light *)((
Object *)l_data->id)->data) != l_data->prim_type_) {
274 for (
i = 0;
i < nm_inst.count; ++
i) {
275 obj_data->prim_id = nonmesh_prim_id(prev_id,
i);
279 for (
i = 0;
i < nm_inst.count; ++
i) {
280 obj_data->prim_id = nonmesh_prim_id(prev_id,
i);
285 for (
i = 0;
i < nm_inst.count; ++
i) {
286 obj_data->prim_id = nonmesh_prim_id(prev_id,
i);
292 while (nm_inst.count < nm_inst.transforms.size()) {
293 obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
298 obj_data->prim_id = prev_id;
301InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath
const &
id)
const
303 const auto *m_inst = mesh_instances_.lookup_ptr(
304 id.GetPathElementCount() == 4 ?
id.GetParentPath() :
id);
308 return const_cast<MeshInstance *
>(m_inst);
311InstancerData::NonmeshInstance *InstancerData::nonmesh_instance(pxr::SdfPath
const &
id)
const
313 const auto *nm_inst = nonmesh_instances_.lookup_ptr(
314 id.GetPathElementCount() == 4 ?
id.GetParentPath() :
id);
318 return const_cast<NonmeshInstance *
>(nm_inst);
bool psys_in_edit_mode(struct Depsgraph *depsgraph, const struct ParticleSystem *psys)
#define LISTBASE_FOREACH(type, var, list)
#define SNPRINTF(dst, format,...)
#define CLOG_DEBUG(clg_ref,...)
static bool is_supported(const ParticleSystem *particle_system)
static bool is_visible(HydraSceneDelegate *scene_delegate, Object *object, ParticleSystem *particle_system)
IdData(HydraSceneDelegate *scene_delegate, const ID *id, pxr::SdfPath const &prim_id)
HydraSceneDelegate * scene_delegate_
pxr::GfMatrix4d transform(pxr::SdfPath const &id) const
pxr::VtIntArray indices(pxr::SdfPath const &id) const
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const
void update_instance(DupliObject *dupli)
InstancerData(HydraSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
pxr::VtValue get_data(pxr::TfToken const &key) const override
void available_materials(Set< pxr::SdfPath > &paths) const
pxr::SdfPathVector prototypes() const
ObjectData * object_data(pxr::SdfPath const &id) const
void update_double_sided(MaterialData *mat_data)
static bool is_mesh(const Object *object)
static std::unique_ptr< ObjectData > create(HydraSceneDelegate *scene_delegate, const Object *object, pxr::SdfPath const &prim_id)
struct CLG_LogRef * LOG_HYDRA_SCENE
pxr::GfMatrix4d gf_matrix_from_transform(const float m[4][4])