def add_particles(context, surface_area: float, height: float, coverage: float, snow_object: bpy.types.Object, ballobj: bpy.types.Object): # Approximate the number of particles to be emitted number = int(surface_area * 50 * (height ** -2) * ((coverage / 100) ** 2)) bpy.ops.object.particle_system_add() particles = snow_object.particle_systems[0] psettings = particles.settings psettings.type = 'HAIR' psettings.render_type = 'OBJECT' # Generate random number for seed random_seed = random.randint(0, 1000) particles.seed = random_seed # Set particles object psettings.particle_size = height psettings.instance_object = ballobj psettings.count = number # Convert particles to mesh bpy.ops.object.select_all(action='DESELECT') context.view_layer.objects.active = ballobj ballobj.select_set(True) bpy.ops.object.convert(target='MESH') snow = bpy.context.active_object snow.scale = [0.09, 0.09, 0.09] bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY') bpy.ops.object.select_all(action='DESELECT') snow_object.select_set(True) bpy.ops.object.delete() snow.select_set(True) return snow
def export_geom(filepath: str, obj: bpy.types.Object, keep_vertex_order=True, use_selection=True, **kwargs): bpy.ops.object.mode_set(mode='OBJECT', toggle=False) bpy.ops.object.select_all(action="DESELECT") obj.select_set(True) ext = filepath.split('.')[-1] if ext == "obj": bpy.ops.export_scene.obj(filepath=filepath, keep_vertex_order=keep_vertex_order, use_selection=use_selection, **kwargs) elif ext == "fbx": bpy.ops.export_scene.fbx(filepath=filepath, use_selection=use_selection, **kwargs) elif ext == "glb": bpy.ops.export_scene.gltf(filepath=filepath, **kwargs) elif ext == "x3d": bpy.ops.export_scene.x3d(filepath=filepath, **kwargs) elif ext == "ply": bpy.ops.export_mesh.ply(filepath=filepath, **kwargs) elif ext == "stl": bpy.ops.export_mesh.stl(filepath=filepath, **kwargs) else: raise Exception("Illegal extension") print(f"Exported {obj.name} to {filepath}")
def bake_animation(original_obj: bpy.types.Object, first_frame: int, last_frame: int): """Bakes animation between given first and last frame. Args: original_obj (bpy.types.Object): Object to bake first_frame (int): First frame last_frame (int): Last Frame """ bpy.context.view_layer.objects.active = original_obj original_obj.select_set(True) original_name = bpy.context.active_object.name bpy.context.scene.frame_current = first_frame bpy.ops.node.sverchok_update_all() bpy.ops.object.duplicate() bpy.context.active_object.name = f"Baked_{original_name}" bpy.context.active_object.data.name = f"Baked_{original_name}" bpy.data.objects[original_name].select_set(state=True) bpy.ops.object.join_shapes() for act_frame in range(first_frame + 1, last_frame + 1): _bake_frame(act_frame) bpy.ops.object.select_all(action="DESELECT") bpy.context.view_layer.objects.active = None
def extract_plane_from_room(obj: bpy.types.Object, used_split_height: float, up_vec: mathutils.Vector, new_name_for_obj: str): """ Extract a plane from the current room object. This uses the FloorExtractor Module functions :param obj: The current room object :param used_split_height: The height at which the split should be performed. Usually 0 or self.wall_height :param up_vec: The up_vec corresponds to the face.normal of the selected faces :param new_name_for_obj: This will be the new name of the created object :return: (bool, bpy.types.Object): Returns True if the object was split and also returns the object. \ Else it returns (False, None). """ compare_height = 0.15 compare_angle = math.radians(7.5) obj.select_set(True) bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_all(action='DESELECT') bm = bmesh.from_edit_mesh(mesh) bm.faces.ensure_lookup_table() # Select faces at given height that should be separate from the mesh counter = FloorExtractor.select_at_height_value( bm, used_split_height, compare_height, mathutils.Vector(up_vec), compare_angle, obj.matrix_world) # if any faces are selected split them up if counter: bpy.ops.mesh.separate(type='SELECTED') bpy.ops.object.mode_set(mode='OBJECT') bm.free() mesh.update() cur_selected_objects = bpy.context.selected_objects if cur_selected_objects: if len(cur_selected_objects) == 2: cur_selected_objects = [ o for o in cur_selected_objects if o != bpy.context.view_layer.objects.active ] cur_selected_objects[0].name = new_name_for_obj cur_created_obj = cur_selected_objects[0] else: raise Exception( "There is more than one selection after splitting, this should not happen!" ) else: raise Exception("No floor object was constructed!") bpy.ops.object.select_all(action='DESELECT') return True, cur_created_obj else: bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action='DESELECT') return False, None
def clear_selection(mesh_obj: bpy.types.Object): """Make sure that the editor is in the following state: * OBJECT_MODE * selected: one object, the mesh object. * active: the mesh object. """ # Switch to OBJECT mode bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action='DESELECT') # Deselect all objects # The MESH object will be the active and the only selected object mesh_obj.select_set(True) bpy.context.view_layer.objects.active = mesh_obj
def disposable_mode(bl_obj: bpy.types.Object, mode='OBJECT'): ''' モードを変更して元のモードに戻る ''' bpy.context.view_layer.objects.active = bl_obj bl_obj.select_set(True) restore = MODE_MAP[bpy.context.mode] try: if restore != mode: bpy.ops.object.mode_set(mode=mode, toggle=False) yield None finally: if bpy.context.mode != restore: bpy.ops.object.mode_set(mode=restore, toggle=False) bl_obj.select_set(False)
def project_uv_normal( arg_object: bpy.types.Object) -> bpy.types.MeshUVLoopLayer: """通常のUV展開を実行する Args: arg_object (bpy.types.Object): 指定オブジェクト Returns: bpy.types.MeshUVLoopLayer: 作成UVマップレイヤーの参照 """ # 不要なオブジェクトを選択しないように # 全てのオブジェクトを走査する for ob in bpy.context.scene.objects: # 非選択状態に設定する ob.select_set(False) # オブジェクトを選択状態にする arg_object.select_set(True) # 対象オブジェクトをアクティブに変更する bpy.context.view_layer.objects.active = arg_object # 編集モードに移行する bpy.ops.object.mode_set(mode='EDIT', toggle=False) # 頂点を全選択した状態とする bpy.ops.mesh.select_all(action='SELECT') # 通常のUV展開を実行する # 方式:アングルベース,穴を埋める:True,アスペクト比の補正:True, # 細分化モディファイアを使用:False,余白:0.1 bpy.ops.uv.unwrap(method='ANGLE_BASED', fill_holes=True, correct_aspect=True, use_subsurf_data=False, margin=0.1) # オブジェクトモードに移行する bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # 対象オブジェクトに追加されたUVマップを取得する active_uvlayer = arg_object.data.uv_layers[-1] return active_uvlayer
def project_uv_smart( arg_object: bpy.types.Object) -> bpy.types.MeshUVLoopLayer: """スマートUV展開を実行する Args: arg_object (bpy.types.Object): 指定オブジェクト Returns: bpy.types.MeshUVLoopLayer: 作成UVマップレイヤーの参照 """ # 不要なオブジェクトを選択しないように # 全てのオブジェクトを走査する for ob in bpy.context.scene.objects: # 非選択状態に設定する ob.select_set(False) # オブジェクトを選択状態にする arg_object.select_set(True) # 対象オブジェクトをアクティブに変更する bpy.context.view_layer.objects.active = arg_object # 編集モードに移行する bpy.ops.object.mode_set(mode='EDIT', toggle=False) # 頂点を全選択した状態とする bpy.ops.mesh.select_all(action='SELECT') # スマートUV展開を実行する # 角度制限:66,島の余白:0.1,エリアウェイト:0,アスペクト比の補正:True,UV境界に合わせる:True bpy.ops.uv.smart_project(angle_limit=66, island_margin=0.1, user_area_weight=0, use_aspect=True, stretch_to_bounds=True) # オブジェクトモードに移行する bpy.ops.object.mode_set(mode='OBJECT', toggle=False) # 対象オブジェクトに追加されたUVマップを取得する active_uvlayer = arg_object.data.uv_layers[-1] return active_uvlayer
def apply(o: bpy.types.Object): o.select_set(True) bpy.ops.object.transform_apply(location=False, rotation=True, scale=False) o.select_set(False)
def set_select(obj: bpy.types.Object, select: bool) -> None: if IS_LEGACY: obj.select = select else: obj.select_set(select)
def setup_material(material: bpy.types.Material, empty: bpy.types.Object = None): """Setup material nodes for the metal tool cap""" # TODO: refactor into smaller node-creation functions that can be re-used elsewhere # logger = get_logger() tree = material.node_tree nodes = tree.nodes # check if we have default nodes n_output, n_bsdf = mutil.check_default_material(material) # set BSDF default values n_bsdf.inputs['Subsurface'].default_value = 0.6 n_bsdf.inputs['Subsurface Color'].default_value = (0.8, 0.444, 0.444, 1.0) n_bsdf.inputs['Metallic'].default_value = 1.0 # thin metallic surface lines (used primarily for normal/bump map computation) n_texcoord_bump = nodes.new('ShaderNodeTexCoord') # setup empty (reference for distance computations) if empty is None: # get currently selected object obj = bpy.context.object # add empty bpy.ops.object.empty_add(type='PLAIN_AXES') empty = bpy.context.object # locate at the top of the object v0 = Vector(obj.bound_box[1]) v1 = Vector(obj.bound_box[2]) v2 = Vector(obj.bound_box[5]) v3 = Vector(obj.bound_box[6]) empty.location = (v0 + v1 + v2 + v3) / 4 # rotate into object space. afterwards we'll have linkage via parenting empty.location = obj.matrix_world @ empty.location # copy rotation empty.rotation_euler = obj.rotation_euler # deselect all bpy.ops.object.select_all(action='DESELECT') # take care to re-select everything empty.select_set(state=True) obj.select_set(state=True) # make obj active again (will become parent of all selected objects) bpy.context.view_layer.objects.active = obj # make parent, keep transform bpy.ops.object.parent_set(type='OBJECT', xmirror=False, keep_transform=True) # set the empty as input for the texture n_texcoord_bump.object = empty # (dot)^2 (distance from empty) n_dot = nodes.new('ShaderNodeVectorMath') n_dot.operation = 'DOT_PRODUCT' tree.links.new(n_texcoord_bump.outputs['Object'], n_dot.inputs[0]) tree.links.new(n_texcoord_bump.outputs['Object'], n_dot.inputs[1]) n_pow = nodes.new('ShaderNodeMath') n_pow.operation = 'POWER' tree.links.new(n_dot.outputs[1], n_pow.inputs[0]) # mapping input from empty to noise n_mapping = nodes.new('ShaderNodeMapping') tree.links.new(n_texcoord_bump.outputs['Object'], n_mapping.inputs[0]) # generate and link up required noise textures n_noise0 = nodes.new('ShaderNodeTexNoise') n_noise0.inputs['Scale'].default_value = 1.0 n_noise0.inputs['Detail'].default_value = 1.0 n_noise0.inputs['Distortion'].default_value = 2.0 tree.links.new(n_pow.outputs[0], n_noise0.inputs[0]) n_noise1 = nodes.new('ShaderNodeTexNoise') n_noise1.inputs['Scale'].default_value = 300.0 n_noise1.inputs['Detail'].default_value = 0.0 n_noise1.inputs['Distortion'].default_value = 0.0 tree.links.new(n_pow.outputs[0], n_noise1.inputs[0]) # XXX: is this noise required? n_noise2 = nodes.new('ShaderNodeTexNoise') n_noise2.inputs['Scale'].default_value = 0.0 n_noise2.inputs['Detail'].default_value = 0.0 n_noise2.inputs['Distortion'].default_value = 0.1 tree.links.new(n_mapping.outputs['Vector'], n_noise2.inputs[0]) n_noise3 = nodes.new('ShaderNodeTexNoise') n_noise3.inputs['Scale'].default_value = 5.0 n_noise3.inputs['Detail'].default_value = 2.0 n_noise3.inputs['Distortion'].default_value = 0.0 tree.links.new(n_mapping.outputs['Vector'], n_noise3.inputs[0]) # color output n_colorramp_col = nodes.new('ShaderNodeValToRGB') n_colorramp_col.color_ramp.color_mode = 'RGB' n_colorramp_col.color_ramp.interpolation = 'LINEAR' n_colorramp_col.color_ramp.elements[0].position = 0.118 n_colorramp_col.color_ramp.elements[1].position = 0.727 tree.links.new(n_noise0.outputs['Fac'], n_colorramp_col.inputs['Fac']) n_output_color = nodes.new('ShaderNodeMixRGB') n_output_color.inputs['Fac'].default_value = 0.400 n_output_color.inputs['Color1'].default_value = (0.485, 0.485, 0.485, 1.0) tree.links.new(n_colorramp_col.outputs['Color'], n_output_color.inputs['Color2']) # roughness finish n_mul_r = nodes.new('ShaderNodeMath') n_mul_r.operation = 'MULTIPLY' n_mul_r.inputs[1].default_value = 0.100 tree.links.new(n_noise3.outputs['Fac'], n_mul_r.inputs[0]) n_output_roughness = nodes.new('ShaderNodeMath') n_output_roughness.operation = 'ADD' n_output_roughness.inputs[1].default_value = 0.050 tree.links.new(n_mul_r.outputs[0], n_output_roughness.inputs[0]) # math nodes to mix noise with distance and get ring-effect (modulo), leading to bump map n_add0 = nodes.new('ShaderNodeMath') n_add0.operation = 'ADD' tree.links.new(n_pow.outputs[0], n_add0.inputs[0]) tree.links.new(n_noise2.outputs['Fac'], n_add0.inputs[1]) n_mul0 = nodes.new('ShaderNodeMath') n_mul0.operation = 'MULTIPLY' n_mul0.inputs[1].default_value = 300.000 tree.links.new(n_add0.outputs[0], n_mul0.inputs[0]) n_mod0 = nodes.new('ShaderNodeMath') n_mod0.operation = 'MODULO' n_mod0.inputs[1].default_value = 2.000 tree.links.new(n_mul0.outputs[0], n_mod0.inputs[0]) n_mul1 = nodes.new('ShaderNodeMath') n_mul1.operation = 'MULTIPLY' tree.links.new(n_noise1.outputs['Fac'], n_mul1.inputs[0]) tree.links.new(n_mod0.outputs[0], n_mul1.inputs[1]) n_min_n = nodes.new('ShaderNodeMath') n_min_n.operation = 'MINIMUM' tree.links.new(n_noise1.outputs['Fac'], n_min_n.inputs[0]) tree.links.new(n_mul1.outputs[0], n_min_n.inputs[1]) n_colorramp_rough = nodes.new('ShaderNodeValToRGB') n_colorramp_rough.color_ramp.color_mode = 'RGB' n_colorramp_rough.color_ramp.interpolation = 'LINEAR' n_colorramp_rough.color_ramp.elements[0].position = 0.159 n_colorramp_rough.color_ramp.elements[1].position = 0.541 tree.links.new(n_min_n.outputs[0], n_colorramp_rough.inputs[0]) n_output_normal = nodes.new('ShaderNodeBump') n_output_normal.inputs['Strength'].default_value = 0.075 n_output_normal.inputs['Distance'].default_value = 1.000 tree.links.new(n_colorramp_rough.outputs['Color'], n_output_normal.inputs['Height']) # output nodes: # n_output_color -> color / outputs['Color'] # n_output_roughness -> roughness / outputs['Value'] # n_output_normal -> normal / outputs['Normal'] # hook to bsdf shader node tree.links.new(n_output_color.outputs['Color'], n_bsdf.inputs['Base Color']) tree.links.new(n_output_roughness.outputs['Value'], n_bsdf.inputs['Roughness']) tree.links.new(n_output_normal.outputs['Normal'], n_bsdf.inputs['Normal'])
def bake_roughness_only(arg_object: bpy.types.Object, arg_refobjects: list = [], arg_bakemargin: int = 0, arg_onesample: bool = False, arg_GPUuse: bool = False): """指定オブジェクトのカラー情報のみをベイクする Args: arg_object (bpy.types.Object): 指定オブジェクト arg_refobjects (list): ベイク参照元オブジェクトリスト. Defaults to []. arg_bakemargin (int, optional): ベイク余白. Defaults to 0. arg_onesample (bool, optional): 簡易サンプリング指定. Defaults to False. arg_GPUuse (bool, optional): GPU利用指定. Defaults to False. """ # [選択->アクティブ]のベイクフラグを作成する selected_to_active = False # 参照元オブジェクトが設定されているか確認する if len(arg_refobjects) > 0: # 参照元オブジェクトが設定されている場合は[選択->アクティブ]のベイクを実行する selected_to_active = True # 全てのオブジェクトを非選択状態にする for obj in bpy.context.scene.objects: # 選択状態を解除する obj.select_set(False) # [選択->アクティブ]のベイクか確認する if selected_to_active == True: # 参照元オブジェクトリストを走査する for refobject in arg_refobjects: # [選択->アクティブ]のベイクの場合、参照元オブジェクトを選択状態にする refobject.select_set(True) # 指定オブジェクトを選択状態にする arg_object.select_set(True) # 指定オブジェクトをアクティブにする bpy.context.view_layer.objects.active = arg_object # レンダリングエンジンを CYCLES に切り替える bpy.context.scene.render.engine = 'CYCLES' # GPUの利用有無を確認する if arg_GPUuse == True: # 利用設定ならGPUの設定を行う bpy.context.scene.cycles.device = 'GPU' # CUDAを選択する bpy.context.preferences.addons[ 'cycles'].preferences.compute_device_type = 'CUDA' # デバイスの一覧を取得する for devices in bpy.context.preferences.addons[ 'cycles'].preferences.get_devices(): for device in devices: # デバイスタイプがCUDAならば利用対象とする if device.type == 'CUDA': device.use = True # render.bake の設定項目を予め設定する bake_setting = bpy.context.scene.render.bake # [選択->アクティブ]のベイクか確認する if selected_to_active == True: # [選択->アクティブ]のベイクを有効化する bake_setting.use_selected_to_active = True # レイの距離を 0.001 (近距離)に設定する bake_setting.cage_extrusion = 0.01 else: # [選択->アクティブ]のベイクを無効化する bake_setting.use_selected_to_active = False # 現在のサンプリング数を記録する current_samples = bpy.context.scene.cycles.samples current_preview_samples = bpy.context.scene.cycles.preview_samples # 簡易サンプリングが有効かチェックする if arg_onesample == True: # サンプリング数を減らす bpy.context.scene.cycles.samples = 1 bpy.context.scene.cycles.preview_samples = 1 # 「粗さ」タイプのベイクを実行する # ベイクの種類 # ('COMBINED', 'AO', 'SHADOW', 'NORMAL', 'UV', 'ROUGHNESS', # 'EMIT', 'ENVIRONMENT', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION') # (render.bake 以外の設定は引数で指定する必要あり) bpy.ops.object.bake(type='ROUGHNESS', margin=arg_bakemargin) # サンプリング数を元に戻す bpy.context.scene.cycles.samples = current_samples bpy.context.scene.cycles.preview_samples = current_preview_samples return
def create_armature_mesh(scene: bpy.types.Scene, armature_object: bpy.types.Object, mesh_name: str) -> bpy.types.Object: assert armature_object.type == 'ARMATURE', 'Error' assert len(armature_object.data.bones) != 0, 'Error' def add_rigid_vertex_group(target_object: bpy.types.Object, name: str, vertex_indices: Iterable[int]) -> None: new_vertex_group = target_object.vertex_groups.new(name=name) for vertex_index in vertex_indices: new_vertex_group.add([vertex_index], 1.0, 'REPLACE') def generate_bone_mesh_pydata( radius: float, length: float) -> Tuple[List[mathutils.Vector], List[List[int]]]: base_radius = radius top_radius = 0.5 * radius vertices = [ # Cross section of the base part mathutils.Vector((-base_radius, 0.0, +base_radius)), mathutils.Vector((+base_radius, 0.0, +base_radius)), mathutils.Vector((+base_radius, 0.0, -base_radius)), mathutils.Vector((-base_radius, 0.0, -base_radius)), # Cross section of the top part mathutils.Vector((-top_radius, length, +top_radius)), mathutils.Vector((+top_radius, length, +top_radius)), mathutils.Vector((+top_radius, length, -top_radius)), mathutils.Vector((-top_radius, length, -top_radius)), # End points mathutils.Vector((0.0, -base_radius, 0.0)), mathutils.Vector((0.0, length + top_radius, 0.0)) ] faces = [ # End point for the base part [8, 1, 0], [8, 2, 1], [8, 3, 2], [8, 0, 3], # End point for the top part [9, 4, 5], [9, 5, 6], [9, 6, 7], [9, 7, 4], # Side faces [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], ] return vertices, faces armature_data: bpy.types.Armature = armature_object.data vertices: List[mathutils.Vector] = [] faces: List[List[int]] = [] vertex_groups: List[Dict[str, Any]] = [] for bone in armature_data.bones: radius = 0.10 * (0.10 + bone.length) temp_vertices, temp_faces = generate_bone_mesh_pydata( radius, bone.length) vertex_index_offset = len(vertices) temp_vertex_group = {'name': bone.name, 'vertex_indices': []} for local_index, vertex in enumerate(temp_vertices): if bpy.app.version >= (2, 80, 0): vertices.append(bone.matrix_local @ vertex) else: vertices.append(bone.matrix_local * vertex) temp_vertex_group['vertex_indices'].append(local_index + vertex_index_offset) vertex_groups.append(temp_vertex_group) for face in temp_faces: if len(face) == 3: faces.append([ face[0] + vertex_index_offset, face[1] + vertex_index_offset, face[2] + vertex_index_offset, ]) else: faces.append([ face[0] + vertex_index_offset, face[1] + vertex_index_offset, face[2] + vertex_index_offset, face[3] + vertex_index_offset, ]) new_object = create_mesh_from_pydata(scene, vertices, faces, mesh_name, mesh_name) new_object.matrix_world = armature_object.matrix_world for vertex_group in vertex_groups: add_rigid_vertex_group(new_object, vertex_group['name'], vertex_group['vertex_indices']) armature_modifier = new_object.modifiers.new('Armature', 'ARMATURE') armature_modifier.object = armature_object armature_modifier.use_vertex_groups = True add_subdivision_surface_modifier(new_object, 1, is_simple=True) add_subdivision_surface_modifier(new_object, 2, is_simple=False) # Set the armature as the parent of the new object bpy.ops.object.select_all(action='DESELECT') if bpy.app.version >= (2, 80, 0): new_object.select_set(True) armature_object.select_set(True) bpy.context.view_layer.objects.active = armature_object else: new_object.select = True armature_object.select = True bpy.context.scene.objects.active = armature_object bpy.ops.object.parent_set(type='OBJECT') return new_object
def only_select(obj: bpy.types.Object): '''Make object the only one selected. Requires object mode.''' bpy.ops.object.select_all(action='DESELECT') obj.select_set(True)
def bake_ambientocclusion(arg_object: bpy.types.Object, arg_bakemargin: int = 0, arg_onesample: bool = False, arg_GPUuse: bool = False, arg_aofactor: float = 1.0, arg_distance: float = 10.0): """指定オブジェクトのアンビエントオクルージョンをベイクする Args: arg_object (bpy.types.Object): 指定オブジェクト arg_bakemargin (int, optional): ベイク余白. Defaults to 0. arg_onesample (bool, optional): 簡易サンプリング指定. Defaults to False. arg_GPUuse (bool, optional): GPU利用指定. Defaults to False. arg_aofactor (float, optional): AO係数. Defaults to 1.0. arg_distance (float, optional): AO距離. Defaults to 10.0. """ # 全てのオブジェクトを非選択状態にする for obj in bpy.context.scene.objects: # 選択状態を解除する obj.select_set(False) # 指定オブジェクトを選択状態にする arg_object.select_set(True) # 指定オブジェクトをアクティブにする bpy.context.view_layer.objects.active = arg_object # レンダリングエンジンを CYCLES に切り替える bpy.context.scene.render.engine = 'CYCLES' # GPUの利用有無を確認する if arg_GPUuse == True: # 利用設定ならGPUの設定を行う bpy.context.scene.cycles.device = 'GPU' # CUDAを選択する bpy.context.preferences.addons[ 'cycles'].preferences.compute_device_type = 'CUDA' # デバイスの一覧を取得する for devices in bpy.context.preferences.addons[ 'cycles'].preferences.get_devices(): for device in devices: # デバイスタイプがCUDAならば利用対象とする if device.type == 'CUDA': device.use = True # render.bake の設定項目を予め設定する bake_setting = bpy.context.scene.render.bake # [選択->アクティブ]のベイクを無効化する bake_setting.use_selected_to_active = False # 現在のワールド参照を取得する context_world = bpy.context.scene.world # アンビエントオクルージョンを有効化する context_world.light_settings.use_ambient_occlusion = True # 係数の設定を行う context_world.light_settings.ao_factor = arg_aofactor # 距離の設定を行う context_world.light_settings.distance = arg_distance # 現在のサンプリング数を記録する current_samples = bpy.context.scene.cycles.samples current_preview_samples = bpy.context.scene.cycles.preview_samples # 簡易サンプリングが有効かチェックする if arg_onesample == True: # サンプリング数を減らす bpy.context.scene.cycles.samples = 1 bpy.context.scene.cycles.preview_samples = 1 # ディフューズタイプのベイクを実行する # ベイクの種類 # ('COMBINED', 'AO', 'SHADOW', 'NORMAL', 'UV', 'ROUGHNESS', # 'EMIT', 'ENVIRONMENT', 'DIFFUSE', 'GLOSSY', 'TRANSMISSION') # (render.bake 以外の設定は引数で指定する必要あり) bpy.ops.object.bake(type='AO', margin=arg_bakemargin) # サンプリング数を元に戻す bpy.context.scene.cycles.samples = current_samples bpy.context.scene.cycles.preview_samples = current_preview_samples return
def only_visible(obj: bpy.types.Object): '''Make object the only one selected and visible. Requires object mode.''' bpy.ops.object.select_all(action='DESELECT') obj.select_set(True) bpy.ops.object.hide_view_set(unselected=True)