What's the right way to set unit of model with C API?

Hey, there.
Just described as the title. I wanna set the units as in model info panel, and all the settings are as shown in below image:

7fbcea27e20e4afcaa85d5593dd7f034558c1270%20-%20%E5%89%AF%E6%9C%AC

And I have completed part of the code, but it couldn’t work well:

	SULengthFormatterRef formatter = SU_INVALID;
	SU_CALL(SULengthFormatterCreate(&formatter));
	SU_CALL(SUModelGetLengthFormatter(model, &formatter));
	SU_CALL(SULengthFormatterSetFormat(formatter, SULengthFormatType::SU_LFORMAT_DECIMAL));
	SU_CALL(SULengthFormatterSetUnits(formatter, SULengthUnitType::SU_LUNIT_CENTIMETER));
	SU_CALL(SULengthFormatterSetPrecision(formatter, 6));

Could someone give me a sample or code segment about my issue? Thanks in advance.

Can you elaborate on what didn’t work well? What did you observe?

Yep. In my mind, when I set format, unit, and precision of model’s LengthFormatter just shown as my code segment, the units part in model info panel of the opening .skp file will be amended as the above image. However, after I execute the code with .skp file, the units part in model info panel is not changed, and the model info panel always automatically popup…

My goal:
Format: Decimal
UnitType: cm
Precision:0.000000cm
Enable length snapping: Checked 0.000001cm
Display units format: Checked

Original:
Format: Architecture
UnitType: feet
Precision:1/16"
Enable length snapping: Checked 1/16"
Display units format: Checked

This is not what the documentation says that LengthFormatter objects do …

The doc says:

Length formatters are used to generate formatted strings (optionally with units) from length, area, and volume values. Additionally length formatters can be used to translate a formatted length/area/volume string into a value. Accessors and setters are exposed for some of the key formatting properties, facilitating customization of the formater. In cases when users want the formatter to reflect the properties of a model, SUModelGetLengthFormatter should be used to more efficiently extract/copy the relevant properties from the model to the formatter.


In order to set units, which are part of the model’s options, you’ll need to access the model’s OptionsManager and OptionsProvider collections.

See:

The keyname for the units options provider is: "UnitsOptions".

Within SketchUp, you can paste this Ruby snippet into the Ruby Console to see the current values assigned to the "UnitsOptions" provider’s key value pairs …

model = Sketchup.active_model
manager = model.options
provider = manager["UnitsOptions"]
provider.each { |key, value| puts "#{key} = #{value}" }

You’ll see that the keys are …

# Ordinal values (0 based position in dropdown list)
LengthFormat = 1
LengthUnit = 0
LengthPrecision = 4
AnglePrecision = 1

# Boolean values
LengthSnapEnabled = true
AngleSnapEnabled = true
SuppressUnitsDisplay = false
ForceInchDisplay = false

# Float values
LengthSnapLength = 0.0625
SnapAngle = 15.0

Also you must save the SKP file after setting Units properties of the model object.

1 Like

P.S. - The C++ API is retired. This applies to the newer C API.

Thanks Dan. I have completed the settings with C API according to your suggestion :slight_smile:

And I find the breakdown of options and value types for each options provider in following page: Page Not Found | SketchUp Extension Warehouse

Anyway, appreciate for your time.:gift_heart:

1 Like

That sounds strange… are you saying the Model Info dialog automatically opens without user interaction? After opening a file you created with the C API?

Sorry to resurrect an old thread but I’m having an issue with setting units to meters.

I’ve copied the “WritingToAskpFile” project and have managed to get the UnitsOptions OptionsProvider and set the values of “LengthUnit”/“LengthFormat” to meters/decimal, after creating the model with SUModelCreate. I can open the resulting SKP file and the model units window appears to have the correct settings:

However, my vertices (which are positioned in meters) are still being placed as if they are specified in inches. I would have to multiply my positions by 1/0.0254 to get the model to be the correct size. How can I ensure my vertex positions are read as meters? I’ve tried saving the SKP file after setting these options but that didn’t work. Would opening the empty file after saving it, before adding the geometry, fix the issue? Or is something else required?

    // Create an empty model
    model = SU_INVALID;
    SUModelCreate(&model);

    // set the options of the model, we need decimal meters units
    
    // get the Options Manager
    SUOptionsManagerRef omr;
    SUModelGetOptionsManager(model, &omr);

    // get Options Provider
    SUOptionsProviderRef opr;
    SUOptionsManagerGetOptionsProviderByName(omr, "UnitsOptions", &opr);

    // set LengthUnit to meters
    SUTypedValueRef tvr;
    SUSetInvalid(tvr);
    SUTypedValueCreate(&tvr);
    SUTypedValueSetInt32(tvr, 4);
    SUOptionsProviderSetValue(opr, "LengthUnit", tvr);
    SUTypedValueRelease(&tvr);

    // set LengthFormat to decimal
    SUSetInvalid(tvr);
    SUTypedValueCreate(&tvr);
    SUTypedValueSetInt32(tvr, 0);
    SUOptionsProviderSetValue(opr, "LengthFormat", tvr);
    SUTypedValueRelease(&tvr);

    // then add geometry as in sample project

Thanks,
Si.

I’m afraid, You can’t!
The UnitsOptions only about the user interface, using code you must specify your lengths in inch, since Internally, all lengths in SketchUp are stored in inches.

I do not know so much about C API but in Ruby API you can read more e.g. here:

Class: Numeric this is about how to convert numeric to :
Class: Length

Thanks for the quick answer, I guess I will just have to convert the numbers myself!

For setting up the model unit properties, you should use the enumerated values defined in:
SketchUp C API: SketchUpAPI/length_formatter.h File Reference

You can use SUModelGetLengthFormatter to retrieve the model’s SULengthFormatter,
… and then use string arguments like "1m" with SULengthFormatterParseString() to get the internal inch double values to pass into geometry functions.

Likely write a wrapper function (macro?) to easily use these API functions to return inch values.

Thanks, I’ll change my code to use the enums. I’m writing a Sketchup format exporter for Unity so I know all my incoming geometry is in meters, it’s easier for me to just multiply everything by 1/0.0254 to get the representation in inches.

I suppose so, as it’s likely that parse function would do this anyway and it would just slow things down going through a numeric String.

I am a bit surprised that the C API did not predefine numeric conversion macros.