FreeCAD + MCP 가이드 업데이트 — 2026-10-14 실전 패치 4종

웰컴스 매니저 조회 184

원문: FreeCAD + MCP AI 제어 환경 구축 가이드)(2026-09-07)
이 문서는 원문 가이드대로 구축한 환경에서 실무 DWG를 다루다 발견한 4가지 문제와 그 해결 패치를 정리한 것이다.
검증 환경: Windows 11 / FreeCAD 1.1.3 / ODA File Converter 27.1.0 / freecad-mcp 0.1.22+


요약 표

# 증상 원인 패치 대상 심각도
1 치수 텍스트가 \fAdobe Myungjo Std M\|b0\|...;\W1;36처럼 서식 코드로 표시됨 레거시 importer의 deformat() 정규식 버그 (백슬래시 2개 매칭) Mod/Draft/importDXF.py 높음
2 DWG를 열면 도면이 안 보여서 매번 축소/이동해야 함, 검은 선이 안 보임 뷰 자동 피팅 없음 + 어두운 색상 원본 보존 신규 애드온 OpenPolisher 중간
3 다국어(한글+라틴) DWG가 에러 없이 빈 문서로 열림 레거시 DXF 리더가 시스템 로케일(cp949)로 읽어 UnicodeDecodeError %APPDATA%\...\Macro\dxfReader.py 높음
4 (3번 수정 후) 블록 텍스트 처리 중 또 크래시 importDXF에 남아 있는 디버그 print()가 콘솔(cp949)로 텍스트 출력 Mod/Draft/importDXF.py:1717 높음

공통 교훈: GUI에서 import 실패는 에러창 없이 조용히 빈 문서만 남긴다. 반드시 FreeCADCmd(콘솔)로 동일 작업을 재현해 트레이스백을 확인해야 한다.


1. MTEXT 서식 코드 미제거 패치 (importDXF.py deformat())

증상

DWG를 열면 치수/텍스트가 다음처럼 화면에 그대로 그려진다:

\fAdobe Myungjo Std M|b0|i0|c0|p34;\W1;36

원인

레거시 importer(Mod/Draft/importDXF.py)의 deformat()이 MTEXT 인라인 서식 코드를 제거하는 함수인데, 정규식이 r"\\\\.*?;" — 백슬래시 2개 연속을 찾는다. 실제 MTEXT 코드는 백슬래시 1개(\f...;, \W1;)라 전혀 제거되지 않는다. \U+XXXX 유니코드 코드도 백슬래시만 지우고 U+XXXX가 남는 버그가 있다.

수정

deformat() 전면 교체:

  • 단일 백슬래시 서식 코드(\f...;, \W1;, \A1;, \H2x; 등) 전부 제거
  • \S 누적 분수(공차 표기)는 내용 보존: \S+0.05^0; → +0.05/0
  • \P → 줄바꿈, \~ → 공백, \U+XXXX → 해당 유니코드 문자, %%d/%%c/%%p → °/Ø/±
  • 리터럴 \\ 보존, 문자열 중간의 {}도 제거

검증

  • 오프라인 17케이스 전부 통과 (실 도면 문자열, 공차 누적 분수, 유니코드, 일반 텍스트 불변)
  • 킬바 도안: 36/38/178/36/38/338 정상 표시
  • 내부 도면: R341, R700, ∅3, R15 정상 표시

2. OpenPolisher 애드온 — 열 때 자동 피팅 + 색 보정

