def sync_update(rpr_context, obj: bpy.types.Object, is_updated_geometry, is_updated_transform, **kwargs): if not (IS_WIN or IS_MAC): return obj_key = object.key(obj) rpr_mesh = rpr_context.objects.get(obj_key, None) if not rpr_mesh: # no such mesh with volume => creating mesh with volume sync(rpr_context, obj, **kwargs) return True material_data = get_material_data(rpr_context, obj) rpr_volume = rpr_context.volumes[key(obj)] emission_changed = ('emission' in rpr_volume.grids) == is_zero( material_data['emission_color']) if is_updated_geometry or emission_changed: # mesh exists, but its settings were changed => recreating mesh with volume rpr_context.remove_object(obj_key) sync(rpr_context, obj, **kwargs) return True if is_updated_transform: # updating only mesh and volume transform transform = get_transform(obj) rpr_mesh.set_transform(transform) rpr_volume.set_transform(transform) assign_material(rpr_volume, material_data) return True
def assign_material(rpr_volume, material_data): d = material_data['density'] rpr_volume.set_lookup('density', np.array([0.0, 0.0, 0.0, d, d, d], dtype=np.float32).reshape(-1, 3)) color = material_data['color'] rpr_volume.set_lookup('albedo', np.array([0.0, 0.0, 0.0, *color], dtype=np.float32).reshape(-1, 3)) emission_color = material_data['emission_color'] if not is_zero(emission_color): rpr_volume.set_lookup('emission', np.array([0.0, 0.0, 0.0, *emission_color], dtype=np.float32).reshape(-1, 3))
def sync(rpr_context, obj: bpy.types.Object): """ sync any volume attached to the object. Note that volumes don't currently use motion blur """ # find the smoke modifier smoke_modifier = get_smoke_modifier(obj) if not smoke_modifier: return log("sync", smoke_modifier, obj) domain = smoke_modifier.domain_settings if len(domain.color_grid) == 0: # empty smoke. warn and return log.warn("Empty smoke domain", domain, smoke_modifier, obj) return # getting volume material volume_material = None if obj.material_slots and obj.material_slots[0].material: volume_material = material.sync(rpr_context, obj.material_slots[0].material, 'Volume') if not volume_material: log.warn("No volume material for smoke domain", obj) return data = volume_material.data # creating rpr_volume volume_key = key(obj, smoke_modifier) rpr_volume = rpr_context.create_hetero_volume(volume_key) rpr_volume.set_name(str(volume_key)) # getting smoke resolution and color_grid if BLENDER_VERSION >= '2.82': x, y, z = domain.domain_resolution else: amplify = domain.amplify if domain.use_high_resolution else 0 x, y, z = ((amplify + 1) * i for i in domain.domain_resolution) if domain.use_noise: # smoke noise upscale the basic domain resolution x, y, z = (domain.noise_scale * e for e in (x, y, z)) color_grid = get_prop_array_data(domain.color_grid).reshape(x, y, z, -1) # set albedo grid albedo_data = np.average(color_grid[:, :, :, :3], axis=3) albedo_grid = rpr_context.create_grid_from_3d_array( np.ascontiguousarray(albedo_data)) color = data['color'] albedo_lookup = np.array([0.0, 0.0, 0.0, *color], dtype=np.float32).reshape(-1, 3) rpr_volume.set_grid('albedo', albedo_grid) rpr_volume.set_lookup('albedo', albedo_lookup) # set density grid density_data = get_prop_array_data(domain.density_grid).reshape(x, y, z) density_grid = rpr_context.create_grid_from_3d_array( np.ascontiguousarray(density_data)) density = data['density'] density_lookup = np.array([0.0, 0.0, 0.0, density, density, density], dtype=np.float32).reshape(-1, 3) rpr_volume.set_grid('density', density_grid) rpr_volume.set_lookup('density', density_lookup) emission_color = data['emission_color'] if not is_zero(emission_color): # set emission grid emission_data = get_prop_array_data(domain.flame_grid).reshape(x, y, z) emission_grid = rpr_context.create_grid_from_3d_array( np.ascontiguousarray(emission_data)) emission_lookup = np.array([0.0, 0.0, 0.0, *emission_color], dtype=np.float32).reshape(-1, 3) rpr_volume.set_grid('emission', emission_grid) rpr_volume.set_lookup('emission', emission_lookup) # set volume transform rpr_volume.set_transform(get_transform(obj)) # attaching to scene and shape rpr_context.scene.attach(rpr_volume) rpr_obj = rpr_context.objects[object.key(obj)] rpr_obj.set_hetero_volume(rpr_volume)
def sync(rpr_context, obj: bpy.types.Object, **kwargs): if not (IS_WIN or IS_MAC): return # getting openvdb grid data volume = obj.data obj_key = object.key(obj) vdb_file = get_volume_file_path(volume, kwargs['frame_current']) if not vdb_file: # nothing to export return grids = helper_lib.vdb_read_grids_list(vdb_file) def get_rpr_grid(grid_name): if grid_name not in grids: return None data = helper_lib.vdb_read_grid_data(vdb_file, grid_name) values = data['values'] m = values.max() if m > 1.0: values /= m return rpr_context.create_grid_from_array_indices( *data['size'], values, data['indices']) material_data = get_material_data(rpr_context, obj) density_grid = get_rpr_grid(material_data['density_attr']) if not density_grid: log.warn(f"No '{material_data['density_attr']}' grid in {vdb_file}.", obj) return # creating hetero volume volume_key = key(obj) rpr_volume = rpr_context.create_hetero_volume(volume_key) rpr_volume.set_name(str(volume_key)) rpr_volume.set_grid('density', density_grid) rpr_volume.set_grid('albedo', density_grid) emission_color = material_data['emission_color'] if not is_zero(emission_color): emission_grid = density_grid if material_data['temperature_attr'] != material_data['density_attr']: emission_grid = get_rpr_grid(material_data['temperature_attr']) if not emission_grid: log.warn( f"No '{material_data['temperature_attr']}' grid in {vdb_file} for " f"emission, '{material_data['density_attr']}' grid will be used.", obj) emission_grid = density_grid rpr_volume.set_grid('emission', emission_grid) assign_material(rpr_volume, material_data) # creating bound box shape mesh_data = mesh.MeshData.init_from_shape_type('CUBE', 1.0, 1.0, 0) rpr_shape = rpr_context.create_mesh(obj_key, mesh_data.vertices, mesh_data.normals, mesh_data.uvs, mesh_data.vertex_indices, mesh_data.normal_indices, mesh_data.uv_indices, mesh_data.num_face_vertices) rpr_shape.set_name(obj.name) transform = get_transform(obj) rpr_shape.set_transform(transform) mat = rpr_context.create_material_node(pyrpr.MATERIAL_NODE_TRANSPARENT) mat.set_input(pyrpr.MATERIAL_INPUT_COLOR, (1.0, 1.0, 1.0)) rpr_shape.set_material(mat) rpr_context.scene.attach(rpr_shape) # attaching rpr_volume to rpr_shape rpr_volume.set_transform(transform) rpr_context.scene.attach(rpr_volume) rpr_shape.set_hetero_volume(rpr_volume)