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

can sverchok create custom vertex connectors like grasshopper from an existing mesh? #2362

Closed
rvisani opened this issue Feb 5, 2019 · 13 comments

Comments

@rvisani
Copy link

rvisani commented Feb 5, 2019

Problem statement

Can sverchok create custom vertex connectors like grasshopper from an existing mesh?

Please describe your problem here.
I am trying to create custom connectors which would describe the verticies in low poly meshes that I have designed in blender. They would connect to linear material which would correspond to the edges of the mesh. I know of similar work being done with Grasshopper, which led me to sverchok. Does sverchok have this capability. I've attached a sample mesh, as well as examples of the grasshopper generated connectors.

nodes_ae_04

capture

Expected result

What did you expect to see as a result of those steps?

Actual result

What did you actually get?

Sverchok version

This is especially important for installation-related issues. Please specify how do you install Sverchok: from sverchok-master.zip from github, or from release zip file, or from cloned git repo.

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

hopefully i'm interpreting the question accurately,.

you want to feed sverchok an arbitrary edge-based mesh, as shown in your screenshot, and ask sverchok to generate these 'connectors' with holes of a certain diameter. For 3d printing and reconstructing a model with sticks of some kind?

we don't yet have a node that spits out the geometry of such connectors. (that's not to say that it isn't possible)

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

there are a few ways to approach this:

    • use metaballs, arrange numerous metaballs at each vertex, to shape the connector
    • convert metaballs to real mesh, maybe subdiv the result
    • boolean subtract the 'edge' geometry
    • separate all geometry to individual units (like a separate loose)
    • automatically rearrange/transform resulting geometry to a plane appropriate for 3d printing
    • use skin modifier, arrange multiple new vertices at each vertex, to shape the connector
    • subdiv mesh
    • boolean subtract the 'edge' geometry ...
    • the rest is same as 1.
    • devise a function that accepts parameters and produce this arithmetically (probably most satisfying to do )
    def generate_connector_geom(vertex_prime, vertex_ring, connector_radius. stick_radius):
        """
        - vertex_prime is p, 
        - vertex_ring are all vertices associated with the edges attached to vertex_prime
        - connector radius, the span of the geometry from the point p
        - stick radius, the size of the opening at the ends of the connector
         r1  ----------  p  ----------- r2
                         |
                        r3 
        """
        return verts, faces

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

image

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

metaballs

some metaball tweaking
image

i can't remember if this is available in Sverchok for 2.79 . I also don't advise yet to use Sverchok in 2.80 (but that's what i'm using as a developer)

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

here i space out the metaballs a bit to give a sense of how it's built up
image

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

and this shows with less stiffness
image

I think i'd not use metaballs, but try skin mesher node..

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

SkinMesher node

this is a little more involved, because you must supply both the vertices and the edges

@zeffii
Copy link
Collaborator

zeffii commented Feb 5, 2019

image

"""
in verts v
in edges s
in radius s d=0.3 n=2
out overts v
out ofaces s
out oedges s
"""

from mathutils import Vector
from collections import defaultdict

for obj in zip(verts, edges):
    overts.append([])
    ofaces.append([])
    oedges.append([])
    new_verts = overts[-1]
    new_faces = ofaces[-1]
    new_edges = oedges[-1]
    vert_list, edge_list = obj
    
    connection_dict = defaultdict(set)

    for edge in edge_list:
        sx = sorted(list(edge))
        connection_dict[sx[0]].add(sx[1])
        connection_dict[sx[1]].add(sx[0])

    for idx1, idx_set in connection_dict.items():     

        # gather vertex prime
        vec1 = Vector(vert_list[idx1]) 
        new_verts.append(vert_list[idx1])
        
        start_idx = len(new_verts) - 1 
        
        # gather vertex radials
        for offset, idx2 in enumerate(idx_set):
            vec2 = Vector(vert_list[idx2])
            rate = radius / (vec1-vec2).length

            new_vtx = vec1.lerp(vec2, rate)[:]
            new_verts.append(new_vtx)
        
            new_edges.append([start_idx, start_idx + offset + 1])

@rvisani
Copy link
Author

rvisani commented Feb 5, 2019

Thanks for the info zeffii! I'm new to nodes and sverchok so it may take a few attempts before I work thru this, but based on what you are showing me it should work for my purposes.

@zeffii
Copy link
Collaborator

zeffii commented Feb 6, 2019

while not optimal, the metaball approach is still pretty fast. the SN:

"""
in verts v
in edges s
in radius s d=0.3 n=2
out overts v
out ofaces s
out oedges s
"""

from collections import defaultdict
from itertools import permutations 

from mathutils import Vector
from mathutils.geometry import interpolate_bezier as bezlerp

def make_arc(prime, vtx1, vtx2, num_verts=22):
    ctrl_1 = ctrl_2 = prime
    knot1 = vtx1
    knot2 = vtx2
    verts = bezlerp(knot1, ctrl_1, ctrl_2, knot2, num_verts)
    return [v[:] for v in verts[1:-1]]
    


for obj in zip(verts, edges):
    overts.append([])
    ofaces.append([])
    oedges.append([])
    new_verts = overts[-1]
    new_faces = ofaces[-1]
    new_edges = oedges[-1]
    vert_list, edge_list = obj
    
    connection_dict = defaultdict(set)

    for edge in edge_list:
        sx = sorted(list(edge))
        connection_dict[sx[0]].add(sx[1])
        connection_dict[sx[1]].add(sx[0])

    for idx1, idx_set in connection_dict.items():

        # gather vertex prime
        vec1 = Vector(vert_list[idx1]) 
        new_verts.append(vert_list[idx1])
        
        start_idx = len(new_verts) - 1 
        
        # gather vertex radials
        for offset, idx2 in enumerate(idx_set):
            vec2 = Vector(vert_list[idx2])
            rate = radius / (vec1-vec2).length

            new_vtx = vec1.lerp(vec2, rate)[:]
            new_verts.append(new_vtx)
        
            new_edges.append([start_idx, start_idx + offset + 1])

    for idx1, idx_set in connection_dict.items():
        perm = permutations(idx_set, 2)
        prime = Vector(vert_list[idx1])

        for p1, p2 in perm:

            vec1 = Vector(vert_list[p1])
            vec2 = Vector(vert_list[p2])
            rate = radius / (prime-vec1).length
            vtx1 = prime.lerp(vec1, rate)[:]
            rate = radius / (prime-vec2).length
            vtx2 = prime.lerp(vec2, rate)[:]
                        
            arc_vecs = make_arc(prime, vtx1, vtx2)
            new_verts.extend(arc_vecs)

this version would generate an arc between all permutations of the edges attached to each vertex, adding structural rigidity
image

under the hood that looks like this:
image

@vicdoval
Copy link
Collaborator

vicdoval commented Feb 8, 2019

This can work too.
Using this SNLite #2362 (comment) and a monad to convert edges to capsule metaballs
conectors.zip
conectors1
Final boolean subtraction done with blender modifiers

@nortikin
Copy link
Owner

@Heinz-Loepmeier
Copy link

Blendersushi posted something similar.
enzyme69/blendersushi#367

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

5 participants