Geometry Nodes

One question, attributes are only for vertex. Is there any plan to be able to use them in edges or faces?

Attributes can be stored on and converted between vertices, edges, polygons and corners

Thanks, I see that only is an option in some nodes, not in everyone.

I think nodes that create attributes have it, otherwise nodes that modify attributes don’t change the domain. This has to be done explicitly with a convert node. But then again we can do very little with edge and polygon attributes, since there are no modeling operators yet. Using them for shading, maybe ? I haven’t tested !

1 Like

Hey, I got some useful geonode python scripts to share

If anyone want a python script that cleanup all unused node path here is one.
i made a huge mastodon of a node with automated links with python and it clean everything up and re-arrange the whole tree quite well.

the re-arrange algorithm is a bit dumb, it only re-arrange nodes by spacing them evenly on the X axis but well it produces a clean result for a horizontal workflow.
See before/after operator below

If anyone is interested with this mastodon scattering node + interacting with python with the geonode you can check up the my commercial plugin project here

import bpy 

def is_node_used(node):
    """check if node is reaching output"""
            
    found_output = False
    
    def recur_node(n):
        #reached destination? 
        if n.type == "GROUP_OUTPUT":
            nonlocal found_output
            found_output = True
            return 
        #else continue recur
        for out in n.outputs:
            for link in out.links:
                recur_node(link.to_node)
        return 
        
    recur_node(node)
    return found_output



def purge_unused_nodes(node_group, delete_muted=True, delete_reroute=True, delete_frame=True, re_arrange=True):
    """delete all nodes not reaching output"""
    
    for n in node_group.nodes:
        #deselect all
        n.select = False
        #delete node if muted?
        if (delete_muted==True and n.mute==True):  
            n.select = True
            continue 
        #delete node if node is reroute?
        if (delete_reroute==True and n.type=="REROUTE"):
            n.select = True
            continue               
        #delete if frame?
        if (delete_frame==False and n.type=="FRAME"):
            continue 
        #delete if unconnected
        if not is_node_used(n):
            node_group.nodes.remove(n)
        continue 

    #delete from selection made above
    if delete_muted or delete_reroute:
        bpy.ops.node.delete_reconnect()
        
    return None 


def re_arrange_nodes(node_group, Xmultiplier=1):

    #sort all nodes by x location
    nodes = { n.location.x:n for n in node_group.nodes }
    nodes = { k:nodes[k] for k in sorted(nodes) }
    #rearrange nodes x location
    for i,n in enumerate(nodes.values()):
        n.location.x = i*200*Xmultiplier
        n.width = 150

    return None 



class EXAMPLE_OT_node_purge_unused(bpy.types.Operator):

    bl_idname      = "example.node_purge_unused"
    bl_label       = "Purge Unused Nodes"
    bl_description = ""
    bl_options     = {'INTERNAL', 'UNDO'}

    delete_frame   : bpy.props.BoolProperty(default=True, name="Remove Frame(s)",)
    delete_muted   : bpy.props.BoolProperty(default=True, name="Remove Muted Node(s)",)
    delete_reroute : bpy.props.BoolProperty(default=True, name="Remove Reroute(s)",)

    re_arrange :      bpy.props.BoolProperty(default=True, name="Re-Arrange Nodes",)
    re_arrange_fake : bpy.props.BoolProperty(default=False, name="Re-Arrange (not possible with frames)",)

    def execute(self, context):
        node_group = context.space_data.node_tree

        #Purge
        purge_unused_nodes(
            node_group, #Supossedly used from node editor only
            delete_muted=self.delete_muted,
            delete_reroute=self.delete_reroute,
            delete_frame=self.delete_frame,
            )

        #Re-Arrange
        if (self.re_arrange and self.delete_frame):
            re_arrange_nodes(node_group)

        return {'FINISHED'}


    def invoke(self, context, event):
        return bpy.context.window_manager.invoke_props_dialog(self)

    def draw(self, context):
        layout = self.layout 
        
        #Remove
        layout.prop(self, "delete_muted")
        layout.prop(self, "delete_reroute")
        layout.prop(self, "delete_frame")
        
        #Re-Arrange
        if self.delete_frame==True:    
            layout.prop(self, "re_arrange")
        else: 
            re = layout.row()
            re.enabled = False
            re.prop(self, "re_arrange_fake") #Props used just for GUI


def cleanup_menu(self, context):
    layout = self.layout 
    layout.separator()
    layout.operator("example.node_purge_unused", text="Purge Unused" )) 





