# encoding: UTF-8
# side3 — 사이드막음판 A/B 하판 관통 제거(재시도) + 전 쌍 간섭 정밀 재검사
#   검사 개선: intersect 결과를 (nil / 빈그룹 / 체적) 3분류하고, 추가로 체적차 방식(A - (A-B))으로 교차검증.
HB = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_보류/_side3_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
    nil
  end
end
MM = 25.4
def vol(g); (g.volume rescue -1) * (25.4**3); end
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" }
won = m.entities.grep(Sketchup::Group).find { |g| g.name == "조립부원판_20260919" }
names = ["SWD_02_jog30_6T_20260919", "SWD_03_jog20_6T_20260919", "사이드막음판_9T_A_20260919", "사이드막음판_9T_B_20260919"]
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')}_side3직전.skp"))
  hb("BACKUP OK")
  # 1) 사이드판 트림 (하판 실체 제거)
  m.start_operation("사이드판 하판 관통 제거", true)
  ["사이드막음판_9T_A_20260919", "사이드막음판_9T_B_20260919"].each do |nm|
    sp = m.entities.grep(Sketchup::Group).find { |g| g.name == nm }
    next if sp.nil?
    v0 = vol(sp)
    wc = m.entities.add_group
    wc.entities.add_instance(won.definition, won.transformation).explode
    if wc.manifold?
      r = wc.subtract(sp)
      if r
        r.name = nm
        out << "#{nm}: 체적 #{v0.round(0)} -> #{vol(r).round(0)}mm3 (제거 #{(v0 - vol(r)).round(0)}mm3), solid=#{r.manifold?}"
        hb("TRIM #{nm}")
      else
        out << "#{nm}: subtract nil (겹침 없음이거나 실패)"
      end
    else
      wc.erase!
      out << "#{nm}: 하판 복제 비솔리드"
    end
  end
  m.commit_operation
  hb("TRIM COMMIT")
rescue Exception => e
  m.commit_operation rescue nil
  out << "ERR(trim) #{e.class}: #{e.message}"
  hb("ERR #{e.message}")
end
# 2) 전 쌍 정밀 검사
parts = [["주황판SWD_04", s04.definition, g2.transformation * s04.transformation],
         ["하판_조립부원판", won.definition, won.transformation]]
names.each do |nm|
  g = m.entities.grep(Sketchup::Group).find { |x| x.name == nm }
  parts << [nm, g.definition, g.transformation] if g
end
begin
  m.start_operation("간섭 정밀 검사", true)
  (0...parts.length).each do |i|
    ((i + 1)...parts.length).each do |j|
      a = m.entities.add_group
      a.entities.add_instance(parts[i][1], parts[i][2]).explode
      b = m.entities.add_group
      b.entities.add_instance(parts[j][1], parts[j][2]).explode
      unless a.manifold? && b.manifold?
        out << "  #{parts[i][0]} vs #{parts[j][0]}: 복제 비솔리드 -> 판정불가"
        a.erase! rescue nil; b.erase! rescue nil
        next
      end
      va = vol(a)
      # 방법2: A - B 체적차
      a2 = m.entities.add_group
      a2.entities.add_instance(parts[i][1], parts[i][2]).explode
      b2 = m.entities.add_group
      b2.entities.add_instance(parts[j][1], parts[j][2]).explode
      diff = b2.subtract(a2)   # = a2 - b2
      vd = diff ? vol(diff) : nil
      overlap2 = vd ? (va - vd) : nil
      diff.erase! if diff && diff.valid?
      r = a.intersect(b)
      if r.nil?
        out << "  #{parts[i][0]} ∩ #{parts[j][0]}: intersect=nil, 체적차법 #{overlap2 ? overlap2.round(1) : '판정불가'}mm3"
      elsif !r.valid?
        out << "  #{parts[i][0]} ∩ #{parts[j][0]}: 결과 무효, 체적차법 #{overlap2 ? overlap2.round(1) : '판정불가'}mm3"
      else
        v = vol(r)
        bb = r.bounds
        if v <= 0.0
          out << "  #{parts[i][0]} ∩ #{parts[j][0]}: 교집합 없음(빈 결과), 체적차법 #{overlap2 ? overlap2.round(1) : '판정불가'}mm3"
        else
          out << "  #{parts[i][0]} ∩ #{parts[j][0]}: 간섭 #{v.round(1)}mm3 bbox (#{(bb.min.x*25.4).round(1)},#{(bb.min.y*25.4).round(1)},#{(bb.min.z*25.4).round(1)})..(#{(bb.max.x*25.4).round(1)},#{(bb.max.y*25.4).round(1)},#{(bb.max.z*25.4).round(1)}), 체적차법 #{overlap2 ? overlap2.round(1) : '-'}mm3"
        end
        r.erase! if r.valid?
      end
      hb("PAIR #{i}-#{j}")
    end
  end
  m.commit_operation
  hb("SCAN COMMIT")
rescue Exception => e
  m.commit_operation rescue nil
  out << "ERR(scan) #{e.class}: #{e.message}"
end
v = m.active_view
sel = m.selection
sel.clear
sel.add(g2); sel.add(won)
names.each { |nm| g = m.entities.grep(Sketchup::Group).find { |x| x.name == nm }; sel.add(g) if g }
v.camera = Sketchup::Camera.new(Geom::Point3d.new(8250 / 25.4, 9900 / 25.4, 700 / 25.4), Geom::Point3d.new(9030 / 25.4, 11380 / 25.4, 160 / 25.4), Geom::Vector3d.new(0, 0, 1))
v.zoom(sel.to_a)
sel.clear
out << "capture=#{v.write_image('E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_보류/_cap5.png', 1400, 900, true)}"
puts out.join("\n")
hb("END")
"SIDE3"
