Archive for category SketchUp Ruby API

Graduation, iOS SDK…

It has been a while since I last posted anything on this blog, and I really should try and post at least once a week. Will try to do so in weeks to come. Since the last time I wrote anything I graduated from University of Ljubljana Slovenia in civil/structural engineering. My final thesis was called: Development of a software tool for creating integrated models in Sketchup.. I defended it on June 29th in Ljubljana, and received a top grade for it. Basically the thesis was written about two software programs I made and shared on this blog. One is OnTime scheduling tool made with Adobe Flex 3.0 Framework and second is OnTime5D, a plugin for Google Sketchup for creating 5D animations of building process inside Sketchup according to a selected building schedule. I would love to enhance both of this programs in the future, so if anyone out here is interested in doing something in this way please drop me a line!

Secondly I would like to share some words on iOS development. I started developing applications for the iPhone and iPad almost a year ago. It was the first time I used any traditional programming language where you actually have to take care of the memory yourself. But I have to say that I like iOS SDK a lot, and was quickly able to build some very interesting applications. The most recent one will soon be sent to Apple for their approval, and hopefully it will be on the App store in about 1 month.

Hopefully see ya in a week :)

2 Comments

OnTime5D plugin tested on newly released Sketchup 8

I just tested the OnTime5D plugin on the newly released Sketchup 8, and it works without a problem. Sketchup 8 was recetly released by Google and can be found on http://sketchup.google.com/.

Leave a comment

OnTime5D plugin tested for:

Just wanted to add a quick note, I have successfully tested OnTime5D Plugin for Skecthup on following OS configurations:

(1) Mac OS X 10.5.8, Sketchup 7.1

(2) Windows XP, sp3, Sketchup 7.1

There was a bug in the previous version of the UI (webDialog), so there is no need to update the plugin itself. It was a problem in Windows Flash Player, and has now been solved.

If anyone try’s the plugin in any other environment please leave a comment.

You can find Plugin on this address:

http://www.tdteam.com/ontime5d/skp/skp.zip
(Zip contains ontime5d.rbs and a sample Bridge model ready for animation)

Leave a comment

Pre-release of Google Sketchup plugin for 5D animation

This will be a very short post, I am pre-releasing Google Sketchup plugin for 5D animation…called onTime5D.

Below is the link to the rbs script that has to be, copied to the plugin folder of your Sketchup installation. (right click and Save Target As)

http://www.tdteam.com/ontime5d/skp/ontime5d.rbs (Ruby plugin file)

http://www.tdteam.com/ontime5d/skp/bridge.skp (bridge model file – ready for animation)


Update:
Please try this links if you are unable to download from above

http://www.tdteam.com/ontime5d/skp/skp.zip


For a quick look at what this plugin can do, download the Bridge model, that is listed above. All you have to do next (after you have copied the plugin to your plugin Sketchup folder) is open Sketchup, open Bridge file. Go to Plugins toolbar and select OnTime5D. This will open up a webdialog, where you can login with provided credentials and select Alfred Zampa Memorial Bridge project. Then you can skip the 1 step (where you have to bind the Sketchup model and schedule), click Next Step and you can leave animation running default 30 seconds and once again click Next Step.

On the last step you are greeted with a Play/Pause button and below with a chart of expenses (shown only if there is any money data inputted into the schedule). And still further below is the list of all the tasks that are currently under way in the animation.

Just click Play and enjoy, and please provide some feedback.

, ,

7 Comments

5D animation for Sketchup

For the last couple of months, I have been building a Sketchup plugin, that in conjecture with a scheduling software (in this case connected to the schedule maker made in Flex – OnTime) that allows users to create 5D animation of the building process, according to the schedule and the financial data that was inputted in the program. (You can check out 2 videos below that are posted on YouTube)

Let’s just for a second talk about 4D animation in construction. 3D Building Information Model (referred to as BIM) is a rather new paradigm, that is seeing rapid growth in the construction industry. Building Information Modeling is the process of generating and managing building data during its life cycle and Building Information Model encompasses building geometry, spatial relationships, geographic information, and quantities and properties of building components. What that really means is that we are attaching a lot of data or information directly to the 3D model itself. For example, for a given wall in a project we would attach the following information: composition of the wall, how the wall will be built (recipes), all the quantities (area, depth…) as well as connection of the wall to the construction schedule, so we can see when the wall will be build (its start and finish date, duration and so on).

