본문으로 건너뛰기
5분 AI.
GITHUB TRENDING C++ WEEKLY #7 딥다이브 · 2026-10-23 분석

OrcaSlicer 딥다이브
— 3D 모델이 프린터의 이동 경로가 되기까지

데스크탑 앱

빠른 판단

무엇
3D 모델과 프린터·재료 설정에서 층별 이동·압출 경로를 계산하는 3D 프린팅 슬라이서
이럴 때
프린터별 출력 조건을 조정하고 지지대·층·경로를 검토한 뒤 출력용 G-code를 만들 때
입력
3D 모델·프린터·재료·슬라이싱 설정
결과
층별 출력 경로·미리보기와 프린터용 G-code
입체 모델을 얇은 층으로 자르고, 벽·내부 채움·지지대의 경로를 계산해 3D 프린터가 읽는 G-code로 만드는 데스크톱 프로그램입니다. C++ 계산 엔진, wxWidgets 화면, OpenGL 미리보기, 제조사별 설정 데이터가 한 제품으로 연결되는 과정을 따라갑니다. 저장소 OrcaSlicer/OrcaSlicer · ⭐16,087 · 포크 3,303 · C++ · AGPL-3.0 · 2026-10-23 GitHub 기준. 코드 설명은 커밋 022769c8의 개발 소스를 기준으로 합니다.
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 / 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

형상을 읽어, 재료를 어디에 얼마나 쌓을지 계산하는 프로그램

OrcaSlicer는 3D 모델과 출력 설정을 프린터용 이동·압출 명령으로 바꾸는 슬라이서입니다. 화면에 예쁜 입체 모형을 보여주는 것만으로는 물체를 만들 수 없습니다. 노즐이 어느 높이에서 어떤 선을 따라 움직이고, 그동안 재료를 얼마나 밀어낼지 정해야 합니다.

이 저장소에서 배울 핵심은 복잡한 계산을 여러 단계로 나누고, 그 결과를 사람이 조작할 수 있는 제품으로 연결하는 방법입니다. 웹 서비스 경험이 있다면 화면과 서버를 떠올려도 좋지만, 여기서는 계산 엔진과 화면이 대체로 같은 데스크톱 프로세스 안에 있습니다.

용어부터
슬라이싱과 G-code
슬라이싱은 입체 형상에서 높이별 단면을 얻고 출력 경로를 만드는 과정입니다. G-code는 그 경로를 이동·압출·온도 등의 명령으로 표현한 텍스트입니다. 모델 파일의 삼각형과 프린터가 실제로 수행할 명령 사이에 계산 단계가 놓입니다.
한 문장 비유

건축 모형을 보고, 층별 공사 순서와 작업자의 동선을 짜는 현장 감독입니다

3D 모델이 완성될 건물의 모양이라면, 프리셋은 벽돌 크기·장비 성능·재료의 성질입니다. 슬라이서는 이를 묶어 “첫 층의 외벽을 돌고, 내부를 채우고, 다음 층으로 올라가라”는 작업 지시서를 만듭니다.

외형이 같은 건물도 재료와 장비가 다르면 공사 방법이 달라집니다. 그래서 좋은 슬라이서는 기하 계산뿐 아니라 설정의 조합과 장비의 차이를 다뤄야 합니다.

1-1. 입력과 출력 사이에 있는 다섯 가지 일

단계하는 일읽을 소스
모델 해석STL·OBJ·3MF 등의 형상과 프로젝트 정보를 읽습니다.src/libslic3r/Format/
단면 생성높이별로 메시를 잘라 윤곽과 구멍을 얻습니다.TriangleMeshSlicer.cpp의 slice_mesh()
경로 생성벽, 내부 채움, 지지대처럼 성격이 다른 경로를 만듭니다.PrintObject.cpp, Fill/, Support/
명령 생성이동 순서와 압출량 등을 G-code로 내보냅니다.Print::export_gcode(), GCode::do_export()
검토·전달경로를 미리 보고 파일로 저장하거나 출력 호스트로 보냅니다.src/slic3r/GUI/, src/slic3r/Utils/PrintHost.cpp

위 표에서 파일명만 적은 계산 파일은 src/libslic3r/ 아래에 있습니다. 실제 파이프라인에는 브림, 퍼지 타워, 경로 단순화, 재료 전환 등 더 많은 단계가 있습니다. 다섯 단계는 처음 읽기 위한 큰 지도입니다.

1-2. G-code는 어떤 모습인가

; 문법 이해용 예시. 특정 프린터용 출력 파일이 아닙니다.
G90                    ; 좌표를 절대 위치로 해석
M82                    ; 압출 위치도 절대값으로 해석
G1 Z0.20 F600          ; 높이 이동
G1 X20 Y20 F3000       ; XY 위치 이동
G1 X40 Y20 E0.75 F1200 ; 이동하며 재료 압출

이 예시에는 가열·원점 복귀·압출 초기화 등이 없습니다. 문법을 읽는 연습에만 사용합니다. 같은 형상이라도 펌웨어와 압출 모드가 다르면 필요한 명령이 달라집니다.

학습 목표
프린터가 없어도 구조를 배울 수 있습니다

모델을 출력하는 데는 장비가 필요하지만, 설정이 계산에 전달되는 경로와 결과를 재사용하는 규칙은 소스만으로 추적할 수 있습니다. 이 글은 FFF/FDM 출력 경로를 중심으로 C++ 제품의 설계를 읽는 안내서입니다.

2왜 주목받는가

트렌딩 순위와, 코드에서 읽히는 실용적인 매력

2026-10-23 GitHub Trending C++ Weekly에서 7위로 선정된 프로젝트입니다. 다만 순위만으로 유입 원인을 확정할 수는 없습니다. 아래의 주목 요인은 README의 기능 설명과 소스 구성을 바탕으로 한 해석이며, 특정 소식 때문에 순위가 올랐다는 인과관계는 확인되지 않았습니다.

2-1. 한 제조사의 장비를 넘어서는 설정과 연결

README는 Bambu Lab·Prusa·Creality·Voron 등을 지원 대상으로 소개합니다. 소스에는 제조사별 resources/profiles/가 있고, PrintHost::get_print_host()는 htOctoPrint, htPrusaLink, htMoonraker 등에 따라 구현 객체를 선택합니다. “호환된다”는 홍보 문구 뒤에 데이터와 연결 코드라는 두 종류의 확장 지점이 있는 셈입니다.

JSON 파일이 있다고 모든 장비 조합을 검증했다는 뜻은 아닙니다. 그럼에도 여러 장비의 차이를 하나의 계산 엔진으로 흡수하는 방식은 프린터 사용자와 개발자 모두에게 관심을 끌 만한 지점입니다.

2-2. 출력 품질을 조절하는 도구가 한곳에 있습니다

README가 강조하는 기능은 온도·유량·리트랙션 교정, 벽 정밀도와 이음매 제어, 지지대 최적화입니다. 관련 코드는 src/libslic3r/calib.hpp, src/libslic3r/PerimeterGenerator.cpp, src/libslic3r/Support/ 등으로 이어집니다. 출력 실패를 줄이고 표면을 다듬는 문제는 사용자가 결과를 직접 확인하기 쉬운 문제입니다.

쉬운 설명
교정과 프리셋
교정은 내 장비·재료에 맞는 값을 실험으로 찾는 일입니다. 프리셋은 그 값을 재사용하는 설정 묶음입니다. 기본 레시피가 있어도 오븐과 재료가 다르면 조정이 필요한 것과 같습니다.

