I would like to automate this and not have to manually select the first and second solid. To do this, I need to determine which of the two solids has the tenon. I was thinking of getting the intersection of the two solid’s bounding box and then take all the vertices of the component and see how many are positioned in the intersecting bounding box. The solid with the most is (likely) the tenon.
If I understand right, you want to select both components and automatically assign the roles “mortise” and “tenon” instead of selecting them in a fixed order?
This is heuristic. There is no rule that guarantees it will always work (an imaginary malicious opponent would always find a shape on 3D Warehouse for which this approach fails). There would be more constraints necessary to ensure the two components constitute a “mortise and tenon” problem.
Since you just want some automation and we can make assumptions about your components (like they are box-like and the bounding box is aligned), a simple solution should be enough.
A possible rule is “the component that is the tenon protrudes into the other one’s volume”.
However both components’ bounding boxes can equally protrude each other (since they are boxes).
Vertices may be at the boundary of a bounding box (if the tenon protrudes totally through the mortise).
We can assume the mortise is mostly a box, and the tenon is the more complex shape (more faces, vertices).
The tenon has some faces that are mostly inside the volume of the mortise.
I would test for each face inside component 1, whether there exists one whose bounding box is contained within the bounding box of component 2. If yes, then component 1 is the tenon, otherwise try vice-versa.
In the domain in which this will be used (Timber Framing Design), the basic shapes would pretty much guarantee the heuristic will work as planned. All of the “timbers” are polygon cylinders (usually with rectangular bases). Tenon’s are only on one or both ends (bases of the cylinder) and mortises are located on the longer faces of the cylinder.
Your algorithm has merit and I think I’ll compare it to one I’ve already implemented. Currently, I identify the intersecting bounding box between the two timbers. By counting the number of vertices included by each timber, I’ve been able to reliably identify the one thats (probably) the tenon. I can then use the the ComponentInstance intersect() method to magically create the mortise in the non-tenon timber. Changing the algorithm to count the faces instead might give a performance improvement (but I’ll have to profile my implementation first).
I really appreciate your thoughtful reply, Aerilius!