# encoding: UTF-8
# CEO 선택 부재(연결브라켓_L_A 현재 사이즈 320 x 70 x 89.5) 기준으로 A/B 완전 동일 사양 재작성
# 홀 3개 Ø18 + 웰드너트 3개 / 날개 장공 삭제(구멍 없음) / 6T, 내R9, 절곡1회
m = Sketchup.active_model
T=6.0; RI=9.0; RO=RI+T
XL=8853.1; XR=9173.1                  # 길이 320 (양쪽 동일)
ZT=250.0; ZFB=ZT-T; ZTAN=ZT-RO; ZBOT=160.5   # 전고 89.5 (양쪽 동일)
WF=70.0                               # 플랜지 폭 70 (양쪽 동일)
HD=18.0; NAF=24.0; NH=13.0; NBORE=17.0
HXS=[8893.1, 9013.1, 9133.1]          # 3개 균등 피치 120, 연단 40

def a2(cu,cv,r,a0,a1,seg)
  (0..seg).map{|i| a=(a0+(a1-a0)*i.to_f/seg)*Math::PI/180.0; [cu+r*Math.cos(a), cv+r*Math.sin(a)]}
end
def circ(cx,cy,d,seg); (0...seg).map{|i| a=2*Math::PI*i/seg; [cx+d/2*Math.cos(a), cy+d/2*Math.sin(a)]}; end

m.start_operation('L브라켓 A/B 동일사양 재작성', true)
m.entities.grep(Sketchup::Group).select{|g| g.name.to_s.start_with?('연결브라켓_L_')}.each{|g| g.erase!}
rep = []
[['A', 10951.0, 1.0], ['B', 11743.5, -1.0]].each do |nm, yo, sg|
  ytan = yo - sg*RO; yi = yo - sg*T; yend = yo - sg*WF
  hy = (yend + ytan)/2.0
  par = m.entities.add_group

  ft = par.entities.add_group                                   # 플랜지: z축 압출 (Ø18 x3 직접 생성)
  ry = [yend, ytan].sort
  ft.entities.add_face([[XL,ry[0]],[XR,ry[0]],[XR,ry[1]],[XL,ry[1]]].map{|x,y| Geom::Point3d.new(x.mm,y.mm,ZFB.mm)})
  HXS.each{|hx| hf=ft.entities.add_face(circ(hx,hy,HD,24).map{|x,y| Geom::Point3d.new(x.mm,y.mm,ZFB.mm)}); hf.erase! if hf&&hf.valid?}
  f=ft.entities.grep(Sketchup::Face).max_by{|q| q.area}; f.reverse! if f.normal.z<0; f.pushpull(T.mm)
  ft.name="플랜지_#{nm}"

  lg = par.entities.add_group                                   # 날개: 구멍 없음
  lg.entities.add_face([[XL,ZBOT],[XR,ZBOT],[XR,ZTAN],[XL,ZTAN]].map{|x,z| Geom::Point3d.new(x.mm, yi.mm, z.mm)})
  f2=lg.entities.grep(Sketchup::Face).max_by{|q| q.area}; f2.reverse! if f2.normal.y*sg<0; f2.pushpull(T.mm)
  lg.name="날개_#{nm}"

  bd = par.entities.add_group                                   # 절곡 R
  ao1 = (sg>0 ? 0.0 : 180.0); ai0 = ao1
  pr = [[ytan, ZT]] + a2(ytan, ZTAN, RO, 90.0, ao1, 10) + [[yi, ZTAN]] + a2(ytan, ZTAN, RI, ai0, 90.0, 10) + [[ytan, ZFB]]
  cl=[]; pr.each{|p| cl << p if cl.empty? || ((p[0]-cl[-1][0]).abs>1e-6 || (p[1]-cl[-1][1]).abs>1e-6)}
  f3=bd.entities.add_face(cl.map{|y,z| Geom::Point3d.new(XL.mm, y.mm, z.mm)})
  raise "#{nm} 절곡부 실패" if f3.nil?
  f3.reverse! if f3.normal.x<0; f3.pushpull((XR-XL).mm)
  bd.name="절곡R_#{nm}"

  rc = NAF/Math.sqrt(3.0)                                       # 웰드너트 3개 (플랜지 하면)
  HXS.each_with_index do |hx,i|
    ng = par.entities.add_group
    ng.entities.add_face((0...6).map{|k| a=(30.0+60.0*k)*Math::PI/180.0; Geom::Point3d.new((hx+rc*Math.cos(a)).mm,(hy+rc*Math.sin(a)).mm, ZFB.mm)})
    bf = ng.entities.add_face(circ(hx,hy,NBORE,16).map{|x,y| Geom::Point3d.new(x.mm,y.mm,ZFB.mm)}); bf.erase! if bf&&bf.valid?
    nf = ng.entities.grep(Sketchup::Face).max_by{|q| q.area}; nf.reverse! if nf.normal.z>0; nf.pushpull(NH.mm)
    ng.name = "웰드너트_M16_#{nm}#{i+1}"
  end

  par.name = "연결브라켓_L_#{nm}_20260919"
  rep << [nm, par, hy, ytan, yi, yend]
end
m.commit_operation

dims = {}
rep.each do |nm, par, hy, ytan, yi, yend|
  b = par.bounds
  subs = par.entities.grep(Sketchup::Group)
  dims[nm] = {
    '길이x'  => (b.max.x-b.min.x).to_mm.round(3),
    '폭y'    => (b.max.y-b.min.y).to_mm.round(3),
    '전고z'  => (b.max.z-b.min.z).to_mm.round(3),
    '플랜지폭'=> (ytan-yend).abs.round(3),
    '날개높이'=> (ZTAN-ZBOT).round(3),
    '홀수'   => 3, '너트수' => subs.count{|g| g.name.to_s.start_with?('웰드너트')},
    '홀x'    => HXS, '피치' => (HXS[1]-HXS[0]).round(3),
    '홀연단x'=> [(HXS[0]-XL).round(2), (XR-HXS[2]).round(2)],
    '홀연단y'=> [(hy-yend).abs.round(2), (ytan-hy).abs.round(2)],
    '두께T'  => T, '내R' => RI, '날개구멍' => 0
  }
  puts "#{par.name} 조각solid=#{subs.map{|g| g.manifold?}.inspect} bbox x %.2f..%.2f y %.2f..%.2f z %.2f..%.2f" %
    [b.min.x.to_mm,b.max.x.to_mm,b.min.y.to_mm,b.max.y.to_mm,b.min.z.to_mm,b.max.z.to_mm]
  puts "   #{dims[nm].inspect}"
end
diff = dims['A'].keys.reject{|k| dims['A'][k] == dims['B'][k]}
puts "A/B 규격 불일치 항목 = #{diff.inspect} (개수 #{diff.size})"
m.save
puts "SAVED #{File.mtime(m.path)} TOP=#{m.entities.count}"
nil