A 4D model incorporates time as added 4th dimension and hence improves quality and accuracy of the entire building life cycle management. Below are listed some of the benefits of using 4D model during construction planning: (as written in this article: Benefits of 4D modeling during construction planning)

  • improved reliability and scheduling efficiency: 4D model enables a project team to easily visualize time constraints and opportunities of improvement in the project schedule
  • 4D model allows the team member to more easily understand the scope of work and access to various resources over a period of time, this allows the member to visually review and evaluate whole construction plan and optimize the resources and labor accordingly
  • Improved communication: During construction phase potential spatial conflict may arise between building components, these can be hard to indentify when coordination is performed using 2D or 3D layouts

4D model provides graphically rich and animated illustration of construction sequence against time.

To get to 5D animation all we do is add money or cost as our 5th variable, so we can track how much money is being spent as the project progresses through its construction process.

, , , , ,

Leave a comment

Using Web Dialogs in Sketchup round two

Last post we were talking about how we can communicate between Sketchup and Web Dialogs in Sketchup. In this short tutorial we will explore how we can for example make a call from Web Dialog and open Input Box in Sketchup, where we will input our first and last name, then we will accept these values from Skatchup and display them in Web Dialog.

So let’s go to work. Open up your text editor and create a new Ruby file. Let’s create a function sendDataToJs and open up a Web Dialog:

def sendDataToJs
dialog = UI::WebDialog.new("Write your first and last name", true, "", 410, 875, 1030, 0, true)
dialog.set_url 'http://www.tdteam.com/work/engineeringtheworld/name.html'
dialog.show
end

Since we will be using inputbox in Sketchup, we have to specify what these inputboxes will show. so we create a new array called prompts = ["Type your first name", "Type your last name"].

Now we will add action callback, where we will first show inputbox in Sketchup, then we will check if first and last names were inputed, if not we will show error msg box, else we will show inputted name in web dialog.

dialog.add_action_callback("typeName") {|dialog, action|
    input = UI.inputbox prompts, [], [], "Tell me your first and last name."
    input[0] = input[0].to_s.chomp #this holds inputted first name
    input[1] = input[1].to_s.chomp #this holds inputted last name
    if input[0] == '' || input[1] == ''
      UI.messagebox 'You have to input first and last name'
    else
      name = input[0] + ' ' + input[1]
      dialog.execute_script("dataFromSketchup('#{name}')")
    end
  }

As you can see above we have removed all whitespaces from input values, we did this with input[0] = input[0].to_s.chomp and input[1] = input[1].to_s.chomp. If first and last name were inputted (and do not consist only of whitespaces) we assign first and last name to variable name, and call function dataFromSketchup(name) in our Web Dialog.

I also added a action call back to show dialog when we click a link show Console in Web Dialog.

The complete script is:

def sendDataToJs
dialog = UI::WebDialog.new("Write your first and last name", true, "", 410, 875, 1030, 0, true)
dialog.set_url 'http://www.tdteam.com/work/engineeringtheworld/name.html'
dialog.show

  prompts = ["Type your first name", "Type your last name"]
  
  dialog.add_action_callback("typeName") {|dialog, action|
    input = UI.inputbox prompts, [], [], "Tell me your first and last name."
    input[0] = input[0].to_s.chomp
    input[1] = input[1].to_s.chomp
    if input[0] == '' || input[1] == ''
      UI.messagebox 'You have to input first and last name'
    else
      name = input[0] + ' ' + input[1]
      dialog.execute_script("dataFromSketchup('#{name}')")
    end
  }
  #show console call up
  dialog.add_action_callback("showConsole") {|dialog, action| Sketchup.send_action("showRubyPanel:")}
end

Now let’s take a look at our HTML file name.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Get your name from Sketchup</title>
<script language="javascript" src="js/prototype.js"></script>
<script language="javascript">
function dataFromSketchup(name){
   $('nameId').update('Your name is <strong>' + name + '<strong>');
}
</script>
</head>
<body>
<div id="nameId">

</div>
<a href="skp:typeName@true">Type in your name in Sketchup</a><br />
<a href="skp:showConsole@true">Show Console</a>
</body>
</html>

I have used javascript framework Prototype in this example, because I do not want to think about browser compatibility when doing JavaScript, that is why I suggest you to use a JavaScript framework like: Prototype or jQuery.

