Пример #1
0
	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'}
Пример #2
0
    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"}
Пример #3
0
    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"}
Пример #4
0
    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"}
Пример #5
0
    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"}
Пример #6
0
    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"}
Пример #7
0
    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"}
Пример #8
0
    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"}
Пример #9
0
    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"}
Пример #10
0
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_
Пример #11
0
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_
Пример #12
0
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()))
Пример #13
0
    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"}
Пример #14
0
    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"}
Пример #15
0
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_)
Пример #16
0
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)
Пример #17
0
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)
Пример #18
0
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)
Пример #19
0
    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"}
Пример #20
0
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)
Пример #21
0
    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"}
Пример #22
0
    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"}
Пример #23
0
            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)
Пример #24
0
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_
Пример #25
0
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_
Пример #26
0
    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"}
Пример #27
0
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_
Пример #28
0
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)
Пример #29
0
    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"}
Пример #30
0
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_
Пример #31
0
    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"}
Пример #32
0
    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"}
Пример #33
0
    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'}
Пример #34
0
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)
Пример #35
0
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)
Пример #36
0
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_
Пример #37
0
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_
Пример #38
0
    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"}