# dae2skp_parts.rb - 부재별 DAE 72개를 각각 컴포넌트(이름=도번)로 임포트해 격자 배열 후
# 500PRO_전체부재_컴포넌트.skp 로 저장. (더블클릭으로 바로 열리는 파일)
# SketchUp Plugins 폴더에 복사한 뒤 SketchUp 을 아무 .skp 인자와 함께 실행하면 동작.
# 제품별 값은 환경변수로 받는다(기본값은 500PRO — 인자 없이 돌리면 예전과 100% 동일).
#   SKP_DIR  : DAE 가 있고 .skp 를 저장할 폴더
#   SKP_GLOB : 부재 DAE 파일 패턴 (도번 접두어가 제품마다 다르다)
#   SKP_NAME : 저장할 .skp 이름(확장자 제외)

# 윈도우 환경변수는 CP949 로 들어온다. 파일 안의 한글 리터럴(UTF-8)과 그대로 이으면
# Encoding::CompatibilityError 가 난다. 그래서 읽는 즉시 UTF-8 로 태그를 맞춘다.
def env_u(k, d)
  v = ENV[k]
  return d unless v
  # force_encoding 은 '꼬리표만' 바꾼다. 바이트는 그대로 CP949 라서 한글 경로가 안 열린다.
  # 실제로 UTF-8 바이트로 변환(transcode)해야 파일 접근까지 된다.
  begin
    v.dup.force_encoding('CP949').encode('UTF-8')
  rescue
    v.dup.force_encoding('UTF-8')
  end
end

D    = env_u('SKP_DIR',  'E:/도진팩토리/3D스캔및티칭시스템/fab_models/sketchup/')
GLOB = env_u('SKP_GLOB', '2110DN-*.dae')
NAME = env_u('SKP_NAME', '500PRO_전체부재')
OUT  = D + NAME + '_컴포넌트.skp'
LOG = D + '_dae2skp.log'
GAP = 150.0 # mm

def lg(m); File.open(LOG, 'a') { |f| f.puts("#{Time.now} #{m}") }; end

begin
  m = Sketchup.active_model
  m.entities.clear!
  # 종합본 DAE(=SKP_NAME 과 같은 이름)는 부재가 아니므로 뺀다.
  files = Dir.glob(D + GLOB).sort.reject { |f| File.basename(f, '.dae') == NAME }
  lg("PARTS files=#{files.length}")
  defs = []
  files.each do |f|
    name = File.basename(f, '.dae')
    before = m.definitions.map { |d| d.name }
    m.import(f, false)
    nd = m.definitions.reject { |d| before.include?(d.name) }.max_by { |d| d.entities.length }
    next if nd.nil?
    nd.name = name rescue nil
    defs << nd
  end
  cols = Math.sqrt(defs.length).ceil
  cw = defs.map { |d| d.bounds.width }.max + GAP.mm
  ch = defs.map { |d| d.bounds.height }.max + GAP.mm
  defs.each_with_index do |d, i|
    org = d.bounds.min
    t = Geom::Transformation.new([(i % cols) * cw - org.x, (i / cols) * ch - org.y, -org.z])
    inst = m.entities.add_instance(d, t)
    inst.name = d.name rescue nil
  end
  m.options['UnitsOptions']['LengthUnit'] = 2 rescue nil
  bb = m.bounds
  lg("PARTS placed=#{m.entities.length} bbox_mm=#{bb.width.to_mm.round}x#{bb.height.to_mm.round}x#{bb.depth.to_mm.round} min=#{bb.min.to_a.map { |v| v.to_mm.round }}")
  # 재실행 시 이전 회차의 컴포넌트 정의가 모델에 남아 파일이 부풀고 컴포넌트 목록이 지저분해진다.
  m.definitions.purge_unused
  m.active_view.zoom_extents
  m.save(OUT)
  lg("PARTS saved=#{File.exist?(OUT)} size=#{File.size(OUT)}")
rescue => e
  lg("PARTS ERROR #{e.class}: #{e.message}")
end
