import os
from dotenv import load_dotenv
# Load configuration
_config_path = os.path.join(os.path.dirname(__file__), "config.env")
load_dotenv(_config_path)
def _get_autocad_application():
try:
import win32com.client
except Exception as exc:
return None, f"pywin32 import failed: {exc}"
try:
acad = win32com.client.GetActiveObject("AutoCAD.Application")
return acad, None
except Exception:
try:
acad = win32com.client.Dispatch("AutoCAD.Application")
return acad, None
except Exception as exc:
return None, f"AutoCAD connection failed: {exc}"
def _normalize_text(text):
if text is None:
return ""
cleaned = text.replace("\\P", " ").replace("\r", " ").replace("\n", " ").replace("\t", " ")
cleaned = " ".join(cleaned.split())
return cleaned.strip()
def _get_insertion_point(entity):
try:
point = entity.InsertionPoint
return float(point[0]), float(point[1]), float(point[2])
except Exception:
try:
point = entity.Location
return float(point[0]), float(point[1]), float(point[2])
except Exception:
return None
# AutoCAD 연결
acad, err = _get_autocad_application()
if err:
print(f"에러: {err}")
exit(1)
try:
doc = acad.ActiveDocument
print(f"활성 문서: {doc.Name}")
except Exception as exc:
print(f"문서 접근 실패: {exc}")
exit(1)
layer_name = os.getenv("LAYER_SHOP_FIELD", "MATLIST")
print(f"\n레이어: {layer_name}")
print("=" * 100)
# MATLIST 레이어의 모든 텍스트 수집
text_items = []
for obj in doc.ModelSpace:
if obj.EntityName not in ["AcDbText", "AcDbMText"]:
continue
if obj.Layer != layer_name:
continue
point = _get_insertion_point(obj)
if not point:
continue
raw_text = getattr(obj, "TextString", "")
norm_text = _normalize_text(str(raw_text))
if not norm_text:
continue
text_items.append({
"text": str(raw_text),
"norm": norm_text,
"x": point[0],
"y": point[1],
})
print(f"총 {len(text_items)}개의 텍스트 항목 발견\n")
# Y 좌표로 정렬 (위에서 아래로)
text_items.sort(key=lambda x: x["y"], reverse=True)
# 카테고리 찾기
categories_str = os.getenv("MATERIAL_CATEGORIES", "SHOP MATERIAL,FIELD MATERIAL")
categories = [cat.strip() for cat in categories_str.split(",") if cat.strip()]
category_map = {c.upper(): c for c in categories}
print("카테고리 헤더 검색:")
print("-" * 100)
for item in text_items:
if item["norm"].upper() in category_map:
print(f"✓ '{item['norm']}' at X={item['x']:.2f}, Y={item['y']:.2f}")
print("\n\n상위 20개 텍스트 항목 (Y 좌표 기준 내림차순):")
print("-" * 100)
for i, item in enumerate(text_items[:20], 1):
print(f"{i:2d}. X={item['x']:8.2f}, Y={item['y']:8.2f} | '{item['norm']}'")
# Y 좌표 범위 확인
if text_items:
max_y = max(item['y'] for item in text_items)
min_y = min(item['y'] for item in text_items)
print(f"\nY 좌표 범위: {min_y:.2f} ~ {max_y:.2f}")
# SHOP MATERIAL 바로 아래 항목들 확인
shop_items = [item for item in text_items if "SHOP MATERIAL" in item["norm"].upper()]
if shop_items:
shop_y = shop_items[0]['y']
print(f"\n\nSHOP MATERIAL 아래 항목들 (Y < {shop_y:.2f}):")
print("-" * 100)
below_items = [item for item in text_items if item['y'] < shop_y - 3.0]
for i, item in enumerate(below_items[:30], 1):
print(f"{i:2d}. X={item['x']:8.2f}, Y={item['y']:8.2f} | '{item['norm']}'")