Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original
SDM_FloorGenerator.rb #------------------------------------------------------------------------------------------------ # 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. #------------------------------------------------------------------------------------------------ # THIS PLUGIN IS ANOTHER FIGMENT OF MY IMAGENATION AND IS NOT BASED ON OR COMPLY WITH ANYTHING! #------------------------------------------------------------------------------------------------ # IT WAS CREATED AND ONLY TESTED IN A WINDOWS ENVIRONMENT AND MAY NOT FUNCTION ON A MAC. #------------------------------------------------------------------------------------------------ # Name: SDM_FloorGenerator # By: sdmitch # Usage: Plugins>SDM Tools>Face Tool>FloorGenerator # Note: The grid pattern will be placed on the side of the face picked starting at the # closest corner to the pick point if origin corner is selected. The grid pattern can # be placed on faces of any orientation,ie vertical or horizontal. The grid pattern # will be painted with the current material, random color or material as selected. # The materials to be randomly applied may be in any folder. The Material Picker window # has multiple selection capability using the Ctrl or Shift Key. Ctrl+A does not work! # The Clapboard pattern can only be placed on a VERTICAL face. # Ceated: Jun 2015 # Updated: Mar 2017 #------------------------------------------------------------------------------------------------ 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__) $sdm_Face_tools.add_item('FloorGenerator') { Sketchup.active_model.select_tool SDM::SDM_FloorGenerator.new } tb=UI::Toolbar.new("FlrGen") cmd=UI::Command.new("FlrGen") { Sketchup.active_model.select_tool SDM::SDM_FloorGenerator.new } cmd.small_icon=cmd.large_icon=File.join(File.dirname(__FILE__).gsub('\\','/'),"FG_Icons/Brick.jpg") cmd.tooltip="Floor Generator";tb.add_item cmd;tb.show unless tb.get_last_state==0 file_loaded(__FILE__) end # ------------------------------------------------------ # module SDM extend self class SDM_FloorGenerator @@dlg_FG_Main=@@opt=nil def initialize @mod=Sketchup.active_model @ent=@mod.active_entities @sel=@mod.selection @vue=@mod.active_view @ip=Sketchup::InputPoint.new @colors=Sketchup::Color.names @separator = begin;'1.0'.to_l;'.';rescue;',';end @icons = File.join(File.dirname(__FILE__).gsub('\\','/'),"FG_Icons/"); #puts @icons RUBY_PLATFORM =~ /(darwin)/ ? @font="Helvetica" : @font="Arial" @current_units=Sketchup.active_model.options["UnitsOptions"]["LengthUnit"] @current_precision=Sketchup.active_model.options["UnitsOptions"]["LengthPrecision"] @@opt ||= "Tile"; @@opt=Sketchup.read_default("FloorGenerator","",@@opt) self.dialog; self.source_of_textures if @app == "Rand_Tex"; end def dialog @@dlg_FG_Main=UI::WebDialog.new("FloorGenerator", false,"BTW",220,600,10,10,true) @failed=false; update_wd @@dlg_FG_Main.add_action_callback("OptionChanged") {|d,p| var,val = p.split("="); update=false; puts p case var when "CBT" then @cbt = val.to_l when "CBW" then @cbw = val.to_l when "CBO" then @cbo = val.to_l when "BTL" then @GX = val.to_l when "BTW" then @GY = val.to_l when "BGW" then @GW = val.to_l;@HW = @GW/2.0 when "BGD" then @GD = val.to_l when "BWB" then @bwb=val.to_i when "ORG" then @spt = val when "ROT" then @rot = val when "MAT" then @app = val; update=true; @app=='Rand_Tex' ? self.source_of_textures : @dlg_FG_Picker.close if @dlg_FG_Picker when "IPD" then @ipd = val.to_f; @ipd = [@ipd,0.1].max; @ipd = [@ipd,1.0].min when "FLW" then @flw=="Yes" ? @flw="No" : @flw="Yes"; when "FWW" then @fww=="Yes" ? @fww="No" : @fww="Yes"; when "FWT" then @fwt=="Yes" ? @fwt="No" : @fwt="Yes"; when "RDS" then @rds=val.to_i when "TSZ" then @tsz=val when "WAG" then @rtr=val when "ATE" then @ate=="Yes" ? @ate="No" : @ate="Yes"; when "WIG" then @rtt=="Yes" ? @rtt="No" : @rtt="Yes"; update=true when "RTI" then @rti=val.to_l; @rti>0 ? @rtt="Yes" : @rtt="No" when "WOB" then @rfr=="Yes" ? @rfr="No" : @rfr="Yes"; update=true when "BVL" then @bev=="Yes" ? @bev="No" : @bev="Yes"; update=true when "R2R" then @r2r=val.to_f;r2r=val when "TWA" then @twa=val.to_f when "RIn" then @rin=val.to_l;@rin=[@rin,0].max when "RIx" then @rix=val.to_l;@rix=[@rix,@GD].min when "BVS" then @bvs=val.to_l; when "CBF" then @cbf=="Yes" ? @cbf="No" : @cbf="Yes"; when "CIG" then @cig=="Yes" ? @cig="No" : @cig="Yes"; end tbx=@GX.to_s.gsub('"','\"'); tby=@GY.to_s.gsub('"','\"'); twa=@twa.to_s; @txs=0;rds=@rds.to_s; r2r=@r2r.to_s (txw,txh=@tsz.split(","); if txh then @txs=[txw.to_l,txh.to_l] else @txs=@tsz.to_l end) if @tsz && @tsz != "0" gw=@GW.to_s.gsub('"','\"'); gd=@GD.to_s.gsub('"','\"');txs=@tsz.gsub('"','\"') if @tsz;bwb=@bwb.to_s; txs=@txs.to_s rin=@rin.to_s.gsub('"','\"'); rix=@rix.to_s.gsub('"','\"'); bvs=@bvs.to_s.gsub('"','\"'); ipd = @ipd.to_s; rti=@rti.to_s.gsub('"','\"'); cbt=@cbt.to_s.gsub('"','\"'); cbw=@cbw.to_s.gsub('"','\"'); cbo=@cbo.to_s.gsub('"','\"'); if @separator == ',' tbx.gsub!('.',','); tby.gsub!('.',','); gw.gsub!('.',','); gd.gsub!('.',','); txs.gsub!('.',','); cbo.gsub!('.',','); rin.gsub!('.',','); rix.gsub!('.',','); bvs.gsub!('.',','); rti.gsub!('.',','); cbt.gsub!('.',','); cbw.gsub!('.',','); end # @spt,@rot,@app,@flw,@fww,r2r,@rtt,@rtr,txs,@rfr,@bev,twa,tbx,tby,gw,gd,bwb,@ate,@fwt,rds,rin,rix,bvs,ipd,rti,@cbf,@cig,cbt,cbw,cbo @defaults=[@spt,@rot,@app,@flw,@fww,r2r,@rtt,@rtr,txs,@rfr,@bev,twa,tbx,tby,gw,gd,bwb,@ate,@fwt,rds,rin,rix,bvs,ipd,rti,@cbf,@cig,cbt,cbw,cbo] Sketchup.write_default("FloorGenerator",@@opt,@defaults); update_wd if update } @@dlg_FG_Main.add_action_callback("PatternChanged") {|d,p| @@opt=p; if @@opt=="Reset" then ["Brick","Tile","Wood","Tweed","Hbone","BsktWv","HpScth1","HpScth2","Rand_Tex"].each{|o| Sketchup.write_default("FloorGenerator",o,nil)}; ["HpScth3","HpScth4","IrPoly","Hexgon","Octgon","Wedge","I_Block","Diamonds","Clapbrd"].each{|o| Sketchup.write_default("FloorGenerator",o,nil)}; @@opt="Tile"; end Sketchup.write_default("FloorGenerator","",@@opt) @failed=false; update_wd self.source_of_textures if @app == "Rand_Tex" } @@dlg_FG_Main.add_action_callback("ChangeSource") {|d,p| self.source_of_textures } end def update_wd if Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]>1 Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]=2; #millimeters Sketchup.active_model.options["UnitsOptions"]["LengthPrecision"]=1 # @spt,@rot, @app,@flw,@fww, r2r,@rtt,@rtr,txs,@rfr,@bev, twa, tbx, tby, gw, gd,bwb,@ate, @fwt,rds,rin,rix,bvs,ipd,rti,@cbf,@cig, cbt, cbw, cbo @defaults=["Corner","0","Current","No","No","50","No","No","0","No","No","30","150","50","6","6","3","No","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Brick" || @@opt=="Wedge"; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","300","300","6","3","3","No","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Tile" || @@opt=="HpScth4"; @defaults=["Corner","0","Current","Yes","Yes","0","No","No","0","No","No","30","2000","100","3","3","3","No","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Wood" || @@opt=="Clapbrd"; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","150","50","12","6","3","Yes","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Tweed" @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","200","100","12","6","3","Yes","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Hbone" || @@opt=="BsktWv" || @@opt=="I_Block" ; @defaults=["Center","0","Current","No","No","0","No","No","0","No","No","30","300","300","12","6","3","Yes","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="HpScth1" || @@opt=="HpScth2"; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","600","600","6","3","3","No","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="HpScth3"; @defaults=["Center","0","Current","No","No","0","No","No","0","No","No","30","300","0","12","6","3","No","Yes","0","0","3","6","1","1",'No','No','25','150','13'] if @@opt=="Hexgon" || @@opt=="Octgon" || @@opt=="IrPoly" || @@opt=="Diamonds"; else Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]=0; #inches Sketchup.active_model.options["UnitsOptions"]["LengthPrecision"]=3 # @spt,@rot, @app,@flw,@fww, r2r,@rtt,@rtr,txs,@rfr,@bev, twa, tbx, tby, gw, gd,bwb,@ate, @fwt,rds,rin,rix,bvs,ipd,rti,@cbf,@cig, cbt, cbw, cbo @defaults=["Corner","0","Current","No","No","50","No","No","0","No","No","30","6.0","2.0","0.25","0.25","3","No","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Brick" || @@opt=="Wedge"; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","12.0","12.0","0.25","0.125","3","No","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Tile" || @@opt=="HpScth4"; @defaults=["Corner","0","Current","Yes","Yes","0","No","No","0","No","No","30","60.0","3.0","0.125","0.125","3","No","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Wood" || @@opt=="Clapbrd" @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","6.0","2.0","0.5","0.25","3","Yes","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Tweed"; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","8.0","4.0","0.5","0.25","3","Yes","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Hbone" || @@opt=="BsktWv" || @@opt=="I_Block" ; @defaults=["Center","0","Current","No","No","0","No","No","0","No","No","30","12.0","12.0","0.5","0.25","3","Yes","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="HpScth1" || @@opt=="HpScth2" || @@opt=='HpScth3'; @defaults=["Corner","0","Current","No","No","0","No","No","0","No","No","30","24.0","24.0","0.25","0.125","3","No","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="HpScth3"; @defaults=["Center","0","Current","No","No","0","No","No","0","No","No","30","12.0","0.0","0.5","0.25","3","No","Yes","0","0","0.125","0.25","1","1",'No','No','1.0','6.0','0.5'] if @@opt=="Hexgon" || @@opt=="Octgon" || @@opt=="IrPoly" || @@opt=="Diamonds"; end begin @spt,@rot,@app,@flw,@fww,r2r,@rtt,@rtr,txs,@rfr,@bev,twa,tbx,tby,gw,gd,bwb,@ate,@fwt,rds,rin,rix,bvs,ipd,rti,@cbf,@cig,cbt,cbw,cbo=Sketchup.read_default("FloorGenerator",@@opt,@defaults) @GX=tbx.to_l;@GY=tby.to_l;@GW=gw.to_l;@HW=@GW/2.0;@GD=gd.to_l;@bwb=bwb.to_i; @rds=rds.to_i; @rin = rin.to_l; @rix = rix.to_l; @bvs = bvs.to_l; @ipd = ipd.to_f txw,txh=txs.split(","); if txh then @txs=[txw.to_l,txh.to_l] else @txs=txs.to_l end; @cbt=cbo.to_l; @cbw=cbw.to_l; @cbo=cbo.to_l @twa=twa.to_f; @r2r=r2r.to_f; @rti=rti.to_l; rescue puts "read_default failed" if @failed ["Brick","Tile","Wood","Tweed","Hbone","BsktWv","HpScth1","HpScth2","Rand_Tex"].each{|o| Sketchup.write_default("FloorGenerator",o,nil)}; ["HpScth3","HpScth4","IrPoly","Hexgon","Octgon","Wedge","I_Block","Diamonds","Clapbrd"].each{|o| Sketchup.write_default("FloorGenerator",o,nil)}; @@opt="Tile"; Sketchup.write_default("FloorGenerator","",@@opt); @failed=false;update_wd else Sketchup.write_default("FloorGenerator","",@@opt) Sketchup.write_default("FloorGenerator",@@opt,@defaults) @failed=true; update_wd end end @@dlg_FG_Main.set_html(get_html) Sketchup.platform == :platform_win ? @@dlg_FG_Main.show : @@dlg_FG_Main.show_modal end def get_html html="<html><body style='background-color:powderblue' ><form style='font-family:#{@font};font-size:70%;color:black' >" html+=pattern_html case @@opt when 'Brick','Tile';html+=brick_tile_html when 'Wood';html+=wood_html when 'Tweed'; html+=tweed_html when 'Hbone'; html+=herringbone_html when 'BsktWv';html+=basketweave_html when 'HpScth1';html+=hopscotch_html when 'HpScth2';html+=hopscotch_html when 'HpScth3';html+=hopscotch_html when 'HpScth4';html+=hopscotch_html when 'IrPoly';html+=irpoly_html when 'Hexgon';html+=hexoctdia_html when 'Octgon';html+=hexoctdia_html when 'Wedge';html+=hopscotch_html when 'I_Block';html+=hopscotch_html when 'Diamonds';html+=hexoctdia_html when 'Clapbrd';html+=clapboard_html else;UI.messagebox "#{@@opt} not found" end html+="</body></html>" html+=script_html end def script_html html=<<-HTML <script type='text/javascript'> function patternchanged(value) { window.location='skp:PatternChanged@'+value; }; function optionchanged(name,value) { window.location='skp:OptionChanged@'+name+'='+value; }; function ChangeSource() { window.location='skp:ChangeSource@'; }; </script> HTML end def pattern_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Pattern </b></legend> <select onChange='patternchanged(value)'> <option value='Brick' #{@@opt=='Brick' ? 'selected' : ''}>Brick</option> <option value='Tile' #{@@opt=='Tile' ? 'selected' : ''}>Tile</option> <option value='Wood' #{@@opt=='Wood' ? 'selected' : ''}>Wood</option> <option value='Tweed' #{@@opt=='Tweed' ? 'selected' : ''}>Tweed</option> <option value='Hbone' #{@@opt=='Hbone' ? 'selected' : ''}>Herringbone</option> <option value='BsktWv' #{@@opt=='BsktWv' ? 'selected' : ''}>Basket Weave</option> <option value='HpScth1' #{@@opt=='HpScth1' ? 'selected' : ''}>Hopscotch1</option> <option value='HpScth2' #{@@opt=='HpScth2' ? 'selected' : ''}>HopScotch2</option> <option value='HpScth3' #{@@opt=='HpScth3' ? 'selected' : ''}>HopScotch3</option> <option value='HpScth4' #{@@opt=='HpScth4' ? 'selected' : ''}>HopScotch4</option> <option value='IrPoly' #{@@opt=='IrPoly' ? 'selected' : ''}>Irregular Polygons</option> <option value='Hexgon' #{@@opt=='Hexgon' ? 'selected' : ''}>Hexagons</option> <option value='Octgon' #{@@opt=='Octgon' ? 'selected' : ''}>Octagons</option> <option value='Wedge' #{@@opt=='Wedge' ? 'selected' : ''}>Wedges</option> <option value='I_Block' #{@@opt=='I_Block' ? 'selected' : ''}>I_Block</option> <option value='Diamonds' #{@@opt=='Diamonds' ? 'selected' : ''}>Diamonds</option> <option value='Clapbrd' #{@@opt=='Clapbrd' ? 'selected' : ''}>Clapboard</option> <option value='Reset'>Reset</option> </select> <!-- Pattern Icons --> #{@@opt=='Brick' ? "<img src='#{@icons}Brick.jpg' align='top'/>" : ''} #{@@opt=='Tile' ? "<img src='#{@icons}Tile.jpg' align='top'/>" : ''} #{@@opt=='Wood' ? "<img src='#{@icons}Wood.jpg' align='top'/>" : ''} #{@@opt=='Tweed' ? "<img src='#{@icons}Tweed.jpg' align='top'/>" : ''} #{@@opt=='Hbone' ? "<img src='#{@icons}Hbone.jpg' align='top'/>" : ''} #{@@opt=='BsktWv' ? "<img src='#{@icons}BsktWv.jpg' align='top'/>" : ''} #{@@opt=='HpScth1' ? "<img src='#{@icons}HpScth1.jpg' align='top'/>" : ''} #{@@opt=='HpScth2' ? "<img src='#{@icons}HpScth2.jpg' align='top'/>" : ''} #{@@opt=='HpScth3' ? "<img src='#{@icons}HpScth3.jpg' align='top'/>" : ''} #{@@opt=='HpScth4' ? "<img src='#{@icons}HpScth4.jpg' align='top'/>" : ''} #{@@opt=='IrPoly' ? "<img src='#{@icons}IrPoly.jpg' align='top'/>" : ''} #{@@opt=='Hexgon' ? "<img src='#{@icons}Hexgon.jpg' align='top'/>" : ''} #{@@opt=='Octgon' ? "<img src='#{@icons}Octgon.jpg' align='top'/>" : ''} #{@@opt=='Wedge' ? "<img src='#{@icons}Wedge.jpg' align='top'/>" : ''} #{@@opt=='I_Block' ? "<img src='#{@icons}I_Block.jpg' align='top'/>" : ''} #{@@opt=='Diamonds' ? "<img src='#{@icons}Diamonds.jpg' align='top'/>" : ''} #{@@opt=='Clapbrd' ? "<img src='#{@icons}Clapboard.jpg' align='top'/>" : ''} </fieldset> HTML end def brick_tile_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed </td></tr> <tr><td align='right' width=54>\% Offset:</td> <td><input type='text' name='R2R' value='#{@r2r}' size=4 onChange='optionchanged(name,value)' /></td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br>#{@@opt=='IrPoly' ? '<!--' : ''} <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr=='No' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr=='No' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev=='No' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev=='No' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> </form> HTML end def wood_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FLW' value='Yes' #{@flw=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FWW' value='Yes' #{@fww=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed </td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br>#{@@opt=='IrPoly' ? '<!--' : ''} <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def tweed_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FLW' value='Yes' #{@flw=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FWW' value='Yes' #{@fww=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed</td></tr> <tr><td align='right' width=54>Angle:</td> <td><input type='text' name='TWA' value='#{@twa}' size=4 onChange='optionchanged(name,value)' /></td></tr> </table> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br>#{@@opt=='IrPoly' ? '<!--' : ''} <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def herringbone_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FLW' value='Yes' #{@flw=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <td><input type='checkbox' name='FWW' value='Yes' #{@fww=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Fixed</td></tr> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed</td></tr> </table> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br> <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def basketweave_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed </td></tr> <tr><td align='right' width=54>Weave Count:</td> <td><input type='text' name='BWB' value='#{@bwb}' size=4 onChange='optionchanged(name,value)' /></td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br>#{@@opt=='IrPoly' ? '<!--' : ''} <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def hopscotch_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right'>Width:</td> <td><input type='text' name='BTW' value='#{@GY}' size=4 onChange='optionchanged(name,value)' /></td> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed </td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br>#{@@opt=='IrPoly' ? '<!--' : ''} <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='ATE' value='Yes' #{@ate=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Align Texture to Longest Edge<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def irpoly_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed</td></tr> <td align='right' width=54>Pt Density(0.1-1.0)</td> <td><input type='text' name='IPD' value='#{@ipd}' size=2 onChange='optionchanged(name,value)'/></td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def hexoctdia_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=60>Side Length:</td> <td><input type='text' name='BTL' value='#{@GX}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Width:</td><td> <input type='text' name='BGW' value='#{@GW}' size=4 onChange='optionchanged(name,value)' /></td></tr> <tr><td align='right' width=54>Gap Depth:</td><td> <input type='text' name='BGD' value='#{@GD}' size=4 onChange='optionchanged(name,value)' /></td><td> <input type='checkbox' name='FWT' value='Yes' #{@fwt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Fixed</td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <select name='ORG' style='width:90px' onChange='optionchanged(name,value)'> <option value='Corner' #{@spt=='Corner' ? 'selected' : ''}>Corner</option> <option value='Center' #{@spt=='Center' ? 'selected' : ''}>Center</option> </select> : Grid Origin<br> <select name='ROT' style='width:90px' onChange='optionchanged(name,value)'> <option value='0' #{@rot=='0' ? 'selected' : ''}>0</option> <option value='45' #{@rot=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rot=='90' ? 'selected' : ''}>90</option> </select> : Grid Rotation<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option><br> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : ''}<br><hr> <input type='text' name='RDS' value='#{@rds}' size=2 onChange='optionchanged(name,value)'/> : Random Seed<br><hr> <input type='text' name='TSZ' value='#{@txs}' size=5 onChange='optionchanged(name,value)'/> : Texture Size (w,h)<br> <input type='checkbox' name='WIG' value='Yes' #{@rtt=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'>Random Position Texture </input> #{@rtt=='No' ? '<!--' : ''} Inc: <input type='text' name ='RTI' value='#{@rti}' size=3 onchange='optionchanged(name,value)'/> #{@rtt=='No' ? '-->' : ''}<br> <select name='WAG' style='width:60px' onChange='optionchanged(name,value)'> <option value='No' #{@rtr=='No' ? 'selected' : ''}>No</option> <option value='30' #{@rtr=='30' ? 'selected' : ''}>30</option> <option value='45' #{@rtr=='45' ? 'selected' : ''}>45</option> <option value='90' #{@rtr=='90' ? 'selected' : ''}>90</option> <option value='180' #{@rtr=='180' ? 'selected' : ''}>180</option> <option value='Rand' #{@rtr=='Rand' ? 'selected' : ''}>Rand</option> </select> : Random Rotation<br> <hr> <input type='checkbox' name='WOB' value='Yes' #{@rfr=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Random Imperfections<br> #{@rfr!='Yes' ? '<!--' : ''} Min:<input type='text' name='RIn' value='#{@rin}' size=4 onChange='optionchanged(name,value)'/> Max:<input type='text' name='RIx' value='#{@rix}' size=4 onChange='optionchanged(name,value)'/> <br> #{@rfr!='Yes' ? '-->' : ''} <input type='checkbox' name='BVL' value='Yes' #{@bev=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Add Bevel to #{@@opt}<br> #{@bev!='Yes' ? '<!--' : ''} Size:<input type='text' name='BVS' value='#{@bvs}' size=4 onChange='optionchanged(name,value)'/><br> #{@bev!='Yes' ? '-->' : ''} <input type='checkbox' name='CBF' value='Yes' #{@cbf=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Behind Face<br> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> </fieldset> HTML end def clapboard_html html=<<-HTML <fieldset> <legend style='font-size:125%;color:red'><b> Size </b></legend> <table style='font-size:100%'> <tr><td align='right' width=60>Thickness:</td> <td><input type='text' name='CBT' value='#{@cbt}' size=4 onChange='optionchanged(name,value)'/></td></tr> <tr><td align='right' width=60>Width:</td> <td><input type='text' name='CBW' value='#{@cbw}' size=4 onChange='optionchanged(name,value)'/></td></tr> <tr><td align='right' width=60>Overlap:</td> <td><input type='text' name='CBO' value='#{@cbo}' size=4 onChange='optionchanged(name,value)'/></td></tr> </table> </fieldset> <fieldset> <legend style='font-size:125%;color:red'><b> Options </b></legend> <input type='checkbox' name='CIG' value='Yes' #{@cig=='Yes' ? 'checked' : ''} onClick='optionchanged(name,value)'/>Create Individual Groups<br> <select name='MAT' style='width:90px' onChange='optionchanged(name,value)'> <option value='Current' #{@app=='Current' ? 'selected' : ''}>Current</option> <option value='Rand_Clr' #{@app=='Rand_Clr' ? 'selected' : ''}>Rand_Clr</option> <option value='Rand_Tex' #{@app=='Rand_Tex' ? 'selected' : ''}>Rand_Tex</option> </select> : Material#{@app!='Rand_Tex' ? '<!--' : '<br>'}   <button id='RTS' onclick='ChangeSource(id)'>Source</button>#{@app!='Rand_Tex' ? '-->' : '<br>'} <textarea name='help' rows="10" cols="20">This pattern can only be placed on a vertical face. If you get a 'beep' that means the face you are trying to select is not vertical.</textarea><br> </fieldset> HTML end def onMouseMove(flags, x, y, view) @ip.pick view,x,y; view.tooltip = @ip.tooltip; view.refresh Sketchup::set_status_text "Select Grid Pattern, change options or sizes if needed then select Face for #{@@opt} pattern" end def onLButtonDown(flags, x, y, view) ph = view.pick_helper; ph.do_pick x,y; face=ph.best_picked; @cp=@ip.position; if face.is_a?(Sketchup::Face) # JQL use material from picked face if defined @mat = @mod.materials.current @mat = face.back_material if face.back_material @mat = face.material if face.material # if @@opt=='Clapbrd' if face.normal.z==0 @mod.start_operation "SDM_FloorGenerator",true self.cb_main(face) @mod.commit_operation else UI.beep; UI.messagebox "Clapboards can only be placed on a vertical face" end return end dmax = [@GX,@GY].max; if (face.bounds.diagonal >= dmax); # make sure the rectangle is big enough to sub-divide unless @@opt=="BsktWv" || @@opt=='Hexgon' || @@opt=='Octgon' || @@opt=='IrPoly' || @@opt=='Diamonds' torb = (face.area/(@GX*@GY)).ceil if (@GX <= 1 || @GY <= 1) || ( torb > 500) then return if UI.messagebox("Tile demensions may be to small. #{torb} #{@@opt} needed. Continue?",MB_YESNO)==7 view.refresh; end end @mod.start_operation "SDM_FloorGenerator",true eye = @vue.camera.eye; ctr=face.bounds.center;@rds>0 ? srand(@rds) : srand; face.reverse! if ((ctr.vector_to(eye)).angle_between(face.normal))>Math::PI/2.0 @edges=face.edges;@norm=face.normal; l=0; fpts=[]; lpts=[] # save material applied to picked face @front_mat = face.material; @back_mat = face.back_material #save original picked face if @@opt=="Brick" for loop in face.loops for v in loop.vertices lpts<<v.position if v.position end fpts[l]=lpts; lpts=[]; l +=1 end end if self.grid_data(face) # begin @ent.erase_entities(face); existing_faces=@ent.grep(Sketchup::Face); dump=@egrp.explode dump.grep(Sketchup::Edge).each{|e| e.find_faces}; created_faces=@ent.grep(Sketchup::Face) - existing_faces; cnt=0; max=created_faces.length;new_faces=[]; @rds>0 ? srand(@rds) : srand fgrp=@ent.add_group;@fge=fgrp.entities;@fgt=fgrp.transformation; @app = "current" if @app=='Rand_Tex' && @textures.length==0 created_faces.each{|f| cnt += 1; self.progress_bar(cnt,max,"#{@@opt} offsets"); f.reverse! unless f.normal.samedirection? @norm; @GW>0 ? pts=self.g_offset(f,@HW) : pts=f.outer_loop.vertices.map{|v|v.position} if pts g = @fge.add_group; ge = g.entities face = g.entities.add_face(pts); new_faces << face face.reverse! unless face.normal.samedirection?(@norm) self.paint_it(face); old = ge.grep(Sketchup::Face) @fwt=='Yes' ? gd=@GD : (gd=@GD+(@GD*rand*(rand<=>0.5))); face.pushpull gd; new = ge.grep(Sketchup::Face) - old new.reject!{|nf| !nf.normal.parallel?(@norm)} if new.length==1 face = new[0] self.wig(face) if @rtt=="Yes" && @rti>0 self.wag(face) unless @rtr=="No" self.wob(g,-1) if @rfr=="Yes" self.bev(face,@bvs) if @bev=="Yes" end g.explode unless @cig=='Yes' end } Sketchup.set_status_text "finishing and cleaning up" dump.each{|e| @ent.erase_entities(e) if e.valid? && e.is_a?(Sketchup::Edge)}; #delete grid lines #re-create original picked face if @@opt=="Brick" for i in 0...fpts.length f=@fge.add_face(fpts[i]) @fge.erase_entities(f) if i > 0 end end # JQL - create pattern behind the original picked face if @cbf=='Yes' cf=(@ent.grep(Sketchup::Face) - existing_faces)[0]; for l in cf.loops nf=@fge.add_face(l.vertices.map{|v|v.position.transform(@fgt.inverse)}); l.outer? ? nf.reverse! : nf.erase!; # leave face with default material to eliminate Z-fighting # l.outer? ? (nf.reverse!;nf.material=@front_material;nf.back_material=@back_mat) : nf.erase! end drop = @bev=='Yes' ? @GD+@bvs : @GD; vector = @norm.reverse; vector.length = drop @ent.transform_entities(Geom::Transformation.new(vector),fgrp); edges=cf.edges; cf.erase!; edges.each{|e|@ent.erase_entities(e) if e.faces.length==0} end # @mod.commit_operation # rescue Exception => e # @mod.abort_operation # UI.messagebox("Error #<#{e.class.name}:#{e.message}.>") # end end @last_opt = @@opt else UI.messagebox "This face is to small for a #{@GX} X #{@GY} #{@@opt} pattern.";return false end end end def cb_main(f) cb_spacing=@cbw-@cbo; lines = @ent.add_group; lent=lines.entities; ltrn=lines.transformation; minz = f.bounds.min.z; maxz = f.bounds.max.z norm = f.normal; norm.reverse! if norm.z < 0; xa,ya,za=norm.axes maxd = f.bounds.diagonal*2; ctr=f.bounds.center pt0 = ctr.offset(xa,-maxd/2).offset(ya,-maxd/2) pt0.z = (pt0.z/cb_spacing).floor*cb_spacing+@cbw/2 ny=(maxd/cb_spacing).ceil for n in 1..ny pt1=pt0.offset(xa,maxd) lent.add_face(self.makeaface(pt0,pt1,norm)) pt0.offset!(ya,cb_spacing) end cbgp = @ent.add_group; cbge=cbgp.entities; cbgt=cbgp.transformation for l in f.loops cbf = cbge.add_face(l.vertices.map{|v|v.position}) cbf.erase! unless l.outer? end lent.intersect_with(true,ltrn,cbge,cbgt,false,cbgp) faces = cbge.grep(Sketchup::Face); angle = Math.atan(@cbt/cb_spacing); #cbt = @cbt faces.each{|nf| rp = nf.bounds.max;xa,ya,za=nf.normal.axes; fgrp = cbge.add_group; fge = fgrp.entities cb = fge.add_face(nf.outer_loop.vertices.map{|v|v.position}) cb.pushpull @cbt; if nf.bounds.min.z==minz next elsif nf.bounds.min.z <= @cbw ang = angle elsif nf.bounds.max.z==maxz unless nf.bounds.depth<@cbw/3 spc = @cbt/Math.cos(angle)*Math.sin(angle) cbt = Math.sqrt(@cbt**2 - spc**2) ang = Math.atan(cbt/(nf.bounds.depth-spc)) end else cbt = @cbt/Math.cos(angle) ang = Math.atan(cbt/cb_spacing) end bf = fge.grep(Sketchup::Face).find_all{|x|x.normal.transform(cbgt).z<-0.99 && x.bounds.min.z==fgrp.bounds.min.z} bf.each{|x|x.pushpull @cbo} tr = Geom::Transformation.rotation(rp,xa,-ang) cbge.transform_entities(tr,fgrp) fgrp.explode if @cig=="No" } self.paint_it(cbgp); # cbgp.material=@mat lines.erase!; end def onRButtonDown(flags, x, y, view) onCancel(flags,view) end def onCancel(flags,view) Sketchup.send_action "selectSelectionTool:" end def deactivate(view) @dlg_FG_Picker.close if @dlg_FG_Picker @@dlg_FG_Main.close; @@dlg_FG_Main=nil Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]=@current_units Sketchup.active_model.options["UnitsOptions"]["LengthPrecision"] = @current_precision end def draw(view) if( @ip.valid? && @ip.display? ) @ip.draw(view) end if @ip.face pts = @ip.face.outer_loop.vertices.map{|v| v.position} view.line_width=3 view.drawing_color='yellow' view.draw GL_LINE_LOOP,pts end end # def source_of_textures ans = UI.inputbox(["Materials From:"],["Folder"],["Folder|Model"],"Random Textures Source") if ans @dlg_FG_Picker.close if @dlg_FG_Picker case ans[0] when "Folder" then self.materials_from_file; @options = @textures_from_file;self.pickMaterials; when "Model" then @options=Sketchup.active_model.materials.map{|m|m.name};self.pickMaterials; end end end # def materials_from_file @textures_from_file = []; @images = []; @image_path = File.dirname(__FILE__)+"/BTW_Textures/*.*" @image_path = Sketchup.read_default("FloorGenerator","Rand_Tex",@image_path) @image_path = (UI.openpanel("Random Texture Files",@image_path)) unless @image_path==nil image_folder = File.dirname(@image_path.gsub('\\','/'));@images = []; @images = Dir[image_folder+"/*.{jpg,png,tif,bmp,gif,tga,epx}"] @images.each{|i| @textures_from_file<<File.basename(i,'.*')}; if @textures_from_file[0] @textures_from_file.each_with_index{|name,i| unless @mod.materials[name] mat = @mod.materials.add(name) mat.texture = @images[i] mat.texture.size = @txs if @txs && @txs != 0 end } Sketchup.write_default("FloorGenerator","Rand_Tex",image_folder+"/*.*") else @app = "current" end else @app = "current" end end # def pickMaterials @dlg_FG_Picker=UI::WebDialog.new("Material Picker", false,"WDID",300,200,10,10,true) html = <<-HTML <!DOCTYPE html> <html lang="en-US"> <head> <meta charset="utf-8" /> <meta content="IE=edge" http-equiv="X-UA-Compatible" /> </head> <body> <form action='skp:selectMaterials@'> <select id='list' name='Material' multiple ></select> <br><br><input type='submit' name='submit' value='Select' /><br> </form> <script> function addToList(id,options) { var x = document.getElementById(id); for (i=0;i<options.length;i++){var option=document.createElement('option');option.text=options[i];x.add(option);}; x.selectIndex=0; }; </script> <script> window.location='skp:InitializeForm@'; </script> </body> </html> HTML @dlg_FG_Picker.set_html(html) RUBY_PLATFORM =~ /(darwin)/ ? @dlg_FG_Picker.show_modal() : @dlg_FG_Picker.show(); @dlg_FG_Picker.add_action_callback("InitializeForm") { @dlg_FG_Picker.execute_script("addToList('list',#{@options});"); }; @dlg_FG_Picker.add_action_callback("selectMaterials") {|d,p| p.gsub!("?",""); tokens=p.split("&"); #puts p @textures = [] tokens.each{|t| var,val = t.split("="); #puts t @textures << val if var=='Material' } }; end # ################################################## # Compute the data points of the grid ################################################## # def grid_data(face) pts=face.outer_loop.vertices.collect{|v| v.position} ndx=0; cp=1e6; ls=0.0; lp=pts.length-1; # assume regular 4 sided rectangle pts.each_with_index{|p,i| d=p.distance(pts[i-1])+p.distance(pts[i-lp]); ndx=i if d>ls; ls=[ls,d].max} ctr=face.bounds.center; ctr=ctr.project_to_plane face.plane unless ctr.on_plane? face.plane d1=pts[ndx].distance(pts[ndx-lp]); d2=pts[ndx].distance(pts[ndx-1]); if d1 >= d2 @v1=pts[ndx].vector_to(pts[ndx-lp]).normalize pol=ctr.project_to_line([pts[ndx],pts[ndx-lp]]) rot = @rot.to_f; @dx = d1; @dy = d2 else @v1=pts[ndx].vector_to(pts[ndx-1]).normalize pol=ctr.project_to_line([pts[ndx],pts[ndx-1]]); rot = -@rot.to_f; @dx = d2; @dy = d1 end @v2=pol.vector_to(ctr).normalize; @v3=face.normal unless @@opt=='IrPoly' if @rot != "0" tr=Geom::Transformation.rotation(ctr,@norm,rot.degrees) @v1.transform! tr; @v2.transform! tr end @cor = pts.min_by{|p|p.distance(@cp)} dx = @GX + @GW; dy = @GY + @GW; nx=(face.bounds.diagonal*1.5/dx).ceil;ny=(face.bounds.diagonal*1.5/dy).ceil; (nx *= 2 if @flw=="No"; ny *= 2 if @fww=="No") if @@opt=="Wood" pt0 = ctr.offset(@v1,-dx*(nx/2)).offset(@v2,-dy*(ny/2)) @data=[];row=[]; cnt=0; max=nx*ny; #@ent.add_cpoint(pt0) case @@opt when "Wood" yd = 0.0; @rds>0 ? srand(@rds) : srand for i in 0..ny p0=row[0]=pt0.offset(@v2,yd) d = 0.0; ty = dy for j in 1..nx tx=dx if j==1 begin tx=rand*dx end until tx>=dx*0.25 && tx<=dx*0.75 else if @flw=="No" begin tx=rand*dx end until tx>=dx*0.75 end end d += tx; row[j]=p0.offset(@v1,d) end if @fww=="No" begin ty=rand*dy end until ty>=dy*0.5 end row.push ty; yd += ty @data[i]=row;row=[] end when "Tweed" dx=@GY + @GW; dy=@GX + @GW; xd=dx/Math.cos(@twa.degrees) yd=dy*Math.cos(@twa.degrees) xx=dy*Math.sin(@twa.degrees) ny=((face.bounds.diagonal*1.5)/yd).ceil;nx=((face.bounds.diagonal*1.5)/xd).ceil; pt0 = ctr.offset(@v1,-(xd*(nx/2))).offset(@v2,-(yd*(ny/2))) for i in 0..ny row[0]=pt0.offset(@v2,yd*i) if i%2==1 then row[0].offset!(@v1,-xx) end for j in 1..nx row[j]=row[j-1].offset(@v1,xd) end @data[i]=row;row=[] end end end case @@opt when "Brick","Tile" ; self.brick_tile(face,dx,dy,nx,ny,pt0) when "Wood" ; self.wood(face,nx,ny) when "Tweed" ; self.tweed(face,nx,ny) when "Hbone" ; self.hbone(face) when "BsktWv" ; self.bsktwv(face,dx,dy) when "HpScth1"; self.hopscotch(face,dx,dy) when "HpScth2" ; self.hopscotch2(face,dx,dy) when 'HpScth3' ; self.hopscotch3(face) when "HpScth4" ; self.hopscotch4(face,dx,dy) when "Hexgon" ; self.hexagon(face,@GX) when "Octgon" ; self.octagon(face,@GX) when "IrPoly" ; self.irregular_polygons(face) when "Wedge" ; self.wedge(face,dx,dy) when "I_Block"; self.i_block(face,dx,dy) when "Diamonds" ; self.diamonds(face,@GX) when "Clapbrd"; self.cb_main(face) else puts "#{@@opt} not found";return false end return true end # ################################################## # Create brick/tile pattern grid on selected face ################################################## # def brick_tile(f,dx,dy,nx,ny,pt0) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation for i in 0..ny+1 p0=pt0.offset(@v2,dy*i);p1=p0.offset(@v1,dx*nx) tge.add_face(self.makeaface(p0,p1,@norm)) unless i>0 p1=p0.offset(@v2,dy*ny) tge.add_face(self.makeaface(p0,p1,@norm)) end end cnt=0; max=nx*ny; md=1e9 for i in 0..ny p0=pt0.offset(@v2,dy*i) i>0 ? xd=((i*@r2r)%100/100.0)*dx : xd=dx for j in 0..nx cnt+=1;self.progress_bar(cnt,max,"#{@@opt} Grid") p1=p0.offset(@v1,xd);xd=dx;p2=p1.offset(@v2,dy) tge.add_face(self.makeaface(p1,p2,@norm)) (d=@cor.distance(p0); (cpt=p0;md=d) if md>d) if @spt=="Corner" && i>0 p0=p1 end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create wood pattern grid on selected face ################################################## # def wood(f,nx,ny) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation cnt=0; max=nx*ny; md=1e9 for i in 0...ny dy = @data[i][-1]; for j in 1..nx cnt += 1; self.progress_bar(cnt,max,"Wood grid") tge.add_face(self.makeaface(@data[i][j-1],@data[i][j],@norm)) tge.add_face(self.makeaface(@data[i][j],@data[i][j].offset(@v2,dy),@norm)) (d=@cor.distance(@data[i][j-1]); (cpt=@data[i][j-1];md=d) if md>d) if @spt=="Corner" && i>0 end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create Tweed pattern grid on selected face ################################################## # def tweed(f,nx,ny) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation cnt=0; max=nx*ny; md=1e9 for i in 1..ny for j in 1..nx cnt += 1; self.progress_bar(cnt,max,"Tweed grid") tge.add_face(self.makeaface(@data[i-1][j-1],@data[i][j-1],@norm)) tge.add_face(self.makeaface(@data[i-1][j-1],@data[i-1][j],@norm)) (d=@cor.distance(@data[i-1][j-1]); (cpt=@data[i-1][j-1];md=d) if md>d) if @spt=="Corner" && i>1 end tge.add_face(self.makeaface(@data[i-1][nx],@data[i][nx],@norm)) end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create Herringbone pattern grid on selected face ################################################## # def hbone(f) dx=@GY + @GW;dy=@GX + @GW;ctr=f.bounds.center ny=((f.bounds.diagonal*1.2)/(dy*0.707107)).ceil;nx=((f.bounds.diagonal*1.2)/(dx/0.707107)).ceil; pt = ctr.offset(@v1,-((dx/0.707107)*(nx/2))).offset(@v2,-((dy/0.707107)*(ny/2))/2); vup=@v1.transform Geom::Transformation.rotation(pt,@norm,45.degrees) vdn=@v1.transform Geom::Transformation.rotation(pt,@norm,-45.degrees) tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation xv=@v1;xv.length=dx/0.707107; yv=@v2;yv.length=dy/0.707107 cnt=0; max=nx*ny; md=1e9; gp=pt; p0=pt#.offset(Geom::Vector3d.new(0,0,-1)) for i in 0..ny/2 for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"H'bone grid") p1=p0.offset(vdn,dy);tge.add_face(self.makeaface(p0,p1,@norm)) p2=p1.offset(vup,dx);tge.add_face(self.makeaface(p1,p2,@norm)) p3=p2.offset(vdn,-dy);tge.add_face(self.makeaface(p2,p3,@norm)) tge.add_face(self.makeaface(p3,p0,@norm)) cnt += 1; self.progress_bar(cnt,max,"H'bone grid") p1=p0.offset(vup,dy);tge.add_face(self.makeaface(p0,p1,@norm)) p2=p1.offset(vdn,-dx);tge.add_face(self.makeaface(p1,p2,@norm)) p3=p2.offset(vup,-dy);tge.add_face(self.makeaface(p2,p3,@norm)) tge.add_face(self.makeaface(p3,p0,@norm)) (d=@cor.distance(gp);(cpt=gp;md=d) if md>d) if @spt=="Corner" && i>0 p0 += xv; gp += xv end pt.offset!(yv); gp=pt p0=pt#.offset(Geom::Vector3d.new(0,0,-1)) end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create Basket Weave pattern on selected face ################################################## # def bsktwv (f,dx,dy) @bwb=3 unless [2,3,4].include?(@bwb) if dx==@GW then del=dy*@bwb*2 elsif dy==@GW del=dx*2 else del=[dx,dy*@bwb].max if del==dx then dy=dx/@bwb del=dx*2 else dx=dy*@bwb del=dx*2 end end name="BW-#{dx.to_l}X#{dy.to_l}X#{@bwb}" unless @mod.definitions[name] bw=@mod.definitions.add(name) be=bw.entities;pts=[];pts[0]=Geom::Point3d.new() v1=[1,0,0]; v2=[0,1,0]; norm=[0,0,1] tr=Geom::Transformation.new(pts[0],norm,90.degrees) for i in 0..@bwb-1 pts<<pts[i].offset(v2,dy) end pts<<pts[@bwb].offset(v1,dx) for i in @bwb+1..@bwb*2 pts<<pts[i].offset(v2,-dy) end for n in 1..4 case @bwb when 2 be.add_face(self.makeaface(pts[0],pts[2],norm)) be.add_face(self.makeaface(pts[2],pts[3],norm)) be.add_face(self.makeaface(pts[3],pts[5],norm)) be.add_face(self.makeaface(pts[1],pts[4],norm)) when 3 be.add_face(self.makeaface(pts[0],pts[3],norm)) be.add_face(self.makeaface(pts[3],pts[4],norm)) be.add_face(self.makeaface(pts[4],pts[7],norm)) be.add_face(self.makeaface(pts[1],pts[6],norm)) be.add_face(self.makeaface(pts[2],pts[5],norm)) when 4 be.add_face(self.makeaface(pts[0],pts[4],norm)) be.add_face(self.makeaface(pts[4],pts[5],norm)) be.add_face(self.makeaface(pts[5],pts[9],norm)) be.add_face(self.makeaface(pts[1],pts[8],norm)) be.add_face(self.makeaface(pts[2],pts[7],norm)) be.add_face(self.makeaface(pts[3],pts[6],norm)) end pts.each{|p| p.transform! tr} end ci=@ent.add_instance(@mod.definitions[name],pts[0]) ci.erase! end cmp = @mod.definitions[name] ctr=f.bounds.center; diag=f.bounds.diagonal*1.5 del=dx*2;ny=nx=(diag/del).ceil;md=1e9;cnt=0;max=nx*ny org=ctr.offset(@v1,-(del*(nx/2))).offset(@v2,-(del*(ny/2))); tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation for i in 0..ny p0=org.offset(@v2,del*i) for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"BasketWeave Grid") pt=p0.offset(@v1,del*j) (d=@cor.distance(pt);(cpt=pt;md=d) if md>d) if @spt=="Corner" && i>0 ci=tge.add_instance(cmp,Geom::Transformation.axes(pt,@v1,@v2,@norm)) end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create HopScotch1 pattern on selected face ################################################## # def hopscotch(f,dx,dy) hx=dx/2.0;hy=dy/2.0; name="HS1-#{dx.to_l}x#{dy.to_l}" cmp=@mod.definitions[name]; unless cmp p0=Geom::Point3d.new(); v1=[1,0,0]; v2=[0,1,0]; norm=[0,0,1] cmp=@mod.definitions.add(name);cpe=cmp.entities p1=p0.offset(v2,dy);cpe.add_face(self.makeaface(p0,p1,norm)) p2=p1.offset(v1,dx);cpe.add_face(self.makeaface(p1,p2,norm)) p3=p2.offset(v1,hx);cpe.add_face(self.makeaface(p2,p3,norm)) p4=p3.offset(v2,-hy);cpe.add_face(self.makeaface(p3,p4,norm)) p5=p4.offset(v1,-hx);cpe.add_face(self.makeaface(p4,p5,norm)) p6=p2.offset(v2,-dy);cpe.add_face(self.makeaface(p2,p6,norm)) cpe.add_face(self.makeaface(p6,p0,norm)) ci=@ent.add_instance(cmp,p0);ci.erase! end ctr=f.bounds.center; dxx=dx+dx+hx tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation nx=(f.bounds.diagonal*1.2/dxx).ceil;ny=(f.bounds.diagonal*1.2/hy).ceil pt0=ctr.offset(@v1,-(dxx*(nx/2))).offset(@v2,-(hy*(ny/2))) cnt=0; max=nx*ny; md=1e9;pt=pt0.clone; for i in 0..ny for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"Hopscotch Grid") ci=tge.add_instance(cmp,Geom::Transformation.axes(pt,@v1,@v2,@norm)) pt.offset!(@v1,dxx) (d=@cor.distance(pt);(cpt=pt.clone;md=d) if md>d) if @spt=="Corner" && i>0 end case i%5 when 0 then pt=pt0.offset(@v1,-dx).offset(@v2,hy);#v01 when 1 then pt=pt0.offset(@v1,hx).offset(@v2,dy);#v02 when 2 then pt=pt0.offset(@v1,-hx).offset(@v2,dy+hy);#v03 when 3 then pt=pt0.offset(@v1,dx).offset(@v2,dy*2);#v04 when 4 then pt=pt0.offset(@v2,dy*2+hy); pt0.offset!(@v2,dy*2+hy);#v05 end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ####################################################### # Create HopScotch2 Pattern on selected face ####################################################### # def hopscotch2(f,dx,dy) hx=dx/2.0;hy=dy/2.0;p0=Geom::Point3d.new(); cpd = @mod.definitions;cid = "HS2-#{dx.to_l}x#{dy.to_l}"; cmp = cpd[cid] unless cmp cmp = cpd.add(cid);xa=[1,0,0];ya=[0,1,0];za=[0,0,1]; p1=p0.offset(ya,dy);cmp.entities.add_face(self.makeaface(p0,p1,za)) p2=p1.offset(xa,dx);cmp.entities.add_face(self.makeaface(p1,p2,za)) p3=p2.offset(xa,hx);cmp.entities.add_face(self.makeaface(p2,p3,za)) p4=p3.offset(ya,-hy);cmp.entities.add_face(self.makeaface(p3,p4,za)) p5=p4.offset(ya,-hy);cmp.entities.add_face(self.makeaface(p4,p5,za)) p6=p0.offset(xa,dx);p7=p6.offset(ya,hy) cmp.entities.add_face(self.makeaface(p5,p0,za)) cmp.entities.add_face(self.makeaface(p6,p2,za)) cmp.entities.add_face(self.makeaface(p7,p4,za)) ci=@ent.add_instance(cmp,p0); ci.erase! end delx=dx+hx; diag=f.bounds.diagonal*1.2; ctr=f.bounds.center nx=(diag/delx).ceil;ny=(diag/dy).ceil pt0=ctr.offset(@v1,-(delx*(nx/2+1))).offset(@v2,-(dy*(ny/2+1))) tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation cnt=0; max=nx*ny; md=1e9; p0=pt0.clone for i in 0..ny p0=pt0.offset(@v2,dy*i) p0.offset!(@v1,-hx) if i%2==1 for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"No Name Grid") tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 p0.offset!(@v1,delx) end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ####################################################### # Create HopScotch3 Pattern on selected face ####################################################### # def hopscotch3(f) cid="HS3-#{@GX}X#{@GY}"; cmp = @mod.definitions[cid] unless cmp cmp = @mod.definitions.add(cid);cde=cmp.entities; norm=[0,0,1] p0=[0.0,0.0,0.0];p1=[8.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[0.0,24.0,0.0];p1=[0.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,4.0,0.0];p1=[4.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,8.0,0.0];p1=[0.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,4.0,0.0];p1=[0.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,16.0,0.0];p1=[12.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,20.0,0.0];p1=[16.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,24.0,0.0];p1=[8.0,20.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,8.0,0.0];p1=[20.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,24.0,0.0];p1=[16.0,20.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[20.0,8.0,0.0];p1=[20.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,8.0,0.0];p1=[16.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[20.0,0.0,0.0];p1=[24.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,12.0,0.0];p1=[16.0,12.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,16.0,0.0];p1=[4.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[20.0,8.0,0.0];p1=[24.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[0.0,16.0,0.0];p1=[0.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,4.0,0.0];p1=[12.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,16.0,0.0];p1=[16.0,12.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,12.0,0.0];p1=[16.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,12.0,0.0];p1=[12.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,20.0,0.0];p1=[24.0,20.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,8.0,0.0];p1=[12.0,12.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,4.0,0.0];p1=[12.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[16.0,4.0,0.0];p1=[20.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,0.0,0.0];p1=[20.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,20.0,0.0];p1=[4.0,20.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[0.0,8.0,0.0];p1=[0.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[20.0,4.0,0.0];p1=[20.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,16.0,0.0];p1=[16.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,4.0,0.0];p1=[12.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[12.0,8.0,0.0];p1=[8.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,20.0,0.0];p1=[8.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,0.0,0.0];p1=[12.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,4.0,0.0];p1=[8.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,8.0,0.0];p1=[4.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[0.0,4.0,0.0];p1=[0.0,0.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,4.0,0.0];p1=[4.0,4.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[8.0,4.0,0.0];p1=[8.0,8.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,16.0,0.0];p1=[0.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,20.0,0.0];p1=[4.0,16.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) p0=[4.0,20.0,0.0];p1=[4.0,24.0,0.0];cde.add_face(self.makeaface(p0,p1,norm)) unless @GX==24.0 && @GY==24.0 xscl=@GX/24.0; yscl=@GY/24.0; zscl=1.0 trs=Geom::Transformation.scaling(xscl,yscl,zscl) cde.transform_entities(trs,cde.to_a) end end dx = @GX; dy = @GY diag=f.bounds.diagonal*1.2;ctr=f.bounds.center nx=[(diag/dx).ceil,5].max;ny=[(diag/dy).ceil,5].max org=ctr.offset(@v1,-(dx*(nx/2))).offset(@v2,-(dy*(ny/2))); tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation cnt=0; max=nx*ny; md=1e9; for i in 0...ny pt=org.offset(@v2,dy*i) for j in 0...nx cnt += 1; self.progress_bar(cnt,max,"Irregular Polygon Grid") (d=@cor.distance(pt);(cpt=pt.clone;md=d) if md>d) if @spt=="Corner" && j>0 ci=tge.add_instance(cmp,Geom::Transformation.axes(pt,@v1,@v2,@norm)) pt.offset!(@v1,dx) end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ####################################################### # Create HopScotch4 Pattern on selected face ####################################################### # def hopscotch4(f,dx,dy) cid="HS4-#{@GX}x#{@GY}" cmp=@mod.definitions[cid] unless cmp cmp=@mod.definitions.add(cid);cde=cmp.entities; hx=dx/2;hy=dy/2 vx=Geom::Vector3d.new(1,0,0);vy=Geom::Vector3d.new(0,1,0); vz=Geom::Vector3d.new(0,0,1); p0=Geom::Point3d.new(-hx,0,0); p1=p0.offset(vx,hx);cde.add_face(self.makeaface(p0,p1,vz)) p2=p1.offset(vx,dx);cde.add_face(self.makeaface(p1,p2,vz)) p3=p2.offset(vx,dx);cde.add_face(self.makeaface(p2,p3,vz)) p4=p3.offset(vy,-hy);cde.add_face(self.makeaface(p3,p4,vz)) p5=p1.offset(vy,hy);cde.add_face(self.makeaface(p1,p5,vz)) p6=p5.offset(vx,-hx);cde.add_face(self.makeaface(p5,p6,vz)) p7=p5.offset(vy,hy);cde.add_face(self.makeaface(p5,p7,vz)) p8=p2.offset(vy,hy);cde.add_face(self.makeaface(p2,p8,vz)) p9=p8.offset(vy,hy);cde.add_face(self.makeaface(p8,p9,vz)) p10=p8.offset(vx,dx);cde.add_face(self.makeaface(p8,p10,vz));cde.add_face(self.makeaface(p10,p3,vz)) p11=p10.offset(vx,dx);cde.add_face(self.makeaface(p10,p11,vz)) p12=p11.offset(vy,-dy);cde.add_face(self.makeaface(p11,p12,vz)) end diag=f.bounds.diagonal*1.2;ctr=f.bounds.center;dxx=dx*3+hx nx=[(diag/dxx).ceil,5].max;ny=[(diag/dy).ceil,5].max org=ctr.offset(@v1,-(dxx*(nx/2))).offset(@v2,-(dy*(ny/2))); tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation cnt=0; max=nx*ny; md=1e9;p0=org.clone for i in 1..ny for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"Irregular Polygon Grid") (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) p0.offset!(@v1,dxx) end p0=org.offset(@v2,dy*i).offset(@v1,-hx*(i%7)); end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with(true,tgt,@ege,@egt,false,f) tg.erase! unless $sdm_debug; end # ################################################## # Create Hexagon pattern on selected face ################################################## # def hexagon(face,side) cpd = @mod.definitions ang=30.0.degrees; rad=side+@HW/Math.cos(ang); cid = "Hex-#{side.to_l}"; cmp = cpd[cid] unless cmp org = [0,-rad,0];xa=[1,0,0];ya=[0,1,0];za=[0,0,1]; cmp = cpd.add(cid);ctb=rad*Math.cos(ang);vec=[0,-rad,0] hex = @ent.add_ngon org,za,rad,6 pts = hex.each.collect{|e| e.end.position} tr1=Geom::Transformation.rotation(org,za,ang) pts.each{|p| p.transform! tr1} for i in 0...pts.length cmp.entities.add_face(self.makeaface(pts[i-1],pts[i],za)) end hex.each{|e| @ent.erase_entities(e)} end cos=Math.cos(ang); ctb=rad*cos; c2c=ctb*2.0; r2r=c2c*cos xo1=ctb; xo2=ctb*2.0;yo1=rad; ctr=face.bounds.center;diag=face.bounds.diagonal*1.2 nx=(diag/c2c).ceil;ny=(diag/r2r).ceil; pt0=ctr.offset(@v1,-(c2c*(nx/2))).offset(@v2,-(r2r*(ny/2))) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation cnt=0; max=nx*ny; md=1e9; #puts "nx=#{nx}, ny=#{ny}, max=#{max}" for j in 0..ny if j%2==1 p0=pt0.offset(@v1,xo1).offset(@v2,yo1) else p0=pt0.offset(@v1,xo2).offset(@v2,yo1) end tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) for i in 0..nx cnt += 1; self.progress_bar(cnt,max,"Hexagon Grid") tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 p0.offset!(@v1,c2c); end pt0.offset!(@v2,r2r); end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with true,tgt,@ege,@egt,false,face tg.erase! unless $sdm_debug; end # ################################################## # Create Diamond pattern on selected face ################################################## # def diamonds(face,side) rad=side+@HW/Math.cos(30.degrees); cid="Dia-#{side}";cmp=@mod.definitions[cid] unless cmp cmp=@mod.definitions.add(cid) p0=[0,0,0];za=[0,0,1] hex=@ent.add_ngon(p0,za,rad,6) pts=hex.each.collect{|e|e.start.position} for i in 0...pts.length cmp.entities.add_face(self.makeaface(pts[i-1],pts[i],za)) end for i in 0...pts.length p1=p0.offset(p0.vector_to(pts[i-1]),p0.distance(pts[i-1])/2) cmp.entities.add_face(self.makeaface(p0,p1,za)) p2=pts[i-1].offset(pts[i-1].vector_to(pts[i]),rad/2.0) cmp.entities.add_face(self.makeaface(p1,p2,za)) p3=pts[i-2].offset(pts[i-2].vector_to(pts[i-1]),rad/2.0) cmp.entities.add_face(self.makeaface(p1,p3,za)) end hex.each{|e| @ent.erase_entities(e)} end ctb=rad*Math.cos(30.degrees); c2c=rad*3.0;r2r=ctb*2.0 ctr=face.bounds.center;diag=face.bounds.diagonal*1.2 nx=(diag/c2c).ceil;ny=(diag/r2r).ceil; pt0=ctr.offset(@v1,-(c2c*(nx/2))).offset(@v2,-(r2r*(ny/2))) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation cnt=0; max=nx*ny; md=1e9;p0=pt0.clone for j in 0..ny for i in 0..nx cnt += 1; self.progress_bar(cnt,max,"Hexagon Grid") tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 p1=p0.offset(@v1,c2c/2.0).offset(@v2,-ctb); tge.add_instance(cmp,Geom::Transformation.axes(p1,@v1,@v2,@norm)) (d=@cor.distance(p1);(cpt=p1.clone;md=d) if md>d) if @spt=="Corner" && j>0 p0.offset!(@v1,c2c); end pt0.offset!(@v2,r2r); p0=pt0.clone end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with true,tgt,@ege,@egt,false,face tg.erase! unless $sdm_debug; end # ################################################## # Create Octagon pattern on selected face ################################################## # def octagon(face,side) half=side/2.0; ang=22.5.degrees; rad=half/Math.sin(ang); rad += @HW/Math.cos(ang) @d_area=(side+(Math.tan(ang)*@HW)*2)**2 cpd = @mod.definitions;cid = "Oct-#{side.to_l}"; cmp = cpd[cid] unless cmp org = [@GW-half,@GW-half,0];xa=[1,0,0];ya=[0,1,0];za=[0,0,1]; cmp = cpd.add(cid); hex = @ent.add_ngon org,za,rad,8 pts = hex.each.collect{|e| e.end.position} tr1=Geom::Transformation.rotation(org,za,ang) pts.each{|p| p.transform! tr1} for i in 0...pts.length cmp.entities.add_face(self.makeaface(pts[i-1],pts[i],za)) end hex.each{|e| @ent.erase_entities(e)} end ctb=half/Math.tan(ang); r2r=c2c=ctb*2.0+@GW; ctr=face.bounds.center;diag=face.bounds.diagonal*1.2 nx=(diag/c2c).ceil;ny=(diag/r2r).ceil; pt0=ctr.offset(@v1,-(c2c*(nx/2))).offset(@v2,-(r2r*(ny/2))) tg=@ent.add_group;tge=tg.entities;tgt=tg.transformation p0=pt0.clone; cnt=0; max=nx*ny; md=1e9; for j in 0..ny for i in 0..nx cnt += 1; self.progress_bar(cnt,max,"Hexagon Grid") tge.add_instance(cmp,Geom::Transformation.axes(p0,@v1,@v2,@norm)) (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 p0.offset!(@v1,c2c); end p0=pt0.offset(@v2,r2r); pt0.offset!(@v2,r2r); end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with true,tgt,@ege,@egt,false,face tg.erase! unless $sdm_debug; end # ####################################################### # Create Irregular Polygon Pattern on selected face ####################################################### # def irregular_polygons(face) require File.dirname(__FILE__)+'/delauney3.rb' require File.dirname(__FILE__)+'/VoronoiXYZ.rb';#Thanks to MattC ctr = face.bounds.center; diag = face.bounds.diagonal*1.2 org = ctr.offset(@v1,-diag/2).offset(@v2,-diag/2) max=[(face.area/144*@ipd).floor,20].max; @sel.clear; nrm=face.normal; min=diag/max*2 @rds>0 ? srand(@rds) : srand; pts = []; new_faces = [] while max > 0 x=diag*rand;y=diag*rand p=org.offset(@v1,x).offset(@v2,y) if face.classify_point(p)==1 if self.proximity(pts,p,min) > min @sel.add @ent.add_cpoint(p);max -= 1 pts << p end end end face.vertices.each{|v|@sel.add @ent.add_cpoint(v.position)} vgrp=MattC::VoronoiXYZ.voronoi(); vgt=vgrp.transformation; cgrp=@ent.add_group;cge=cgrp.entities;cgt=cgrp.transformation vgrp.entities.grep(Sketchup::Edge).each{|e| p1 = e.start.position.transform vgt; p2 = e.end.position.transform vgt cge.add_face(makeaface(p1,p2,nrm)) } @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation cge.intersect_with true,cgt,@ege,@egt,false,face vgrp.erase!; cgrp.erase!; @ent.erase_entities(@sel) end def proximity(old,new,min) prox = 1e6 for o in old prox = [o.distance(new),prox].min break if prox < min end return prox end # ####################################################### # Create Wedge Pattern on selected face ####################################################### # def wedge(face,dx,dy) cid="Wedge-#{dx.to_l}x#{dy.to_l}" cmp=@mod.definitions[cid] unless cmp cmp=@mod.definitions.add(cid);cde=cmp.entities p0=Geom::Point3d.new(); v1=[1,0,0];v2=[0,1,0];norm=[0,0,1] p1=p0.offset(v1,-dx/2).offset(v2,dy/4);cde.add_face(self.makeaface(p0,p1,norm)) p2=p1.offset(v2,dy/2);cde.add_face(self.makeaface(p1,p2,norm)) p3=p2.offset(v2,dy/4).offset(v1,dx/2);cde.add_face(self.makeaface(p2,p3,norm)) p4=p3.offset(v1,dx/2).offset(v2,-dy/4);cde.add_face(self.makeaface(p3,p4,norm)) p5=p4.offset(v2,-dy/2);cde.add_face(self.makeaface(p4,p5,norm)) cde.add_face(self.makeaface(p5,p0,norm)) end diag=face.bounds.diagonal*1.2;ctr=face.bounds.center nx=[(diag/dx).ceil,5].max;ny=[(diag/dy).ceil,5].max org=ctr.offset(@v1,-(dx*(nx/2))).offset(@v2,-(dy*(ny/2))); tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation cnt=0; max=nx*ny; md=1e9; p0=org.clone for i in 0..ny pt=p0.offset(@v2,dy*0.75*i) pt.offset!(@v1,dx/2) if i%2==1 for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"Wedge Grid") (d=@cor.distance(pt);(cpt=pt.clone;md=d) if md>d) if @spt=="Corner" && j>0 tge.add_instance(cmp,Geom::Transformation.axes(pt,@v1,@v2,@norm)) pt.offset!(@v1,dx) end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with true,tgt,@ege,@egt,false,face tg.erase! unless $sdm_debug; end # ####################################################### # Create I_Block Pattern on selected face ####################################################### # def i_block(face,dx,dy) cid="I_Block-#{@GX}x#{@GY}" cpd=@mod.definitions[cid] unless cpd cpd=@mod.definitions.add(cid);cde=cpd.entities p0=[0,0,0];v1=[-1,0,0];v2=[0,1,0]; v3=[0,0,1]; d1=dx*0.1875;d2=dx*0.125;d3=dx-((d1+d2)*2);dy=[dy,(d2+@GW)*2].max p1=p0.offset(v1,d1);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 p1=p0.offset(v1,d2).offset(v2,d2);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 p1=p0.offset(v1,d3);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 p1=p0.offset(v1,d2).offset(v2,-d2);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 p1=p0.offset(v1,d1);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 p1=p0.offset(v2,dy);cde.add_face(self.makeaface(p0,p1,v3));p0=p1 end diag=face.bounds.diagonal*1.2; ctr=face.bounds.center nx=(diag/dx).ceil;dy-=dx*0.125;ny=(diag/dy).ceil org=ctr.offset(@v1,-(dx*(nx/2))).offset(@v2,-(dy*(ny/2))) tg=@ent.add_group; tge=tg.entities; tgt=tg.transformation cnt=0; max=nx*ny; md=1e9 for i in 0..ny p0=org.offset(@v2,dy*i);p0.offset!(@v1,dx/2.0) if i%2==1 for j in 0..nx cnt += 1; self.progress_bar(cnt,max,"I_Block Grid") (d=@cor.distance(p0);(cpt=p0.clone;md=d) if md>d) if @spt=="Corner" && j>0 tge.add_instance(cpd,Geom::Transformation.axes(p0,@v1,@v2,@norm)) p0.offset!(@v1,dx) end end (tr = Geom::Transformation.new(cpt.vector_to(@cor)); tge.transform_entities(tr,tge.to_a )) if @spt=="Corner" @egrp=@ent.add_group;@ege=@egrp.entities;@egt=@egrp.transformation Sketchup::set_status_text "Intersecting Grid and Face" tge.intersect_with true,tgt,@ege,@egt,false,face tg.erase! unless $sdm_debug; end # ######################################################## # Common sub-routines ######################################################## # def paint_it(f) if @app=="Current" f.material = @mat f.material.texture.size = @txs if f.material && f.material.texture && @txs && @txs != 0 self.ate(f) elsif @app=="Rand_Clr" name = @colors[rand(@colors.length)] unless @mod.materials[name] mat = @mod.materials.add(name) mat.color = name end f.material = @mod.materials[name] elsif @app=="Rand_Tex" i=rand(@textures.length);name = @textures[i] f.material = @mod.materials[name] self.ate(f) end end def ate(f) #Align Texture to Edge if @ate=="Yes" && f.material && f.material.texture case @@opt when "Tweed","BsktWv","IrPoly" l=n=0; f.outer_loop.edges.each_with_index{|e,i| d=e.length;(n=i;l=d) if d>l} vector = f.edges[n].line[1] # Align to longest bounding edge when "HpScth1","HpScth2","HpScth4" n=0; @GX>=@GY ? vector=@v1 : vector=@v2; when 'HpScth3',"Hbone" edges=f.outer_loop.edges j=edges.length-1;l=d=0 for i in 0..j d+=edges[i].length; unless edges[i].line[1].parallel?(edges[i-j].line[1]) (l=d;n=i;d=0)if l<d end end vector=edges[n].line[1] else n=0;vector = @v1 # Align to longest face edge end return unless f.normal.perpendicular? vector # Skip if vector isn't in the plane of the face achorPoint = f.edges[n].line[0] # Define point to rotate around textureWidth = f.material.texture.width vector.length = textureWidth # Change vector's length to materials width points = [achorPoint, [0,0,0], [achorPoint[0]+vector[0],achorPoint[1]+vector[1],achorPoint[2]+vector[2]], [1,0,0]] # Reposition material f.position_material(f.material, points, true) end end def wig(f)#Random Texture Translation if f.material && f.material.texture tw = Sketchup.create_texture_writer # Create uv helper to get current material position uvh = f.get_UVHelper true, false, tw; pointPairs = []; #puts "rtt" vector = f.edges[0].line[1] # Get a vector in the face's plane vector.length = rand(f.material.texture.height+f.material.texture.width)*@rti # Set vector length trans = Geom::Transformation.rotation f.outer_loop.vertices[0].position, f.normal, rand(360).degrees # Rotate vector randomly in plane vector.transform! trans; trans = Geom::Transformation.translation vector # Create translation, move point by vector (0..1).each do |j| # Loop some points around face point3d = f.outer_loop.vertices[j].position # Select a 3d point point3dRotated = point3d.transform(trans) # Move 3d point pointPairs << point3dRotated # Save model's 3d point to array point2d = uvh.get_front_UVQ(point3d) pointPairs << point2d # Save material's corresponding 2d point to array end#each f.position_material(f.material, pointPairs, true) #Set material position (pair up model 3d points with texture 2d point) end end def wag(f)#Random Texture Rotation if f.material && f.material.texture tw = Sketchup.create_texture_writer # Create uv helper to get current material position uvh = f.get_UVHelper true, false, tw; @rtr=="Rand" ? angle=rand(360) : (angle = @rtr.to_i; incs = 360/angle; angle*=rand(incs)) trans = Geom::Transformation.rotation f.outer_loop.vertices[0].position, f.normal, angle.degrees #Define rotation pointPairs = []; #puts "rtr angle=#{angle}" (0..1).each do |j| # Loop some points around face point3d = f.outer_loop.vertices[j].position # Selet a 3d point point3dRotated = point3d.transform(trans) # Rotate 3d pont pointPairs << point3dRotated # Save model's 3d point to array point2d = uvh.get_front_UVQ(point3d) pointPairs << point2d # Save material's corresponding 2d point to array end#each f.position_material(f.material, pointPairs, true) #Set material position (pair up model 3d points with texture 2d point) end end def wob(g,d)#Random Face Rotation i = rand(2); axis = [@v1,@v2][i]; while d<@rin || d>@rix d = rand*@GD end case @@opt when "Brick","Tile","Wood" angle=Math.atan(d/[@GY,@GX][i])*(rand<=>0.5) else angle=Math.atan(d/(([[g.bounds.height,g.bounds.depth].max,g.bounds.width].max)/2))*(rand<=>0.5) end tr=Geom::Transformation.rotation(g.bounds.center,axis,angle) g.transform! tr end def bev(f,d)#Add Bevel to Face Edge p=self.g_offset(f,d) if p b=f.parent.entities.add_face(p) v=b.normal;v.length=d tr=Geom::Transformation.translation(v) f.parent.entities.transform_entities(tr,b) end end def edge_to_close(f,p) return true if p[0].distance(p[1]) <= @GW for loop in f.loops loop.edges.each{|e| if e.line[1].parallel?(p[0].vector_to(p[1])) for i in 0..1 pp=p[i].project_to_line(e.line) if e.bounds.contains?(pp) if p[i].distance(pp) <= @GW return true end end end end } end return false end def g_offset(face,dist) return nil unless (dist.class==Fixnum || dist.class==Float || dist.class==Length) return nil if (@@opt != "I_Block" && !self.ctr_to_edge(face)); @c_pts=face.outer_loop.vertices.collect{|v|v.position}; unless dist==0 edges=face.outer_loop.edges;last=edges.length-1 0.upto(last) do |i| unless edges[i].length > @GW if edges[i].line[1].perpendicular?(edges[i-1].line[1]) if edges[i].line[1].perpendicular?(edges[i-last].line[1]) @c_pts -= [edges[i].start,edges[i].end]; #remove short edge between square corners end end end end last = @c_pts.length-1;@o_pts = [] 0.upto(last) do |a| vec1 = (@c_pts[a]-@c_pts[a-last]).normalize vec2 = (@c_pts[a]-@c_pts[a-1]).normalize if vec1.parallel? vec2 ctr = face.bounds.center; poe = ctr.project_to_line([@c_pts[a],vec1]) vec3 = poe.vector_to(ctr); ang = 90.degrees else vec3=(vec1+vec2).normalize ang = vec1.angle_between(vec2)/2; end if vec3.valid? vec3.length = -dist/Math::sin(ang); t = Geom::Transformation.new(vec3) if face.classify_point(@c_pts[a].transform(t))==16 t = Geom::Transformation.new(vec3.reverse); end @o_pts << @c_pts[a].transform(t) end end (@o_pts.length > 2) ? (return(@o_pts)) : (return nil) else return nil end end def progress_bar(cnt,max,opt) pct = (cnt*100)/max; pct=[pct,100].min; @pb = "|"*pct Sketchup::set_status_text(@pb + " #{pct}% of #{opt} done.") end def makeaface(p1,p2,v) pts=[]; pts<<p1.offset(v) pts<<p2.offset(v) pts<<p2.offset(v.reverse) pts<<p1.offset(v.reverse) end def ctr_to_edge(f) edges=f.edges; c=self.calc_centroid(f); edges.each{|e| return false if c.distance_to_line(e.line) <= @HW} return true end def calc_centroid(f) tx=0.0;ty=0.0;tz=0.0; p=f.outer_loop.vertices.collect{|v|v.position} p.each{|v| tx+=v.x;ty+=v.y;tz+=v.z} ax=tx/p.length;ay=ty/p.length;az=tz/p.length c=Geom::Point3d.new(ax,ay,az);#ent.add_cpoint(c) area = 0.0;cx = 0.0;cy = 0.0;cz = 0.0; for i in 0...p.length areat = (p[i].distance(p[i-1])*(c.distance_to_line([p[i],p[i].vector_to(p[i-1])])))/2.0 area = area + areat; cx = cx + areat * ( p[i].x + p[i-1].x + c.x ) / 3.0; cy = cy + areat * ( p[i].y + p[i-1].y + c.y ) / 3.0; cz = cz + areat * ( p[i].z + p[i-1].z + c.z ) / 3.0; end cx = cx / area;cy = cy / area;cz = cz / area; Geom::Point3d.new(cx,cy,cz) end end end delauney3.rb # Credit to Paul Bourke (pbourke@swin.edu.au) for original Fortran 77 Program :)) # August 2004 - Conversion and adaptation to Ruby by Carlos Fale (carlosfale@sapo.pt) # September 2004 - Updated by Carlos Fale # # You can use this code, for non commercial purposes, however you like, providing the above credits remain in tact # Return two logical values, first is TRUE if the point (xp, yp) lies inside the circumcircle made up by points (x1, y1), (x2, y2) and (x3, y3) # and FALSE if not, second is TRUE if xc + r < xp and FALSE if not # NOTE: A point on the edge is inside the circumcircle ### ### TIG made as delauney3 with class to avoid clashes ### otherwise as PBourke's (c) ### class Delauney3 def Delauney3::incircum(xp, yp, x1, y1, x2, y2, x3, y3) eps = 0.000001 res = [FALSE, FALSE] if (y1 - y2).abs >= eps || (y2 - y3).abs >= eps if (y2 - y1).abs < eps m2 = -(x3 - x2) / (y3 - y2) mx2 = (x2 + x3) / 2 my2 = (y2 + y3) / 2 xc = (x1 + x2) / 2 yc = m2 * (xc - mx2) + my2 elsif (y3 - y2).abs < eps m1 = -(x2 - x1) / (y2 - y1) mx1 = (x1 + x2) / 2 my1 = (y1 + y2) / 2 xc = (x2 + x3) / 2 yc = m1 * (xc - mx1) + my1 else m1 = -(x2 - x1) / (y2 - y1) m2 = -(x3 - x2) / (y3 - y2) mx1 = (x1 + x2) / 2 mx2 = (x2 + x3) / 2 my1 = (y1 + y2) / 2 my2 = (y2 + y3) / 2 if (m1 - m2) == 0 xc = (x1 + x2 + x3) / 3 yc = (y1 + y2 + y3) / 3 else xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2) yc = m1 * (xc - mx1) + my1 end end dx = x2 - xc dy = y2 - yc rsqr = dx * dx + dy * dy r = Math.sqrt(rsqr) dx = xp - xc dy = yp - yc drsqr = dx * dx + dy * dy if drsqr < rsqr res[0] = TRUE end if xc + r < xp res[1] = TRUE end end return res end # Takes as input a array with NVERT lines, each line is a array with three values x, y, and z (vertex[j][0] = x value of j + 1 component) and # return a array with NTRI lines, each line is a array with three values i, j, and k (each value is the index of a point in the input array (vertex array)) # i is the index of the first point, j is the index of the second point and k is the index of the third point, def Delauney3::triangulate(vert) # Sort the input array in x values vert.sort! nvert = vert.length triang = Array.new edges = Array.new complete = Array.new # Verbose Sketchup.set_status_text("Starting triangulation of " + nvert.to_s + " Points") # Find the minimum and maximum vertex bounds. This is to allow calculation of the bounding triagle xmin = vert[0][0] ymin = vert[0][1] xmax = xmin ymax = ymin for i in (2..nvert) x1 = vert[i - 1][0] y1 = vert[i - 1][1] xmin = [x1, xmin].min xmax = [x1, xmax].max ymin = [y1, ymin].min ymax = [y1, ymax].max end dx = xmax - xmin dy = ymax - ymin dmax = [dx, dy].max xmid = (xmin + xmax) / 2 ymid = (ymin + ymax) / 2 # Set up the supertriangle. This is a triangle which encompasses all the sample points. The supertriangle coordinates are added to the end # of the vertex list. The supertriangle is the first triangle in the triangles list. p1 = nvert + 1 p2 = nvert + 2 p3 = nvert + 3 vert[p1 - 1] = [xmid - 2 * dmax, ymid - dmax, 0] vert[p2 - 1] = [xmid, ymid + 2 * dmax, 0] vert[p3 - 1] = [xmid + 2 * dmax, ymid - dmax, 0] triang[0] = [p1 - 1, p2 - 1, p3 - 1] complete[0] = FALSE ntri = 1 # Include each point one at a time into the exixsting mesh for i in (1..nvert) xp = vert[i - 1][0] yp = vert[i - 1][1] nedge = 0 # Verbose Sketchup.set_status_text("Triangulating point " + i.to_s + " / " + nvert.to_s ) # Set up the edge buffer. If the point (xp, yp) lies inside the circumcircle then the three edges of that triangle are added to the edge buffer. j = 0 while j < ntri j = j +1 if complete[j - 1] != TRUE p1 = triang[j - 1][0] p2 = triang[j - 1][1] p3 = triang[j - 1][2] x1 = vert[p1][0] y1 = vert[p1][1] x2 = vert[p2][0] y2 = vert[p2][1] x3 = vert[p3][0] y3 = vert[p3][1] inc = Delauney3::incircum(xp, yp, x1, y1, x2, y2, x3, y3) if inc[1] == TRUE complete[j - 1] = TRUE else if inc[0] == TRUE edges[nedge] = [p1, p2] edges[nedge + 1] = [p2, p3] edges[nedge + 2] = [p3, p1] nedge = nedge + 3 triang[j - 1] = triang[ntri - 1] complete[j - 1] = complete[ntri - 1] j = j - 1 ntri = ntri - 1 end end end end # Tag multiple edges # NOTE: if all triangles are specified anticlockwise then all interior edges are pointing in direction. for j in (1..nedge - 1) if edges[j - 1][0] != -1 || edges[j - 1][1] != -1 for k in ((j + 1)..nedge) if edges[k - 1][0] != -1 || edges[k - 1][1] != -1 if edges[j - 1][0] == edges[k - 1][1] if edges[j - 1][1] == edges[k - 1][0] edges[j - 1] = [-1, -1] edges[k - 1] = [-1, -1] end end end end end end # Form new triangles for the current point. Skipping over any tagged adges. All edges are arranged in clockwise order. for j in (1..nedge) if edges[j - 1][0] != -1 || edges[j - 1][1] != -1 ntri = ntri + 1 triang[ntri - 1] = [edges[j - 1][0], edges[j - 1][1], i - 1] complete[ntri - 1] = FALSE end end end # Remove triangles with supertriangle vertices. These are triangles which have a vertex number greater than NVERT. i = 0 while i < ntri i = i + 1 if triang[i - 1][0] > nvert - 1 || triang[i - 1][1] > nvert - 1 || triang[i - 1][2] > nvert - 1 triang[i - 1] = triang[ntri - 1] i = i - 1 ntri = ntri - 1 end end # Verbose Sketchup.set_status_text("Triangulation Completed: " + ntri.to_s + " Triangles Created.") return triang[0..ntri - 1] end end#class VoronoiXYZ.rb # Modified by sdmitch for irregular polygon creation in FloorGenerator require File.dirname(__FILE__)+'/delauney3.rb' module MattC module VoronoiXYZ def self.voronoi() @mod = Sketchup.active_model @ent = @mod.active_entities @sel = @mod.selection ### points_table = [] points_table = self.points_to_array() ### triangles = [] if points_table[0] triangles = Delauney3::triangulate(points_table) else puts "No triangles were created." return nil end ### group for tri's output point_groups=[] for i in 0..points_table.length-1 point_groups[i]=[] triangles.each do |tri| if tri.include? i point_groups[i]<<tri end end end point_groups.each do |pg| pg.flatten! pg.uniq! end vgrp = @ent.add_group() grent=vgrp.entities conhull=[] qhull(@cpts).each do |p| for i in 0..points_table.length-1 if p.position==points_table[i] conhull<<i end end end for i in 0..points_table.length-1 connpoints=point_groups[i] if conhull.include?(i) j=conhull.index(i) if j == 0 connpoints<<conhull[1] connpoints<<conhull[conhull.length-1] else if j == conhull.length-1 connpoints<<conhull[j-1] connpoints<<conhull[0] else connpoints<<conhull[j-1] connpoints<<conhull[j+1] end end end connpoints.uniq! connpoints.delete(i) sorted=sortradial(connpoints,i,points_table) cellpoints=voropoints(i,sorted,points_table,conhull) cellpoints=removedupilcates(cellpoints) if cellpoints.length>2 grent.add_face(cellpoints) end end ##### return everthing to original plane @ent.transform_entities(@trans.inverse,@cpts) vgrp.transform! @trans.inverse ##### end#def def self.points_to_array() ##### put selected ConstructionPoints on the XY plane @cpts = @sel.grep(Sketchup::ConstructionPoint) @bb = Geom::BoundingBox.new; @bb.add @cpts.map{|cp|cp.position}; px,py,pz = plane = Geom.fit_plane_to_points(@cpts.map{|cp|cp.position}) @cpts.each{|cp| pp = cp.position.project_to_plane(plane) vec = cp.position.vector_to(pp) @ent.transform_entities(Geom::Transformation.new(vec),cp) } x_axis = Geom::Vector3d.new(px,py,pz).axes[0] ang = Math.acos(pz); @max_length = @bb.diagonal/4 @trans = Geom::Transformation.new(ORIGIN,x_axis,-ang) @ent.transform_entities(@trans,@cpts) ##### points_array = [] @cpts.each{|cpt| ### TIG'd x = cpt.position.x.to_f y = cpt.position.y.to_f z = cpt.position.z.to_f points_array << [x, y ,z] } points_array.uniq! return points_array end #of def def self.removedupilcates(points) uniqpoints=[]; temp=[] n=points.length for i in 0..n-1 for j in i+1..n-1 if points[i]==points[j] || points[i].distance(points[j]) > @max_length temp<<points[j] end end end uniqpoints=points-temp uniqpoints end def self.qhull(points) vector=Geom::Vector3d.new 1,0,0 pminy=[points[0]] for i in 1..points.length-1 if points[i].position.y < pminy.last.position.y pminy<<points[i] end end vertices=[pminy.last] temp=[] angle=180.degrees for i in 0..points.length-1 if (vertices.last.position!=points[i].position)&&(vector.angle_between(vertices.last.position.vector_to(points[i].position)) < angle) temp<<points[i] angle = vector.angle_between(vertices.last.position.vector_to(points[i].position)) end end vertices<<temp.last angle=180.degrees for k in 1..points.length-1 vector=vertices[vertices.length-2].position.vector_to(vertices.last.position) for i in 0..points.length-1 if (vertices.last.position!=points[i].position)&&(vector.angle_between(vertices.last.position.vector_to(points[i].position))<angle) temp<<points[i] angle = vector.angle_between(vertices.last.position.vector_to(points[i].position)) end end vertices<<temp.last angle=vector.angle_between(vertices[vertices.length-2].position.vector_to(vertices.last.position))+180.degrees if vertices.first==vertices.last break end end vertices.delete_at(vertices.length-1) vertices end def self.sortradial(pointsind,bpointindex,pointstable) angles=[]; sortedp=[] vec=Geom::Vector3d.new(1,0,0) pointsind.each do |p| if vec.cross(pointstable[bpointindex].vector_to(pointstable[p])).z>=0 angles<<vec.angle_between(pointstable[bpointindex].vector_to(pointstable[p])) else angles<<360.degrees-vec.angle_between(pointstable[bpointindex].vector_to(pointstable[p])) end end angles.sort! for i in 0..angles.length-1 for j in 0..pointsind.length-1 if vec.cross(pointstable[bpointindex].vector_to(pointstable[pointsind[j]])).z>=0 if vec.angle_between(pointstable[bpointindex].vector_to(pointstable[pointsind[j]]))==angles[i] sortedp<<pointsind[j] break end else if 360.degrees-vec.angle_between(pointstable[bpointindex].vector_to(pointstable[pointsind[j]]))==angles[i] sortedp<<pointsind[j] break end end end end sortedp end def self.voropoints(bpntindx,sorpntindx,pointstable,conhulindx) polygon=[] conhulindx.each do |i| polygon<<pointstable[i] end points=[] vec=Geom::Vector3d.new(0,0,1) for i in 0..sorpntindx.length-1 if i<sorpntindx.length-1 j=i+1 else j=0 end test=[] if (conhulindx.include? bpntindx) test<<0 else test<<1 end if (conhulindx.include? sorpntindx[i]) test<<0 else test<<1 end if (conhulindx.include? sorpntindx[j]) test<<0 else test<<1 end linevector=[pointstable[bpntindx].vector_to(pointstable[sorpntindx[i]]),pointstable[bpntindx].vector_to(pointstable[sorpntindx[j]])] midpoints=[Geom.linear_combination(0.5,pointstable[bpntindx],0.5,pointstable[sorpntindx[i]]),Geom.linear_combination(0.5,pointstable[bpntindx],0.5,pointstable[sorpntindx[j]])] midlines=[[midpoints[0],vec.cross(linevector[0])],[midpoints[1],vec.cross(linevector[1])]] int=Geom.intersect_line_line([midlines[0][0],midlines[0][1]], [midlines[1][0],midlines[1][1]]) if (test[0]==0)&&(test[1]==0)&&(test[2]==0) intprim=int+int.vector_to(pointstable[bpntindx])+int.vector_to(pointstable[bpntindx]) points<<intprim.project_to_line([midlines[0][0],midlines[0][1]]) points<<intprim points<<intprim.project_to_line([midlines[1][0],midlines[1][1]]) else points<<int end end adjpoints=[] for i in 0..points.length-1 if i==points.length-1 j=0 else j=i+1 end if Geom.point_in_polygon_2D(points[i], polygon, true) adjpoints<<points[i] if Geom.point_in_polygon_2D(points[j], polygon, true)==false adjpoints<<Geom::Point3d.new(intersect_p_p_ps(points[i],points[j],polygon)) if Geom.point_in_polygon_2D(pointstable[bpntindx], polygon, false)==false adjpoints<<Geom::Point3d.new(pointstable[bpntindx]) end end else if Geom.point_in_polygon_2D(points[j], polygon, true) adjpoints<<Geom::Point3d.new(intersect_p_p_ps(points[i],points[j],polygon)) end end end if adjpoints.length==0 temp=intersections_ps_ps(points,polygon) if temp.length==2 adjpoints<<Geom::Point3d.new(temp[0]) adjpoints<<Geom::Point3d.new(temp[1]) adjpoints<<Geom::Point3d.new(pointstable[bpntindx]) end end adjpoints.reject! { |c| c.nil? } adjpoints end def self.intersect_p_p_ps(p1,p2,polygon) point=[] p1p2line=[p1,p1.vector_to(p2)] for i in 0..polygon.length-1 if i==polygon.length-1 j=0 else j=i+1 end ijline=[polygon[i],polygon[i].vector_to(polygon[j])] int=Geom.intersect_line_line(p1p2line, ijline) if (int)&&(point_is_between(p1,p2,int)&&point_is_between(polygon[i],polygon[j],int)) point<<int break end end point[0] end def self.intersections_p_p_ps(p1,p2,polygon) point=[] p1p2line=[p1,p1.vector_to(p2)] for i in 0..polygon.length-1 if i==polygon.length-1 j=0 else j=i+1 end ijline=[polygon[i],polygon[i].vector_to(polygon[j])] int=Geom.intersect_line_line(p1p2line, ijline) if point_is_between(p1,p2,int)&&point_is_between(polygon[i],polygon[j],int) point<<int end end point end def self.intersections_ps_ps(points,polygon) point=[] for i in 0..polygon.length-1 if i==polygon.length-1 j=0 else j=i+1 end ijline=[polygon[i],polygon[i].vector_to(polygon[j])] for k in 0..points.length-1 if k==points.length-1 l=0 else l=k+1 end klline=[points[k],points[k].vector_to(points[l])] int=Geom.intersect_line_line(klline, ijline) if (int!=nil)&&(point_is_between(points[k],points[l],int))&&(point_is_between(polygon[i],polygon[j],int)) point<<int end end end point.reject! { |c| c.nil? } point end def self.point_is_between(p1,p2,pt) bb=Geom::BoundingBox.new;bb.add p1,p2 bb.contains?(pt) end end#VoronoiXYZ end FG_Icons/Brick.jpg FG_Icons/BsktWv.jpg FG_Icons/Clapboard.jpg FG_Icons/diamonds.jpg FG_Icons/Hbone.jpg FG_Icons/Hexgon.jpg FG_Icons/HpScth1.jpg FG_Icons/HpScth2.jpg FG_Icons/HpScth3.jpg FG_Icons/HpScth4.jpg FG_Icons/I_Block.jpg FG_Icons/IrPoly.jpg FG_Icons/Octgon.jpg FG_Icons/Tile.jpg FG_Icons/Tweed.jpg FG_Icons/Wedge.jpg FG_Icons/Wood.jpg FlrGenReset.rb module SDM def flrgenreset patterns=["Brick","Tile","Wood","Tweed","Hbone","BsktWv","HpScth1","HpScth2","Rand_Tex","HpScth3","HpScth4","IrPoly","Hexgon","Octgon","Wedge","I_Block","Diamonds","Clapbrd"] patterns.each{|o| Sketchup.write_default("FloorGenerator",o,nil)}; Sketchup.write_default("FloorGenerator","","Tile"); end end