Why am I still building slides?
This commit is contained in:
		
							parent
							
								
									c22060d8d8
								
							
						
					
					
						commit
						b1a52b99fd
					
				
					 4 changed files with 179 additions and 6 deletions
				
			
		
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
*.blend*
 | 
			
		||||
.env
 | 
			
		||||
venv
 | 
			
		||||
.vscode
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,22 +1,23 @@
 | 
			
		|||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
if [[ -d venv ]]; then
 | 
			
		||||
    source ./venv/bin/activate
 | 
			
		||||
    return
 | 
			
		||||
    exit 0
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if ! [[ -f .env ]]; then
 | 
			
		||||
    echo "Add a .env file with PYTHON_PATH containing an absolute path path to"
 | 
			
		||||
    echo "blender's python build with bpy. "
 | 
			
		||||
    echo "E.g  PYTHON_PATH=~/blender-git/lib/linux_centos7_x86_64/python/bin/python3.9"
 | 
			
		||||
    echo "PYTHON_PATH=~/blender-git/lib/linux_centos7_x86_64/python/bin/python3.9" > .env
 | 
			
		||||
    echo "VIRTUAL_ENV_DISABLE_PROMPT=YESPLEASE" >> .env
 | 
			
		||||
    echo "Created the file. Now go edit it"
 | 
			
		||||
    exit 1;
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
source .env
 | 
			
		||||
 | 
			
		||||
if [[ -d venv ]]; then
 | 
			
		||||
    source ./venv/bin/activate
 | 
			
		||||
    return
 | 
			
		||||
    exit 0
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ -z "$PYTHON_PATH" ]]; then
 | 
			
		||||
    echo Missing variable PYTHON_PATH in .env
 | 
			
		||||
    exit 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										171
									
								
								playground/playground.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								playground/playground.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,171 @@
 | 
			
		|||
import bpy
 | 
			
		||||
from bpy.types import (
 | 
			
		||||
    Curve,
 | 
			
		||||
    LayerCollection,
 | 
			
		||||
    MaterialSlot,
 | 
			
		||||
    ViewLayer,
 | 
			
		||||
    Object,
 | 
			
		||||
    Mesh,
 | 
			
		||||
)
 | 
			
		||||
from pathlib import Path
 | 
			
		||||
from typing import Collection, Generic, TypeVar
 | 
			
		||||
from mathutils import Color
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
SCENE = bpy.data.scenes[0]
 | 
			
		||||
 | 
			
		||||
# Tiny helper to make autocompletion more precise for objects
 | 
			
		||||
T = TypeVar("T")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ObjectData(Generic[T], Object):
 | 
			
		||||
    data: T
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Default names
 | 
			
		||||
 | 
			
		||||
