🏢 PlaceMaker | 25% off for February including new Google Earth data imports! Learn more
  • Model attributes and importing

    7
    0 Votes
    7 Posts
    178 Views
    thomthomT
    @joshb said: Thanks thomthom! That is exactly what I needed to know! Right now users are just going through the SketchUp GUI File, Import to do their work. I'm going to look at the observers, perhaps DefinitionsObserver.onComponentAdded to see if I can do my merging there. Thanks again! Josh Beware! UI import is not the only thing that might import a model. If you react to an observer event you can crash SketchUp. You may also interfere with some other operation. Setting attributes is something that can be undone. And starting an operation in the middle of another one will interfer and break the first one. So if you react to an observer event and modify anything - you might break the undo-stack, you might break an operation of another plugin or native function - or you might even crash SketchUp. My recommendation for observers is to only read data. If you need to react with model changes, cache it for a later time when you know it's safe to modify your model. For instance, you detect a model import, you cache what definition that was and wait with the merge until your plugin need to access any of your data. Another thing: be very careful what your observers do. Make them do as little as possible. Events can trigger in the thousands in some scenarios and then it doesn't take much to bog down a model. Refer to this list of observer issues which I've been trying to chart: http://www.thomthom.net/software/sketchup/observers/
  • Storing Data

    3
    0 Votes
    3 Posts
    103 Views
    TIGT
    Let's assume your 'box' is a component. Let's assume there is a value 'x' thet you want it to 'remember' for another time... You have a reference to the definition - let's say it's ' defn'... Then this code remembers it: defn.set_attribute("Cheez_Data","x",x) Provided that you save the model the next time you want to access the SKP and that definition - perhaps via a selected instance... like defn=model.selection[0].definition - after you test for it being a suitable instance etc... You could use: x=defn.get_attribute("Cheez_Data","x",0) Here it's set to return 0 if it's not been set before - otherwise it's 'nil'. You can store loads of different data in an object's attribute-dictionary. The data types can be integer, float, string, boolean, array... A hash has to be stored as an array for the 'set'... and reconstructed into a hash after the 'get'. You could attach data to the the model itself, BUT since you are going to change a specific definition you might be best storing it there... You can attached attribute data to most 'types', but some like geometry are more 'transient'...
  • Array woes

    4
    0 Votes
    4 Posts
    73 Views
    TIGT
    Yes, it'd return an error or if @ip1 is nil then it might be seen as equal to an empty @pts[] ? If you are testing something that might be nil it's a good idea to check it exists first...
  • Ruby api - Get the thickness of component

    4
    0 Votes
    4 Posts
    219 Views
    N
    @TIG Thanks for the great long and damn useful answer. I will try it today
  • Forcing Sketchup to use IE8 and other Web Dialog problems

    24
    0 Votes
    24 Posts
    1k Views
    Dan RathbunD
    Well.. it returns white on Win7 because that IS the system dialog background color "out of the box". (One reason I hate Windows 6+ is they try to make dialogs look like webpages!) Anyway.. a user can set their own theme, or download a premade theme from the Web, in which the dialog background may not be white at all. The other day, on XP, as a test I changed my system dialog color to Purple, just to test that method, and it worked, it returned the purple color that I had set. And SketchUp also used that color for background of it's dialogs and toolbars, etc.
  • [Webdialog] Javascript lerts with object bypass

    6
    0 Votes
    6 Posts
    301 Views
    Dan RathbunD
    @chrisglasier said: Did not mean to offend! Ya' did not... It was a half-tease... ... and a half devil's advocate, asking the obvious question (that a novice might ask.).
  • [Code] WebDialog communication

    35
    0 Votes
    35 Posts
    5k Views
    alexschreyerA
    Great idea to clean up the web-dialog interfacing! Let me throw one more idea in there: Apparently post_url does not accept any returned data (it just opens it in the embedded browser window). Might be nice to have get_url and post_url functions that at least return the data. That could even be expanded into get_json and post_json . Of course, jQuery will do that but a native way might be neater. It's definitely on my feature request list for SU... Cheers, Alex
  • SU SDK and geometry creation

    11
    0 Votes
    11 Posts
    243 Views
    Dan RathbunD
    I could see doing that, so as to work with skp files in a normal Ruby session (outside of embedded SketchUp Ruby.) But D.M. says that his goal is to work inside SketchUp embedded Ruby. What's the point ?? The SDK is a subset of the Sketchup engine. Inside SU it is already loaded into memory, so you do not need reader and writer DLLs at all. Just use IT. There IS an example in the SDK that shows how to.. and the first step is to always get a handle on the Sketchup application.
  • EntitiesObserver and Attributes - work around

    21
    0 Votes
    21 Posts
    2k Views
    R
    Ok. hopefully there is a solution. If I find one I will return...
  • State of Observers Redux — 18 August 2011

    30
    0 Votes
    30 Posts
    5k Views
    thomthomT
    Added public bug tracker to the BitBucket repo: https://bitbucket.org/thomthom/sketchup-observers/issues?status=new&status=open People can add reports of broken observer events there.
  • How can a dialog be made modal on Mac

    16
    0 Votes
    16 Posts
    1k Views
    thomthomT
    Ah, as it turns out - I made the modal feature only for TT::GUI::Inputbox. (What I use with CleanUp) My approach to "modal" was to push a Tool to the tool stack which will draw the dimming screen. It also detect if the user activates another tool which it takes as a cancel action to close the dialog. There is much to be improved with this method. (For instance, I think you can block the Orbit tool from activating) https://bitbucket.org/thomthom/tt-library-2/src/7462992bf4f3/TT_Lib2/modal_wrapper.rb In either case, my TT:GUI::Window class is something you can't easily swap in for UI::WebDialog. I have a set of Ruby classes for Button, Checkbox etc which generates the HTML and JS for you. As well as pre-defined styling. To add custom behaviour you must attach JS scripts. It's far from complete and likely to change. But for the sake of it - Hello World example of my TT:GUI::Window class: <span class="syntaxdefault"><br />module TT_Test<br /><br />  def self</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">create_window<br />    options </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">;</span><span class="syntaxdefault">title </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> </span><span class="syntaxstring">'Hello Window'</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">;</span><span class="syntaxdefault">resizable </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> false</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">;</span><span class="syntaxdefault">width </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> 300</span><span class="syntaxkeyword">,<br /></span><span class="syntaxdefault">      </span><span class="syntaxkeyword">;</span><span class="syntaxdefault">height </span><span class="syntaxkeyword">=></span><span class="syntaxdefault"> 200<br />    </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    window </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> TT</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">GUI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Window</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault"> options </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">theme </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> TT</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">GUI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Window</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">THEME_GRAPHITE<br />    <br />    button </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> TT</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">GUI</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Button</span><span class="syntaxkeyword">.new(</span><span class="syntaxdefault"> </span><span class="syntaxstring">'Close'</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">{</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">|</span><span class="syntaxdefault">control</span><span class="syntaxkeyword">|<br /></span><span class="syntaxdefault">      control</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">close<br />    </span><span class="syntaxkeyword">}<br /></span><span class="syntaxdefault">    button</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">size</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> 75</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> 28 </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    button</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">right </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 5<br />    button</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">bottom </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> 5<br />    window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_control</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> button </span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault">    <br />    window</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">show_window<br />    <br />    window<br />  end<br /><br />end </span><span class="syntaxcomment"># module<br />&nbsp;</span><span class="syntaxdefault"></span> I've found that instead of fighting against this problem I change the code flow to not require modal windows. Often it can be done - just needs a different thinking. Which is why I haven't worked further on the issue.
  • Save coordinates in an array

    17
    0 Votes
    17 Posts
    637 Views
    M
    Thank you so much, Dan. Your tips solved the problem. Now, I have the program running, but I don't get the correct coordinates. I was expecting to get some positive and some negative, according to where I am from the axes. I clicked the 4 corners of the screen and I got the following, which doesn't look right: @unknownuser said: x: 46 y: 48 z: 48 x: 53 y: 52 z: 46 x: 54 y: 57 z: 46 x: 52 y: 46 z: 56
  • Trimble??? - the beginning og the end!?

    5
    0 Votes
    5 Posts
    209 Views
    R
    I think Im calmed a little down for now...
  • Count Certain Shapes

    8
    0 Votes
    8 Posts
    240 Views
    TIGT
    @michaelazer said: Thanks, TIG. I think I mixed up with the logic of Sketchup. (1) Does count=faces.length count all faces on the screen OR in the array I made? It's 'faces' in the array you have made - so it counts just the faces that match your pattern. (2) If a user deletes a face manually, will it be removed from the array? OR only from the screen? When a users erases a face it vanishes from the model's entities collection. If you have made the array of faces before the deletion then the now deleted face is still counted - because the array is a list of faces that matched the pattern at the moment the list was made... You can check for each face's 'validity' before 'counting' thus: count=0; faces.each{|face|count+=1 if face.valid?} Now 'count' only includes 'valid' [i.e. NOT-deleted faces. Again this is dependent on the moment you make the count. The array 'faces' includes all matching faces at the moment the list is made. The 'count' is now the number of valid faces within that array [they were check to be 'matching']. If the user erases another face after the count is made you are again 'out of step'. Similarly if additional matching faces are added after the matching 'faces' array is compiled the list is incomplete. It's easy enough to have some code to compile a list of matching faces and count valid ones at various stages of your tool's use, just remember to do it at the appropriate moment to avoid having out of date information in the array or count...] (3) If the answer to (2) is "only from the screen" does this mean that if I re-draw the array, will the shape that the user deleted get re-drawn? Thanks, again.The array is only a list of faces that match your pattern. You can't 'redraw the array' as it's a list of references to faces only. If a face is deleted from the model you can no longer access its information as it no longer exists. If you mean 'remake' the array you can just rerun the code (remembering to empty the array first with faces=[]), and the new list will no longer include the face that was erased. If you want to remember faces even if they are gone you can make an array of say 'face_points' and later use those to recreate a missing face... this is porbably more complex than you want... for each face face_points=[]; face.vertices.each{|v|face_points<<v.position}
  • Followme - hang

    10
    0 Votes
    10 Posts
    224 Views
    W
    Hi , Dan unfortunately , i've removed all the ".mm" in your code , if the diamter of the circle is 50 mm , this will hang , but it's fine if the diameter is 20mm , this is the reason why i said it seem to be related to the diameter of the circle instead of decimal place or array type.
  • Geometry, Transformation, and Scaling

    5
    0 Votes
    5 Posts
    520 Views
    A
    Tnks! All logical and useful
  • BitBucket Basics / Git Tips

    6
    0 Votes
    6 Posts
    568 Views
    Dan RathbunD
    Great Idea, I was wondering how to do that. Done.
  • How to rotate an object in ruby?

    2
    0 Votes
    2 Posts
    112 Views
    thomthomT
    Geom::Transformation.new( origin, zaxis ) <- that isn't a rotation transformation. To rotate you must use one of these formats. Geom::Transformation.new( pt, axis, angle ) Geom::Transformation.rotation( point, vector, angle ) https://developers.google.com/sketchup/docs/ourdoc/transformation#rotation But what is not clear is this: "how to rotate an object in the direction of the cursor" What do you mean by this?
  • Can Sketchup receive Window message?

    7
    0 Votes
    7 Posts
    192 Views
    thomthomT
    @debbie said: @thomthom said: Maybe you can make a Ruby C Extension work for you? Ruby C extension? seems useful! thanks. I made a Hello World project for getting Ruby C Extensions to work under SketchUp: https://bitbucket.org/thomthom/sketchup-ruby-c-extension
  • Complete Crash?

    4
    0 Votes
    4 Posts
    86 Views
    A
    OK...it doesn't crash if just before showing the savepanel I put a line of code to show a simple messagebox: then the savepanel shows. Although the messagebox is nowhere to be seen. Then I tried this code: if UI.messagebox("Save results to file?", MB_YESNO) == 6 savePath = UI.savepanel("Save results file",model.path,"Sunlight analysis.csv") # If the user doesn't press cancel; if savePath outfile = File.new(savePath, "w") outfile.write(allResults) outfile.close() end end Now when the execution reaches this point SU suddenly switches program, i.e. as if someone had pressed Alt+Tab. It's still there, but I have to reopen it. And the messagebox still isn't anywhere, hence neither is the savepanel. I just seem to have gotten the UI very confused in general.

Advertisement