Code here in name.html is pretty straightforward so there is not much to talk about. As you can see we have to links, one is calling typeName and other one showConsole from our Ruby code. We also added a function dataFromSketchup that accepts one argument (which is the name inputted).
Then we just use $ selector to find tag with nameId id and use update Prototype method to show inputted name inside div tag with id=nameId. Name will be show as bold text.

, ,

Leave a comment

Creating Web Dialogs in Sketchup and making calls from and to Sketchup

Ok, in last three little tutorials I showed some of the things you can do with just a little Ruby code in Sketchup with it’s Ruby API.

Now it is time to move to as far as I am concerned the most interesting part of doing Sketchup development and that is using Web Dialogs. Since I have been doing web related projects for years now I feel right at home using web pages as means to do something. Sketchup let’s us open Web Dialog, which is nothing more than a normal browser window that is opened within Sketchup, where you can make calls from Sketchup to web page on other side and vice versa (via JavaScript).

One thing to note is that webpage is opened in a default browser in a given operating system, that being Internet Explorer on Windows and Safari on a Mac.

Let’s first take a look at how we can open a Web Dialog within Sketchup using Ruby call:

dialog = UI::WebDialog.new("Title of Web Dialog", true, "", 410, 875, 1030, 0, true)

As you can see there are 8 arguments that Web Dialog accepts when it is being created.

  1. title – Web Dialog title
  2. scrolable – true if you want page to be scrollable and false if you don’t
  3. pref key – The registry entry where the location and size of the dialog will be saved
  4. width – width of Web Dialog
  5. height – height of Web Dialog
  6. left – position from the left of the screen in pixels
  7. top – postion from the top of the screen in pixles
  8. resizable – true if you want the webdialog to be resizable, false if you do not want the webdialog to be resizable

Next thing we want to do is show assign which web page to open as our Web Dialog, we do this by: dialog.set_url filepath, where filepath is the path to the html document we want to open. The last thing to do is to show our Web Dialog, which we do by: dialog.show.

Second part of what I wanted to talk in this post is how can we communicate between our Web Dialog and Sketchup.

First let’s see how we can use Ruby to execute any JavaScript code in Web Dialog. If we stored our Web Dialog in a variable called dialog, we can do the following:

dialog.execute_script("any JavaScript here will be executed in Web Dialog");
//we could show JavaScript alert with
dialog.execute_script("alert('Hello from Web Dialog')");

The second line of code will produce a alert window from Web Dialog with text Hello from Web Dialog.

If we wanted to call let’s say a function called test_function, we would just say dialog.execute_script(“test_function()”);, and test_function in Web Dialog will be executed.

One thing to note to all Mac users is that you have to upgrade Sketchup to 6.0 in order for execute_script to work, there was a bug that prevented scripts to be called from Ruby in Web Dialog and that has been fixed in Sketchup 7.

Ok, now to the other side, how to execute code in Ruby (Sketchup) from Web Dialog. This has to be done both on Ruby side and Web Dialog side. Let’s suppose we have a function defined in Ruby called show_hello_world defined like:

def show_hello_world
  UI.messagebox('Hello world');
end

Now we have to tell Ruby to be expecting a call from JavaScript, we can do this by calling add_action_callback method on Web Dialog. Let’s see an example:

dialog.add_action_callback("execRubyFunction") {|dialog, action| show_hello_world}

All there is left to do is to add a link to Web Dialog that will execute show_hello_world function:

<a href="skp:execRubyFunction@true">Execute show_hello_world </a>

As you look at the code above, you can see that we have to add name to add_action_callback within brackets, in our case we wrote execRubyFunction, this is the name we have to repeat in a link, so we do skp:execRubyFunction for our link (plus we add @true).

So if we wrote dialog.add_action_callback(“someOtherNameHere”)… we would have to do the same in html tag skp:someOtherNameHere@true for this to work.

One thing to note also is that after we call dialog.add_action_callback(“nameFunction”){|dialog, action|, everything after this and befor closing } is the code that will be executed when this code is executed from Web Dialog.

dialog.add_action_callback("nameFunction"){|dialog, action|
puts 'this will be written to console'
puts 'this too'
puts 'and this too'
}

Ok, at the end let’s to one quick example, we will use our knowledge of Web Dialogs and action_callback’s to show console of Sketchup when clicking on a link in Web Dialog.

