Schwarze Streifen in Glas

Nov 03 2020

Ich bin ziemlich neu bei Blender und versuche, eine Visualisierung meiner wissenschaftlichen Ergebnisse zu erstellen. Ich habe zunächst Dummy-Daten der Mittellinie erstellt und dann die Bezier-Kurve für die Interpolation verwendet. Dann habe ich ihm eine Abschrägung zugewiesen (ein einfaches Quadrat, definiert durch eine Polylinie) und so ein 3D-Objekt erstellt (ich habe auch die Kappen geschlossen). Zumindest hoffe ich, dass es sich um ein 3D-Objekt handelt. Ich bin mir nicht sicher, ob ich auch eine Füllfunktion verwenden soll.

Trotzdem habe ich es geschafft, all dies zu schaffen, es in eine Umgebung zu bringen, in der ich mein Objekt mit Wänden umgeben und dort ein Licht hineinlegen kann. Ich habe ihm ein glasartiges Material zugewiesen. Beim Rendern (Zyklen) weist mein Bild seltsame schwarze Streifen auf und ich bin mir nicht sicher, wie ich das beheben soll. Ich habe alles in einem Skript, das Sie unten finden können.

Natürlich macht es mir nichts aus, wenn die Lösung nicht in einem Python-Skript enthalten ist, ich werde es schaffen, sie zu konvertieren. Ich möchte nur verstehen, warum sie erscheinen und wie man es löst.

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)

Antworten

3 lemon Nov 03 2020 at 18:42

Sie können dies korrigieren, indem Sie die Formkanten etwas glätten.

In diesem Fall, um es zu tun:

Kehren Sie das Abschrägungsobjekt um (als ob die endgültige Form die Normalen invertiert hätte):

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

Fügen Sie dem "Mittellinien" -Objekt einen Abschrägungsmodifikator hinzu:

# Bevel modifier
bevel_modifier = centerline.modifiers.new("Bevel", "BEVEL")
bevel_modifier.width = 0.005
bevel_modifier.segments = 3
bevel_modifier.limit_method = 'ANGLE'

Hinweis: Zuerst war dies Ätzmittel und das sollte (?) Sein. Obwohl dies nicht , hier zu arbeiten .