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
Exemplo n.º 2
0
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))
Exemplo n.º 3
0
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)