Help modifying onshape featurescript

I’m trying to modify a screw generating featurescript to automatically round up the screw length to the nearest 5.
The feture script link is: Onshape

the existing script uses this for the screw length:
(definition.length = screwData.L * UOM)
I’ve added this to round the length:
( if (definition.length%5!=0)
{
definition.length+=5-(definition%5);
}
)

however, when testing this modification, the feature doesn’t round the length.

any help is appreciated

1 Like

I notice you have definition in the second-last line where you probably intended definition.length.

Another problem is that you cannot “round … to the nearest 5” unless you specify the units that you’re working in. Is UOM intended to be unit of measure here? Should you apply this rounding to screwData.L instead?

In some languages, the modulo (%) operator doesn’t work on non-integer values. I can’t find any FeatureScript documentation that specifically addresses this point.

I would double, round to the nearest whole, then half. Given the context, you may want to ceil() or floor() instead of round.

Feel free to ping me for further assistance

So, length is a ValueWithUnits, which means it’s a number in meters. In FeatureScript, the modulus operator only works with numbers, so you’ll naturally have to convert length to a number first. This can easily be done by dividing length by a unit constant, like inch or millimeter:
println(definition.length / millimeter); // prints the value of length in millimeters
The other thing you should watch out for is issues stemming from floating point precision (decimals). For example,
definition.length = 1 * inch; println(definition.length / inch); // prints 0.99999...
To solve this issue, you can bake a tolerance into your if statement. Onshape has a secret set of tolerances you can use for this (or you can use any arbitrary small number, like 0.00001).

Edit: There’s also an additional nuance that arises from the modulo operator. 0.4999999 modulus 0.5 is 0.499999, which isn’t very good since 0.499999 probably doesn’t need to be rounded. This can be solved by adding a small value to our value initially (so 0.49999 wraps over 0.5), and then using a slightly looser tolerance in the if statement:

const remainder = (definition.length / inch + TOLERANCE.zeroLength) % 0.5;
if (remainder > TOLERANCE.zeroLength * 100 || remainder < -TOLERANCE.zeroLength * 100)
{
println(“Round me!”);
}
else
{
println(“I’m round!”);
}

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.