There are extensions to the base classes in SketchUp’s Ruby API which often new SketchUp plugin developers overlook. If you aren’t aware of them you might find yourself reinventing many features of the SketchUp API which already exists. There is very little you need to do to deal with units, SketchUp does most of the work.
Internally SketchUp uses inches as system unit. All 3D coordinates in the model data are in inches – no exceptions! This internal units are converted to model units only when presented in the UI. Similarly, all user input is immediately converted to internal units. Your plugin should do this to!
Internal Units to Model Units
To convert an internal unit, to a string in model unit, ensure that your length value is of the Length class. Length.to_s – which is the same as Sketchup.format_length( value ) - formats the internal unit into a user friendly string using the model settings and user locale.
Float and Length
Length is a sub-class of Float. Geom::Point3d and Geom::Vector3d will return Length objects for it’s coordinate components.
Note that using Length for arithmetic operations will return Float objects. So make sure you know whether you have a Float or Length object when you eventually want to present that value to the UI. Float.to_l will give you a Length object when you need to.
Model Units to Internal Units
The String class takes care of converting model units to internal units in the form of String.to_l. If you have a string "50".to_l and the model units is millimetres it will assume the numeric value in the string is millimetres. But at the same time the string can contain unit indicators to override this: "50m".to_l will be treated as 50 metres regardless of model unit settings. This is useful for processing VCB input for instance as the user can then input lengths in any units supported by SketchUp – just like the native tools and you don’t have to do anything more than .to_l.
The input box in SketchUp will actually try and do the conversion between model units and user input strings for you if you set it up correctly. If you give it Length objects as default values it will automatically convert the values into model unit strings in the UI of the dialogue and back into Length for the return values.
As you can see from this example, SketchUp does all the work – you do not need to convert to and from string yourself.
Note that this doesn’t work so well for floats, as Ruby assumes floats are using period for decimal separator even if the user locale uses comma. If the user uses a comma for decimal separator for Float values you get anArgumentError when SketchUp tries to convert theString back to Float. This error is unique to UI.inputbox – when you otherwise convert for instance '0,8'.to_f you will get 0.0 without any errors.
Storing Unit Data
Because users have different decimal separators depending on their locale, never store unit data as formatted strings! Don’t write Length values out as length.to_s – instead convert it to a Float. That way you can be sure that you can read the data back regardless of the locale of the target system becauseFloat.to_s always use period as decimal separator – and String.to_f always expect a period. To load a unit from a float stored as string correctly you use: string.to_f.to_l.
A string like "10,5m” can only be parsed with .to_l correctly on systems with comma as decimal separator - similarly "10.5m" can only be parsed with .to_l correctly on systems with period as decimal separator. Mixing up this and you end up with ArgumentError.
Internally SketchUp uses radians instead of degrees. The numeric class is extended to provide easy conversions so you can type stuff like 75.degrees which will return 75 degrees in radians - similarly you can type 0.25.radians to return a radian value to degrees. These methods also exists asSketchUp.format_degrees and Sketchup.format_angle.
You also have Sketchup.format_area which will take a value representing an area inch-squared and format it into model units. But the problem arise when you want to convert the other way around. Currently, SketchUp 8 M3, there is no methods for converting area strings in model units to internal units. You have to craft your own. This is not so easy because some user locales uses comma as decimal separator – and there is no method that returns this in SketchUp. But you can hack it.
SketchUp Units and Locale Helper Library
I’ve collected most of my units and locale methods into an example library on GitHub. Feel free to use it for whatever you need and please push back improvements.
Cross Posted From : http://www.thomthom.net/