Followme crash

I have possibly the same problem as this question: Why does face.followme crash Sketchup?

I have created a nice tapering spiral with this script. At the end I want to make the spiral thicker by using followme along the edges of the spiral.

Here is the script:

module Spiral

  def self.make_circle_face(entities, circle_edges)
    pts = []
    circle_edges.each { |e|
      pts << e.vertices[0]
    }
    face = entities.add_face(pts)
    return face
  end

  def self.make_circle(entities, point, radius, normal)
    # make a circle face at the point with the given radius
    circ = entities.add_circle(point, normal, radius)
    circ_face = self.make_circle_face(entities, circ)
    return circ_face
  end

  def self.draw_turn(entities, segments, radius, taper_amount, 
                        z, z_increment, facet_size, last_point)
    (0..360).step(facet_size).each do |angle|
      theta = angle.degrees
      radius -= taper_amount
      x = radius * Math.cos(theta)
      y = radius * Math.sin(theta)
      z += z_increment
      point = Geom::Point3d.new(x, y, z)
      line = entities.add_line(last_point, point)
      segments << line
      last_point = point
    end
    return [last_point, z, radius]
  end

  def self.draw(radius, taper_amount, z_increment, num_turns, facet_size, segments)
    model = Sketchup.active_model
    entities = model.active_entities
    z = 0
    y = 0
    orig = Geom::Point3d.new(0,y,z)
    endpoint = Geom::Point3d.new(radius, y, z)
    spiral_group = entities.add_group
    spiral_entities = spiral_group.entities
    (0..num_turns).each do |turn|
      endpoint, z, radius  = self.draw_turn(spiral_entities, segments, radius, 
          taper_amount, z, z_increment, facet_size, endpoint)
    end
    return spiral_group
  end # method draw

end # module Spiral

radius = 100
taper_amount = 0.1
z_increment = 0.5
num_turns = 4
facet_size = 2
segments = []

spiral_group = Spiral.draw(radius, taper_amount, z_increment, num_turns, facet_size, segments)

entities = spiral_group.entities

# create a small circle at the starting point 
start_point = Geom::Point3d.new(radius, 0, 0)
normal = [0,1,0]
face = Spiral.make_circle(entities, start_point, 10, normal)

# uncomment this and crash happens
#face.followme(segments)



without the followme, it generates the spiral I want.

As soon as I add the followme at the end, sketchup crashes.

How can I do this correctly?

Thank you for any clues
-j_jones

The face isn’t perpendicular to the start of the path.

It seems to me that it is perpendicular? Can you explain how you would change the normal so that it would be, in your estimation, properly perpendicular?

The spiral has a small, repeating, line segment that offsets what seems to be the intended start of the path.

The first spiral line segment does not pass through the face of the circle at a right angle. If you move the circle back (on green) and then draw a small line segment on green, Follow Me works manually (but the starter segment is still repeated throughout the spiral).

I couldn’t fix the spiral but that’s probably something to be fixed first.

1 Like

Starting the Range for the angle at zero was adding an initial vertical line which snarled up the followme algorithm. Here’s the line that needed to be adjusted.

# start_point is our [x,0,0] point so we start the range with facet_size instead of zero
    (facet_size..(360 * num_turns)).step(facet_size).each do |angle|

The complete example

module Spiral

  def self.make_circle_face(entities, circle_edges)
    pts = []
    circle_edges.each { |e|
      pts << e.vertices[0]
    }
    face = entities.add_face(pts)
    return face
  end

  def self.make_circle(entities, point, radius, normal)
    # make a circle face at the point with the given radius
    circ = entities.add_circle(point, normal, radius)
    circ_face = self.make_circle_face(entities, circ)
    return circ_face
  end

  # Draw all of the turns in one complete operation
  #
  def self.draw_turns(entities, segments, radius, taper_amount, z, z_increment, facet_size, start_point, num_turns)
    # start_point is our [x,0,0] point so we start the range with facet_size instead of zero
    (facet_size..(360 * num_turns)).step(facet_size).each do |angle|
      theta = angle.degrees
      radius -= taper_amount
      x = radius * Math.cos(theta)
      y = radius * Math.sin(theta)
      z += z_increment
      end_point = Geom::Point3d.new(x, y, z)
      line = entities.add_line(start_point, end_point)
      segments << line
      start_point = end_point
    end
  end

  def self.draw(radius, taper_amount, z_increment, num_turns, facet_size, segments)
    model = Sketchup.active_model
    entities = model.active_entities
    z = 0
    y = 0
    #orig = Geom::Point3d.new(0,y,z)
    start_point = Geom::Point3d.new(radius, y, z)
    spiral_group = entities.add_group
    spiral_entities = spiral_group.entities
    draw_turns(spiral_entities, segments, radius, taper_amount, z, z_increment, facet_size, start_point, num_turns)
    return spiral_group
  end # method draw

end # module Spiral

radius = 100
taper_amount = 0.1
z_increment = 0.5
num_turns = 4
facet_size = 2
segments = []

model = Sketchup.active_model
model.start_operation('spiral', true)

  spiral_group = Spiral.draw(radius, taper_amount, z_increment, num_turns, facet_size, segments)
  entities = spiral_group.entities

  # create a small circle at the starting point 
  start_point = Geom::Point3d.new(radius, 0, 0)
  normal = [0,-1,0]
  face = Spiral.make_circle(entities, start_point, 10, normal)

  # uncomment this and crash happens
  face.followme(segments)

model.commit_operation

3 Likes

Just for giggles, a few alternate ways to make the circle face:

  def self.make_circle_face(entities, circle_edges)
    # Map the member edges in circle_edges array to their start vertex:
    verts = circle_edges.map(&:start)
    face  = entities.add_face(verts)
    return face
  end

  def self.make_circle_face(entities, circle_edges)
    # Get the curve object from the first member of the circle_edges array:
    circ = circle_edges.first.curve
    # The Entities#add_face factory method accepts a Curve object:
    face = entities.add_face(circ)
    return face
  end

  def self.make_circle_face(entities, circle_edges)
    # Snapshot of faces in entities:
    before = entities.grep(Sketchup::Face)
    # Make all faces from the first member of the circle_edges array:
    circle_edges.first.find_faces
    # Get the new faces via Array subtraction:
    new_faces = entities.grep(Sketchup::Face) - before
    return new_faces[0]
  end
1 Like

Ah, I had not noticed that tiny little jump at the beginning of the spiral.

First I tried moving the ‘z += z_increment’ to the end of the iteration, which eliminates that little initial jump, then run again, still results in a crash for me.

However, running your code where you combine all the turns into one function call doesn’t crash.

Still not sure why my modified version crashes, but I’m grateful that it isn’t just my too old version of Sketchup or something.

Thank you!!
-j_jones

Ah, I see why now. Every turn had that little jump in it at the start, even my modified version.

Thanks!
-j_jones