Here is the code for showConsole.rb:

require 'sketchup.rb'
dialog = UI::WebDialog.new("Sending data to JavaScript", true, "", 410, 875, 1030, 0, true)
dialog.set_url 'http://www.tdteam.com/work/engineeringtheworld/showConsole.html'
dialog.show
dialog.add_action_callback("showConsole"){|dialog, action|
  Sketchup.send_action("showRubyPanel:")
}

And sourcecode for showConsole.html (you can use the same address as the one above and you will get this HTML file – also make sure to set width, height, top and left settings when executing WebDialog.new to values of your liking)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Show console</title>
</head>

<body>
<a href="skp:showConsole@true">Show console</a>
</body>
</html>

When you try out this code in Sketchup using Web Console you show see that console will be shown, when you click on a link in Web Dialog. This is because we execute Sketchup.send_action(“showRubyPanel:”) when link is called. You can see what else you can call by using Sketchup.send_action on this link: http://code.google.com/apis/sketchup/docs/ourdoc/sketchup.html#send_action)

, , , , ,

Leave a comment

Adding different types of entities to different layers

Building upon our previous example where we counted number of different types of entities in Sketchup file, we will take a look at how we can create new layers in Sketchup with Ruby API and assign different entity types to their appropriate layer.

We will create 3 layers of most basic types of entities in Sketchup, and those are Edge, Face and ComponentInstance.

Let’s open up a new file in text editor and define a function assign_layer_for_elements. First we will create 3 layers: edges, faces, componentInstances.

  model = Sketchup.active_model
  ent = model.entities
  #create layers for each type of entity
  edge_layer = model.layers.add("edges")
  face_layer = model.layers.add("faces")
  componentInstance_layer = model.layers.add("componentInstances")

As you can see from the code above, we can create layers current active model by model.layer.add(“name of layer”). We did this 3 times for 3 types of entities.

Next we will once again use each method on ent variable (which holds all entities in our Sketchup model) and based upon their type assign them to appropriate layer.

ent.each{|x|
   x.layer = edge_layer if x.is_a? Sketchup::Edge
   x.layer = face_layer if x.is_a? Sketchup::Face
   x.layer = componentInstance_layer if x.is_a? Sketchup::ComponentInstance
  }

If current entity (x) is of type Sketchup:Edge, we assign it to edge_layer, the same goes for Sketchup::Face and Sketchup::ComponentInstance.

Run this code in Web Console and you will see that 3 new layers appeared (if you don’t have layers view active, go to Window->Layers). In my model, if I turn off all layers except edges layer I get the following result (as compared to view if I have all layers turned ON):

Final sourcecode of assign_layer_for_elements function

def assign_layer_for_elements
  model = Sketchup.active_model
  ent = model.entities
  #create layers for each type of element
  edge_layer = model.layers.add("edges")
  face_layer = model.layers.add("faces")
  componentInstance_layer = model.layers.add("componentInstances")
  
  ent.each{|x|
   x.layer = edge_layer if x.is_a? Sketchup::Edge
   x.layer = face_layer if x.is_a? Sketchup::Face
   x.layer = componentInstance_layer if x.is_a? Sketchup::ComponentInstance
  }

end

, ,

Leave a comment

Counting types of entities in Sketchup with Ruby API

Following up on the previous example, where I showed how you can get an array of all entities and an array of all selected entities we will sort the entities by type or class this time, and let the user know how many entities of each type there are.

We will once again begin our script with require ‘sketchup.rb’.

We will check and count the following types of entities:

  • Sketchup::Edge
  • Sketchup::Face
  • Sketchup::ConstructionLine
  • Sketchup::ComponentInstance
  • Sketchup::ConstructionPoint
  • Sketchup::Image

Let’s create a function sort_count_elements. Again we will asign active model to variable model and all model entities to variable ent. We will also set variables face, edge, componentInstance, constructionPoint, constructionLine and image to equal 0.

Now we will go through the ent array and if it is going to be of type Sketchup:Edge we will add 1 to edge varable, and the same for face, constructionLine etc.

At the end we will notify user about how many entities of each type we counted.

Again save the code and load it in Sketchup with Web Colsole plugin and press Eval (make sure you add sort_count_elements call as the last line in Web Console).

