Error with "Component Options" Tool and Custom Attribute Dictionaries created using API

Actually, the opposite is the case. The SketchUp API itself has no problem saving these API types and getting them back out of an attribute dictionary. (Do @sWilliams test at the console and it can be verified.)
It is the DC extension code that has the problem and makes incorrect assumptions about the types stored in array attributes.

I would foresee a challenge if the type of objects in the array are mixed.

This may work, as the API overrides the Geom::Point3d#inspect and Geom::Vector3d#inspect methods to output a string like: "Point3d(2.34, 5.67, 1.23)" & "Vector3d(2.34, 5.67, 1.23)"

However the API does not define a reciprocal method to convert back (AFAIK).
The following is what I came up with to convert back.

UPDATE: Switched to using #scan with a new Regexp (matching groups of digit and . characters that are not followed by a “d” character.) It now works for whole integers and decimal numbers.
In addition, it also works for the #to_s and #inspect output of numeric arrays.
But a word of warning, … the String#to_l method may be reading the string values in model units. Trying to get my head around this is difficult as the Ruby Console is displaying stuff in model units and confusing the issue.
ADD: I decided to append a " to the end of each numeric string to force String#to_l to read the values as inches.

Within your extension submodule:

  def str_to_point(str)
    Geom::Point3d.new(
      str.scan(/([0-9.]+)[^d]/).flatten.map {|s| (s<<'"').to_l }
    )
  end

  def str_to_vector(str)
    Geom::Vector3d.new(
      str.scan(/([0-9.]+)[^d]/).flatten.map {|s| (s<<'"').to_l }
    )
  end

Or you might use a class refinement:

module CustomNamespace

  module StringConverter

    refine String do

      # Converts the output of Geom::Point3d#inspect back into a Geom::Point3d
      # object. These strings have the format of "Point3d(1, 2, 3)".
      def to_point
        ::Geom::Point3d.new(
          self.scan(/([0-9.]+)[^d]/).flatten.map {|s| (s<<'"').to_l }
        )
      end

      # Converts the output of Geom::Vector3d#inspect back into a Geom::Vector3d
      # object. These strings have the format of "Vector3d(1, 2, 3)".
      def to_vector
        ::Geom::Vector3d.new(
          self.scan(/([0-9.]+)[^d]/).flatten.map {|s| (s<<'"').to_l }
        )
      end

    end # String class refinement
  
  end # refinement module

  module SomeCustomExtensionSubmodule
  
    using StringConverter
    
    # code that uses String#to_point() and/or String#to_vector()
    
  end # extension submodule

end # top-level namespace
1 Like