[code] Accessing and Loading SketchUp Shipped Materials

Accessing and Loading SketchUp Shipped Materials

Prompted by many requests over the years and recent changes to the Materials collection that is shipped with SketchUp.

Major changes regarding the shipped Materials collection: (click to expand)
  • 2015 - Access to Colorization properties for materials is implemented.

  • 2016 and earlier - On Windows the shipped materials resided in the %ProgramFiles% path, in SketchUp’s binary folder.

    • Before 2017, extensions had to load a component file with the material embedded assigned to a cpoint object. Then use the material. It was not until 2018 that code could afterward remove the temporary definition.
  • 2017.0 - On Windows the shipped materials were moved to the %ProgramData% path for the version of SketchUp.

    • The Materials#load method was implemented allowing materials to be loaded from storage.
  • 2019.2 - The owner_type method is implemeted to determine what collection owns a material.

  • 2024.0 - A "MaterialTemplate.skp" file is now present in the shipped materials folder which can be used to find it. See the example shipped_materials_path() method below, or the snippet in the API documentation for Sketchup::Materials#load.

  • 2025.0 - Physically-Based Rendering (PBR) material support is added.

    • Both the "Colors" and "Colors-Named" material subfolders were removed and replaced with the new PBR material subfolder which is named "Solid Colors".
    • Many historical shipped materials in all categories where removed or renamed when the Physically-Based Rendering materials were introduced with the 2025.0 release. So, code defensively and notify the user if nil is the result of attempting to load an “antiquated” material.
    • Many new API methods to access and set PBR properties for material objects.

:nerd:


load_shipped_material.rb (3.5 KB)


# Returns the path to SketchUp's shipped materials folder.
#
# @return [String,nil] The shipped materials path or `nil` if not found.
def shipped_materials_path
  materials_template = Sketchup.find_support_file('Materials/MaterialTemplate.skp')
  if materials_template && File.exist?(materials_template)
    # Newer SketchUp versions >= 24.0 :
    return File.dirname(materials_template)
  else
    # Older SketchUp versions 17.0 .. 23.0 :
    #
    # Prior to SU2017 the distributed Materials were in the %ProgramFiles%
    # path. With 2017 they were moved to the %ProgramData% path on Windows.
    # On Mac they may still be in the bundle.
    #
    # Before 2017, extensions had to load a component file with the material
    # embedded assigned to a cpoint object. Then use the material. It was not
    # until 2018 that code could afterward remove the temporary definition.
    #
    colors_path = Sketchup.find_support_file('Materials/Colors-Named')
    # NOTE: "Colors-Named" subfolder replaced with "Solid Colors" in SU25.0
    colors_path = File.dirname(colors_path) if colors_path
    if colors_path
      return File.dirname(colors_path)
    else
      puts %[Cannot find shipped Materials path.]
      return nil
    end
  end
end ### shipped_materials_path()

# Returns an array of relative paths for all the shipped materials files. The
# paths are relative to the shipped materials directory path.
#
# @return [Array<String>] The relative paths to all shipped materials.
# @return [nil] If the shipped materials path is not found.
def shipped_materials
  #
  materials_path = shipped_materials_path()
  return nil unless materials_path
  #
  if RUBY_VERSION.to_f >= 2.5 # Dir.glob accepts hash arg for :base
    Dir.glob('**/*.skm', base: materials_path)
  else
    Dir.chdir(materials_path) { Dir.glob('**/*.skm') }
  end
end ### shipped_materials()

# Load a material from the shipped SketchUp library.
#
# WARNING: Many historical shipped materials in all categories where removed
# or renamed when the Physically-Based Rendering materials were introduced with
# the 2025.0 release. So, code defensively and notify the user if `nil` is the
# result of attempting to load an "antiquated" material.
#
# @example Load the OSB material only from "Wood" subfolder (<= 24.0):
#   matl = load_shipped_material("Wood/Wood OSB")
#
# @example Search all shipped material subfolders:
#   matl = load_shipped_material("Rough Square Concrete Block")
#
# @param matl [String] The material file name. A filetype extension is not needed.
#  A material subfolder prefix can be included to narrow the search.
#
# @return [nil] Upon failure to find the material path requested.
# @return [Sketchup::Material] The loaded or existing material.
#
# @raise [RuntimeError] If the material skm file failed to load.
#
# @since SketchUp 2017.0
def load_shipped_material(matl)
  # Append a .skm filetype if just the name is passed:
  matl = matl + '.skm' if File.extname(matl).empty?
  # Get the list of shipped materials:
  files = shipped_materials()
  # Check for a valid array:
  return nil unless files
  # Find a filepath ending with the matl argument:
  path = files.find { |file| file =~ /#{matl}\Z/i }
  # If path is not nil, then it exists:
  unless path
    puts %[Cannot find Material path for "#{matl}".]
    return nil
  else
    path = File.join(shipped_materials_path, path)
  end
  materials = Sketchup.active_model.materials
  material = materials.load(path)
end ### load_shipped_material()
3 Likes