Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Texture Preservation in Open3D for Merging Meshes #7092

Open
3 tasks done
daddo-intel opened this issue Dec 11, 2024 · 1 comment
Open
3 tasks done

Texture Preservation in Open3D for Merging Meshes #7092

daddo-intel opened this issue Dec 11, 2024 · 1 comment
Assignees

Comments

@daddo-intel
Copy link

daddo-intel commented Dec 11, 2024

Checklist

Proposed new feature or change

to support merging meshes while preserving textures so we don’t have to depend on trimesh

References

MergeMesh.zip

Additional information

No response

@ssheorey
Copy link
Member

Test code from zip file pasted here:

import argparse
import trimesh

def build_argparser():
    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument("glb", help=".glb file")
    return parser

def get_albedo_texture(mesh):
    """
    Extracts the albedo texture from the mesh, if available.
    """
    albedo_texture = None
    if 'materials' in mesh.metadata:
        for material in mesh.metadata['materials']:
            if 'baseColorTexture' in material:
                albedo_texture = material['baseColorTexture']
                break 
    return albedo_texture

def get_cumulative_transform(graph, node_name, visited_nodes):
    """
    Compute the cumulative transformation for a node by traversing
    its parent nodes in the scene graph.
    """
    transform = trimesh.transformations.identity_matrix()
    current_node = node_name

    if current_node not in visited_nodes:
        if current_node not in graph.nodes:
            raise ValueError(f"Node {current_node} not found in graph.")
        
        # Get node data: (matrix, parent)
        node_data = graph[current_node]
        if not isinstance(node_data, tuple) or len(node_data) != 2:
            raise ValueError(f"Node data for {current_node} is invalid: {node_data}")
        
        matrix, parent = node_data
        print(f"Applying transform for {current_node}: {matrix}")
        
        transform = matrix @ transform  # Apply current node's transformation
        visited_nodes.add(current_node)  # Mark this node as visited
        
        current_node = parent  # Move to the parent node
    
    return transform

# Main script
args = build_argparser().parse_args()

scene = trimesh.load(args.glb)

# Create a list to store transformed meshes
transformed_meshes = []
visited_nodes = set()

#scene.geometry.items(),  scene.graph.nodes, scene.graph.nodes_geometry
for geometry_name, mesh in scene.geometry.items():
    # Convert dict_keys to a list to avoid 'dict_keys' object not subscriptable error
    # Iterate through all nodes to find those referencing this geometry
    for node_name in scene.graph.nodes:
        node_data = scene.graph[node_name]
        if not isinstance(node_data, tuple) or len(node_data) != 2:
            continue  # Skip invalid nodes
        # Check if this node references the current geometry

        for item in scene.graph.nodes_geometry:
            if item == node_name:
                if node_name == scene.graph.geometry_nodes[geometry_name][0]:
                    transform = get_cumulative_transform(scene.graph, node_name, visited_nodes)
                    transformed_mesh = mesh.copy()
                    transformed_mesh.apply_transform(transform)
                    if 'materials' in mesh.metadata:
                        transformed_mesh.metadata['materials'] = mesh.metadata['materials']
                    
                    # Extract albedo texture if available
                    albedo_texture = get_albedo_texture(mesh)
                    if albedo_texture:
                        print(f"Found albedo texture for {geometry_name}: {albedo_texture}")
                        transformed_mesh.metadata['albedo_texture'] = albedo_texture
                    transformed_meshes.append(transformed_mesh)

# Merge all the transformed meshes into one
merged_mesh = trimesh.util.concatenate(transformed_meshes)
merged_mesh.metadata["name"] = "mesh_0"

# Export the merged mesh while preserving the rotation
merged_mesh.export("merged_mesh.glb")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants