RBZs in SketchUp 8M2: Distribute Your Plugin as One File!

Thursday, December 1, 2011

Posted by Scott Lininger, SketchUp Engineer

In the latest and greatest SketchUp 8 maintenance release, M2, we added an easier way for users to install your Ruby scripts. In the past, folks had to manually copy your .rb files into their Plugins folder, or you would have to write a custom installer to do it for them.

Now there's a button in SketchUp that'll make this easier. It's found under Preferences > Extensions > Install Extension. Clicking this button will bring up a file browser window where your users can select any .RBZ file from their harddrive, and SketchUp will put them in the right spot plus load them up. No more fumbling around looking for the Plugins folder. No need to restart SketchUp to see your shiny plugin.

But what is an RBZ file?

And how do I make one?


It's simple. RBZ files are nothing more than ZIP files. You can use your favorite ZIP tool (I like 7-zip on Windows) to create the archive, then rename it to have a .RBZ extension. Anything you put inside of this RBZ file, including files and subfolders, will be unpacked into the user's Plugins folder. That's it!

So let's say you had a plugin with the following files in it:

  • SketchUp 8/Plugins/helloworld.rb
  • SketchUp 8/Plugins/helloworld_files/hello.html
  • SketchUp 8/Plugins/helloworld_files/smiley.png
You would create a ZIP file containing the above files. With my ZIP tool, I simply select the helloworld.rb and helloworld_files folder, right click on them, and select "Create ZIP". The resulting file is called helloworld.zip. Right click > rename to helloworld.rbz, and you're golden. HOWEVER, before I do this, it would be even better to change my simple ruby script into a SketchupExtension. That way my users will see your Extension added to the Extensions panel when they do the install, and in the future it's easy for them to turn it off.

Happy distributing!

Hidden Corners of SketchUp's Ruby API: Transforming Vertices

Thursday, August 11, 2011


There are many capabilities of the SketchUp Ruby API that aren't easy to discover. With over 1000 methods, it's not surprising! In this semi-regular blog series, I'll be pointing out my favorites.

Here's one: transforming individual vertices.

Let's say I've drawn a 2x2 grid of squares on the ground...

ents = Sketchup.active_model.entities
square1 = ents.add_face [0,0,0], [10,0,0], [10,10,0], [0,10,0]
square2 = ents.add_face [10,0,0], [20,0,0], [20,10,0], [10,10,0]
square3 = ents.add_face [0,10,0], [10,10,0], [10,20,0], [0,20,0]
square4 = ents.add_face [10,10,0], [20,10,0], [20,20,0], [10,20,0]
center_vertex = square1.vertices[3]

Easy. Now, this also gives me a 3x3 grid of vertices. Let's say I want to move that center_vertex 10" into the sky without moving the others. Can it be done?

If you go to the Vertex class documentation, there isn't a simple transform() method. There's a Vertex.position method... but alas, it's read only.

But wait! What about the parent class? A Vertex is an Entity, and so I can call any Entity method, too. Maybe there's a transform() method on the Entity class...

Nope.

At this point, you might have given up. (I know I did the first time I tried this...) But don't! The secret is that Entities.transform_entities can accept naked vertices as well as edges and faces. This wasn't obvious to me because if you iterate over the Entities collection, it doesn't contain vertices! So I just assumed that the transform_entities method wouldn't work on vertices. I was wrong, though. It'll accept any Entity, just like the documentation says. Check this out...

ents = Sketchup.active_model.entities
square1 = ents.add_face [0,0,0], [10,0,0], [10,10,0], [0,10,0]
square2 = ents.add_face [10,0,0], [20,0,0], [20,10,0], [10,10,0]
square3 = ents.add_face [0,10,0], [10,10,0], [10,20,0], [0,20,0]
square4 = ents.add_face [10,10,0], [20,10,0], [20,20,0], [10,20,0]
center_vertex = square1.vertices[3]

move_up = Geom::Transformation.new([0, 0, 10])
ents.transform_entities move_up, [center_vertex]

Hopefully that will help you out in some future plugin coding adventure.

What are your favorite "secrets" of the API? Share 'em in the comments.


Being a Good SketchUp Ruby Citizen

Wednesday, August 3, 2011



In the world of Ruby scripts, keep in mind that users who will install your SketchUp plugin probably have installed other SketchUp plugins, too. Since Ruby is a wide-open language that lets you override and inspect just about anything, this can lead to bugs where your plugin conflicts with someone else's.

So before you distribute your hot new plugin, don't forget to follow these important steps:
  1. Try to know what others are doing/have done. This isn't always easy, but some research and questions go a long way in avoiding conflicting class/method names. It can also prevent you from duplicating someone else's effort - why re-create method x when it's already been written? Just tap into it and go (with permission, of course). Look for public scripts that are doing similar things to what you're acconplishing, and consider working with that author to cross-promote your tools. Sometimes, the already-written code won't do exactly what you want. In that case, you can either subclass yours and modify the methods (for classes, obviously), or write your own using a different class/method name.

  2. Try to use unique names rather than common ones. For example, if you write a "ProgressBar" class, you will cause conflicts with any other "ProgressBar" class. That will make for unhappy users, as they try to get tech support for something the author says works just fine on his machine, but clearly won't work on their machine; and will make for unhappy fellow developers, who have to hunt down the conflicting script, locate the author, and try to work out a solution. Better to do something like "mskp_ProgressBar" which is unlikely to collide.

  3. Encapsulate methods in a Module or a Class. Within a class, you don't have to worry about method naming conflicts, and within a module, you can be less careful about both class and method names.

  4. Test your work against as many other works as possible, and test them against yours. Unfortunately, the burden of compatibility will more than likely fall to the second developer. However, if you send your script to other developers asking them to test for compatibility with their works, they'll most likely be happy to oblige (subject to their own time constraints, naturally). This will help keep the user experience (and your reputation) positive.

  5. Be respectful of the Plugins directory structure. If your plugins has a lot of support files (piles of .rb files, html file, image files, etc.), group them together into a subdirectory under the Plugins folder. This will make it easy for users to identify (and potentially uninstall) your script. It will also make it less likely that your "cursor.png" will by overwritten by someone else's "cursor.png".

  6. Document your code and include contact information. Write generous comments and include a header block at the top of your scripts that tells people what is included with your Plugin, what it does, and how to contact you in case of upgrades or bug reports.

Thanks for Rick Wilson for the original post that I took these tips from. Code on!

Turn Your Plugin Into An Extension

Thursday, July 21, 2011



Around the office here we're always amazed at the awesome Ruby scripts you developers create. They make SketchUp more productive, smarter, and downright snazzy. So it's no surprise when we hear from users who have a lot of plugins installed.

Plugin management can get really difficult, though. If two scripts conflict with each other somehow, SketchUp can go haywire, and figuring out which scripts are the culprits can require a lot of detective work. If only all of the ruby programmers out there used SketchupExtensions... ahh, the world would be so much nicer.

SketchupExtensions are a handy-dandy way for you to package your plugin that is easier for users to toggle on and off. You can see the extensions you already have under Window > Preferences > Extensions. With a quick click, you can learn about who authored each of them and can even turn 'em on and off. It's dandy!



And the cool thing is that an extension is nothing but a normal Ruby plugin wrapped in a little bit of extra code. Making one of your own is easy and well worth your time. Here are several advantages:

  • Makes it easier for your users to turn off your script if they don't need it at the moment
  • Makes customer support easier for you, because you can track plugin versions
  • Gives you a handy promotional space to put contact info, website details, etc.
  • Keeps everyone's scripts better isolated so there are fewer cross-script conflicts