증상

  • DWG를 열면 도면이 화면 밖에 있어서 매번 축소/이동해야 한다.
  • 어두운 테마에서 형상 일부(ACI 250 ≈ #333333)와 치수(BYBLOCK 폴백 = 순수 검정)가 배경(#1f1f1f)에 묻혀 안 보인다.
  • 전부 흰색으로만 보정하면 형상과 치수가 구분되지 않는다.

구조

%APPDATA%\FreeCAD\v1-1\Mod\OpenPolisher\ 폴더에 두 파일:

파일 역할
InitGui.py 진입점. 모듈 import 후 deferred_install() 호출
OpenPolisher.py 실제 로직 (문서 옵저버, 리컬러, 피팅)

동작: 새 문서의 첫 재계산 시점에 동기 실행

  1. 뷰 전체 피팅 (fitAll() — 1.1에서 viewFit() 제거됨)
  2. 어두운 LineColor/TextColor(max(r,g,b) < 0.35) 밝힘
    • 형상(일반) → 흰색
    • *치수(`Dimension` 객체 또는 dim/치수 레이어 멤버) → 회색 (0.62)** — 형상과 구분

지오메트리는 변경하지 않고 ViewObject 색상만 건드린다. 제거는 폴더 삭제.

작성 중 발견한 FreeCAD 애드온 함정 (중요)

  1. Init.py는 GUI 초기화 전에 실행된다 (App.GuiUp == False) → GUI 관련 초기화는 반드시 InitGui.py로.
  2. FreeCAD는 InitGui.py 실행 후 모듈 레벨 이름을 정리한다 → QTimer 지연 콜백에서 클래스/상수가 NameError. 로직은 별도 .py 모듈로 분리해 sys.modules에 남아 있게 해야 한다.
  3. RPC 자동화 중에는 QTimer가 발화하지 않는다 (이벤트 루프 기아) → 옵저버 처리는 동기 실행이 안전.
  4. App.addDocumentObserver는 등록 시점에 메서드를 바인딩한다 → 등록 후 인스턴스 속성을 교체해도 무시됨.
  5. Draft 치수 객체는 TypeId가 App::FeaturePython(이름이 Dimension*), 레이어 객체도 App::FeaturePython(이름이 Layer*) — TypeId 검색으로는 못 찾는다.

3. dxfReader.py 인코딩 패치 — 다국어 DWG가 빈 문서로 열리는 문제

증상

한글+라틴 혼합 도면(switch.dwg, 2.2MB ACAD2000)을 열면 에러 없이 객체 0개짜리 빈 문서가 열린다.

원인 (2단)

  1. 레거시 DXF 리더(%APPDATA%\FreeCAD\v1-1\Macro\dxfReader.py — FreeCAD가 내려받는 레거시 라이브러리)가 파일을 open(filename, encoding=None) = 시스템 로케일(cp949)로 연다. 다국어 바이트에서 UnicodeDecodeError → 임포트 전체 중단 → 빈 문서.
    • 참고: ODA를 ACAD2018(UTF-8)로 변환하면 우연히 통과한다. importDWG의 내부 변환은 ACAD2000(ANSI)이라 폭발한다.
  2. 리더 내부의 $DWGCODEPAGE 기반 reconfigure()는 seek(0) 후 실제로 성공해버려서, 파일 전체를 헤더 코드페이지로 강제 재인코딩 → 실제 바이트와 다르면(혼합 언어) 또 크래시.

수정

  • readDXF() 진입에서 파일 전체 바이트를 검사해 인코딩 선택: utf-8 → cp949 → cp949+치환 → latin-1 순. 세 번째 티어가 핵심: 혼합 인코딩 도면(한글+라틴 공존)에서 한글을 살린다.
  • end_section의 $DWGCODEPAGE reconfigure 블록 제거 (스니프 인코딩 신뢰).

검증

  • switch.dwg: 3초 만에 1,936 객체 (형상 1,878 + 텍스트 57)
  • 한글 텍스트 8개 전부 정상: 일괄 소등 스위치 결선도, 기구도면, 블로킹필터, 전등 1/2, 전등 라인 1/2, NC반대

4. importDXF 디버그 print 제거

원인

importDXF.py 1717행에 업스트림에서 남아 있는 디버그 출력이 있다:

print("adding block text", text.value, " from ", blockref)

dxfImportTexts가 켜진 상태에서 블록 내 MTEXT마다 텍스트 값을 콘솔로 출력하는데, 콘솔 인코딩이 cp949라 É 같은 라틴 문자에서 UnicodeEncodeError → 크래시.

수정

해당 print 주석 처리.


적용 및 재적용 방법

파일 위치 백업 덮어써지는 경우
importDXF.py (deformat + print) C:\Program Files\FreeCAD 1.1\Mod\Draft\ importDXF.py.bak-1.1.3 FreeCAD 업데이트/재설치
dxfReader.py (인코딩) %APPDATA%\FreeCAD\v1-1\Macro\ dxfReader.py.bak 레거시 라이브러리 재다운로드
OpenPolisher\ %APPDATA%\FreeCAD\v1-1\Mod\OpenPolisher\ — (신규) 해당 없음 (폴더 삭제 = 제거)

FreeCAD를 업데이트/재설치하면 Program Files 쪽 패치와 레거시 라이브러리가 원본으로 돌아간다. 패치 명세는 워크스페이스 AGENTS.md #28~36에 보관되어 있으니 그대로 재적용하면 된다.

변경 후 효과 (탐색기 더블클릭 기준)

  1. 한글 경로 DWG — 정상 (레거시 importer + 한글 경로 회피 유지)
  2. 텍스트/치수 — 서식 코드 없이 순수 값만 표시 (R341, ∅3, 36 …)
  3. 열자마자 — 뷰 자동 피팅, 형상은 흰색/치수는 회색으로 즉시 판별 가능
  4. 다국어(한글+라틴) DWG — 빈 문서 대신 정상 임포트 (한글 텍스트 생존)
  5. 임포트 속도 — switch.dwg 기준 약 3초
💬 댓글 0
글보기
제목FreeCAD + MCP 가이드 업데이트 — 2026-10-14 실전 패치 4종2026-10-14 16:10
카테고리AI 활용
작성자
> 원문: [FreeCAD + MCP AI 제어 환경 구축 가이드](https://www.wellcoms.co.kr/info/148/) (2026-09-07)
> 이 문서는 원문 가이드대로 구축한 환경에서 **실무 DWG를 다루다 발견한 4가지 문제와 그 해결 패치**를 정리한 것이다.
> 검증 환경: Windows 11 / FreeCAD 1.1.3 / ODA File Converter 27.1.0 / freecad-mcp 0.1.22+

---

## 요약 표

| # | 증상 | 원인 | 패치 대상 | 심각도 |
|---|------|------|-----------|--------|
| 1 | 치수 텍스트가 `\fAdobe Myungjo Std M\|b0\|...;\W1;36`처럼 서식 코드로 표시됨 | 레거시 importer의 `deformat()` 정규식 버그 (백슬래시 2개 매칭) | `Mod/Draft/importDXF.py` | 높음 |
| 2 | DWG를 열면 도면이 안 보여서 매번 축소/이동해야 함, 검은 선이 안 보임 | 뷰 자동 피팅 없음 + 어두운 색상 원본 보존 | 신규 애드온 `OpenPolisher` | 중간 |
| 3 | 다국어(한글+라틴) DWG가 **에러 없이 빈 문서**로 열림 | 레거시 DXF 리더가 시스템 로케일(cp949)로 읽어 UnicodeDecodeError | `%APPDATA%\...\Macro\dxfReader.py` | 높음 |
| 4 | (3번 수정 후) 블록 텍스트 처리 중 또 크래시 | importDXF에 남아 있는 디버그 `print()`가 콘솔(cp949)로 텍스트 출력 | `Mod/Draft/importDXF.py:1717` | 높음 |

공통 교훈: **GUI에서 import 실패는 에러창 없이 조용히 빈 문서만 남긴다.** 반드시 `FreeCADCmd`(콘솔)로 동일 작업을 재현해 트레이스백을 확인해야 한다.

---

## 1. MTEXT 서식 코드 미제거 패치 (importDXF.py `deformat()`)

### 증상
DWG를 열면 치수/텍스트가 다음처럼 화면에 그대로 그려진다:

```
\fAdobe Myungjo Std M|b0|i0|c0|p34;\W1;36
```

### 원인
레거시 importer(`Mod/Draft/importDXF.py`)의 `deformat()`이 MTEXT 인라인 서식 코드를 제거하는 함수인데, 정규식이 `r"\\\\.*?;"` — **백슬래시 2개 연속**을 찾는다. 실제 MTEXT 코드는 백슬래시 **1개**(`\f...;`, `\W1;`)라 전혀 제거되지 않는다. `\U+XXXX` 유니코드 코드도 백슬래시만 지우고 `U+XXXX`가 남는 버그가 있다.

### 수정
`deformat()` 전면 교체:

- 단일 백슬래시 서식 코드(`\f...;`, `\W1;`, `\A1;`, `\H2x;` 등) 전부 제거
- **`\S` 누적 분수(공차 표기)는 내용 보존**: `\S+0.05^0;` → `+0.05/0`
- `\P` → 줄바꿈, `\~` → 공백, `\U+XXXX` → 해당 유니코드 문자, `%%d/%%c/%%p` → °/Ø/±
- 리터럴 `\\` 보존, 문자열 중간의 `{}`도 제거

### 검증
- 오프라인 17케이스 전부 통과 (실 도면 문자열, 공차 누적 분수, 유니코드, 일반 텍스트 불변)
- 킬바 도안: `36/38/178/36/38/338` 정상 표시
- 내부 도면: `R341`, `R700`, `∅3`, `R15` 정상 표시

---

## 2. OpenPolisher 애드온 — 열 때 자동 피팅 + 색 보정

### 증상
- DWG를 열면 도면이 화면 밖에 있어서 매번 축소/이동해야 한다.
- 어두운 테마에서 형상 일부(ACI 250 ≈ #333333)와 치수(BYBLOCK 폴백 = 순수 검정)가 배경(#1f1f1f)에 묻혀 안 보인다.
- 전부 흰색으로만 보정하면 형상과 치수가 구분되지 않는다.

### 구조
`%APPDATA%\FreeCAD\v1-1\Mod\OpenPolisher\` 폴더에 두 파일:

| 파일 | 역할 |
|------|------|
| `InitGui.py` | 진입점. 모듈 import 후 `deferred_install()` 호출 |
| `OpenPolisher.py` | 실제 로직 (문서 옵저버, 리컬러, 피팅) |

동작: 새 문서의 **첫 재계산 시점에 동기 실행**
1. 뷰 전체 피팅 (`fitAll()` — 1.1에서 `viewFit()` 제거됨)
2. 어두운 `LineColor`/`TextColor`(max(r,g,b) < 0.35) 밝힘
- **형상(일반) → 흰색**
- **치수(`Dimension*` 객체 또는 dim/치수 레이어 멤버) → 회색 (0.62)** — 형상과 구분

지오메트리는 변경하지 않고 ViewObject 색상만 건드린다. 제거는 폴더 삭제.

### 작성 중 발견한 FreeCAD 애드온 함정 (중요)
1. **`Init.py`는 GUI 초기화 전에 실행된다** (`App.GuiUp == False`) → GUI 관련 초기화는 반드시 `InitGui.py`로.
2. FreeCAD는 **InitGui.py 실행 후 모듈 레벨 이름을 정리**한다 → QTimer 지연 콜백에서 클래스/상수가 `NameError`. 로직은 별도 `.py` 모듈로 분리해 `sys.modules`에 남아 있게 해야 한다.
3. **RPC 자동화 중에는 QTimer가 발화하지 않는다** (이벤트 루프 기아) → 옵저버 처리는 동기 실행이 안전.
4. `App.addDocumentObserver`는 **등록 시점에 메서드를 바인딩**한다 → 등록 후 인스턴스 속성을 교체해도 무시됨.
5. Draft 치수 객체는 `TypeId`가 `App::FeaturePython`(이름이 `Dimension*`), 레이어 객체도 `App::FeaturePython`(이름이 `Layer*`) — **TypeId 검색으로는 못 찾는다**.

---

## 3. dxfReader.py 인코딩 패치 — 다국어 DWG가 빈 문서로 열리는 문제

### 증상
한글+라틴 혼합 도면(switch.dwg, 2.2MB ACAD2000)을 열면 **에러 없이 객체 0개짜리 빈 문서**가 열린다.

### 원인 (2단)
1. 레거시 DXF 리더(`%APPDATA%\FreeCAD\v1-1\Macro\dxfReader.py` — FreeCAD가 내려받는 레거시 라이브러리)가 파일을 `open(filename, encoding=None)` = **시스템 로케일(cp949)**로 연다. 다국어 바이트에서 `UnicodeDecodeError` → 임포트 전체 중단 → 빈 문서.
- 참고: ODA를 **ACAD2018(UTF-8)**로 변환하면 우연히 통과한다. **importDWG의 내부 변환은 ACAD2000(ANSI)이라 폭발**한다.
2. 리더 내부의 `$DWGCODEPAGE` 기반 `reconfigure()`는 `seek(0)` 후 **실제로 성공**해버려서, 파일 전체를 헤더 코드페이지로 강제 재인코딩 → 실제 바이트와 다르면(혼합 언어) 또 크래시.

### 수정
- `readDXF()` 진입에서 **파일 전체 바이트를 검사**해 인코딩 선택: `utf-8 → cp949 → cp949+치환 → latin-1` 순. 세 번째 티어가 핵심: **혼합 인코딩 도면(한글+라틴 공존)에서 한글을 살린다.**
- `end_section`의 `$DWGCODEPAGE` reconfigure 블록 제거 (스니프 인코딩 신뢰).

### 검증
- switch.dwg: **3초** 만에 1,936 객체 (형상 1,878 + 텍스트 57)
- 한글 텍스트 8개 전부 정상: `일괄 소등 스위치 결선도`, `기구도면`, `블로킹필터`, `전등 1/2`, `전등 라인 1/2`, `NC반대`

---

## 4. importDXF 디버그 print 제거

### 원인
`importDXF.py` 1717행에 업스트림에서 남아 있는 디버그 출력이 있다:

```python
print("adding block text", text.value, " from ", blockref)
```

`dxfImportTexts`가 켜진 상태에서 블록 내 MTEXT마다 텍스트 값을 콘솔로 출력하는데, 콘솔 인코딩이 cp949라 `É` 같은 라틴 문자에서 `UnicodeEncodeError` → 크래시.

### 수정
해당 print 주석 처리.

---

## 적용 및 재적용 방법

| 파일 | 위치 | 백업 | 덮어써지는 경우 |
|------|------|------|----------------|
| `importDXF.py` (deformat + print) | `C:\Program Files\FreeCAD 1.1\Mod\Draft\` | `importDXF.py.bak-1.1.3` | FreeCAD 업데이트/재설치 |
| `dxfReader.py` (인코딩) | `%APPDATA%\FreeCAD\v1-1\Macro\` | `dxfReader.py.bak` | 레거시 라이브러리 재다운로드 |
| `OpenPolisher\` | `%APPDATA%\FreeCAD\v1-1\Mod\OpenPolisher\` | — (신규) | 해당 없음 (폴더 삭제 = 제거) |

FreeCAD를 업데이트/재설치하면 Program Files 쪽 패치와 레거시 라이브러리가 원본으로 돌아간다. 패치 명세는 워크스페이스 `AGENTS.md` #28~36에 보관되어 있으니 그대로 재적용하면 된다.

## 변경 후 효과 (탐색기 더블클릭 기준)

1. **한글 경로 DWG** — 정상 (레거시 importer + 한글 경로 회피 유지)
2. **텍스트/치수** — 서식 코드 없이 순수 값만 표시 (`R341`, `∅3`, `36` …)
3. **열자마자** — 뷰 자동 피팅, 형상은 흰색/치수는 회색으로 즉시 판별 가능
4. **다국어(한글+라틴) DWG** — 빈 문서 대신 정상 임포트 (한글 텍스트 생존)
5. 임포트 속도 — switch.dwg 기준 약 3초


댓글
자동등록방지
(자동등록방지 숫자를 입력해 주세요)
목록으로