PARTS = ("controller", "curve", "fin", "maker", "screw", "spool")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Slide:
 | 
			
		||||
    collection: LayerCollection
 | 
			
		||||
    controller: ObjectData[None]
 | 
			
		||||
    curve: ObjectData[Curve]
 | 
			
		||||
    fin: ObjectData[Curve]
 | 
			
		||||
    maker: ObjectData[Mesh]
 | 
			
		||||
    screw: ObjectData[Mesh]
 | 
			
		||||
    spool: ObjectData[Mesh]
 | 
			
		||||
 | 
			
		||||
    def __init__(self, blend_file_path: str):
 | 
			
		||||
        self.__dict__.update(load_slide(blend_file_path))
 | 
			
		||||
        self.__localize()
 | 
			
		||||
 | 
			
		||||
    def __localize(self):
 | 
			
		||||
        "Make sure node inputs are linked to themselves"
 | 
			
		||||
        self.maker.modifiers["MakeTunnel"]["Input_5"] = self.curve
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_6"] = self.curve
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_3"] = self.spool
 | 
			
		||||
        slide_body_material = self.maker.material_slots[0].material
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_7"] = slide_body_material
 | 
			
		||||
        self.fin.modifiers["AddFin"]["Input_2"] = self.curve
 | 
			
		||||
        self.fin.modifiers["AddFin"]["Input_3"] = self.spool.material_slots[0].material
 | 
			
		||||
        self.screw.hide_viewport = True
 | 
			
		||||
        self.screw.hide_render = True
 | 
			
		||||
        self.spool.hide_viewport = True
 | 
			
		||||
        self.spool.hide_render = True
 | 
			
		||||
        for part in PARTS[1:]:
 | 
			
		||||
            getattr(self, part).parent = self.controller
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def radius(self) -> float:
 | 
			
		||||
        return self.maker.modifiers["MakeTunnel"]["Input_2"]
 | 
			
		||||
 | 
			
		||||
    @radius.setter
 | 
			
		||||
    def radius(self, v: float):
 | 
			
		||||
        self.maker.modifiers["MakeTunnel"]["Input_2"] = v
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_8"] = v
 | 
			
		||||
        self.fin.modifiers["AddFin"]["Input_4"] = v
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def thickness(self) -> float:
 | 
			
		||||
        return self.maker.modifiers["Solidify"].thickness
 | 
			
		||||
 | 
			
		||||
    @thickness.setter
 | 
			
		||||
    def thickness(self, v: float):
 | 
			
		||||
        self.maker.modifiers["Solidify"].thickness = v
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_9"] = v
 | 
			
		||||
        self.fin.modifiers["AddFin"]["Input_5"] = v
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def spool_spacing(self) -> float:
 | 
			
		||||
        return self.maker.modifiers["AddSpool"]["Input_5"]
 | 
			
		||||
 | 
			
		||||
    @spool_spacing.setter
 | 
			
		||||
    def spool_spacing(self, v: float):
 | 
			
		||||
        self.maker.modifiers["AddSpool"]["Input_5"] = v
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def body_color(self) -> Color:
 | 
			
		||||
        c = tuple(
 | 
			
		||||
            self.maker.material_slots[0]
 | 
			
		||||
            .material.node_tree.nodes["Principled BSDF.001"]
 | 
			
		||||
            .inputs[0]
 | 
			
		||||
            .default_value
 | 
			
		||||
        )
 | 
			
		||||
        return Color(c[:3])
 | 
			
		||||
 | 
			
		||||
    @body_color.setter
 | 
			
		||||
    def body_color(self, c: Color):
 | 
			
		||||
        c = (*c, 1.0)
 | 
			
		||||
        self.maker.material_slots[0].material.node_tree.nodes[
 | 
			
		||||
            "Principled BSDF.001"
 | 
			
		||||
        ].inputs[0].default_value = c
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def secondary_color(self) -> Color:
 | 
			
		||||
        c = tuple(
 | 
			
		||||
            self.spool.material_slots[0]
 | 
			
		||||
            .material.node_tree.nodes["Principled BSDF.001"]
 | 
			
		||||
            .inputs[0]
 | 
			
		||||
            .default_value
 | 
			
		||||
        )
 | 
			
		||||
        return Color(c[:3])
 | 
			
		||||
 | 
			
		||||
    @secondary_color.setter
 | 
			
		||||
    def secondary_color(self, c: Color):
 | 
			
		||||
        c = (*c, 1.0)
 | 
			
		||||
        self.spool.material_slots[0].material.node_tree.nodes[
 | 
			
		||||
            "Principled BSDF.001"
 | 
			
		||||
        ].inputs[0].default_value = c
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_parts(c: Collection):
 | 
			
		||||
    return {
 | 
			
		||||
        part: next(obj for obj in c.all_objects if part in obj.name.lower())
 | 
			
		||||
        for part in PARTS
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def toplevel_collection_to_layer_collection(
 | 
			
		||||
    c: Collection, view_layer: ViewLayer
 | 
			
		||||
) -> LayerCollection:
 | 
			
		||||
    return next(cv for cv in view_layer.layer_collection.children if cv.collection == c)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def duplicate_collection_objects(c: Collection, name: str):
 | 
			
		||||
    c2 = bpy.data.collections.new(name)
 | 
			
		||||
    for obj in c.all_objects:
 | 
			
		||||
        c2.objects.link(obj.copy())
 | 
			
		||||
    return c2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def dup_obj_materials_inplace(obj: Object):
 | 
			
		||||
    for slot in obj.material_slots:
 | 
			
		||||
        slot: MaterialSlot
 | 
			
		||||
        slot.material = slot.material.copy()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def load_slide(file_path: str):
 | 
			
		||||
    bpy.ops.wm.append(
 | 
			
		||||
        filepath=f"{file_path}/Scene/SlideTemplate",
 | 
			
		||||
        directory=f"{file_path}/Scene/",
 | 
			
		||||
        filename="SlideTemplate",
 | 
			
		||||
    )
 | 
			
		||||
    scene = bpy.data.scenes["SlideTemplate"]
 | 
			
		||||
    template = scene.collection.children[0]
 | 
			
		||||
 | 
			
		||||
    c = duplicate_collection_objects(template, "Slide")
 | 
			
		||||
    SCENE.collection.children.link(c)
 | 
			
		||||
    bpy.data.scenes.remove(scene)
 | 
			
		||||
    c = toplevel_collection_to_layer_collection(c, SCENE.view_layers[0])
 | 
			
		||||
    parts = get_parts(c.collection)
 | 
			
		||||
    for part_obj in parts.values():
 | 
			
		||||
        dup_obj_materials_inplace(part_obj)
 | 
			
		||||
 | 
			
		||||
    return {"collection": c, **parts}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    file_name = "playground.blend"
 | 
			
		||||
    blend_file_path = str((Path(__file__) / ".." / file_name).resolve())
 | 
			
		||||
    slide = Slide(blend_file_path)
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue