def _init_world(cfg_bg, cfg_light, brick_file_path): # load object from file bpy.ops.import_scene.importldraw(filepath=brick_file_path) bpy.data.objects.remove(bpy.data.objects['LegoGroundPlane']) # create world world = bpy.data.worlds['World'] # set world background path = os.path.join(os.path.dirname(__file__), 'Background2.JPG') print(path) img = bpy.data.images.load(path) world.use_nodes = True nodes = world.node_tree.nodes nodes.clear() ShaderTexCo = nodes.new('ShaderNodeTexCoord') ShaderTexImg = nodes.new('ShaderNodeTexEnvironment') BSDF = nodes.new('ShaderNodeBackground') Output = nodes.new('ShaderNodeOutputWorld') img = bpy.data.images.load(path) ShaderTexImg.image = img links = world.node_tree.links link = links.new(ShaderTexCo.outputs[1], ShaderTexImg.inputs[0]) link = links.new(ShaderTexImg.outputs[0], BSDF.inputs[0]) #link = links.new(ShaderTexImg.outputs[1],BSDF.inputs[1]) link = links.new(BSDF.outputs[0], Output.inputs[0]) # create camera bpy.ops.object.add(type='CAMERA') cam = bpy.context.object bpy.context.scene.camera = cam # move camera position cam.location = cfg['world']['cam']['location'] cam.rotation_euler = Euler(deg2rad(cfg['world']['cam']['rotation']), 'XYZ') bpy.ops.object.light_add(type='SUN', radius=1, align='WORLD', location=(0, 0, 3)) # create light bpy.ops.object.light_add( type=cfg_light['type'], radius=cfg_light['radius'], align='WORLD', location=cfg_light['location'], rotation=deg2rad(cfg_light['rotation']), ) light = bpy.context.object light.data.energy = cfg_light['energy'] if not cfg_light['random']: # set light to camera position constraint = light.constraints.new('COPY_LOCATION') constraint.target = bpy.data.objects['Camera'] return world, cam, light
def _init_world(cfg_bg, cfg_light, brick_file_path): # remove all elements in scene bpy.ops.object.select_by_layer() bpy.ops.object.delete(use_global=False) # create world world = bpy.data.worlds.new("World") world.use_sky_paper = True bpy.context.scene.world = world # set world background world.use_sky_blend = True world.horizon_color = hex2rgb(cfg_bg['horizon_color']) world.zenith_color = hex2rgb(cfg_bg['zenith_color']) world.ambient_color = hex2rgb(cfg_bg['ambient_color']) # load object from file bpy.ops.import_scene.importldraw(filepath=brick_file_path) bpy.data.objects.remove(bpy.data.objects['LegoGroundPlane']) # create camera bpy.ops.object.add(type='CAMERA') cam = bpy.context.object bpy.context.scene.camera = cam # move camera position cam.location = cfg['world']['cam']['location'] cam.rotation_euler = Euler(deg2rad(cfg['world']['cam']['rotation']), 'XYZ') bpy.ops.object.lamp_add(type='SUN', radius=1, view_align=False, location=(0, 0, 3)) # create light bpy.ops.object.lamp_add( type=cfg_light['type'], radius=cfg_light['radius'], view_align=False, location=cfg_light['location'], rotation=deg2rad(cfg_light['rotation']), ) light = bpy.context.object light.data.energy = cfg_light['energy'] if not cfg_light['random']: # set light to camera position constraint = light.constraints.new('COPY_LOCATION') constraint.target = bpy.data.objects['Camera'] return world, cam, light
def render_brick(brick_file_path, number_of_images, render_folder, cfg): # create world, camera, light and background world, cam, light = _init_world(cfg['world']['background'], cfg['world']['light'], brick_file_path) logging.info('initialized world successfully') brick = _get_brick() # possible cam locations cfg_campos = cfg['world']['cam']['augmentation'] if cfg_campos['enabled']: _, _, _, sphere_locations = sphere.get_positions( theta_range=deg2rad(cfg_campos['theta_range']), phi_range=deg2rad(cfg_campos['phi_range']), radius=cfg_campos['radius'], step_size=cfg_campos['step_size'], n_points_circle=cfg_campos['n_points_circle'], zlow=cfg_campos['zlow'], zhigh=cfg_campos['zhigh']) logging.debug('possible cam locations: {}'.format( len(sphere_locations))) render = _render_settings(render_folder, cfg['render']) logging.info("render setup") # default location, rotation, color and size normalization brick = _init_brick(brick, cfg['brick']) logging.info("init brick") # set camera view to center if cfg['world']['cam']['augmentation']['enabled']: constraint = cam.constraints.new('TRACK_TO') constraint.target = brick constraint.track_axis = 'TRACK_NEGATIVE_Z' constraint.up_axis = 'UP_Y' logging.info("camer center") if cfg['world']['background']['surface']['enabled']: random_background_surface() logging.debug("background set") base_scale = deepcopy(brick.scale) # create n images using several augmentation parameters logging.info('start rendering %s images', number_of_images) for i in range(number_of_images): # randomly select one possible camera position if cfg['world']['cam']['augmentation']['enabled']: l = random.choice(sphere_locations) logging.debug('set new camera location: {}'.format(l)) cam.location = l # randomly select one possible position for lighting if cfg['world']['light']['random']: light_position = random.choice(sphere_locations) logging.debug('set new light location: {}'.format(light_position)) light.location = light_position # change bg color if cfg['world']['background']['surface']['enabled']: sf = cfg['world']['background']['surface'] c = random_like_color(grayscale=sf['grayscale'], lower_limit=sf['lower_limit'], upper_limit=sf['upper_limit']) logging.info("Color: {}".format(c)) #bg.data.materials['surfpatch color'].diffuse_color = c +(1,) augmentation = cfg['brick']['augmentation'] if augmentation['rotation']['enabled']: rotx = deg2rad(random.choice(augmentation['rotation']['xvalues'])) brick.rotation_euler[0] = rotx logging.debug( 'rotation parameters: rotx {}, roty {}, rotz {}'.format( rotx, brick.rotation_euler[1], brick.rotation_euler[2])) if augmentation['zoom']['enabled']: zoom_factor = random.uniform(augmentation['zoom']['min'], augmentation['zoom']['max']) #brick.scale = zoom_factor * base_scale delta_location = cam.location - brick.location logging.info(delta_location) #exit(0) logging.debug('zoom factor: {}'.format(zoom_factor)) logging.debug('brick scale {}'.format(brick.scale)) if augmentation['translation']['enabled']: posx = random.uniform(augmentation['translation']['min'], augmentation['translation']['max']) posz = random.uniform(augmentation['translation']['min'], augmentation['translation']['max']) brick.location = (posx, 0.0, posz) logging.debug('brick location after translation: {}'.format( brick.location)) if augmentation['color']['enabled']: _set_brick_color(augmentation['color']['colors'], brick, random_color=True) # render image brick_class = os.path.splitext(os.path.basename(brick_file_path))[0] render.filepath = os.path.join(render_folder, brick_class + '_' + str(i) + '.jpg') bpy.ops.render.render(write_still=True) # remove current background #world.texture_slots.clear(0) return
def _init_brick(brick, cfg_brick): brick.location = cfg_brick['location'] _set_brick_color([cfg_brick['color']], brick, random_color=True) # size normalization: set longest dimension to target size multiple_obj = False if cfg_brick['size_normalization']['enabled']: dim_target = cfg_brick['size_normalization']['target_dim'] try: logging.debug(brick.dimensions) if brick.dimensions[0] == 0.0000: logging.debug(bpy.context.object.dimensions) #Calculate Max Dimension max_dimensions = [] for obj in bpy.context.scene.objects: max_dimensions.append(obj.dimensions) scale_factor = dim_target / max(max(max_dimensions)) brick.scale = brick.scale * scale_factor brick.location = cfg_brick['location'] brick.rotation_euler = Euler(deg2rad(cfg_brick['rotation'])) multiple_obj = True else: scale_factor = dim_target / max(brick.dimensions) brick.dimensions = brick.dimensions * scale_factor logging.debug(scale_factor) logging.debug(brick.dimensions) brick.location = cfg_brick['location'] brick.rotation_euler = Euler(deg2rad(cfg_brick['rotation'])) logging.debug(brick.rotation_euler) logging.debug(brick.scale) logging.debug(brick.location) except Exception as e: logging.error(e) raise e # set new origin to geometry center bpy.ops.object.select_all(action='DESELECT') for obj in bpy.context.scene.objects: if bpy.context.object.name == obj.name: obj.select_set(True) bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS') # set origin to center bpy.context.object.location = cfg_brick['location'] obj.select_set(False) # bpy.context.scene.update() if multiple_obj: #brick = bpy.context.object bpy.ops.object.select_all(action='DESELECT') else: bpy.ops.object.select_all(action='DESELECT') for obj in bpy.context.scene.objects: if brick.name == obj.name: obj.select_set(True) bpy.ops.object.origin_set( type='ORIGIN_GEOMETRY', center='BOUNDS') # set origin to center bpy.context.object.location = cfg_brick['location'] obj.select_set(False) return brick
def _init_brick(brick, cfg_brick): brick.location = cfg_brick['location'] _set_brick_color([cfg_brick['color']], brick, random_color=True) ## if len(brick.children) >= 1: # brick with multiple parts ## logging.debug('brick with multiple objects: %s', brick.children) ## #scene = bpy.context.scene ## # join sub-elements to a new brick ## for obj in brick.children: ## logging.info(obj) ## #scene.collection.objects.link(obj) ## #obj.select_set(True) #obj.select = True ## #bpy.context.collection.objects.link(obj) # bpy.context.scene.collection.objects.active(obj) ## #logging.info(obj.dimensions) ## ## #bpy.ops.object.collection_objects_select() ## logging.info(bpy.context.selected_objects) ## logging.debug(brick.dimensions) ## #bpy.ops.object.join() # combine sub-elements ## #bpy.ops.object.parent_clear(type='CLEAR') # move group outside the parent #remove old brick #bpy.data.objects.remove(bpy.data.objects[brick.name], do_unlink = True) # set the new brick ## logging.info("Selected=",bpy.context.selected_objects[0].name) ## new = False ## for obj in bpy.data.objects: ## if obj.name == bpy.context.selected_objects[0].name: ## new = True ## logging.debug('object name: %s', obj.name) ## brick = obj ## logging.debug('new brick selected: %s', brick) ## if not new: ## e = 'new brick could not be selected' ## logging.error(e) ## raise ValueError(e) # size normalization: set longest dimension to target size multiple_obj = False if cfg_brick['size_normalization']['enabled']: dim_target = cfg_brick['size_normalization']['target_dim'] try: logging.debug(brick.dimensions) if brick.dimensions[0] == 0.0000: logging.debug(bpy.context.object.dimensions) scale_factor = dim_target / max(bpy.context.object.dimensions) bpy.context.object.dimensions = bpy.context.object.dimensions * scale_factor bpy.context.object.location = cfg_brick['location'] #bpy.context.object.rotation_euler = Euler(deg2rad(cfg_brick['rotation'])) multiple_obj = True else: scale_factor = dim_target / max(brick.dimensions) brick.dimensions = brick.dimensions * scale_factor logging.debug(scale_factor) logging.debug(brick.dimensions) brick.location = cfg_brick['location'] brick.rotation_euler = Euler(deg2rad(cfg_brick['rotation'])) logging.debug(brick.rotation_euler) logging.debug(brick.scale) logging.debug(brick.location) except Exception as e: logging.error(e) raise e # set new origin to geometry center bpy.ops.object.select_all(action='DESELECT') for obj in bpy.context.scene.objects: if bpy.context.object.name == obj.name: obj.select_set(True) bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS') # set origin to center bpy.context.object.location = cfg_brick['location'] obj.select_set(False) # bpy.context.scene.update() if multiple_obj: brick = bpy.context.object bpy.ops.object.select_all(action='DESELECT') else: bpy.ops.object.select_all(action='DESELECT') for obj in bpy.context.scene.objects: if brick.name == obj.name: obj.select_set(True) bpy.ops.object.origin_set( type='ORIGIN_GEOMETRY', center='BOUNDS') # set origin to center bpy.context.object.location = cfg_brick['location'] obj.select_set(False) return brick