#!BPY

"""
Name: 'Torus Primitive'
Blender: 248
Group: 'Add'
Tooltip: 'A torus with some special parameters'
"""

__author__ = ["Wim Van Hoydonck"]
__url__ = ("http://wiki.blender.org/index.php/Scripts/Manual/Add/Torus_Primitive")
__version__ = "248 - 2008-10"

__bpydoc__ = """\

This Script creates a Torus Primitive.Copy the script to .blender/scripts.The script shows up in Scripts Misc

This script has many more options

Than you can find in the normal Torus object.

It is limited to donut shape.

But you can greatly modify the parameters.

This script can create a variety of shapes.

Experimenting is the key. 
.\n\
"""

# ***** BEGIN GPL LICENSE BLOCK ***** 
#(C) Februari 2004 Wim Van Hoydonck 
# 
# This program is free software; you can redistribute it and/or 
# modify it under the terms of the GNU General Public License 
# as published by the Free Software Foundation; either version 2 
# of the License, or (at your option) any later version. 
# 
# This program is distributed in the hope that it will be useful, 
# but WITHOUT ANY WARRANTY; without even the implied warranty of 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
# GNU General Public License for more details. 
# 
# You should have received a copy of the GNU General Public License 
# along with this program; if not, write to the Free Software Foundation, 
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
# 
# ***** END GPL LICENCE BLOCK ***** 
#
# -------------------------------------------------------------------------- 
#############################################################################
#                                                                           #
# Supertoroid Primitive                                                     #
# equations from: http://astronomy.swin.edu.au/~pbourke/                    #
#                                                                           #
# (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   - 28-03-04 - Modified the interface a bit                        #
#                                                                           #
#############################################################################

import Blender
from Blender import *
from Blender.Draw import *
from Blender.BGL import *

from math import pi, sin, cos, fmod

# parameters

# 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)

# segments (vertical)
# rings (horizontal)
segments = Create(16)
rings = Create(16)

# r0: base radius of the torus
# r1: radius of cross section of ring
r0 = Create(1.0)
r1 = Create(0.5)

#=============#
# SuperToroid #
#=============#

def SuperToroid():


	
	try:
		# torus selected
		
		meshname = NMesh.GetNames()
		

		selectedobject = Object.GetSelected()


		
	except:
		# no torus selected, create a new one
		print "nothing selected, creating a new one"
	
	
	# parameters
	# powers of sines and cosines
	n1v = n1.val
	n2v = n2.val

	# segments (meridiaan: vertikaal)
	# rings (breedtegraad: horizontal)
	segmentsv = segments.val
	ringsv = rings.val

	r0v = r0.val
	r1v = r1.val

	dtheta = 2*pi/segmentsv
	dphi = 2*pi/ringsv

	supertoroid = 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)
			y = s1m*(r0v+r1v*c2m)
			z = (r1v*s2m)

			v = NMesh.Vert(x,y,z)
			supertoroid.verts.append(v)

	# make faces
	for i in range(0, segmentsv):
		for j in range(0, ringsv):
			f = NMesh.Face()

			f.v.append(supertoroid.verts[i*ringsv + j])
			f.v.append(supertoroid.verts[i*ringsv + int(fmod(j+1, ringsv))])
			f.v.append(supertoroid.verts[int(fmod((i+1)*ringsv, segmentsv*ringsv)) + int(fmod(j+1, ringsv))])
			f.v.append(supertoroid.verts[int(fmod((i+1)*ringsv, segmentsv*ringsv)) + j])
			f.v.reverse()

			supertoroid.faces.append(f)

	st_ob = NMesh.PutRaw(supertoroid,'torus')

#############################################################
# Graphics                                                  #
#############################################################

def draw():
	global n1, n2, segments, rings, r0, r1

	# Background
	BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
	BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
	BGL.glColor3f(0.2,0.2,0.2)
	BGL.glRectf(2, 2, 370, 180)

	# Text
	BGL.glColor3f(1, 1, 1)
	BGL.glRasterPos2d(10, 160)
	Text("Torus Primitive")
	BGL.glRasterPos2d(10, 140)
	Text("(C) Febr. 2004 Wim Van Hoydonck")

	# Buttons & sliders
	Button("Create", 3, 10, 10, 350, 20, "create torus at cursor position in XY-plane, CKEY with mouse in script window")
	Button("Exit", 1, 320, 145, 40, 20, "get out, QKEY with mouse in script window")

	r0 = Slider("radius0: ", 2, 10, 85, 240, 20, r0.val, 0.0, 10.0, 1, "base radius of toroid")
	r1 = Slider("radius1: ", 2, 10, 106, 240, 20, r1.val, 0.0, 5.0, 1, "thickness of toroid")

	n1 = Slider("ring shape: ", 2, 10, 57, 240, 20, n1.val, 0.0, 5.0, 1, "shape of torus ring; 1: normal torus")
	n2 = Slider("segm. shape: ", 2, 10, 36, 240, 20, n2.val, 0.0, 5.0, 1, "shape of cross section of ring; 1: normal torus")

	rings = Number("rings: ", 2, 260, 57, 100, 20, rings.val, 3, 64, "number of rings (horizontal)")
	segments = Number("segments: ", 2, 260, 36, 100, 20, segments.val, 3, 64, "number of segments (vertical)")



def event(evt, val): 
	if (evt== QKEY and not val):
		Exit()
	if (evt==CKEY and not val):
		SuperToroid()
		Redraw()


def bevent(evt):
	if evt == 1:
		Exit()
	elif evt == 3:
		SuperToroid()
		Redraw()

	# if a button is pressed, redraw the gui
	elif evt == 2:
		SuperToroid()
		Redraw()

Register(draw, event, bevent)