bpy.utils.register_class(EXAMPLE_OT_node_purge_unused)
bpy.types.NODE_MT_node.append(cleanup_menu)

There’s also a little plugin available on BA that let you create shortcuts in your node tree.

Cheers

10 Likes

I normally test with randomize node that creates info form zero but it didn’t have type to select, so I suppose that the rest didn’t have.

I think that to learn geometry nodes is really important to have a transparent node that shows in a raw or readable format what passes through it. Sometimes I’m having a hard time understanding what really gets throught…

Is it a float? An integer? And what about a vector? Can you show me the coordinates of the input object?

$Untitled

Edit:
it’s being worked on
Implement socket inspection and links values
Add support for node socket tooltips

Sverchok has something similar in place

1 Like

Is there a way to get access to the first or last point and use only that point for Point Instance? Or is there a way to specify a point with vectors for point instance?

If there is no other way, I would like to suggest to add a Point mesh primitive.

Use case would be to use GN as an array for a collection for building floors, for example. I would like to have a unique bottom “cap” and top “cap” (a roof) as in the array modifier.

1 Like

I don’t know if I’m interpreting your question correctly, but regarding specifying a point with vector for point instance, you can use a line primitive with count 1.

1 Like

Nice! That’s it! I didn’t know the line tool is also a point tool :wink:

1 Like

Would it be possible to add some kind of highlighting in the spreadsheet of geometry selected in the viewport (in edit mode)? You can already use ‘selected only’ for this, but for quickly identifying what geometry corresponds to which line, highlighting the corresponding lines would be nice.

I Just made an instancing by rate system in geonode
Might be handy to some @dimitar

https://pasteall.org/blend/d98f55bce302490984bc6c335995d54f

Capture d’écran 2021-04-13 032543

I think it’s a bit slow? curious to see if there’s a faster/better method, I’m almost sure that i took a long detour as it is quite redundant. (the rate is basically calculated 10 times, with a generated random int attr from 0 to 100 which is then compared with user rate input, then with in some boolean maths we place a new idx on available spots of instance_idx attr)

Note that instancing by index can be really handy,
for example you can use a TextureSample node, remap the texture values as Integrer so they can be read as instance_idx then poof you have a multi instance texture cluster set up

8 Likes

I thought this was a fun idea, so I gave it a try. I think it can be a bit simpler than your setup.

I had way too much fun organizing the node links…

There’s just an accumulated sum of all the weights used as a max for the attribute randomize, an attribute compare, point separate, and point instance in the node groups. I think there’s some math in there to fix up but I believe the basic idea works.

Conclusions-- hopefully there’s a better way of addressing this use case, and I wish sockets lined up with the grid when you use snapping to place nodes.

12 Likes

Is it possible to create Geometry Nodes Instances exactly on the elements of a Vertex Group? Just one node for each Vertex Without randomization?

Thanks Rusculleda

1 Like

You don’t need a point distribute for that. You can use the vertex group as mask on a point separate node and connect that directly to a point instance node.

2 Likes

The drop down menu currently only displays attributes from the node on the left. Most of the time, it make sense, but sometimes in cases like this:

I am trying to instance little cubes on the vertices of the large cubes, and I want to input a rotation, but it is not there. If I use point distribute first, “rotation” would be there, but when I just simply want to instance on the vertex, it is not there.

I understand the logic, that the attribute needs to be created first, to be displayed on the drop down. But from a UX perspective, it also does not make sense why things like “rotation” and “scale” are not part of the point cloud’s built in attributes included in drop down, despite the “point instance” node clearly accepts a rotation attribute and scale attribute input. I hope I can soon see “rotation” and “scale” in the drop down without the need to manually create it.

A proper way to do per vertices point instancing would be to convert the mesh to a point cloud first,
it would avoid a lot of problems
unfortunately it’s not yet possible

3 Likes

Guys, I’m trying to push particles evenly from the sphere using normal data. Why it is not working?
Thanks!

Just a small oversight: You’re using the Attribute Math node instead of the Attribute Vector Math node :upside_down_face:

(The Attribute Math node creates a Float attribute that is automatically interpreted as a Vector by the Point Translate node by simply using the value of the float attribute for all three components of the vector. That’s why the points are translated along the diagonal.)

2 Likes

Oh, wow. I need to be carefull. Thanks a lot.
Was banging my head against the wall for the whole day.

2 Likes