Inexplicable error

Hello Sketchup Folks,

I wanted to create an illustration of a simple neural network and I wrote this script to try to accomplish it.

module Network

  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)
    # make a circle face at the point with the given radius
    normal = [0,0,point[2]+1]
    circ = entities.add_circle(point, normal, radius)
    circ_face = self.make_circle_face(ents, circ)
    return circ_face
  end
  
  def self.draw_layer(num_pts_per_side, spacing, width, z, pipe_radius)
    # draw a flat layer and calculate the position of the nodes
    model = Sketchup.active_model
    entities = model.entities
    layer_group = entities.add_group

    face = layer_group.entities.add_face [0,0,z],[width,0,z],[width,width,z],[0,width,z]

    nodes = []
    (0..num_pts_per_side-1).each { |i|
      (0..num_pts_per_side-1).each { |j|
        center = [spacing + i*spacing, spacing + j*spacing, z]
        normal = [0,0,z+1]
        nodes << Geom::Point3d.new(center)
      } # j
    } # i

    return layer_group, nodes
  end # method draw_layer
  
  def self.get_NWSE(nodes, num_pts_per_side, index)
    # using index into array of nodes, 
    # determine if points N,S,E,or W of it are nodes that exist
    # indexes go up y axis first, then x, e.g.
    # 2  5  8
    # 1  4  7
    # 0  3  6     
    total = nodes.size
    i = index
    north = south = east = west = nil
    if ((i+1) % num_pts_per_side) != 0 
      north = nodes[i+1]
    end
    if (i % num_pts_per_side) !=0 
      south = nodes[i-1]
    end
    if i < (total-num_pts_per_side)
      east = nodes[i+num_pts_per_side]
    end
    if i >= num_pts_per_side
      west = nodes[i-num_pts_per_side]
    end
    return [north, west, south, east]
  end # method get_NWSE
  
  def self.draw_connector(entities, start_point, end_point, radius, make_thick)
    if end_point
      # draw a line, then if thickness is desired, use followme to create a thicker line
      path = entities.add_line(start_point, end_point)
      if make_thick
        circ_face = self.make_circle(entities, start_point, radius)
        circ_face.followme(path)
      end
    end
  end

  def self.draw(num_pts_per_side, spacing, width, num_layers, layer_separation, radius)
    # draw the network
    model = Sketchup.active_model
    entities = model.entities
    
    # draw the layers
    limit = num_layers * layer_separation
    layers = []
    (0..limit-1).step(layer_separation).each { |z|
      layer_group, nodes = self.draw_layer(num_pts_per_side, spacing, width, z, radius)
      results = [layer_group, nodes]
      layers << results
    }
    
    # draw node connectors
    (0..num_layers-2).each { |z|
      layer1, nodes1  = layers[z]
      layer2, nodes2  = layers[z+1]
      entities = layer1.entities
      nodes1.each_with_index { |point, index|
        # draw a line to the point just above
        self.draw_connector(entities, point, nodes2[index], radius, FALSE)
        # draw lines to NSEW above if possible
        north,west,south,east = self.get_NWSE(nodes2, num_pts_per_side, index)
        self.draw_connector(entities, point, north, radius, FALSE)
        self.draw_connector(entities, point, south, radius, FALSE)
        self.draw_connector(entities, point, east, radius, FALSE)
        self.draw_connector(entities, point, west, radius, FALSE)
      }
    }
  end #method draw
end # module

num_pts_per_side = 4.0 # number of holes per side
width = 10.0
num_layers = 2
layer_separation = 5
connector_radius = 0.1
spacing = width/(num_pts_per_side+1).to_f 

Network.draw(num_pts_per_side, spacing, width, num_layers, layer_separation, connector_radius)

In the script I create two layers with nodes and draw lines between the layers, connecting every possible node from the bottom layer to the top so that each node connects to the one above and then the north, south, east and west neighbors if possible.

So far so good, but I would like to colorize the connectors, so I decided to create a small circle and use follow me along the connection so the line could be colored. This works fine if I only choose one of north, south, east or west.

network connected directly above, no problem

network connected to north nodes, ok so far

But as soon as I try to thicken the connections for more than one direction this strange error results. I have no idea why.

strange error

I’ve tried all combinations of north, south, east and west, and any two pairs of directions result in this weird result

Thank you for any clues
-j_jones

Add each set of the new geometry to its own group so you have complete and un-intersected geometry. I think the problem was that followme() was being called on a very funky face.

  def self.draw_connector(entities, start_point, end_point, radius, make_thick)
    if end_point
      grp = entities.add_group # add the new geometry to a new group
      entities = grp.entities
      # draw a line, then if thickness is desired, use followme to create a thicker line
      path = entities.add_line(start_point, end_point)
      if make_thick
        circ_face = self.make_circle(entities, start_point, radius)
        circ_face.followme(path)
      end
    end
  end
1 Like

works great! many thanks!