2-3. 경쟁 제품을 볼 때는 출발점과 학습 초점을 비교합니다

README의 계보 설명에 따르면 Slic3r에서 PrusaSlicer로, 다시 Bambu Studio로 발전한 흐름 위에서 OrcaSlicer가 시작됐습니다. SuperSlicer와 Cura에서 영향을 받은 아이디어도 언급합니다. 따라서 비슷한 화면이나 클래스 이름은 공유한 역사와 연결해 읽는 편이 정확합니다.

비교 대상관계를 읽는 관점OrcaSlicer에서 볼 장점
Bambu StudioREADME가 밝힌 주요 출발점입니다.여러 제조사 프로필과 다양한 출력 호스트를 한 저장소에서 추적할 수 있습니다.
PrusaSlicer공유하는 상류 계보가 있습니다.계승된 엔진 위에 교정·벽·이음매 기능과 제품 UI가 연결되는 사례를 읽습니다.
SuperSlicerREADME가 기능 아이디어의 영향을 언급합니다.세부 출력 제어가 설정 정의·프리셋·파이프라인으로 분산되는 방식을 배웁니다.
CuraREADME가 아이디어의 영향을 언급한 다른 슬라이서입니다.이 글에서는 Orca의 C++ 엔진과 wxWidgets UI가 결합하는 구체적인 구현을 살펴봅니다.

이 표는 다른 제품에 해당 기능이 없다는 주장이나 성능 순위가 아닙니다. 동일 모델·설정·하드웨어로 비교한 측정 자료가 없으므로 “가장 빠르다”는 결론도 내리지 않습니다.

2-4. 개발 브랜치는 슬라이서 주변으로 범위를 넓힙니다

커밋 022769c8에는 src/libslic3r/CAD/와 src/slic3r/GUI/CAD/, Python 플러그인 구현이 존재합니다. 루트 CMakeLists.txt의 SLIC3R_CAD 기본값도 켜져 있습니다. 이는 현재 개발 소스의 사실이며, 안정 릴리스 v2.4.2에 모두 들어 있다는 뜻은 아닙니다.

OrcaSlicer의 학습 가치는 새 알고리즘 하나보다, 오래된 엔진에 새 기능을 붙이면서 설정·호환성·화면 반응성을 함께 지키는 데 있습니다.

주장과 근거의 거리
README의 최상급 표현은 측정 결과와 구분합니다

README는 매우 빠른 슬라이싱과 폭넓은 사용을 강조하지만, 그 문장 자체가 비교 벤치마크나 시장 점유율 자료는 아닙니다. 이 글은 소스에 존재하는 기능과 설계를 설명하며, 인기의 원인이나 속도 우위를 수치로 확정하지 않습니다.

3기술 스택 전체 지도

계산 엔진 · 사용자 화면 · 의존성과 배포를 나누어 보기

3-1. 백엔드에 해당하는 부분: 로컬 C++ 계산 엔진

웹 서비스의 백엔드에 가까운 역할은 src/libslic3r/가 맡습니다. 모델·설정·단면·경로를 다루는 라이브러리이며, 외부 HTTP 서버를 띄워야 슬라이싱할 수 있는 구조는 아닙니다. 루트와 src/CMakeLists.txt 모두 기본 C++ 표준을 17로 설정합니다.

기술소스에 적힌 버전역할과 근거 파일
C++C++17계산과 제품 구현. CMakeLists.txt의 CMAKE_CXX_STANDARD.
Boost의존성 빌드 1.84.0파일 시스템·로그·스레드 등. deps/Boost/Boost.cmake.
oneTBB2021.5.0레이어 등의 병렬 계산. deps/TBB/TBB.cmake.
Eigen5.0.1벡터·행렬 연산. deps/Eigen/Eigen.cmake.
CGAL6.2.1계산기하 기능. deps/CGAL/CGAL.cmake.
Clipper22.0.1다각형 교집합·차집합·오프셋. deps_src/clipper2/CMakeLists.txt.
OCCT8.0.1STEP·형상 처리와 CAD 기능. deps/OCCT/OCCT.cmake의 V8_0_1.
cereal1.3.0C++ 데이터를 직렬화. deps/Cereal/Cereal.cmake.
CPython3.12.13내장 Python 실행 환경. deps/python3/python3.cmake.
pybind113.0.1C++와 Python 연결. deps_src/pybind11/include/pybind11/detail/common.h의 버전 상수.

여기서 버전은 해당 커밋의 의존성 빌드 정의 또는 포함된 소스 버전입니다. 운영체제 패키지를 이용하는 빌드나 배포본의 실제 링크 결과까지 같은 버전이라고 단정할 수는 없습니다.

빌드 설정 읽는 요령

find_package(Boost 1.83.0 REQUIRED ...)는 사용할 Boost를 찾는 요구 조건이고, 의존성 빌드 파일의 1.84.0은 가져와 빌드할 대상입니다. 주문 가능한 최소 규격과 실제 발주한 부품을 구분하면 버전 숫자가 달라도 이해할 수 있습니다.

3-2. 프론트엔드: wxWidgets와 OpenGL, 일부 내장 웹 화면

주 UI는 src/slic3r/GUI/의 네이티브 C++ 코드입니다. deps/wxWidgets/wxWidgets.cmake는 Orca용 wxWidgets 저장소의 v3.3.2를 고정하고, src/CMakeLists.txt는 wxWidgets 3.3을 요구합니다. 창·버튼·이벤트는 wxWidgets가, 3D 장면과 경로 표시는 OpenGL 관련 코드가 담당합니다.

구성근거읽을 때 볼 질문
일반 화면src/slic3r/GUI/GUI_App.cpp, Plater.cpp사용자 동작이 어떤 계산 요청으로 바뀌는가?
3D 뷰src/slic3r/GUI/GLCanvas3D.cpp모델 좌표와 화면 좌표를 어떻게 연결하는가?
그래픽 초기화src/slic3r/GUI/OpenGLManager.cpp드라이버의 기능을 어떻게 검사하는가?
내장 웹 UIresources/web/페이지가 C++ 쪽으로 어떤 메시지를 보내는가?

예를 들어 resources/web/dialog/ExportPresetDialog/index.js의 RequestProfile()은 request_export_preset_profile을 보내고, HandleStudio()는 응답 명령을 확인합니다. resources/web/include/globalapi.js에는 SendWXMessage()가 있습니다. 웹 화면이 있어도 제품 전체를 웹 앱으로 분류하면 실제 구조를 놓칩니다.

저장소에는 package.json, Cargo.toml, pyproject.toml, go.mod가 없습니다. 이 프로젝트의 빌드 출발점은 CMake입니다. JavaScript 파일이 존재한다는 이유만으로 Node.js 기반 프론트엔드 빌드를 가정하면 안 됩니다.

3-3. 인프라·빌드: 의존성을 먼저 만들고 앱에 연결합니다

deps/는 외부 의존성을 준비하는 빌드 정의이고, deps_src/는 저장소에 포함된 외부 소스입니다. 거대한 C++ 제품에서는 코드 컴파일만큼 버전·패치·운영체제별 라이브러리 배치를 맞추는 일이 중요합니다.

