General question - definition of units (inch/metric)
-
@artmusicstudio said:
hi all,
when the ruby is for all over the world, how can i programm the ruby to know, in which units the user works and makes the input ( = user's skp-preferences-setting)?or is it ok fo "force" the user to use metric system (in my case) ?? that would not be user friendly, i think.
thanx for a tip.
stan
I believe you can find these settings in the OptionsProvider named "UnitsOptions" in the model's OptionsManager. The names in that OP are pretty clear, but you may have to do some experimentation to figure out what the numeric values mean for the key "LengthUnit".
IMHO, forcing metric is entirely between you and your users
Steve
-
Thomthom wrote a guide for this.
-
As Daniel mentioned, I wrote an article on this. It's actually less work to make it work for whatever unit the user is using because you use the methods that the Ruby API provides for this.
Basically, all units in SketchUp is internally inches. Work with that - and just ensure you use the Length.to_s method to present the unit to the user. If you want to define some specific length to your calculations, use the helper methods of the Numeric class, sch as:
1000.mm
to define a Length object representing 1000mm. It will be stored as inches, but when you convert it to a string it will appear in the current model's units. -
@slbaumgartner said:
I believe you can find these settings in the OptionsProvider named "UnitsOptions" in the model's OptionsManager. The names in that OP are pretty clear, but you may have to do some experimentation to figure out what the numeric values mean for the key "LengthUnit".
You would rarely need to use those values. Only if you needed to implement a custom unit function that SU doesn't already implement. I did write a library to expand area and volume units - as well as formatting of floats in the user locale: https://github.com/thomthom/SketchUp-Units-and-Locale-Helper
-
If your inputbox dialog uses
length: 0.0.mm
it displays in current units to match the user's settings.
But if you have it as0.0
that is a float and it's always interpreted as 'inches' [the 'base-units'].If you want to default a value, then you can use a test using the model's OptionsManager.
If its 0 or 1 it's imperial ["/'] otherwise it's metric [mm/cm/m].
I'd use something like this pseudo-code:if Sketchup.active_model.options["UnitsOptions"]["LengthUnit"] > 1 ### metric @length=25.mm unless @length else #### imperial 0 or 1 @length==1.inch unless @length end
That way the user gets a sensible starting default value - otherwise if you set it as always
1"
the metric users default looks like25.4mm
!
Using25.mm
converts properly into other metric values like2.5cm
etc...
The 'unless' test only sets a default at startup and the last used value is used thereafter during that session [use@@var
inside a class &@var
inside a module to make it enduring]... -
HI AND THANX TO ALL,
this is going to be a challenge, i will report...
stan -
hi,
thanx for the tips, i read the articles. i will make changes to my system, so that every saved value will be in inches (like basic skp) and i will recalculate to meters for "metric"-world.but i need a tip for the "inch"-world:
do user prefer to input higher values (equivalent > 1,0 m) in feet or inches ?
i would like to make my menues
metric: meters for concrete etc / mm for steel-details
would it be the same for
feet / inches ? or shall everything be input in inches? what is common ?
thanx
stan
-
Normally the user would like to work in current set Units.
To convert numbers to that, you could use this for starters ?
Someone else may come up with better idea, just a rough idea..edit: ah! I missed Thomthoms SketchUp-Units-and-Locale-Helper
#default @su_units = ;inch def set_model_units current_unit = Sketchup.active_model.options["UnitsOptions"]["LengthUnit"] return case current_unit when 0 then @su_units = ;inch when 1 then @su_units = ;feet when 2 then @su_units = ;mm when 3 then @su_units = ;cm when 4 then @su_units = ;m end end # init 1 time in your module set_model_units puts 5.to_l puts (5).send( @su_units )
-
You are [again] over thinking this.
So set your units as say 25.mm if metric, or 1.inch if imperial [testing the model's units - as outlined earlier]... Then there are no odd fractional issues.
Then your inputbox dialog will display its values in whatever units settings the user has already for that model.
For something longer:
18.0"
1.5'
1' 6"
457.2mm
~45.7cm
~0.457m
or more logically when it's found as metric make that default
450mm or 500mm etcSketchUp has the numeric class addition of 'length', so if the user types in 1" he gets some geometry 1" long, but if he types 25mm although it measures as 25mm it is actually remembered in the SketchUp database in inches - all geometry is remembered in inches, it's displayed in the model-units for the convenience of the user.
-
@artmusicstudio said:
thanx for the tips, i read the articles. i will make changes to my system, so that every saved value will be in inches (like basic skp) and i will recalculate to meters for "metric"-world.
You don't really need to recalculate anything. Just keep your units as
Length
objects and letLength.to_s
take care of presenting the unit to the user - as the user prefers it.If you need to specify some fixed values in your calculations, like you want to create a 1x1 meter square, then use the helper methods of the
Numeric
class:width = 1000.mm height = 1000.mm
That will give you
Length
objects that stored that unit in inches. All done for you by the API. -
@jolran said:
Normally the user would like to work in current set Units.
To convert numbers to that, you could use this for starters ?
Someone else may come up with better idea, just a rough idea..edit: ah! I missed Thomthoms SketchUp-Units-and-Locale-Helper
#default > @su_units = ;inch > > def set_model_units > current_unit = Sketchup.active_model.options["UnitsOptions"]["LengthUnit"] > return case current_unit > when 0 then @su_units = ;inch > when 1 then @su_units = ;feet > when 2 then @su_units = ;mm > when 3 then @su_units = ;cm > when 4 then @su_units = ;m > end > end > > # init 1 time in your module > set_model_units > > puts 5.to_l > > puts (5).send( @su_units )
That would be the same as:
puts 5.to_l puts 5.to_s.to_l
There really is few cases when you need to get the model unit and do special work like that. The Ruby API provides most of that - the exception is area and volume, which is why I made that library.
If you find yourself poking into the model unit then pause and consider if you are doing too much work. Most of the time when I see this done the API provides a much shorter and easier way.
This is something that might need another blog post. It keeps coming up.
It's certainly something I want to see improved in the API docs to make it more visible - as these very useful methods are easy to miss. -
Your right!
I wrongly assumed using send instead would be faster, which it isent.
-
I don't know about the speed differences - but I'd not try to optimize that before it's a problem. Less code = less chance of bugs.
-
Heh, it was like this for 100 puts statements in the console.
to_s_to_l: 2.884
using send: 2.915Rookie premature refactoring gone bad
Advertisement