# encoding: UTF-8
begin
  puts "###DZW-COVER-OUTER-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_coverouter.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  cov = nil
  lh = nil
  rh = nil
  others = []
  m.active_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 : '')
    cov = e if nm == '하부프레임커버'
    lh = e if nm == 'RJ102-0604_LH_20260918'
    rh = e if nm == 'RJ102-0602_RH_20260918'
    unless nm == '하부프레임커버'
      nmx = (nm.empty? && e.is_a?(Sketchup::ComponentInstance)) ? e.definition.name.to_s : nm
      others << [e, nmx]
    end
  end
  if cov.nil? || lh.nil? || rh.nil?
    puts "STOP: 대상 미발견"
  else
    y_lo = lh.bounds.min.y.to_mm   # LH 사이드 바깥면
    y_hi = rh.bounds.max.y.to_mm   # RH 사이드 바깥면
    lh_in = lh.bounds.max.y.to_mm
    rh_in = rh.bounds.min.y.to_mm
    cb = cov.bounds
    c0 = cb.min.y.to_mm
    c1 = cb.max.y.to_mm
    puts "[월드] LH 사이드 Y=[#{lh.bounds.min.y.to_mm.round(1)},#{lh_in.round(1)}] (판두께 #{(lh_in - y_lo).round(1)})"
    puts "[월드] RH 사이드 Y=[#{rh_in.round(1)},#{rh.bounds.max.y.to_mm.round(1)}] (판두께 #{(y_hi - rh_in).round(1)})"
    puts "[월드] 바깥면~바깥면 간격=#{(y_hi - y_lo).round(1)} (안쪽 #{(rh_in - lh_in).round(1)} + 판두께 2장)"
    puts "[월드] 커버 현재 Y=[#{c0.round(1)},#{c1.round(1)}] 폭=#{(c1 - c0).round(1)} -> 목표 폭=#{(y_hi - y_lo).round(1)} (좌 #{(c0 - y_lo).round(2)} / 우 #{(y_hi - c1).round(2)} 만큼 외곽 연장)"
    log = []
    collect = nil
    collect = lambda do |ent, tr, acc|
      subs = ent.grep(Sketchup::Group) + ent.grep(Sketchup::ComponentInstance)
      vs = []
      ent.grep(Sketchup::Edge).each { |ed| ed.vertices.each { |v| vs << v } }
      vs.uniq!
      acc << [ent, tr, vs] unless vs.empty?
      subs.each { |s| collect.call(s.entities, tr * s.transformation, acc) }
    end
    m.start_operation('커버 폭 재설계(바깥면 플러시)', true)
    kids = cov.entities.grep(Sketchup::Group) + cov.entities.grep(Sketchup::ComponentInstance)
    kids.each do |k|
      nm = (k.respond_to?(:name) ? k.name.to_s : '')
      nm = k.definition.name.to_s if nm.empty? && k.is_a?(Sketchup::ComponentInstance)
      b = k.bounds
      sy0 = b.min.y.to_mm
      sy1 = b.max.y.to_mm
      span = sy1 - sy0
      if span > 200.0
        acc = []
        collect.call(k.entities, cov.transformation * k.transformation, acc)
        cnt = 0
        tot = 0
        acc.each do |ent, tr, vs|
          mv = []
          vc = []
          vs.each do |v|
            w = v.position.transform(tr)
            wy = w.y.to_mm
            tot += 1
            ny = if wy <= sy0 + 0.5 then y_lo
                 elsif wy >= sy1 - 0.5 then y_hi
                 else wy
                 end
            next if (ny - wy).abs < 1.0e-9
            w2 = Geom::Point3d.new(w.x, ny.mm, w.z)
            mv << v
            vc << (w2.transform(tr.inverse) - v.position)
          end
          unless mv.empty?
            ent.transform_by_vectors(mv, vc)
            cnt += mv.length
          end
        end
        log << "   '#{nm}' 폭방향 #{span.round(1)}mm -> 양끝면 외곽 트림/연장 (정점 #{cnt}/#{tot}, 내부·구멍 정점 불변)"
      else
        sh = if (sy0 - c0).abs <= (c1 - sy1).abs
               y_lo - sy0
             else
               y_hi - sy1
             end
        k.transform!(Geom::Transformation.new(Geom::Vector3d.new(0, sh.mm, 0))) if sh.abs > 1.0e-6
        log << "   '#{nm}' 폭방향 #{span.round(1)}mm(얇은 판) -> 바깥면 플러시로 이동 dY=#{sh.round(2)}"
      end
    end
    m.commit_operation
    log.each { |s| puts s }
    nb = cov.bounds
    n0 = nb.min.y.to_mm
    n1 = nb.max.y.to_mm
    puts "== 커버 Y=[#{n0.round(2)},#{n1.round(2)}] 폭=#{(n1 - n0).round(2)} (목표 #{(y_hi - y_lo).round(2)})"
    puts "   LH 바깥면 플러시 오차=#{(n0 - y_lo).round(2)}mm / RH 바깥면 플러시 오차=#{(n1 - y_hi).round(2)}mm"
    puts "   bbox min=#{nb.min.to_a.map { |v| v.to_mm.round(1) }.inspect} max=#{nb.max.to_a.map { |v| v.to_mm.round(1) }.inspect}"
    ov = []
    others.each do |e, onm|
      ob = e.bounds
      ox = [ob.max.x.to_mm, nb.max.x.to_mm].min - [ob.min.x.to_mm, nb.min.x.to_mm].max
      oy = [ob.max.y.to_mm, nb.max.y.to_mm].min - [ob.min.y.to_mm, nb.min.y.to_mm].max
      oz = [ob.max.z.to_mm, nb.max.z.to_mm].min - [ob.min.z.to_mm, nb.min.z.to_mm].max
      next unless ox > 0.5 && oy > 0.5 && oz > 0.5
      ov << "   BBOX겹침 '#{onm}' #{ox.round(1)}x#{oy.round(1)}x#{oz.round(1)}"
    end
    puts "   bbox 겹침 #{ov.length}건 (bbox 수준)"
    ov.first(12).each { |s| puts s }
    ok = m.save
    puts "SAVE=#{ok.inspect} modified?=#{m.modified?.inspect}"
    puts "DONE"
  end
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