# CMakeLists.txt의 설정 중 일부를 발췌
cmake_minimum_required(VERSION 3.13)
option(SLIC3R_GUI "Compile OrcaSlicer with GUI components (OpenGL, wxWidgets)" 1)
option(SLIC3R_CAD "Compile OrcaSlicer with the parametric Design/CAD tab (needs OCCT ModelingAlgorithms)" 1)
option(BUILD_TESTS "Build unit tests" OFF)
set(CMAKE_CXX_STANDARD 17)

CMAKE_BUILD_TYPE이 비어 있고 다중 구성 생성기도 아니면 기본값은 Release입니다. scripts/Dockerfile은 ubuntu:24.04를 기반으로 의존성·앱·AppImage를 만드는 단계를 나눕니다. 이 Dockerfile은 개발·패키징 환경을 설명하며 웹 서버 배포의 증거가 아닙니다.

.github/workflows/build_all.yml은 Linux x86_64·aarch64, Windows x64·arm64, macOS의 아키텍처별 빌드와 Universal 패키지 결합을 구성합니다. unit_tests.yml은 빌드된 테스트 산출물을 내려받아 실행하고 JUnit 결과를 올립니다.

.github/workflows/clang_tidy.yml은 PR의 변경된 C++ 줄을 검사합니다. 미리 컴파일한 헤더를 끈 컴파일 데이터베이스를 사용해, 우연히 다른 헤더를 통해 공급된 선언에 의존하는 코드도 드러내려 합니다. 테스트 프레임워크는 tests/catch2/CMakeLists.txt 기준 Catch2 3.11.0입니다.

앱에 포함하는 패키지 도구 uv도 루트 CMake에서 0.11.21로 고정하고 플랫폼별 SHA-256을 검사합니다. 이처럼 빌드 파일은 프로그램을 만드는 명령 목록이면서, 제품에 어떤 부품을 넣을지 기록한 명세서이기도 합니다.

4아키텍처 심화 분석

진입점에서 결과 파일까지, 네 가지 설계 선택을 따라갑니다

4-1. 전체 시스템 지도

src/OrcaSlicer.cpp의 일반 플랫폼 진입점 main()은 CLI().run(argc, argv)를 호출합니다. CLI::run()은 실행할 작업이 없고 하위 호환성 검사(downward_check)가 꺼져 있으면 GUI 시작 경로를 선택하고, GUI를 포함한 빌드에서는 GUI_Run()으로 들어갑니다. CLI와 GUI가 서로 다른 슬라이싱 엔진을 따로 갖는다고 이해할 필요는 없습니다.

[사용자 / 명령행] | v src/OrcaSlicer.cpp : main() -> CLI::run() | +-- GUI_Run() -> wxWidgets 이벤트 루프 | | | Plater / 설정 화면 | | | BackgroundSlicingProcess | | +-- CLI 작업 -------+---> Model + DynamicPrintConfig | v Print::apply() [설정·모델 반영] | v Print::process() [단계 실행] | PrintObject / Layer / PrintRegion | 단면 -> 벽 -> 채움 준비 -> 채움·지지대 등 | v Print::export_gcode() | GCode / GCodeWriter / 분석 결과 | 파일 저장 / 경로 미리보기 | 선택적으로 PrintHost에 전달 [프로필 JSON / .opc 캐시] --> PresetBundle --> 설정 [선택적 CAD 탭] -----------> 일반 Model로 변환해 합류

위 그림은 주요 책임을 묶은 개념도입니다. 모든 화살표가 인접한 함수의 직접 호출을 뜻하지는 않습니다. 특히 실제 출력은 경로 생성 외에 프린터 설정 검증과 별도의 전달·시작 동작을 거칩니다.

4-2. 데이터 모델부터 구분하기

객체무엇을 표현하나어디서 보나
Model가져온 형상, 오브젝트와 배치 같은 입력 프로젝트 정보.src/libslic3r/Model.hpp
Print출력 작업 전체와 그 작업의 설정·진행 단계.src/libslic3r/Print.hpp
PrintObject개별 출력 대상의 층과 계산 결과.src/libslic3r/Print.hpp
PrintRegion출력 영역에 적용되는 설정 묶음.src/libslic3r/Print.hpp
Layer특정 높이의 단면과 경로를 다루는 층.src/libslic3r/Layer.hpp

Model과 Print를 구분해야 “모델은 그대로인데 설정 때문에 경로만 다시 계산한다”는 상황이 이해됩니다. src/libslic3r/PrintApply.cpp의 Print::apply()가 그 사이를 잇습니다. 출력 작업을 다루는 Print.cpp에 모든 구현이 모여 있지는 않다는 점도 기억하세요.

4-3. 설계 ① 파이프라인과 단계별 무효화

Print::process()는 PrintObject::slice(), make_perimeters(), prepare_infill(), infill() 등을 단계적으로 호출합니다. 하지만 호출됐다는 사실과 실제 계산이 다시 수행됐다는 사실은 다릅니다.

src/libslic3r/PrintBase.hpp의 PrintState::set_started()는 뮤텍스를 잡고 취소 여부를 확인한 뒤, 단계가 이미 DONE이면 false를 반환합니다. 이를 이용해 선행 단계를 다시 호출하더라도 유효한 결과는 재사용합니다.

// PrintObject.cpp의 infill()을 핵심 흐름만 남겨 재구성
void PrintObject::infill()
{
    this->prepare_infill();
    if (this->set_started(posInfill)) {
        // 실제 구현은 TBB로 레이어별 make_fills() 수행
        // 중간과 완료 직전에 취소 요청 확인
        this->set_done(posInfill);
    }
}

그렇다면 언제 DONE을 버릴까요? Print::apply()에서 설정 차이를 반영하고, PrintObject::invalidate_state_by_config_options()가 변경된 키를 재계산할 단계로 연결합니다.

변경 키소스의 무효화 출발점이유를 생각해 보기
layer_heightposSlice단면을 얻을 높이가 달라집니다.
wall_loopsposPerimeters벽 경로와 그 뒤의 내부 영역 계산에 영향을 줍니다.
sparse_infill_patternposPrepareInfill패턴 생성 전에 영역 준비부터 갱신합니다.
sparse_infill_density준비 단계, 일부 경우 벽 단계도이전·새 값 중 0%나 100%가 있으면 벽 단계도 무효화합니다.

이 표는 전체 무효화 목록이 아닌 대표 분기입니다. 무효화는 뒤 단계에도 전파되므로 “출발 단계 하나만 다시 계산한다”는 뜻은 아닙니다. 특히 채움 밀도는 숫자만 바뀌는 설정처럼 보이지만, 비어 있음·일반 채움·완전 채움의 경계에서 더 많은 계산에 영향을 줍니다.

증분 계산 비유

층별 설계도가 그대로인데 벽돌을 쌓는 무늬만 바꾸었다면 건물의 모든 치수를 처음부터 재지 않아도 됩니다. 반대로 층고가 바뀌면 위층의 기준도 달라집니다. 재사용하려면 먼저 “무엇이 무엇에 의존하는가”를 명확히 해야 합니다.

빠르게 만드는 핵심은 계산을 무조건 병렬화하는 것뿐 아니라, 바뀌지 않은 계산을 다시 하지 않는 데 있습니다.

4-4. 설계 ② 팩터리와 전략: 패턴을 교체하는 방법

