class ObjectSelectionNode(Node, TrafficNode): bl_idname = "ObjectSelectionNode" bl_label = "Objects Selection Mk.1" object: PointerProperty(type = Object) objectCP: CollectionProperty(type = ObjectPropertyGroup) collectionCP: CollectionProperty(type = CollectionPropertyGroup) showEditOptions: BoolProperty(default = False) def init(self, context): self.outputs.new("ObjectSocket", "Object") self.outputs.new("ObjectListSocket", "Object List") def draw_buttons(self, context, layout): # SINGLE OBJECT INPUT AREA col = layout.column(align = True) row = col.row(align = True) row.prop(self, "object", text = "") selector = row.operator("tn.assign_active_object_to_node", icon = "EYEDROPPER", text = "") selector.nodeTreeName = self.id_data.name selector.nodeName = self.name selector.target = "object" col.separator() # OBJECT LIST INPUT AREA col.separator() col.separator() row = col.row(align = True) row.scale_y = 1 listBelow = row.label(text = "GenObjList [Excl.Above1]") row.prop(self, "showEditOptions", text = "Show Options") indexOBJ = 0 indexCOL = 0 if self.showEditOptions: for item in self.objectCP: row = col.row(align = True) row.scale_y = 1 select = row.operator("tn.assign_active_object_to_list_node", icon = "EYEDROPPER", text="") select.nodeTreeName = self.id_data.name select.nodeName = self.name select.index = indexOBJ row.prop(item, "object", text = "") remove = row.operator("tn.remove_property_from_list_node", text = "", icon = "X") remove.nodeTreeName = self.id_data.name remove.nodeName = self.name remove.index = indexOBJ indexOBJ += 1 col.separator() add = col.operator("tn.new_property_to_list_node", text = "New Object", icon = "PLUS") add.nodeTreeName = self.id_data.name add.nodeName = self.name #COLLECTION INPUT AREA col.separator() for item in self.collectionCP: row = col.row(align = True) row.scale_y = 1 row.prop(item, "collection", text = "") remove = row.operator("tn.remove_collection_from_list_node", text = "", icon = "X") remove.nodeTreeName = self.id_data.name remove.nodeName = self.name remove.index = indexCOL indexCOL += 1 col.separator() add2 = col.operator("tn.new_collection_to_list_node", text = "New Collection", icon = "PLUS") add2.nodeTreeName = self.id_data.name add2.nodeName = self.name col.separator() def execute(self, input): output = {} output["Object List"] = self.getCurrentList() #TODO Improve this. Improvise this... Currently the logic sucks if self.object is not None: output["Object"] = bpy.data.objects.get(self.object.name) else: output["Object"] = "No SINGLE Object selected" return output def getCurrentList(self): objectList = [] for item in self.objectCP: objectList.append(item.object) for C in self.collectionCP: for obj in C.collection.objects: objectList.append(obj) return objectList def addItemCP(self): item = self.objectCP.add() def removeItemCP(self, index): self.objectCP.remove(index) def setObject(self, object, index): self.objectCP[index].object = object def addCCP(self): item = self.collectionCP.add() def removeCCP(self, index): self.collectionCP.remove(index) def setCollection(self, object, index): self.collectionCP[index].object = object
class SelectionSet(bpy.types.PropertyGroup): name = StringProperty(name="Set Name") bone_ids = CollectionProperty(type=SelectionEntry)
# ------------------------------------------------------------------ # Define property group class to create or modify a rooms. # ------------------------------------------------------------------ class ArchLabRoomProperties(PropertyGroup): room_height = room_height_property(callback=update_room) room_floor = room_floor_property(callback=update_room) room_ceiling = room_ceiling_property(callback=update_room) room_wall_count = room_wall_count_property(callback=update_room) room_wall_count = room_wall_count_property(callback=update_room) room_walls = room_walls_property(callback=update_room) bpy.utils.register_class(ArchLabWallProperties) bpy.utils.register_class(ArchLabRoomProperties) Object.ArchLabRoomGenerator = CollectionProperty(type=ArchLabRoomProperties) # ------------------------------------------------------------------ # Define panel class to modify rooms. # ------------------------------------------------------------------ class ArchLabRoomGeneratorPanel(Panel): bl_idname = "OBJECT_PT_room_generator" bl_label = "Room" bl_space_type = 'VIEW_3D' bl_region_type = 'TOOLS' bl_category = 'ArchLab' # ----------------------------------------------------- # Verify if visible # -----------------------------------------------------
class PsetQto(PropertyGroup): name: StringProperty(name="Name") properties: CollectionProperty(name="Properties", type=Attribute)
class ClashSet(PropertyGroup): name: StringProperty(name='Name') tolerance: FloatProperty(name='Tolerance') a: CollectionProperty(name='Group A', type=ClashSource) b: CollectionProperty(name='Group B', type=ClashSource)
class SimpGameImport(bpy.types.Operator, ImportHelper): bl_idname = "custom_import_scene.simpgame" bl_label = "Import" bl_options = {'PRESET', 'UNDO'} filter_glob = StringProperty( default="*.preinstanced", options={'HIDDEN'}, ) filepath = StringProperty(subtype='FILE_PATH', ) files = CollectionProperty(type=bpy.types.PropertyGroup) def draw(self, context): pass def execute(self, context): CurFile = open(self.filepath, "rb") CurCollection = bpy.data.collections.new("New Mesh") bpy.context.scene.collection.children.link(CurCollection) tmpRead = CurFile.read() mshBytes = re.compile(b"\x33\xEA\x00\x00....\x2D\x00\x02\x1C", re.DOTALL) iter = 0 for x in mshBytes.finditer( tmpRead): # Files can have multiple mesh containers CurFile.seek(x.end() + 4) FaceDataOff = int.from_bytes(CurFile.read(4), byteorder='little') MeshDataSize = int.from_bytes(CurFile.read(4), byteorder='little') MeshChunkStart = CurFile.tell() CurFile.seek(0x14, 1) mDataTableCount = int.from_bytes(CurFile.read(4), byteorder='big') mDataSubCount = int.from_bytes(CurFile.read(4), byteorder='big') mDataOffsets = [] # This section isn't used right now... probably not needed for i in range(mDataTableCount): CurFile.seek(4, 1) mDataOffsets.append( int.from_bytes(CurFile.read(4), byteorder='big')) mDataSubStart = CurFile.tell() for i in range( mDataSubCount): # Containers can have multiple sub-meshes CurFile.seek(mDataSubStart + i * 0xc + 8) offset = int.from_bytes(CurFile.read(4), byteorder='big') chunkHead = CurFile.seek(offset + MeshChunkStart + 0xC) VertCountDataOff = int.from_bytes( CurFile.read(4), byteorder='big') + MeshChunkStart CurFile.seek(VertCountDataOff) VertChunkTotalSize = int.from_bytes(CurFile.read(4), byteorder='big') VertChunkSize = int.from_bytes(CurFile.read(4), byteorder='big') VertCount = int(VertChunkTotalSize / VertChunkSize) CurFile.seek(8, 1) VertexStart = int.from_bytes( CurFile.read(4), byteorder='big') + FaceDataOff + MeshChunkStart CurFile.seek(0x14, 1) FaceCount = int( int.from_bytes(CurFile.read(4), byteorder='big') / 2) CurFile.seek(4, 1) FaceStart = int.from_bytes( CurFile.read(4), byteorder='big') + FaceDataOff + MeshChunkStart CurFile.seek(FaceStart) StripList = [] tmpList = [] for f in range(FaceCount): Indice = int.from_bytes(CurFile.read(2), byteorder='big') if Indice == 65535: StripList.append(tmpList.copy()) tmpList.clear() else: tmpList.append(Indice) FaceTable = [] for f in StripList: for f2 in strip2face(f): FaceTable.append(f2) VertTable = [] UVTable = [] CMTable = [] for v in range(VertCount): CurFile.seek(VertexStart + v * VertChunkSize) TempVert = struct.unpack('>fff', CurFile.read(4 * 3)) VertTable.append(TempVert) # UV data for the textures CurFile.seek(VertexStart + v * VertChunkSize + VertChunkSize - 16) TempUV = struct.unpack('>ff', CurFile.read(4 * 2)) UVTable.append((TempUV[0], 1 - TempUV[1])) # Color map data for the palette CurFile.seek(VertexStart + v * VertChunkSize + VertChunkSize - 8) TempCM = struct.unpack('>ff', CurFile.read(4 * 2)) CMTable.append((TempCM[0], 1 - TempCM[1])) #build mesh mesh1 = bpy.data.meshes.new("Mesh") mesh1.use_auto_smooth = True obj = bpy.data.objects.new("Mesh_" + str(iter) + "_" + str(i), mesh1) CurCollection.objects.link(obj) bpy.context.view_layer.objects.active = obj obj.select_set(True) mesh = bpy.context.object.data bm = bmesh.new() for v in VertTable: bm.verts.new((v[0], v[1], v[2])) list = [v for v in bm.verts] for f in FaceTable: try: bm.faces.new((list[f[0]], list[f[1]], list[f[2]])) except: continue bm.to_mesh(mesh) uv_layer = bm.loops.layers.uv.verify() cm_layer = bm.loops.layers.uv.new() for f in bm.faces: f.smooth = True for l in f.loops: luv = l[uv_layer] lcm = l[cm_layer] try: luv.uv = UVTable[l.vert.index] lcm.uv = CMTable[l.vert.index] except: continue bm.to_mesh(mesh) bm.free() obj.rotation_euler = (1.5707963705062866, 0, 0) iter += 1 CurFile.close() del CurFile return {'FINISHED'}
class ImportGLTF2(Operator, ImportHelper): """Load a glTF 2.0 file""" bl_idname = 'import_scene.gltf' bl_label = 'Import glTF 2.0' filter_glob: StringProperty(default="*.glb;*.gltf", options={'HIDDEN'}) files: CollectionProperty( name="File Path", type=bpy.types.OperatorFileListElement, ) loglevel: IntProperty(name='Log Level', description="Log Level") import_pack_images: BoolProperty( name='Pack Images', description='Pack all images into .blend file', default=True) import_shading: EnumProperty( name="Shading", items=(("NORMALS", "Use Normal Data", ""), ("FLAT", "Flat Shading", ""), ("SMOOTH", "Smooth Shading", "")), description="How normals are computed during import", default="NORMALS") bone_heuristic: EnumProperty( name="Bone Dir", items=( ("BLENDER", "Blender (best for re-importing)", "Good for re-importing glTFs exported from Blender.\n" "Bone tips are placed on their local +Y axis (in glTF space)"), ("TEMPERANCE", "Temperance (average)", "Decent all-around strategy.\n" "A bone with one child has its tip placed on the local axis\n" "closest to its child"), ("FORTUNE", "Fortune (may look better, less accurate)", "Might look better than Temperance, but also might have errors.\n" "A bone with one child has its tip placed at its child's root.\n" "Non-uniform scalings may get messed up though, so beware"), ), description="Heuristic for placing bones. Tries to make bones pretty", default="TEMPERANCE", ) guess_original_bind_pose: BoolProperty( name='Guess Original Bind Pose', description=( 'Try to guess the original bind pose for skinned meshes from ' 'the inverse bind matrices.\n' 'When off, use default/rest pose as bind pose'), default=True, ) def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False # No animation. layout.prop(self, 'import_pack_images') layout.prop(self, 'import_shading') layout.prop(self, 'guess_original_bind_pose') layout.prop(self, 'bone_heuristic') def execute(self, context): return self.import_gltf2(context) def import_gltf2(self, context): import os self.set_debug_log() import_settings = self.as_keywords() if self.files: # Multiple file import ret = {'CANCELLED'} dirname = os.path.dirname(self.filepath) for file in self.files: path = os.path.join(dirname, file.name) if self.unit_import(path, import_settings) == {'FINISHED'}: ret = {'FINISHED'} return ret else: # Single file import return self.unit_import(self.filepath, import_settings) def unit_import(self, filename, import_settings): import time from .io.imp.gltf2_io_gltf import glTFImporter from .blender.imp.gltf2_blender_gltf import BlenderGlTF self.gltf_importer = glTFImporter(filename, import_settings) success, txt = self.gltf_importer.read() if not success: self.report({'ERROR'}, txt) return {'CANCELLED'} success, txt = self.gltf_importer.checks() if not success: self.report({'ERROR'}, txt) return {'CANCELLED'} print("Data are loaded, start creating Blender stuff") start_time = time.time() BlenderGlTF.create(self.gltf_importer) elapsed_s = "{:.2f}s".format(time.time() - start_time) print("glTF import finished in " + elapsed_s) self.gltf_importer.log.removeHandler(self.gltf_importer.log_handler) return {'FINISHED'} def set_debug_log(self): import logging if bpy.app.debug_value == 0: self.loglevel = logging.CRITICAL elif bpy.app.debug_value == 1: self.loglevel = logging.ERROR elif bpy.app.debug_value == 2: self.loglevel = logging.WARNING elif bpy.app.debug_value == 3: self.loglevel = logging.INFO else: self.loglevel = logging.NOTSET
class action_groups_collection(PropertyGroup): groups: CollectionProperty(type=action_group) index: IntProperty()
class action_pair_collection(PropertyGroup): coll: CollectionProperty(type=action_pair) index: IntProperty()
class ImportSTL(Operator, ImportHelper, IOSTLOrientationHelper): """Load STL triangle mesh data""" bl_idname = "import_mesh.stl" bl_label = "Import STL" bl_options = {'UNDO'} filename_ext = ".stl" filter_glob = StringProperty( default="*.stl", options={'HIDDEN'}, ) files = CollectionProperty( name="File Path", type=OperatorFileListElement, ) directory = StringProperty(subtype='DIR_PATH', ) global_scale = FloatProperty( name="Scale", soft_min=0.001, soft_max=1000.0, min=1e-6, max=1e6, default=1.0, ) use_scene_unit = BoolProperty( name="Scene Unit", description= "Apply current scene's unit (as defined by unit scale) to imported data", default=True, ) def execute(self, context): from . import stl_utils from . import blender_utils from mathutils import Matrix paths = [ os.path.join(self.directory, name.name) for name in self.files ] scene = context.scene # Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000. global_scale = self.global_scale if scene.unit_settings.system != 'NONE' and self.use_scene_unit: global_scale /= scene.unit_settings.scale_length global_matrix = axis_conversion( from_forward=self.axis_forward, from_up=self.axis_up, ).to_4x4() * Matrix.Scale(global_scale, 4) if not paths: paths.append(self.filepath) if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode='OBJECT') if bpy.ops.object.select_all.poll(): bpy.ops.object.select_all(action='DESELECT') for path in paths: objName = bpy.path.display_name(os.path.basename(path)) tris, pts = stl_utils.read_stl(path) blender_utils.create_and_link_mesh(objName, tris, pts, global_matrix) return {'FINISHED'}
class ImportObs(bpy.types.Operator, ImportHelper): '''Import object(s)''' bl_idname = "import_scene.obs" bl_label = "Import object(s)" bl_options = {'PRESET', 'UNDO'} # List of operator properties, the attributes will be assigned # to the class instance from the operator settings before calling. directory = StringProperty(maxlen=1024, subtype='DIR_PATH', options={'HIDDEN', 'SKIP_SAVE'}) files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'}) filename_ext = ".obj" filter_glob = StringProperty(default="*.obj", options={'HIDDEN'}) replace_existing = BoolProperty( name="Replace objects", description="Replace objects already present in the scene", default=True) copy_location = BoolProperty( name="Location", description="Copy the location from the old to the new object", default=True) copy_rotation = BoolProperty( name="Rotation", description="Copy the rotation from the old to the new object", default=True) copy_scale = BoolProperty( name="Scale", description="Copy the scale from the old to the new object", default=True) copy_modifiers_options = BoolProperty( name="Preserve modifiers", description="Copy the modifiers from the replaced object to the "\ "newly imported one", default=True) material_options = EnumProperty( name="Materials", items=[("scene", "Scene", "Use the materials that are now assigned to the objects "\ "(if they already exist), else don't assign materials"), ("obj", "From file", "Use the materials from the OBJ"), ("ignore", "No Materials", "Don't assign materials")], description="Select which materials to use for the imported models", default='scene') is_apply_rotation = BoolProperty(name="Apply rotation", description="Apply rotation after import", default=False) def draw(self, context): layout = self.layout col = layout.column() col.separator() col.prop(self, "is_apply_rotation") col.prop(self, "replace_existing") if self.replace_existing: box = col.box() subcol = box.column() subcol.label("Preserve transforms") row = subcol.row(align=True) row.prop(self, "copy_location", toggle=True) row.prop(self, "copy_rotation", toggle=True) row.prop(self, "copy_scale", toggle=True) subcol.separator() subcol.label("Preserve modifiers") subcol.prop(self, "copy_modifiers_options", text="All", toggle=True) col.separator() col.label("Materials") col.row().prop(self, "material_options", expand=True) def execute(self, context): start_time = time.time() print() d = self.properties.directory fils = self.properties.files if not fils[0].name: # No files selected, getting all obj's in the directory. import_files = glob(path.join(d, "*.[oO][bB][jJ]")) else: # Get the full path names for the files. import_files = [path.join(d, f.name) for f in fils] if import_files: # Import the objects and append them to "imported_list". imported_objects = [] for progress, f in enumerate(import_files): obj = self.import_file(f) if obj: imported_objects.append(obj) if self.material_options == 'ignore': self.remove_materials(obj) self.print_progress(progress, maximum=len(import_files) - 1) # Select all imported objects and make the last one the active object. # The obj importer already deselects previously selected objects. bpy.ops.object.select_all(action='DESELECT') for obj_name in imported_objects: bpy.context.scene.objects[obj_name].select = True context.scene.objects.active = bpy.context.scene.objects[ imported_objects[-1]] print("\nFiles imported in {s:.2f} seconds".format(s=time.time() - start_time)) return {'FINISHED'} # Helper functions def import_file(self, f): ''' Imports an obj file and returns the name of the object ''' old_stdout = sys.stdout old_stderr = sys.stderr dvnull = open(devnull, 'w') sys.stdout = sys.stderr = dvnull # Check if obj importer is enabled if not addon_utils.check("io_scene_obj")[1]: # Enable it if not addon_utils.enable("io_scene_obj"): self.report({'ERROR'}, "could not load obj importer, aborting...") # try: bpy.ops.import_scene.obj(filepath=f, axis_forward='-Z', axis_up='Y', use_edges=True, use_smooth_groups=True, use_split_objects=False, use_split_groups=False, use_groups_as_vgroups=False, use_image_search=True, split_mode='OFF', global_clamp_size=0) # except AttributeError: # self.report({'ERROR'}, "obj importer not loaded, aborting...") sys.stdout = old_stdout sys.stderr = old_stderr return self.rename_object(f) def rename_object(self, f): ''' Renames the object according to the file name and returns the name ''' name = self.get_object_name(f) imported_object = bpy.context.selected_objects[0] if imported_object: if self.is_apply_rotation: self.apply_rotation(imported_object) if self.is_replace_object(name, imported_object): self.replace_object(self.get_object_name(f), imported_object) imported_object.name = imported_object.data.name = name else: print("File: {f} appears to be empty...".format(f=f)) return name def is_replace_object(self, name, imported_object): ''' Returns True if the imported object replaces an already existing one ''' if name in bpy.context.scene.objects and self.replace_existing: if bpy.context.scene.objects[name] != imported_object: return True return False def get_object_name(self, f): ''' Determines the object name from the file name ''' return path.splitext(path.split(f)[1])[0] def replace_object(self, obj_name, obj_new): ''' Replace existing object with new object and copy materials if wanted ''' obj_old = bpy.context.scene.objects[obj_name] if self.material_options == 'scene': self.copy_materials(obj_new, obj_old) if self.copy_location: self.copy_transforms(obj_new, obj_old, 'location') if self.copy_rotation: self.copy_transforms(obj_new, obj_old, 'rotation') if self.copy_scale: self.copy_transforms(obj_new, obj_old, 'scale') if self.copy_modifiers_options: self.copy_modifiers(obj_new, obj_old) bpy.context.scene.objects.unlink(obj_old) def copy_materials(self, obj_copy_to, obj_copy_from): ''' Copy materials from obj_copy_from to obj_copy_to ''' bpy.ops.object.select_all(action='DESELECT') obj_copy_to.select = obj_copy_from.select = True bpy.context.scene.objects.active = obj_copy_from bpy.ops.object.make_links_data(type='MATERIAL') if len(obj_copy_to.data.polygons) > len(obj_copy_from.data.polygons): obj_iter = obj_copy_from else: obj_iter = obj_copy_to for p in obj_iter.data.polygons: pi = p.index mi = obj_copy_from.data.polygons[pi].material_index obj_copy_to.data.polygons[pi].material_index = mi def remove_materials(self, obj_name): ''' Remove all materials from object with name obj_name ''' obj = bpy.context.scene.objects[obj_name] bpy.context.scene.objects.active = obj for _ in obj.material_slots: bpy.ops.object.material_slot_remove() def copy_transforms(self, obj_new, obj_old, transform): ''' Copy the given transformation from the old to the new object ''' if transform == 'location': obj_new.location = obj_old.location if transform == 'rotation': obj_new.rotation_mode = obj_old.rotation_mode if obj_old.rotation_mode == 'AXIS_ANGLE': obj_new.rotation_axis_angle[0] = obj_old.rotation_axis_angle[0] obj_new.rotation_axis_angle[1] = obj_old.rotation_axis_angle[1] obj_new.rotation_axis_angle[2] = obj_old.rotation_axis_angle[2] obj_new.rotation_axis_angle[3] = obj_old.rotation_axis_angle[3] if obj_old.rotation_mode == 'QUATERNION': obj_new.rotation_quaternion = obj_old.rotation_quaternion else: obj_new.rotation_euler = obj_old.rotation_euler if transform == 'scale': obj_new.scale = obj_old.scale def copy_modifiers(self, obj_new, obj_old, modifiers='all'): ''' Copy the specified modifiers from obj_old to obj_new ''' print("*** Copying modifiers to {obj_new}...".format(obj_new=obj_new)) bpy.ops.object.select_all(action='DESELECT') obj_new.select = obj_old.select = True bpy.context.scene.objects.active = obj_old if modifiers == 'all': bpy.ops.object.make_links_data(type='MODIFIERS') def apply_rotation(self, obj): ''' Apply the object's rotation to its data ''' bpy.context.scene.objects.active = obj bpy.ops.object.transform_apply(rotation=True) def print_progress(self, progress, minimum=0, maximum=100, barlen=50): if maximum <= minimum: return total_len = maximum - minimum bar_progress = int((progress - minimum) * barlen / total_len) * "=" bar_empty = (barlen - int( (progress - minimum) * barlen / total_len)) * " " percentage = "".join((str(int( (progress - minimum) / total_len * 100)), "%")) print("".join(("[", bar_progress, bar_empty, "]", " ", percentage)), end="\r")
class SCENE_OT_POV_Import(bpy.types.Operator, ImportHelper): """Load Povray files""" bl_idname = "import_scene.pov" bl_label = "POV-Ray files (.pov/.inc)" bl_options = {"PRESET", "UNDO"} COMPAT_ENGINES = {"POVRAY_RENDER"} # ----------- # File props. files: CollectionProperty(type=bpy.types.OperatorFileListElement, options={"HIDDEN", "SKIP_SAVE"}) directory: StringProperty(maxlen=1024, subtype="FILE_PATH", options={"HIDDEN", "SKIP_SAVE"}) filename_ext = {".pov", ".inc"} filter_glob: StringProperty(default="*.pov;*.inc", options={"HIDDEN"}) import_at_cur: BoolProperty(name="Import at Cursor Location", description="Ignore Object Matrix", default=False) def execute(self, context): from mathutils import Matrix verts = [] faces = [] materials = [] blend_mats = [] # XXX pov_mats = [] # XXX colors = [] mat_names = [] lenverts = None lenfaces = None suffix = -1 name = "Mesh2_%s" % suffix name_search = False verts_search = False faces_search = False plane_search = False box_search = False cylinder_search = False sphere_search = False cone_search = False tex_search = False # XXX cache = [] matrixes = {} write_matrix = False index = None value = None # file_pov = bpy.path.abspath(self.filepath) # was used for single files def mat_search(cache): r = g = b = 0.5 f = t = 0 color = None for item, value in enumerate(cache): # if value == 'texture': # add more later if value == "pigment": # Todo: create function for all color models. # instead of current pass statements # distinguish srgb from rgb into blend option if cache[item + 2] in {"rgb", "srgb"}: pass elif cache[item + 2] in {"rgbf", "srgbf"}: pass elif cache[item + 2] in {"rgbt", "srgbt"}: try: r, g, b, t = ( float(cache[item + 3]), float(cache[item + 4]), float(cache[item + 5]), float(cache[item + 6]), ) except BaseException as e: print(e.__doc__) print("An exception occurred: {}".format(e)) r = g = b = t = float(cache[item + 2]) color = (r, g, b, t) elif cache[item + 2] in {"rgbft", "srgbft"}: pass else: pass if colors == [] or color not in colors: colors.append(color) name = ob.name + "_mat" mat_names.append(name) mat = bpy.data.materials.new(name) mat.diffuse_color = (r, g, b) mat.pov.alpha = 1 - t if mat.pov.alpha != 1: mat.pov.use_transparency = True ob.data.materials.append(mat) else: for i, value in enumerate(colors): if color == value: ob.data.materials.append( bpy.data.materials[mat_names[i]]) for file in self.files: print("Importing file: " + file.name) file_pov = self.directory + file.name # Ignore any non unicode character with open(file_pov, 'r', encoding='utf-8', errors="ignore") as infile: for line in infile: string = line.replace("{", " ") string = string.replace("}", " ") string = string.replace("<", " ") string = string.replace(">", " ") string = string.replace(",", " ") lw = string.split() # lenwords = len(lw) # Not used... why written? if lw: if lw[0] == "object": write_matrix = True if write_matrix: if lw[0] not in {"object", "matrix"}: index = lw[0] if lw[0] in {"matrix"}: value = [ float(lw[1]), float(lw[2]), float(lw[3]), float(lw[4]), float(lw[5]), float(lw[6]), float(lw[7]), float(lw[8]), float(lw[9]), float(lw[10]), float(lw[11]), float(lw[12]), ] matrixes[index] = value write_matrix = False with open(file_pov, 'r', encoding='utf-8', errors="ignore") as infile: for line in infile: S = line.replace("{", " { ") S = S.replace("}", " } ") S = S.replace(",", " ") S = S.replace("<", "") S = S.replace(">", " ") S = S.replace("=", " = ") S = S.replace(";", " ; ") S = S.split() # lenS = len(S) # Not used... why written? for word in S: # -------- Primitives Import -------- # if word == "cone": cone_search = True name_search = False if cone_search: cache.append(word) if cache[-1] == "}": try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) r0 = float(cache[5]) x1 = float(cache[6]) y1 = float(cache[7]) z1 = float(cache[8]) r1 = float(cache[9]) # Y is height in most pov files, not z bpy.ops.pov.addcone(base=r0, cap=r1, height=(y1 - y0)) ob = context.object ob.location = (x0, y0, z0) # ob.scale = (r,r,r) mat_search(cache) except ValueError: pass cache = [] cone_search = False if word == "plane": plane_search = True name_search = False if plane_search: cache.append(word) if cache[-1] == "}": try: bpy.ops.pov.addplane() ob = context.object mat_search(cache) except ValueError: pass cache = [] plane_search = False if word == "box": box_search = True name_search = False if box_search: cache.append(word) if cache[-1] == "}": try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) x1 = float(cache[5]) y1 = float(cache[6]) z1 = float(cache[7]) # imported_corner_1=(x0, y0, z0) # imported_corner_2 =(x1, y1, z1) center = ((x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2) bpy.ops.pov.addbox() ob = context.object ob.location = center mat_search(cache) except ValueError: pass cache = [] box_search = False if word == "cylinder": cylinder_search = True name_search = False if cylinder_search: cache.append(word) if cache[-1] == "}": try: x0 = float(cache[2]) y0 = float(cache[3]) z0 = float(cache[4]) x1 = float(cache[5]) y1 = float(cache[6]) z1 = float(cache[7]) imported_cyl_loc = (x0, y0, z0) imported_cyl_loc_cap = (x1, y1, z1) r = float(cache[8]) vec = Vector(imported_cyl_loc_cap ) - Vector(imported_cyl_loc) depth = vec.length rot = Vector( (0, 0, 1)).rotation_difference( vec) # Rotation from Z axis. trans = rot @ Vector( # XXX Not used, why written? (0, 0, depth / 2) ) # Such that origin is at center of the base of the cylinder. # center = ((x0 + x1)/2,(y0 + y1)/2,(z0 + z1)/2) scale_z = sqrt((x1 - x0)**2 + (y1 - y0)**2 + (z1 - z0)**2) / 2 bpy.ops.pov.addcylinder( R=r, imported_cyl_loc=imported_cyl_loc, imported_cyl_loc_cap= imported_cyl_loc_cap, ) ob = context.object ob.location = (x0, y0, z0) # todo: test and search where to add the below currently commented # since Blender defers the evaluation until the results are needed. # bpy.context.view_layer.update() # as explained here: https://docs.blender.org/api/current/info_gotcha.html?highlight=gotcha#no-updates-after-setting-values ob.rotation_euler = rot.to_euler() ob.scale = (1, 1, scale_z) # scale data rather than obj? # bpy.ops.object.mode_set(mode='EDIT') # bpy.ops.mesh.reveal() # bpy.ops.mesh.select_all(action='SELECT') # bpy.ops.transform.resize(value=(1,1,scale_z), orient_type='LOCAL') # bpy.ops.mesh.hide(unselected=False) # bpy.ops.object.mode_set(mode='OBJECT') mat_search(cache) except ValueError: pass cache = [] cylinder_search = False if word == "sphere": sphere_search = True name_search = False if sphere_search: cache.append(word) if cache[-1] == "}": x = y = z = r = 0 try: x = float(cache[2]) y = float(cache[3]) z = float(cache[4]) r = float(cache[5]) except ValueError: pass except BaseException as e: print(e.__doc__) print( "An exception occurred: {}".format(e)) x = y = z = float(cache[2]) r = float(cache[3]) bpy.ops.pov.addsphere(R=r, imported_loc=(x, y, z)) ob = context.object ob.location = (x, y, z) ob.scale = (r, r, r) mat_search(cache) cache = [] sphere_search = False # -------- End Primitives Import -------- # if word == "#declare": name_search = True if name_search: cache.append(word) if word == "mesh2": name_search = False if cache[-2] == "=": name = cache[-3] else: suffix += 1 cache = [] if word in {"texture", ";"}: name_search = False cache = [] if word == "vertex_vectors": verts_search = True if verts_search: cache.append(word) if word == "}": verts_search = False lenverts = cache[2] cache.pop() cache.pop(0) cache.pop(0) cache.pop(0) for j in range(int(lenverts)): x = j * 3 y = (j * 3) + 1 z = (j * 3) + 2 verts.append( (float(cache[x]), float(cache[y]), float(cache[z]))) cache = [] # if word == 'face_indices': # faces_search = True if word == "texture_list": # XXX tex_search = True # XXX if tex_search: # XXX if (word not in { "texture_list", "texture", "{", "}", "face_indices" } and not word.isdigit()): # XXX pov_mats.append(word) # XXX if word == "face_indices": tex_search = False # XXX faces_search = True if faces_search: cache.append(word) if word == "}": faces_search = False lenfaces = cache[2] cache.pop() cache.pop(0) cache.pop(0) cache.pop(0) lf = int(lenfaces) var = int(len(cache) / lf) for k in range(lf): if var == 3: v0 = k * 3 v1 = k * 3 + 1 v2 = k * 3 + 2 faces.append( (int(cache[v0]), int(cache[v1]), int(cache[v2]))) if var == 4: v0 = k * 4 v1 = k * 4 + 1 v2 = k * 4 + 2 m = k * 4 + 3 materials.append((int(cache[m]))) faces.append( (int(cache[v0]), int(cache[v1]), int(cache[v2]))) if var == 6: v0 = k * 6 v1 = k * 6 + 1 v2 = k * 6 + 2 m0 = k * 6 + 3 m1 = k * 6 + 4 m2 = k * 6 + 5 materials.append( (int(cache[m0]), int(cache[m1]), int(cache[m2]))) faces.append( (int(cache[v0]), int(cache[v1]), int(cache[v2]))) # mesh = pov_define_mesh(None, verts, [], faces, name, hide_geometry=False) # ob = object_utils.object_data_add(context, mesh, operator=None) me = bpy.data.meshes.new(name) # XXX ob = bpy.data.objects.new(name, me) # XXX bpy.context.collection.objects.link(ob) # XXX me.from_pydata(verts, [], faces) # XXX for mat in bpy.data.materials: # XXX blend_mats.append(mat.name) # XXX for m_name in pov_mats: # XXX if m_name not in blend_mats: # XXX bpy.data.materials.new(m_name) # XXX mat_search(cache) ob.data.materials.append( bpy.data.materials[m_name]) # XXX if materials: # XXX for idx, val in enumerate( materials): # XXX try: # XXX ob.data.polygons[ idx].material_index = val # XXX except TypeError: # XXX ob.data.polygons[ idx].material_index = int( val[0]) # XXX blend_mats = [] # XXX pov_mats = [] # XXX materials = [] # XXX cache = [] name_search = True if name in matrixes and not self.import_at_cur: global_matrix = Matrix.Rotation( pi / 2.0, 4, "X") ob = bpy.context.object matrix = ob.matrix_world v = matrixes[name] matrix[0][0] = v[0] matrix[1][0] = v[1] matrix[2][0] = v[2] matrix[0][1] = v[3] matrix[1][1] = v[4] matrix[2][1] = v[5] matrix[0][2] = v[6] matrix[1][2] = v[7] matrix[2][2] = v[8] matrix[0][3] = v[9] matrix[1][3] = v[10] matrix[2][3] = v[11] matrix = global_matrix * ob.matrix_world ob.matrix_world = matrix verts = [] faces = [] # if word == 'pigment': # try: # #all indices have been incremented once to fit a bad test file # r,g,b,t = float(S[2]),float(S[3]),float(S[4]),float(S[5]) # color = (r,g,b,t) # except IndexError: # #all indices have been incremented once to fit alternate test file # r,g,b,t = float(S[3]),float(S[4]),float(S[5]),float(S[6]) # color = (r,g,b,t) # except UnboundLocalError: # # In case no transmit is specified ? put it to 0 # r,g,b,t = float(S[2]),float(S[3]),float(S[4],0) # color = (r,g,b,t) # except ValueError: # color = (0.8,0.8,0.8,0) # pass # if colors == [] or (colors != [] and color not in colors): # colors.append(color) # name = ob.name+"_mat" # mat_names.append(name) # mat = bpy.data.materials.new(name) # mat.diffuse_color = (r,g,b) # mat.pov.alpha = 1-t # if mat.pov.alpha != 1: # mat.pov.use_transparency=True # ob.data.materials.append(mat) # print (colors) # else: # for m in range(len(colors)): # if color == colors[m]: # ob.data.materials.append(bpy.data.materials[mat_names[m]]) # To keep Avogadro Camera angle: # for obj in bpy.context.view_layer.objects: # if obj.type == "CAMERA": # track = obj.constraints.new(type = "TRACK_TO") # track.target = ob # track.track_axis ="TRACK_NEGATIVE_Z" # track.up_axis = "UP_Y" # obj.location = (0,0,0) return {"FINISHED"}
class AnnotationContainer(PropertyGroup): num_annotations: IntProperty(name='Number of Annotations', min=0, max=1000, default=0, description='Number total of Annotations') active_annotation_index: IntProperty(name='Active Annotation Index') show_anotation_settings: BoolProperty(name='Show Annotation Settings', default=False) # Array of segments annotations: CollectionProperty(type=AnnotationProperties) bpy.utils.register_class(AnnotationContainer) Object.AnnotationGenerator = CollectionProperty(type=AnnotationContainer) class AddAnnotationButton(Operator): bl_idname = "measureit_arch.addannotationbutton" bl_label = "Add" bl_description = "Add a new Annotation (For Mesh Objects Select 1 Vertex in Edit Mode)" bl_category = 'MeasureitArch' # ------------------------------ # Poll # ------------------------------ @classmethod def poll(cls, context): obj = context.object if obj is None or len(context.selected_objects) == 0:
class MMDRoot(PropertyGroup): """ MMDモデルデータ モデルルート用に作成されたEmtpyオブジェクトで使用します """ name = StringProperty( name='Name', default='', ) name_e = StringProperty( name='Name (English)', default='', ) show_meshes = BoolProperty( name='Show Meshes', update=_toggleVisibilityOfMeshes, ) show_rigid_bodies = BoolProperty( name='Show Rigid Bodies', update=_toggleVisibilityOfRigidBodies, ) show_joints = BoolProperty( name='Show Joints', update=_toggleVisibilityOfJoints, ) show_temporary_objects = BoolProperty( name='Show Temps', update=_toggleVisibilityOfTemporaryObjects, ) show_armature = BoolProperty( name='Show Armature', get=lambda x: not mmd_model.Model(x.id_data).armature().hide, set=lambda x, v: _setVisibilityOfMMDRigArmature(x.id_data, v), ) show_names_of_rigid_bodies = BoolProperty( name='Show Rigid Body Names', update=_toggleShowNamesOfRigidBodies, ) show_names_of_joints = BoolProperty( name='Show Joint Names', update=_toggleShowNamesOfJoints, ) scale = FloatProperty( name='Scale', min=0.1, default=1, ) is_built = BoolProperty( name='Is Built', ) active_rigidbody_index = IntProperty( name='Active Rigidbody Index', min=0, get=_getActiveRigidbodyObject, set=_setActiveRigidbodyObject, ) active_joint_index = IntProperty( name='Active Joint Index', min=0, get=_getActiveJointObject, set=_setActiveJointObject, ) #************************* # Display Items #************************* display_item_frames = CollectionProperty( name='Display Frames', type=MMDDisplayItemFrame, ) active_display_item_frame = IntProperty( name='Active Display Item Frame', min=0, default=0, ) #************************* # Morph #************************* material_morphs = CollectionProperty( name='Material Morphs', type=MaterialMorph, ) bone_morphs = CollectionProperty( name='Bone Morphs', type=BoneMorph, ) vertex_morphs = CollectionProperty( name='Vertex Morphs', type=VertexMorph ) active_morph_type = EnumProperty( name='Active Morph Type', items = [ ('MATMORPH', 'Material', '', 0), ('BONEMORPH', 'Bone', '', 1), ('VTXMORPH', 'Vertex', '', 2), ], default='VTXMORPH', update=_activeMorphReset ) active_morph = IntProperty( name='Active Morph', min=0, default=0 )
class SetGeophotosCam(Operator): bl_idname = "camera.geophotos" bl_description = "Create cameras from geotagged photos" bl_label = "Exif cam" bl_options = {"REGISTER"} files = CollectionProperty( name="File Path", type=OperatorFileListElement, ) directory = StringProperty(subtype='DIR_PATH', ) filter_glob = StringProperty( default="*.jpg;*.jpeg;*.tif;*.tiff", options={'HIDDEN'}, ) filename_ext = "" exifMode = EnumProperty(attr="exif_mode", name="Action", description="Choose an action", items=[('TARGET_CAMERA', 'Target Camera', 'Create a camera with target helper'), ('CAMERA', 'Camera', 'Create a camera'), ('EMPTY', 'Empty', 'Create an empty helper'), ('CURSOR', 'Cursor', 'Move cursor')], default="TARGET_CAMERA") def invoke(self, context, event): scn = context.scene geoscn = GeoScene(scn) if not geoscn.isGeoref: self.report({'ERROR'}, "The scene must be georeferenced.") return {'CANCELLED'} #File browser context.window_manager.fileselect_add(self) return {'RUNNING_MODAL'} def execute(self, context): scn = context.scene geoscn = GeoScene(scn) directory = self.directory for file_elem in self.files: filepath = os.path.join(directory, file_elem.name) if not os.path.isfile(filepath): self.report({'ERROR'}, "Invalid file") return {'FINISHED'} imgFormat = getImgFormat(filepath) if imgFormat not in ['JPEG', 'TIFF']: self.report({'ERROR'}, "Invalid format " + str(imgFormat)) return {'FINISHED'} try: exif = Tyf.open(filepath) #tags = {t.key:exif[t.key] for t in exif.exif.tags() if t.key != 'Unknown' } except Exception as e: self.report({'ERROR'}, "Unable to open file. " + str(e)) return {'FINISHED'} try: lat = exif["GPSLatitude"] * exif["GPSLatitudeRef"] lon = exif["GPSLongitude"] * exif["GPSLongitudeRef"] except: self.report({'ERROR'}, "Can't find gps longitude or latitude") return {'FINISHED'} try: alt = exif["GPSAltitude"] except: alt = 0 try: x, y = reprojPt(4326, geoscn.crs, lon, lat) except Exception as e: self.report({'ERROR'}, "Reprojection error. " + str(e)) return {'FINISHED'} try: print(exif["FocalLengthIn35mmFilm"]) focalLength = exif["FocalLengthIn35mmFilm"] except: focalLength = 35 try: location = (x - geoscn.crsx, y - geoscn.crsy, alt) name = bpy.path.display_name_from_filepath(filepath) if self.exifMode == "TARGET_CAMERA": cam, cam_obj = newTargetCamera(scn, name, location, focalLength) elif self.exifMode == "CAMERA": cam, cam_obj = newCamera(scn, name, location, focalLength) elif self.exifMode == "EMPTY": newEmpty(scn, name, location) else: scn.cursor_location = location except Exception as e: self.report({'ERROR'}, "Can't perform action. " + str(e)) return {'FINISHED'} if self.exifMode in ["TARGET_CAMERA", "CAMERA"]: cam['background'] = filepath ''' try: cam['imageWidth'] = exif["PixelXDimension"] #for jpg, in tif tag is named imageWidth... cam['imageHeight'] = exif["PixelYDimension"] except: pass ''' img = bpy.data.images.load(filepath) w, h = img.size cam['imageWidth'] = w #exif["PixelXDimension"] #for jpg, in tif tag is named imageWidth... cam['imageHeight'] = h try: cam['orientation'] = exif["Orientation"] except: cam['orientation'] = 1 #no rotation #Set camera rotation (NOT TESTED) if cam['orientation'] == 8: #90° CCW cam_obj.rotation_euler[1] -= pi / 2 if cam['orientation'] == 6: #90° CW cam_obj.rotation_euler[1] += pi / 2 if cam['orientation'] == 3: #180° cam_obj.rotation_euler[1] += pi if scn.camera is None: bpy.ops.camera.geophotos_setactive('EXEC_DEFAULT', camLst=cam_obj.name) return {'FINISHED'}
class actions_collection(PropertyGroup): coll: CollectionProperty(type=action_entry) index: IntProperty()
class events_collection(PropertyGroup): coll = CollectionProperty(type=event_entry) index = IntProperty()
class RendermanObjectSettings(RmanBasePropertyGroup, bpy.types.PropertyGroup): rman_config_name: StringProperty(name='rman_config_name', default='rman_properties_object') openvdb_channels: CollectionProperty(type=RendermanOpenVDBChannel, name="OpenVDB Channels") openvdb_channel_index: IntProperty(min=-1, default=-1) archive_anim_settings: PointerProperty(type=RendermanAnimSequenceSettings, name="Animation Sequence Settings") hide_primitive_type: BoolProperty(name="Hide Primitive Type", default=False) rman_material_override: PointerProperty(name='Material', type=bpy.types.Material) rman_lighting_excludesubset: CollectionProperty( name='lighting:excludesubset', type=RendermanLightPointer) rman_lightfilter_subset: CollectionProperty(name='lighting:excludesubset', type=RendermanLightPointer) export_archive: BoolProperty( name="Export as Archive", description="At render export time, store this object as a RIB archive", default=False) export_archive_path: StringProperty( name="Archive Export Path", description="Path to automatically save this object as a RIB archive", subtype='FILE_PATH', default="") export_as_coordsys: BoolProperty( name="Export As CoordSys", description="Export this empty as a coordinate system.", default=False) mute: BoolProperty(name="Mute", description="Turn off this light", default=False) def update_solo(self, context): light = self.id_data scene = context.scene # if the scene solo is on already find the old one and turn off scene.renderman.solo_light = self.solo if self.solo: if scene.renderman.solo_light: for ob in scene.objects: if shadergraph_utils.is_rman_light( ob, include_light_filters=False): rm = ob.renderman if rm != self and rm.solo: rm.solo = False break solo: BoolProperty(name="Solo", update=update_solo, description="Turn on only this light", default=False)
class NodeAddOperator: type: StringProperty( name="Node Type", description="Node type", ) use_transform: BoolProperty( name="Use Transform", description="Start transform operator after inserting the node", default=False, ) settings: CollectionProperty( name="Settings", description="Settings to be applied on the newly created node", type=NodeSetting, options={'SKIP_SAVE'}, ) @staticmethod def store_mouse_cursor(context, event): space = context.space_data tree = space.edit_tree # convert mouse position to the View2D for later node placement if context.region.type == 'WINDOW': # convert mouse position to the View2D for later node placement space.cursor_location_from_region(event.mouse_region_x, event.mouse_region_y) else: space.cursor_location = tree.view_center # XXX explicit node_type argument is usually not necessary, # but required to make search operator work: # add_search has to override the 'type' property # since it's hardcoded in bpy_operator_wrap.c ... def create_node(self, context, node_type=None): space = context.space_data tree = space.edit_tree if node_type is None: node_type = self.type # select only the new node for n in tree.nodes: n.select = False node = tree.nodes.new(type=node_type) for setting in self.settings: # XXX catch exceptions here? value = eval(setting.value) node_data = node node_attr_name = setting.name # Support path to nested data. if '.' in node_attr_name: node_data_path, node_attr_name = node_attr_name.rsplit(".", 1) node_data = node.path_resolve(node_data_path) try: setattr(node_data, node_attr_name, value) except AttributeError as e: self.report({'ERROR_INVALID_INPUT'}, "Node has no attribute " + setting.name) print(str(e)) # Continue despite invalid attribute node.select = True tree.nodes.active = node node.location = space.cursor_location return node @classmethod def poll(cls, context): space = context.space_data # needs active node editor and a tree to add nodes to return ((space.type == 'NODE_EDITOR') and space.edit_tree and not space.edit_tree.library) # Default execute simply adds a node def execute(self, context): if self.properties.is_property_set("type"): self.create_node(context) return {'FINISHED'} else: return {'CANCELLED'} # Default invoke stores the mouse position to place the node correctly # and optionally invokes the transform operator def invoke(self, context, event): self.store_mouse_cursor(context, event) result = self.execute(context) if self.use_transform and ('FINISHED' in result): # removes the node again if transform is canceled bpy.ops.node.translate_attach_remove_on_cancel('INVOKE_DEFAULT') return result
def register(): bpy.utils.register_module(__name__) wm = bpy.types.WindowManager # Project wm.flamenco_project = EnumProperty(items=project_list, name="Projects", description="Flamenco Projects") wm.flamenco_projectCache = StringProperty(name="Project list cache", default="", options={'HIDDEN', 'SKIP_SAVE'}) # Job Name wm.flamenco_jobName = StringProperty(name="Job Name", default="", options={'HIDDEN', 'SKIP_SAVE'}) # Job Type wm.flamenco_jobType = EnumProperty(items=jobType_list, name="Job type", description="Type of job available") # File Format wm.flamenco_file_format = EnumProperty( items=[('EXR', 'EXR', ''), ('JPEG', 'JPEG', ''), ('PNG', 'PNG', ''), ('JPEG2000', 'JPEG2000', '')], name="File Format", description="Output file format for the job") # Chunk Size wm.flamenco_chunkSize = IntProperty( name="Chunk Size", description="Number of chunks in which the render will be divided.", default=5, soft_min=1, options={'HIDDEN', 'SKIP_SAVE'}) # Managers wm.flamenco_managers = CollectionProperty(type=flamencoManagers, name="Managers", description="Flamenco Managers") wm.flamenco_managersIndex = IntProperty( name="Manager Index", description="Currently selected Flamenco Manager") # Command (Blender Version) wm.flamenco_command = EnumProperty(items=command_names, name="Command", description="Flamenco Command") # Priority wm.flamenco_priority = IntProperty( name="Priority", description= "A value between 0 and 100. The closer to 100, the higher the priority.", default=50, soft_min=0, soft_max=100, options={'HIDDEN', 'SKIP_SAVE'}) # Start Job wm.flamenco_startJob = BoolProperty( name="Start Job", description= "As soon the file is sent to the server, the job will be started.", options={'HIDDEN', 'SKIP_SAVE'}) # Send Packed file wm.flamenco_submit_archive = BoolProperty( name="Send Packed File", description= "If unchecked, the file will be BAM packed, but not sent to the server. \ This will have to be done by hand.", options={'HIDDEN', 'SKIP_SAVE'}, default=True) # Pack Alembic Caches wm.flamenco_pack_alembic_caches = BoolProperty( name="Pack Alembic Caches", description="If checked, .abc caches will be added to the bam archive. \ This can generate very large files.", options={'HIDDEN', 'SKIP_SAVE'}, default=False) # Pack EXR files wm.flamenco_pack_exr_sequences = BoolProperty( name="Pack EXR sequences", description= "If checked, .exr image sequences will be included in the bam archive. \ This can generate very large files.", options={'HIDDEN', 'SKIP_SAVE'}, default=False) # Pack movie files wm.flamenco_pack_movie_files = BoolProperty( name="Pack movie files", description= "If checked, .mov and .avi files will be included in the bam archive. \ This can generate very large files.", options={'HIDDEN', 'SKIP_SAVE'}, default=False) # Pack movie files wm.flamenco_pack_audio_files = BoolProperty( name="Pack audio files", description= "If checked, .wav and .mp3 files will be included in the bam archive. \ This can generate very large files.", options={'HIDDEN', 'SKIP_SAVE'}, default=False) wm.flamenco_settingsServer = CollectionProperty( type=flamencoSettingsServer, name="Server Settings", description="Server Settings") wm.flamenco_settingsServerIndex = IntProperty( name="Server Setting Index", description="Currently selected Flamenco Server Setting") wm.flamenco_settingsManagers = CollectionProperty( type=flamencoSettingsManagers, name="Managers Settings", description="Managers Settings") wm.flamenco_settingsManagerIndex = IntProperty( name="Manager Setting Index", description="Currently selected Flamenco Manager Setting")
class ImportGLTF2(Operator, ImportHelper): """Load a glTF 2.0 file""" bl_idname = 'import_scene.gltf' bl_label = 'Import glTF 2.0' filter_glob: StringProperty(default="*.glb;*.gltf", options={'HIDDEN'}) files: CollectionProperty( name="File Path", type=bpy.types.OperatorFileListElement, ) loglevel: IntProperty(name='Log Level', description="Log Level") import_pack_images: BoolProperty( name='Pack images', description='Pack all images into .blend file', default=True) import_shading: EnumProperty( name="Shading", items=(("NORMALS", "Use Normal Data", ""), ("FLAT", "Flat Shading", ""), ("SMOOTH", "Smooth Shading", "")), description="How normals are computed during import", default="NORMALS") def draw(self, context): layout = self.layout layout.prop(self, 'import_pack_images') layout.prop(self, 'import_shading') def execute(self, context): return self.import_gltf2(context) def import_gltf2(self, context): import os self.set_debug_log() import_settings = self.as_keywords() if self.files: # Multiple file import ret = {'CANCELLED'} dirname = os.path.dirname(self.filepath) for file in self.files: path = os.path.join(dirname, file.name) if self.unit_import(path, import_settings) == {'FINISHED'}: ret = {'FINISHED'} return ret else: # Single file import return self.unit_import(self.filepath, import_settings) def unit_import(self, filename, import_settings): import time from .io.imp.gltf2_io_gltf import glTFImporter from .blender.imp.gltf2_blender_gltf import BlenderGlTF self.gltf_importer = glTFImporter(filename, import_settings) success, txt = self.gltf_importer.read() if not success: self.report({'ERROR'}, txt) return {'CANCELLED'} success, txt = self.gltf_importer.checks() if not success: self.report({'ERROR'}, txt) return {'CANCELLED'} self.gltf_importer.log.critical( "Data are loaded, start creating Blender stuff") start_time = time.time() BlenderGlTF.create(self.gltf_importer) elapsed_s = "{:.2f}s".format(time.time() - start_time) self.gltf_importer.log.critical("glTF import finished in " + elapsed_s) self.gltf_importer.log.removeHandler(self.gltf_importer.log_handler) return {'FINISHED'} def set_debug_log(self): import logging if bpy.app.debug_value == 0: self.loglevel = logging.CRITICAL elif bpy.app.debug_value == 1: self.loglevel = logging.ERROR elif bpy.app.debug_value == 2: self.loglevel = logging.WARNING elif bpy.app.debug_value == 3: self.loglevel = logging.INFO else: self.loglevel = logging.NOTSET
class SelectionSet(PropertyGroup): name: StringProperty(name="Set Name", override={'LIBRARY_OVERRIDABLE'}) bone_ids: CollectionProperty(type=SelectionEntry, override={'LIBRARY_OVERRIDABLE'}) is_selected: BoolProperty(name="Is Selected", override={'LIBRARY_OVERRIDABLE'})
class BoundaryCondition(PropertyGroup): name: EnumProperty(items=getBoundaryConditionClasses, name='Boundary Type', update=refreshBoundaryConditionAttributes) attributes: CollectionProperty(name="Attributes", type=Attribute)
class ImportZOXEL(bpy.types.Operator): """Load a zoxel file""" bl_idname = "import_scene.zoxel" bl_label = "Import Zoxel" # bl_options = {'PRESET', 'UNDO'} filename_ext = ".zox" filter_glob = StringProperty(default="*.zox", options={'HIDDEN'}) x_off = 0.1 y_off = 0.1 z_off = 0.1 files = CollectionProperty(type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'}) directory = StringProperty(maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}) def execute(self, context): for file in self.files: self.doImport(self.directory, file.name) return {'FINISHED'} def draw(self, context): self.layout.operator('file.select_all_toggle') def invoke(self, context, event): wm = context.window_manager wm.fileselect_add(self) return {'RUNNING_MODAL'} def doImport(self, directory, filename): file = os.path.join(directory, filename) print("Loading: " + file) json_string_data = open(file).read() data = json.loads(json_string_data) i = 1 while "frame" + str(i) in data.keys(): framedata = data["frame" + str(i)] self.importFrame(framedata, filename) i = i + 1 def hasVoxel(self, frame, x, y, z): for data in frame: if data[0] == x and data[1] == y and data[2] == z: return True return False def importFrame(self, frame, name): verts = [] faces = [] colors = [] for data in frame: x = data[0] z = data[1] y = data[2] color = data[3] blender_color = (((color >> 8) // 256 // 256 % 256) / 255, ((color >> 8) // 256 % 256) / 255, ((color >> 8) % 256) / 255) numVertAdded = 0 vertOff = len(verts) verts.append((x * self.x_off, y * self.y_off, z * self.z_off)) verts.append( (x * self.x_off + self.x_off, y * self.y_off, z * self.z_off)) verts.append((x * self.x_off + self.x_off, y * self.y_off + self.y_off, z * self.z_off)) verts.append( (x * self.x_off, y * self.y_off + self.y_off, z * self.z_off)) verts.append( (x * self.x_off, y * self.y_off, z * self.z_off + self.z_off)) verts.append((x * self.x_off + self.x_off, y * self.y_off, z * self.z_off + self.z_off)) verts.append( (x * self.x_off + self.x_off, y * self.y_off + self.y_off, z * self.z_off + self.z_off)) verts.append((x * self.x_off, y * self.y_off + self.y_off, z * self.z_off + self.z_off)) # Bottom if not self.hasVoxel(frame, x, z - 1, y): faces.append( (0 + vertOff, 3 + vertOff, 2 + vertOff, 1 + vertOff)) numVertAdded = numVertAdded + 4 # Top if not self.hasVoxel(frame, x, z + 1, y): faces.append( (4 + vertOff, 5 + vertOff, 6 + vertOff, 7 + vertOff)) numVertAdded = numVertAdded + 4 # Left if not self.hasVoxel(frame, x - 1, z, y): faces.append( (0 + vertOff, 4 + vertOff, 7 + vertOff, 3 + vertOff)) numVertAdded = numVertAdded + 4 # Right if not self.hasVoxel(frame, x + 1, z, y): faces.append( (1 + vertOff, 2 + vertOff, 6 + vertOff, 5 + vertOff)) numVertAdded = numVertAdded + 4 # Back if not self.hasVoxel(frame, x, z, y + 1): faces.append( (3 + vertOff, 7 + vertOff, 6 + vertOff, 2 + vertOff)) numVertAdded = numVertAdded + 4 # Front if not self.hasVoxel(frame, x, z, y - 1): faces.append( (0 + vertOff, 1 + vertOff, 5 + vertOff, 4 + vertOff)) numVertAdded = numVertAdded + 4 for i in range(numVertAdded): colors.append(blender_color) meshdata = bpy.data.meshes.new(name) meshdata.from_pydata(verts, [], faces) cl = meshdata.vertex_colors.new() for i in range(len(colors)): cl.data[i].color = colors[i] meshdata.update() obj = bpy.data.objects.new(name, meshdata) scene = bpy.context.scene mesh = obj.data scene.objects.link(obj) obj.select = True scene.update() bpy.context.scene.objects.active = bpy.data.objects[obj.name] bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.remove_doubles() bpy.ops.mesh.select_loose() bpy.ops.mesh.delete(type='VERT') bpy.ops.object.mode_set(mode='OBJECT')
class BIMProperties(PropertyGroup): schema_dir: StringProperty(default=os.path.join(cwd, 'schema') + os.path.sep, name="Schema Directory") data_dir: StringProperty(default=os.path.join(cwd, 'data') + os.path.sep, name="Data Directory") ifc_file: StringProperty(name="IFC File") ifc_cache: StringProperty(name="IFC Cache") audit_ifc_class: EnumProperty(items=getIfcClasses, name="Audit Class") ifc_product: EnumProperty(items=getIfcProducts, name="Products", update=refreshClasses) ifc_class: EnumProperty(items=getIfcClasses, name="Class", update=refreshPredefinedTypes) ifc_predefined_type: EnumProperty(items=getIfcPredefinedTypes, name="Predefined Type", default=None) ifc_userdefined_type: StringProperty(name="Userdefined Type") export_schema: EnumProperty(items=[('IFC4', 'IFC4', ''), ('IFC2X3', 'IFC2X3', '')], name='IFC Schema') export_has_representations: BoolProperty(name="Export Representations", default=True) export_should_export_all_materials_as_styled_items: BoolProperty( name="Export All Materials as Styled Items", default=False) export_should_use_presentation_style_assignment: BoolProperty( name="Export with Presentation Style Assignment", default=False) import_should_ignore_site_coordinates: BoolProperty( name="Import Ignoring Site Coordinates", default=False) import_should_ignore_building_coordinates: BoolProperty( name="Import Ignoring Building Coordinates", default=False) import_should_reset_absolute_coordinates: BoolProperty( name="Import Resetting Absolute Coordinates", default=False) import_should_import_type_representations: BoolProperty( name="Import Type Representations", default=False) import_should_import_curves: BoolProperty(name="Import Curves", default=False) import_should_import_opening_elements: BoolProperty( name="Import Opening Elements", default=False) import_should_import_spaces: BoolProperty(name="Import Spaces", default=False) import_should_auto_set_workarounds: BoolProperty( name="Automatically Set Vendor Workarounds", default=True) import_should_treat_styled_item_as_material: BoolProperty( name="Import Treating Styled Item as Material", default=False) import_should_use_legacy: BoolProperty(name="Import with Legacy Importer", default=False) import_should_import_native: BoolProperty( name="Import Native Representations", default=False) import_should_use_cpu_multiprocessing: BoolProperty( name="Import with CPU Multiprocessing", default=False) import_should_import_aggregates: BoolProperty(name="Import Aggregates", default=True) import_should_merge_aggregates: BoolProperty( name="Import and Merge Aggregates", default=False) import_should_merge_by_class: BoolProperty( name="Import and Merge by Class", default=False) import_should_merge_by_material: BoolProperty( name="Import and Merge by Material", default=False) import_should_merge_materials_by_colour: BoolProperty( name="Import and Merge Materials by Colour", default=False) import_should_clean_mesh: BoolProperty(name="Import and Clean Mesh", default=True) qa_reject_element_reason: StringProperty(name="Element Rejection Reason") person: EnumProperty(items=getPersons, name="Person") organisation: EnumProperty(items=getOrganisations, name="Organisation") has_georeferencing: BoolProperty(name="Has Georeferencing", default=False) has_library: BoolProperty(name="Has Project Library", default=False) search_regex: BoolProperty(name="Search With Regex", default=False) search_ignorecase: BoolProperty(name="Search Ignoring Case", default=True) global_id: StringProperty(name="GlobalId") search_attribute_name: StringProperty(name="Search Attribute Name") search_attribute_value: StringProperty(name="Search Attribute Value") search_pset_name: StringProperty(name="Search Pset Name") search_prop_name: StringProperty(name="Search Prop Name") search_pset_value: StringProperty(name="Search Pset Value") features_dir: StringProperty(default='', name="Features Directory", update=refreshFeaturesFiles) features_file: EnumProperty(items=getFeaturesFiles, name="Features File", update=refreshScenarios) scenario: EnumProperty(items=getScenarios, name="Scenario") diff_json_file: StringProperty(default='', name="Diff JSON File") diff_old_file: StringProperty(default='', name="Diff Old IFC File") diff_new_file: StringProperty(default='', name="Diff New IFC File") diff_relationships: StringProperty(default='', name="Diff Relationships") aggregate_class: EnumProperty(items=getIfcClasses, name="Aggregate Class") aggregate_name: StringProperty(name="Aggregate Name") classification: EnumProperty(items=getClassifications, name="Classification", update=refreshReferences) classifications: CollectionProperty(name="Classifications", type=Classification) has_model_context: BoolProperty(name="Has Model Context", default=True) has_plan_context: BoolProperty(name="Has Plan Context", default=False) model_subcontexts: CollectionProperty(name='Model Subcontexts', type=Subcontext) plan_subcontexts: CollectionProperty(name='Plan Subcontexts', type=Subcontext) available_contexts: EnumProperty(items=[('Model', 'Model', ''), ('Plan', 'Plan', '')], name="Available Contexts") available_subcontexts: EnumProperty(items=getSubcontexts, name="Available Subcontexts") available_target_views: EnumProperty(items=getTargetViews, name="Available Target Views") classification_references: PointerProperty(type=ClassificationView) pset_template_files: EnumProperty(items=getPsetTemplateFiles, name="Pset Template Files", update=refreshPropertySetTemplates) property_set_templates: EnumProperty(items=getPropertySetTemplates, name="Pset Template Files") active_property_set_template: PointerProperty(type=PropertySetTemplate) property_templates: CollectionProperty(name='Property Templates', type=PropertyTemplate) should_section_selected_objects: BoolProperty( name="Section Selected Objects", default=False) section_plane_colour: FloatVectorProperty( name='Temporary Section Cutaway Colour', subtype='COLOR', default=(1, 0, 0), min=0.0, max=1.0) ifc_import_filter: EnumProperty(items=[ ('NONE', 'None', ''), ('WHITELIST', 'Whitelist', ''), ('BLACKLIST', 'Blacklist', ''), ], name='Import Filter') ifc_selector: StringProperty(default='', name='IFC Selector') csv_attributes: CollectionProperty(name='CSV Attributes', type=StrProperty) document_information: CollectionProperty(name='Document Information', type=DocumentInformation) active_document_information_index: IntProperty( name='Active Document Information Index') document_references: CollectionProperty(name='Document References', type=DocumentReference) active_document_reference_index: IntProperty( name='Active Document Reference Index') clash_sets: CollectionProperty(name='Clash Sets', type=ClashSet) active_clash_set_index: IntProperty(name='Active Clash Set Index')
def register(): from bpy.utils import register_class # Sub-modules. ui.register() feature_set_list.register() metarig_menu.register() # Classes. for cls in classes: register_class(cls) # Properties. bpy.types.Armature.rigify_layers = CollectionProperty(type=RigifyArmatureLayer) bpy.types.Armature.active_feature_set = EnumProperty( items=feature_set_list.feature_set_items, name="Feature Set", description="Restrict the rig list to a specific custom feature set" ) bpy.types.PoseBone.rigify_type = StringProperty(name="Rigify Type", description="Rig type for this bone") bpy.types.PoseBone.rigify_parameters = PointerProperty(type=RigifyParameters) bpy.types.Armature.rigify_colors = CollectionProperty(type=RigifyColorSet) bpy.types.Armature.rigify_selection_colors = PointerProperty(type=RigifySelectionColors) bpy.types.Armature.rigify_colors_index = IntProperty(default=-1) bpy.types.Armature.rigify_colors_lock = BoolProperty(default=True) bpy.types.Armature.rigify_theme_to_add = EnumProperty(items=( ('THEME01', 'THEME01', ''), ('THEME02', 'THEME02', ''), ('THEME03', 'THEME03', ''), ('THEME04', 'THEME04', ''), ('THEME05', 'THEME05', ''), ('THEME06', 'THEME06', ''), ('THEME07', 'THEME07', ''), ('THEME08', 'THEME08', ''), ('THEME09', 'THEME09', ''), ('THEME10', 'THEME10', ''), ('THEME11', 'THEME11', ''), ('THEME12', 'THEME12', ''), ('THEME13', 'THEME13', ''), ('THEME14', 'THEME14', ''), ('THEME15', 'THEME15', ''), ('THEME16', 'THEME16', ''), ('THEME17', 'THEME17', ''), ('THEME18', 'THEME18', ''), ('THEME19', 'THEME19', ''), ('THEME20', 'THEME20', '') ), name='Theme') IDStore = bpy.types.WindowManager IDStore.rigify_collection = EnumProperty(items=(("All", "All", "All"),), default="All", name="Rigify Active Collection", description="The selected rig collection") IDStore.rigify_types = CollectionProperty(type=RigifyName) IDStore.rigify_active_type = IntProperty(name="Rigify Active Type", description="The selected rig type") bpy.types.Armature.rigify_advanced_generation = BoolProperty(name="Advanced Options", description="Enables/disables advanced options for Rigify rig generation", default=False) def update_mode(self, context): if self.rigify_generate_mode == 'new': self.rigify_force_widget_update = False bpy.types.Armature.rigify_generate_mode = EnumProperty(name="Rigify Generate Rig Mode", description="'Generate Rig' mode. In 'overwrite' mode the features of the target rig will be updated as defined by the metarig. In 'new' mode a new rig will be created as defined by the metarig. Current mode", update=update_mode, items=( ('overwrite', 'overwrite', ''), ('new', 'new', ''))) bpy.types.Armature.rigify_force_widget_update = BoolProperty(name="Force Widget Update", description="Forces Rigify to delete and rebuild all the rig widgets. if unset, only missing widgets will be created", default=False) bpy.types.Armature.rigify_target_rig = PointerProperty(type=bpy.types.Object, name="Rigify Target Rig", description="Defines which rig to overwrite. If unset, a new one called 'rig' will be created", poll=lambda self, obj: obj.type == 'ARMATURE' and obj.data is not self) bpy.types.Armature.rigify_rig_ui = PointerProperty(type=bpy.types.Text, name="Rigify Target Rig UI", description="Defines the UI to overwrite. If unset, 'rig_ui.py' will be used") bpy.types.Armature.rigify_rig_basename = StringProperty(name="Rigify Rig Name", description="Defines the name of the Rig. If unset, in 'new' mode 'rig' will be used, in 'overwrite' mode the target rig name will be used", default="") IDStore.rigify_transfer_only_selected = BoolProperty( name="Transfer Only Selected", description="Transfer selected bones only", default=True) # Update legacy on restart or reload. if legacy_loaded or bpy.context.preferences.addons['rigify'].preferences.legacy_mode: bpy.context.preferences.addons['rigify'].preferences.legacy_mode = True bpy.context.preferences.addons['rigify'].preferences.register_feature_sets(True) bpy.context.preferences.addons['rigify'].preferences.update_external_rigs() # Add rig parameters register_rig_parameters()
class MMDRoot(PropertyGroup): """ MMDモデルデータ モデルルート用に作成されたEmtpyオブジェクトで使用します """ name = StringProperty( name='Name', description='The name of the MMD model', default='', ) name_e = StringProperty( name='Name (English)', description='The english name of the MMD model', default='', ) comment_text = StringProperty( name='Comment', description='The text datablock of the comment', default='', ) comment_e_text = StringProperty( name='Comment (English)', description='The text datablock of the english comment', default='', ) show_meshes = BoolProperty( name='Show Meshes', description='Show all meshes of the MMD model', update=_toggleVisibilityOfMeshes, ) show_rigid_bodies = BoolProperty( name='Show Rigid Bodies', description='Show all rigid bodies of the MMD model', update=_toggleVisibilityOfRigidBodies, ) show_joints = BoolProperty( name='Show Joints', description='Show all joints of the MMD model', update=_toggleVisibilityOfJoints, ) show_temporary_objects = BoolProperty( name='Show Temps', description='Show all temporary objects of the MMD model', update=_toggleVisibilityOfTemporaryObjects, ) show_armature = BoolProperty( name='Show Armature', description='Show the armature object of the MMD model', get=_getVisibilityOfMMDRigArmature, set=_setVisibilityOfMMDRigArmature, ) show_names_of_rigid_bodies = BoolProperty( name='Show Rigid Body Names', description='Show rigid body names', update=_toggleShowNamesOfRigidBodies, ) show_names_of_joints = BoolProperty( name='Show Joint Names', description='Show joint names', update=_toggleShowNamesOfJoints, ) use_toon_texture = BoolProperty( name='Use Toon Texture', description='Use toon texture', update=_toggleUseToonTexture, default=True, ) use_sphere_texture = BoolProperty( name='Use Sphere Texture', description='Use sphere texture', update=_toggleUseSphereTexture, default=True, ) is_built = BoolProperty(name='Is Built', ) active_rigidbody_index = IntProperty( name='Active Rigidbody Index', min=0, get=_getActiveRigidbodyObject, set=_setActiveRigidbodyObject, ) active_joint_index = IntProperty( name='Active Joint Index', min=0, get=_getActiveJointObject, set=_setActiveJointObject, ) #************************* # Display Items #************************* display_item_frames = CollectionProperty( name='Display Frames', type=MMDDisplayItemFrame, ) active_display_item_frame = IntProperty( name='Active Display Item Frame', min=0, default=0, ) #************************* # Morph #************************* material_morphs = CollectionProperty( name='Material Morphs', type=MaterialMorph, ) uv_morphs = CollectionProperty( name='UV Morphs', type=UVMorph, ) bone_morphs = CollectionProperty( name='Bone Morphs', type=BoneMorph, ) vertex_morphs = CollectionProperty(name='Vertex Morphs', type=VertexMorph) group_morphs = CollectionProperty( name='Group Morphs', type=GroupMorph, ) active_morph_type = EnumProperty( name='Active Morph Type', description='Select current morph type', items=[ ('material_morphs', 'Material', 'Material Morphs', 0), ('uv_morphs', 'UV', 'UV Morphs', 1), ('bone_morphs', 'Bone', 'Bone Morphs', 2), ('vertex_morphs', 'Vertex', 'Vertex Morphs', 3), ('group_morphs', 'Group', 'Group Morphs', 4), ], default='vertex_morphs', ) active_morph = IntProperty( name='Active Morph', min=0, set=_setActiveMorph, get=_getActiveMorph, ) active_mesh_index = IntProperty( name='Active Mesh', description='Active Mesh in this model', set=_setActiveMeshObject, get=_getActiveMeshObject, )
class CurveTools2Settings(PropertyGroup): # selection SelectedObjects = CollectionProperty( type=Properties.CurveTools2SelectedObject) NrSelectedObjects = IntProperty(name="NrSelectedObjects", default=0, description="Number of selected objects", update=UpdateDummy) """ NrSelectedObjects = IntProperty( name="NrSelectedObjects", default=0, description="Number of selected objects" ) """ # curve CurveLength = FloatProperty(name="CurveLength", default=0.0, precision=6) # splines SplineResolution = IntProperty( name="SplineResolution", default=64, min=2, max=1024, soft_min=2, description="Spline resolution will be set to this value") SplineRemoveLength = FloatProperty( name="SplineRemoveLength", default=0.001, precision=6, description="Splines shorter than this threshold length will be removed" ) SplineJoinDistance = FloatProperty( name="SplineJoinDistance", default=0.001, precision=6, description="Splines with starting/ending points closer to each other " "than this threshold distance will be joined") SplineJoinStartEnd = BoolProperty( name="SplineJoinStartEnd", default=False, description= "Only join splines at the starting point of one and the ending point of the other" ) splineJoinModeItems = (('At midpoint', 'At midpoint', 'Join splines at midpoint of neighbouring points'), ('Insert segment', 'Insert segment', 'Insert segment between neighbouring points')) SplineJoinMode = EnumProperty( items=splineJoinModeItems, name="SplineJoinMode", default='At midpoint', description="Determines how the splines will be joined") # curve intersection LimitDistance = FloatProperty( name="LimitDistance", default=0.0001, precision=6, description="Displays the result of the curve length calculation") intAlgorithmItems = (('3D', '3D', 'Detect where curves intersect in 3D'), ('From View', 'From View', 'Detect where curves intersect in the RegionView3D')) IntersectCurvesAlgorithm = EnumProperty( items=intAlgorithmItems, name="IntersectCurvesAlgorithm", description="Determines how the intersection points will be detected", default='3D') intModeItems = (('Insert', 'Insert', 'Insert points into the existing spline(s)'), ('Split', 'Split', 'Split the existing spline(s) into 2'), ('Empty', 'Empty', 'Add empty at intersections')) IntersectCurvesMode = EnumProperty( items=intModeItems, name="IntersectCurvesMode", description="Determines what happens at the intersection points", default='Split') intAffectItems = (('Both', 'Both', 'Insert points into both curves'), ('Active', 'Active', 'Insert points into active curve only'), ('Other', 'Other', 'Insert points into other curve only')) IntersectCurvesAffect = EnumProperty( items=intAffectItems, name="IntersectCurvesAffect", description= "Determines which of the selected curves will be affected by the operation", default='Both')
def room_walls_property(callback=None): return CollectionProperty(type=ArchLabWallProperties)
class PALETTE_Props(PropertyGroup): def update_color_name(self, context): pp = bpy.context.scene.palette_props pp.colors[pp.current_color_index].name = pp.color_name return None def move_color(self, context): pp = bpy.context.scene.palette_props if pp.colors.items() and pp.current_color_index != pp.index: if pp.index >= pp.colors.__len__(): pp.index = pp.colors.__len__() - 1 pp.colors.move(pp.current_color_index, pp.index) pp.current_color_index = pp.index return None def update_weight(self, context): pp = context.scene.palette_props weight = pp.weight if pp.current_weight_index == 0: pp.weight_0 = weight elif pp.current_weight_index == 1: pp.weight_1 = weight elif pp.current_weight_index == 2: pp.weight_2 = weight elif pp.current_weight_index == 3: pp.weight_3 = weight elif pp.current_weight_index == 4: pp.weight_4 = weight elif pp.current_weight_index == 5: pp.weight_5 = weight elif pp.current_weight_index == 6: pp.weight_6 = weight elif pp.current_weight_index == 7: pp.weight_7 = weight elif pp.current_weight_index == 8: pp.weight_8 = weight elif pp.current_weight_index == 9: pp.weight_9 = weight elif pp.current_weight_index == 10: pp.weight_10 = weight bpy.context.tool_settings.unified_paint_settings.weight = weight return None palette_name: StringProperty(name="Palette Name", default="Preset", subtype='FILE_NAME') color_name: StringProperty(name="", description="Color Name", default="Untitled", update=update_color_name) columns: IntProperty(name="Columns", description="Number of Columns", min=0, max=16, default=0) index: IntProperty(name="Index", description="Move Selected Color", min=0, update=move_color) notes: StringProperty(name="Palette Notes", default="#\n") current_color_index: IntProperty(name="Current Color Index", description="", default=0, min=0) current_weight_index: IntProperty(name="Current Color Index", description="", default=10, min=-1) presets_folder: StringProperty(name="", description="Palettes Folder", subtype="DIR_PATH", default="//") colors: CollectionProperty(type=PALETTE_Colors) weight: FloatProperty( name="Weight", description="Modify the active Weight preset slot value", default=0.0, min=0.0, max=1.0, precision=3, update=update_weight) weight_0: FloatProperty(default=0.0, min=0.0, max=1.0, precision=3) weight_1: FloatProperty(default=0.1, min=0.0, max=1.0, precision=3) weight_2: FloatProperty(default=0.25, min=0.0, max=1.0, precision=3) weight_3: FloatProperty(default=0.333, min=0.0, max=1.0, precision=3) weight_4: FloatProperty(default=0.4, min=0.0, max=1.0, precision=3) weight_5: FloatProperty(default=0.5, min=0.0, max=1.0, precision=3) weight_6: FloatProperty(default=0.6, min=0.0, max=1.0, precision=3) weight_7: FloatProperty(default=0.6666, min=0.0, max=1.0, precision=3) weight_8: FloatProperty(default=0.75, min=0.0, max=1.0, precision=3) weight_9: FloatProperty(default=0.9, min=0.0, max=1.0, precision=3) weight_10: FloatProperty(default=1.0, min=0.0, max=1.0, precision=3)