# encoding: UTF-8
begin
  puts "###DZW-OILCOVER-BUILD-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_oilcover.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  lh = nil
  rh = nil
  dj = nil
  cov = nil
  m.entities.each do |e|
    next unless e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance)
    nm = (e.respond_to?(:name) ? e.name.to_s : '')
    lh = e if nm == 'RJ102-0604_LH_20260918'
    rh = e if nm == 'RJ102-0602_RH_20260918'
    cov = e if nm == '하부프레임커버'
  end
  if cov
    (cov.is_a?(Sketchup::Group) ? cov.entities : cov.definition.entities).each do |s|
      next unless s.is_a?(Sketchup::Group) || s.is_a?(Sketchup::ComponentInstance)
      dj = s if (s.respond_to?(:name) ? s.name.to_s : '') == 'DJ1250-윈치받침'
    end
  end
  if lh.nil? || rh.nil? || dj.nil?
    puts "STOP: 기준 부재 미발견 lh=#{!lh.nil?} rh=#{!rh.nil?} dj=#{!dj.nil?}"
  else
    y0 = lh.bounds.max.y.to_mm      # LH 안쪽면
    y1 = rh.bounds.min.y.to_mm      # RH 안쪽면
    wid = y1 - y0
    # 착좌면: LH/RH 뒤쪽 평판 상면 Z (두 사이드 중 큰 값)
    zl = lh.bounds.max.z.to_mm
    zr = rh.bounds.max.z.to_mm
    seat = [44.4, 47.8].max
    # 실측: 사이드 뒤평판 상면
    seat = nil
    [lh, rh].each do |s|
      pts = []
      (s.is_a?(Sketchup::Group) ? s.entities : s.definition.entities).grep(Sketchup::Edge).each { |ed| ed.vertices.each { |v| pts << v.position.transform(s.transformation) } }
      xs = pts.map { |p| p.x.to_mm }
      rear = pts.select { |p| p.x.to_mm >= xs.max - 1.0 }
      zz = rear.map { |p| p.z.to_mm }.select { |z| z < 100.0 }.max
      seat = zz if seat.nil? || (zz && zz > seat)
    end
    th = 12.0
    djw = cov.transformation * dj.transformation
    djp = []
    (dj.is_a?(Sketchup::Group) ? dj.entities : dj.definition.entities).grep(Sketchup::Edge).each { |ed| ed.vertices.each { |v| djp << v.position.transform(djw) } }
    xstart = djp.empty? ? dj.bounds.max.x.to_mm : djp.map { |p| p.x.to_mm }.max
    puts "[월드 실측] 사이드 안쪽 Y=[#{y0.round(1)},#{y1.round(1)}] 폭=#{wid.round(1)} / 착좌면 Z=#{seat ? seat.round(1) : 'nil'} / 윈치받침 뒤끝 X=#{xstart.round(1)}"
    puts "[검산] 길이방향=X(윈치→센터프레임 +X), 커버 2장 420+420=840, 폭=#{wid.round(1)}, 두께=#{th}"
    if seat.nil? || wid < 500 || wid > 2000
      puts "STOP: 착좌면/폭 실측 이상 -> 생성 중단"
    else
      made = []
      m.start_operation('오일탱크커버 2분할 생성', true)
      2.times do |k|
        xa = xstart + 420.0 * k
        xb = xa + 420.0
        nm = k == 0 ? '오일탱크커버_A_420_20260920' : '오일탱크커버_B_420_20260920'
        g = m.entities.add_group
        z0 = seat
        pts = [
          Geom::Point3d.new(xa.mm, y0.mm, z0.mm),
          Geom::Point3d.new(xb.mm, y0.mm, z0.mm),
          Geom::Point3d.new(xb.mm, y1.mm, z0.mm),
          Geom::Point3d.new(xa.mm, y1.mm, z0.mm)
        ]
        fc = g.entities.add_face(pts)
        # 볼트 홀 M16(Ø18): 양 사이드 가장자리 2열, 열당 4개
        edge_off = 40.0
        rows = [y0 + 30.0, y1 - 30.0]
        n = 4
        pitch = (420.0 - 2 * edge_off) / (n - 1)
        rows.each do |yy|
          n.times do |i|
            cx = xa + edge_off + pitch * i
            g.entities.add_circle(Geom::Point3d.new(cx.mm, yy.mm, z0.mm), Geom::Vector3d.new(0, 0, 1), 9.0.mm, 16)
          end
        end
        small = g.entities.grep(Sketchup::Face).select { |f| (f.area * 0.00155).abs < 500.0 }
        g.entities.erase_entities(small) unless small.empty?
        big = g.entities.grep(Sketchup::Face).max_by { |f| f.area }
        big.pushpull(th.mm) if big
        g.name = nm
        b = g.bounds
        holes = 0
        g.entities.grep(Sketchup::Face).each { |f| f.loops.each { |lp| holes += 1 if !lp.outer? && lp.vertices.length >= 8 } }
        made << [nm, g, b, holes]
      end
      m.commit_operation
      made.each do |nm, g, b, holes|
        puts "== #{nm} bbox min=#{b.min.to_a.map { |v| v.to_mm.round(1) }.inspect} max=#{b.max.to_a.map { |v| v.to_mm.round(1) }.inspect} 면수=#{g.entities.grep(Sketchup::Face).length} 내부루프(홀)=#{holes}"
      end
      jx = xstart + 420.0
      sup = []
      m.entities.each do |e|
        next unless e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance)
        nm2 = (e.respond_to?(:name) ? e.name.to_s : '')
        next if nm2.start_with?('오일탱크커버')
        bb = e.bounds
        next unless bb.min.x.to_mm <= jx + 40 && bb.max.x.to_mm >= jx - 40
        next unless bb.max.z.to_mm >= seat - 30 && bb.min.z.to_mm <= seat + 30
        sup << "#{nm2.empty? ? '(무명)' : nm2} X=[#{bb.min.x.to_mm.round(1)},#{bb.max.x.to_mm.round(1)}] Z=[#{bb.min.z.to_mm.round(1)},#{bb.max.z.to_mm.round(1)}]"
      end
      puts "이음부 X=#{jx.round(1)} 지지 후보 #{sup.length}건: #{sup.first(5).inspect}"
      vw = m.active_view
      cam0 = vw.camera
      begin
        c = Geom::Point3d.new(((xstart + 840.0) / 2.0).mm, ((y0 + y1) / 2.0).mm, seat.mm)
        [['bottom', Geom::Point3d.new(c.x.to_f, c.y.to_f, c.z - 2500.mm)],
         ['bottomiso', Geom::Point3d.new(c.x - 1800.mm, c.y - 2200.mm, c.z - 1600.mm)]].each do |tag, eye|
          vw.camera = Sketchup::Camera.new(eye, c, Geom::Vector3d.new(1, 0, 0))
          f = "E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_oilcover_#{tag}.png"
          vw.write_image(f, 1600, 1000, true)
          puts "캡처 #{tag}=#{f} 존재=#{File.exist?(f)}"
        end
      rescue Exception => e3
        puts "캡처 실패 #{e3.message}"
      ensure
        vw.camera = cam0
      end
      ok = m.save
      puts "SAVE=#{ok.inspect} modified?=#{m.modified?.inspect}"
      puts "DONE"
    end
  end
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
