# Convert blender's 2d Bezier curve into a ShapePath

i have a 2d bezier curve with 4 handles in blender which looks like this:

using this python code i’m trying to convert it into a shape path

``````import bpy
curve = bpy.data.curves['BezierCircle']

path_string = "const shape = new Shape()\n"

for spline in curve.splines:
if spline.type == 'BEZIER':
start_point = spline.bezier_points.co
path_string += ".moveTo(" + str(start_point) + "," + str(start_point) + ")\n"

for i, point in enumerate(spline.bezier_points):

x = point.co
y = point.co

handle_left_x=point.handle_left
handle_left_y = point.handle_left

handle_right_x = point.handle_right
handle_right_y= point.handle_right

path_string += ".bezierCurveTo(" + str(handle_left_x) + "," + str(handle_left_y) + "," + str(handle_right_x) + "," + str(handle_right_y) + "," + str(x) + "," + str(y) + ")\n"

print(path_string)
``````

which prints

``````
const shape = new Shape()
.moveTo(-0.5, 0.0)
.bezierCurveTo(-0.5, -0.2, -0.5, 0.2, -0.5, 0.0)
.bezierCurveTo(-0.2, 0.5, 0.2, 0.5, 0.0, 0.5)
.bezierCurveTo(0.5, 0.2, 0.5, -0.2, 0.5, 0.0)
.bezierCurveTo(0.2, -0.5, -0.2, -0.5, 0.0, -0.5)

``````

on using this as a shapeGeomtery in three js
the shape looks broken

are there any mistakes here ?

the syntax i’m using is

`bezierCurveTo( handle_x1 ,handle_y1 ,handle_x2 ,handle_y2, x ,y )`

Yes, there is a mistake. The control points are messed up. Try this. Does it show correctly?

``````.moveTo(-0.5, 0.0)
.bezierCurveTo(-0.5, -0.2, -0.2, -0.5, 0, -0.5)
.bezierCurveTo(0.2, -0.5, 0.5, -0.2, 0.5, 0)
.bezierCurveTo(0.5, 0.2, 0.2, 0.5, 0, 0.5)
.bezierCurveTo(-0.2, 0.5, -0.5, 0.2, -0.5, 0)
``````
2 Likes indeed it looks correct now.

do you know where in the translation it went wrong ?

Yes.

Your input data is about handles (i.e. one central point, and two points from both sides).

The Bezier curve is defined by 4 points – two end points and two points between them. The command `bezierCurveTo` expects these 4 points in this way:

• point 1 – it is the current point and is not included as parameter
• point 2 – its coordinates give the first two parameters
• point 3 – its coordinates give the next two parameters
• point 4 – its coordinates give the last two parameters

The blue curve is one Bezier curve. You can see its 4 points with blue circles.

2 Likes

I’m a bit late to the party https://codepen.io/prisoner849/pen/qByQRyX

2 Likes

ohhhhh !

when iterating over blender curve’s point i’m just dealing with a single coordinate point and it’s two handles .

i’ll update the python code to use two consecutive points to fill the constructor params

1 Like

does not work without “.js” in imports (firefox)

Hm… works for me both in FF and in Chrome Also works with Opera.

i’m using firefox too, it runs fine for me

it might be time for you to do a factory reset on firefox (don’t forget to backup your bookmarks and stuff),

I also had issues with three js examples which got fixed after a fresh install

1 Like

that image explanation was just what i needed !

New 2d bezier curve drawn in blender:

Updated python script code :

``````import bpy
curve = bpy.data.curves['BezierCircle']

path_string = "const shape = new Shape()\n"

for spline in curve.splines:
if spline.type == 'BEZIER':
start_point = spline.bezier_points.co
path_string += ".moveTo(" + str(round(start_point,2)) + "," + str(round(start_point,2)) + ")\n"

count=len(spline.bezier_points)
for i in range(count):
dat_a=spline.bezier_points[i]

ax,ay=round(dat_a.co,3),round(dat_a.co,3)
al1,al2=round(dat_a.handle_left,3),round(dat_a.handle_left,3)
ar1,ar2=round(dat_a.handle_right,3),round(dat_a.handle_right,3)

if i+1<count:
dat_b=spline.bezier_points[i+1] # connect to next point
else:
dat_b=spline.bezier_points # connect last to first

bx,by=round(dat_b.co,3),round(dat_b.co,3)
bl1,bl2=round(dat_b.handle_left,3),round(dat_b.handle_left,3)
br1,br2=round(dat_b.handle_right,3),round(dat_b.handle_right,3)

path_string += (".bezierCurveTo("
+ str(ar1) + "," + str(ar2) + ","
+ str(bl1) + ","  + str(bl2) + ","
+ str(bx) + "," + str(by) + ")\n")

print(path_string)
``````

which prints

``````const shape = new Shape()
.moveTo(-0.26, 0.3)
.bezierCurveTo(-0.189, 0.336, -0.213, 0.162, -0.137, 0.137)
.bezierCurveTo(0.031, 0.081, 0.221, 0.419, 0.3, 0.261)
.bezierCurveTo(0.336, 0.189, 0.162, 0.213, 0.137, 0.137)
.bezierCurveTo(0.081, -0.031, 0.419, -0.221, 0.261, -0.3)
.bezierCurveTo(0.189, -0.336, 0.213, -0.162, 0.137, -0.137)
.bezierCurveTo(-0.031, -0.081, -0.221, -0.419, -0.3, -0.261)
.bezierCurveTo(-0.336, -0.189, -0.162, -0.213, -0.137, -0.137)
.bezierCurveTo(-0.081, 0.031, -0.419, 0.221, -0.261, 0.3)
``````

and in three js

thank you again @PavelBoytchev

CodePen of this shape (thank you @prisoner849 for the codepen)

3 Likes