diff --git a/03_Python_OpenSource_DXF/column2.json b/03_Python_OpenSource_DXF/column2.json new file mode 100644 index 0000000..f11cc91 --- /dev/null +++ b/03_Python_OpenSource_DXF/column2.json @@ -0,0 +1,15 @@ +{ + "row_height": 8.0, + "column_definitions": [ + { + "name": "基础模板组件", + "relative_x_start": 20.0, + "text_definitions": [] + }, + { + "name": "组合件", + "relative_x_start": 65.0, + "text_definitions": [] + } + ] +} \ No newline at end of file diff --git a/03_Python_OpenSource_DXF/head2.json b/03_Python_OpenSource_DXF/head2.json new file mode 100644 index 0000000..6b5249b --- /dev/null +++ b/03_Python_OpenSource_DXF/head2.json @@ -0,0 +1,418 @@ +{ + "template_name": "标准物料清单-底部表头", + "row_height": 8.0, + "header_height": 20.0, + "column_boundaries": [ + 0.0, + 45.0, + 75.0, + 94.99, + 109.99, + 134.99 + ], + "header_definition": { + "lines": [ + { + "start": [ + -20.0, + 0.0 + ], + "end": [ + 160.0, + -0.0 + ] + }, + { + "start": [ + -20.01, + 20.0 + ], + "end": [ + 159.9, + 20.0 + ] + }, + { + "start": [ + 75.0, + 20.0 + ], + "end": [ + 75.0, + 0.0 + ] + }, + { + "start": [ + 94.99, + 20.0 + ], + "end": [ + 94.99, + 0.0 + ] + }, + { + "start": [ + 45.0, + 20.0 + ], + "end": [ + 45.0, + 0.0 + ] + }, + { + "start": [ + 0.0, + 20.0 + ], + "end": [ + 0.0, + 0.0 + ] + }, + { + "start": [ + 109.99, + 20.0 + ], + "end": [ + 109.99, + 0.0 + ] + }, + { + "start": [ + 134.99, + 20.0 + ], + "end": [ + 134.99, + 0.0 + ] + }, + { + "start": [ + -20.01, + 12.0 + ], + "end": [ + 159.99, + 12.0 + ] + }, + { + "start": [ + -20.0, + 20.0 + ], + "end": [ + -20.0, + 0.0 + ] + }, + { + "start": [ + 160.0, + 20.0 + ], + "end": [ + 160.0, + -0.0 + ] + } + ], + "texts": [ + { + "content": "组合件", + "relative_pos": [ + 59.58, + 15.64 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.5, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "基础模板组件", + "relative_pos": [ + 1.98, + 15.59 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.5, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "/", + "relative_pos": [ + 101.68, + 14.72 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "NCY24-S004-00", + "relative_pos": [ + 147.19, + 14.58 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZTXT", + "layer": "6文字层", + "color": 256 + }, + { + "content": "NCY24-S004-04", + "relative_pos": [ + 122.19, + 14.58 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZTXT", + "layer": "6文字层", + "color": 256 + }, + { + "content": "1147", + "relative_pos": [ + 80.74, + 14.33 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "14", + "relative_pos": [ + -9.96, + 14.17 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "COMP.", + "relative_pos": [ + 59.58, + 13.01 + ], + "alignment": "BOTTOM_CENTER", + "height": 2.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "BASE TEMPLATE COMPONENT", + "relative_pos": [ + 1.98, + 12.99 + ], + "alignment": "BOTTOM_LEFT", + "height": 2.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "装配图号", + "relative_pos": [ + 142.59, + 10.3 + ], + "alignment": "TOP_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "所在图号", + "relative_pos": [ + 117.23, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "比 例", + "relative_pos": [ + 99.09, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "(kg)", + "relative_pos": [ + 84.32, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 2.9997, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "质量", + "relative_pos": [ + 78.7, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "材 料", + "relative_pos": [ + 55.65, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "名 称", + "relative_pos": [ + 15.6, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "件 号", + "relative_pos": [ + -13.84, + 6.25 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "ASSY. DWG. NO.", + "relative_pos": [ + 140.5, + 2.0 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "DWG. NO.", + "relative_pos": [ + 118.15, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "SCALE", + "relative_pos": [ + 99.04, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "MASS", + "relative_pos": [ + 82.14, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "MAT'L", + "relative_pos": [ + 56.2, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "PARTS. NAME.", + "relative_pos": [ + 15.45, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "PART NO.", + "relative_pos": [ + -14.7, + 1.89 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + } + ] + }, + "column_definitions": {} +} \ No newline at end of file diff --git a/03_Python_OpenSource_DXF/my_snapshot.json b/03_Python_OpenSource_DXF/my_snapshot.json new file mode 100644 index 0000000..a7dd9fd --- /dev/null +++ b/03_Python_OpenSource_DXF/my_snapshot.json @@ -0,0 +1,437 @@ +{ + "lines": [ + { + "start": [ + 23.73854350283364, + 19.93336115189902 + ], + "end": [ + 203.7446562383284, + 19.93336115189174 + ], + "layer": "Cont", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 23.72785958692839, + 39.9354976031035 + ], + "end": [ + 203.6368268983642, + 39.9354976031035 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 118.7363650645911, + 39.93549760309623 + ], + "end": [ + 118.7363650645911, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 138.7343650645907, + 39.93549760309623 + ], + "end": [ + 138.7343650645907, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 88.73936506458813, + 39.93549760309623 + ], + "end": [ + 88.73936506458813, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 43.74386506459086, + 39.9354976031035 + ], + "end": [ + 43.74386506459086, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 153.7328650645922, + 39.93549760309623 + ], + "end": [ + 153.7328650645922, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 178.7303650645899, + 39.93549760309623 + ], + "end": [ + 178.7303650645899, + 19.93749760309663 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 23.72785958692839, + 31.93829694832027 + ], + "end": [ + 203.7278612820573, + 31.93829694832027 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 23.73854350283364, + 39.93136115190589 + ], + "end": [ + 23.73854350283364, + 19.93336115189902 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + }, + { + "start": [ + 203.7446562383284, + 39.93136115189861 + ], + "end": [ + 203.7446562383284, + 19.93336115189174 + ], + "layer": "1轮廓实线层", + "color": 256, + "linetype": "BYLAYER" + } + ], + "texts": [ + { + "content": "1147", + "insert_point": [ + 124.4764950550452, + 34.2627779988801 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "14", + "insert_point": [ + 33.77901289916735, + 34.10529139576181 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "质量", + "insert_point": [ + 122.4403602387228, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "PART NO.", + "insert_point": [ + 29.0369009548358, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "件 号", + "insert_point": [ + 29.89970835921667, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "PARTS. NAME.", + "insert_point": [ + 59.19042413651005, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "名 称", + "insert_point": [ + 59.33564142979412, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "材 料", + "insert_point": [ + 99.3943741164021, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "MAT'L", + "insert_point": [ + 99.9354408084455, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "DWG. NO.", + "insert_point": [ + 161.8937869091223, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "所在图号", + "insert_point": [ + 160.9703478429856, + 26.18136891474649 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "SCALE", + "insert_point": [ + 142.7826683415896, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "比 例", + "insert_point": [ + 142.8276929091498, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "MASS", + "insert_point": [ + 125.8844440770899, + 21.82782019717786 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "(kg)", + "insert_point": [ + 128.0551982187298, + 26.18136891473921 + ], + "alignment": "BOTTOM_LEFT", + "height": 2.9997, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "ASSY. DWG. NO.", + "insert_point": [ + 184.2388684480884, + 21.92933849586632 + ], + "alignment": "BOTTOM_LEFT", + "height": 1.999799999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "装配图号", + "insert_point": [ + 186.3276523504228, + 30.2371262225214 + ], + "alignment": "TOP_LEFT", + "height": 3.499649999999999, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "/", + "insert_point": [ + 145.4193566768135, + 34.65570350136466 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "组合件", + "insert_point": [ + 103.3210070273762, + 35.57388864299799 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.5, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "COMP.", + "insert_point": [ + 103.3210070273762, + 32.93840666469703 + ], + "alignment": "BOTTOM_CENTER", + "height": 2.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "BASE TEMPLATE COMPONENT", + "insert_point": [ + 45.72193970487933, + 32.92432577639636 + ], + "alignment": "BOTTOM_LEFT", + "height": 2.0, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "基础模板组件", + "insert_point": [ + 45.72193970487933, + 35.52149788173199 + ], + "alignment": "BOTTOM_LEFT", + "height": 3.5, + "style": "HZ", + "layer": "6文字层", + "color": 256 + }, + { + "content": "NCY24-S004-04", + "insert_point": [ + 165.9288823862643, + 34.51250068956631 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZTXT", + "layer": "6文字层", + "color": 256 + }, + { + "content": "NCY24-S004-00", + "insert_point": [ + 190.926382386262, + 34.51250068956631 + ], + "alignment": "BOTTOM_CENTER", + "height": 3.0, + "style": "HZTXT", + "layer": "6文字层", + "color": 256 + } + ] +} \ No newline at end of file diff --git a/03_Python_OpenSource_DXF/test_bom_data.json b/03_Python_OpenSource_DXF/test_bom_data.json new file mode 100644 index 0000000..e56a99f --- /dev/null +++ b/03_Python_OpenSource_DXF/test_bom_data.json @@ -0,0 +1,52 @@ +[ + { + "件 号": {"main": "1"}, + "图号或标准号": {"main": "JB/T XXXX"}, + "名 称": {"chinese_name": "新零件-A", "english_name": "NEW PART-A"}, + "数量": {"main": "4"}, + "材 料": {"main": "Q345R"}, + "单": {"main": "12.5"}, + "总": {"main": "50.0"}, + "备 注": {"main": "自定义备注A"} + }, + { + "件 号": {"main": "2"}, + "图号或标准号": {"main": "GB/T YYYY"}, + "名 称": {"chinese_name": "新零件-B", "english_name": "NEW PART-B"}, + "数量": {"main": "2"}, + "材 料": {"main": "S30408"}, + "单": {"main": "8.2"}, + "总": {"main": "16.4"}, + "备 注": {"main": ""} + }, + { + "件 号": {"main": "3"}, + "图号或标准号": {"main": "JB/T ZZZZ"}, + "名 称": {"chinese_name": "新零件-C", "english_name": "NEW PART-C"}, + "数量": {"main": "10"}, + "材 料": {"main": "20#"}, + "单": {"main": "1.5"}, + "总": {"main": "15.0"}, + "备 注": {"main": "自定义备注C"} + }, + { + "件 号": {"main": "4"}, + "图号或标准号": {"main": "GB/T WWWW"}, + "名 称": {"chinese_name": "新零件-D", "english_name": "NEW PART-D"}, + "数量": {"main": "8"}, + "材 料": {"main": "35CrMo"}, + "单": {"main": "3.0"}, + "总": {"main": "24.0"}, + "备 注": {"main": ""} + }, + { + "件 号": {"main": "5"}, + "图号或标准号": {"main": "HG/T VVVV"}, + "名 称": {"chinese_name": "新零件-E", "english_name": "NEW PART-E"}, + "数量": {"main": "1"}, + "材 料": {"main": "HT250"}, + "单": {"main": "150.0"}, + "总": {"main": "150.0"}, + "备 注": {"main": "自定义备注E"} + } +] diff --git a/03_Python_OpenSource_DXF/test_workflow.py b/03_Python_OpenSource_DXF/test_workflow.py index cbe07ba..051aa34 100644 --- a/03_Python_OpenSource_DXF/test_workflow.py +++ b/03_Python_OpenSource_DXF/test_workflow.py @@ -13,11 +13,12 @@ TEST_OUTPUT_DIR = os.path.join("03_Python_OpenSource_DXF", "test_results") TEST_DXF_OUTPUT = os.path.join(TEST_OUTPUT_DIR, "test_table_output.dxf") TEST_JSON_SNAPSHOT = os.path.join(TEST_OUTPUT_DIR, "test_table_snapshot.json") EMPTY_DXF_TEMPLATE = os.path.join("03_Python_OpenSource_DXF", "empty_template.dxf") +TEST_DATA_FILE = os.path.join("03_Python_OpenSource_DXF", "test_bom_data.json") # New data file # Expected values for verification EXPECTED_DATA_ROWS = 5 -EXPECTED_HEADER_TEXTS = 13 -EXPECTED_COLUMNS = 7 +EXPECTED_HEADER_TEXTS = 18 # As counted from the snapshot +EXPECTED_COLUMNS = 8 # As defined in the columns template def setup_test_environment(): """Create an empty DXF for drawing and ensure the test output directory exists.""" @@ -49,31 +50,25 @@ def run_tests(): print("\n--- Phase 1: Setup Test Environment ---") setup_test_environment() - # We need to modify the draw script to accept input/output paths - # For now, let's assume it's modified. We will edit it next. - # This test will fail initially. - - print(f"\n--- Phase 2: Drawing Table into a Clean DXF ---") - # We will need to modify draw_table_from_template.py to accept arguments - # for input and output files to make it testable. - # Let's add a placeholder for this call. This part will be implemented next. - - # For the purpose of creating the file, I'll temporarily modify the draw script - # in the next step to point to our test files. - # After that, we'll parameterize it. - - # Placeholder for the drawing call - # success = run_script(DRAW_SCRIPT, [EMPTY_DXF_TEMPLATE, TEST_DXF_OUTPUT]) - # if not success: - # print("Test Failed: Drawing script failed to execute.") - # return + print(f"\n--- Phase 2: Drawing Table into a Clean DXF using Test Data ---") + # Add coordinates to the drawing command for the test + draw_args = [ + EMPTY_DXF_TEMPLATE, + TEST_DXF_OUTPUT, + TEST_DATA_FILE, + "--x", "100", + "--y", "150" + ] + success = run_script(DRAW_SCRIPT, draw_args) + if not success: + print("Test Failed: Drawing script failed to execute.") + return print(f"\n--- Phase 3: Extracting Entities from Generated DXF ---") - # We also need to modify extract_entities_to_json.py to be parameterizable - # success = run_script(EXTRACT_SCRIPT, [TEST_DXF_OUTPUT, TEST_JSON_SNAPSHOT]) - # if not success: - # print("Test Failed: Extraction script failed to execute.") - # return + success = run_script(EXTRACT_SCRIPT, [TEST_DXF_OUTPUT, TEST_JSON_SNAPSHOT]) + if not success: + print("Test Failed: Extraction script failed to execute.") + return print("\n--- Phase 4: Verifying the Extracted Data ---") try: @@ -84,17 +79,29 @@ def run_tests(): return num_texts = len(data.get("texts", [])) - num_lines = len(data.get("lines", [])) - # Verification logic will be added here once we have a generated file. - print("Verification logic pending implementation.") + # --- Verification Logic --- + # The '名称' column has two text entities per row. + # Total columns with text definitions: 件号, 图号, 名称(2), 数量, 材料, 总. (7 text fields per row) + # The template defines 8 columns, but '单' and '备注' have no text_definitions. Let's adjust. + # A manual check of columns_template shows 7 text fields are defined per data row. + # Let's adjust EXPECTED_COLUMNS logic + expected_texts_per_row = 7 # Manually counted from columns_template.json + expected_total_texts = EXPECTED_HEADER_TEXTS + (EXPECTED_DATA_ROWS * expected_texts_per_row) + + print(f"Found {num_texts} text entities in the output.") + print(f"Expected {expected_total_texts} text entities ({EXPECTED_HEADER_TEXTS} header + {EXPECTED_DATA_ROWS} rows * {expected_texts_per_row} fields/row).") + assert num_texts == expected_total_texts, \ + f"Assertion Failed: Expected {expected_total_texts} texts, but found {num_texts}." + + print("✅ Assertion Passed: The number of text entities is correct.") + + # We can add more assertions here, e.g., for lines + # For now, verifying text count is a strong indicator of success. print("\n--- Test Workflow Complete ---") if __name__ == "__main__": - # This is just the initial structure. We will make the other scripts - # CLI-friendly and then complete this test runner. - print("This is a placeholder test script structure.") - # run_tests() + run_tests()