Let's walk through an example. Say you have a script called drawboat.rb. It already works. Now you just want to make it an extension. Here are the steps.

  1. Copy plugins/drawboat.rb into a new subfolder and rename it, plugins/drawboat/drawboat_loader.rb
  2. Create a new, empty file called plugins/drawboat.rb
  3. Put the following code into plugins/drawboat.rb
  # Load the normal support files.
require 'sketchup.rb'
require 'extensions.rb'


# Create the extension.
ext = SketchupExtension.new 'BoatCreator Beta',
'drawboat/drawboat_loader.rb'

# Attach some nice info.
ext.creator = 'DrawingBoats, Inc.'
ext.version = '1.0.0'
ext.copyright = '2011, DrawingBoats, Inc.'
ext.description = 'Draw boats! Visit drawboats.com for support.'

# Register and load the extension on startup.
Sketchup.register_extension ext, true


That's all there is to it. When you restart SketchUp your plugin will load as before, but now people can control it in the Preferences panel. We highly recommend that you do this with all of your plugins that extend SketchUp's UI with buttons or menu items.

The go_faster Parameter

Thursday, July 7, 2011



So I've been sitting in on a lot of product demos recently from some great Ruby API developers, and in a couple of cases they did not know about the "go_faster" parameter.

The "go_faster" parameter, you say. What's that?!

Let's look at two pieces of code. First without it:


start_time = Time.new
Sketchup.active_model.start_operation("Draw a grid")
for x in 0..50
for y in 0..50
p1 = [x, y]
p2 = [x+1, y]
p3 = [x+1, y+1]
p4 = [x, y+1]
Sketchup.active_model.entities.add_face(p1, p2, p3, p4);
end
end
Sketchup.active_model.commit_operation
end_time = Time.new
total_time = end_time - start_time
puts total_time.to_s + " seconds to run"


On my IBM Thinkpad this executes in 5.9 seconds. Now let's add the parameter...


start_time = Time.new
Sketchup.active_model.start_operation("Draw a grid", true)
for x in 0..50
for y in 0..50
p1 = [x, y]
p2 = [x+1, y]
p3 = [x+1, y+1]
p4 = [x, y+1]
Sketchup.active_model.entities.add_face(p1, p2, p3, p4);
end
end
Sketchup.active_model.commit_operation
end_time = Time.new
total_time = end_time - start_time
puts total_time.to_s + " seconds to run"


Whoohoo! One little flag and now it runs in 4.7 seconds. That's a 25% increase in performance for typing six keys on my keyboard.

If you're already using Model.start_operation in your plugins, this is a change worth making. If you're not, you should be. In addition to this performance increase, start_operation groups all of your model changes into a single "undo," which makes your plugin easier on your users.

What Ruby performance secrets do you know? Let's hear 'em in the comments!

SketchUp Ruby API documentation for SketchUp8 is live

Thursday, September 2, 2010

As many of you already know, we released SketchUp 8 yesterday. Check it out: http://sketchup.google.com/

We have updated the documentation for the Ruby API and you can find the Ruby API release notes at: http://code.google.com/apis/sketchup/docs/releases.html

Enjoy!

Posted by Simone Nicolo, Google SketchUp team.

New User's Comments Feature on the Google SketchUp Ruby API documentation site

Wednesday, March 10, 2010

New User's Comments Feature on the Google SketchUp Ruby API documentation site

Google Code is running a pilot on user-contributed notes to the API documentation. This feature is currently enabled for the documentation of a handful of products, including the Google SketchUp Ruby API! The ultimate goal of this feature is to provide a richer documentation experience for our developers, similar to that offered in open source projects such as php.net.

We invite you to participate by adding notes, insights, or code examples to a particular doc. Your note may take up to 24 hours to appear after you submit it. All notes will be moderated to ensure they provide a useful contribution to the topic to which they are attached. Requests for help with the API should not be submitted as notes, but should continue to be posted to the Google SketchUp Developers Google Group.

Posted by Simone Nicolo, Google Sketchup Team