Tuesday, June 02, 2009

Drill holes in objects using sketchup

If you've ever used sketchup for woodworking, you've probably noticed that it's a pain to drill holes in your workpieces. You have to create a circle, type in its diameter, then use the push/pull tool to push the hole through to the other side. Unfortunately, you can't make the hole a component, either, since it won't intersect right unless you explode it first.

So here's a ruby extension for drilling holes with a single click. Save the below code to a file called "drill.rb" in your Plugins/ directory. Open sketchup, go to Window... Preferences, click Extensions, and enable "Ruby Script Examples". Then you may need to restart sketchup to see the Plugins dropdown. Select "drill", type a hole diameter in the VCB and then hit enter. It'll save that value until you change it. Now click on a face on a 3d object to drill a hole through it.


# Hacked together from the linetool example by Jason E. Holt
# Copyright 2005-2008, Google, Inc.

# This software is provided as an example of using the Ruby interface
# to SketchUp.

# Permission to use, copy, modify, and distribute this software for
# any purpose and without fee is hereby granted, provided that the above
# copyright notice appear in all copies.

# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#-----------------------------------------------------------------------------

require 'sketchup.rb'

class Drill

@@drill_diameter = 1

# This is the standard Ruby initialize method that is called when you create
# a new object.
def initialize
end

def draw(view)
Sketchup::set_status_text "DIAMETER", SB_VCB_LABEL
Sketchup::set_status_text @@drill_diameter.to_s, SB_VCB_VALUE
end

# The activate method is called by SketchUp when the tool is first selected.
# it is a good place to put most of your initialization
def activate
Sketchup::set_status_text "DIAMETER", SB_VCB_LABEL
Sketchup::set_status_text @@drill_diameter.to_s, SB_VCB_VALUE
end

# The onLButtonDOwn method is called when the user presses the left mouse button.
def onLButtonDown(flags, x, y, view)
center_ip = Sketchup::InputPoint.new
center_ip.pick view, x, y
face = center_ip.face

center = center_ip.position
normal = face.normal

if ( face )
circle = view.model.entities.add_circle center, normal, @@drill_diameter / 2.0

other_entities = face.all_connected

reversed_normal = normal.reverse

circleface = nil

# This seems lame. add_circle seems to add it as a face, but then I have
# to go looking for that face.
for other in other_entities
if other.typename == "Face" and other.classify_point(center) == 1
#UI.messagebox("found myself :/")
circleface = other
end
end

# Find a face opposite the one they clicked in
for other in other_entities

#UI.messagebox("type is " + other.typename)

if other.typename == "Face"
if reversed_normal.samedirection? other.normal
#UI.messagebox "found it!"

point_on_other_face = center.project_to_plane other.plane
if other.classify_point(point_on_other_face) == 1
#UI.messagebox "yes, point projects onto other face."
pushpull_distance = point_on_other_face.vector_to(center).length

circleface.pushpull(-pushpull_distance)
else
#UI.messagebox "nope, doesn't project"
end
else
#UI.messagebox "nope"
end
end
end

view.model.commit_operation

else
UI.messagebox "Drilling only works on faces"
end
end

def onUserText(text, view)

# The user may type in something that we can't parse as a length
# so we set up some exception handling to trap that
begin
value = text.to_l
rescue
# Error parsing the text
UI.beep
puts "Cannot convert #{text} to a Diameter"
value = nil
Sketchup::set_status_text "", SB_VCB_VALUE
end
return if !value

@@drill_diameter = value
end

end # class Drill

#-----------------------------------------------------------------------------
# This functions is just a shortcut for selecting the new tool
def drill
Sketchup.active_model.select_tool Drill.new
end

UI.menu("PlugIns").add_item("Drill") {
drill
}

6 comments:

Anonymous said...

This seems to drill only "halfway" through for me, ie. it leaves the circle on the other side.

Lunkwill said...

Try using the "reverse faces" option on the object first and see if that makes it work.

Anonymous said...

Doesn't work within components or groups. Rather does a push/pull of the entire face in the component.

jacques sauniere said...

Hi,

I desperately need some help.

I want to draw a wire...like a cylinder, so it is circle drawing then pushpull.

But, circle itself is a curve not face so, I can't do pushpull.

I tried to hack your onLbuttondown method, but it says the circle drawn is type 'edge'

can you please help on how to draw a cylinder in ruby.

Thanks

Larry said...

Thank You so very much. I have been trying to poke a hole in an "object" all day. All I had to do was explode, drill and whalla! a hole.

Trout Fishing said...

Great, I just used it in sketchup 2013. Thank you.