def execute(self, context): obj = context.active_object bv_dp = False bv_ob = False if obj.data.bevel_depth: bv_dp = obj.data.bevel_depth obj.data.bevel_depth = 0.0 if obj.data.bevel_object: bv_ob = obj.data.bevel_object obj.data.bevel_object = None length = unit.to_metric(mesh.edges_length(obj)) curve_length = '{:.2f} {}'.format(length, _('mm')) popup_report(self, curve_length, title=_('Curve Length'), icon='IPO_QUAD') if bv_dp: obj.data.bevel_depth = bv_dp if bv_ob: obj.data.bevel_object = bv_ob return {'FINISHED'}
def execute(self, context): ReportData = report_get.data_collect(self, context, gem_map=True) if not ReportData.gems: self.report({"ERROR"}, "No gems in the scene") return {"CANCELLED"} import time self.region = context.region self.region_3d = context.space_data.region_3d self.view_mat = self.region_3d.perspective_matrix.copy() self.offscreen = None self.handler = None self.use_navigate = False self.is_rendering = False self.time_tag = time.time() # 3D View # ---------------------------- self.view_padding_left, self.view_padding_top = view3d_lib.padding_init( context) self.view_margin = 40 view3d_lib.options_init( self, ( (_("Limit By Selection"), "(S)", "use_select", view3d_lib.TYPE_BOOL), (_("Save To Image"), "(F12)", "is_rendering", view3d_lib.TYPE_PROC), ), ) # Gem report # ---------------------------- self.data_process(ReportData) # Warnings # ---------------------------- self.show_warn = bool(ReportData.warnings) if self.show_warn: self.warn = [_("WARNING") ] + [f"* {_(x)}" for x in ReportData.warnings] # Handlers # ---------------------------- self.offscreen_refresh(context) self.handler = bpy.types.SpaceView3D.draw_handler_add( draw_handler.draw, (self, context), "WINDOW", "POST_PIXEL") context.window_manager.modal_handler_add(self) context.workspace.status_text_set("ESC/↵/␣: Exit") return {"RUNNING_MODAL"}
def execute(self, context): obs = [ob for ob in context.selected_objects if ob.type == "MESH"] if not obs: self.report({"ERROR"}, "At least one mesh object must be selected") return {"CANCELLED"} materials = context.scene.jewelcraft.weighting_materials vol = unit.Scale(context).from_scene(mesh.est_volume(obs), volume=True) weight_report = [] volume_fmt = "{} {} {}".format(round(vol, 4), _("mm³"), _("Volume")) weight_report.append(volume_fmt) for mat in materials.values(): if mat.enabled: density = unit.convert(mat.density, "CM3_TO_MM3") weight = round(vol * density, 2) weight_fmt = "{} {} {}".format(weight, _("g"), mat.name) weight_report.append(weight_fmt) ui_lib.popup_report_batch(self, context, data=weight_report, title=_("Weighting")) return {"FINISHED"}
def execute(self, context): item = context.scene.jewelcraft.measurements.add() item.type = self.type if self.type == "RING_SIZE": if self.object_name: item.object = bpy.data.objects[self.object_name] else: if self.collection_name: item.collection = bpy.data.collections[self.collection_name] if self.type == "WEIGHT": materials = context.scene.jewelcraft.weighting_materials mat = materials.values()[int(self.material)] item.name = mat.name item.material_name = mat.name item.material_density = mat.density elif self.type == "DIMENSIONS": item.name = "{} {}".format(self.collection_name, _("Dimensions")) item.x = self.x item.y = self.y item.z = self.z elif self.type == "RING_SIZE": size_format = UILayout.enum_item_name(self, "ring_size", self.ring_size) item.name = "{} ({})".format(_("Ring Size"), size_format) item.ring_size = self.ring_size item.axis = self.axis context.area.tag_redraw() return {"FINISHED"}
def execute(self, context): from ..lib import unit, mesh, ui_lib obs = [ ob for ob in context.selected_objects if ob.type in {"MESH", "CURVE", "SURFACE", "FONT", "META"} ] if not obs: self.report({"ERROR"}, "At least one mesh object must be selected") return {"CANCELLED"} materials = context.scene.jewelcraft.weighting_materials vol = unit.Scale().from_scene_vol(mesh.est_volume(obs)) weight_report = [] volume_fmt = "{} {} {}".format(round(vol, 4), _("mm³"), _("Volume")) weight_report.append(volume_fmt) for mat in materials.values(): if mat.enabled: density = unit.convert_cm3_mm3(mat.density) weight = round(vol * density, 2) weight_fmt = "{} {} {}".format(weight, _("g"), mat.name) weight_report.append(weight_fmt) ui_lib.popup_list(self, _("Weighting"), weight_report) return {"FINISHED"}
def execute(self, context): obs = [ob for ob in context.selected_objects if ob.type == "MESH"] if not obs: self.report({"ERROR"}, "At least one mesh object must be selected") return {"CANCELLED"} prefs = context.preferences.addons[var.ADDON_ID].preferences materials = prefs.weighting_materials vol = unit.to_metric(mesh.est_volume(obs), volume=True) weight_report = [] volume_fmt = "{} {} {}".format(round(vol, 4), _("mm³"), _("Volume")) weight_report.append(volume_fmt) for mat in materials.values(): if mat.enabled: density = unit.convert(mat.density, "CM3_TO_MM3") weight = round(vol * density, 2) weight_fmt = "{} {} {}".format(weight, _("g"), mat.name) weight_report.append(weight_fmt) ui_lib.popup_report_batch(self, weight_report, title=_("Weighting")) return {"FINISHED"}
def execute(self, context): ob = context.active_object if not ob or ob.type != "CURVE": self.report({"ERROR"}, "Active object must be a curve") return {"CANCELLED"} # Reset curve # --------------------------- settings = {"bevel_object": None, "bevel_depth": 0.0, "extrude": 0.0} for k, v in settings.items(): x = getattr(ob.data, k) setattr(ob.data, k, v) settings[k] = x # Display length # --------------------------- length = unit.to_metric(mesh.curve_length(ob)) lengthf = "{:.2f} {}".format(length, _("mm")) ui_lib.popup_report(self, lengthf, title=_("Curve Length")) # Restore curve # --------------------------- for k, v in settings.items(): setattr(ob.data, k, v) return {"FINISHED"}
def execute(self, context): from ..lib import asset for ob in context.selected_objects: ob.select_set(False) obs = [] ob_data = [] app_obs = obs.append app_data = ob_data.append depsgraph = context.evaluated_depsgraph_get() for dup, _, ob in asset.iter_gems(depsgraph): app_obs(ob) app_data(asset.gem_transform(dup)) overlaps = asset.gem_overlap(ob_data, self.threshold) if overlaps: for i in overlaps: obs[i].select_set(True) self.report({"WARNING"}, _("{} overlaps found").format(len(overlaps))) else: self.report({"INFO"}, _("{} overlaps found").format(0)) return {"FINISHED"}
def execute(self, context): doubles = collections.defaultdict(list) for ob in context.visible_objects: ob.select = False if "gem" in ob: loc = ob.matrix_world.to_translation().to_tuple() doubles[loc].append(ob) doubles = {k: v for k, v in doubles.items() if len(v) > 1} if doubles: d = 0 for obs in doubles.values(): for ob in obs[:-1]: ob.select = True d += 1 self.report({"WARNING"}, _("{} duplicates found").format(d)) else: self.report({"INFO"}, _("{} duplicates found").format(0)) return {"FINISHED"}
def cuts(self, context): lang = _iface_lang(context) color = context.preferences.themes[0].user_interface.wcol_menu_item.text.v if lang == _cache.get("cuts__LANG") and color == _cache.get("cuts__COLOR"): return _cache["cuts__RESULT"] theme = "DARK" if color < 0.5 else "LIGHT" pcoll = var.preview_collections.get("cuts") if not pcoll: import bpy.utils.previews pcoll = bpy.utils.previews.new() for entry in os.scandir(var.GEM_ASSET_DIR): if entry.is_dir(): for subentry in os.scandir(entry.path): if subentry.is_file() and subentry.name.endswith(".png"): preview_id = entry.name + os.path.splitext( subentry.name)[0] pcoll.load(preview_id.upper(), subentry.path, "IMAGE") var.preview_collections["cuts"] = pcoll list_ = tuple((k, _(_(v.name, "Jewelry")), "", pcoll[theme + k].icon_id, i) # _(_()) default return value workaround for i, (k, v) in enumerate(var.CUTS.items())) _cache["cuts__RESULT"] = list_ _cache["cuts__LANG"] = lang _cache["cuts__COLOR"] = color return list_
def cuts(self, context): lang = _iface_lang(context) theme = context.preferences.addons[var.ADDON_ID].preferences.theme_icon if lang == _cache.get("cuts__LANG") and theme == _cache.get("cuts__THEME"): return _cache["cuts__RESULT"] pcoll = var.preview_collections.get("cuts") if not pcoll: pcoll = bpy.utils.previews.new() for entry in os.scandir(var.GEM_ASSET_DIR): if entry.is_dir(): for subentry in os.scandir(entry.path): if subentry.is_file() and subentry.name.endswith(".png"): preview_id = entry.name + os.path.splitext( subentry.name)[0] pcoll.load(preview_id.upper(), subentry.path, "IMAGE") var.preview_collections["cuts"] = pcoll list_ = tuple((k, _(_(v.name, "JewelCraft")), "", pcoll[theme + k].icon_id, i) # _(_()) default return value workaround for i, (k, v) in enumerate(var.CUTS.items())) _cache["cuts__RESULT"] = list_ _cache["cuts__LANG"] = lang _cache["cuts__THEME"] = theme return list_
def _cuts(lang: str, color: float) -> EnumItems5: from . import gemlib pcoll = previewlib.scan_icons("cuts", var.GEM_ASSET_DIR) theme = "DARK" if color < 0.5 else "LIGHT" return tuple((k, _(_(v.name, "Jewelry")), "", pcoll[theme + k].icon_id, i) # _(_()) default return value workaround for i, (k, v) in enumerate(gemlib.CUTS.items()))
def execute(self, context): from ..lib import asset obs = [] ob_data = [] depsgraph = context.evaluated_depsgraph_get() for dup in depsgraph.object_instances: if dup.is_instance: ob = dup.instance_object.original else: ob = dup.object.original ob.select_set(False) if "gem" in ob: loc = dup.matrix_world.to_translation() rad = max(ob.dimensions[:2]) / 2 if dup.is_instance: mat = dup.matrix_world.copy() if ob.parent and ob.parent.is_instancer: sel = ob.parent else: sel = None else: mat_loc = Matrix.Translation(loc) mat_rot = dup.matrix_world.to_quaternion().to_matrix( ).to_4x4() mat = mat_loc @ mat_rot sel = ob loc.freeze() mat.freeze() obs.append(sel) ob_data.append((loc, rad, mat)) overlaps = asset.gem_overlap(context, ob_data, self.threshold) if overlaps: for i in overlaps: ob = obs[i] if ob: ob.select_set(True) self.report({"WARNING"}, _("{} overlaps found").format(len(overlaps))) else: self.report({"INFO"}, _("{} overlaps found").format(0)) return {"FINISHED"}
def execute(self, context): obs = [] ob_data = [] context.scene.update() for dup in context.depsgraph.object_instances: if dup.is_instance: ob = dup.instance_object.original else: ob = dup.object.original ob.select_set(False) if "gem" in ob: loc = dup.matrix_world.to_translation() rad = max(ob.dimensions[:2]) / 2 if dup.is_instance: mat = dup.matrix_world.copy() if ob.parent and ob.parent.is_instancer: sel = ob.parent else: sel = None else: mat_loc = Matrix.Translation(loc) mat_rot = dup.matrix_world.to_quaternion().to_matrix().to_4x4() mat = mat_loc @ mat_rot sel = ob loc.freeze() mat.freeze() obs.append(sel) ob_data.append((loc, rad, mat)) overlaps = asset.gem_overlap(context, ob_data, self.threshold) if overlaps: for i in overlaps: ob = obs[i] if ob: ob.select_set(True) self.report({"WARNING"}, _("{} overlaps found").format(len(overlaps))) else: self.report({"INFO"}, _("{} overlaps found").format(0)) return {"FINISHED"}
def _stones(lang: str) -> EnumItems4: import operator from . import gemlib list_ = [ (k, _(_(v.name, "Jewelry")), "", i) # _(_()) default return value workaround for i, (k, v) in enumerate(gemlib.STONES.items()) ] list_.sort(key=operator.itemgetter(1)) return tuple(list_)
def sidebar_ui(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False row = layout.row(align=True) row.alignment = "CENTER" if var.update_completed: row.label(text="Update completed") row.operator(operators.OP_IDNAME_WHATS_NEW) row = layout.row(align=True) row.alignment = "CENTER" row.label(text="Close Blender to complete the installation", icon="ERROR") elif var.update_in_progress: row.label(text="Installing...") elif var.update_available: row.label(text=_("Update {} is available").format(var.update_version)) col = layout.row() col.alignment = "CENTER" col.scale_y = 1.5 col.enabled = not var.update_in_progress and not var.update_completed col.operator(operators.OP_IDNAME_DOWNLOAD)
def sidebar_ui(layout): row = layout.row(align=True) row.alignment = "CENTER" if state.status is state.COMPLETED: row.label(text="Update completed") row.operator(operators.WM_OT_update_whats_new.bl_idname) row = layout.row(align=True) row.alignment = "CENTER" row.label(text="Close Blender to complete the installation", icon="ERROR") elif state.status is state.INSTALLING: row.label(text="Installing...") elif state.status is state.ERROR: row.label(text=state.error_msg) else: row.label( text=_("Update {} is available").format(state.update_version)) col = layout.row() col.alignment = "CENTER" col.scale_y = 1.5 col.enabled = state.status is None or state.status is state.ERROR col.operator(operators.WM_OT_update_download.bl_idname)
def execute(self, context): import json if self.clear_materials: self.materials.clear() if self.filename.startswith("JCASSET"): for name, dens, comp in var.DEFAULT_WEIGHTING_SETS[self.filename]: item = self.materials.add() item.name = _(name) item.composition = comp item.density = dens else: with open(self.filepath, "r", encoding="utf-8") as file: data = json.load(file) for mat in data: item = self.materials.add() if mat["name"]: item.name = mat["name"] if mat["composition"]: item.composition = mat["composition"] item.density = mat["density"] return {"FINISHED"}
def sidebar_ui(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False row = layout.row(align=True) row.alignment = "CENTER" if state.status is state.COMPLETED: row.label(text="Update completed") row.operator(operators.OP_IDNAME_WHATS_NEW) row = layout.row(align=True) row.alignment = "CENTER" row.label(text="Close Blender to complete the installation", icon="ERROR") elif state.status is state.INSTALLING: row.label(text="Installing...") elif state.status is state.ERROR: row.label(text=state.error_msg) else: row.label(text=_("Update {} is available").format(state.version_new)) col = layout.row() col.alignment = "CENTER" col.scale_y = 1.5 col.enabled = state.status is None or state.status is state.ERROR col.operator(operators.OP_IDNAME_DOWNLOAD)
def execute(self, context): import collections doubles = collections.defaultdict(list) for dup in context.depsgraph.object_instances: if dup.is_instance: ob = dup.instance_object.original else: ob = dup.object.original ob.select_set(False) if "gem" in ob: if dup.is_instance: if ob.parent and ob.parent.is_instancer: value = ob.parent else: value = None else: value = ob loc = dup.matrix_world.translation.to_tuple() doubles[loc].append(value) doubles = {k: v for k, v in doubles.items() if len(v) > 1} if doubles: d = 0 for obs in doubles.values(): for ob in obs[1:]: if ob: ob.select_set(True) d += 1 self.report({"WARNING"}, _("{} duplicates found").format(d)) else: self.report({"INFO"}, _("{} duplicates found").format(0)) return {"FINISHED"}
def execute(self, context): prefs = context.preferences.addons[var.ADDON_ID].preferences data_raw = report_get.data_collect(context) data_fmt = report_fmt.data_format(context, data_raw) # Compose text datablock # --------------------------- if data_raw["warn"]: sep = "-" * 30 warn_fmt = _("WARNING") + "\n" warn_fmt = sep + "\n" for msg in data_raw["warn"]: warn_fmt += f"* {_(msg)}\n" warn_fmt += sep + "\n\n" data_fmt = warn_fmt + data_fmt if "Product Report" in bpy.data.texts: txt = bpy.data.texts["Product Report"] txt.clear() else: txt = bpy.data.texts.new("Product Report") txt.write(data_fmt) txt.current_line_index = 0 # Save to file # --------------------------- if prefs.product_report_save and bpy.data.is_saved: filepath = bpy.data.filepath filename = os.path.splitext(os.path.basename(filepath))[0] save_path = os.path.join(os.path.dirname(filepath), filename + " Report.txt") with open(save_path, "w", encoding="utf-8") as file: file.write(data_fmt) # Display # --------------------------- space_data = { "show_line_numbers": False, "show_word_wrap": False, "show_syntax_highlight": False, "text": txt, } asset.show_window(800, 540, area_type="TEXT_EDITOR", space_data=space_data) return {"FINISHED"}
def draw(self_local, context): for msg in warnf: self_local.layout.label(text=msg, icon="ERROR") self.report({"WARNING"}, msg) if prefs.product_report_save: if bpy.data.is_saved: msg = _("Text file successfully created in the project folder") report_icon = "BLANK1" report_type = {"INFO"} else: msg = _("Could not create text file, project folder does not exist") report_icon = "ERROR" report_type = {"WARNING"} self_local.layout.label(text=msg, icon=report_icon) self.report(report_type, msg)
def stones(self, context): lang = _iface_lang(context) if lang == _cache.get("stones__LANG"): return _cache["stones__RESULT"] list_ = [ (k, _(_(v.name, "JewelCraft")), "", i ) # _(_()) default return value workaround for i, (k, v) in enumerate(var.STONES.items()) ] list_.sort(key=lambda x: x[1]) list_ = tuple(list_) _cache["stones__RESULT"] = list_ _cache["stones__LANG"] = lang return list_
def stones(self, context) -> EnumItems4: import operator lang = _iface_lang(context) if lang == _cache.get("stones__LANG"): return _cache["stones__RESULT"] list_ = [ (k, _(_(v.name, "Jewelry")), "", i) # _(_()) default return value workaround for i, (k, v) in enumerate(var.STONES.items()) ] list_.sort(key=operator.itemgetter(1)) list_ = tuple(list_) _cache["stones__RESULT"] = list_ _cache["stones__LANG"] = lang return list_
def weighting_set(self, context) -> EnumItems4: if "weighting_set__RESULT" in _cache: return _cache["weighting_set__RESULT"] prefs = context.preferences.addons[var.ADDON_ID].preferences lib_path = pathutils.get_weighting_lib_path() wsets = {} list_ = [] if not prefs.weighting_hide_default_sets: description = { "Base.json": "Set of base metal alloys, physical properties taken directly from suppliers", "Precious RU (ГОСТ 30649-99).json": "Set of precious alloys according to Russian regulations", "Precious.json": "Commonly used precious alloys, physical properties taken directly from suppliers", } for entry in os.scandir(var.WEIGHTING_SET_DIR): if entry.is_file() and entry.name.endswith(".json"): name = _(os.path.splitext(entry.name)[0], "Jewelry") wsets[f"__ASSET__{entry.name}"] = (name, description.get( entry.name, "")) if os.path.exists(lib_path): for entry in os.scandir(lib_path): if entry.is_file() and entry.name.endswith(".json"): name = os.path.splitext( entry.name )[0] + " " # Add trailing space to deny UI translation wsets[entry.name] = (name, "") if wsets: if prefs.weighting_set_autoload not in wsets: prefs.weighting_set_autoload = next(iter(wsets)) context.preferences.is_dirty = True i = 1 for k, v in wsets.items(): if k == prefs.weighting_set_autoload: list_.append((k, *v, "DOT", 0)) else: list_.append((k, *v, "BLANK1", i)) i += 1 list_ = tuple(list_) _cache["weighting_set__RESULT"] = list_ return list_
def weighting_set_deserialize(filename: str) -> None: mats = bpy.context.scene.jewelcraft.weighting_materials if filename.startswith("JCASSET"): for name, dens, comp in var.DEFAULT_WEIGHTING_SETS[filename]: item = mats.add() item.name = _(name) item.composition = comp item.density = dens mats.index = 0 else: filepath = os.path.join(pathutils.get_weighting_lib_path(), filename) ul_deserialize(mats, filepath)
def execute(self, context): version_281 = bpy.app.version >= (2, 81, 14) data_raw = report_get.data_collect(self, context) data_fmt = report_fmt.data_format(self, context, data_raw) # Compose text datablock # --------------------------- if data_raw["warn"]: sep = "-" * 30 warn_fmt = sep + "\n" warn_fmt += _("WARNING") + "\n" for msg in data_raw["warn"]: warn_fmt += f"* {_(msg)}\n" warn_fmt += sep + "\n\n" data_fmt = warn_fmt + data_fmt if "Product Report" in bpy.data.texts: txt = bpy.data.texts["Product Report"] txt.clear() else: txt = bpy.data.texts.new("Product Report") txt.write(data_fmt) if version_281: txt.cursor_set(0) else: txt.current_line_index = 0 # Save to file # --------------------------- if self.use_save and bpy.data.is_saved: filepath = bpy.data.filepath filename = os.path.splitext(os.path.basename(filepath))[0] save_path = os.path.join(os.path.dirname(filepath), filename + " Report.txt") with open(save_path, "w", encoding="utf-8") as file: file.write(data_fmt) # Display, workaround for T64439 # --------------------------- self.txt = txt context.window_manager.modal_handler_add(self) return {"RUNNING_MODAL"}
def weighting_set(self, context): if "weighting_set__RESULT" in _cache: return _cache["weighting_set__RESULT"] prefs = context.preferences.addons[var.ADDON_ID].preferences lib_path = asset.get_weighting_lib_path() wsets = {} list_ = [] if not prefs.weighting_hide_default_sets: wsets["JCASSET_PRECIOUS"] = ( "Precious", "Commonly used precious alloys, physical properties taken directly from suppliers", ) wsets["JCASSET_PRECIOUS_RU"] = ( "Precious RU (ГОСТ 30649-99)", "Set of precious alloys according to Russian regulations", ) wsets["JCASSET_BASE"] = ( _("Base", "Jewelry"), "Set of base metal alloys, physical properties taken directly from suppliers", ) if os.path.exists(lib_path): for entry in os.scandir(lib_path): if entry.is_file() and entry.name.endswith(".json"): name = os.path.splitext( entry.name )[0] + " " # Add trailing space to deny UI translation wsets[entry.name] = (name, "") if wsets: if prefs.weighting_set_autoload not in wsets: prefs.weighting_set_autoload = next(iter(wsets)) context.preferences.is_dirty = True i = 1 for k, v in wsets.items(): if k == prefs.weighting_set_autoload: list_.append((k, *v, "DOT", 0)) else: list_.append((k, *v, "BLANK1", i)) i += 1 list_ = tuple(list_) _cache["weighting_set__RESULT"] = list_ return list_
def execute(self, context): ob = context.object if not ob or ob.type != "CURVE": self.report({"ERROR"}, "Active object must be a curve") return {"CANCELLED"} # Reset curve # --------------------------- settings = { "bevel_object": None, "bevel_depth": 0.0, "extrude": 0.0, } for k, v in settings.items(): x = getattr(ob.data, k) setattr(ob.data, k, v) settings[k] = x # Display length # --------------------------- length = unit.Scale(context).from_scene(mesh.curve_length(ob)) lengthf = "{:.2f} {}".format(length, _("mm")) ui_lib.popup_report(self, context, text=lengthf, title=_("Curve Length")) # Restore curve # --------------------------- for k, v in settings.items(): setattr(ob.data, k, v) return {"FINISHED"}
def execute(self, context): from ..lib import mesh, ui_lib ob = context.object if not ob or ob.type != "CURVE": self.report({"ERROR"}, "Active object must be a curve") return {"CANCELLED"} length = unit.Scale().from_scene(mesh.est_curve_length(ob)) report = f"{length:.2f} {_('mm')}" ui_lib.popup_list(self, _("Curve Length"), (report, )) return {"FINISHED"}
def execute(self, context): props = context.window_manager.jewelcraft mat = props.weighting_mat obj = context.active_object vol = unit.to_metric(mesh.volume(obj), volume=True) if mat == 'VOLUME': weight = '{} {}'.format(round(vol, 4), _('mm³')) title = 'Volume' elif mat == 'CUSTOM': dens = unit.convert(props.weighting_dens, 'CM3_TO_MM3') weight = '{} {}'.format(round(vol * dens, 2), _('g')) title = 'Custom Density' else: dens = unit.convert(var.alloy_density[mat], 'CM3_TO_MM3') weight = '{} {}'.format(round(vol * dens, 2), _('g')) alloy_list = dynamic_lists.alloys(self, context) title = [x[1] for x in alloy_list if x[0] == mat][0] popup_report(self, weight, title=_(title)) return {'FINISHED'}
def prefs_ui(self, layout): col = layout.column() col.prop(self, "update_use_auto_check") col.prop(self, "update_use_prerelease") sub = col.column() sub.active = self.update_use_auto_check sub.prop(self, "update_interval") layout.separator() row = layout.row(align=True) row.alignment = "CENTER" if state.status is state.COMPLETED: row.label(text="Update completed") row.operator(operators.WM_OT_update_whats_new.bl_idname) row = layout.row(align=True) row.alignment = "CENTER" row.label(text="Close Blender to complete the installation", icon="ERROR") elif state.status is state.CHECKING: row.label(text="Checking...") elif state.status is state.INSTALLING: row.label(text="Installing...") elif state.status is state.ERROR: row.label(text=state.error_msg) elif state.update_available: row.label( text=_("Update {} is available").format(state.update_version)) else: if state.days_passed is None: msg_date = _("never") elif state.days_passed == 0: msg_date = _("today") elif state.days_passed == 1: msg_date = _("yesterday") else: msg_date = "{} {}".format(state.days_passed, _("days ago")) row.label(text="{} {}".format(_("Last checked"), msg_date)) col = layout.row() col.alignment = "CENTER" col.scale_y = 1.5 col.enabled = state.status is None or state.status is state.ERROR if state.update_available: col.operator(operators.WM_OT_update_download.bl_idname) else: col.operator(operators.WM_OT_update_check.bl_idname)
def prefs_ui(self, layout): col = layout.column() col.prop(self, "update_use_auto_check") col.prop(self, "update_use_prerelease") sub = col.column() sub.active = self.update_use_auto_check sub.prop(self, "update_interval") layout.separator() row = layout.row(align=True) row.alignment = "CENTER" if var.update_completed: row.label(text="Update completed") row.operator(operators.OP_IDNAME_WHATS_NEW) row = layout.row(align=True) row.alignment = "CENTER" row.label(text="Close Blender to complete the installation", icon="ERROR") elif var.update_in_progress: if var.update_available: row.label(text="Installing...") else: row.label(text="Checking...") elif var.update_available: row.label(text=_("Update {} is available").format(var.update_version)) else: if var.update_days_passed is None: msg_date = _("never") elif var.update_days_passed == 0: msg_date = _("today") elif var.update_days_passed == 1: msg_date = _("yesterday") else: msg_date = "{} {}".format(var.update_days_passed, _("days ago")) row.label(text="{} {}".format(_("Last checked"), msg_date)) col = layout.row() col.alignment = "CENTER" col.scale_y = 1.5 col.enabled = not var.update_in_progress and not var.update_completed if var.update_available: col.operator(operators.OP_IDNAME_DOWNLOAD) else: col.operator(operators.OP_IDNAME_CHECK)
def cuts(self, context): lang = _iface_lang(context) if _cache.get("cuts__lang") == lang: return _cache["cuts__list"] pcoll = var.preview_collections.get("cuts") if not pcoll: pcoll = bpy.utils.previews.new() for entry in os.scandir(var.GEM_ASSET_DIR): if entry.name.endswith(".png"): name = os.path.splitext(entry.name)[0] pcoll.load(name, entry.path, "IMAGE") var.preview_collections["cuts"] = pcoll list_ = ( ("ROUND", _("Round", "JewelCraft"), "", pcoll["round"].icon_id, 0), ("OVAL", _("Oval"), "", pcoll["oval"].icon_id, 1), ("CUSHION", _("Cushion"), "", pcoll["cushion"].icon_id, 2), ("PEAR", _("Pear"), "", pcoll["pear"].icon_id, 3), ("MARQUISE", _("Marquise"), "", pcoll["marquise"].icon_id, 4), ("PRINCESS", _("Princess"), "", pcoll["princess"].icon_id, 5), ("BAGUETTE", _("Baguette"), "", pcoll["baguette"].icon_id, 6), ("SQUARE", _("Square"), "", pcoll["square"].icon_id, 7), ("EMERALD", _("Emerald"), "", pcoll["emerald"].icon_id, 8), ("ASSCHER", _("Asscher"), "", pcoll["asscher"].icon_id, 9), ("RADIANT", _("Radiant"), "", pcoll["radiant"].icon_id, 10), ("FLANDERS", _("Flanders"), "", pcoll["flanders"].icon_id, 11), ("OCTAGON", _("Octagon"), "", pcoll["octagon"].icon_id, 12), ("HEART", _("Heart"), "", pcoll["heart"].icon_id, 13), ("TRILLION", _("Trillion"), "", pcoll["trillion"].icon_id, 14), ("TRILLIANT", _("Trilliant"), "", pcoll["trilliant"].icon_id, 15), ("TRIANGLE", _("Triangle"), "", pcoll["triangle"].icon_id, 16), ) _cache["cuts__list"] = list_ _cache["cuts__lang"] = lang return list_
def stones(self, context): lang = _iface_lang(context) if _cache.get("stones__lang") == lang: return _cache["stones__list"] list_ = [ ("DIAMOND", _("Diamond"), "", 0), ("ALEXANDRITE", _("Alexandrite"), "", 1), ("AMETHYST", _("Amethyst"), "", 2), ("AQUAMARINE", _("Aquamarine"), "", 3), ("CITRINE", _("Citrine"), "", 4), ("CUBIC_ZIRCONIA", _("Cubic Zirconia"), "", 5), ("EMERALD", _("Emerald"), "", 6), ("GARNET", _("Garnet"), "", 7), ("MORGANITE", _("Morganite"), "", 8), ("QUARTZ", _("Quartz"), "", 9), ("PERIDOT", _("Peridot"), "", 10), ("RUBY", _("Ruby"), "", 11), ("SAPPHIRE", _("Sapphire"), "", 12), ("SPINEL", _("Spinel"), "", 13), ("TANZANITE", _("Tanzanite"), "", 14), ("TOPAZ", _("Topaz"), "", 15), ("TOURMALINE", _("Tourmaline"), "", 16), ("ZIRCON", _("Zircon"), "", 17), ] list_.sort(key=lambda x: x[1]) _cache["stones__list"] = list_ _cache["stones__lang"] = lang return list_
def invoke(self, context, event): data = report_get.data_collect(context, gem_map=True) if context.area.type != "VIEW_3D": self.report({"ERROR"}, "Area type is not 3D View") return {"CANCELLED"} if not data["gems"]: self.report({"ERROR"}, "No gems in the scene") return {"CANCELLED"} import time self.region = context.region self.region_3d = context.space_data.region_3d self.prefs = context.preferences.addons[var.ADDON_ID].preferences self.view_mat = self.region_3d.perspective_matrix.copy() self.offscreen = None self.handler = None self.use_navigate = False self.is_rendering = False self.time_tag = time.time() # View margins # ---------------------------- self.view_padding_top = 10 self.view_padding_left = 20 self.view_margin = 40 for region in context.area.regions: if region.type == "HEADER": self.view_padding_top += region.height elif region.type == "TOOLS": self.view_padding_left += region.width view = context.preferences.view show_text = context.space_data.overlay.show_text view_text = show_text and (view.show_view_name or view.show_object_info) if view_text: self.view_padding_top += 60 # Gem report # ---------------------------- report_fmt.data_format(self, context, data) # Warnings # ---------------------------- self.show_warn = bool(data["warn"]) if self.show_warn: self.warn = [_("WARNING")] + [f"* {_(x)}" for x in data["warn"]] # Options # ---------------------------- self.option_list = ( (_("Limit By Selection"), "(S)", "use_select", self.TYPE_BOOL), (_("Save To Image"), "(F12)", "is_rendering", self.TYPE_RENDER), ) self.option_col_1_max = max(self.option_list, key=lambda x: len(x[0]))[0] self.option_col_2_max = max(self.option_list, key=lambda x: len(x[1]))[1] # Handlers # ---------------------------- self.offscreen_refresh(context) self.handler = bpy.types.SpaceView3D.draw_handler_add(draw_handler.draw, (self, context), "WINDOW", "POST_PIXEL") context.window_manager.modal_handler_add(self) return {"RUNNING_MODAL"}