Scripted scene building - where to begin? First off, I'm very much a novice Blender user. I use Blender mainly for building mock-ups of PCBs that I design for customers to see how the designs will look when finished. (Yes, most professional PCB packages will do this for you, but I am an open-source nut and my chosen PCB design package doesn't, so I choose Blender. Also the results from Blender are far superior to what PCB packages make).

However, putting together a new PCB design in Blender is a time consuming thing, and I would love to automate it.

I have plenty of component models in blender files, all nicely textured and looking all spangly. Making the actual PCB substrate is simple enough - import an SVG of the outline and texture it with PNG exports from the PCB package. That side of things is all fine and I am happy doing that manually.

What I'd like to automate, though, is the importing of all the components from their respective blender files and positioning them within the scene. I have a CSV file with the ID, name, and location of each component, and currently I manually clone each component from a base model and type in the location details into Blender. Which works fine, it's just very slow.

Here's an example of the end result (I am still laying out some of the components on this one):



So I know that Blender can do fancy things with plugins written in Python. I am not a Python programmer, I do 99% of my programming in C and C++. That's not to say I can't program in Python, just that I don't, and as a result I don't know the finer points of Python crafting, but that will come as I learn.

As a result I'd like to write a plugin which can load this CSV file (specified at run time by me - preferably with a file browser window), parse it for components, find the right blender files (or the right models in a single large blender file, I am not fussy which), clone the models along with their textures, etc, and set the location of each one.

First off: is this something that is possible in Python in Blender, or am I asking too much of it with the automated file loading / model finding, etc? 

Secondly: Where on earth would I start writing a plugin like this? I have absolutely no knowledge of how the internals of Blender work (which really helps things ;) ). Yes, I have the blender python API reference, but to use that I really need some idea of what I am looking for in it. 

So I could do with a couple of things:


Some pointers to friendly plugin writing tutorials to kick-start my effort,
A clue as to which parts of the API would be of most interest to a plugin like this,
What would be the best way to store the component models:


A single file with all components in it, each named properly,
A file per component named after the component with the component named properly, or
A file per component named after the component with the component having a common name (such as "component")

Procedurally, what steps would need to occur for the plugin to do what I need of it (how I would put the different concepts from the API together to make it work).
This might get you started


BlendData.libraries
csv




import bpy
import csv

file_csv = ".../layout.csv"
file_components = ".../components.blend"

with open(file_csv, newline='') as fobj:
    reader = csv.reader(fobj)
    layout_table = list(reader)

required = set(col[1] for col in layout_table)

with bpy.data.libraries.load(file_components, link=True) as (data_from, data_to):
    available = set(data_from.meshes)
    missing = required - available
    data_to.meshes = list(required &amp; available)

if missing:
    txt = bpy.data.texts.new("missing_components.txt")
    for comp in missing:
        txt.write(comp + "\n")

objects_data  = bpy.data.objects
objects_scene = bpy.context.scene.objects
name_to_index = {mesh.name: index for index, mesh in enumerate(data_to.meshes)}

def create_dupli(id, name, location):
    try:
        mesh = data_to.meshes[name_to_index[name]]
    except KeyError:
        return

    dupli = objects_data.new(id, mesh)
    dupli.location = location
    objects_scene.link(dupli)

for id, name, x, y, z in layout_table:
    loc = tuple(float(val) for val in (x, y, z))
    create_dupli(id, name, loc)