# Copyright 2004, @Last Software, Inc. # The code related to click 3 points was reused here from an original # example titled rectangle.rb by Last Software, Inc. # To it I added the FilletTool code. cheers! Tim # Name: FilletTool # Description: input the radius and create a filleted rectanglular area # Usage: click 3 points, to create a filleted rectanglular area # Date: 2005/06/06 # Type: Tool # Revision: 2005/06/08 error checking for radius added #------------------------------------------------------------------------------------------------ require 'sketchup.rb' class FilletTool def initialize @ip = Sketchup::InputPoint.new @ip1 = Sketchup::InputPoint.new reset $fr=6.cm if not $fr $fh=0.cm if not $fh # Dialog box prompts=[ "Fillet Radius", "Extruded Height "] values=[$fr, $fh] results=inputbox prompts, values, "Fillet Parameters" return if not results $fr, $fh =results if ($fr <= 0.0.cm) then $fr = 0.01.cm end end def reset @pts = [] @state = 0 @ip1.clear @drawn = false Sketchup::set_status_text "", SB_VCB_LABEL Sketchup::set_status_text "", SB_VCB_VALUE Sketchup::set_status_text "Click any TOP LEFT start location" @shift_down_time = Time.now end def activate self.reset end def deactivate(view) view.invalidate if @drawn end def set_current_point(x, y, view) if( !@ip.pick(view, x, y, @ip1) ) return false end need_draw = true # Set the tooltip that will be displayed view.tooltip = @ip.tooltip # Compute points case @state when 0 @pts[0] = @ip.position @pts[4] = @pts[0] need_draw = @ip.display? || @drawn when 1 @pts[1] = @ip.position @length = @pts[0].distance @pts[1] Sketchup::set_status_text @length.to_s, SB_VCB_VALUE when 2 pt1 = @ip.position pt2 = pt1.project_to_line @pts vec = pt1 - pt2 @pt1 = @ip.position @pt2 = pt1.project_to_line @pts @vec = @pt1 - @pt2 @width = vec.length if( @width > 0 ) # test for a square square_point = pt2.offset(vec, @length) if( view.pick_helper.test_point(square_point, x, y) ) @width = @length @pts[2] = @pts[1].offset(vec, @width) @pts[3] = @pts[0].offset(vec, @width) view.tooltip = "Square" else @pts[2] = @pts[1].offset(vec) @pts[3] = @pts[0].offset(vec) end else @pts[2] = @pts[1] @pts[3] = @pts[0] end Sketchup::set_status_text @width.to_s, SB_VCB_VALUE end view.invalidate if need_draw end def onMouseMove(flags, x, y, view) self.set_current_point(x, y, view) end def create_rectangle #-------------------------------------------------------------------------- model=Sketchup.active_model model.start_operation "Create Fillet" entities=model.active_entities #------create a new set of points from the original 3 point pick $pt0=Geom::Point3d.new(@pts[0].x, @pts[0].y, @pts[0].z) $pt1=Geom::Point3d.new(@pts[1].x, @pts[1].y, @pts[1].z) $pt2=Geom::Point3d.new(@pts[2].x, @pts[2].y, @pts[2].z) $pt3=Geom::Point3d.new(@pts[3].x, @pts[3].y, @pts[3].z) #------create vert arc startpoint $pt0a=Geom::Point3d.new(@pts[0].x, @pts[0].y-$fr, @pts[0].z) $pt1a=Geom::Point3d.new(@pts[1].x, @pts[1].y-$fr, @pts[1].z) $pt2a=Geom::Point3d.new(@pts[2].x, @pts[2].y+$fr, @pts[2].z) $pt3a=Geom::Point3d.new(@pts[3].x, @pts[3].y+$fr, @pts[3].z) #------create horiz arc startpoint $pt0b=Geom::Point3d.new(@pts[0].x+$fr, @pts[0].y, @pts[0].z) $pt1b=Geom::Point3d.new(@pts[1].x-$fr, @pts[1].y, @pts[1].z) $pt2b=Geom::Point3d.new(@pts[2].x-$fr, @pts[2].y, @pts[2].z) $pt3b=Geom::Point3d.new(@pts[3].x+$fr, @pts[3].y, @pts[3].z) #------center of arc $pt0c=Geom::Point3d.new(@pts[0].x+$fr, @pts[0].y-$fr, @pts[0].z) $pt1c=Geom::Point3d.new(@pts[1].x-$fr, @pts[1].y-$fr, @pts[1].z) $pt2c=Geom::Point3d.new(@pts[2].x-$fr, @pts[2].y+$fr, @pts[2].z) $pt3c=Geom::Point3d.new(@pts[3].x+$fr, @pts[3].y+$fr, @pts[3].z) pi = 3.141592653589793 # 180 degree angle = pi radians vecz = Geom::Vector3d.new(0, 0, 1) vecy = Geom::Vector3d.new(0, 1, 0) vecx = Geom::Vector3d.new(1, 0, 0) vecy = $pt0 - $pt3 vert = vecy[1] # extract the vector length y between $pt0 - $pt3 vecx = $pt1 - $pt0 horiz = vecx[0] # extract the vector length x between $pt1 - $pt0 if ($fr*2 > horiz) UI.messagebox( "you picked a Fillet radius thats GREATER than the lenght of the object! try again!") return nil end if ($fr*2 > vert) UI.messagebox( "you picked a Fillet radius thats GREATER than the width of the object! try again! ") return nil end model.entities.add_arc($pt0c, vecx, vecz, $fr, pi, pi/2, 12) model.entities.add_arc($pt1c, vecx, vecz, $fr, pi/2, 0, 12) model.entities.add_arc($pt2c, vecx, vecz, $fr, 0, -pi/2, 12) model.entities.add_arc($pt3c, vecx, vecz, $fr, -pi/2, -pi, 12) model.entities.add_line($pt0b, $pt1b) model.entities.add_line($pt1a, $pt2a) model.entities.add_line($pt2b, $pt3b) e=model.entities.add_line($pt3a, $pt0a) e.find_faces e.faces.first.pushpull -$fh model.commit_operation end def increment_state @state += 1 case @state when 1 @ip1.copy! @ip Sketchup::set_status_text "Drag Right for second point " Sketchup::set_status_text "Slab Length", SB_VCB_LABEL Sketchup::set_status_text "", SB_VCB_VALUE when 2 @ip1.clear Sketchup::set_status_text "Drag Down for third point" Sketchup::set_status_text "Slab Width", SB_VCB_LABEL Sketchup::set_status_text "", SB_VCB_VALUE when 3 self.create_rectangle end end def onLButtonDown(flags, x, y, view) self.set_current_point(x, y, view) self.increment_state view.lock_inference end def onCancel(flag, view) view.invalidate if @drawn self.reset end # This is called when the user types a value into the VCB 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 value = nil Sketchup::set_status_text "", SB_VCB_VALUE end return if !value case @state when 1 # update the width vec = @pts[1] - @pts[0] if( vec.length > 0.0 ) vec.length = value @pts[1] = @pts[0].offset(vec) view.invalidate self.increment_state end when 2 # update the height vec = @pts[3] - @pts[0] if( vec.length > 0.0 ) vec.length = value @pts[2] = @pts[1].offset(vec) @pts[3] = @pts[0].offset(vec) self.increment_state end end end def getExtents bb = Geom::BoundingBox.new case @state when 0 # We are getting the first point if( @ip.valid? && @ip.display? ) bb.add @ip.position end when 1 bb.add @pts[0] bb.add @pts[1] when 2 bb.add @pts end bb end def draw(view) @drawn = false # Show the current input point if( @ip.valid? && @ip.display? ) @ip.draw(view) @drawn = true end # show the rectangle if( @state == 1 ) # just draw a line from the start to the end point view.set_color_from_line(@ip1, @ip) inference_locked = view.inference_locked? view.line_width = 3 if inference_locked view.draw(GL_LINE_STRIP, @pts[0], @pts[1]) view.line_width = 1 if inference_locked @drawn = true elsif( @state > 1 ) # draw the curve view.drawing_color = "black" view.draw(GL_LINE_STRIP, @pts) @drawn = true end end def onKeyDown(key, rpt, flags, view) if( key == CONSTRAIN_MODIFIER_KEY && rpt == 1 ) @shift_down_time = Time.now # if we already have an inference lock, then unlock it if( view.inference_locked? ) view.lock_inference elsif( @state == 0 ) view.lock_inference @ip elsif( @state == 1 ) view.lock_inference @ip, @ip1 end end end def onKeyUp(key, rpt, flags, view) if( key == CONSTRAIN_MODIFIER_KEY && view.inference_locked? && (Time.now - @shift_down_time) > 0.5 ) view.lock_inference end end end # of class FilletTool #---------------------------------------------------------------------------- def frametool Sketchup.active_model.select_tool FilletTool.new end if( not file_loaded?("FilletTool.rb") ) UI.menu("Plugins").add_item("FilletTool") { Sketchup.active_model.select_tool FilletTool.new } end #----------------------------------------------------------------------------- file_loaded("FilletTool.rb") # load"FilletTool.rb"