Polygon Positioning Tool

Polygon Positioning Tool

Postby medeek » Sun Apr 09, 2017 11:01 pm

I've got the polygon positioning tool mostly worked out for my foundation plugin. However, when the user enters in a value for the length of the segment (VCB_VALUE) then the subsequent line selection does not properly infer the X and Y axis. I've spent already way too much time on this and I can't figure it out. My code is shown below for the polygon positioning tool:

Code: Select all
#########################################
#
# 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
   @sectionlength = @pts[0].distance @pts[1]
   Sketchup::set_status_text @sectionlength.to_s, SB_VCB_VALUE
    when STATE_PICK_3
   @pts[2] = @ip.position
   @sectionlength = @pts[1].distance @pts[2]
   Sketchup::set_status_text @sectionlength.to_s, SB_VCB_VALUE
    when STATE_PICK_FINAL
   @pts[@pointcount] = @ip.position
   @sectionlength = @pts[@lastpointcount].distance @pts[@pointcount]
   Sketchup::set_status_text @sectionlength.to_s, SB_VCB_VALUE
    end   

    view.invalidate if need_draw
end

def update_state
    case @state
    when STATE_PICK
        @ip1.copy! @ip
   @lastpointcount = @pointcount
   @pointcount = @pointcount + 1
        Sketchup::set_status_text "[#{@tool_name}] Click second corner of Polygon"
   Sketchup::set_status_text "Section Length", SB_VCB_LABEL
        Sketchup::set_status_text "", SB_VCB_VALUE
        @state = STATE_PICK_2
   puts "#{@state} #{@pointcount}"
   @status_text = "[#{@tool_name}] Click second corner of Polygon"
    when STATE_PICK_2
        # @ip1.clear
   @ip1.copy! @ip
   @lastpointcount = @pointcount
   @pointcount = @pointcount + 1
   Sketchup::set_status_text "[#{@tool_name}] Click third corner of Polygon"
   Sketchup::set_status_text "Section Length", SB_VCB_LABEL
        Sketchup::set_status_text "", SB_VCB_VALUE
        @state = STATE_PICK_3
   puts "#{@state} #{@pointcount}"
   @status_text = "[#{@tool_name}] Click third corner of Polygon"
    when STATE_PICK_3
        # @ip1.clear
   @ip1.copy! @ip
   @lastpointcount = @pointcount
   @pointcount = @pointcount + 1
   Sketchup::set_status_text "[#{@tool_name}] Click fourth corner of Polygon"
   Sketchup::set_status_text "Section Length", SB_VCB_LABEL
        Sketchup::set_status_text "", SB_VCB_VALUE
        @state = STATE_PICK_FINAL
   puts "#{@state} #{@pointcount}"
   @status_text = "[#{@tool_name}] Click fourth corner of Polygon"
    when STATE_PICK_FINAL
   # @ip1.clear
   @ip1.copy! @ip
   ptcurrent = @ip.position
   @distorigin = @pts[0].distance ptcurrent
   if (@distorigin > 0.0001)
      @lastpointcount = @pointcount
      @pointcount = @pointcount + 1
      @nextpointcount = @pointcount + 1
      @state = STATE_PICK_FINAL
      puts "#{@state} #{@pointcount}"
      Sketchup::set_status_text "[#{@tool_name}] Click corner #{@nextpointcount} of Polygon"
      Sketchup::set_status_text "Section Length", SB_VCB_LABEL
           Sketchup::set_status_text "", SB_VCB_VALUE
      @status_text = "[#{@tool_name}] Click corner #{@nextpointcount} of Polygon"
   else
      # Final point picked, jump to calculation and exit tool to main program
      
           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
   

   # Back to main program

   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_2
        # update the section length
        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_3
        # update the section length
        vec = @pts[2] - @pts[1]
        if( vec.length > 0.0 )
            vec.length = value
            @pts[2] = @pts[1].offset(vec)
            # view.invalidate
            self.update_state
        end
    when STATE_PICK_FINAL
   # update the section length
        vec = @pts[@pointcount] - @pts[@lastpointcount]
        if( vec.length > 0.0 )
            vec.length = value
            @pts[@pointcount] = @pts[@lastpointcount].offset(vec)
            # view.invalidate
            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
    when STATE_PICK_3
        # 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, @ip1, @ip)
   view.draw(GL_LINE_STRIP, @pts)
        @drawn = true
    else
   # 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)
        @drawn = true
    end
end

end # class PositionToolPolygon


#######################################

end # module FoundationPositionToolPolygon
0
Nathaniel P. Wilkerson PE
Medeek Engineering Inc
design.medeek.com
User avatar
medeek 
PluginStore Author
PluginStore Author
 

Re: Polygon Positioning Tool

Postby Dan Rathbun » Mon Apr 10, 2017 1:40 am

