# encoding: UTF-8
begin
  puts "###DZW-COMP2GROUP-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_comp2group.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  ents = lambda { |s| s.is_a?(Sketchup::Group) ? s.entities : s.definition.entities }
  target = nil
  tpath = nil
  walk = nil
  walk = lambda do |ent, path, depth|
    (ent.grep(Sketchup::Group) + ent.grep(Sketchup::ComponentInstance)).each do |s|
      nm = (s.respond_to?(:name) ? s.name.to_s : '')
      dn = s.is_a?(Sketchup::ComponentInstance) ? s.definition.name.to_s : ''
      lbl = nm.empty? ? (dn.empty? ? '(무명)' : dn) : nm
      if (nm == '하부프레임커버' || dn == '하부프레임커버') && target.nil?
        target = s
        tpath = "#{path}/#{lbl}"
      end
      walk.call(ents.call(s), "#{path}/#{lbl}", depth + 1) if depth < 3 && target.nil?
    end
  end
  walk.call(m.entities, '', 0)
  if target.nil?
    puts "STOP: 하부프레임커버 미발견"
  elsif target.is_a?(Sketchup::Group)
    puts "이미 Group 입니다: #{tpath} -> 변환 불필요(무수정)"
  else
    defn = target.definition
    others = defn.instances.length
    par = target.parent
    pents = par.is_a?(Sketchup::Model) ? par.entities : par.entities
    b0 = target.bounds
    bb0 = [b0.min.to_a.map { |v| v.to_mm.round(2) }, b0.max.to_a.map { |v| v.to_mm.round(2) }]
    kids0 = ents.call(target).grep(Sketchup::Group).map { |g| g.name.to_s } +
            ents.call(target).grep(Sketchup::ComponentInstance).map { |g| g.name.to_s.empty? ? g.definition.name.to_s : g.name.to_s }
    puts "대상 #{tpath} (ComponentInstance) 정의='#{defn.name}' 인스턴스 수=#{others}"
    puts "  전 bbox min=#{bb0[0].inspect} max=#{bb0[1].inspect} / 직계 자식 #{kids0.length}개: #{kids0.inspect}"
    if others > 1
      puts "STOP: 같은 정의의 인스턴스가 #{others}개 -> 폭발 시 다른 배치에 영향 가능. 변환하지 않음(무수정)"
    else
      m.start_operation('컴포넌트 -> 그룹 변환', true)
      res = target.explode
      made = res.select { |e| e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance) || e.is_a?(Sketchup::Edge) || e.is_a?(Sketchup::Face) }
      made = made.select { |e| e.valid? }
      g = pents.add_group(made)
      g.name = '하부프레임커버'
      m.commit_operation
      b1 = g.bounds
      bb1 = [b1.min.to_a.map { |v| v.to_mm.round(2) }, b1.max.to_a.map { |v| v.to_mm.round(2) }]
      kids1 = g.entities.grep(Sketchup::Group).map { |x| x.name.to_s } +
              g.entities.grep(Sketchup::ComponentInstance).map { |x| x.name.to_s.empty? ? x.definition.name.to_s : x.name.to_s }
      dmin = (0..2).map { |i| (bb1[0][i] - bb0[0][i]).abs }.max
      dmax = (0..2).map { |i| (bb1[1][i] - bb0[1][i]).abs }.max
      puts "== 변환 결과: #{g.class} '#{g.name}' 자식 #{kids1.length}개"
      puts "   후 bbox min=#{bb1[0].inspect} max=#{bb1[1].inspect} (최대 편차 min #{dmin.round(3)}mm / max #{dmax.round(3)}mm)"
      puts "   자식 목록: #{kids1.inspect}"
      puts "   판정: #{(dmin < 0.5 && dmax < 0.5 && kids1.length == kids0.length) ? '위치·구성 불변 정상' : '이상 -> CEO 확인 필요'}"
      vw = m.active_view
      cam0 = vw.camera
      begin
        c = g.bounds.center
        vw.camera = Sketchup::Camera.new(Geom::Point3d.new(c.x - 2500.mm, c.y - 3000.mm, c.z - 1500.mm), c, Geom::Vector3d.new(0, 0, 1))
        f = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_c2g.png'
        vw.write_image(f, 1600, 1000, true)
        puts "   캡처=#{f} 존재=#{File.exist?(f)}"
      rescue Exception => e3
        puts "   캡처 실패 #{e3.message}"
      ensure
        vw.camera = cam0
      end
      ok = m.save
      puts "SAVE=#{ok.inspect} modified?=#{m.modified?.inspect}"
    end
  end
  puts "DONE"
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
