Ok,
This thread is dedicated to creating a python script that will make a valid circle in Blender.
You should be able for pass it a radius and it will generate a bezier curve circle.
That said, here is what I know about point on a circle code: (I am learning python and don’t have the syntax, so I am posting VB for now.)
radius = 10
for n = 0 to 360
x = cos(n) * radius
y = sin (n) * radius
next
Ok, yeah, we have point on a circle. let’s turn it into a function.
function (passedRadius, passedPointCount) as array
for n = 0 to 360 step (360/passedPointCount)
x = cos(n) * passedRadius
y = sin(n) * passed Radius
tempArray (n) = trim$(x) & "," & trim$(y)
next
return tempArray
Ok, I know that is a hack, but the intention is to have a funtion that will return an array of points when you give it a radius and point count.
So now we have an array of x,y coordinates that are points on a circle at a given radius.
Time for python now…
from Blender import Curve, Object, Scene
c = Curve.New() # create new curve data
cur = Scene.getCurrent() # get current scene
ob = Object.New('Curve') # make curve object
ob.link(c) # link curve data with this object
cur.link(ob) # link object into scene
This code, of course, does not work and crashes on line 1.
But the basic premise is here.
The question is, how do I link my array of coordinates into these objects?
A bezier circle can be defined by four points (knots) equally spaced around the circle. Actually you could probably do it with any number >= 2 if you were tricky. With four though you only need to create auto handles and the circle shall appear…
There is unfortunatly a bug in Blender 2.42a that prevents curve handles from being recalculated when they are made by a script. I think it is fixed in cvs though. If you want I could post some code to draw a bezier circle.
Drawing a circle with a mesh on the other hand is a much more difficult problem. With curves you should define as few control points as possible because the curve will interpolate between points - that is the point of using curves! On a mesh though you can only make straight segments, so you have to decide how many verts to put around a circle, and of course bigger circles will need more verts to stay smooth…
Gimme a little bit, the code I have is part of a larger script…
Okay, that was easy:
import Blender
from Blender import BezTriple, Curve, Mathutils, Object, Scene
c = Curve.New() # create new curve data
cur = Scene.getCurrent() # get current scene
ob = Object.New('Curve') # make curve object
ob.link(c) # link curve data with this object
cur.link(ob) # link object into scene
center = (5,5,0)
radius = 5
AUTO = BezTriple.HandleTypes.AUTO
# Build four points at radius distance in the four cardnal directions
p1 = (0, -radius, 0)
p2 = (radius, 0, 0)
p3 = (0, radius, 0)
p4 = (-radius, 0, 0)
p1 = BezTriple.New(p1)
p2 = BezTriple.New(p2)
p3 = BezTriple.New(p3)
p4 = BezTriple.New(p4)
# Can't have a curve without points...
curve = c.appendNurb(p1)
curve.append(p2)
curve.append(p3)
curve.append(p4)
# Set both handles to auto for each point
for point in curve:
point.handleTypes = [AUTO, AUTO]
curve.flagU = 1 # Set curve cyclic
c.update()
ob.loc = center # Put it where it goes
Blender.Redraw()
This is actually the test code I wrote while trying to figure out how to do this myself. I think I have a nice version wrapped in a function in the code I mentioned above, but I found this first
I tested it and it works under the current cvs! On 2.42a it draws a square instead of a circle though :rolleyes:
#Create a circular path for Blender 2.42a
import Blender
from Blender import *
import math
from math import *
def makeCircle(passedNumberOfPoints, passedRadius):
c = Curve.New()
c.setPathLen(300)
c.setFlag(8)
z = 0 # 2D Drawing for now.
w = 1 #Weight is 1.
final_x = 0
final_y = 0
angleStep = 360/ passedNumberOfPoints
for ang in range(0, 359,angleStep):
x = passedRadius * math.cos(math.radians(ang))
y = passedRadius * math.sin(math.radians(ang))
if (ang ==0):
final_x = x
final_y = y
c.appendNurb([x,y,z,w])
c[0].type = 0 # Poly line
else:
c.appendPoint(0,[x,y,z,w,0]) # Can add tilt here with w.
c.appendPoint(0,[final_x,final_y,z,w,0]) # Can add tilt here.
c.update()
scn = Scene.GetCurrent() # New Curve and add to Scene.
ob = Object.New('Curve')
ob.setName ("PolyBezier")
ob.link(c)
scn.link(ob)
ob.sel = 1 # Make active and selected
makeCircle(16,5)