Skip to content

Instantly share code, notes, and snippets.

@lancelet
Created September 27, 2020 03:42
Show Gist options
  • Save lancelet/906c38e452cb9496bc530a61235600ae to your computer and use it in GitHub Desktop.
Save lancelet/906c38e452cb9496bc530a61235600ae to your computer and use it in GitHub Desktop.
Attempt at a Utah Teapot loader
# Crappy Utah Teapot loader script for Blender 2.90.1
import bpy
from mathutils import Vector
def create4x4patch(points):
surface_data = bpy.data.curves.new('wook', 'SURFACE')
surface_data.dimensions = '3D'
# set points per segments (U * V)
for i in range(0, 16, 4):
spline = surface_data.splines.new(type='NURBS')
spline.points.add(3) # already has a default vector
for p, new_co in zip(spline.points, points[i:i+4]):
p.co = new_co
surface_object = bpy.data.objects.new('NURBS_OBJ', surface_data)
bpy.context.collection.objects.link(surface_object)
splines = surface_object.data.splines
for s in splines:
for p in s.points:
p.select = True
bpy.context.view_layer.objects.active = surface_object
bpy.ops.object.mode_set(mode = 'EDIT')
bpy.ops.curve.make_segment()
bpy.ops.object.mode_set(mode = 'OBJECT')
bpy.context.object.data.splines[0].use_endpoint_u = True
bpy.context.object.data.splines[0].use_endpoint_v = True
# File from: http://www.holmes3d.net/graphics/teapot/teapotCGA.bpt
with open('<insert-filename.bpt>', 'r') as infile:
str_data = infile.read().splitlines(True)
# Drop the first line
del str_data[0]
# Create points
while len(str_data) > 0:
coords = []
del str_data[0]
for line in str_data[0:16]:
items = list(map(lambda s: float(s.strip()), line.split()))
coords.append(Vector((items[0], items[1], items[2], 1.0)))
del str_data[0:16]
create4x4patch(coords)
@lancelet
Copy link
Author

Another version with embedded GLUT teapot data:

import bpy
from mathutils import Vector

def create4x4patch(points):
    surface_data = bpy.data.curves.new('wook', 'SURFACE')
    surface_data.dimensions = '3D'

    # set points per segments (U * V)
    for i in range(0, 16, 4):
        spline = surface_data.splines.new(type='NURBS')
        spline.points.add(3)  # already has a default vector

        for p, new_co in zip(spline.points, points[i:i+4]):
            p.co = new_co

    surface_object = bpy.data.objects.new('NURBS_OBJ', surface_data)
    bpy.context.collection.objects.link(surface_object)

    splines = surface_object.data.splines
    for s in splines:
        for p in s.points:
            p.select = True

    bpy.context.view_layer.objects.active = surface_object
    bpy.ops.object.mode_set(mode = 'EDIT') 
    bpy.ops.curve.make_segment()
    bpy.ops.object.mode_set(mode = 'OBJECT')
    bpy.context.object.data.splines[0].use_endpoint_u = True
    bpy.context.object.data.splines[0].use_endpoint_v = True

# Teapot data from: https://github.com/dcnieho/FreeGLUT/blob/c8d14b13af997a907a9c1c98f3f26b102bb89401/freeglut/freeglut/src/fg_teapot_data.h