src/libslic3r/Fill/FillBase.cpp의 Fill::new_from_type()는 패턴 열거값을 구현 객체로 바꿉니다. FillBase.hpp의 Fill은 가상 함수를 제공하고, 구체적인 채움 구현은 그 인터페이스를 따릅니다. 객체 선택은 팩터리로, 바꿔 끼우는 계산 방식은 전략으로 읽을 수 있습니다.

// FillBase.cpp의 switch 중 대표 분기 발췌
case ipGyroid:      return new FillGyroid();
case ipRectilinear: return new FillRectilinear();
case ipGrid:        return new FillGrid();

// Fill.cpp의 소유권 처리 방식
std::unique_ptr<Fill> f =
    std::unique_ptr<Fill>(Fill::new_from_type(surface_fill.params.pattern));

공장 역할의 함수가 원시 포인터를 반환해도 호출부는 std::unique_ptr로 소유권을 받습니다. 소유 객체가 범위를 벗어날 때 정리되는 RAII의 실제 사용입니다. 새 패턴을 추가할 때는 구현 클래스뿐 아니라 열거값·설정 선택지·팩터리 연결·테스트까지 찾아야 합니다.

장비 연결에도 비슷한 선택 구조가 있습니다. src/slic3r/Utils/PrintHost.cpp의 PrintHost::get_print_host()는 host_type을 보고 연결 구현을 만듭니다. 학습할 때는 서로 다른 파일에서 반복되는 “설정값 → 구체 구현”의 모양을 찾아보세요.

4-5. 설계 ③ 이벤트와 작업 스레드의 책임 분리

오래 걸리는 계산을 화면 이벤트 처리 중에 모두 수행하면 창이 멈춘 것처럼 보입니다. src/slic3r/GUI/BackgroundSlicingProcess.cpp는 작업 스레드와 상태를 관리하고, 계산 완료 등은 wxQueueEvent()로 GUI 쪽에 전달합니다.

[GUI 스레드] [작업 스레드] 설정 변경 / 시작 요청 -- 상태·조건변수 --> 대기에서 깨어남 화면 이벤트 처리 계속 Print::process() export_gcode() 완료 이벤트 수신 <---- wxQueueEvent ---- 완료·취소·오류 통지 미리보기와 상태 갱신

BackgroundSlicingProcess::start(), stop()과 작업 루프를 함께 읽으면 STATE_IDLE, STATE_STARTED, STATE_RUNNING, STATE_FINISHED의 역할이 보입니다. 루프는 조건변수로 시작·종료 요청을 기다리며, 완료 통지에는 예외 정보와 취소 상태도 반영합니다.

여기에 TBB 병렬 계산이 한 겹 더 있습니다. PrintObject::infill()은 tbb::blocked_range<size_t>로 레이어 범위를 나누고 make_fills()를 호출합니다. “GUI와 계산을 분리하는 동시성”과 “계산 내부를 나누는 병렬성”은 목적이 다릅니다.

헷갈리기 쉬운 두 말
동시성과 병렬성
동시성은 여러 일이 진행되도록 구조를 짜는 관점입니다. 화면이 입력을 받으면서 계산을 기다리는 상황이 예입니다. 병렬성은 실제로 여러 계산을 함께 수행하는 관점입니다. 여러 CPU 코어에서 다른 레이어의 경로를 계산하는 상황이 예입니다.

4-6. 설계 ④ 데이터 중심 설정과 검증 가능한 캐시

PrintConfig.cpp는 옵션의 타입·범위·설명·기본값을 정의하고, PresetBundle.cpp는 제조사와 프리셋 데이터를 읽어 조합합니다. PresetBundle::load_vendor_configs_from_json()은 이름과 달리 현재 소스에서 read_vendor()와 install_vendor_read()를 거치며 캐시 경로도 처리합니다.

read_vendor()는 조건에 따라 VendorCacheFile::load()를 시도하고, 채택되지 않으면 parse_vendor_json()으로 진행합니다. 검증 모드에서는 캐시를 사용하지 않고 JSON을 읽습니다. 다만 JSON이 제거된 배포 형태라면 캐시 손상을 JSON 재해석만으로 복구할 수는 없습니다.

검사실제 구현지키려는 성질
파일 형식CACHE_MAGIC = 0x4F52435A다른 파일을 캐시로 오해하지 않기.
본문 길이read_cache_blob()에서 실제 파일 길이와 비교잘린 파일과 잘못된 크기 필드 거부.
손상 검사본문의 CRC32 비교저장·전송 중 데이터 손상 탐지. 디지털 서명과는 다릅니다.
형식·제조사CACHE_VERSION = 2, read_cache_stamps()버전과 제조사 이름이 맞는 데이터만 채택.
설정 사전CacheDictionary설정 이름과 타입을 이용해 현재 설정 정의에 대응.

상세 설계 문서 docs/HLSD/preset-cache.md는 상속 결과를 모두 굳혀 저장하기보다, 원래 설정의 차이와 부모 이름을 보관하고 로딩 때 상속을 해결한다고 설명합니다. 선언 순서 번호만 저장하면 설정 하나를 끼워 넣었을 때 뒤 번호가 밀릴 수 있기 때문에, 이름으로 해석하는 사전이 의미를 갖습니다.

커밋 제목은 프리셋 캐시를 배포할 때 제조사 데이터 파일을 보존하는 수정입니다. 실제 scripts/build_preset_cache.sh의 listed_presets()는 제조사 목록의 sub_path를 모으고, 패키징 대상에서는 캐시가 생성된 제조사의 목록 JSON과 그 목록에 나열된 프리셋 파일을 제거합니다. 옆에 있는 색상표·별도 설정·이미지까지 지우지 않도록 구분하는 규칙이 코드에 보입니다.

설계에서 가져갈 것
속도 최적화에도 데이터의 의미가 먼저입니다

캐시를 빨리 읽는 일과 올바른 값을 읽는 일은 함께 설계해야 합니다. 버전, 무결성, 이름 기반 해석, 원본이 있을 때의 재해석 경로가 모여 하나의 최적화를 제품 기능으로 만듭니다.

5디렉토리 구조 해부

파일 수보다 책임의 경계를 먼저 찾으세요
OrcaSlicer/ ├── CMakeLists.txt 앱 전체 빌드와 의존성 탐색 ├── version.inc 앱 이름·개발 버전 정보 ├── src/ │ ├── OrcaSlicer.cpp 명령행·GUI 진입 분기 │ ├── libslic3r/ 모델·설정·기하·슬라이싱 엔진 │ │ ├── Print.cpp 출력 작업의 단계 실행 │ │ ├── PrintApply.cpp 변경된 모델·설정 반영 │ │ ├── PrintObject.cpp 오브젝트별 경로 생성·무효화 │ │ ├── Fill/ 채움 패턴 구현 │ │ ├── Support/ 지지대 관련 계산 │ │ ├── GCode/ G-code 처리와 분석 │ │ ├── Format/ 모델·프로젝트 파일 형식 │ │ ├── Arachne/ 가변 폭 벽 경로 관련 구현 │ │ └── CAD/ 개발 소스의 CAD 모델 처리 │ └── slic3r/ │ ├── GUI/ 창·설정·3D 화면·백그라운드 작업 │ ├── Utils/ 출력 호스트 등 제품 연결 기능 │ └── plugin/ Python 실행·플러그인 연결 ├── resources/ │ ├── profiles/ 제조사·장비·재료·출력 프리셋 │ ├── web/ 내장 웹 화면과 리소스 │ └── fonts/ 포함된 글꼴 ├── deps/ 외부 의존성 다운로드·빌드 정의 ├── deps_src/ 저장소에 포함된 외부 소스 ├── tests/ 기능별 테스트와 테스트 데이터 ├── localization/ 번역 카탈로그와 추출 목록 ├── docs/HLSD/ 하위 시스템 설계 문서 ├── scripts/ 빌드 보조·프로필·패키징 도구 ├── sandboxes/ 개별 알고리즘 실험 코드 └── .github/workflows/ 빌드·검사·배포 자동화

5-1. 목적에 따라 들어갈 문을 고릅니다

알고 싶은 것시작할 곳그다음 확인
설정 하나의 의미PrintConfig.cpp프로필 JSON과 PrintObject.cpp의 무효화 분기.
채움 무늬Fill/FillBase.cpp선택된 클래스와 Fill.cpp의 호출부.
창이 멈추는 문제BackgroundSlicingProcess.cpp작업 상태·취소·GUI 이벤트의 왕복.
새 장비 설정resources/profiles/제조사 목록·상속·버전과 호스트 연결 구현.
호환성 보장tests/, docs/HLSD/저장 형식의 버전과 과거 데이터 표본.

5-2. 줄 수로 본 크기: 직접 센 물리적 줄 수

아래는 커밋 022769c8의 파일을 확장자별로 읽어 센 결과입니다. 빈 줄·주석·헤더·포함된 외부 코드를 포함하고 .git은 제외했습니다. 마지막 줄에 개행이 없어도 한 줄로 계산했습니다. 중복 코드나 실제 실행 코드만 가려낸 수치는 아닙니다.

분류파일 수대략적인 줄 수
C/C++·헤더3,7941,589,593줄
Python4325,462줄
JavaScript5216,467줄
TypeScript2490줄
HTML7322,273줄
CSS417,984줄
셸 스크립트355,257줄
CMake13413,950줄

C/C++·헤더는 .c .cc .cpp .cxx .h .hh .hpp .hxx .ipp .inl을 묶었습니다. 셸은 .sh .bash, CMake는 .cmake와 CMakeLists.txt입니다. HTML에는 .html과 .htm을 함께 집계했습니다. Objective-C 계열, JSON·번역·문서 등은 이 표에 포함하지 않았으므로 표의 합이 저장소 전체 줄 수는 아닙니다.

C/C++ 묶음 안에서도 앱의 src/는 894,137줄, deps_src/는 462,355줄, deps/는 79,422줄, tests/는 152,429줄, sandboxes/는 1,250줄입니다. 테스트 폴더에는 Catch2 소스도 들어 있으므로 이 숫자로 자체 테스트 비중을 계산하면 왜곡됩니다.

resources/profiles/ 아래 JSON은 14,408개입니다. 이 수는 장비 대수가 아니라 제조사 목록·기본 설정·파생 프리셋·보조 데이터 등을 포함한 파일 수입니다. 프리셋 캐시가 왜 별도 하위 시스템으로 발전했는지 이해할 단서가 됩니다.

6학습 포인트 (기술별)

큰 저장소를 기술 수업 여섯 개로 나누어 읽기

6-1. C++: 누가 객체를 소유하는지 따라가기

Fill::new_from_type()과 호출부의 std::unique_ptr<Fill>를 함께 읽으세요. 생성·사용·파괴를 한 함수 안에서만 찾으면 객체의 수명이 보이지 않습니다. 기반 클래스의 가상 소멸자와 호출부의 소유권을 연결해야 구체 구현이 올바르게 정리되는 이유를 이해할 수 있습니다.

PrintState의 std::scoped_lock<std::mutex>도 같은 관점입니다. 자원을 메모리에 한정하지 않고 잠금까지 확장해 보면 RAII가 제품 코드 전반에 쓰이는 방식이 보입니다.

읽기 실습

객체 수명 지도 한 장 그리기

FillGyroid가 어디서 만들어지고 어떤 포인터에 담기는지 적습니다. 이어서 FillBase.hpp의 가상 소멸자를 찾고, 반환 이후 예외가 나도 소유 객체가 정리되는 이유를 설명해 보세요.

6-2. 계산기하: 형상과 경로의 차이 이해하기

메시는 입체 표면을 삼각형으로 표현합니다. 단면은 평면의 다각형이며, 출력 경로는 노즐 중심이 움직일 선입니다. 바깥 윤곽 그대로 노즐을 움직이면 선의 폭 때문에 원하는 치수와 달라질 수 있습니다. 윤곽을 안팎으로 이동하는 오프셋 연산이 필요한 이유입니다.

src/libslic3r/ClipperUtils.hpp와 ClipperUtils.cpp는 내부 다각형 타입과 Clipper2 사이의 접점을 제공합니다. 합집합·교집합·차집합·오프셋이 벽과 채움 영역 계산의 공통 도구가 됩니다.

기하 입문
오프셋과 구멍의 방향
오프셋은 테두리에서 일정 거리 떨어진 새 테두리를 만드는 연산입니다. 바깥 경계와 내부 구멍을 구분해야 같은 거리의 이동이 물체를 키우는지 줄이는지 결정할 수 있습니다. 좌표 목록만 보고 비교하기보다 방향과 면적도 함께 봐야 합니다.

tests/libslic3r/test_clipper_utils.cpp의 첫 시나리오는 사각형 안에 구멍을 둔 뒤 오프셋 결과를 확인합니다. 보조 함수 start_at_min()으로 다각형 시작 꼭짓점을 정규화하는 점도 좋습니다. 같은 테두리라도 어느 꼭짓점부터 나열했느냐는 달라질 수 있기 때문입니다.

작은 실습으로 종이에 사각형과 구멍을 그리고 각각 1칸씩 오프셋해 보세요. 두 다각형의 정점 배열이 다르다는 이유만으로 형상이 다르다고 판단하면 안 되는 사례를 직접 만들 수 있습니다.

6-3. 수치 표현: 단위와 정밀도는 따로 생각하기

src/libslic3r/libslic3r.h의 활성 분기에서 coord_t는 int64_t입니다. SCALING_FACTOR_INTERNAL은 0.000001, 큰 프린터용 상수는 0.00001입니다. libslic3r.cpp에서 전역 배율은 기본 상수로 초기화됩니다.

# 기본 배율에서 단위를 이해하기 위한 계산
내부 좌표 = mm 좌표 / 0.000001
1 mm      = 내부 좌표 1,000,000
20 mm     = 내부 좌표 20,000,000

# 저장 단위가 작다고 실제 출력 정밀도가 그만큼 높아지지는 않습니다.

정수 격자는 좌표 표현을 일정하게 만들지만, 모든 기하 연산이 무한히 정확해지는 것은 아닙니다. docs/HLSD/polygon-clipping.md는 Clipper2의 일부 교점·기울기 계산에 부동소수점이 쓰인다는 점과 좌표 범위를 설명합니다. 실습에서는 mm와 내부 단위를 섞었을 때 100만 배 오류가 어디서 생기는지 적어 보세요.

6-4. 설정 시스템: 스키마의 기본값과 사용자 값 구분하기

PrintConfig.cpp에서 sparse_infill_density는 coPercent, 범위 0~100, 기본값 20입니다. wall_loops는 coInt, 범위 0~1000, 기본값 2입니다. 하지만 이는 옵션 정의의 기본값이지, 모든 프리셋을 선택했을 때 화면에 나타나는 값은 아닙니다.

// resources/profiles/Vzbot/process/0.20mm Standard @Vzbot.json
{
  "type": "process",
  "name": "0.20mm Standard @Vzbot",
  "inherits": "fdm_process_Vzbot_common",
  "from": "system",
  "setting_id": "aufrk8Rt9qtJksVX",
  "instantiation": "true",
  "layer_height": "0.2",
  "bottom_shell_layers": "3",
  "top_shell_layers": "4"
}

이 프리셋의 부모 resources/profiles/Vzbot/process/fdm_process_Vzbot_common.json은 wall_loops를 "3", sparse_infill_density를 "15%"로 지정합니다. 부모의 top_shell_layers는 3이지만 자식은 4로 덮어씁니다. 또한 JSON에서는 많은 값이 문자열로 저장되므로 파일 표기와 엔진 내부 타입을 구분해야 합니다.

설정 상속 비유

공통 레시피가 “설탕 20g”이라고 적혀 있어도, 특정 빵의 레시피가 15g으로 고치면 실제 사용량은 달라집니다. 옵션 정의는 항목의 뜻과 기본값을, 프리셋 상속은 특정 조건에서의 선택을 나타냅니다.

설정을 이해하려면 이름과 기본값만 읽지 말고, 누가 덮어쓰고 어느 계산을 다시 시작시키는지까지 따라가야 합니다.

6-5. 병렬 처리: 쓰는 데이터와 읽는 데이터를 구분하기

PrintObject::infill()의 람다는 this를 캡처하고 여러 레이어를 처리합니다. 범위가 나뉜다는 사실만으로 모든 공유 데이터가 안전해지는 것은 아닙니다. 각 작업이 쓰는 레이어와 함께 참조하는 자료구조를 구분해야 합니다.

실습으로 함수 안의 값을 “레이어별 결과”, “공유해서 읽는 입력”, “취소·진행 상태”로 나눠 보세요. throw_if_canceled()가 반복 안과 완료 전에도 호출되는 이유를 설명하면, 빠른 완료 외에 취소 반응성이라는 목표가 있음을 이해하게 됩니다.

6-6. 테스트·저장 형식: 미래의 변경을 견디는 방법

tests/fff_print/test_print.cpp는 G-code 생성 등 출력 관련 동작을, tests/libslic3r/test_vendor_cache.cpp는 제조사 캐시를 다룹니다. 캐시 테스트의 TempDir은 생성자에서 임시 디렉토리를 만들고 소멸자에서 정리합니다. 테스트도 C++ 자원 수명 관리의 학습 자료입니다.

docs/HLSD/design-tab.md는 CAD 레시피의 과거 버전 표본을 이용한 호환성 검사를 설명합니다. 같은 버전에서 저장하고 다시 읽는 왕복 검사만으로는, 저장·읽기 구현이 함께 잘못 바뀐 문제를 놓칠 수 있습니다. 과거 프로그램이 만든 고정 표본을 읽는 검사가 필요한 이유입니다.

실습 아이디어
코드가 아니라 성질을 먼저 적습니다

예를 들어 “손상된 캐시는 거부된다”, “채움 패턴을 바꾸면 채움 준비 결과가 무효화된다”, “구멍을 포함한 오프셋은 올바른 영역을 만든다”처럼 검증하고 싶은 동작을 문장으로 써 보세요. 그 문장을 어떤 입력과 관찰 결과로 확인할지 연결하는 것이 테스트 설계입니다.

7하드웨어 / 시스템 요구사항

앱을 사용하는 조건과 직접 빌드하는 조건은 다릅니다

소스와 README에 명시된 조건은 아래와 같습니다. 아래의 RAM·디스크 수치는 빌드 전 검사값이므로 앱 실행 최소 사양과 구분해야 합니다.

항목확인되는 사실읽을 때의 주의점
운영체제README는 Windows·macOS·Linux 설치를 안내합니다.배포 파일의 대상 아키텍처를 구분합니다.
CPU 아키텍처CI에 Windows x64·arm64, Linux x86_64·aarch64, macOS 아키텍처별 빌드가 있습니다.개발 CI 구성과 과거 안정 배포 파일 목록은 같다고 단정하지 않습니다.
macOS 대상루트 CMake의 기본 CMAKE_OSX_DEPLOYMENT_TARGET은 12.0입니다.직접 지정하면 달라질 수 있는 빌드 기본값입니다.
Linux 화면GUI 진입 때 DISPLAY 또는 WAYLAND_DISPLAY를 확인합니다.화면이 없는 환경의 GUI 실행과 CLI 작업을 구분합니다.
그래픽OpenGL을 사용하는 3D 화면과 초기화 검사가 있습니다.검사 조건과 메시지의 버전 차이를 아래에서 설명합니다.
Linux 빌드 RAMbuild_linux.sh의 기본 검사는 가용 메모리를 GiB 정수로 읽어 10 이하이면 거부합니다.설치된 총 RAM이 아닌 빌드 전 가용량 검사입니다. -r 옵션으로 생략할 수 있습니다.
Linux 빌드 디스크기본 검사에서 남은 공간이 10 * 1024 * 1024 KiB 이하이면 거부합니다.10 GiB 경계 검사입니다. -r 옵션으로 생략할 수 있으며 최종 빌드의 총 필요량 보장은 아닙니다.
프린터·인터넷코드 읽기와 로컬 형상·경로 학습에는 물리 프린터가 필요 없습니다.장비 연결·업데이트·다운로드는 별도의 네트워크 기능입니다.

7-1. 오류 문구 하나만 믿으면 생기는 오해

src/slic3r/GUI/OpenGLManager.cpp의 해당 초기화 분기는 is_version_greater_or_equal_to(2, 0)으로 검사합니다. 그런데 실패 시 표시할 문장은 OpenGL 3.2보다 낮다고 안내합니다. 검사식과 사용자 문구가 서로 다릅니다.

따라서 이 분기 하나만 보고 앱 전체가 모든 OpenGL 2.0 장치에서 정상 동작한다고 보장해서도, 안내 문장만 보고 그 검사가 정확히 3.2를 요구한다고 설명해서도 안 됩니다. 실제 배포본과 드라이버의 조합은 따로 확인해야 합니다.

7-2. 공부를 시작할 때의 현실적인 선택

코드 탐색은 일반 개발용 PC와 편집기로 시작할 수 있습니다. 직접 빌드를 계획한다면 여유 있는 멀티코어 CPU, SSD, 32GB급 RAM을 학습용 권장 환경으로 고려할 만합니다. 이 수치는 공식 최소 사양이나 측정 결과가 아니라, 의존성과 병렬 컴파일의 여유를 위한 제안입니다.

우선 작은 단일 모델로 학습하고, 레이어 높이·삼각형 수·오브젝트 수를 한 번에 하나씩 늘려 관찰하세요. 대략 20mm 높이를 0.2mm 층으로 나누면 100층, 0.1mm면 200층입니다. 실제 층 수는 첫 층 설정과 형상 등에 따라 달라지고 실행 시간도 단순히 두 배가 되는 것은 아닙니다.

요구사항을 읽을 때는 사용자 실행 조건, 빌드 도구의 검사값, 학습용 권장 환경을 서로 구분해야 합니다.

적용 범위
물리 프린터의 조건은 소프트웨어 조건과 별개입니다

