# encoding: UTF-8
# cut1 — SWD_04_t9_240x1046 양쪽 끝 볼트결합부 제거 (남길 부분만 keep-box 로 intersect)
#   로컬 x 111..889 만 남긴다. (구멍 외곽 98.5 / 벤딩 시작 123.06 의 중간, 좌우 대칭)
#   삭제 방식 아님. 단일 solid 연산 1회. erase! 후 부모 재조회 없음.

HB = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_보류/_cut1_heartbeat.txt'
def hb(msg)
  begin
    File.open(HB, 'a:UTF-8') { |f| f.write("[#{Time.now.strftime('%H:%M:%S')}] #{msg}\n"); f.flush }
  rescue Exception
    nil
  end
end
def r1(v); (v * 25.4).round(1); end

m = Sketchup.active_model
out = []
hb("START path=#{m.path}")

parent = m.entities.grep(Sketchup::Group).find { |g| g.definition.name == "그룹#2" }
if parent.nil?
  out << "그룹#2 없음 -> 중단"
  hb("ABORT no 그룹#2")
else
  cands = parent.entities.grep(Sketchup::Group).select { |g| g.name == "SWD_04_t9_240x1046" }
  if cands.length != 1
    out << "SWD_04_t9_240x1046 #{cands.length}개 -> 중단(1개여야 함)"
    hb("ABORT cand=#{cands.length}")
  else
    tgt = cands[0]
    lb = tgt.definition.bounds
    loops = 0
    tgt.entities.grep(Sketchup::Face).each { |f| f.loops.each { |lp| loops += 1 unless lp.outer? } }
    out << "대상 로컬 bbox (#{r1(lb.min.x)},#{r1(lb.min.y)},#{r1(lb.min.z)})..(#{r1(lb.max.x)},#{r1(lb.max.y)},#{r1(lb.max.z)}) 내부루프=#{loops}개 solid=#{tgt.manifold?}"
    ok = (r1(lb.max.x) - 1000.0).abs < 1.0 && (r1(lb.max.y) - 240.0).abs < 1.0 &&
         (r1(lb.max.z) - 109.0).abs < 1.0 && loops == 18 && tgt.manifold?
    if !ok
      out << "형상 확인 실패(예상: 1000x240x109, 내부루프18, solid) -> 중단, 무변경"
      hb("ABORT shape mismatch")
    elsif !tgt.respond_to?(:intersect)
      out << "intersect 미지원 -> 중단"
      hb("ABORT no intersect")
    else
      bak = nil
      begin
        base = m.path.to_s.empty? ? 'untitled' : File.basename(m.path, '.skp')
        dir  = m.path.to_s.empty? ? 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave' : File.dirname(m.path)
        bak  = File.join(dir, "#{base}.bak_#{Time.now.strftime('%Y%m%d_%H%M%S')}_cut1직전.skp")
        m.save_copy(bak)
        out << "사전 백업 OK -> #{bak}"
        hb("BACKUP OK")
      rescue Exception => e
        out << "사전 백업 실패 #{e.class}: #{e.message} -> 중단"
        hb("BACKUP FAIL #{e.message}")
        ok = false
      end

      if ok
        nm  = tgt.name
        lay = (tgt.layer rescue nil)
        mat = (tgt.material rescue nil)
        tr  = tgt.transformation
        pents = parent.entities
        res = nil
        begin
          m.start_operation("SWD_04 볼트결합부 양단 제거", true)
          x0 = 111.mm; x1 = 889.mm; y0 = -10.mm; y1 = 250.mm; z0 = -10.mm; z1 = 120.mm
          box = pents.add_group
          bf = box.entities.add_face([x0, y0, z0], [x1, y0, z0], [x1, y1, z0], [x0, y1, z0])
          bf.reverse! if bf.normal.z > 0
          bf.pushpull(z1 - z0)
          box.transformation = tr
          hb("BOX READY solid=#{box.manifold?}")
          res = tgt.intersect(box)
          hb("INTERSECT DONE res=#{res.class}")
          if res
            res.name = nm
            res.layer = lay if lay
            res.material = mat if mat
          end
          m.commit_operation
          hb("COMMIT OK")
        rescue Exception => ex
          m.commit_operation rescue nil
          out << "ERR #{ex.class}: #{ex.message}"
          hb("ERR #{ex.class}: #{ex.message}")
        end

        if res.nil?
          out << "intersect 실패(nil) -> 변경 없음 또는 부분 상태. 백업본 존재."
        else
          out << "절단 완료: 로컬 x 0..111, x 889..1000 제거 (양 끝 각 111mm), d17 볼트구멍 각 4개씩 총 8개 제거"
        end

        begin
          p2 = m.entities.grep(Sketchup::Group).find { |g| g.definition.name == "그룹#2" }
          if p2
            names = p2.entities.grep(Sketchup::Group).map { |s| s.name }
            out << "== 그룹#2 구성 (#{names.length}개) == #{names.inspect}"
            t2 = p2.entities.grep(Sketchup::Group).find { |g| g.name == "SWD_04_t9_240x1046" }
            if t2
              b2 = t2.definition.bounds
              l2 = 0
              t2.entities.grep(Sketchup::Face).each { |f| f.loops.each { |lp| l2 += 1 unless lp.outer? } }
              out << "결과: 로컬 bbox (#{r1(b2.min.x)},#{r1(b2.min.y)},#{r1(b2.min.z)})..(#{r1(b2.max.x)},#{r1(b2.max.y)},#{r1(b2.max.z)}) 내부루프=#{l2}개 solid=#{t2.manifold?}"
            else
              out << "결과 그룹 못 찾음"
            end
          end
          hb("VERIFY DONE")
        rescue Exception => e
          out << "검증 실패 #{e.class}: #{e.message}"
          hb("VERIFY FAIL #{e.message}")
        end
      end
    end
  end
end

puts out.join("\n")
hb("END")
"CUT1"
