# encoding: UTF-8
# drop1 — 주황판(SWD_04) 6.0mm 하강(수평 유지) + 사이드판 B를 A(=CEO가 키운 것)의 거울상으로 갱신
HB = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_보류/_drop_heartbeat.txt'
def hb(s); begin; File.open(HB,'a:UTF-8'){|f| f.write("[#{Time.now.strftime('%H:%M:%S')}] #{s}\n"); f.flush}; rescue Exception; end; end
MM = 25.4
m = Sketchup.active_model
out = []
hb("START")
g2 = m.entities.grep(Sketchup::Group).find { |g| g.definition.name == "그룹#2" }
s04 = g2.entities.grep(Sketchup::Group).find { |g| g.name == "SWD_04_t9_240x1046" }
pa = m.entities.grep(Sketchup::Group).find { |g| g.name == "사이드막음판_9T_A_20260919" }
pb = m.entities.grep(Sketchup::Group).find { |g| g.name == "사이드막음판_9T_B_20260919" }
if [s04, pa, pb].any?(&:nil?)
  out << "대상 없음 -> 중단"; hb("ABORT")
else
  drop = 6.0
  ab = pa.bounds
  out << "사이드판A(CEO 변경): x #{(ab.min.x*25.4).round(2)}..#{(ab.max.x*25.4).round(2)} z #{(ab.min.z*25.4).round(2)}..#{(ab.max.z*25.4).round(2)} 두께 #{((ab.max.y-ab.min.y)*25.4).round(2)}mm"
  sb = s04.bounds
  wb = Geom::BoundingBox.new; [sb.min, sb.max].each { |p| wb.add(p.transform(g2.transformation)) }
  out << "주황판 전: z #{(wb.min.z*25.4).round(2)}..#{(wb.max.z*25.4).round(2)}"
  begin
    base = File.basename(m.path,'.skp'); dir = File.dirname(m.path)
    m.save_copy(File.join(dir, "#{base}.bak_#{Time.now.strftime('%Y%m%d_%H%M%S')}_drop직전.skp"))
    hb("BACKUP OK")
    m.start_operation("주황판 #{drop}mm 하강 + 사이드판 B 대칭", true)
    tw = Geom::Transformation.translation(Geom::Vector3d.new(0, 0, -drop / MM))
    s04.transformation = g2.transformation.inverse * tw * g2.transformation * s04.transformation
    hb("DROP")
    # B = A 거울 (y 중심축)
    ymid = 11376.055
    pts = nil
    pa.entities.grep(Sketchup::Face).each do |f|
      next unless f.normal.y.abs > 0.9
      pts = f.vertices.map { |v| v.position.transform(pa.transformation) } if pts.nil? || f.area > 0
    end
    fmax = pa.entities.grep(Sketchup::Face).select { |f| f.normal.y.abs > 0.9 }.max_by { |f| f.area }
    pts = fmax.vertices.map { |v| v.position.transform(pa.transformation) }
    ymin_a = pts.map { |p| p.y }.min
    newpts = pts.map { |p| Geom::Point3d.new(p.x, (2 * ymid / 25.4) - p.y, p.z) }
    pb.erase!
    nb = m.entities.add_group
    f = nb.entities.add_face(newpts)
    f.pushpull(f.normal.y > 0 ? 9.0 / MM : -9.0 / MM)
    nb.name = "사이드막음판_9T_B_20260919"
    hb("MIRROR B solid=#{nb.manifold?}")
    m.commit_operation
    hb("COMMIT")
    wb2 = Geom::BoundingBox.new; [s04.bounds.min, s04.bounds.max].each { |p| wb2.add(p.transform(g2.transformation)) }
    out << "주황판 후: z #{(wb2.min.z*25.4).round(2)}..#{(wb2.max.z*25.4).round(2)} (#{drop}mm 하강, 수평 유지)"
    b2 = nb.bounds
    out << "사이드판B(대칭 재작성): x #{(b2.min.x*25.4).round(2)}..#{(b2.max.x*25.4).round(2)} y #{(b2.min.y*25.4).round(2)}..#{(b2.max.y*25.4).round(2)} z #{(b2.min.z*25.4).round(2)}..#{(b2.max.z*25.4).round(2)} 두께 #{((b2.max.y-b2.min.y)*25.4).round(2)} solid=#{nb.manifold?}"
  rescue Exception => e
    m.commit_operation rescue nil
    out << "ERR #{e.class}: #{e.message}"; hb("ERR #{e.message}")
  end
end
puts out.join("\n")
hb("END")
"DROP1"
