CadQuery / CadQuery/cadquery

Enhancements for Assemblies

Open
#522 13 comments 2 reactions 0 assignees View on GitHub
assembly enhancement
Dominant language
Python
Stars
5.8k
Forks
541
Avg merge
3d 2h
Merged PRs (30d)
5

Description

As discussed in https://github.com/bernhard-42/jupyter-cadquery/issues/23 I had added some enhancements to Assemblies which might be helpful for cadquery:

## 1 Enhancements
### 1.1 Chained assembly selectors "name1>name2>name3"

**Problem:** Using the same assemblies several times in an assembly

Simplified example [full code](https://github.com/bernhard-42/jupyter-cadquery/blob/master/examples/assemblies/2-hexapod.ipynb):

```python
# Assembly 1: The leg
leg = Assembly(upper_leg, name="upper").add(lower_leg, name="lower")

# Assembly 2: The six legged Hexapod
hexapod = (Assembly(base, name="bottom"))
for name in ['right_back', 'right_middle', 'right_front', 'left_back', 'left_middle', 'left_front']:
hexapod.add(leg, name=name)
```

Now `hexapod.objects` only has one `lower` element:

```
{'bottom': ,
'right_back': ,
'upper': ,
'lower': ,
'right_middle': ,
'right_front': ,
'left_back': ,
'left_middle': ,
'left_front': }
```

If you need to select the `lower` leg of the left back leg (e.g. to assemble yet another object), it doesn't seem to be obvious.

**Solution approach:** I enhanced the assembly selector to support the chain `bottom>right_back>lower` or, because it's also unique, `right_back>lower`. In `MAssembly` this is done via [this function](https://github.com/bernhard-42/jupyter-cadquery/blob/e14f316dd9384f0586e21c5fdfa46f1d8931f697/jupyter_cadquery/mate_assembly/massembly.py#L53-L75)

### 1.2 Chaining object selectors

**Problem**: Many times one selects components via a chain, e.g. `cad_obj.faces(">Z").edges(">X")`. I did not see a way to do this via `"obj_name?tag1@faces@>Z"` query

**Solution Approach**: Besides string queries also allow tuple queries like `("obj_name?tag", "faces@>Z")` and allow more than one object selector, e.g.: `("obj_name?tag", "faces@>Z", "edges@>Y")`.
Note: `"obj_name?tag1@faces@>Z"` and `("obj_name?tag", "faces@>Z")` lead to the same result.

Of course, one could also use e.g. `obj_name?tag1@faces@>Z@@edges@>X`, but for me this seems to be harder to read and I anyhow needed the tuple selector for problem 3

### 1.3 Selecting one of several holes on a face

**Problem**: If you have e.g. several holes on a face and want to select a specific one, the only way that came to my mind was to use the `NearestToPointSelector`. But I wanted to use that with a simple query again.

**Solution approach:** Given the tuple query from above, I defined a new pattern: `("wires", (x,y))`. This allowed me to do

```python
for coord_2d in hole_coords:
sel = ("obj_name?tag", "faces@>Z", ("wires", coord_2d))
...
```

In `MAssembly` 1.2 and 1.3 are implemented with [these functions](https://github.com/bernhard-42/jupyter-cadquery/blob/e14f316dd9384f0586e21c5fdfa46f1d8931f697/jupyter_cadquery/mate_assembly/massembly.py#L77-L138), however, currently without tag support.

## 2 Questions

1) What is your take on my 3 problems. Do you see easier solutions already with the existing Assembly selectors?

2) Would you be interested in a PR to solve these three problems (assuming there is no simple solution at the moment)

3) The classes `MAssembly` and `Mate` are a little bit of aliens in my CAD viewer repo. Since the `Massembly` approach is based on `cq.Assembly` would you be interested in a PR to add the property `mates` and the methods [mate()](https://github.com/bernhard-42/jupyter-cadquery/blob/e14f316dd9384f0586e21c5fdfa46f1d8931f697/jupyter_cadquery/mate_assembly/massembly.py#L140-L155), [assemble()](https://github.com/bernhard-42/jupyter-cadquery/blob/e14f316dd9384f0586e21c5fdfa46f1d8931f697/jupyter_cadquery/mate_assembly/massembly.py#L177-L190) to `cq.Assemblies` (both methods have 8 lines of code each) and of course the [Mate](https://github.com/bernhard-42/jupyter-cadquery/blob/e14f316dd9384f0586e21c5fdfa46f1d8931f697/jupyter_cadquery/mate_assembly/mate.py) class?
This would add a static assembly approach (similar to cqparts and Assembly4 of FreeCad) parallel to your dynamic solver.

4) If you would add the `MAssembly` functionality to `cq.Assembly`, would it be OK to support the `origin` property that holds the origin mate of an Assembly, even if this is only necessary for jupyter_cadquery? Otherwise I would need to monkey-patch CadQuery for origin support.
The `relocate()` functions could be omitted, since they are only necessary for the animations system in jupyter-cadquery.

These are just a few ideas being developed while learning about assemblies and I would be happy to contribute some stuff to CadQuery if you are interested ...

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.