• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Polygon Tool

Scheduled Pinned Locked Moved Developers' Forum
8 Posts 3 Posters 1.5k Views 3 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    medeek
    last edited by medeek 6 Feb 2017, 06:39

    When it comes to creating "tools" within SketchUp I am severely handicapped. I kind of understand what is going on but it is more of black box to me than anything. With the code below I am trying to have the user input in a polygon that will be the perimeter of the slab foundation. I've got it mostly working but cannot figure out how to make it snap to the x and y axis or start and end points of lines. My code thus far is below:

    
    #########################################
    #
    # Foundation POSITIONING LOGIC (Polygon)
    #
    #########################################
    
    
    
    module FoundationPositionToolPolygon
    
    
    # --------  FOUNDATION POSITIONING TOOL  ------------------------------------------------
    
    # Positions the foundation assembly. This tool allows the user
    # to place the foundation assembly using the mouse to select a polygon 
    
    
    
    class PositionToolPolygon
    
    	# Show the Ruby Console at startup so we can
    	# see any programming errors we may make.
    	# SKETCHUP_CONSOLE.show
    
    	#  these are the states that a tool can be in
    	STATE_EDIT = 0 if not defined? STATE_EDIT
    	STATE_PICK = 1 if not defined? STATE_PICK
    	STATE_PICK_2 = 2 if not defined? STATE_PICK_2
    	STATE_PICK_3 = 3 if not defined? STATE_PICK_3
    	STATE_PICK_FINAL = 4 if not defined? STATE_PICK_FINAL
    	STATE_MOVING = 6 if not defined? STATE_MOVING
    	STATE_SELECT = 7 if not defined? STATE_SELECT
       
    
    def initialize()
    
    	
    
        	@tool_name = "FOUNDATION LOCATOR"
    	@type = "foundation"
    	@pointcount = 0
    end
    
    def reset
        	@pts = []
        	@state = STATE_PICK
    	@pointcount = 0
    	
        	# This sets the label for the VCB
        	Sketchup;;set_status_text "MEDEEK FOUNDATION", SB_VCB_LABEL
        	Sketchup;;set_status_text "[#{@tool_name}] Click first corner of Polygon"
    	@status_text = "[#{@tool_name}] Click first corner of Polygon"
        	@drawn = false
    end
    
    def activate
        	@ip1 = Sketchup;;InputPoint.new
        	@ip = Sketchup;;InputPoint.new
    
    	
    
        	self.reset
    end
    
    def deactivate(view)
        view.invalidate if @drawn
        @ip1 = nil
    end
    
    
    def onMouseMove(flags, x, y, view)
    	self.set_current_point(x, y, view)
    	Sketchup;;set_status_text @status_text,SB_PROMPT
    end
    
    
    def onLButtonDown(flags, x, y, view)
        	self.set_current_point(x, y, view)
        	self.update_state
    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 STATE_PICK
            @pts[0] = @ip.position
           	# need_draw = @ip.display? || @drawn
        when STATE_PICK_2
            @pts[1] = @ip.position
        when STATE_PICK_3
    	@pts[2] = @ip.position
        when STATE_PICK_FINAL
    	@pts[@pointcount] = @ip.position
        end   
    
        view.invalidate if need_draw
    end
    
    def update_state
        case @state
        when STATE_PICK
            @ip1.copy! @ip
    	@pointcount = @pointcount + 1
            Sketchup;;set_status_text "[#{@tool_name}] Click second corner of Polygon"
            @state = STATE_PICK_2
    	puts "#{@state} #{@pointcount}"
    	@status_text = "[#{@tool_name}] Click second corner of Polygon"
        when STATE_PICK_2
            @ip1.clear
    	@pointcount = @pointcount + 1
    	Sketchup;;set_status_text "[#{@tool_name}] Click third corner of Polygon"
            @state = STATE_PICK_3
    	puts "#{@state} #{@pointcount}"
    	@status_text = "[#{@tool_name}] Click third corner of Polygon"
        when STATE_PICK_3
            @ip1.clear
    	@pointcount = @pointcount + 1
    	Sketchup;;set_status_text "[#{@tool_name}] Click fourth corner of Polygon"
            @state = STATE_PICK_FINAL
    	puts "#{@state} #{@pointcount}"
    	@status_text = "[#{@tool_name}] Click fourth corner of Polygon"
        when STATE_PICK_FINAL
    	@ip1.clear
    	ptcurrent = @ip.position
    	@distorigin = @pts[0].distance ptcurrent
    	if (@distorigin > 0.0001)
    		@pointcount = @pointcount + 1
    		@nextpointcount = @pointcount + 1
    		@state = STATE_PICK_FINAL
    		puts "#{@state} #{@pointcount}"
    		Sketchup;;set_status_text "[#{@tool_name}] Click corner #{@nextpointcount} of Polygon"
    		@status_text = "[#{@tool_name}] Click corner #{@nextpointcount} of Polygon"
    	else
    		# Final point picked
    		
            	self.calculate_obj
            	Sketchup.active_model.select_tool(nil)
    	end
    	
        end
    end
    
    
    def calculate_obj
        	
    	###########
    	#
    	# Check units of template again
    
    	lengthconstant = Sketchup.active_model.options["UnitsOptions"]["LengthUnit"]
    
     	if (lengthconstant == 0) || (lengthconstant == 1)
    		@Unitstemplate2 = "imperial"
    	else
    		@Unitstemplate2 = "metric"
     	end
    
    
    	if @Unitstemplate2 == "metric"
    		# Sketchup;;set_status_text "Foundation Width; #{@BuildingSpan_m.round(4)} m - Foundation Length; #{@BuildingLength_m.round(4)} m"
    	else
    		# Sketchup;;set_status_text "Foundation Width; #{@BuildingSpan_ft.round(4)} ft. - Foundation Length; #{@BuildingLength_ft.round(4)} ft."
    	end
    	
    	MedeekMethods.main_menu_polygon @pts, @pointcount
       
    end
    
    
    def onCancel(flag, view)
        view.invalidate if @drawn
        reset
    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
            value = nil
            Sketchup;;set_status_text "", SB_VCB_VALUE
        end
        return if !value
        
        case @state
        when STATE_PICK_NEXT
            # 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.update_state
            end
        when STATE_PICK_LAST
            # 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.update_state
            end
        end
    end
    
    def getExtents
        bb = Geom;;BoundingBox.new
        case @state
        when STATE_PICK
            # We are getting the first point
            if( @ip.valid? && @ip.display? )
                bb.add @ip.position
            end
        when STATE_PICK_2
            bb.add @pts[0]
            bb.add @pts[1]
        when STATE_PICK_3
            bb.add @pts[2]
        when STATE_PICK_FINAL
    	bb.add @pts
        end
        return bb
    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
    	elsif( @state == 2 )
                view.lock_inference @ip, @ip1
    	elsif( @state == 3 )
                view.lock_inference @ip, @ip1
    	elsif( @state == 4 )
                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
    
    # draw a polygon for the outline of the foundation
    def draw(view)
        @drawn = false
        
        # Show the current input point
        if( @ip.valid? && @ip.display? )
            @ip.draw(view)
            @drawn = true
        end
    
        case @state
        when STATE_PICK
            # do nothing
        when STATE_PICK_2
            # just draw a line from the start to the end point
            view.set_color_from_line(@ip1, @ip)
    	view.drawing_color = [0, 0, 200]
            inference_locked = view.inference_locked?
    	view.line_width = 2 if inference_locked
    	view.line_width = 2
            view.draw(GL_LINE_STRIP, @pts[0], @pts[1])
            @drawn = true
        else
    	# view.set_color_from_line(@ip1, @ip)
    	view.drawing_color = [0, 0, 200]
    	inference_locked = view.inference_locked?
    	view.line_width = 2 if inference_locked
    	view.line_width = 2
            view.draw(GL_LINE_STRIP, @pts)
            @drawn = true
        end
    end
    
    end # class PositionToolPolygon
    
    
    #######################################
    
    end # module FoundationPositionToolPolygon
    

    Nathaniel P. Wilkerson PE
    Medeek Engineering Inc
    design.medeek.com

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 6 Feb 2017, 18:06

      Pls edit and remove code, then re-post properly indented code in a [ code ] ... [ /code ] block.

      (Ie, no one will even attempt to read it.)

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • M Offline
        medeek
        last edited by 6 Feb 2017, 20:10

        Hopefully that is a bit better.

        Nathaniel P. Wilkerson PE
        Medeek Engineering Inc
        design.medeek.com

        1 Reply Last reply Reply Quote 0
        • M Offline
          medeek
          last edited by 8 Feb 2017, 05:13

          What would be useful is if I could somehow constrain the line angle (or snap to) to 15 degree increments. Has anyone ever tried to do something like this?

          Nathaniel P. Wilkerson PE
          Medeek Engineering Inc
          design.medeek.com

          1 Reply Last reply Reply Quote 0
          • R Offline
            Rich O Brien Moderator
            last edited by 8 Feb 2017, 11:11

            Fredo's DrawAlong tool in Fredo Tools snaps to increments.

            Download the free D'oh Book for SketchUp 📖

            1 Reply Last reply Reply Quote 0
            • D Offline
              Dan Rathbun
              last edited by 8 Feb 2017, 21:15

              You would basically save the user's current angle snap settings, set 15 degrees and angle snap ON, do your thing, then restore the user's settings.

              At the least you should honor the user's settings (perhaps as a starting point.)

              Access via Sketchup::Model#options(), ie:

              
              model = Sketchup.active_model
              manager = model.options
              
              manager.each {|key| puts "#{key.name}" }
              #=> PageOptions
              #=> UnitsOptions
              #=> SlideshowOptions
              #=> NamedOptions
              #=> PrintOptions
              
              opts = manager["UnitsOptions"]
              #=> #<Sketchup;;OptionsProvider;0x00000009215148>
              
              opts.each {|key,name| puts "#{key} = #{name}" }
              #=> LengthPrecision = 3
              #=> LengthFormat = 0
              #=> LengthUnit = 0
              #=> LengthSnapEnabled = true
              #=> LengthSnapLength = 0.0001
              #=> AnglePrecision = 1
              #=> AngleSnapEnabled = true
              #=> SnapAngle = 15.0
              #=> SuppressUnitsDisplay = false
              #=> ForceInchDisplay = false
              
              

              so:

              
              def save_angle_options(model=Sketchup;;active_model)
                opts = model.options["UnitsOptions"]
                opts["AngleSnapEnabled"], opts["SnapAngle"]
              end
              
              def restore_angle_options(snapping,angle,model=Sketchup;;active_model)
                opts = model.options["UnitsOptions"]
                opts["AngleSnapEnabled"]= snapping
                opts["SnapAngle"]= angle
              end
              
              # In code elsewhere;
              
              snapping, angle = save_angle_options()
              # do your thing
              restore_angle_options(snapping,angle)
              
              

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • M Offline
                medeek
                last edited by 11 Feb 2017, 05:14

                Even when I'm drawing a line with the built in tools the angle snapping in SketchUp doesn't seem to work, what am I missing here?

                Nathaniel P. Wilkerson PE
                Medeek Engineering Inc
                design.medeek.com

                1 Reply Last reply Reply Quote 0
                • D Offline
                  Dan Rathbun
                  last edited by 11 Feb 2017, 20:41

                  Angle snapping works for rotational tools or tool states.

                  Length snapping would work for linear tool states.

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • 1 / 1
                  1 / 1
                  • First post
                    6/8
                    Last post
                  Buy SketchPlus
                  Buy SUbD
                  Buy WrapR
                  Buy eBook
                  Buy Modelur
                  Buy Vertex Tools
                  Buy SketchCuisine
                  Buy FormFonts

                  Advertisement