7#include <pxr/base/gf/vec2f.h>
8#include <pxr/imaging/hd/light.h>
24 :
IdData(scene_delegate, nullptr, prim_id)
35 for (
auto &m_inst : mesh_instances_.
values()) {
36 m_inst.data->remove();
41 mesh_instances_.
clear();
43 for (
auto &l_inst : nonmesh_instances_.
values()) {
44 l_inst.transforms.clear();
45 update_nonmesh_instance(l_inst);
47 nonmesh_instances_.
clear();
54 ID_LOG(3,
"%s", key.GetText());
55 if (key == pxr::HdInstancerTokens->instanceTransforms) {
56 return pxr::VtValue(mesh_transforms_);
58 return pxr::VtValue();
63 NonmeshInstance *nm_inst = nonmesh_instance(
id);
65 return nm_inst->transforms[nonmesh_prim_id_index(
id)];
69 return pxr::GfMatrix4d(1.0);
73 pxr::HdInterpolation interpolation)
const
75 pxr::HdPrimvarDescriptorVector primvars;
76 if (interpolation == pxr::HdInterpolationInstance) {
77 primvars.emplace_back(
78 pxr::HdInstancerTokens->instanceTransforms, interpolation, pxr::HdPrimvarRoleTokens->none);
85 return mesh_instance(
id)->indices;
90 MeshInstance *m_inst = mesh_instance(
id);
92 return m_inst->data.get();
94 NonmeshInstance *nm_inst = nonmesh_instance(
id);
96 return nm_inst->data.get();
103 pxr::SdfPathVector paths;
104 for (
auto &m_inst : mesh_instances_.
values()) {
105 for (
auto &p : m_inst.data->submesh_paths()) {
114 for (
auto &m_inst : mesh_instances_.
values()) {
115 m_inst.data->available_materials(paths);
117 for (
auto &l_inst : nonmesh_instances_.
values()) {
118 l_inst.data->available_materials(paths);
124 for (
auto &m_inst : mesh_instances_.
values()) {
125 m_inst.data->update_double_sided(mat_data);
131 mesh_transforms_.clear();
132 for (
auto &m_inst : mesh_instances_.
values()) {
133 m_inst.indices.clear();
135 for (
auto &l_inst : nonmesh_instances_.
values()) {
136 l_inst.transforms.clear();
143 pxr::SdfPath p_id = object_prim_id(
object);
145 MeshInstance *m_inst = mesh_instance(p_id);
148 m_inst->data = std::make_unique<MeshData>(
scene_delegate_,
object, p_id);
149 m_inst->data->init();
150 m_inst->data->insert();
153 m_inst->data->update();
155 ID_LOG(2,
"Mesh %s %d", m_inst->data->id->name,
int(mesh_transforms_.size()));
156 m_inst->indices.push_back(mesh_transforms_.size());
160 NonmeshInstance *nm_inst = nonmesh_instance(p_id);
165 ID_LOG(2,
"Nonmesh %s %d", nm_inst->data->id->name,
int(nm_inst->transforms.size()));
174 pxr::SdfPath h_id = hair_prim_id(
object, psys);
175 NonmeshInstance *nm_inst = nonmesh_instance(h_id);
178 nm_inst->data = std::make_unique<HairData>(
scene_delegate_,
object, h_id, psys);
179 nm_inst->data->init();
181 ID_LOG(2,
"Nonmesh %s %d", nm_inst->data->id->name,
int(nm_inst->transforms.size()));
191 mesh_instances_.
remove_if([&](
auto item) {
192 bool res = item.value.indices.empty();
194 item.value.data->remove();
200 for (
auto &l_inst : nonmesh_instances_.
values()) {
201 update_nonmesh_instance(l_inst);
203 nonmesh_instances_.
remove_if([&](
auto item) {
return item.value.transforms.empty(); });
210 index.RemoveInstancer(
prim_id);
211 ID_LOG(1,
"Remove instancer");
215 if (index.HasInstancer(
prim_id)) {
216 index.GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
217 ID_LOG(1,
"Update instancer");
221 ID_LOG(1,
"Insert instancer");
226pxr::SdfPath InstancerData::object_prim_id(
Object *
object)
const
231 return prim_id.AppendElementString(name);
238 SNPRINTF(name,
"%s_PS_%p", object_prim_id(parent_obj).GetName().c_str(), psys);
239 return prim_id.AppendElementString(name);
242pxr::SdfPath InstancerData::nonmesh_prim_id(pxr::SdfPath
const &prim_id,
int index)
const
246 return prim_id.AppendElementString(name);
249int InstancerData::nonmesh_prim_id_index(pxr::SdfPath
const &
id)
const
252 sscanf(
id.GetName().c_str(),
"NM_%d", &index);
256void InstancerData::update_nonmesh_instance(NonmeshInstance &nm_inst)
258 ObjectData *obj_data = nm_inst.data.get();
259 pxr::SdfPath prev_id = nm_inst.data->prim_id;
263 while (nm_inst.count > nm_inst.transforms.size()) {
265 obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
272 if (l_data && l_data->prim_type((
Light *)((
Object *)l_data->id)->data) != l_data->prim_type_) {
273 for (i = 0; i < nm_inst.count; ++i) {
274 obj_data->prim_id = nonmesh_prim_id(prev_id, i);
278 for (i = 0; i < nm_inst.count; ++i) {
279 obj_data->prim_id = nonmesh_prim_id(prev_id, i);
284 for (i = 0; i < nm_inst.count; ++i) {
285 obj_data->prim_id = nonmesh_prim_id(prev_id, i);
291 while (nm_inst.count < nm_inst.transforms.size()) {
292 obj_data->prim_id = nonmesh_prim_id(prev_id, nm_inst.count);
297 obj_data->prim_id = prev_id;
300InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath
const &
id)
const
302 auto m_inst = mesh_instances_.
lookup_ptr(
id.GetPathElementCount() == 4 ?
id.GetParentPath() :
307 return const_cast<MeshInstance *
>(m_inst);
310InstancerData::NonmeshInstance *InstancerData::nonmesh_instance(pxr::SdfPath
const &
id)
const
312 auto nm_inst = nonmesh_instances_.
lookup_ptr(
id.GetPathElementCount() == 4 ?
id.GetParentPath() :
317 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_INFO(clg_ref, level,...)
const Value * lookup_ptr(const Key &key) const
Value & lookup_or_add_default(const Key &key)
ValueIterator values() const
int64_t remove_if(Predicate &&predicate)
static bool is_supported(const ParticleSystem *particle_system)
static bool is_visible(HydraSceneDelegate *scene_delegate, Object *object, ParticleSystem *particle_system)
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)
#define ID_LOG(level, msg,...)
struct CLG_LogRef * LOG_HYDRA_SCENE
pxr::GfMatrix4d gf_matrix_from_transform(const float m[4][4])