Create an array of points from a face

I got issues with @thomthom algorithm (bad grid position), so I recoded my own algorithm… I use it on my Random Entity Generator plugin and it works very well:

require 'sketchup'

# REG plugin namespace.
module REG

  # Grid of points.
  module PointGrid

    # Returns a point grid for a face.
    #
    # @param [Sketchup::Face] face
    # @param [Integer] grid_size
    #
    # @raise [StandardError]
    #
    # @return [Array<Geom::Point3d>]
    def self.face(face, grid_size = 10)

  face_vertices = face.vertices

  if face_vertices.size != 4

    raise StandardError.new('Only quad faces are supported.')

  end

  lc_points_x = []
  lc_points_y = []

  face_point_grid = []

  start_lc_count = 0
  end_lc_count = grid_size

  grid_size.times do

    start_lc_count += 1
    end_lc_count -= 1

    lc_points_x.push(Geom.linear_combination(
      start_lc_count.to_f / grid_size,
      face_vertices.first.position,
      end_lc_count.to_f / grid_size,
      face_vertices.last.position
    ))

    lc_points_y.push(Geom.linear_combination(
      start_lc_count.to_f / grid_size,
      face_vertices[1].position,
      end_lc_count.to_f / grid_size,
      face_vertices[2].position
    ))

  end

  lc_point_index = 0

  lc_points_y.size.times do

    start_lc_count = 0
    end_lc_count = grid_size

    grid_size.times do

      start_lc_count += 1
      end_lc_count -= 1

      face_point_grid.push(Geom.linear_combination(
        start_lc_count.to_f / grid_size,
        lc_points_x[lc_point_index],
        end_lc_count.to_f / grid_size,
        lc_points_y[lc_point_index]
      ))

    end

    lc_point_index += 1

  end

  face_point_grid

    end

    # Returns a point grid for a group or component.
    #
    # @param [Sketchup::Group|Sketchup::ComponentInstance] grouponent
    # @raise [ArgumentError]
    #
    # @param [Integer] grid_size
    #
    # @return [Array<Geom::Point3d>]
    def self.grouponent(grouponent, grid_size = 10)

  raise ArgumentError, 'Grouponent parameter is invalid.'\
    unless grouponent.is_a?(Sketchup::Group)\
      || grouponent.is_a?(Sketchup::ComponentInstance)

  grouponent_transformation = grouponent.transformation

  grouponent_point_grid = []

  if grouponent.is_a?(Sketchup::Group)

    grouponent_faces = grouponent.entities.grep(Sketchup::Face)

  else # if grouponent.is_a?(Sketchup::ComponentInstance)

    grouponent_faces = grouponent.definition.entities.grep(Sketchup::Face)

  end

  grouponent_faces.each { |grouponent_face|

    not_trans_point_grid = face(grouponent_face, grid_size)

    transformed_point_grid = []

    not_trans_point_grid.each { |not_trans_point|

      transformed_point_grid.push(
        not_trans_point.transform!(grouponent_transformation)
      )

    }

    grouponent_point_grid.concat(transformed_point_grid)

  }

  grouponent_point_grid

    end

  end

end

Usage

point_grid = REG::PointGrid.face(face)

or

point_grid = REG::PointGrid.grouponent(group_or_component)

Limitations

It works only on quad faces. So you can use Quadrilateralizer plugin if needed.

经测试,当面朝上或朝南时,可用;但面向北时不可用
Available when facing up or south; However, it is not available when facing north
这两朝向不可用
These two orientations are not available
image
image