I am trying to cut out a section from a "spherical shell of yarn", without much success.
Using a python script, I created a series of coordinates on a spherical surface:
import bpy
import numpy as np
import random
npoints = 100
R0 = 1
a = 1.0-np.random.rand()*2.0
theta = np.random.rand()*2*np.pi
coords = []
for j in range(npoints):
b = (np.random.rand()-0.5)/np.sqrt(npoints)*2
if (a+b > 1.0 or a+b < -1.0):
a = a-b
else:
a = a+b
phi = np.arccos(a)
theta += np.random.rand()*2*np.pi/npoints
R = R0*(1.0+np.random.rand()/10.)
coords.append((R*np.cos(theta)*np.sin(phi), R*np.sin(theta)*np.sin(phi), R*np.cos(phi)))
# create the Curve Datablock
curveData = bpy.data.curves.new('myCurve', type='CURVE')
curveData.dimensions = '3D'
curveData.resolution_u = 2
curveData.fill_mode = 'FULL'
curveData.bevel_depth = 0.02
#curveData.materials.append(mat1)
# map coords to spline
polyline = curveData.splines.new('NURBS')
polyline.points.add(len(coords))
for i, coord in enumerate(coords):
x,y,z = coord
polyline.points[i].co = (x, y, z, 1)
# create Object
curveOB = bpy.data.objects.new('myCurve', curveData)
curveOB.rotation_euler = (np.pi-2.*np.random.rand()*np.pi,np.pi-2.*np.random.rand()*2.*np.pi,np.pi-np.random.rand()*np.pi) # Note that you need to use radians rather than angles here
# attach to scene and validate context
scn = bpy.context.scene
scn.objects.link(curveOB)
scn.objects.active = curveOB
curveOB.select = False
This generates a shell of yarn, as showed in the image below.
I would like now to cut out a quarter of this spherical shell. To do that, I tought to add a cube to the scene and apply the boolean operator "difference" to all of the curves. Indeed, this strategy does not work as I cannot aplly a boolean operator to the bezier curves... I am now wondering how to proceed.
Could another option be to identify all coordinates of the bezier which are found in a certain region of the scene and eliminate them?
Addition after the comment, stating if I cannot modify the script. I can, but the result is not as i wanted. What I can do, is to rotate the chain with the script, and eliminate all the coordinates which are located in a certain volume. But then, when I create the curve, all the coordinates will be connected, and therefore there will be still chain segments (straight) in the area I wanto to free.
Once the coordinates of the chain were created, I rotated it with
def randomrot(coords):
x = 2.*np.random.rand()*np.pi -np.pi #random angle between 0 and 2pi
y = 2.*np.random.rand()*np.pi #random angle between 0 and 2pi
z = 2.*np.random.rand()*np.pi #random angle between 0 and 2pi
Rx = [[1., 0., 0.], [0., np.cos(x), -np.sin(x)], [0., np.sin(x), np.cos(x)]]
Ry = [[np.cos(y), 0., np.sin(y)], [0., 1.0, 0.0], [-np.sin(y), 0.0, np.cos(y)]]
Rz = [[np.cos(z), -np.sin(z), 0.], [np.sin(z), np.cos(z), 0.0], [0., 0., 1.]]
return np.matmul(np.matmul(np.matmul(coords,Rx),Ry),Rz)
Then I can cut out all the points from the coordinate list which are located in a certain volume with:
for i in range(len(rotcoords)): #cuts the top quarter corner of the polymer sghell
if rotcoords[i,0] < 0.0 and rotcoords[i,1] < 0.0 and rotcoords[i,2] > 0.5:
None
else:
newcoords.append(new[i,:])
The output then looks so:
Many greets, Leo