ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info
  • [Code]Text label system

    8
    0 Votes
    8 Posts
    150 Views
    TIGT
    Plain variables, or perhaps more correctly 'references', [e.g. x] are only used/changed in their specific def [method] that defines them. Ones starting with @ [e.g. @x] - their current value is accessible to all methods during that instance of the class/module. Any method can define or redefine them, Ones starting with @@ [e.g. @@x] are similar to @ ones, BUT their current value is remembered across multiple uses of that class/module - e.g. good for remebering values last used in dialogs. They need to be 'declared' outside of any method, but after that any method can then redefine them. Constants [starting with a capital letter, or commonly with all caps, e.g. Z_AXIS] are similar to @@ ones, they are remembered across all uses of that class/method, BUT they are not readily changeable - because they are 'constants'! Move your 'start_operation' out of the iteration block [to match the 'commit_'] that way all we become 'undo-able' in one go. The selection.each{} block adds a piece of text to every selected object when the code starts. However, the Sketchup.send_action("selectSelectionTool:") will stop more that one iteration. It simply exits the tool and activates the 'Select' tool. If you want to be able to 'pick objects' in turn you will need to [re]write/launch this as a proper Tool... this will involve getting input-points, reading mouse-positions and mouse-clicks etc... Then using those for new text objects etc... See the API and examples - 'linetool.rb' etc - for some Tool method ideas/examples... Or other authors' tools' .rb files - like say some of my 2dTools... There is limited access to 'Text' objects' properties through the API - see the relevant pages - http://code.google.com/apis/sketchup/docs/ - height is not one of them - unless you make it as '3d-text'... It's a long standing request...
  • Start a Java application asynchronous

    12
    0 Votes
    12 Posts
    981 Views
    TIGT
    As I explained... Dan's idea of opening [executing] a file, can't work by passing a 'command' or even an exectable with following arguments, it will only work if you pass it a file. So UI.openURL(full_url) opens that web-page in the default browser. And UI.openURL('file:///'<<full_path_to_file) opens that file in its default application, so if it's a .txt file then Notepad opens it, if it's a .doc file then Word opens it and so on [for a PC at least]. If it's an 'executable' then it 'runs' - these kinds of file include .exe, .cmd, .bat, .vbs etc on a PC [.command on a MAC etc]. Some executables take arguments when they are run from a 'shell'/'console'/'terminal' - e.g. in a PC command-shell typing Notepad[.exe] opens that program with a new empty/untitled window; but Notepad "txt_file" would open that file if it exists, or if it doesn't exist it asks you if you want to make it... BUT you CAN'T pass arguments with UI.openURL() So UI.openURL("Notepad.exe") will open an instance of 'Notepad' [true] UI.openURL("\"Notepad.exe\" \"path_to_my_txt_file\"") will fail [false] UI.openURL('file:///'<<"path_to_my_txt_file") will open that existing txt file with Notepad [true] or it will fail [false] if that txt file doesn't exist. Using system(commands) in Ruby should give similar results to typing the exact same text into a command-shell - hence Dan's advice to 'quote' arguments - because 'spaces' in file paths will be taken as the start of a new argument otherwise and mess you up... So using system(system("\"Notepad.exe\" \"path_to_test.txt\"")) is the same as using the very same strings inside a command-shell... BUT this runs as part of the Ruby thread, and Ruby will wait for it to complete... The way to pass arguments to an external executable, that runs independently of Ruby once it's started, is to run it as something like a .cmd/.bat [.command on MAC]. You can't avoid the startup black PC window [although you can reduce it to a flicker by having one .cmd file to start another main .cmd file, the first opens and closes almost instantaneously while the second then runs silently]. So you can write a temporary .cmd' file [etc] then use UI.openURL('file:///'<<path_to_cmd_file) to run it [also changing directory briefly to the file's folder does allow you to 'open' it 'by name only'...] If you use some other kinds of executables like .jar or .vbs these can be set to run 'silently' - however, passing arguments to them is then awkward [although you could 'write' a temporary .vbs file etc containing ALL of the info needed to complete things*, or perhaps use an .ini. file containing the data needed by the .jar to read in for that to do it's stuff; on a MAC you would use an AppleScript or equivalent]. *For a 'silent' VBS solution you would use something like this line of code that you 'puts' into a 'temp.vbs' file... createobject("wscript.shell").RUN "java -jar \"full_path_to_Model2GCode.jar\" \"full_path_to_fileForJava\"", 0, False Obviously you need to adjust it for you own full file paths/names etc... Then in Ruby you'd use UI.openURL('file:///'<<"full_path_to_temp.vbs") to run it - and it then executes asynchronously, quite separate from Ruby...
  • Determining when a model has changed

    4
    0 Votes
    4 Posts
    50 Views
    Dan RathbunD
    @al hart said: @tig said: The model.modified? method determines if the Model has been modified since the last save. That would work if there was a "saved" Observer, ... The "saved" callbacks are in the Sketchup::ModelObserver class (where they should be, because there can be more than one model open on the Mac. But you can write a generic model observer that handles all open model instances, since the model instance's reference is passed to most callbacks.)
  • [Code] Locking down the API

    3
    0 Votes
    3 Posts
    142 Views
    thomthomT
    @dan rathbun said: You can shorten the file using ObjectSpace.each_object() iterators: I'm locking down more than the API - also the Ruby core classes. @dan rathbun said: It NEEDS to modify several classes, so you will need to add a require('dynamiccomponents.rb') at the top of the file, before freezing. Well, "needs"... ...they chose to. But yes. One adds exceptions as one pleases. This list is just a boilerplate lock-down.
  • Problem with group.copy

    20
    0 Votes
    20 Posts
    643 Views
    Dan RathbunD
    @thomthom said: hm... I'm tempted of adding a script that loads first that freezes the base ruby and SketchUp classes and modules just to see what happens. Could be useful to catch misbehaving plugins. Problem is that Ruby is designed to allow this by people who know what they are doing. Many of the Extended ruby Library files add needed methods to base classes, or modify some methods (RubyGems is an example that modifies the global require method, although I never understood why it really needed to do it.) Even though methods are objects, it is difficult to get a reference to an instance method within the class definition (very easy within an instance of the class.) So it is hard to freeze particular instance methods class-wide, without freezing the whole class or module. (Perhaps the gurus on the Ruby Forum know a trick?) An alternative would possibly be (untested): class Sketchup;;Group # Make a copy of method ;copy alias_method(;_copy_,;copy) def self.method_added(sym) # # callback called by Ruby when a new method is defined; # alias_method(;copy,;_copy_) if sym == ;copy # end end EDIT: method_added is a class callback, so must be defined using def self.method_added(sym)
  • Intersecting line with BoundingBox

    10
    0 Votes
    10 Posts
    351 Views
    A
    I hadn't considered that because planes are infinite, but it works well combined with BoundingBox.contains? def intersect_line_boundingbox(line, bb) # Intersect with 6 planes of the bounding box's sides. p0 = bb.corner(0) p1 = bb.corner(7) [ [p0, X_AXIS], [p0, Y_AXIS], [p0, Z_AXIS], [p1, X_AXIS], [p1, Y_AXIS], [p1, Z_AXIS] ].each{|plane| intersection = Geom;;intersect_line_plane(line, plane) # Stop when the intersection point is inside the bounding box. return intersection if bb.contains?(intersection) # else continue } # No intersection (because bb is aside line or behind line start). return nil end There is certainly room for optimization (ie. maybe less than 6 planes, or checking whether BB is behind line start). I first had the code with an infinite straight line (starting from -infinity) and only one intersection with a plane but that failed due to precision errors.
  • Intersecting and Attribute inheritance

    12
    0 Votes
    12 Posts
    299 Views
    TIGT
    Put very simply we need to see what face is under what point. We find all of the 'combined faces' in group3 [after the explosion of copies of group1 and group2 we added into it] - an array which I named faces3. Each face in faces3 has vertices, we consider the first one in each case = vertices[0], we find it's .position, we offset that position a little and rotate it around the Z_AXIS and the vertex.position by steps of 1.degree until we know it's on the 'face'. That's the classify_point method. So now we have a point we know is on the face. We test all of the faces in faces1 until we get on that 'contains' the point - we remember its 'Plot' attributes. We test all of the faces in faces2 until we get on that 'contains' the point - we remember its 'Zone' attributes. We add new attributes [Combo] to 'face' combining these two sets of attributes... You could probably do with testing group1 and group2 faces for both attribute dictionaries, since you can't be sure which group is which in the selection - unless they have 'names' that tell us?
  • UI::WebDialog =&gt; set_html =&gt; large HTML pages

    12
    0 Votes
    12 Posts
    2k Views
    N
    Thanks guys for the hints! I got a message from Noel!
  • Mysterious change of group bounding box coords

    3
    0 Votes
    3 Posts
    121 Views
    sdmitchS
    thomthom, Thanks for the help. The solution was to obvious I guess.
  • Using win32ole on startup

    14
    0 Votes
    14 Posts
    272 Views
    S
    @thomthom said: For timer delay you should immediately stop the timer in it's block - because if a modal window appear within the block, like a messagebox or an error message (which you get when you start SU) will make the timer repeat until the modal window is closed. <span class="syntaxdefault"><br />timer </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">start_timer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">false</span><span class="syntaxkeyword">){<br /></span><span class="syntaxdefault">  UI</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">stop_timer</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">timer</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">  </span><span class="syntaxcomment"># ...<br /></span><span class="syntaxkeyword">}<br />&nbsp;</span><span class="syntaxdefault"></span> Hi Thom and TIG, that's exactly how ì solved it. Noticed the fact that a UI.messagebox in the block will make the timer repeat too. Never used UI.start_timer before but I can think of some nice implementations of it.
  • Purpose of Single Line Consoles for Ruby?

    10
    0 Votes
    10 Posts
    229 Views
    thomthomT
    @chris fullmer said: I think I can see that I'm conflating the concepts of editor vs. console. If so, I guess I only see the need for a built in simple editor, and I don't comprehend what a single line console is good for. I think this is the key here. You use it to develop plugins / snippets directly into SketchUp. (Which makes sense as you get a direct result.) Personally I'm too paranoid that SketchUp crashes and bye-bye goes all my work. And I have grown to rely heavily on the features Notepad++ or Sublime2 gives me that I always write my code in an editor. I use the console for debug output, reloading, and minor testing (multiple command over multiple lines, or multi-command-one-liners.) (Btw, isn't it Shift+Return for the new-line in the SU developer console?)
  • [API] Menu.add_item( caption, index )

    8
    0 Votes
    8 Posts
    426 Views
    J
    Just confirmed it does work in sub-menus. [image: 8NrV_2012-11-04_134125.jpg]
  • WebDialogs - The Lost Manual — R1 09 November 2009

    43
    0 Votes
    43 Posts
    22k Views
    thomthomT
    hm.. interesting. Wasn't aware of this Pages feature. Nice.
  • Losing focus on window

    2
    0 Votes
    2 Posts
    526 Views
    thomthomT
    Some times the toolwindows get the focus. Say if you undo a change where you edited a material in the Material Editor - SU will send the focus back to that window. Annoying.
  • Scaling a component with subcomponents

    12
    0 Votes
    12 Posts
    214 Views
    F
    Hey Fredo6, I actually mentionned you plugin in my other post and how I was trying to figure out how you did it. Only problem is you're a ruby/sketchup god and I'm more of a peasant. Thanks to Chris, I now know that what I'm trying to accomplish is called parametric modeling, learn something new everyday . So I did a search for that and came up with this file parametric.rb (attached) and a couple of interesting websites, though I haven't had a chance to go through them so I apologize if they aren't that good. http://drivingdimensions.com/SketchUp/FAQ/ http://www.sketchup.com/intl/en/download/rubyscripts.html [EDIT: attachment removed by admin]
  • Creating a nested component

    4
    0 Votes
    4 Posts
    346 Views
    TIGT
    Entering a faces edges/vertices 'in order' to add a clone into another context will determine the normal of the new_face. But it's always possible that the original face has been reversed if you took the edges ? So get the original_face.normal and compare it with the new_face.normal [allowing for the transformation differences!] - then if they don't match you must reverse the new_face...
  • [Code] Progress bar with tasks

    2
    0 Votes
    2 Posts
    72 Views
    renderizaR
    This looks very interesting...Thank you both!
  • Edit Watermarks by code?

    3
    0 Votes
    3 Posts
    55 Views
    renderizaR
    I was hopping there was more functions regarding watermarks with the API, maybe in SketchUp 9 who knows. For creating water drops on screen I guess I can still make it work by animating the Scene Manager to desired style. Thanks
  • Trouble understanding how Dynamic Components are created

    5
    0 Votes
    5 Posts
    118 Views
    F
    Hi Chris, @chris fullmer said: Well then, the bigger question is does you component need to be compatible with the built in dynamic component webdialog, like for others to interact with it. I didn't think of that since I assumed the way of doing this was through Dynamic Components. So I'm not sure what being compatible with implies the DC webdialog implies either way. @unknownuser said: There is no need to actually make a "dynamic component" to do what you are asking. There is a lot that goes on behind the scenes of dynamic components. If all you want to do is manipulate components using your own webdialog, I'd recommend not using the term dynamic component a that confuses the question with the actual dynamic components. Gotcha, knowing that now, yes that's exactly what I'd like to do is being able to manipulate the created components. eg: height, width, depth... along with other variables I have. And being able to do so to all the components or just selected ones. @unknownuser said: The way I see it is that you have 2 main issues to tackle here. 1 - You need to learn how to work with components, and scale them or manipulate their geometry. You can learn this without the trouble of a webdiloag first. I have a pretty good handle on creating components already but manipulating tham after they've been created is another story which is what my original question should of been. @unknownuser said: 2 - You need to master is how to converse freely back and forth from ruby and your web dialog. Once you get them talking, and you know what you need to do to your components, then its easier to understand how to put your webdialog together so it can reach into the model and make changes. I've got the initial communication between WD and ruby working just fine. Actually My plugin is built with WD and also works great, well it needs a few 'fixes' but I'm able to get all that done, as best as I can for a newbie at lest. But getting my WD to then modify or manipulate as you say the components I create is a whole other story! I fugured integrating DCs was the way to go but seems like there are other ways of doing so. That being said, from your reply maybe I should look into scaling my components? Or resending new values and some how applying them to existing components and redrawing? Am I even close in my assumptions? Thanks, Frank
  • [API] curve.move_vertices

    10
    0 Votes
    10 Posts
    170 Views
    thomthomT
    @mptak said: If I apply a transformation to the separate vertices in an circle or arc it acts differently than if I have exploded the curve. Any insights? When the vertices are a part of a circle the circle seems to dilate about the center even if the transformation is defined as tran=Geom::Transformation.new([0,0,10]) If the curve is exploded the transformation does the expected shift of 10 in the "z" direction. Thanks for any immediate insights. In Vertex Tools I had to explode all curves for the vertices I wanted to move. Weird things happen when you move vertices connected to a Curve. I have never tried Curve.move_vertices though...

Advertisement