#!BPY """ Name: 'Torus primitive' Blender: 232 Group: 'Misc' Tooltip: 'A torus with some special parameters' """ ############################################################################# # # # (modified) Supertoroid Primitive # # equations from: http://astronomy.swin.edu.au/~pbourke/ # # lots of interesting stuff to find their regarding computer graphics :) # # # # (C) Februari 2004 Wim Van Hoydonck # # email: tuinbels@hotmail.com # # # # Released under the Blender Artistic Licence (BAL) # # see www.blender.org # # # # Works in Blender 2.32 and higher # # # # this script can be found online at: # # http://users.pandora.be/tuinbels/scripts/torus.py # # # ############################################################################# # # # History # # V: 0.1 - 06-02-04 - First working version # # 0.2 - 07-02-04 - Added extra parameter: ellipticity in z-direction # # # ############################################################################# import Blender from Blender import * from Blender.Draw import * from Blender.BGL import * from math import pi, sin, cos, fmod # parameters # create primitive 1 primitive = Create(1) # n1: shape of torus ring # n2: shape of cross section of ring # 1 gives normal torusshape, 2 gives straight edges, 0 creates doubles n1 = Create(1.0) n2 = Create(1.0) # ellipticity of segments, also scales in z-direction # zero gives no effect, positive 'tapers' the top, negative tapers the bottom ellipt = Create(0.0) # segments (vertical) # rings (horizontal) segments = Create(16) rings = Create(16) # scale factors in x,y and z direction # note: these are scale factors wrt to the mathematical function, not # the parameterization rx = Create(1.0) ry = Create(1.0) rz = Create(1.0) # r0: base radius of the torus # r1: radius of cross section of ring r0 = Create(1.0) r1 = Create(0.5) #=============# # SuperToroid # #=============# def SuperToroid(): # parameters # powers of sines and cosines n1v = n1.val n2v = n2.val elliptv = ellipt.val # segments (meridiaan: vertikaal) # rings (breedtegraad: horizontal) segmentsv = segments.val ringsv = rings.val rxv = rx.val ryv = ry.val rzv = rz.val r0v = r0.val r1v = r1.val dtheta = 2*pi/segmentsv dphi = 2*pi/ringsv ST = NMesh.GetRaw() # make verts for i in range(0,segmentsv): for j in range(0, ringsv): c1 = cos(i*dtheta) s1 = sin(i*dtheta) c2 = cos(j*dphi) s2 = sin(j*dphi) # make sure to take a fractional power of a negative number if c1 < 0: c1m = -((-c1)**n1v) else: c1m = c1**n1v if s1 < 0: s1m = -((-s1)**n1v) else: s1m = s1**n1v if c2 < 0: c2m = -((-c2)**n2v) else: c2m = c2**n2v if s2 < 0: s2m = -((-s2)**n2v) else: s2m = s2**n2v # x, y and z coordinates of the current vertex x = c1m*(r0v+r1v*c2m)*rxv y = s1m*(r0v+r1v*c2m)*ryv # modification from supertoroid primitve by substraction ellipt*c2m from r1*s2m z = (r1v*s2m-elliptv*c2m)*rzv v = NMesh.Vert(x,y,z) ST.verts.append(v) # make faces for i in range(0, segmentsv): for j in range(0, ringsv): f = NMesh.Face() f.v.append(ST.verts[i*ringsv + j]) f.v.append(ST.verts[i*ringsv + int(fmod(j+1, ringsv))]) f.v.append(ST.verts[int(fmod((i+1)*ringsv, segmentsv*ringsv)) + int(fmod(j+1, ringsv))]) f.v.append(ST.verts[int(fmod((i+1)*ringsv, segmentsv*ringsv)) + j]) f.v.reverse() ST.faces.append(f) st_ob = NMesh.PutRaw(ST) # set solid DrawType st_ob.setDrawType(3) # set wire DrawMode st_ob.setDrawMode(32) # placement (and orientation) of mesh cursorpos = Window.GetCursorPos() st_ob.setLocation(cursorpos[0],cursorpos[1],cursorpos[2]) ############################################################# # Graphics # ############################################################# def draw(): global primitive, n1, n2, ellipt, segments, rings, rx, ry, rz, r0, r1 BGL.glClearColor(0.5, 0.5, 0.5, 1) BGL.glColor3f(1.,1.,1.) BGL.glClear(BGL.GL_COLOR_BUFFER_BIT) BGL.glColor3f(1, 1, 1) BGL.glRasterPos2d(10, 160) Text("Torus primitive") BGL.glRasterPos2d(10, 140) Text("(C) Febr. 2004 Wim Van Hoydonck") #Create Buttons & sliders Button("Create", 3, 10, 4, 70, 20, "create primitive, CKEY with mouse in script window") Button("Exit", 1, 90, 4, 40, 20, "get out, QKEY with mouse in script window") r0 = Slider("radius0: ", 2, 180, 86, 180, 20, r0.val, 0.0, 10.0, 0, "base radius of toroid") r1 = Slider("radius1: ", 2, 180, 107, 180, 20, r1.val, 0.0, 5.0, 0, "thickness of toroid") n1 = Slider("ring shape: ", 2, 10, 52, 240, 20, n1.val, 0.0, 5.0, 0, "shape of torus ring") n2 = Slider("segm. shape: ", 2, 10, 31, 240, 20, n2.val, 0.0, 5.0, 0, "shape of cross section of ring") ellipt = Slider("segm. ellipt.:", 2, 140, 4, 220, 20, ellipt.val, -1.0, 1.0, 0, "ellipticity of segments") segments = Number("segments: ", 2, 260, 31, 100, 20, segments.val, 3, 64, "number of segments (vertical)") rings = Number("rings: ", 2, 260, 52, 100, 20, rings.val, 3, 64, "number of rings (horizontal)") rx = Slider("SizeX: ", 2, 10, 116, 160, 17, rx.val, 0.0, 5.0, 0, "size in x-direction") ry = Slider("SizeY: ", 2, 10, 98, 160, 17, ry.val, 0.0, 5.0, 0, "size in y-direction") rz = Slider("SizeZ: ", 2, 10, 80, 160, 17, rz.val, 0.0, 5.0, 0, "size in z-direction") def event(evt, val): if (evt== QKEY and not val): Exit() if (evt==CKEY and not val): if primitive.val == 1: SuperToroid() Redraw() elif primitive.val == 2: SuperEllipsoid() Redraw() def bevent(evt): if (evt== 1): Exit() elif (evt== 3): if primitive.val == 1: SuperToroid() Redraw() elif primitive.val == 2: SuperToroid() Redraw() # if a button is pressed, redraw the gui elif (evt== 2): Redraw() Register(draw, event, bevent)