Just an FYI, the posted code's improper indentation is so annoying I will not bother to read nor try it out.
1
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby medeek » Mon Apr 10, 2017 3:11 am

    I agree, the indentation is killing me. Trust me it doesn't actually look like this, when I cut and past it into the text box it completely mucks it up.
    0
    Nathaniel P. Wilkerson PE
    Medeek Engineering Inc
    design.medeek.com
    User avatar
    medeek 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby sdmitch » Mon Apr 10, 2017 1:46 pm

    medeek wrote:I've got the polygon positioning tool mostly worked out for my foundation plugin. However, when the user enters in a value for the length of the segment (VCB_VALUE) then the subsequent line selection does not properly infer the X and Y axis.


    There are two problems as I see it.

    1. You are using @ip1 and @ip to set the line color but, when you enter a length, @ip1 is no longer valid since the point it represents has changed. I think you should use the last to values of the @pts array to set the color.

    2. Expecting the user to get within 0.0001 of the first point to close is way to restrictive.
    0
    Nothing is worthless, it can always be used as a bad example.

    http://sdmitch.blogspot.com/
    User avatar
    sdmitch 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby medeek » Mon Apr 10, 2017 3:14 pm

    I replace the set color line with:

    view.set_color_from_line(@pts[@lastpointcount], @pts[@pointcount])

    however the behavior is identical.

    I agree the .0001 is probably too restrictive. What I should probably do is insert a temporary guide point (add_cpoint) and then delete it once I jump back to my main program out of the tool or as the tool terminates. This way the user has something to snap to in order to close out the polygon.
    0
    Nathaniel P. Wilkerson PE
    Medeek Engineering Inc
    design.medeek.com
    User avatar
    medeek 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby sdmitch » Mon Apr 10, 2017 4:07 pm

    medeek wrote:I replace the set color line with:

    view.set_color_from_line(@pts[@lastpointcount], @pts[@pointcount])

    however the behavior is identical.



    I too find it odd that entering a length suddenly causes the axis inference to change its' behavior. The tooltip seems to think that @ip1 is still valid while, if you zoom in and move the mouse very slowly, the correct inference will occur. After that everything is back to normal until the next length entry.

    Very strange indeed and an obvious bug in Sketchup.
    0
    Nothing is worthless, it can always be used as a bad example.

    http://sdmitch.blogspot.com/
    User avatar
    sdmitch 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby medeek » Tue Apr 11, 2017 3:26 am

    Yes it is strange. If you enter a value then the next line won't infer the axis, but if you then click the mouse and begin another line the inference returns to normal. The whole tool thing is still somewhat of a black box to me so I don't really understand it fully but this certainly has me confounded.
    0
    Nathaniel P. Wilkerson PE
    Medeek Engineering Inc
    design.medeek.com
    User avatar
    medeek 
    PluginStore Author
    PluginStore Author
     

    Re: Polygon Positioning Tool

    Postby Dan Rathbun » Tue Apr 11, 2017 9:31 pm

    Nat, use 2 space characters for indents. Tabs will not come out well in the forum code blocks.
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: Polygon Positioning Tool

      Postby medeek » Wed Apr 12, 2017 1:28 am

      I've been using tabs for indents since 1999, getting me to change now is not easy. You can probably tell that I like a lot of whitespace in my code, easier to read.
      0
      Nathaniel P. Wilkerson PE
      Medeek Engineering Inc
      design.medeek.com
      User avatar
      medeek 
      PluginStore Author
      PluginStore Author
       

      Re: Polygon Positioning Tool

      Postby Dan Rathbun » Wed Apr 12, 2017 11:58 pm

      That is okay (whitespace). I use Notepad++ which automatically replaces TAB with spaces. Each language can have a different indent spacing. (I'd think most editors can [or should] do this.)
      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: Polygon Positioning Tool

        Postby Garry K » Thu Apr 13, 2017 3:31 am

        I totally agree. I use Notepad++ as well and I do not use tabs.

        The main reason is everyone can set their tabs differently - but spaces are spaces so the reader gets to see what you want them to see.
        0

        Garry K 
        Premium Member
        Premium Member
         

        Re: Polygon Positioning Tool

        Postby medeek » Thu Apr 13, 2017 2:58 pm

        I tried Notepad++ a couple years ago but something about it perturbed me so I went back to my basic Windows Notepad, I may revisit it.
        0
        Nathaniel P. Wilkerson PE
        Medeek Engineering Inc
        design.medeek.com
        User avatar
        medeek 
        PluginStore Author
        PluginStore Author
         

        Re: Polygon Positioning Tool

        Postby Dan Rathbun » Thu Apr 13, 2017 6:03 pm

        medeek wrote:... so I went back to my basic Windows Notepad, ...

        How do you know what encoding it saves the file it ?
        How do you know what type of line ending characters it uses ?

        These are things easily set with a real code editor.

        In addition code editors use color lexing to help you spell keywords correctly, match up the begins and ends of code blocks, etc. They also can use autocomplete features to help fillout method calls.
        0
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          SketchUcation One-Liner Adverts

          by Ad Machine » 5 minutes ago



          Ad Machine 
          Robot
           



           

          Return to Developers' Forum

          Who is online

          Users browsing this forum: salehas, TMLEE and 2 guests

          Visit our sponsors: