Skip to content

Onboard

core.OnboardHandler

CAD 부품을 하나씩 온보딩해 부품별 산출물을 반환하는 public handler class.

부품마다 식별 template 과 정합/편차용 기하 캐시를 항상 함께 계산해 PartRecord 로 반환. handler 는 부품 간 상태가 없어 같은 입력이면 호출 순서와 무관하게 같은 산출. 입력은 CAD 파일 경로 하나이고 부품 식별자는 받지 않음. 산출물 보관, 부품 식별자 부여, 카탈로그 구성(CatalogEntry·CatalogData)은 호출자 담당.

모든 public 메서드는 (code, message, value) 튜플을 반환. code 는 성공 시 0, 실패 시 음수 6자리 정수이고 실패한 호출의 value 는 None. 메서드별 Raises 의 오류는 예외로 전파되지 않고 code 로 반환되며, code 절댓값의 끝 세 자리가 오류 종류. 실패한 호출의 message 는 첫 줄이 오류 종류별 고정 문구이고 상세 사유가 있으면 다음 줄에 이어짐. CUDA 메모리 부족과 numpy 배열 할당 실패는 SaigeToolkit 공통 오류 번호로 반환되고, 그 밖의 종류별 번호는 다음과 같음.

  • 001: ConfigError
  • 003: CheckpointNotExistError
  • 006: DataFormatError
  • 019: WeightBundleCorruptError
  • 025: DegenerateGeometryError
  • 999: 위 종류에 속하지 않는 예외 (message 는 Unknown error).
Usage
from core import OnboardHandler
from core.data.catalog.catalog_data import CatalogData, CatalogEntry

err, msg, handler = OnboardHandler.build({"device": "cuda:0"})
parts = []
for part_id, cad_path in cad_paths.items():  # 부품 식별자는 호출자가 부여
    err, msg, record = handler.onboard(cad_path)
    if err < 0:
        continue  # 부분 실패: 해당 부품만 스킵
    parts.append(CatalogEntry(part_id=part_id, record=record))
catalog = CatalogData(catalog_id="v0001", parts=parts)

build(config) classmethod

config로부터 OnboardHandler instance를 생성.

허용 key 는 아래 둘뿐이며 그 밖의 key 가 포함되면 ConfigError 로 거절. render·cropper·feature_extractor·geometry 구성은 core 기본값으로 고정되고 공개면에 노출하지 않음.

Parameters:

Name Type Description Default
config dict[str, Any]

build config. 허용 key 는 다음과 같음.

{
    "device": str,          # 선택. 연산 device. (default "cuda:0")
    "enable_timer": bool,   # 선택. 단계별 시간 측정 여부. bool 이 아닌 값은 거절. (default False)
}

required

Returns:

Type Description
OnboardHandler

build가 완료된 instance.

Raises:

Type Description
ConfigError

허용 밖의 key가 있거나 enable_timer 가 bool 이 아닌 경우.

CheckpointNotExistError

feature extractor weight 번들이 존재하지 않는 경우.

WeightBundleCorruptError

feature extractor weight 번들이 손상되어 읽을 수 없는 경우.

Usage
err, msg, handler = OnboardHandler.build({"device": "cuda:0", "enable_timer": True})

onboard(path)

CAD 부품 하나를 온보딩해 식별 template·기하 캐시·썸네일을 PartRecord 로 반환.

부품 하나만으로 계산을 마치므로 이전 호출의 영향이 없음. 부품 식별자는 받지 않고 호출자가 CatalogEntry 로 부여하며, 식별자 형식·중복 검사와 부품 간 구성 일치 검사는 CatalogEntry·CatalogData 생성 시점에 수행.

진입부에서 validate 와 같은 형상 규칙을 수행하고, 위반이면 렌더·특징 추출을 시작하기 전에 거절. 사전 판정 없이 등록만 수행하는 호출자에게도 같은 규칙을 적용.

Parameters:

Name Type Description Default
path str

CAD/mesh 파일 경로. 확장자로 loader 추론 (.ply/.stl/.obj/.stp/.step).

required

Returns:

Type Description
PartRecord

