모듈 7: Examples & Samples - 예제 프로젝트 활용
학습 목표
- examples/ 폴더의 구조와 역할을 이해한다
- snippets와 전체 예제 프로젝트의 차이를 설명할 수 있다
- AI가 예제를 어떻게 활용하는지 이해한다
- 새 예제를 추가하여 팀 코드베이스를 확장할 수 있다
examples/ 폴더 구조
examples/
├── EGViewportSample/ # 완전한 WPF 프로젝트 (뷰포트 기능 전시)
│ ├── ViewModels/ # 각 기능별 ViewModel
│ │ ├── MainViewModel.cs
│ │ ├── CrossSectionViewModel.cs
│ │ ├── CameraViewModel.cs
│ │ ├── LightViewModel.cs
│ │ └── ... (총 10개)
│ └── Views/ # XAML 뷰
│
├── HmModelSample/ # 모델 조작 전용 프로젝트
│ └── MainViewModel.cs
│
├── snippets/ # 단일 기능 코드 조각
│ ├── AddBox.cs
│ ├── AddSphere.cs
│ └── ZoomExtents.cs
│
└── categories/ # 카테고리별 샘플 문서
└── basic-shapes.md
두 가지 예제 레이어
Layer 1: snippets/ - 단일 기능 코드 조각
특정 HmEG API 하나를 사용하는 최소한의 예제입니다.
// examples/snippets/AddBox.cs
// Category: Basic Shapes, API: AddShapeBox
public static void CreateBasicBox(EGViewport viewport)
{
if (viewport?.RootSpace == null) return;
viewport.RootSpace.AddShapeBox(
new HmPoint3D(0, 0, 0), // 중심점
50, // width (X축)
50, // height (Y축)
50, // depth (Z축)
Colors.Blue // 색상
);
}AI가 이것을 읽으면:
AddShapeBox의 정확한 파라미터 순서 학습HmPoint3D타입으로 좌표 지정하는 패턴 학습- null 체크 패턴 학습
Layer 2: EGViewportSample/ - 완전한 MVVM 구현
실제 프로덕션에 가까운 전체 기능 구현입니다.
// examples/EGViewportSample/ViewModels/CrossSectionViewModel.cs
public class CrossSectionViewModel : ViewportViewModel
{
private double sliderX;
public double SliderX
{
get => sliderX;
set
{
if (Set(ref sliderX, value))
OnSliderXChanged();
}
}
private void OnSliderXChanged()
{
var boundingBox = _viewport.GetBoundingBox();
var x = boundingBox.Minimum.X + boundingBox.Size.X * SliderX;
var newPlane = new HmPlane3D(new HmPoint3D(x, 0, 0), HmVector3D.AxisX);
if (_viewport.CrossSectionPlane1 == null)
_viewport.CrossSectionPlane1 = new CrossSectionPlane(newPlane) { ShowIntersection = true };
else
_viewport.CrossSectionPlane1.CutPlane = newPlane;
}
}AI가 이것을 읽으면:
- MVVM 패턴의 실제 적용 방법 학습
GetBoundingBox()+CrossSectionPlane연계 패턴 학습- 기존 Plane 재사용 vs 신규 생성 분기 패턴 학습
examples/가 AI에게 하는 역할
역할 1: 코드 패턴 제공
사용자: "3D 구 추가해줘"
AI (examples/snippets/AddSphere.cs 참조):
viewport.RootSpace.AddShapeSphere(
new HmPoint3D(0, 0, 0),
radius: 25,
Colors.Green
);
// AddBox.cs와 동일한 패턴 -> 올바른 코드 생성
역할 2: MVVM 구조 가이드
사용자: "카메라 제어 ViewModel 만들어줘"
AI (examples/EGViewportSample/ViewModels/CameraViewModel.cs 참조):
public class CameraViewModel : ViewportViewModel
{
// 기존 패턴: ObservableObject 상속 대신 ViewportViewModel 상속
// 기존 패턴: EGViewport를 생성자로 주입
// 기존 패턴: RaisePropertyChanged 사용
}
역할 3: 통합 패턴 제공
// MainViewModel.cs를 보면:
// EGViewport 하나를 여러 ViewModel이 공유하는 패턴을 학습
public void OnViewportLoadComplete(EGViewport viewport)
{
CrossSectionViewModel = new(viewport);
LightViewModel = new(viewport);
CameraViewModel = new(viewport);
// ...
}
snippets 파일 작성 규칙
// ============================================================================
// HmEG Sample: [기능명] (ID: [번호])
// Category: [카테고리]
// API: [주요 API명]
// ============================================================================
// 1. 헤더 주석: 카테고리, ID, API 명시
// 2. 네임스페이스: HmEGSamples (일관성)
// 3. 클래스: static - 인스턴스 불필요
// 4. 메서드: 입력은 EGViewport만
// 5. null 체크: viewport?.RootSpace == null 패턴
// 6. 마지막: Usage Examples 주석좋은 snippet 예시
// ============================================================================
// HmEG Sample: Camera Zoom Extents (ID: 20)
// Category: Camera Control
// API: ZoomExtents
// ============================================================================
using HmEG;
namespace HmEGSamples
{
public static class ZoomExtentsSample
{
/// <summary>
/// 모든 오브젝트가 보이도록 카메라 자동 조정
/// </summary>
public static void FitAll(EGViewport viewport)
{
if (viewport == null) return;
viewport.ZoomExtents();
}
/// <summary>
/// 특정 오브젝트 기준으로 카메라 조정
/// </summary>
public static void FitToObject(EGViewport viewport, HmModel model)
{
if (viewport == null || model == null) return;
viewport.ZoomExtents(model.BoundingBox);
}
}
}
// ============================================================================
// Usage:
// ZoomExtentsSample.FitAll(viewport);
// ZoomExtentsSample.FitToObject(viewport, selectedModel);data/HmEGSample/ - 사내 공식 샘플
회사 내 HmEG 엔진 팀이 제공하는 공식 샘플 프로젝트들입니다:
data/HmEGSample/
├── ACIColoringSample/ # AutoCAD 색상 체계 적용
├── AllocateViewerSample/ # 뷰어 동적 할당
├── BillboardSample/ # 빌보드 객체 (항상 카메라를 향함)
├── BlockSample/ # 블록 참조 객체
├── CameraAnimationSample/ # 카메라 애니메이션
├── ContourMesh_CSD/ # 등고선 메시 (토목 특화)
├── DimensionSample/ # 치수선
├── LayerSample/ # 레이어 관리
├── LegendSample/ # 범례
├── ModelKeyframeAnimationSample/ # 키프레임 애니메이션
└── ... (총 30+ 샘플)
토목 엔지니어 관련 샘플
| 샘플 | 설명 | 주요 API |
|---|---|---|
| ContourMesh_CSD | 등고선 메시 | ContourMeshData |
| DimensionSample | 치수선/치수 표시 | DimensionEntity |
| LayerSample | 레이어 제어 | LayerTable |
| LegendSample | 범례 표시 | LegendControl |
| ACIColoringSample | ACI 색상 체계 | ACIColor |
generate-prp에서 examples 활용
/generate-prp PRPs/INITIAL.md
generate-prp가 자동으로 수행:
examples/디렉토리 전체 스캔- 요청된 기능과 관련된 기존 예제 식별
- PRP에 참조 파일 목록 포함
# 생성된 PRP 내 예제 참조 섹션
## All Needed Context
### Code Patterns to Follow
- file: examples/EGViewportSample/ViewModels/CrossSectionViewModel.cs
why: CrossSectionPlane 생성 및 BoundingBox 기반 offset 계산 패턴
- file: examples/EGViewportSample/ViewModels/MainViewModel.cs
why: ViewportViewModel 초기화 및 자식 ViewModel 연결 패턴
- file: examples/snippets/AddBox.cs
why: RootSpace.AddShape* 계열 API 호출 패턴examples 폴더 확장 가이드
팀원이 새 패턴을 발견했을 때:
Step 1: snippet 추가
// examples/snippets/ApplyTransparency.cs
// ============================================================================
// HmEG Sample: Apply Transparency (ID: 30)
// Category: Materials
// API: HmModel.Transparency
// ============================================================================
public static void SetModelTransparency(HmModel model, float transparency)
{
// transparency: 0.0 (불투명) ~ 1.0 (완전 투명)
if (model == null) return;
model.Transparency = Math.Clamp(transparency, 0f, 1f);
}Step 2: categories 문서 업데이트
// examples/categories/materials-rendering.md에 추가
| ID | Name | API | 난이도 |
|----|------|-----|--------|
| 30 | Apply Transparency | HmModel.Transparency | ⭐ |Step 3: hmeg-api Skill 코퍼스 업데이트 (필요시)
새 API가 HmEG.md에 없다면:
python setup_store.py upload --path data/HmEG_transparency.md예제 활용 실습
실습 1: 기존 패턴으로 새 기능 구현
CrossSectionViewModel.cs를 참조하여 HitTest 기능 구현하기:
참조: examples/EGViewportSample/ViewModels/HitTestViewModel.cs
패턴 확인:
1. ViewportViewModel 상속
2. EGViewport.RayCast 또는 HitTest API 사용
3. 선택된 모델 강조 표시
4. ICommand 패턴으로 UI 바인딩
실습 2: snippet 작성
다음 기능의 snippet을 작성해보세요:
- 기능: 모든 모델 선택 해제
- API:
[API 조회 필요: EGViewport.ClearSelection] - 카테고리: Selection Control
핵심 정리
examples/snippets/: 단일 API 사용법 - AI의 패턴 학습 자료examples/EGViewportSample/: 완전한 MVVM 구현 - AI의 구조 학습 자료data/HmEGSample/: 공식 사내 샘플 - 고급 기능 참조- generate-prp가 자동으로 관련 예제를 찾아 PRP에 포함
- 팀이 좋은 패턴을 발견하면 즉시 snippet으로 추가 → AI가 다음 기회에 활용
- snippets는 짧고 명확하게 + 헤더 주석으로 검색 가능하게 작성