vertices = list(map (lambda v: Vector((v[0], v[1], v[2], 1.0)), [
    ( 1.40000,  0.00000,  2.40000), ( 1.40000, -0.78400,  2.40000),
    ( 0.78400, -1.40000,  2.40000), ( 0.00000, -1.40000,  2.40000),
    ( 1.33750,  0.00000,  2.53125), ( 1.33750, -0.74900,  2.53125),
    ( 0.74900, -1.33750,  2.53125), ( 0.00000, -1.33750,  2.53125),
    ( 1.43750,  0.00000,  2.53125), ( 1.43750, -0.80500,  2.53125),
    ( 0.80500, -1.43750,  2.53125), ( 0.00000, -1.43750,  2.53125),
    ( 1.50000,  0.00000,  2.40000), ( 1.50000, -0.84000,  2.40000),
    ( 0.84000, -1.50000,  2.40000), ( 0.00000, -1.50000,  2.40000),
    ( 1.75000,  0.00000,  1.87500), ( 1.75000, -0.98000,  1.87500),
    ( 0.98000, -1.75000,  1.87500), ( 0.00000, -1.75000,  1.87500),
    ( 2.00000,  0.00000,  1.35000), ( 2.00000, -1.12000,  1.35000),
    ( 1.12000, -2.00000,  1.35000), ( 0.00000, -2.00000,  1.35000),
    ( 2.00000,  0.00000,  0.90000), ( 2.00000, -1.12000,  0.90000),
    ( 1.12000, -2.00000,  0.90000), ( 0.00000, -2.00000,  0.90000),
    ( 2.00000,  0.00000,  0.45000), ( 2.00000, -1.12000,  0.45000),
    ( 1.12000, -2.00000,  0.45000), ( 0.00000, -2.00000,  0.45000),
    ( 1.50000,  0.00000,  0.22500), ( 1.50000, -0.84000,  0.22500),
    ( 0.84000, -1.50000,  0.22500), ( 0.00000, -1.50000,  0.22500),
    ( 1.50000,  0.00000,  0.15000), ( 1.50000, -0.84000,  0.15000),
    ( 0.84000, -1.50000,  0.15000), ( 0.00000, -1.50000,  0.15000),
    ( 0.00000,  0.00000,  3.15000), ( 0.00000, -0.00200,  3.15000),
    ( 0.00200,  0.00000,  3.15000), ( 0.80000,  0.00000,  3.15000),
    ( 0.80000, -0.45000,  3.15000), ( 0.45000, -0.80000,  3.15000),
    ( 0.00000, -0.80000,  3.15000), ( 0.00000,  0.00000,  2.85000),
    ( 0.20000,  0.00000,  2.70000), ( 0.20000, -0.11200,  2.70000),
    ( 0.11200, -0.20000,  2.70000), ( 0.00000, -0.20000,  2.70000),
    ( 0.40000,  0.00000,  2.55000), ( 0.40000, -0.22400,  2.55000),
    ( 0.22400, -0.40000,  2.55000), ( 0.00000, -0.40000,  2.55000),
    ( 1.30000,  0.00000,  2.55000), ( 1.30000, -0.72800,  2.55000),
    ( 0.72800, -1.30000,  2.55000), ( 0.00000, -1.30000,  2.55000),
    ( 1.30000,  0.00000,  2.40000), ( 1.30000, -0.72800,  2.40000),
    ( 0.72800, -1.30000,  2.40000), ( 0.00000, -1.30000,  2.40000),
    ( 0.00000,  0.00000,  0.00000), ( 0.00000, -1.42500,  0.00000),
    ( 0.79800, -1.42500,  0.00000), ( 1.42500, -0.79800,  0.00000),
    ( 1.42500,  0.00000,  0.00000), ( 0.00000, -1.50000,  0.07500),
    ( 0.84000, -1.50000,  0.07500), ( 1.50000, -0.84000,  0.07500),
    ( 1.50000,  0.00000,  0.07500), (-1.60000,  0.00000,  2.02500),
    (-1.60000, -0.30000,  2.02500), (-1.50000, -0.30000,  2.25000),
    (-1.50000,  0.00000,  2.25000), (-2.30000,  0.00000,  2.02500),
    (-2.30000, -0.30000,  2.02500), (-2.50000, -0.30000,  2.25000),
    (-2.50000,  0.00000,  2.25000), (-2.70000,  0.00000,  2.02500),
    (-2.70000, -0.30000,  2.02500), (-3.00000, -0.30000,  2.25000),
    (-3.00000,  0.00000,  2.25000), (-2.70000,  0.00000,  1.80000),
    (-2.70000, -0.30000,  1.80000), (-3.00000, -0.30000,  1.80000),
    (-3.00000,  0.00000,  1.80000), (-2.70000,  0.00000,  1.57500),
    (-2.70000, -0.30000,  1.57500), (-3.00000, -0.30000,  1.35000),
    (-3.00000,  0.00000,  1.35000), (-2.50000,  0.00000,  1.12500),
    (-2.50000, -0.30000,  1.12500), (-2.65000, -0.30000,  0.93750),
    (-2.65000,  0.00000,  0.93750), (-2.00000,  0.00000,  0.90000),
    (-2.00000, -0.30000,  0.90000), (-1.90000, -0.30000,  0.60000),
    (-1.90000,  0.00000,  0.60000), ( 1.70000,  0.00000,  1.42500),
    ( 1.70000, -0.66000,  1.42500), ( 1.70000, -0.66000,  0.60000),
    ( 1.70000,  0.00000,  0.60000), ( 2.60000,  0.00000,  1.42500),
    ( 2.60000, -0.66000,  1.42500), ( 3.10000, -0.66000,  0.82500),
    ( 3.10000,  0.00000,  0.82500), ( 2.30000,  0.00000,  2.10000),
    ( 2.30000, -0.25000,  2.10000), ( 2.40000, -0.25000,  2.02500),
    ( 2.40000,  0.00000,  2.02500), ( 2.70000,  0.00000,  2.40000),
    ( 2.70000, -0.25000,  2.40000), ( 3.30000, -0.25000,  2.40000),
    ( 3.30000,  0.00000,  2.40000), ( 2.80000,  0.00000,  2.47500),
    ( 2.80000, -0.25000,  2.47500), ( 3.52500, -0.25000,  2.49375),
    ( 3.52500,  0.00000,  2.49375), ( 2.90000,  0.00000,  2.47500),
    ( 2.90000, -0.15000,  2.47500), ( 3.45000, -0.15000,  2.51250),
    ( 3.45000,  0.00000,  2.51250), ( 2.80000,  0.00000,  2.40000),
    ( 2.80000, -0.15000,  2.40000), ( 3.20000, -0.15000,  2.40000),
    ( 3.20000,  0.00000,  2.40000)
]))

patches = [
    [  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15 ],
    [ 12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27 ],
    [ 24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39 ],
    [ 40,  41,  42,  40,  43,  44,  45,  46,  47,  47,  47,  47,  48,  49,  50,  51 ],
    [ 48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63 ],
    [ 64,  64,  64,  64,  65,  66,  67,  68,  69,  70,  71,  72,  39,  38,  37,  36 ],
    [ 73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88 ],
    [ 85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,  99, 100 ],
    [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116 ],
    [113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128 ]
]

for patch in patches:
    patch_coords = []
    for index in patch:
        patch_coords.append(vertices[index])
    create4x4patch(patch_coords)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment