Intro exercise: Can we corrugate a doughnut? trig review or intro: atan, quadrants, ratios, and atan2 Up and down first (easy) Inside and outside: How do we know which is which? Possible second intro exercise: Could we put a roof over the doughnut instead? Might leave this one for extra practice We'd need trapazoidal panels Could apply a modification to our panel before rotating it? A note if you've been following the tutorial: The API has options to do the same stuff from scripts So if you want to extrude or something, you can Today's main topic: Color! Color: vertex_colors is depricated Says to use "color attributes" instead What does that mean? Vertex vs. Loop: loop here seems to indicate a vertex and the face it appears in Example: In a cube, each vertex is in 3 faces So there are three times as many loops as vertices Why "loop"? It's part of a loop around the face Still sounds kinda odd Maybe think about it this way: It's the first step in a loop Traversing in a different order makes a different loop? We can assign colors on a per loop basis Probably better anyway - we can color each face a different color that way bmesh https://docs.blender.org/api/current/bmesh.html#module-bmesh from_edit_mesh, but we seem to need to be in edit mode It says that, and my test didn't work in object mode So we don't have to look it up: bpy.ops.object.mode_set(mode="EDIT") Can switch to object mode the same way And we might need to be! Making a layer: bmesh.loops: "kind of" gives access to loops We're supposed to work through faces So say the docs...didn't try it From here, we can get to layers There's already one named color color is a MeshLoopColorLayer: https://docs.blender.org/api/current/bpy.types.MeshLoopColorLayer.html#bpy.types.MeshLoopColorLayer It inherits new from LoopColors, which has a .new method Default name is "Col" Remember to save the result, it's the color layer Now we can go through the faces in our_mesh.faces For each of these, the loops Each of those can have the_loop[color_layer] set Getting there: Still need a material We can add one in object mode easy enough Then in the shader editor, add an input for our new color attribute Since this is a scripting class instead: We can make a material bpy.data.materials is where the materials are It has a .new, which will let us make a new material Principled BSDF is the shader we're using, and we can get a reference to it like this: bsdf = mat.node_tree.nodes.get("Principled BSDF") Didn't think I'd remember that mat is our new material, whatever we named it shaders are associated with a material Now we need our new color node, like we did before (node_tree.nodes has a new) type is ShaderNodeVertexColor mat.node_tree.nodes.new can make one This can be linked in just like we did in the UI The node_tree contains links node_tree.links.new( thing to link , where to link it ) In our case, our color node's output named "Color" should be linked to bsdf's input "Base color" They have lists of inputs and outputs (like, color_node.outputs[ ] ) Finally, the material has to be attached to our object our_object.data.materials.append(the material) Unless it's already there...but we probably just made the object You also have to be in the right rendering mode (upper right corner) It's harder than you might think to change that by script The UI for Blender is arrange in screen areas Each area can have spaces bpy.context.screen.areas is a list of areas, and the type is "VIEW_3D" Once we find it, the area will have a spaces property Spaces have a type as well, and this should also be VIEW_3D The right space will have a .shading.type property Can be set to "MATERIAL" Now! We can add weird color schemes to whatever we want! Colored stairs or something