How can we find followme path?

Dear friends,
I have @face1 and @path1. I wish to draw similar to followme. One point of face is on the path and simply I can show it like this…

def draw(view)
  view.drawing_color= "yellow"
  view.line_width = 1
  view.draw_polyline @path1
end

How can I find other points of @face1 paths?
Thank you in advance for your help.

I presume you want to do this to show a “ghost” of what followme would generate without actually doing the followme and without adding real geometry to the model yet. But the SketchUp Ruby API provides no “virtual followme” that would generate the Point3d for the vertices of the extrusion without actually generating the geometry and adding it to the model.

So far as I can see, your only way would be to emulate the calculations of the followme algorithm and use the resulting Point3d values in various view.draw methods. That’s easy for a straight extrusion such as would be formed by push-pull, but much more complicated for a non-straight path. Obviously it can be done - for example Curviloft shows you a preview of the surface it will create. But Curviloft also has access to all the math and data involved in creating that surface; the only difference is between drawing it as a ghost to the screen versus adding the geometry to the model then letting SketchUp display it as usual.

Hi, You are right. In fact, I wish to show a wireframe of it.

In 2D or one direction (same as push-pull), it is easy. in 2D perpendicular to a line is a line but in 3D it is a panel and finding the right line in this panel is difficult.
Is it possible we find the math calculation of SU followme?

Some simple example about one of the possibilities :thinking:
… with minimal error handling… :blush:

class Tool_test_draw_gl_paths
  ###dirty!!###
  def initialize
    # create example face and path
    # Note: the path should be a curve
    #       to get ordered vertices
    model = Sketchup.active_model
    ents = model.active_entities
    face1_pts = [ [0,0,0], [0,0,1], [1,0,0] ]
    path1_pts = [ [0,0,0], [0,1,0], [1,2,1] ]
    path2_pts = [ [0,0,0], [0,-1,0], [-1,-2,1] ]
    @face1 = ents.add_face( face1_pts )
    path1 = ents.add_curve( path1_pts )
    path2 = ents.add_curve( path2_pts )
    @ip = Sketchup::InputPoint.new
  end
  
  def resume(view)
    view.invalidate
  end
  
  def onMouseMove(flags, x, y, view)
    @ip.pick(view, x, y)
    # select one of the path
    if @ip.edge && @ip.edge.curve
      curve_edge = @ip.edge
      calcualte_paths(curve_edge)
    end
    view.invalidate
  end
  
  def calcualte_paths(path)
    # get the face vertices position
    vp_face = @face1.outer_loop.vertices.map(&:position)
    #get the path vertices position
    vp_path = path.curve.vertices.map(&:position)
    p_size = vp_path.size
    # this will be a "virtual faces" (planes) where the path turns
    @p_faces = []
    # the first virual face will be the original face points
    @p_faces[0] = vp_face
    # iterate through path vertices
    (1...p_size).each{|i|
      # get a vector from previous to next points of path
      vec1 = vp_path[i-1].vector_to(vp_path[i]).normalize
      # get second vector to the next points
      #  but if we are at the end there will be no vec
      if i == p_size-1
        vec2 = nil
      else
        vec2 = vp_path[i].vector_to(vp_path[i+1]).normalize
      end
      # calculate the "turning" plane vector...
      if !vec2 || vec1.parallel?(vec2)
        vec_plane = vec1
      else
        # some vector "magic" 
        #get a perpendicular vector
        vec_perp = vec1 * vec2
        #get a biselector vector
        vec_bise = vec2 - vec1
        # get a perpendicular vector again
        vec_plane = vec_bise * vec_perp 
      end
      # the turning plane is perpendicular to the path edges
      # and located at their angle bisector
      # https://ruby.sketchup.com/Geom.html
      plane = [vp_path[i], vec_plane]
      # get an intersect points with a line from a previous
      # points of virtual feces to plane and calculate the next
      # virtual face
      @p_faces[i] = @p_faces[i-1].map{|p|
        Geom.intersect_line_plane([p, vec1], plane)
      }
    }
    # calculate the paths by transposing the 
    # nested ("two dimensional") array
    # https://ruby-doc.org/core-2.7.1/Array.html#method-i-transpose
    @p_paths = @p_faces.transpose
  end
  
  def draw(view)
    # https://ruby.sketchup.com/Sketchup/View.html#draw-instance_method
    #let show the paths
    view.drawing_color= "yellow"
    view.line_width = 1
    @p_paths.each{|points|
      view.draw(GL_LINE_STRIP, points)
    } if @p_paths
    #let show the virtual faces
    view.drawing_color= [225,255,0,64]
    @p_faces.each{|points|
      view.draw(GL_POLYGON, points)
    } if @p_faces
  end
end
Sketchup.active_model.select_tool(Tool_test_draw_gl_paths.new)
4 Likes

Dear Dezmo,
For sure I need time to fully understand your codes and I will keep it as a reference. I really love vector magic in your code and your idea to solve the problem.

1 Like

Suggestion: tag @dezmo 's reply as the solution, rather than your own reply that mentions his solution.

3 Likes

I also did it. Sorry for my mistake. I wanted click on his post. Thank you for the suggestion.


Your codes work well. Thanks again.

3 Likes