Linear Mass Custom Property via FeatureScript

graeme_anderson
graeme_anderson Member Posts: 12 PRO
I have successfully created a few lines of FeatureScript to take the volume of a 100mm long extrusion and output the volume per metre (including changing the units) using evVolume.

I want to do the same thing with mass per metre, but it appears evApproximateMassProperties requires a hard-called density, even though the part has a material assigned. I suspect this is why my FeatureScript compiles correctly, but the Custom Property it is linked to returns "computation failed."

FeatureScript code:

annotation { "Property Function Name" : "computeLinearMass" }
export const computeMass = defineComputedPartProperty(function(context is Context, part is Query, definition is map) returns string
    {
        var linearMass = evApproximateMassProperties(context, { "entities" : part, "density" : 1 * kilogram / meter ^ 3 });
        linearMass = toString(roundToPrecision((linearMass / 100), 3)) ~ "g/m"; //convert part mass in kg to gram per linear metre, extrusion only, part must be modelled 100mm long
        return linearMass;
});
Have anyone found a way around this limitation?



Comments

  • ilya_baran
    ilya_baran Onshape Employees, Developers, HDM Posts: 1,274 image
    edited May 2023
    You can debug custom properties by making a part studio with parts in the same workspace -- and then a custom table will appear with rows for the parts and a column for the property.  At that point, you'll see errors with stack traces, and you can monitor/profile as with other custom tables.

    Trying it shows that there was a units error, as well as evApproximateMassProperties returning several things besides mass.  A working version is:
    annotation { "Property Function Name" : "computeLinearMass" }
    export const computeMass = defineComputedPartProperty(function(context is Context, part is Query, definition is map) returns string
        {
            var linearMass = evApproximateMassProperties(context, { "entities" : part, "density" : 1 * kilogram / meter ^ 3 }).mass;
            linearMass = toString(roundToPrecision((linearMass / (100 * millimeter)) / (gram / millimeter), 3)) ~ "g/m"; //convert part mass in kg to gram per linear metre, extrusion only, part must be modelled 100mm long
            return linearMass;
    });

    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • graeme_anderson
    graeme_anderson Member Posts: 12 PRO
    edited May 2023
    Thanks for taking the time to reply @ilya_baran, much appreciated.

    If I wanted to keep the kg part of the units, is it as easy as changing the "gram" to "kg"?

    Edit: Looking at the output, I'm not sure the conversion from kg to gram is working properly. I have a 100mm long part that is 0.138kg. The output of the code is returning 0.001 g/m when it should be 1380 g/m.

  • ilya_baran
    ilya_baran Onshape Employees, Developers, HDM Posts: 1,274 image
    Yeah, except in FeatureScript you have to use kilogram, not kg.  Also I just saw that  in my example, I'm providing gram/millimeter instead of gram/meter -- that should be corrected.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • graeme_anderson
    graeme_anderson Member Posts: 12 PRO
    Further to my edit above, how "approximate" is evApproximateMassProperties?

  • ilya_baran
    ilya_baran Onshape Employees, Developers, HDM Posts: 1,274 image
    If the shape you're extruding is lines and arcs, it should be close to within floating point precision.  If you have splines, it should still be very close -- you can try measuring manually and see the bounds, it's a similar precision.  It's more approximate for more complex shapes and if you try to build using the value.  For your use case, I think it's the right thing.
    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • graeme_anderson
    graeme_anderson Member Posts: 12 PRO
    edited May 2023
    I've updated the code following your advice, but the output still doesn't match the manual check.

    annotation { "Property Function Name" : "computeLinearMass" }
    export const computeMass = defineComputedPartProperty(function(context is Context, part is Query, definition is map) returns string
        {
            var linearMass = evApproximateMassProperties(context, { "entities" : part, "density" : 1 * kilogram / meter ^ 3 }).mass;
            linearMass = toString(roundToPrecision((linearMass / (100 * millimeter)) / (gram / meter), 4)) ~ " g/m"; //convert part mass in kg to gram per linear metre, extrusion only, part must be modelled 100mm long from the Front Plane
            return linearMass;
    });

    Output should be 1380 g/m not 0.9 g/m. I think there is a problem converting from kilogram to gram or from meter to millimeter and I'm not sure which.






  • ilya_baran
    ilya_baran Onshape Employees, Developers, HDM Posts: 1,274 image
    edited May 2023
    Ah, you're passing in 1kg/m^3 for the density.  Try:
    var material = getProperty(context, { "entity" : part, "propertyType" : PropertyType.MATERIAL });
    var linearMass = evApproximateMassProperties(context, { "entities" : part, "density" : material.density }).mass;


    Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc
  • graeme_anderson
    graeme_anderson Member Posts: 12 PRO
    Problem solved! Thanks again @ilya_baran, much appreciated.