Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- Be respectful, on topic and if you see a problem, Flag it.
If you would like to contact our Community Manager personally, feel free to send a private message or an email.
How do you bring numbers in as a precondition
ron_moreland
Member Posts: 90 ✭✭
I want to bring a simple unitless number in as a multiplier. I also want to restrict the range and assign a default value.
annotation { "Name" : "Scale" }
isLength(definition.scale, { (inch) : [1, 1.059463, 1.07463] } as LengthBoundSpec);this works, but I think I want this:annotation { "Name" : "Scale" }
isLength(definition.scale, { (unitless) : [1, 1.059463, 1.07463] } as LengthBoundSpec);which doesn't. Should I bring it in as an "inch" then divide by"inch" later?
Tagged:
0
Best Answer
-
ilya_baran
Onshape Employees, Developers, HDM Posts: 1,248
annotation { "Name" : "My Number" }isReal(definition.myCount, { (unitless) : [0, 1, 6] } as RealBoundSpec);Ilya Baran \ VP, Architecture and FeatureScript \ Onshape Inc5
Answers
Thanks
EXAMPLE
Everything is queries. Not an array in sight, except "sides[0]", and what the heck is it doing there? For someone with my background, it's very hard to get my head around. It's difficult to know if I'm passing the correct parameters and hard to decipher what came back.
Here's another example. I want to use "canBePlane()". Here's the documentation:
canBePlane (value) predicate
Typecheck for
PlaneWhat is "value"? I think I've passed it a plane, or a planar face, but it always fails. Should it be a query? a map? either?
I know featurescript is incredibly powerful, but where I am, I spend most of my time trying to determine if what I'm asking for and getting are correct. Very little time is spent on data manipulation.
I saw your discussions in this thread and the other thread, and thought it may be useful to clear up some stuff about types in FeatureScript.
For every type <X> in FeatureScript there is a canBe<X>() method, which is the typecheck for that type. You should never need to actually call the canBe<X>() method, its just a construction for declaring types.
Some examples of types in FeatureScript:
- Query
- Vector
- Matrix
- Transform
- Line
- Plane
- BoundingBox
- ValueWithUnits (length, angle, volume, etc)
Here's an example:var planeQuery = qNthElement(qGeometry(qEverything(EntityType.FACE), GeometryType.PLANE), 0); var isPlane1 = planeQuery is Plane; // false var isQuery1 = planeQuery is Query; // true var planeEvaluated = evPlane(context, { "face" : planeQuery }); var isPlane2 = planeEvaluated is Plane; // true var isQuery2 = planeEvaluated is Query; // falseIf you look in the documentation, you'll see that evPlane returns a 'Plane':https://cad.onshape.com/FsDoc/library.html#evPlane-Context-map
And that a 'Plane' is just a special map that contains the mathematical information about a plane in 3D space:
https://cad.onshape.com/FsDoc/library.html#Plane
You can use these 'is <X>' predicates to check whether a variable that you have is of the type that you expect, but you can't use 'is Line' to check if a 'Query' references a linear edge (because 'Query is Query').
You could use 'evLine()' to both check if the edge is linear, and find out the mathematical information about the line:
var line = try silent(evLine(context, { "edge" : someQuery })); if (line == undefined) { // This could indicate lots of things. Maybe the query doesn't reference one entity, // or the one entity it references is not an edge, or not a linear edge. throw regenError("someQuery was not a line"); } else { var recievedLineDefinition = line is Line; // true var origin = line.origin; var direction = line.direction; }https://cad.onshape.com/FsDoc/library.html#evLine-Context-maphttps://cad.onshape.com/FsDoc/library.html#Line
Or, you could just make sure the user passes linear edges into your feature:
annotation { "Feature Type Name" : "Evaluate line" } export const myFeature = defineFeature(function(context is Context, id is Id, definition is map) precondition { annotation { "Name" : "Line", "Filter" : GeometryType.LINE, "MaxNumberOfPicks" : 1 } definition.lineQuery is Query; } { var lineDefinition = evLine(context, { "edge" : definition.lineQuery }); });Hope this isn't just adding confusion. Let us know if you still have questions.
Thanks.
"this is a string" as Plane
If you monitor a part studio that uses that feature, you'll be warned about a typecheck failure.
I may be misunderstanding your question, but 'varX is typeX' cannot be used to check geometry types of queries, it can only be used to check what type a FeatureScript variable is.
To answer the second part of your question in detail, you can't have 'evX() is X' without declaring 'canBeX()'.
Here's an example:
export predicate canBeVehicle(value) { value is map; value.numWheels is number; value.color is Color; } export type Vehicle typecheck canBeVehicle; export function vehicle(numWheels is number, color is Color) { return { "numWheels" : numWheels, "color" : color } as Vehicle; } annotation { "Feature Type Name" : "Make vehicles" } export const myFeature = defineFeature(function(context is Context, id is Id, definition is map) precondition { } { // These variables both have type: Vehicle var redCar = vehicle(4, color(1, 0, 0)); var blueMotorcycle = vehicle(2, color(0, 0, 1)); });You fundamentally can't have 'Vehicle's without 'canBeVehicle()'. You can now check if a variable is a Vehicle with 'someVariable is Vehicle', but only because you wrote out its definition using the 'canBe' predicate.
'canBeVehicle()' is a construction of FeatureScript, and is used internally by the system to make sure that things declared 'as Vehicle' actually qualify for this role.
Another example:
var fakeVehicle = { "numWheels" : 5, "color" : color(0, 0, 0) }; var check1 = fakeVehicle is Vehicle; // false. fakeVehicle is a map, it was never declared to be a Vehicle. var check2 = canBeVehicle(fakeVehicle); // true. fakeVehicle follows all the rules of what a vehicle should be. var vehicle = fakeVehicle as Vehicle; // doesn't fail because canBeVehicle() passes. var check3 = vehicle is Vehicle; // true. vehicle was declared as a Vehicle.In short: you should never need to call 'canBeX()' yourself. It's used by the system to declare variable types.
Coming full circle: It's not really useful to check whether something 'is Plane' or 'is Line' or 'canBePlane' or 'canBeLine'. If you end up with something of these variable types, you'll already know that you have them (because you would have had to call 'evPlane()' or 'evLine()' or similar to get those). To check if some piece of geometry is a plane, you can do:
var isPlane = try silent(evPlane(context, { "face" : faceQuery })) != undefined; --- or --- var queryContainsPlane = size(evaluateQuery(context, qGeometry(someQuery, GeometryType.PLANE))) != 0;