# encoding: UTF-8
begin
  puts "###DZW-CLEAN-EDGES-20260920"
  m = Sketchup.active_model
  bk = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/autosave/BACKUP_before_cleanedges.skp'
  m.save_copy(bk)
  puts "BACKUP=#{bk}"
  ents = lambda { |s| s.is_a?(Sketchup::Group) ? s.entities : s.definition.entities }
  targets = []
  m.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 : '')
    if nm == '하부프레임커버'
      (ents.call(e)).each do |s|
        next unless s.is_a?(Sketchup::Group) || s.is_a?(Sketchup::ComponentInstance)
        cn = (s.respond_to?(:name) ? s.name.to_s : '')
        targets << [cn.empty? ? '(무명)' : cn, s]
      end
    elsif nm.start_with?('오일탱크커버')
      targets << [nm, e]
    end
  end
  puts "대상 부재 #{targets.length}개"
  tot_del = 0
  tot_soft = 0
  targets.each do |nm, g|
    en = ents.call(g)
    v0 = (g.respond_to?(:volume) ? g.volume : -1.0)
    edges = en.grep(Sketchup::Edge)
    rem = []
    soft = []
    edges.each do |ed|
      fs = ed.faces
      next unless fs.length == 2
      n1 = fs[0].normal
      n2 = fs[1].normal
      d = n1.dot(n2)
      d = 1.0 if d > 1.0
      d = -1.0 if d < -1.0
      ang = Math.acos(d.abs) * 180.0 / Math::PI
      if ang < 0.05
        rem << ed
      elsif ang < 20.0
        soft << ed
      end
    end
    del = 0
    if !rem.empty?
      m.start_operation("에지정리 #{nm}", true)
      rem.each_slice(40) do |ch|
        live = ch.select { |e2| e2.valid? }
        begin
          en.erase_entities(live)
        rescue Exception
          live.each { |e2| (e2.erase! if e2.valid?) rescue nil }
        end
        del += live.length
      end
      m.commit_operation
    end
    sf = 0
    if !soft.empty?
      m.start_operation("소프트닝 #{nm}", true)
      soft.each do |ed|
        next unless ed.valid?
        ed.soft = true
        ed.smooth = true
        sf += 1
      end
      m.commit_operation
    end
    v1 = (g.valid? && g.respond_to?(:volume) ? g.volume : -1.0)
    dv = (v0 > 0 && v1 > 0) ? ((v1 - v0).abs / v0 * 100.0) : nil
    tot_del += del
    tot_soft += sf
    puts "  '#{nm}' 에지 #{edges.length} -> 동일평면 제거 #{del}, 소프트닝 #{sf}, 체적 #{v0 > 0 ? (v0 * 16387.064).round(0) : 'n/a'} -> #{v1 > 0 ? (v1 * 16387.064).round(0) : 'n/a'} mm3#{dv ? " (차 #{dv.round(4)}%)" : ' (솔리드 아님)'}"
  end
  puts "합계: 제거 #{tot_del}개, 소프트닝 #{tot_soft}개"
  vw = m.active_view
  cam0 = vw.camera
  begin
    c = Geom::Point3d.new(4600.mm, 8140.mm, 100.mm)
    vw.camera = Sketchup::Camera.new(Geom::Point3d.new(c.x.to_f, c.y.to_f, c.z - 2200.mm), c, Geom::Vector3d.new(1, 0, 0))
    f = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_clean_bottom.png'
    vw.write_image(f, 1600, 1000, true)
    puts "캡처=#{f} 존재=#{File.exist?(f)}"
  rescue Exception => e3
    puts "캡처 실패 #{e3.message}"
  ensure
    vw.camera = cam0
  end
  ok = m.save
  puts "SAVE=#{ok.inspect} modified?=#{m.modified?.inspect}"
  puts "DONE"
rescue Exception => e
  puts "EXC #{e.class}: #{e.message}"
  puts e.backtrace.first(6).join(" | ")
end
nil
