9f11de19 by shady

Merge remote-tracking branch 'origin/master'

2 parents a7a323f8 0909edd6
...@@ -2605,86 +2605,6 @@ class ImageGenerationWorker(QThread): ...@@ -2605,86 +2605,6 @@ class ImageGenerationWorker(QThread):
2605 # 珠宝设计功能模块 2605 # 珠宝设计功能模块
2606 # ============================================================================ 2606 # ============================================================================
2607 2607
2608 # 默认珠宝词库(纯中文)
2609 DEFAULT_JEWELRY_LIBRARY = {
2610 "主石形状": [
2611 "椭圆形",
2612 "圆形",
2613 "祖母绿形",
2614 "梨形",
2615 "垫形",
2616 "公主方形",
2617 "心形"
2618 ],
2619 "主石材质": [
2620 "黑发晶",
2621 "莫桑石",
2622 "红宝石",
2623 "蓝宝石",
2624 "绿碧玺",
2625 "黄水晶带天然包裹体",
2626 "钻石",
2627 "粉红蓝宝石"
2628 ],
2629 "金属": [
2630 "14K黄金",
2631 "18K玫瑰金",
2632 "14K白金",
2633 "铂金(PT950)",
2634 "双色14K黄金+白金",
2635 "950银镀铑",
2636 "钛金属"
2637 ],
2638 "花头形式": [
2639 "花卉风格光环",
2640 "经典圆形光环",
2641 "复古风格米粒边光环",
2642 "双层光环",
2643 "几何六边形光环",
2644 "非对称光环",
2645 "简约爪镶无光环"
2646 ],
2647 "戒臂结构": [
2648 "扭转戒臂",
2649 "分裂戒臂",
2650 "刀刃戒臂",
2651 "大教堂戒臂",
2652 "交叉戒臂",
2653 "直线平滑戒臂",
2654 "三股编织戒臂"
2655 ],
2656 "戒臂处理": [
2657 "雕刻镂空花丝工艺",
2658 "密钉镶戒臂",
2659 "抛光平滑戒臂",
2660 "浮雕雕刻",
2661 "编织纹理",
2662 "极简干净戒臂",
2663 "穿孔镂空细节",
2664 "锤纹处理"
2665 ],
2666 "特殊元素": [
2667 "凯尔特结图案",
2668 "装饰艺术几何元素",
2669 "自然风格叶子图案",
2670 "复古米粒边细节",
2671 "哥特式图案元素",
2672 "天体图案(星星、月亮)",
2673 "藤蔓装饰曲线",
2674 "蝴蝶结装饰"
2675 ],
2676 "辅石镶嵌": [
2677 "密钉镶",
2678 "微密钉镶",
2679 "槽镶",
2680 "珠粒镶",
2681 "共爪镶",
2682 "包镶",
2683 "轨道镶"
2684 ]
2685 }
2686
2687
2688 class JewelryLibraryManager: 2608 class JewelryLibraryManager:
2689 """珠宝词库管理器""" 2609 """珠宝词库管理器"""
2690 2610
...@@ -2697,6 +2617,8 @@ class JewelryLibraryManager: ...@@ -2697,6 +2617,8 @@ class JewelryLibraryManager:
2697 self.logger = logging.getLogger(__name__) 2617 self.logger = logging.getLogger(__name__)
2698 self.config_dir = config_dir 2618 self.config_dir = config_dir
2699 self.config_path = config_dir / "jewelry_library.json" 2619 self.config_path = config_dir / "jewelry_library.json"
2620 # 获取默认词库文件的路径
2621 self.default_library_path = Path(__file__).parent / "data" / "default_jewelry_library.json"
2700 self.library = self.load_library() 2622 self.library = self.load_library()
2701 2623
2702 def load_library(self) -> Dict[str, List[str]]: 2624 def load_library(self) -> Dict[str, List[str]]:
...@@ -2713,14 +2635,35 @@ class JewelryLibraryManager: ...@@ -2713,14 +2635,35 @@ class JewelryLibraryManager:
2713 return library 2635 return library
2714 except Exception as e: 2636 except Exception as e:
2715 self.logger.error(f"珠宝词库加载失败: {e},使用默认词库") 2637 self.logger.error(f"珠宝词库加载失败: {e},使用默认词库")
2716 return DEFAULT_JEWELRY_LIBRARY.copy() 2638 return self._load_default_library()
2717 else: 2639 else:
2718 # 首次使用,创建默认词库 2640 # 首次使用,创建默认词库
2719 self.logger.info("未找到珠宝词库文件,创建默认词库") 2641 self.logger.info("未找到珠宝词库文件,创建默认词库")
2720 library = DEFAULT_JEWELRY_LIBRARY.copy() 2642 library = self._load_default_library()
2721 self.save_library(library) 2643 self.save_library(library)
2722 return library 2644 return library
2723 2645
2646 def _load_default_library(self) -> Dict[str, List[str]]:
2647 """从文件加载默认词库"""
2648 try:
2649 with open(self.default_library_path, 'r', encoding='utf-8') as f:
2650 library = json.load(f)
2651 self.logger.info(f"默认词库加载成功: {self.default_library_path}")
2652 return library
2653 except Exception as e:
2654 self.logger.error(f"默认词库加载失败: {e}")
2655 # 如果默认词库文件也不存在,返回一个最小的词库
2656 return {
2657 "主石形状": ["圆形", "椭圆形"],
2658 "主石材质": ["钻石", "莫桑石"],
2659 "金属": ["14K黄金", "18K白金"],
2660 "花头形式": ["经典圆形光环"],
2661 "戒臂结构": ["直臂"],
2662 "戒臂处理": ["抛光平滑戒臂"],
2663 "辅石镶嵌": ["三石结构"],
2664 "特殊元素": []
2665 }
2666
2724 def _migrate_library_if_needed(self, library: Dict[str, List[str]]) -> Dict[str, List[str]]: 2667 def _migrate_library_if_needed(self, library: Dict[str, List[str]]) -> Dict[str, List[str]]:
2725 """检查并执行数据迁移""" 2668 """检查并执行数据迁移"""
2726 # 如果存在旧的"主石"字段,需要拆分 2669 # 如果存在旧的"主石"字段,需要拆分
...@@ -2744,8 +2687,9 @@ class JewelryLibraryManager: ...@@ -2744,8 +2687,9 @@ class JewelryLibraryManager:
2744 materials.append(material) 2687 materials.append(material)
2745 2688
2746 # 更新词库 2689 # 更新词库
2747 library["主石形状"] = shapes if shapes else DEFAULT_JEWELRY_LIBRARY["主石形状"] 2690 default_library = self._load_default_library()
2748 library["主石材质"] = materials if materials else DEFAULT_JEWELRY_LIBRARY["主石材质"] 2691 library["主石形状"] = shapes if shapes else default_library["主石形状"]
2692 library["主石材质"] = materials if materials else default_library["主石材质"]
2749 2693
2750 # 保留旧字段作为备份 2694 # 保留旧字段作为备份
2751 # library.pop("主石", None) # 可以选择是否移除 2695 # library.pop("主石", None) # 可以选择是否移除
...@@ -2758,18 +2702,29 @@ class JewelryLibraryManager: ...@@ -2758,18 +2702,29 @@ class JewelryLibraryManager:
2758 2702
2759 def _extract_shape(self, item: str) -> Optional[str]: 2703 def _extract_shape(self, item: str) -> Optional[str]:
2760 """从主石描述中提取形状""" 2704 """从主石描述中提取形状"""
2761 shapes = ["椭圆形", "圆形", "祖母绿形", "梨形", "垫形", "公主方形", "心形"] 2705 # 从默认词库文件获取形状列表,确保同步
2706 default_library = self._load_default_library()
2707 shapes = default_library.get("主石形状", [])
2762 for shape in shapes: 2708 for shape in shapes:
2763 if item.startswith(shape): 2709 # 处理带括号的形状(如"子弹形(Baguette 子弹刻面)")
2710 if "(" in shape:
2711 shape_base = shape.split("(")[0]
2712 if item.startswith(shape_base):
2713 return shape_base
2714 elif item.startswith(shape):
2764 return shape 2715 return shape
2765 return None 2716 return None
2766 2717
2767 def _extract_material(self, item: str) -> Optional[str]: 2718 def _extract_material(self, item: str) -> Optional[str]:
2768 """从主石描述中提取材质""" 2719 """从主石描述中提取材质"""
2769 shapes = ["椭圆形", "圆形", "祖母绿形", "梨形", "垫形", "公主方形", "心形"] 2720 # 从默认词库文件获取形状列表,确保同步
2721 default_library = self._load_default_library()
2722 shapes = default_library.get("主石形状", [])
2770 for shape in shapes: 2723 for shape in shapes:
2771 if item.startswith(shape): 2724 # 处理带括号的形状(如"子弹形(Baguette 子弹刻面)")
2772 material = item[len(shape):] 2725 shape_base = shape.split("(")[0] if "(" in shape else shape
2726 if item.startswith(shape_base):
2727 material = item[len(shape_base):]
2773 # 去除可能的连接词 2728 # 去除可能的连接词
2774 if material.startswith("的"): 2729 if material.startswith("的"):
2775 material = material[1:] 2730 material = material[1:]
...@@ -2831,8 +2786,9 @@ class JewelryLibraryManager: ...@@ -2831,8 +2786,9 @@ class JewelryLibraryManager:
2831 Args: 2786 Args:
2832 category: 类别名称 2787 category: 类别名称
2833 """ 2788 """
2834 if category in DEFAULT_JEWELRY_LIBRARY: 2789 default_library = self._load_default_library()
2835 self.library[category] = DEFAULT_JEWELRY_LIBRARY[category].copy() 2790 if category in default_library:
2791 self.library[category] = default_library[category].copy()
2836 self.save_library() 2792 self.save_library()
2837 self.logger.info(f"恢复默认词库: {category}") 2793 self.logger.info(f"恢复默认词库: {category}")
2838 else: 2794 else:
...@@ -2840,7 +2796,7 @@ class JewelryLibraryManager: ...@@ -2840,7 +2796,7 @@ class JewelryLibraryManager:
2840 2796
2841 def reset_all(self): 2797 def reset_all(self):
2842 """恢复所有类别的默认词库""" 2798 """恢复所有类别的默认词库"""
2843 self.library = DEFAULT_JEWELRY_LIBRARY.copy() 2799 self.library = self._load_default_library()
2844 self.save_library() 2800 self.save_library()
2845 self.logger.info("恢复所有默认词库") 2801 self.logger.info("恢复所有默认词库")
2846 2802
...@@ -2946,6 +2902,12 @@ class StyleDesignerTab(QWidget): ...@@ -2946,6 +2902,12 @@ class StyleDesignerTab(QWidget):
2946 # 存储每个类别的 ComboBox 2902 # 存储每个类别的 ComboBox
2947 self.combo_boxes = {} 2903 self.combo_boxes = {}
2948 2904
2905 # 存储每个类别的锁定按钮
2906 self.lock_buttons = {}
2907
2908 # 存储锁定的类别
2909 self.locked_fields = set()
2910
2949 # 生成相关 2911 # 生成相关
2950 self.generated_image_bytes = None 2912 self.generated_image_bytes = None
2951 2913
...@@ -3124,9 +3086,9 @@ class StyleDesignerTab(QWidget): ...@@ -3124,9 +3086,9 @@ class StyleDesignerTab(QWidget):
3124 self.update_prompt_preview() 3086 self.update_prompt_preview()
3125 3087
3126 def randomize_parameters(self): 3088 def randomize_parameters(self):
3127 """随机生成一套参数""" 3089 """随机生成一套参数(跳过锁定的字段)"""
3128 for category, combo in self.combo_boxes.items(): 3090 for category, combo in self.combo_boxes.items():
3129 if combo.count() > 0: 3091 if category not in self.locked_fields and combo.count() > 0:
3130 random_index = random.randint(0, combo.count() - 1) 3092 random_index = random.randint(0, combo.count() - 1)
3131 combo.setCurrentIndex(random_index) 3093 combo.setCurrentIndex(random_index)
3132 # 触发prompt预览更新 3094 # 触发prompt预览更新
...@@ -3153,18 +3115,28 @@ class StyleDesignerTab(QWidget): ...@@ -3153,18 +3115,28 @@ class StyleDesignerTab(QWidget):
3153 self.combo_boxes[category] = combo 3115 self.combo_boxes[category] = combo
3154 layout.addWidget(combo, 3) 3116 layout.addWidget(combo, 3)
3155 3117
3156 # 添加按钮 3118 # 添加按钮(使用表情符号)
3157 add_btn = QPushButton("添加") 3119 add_btn = QPushButton("")
3158 add_btn.clicked.connect(lambda: self.add_library_item(category)) 3120 add_btn.clicked.connect(lambda: self.add_library_item(category))
3159 add_btn.setFixedWidth(60) 3121 add_btn.setFixedWidth(40)
3122 add_btn.setToolTip("添加词库项")
3160 layout.addWidget(add_btn) 3123 layout.addWidget(add_btn)
3161 3124
3162 # 删除按钮 3125 # 删除按钮(使用表情符号)
3163 del_btn = QPushButton("删除") 3126 del_btn = QPushButton("🗑️")
3164 del_btn.clicked.connect(lambda: self.remove_library_item(category)) 3127 del_btn.clicked.connect(lambda: self.remove_library_item(category))
3165 del_btn.setFixedWidth(60) 3128 del_btn.setFixedWidth(40)
3129 del_btn.setToolTip("删除词库项")
3166 layout.addWidget(del_btn) 3130 layout.addWidget(del_btn)
3167 3131
3132 # 锁定/解锁按钮(使用表情符号)
3133 lock_btn = QPushButton("🔓")
3134 lock_btn.clicked.connect(lambda: self.toggle_field_lock(category))
3135 lock_btn.setFixedWidth(40)
3136 lock_btn.setToolTip("锁定/解锁字段")
3137 self.lock_buttons[category] = lock_btn
3138 layout.addWidget(lock_btn)
3139
3168 widget.setLayout(layout) 3140 widget.setLayout(layout)
3169 return widget 3141 return widget
3170 3142
...@@ -3300,6 +3272,21 @@ class StyleDesignerTab(QWidget): ...@@ -3300,6 +3272,21 @@ class StyleDesignerTab(QWidget):
3300 else: 3272 else:
3301 combo.setCurrentIndex(0) 3273 combo.setCurrentIndex(0)
3302 3274
3275 def toggle_field_lock(self, category: str):
3276 """切换字段锁定状态"""
3277 if category in self.locked_fields:
3278 # 解锁
3279 self.locked_fields.remove(category)
3280 button = self.lock_buttons[category]
3281 button.setText("🔓")
3282 button.setToolTip("字段已解锁")
3283 else:
3284 # 锁定
3285 self.locked_fields.add(category)
3286 button = self.lock_buttons[category]
3287 button.setText("🔒")
3288 button.setToolTip("字段已锁定")
3289
3303 def generate_image(self): 3290 def generate_image(self):
3304 """Submit image generation task to queue""" 3291 """Submit image generation task to queue"""
3305 from task_queue import TaskType 3292 from task_queue import TaskType
......
1 { 1 {
2 "主石": [ 2 "主石形状": [
3 "椭圆形黑发晶", 3 "圆形",
4 "圆形莫桑石", 4 "椭圆形",
5 "祖母绿形红宝石", 5 "梨形",
6 "梨形蓝宝石", 6 "马眼形",
7 "垫形绿碧玺", 7 "子弹形(Baguette 子弹刻面)",
8 "椭圆形黄水晶带天然包裹体", 8 "垫形",
9 "公主方形钻石", 9 "公主方形",
10 "心形粉红蓝宝石" 10 "祖母绿形",
11 "心形",
12 "风筝形",
13 "棺材形(Coffin Cut)",
14 "菱形(Rhombus)",
15 "正六边形",
16 "四叶草形",
17 "梯方形(Tapered Step)",
18 "阿斯切形",
19 "平底刻面风格"
20 ],
21 "主石材质": [
22 "莫桑石",
23 "钻石",
24 "黑发晶",
25 "蓝宝石",
26 "红宝石",
27 "粉蓝宝石",
28 "绿碧玺",
29 "黄水晶(天然包体)",
30 "月光石",
31 "摩根石",
32 "海蓝宝",
33 "天然白玉髓",
34 "金绿宝石(猫眼)"
11 ], 35 ],
12 "金属": [ 36 "金属": [
13 "14K黄金", 37 "14K黄金",
14 "18K玫瑰金",
15 "14K白金", 38 "14K白金",
16 "铂金(PT950)", 39 "14K玫瑰金",
17 "双色14K黄金+白金", 40 "18K黄金",
18 "950银镀铑", 41 "18K白金",
19 "钛金属" 42 "18K玫瑰金",
43 "双色金(白金+黄金)",
44 "950铂金",
45 "925银镀铑",
46 "钛金属",
47 "定制复古做旧金"
20 ], 48 ],
21 "花头形式": [ 49 "花头形式": [
50 "全halo光环",
51 "半halo光环",
52 "双层halo",
22 "花卉风格光环", 53 "花卉风格光环",
54 "围圈雕刻光环",
55 "围圈密钉镶",
23 "经典圆形光环", 56 "经典圆形光环",
24 "复古风格米粒边光环",
25 "双层光环",
26 "几何六边形光环", 57 "几何六边形光环",
27 "非对称光环", 58 "非对称光环",
28 "简约爪镶无光环" 59 "三石花头(cluster 结构)",
60 "五石花头",
61 "cluster堆砌花头(大小堆/不规则)",
62 "双石结构(Two-stone)",
63 "单石无光环(爪镶/包镶)",
64 "花头侧面结构",
65 "高耸花头(Cathedral halo)"
29 ], 66 ],
30 "戒臂结构": [ 67 "戒臂结构": [
31 "扭转戒臂", 68 "直臂",
32 "分裂戒臂", 69 "xox扭臂(交叉扭绞)",
33 "刀刃戒臂", 70 ">O< 戒臂结构",
34 "大教堂戒臂", 71 "<O> 戒臂结构",
72 "V字戒臂",
35 "交叉戒臂", 73 "交叉戒臂",
36 "直线平滑戒臂", 74 "overlap重叠戒臂",
37 "三股编织戒臂" 75 "wave波浪戒臂",
76 "刀锋臂",
77 "大教堂戒臂(高肩设计)",
78 "三股编织戒臂",
79 "分裂戒臂(split shank)",
80 "戒臂夹层",
81 "小夹层戒臂(如莲花夹层设计)",
82 "不对称戒臂"
38 ], 83 ],
39 "戒臂处理": [ 84 "戒臂处理": [
40 "雕刻镂空花丝工艺",
41 "密钉镶戒臂", 85 "密钉镶戒臂",
86 "微密钉镶",
87 "镶石虎爪镶/逼镶",
42 "抛光平滑戒臂", 88 "抛光平滑戒臂",
43 "浮雕雕刻", 89 "珠边戒臂(milgrain)",
44 "编织纹理", 90 "光金戒臂",
45 "极简干净戒臂", 91 "雕刻镂空花丝",
92 "浮雕雕刻(凸雕)",
93 "凹刻雕刻(内刻)",
94 "几何雕刻纹理",
95 "复古米粒边装饰(milgrain)",
96 "编织纹理戒臂",
46 "穿孔镂空细节", 97 "穿孔镂空细节",
47 "锤纹处理" 98 "锤纹处理"
48 ], 99 ],
49 "特殊元素": [
50 "凯尔特结图案",
51 "装饰艺术几何元素",
52 "自然风格叶子图案",
53 "复古米粒边细节",
54 "哥特式图案元素",
55 "天体图案(星星、月亮)",
56 "藤蔓装饰曲线",
57 "蝴蝶结装饰"
58 ],
59 "辅石镶嵌": [ 100 "辅石镶嵌": [
60 "密钉镶", 101 "三石结构",
61 "微密钉镶", 102 "五石结构",
62 "槽镶", 103 "cluster自由堆砌侧石",
63 "珠粒镶", 104 "大小堆组合",
64 "共爪镶", 105 "共爪镶侧钻",
65 "包镶", 106 "包镶侧钻",
66 "轨道镶" 107 "轨道镶",
67 ], 108 "槽镶"
68 "主石形状": [
69 "椭圆形",
70 "圆形",
71 "祖母绿形",
72 "梨形",
73 "垫形",
74 "公主方形",
75 "心形"
76 ], 109 ],
77 "主石材质": [ 110 "特殊元素": [
78 "黑发晶", 111 "花朵元素",
79 "莫桑石", 112 "月亮元素",
80 "红宝石", 113 "星星元素",
81 "蓝宝石", 114 "日月星组合",
82 "绿碧玺", 115 "凯尔特结",
83 "黄水晶带天然包裹体", 116 "叶子图案",
84 "钻石", 117 "自然植物藤蔓纹理",
85 "粉红蓝宝石" 118 "蝴蝶结元素",
119 "装饰艺术几何元素",
120 "复古花纹",
121 "哥特式结构元素"
86 ] 122 ]
87 } 123 }
...\ No newline at end of file ...\ No newline at end of file
......