부품 하나의 온보딩 산출물. dataclass 이며 필드는 attribute 로 접근. 필드 구조는 다음과 같음.

  • features_q8 (np.ndarray): shape (V, D) int8 뷰별 CLS feature 코드.
  • features_scale (np.ndarray): shape (V, 1) f16 행별 scale. 복원은 codes * scale.
  • geometry (PartGeometry): 정합·편차 계산용 기하 캐시. InferenceHandler.inspect_scan 의 part_geometry 로 그대로 전달. 필드는 계측 mesh 의 mesh_vertices (f32, mm)·mesh_faces (i32), 정합용 표본의 reg_points (f32, mm)·reg_normals (f32), SE(3) 불변 특징 invariants (dict[str, float]), 편차 부호 신뢰 근거인 watertight (bool).
  • thumbnails (list[np.ndarray]): 뷰별 렌더 원본 RGB uint8 (H, W, 3), features_q8 행 순서. 항상 V 장.
  • config_digest (str): 온보딩 구성의 digest. InferenceHandler.set_catalog 가 추론 쪽 구성과 대조하는 값.

Raises:

Type Description
DataFormatError

path 가 문자열이 아니거나, 지원하지 않는 확장자이거나, 파일을 읽지 못했거나, mesh에 정점이 없는 경우.

DegenerateGeometryError

형상 규칙을 어겼거나, 렌더·기하 단계가 이 mesh 로 값을 산출하지 못한 경우. 메시지에 CAD 경로와 위반 규칙 이름·사유 표기. 부품별 위반 사유는 validate 로 등록 전에 확인 가능.

Usage
err, msg, record = handler.onboard("/cad/bracket.stp")
catalog = CatalogData(catalog_id="v0001", parts=[CatalogEntry(part_id=1024, record=record)])

get_time()

직전 onboard 의 단계별 누적 소요 시간(ms)을 반환.

Returns:

Type Description
dict[str, float] | None

단계별 누적 시간(ms). render_time·crop_time·extract_time· geometry_load_time·geometry_sample_time·geometry_invariant_time. enable_timer=False 면 None.

validate(path)

부품 하나가 온보딩 가능한 형상인지 미리 판정해 실패 사유를 반환 (등록하지 않음).

규칙은 onboard 진입부가 수행하는 것과 같은 본체이며, 판정 결과의 전달 방식만 다름. 이 메서드는 보고를 반환하고 onboard 는 위반 시 DegenerateGeometryError 로 거절. 렌더·특징 추출 없이 계측 mesh 만 읽어 판정하므로 등록보다 비용이 작고, 등록 전에 입력 파일 목록을 점검해 수정할 파일을 먼저 선별하는 용도.

실패는 그 부품의 카탈로그 항목이 소비처에서 사용되지 못하거나 다른 부품의 점수·게이트를 오염시키는 형상. 입력 포맷별 분기는 없으며 계측 mesh 하나에 같은 규칙을 적용. 규칙은 다음과 같음.

  • unreadable: 파일이 없거나, mesh 로 읽히지 않거나, STEP 의 길이 단위 선언이 실제 단위로 해석되지 않음.
  • non_finite_coordinates: 정점 좌표에 NaN 또는 무한대가 포함됨. 이 경우 나머지 규칙은 값을 산출할 수 없어 판정하지 않음.
  • zero_surface_area: 모든 삼각형의 면적이 0.
  • no_volume: 형상이 한 평면 위에 있어 convex hull 부피가 0.
  • below_minimum_size: 최장 변이 하한 미만. 카탈로그 좌표는 mm 이므로 미터 좌표로 저장된 부품이 여기에 해당.

Parameters:

Name Type Description Default
path str

CAD/mesh 파일 경로. 허용 형식은 onboard 와 같음.

required

Returns:

Type Description
dict[str, Any]

판정 보고. 필드 구조는 다음과 같음.

{
    "path": str,                 # 입력 경로 그대로. 입력 목록과의 대응 키.
    "failures": dict[str, str],  # 규칙 이름 → 사유. 비면 등록 가능.
}

Raises:

Type Description
DataFormatError

path 가 문자열이 아니거나 지원하지 않는 확장자인 경우. 파일을 읽지 못하는 것은 예외가 아니라 failures["unreadable"] 로 보고됨.

Note

failures 가 비어도 onboard 가 다른 사유로 실패할 수 있음 (렌더·기하 단계가 값을 산출하지 못한 경우 등). 이 메서드의 판정 대상은 부품 형상뿐.

onboard 가 형상 규칙 넷으로 거절하는 것은 DegenerateGeometryError, 파일을 읽지 못하는 것은 DataFormatError. 이 메서드가 unreadable 하나로 보고하는 사유가 onboard 에서는 별도 code.

닫히지 않은 형상은 실패로 판정하지 않음. 편차 부호 신뢰 여부는 onboard 산출물의 geometry.watertight 로 확인.

Usage
err, msg, report = handler.validate("/cad/bracket.stp")
if report["failures"]:
    print(report["path"], list(report["failures"]))