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

Feature Request: Connectors #16

Open
mrsimicsak opened this issue Jun 10, 2020 · 7 comments
Open

Feature Request: Connectors #16

mrsimicsak opened this issue Jun 10, 2020 · 7 comments

Comments

@mrsimicsak
Copy link

I'm trying to use your library to design a laser cutter and it would be really helpful if I could add "connectors" to parts and then call a function to connect them together. Basically something like this as discussed here.

The general idea being to store a collection of locations and orientations with each object that get changed as object does so that the locations and orientations remain fixed relative to the part. Then connecting two parts can be done by calculating the transform required to align the connector on the second part with the connector on the first part and applying the transform to the second part.

I made a couple attempts at adding connectors myself but I couldn't figure out how to do it without major changes to the API. I'm new to golang which doesn't help.

I had a little bit of success by storing the connectors separately and creating a transform function that could take a map of connectors in addition to the SDF, but handling the connectors separately would quickly become tedious.

If you could point me in the direction of the best way to store a map[string]Connector with the SDF, I'll take a stab at implementing the rest of it myself.

@deadsy
Copy link
Owner

deadsy commented Jun 10, 2020

Interesting - I see the need. I've mostly focused on single parts rather than assemblies, so I haven't though to generalise the connect and orient problem. Two problems: 1) Add attachment points to an SDF. 2) connect the SDFs with attachment points. I think I'd handle it the same way I do Union3D or meta things like that. ie- Attach3D takes and SDF and a slice of attachments, and then Connect3D takes a slice (2?) of SDFs (with attachments) and returns an SDF that has them oriented wrt one another. AS you indicate, naming the attachment points is probably necessary given that a given attachable SDF may have more than one attach point.

@deadsy
Copy link
Owner

deadsy commented Jun 10, 2020

There's an open question: - the (position, vector, angle) tuple for a connection point will be overconstrained in many cases. E.g. 3-links connected as a triangle. There may be 0 solutions generally (a + b < c), or even 0 specifically given the value of the connection constraints. How do you deal with that?

@mrsimicsak
Copy link
Author

I was thinking the "Connect" function would only connect two parts, and only accept 1 connector per part. The transform to connect the two parts would only be applied to the second part. Once connected the two parts would be treated as a single part.

If an assembly is passed to the "Connect" function it would be treated as a single part.

The "Connect" function definition would look something like this:

func (*SDF SDF3) Connect3d (parent SDF3, parentConnectorName string, child SDF3, childConnectorName string, offsetPosition V3, offsetRotation R3) SDF3

(I think of a parts orientation as being a rotation value for each of x,y,z, which is what R3 represents above)

I'm debating if the "Connect" function should actually union the parts after applying the transform.

@deadsy
Copy link
Owner

deadsy commented Jun 11, 2020

To be useful you need more than one attachment point per SDF. E.g. imagine you wanted to draw molecules. You would need 4 points for a carbon atom with single bonds. You could punt on the constraint problem. ie- you just assume that the connection graph is a DAG from root part to leaf parts. It's down to the user to set the constraints properly to ensure that the ends meet up if the parts actually connect back to one another.

func (s *SDF) AddConnector(name, point, vector, angle) SDF
func (s *SDF) Connect(child SDF, childName, parentName string) SDF

Having connected multiple parts you may then wish to add connections to the assemblage so it can be connected at a higher level in the herarchy. Some of the connectors from the lower level may be made available for connections at a higher level. (E.g. dangling bonds for molecular components)

Maybe:
func (s *SDF) ExportConnector(child SDF, chilName string) SDF

API wise it might be easier if a "connector" was it's own type that bundled the SDF with point, vector and angle.

BTW - the original attach/connect nomenclature is confusing because they are both verbs that mean the same thing. I think connector/connect (noun/verb) is better.

I'm debating if the "Connect" function should actually union the parts after applying the transform.

Connect is effectively a union operator that transforms it's sub-elements before doing the union. The assumption is that it returns an SDF that works like a normal SDF.

@mrsimicsak
Copy link
Author

I've put together a rough draft of a connector implementation: mrsimicsak@47486fa

It currently handles enabling connectors, adding connectors and joining two SDFs based upon the position part of the connector..

At the moment it discards any connectors on the child, which I will fix once I sort out the complexities of dealing with connector identities once multiple parts have been joined.

I think if an SDF to which connectors have been added is passed to one of the existing operations (transform, union, etc) the connectors will be lost. Which means that connectors have to added last and once connectors are added the SDF can only be used to connect to other things. I think that is too much of a limitation. The only way I can see to fix it is to add connector functionality to the SDF interface and then add code to all existing operations to support Connectors.

Do you see a better way to get around the limitation?

Would you accept a pull request that modifies the SDF interface to added connectors?

@deadsy
Copy link
Owner

deadsy commented Jul 30, 2020 via email

@stevegt
Copy link
Contributor

stevegt commented Feb 20, 2021

Thinking to have a go at this, but before I dive into connectors, I have to ask -- would a "constraints" implementation be a more general way of implementing connectors as well as provide more flexibility, possibly even support motion simulations? Still thinking about that, but for now, just looking at a simple connectors implementation:

The connected assembly is really just a fancy union. The assembly is specified by a DAG. Each node of the DAG is a connector (position, vector, angle) with an associated SDF3. When you go to build the full sdf3 you visit each node and create the union as you go. At the root of the DAG you have your full SDF3 which you can either render or plug into something else that wants an SDF3.

I'm finally grokking this well enough to say that I think this is closer to the right approach. If connectors are all we want, then I would move the connector data out of the mrsimicsak@47486fa SDF3WithConnectors.connectors map into a DAG, where an edge is a connector and a node is an SDF3 object. Get rid of the UnionConnectorizedSDF3 struct and its methods; just traverse the DAG to build a temporary union immediately before rendering.

I'm thinking an edge could be as simple as:

type Connector struct {
    Tail        SDF3 
    Head        SDF3
    // Translate and Transform are relative to Tail's reference frame, 
    // and describe the origin and transformation of Head.
    Translate   V3 
    Transform   M44
}

This simple edge struct doesn't support the named connectors from mrsimicsak@47486fa, but could be improved and would at least support something like this:


                                                    .------.
                                         .----------| case |--------.
                                         |          '------'        |
                                         |              |           |
                                         |              |           |
                                         |              |           |
                                         v              v           v
                                  .-------------.   .-------.   .-------.
                                  |    front    |   | main  |   | power |
                                  |    panel    |   | board |   | jack  |
                                  '-------------'   '-------'   '-------'
                                         |              |
                                         v              v
                                     .------.     .----------.
                                     | knob |     | daughter |
                                     '------'     |  board   |
                                                  '----------'

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

3 participants