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

dict_to_path is broken for Line objects #2303

Open
Tomaubier opened this issue Oct 16, 2024 · 0 comments
Open

dict_to_path is broken for Line objects #2303

Tomaubier opened this issue Oct 16, 2024 · 0 comments

Comments

@Tomaubier
Copy link

Currently working with the dict_to_path function to generate parametric meshes from dictionaries, I ran across a bug where passing Line objects raises AttributeError: property 'closed' of 'Line' object has no setter.
I managed to find a patch consisting in checking the entity type and forwarding the closedargument accordingly.

import trimesh

def dict_to_path_patched(as_dict):
    """
    Turn a pure dict into a dict containing entity objects that
    can be sent directly to a Path constructor.

    Parameters
    ------------
    as_dict : dict
      Has keys: 'vertices', 'entities'

    Returns
    ------------
    kwargs : dict
      Has keys: 'vertices', 'entities'
    """
    # start kwargs with initial value
    result = as_dict.copy()
    # map of constructors
    loaders = {"Arc": trimesh.path.entities.Arc, "Line": trimesh.path.entities.Line}
    # pre- allocate entity array
    entities = [None] * len(as_dict["entities"])
    # run constructor for dict kwargs
    for entity_index, entity in enumerate(as_dict["entities"]):

        # --- start of edited section ---

        if entity["type"] == 'Line':
            entities[entity_index] = loaders[entity["type"]](
                points=entity["points"]
            )
        else:
            entities[entity_index] = loaders[entity["type"]](
                points=entity["points"], closed=entity["closed"]
            )

        # --- end of edited section ---
        # --- start of original section ---

        entities[entity_index] = loaders[entity["type"]](
            points=entity["points"], closed=entity["closed"]
        )

        # --- end of original section ---

    result["entities"] = entities

    return result

Here is minimum working example demonstrating the issue and the proposed fix.

x, y, z = 2, 3, 5

path_2d_dict = {
    'entities': [
        {'type': 'Line', 'points': [0, 1, 2, 3, 0], 'closed': False},
        ],
    'vertices': [
        [-x/2, y/2],
        [x/2, y/2],
        [x/2, -y/2],
        [-x/2, -y/2],
    ]
}

path_2d_from_dict = trimesh.path.exchange.load.load_path(
    trimesh.path.exchange.misc.dict_to_path(path_2d_dict) # Default function -> raises AttributeError: property 'closed' of 'Line' object has no setter
    # dict_to_path_patched(path_2d_dict) # Patched function -> Works as expected
)

path_2d_from_dict.show()

Also removing closed: False from the entities list ('entities': [{'type': 'Line', 'points': [0, 1, 2, 3, 0]}],) raises KeyError: 'closed'.

System infos

  • Python 3.13.0
  • trimesh 4.5.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant