From 2397e47364759c5d9b6b761ea12b7e800f41447b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EC=83=81=EC=9A=B1?= Date: Thu, 29 Oct 2026 14:27:33 +0900 Subject: [PATCH] =?UTF-8?q?test=5Fpipeline.py=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test_pipeline.py | 176 ----------------------------------------------- 1 file changed, 176 deletions(-) delete mode 100644 test_pipeline.py diff --git a/test_pipeline.py b/test_pipeline.py deleted file mode 100644 index c3588cb..0000000 --- a/test_pipeline.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env python3 -""" -Comprehensive End-to-End Pipeline Verification Test -Verifies 2D drawing classification, DWG parsing, 3D solid & rebar modeling, -mesh watertightness, exporter functionality, and Flask API endpoints. -""" -import os -import json -import unittest - -import cad_parser -import model_3d -import rebar_model -import exporters -import app - - -class Test3DDrawingPipeline(unittest.TestCase): - - @classmethod - def setUpClass(cls): - current_dir = os.path.dirname(os.path.abspath(__file__)) - cls.project_root = os.path.abspath(os.path.join(current_dir, '..', '..')) - cls.rag_dir = os.path.join(cls.project_root, 'RAG') - cls.general_dwg = os.path.join(cls.rag_dir, '13. 수로암거 일반도(STA.13+611.21)(02).dwg') - app.app.testing = True - cls.flask_app = app.app.test_client() - - def test_01_drawing_classification(self): - """1.2 도면 종류 키워드 기반 자동 판별 검증""" - # 일반도 판별 - res_gen = cad_parser.classify_drawing_by_name('13. 수로암거 일반도(STA.13+611.21)(02).dwg') - self.assertEqual(res_gen['auto_type'], 'GENERAL') - self.assertEqual(res_gen['matched_keyword'], '일반') - self.assertFalse(res_gen['needs_manual_selection']) - - # 배근도/구조도 판별 - res_rebar1 = cad_parser.classify_drawing_by_name('14. 수로암거 구조도(STA.13+611.21, 종점 우)(01).dwg') - self.assertEqual(res_rebar1['auto_type'], 'REBAR') - self.assertIn('구조', res_rebar1['matched_keyword']) - self.assertFalse(res_rebar1['needs_manual_selection']) - - res_rebar2 = cad_parser.classify_drawing_by_name('날개벽 배근도(종점 좌).dwg') - self.assertEqual(res_rebar2['auto_type'], 'REBAR') - self.assertIn('배근', res_rebar2['matched_keyword']) - - # 미분류 도면 - res_unclass = cad_parser.classify_drawing_by_name('기타 도면#01.dwg') - self.assertEqual(res_unclass['auto_type'], 'UNCLASSIFIED') - self.assertTrue(res_unclass['needs_manual_selection']) - - def test_02_dwg_parsing(self): - """1.1 DWG 도면 파싱 및 파라미터 추출 검증""" - if not os.path.exists(self.general_dwg): - self.skipTest(f"DWG file not found at {self.general_dwg}") - - drawing_data = cad_parser.parse_dwg(self.general_dwg) - self.assertIsNotNone(drawing_data) - self.assertIn('entities', drawing_data) - self.assertIn('structuralParams', drawing_data) - self.assertGreater(len(drawing_data['entities']), 100) - - # 수로암거 제원 확인 - sp = drawing_data['structuralParams'] - self.assertEqual(sp.get('station'), 'STA.13+611.21') - self.assertAlmostEqual(sp.get('culvert_span', 2.0), 2.0, delta=0.1) - - def test_03_3d_solid_modeling_and_watertightness(self): - """2단계 일반도 기반 3D 외형 모델링 및 수밀성(Watertight) 검증""" - model_res = model_3d.generate_full_model() - self.assertIsNotNone(model_res) - self.assertIn('objects', model_res) - - objects = model_res['objects'] - self.assertIn('culvert', objects) - self.assertIn('ww_end_left', objects) - self.assertIn('ww_end_right', objects) - - # 도면에 없는 시점부 날개벽 임의 생성 차단 확인 - self.assertNotIn('ww_start_left', objects) - self.assertNotIn('ww_start_right', objects) - - # 수밀성 (Watertight 2-Manifold Mesh) 검증 - for part_key in ['culvert', 'ww_end_left', 'ww_end_right']: - part_data = objects[part_key] - vertices = part_data['vertices'] - faces = part_data['faces'] - self.assertGreater(len(vertices), 0, f"{part_key} has no vertices") - self.assertGreater(len(faces), 0, f"{part_key} has no faces") - - # Edge manifold check: Every edge in a watertight 2-manifold closed surface is shared by exactly 2 faces - edge_count = {} - for f in faces: - for i in range(3): - v1, v2 = f[i], f[(i + 1) % 3] - edge = tuple(sorted([v1, v2])) - edge_count[edge] = edge_count.get(edge, 0) + 1 - - non_manifold = [e for e, count in edge_count.items() if count != 2] - self.assertEqual(len(non_manifold), 0, - f"{part_key} mesh is not watertight! Non-manifold edges: {len(non_manifold)}") - - def test_04_3d_rebar_modeling(self): - """3단계 구조도/배근도 기반 날개벽 내부 3D 철근 배근(508본) 검증""" - rebar_data = rebar_model.generate_full_rebar_model() - self.assertIsNotNone(rebar_data) - self.assertIn('wingwalls', rebar_data) - self.assertIn('summary', rebar_data) - - summary = rebar_data['summary'] - total_bars = summary.get('total_bars', 0) - self.assertEqual(total_bars, 508, f"Expected 508 total rebars, got {total_bars}") - - # 좌측(231본) 및 우측(277본) 검증 - left_bars = summary.get('left_bars', 0) - right_bars = summary.get('right_bars', 0) - self.assertEqual(left_bars, 231) - self.assertEqual(right_bars, 277) - - # W1 철근 3D 형상 검증: 벽체-저판 접합부에서 꺾이지 않고 저판 하면에서 1회만 꺾이는 ㄱ자 형상(3개 정점) 확인 - for ww_key in ['WW_END_LEFT', 'WW_END_RIGHT']: - ww_groups = rebar_data['wingwalls'][ww_key]['groups'] - w1_group = next((g for g in ww_groups if g['mark'] == 'W1'), None) - self.assertIsNotNone(w1_group) - for poly in w1_group['polylines']: - self.assertEqual(len(poly), 3, f"{ww_key} W1 bar must have 3 points (1 bend at footing bottom)") - # 저판 하면 구간(poly[0] -> poly[1]) 동일 Z 표고 유지 - self.assertAlmostEqual(poly[0][2], poly[1][2], places=4) - # 벽체 긴 구간(poly[1] -> poly[2]) 접합부 꺾임 없이 일직선 연장 확인 - self.assertAlmostEqual(poly[1][0], poly[2][0], places=4) - self.assertAlmostEqual(poly[1][1], poly[2][1], places=4) - - def test_05_exporters(self): - """3D 모델 OBJ, STL, DXF 내보내기 검증""" - model_res = model_3d.generate_full_model() - - obj_str = exporters.export_obj(model_res) - self.assertIn('v ', obj_str) - self.assertIn('f ', obj_str) - - stl_str = exporters.export_stl(model_res) - self.assertIn('solid ', stl_str) - self.assertIn('facet normal', stl_str) - - dxf_str = exporters.export_dxf_3d(model_res) - self.assertIn('SECTION', dxf_str) - self.assertIn('ENTITIES', dxf_str) - - csv_str = exporters.export_rebar_bom_csv(model_res) - self.assertIn('구분(날개벽)', csv_str) - self.assertIn('기호(Mark)', csv_str) - - def test_06_flask_web_endpoints(self): - """Flask API 및 웹 엔드포인트 응답 검증""" - # 1. 메인 웹페이지 - r_index = self.flask_app.get('/') - self.assertEqual(r_index.status_code, 200) - r_index.close() - - # 2. 기본 도면 데이터 조회 API - r_def = self.flask_app.get('/api/default-drawing') - self.assertEqual(r_def.status_code, 200) - data_def = json.loads(r_def.data) - self.assertEqual(data_def.get('status'), 'success') - - # 3. 도면 분류 API - r_cls = self.flask_app.post('/api/classify', - data=json.dumps({'drawingName': '13. 수로암거 일반도.dwg'}), - content_type='application/json') - self.assertEqual(r_cls.status_code, 200) - data_cls = json.loads(r_cls.data) - self.assertEqual(data_cls['classification']['selectedType'], 'GENERAL') - - -if __name__ == '__main__': - unittest.main()