1
$\begingroup$

enter image description here

Is it possible to use a python script to generate a geometry node set up like this? As in, selecting all the objects, with the cube as the active, and then running the script to automatically generate all the Object Info nodes associated to each object. I've seen a couple tutorials but I don't find anything that involves multiple objects like that

Or maybe is there an add-on that does this? Paid or not

$\endgroup$
2
  • $\begingroup$ If you can do that for one object, why wouldn't you be able to do it with multiple objects? So the question is really how to do it at all, not how to do it to multiple objects, correct? All you need to do is to create a new node node = D.node_groups['Geometry Nodes'].nodes.new('GeometryNodeObjectInfo') and set its attribute to an object node.inputs['Object'].default_value = D.objects['Cylinder.003'] $\endgroup$ Commented Jun 15 at 21:19
  • $\begingroup$ @MarkusvonBroady I assume that's manually inputting the name of each secondary object? The idea is to have a way to create it automatically based on the selected objects (or maybe the objects in a specific collection) without knowing the names beforehand. The pic is just an example, I'd use this in situations where there could be several dozen objects. That's why I don't do it manually from the node editor. At the moment I usually merge all the secondary objects by using a boolean but that's not ideal in every situation and causes a lot of lag when doing modifications $\endgroup$
    – Cornivius
    Commented Jun 15 at 21:26

2 Answers 2

4
$\begingroup$

What you're looking for is a loop. A loop in programming allows you to repeat a given operation some number of times - here you want to repeat the operation of adding a node for each selected object:

from bpy import context as C, data as D

nt = D.node_groups['Geometry Nodes']
nodes = nt.nodes
links = nt.links
join_geo = nodes.new('GeometryNodeJoinGeometry')
join_geo.location.x = 300
for i, ob in enumerate(C.selected_objects):
    node = nodes.new('GeometryNodeObjectInfo')
    node.inputs['Object'].default_value = ob
    node.location = (-170*(i % 2), i*100)
    links.new(input=join_geo.inputs['Geometry'], output=node.outputs['Geometry'])

Result:

Obviously you need to adjust locations to fit it into your node setup. Also consider using this to add some reroutes for a nice layout...

$\endgroup$
4
  • $\begingroup$ I know next to nothing about coding but is there a way to set them to 'relative' as they are created? I've tried copying the script from the scripting tab when I change it manually and putting it into the loop but that doesn't seem to work Also, could all of them be connected to a Join Geometry node automatically? If not this is already pretty good, thanks. $\endgroup$
    – Cornivius
    Commented Jun 15 at 22:09
  • $\begingroup$ @Cornivius go to the Scripting tab and in the console there type D. then TAB key. You will see suggestions. Sometimes it's obvious what to pick, sometimes you need to investigate, sometimes you know what to pick but don't quite remember the name. Then continue typing D.node and press TAB, which will auto-complete to D.node_groups[ and suggest various names - start typing the name of your node group, TAB, then close the quotation and square bracket, dot, nod, TAB again so it completes to nodes and suggests node names - pick one, dot, and then it will suggest various attributes $\endgroup$ Commented Jun 15 at 23:04
  • $\begingroup$ @Cornivius I'm trying to give you the fishing rod here :) For the Join Geometry part, see the edit. $\endgroup$ Commented Jun 15 at 23:17
  • $\begingroup$ yea i don't really know enough (or anything) about programming to do this on my own tbh. The options that come up don't really mean anything to me since none are the one attribute I want to change. But this works fine, I've seen the 'relative' mode can be changed in 1 node and copied to all the selected ones so that works. I only see a couple other issues: Can it create a new geonode setup on the active object and use that instead of calling a specific node set by name? And can it exclude the active object from the 'selected object' so it doesn't create a node for it again? $\endgroup$
    – Cornivius
    Commented Jun 15 at 23:33
0
$\begingroup$

Final Code if anyone is interested in this kind of tool. The loop is from Markus von Broady in the other answer and some other ai script and copy-pasted code from a couple other pages:

import bpy

# Create a new Geometry Nodes tree
nt = bpy.data.node_groups.new(name='NewGeometryNodesTree', type='GeometryNodeTree')

# Retrieve active object
active_object = bpy.context.active_object

# Create Geometry Nodes modifier on the active object
modifier = active_object.modifiers.new(name="Geometry Nodes", type='NODES')
modifier.node_group = nt

# Access the node tree within the modifier
nodes = modifier.node_group.nodes
links = modifier.node_group.links

#Create group output
group_output = nodes.new('NodeGroupOutput')
group_output.location.x = 600

# Add a Geometry output to the Group Output node
nt.outputs.new('NodeSocketGeometry', 'Geometry')


#Create group input
group_input = nodes.new('NodeGroupInput')
group_input.location.x = -500

# Add a Geometry input to the Group input node
nt.inputs.new('NodeSocketGeometry', 'Geometry')

# Create nodes and set up the node tree
join_geo = nodes.new('GeometryNodeJoinGeometry')
join_geo.location.x = 300
for i, ob in enumerate(bpy.context.selected_objects):
    if ob == active_object:
        continue
    node = nodes.new('GeometryNodeObjectInfo')
    node.location = (-170 * (i % 2), i * 100)
    node.inputs['Object'].default_value = ob
    #Comment next line to have them set to Original Instead
    node.transform_space = 'RELATIVE'
    links.new(node.outputs['Geometry'], join_geo.inputs['Geometry'])
    
   
links.new(join_geo.outputs['Geometry'], group_output.inputs['Geometry'])

#Commenting the last line prevents the original geometry from being included
links.new(group_input.outputs['Geometry'], join_geo.inputs['Geometry'])
 

It seems to work fine so far but I'm no programmer so I can't know if it's doing stuff poorly

enter image description here

enter image description here

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .