#------------------------------------------------------------------------------------------------ # Permission to use, copy, modify, and distribute this software for # any purpose and without fee is hereby granted. #------------------------------------------------------------------------------------------------ # THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. #------------------------------------------------------------------------------------------------ # IT WAS CREATED AND TESTED IN A WINDOWS ENVIRONMENT ONLY AND MAY NOT FUNCTION ON A MAC. #------------------------------------------------------------------------------------------------ # THIS PLUGIN IS ANOTHER FIGMENT OF MY IMAGENATION AND IS NOT BASED ON OR COMPLY WITH ANYTHING! #------------------------------------------------------------------------------------------------ # Name: Face2Frame IV # By: sdmitch # Usage: Add a stud wall framework to the selected face. # Note: I am not an architech or carpenter. What this plugin creates is my interpretation of # what a stud wall should look like and does not attempt to comply with accepted building # practices or standards. Use them at your own risk. # # Date: Mar 2013 #------------------------------------------------------------------------------------------------ require 'Sketchup' # ------------------ MENU SETUP ---------------------- # unless $sdm_tools_menu $sdm_tools_menu = UI.menu("Plugins").add_submenu("SDM Tools") $sdm_Edge_tools = $sdm_tools_menu.add_submenu("Edge Tool") $sdm_Face_tools = $sdm_tools_menu.add_submenu("Face Tool") $sdm_CorG_tools = $sdm_tools_menu.add_submenu("CorG Tool") $sdm_Misc_tools = $sdm_tools_menu.add_submenu("Misc Tool") end unless file_loaded?(__FILE__) sub=$sdm_Face_tools.add_submenu("Face2Frame") sub.add_item("Frame It") { Sketchup.active_model.select_tool SDM::Face_To_Frame.new } sub.add_item("Brace It") { Sketchup.active_model.select_tool SDM::Corner_Brace.new } sub.add_item("Material") { SDM::Estimate_Materials.main } file_loaded(__FILE__) end # ------------------------------------------------------ # module SDM class Face_To_Frame @@dlg=nil def initialize @mod=Sketchup.active_model @ent=@mod.active_entities @sel=@mod.selection @vue=@mod.active_view @ip=Sketchup::InputPoint.new @wall_type = "Ext" #unless @wall_type @stud_size = "2X6" #unless @stud_size; @stud_space=16.inch #unless @stud_space @header_size = "2X8" #unless @header_size @corner_type = "A" @thickness=0.0 @corner_edges=[]; @tpcnt=2 self.reset end def activate unless @@dlg @dlg=UI::WebDialog.new("", false,"",30,30,300,500,true) @dlg.set_html( "
Face to Frame Wall Type:

Stud Size:

Stud Spacing:

Header Size:

Ext Corner:

Sheeting:

" ) RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show() @dlg.add_action_callback("face2frame") {|d,p| @wall_type=p.split("&")[0].split("=")[1]; #puts "wall type=#{@wall_type}" @stud_size=p.split("&")[1].split("=")[1]; #puts "stud_size=#{@stud_size}" @stud_space=p.split("&")[2].split("=")[1].to_l; #puts "stud_space=#{@stud_space}" @header_size=p.split("&")[3].split("=")[1]; #puts "header size=#{@header_size}" @corner_type=p.split("&")[4].split("=")[1]; #puts "corner type=#{@corner_type}" @thickness=p.split("&")[5].split("=")[1].to_f*0.250; #puts "thickness=#{@thickness}" @wall_type=="Ext" ? @tpcnt=2 : @tpcnt=1 } @@dlg=true end end def reset @sel.clear @status = 0 @status_text = "Pick a Face" end def onMouseMove(flags, x, y, view) @ip.pick view,x,y; view.tooltip = @ip.tooltip; view.refresh Sketchup::set_status_text @status_text @ip.face ? (@sel.add @ip.face) : @sel.clear end def onLButtonDown(flags, x, y, view) ph = view.pick_helper; ph.do_pick x,y; best=ph.best_picked if @status==0 && best.class==Sketchup::Face @mod.start_operation "Face2Frame" fgrp = @ent.add_group; @fge = fgrp.entities; fgrp.name = "Frame" face = best;norm=face.normal; btmz=face.bounds.min.z;topz=face.bounds.max.z; dz = topz - btmz case @stud_size when "2X2" : dx = 1.500.inch; dy = 1.500.inch; # 38 x 38 mm when "2X4" : dx = 1.500.inch; dy = 3.500.inch; # 38 x 89 mm when "2X6" : dx = 1.500.inch; dy = 5.500.inch; # 38 x 140 mm else UI.messagebox "stud_size #{@stud_size} not found"; return end case @header_size when "2X6" : hx = 1.500.inch; hy = 5.500.inch; # 38 x 140 mm when "2X8" : hx = 1.500.inch; hy = 7.250.inch; # 38 x 184 mm when "2X10" : hx = 1.500.inch; hy = 9.250.inch; # 89 x 235 mm when "4X6" : hx = 3.500.inch; hy = 5.500.inch; # 89 x 140 mm else UI.messagebox "header_size #{@header_size} not found"; return end self.draw_studs(face,dx,dy) ### process loops, all inner loops are assumed to be windows for loop in face.loops if loop.outer? for edge in loop.edges p,v=edge.line;pts=[] if v.z.abs < 0.5 # horizontal edge za,xa,ya=norm.axes; tp = p.offset(v).offset(xa) xa.reverse! if face.classify_point(tp)==16 if p.z > btmz && p.z < topz # door header? # add first header pts=[]; pts< 2 || dy < 2 # add 1/2" plywood spacer between headers pts=[];pts< 0.0 pts=[]; pts<a[1]} edgs=whsh.sort{|a,b| b[1]<=>a[1]}.map {|x| x[0]} # add header to window edg=edgs[0];p,v=edg.line; hz = p.z - btmz za,xa,ya=norm.axes tp=p.offset(v,dy).offset(xa,dx); xa.reverse! if face.classify_point(tp)==16; pts=[]; pts< 2 || dy < 2 # add 1/2" plywood spacer between headers pts=[];pts< 0.0 tp=p.offset(v,dy).offset(xa,dx); xa.reverse! if face.classify_point(tp)==16; pts=[]; pts< 0.5 || x.normal.parallel?(face.normal) || x.bounds.depth < face.bounds.depth} faces.each{|f| f.pushpull -dy} end end ### ### 2x4 Corners ### def A_2X4(vx,vy,p,v,dx,dy) studs=[] pts=[];pts< 0.0 pts=[];pts<<@pt0.offset(vz,0.01) pts< 0.0 pts=[];pts<<@pt0 pts<