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