LEGO Artworks - Generativ Art with Python

Hey,
I wrote a quick and simple python-script, that clones a small lego-brick to a grid and add a vertex color based on an image pixelcolor. I generated these images with it:

See all images here:
https://www.instagram.com/p/BwSHhdjAYPF/

58 Likes

This looks great! Are you sharing the script?

4 Likes

Awesome!! :+1:

1 Like

In case you want to try it, here is the script:
You have to model a Lego-brick at first. That shouldn’t be a problem :wink:

This is the setup:



"""
This script copies an object based on an image input and sets the vertex color to the corresponding pixels.
Make sure that the image is already scaled down and is loaded into the blend file. 
One side of the image should not be larger than 20px. It takes some time ;)
But if you have time feel free to go larger.

1. Change the image name to your image input
2. Make sure the object you want to clone is selected
3. Run the Script!
4. In the shader network you can access the color with the attribute node. 

"""

import bpy

# get image data, image has to be loaded into the blend-file
img = bpy.data.images["image.jpg"]
width = img.size[0]
height = img.size[1]

#get object-size for grid (has to be square)
obj = bpy.context.active_object
size = obj.dimensions[0]

#create new collection if necessary
if bpy.data.collections.get("LegoGrid") is None:
    grid_coll = bpy.data.collections.new("LegoGrid")
    bpy.context.scene.collection.children.link(grid_coll)
else:
    grid_coll = bpy.data.collections["LegoGrid"]
    
#generate grid and match pixeldata to vertex color
for y in range(height):
    for x in range(width):
        copy = obj.copy()
        copy.data = obj.data.copy()
        
        copy.location = x*size,y*size,0
        
        mesh = copy.data
        if not mesh.vertex_colors:
            mesh.vertex_colors.new()
        
        color_layer = mesh.vertex_colors["Col"]
        
        index = (y * width + x) * 4
        
        r = img.pixels[index + 0]
        g = img.pixels[index + 1]
        b = img.pixels[index + 2]
        a = img.pixels[index + 3]

        i = 0
        for poly in mesh.polygons:
            for idx in poly.loop_indices:
                rgb = [r,g,b,a]
                color_layer.data[i].color = rgb
                i += 1
                
        grid_coll.objects.link(copy)
11 Likes

Yes, i attechd it to this thread. Have fun!

1 Like

Thanks for releasing the script! I was really interested in how you were reading color data from an image. I’m definitely gonna play around with it when I get some spare time!! :rofl:

2 Likes

You’re #featured! :+1:

1 Like

Sidenote : activate simplify before generation. Or don’t use subdiv. Or use low poly legos. Or don’t use legos at all. :joy:

A few tests:

A little suggestion though (which would have a huge impact actually), try to make instances instead of duplicates.
I guess vertex color is linked to the mesh so you would still have to create duplicates for each new color. But still, that would drastically reduce the object data load.

Summary

If instead of duplicating, you make instances for same color objects, you end up storing only as much duplicates as the number of color you use (and it’s quite low on low def pictures, especially if you use black and white pictures : only two colors/meshes to use).
Let’s say we have a 20px² image with 8 colors, and a lego mesh of 100 triangles.
If you duplicate every lego piece, that’s 400 lego pieces of 100 triangles each, so you actually create and store in memory 40 000 triangles.
If you generate only duplicates for each new color, and make instances for the same colored objects, you still generate 400 objects, but they share the geometry of 8 “true” objects, which brings the polycount to 3 200. It’s 12,5 less.

5 Likes

Hi five! I saw your work on FB shared by Blender Artist. I developed a similar script, but not nearly as elegant. Mine cross-checked each RGB with a Lego part color list and used an X-Y-Z distance formula to find the closest Lego color, in case I actually wanted to order parts.

I like the artistic effect of minimal pixels so that it could actually be built. Brute force coding on a large image is impractical unless you have thousands of dollars and an entire wall. :slight_smile:

Well done!

2 Likes

Nice! Really cool to see your work and thanks for you advice. That’s really helpful!

wow thats cool!

1 Like

WOw for a minute that banana looked like a yellow duck hahaha

3 Likes

that wasn’t a duck?

2 Likes

It’s a Banaduck!!!
bananaduck

12 Likes

My post was flagged as off-topic here. Sorry all.
I moved it here - if somone want to see faster version of that script, translated to Animation Nodes.

1 Like

I thought we can change only transformations (loc,rot,scale) for instances. Can we really change somehow instance properties/attributes like vertex color? When I change ‘Col’ for one instance - all objects using the same mesh changes as well… Give me some hint, please :slight_smile:

EDIT: Ups, I missed you wrote about instances for same color. I see optimalization now :+1:.

Perhaps this one can help you. I believe he changes also colors and such in this animation
Check around 35min orso

Thanks, that tutorial is amazing!

1 Like

Now I see the banana…

1 Like

I featured you on BlenderNation, enjoy!

1 Like