def sort_count_elements
  model = Sketchup.active_model
  ent = model.entities
  edge = face = constructionLine = componentInstance = constructionPoint = image = 0
  ent.each {|x| 
   edge+= 1 if x.is_a? Sketchup::Edge
   face+= 1 if x.is_a? Sketchup::Face
   constructionLine+= 1 if x.is_a? Sketchup::ConstructionLine
   componentInstance+= 1 if x.is_a? Sketchup::ComponentInstance
   constructionPoint+= 1 if x.is_a? Sketchup::ConstructionPoint
   image+= 1 if x.is_a? Sketchup::Image
  }
  
  UI.messagebox "Nr edges: #{edge}\nNr Faces: #{face}\nNr constructionLine: #{constructionLine}\nNr componentInstance: #{componentInstance}\nNr constructionPoint: #{constructionPoint}\nNr images: #{image}"

end

The end result will show you a pop up like the one below:

As you look at the code above you will see that we are going through array ent with ent.each. each is a standard iterator for arrays, ranges and hashes. ent.each method call is followed by code within a block that will be executed for every element in array, range or hash. In our example we used:

ent.each {|x| do something with x}, where x is value of the current element in array (in our case an entity). This is where we check if entity is of type Face, Edge etc., which we do with x.is_a? Sketchup::Face for example. We could also use x.class == Sketchup::Face, but using is_a? is nicer since it is a method made for comparing if given class is the same as the one provided.

, ,

Leave a comment

Google Sketchup Ruby API

Since I am doing some work in Google Sketchup these days using it’s Ruby API, I would like to talk about it a little bit here.

Google Sketchup is a powerful tool that Google acquired couple of years back. Idea behind Sketchup is, that you can learn how to do some pretty interesting 3D modeling in a short period of time. There are a lot of 3D modeling software out there, but probably Sketchup is the one that is the easiest to learn, but at the same time pretty powerful.

In order for users to make their own plugins or extenitions Sketchup provides us with Ruby Sketchup API. As you know API stands for Application Programming Interface, which means that you are given a set of tools or calls that you can make to interact with Sketchup model with Ruby script.

Today we will take a look at a fairly easy Ruby program, which will show us how many elements there are in a model, and how many of them are currently selected.

Before we go into any code I would like you to download a plugin called Web Console made by Jim Foltz. It can be downloaded from this URL: http://sketchuptips.blogspot.com/2007/08/plugin-webconsolerb.html.

What Web Console allows us to do is input or load a Ruby script into Skecthup and try it out. Normaly without this plugin, we would have to restart Sketchup every time we made a change to our plugin code to retry it.

So after you installed Web Console plugin you are ready to follow this tutorial. (plugins are saved in plugins folder inside your Google Sketchup application folder).

Now create a new file in your favorite text editor. I am using the free Komodo Edit.

In the first line write the following:

require 'sketchup.rb'

This will always be the first line of any plugin we make for Sketchup. It just ads contents of sketchup.rb file into this file so we can start interacting with Sketchup.

Next we will define a function count_elements, inside this function we will get all elements in our Sketchup model (or entities as they are called in Sketchup), and all selected elements or entities for our model. We will then notify the user about how many entities there are and how many of them are selected.

def count_elements
  model = Sketchup.active_model
  ent = model.entities
  selection = model.selection
 
  UI.messagebox "Number of elements in this model: #{ent.length} \nNumber of selected elements: #{selection.length}"

end

Let’s go through this code line by line…since it only has 4 lines of code it will be easy :)

First we save active model (that is the model that we currently have on screen) into a variable called model. Now we can store all entities of active model into an array ent (with model.entities). Next we store the selected entities into variable selection.

At the end we want to present a pop up window that will state how many elements there are in our model and how many of them are selected.

Pop ups can be created by UI.messagebox “message we want to show in our pop up”.

Since we are using double quotes and not single ones we can include variables by using construct #{variable here}. We can add new line with \n.

Now save this script with rb extension. You can save it anywhere, since we will activate it with Web Console plugin.

Open Sketchup, either load any 3D model you have or just add some shapes, lines and such and select couple of them. Now open Web Console, click load button at the top of the plugin window, load script you just saved. Go to the script and add one line calling our count_elements function and press Eval. Your Web Console should look like the one below:

The UI message box shown on my loaded model can be seen below:

, , ,

Leave a comment

Follow

Get every new post delivered to your Inbox.