# Quady3D AI — local Blender 4.5 LTS exercise. CC0. No network calls. # Run in a new Blender file's Scripting workspace. Creates a new collection. import bpy if bpy.context.mode != 'OBJECT' and bpy.context.object: bpy.ops.object.mode_set(mode='OBJECT') collection = bpy.data.collections.new('InspectionArmExercise') bpy.context.scene.collection.children.link(collection) def cube(name, location, scale): bpy.ops.mesh.primitive_cube_add(size=1, location=location) obj = bpy.context.object obj.name = name for old in list(obj.users_collection): old.objects.unlink(obj) collection.objects.link(obj) obj.scale = scale bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) return obj base = cube('ExercisePedestal', (0,0,.12), (.7,.6,.24)) arm = cube('ExerciseArm', (0,0,.8), (.18,.18,1.15)) for obj, name, color in [(base, 'Teal enamel', (.05,.52,.48,1)), (arm, 'Orange tool', (.95,.34,.12,1))]: material = bpy.data.materials.new(name) material.diffuse_color = color material.use_nodes = True material.node_tree.nodes.get('Principled BSDF').inputs['Base Color'].default_value = color obj.data.materials.append(material) bpy.ops.object.armature_add(location=(0,0,.24)) rig = bpy.context.object rig.name = 'ExerciseRig' for old in list(rig.users_collection): old.objects.unlink(rig) collection.objects.link(rig) bpy.ops.object.mode_set(mode='EDIT') bone = rig.data.edit_bones[0] bone.name = 'Arm' bone.head = (0,0,0) bone.tail = (0,0,1.2) bpy.ops.object.mode_set(mode='OBJECT') weight = arm.vertex_groups.new(name='Arm') weight.add(list(range(len(arm.data.vertices))), 1, 'REPLACE') modifier = arm.modifiers.new('Armature', 'ARMATURE') modifier.object = rig pose = rig.pose.bones['Arm'] pose.rotation_mode = 'XYZ' for frame, angle in [(1,-.45),(25,.45),(49,-.45)]: pose.rotation_euler[0] = angle pose.keyframe_insert('rotation_euler', frame=frame) bpy.context.scene.frame_end = 49 bpy.context.scene.frame_set(1) print('Created two cubes, one bone and a 49-frame swing. Save a new .blend after inspection.')