ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info
  • Calculate the needed width of a WebDialog

    10
    0 Votes
    10 Posts
    477 Views
    onidarbeO
    Thanks! I found the solution... [update 2013-01-23] def popup(msg="", timeOut=0, posX=20, posY=70) # 2013-01-23 onidarbe () gmail # Popup a message (including html-tags & \r) with a timout and auto-resize the window # A click on the popup-window will disable timeOut and has to be closed manually # To see how it's working, add border;1px solid black; in the <div style='...'> htmlCode = %{ <html onclick='clicked();' > <div id='div' style='float;left; white-space;nowrap;' > #{msg.gsub(/\r/,"<br>\n")} </div> <script type='text/javascript'> width=document.getElementById('div').offsetWidth; height=document.getElementById('div').offsetHeight; document.write("<input type='hidden' id='width' value='" + width + "'/>"); document.write("<input type='hidden' id='height' value='" + height + "'/>"); function clicked() { location = 'skp;clicked' }; document.body.scroll = "auto"; </script> </html> } win = UI;;WebDialog.new( "" ) # NOTE; Variables made up on multiple lines have only a \n at the end of each line! # "View source" with Windows Notepad needs to have \r\n win.set_html( htmlCode.gsub(/\r\n|\n\r|\n|\r/,"\r\n") ) # Although WebDialog without pref_key doesn't keep size or location, set_size does! # Thereby start with a smaller window instead of a larger previous version win.set_size( 130, 30 ) win.set_position( posX, posY ) win.show UI;;start_timer( 0, false ) { win.set_size( win.get_element_value("width").to_f+60, [800, win.get_element_value("height").to_f+80].min ) } if timeOut != 0 timerID = UI;;start_timer( timeOut, false ) { win.close } win.add_action_callback( "clicked" ) { UI.stop_timer( timerID ) } end end pluginPath = Sketchup.find_support_file( "Plugins" ) Dir.chdir( pluginPath ) rbFiles = Dir[ "*.rb" ] popup( "<B>All plugins;</B>\r#{pluginPath }\r\r#{rbFiles.join("\r")}", 2 )
  • Method -- Best Naming Techniques

    3
    0 Votes
    3 Posts
    267 Views
    Dan RathbunD
    #2 is the Ruby way. (#1 is Javascript or VisualBasic) [#3 is noway!]
  • Rotate face in ruby

    3
    0 Votes
    3 Posts
    428 Views
    I
    Thank you very much. This has really been helpful. It was OK the first time I tried This is the end result: [image: qGNs_moebius.jpg]
  • Dynamic Components reacting to Scene (aka Page) changes

    9
    0 Votes
    9 Posts
    9k Views
    G
    Dan , thanks for your help. I will study it.
  • Model in model sharing methods

    7
    0 Votes
    7 Posts
    283 Views
    Dan RathbunD
    try something like: file "MR/MIX/P.rb" module MR module P def p(msg="") puts "from MR;;P; '#{msg}'" end end # create a module function within module MR; extend(P) # creates a singleton method end other files: require("MR/MIX/P.rb") module MR module Test p "Called p inherited down from Kernel" include(MR;;P) # overrides the p() inherited from Object, as mixed in from Kernel MR;;p "Called MR;;p" p "Called p" # should call overridden p() def self.pedigree() puts "#{Module.nesting[0].name} ancestors; #{self.ancestors.inspect}" end end end
  • How to check showRubyPanel is ready to accept puts

    16
    0 Votes
    16 Posts
    588 Views
    D
    @onidarbe said: Seems I need to use Win32API. most probably... for the Notepad++ side of things. I understand more what your doing now... I have a similar setup that uses 'Applescript' and 'Unix' to let me work in 'dev-mode', I struggled to get it to work for many versions. I'm very happy with it now, and it is possibly portable, if you want to have a look I'll PM you a copy... It now functions on a very simple premies. Let SU do the SU bits and only do what it can't with other tools... when you use Sketchup.plugins_disabled = true => 'only' the standard Sketchup.find_support_file("Plugins") are disabled. 'Ruby Console' can be opened from any other other loaded path. I have two different 'loader files' One is in "../Plugins/My_Folder/my_file", it has a cmd that toggles Sketchup.plugins_disabled = true : Sketchup.plugins_disabled = false Then, I use the "Tools" folder to hold a small ruby that basically... [sudo code] my_file = ( Sketchup.find_support_file("my_file.rb", "Tools") ).sub( "Tools", "Plugins") if Sketchup.plugins_disabled? && FileTest.readable?( my_file ) "Sketchup.send_action 'showRubyPanel;'" load(my_file) else ignore_me end john
  • Edge intersection

    5
    0 Votes
    5 Posts
    255 Views
    Dan RathbunD
    Sketchup::Model#raytest()
  • Memory management in C++ Extension

    15
    0 Votes
    15 Posts
    753 Views
    tt_suT
    rb_intern doesn't return VALUE, it returns ID. Adam, would the same issues for VALUE be valid for ID? I've used to make static const out of ID's I use a lot for easy access and avoid Ruby lookup up for every function call.
  • Special Characters in ENV[APPDATA] not recognized

    6
    0 Votes
    6 Posts
    314 Views
    AdamBA
    The only way around this I found was to write all my own Filepath handling in C++ for LightUp so handling Kanji, etc etc all works correctly.
  • Pushpull makes google 8 to crash

    4
    0 Votes
    4 Posts
    213 Views
    TIGT
    Here's a version that works, with undo, and a menu etc... require 'sketchup.rb' module PorteBuilder class Porte attr_accessor ;espaceBas, ;espaceHaut, ;espaceCote, ;charniereEspaceBas, ;charniereEspaceHaut, ;poigneeEspaceBas, ;hauteur, ;largeur, ;epaisseur, ;frontFace def initialize(espaceBas, espaceHaut, espaceCote, charniereEspaceHaut, charniereEspaceBas, poigneeEspaceBas, hauteur, largeur, epaisseur) @espaceBas = espaceBas @espaceHaut = espaceHaut @espaceCote = espaceCote @charniereEspaceHaut = charniereEspaceHaut @charniereEspaceBas = charniereEspaceBas @poigneeEspaceBas = poigneeEspaceBas @hauteur = hauteur @largeur = largeur @epaisseur = epaisseur end # initialize def draw() model = Sketchup.active_model entities = model.entities group = entities.add_group() entities = group.entities # dessiner la base de la porte basePts = [] basePts[0] = [0, 0, @espaceBas] basePts[1] = [@largeur, 0, @espaceBas] basePts[2] = [@largeur, @epaisseur, @espaceBas] basePts[3] = [0, @epaisseur, @espaceBas] base = entities.add_face(basePts) @hauteur = -@hauteur if( base.normal.dot(Z_AXIS) < 0 ) # faire une porte avec la base array_before = entities.to_a base.pushpull(@hauteur) array_after = entities.to_a new_entities = array_after - array_before # aller chercher la face qui aura la poignée new_entities.grep(Sketchup;;Face).each{|face| resultClassify = face.classify_point(basePts[0]) if (face.normal.parallel?(Y_AXIS) && resultClassify == Sketchup;;Face;;PointOnVertex) @frontFace = face break end } # bâtir le trou de la poignee rayonPoignee = 1.25.inch posXPoignee = @largeur - 2.0375.inch - rayonPoignee posYPoignee = 0 posZPoignee = @poigneeEspaceBas + @espaceBas centrePoignee = Geom;;Point3d.new(posXPoignee, posYPoignee, posZPoignee) # décider de la normal de la poignee edgesPoignee = entities.add_circle(centrePoignee, Y_AXIS, rayonPoignee) facePognee = ( edgesPoignee[0].faces - [@frontFace] )[0] facePognee.pushpull(-@epaisseur) end # draw end # class Porte class Moulure largeur = 3.75.inch epaisseur = 0.75.inch end # class Moulure class Montant attr_accessor ;largeur, ;epaisseur def initialize(largeur, epaisseur) model = Sketchup.active_model entities = model.entities group=entities.add_group() @entities=group.entities @largeur = largeur @epaisseur = epaisseur end # initialize def draw(porte) normalFrontFace = porte.frontFace.normal nearestPoint=nil porte.frontFace.edges.each{|edgeFrontFace| linesPoint3d=[] edgeFrontFace.line.each{|e| linesPoint3d<<e if e.class==Geom;;Point3d } linesPoint3d.each{|linePoint3d| point = ORIGIN.clone if nearestPoint == nil || linePoint3d.distance(point) < nearestPoint.distance(point) nearestPoint = linePoint3d end } } startingPoint = nearestPoint.offset [-porte.espaceCote-@epaisseur, 0, porte.hauteur+porte.espaceHaut] drawPart(startingPoint, @epaisseur*2+porte.largeur+porte.espaceCote*2, @largeur, @epaisseur) startingPoint = nearestPoint.offset [-porte.espaceCote-@epaisseur, 0, -porte.espaceBas] drawPart(startingPoint, @epaisseur, @largeur, porte.espaceBas+porte.hauteur+porte.espaceHaut) startingPoint = nearestPoint.offset [porte.largeur+porte.espaceCote, 0, -porte.espaceBas] drawPart(startingPoint, @epaisseur, @largeur, porte.espaceBas+porte.hauteur+porte.espaceHaut) end # draw def drawPart(startingPoint, offsetX, offsetY, hauteur) begin basePts=[] basePts[0] = startingPoint basePts[1] = basePts[0].offset [offsetX, 0, 0] basePts[2] = basePts[1].offset [0, offsetY, 0] basePts[3] = basePts[2].offset [-offsetX, 0, 0] base = @entities.add_face(basePts) if base.normal.dot(Z_AXIS) < 0 base.pushpull(-hauteur + 0.03125.inch) else base.pushpull(hauteur) end rescue puts $!, $@ end end # drawPart end # class Montant def self.dialog() prombasePts = ["Hauteur?", "Largeur?", "Profondeur"] values = [80.0.inch, 30.0.inch, 1.875.inch] results = inputbox(prombasePts, values, "Dimension de votre porte ?") return unless results # This means that the user canceld the operation height, width, depth = results Sketchup.active_model.start_operation('PorteBuilder') #espaceBas, espaceHaut, espaceCote, charniereEspaceHaut, charniereEspaceBas, poigneeEspaceBas, hauteur, largeur, epaisseur) unePorte = PorteBuilder;;Porte.new(0.75.inch, 0.0625.inch, 0.0625.inch, 7.0.inch, 11.0.inch, 36.0.inch, height, width, depth) unePorte.draw() lesMontant = PorteBuilder;;Montant.new(3.5.inch, 0.75.inch) lesMontant.draw(unePorte) Sketchup.active_model.commit_operation end UI.menu("Plugins").add_item('PorteBuilder'){self.dialog()} unless file_loaded?('PorteBuilder') file_loaded('PorteBuilder') end # module PorteBuilder I'm unsure of the exact issue. Your code seems more complex than it needs to be Why not draw the vertical face for the inverted U of the door-frame and pushpull that inside a door-frame-group, then draw the vertical face of the door-leaf and pushpull that inside a door-leaf-group, with the hole punched out for the ironmongery ? That way you control the face orientation - the counter-clockwise points around a face loop determine its normal vector. If you want door-stops add those inside a door-stop-group, in a manner similar to the frame itself: it can be inside the frame group too. You really don't need so many classes as a range of methods self.xxx() would do whatever you want with in the module, and using @xxx variables would make them available across the module too...
  • Intersection - Problem with coplanar cuts

    5
    0 Votes
    5 Posts
    365 Views
    TIGT
    You could try the first argument (recurse) of .intersect_with() method set as 'true'. Also you can include more than one 'entity' in the method's final argument (entities2) - passed as an array of entities... Say [g1, g2] or even [g1.entities.to_a, g2.entities.to_a].flatten
  • X-ray transparency settings?

    5
    0 Votes
    5 Posts
    1k Views
    TIGT
    You can only get/set and toggle Xray-mode on/off using: Sketchup.active_model.rendering_options["ModelTransparency"] Sketchup.active_model.rendering_options["ModelTransparency"]=true Sketchup.active_model.rendering_options["ModelTransparency"]=false The amount of Xray-mode's 'opacity' is 'hard-coded' Fredo has made a pseudo Xray-mode tool [can't recall it's name off-hand ], which works on selected objects, but that just swaps to similar but translucent materials [you could customize the amount of transparency in it] - so although it mimics Xray for parts of the model, it is only useful 'graphically' in images - there are none of the Xray-mode's advantages - like being able to pick 'through' intervening faces etc...
  • Class installs twice when reloaded!

    14
    0 Votes
    14 Posts
    477 Views
    onidarbeO
    aoh, I need to have that file Win32API.so in the plugin map! thanks
  • Web dialog fractions conversion

    8
    0 Votes
    8 Posts
    357 Views
    Dan RathbunD
    @garry k said: This is NOT as expected - regardless. I know myself that I work mostly in millimeters but feel quite at home going back and forth. All the other built in conversions work just fine. Just not this one. Yes I think it IS a bug. Today I tested with a model set to decimal feet (0.001) and got this: ` '2 1/2"'.to_l 30.0 Sketchup::format_length('2 1/2"'.to_l) 2.500'` So the inch symbol is ignored. But in a model set to inches: "2.54'".to_l %(#008000)[30.48] So it seems the foot symbol works, IF the numeric is decimal. But IF it is fractional (model set to inches): "2 1/2'".to_l %(#008000)[24.0] **So I agree. It is a bug issue with fractional expressions. ADD: The error also occurs within the VCB (Measurements Box) !**
  • How can I run code on view-change

    8
    0 Votes
    8 Posts
    330 Views
    onidarbeO
    thanks!
  • Erase Selection from within any plugin (VK_DELETE)

    2
    0 Votes
    2 Posts
    212 Views
    Dan RathbunD
    @fredo6 said: The Selection observers remain completely silent about the erasing of the current selection. No event is fired. Not true... they are calling misspelled callbacks. To see what the SkecthUp engine wants to call (even tho the spelling is a bug,) ... override the respond_to?() method in your observer subclass, (being sure to pass the arg on to super,) but puts'ing the method name to STDOUT. Once you know the mispelling... you can write wrapper callbacks that use the mispelled method name that simply call the correctly spelled callback (or just alias the bad names to the good names.)
  • Remove last line in Ruby Console?

    3
    0 Votes
    3 Posts
    226 Views
    onidarbeO
    ok, thanks
  • What use are Tool id's?

    6
    0 Votes
    6 Posts
    257 Views
    Dan RathbunD
    Last I knew Mac only worked with string arguments for actions.
  • 1 second pop-up, timed message

    3
    0 Votes
    3 Posts
    221 Views
    onidarbeO
    Short and ride to the point Thanks again Dan! Have a nice new year's eve...
  • Workflow for script coding and testing

    3
    0 Votes
    3 Posts
    207 Views
    Dan RathbunD
    (1) If you are going to develop, logon as an admmistrator, so you have full access rights to the plugins folder. (Or right-click the SketchUP icon, and choose "Run As Administrator", or "Run with elevated Privileges" etc.) (2) Forget about zip & rbz during development, that is the avenue of distribution. (3) Stop thinking of SCRIPT, and start thinking of your code as being defined WITHIN and executing FROM your namespaces. You need to choose a toplevel namespace (module name,) and then write ALL of your plugins within a sub-module of your toplevel module. (Clarify: I mean each plugin has it's OWN sub-module of your toplevel author/company module. That way NONE of your plugins clash with each other, NOR any other author's plugins.) (4) BE wary of comparing Ruby to Fortran, BASIC, etc. Ruby is MUCH different. It is a dynamic language. This means that modules and classes can be modified at any time. Methods can be redefined, removed, access changed (made private,) etc. This also means you can reload a file that defines your plugin's module, after making changes, and the changed methods are updated. This is great for development. (5) Ruby is 100% object-oriented. Ruby has 2 (TWO) things. Objects and references that point at objects. Ruby does not really have variables, but the documentation and some query methods refer to "variables", but I think it is best to have programmers from other languages know from day one, that Ruby only has references, not variables like BASIC. For example, Ruby references can point at any object, at any time, of any class, and then be changed (re-assigned,) to point at any other object, of any other class (or perhaps the same class.) So any "typing" of reference names is only in your mind. It it makes you "comfy" to say use bMyRefName to hold a reference only to true or false (or nil,) then thats OK. Add (6) Read the "Pick-Axe" Ruby book cover to cover. (see the Ruby Resources sticky topic.) Doing so will make your journey so much easier, and avoid asking all the questions here that people who do not read the book first have already asked (here and in other forums.) (7) Do not think or write your code in a linear manner. Think in and write code in an event-driven manner. (Have your code respond to things the user does, or act upon objects the user has selected, or do something with the entity the user has just modified, etc.) See the API dictionary on all the observer classes.

Advertisement