Skip to content

Commit

Permalink
Getting started with pytests with onshape URLS
Browse files Browse the repository at this point in the history
  • Loading branch information
senthurayyappan committed Dec 10, 2024
1 parent 9eb6aa4 commit 1e22756
Show file tree
Hide file tree
Showing 9 changed files with 2,434 additions and 3 deletions.
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -165,16 +165,26 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
poetry.lock

examples/**/*.urdf
examples/**/*.stl
examples/**/*.png
examples/**/*.prof
examples/**/*.json

onshape_api/data/**/*.json
onshape_api/data/**/*.parquet

benchmark/**/*.urdf
benchmark/**/*.stl
benchmark/**/*.png
benchmark/**/*.prof
benchmark/**/*.json

tests/**/*.urdf
tests/**/*.stl
tests/**/*.png
tests/**/*.prof
tests/**/*.json

playground
4 changes: 2 additions & 2 deletions examples/export/robots.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# ballbot = https://cad.onshape.com/documents/1f42f849180e6e5c9abfce52/w/0c00b6520fac5fada24b2104/e/c96b40ef586e60c182f41d29

document = Document.from_url(
"https://cad.onshape.com/documents/12124a46ebda8f31ccfe8c8f/w/820e30e034d40fc174232361/e/54c32b7d2abd32b9bf6d9641"
"https://cad.onshape.com/documents/1f42f849180e6e5c9abfce52/w/0c00b6520fac5fada24b2104/e/c96b40ef586e60c182f41d29"
)
assembly, _ = client.get_assembly(
did=document.did,
Expand All @@ -47,7 +47,7 @@
instances=instances,
parts=parts,
mates=mates,
use_user_defined_root=True,
use_user_defined_root=False,
)
plot_graph(graph, f"{assembly_robot_name}.png")

Expand Down
80 changes: 80 additions & 0 deletions onshape_api/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,86 @@ def get_instances(
return instance_map, occurrence_map, id_to_name_map


def get_instances_sync(
assembly: Assembly, max_depth: int = 5
) -> tuple[dict[str, Union[PartInstance, AssemblyInstance]], dict[str, Occurrence], dict[str, str]]:
"""
Get instances and their sanitized names from an Onshape assembly.
Args:
assembly: The Onshape assembly object to use for extracting instances.
max_depth: Maximum depth to traverse in the assembly hierarchy. Default is 5
Returns:
A tuple containing:
- A dictionary mapping instance IDs to their corresponding instances.
- A dictionary mapping instance IDs to their sanitized names.
Examples:
>>> assembly = Assembly(...)
>>> get_instances(assembly, max_depth=2)
(
{
"part1": PartInstance(...),
"subassembly1": AssemblyInstance(...),
},
{
"part1": "part1",
"subassembly1": "subassembly1",
}
)
"""

def traverse_instances(
root: Union[RootAssembly, SubAssembly], prefix: str = "", current_depth: int = 0
) -> tuple[dict[str, Union[PartInstance, AssemblyInstance]], dict[str, str]]:
"""
Traverse the assembly structure to get instances.
Args:
root: Root assembly or subassembly object to traverse.
prefix: Prefix for the instance ID.
current_depth: Current depth in the assembly hierarchy.
Returns:
A tuple containing:
- A dictionary mapping instance IDs to their corresponding instances.
- A dictionary mapping instance IDs to their sanitized names.
"""
instance_map = {}
id_to_name_map = {}

# Stop traversing if the maximum depth is reached
if current_depth >= max_depth:
LOGGER.debug(f"Max depth {max_depth} reached. Stopping traversal at depth {current_depth}.")
return instance_map, id_to_name_map

for instance in root.instances:
sanitized_name = get_sanitized_name(instance.name)
LOGGER.debug(f"Parsing instance: {sanitized_name}")
instance_id = f"{prefix}{SUBASSEMBLY_JOINER}{sanitized_name}" if prefix else sanitized_name
id_to_name_map[instance.id] = sanitized_name
instance_map[instance_id] = instance

# Recursively process sub-assemblies if applicable
if instance.type == InstanceType.ASSEMBLY:
for sub_assembly in assembly.subAssemblies:
if sub_assembly.uid == instance.uid:
sub_instance_map, sub_id_to_name_map = traverse_instances(
sub_assembly, instance_id, current_depth + 1
)
instance_map.update(sub_instance_map)
id_to_name_map.update(sub_id_to_name_map)

return instance_map, id_to_name_map

instance_map, id_to_name_map = traverse_instances(assembly.rootAssembly)
# return occurrences internally as it relies on max_depth
occurrence_map = get_occurrences(assembly, id_to_name_map, max_depth)

return instance_map, occurrence_map, id_to_name_map


def get_occurrences(assembly: Assembly, id_to_name_map: dict[str, str], max_depth: int = 5) -> dict[str, Occurrence]:
"""
Optimized occurrences fetching using comprehensions.
Expand Down
Loading

0 comments on commit 1e22756

Please sign in to comment.