노즐 지름·출력 영역·온도·펌웨어가 맞지 않으면 파일이 만들어져도 올바른 출력은 보장되지 않습니다. 처음에는 경로 검토까지 진행하고, 실제 출력은 사용하는 장비에 맞는 프리셋과 절차를 확인한 뒤 진행하세요.

8직접 해볼 수 있는 실습 과제

읽기에서 설계 검증으로 이어지는 다섯 과제

다음 과제는 프린터 없이 시작할 수 있습니다. 소스 검색 명령은 저장소 루트에서 읽기만 수행하는 예입니다. 구현·빌드가 필요한 확장은 별도 연습용 사본에서 진행하고, 처음에는 분석 결과물부터 완성해 보세요.

과제 1 · 입문

프리셋의 실제 값 복원하기 입문

질문: 0.20mm Standard @Vzbot의 벽 개수·채움 밀도·상단 층 수는 어디서 오는가?

  1. PrintConfig.cpp에서 세 옵션의 타입과 기본값을 찾습니다.
  2. 자식 JSON의 inherits를 따라 부모와 공통 조상 파일을 읽습니다.
  3. 기본값·부모값·자식값을 표로 나눕니다. 값이 없는 칸은 빈칸으로 둡니다.

결과물: 옵션 세 개의 출처 표. 완료 기준: 왜 벽 3개, 채움 15%, 상단 4층으로 읽히는지 각 파일을 가리키며 설명합니다.

# 저장소 루트에서 실행하는 읽기 전용 검색
rg -n 'wall_loops|sparse_infill_density|top_shell_layers' \
  src/libslic3r/PrintConfig.cpp resources/profiles/Vzbot/process

# 이름에 공백이 있으므로 경로 전체를 따옴표로 감쌉니다.
cat 'resources/profiles/Vzbot/process/0.20mm Standard @Vzbot.json'
과제 2 · 입문

채움 패턴 한 개의 연결 고리 찾기 입문

질문: 화면에서 선택한 자이로이드 패턴은 어떤 C++ 객체로 계산되는가?

  1. ipGyroid, FillGyroid, new_from_type을 검색합니다.
  2. FillBase.hpp의 공통 인터페이스와 FillGyroid.cpp의 구현을 연결합니다.
  3. Fill.cpp에서 생성된 객체가 어떻게 소유되고 사용되는지 적습니다.

결과물: 설정값 → 팩터리 → 구현 → 호출부의 네 칸 그림. 완료 기준: 객체 생성과 알고리즘 실행이 각각 어디에서 일어나는지 구분합니다.

rg -n 'ipGyroid|FillGyroid|new_from_type' src/libslic3r/Fill
rg -n 'gyroid' src/libslic3r/PrintConfig.cpp
과제 3 · 중급

설정 변경의 재계산 범위 비교하기 중급

질문: 밀도를 15%→20%로 바꾸는 경우와 0%→20%로 바꾸는 경우는 무엇이 다른가?

  1. PrintObject::invalidate_state_by_config_options()의 밀도 분기를 읽습니다.
  2. 두 경우 각각 steps에 추가되는 단계를 적습니다.
  3. invalidate_step() 관련 구현에서 뒤 단계로의 전파를 찾습니다.
  4. 별도 연습 환경에서는 이 동작을 검증하는 회귀 테스트의 입력과 관찰값을 설계합니다.

결과물: 변경 전후 값·출발 단계·전파 단계 표. 완료 기준: 0% 경계를 일반적인 밀도 조정과 다르게 다루는 이유를 코드 분기와 연결합니다.

과제 4 · 중급

사각형과 구멍으로 기하 테스트 설계하기 중급

질문: 같은 다각형을 다른 정점부터 나열해도 같은 형상이라고 확인할 수 있는가?

  1. test_clipper_utils.cpp의 square_with_hole 사례를 읽습니다.
  2. 바깥 사각형과 안쪽 구멍의 방향·면적·오프셋 후 변화를 종이에 계산합니다.
  3. 정점 시작점을 회전한 입력에서도 유지되어야 할 성질 세 개를 적습니다.

결과물: 좌표 그림과 검증 조건. 완료 기준: 배열의 시작 위치 같은 표현 차이와 실제 영역의 차이를 구분합니다. 구현으로 확장한다면 핵심 라이브러리 테스트인 tests/libslic3r/가 자연스러운 위치입니다.

과제 5 · 고급

제조사 캐시의 실패 경로 검토하기 고급

질문: 캐시가 빠르면서도 잘못된 설정을 조용히 적용하지 않게 하려면 무엇을 검사해야 하는가?

  1. PresetCacheFormat.cpp의 매직·길이·CRC·형식 버전 검사를 순서대로 적습니다.
  2. 파일 잘림, 본문 변조, 다른 제조사, 새 형식 버전이라는 네 입력을 가정합니다.
  3. read_vendor()가 실패 뒤 어디로 가는지, JSON이 남아 있는 경우와 없는 경우를 나눕니다.
  4. tests/libslic3r/test_vendor_cache.cpp에서 관련 검사와 테스트용 데이터 생성 방식을 찾습니다.

결과물: 네 실패 입력에 대한 기대 동작 표와 복구 경로 그림. 완료 기준: 거부·원본 재해석·재설치가 필요한 상황을 구분하고, CRC를 인증으로 설명하지 않습니다.

실습의 완료 기준은 파일을 많이 읽는 것이 아니라, 입력 하나가 결과와 재계산 범위에 미치는 영향을 설명하는 것입니다.

9관련 기술 심화 학습 로드맵

6주 동안 한 가지 입력을 끝까지 따라가 보는 순서

다음은 C++ 기초 문법을 조금 아는 독자를 위한 학습 제안입니다. 처음부터 전체 빌드를 성공시키는 일을 목표로 삼기보다, 작은 설정 하나와 단순한 형상을 반복해서 사용하세요. 각 주의 결과물을 다음 주에 연결하면 지식이 따로 흩어지지 않습니다.

주차배울 내용과 읽을 곳남길 결과물
1주차C++ 클래스·열거형·가상 함수·스마트 포인터. FillBase.hpp와 팩터리 호출부를 읽습니다.FillGyroid의 생성·호출·파괴 흐름도.
2주차설정 타입과 상속. PrintConfig.cpp, Vzbot 프리셋, PresetBundle.cpp를 연결합니다.옵션 세 개의 타입·기본값·최종 출처 표.
3주차벡터·다각형·오프셋·좌표 단위. ClipperUtils와 작은 테스트를 읽습니다.구멍이 있는 형상의 오프셋 그림과 성질 세 개.
4주차단계 상태와 무효화. PrintApply.cpp, PrintObject.cpp, PrintBase.hpp를 읽습니다.레이어 높이·벽 개수·채움 밀도의 재계산 비교표.
5주차뮤텍스·조건변수·GUI 이벤트·TBB. BackgroundSlicingProcess.cpp와 infill()을 읽습니다.시작·완료·취소 시의 두 스레드 시간 흐름도.
6주차직렬화·캐시·CI·호환성. PresetCacheFormat.cpp, 캐시 테스트, 워크플로를 읽습니다.실패 입력별 기대 동작과 테스트 계획 한 장.

9-1. 기초가 부족하면 앞에 한 단계를 더 둡니다

C++가 처음이라면 참조와 포인터, const, 컨테이너, 생성자·소멸자, 예외를 먼저 익히세요. 수학은 2D 좌표·벡터·선분·넓이부터 시작하면 됩니다. 자이로이드의 수식이나 복잡한 지지대 알고리즘을 첫 관문으로 삼을 필요는 없습니다.

