www.xbdev.net
xbdev - software development
Thursday April 30, 2026
Home | Contact | Support | Blender (.py) Scripts... Automating Blender ..
     
 

Blender (.py) Scripts...

Automating Blender ..

 

Solar System (with Animation)


As it's easy to create spheres - let's write a simple script to construct our solar system - but to make it more interesting, we'll also animate the solar system - have the planets orbit the sun.

We'll give each planet a color that matches its planet (e.g., Earth is blue while the Sun is yellow).

Just so we can see the 'orbits' - we'll also draw rings for each planet (so we can see its path). Of course, it's dirty simple - so we'll just use 'rings' for the orbits - but so it's not totally wrong - we'll scale the planets so they're similar to the real-world planets and have different speeds.

<?php
import bpy
import math

# --- Clear scene ---
def clear_scene():
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete(use_global=False)
    for block in bpy.data.meshes:
        bpy.data.meshes.remove(block)
    for block in bpy.data.materials:
        bpy.data.materials.remove(block)
    for block in bpy.data.lights:
        bpy.data.lights.remove(block)
    for block in bpy.data.cameras:
        bpy.data.cameras.remove(block)

# --- Create material with emission ---
def create_material(name, color):
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    links = mat.node_tree.links
    nodes.clear()

    output = nodes.new(type='ShaderNodeOutputMaterial')
    principled = nodes.new(type='ShaderNodeBsdfPrincipled')
    emission = nodes.new(type='ShaderNodeEmission')
    mix = nodes.new(type='ShaderNodeMixShader')

    output.location = (400, 0)
    principled.location = (0, 100)
    emission.location = (0, -100)
    mix.location = (200, 0)

    principled.inputs["Base Color"].default_value = (*color, 1)
    emission.inputs["Color"].default_value = (*color, 1)
    emission.inputs["Strength"].default_value = 2.0

    links.new(principled.outputs[0], mix.inputs[1])
    links.new(emission.outputs[0], mix.inputs[2])
    links.new(mix.outputs[0], output.inputs[0])

    return mat

# --- Create orbit ring ---
def create_orbit_ring(distance, name="OrbitRing"):
    bpy.ops.mesh.primitive_torus_add(
        major_radius=distance,
        minor_radius=0.05,
        major_segments=100,
        minor_segments=6,
        location=(0, 0, 0),
        rotation=(0, 0, 0)
    )
    ring = bpy.context.active_object
    ring.name = name

    mat = bpy.data.materials.new(name + "_Mat")
    mat.use_nodes = True
    bsdf = mat.node_tree.nodes["Principled BSDF"]
    bsdf.inputs["Base Color"].default_value = (1, 1, 1, 1)
    bsdf.inputs["Roughness"].default_value = 1.0
    ring.data.materials.append(mat)

    return ring

# --- Create planet with orbit animation ---
def create_planet(name, radius, distance, color, orbit_duration, frame_start=1):
    orbit_empty = bpy.data.objects.new(name + "_Orbit", None)
    bpy.context.collection.objects.link(orbit_empty)

    bpy.ops.mesh.primitive_uv_sphere_add(radius=radius, location=(distance, 0, 0))
    planet = bpy.context.active_object
    planet.name = name
    planet.data.materials.append(create_material(name + "_Mat", color))
    planet.parent = orbit_empty

    # Animate orbit
    orbit_empty.rotation_euler = (0, 0, 0)
    orbit_empty.keyframe_insert(data_path="rotation_euler", frame=frame_start)
    orbit_empty.rotation_euler[2] = math.radians(360)
    orbit_empty.keyframe_insert(data_path="rotation_euler", frame=frame_start + orbit_duration)

    fcurve = orbit_empty.animation_data.action.fcurves[2]
    for kp in fcurve.keyframe_points:
        kp.interpolation = 'LINEAR'

    # Create visible orbit ring
    create_orbit_ring(distance, name + "_Ring")


# --- Main execution ---
clear_scene()

# Create Sun
bpy.ops.mesh.primitive_uv_sphere_add(radius=2, location=(0, 0, 0))
sun = bpy.context.active_object
sun.name = "Sun"
sun.data.materials.append(create_material("Sun_Mat", (1.0, 0.7, 0.0)))

# Sun light
light_data = bpy.data.lights.new(name="Sun_Light", type='POINT')
light_data.energy = 5000
light = bpy.data.objects.new(name="Sun_Light", object_data=light_data)
light.location = (0, 0, 0)
bpy.context.collection.objects.link(light)

# Planet data
planet_data = [
    ("Mercury", 0.2, 4, (0.5, 0.5, 0.5), 60),
    ("Venus",   0.3, 6, (1.0, 0.8, 0.2), 100),
    ("Earth",   0.35, 8, (0.2, 0.5, 1.0), 160),
    ("Mars",    0.25, 10, (1.0, 0.3, 0.2), 220),
    ("Jupiter", 0.9, 14, (1.0, 0.6, 0.3), 400),
    ("Saturn",  0.75, 18, (1.0, 0.9, 0.6), 600),
    ("Uranus",  0.6, 22, (0.6, 0.8, 1.0), 800),
    ("Neptune", 0.6, 26, (0.2, 0.4, 1.0), 1000),
]

# Create planets
for name, radius, distance, color, duration in planet_data:
    create_planet(name, radius, distance, color, duration)

# --- Camera setup ---
bpy.ops.curve.primitive_bezier_circle_add(radius=40, location=(0, 0, 0))
orbit_path = bpy.context.active_object
orbit_path.name = "Camera_Path"
orbit_path.data.path_duration = 800

cam_data = bpy.data.cameras.new(name="Camera")
camera = bpy.data.objects.new("Camera", cam_data)
bpy.context.collection.objects.link(camera)

camera.location = (0, -40, 10)
camera.rotation_mode = 'XYZ'

# Follow Path
constraint = camera.constraints.new(type='FOLLOW_PATH')
constraint.target = orbit_path
constraint.use_fixed_location = True
constraint.use_curve_follow = True

# Track To Sun
track_to = camera.constraints.new(type='TRACK_TO')
track_to.target = sun
track_to.track_axis = 'TRACK_NEGATIVE_Z'
track_to.up_axis = 'UP_Y'

# Animate camera on path
camera.constraints["Follow Path"].offset_factor = 0.0
camera.keyframe_insert(data_path='constraints["Follow Path"].offset_factor', frame=1)
camera.constraints["Follow Path"].offset_factor = 1.0
camera.keyframe_insert(data_path='constraints["Follow Path"].offset_factor', frame=800)

fcurve = camera.animation_data.action.fcurves[0]
for kp in fcurve.keyframe_points:
    kp.interpolation = 'LINEAR'

bpy.context.scene.frame_end = 800


This is just the beginning - to make it look more like 'star-trek' - you'd need to add a star field (background) - also the camera just circles the planets but with a few more tweeks you could have it go in and through the galaxy, cirlce planets and so on - so it feels like you're in space craft travelling through out solar system.

Things to Try


• Add sky box (or a ciclular dome) for background stars/cosmos effects
• Add more planet effects (bumpy surface, glow, rings, circling asteroids)
• Add lens flare
• Make each plane 'spin' as well as rotating around the sun
• Make the sun more magnanamous (sparks, glow, ) - so it really looks like our sun!
• Add some little satelittes
• Get some data from NASA for real position of planets etc (texture data)








 
Advert (Support Website)

 
 Visitor:
Copyright (c) 2002-2026 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.