Camda siyah şeritler
Blender'da oldukça yeniyim ve bilimsel sonuçlarımın bir görselleştirmesini oluşturmaya çalışıyorum. Merkez hattının sahte verilerini oluşturarak başladım ve ardından enterpolasyon için Bezier eğrisini kullandım. Sonra ona eğim verdim (çoklu çizgi ile tanımlanan basit bir kare) ve böylece bir 3B nesne oluşturdum (kapakları da kapattım). En azından umarım bu bir 3D nesne, bazı doldurma işlevini de kullanmam gerekip gerekmediğinden emin değilim.
Yine de tüm bunları yaratmayı, nesnemi duvarlarla çevrelediğim ve oraya bir ışık koyduğum bir ortama koymayı başardım. Cam gibi bir malzeme verdim. İşlediğimde (döngüleri), resmimde garip siyah çizgiler var ve nasıl düzelteceğimi bilmiyorum. Hepsini aşağıda bulabileceğiniz bir senaryoda bulabilirsiniz.
Elbette, çözümün bir Python betiğinde olmaması umurumda değil, onu dönüştürmeyi başaracağım. Sadece neden ortaya çıktıklarını ve nasıl çözüleceğini anlamak istiyorum.
import bpy
import numpy as np
# delete everything
print("\n\n\n\nNew run")
objs = [ob for ob in bpy.context.scene.objects]
bpy.ops.object.delete({"selected_objects": objs})
print("\n\n\n\n")
def dump(obj):
for attr in dir(obj):
if hasattr( obj, attr ):
print( "obj.%s = %s" % (attr, getattr(obj, attr)))
def polyline_from(coords, name, closed):
# create the Curve Datablock
curvedata = bpy.data.curves.new(name, type='CURVE')
curvedata.dimensions = '3D'
# map coords to spline
polyline = curvedata.splines.new('POLY')
polyline.points.add(len(coords)-1)
for i, coord in enumerate(coords):
x,y = coord
polyline.points[i].co = (x, y, 0, 1)
if(closed):
polyline.use_cyclic_u = True
# create Object
objectdata = bpy.data.objects.new(name+"Object", curvedata)
return objectdata
def curve_from(coords, name, closed, res=10):
# create the Curve Datablock
curvedata = bpy.data.curves.new(name, type='CURVE')
curvedata.dimensions = '3D'
curvedata.resolution_u = res
# map coords to spline
spline = curvedata.splines.new('BEZIER')
spline.bezier_points.add(len(coords)-1)
for i, p in enumerate(spline.bezier_points):
x,y,z = coords[i]
p.co = (x, y, z)
p.handle_left = (x, y, z)
p.handle_right = (x, y, z)
#Set automatic
p.handle_right_type = 'AUTO'
p.handle_left_type = 'AUTO'
if(closed):
spline.use_cyclic_u = True
# create Object
objectdata = bpy.data.objects.new(name+"Object", curvedata)
return objectdata
# create scene
scene = bpy.context.scene
scene.world.color = (0,0,0)
# select render engine
scene.render.engine = 'CYCLES'
# Set render resolution
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080
# Generate fake data
def data(t):
x = np.linspace(0, 1, 10)
y = 0*x
z = x**2 * 0.2 * np.sin(t)
return np.array([x, y, z]).T
centerline_points = data(0)
# Cross section
cross_section_points = 0.5*np.array([
[-0.1,-0.1],
[ 0.1,-0.1],
[ 0.1, 0.1],
[-0.1, 0.1]
])
centerline = curve_from(
coords=centerline_points,
name="Centerline",
closed=False,
res=13
)
cross_section = polyline_from(
coords=cross_section_points,
name="CrossSection",
closed=True
)
# add bevel object
centerline.data.bevel_object = cross_section
centerline.data.use_fill_caps = True
# attach to scene and validate context
scene.collection.objects.link(centerline)
# clear all previous animation data
centerline.animation_data_clear()
# set first and last frame index
total_time = 2*np.pi # Animation should be 2*pi seconds long
fps = 10 # Frames per second (fps)
scene.frame_start = 0
scene.frame_end = int(total_time*fps)+1
# loop of frames and insert keyframes every 10th frame
keyframe_freq = 1
nlast = bpy.context.scene.frame_end
for n in range(nlast):
t = total_time*n/nlast
# Do computations
new_points = data(t)
# Check if n is a multiple of keyframe_freq
if n%keyframe_freq == 0:
# Set frame like this
scene.frame_set(n)
# Set current location like this
for (i, p) in enumerate(centerline.data.splines.active.bezier_points):
x,y,z = new_points[i]
p.co = (x,y,z)
p.keyframe_insert(data_path="co")
p.handle_left = (x, y, z)
p.keyframe_insert(data_path="handle_left")
p.handle_right = (x, y, z)
p.keyframe_insert(data_path="handle_right")
# create material
material = bpy.data.materials.new("Material")
centerline.active_material = material
material.use_nodes = True
material.node_tree.links.remove(material.node_tree.links[0])
material.node_tree.nodes.remove(material.node_tree.nodes['Principled BSDF'])
glass_node = material.node_tree.nodes.new("ShaderNodeBsdfGlass")
glass_node.inputs["Color"].default_value = (0.0, 0.8, 1.0, 1.0)
glass_node.inputs["Roughness"].default_value = 0.1
material.node_tree.links.new(material.node_tree.nodes["Material Output"].inputs["Surface"], glass_node.outputs["BSDF"])
# create plane
minx = -0.1
maxx = 1.1
miny = -0.25
maxy = 0.25
minz = -0.25
maxz = 0.25
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,0.0,minz), rotation=(0.0,0.0,0.0))
basez1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,0.0,15), rotation=(0.0,0.0,0.0))
basez2 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,-15,0.0), rotation=(-np.pi/2,0.0,0.0))
basey1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(0.0,15,0.0), rotation=(np.pi/2,0.0,0.0))
basey2 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(-15,0.0,0.0), rotation=(0.0,-np.pi/2,0.0))
basex1 = bpy.context.active_object
bpy.ops.mesh.primitive_plane_add(size=30, location=(15,0.0,0.0), rotation=(0.0,np.pi/2,0.0))
basex2 = bpy.context.active_object
# create material
base_material = bpy.data.materials.new("BaseMaterial")
base_material.use_nodes = True
base_bsdf = base_material.node_tree.nodes["Principled BSDF"]
texture_image = base_material.node_tree.nodes.new('ShaderNodeTexImage')
texture_path = "/Users/jantomec/Downloads/fabric_pattern_05_8k_png/fabric_pattern_05_rough_8k.png"
texture_image.image = bpy.data.images.load(texture_path)
texture_image.texture_mapping.scale = (10,10,10)
base_material.node_tree.links.new(base_bsdf.inputs['Base Color'], texture_image.outputs['Color'])
basez1.active_material = base_material
basez2.active_material = base_material
basey1.active_material = base_material
basey2.active_material = base_material
basex1.active_material = base_material
basex2.active_material = base_material
# add light
# create light datablock, set attributes
light_data = bpy.data.lights.new(name="light_2.80", type='POINT')
light_data.energy = 10000
light_data.cycles.samples = 4
# create new object with our light datablock
light_object = bpy.data.objects.new(name="Light", object_data=light_data)
light_object.location = (7,-10,10)
# link light object
bpy.context.collection.objects.link(light_object)
# add camera
camera_data = bpy.data.cameras.new(name='Camera')
camera_object = bpy.data.objects.new('Camera', camera_data)
bpy.context.scene.collection.objects.link(camera_object)
# Set camera fov in degrees
camera_object.data.angle = 35*np.pi/180.0
# Set camera rotation in euler angles
xc = 1.3
yc = -3.0
zc = 0.75
midpoint = [(minx+maxx)/2, (miny+maxy)/2, (minz+maxz)/2]
camera_object.rotation_mode = 'XZY'
camera_object.rotation_euler[0] = np.pi/2
camera_object.rotation_euler[2] = np.arctan2(xc - midpoint[0], -(yc - midpoint[1]))
camera_object.rotation_euler[0] = np.pi/2 - np.arctan2(zc, np.sqrt((xc - midpoint[0])**2 * (yc-midpoint[1])**2)) + 0.07
# Set camera translation
camera_object.location = (xc, yc, zc)
Yanıtlar
Şekil kenarlarını biraz düzleştirerek bunu düzeltebilirsiniz.
Bu durumda yapmak için:
Eğim nesnesini ters çevirin (sanki öyle değil, son şeklin ters normalleri var):
#Reversed indices to make the final shape correctly oriented
cross_section_points = 0.5*np.array([
[-0.1, 0.1],
[ 0.1, 0.1],
[ 0.1,-0.1],
[-0.1,-0.1]
])
"Merkez çizgisi" nesnesine bir Eğim değiştirici ekleyin:
# Bevel modifier
bevel_modifier = centerline.modifiers.new("Bevel", "BEVEL")
bevel_modifier.width = 0.005
bevel_modifier.segments = 3
bevel_modifier.limit_method = 'ANGLE'
Not: ilk olarak bu kostikti ve bu (?) Olmalıdır. Yine de, bu burada çalışmıyor .