# encoding: UTF-8
begin
  puts "###DZW-LEVELFIX-DJ1250-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_levelfix.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  ents = lambda { |s| s.is_a?(Sketchup::Group) ? s.entities : s.definition.entities }
  cov = nil
  m.entities.each do |e|
    next unless e.is_a?(Sketchup::Group) || e.is_a?(Sketchup::ComponentInstance)
    cov = e if (e.respond_to?(:name) ? e.name.to_s : '') == '하부프레임커버'
  end
  tgt = nil
  if cov
    ents.call(cov).each do |s|
      next unless s.is_a?(Sketchup::Group) || s.is_a?(Sketchup::ComponentInstance)
      tgt = s if (s.respond_to?(:name) ? s.name.to_s : '') == 'DJ1250-윈치받침'
    end
  end
  if tgt.nil?
    puts "STOP: DJ1250-윈치받침 미발견"
  else
    meas = lambda do
      wt = cov.transformation * tgt.transformation
      best = nil
      ff = nil
      ff = lambda do |en, t|
        en.grep(Sketchup::Face).each do |fa|
          vp = fa.outer_loop.vertices.map { |v| v.position.transform(t) }
          next if vp.length < 3
          n = (vp[1] - vp[0]).cross(vp[2] - vp[0])
          next if n.length.to_f < 1.0e-12
          n.normalize!
          next if n.z.abs < 0.7
          bb = Geom::BoundingBox.new
          vp.each { |p| bb.add(p) }
          ex = [bb.width.to_mm, bb.height.to_mm, bb.depth.to_mm].sort
          a = ex[1] * ex[2]
          best = [a, n, bb] if best.nil? || a > best[0]
        end
        (en.grep(Sketchup::Group) + en.grep(Sketchup::ComponentInstance)).each { |q| ff.call(ents.call(q), t * q.transformation) }
      end
      ff.call(ents.call(tgt), wt)
      best
    end
    b0 = meas.call
    if b0.nil?
      puts "STOP: 기준면 미검출"
    else
      a0, n0, bb0 = b0
      up = n0.z < 0 ? -1.0 : 1.0
      nx = n0.x * up
      nz = n0.z * up
      t0 = Math.acos([[nz, 1.0].min, -1.0].max) * 180.0 / Math::PI
      ang = Math.atan2(-nx, nz) * 180.0 / Math::PI   # 부호 수정본
      pvx = (bb0.min.x.to_mm + bb0.max.x.to_mm) / 2.0
      pvz = (bb0.min.z.to_mm + bb0.max.z.to_mm) / 2.0
      halfx = (bb0.max.x.to_mm - bb0.min.x.to_mm) / 2.0
      mv = halfx * Math.tan(ang.abs * Math::PI / 180.0)
      puts "현재 기울기 #{t0.round(4)}deg (법선 [#{nx.round(5)},#{(n0.y * up).round(5)},#{nz.round(5)}])"
      puts "검산: Y축 #{ang.round(4)}deg 회전(부호 수정), 피벗 X#{pvx.round(1)}/Z#{pvz.round(1)}, 양끝 이동 ±#{mv.round(1)}mm"
      if ang.abs > 12.0 || mv > 45.0
        puts "STOP: 과다 -> 변경 없음"
      else
        piv = Geom::Point3d.new(pvx.mm, 0, pvz.mm)
        rw = Geom::Transformation.rotation(piv, Geom::Vector3d.new(0, 1, 0), ang * Math::PI / 180.0)
        loc = cov.transformation.inverse * rw * cov.transformation
        m.start_operation('DJ1250 수평 정렬(부호 수정)', true)
        tgt.transform!(loc)
        m.commit_operation
        b1 = meas.call
        t1 = b1 ? Math.acos([[b1[1].z.abs, 1.0].min, -1.0].max) * 180.0 / Math::PI : 999.0
        puts "== 결과 기울기 #{t0.round(4)} -> #{t1.round(4)}deg"
        if t1 > 0.05
          m.start_operation('되돌리기', true)
          tgt.transform!(loc.inverse)
          m.commit_operation
          b2 = meas.call
          t2 = b2 ? Math.acos([[b2[1].z.abs, 1.0].min, -1.0].max) * 180.0 / Math::PI : 999.0
          puts "   수평 실패 -> 즉시 롤백 완료(기울기 #{t2.round(4)}deg), 저장하지 않음"
        else
          ps = []
          cp = nil
          cp = lambda do |en, t|
            en.grep(Sketchup::Edge).each { |ed| ed.vertices.each { |v| ps << v.position.transform(t) } }
            (en.grep(Sketchup::Group) + en.grep(Sketchup::ComponentInstance)).each { |q| cp.call(ents.call(q), t * q.transformation) }
          end
          cp.call(ents.call(tgt), cov.transformation * tgt.transformation)
          puts "   월드 X=#{ps.map { |p| p.x.to_mm }.minmax.map { |v| v.round(1) }.inspect} Y=#{ps.map { |p| p.y.to_mm }.minmax.map { |v| v.round(1) }.inspect} Z=#{ps.map { |p| p.z.to_mm }.minmax.map { |v| v.round(1) }.inspect}"
          vw = m.active_view
          cam0 = vw.camera
          begin
            c = cov.bounds.center
            [['iso', Geom::Point3d.new(c.x - 3500.mm, c.y - 4500.mm, c.z + 2200.mm)],
             ['side', Geom::Point3d.new(c.x, c.y - 6000.mm, c.z + 300.mm)]].each do |tag, eye|
              vw.camera = Sketchup::Camera.new(eye, c, Geom::Vector3d.new(0, 0, 1))
              vw.zoom_extents
              f = "E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_levelfix_#{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}"
        end
        puts "DONE"
      end
    end
  end
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
