# encoding: UTF-8
# clean1 — CEO가 그은 잔여 보조선 정리 (최근 생성 고립 에지 + 안내점). 소량 배치 삭제.
HB = 'E:/도진팩토리/3D스캔및티칭시스템/_자동화/inbox/_보류/_clean_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
m = Sketchup.active_model
out = []
hb("START")
loose = m.entities.grep(Sketchup::Edge).select { |e| e.faces.empty? }
recent = loose.select { |e| e.entityID > 2900000 }
legacy = loose - recent
cpts = m.entities.grep(Sketchup::ConstructionPoint)
clines = m.entities.grep(Sketchup::ConstructionLine)
sol_before = m.entities.grep(Sketchup::Group).count { |g| (g.manifold? rescue false) }
grp_before = m.entities.grep(Sketchup::Group).length
face_before = m.entities.grep(Sketchup::Face).length
out << "고립에지 #{loose.length}개 = 최근(CEO 작도, eid>2.9M) #{recent.length}개 + 기존모델 #{legacy.length}개"
out << "안내선 #{clines.length} / 안내점 #{cpts.length}"
out << "삭제 예정 #{recent.length + cpts.length + clines.length}개 (기존모델 #{legacy.length}개는 보존)"
out << "전: 최상위 그룹 #{grp_before} / 솔리드 #{sol_before} / loose면 #{face_before}"
tgt = recent + cpts + clines
if tgt.empty?
  out << "삭제 대상 없음"
elsif tgt.length > 300
  out << "대상 과다 #{tgt.length}개 -> 중단(형상 손상 위험)"
  hb("ABORT many")
else
  begin
    base = File.basename(m.path, '.skp'); dir = File.dirname(m.path)
    bak = File.join(dir, "#{base}.bak_#{Time.now.strftime('%Y%m%d_%H%M%S')}_clean직전.skp")
    m.save_copy(bak)
    hb("BACKUP OK")
    n = 0
    m.start_operation("CEO 보조선 정리", true)
    tgt.each_slice(50) do |batch|
      batch.each do |e|
        next unless e.valid?
        e.erase!
        n += 1
      end
      hb("BATCH done n=#{n}")
    end
    m.commit_operation
    hb("COMMIT n=#{n}")
    out << "삭제 #{n}개 완료"
  rescue Exception => e
    m.commit_operation rescue nil
    out << "ERR #{e.class}: #{e.message}"
    hb("ERR #{e.message}")
  end
end
sol_after = m.entities.grep(Sketchup::Group).count { |g| (g.manifold? rescue false) }
grp_after = m.entities.grep(Sketchup::Group).length
face_after = m.entities.grep(Sketchup::Face).length
loose_after = m.entities.grep(Sketchup::Edge).count { |e| e.faces.empty? }
out << "후: 최상위 그룹 #{grp_after} / 솔리드 #{sol_after} / loose면 #{face_after} / 남은 고립에지 #{loose_after}"
["SWD_02_jog30_6T_20260919", "SWD_03_jog20_6T_20260919", "사이드막음판_9T_A_20260919", "사이드막음판_9T_B_20260919", "조립부원판_20260919"].each do |nm|
  g = m.entities.grep(Sketchup::Group).find { |x| x.name == nm }
  out << "  #{nm}: #{g ? "존재 solid=#{g.manifold? rescue 'n/a'}" : '없음!!'}"
end
v = m.active_view
sel = m.selection
sel.clear
g2 = m.entities.grep(Sketchup::Group).find { |g| g.definition.name == "그룹#2" }
won = m.entities.grep(Sketchup::Group).find { |g| g.name == "조립부원판_20260919" }
sel.add(g2) if g2
sel.add(won) if won
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/_보류/_cap4.png', 1400, 900, true)}"
puts out.join("\n")
hb("END")
"CLEAN1"