처음에는 “이 함수가 무슨 일을 하나”를 적고, 익숙해지면 “이 함수가 어떤 전제에 기대나”를 적으세요. 예를 들어 레이어 수가 0일 때, 취소가 들어왔을 때, 설정 타입이 바뀌었을 때의 행동을 묻는 식입니다.

9-2. 이후에는 관심 분야를 하나 선택합니다

한 기능을 입력·설정·계산·저장·검증까지 연결해 읽는 경험이, 디렉토리 전체를 훑는 것보다 오래 남습니다.

10핵심 키워드 사전

코드와 3D 출력 용어를 한 문장으로 다시 보기
용어쉬운 설명
슬라이서입체 형상과 설정에서 층별 출력 경로와 프린터 명령을 만드는 프로그램입니다.
FFF / FDM가열한 재료를 노즐로 내보내 층층이 쌓는 방식입니다. 이 글의 파이프라인 설명 범위입니다.
메시물체의 표면을 작은 면들로 표현한 데이터입니다. 삼각형 메시가 대표적입니다.
STL주로 삼각형 표면 형상을 전달하는 파일 형식입니다. 완전한 출력 프로젝트와는 다릅니다.
3MF형상과 관련 정보를 담는 형식입니다. Orca 프로젝트에는 설정과 확장 데이터도 포함될 수 있습니다.
G-code이동·압출·온도 등 프린터 동작을 표현하는 명령입니다. 펌웨어별 차이가 있습니다.
레이어 높이한 층의 두께입니다. 값이 작아지면 같은 높이에 필요한 층 수가 늘어납니다.
퍼리미터 / 벽물체의 외곽이나 구멍을 따라 만드는 벽 경로입니다.
인필 / 채움내부 영역을 지지하고 강도를 만드는 경로입니다. 패턴과 밀도를 조절합니다.
지지대아래가 비어 있는 형상을 받치기 위해 추가하는 구조입니다.
브리지양쪽 지지점 사이의 빈 공간을 건너 출력하는 구간입니다.
브림첫 층 주변에 넓게 덧붙여 바닥 접착을 돕는 경로입니다.
이음매닫힌 벽 경로의 시작·끝이 만나는 자리입니다. 표면 흔적과 관련됩니다.
프리셋프린터·재료·출력 조건에 맞게 저장한 설정 묶음입니다.
스키마설정 항목의 이름·타입·범위·기본값 등 구조를 정의한 규칙입니다.
상속공통 설정을 가져오고 차이가 나는 값만 덮어쓰는 방식입니다.
오프셋테두리를 일정 거리 안쪽이나 바깥쪽으로 이동해 새 경계를 만드는 연산입니다.
정수 좌표정해진 작은 단위의 정수로 위치를 표현하는 방식입니다. 물리 출력 정밀도와 같지는 않습니다.
팩터리설정이나 조건을 보고 사용할 구체 객체를 만들어 주는 코드입니다.
전략 패턴같은 역할의 여러 알고리즘을 공통 인터페이스 뒤에서 바꿔 쓰는 설계입니다.
RAII객체 수명에 메모리·파일·잠금 같은 자원의 획득과 해제를 연결하는 C++ 기법입니다.
무효화입력이 바뀌어 기존 계산 결과를 더 이상 재사용하면 안 된다고 표시하는 일입니다.
뮤텍스여러 스레드가 같은 상태를 동시에 바꾸지 않도록 접근을 조절하는 잠금입니다.
조건변수스레드가 조건이 충족될 때까지 기다리고, 요청이 오면 깨어나게 하는 도구입니다.
TBB작업을 나누어 여러 CPU 코어에서 수행하도록 돕는 병렬 처리 라이브러리입니다.
직렬화객체의 데이터를 파일에 저장하거나 전달할 수 있는 바이트 형태로 바꾸는 일입니다.
CRC32바이트가 손상됐는지 확인하는 검사값입니다. 작성자의 신원을 증명하는 서명은 아닙니다.
회귀 테스트수정 후 예전에 맞던 동작이 다시 깨지지 않았는지 확인하는 검사입니다.
고정 표본과거 형식의 저장 파일처럼 변하지 않는 입력을 두고 새 구현의 호환성을 확인하는 자료입니다.
CI코드 변경에 맞춰 빌드·검사·산출물 생성을 자동으로 수행하는 환경입니다.
AGPL-3.0이 프로젝트의 주 라이선스입니다. 구체적인 조건은 원문과 포함된 구성요소의 고지를 확인합니다.

11참고 링크

공식 안내와, 같은 커밋에서 다시 읽을 소스

11-1. 공식 저장소와 사용자 문서

11-2. 코드 설명의 기준점

11-3. 관련 기술의 공식 학습 자료

기술 문서의 최신판은 여기서 인용한 의존성 버전과 다를 수 있습니다. API를 실제로 적용할 때는 저장소가 고정한 버전과 포함된 패치도 함께 확인하세요.

현재 상태 (2026-10-23 기준)

항목확인 값과 범위
저장소OrcaSlicer/OrcaSlicer · 주 언어 C++.
트렌딩GitHub Trending C++ Weekly #7 · 2026-10-23 분석 기준.
스타 / 포크16,087 / 3,303 · 2026-10-23 GitHub 기준.
생성일2022-07-16 · 저장소 생성일이며 모든 코드의 개발 시작일은 아닙니다.
최신 릴리스v2.4.2 · 2026-07-07 · 2026-10-23 GitHub 기준.
개발 소스 버전version.inc의 SoftFever_VERSION은 2.5.0-dev.
최근 push2026-10-23 · GitHub 기준.
최근 커밋022769c8 · 2026-10-23 · fix: keep vendor data files when shipping preset caches (#16706)
프리셋 캐시 배포 시 제조사 데이터 파일을 보존하는 수정.
코드 규모C/C++·헤더 1,589,593줄 / 3,794개 파일. 이 중 앱 src/ 894,137줄. 집계 범위는 5절 참조.
설정 데이터resources/profiles/ JSON 14,408개. 장비 대수와는 다릅니다.
라이선스AGPL-3.0. 외부 구성요소에는 별도 고지가 있습니다. README는 Bambu 네트워킹 플러그인을 선택적인 비자유 라이브러리 기반 구성요소로 설명합니다.
쓰기 전에 알아둘 한계
개발 소스의 존재와 배포 제품의 보장은 다릅니다

코드 분석 범위는 커밋 022769c8이며, 안정 릴리스 v2.4.2와 차이가 있습니다. CAD·Python 플러그인 등 개발 소스의 구성을 안정 버전의 확정 기능으로 읽지 마세요.

속도·메모리·출력 품질은 실행 측정으로 검증한 값이 아닙니다. 트렌딩 유입 원인과 경쟁 제품 대비 우위도 동일 조건의 비교 실험으로 확인되지 않았습니다.

프로필 존재는 모든 장비·재료 조합의 검증을 뜻하지 않습니다. G-code 예시는 문법 학습용입니다. 실제 사용 전에는 배포 버전, 프리셋, 펌웨어, 장비 조건을 맞추어 확인하세요.

코드를 다른 제품에 활용할 때는 LICENSE.txt와 구성요소별 라이선스 고지를 읽어야 합니다. README의 짧은 라이선스 요약은 원문의 조건 전체를 대신하지 않습니다.