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.
Import sketch/body using FS?
eric_schimelpfenig
Member Posts: 75 EDU
I'm just starting out learning FeatureScript (again) and I did the first tutorial:
https://cad.onshape.com/FsDoc/tutorials/create-a-slot-feature.html
That's making sense to me so far, and then I get to the second part of the tutorial where they add some "bumps" to the inside of the slots:
https://cad.onshape.com/FsDoc/tutorials/add-sketch-geometry.html
I get what's happening here, you're essentially coding a sketch.
What I'm after is essentially learning how to easily create a lot of furniture/plywood joints as feature scripts, things like this:
The idea is to make all of these kinds of furniture fasteners so I can make creating furniture easier. So you're wondering.. where's the question?
Well, from reading this tutorial it definitely seems like it's possible to "code" a sketch that will create the above pockets, but I'm wondering if there's a way that I can just import a sketch that I've already created? This way, the featurescript itself would be very simple, and if I wanted to update the shape/size of the pocket it would be almost no coding. That would also allow non coders to be able to update the shape of a joint.
So... Could I bring in a sketch that I've create using featurescript, or perhaps even a surface or a body, extrude and subtract it from an existing body in a model?
https://cad.onshape.com/FsDoc/tutorials/create-a-slot-feature.html
That's making sense to me so far, and then I get to the second part of the tutorial where they add some "bumps" to the inside of the slots:
https://cad.onshape.com/FsDoc/tutorials/add-sketch-geometry.html
I get what's happening here, you're essentially coding a sketch.
What I'm after is essentially learning how to easily create a lot of furniture/plywood joints as feature scripts, things like this:
The idea is to make all of these kinds of furniture fasteners so I can make creating furniture easier. So you're wondering.. where's the question?
Well, from reading this tutorial it definitely seems like it's possible to "code" a sketch that will create the above pockets, but I'm wondering if there's a way that I can just import a sketch that I've already created? This way, the featurescript itself would be very simple, and if I wanted to update the shape/size of the pocket it would be almost no coding. That would also allow non coders to be able to update the shape of a joint.
So... Could I bring in a sketch that I've create using featurescript, or perhaps even a surface or a body, extrude and subtract it from an existing body in a model?
0
Comments
You're definitely on the right track. That said, I'm not sure how you would go about implementing the Derive and Boolean operations in the featurescript.
Check out this page documenting workflows for imports, including Part Studio imports: https://cad.onshape.com/FsDoc/imports.html
As you can see there, you could use the instantiator with function calls like
This would place the all the sketch bodies from some imported Part Studio into the feature's Part Studio, at the desired location.
@kevin_o_toole_1
Thank you very much for that example. I gave it a shot, but I wasn't able to get it to work because I'm really new to FS and coding in general. Here's what I tried:
https://cad.onshape.com/documents/df9fc898ac3275697989261f/w/bdd0739a147106b6ab1dc4b1/e/b9b3376923d80f285da95cbe
I see the error messages in in the feature studio but I don't understand them...
What I'm trying to accomplish with this example is very simply to get a sketch dropped into the drawing using the FS on the line that I select. Later I'll try and add the complexity of extruding it, subtracting, etc.
The two problems in your feature studio:
In the import at the top, you need to add the namespace that you want to reference later.
The second, smaller problem right now is that in this map:
You are missing a comma at the end of the "partQuery" line.
(Also worth mentioning that after you fix these two problems, it will complain because you have not defined a cSysForSketch, for now you could replace the transform with something like identityTransform(), and then worry about taking a mate connector for placement later)
Another problem, it looks like you have done:
As mentioned in the previous comment, the namespace is what is going to link the instantiate to what it is supposed to build. This line is just giving the instantiator an id that it will use to build its geometry (similar to opExtrude(context, id + "extrude1", { ... }) ), so you do literally want to put `id + "instantiator"` there.
The instantiator documentation has a nice example of how to do the whole thing:
https://cad.onshape.com/FsDoc/library.html#module-instantiator.fs
You can ignore the bit about configurations, unless you want to have the part studio you are importing expose a configuration
https://cad.onshape.com/documents/df9fc898ac3275697989261f/w/bdd0739a147106b6ab1dc4b1/e/b9b3376923d80f285da95cbe
But I'm not sure I fully understand...
If you're up for it feel free to explain this like I'm a complete dummy...
So "namespace" Is this something throwing the whole part studio a "bucket" that I can rummage through later with my code to pull out bits that I need? To put another way: I could import a whole part studio and put it into a "bucket" and then later say "go into THAT bucket and get me this solid, sketch or whatever?
Your comment above:
So as you can see in my code (link at top) I got it to "work" as in there are no errors being reported in my FS, but it doesn't work in my model...
Sorry if these questions are really stupid
That's a good way of looking at it! More technically, it is just a way to give that import a name so that you can refer to it later, otherwise, there is no way to say "get stuff from THAT part studio", especially if you are importing a few different part studios. The way that you then start to filter down is using queries (see the `partQuery` parameter of `addInstance(...)`)
The current failure for your feature is as follows:
If you click on the top line there (20:27 Feature Studio 2...), it will bring you to the line that is failing. The bad line is:
For now, just do:
toWorld takes a coordinate system, and you are passing in the feature's Id.
More info on Ids here: https://cad.onshape.com/FsDoc/library.html#Id
https://cad.onshape.com/documents/df9fc898ac3275697989261f/v/3aaba8f336bb7e8973c60bc6/e/b9b3376923d80f285da95cbe
So, I checked out the ID link on the documentation, and it didn't make any sense to me.
So I assume what I've successfully done here is import the sketch, and just dropped it at the origin. What I'd like to do is place it on a point or a line. So imagine that on the larger rectangle I had a few lines facing inwards I'd like to be able to select and have the sketch "facing in"... So I guess "normal" to the line?
So here's what I'd like to learn: How do I have to think about placing stuff?
There's a coordinate system for the part studio as a whole, is there also a coordinate system for each individual sketch or body/part?
Assuming that is correct, my guess is that I have to somehow get the coordinate system for a particular sketch, or a line/point that I select and how that's related to the sketch that it's in?
Or maybe it's simpler, maybe all I need is the location of the point or line I want the imported sketch on?
Then from there I have to somehow place my imported sketch on whatever coordinate I collect... And then use that information to import and place my sketch?
It is a bit simpler than you think. By default (i.e. using the identity transform), that sketch is going to come into the Part Studio at exactly the same place it is in the original part studio. By changing the transform, you can move where it comes in. So if you were to do the following, it would come in one inch to the right of where it is in the original part studio:
To allow for generic placement by the end-user, I would take a mate connector as input:
(Note that the end-user does not need to make a mate connector in advance, just doing this will allow them to make an implicit mate connector on-the-fly while working on your custom feature)
And then use that mate connector to place the sketch:
So I want to take this a bit further:
1: I want users to be able to insert multiple sketches/parts/whatever I want from the inserted part studio
2: I want all of the sketches to "point" into the rectangle/outer shape (shape will always be closed, but might not be a rectangle)
So basically if I had a shape like this:
So how would I do this?
My guess is that the first thing is to change the pre-condition to "line" and allow multiple picks?
And then for the transform I somehow need to figure out where the line intersects with the outer shape? And then if I have that figured out, somehow always guarantee that the part studio is "lined up" the right way?
I noodled with it a bit, but I'm not sure how to approach the problem...
PS this has been a great help so far!
PS this is the code I tried to make:
I think the most reliable thing to do here really is to just allow mate connector selections, and then respect the position and orientation of the mate connector (since the mate connector is not just a location, it fully defines a coordinate system that the end user can edit as they wish)
If you really do want your feature to be smarter than that, I would probably suggest having your user select a point, rather than a line, and then just having the sketch point "inwards" perpendicularly from the edge direction at that point. But there may be a desired degree of freedom that the sketch does not always point straight inward, and could point "inward" at any angle that the line is?
If you pick an approach from:
1. just use mate connectors
2. pick a point and point "straight inward"
3. pick a line and point "inward" along the line
I can show you how to do the geometry querying and math to get the sketch transform.
While I agree that it's a pretty simple way to do it, when you're placing a ton of these (which is how I intend for this to work) I think it will get really fidgety.
Here's a use case I'm thinking about:
Here I don't think it puts too much work on the user to get them to draw a bunch of lines pointing inward, and as you can see many of those lines are coming off of non straight edges.
If they had to do mate connectors here it'd be a lot of clicking..
I think if I get what you're saying here: You're saying that they'd pick a base point, so a point touching the outer edge of the shape, and then another point, or a line indicating the way they want the feature to "face"?
if I get that, you're talking about your option 3?
Regarding:
In the image you have posted above, all of the notches are pointing directly perpendicular to the tangent direction of the edge at the selected point. At any given point along your edge, the edge has a tangent line defining the direction it is currently moving in. Within the plane of the face, there are two perpendicular directions to that direction: "straight out" and "straight in". Here is an image that may make it more clear:
What I am trying to say here is that if you always want your imported sketches to just point "straight in", then you could just have the user select one point per sketch, and use math the determine the "straight in" direction.
If you do not expect that the user would want the sketches to always face "straight in", and want to expose a degree of freedom that the sketch could be pointing any direction along the 180 degrees of available "inward" directions, you could expose a line selection to let your end-user fully define the exact direction they want the imported sketch to face.
The problem with requiring the user to select lines is that if the most common use case is that the sketches should be "straight in", then requiring the user to draw a bunch of lines that face perfectly "straight in" will be tedious and burdensome for the user, when a point selection and a smarter feature would not require them to draw the lines in the perfectly correct direction.
Of course, you could always make your feature accept points AND lines, and face "straight in" for each point that is selected, and face the line direction for each line that is selected.
Right now I can get a sketch from another part studio imported and "transformed" off of the origin.
What I really want to do is have it at a point on a line. Eventually I'll have it arrayed out from that point. This will let my users define the origin position easily by dropping points in sketches.
Where I got a little lost is the variables. As I understand it you have to start a FS with importing stuff, like the FS version and the model you're working with, then you have to "ask" the users questions, in my case this would be the face and an edge.
Then you collect those faces and edges into variables
And then you can use those collected variables to then do something, like place my sketch, transform it along a line, etc.
As you can see from my script I tried variables but I failed.
https://cad.onshape.com/documents/df9fc898ac3275697989261f/v/d1cc045edbd9846e669b6252/e/b5c3f6e857618355c3a380f3
Assuming my strategy is right, I don't really understand how to start thinking about transforming my sketch onto a body...The only programing experience I have doing this sort of thing is doing this in SketchUp. There each "component" or part has it's own coordinate system and you just move parts off of that. Here I'm learning that it's quite different... I'm just fuzzy as to in what way it's different...
Your use of definition parameters here looks fine. If you want to check that you are using them correctly, you could do something like debug(context, definion.pickedge), and then when you have your feature dialog open, that edge will show up highlighted in red.
You could also do something like println(definition.distfromstart) and that will print to the FeatureScript console, to make sure that your length is making it through correctly.
The issue here is with the use of evFaceNormalAtEdge. There are two problems:
Broader suggestions on how to procceed:
Barring those suggestions, with just the variables you have set up, this is how I would get the face normal at a specific distance along the edge:
As mentioned before, this example is without taking any of my suggestions into account, so if you decide that you would like some examples of how to do things with those suggestions in mind, I would be happy to provide those suggestions too.
Happy coding!
P.S. Maybe worth noting that I did not actually run the example code that I wrote, so there may be minor typos that make it fail. The point was more to show what calls would be used to get the information you seek
Ok, let's back up for a second, I think I get what you're saying here, but I'm realizing now that this is a little too much for me to get my head around right now.. That must be why you were trying to push me to use mate connectors!
The mate connectors do require more input from the user, but less coding it seems.
So I walked back the complexity of what I'm trying to do back to this:
https://cad.onshape.com/documents/df9fc898ac3275697989261f/v/6dbeab89eb8a51eaef4306b4/e/b9b3376923d80f285da95cbe
All this does is drop the sketch in at a point where the mate connector is. The code is simple and I understand it (mostly). I think I should just build off of here one little bit at a time.
I tried "opextrude" on my sketch and I failed to make even that work which to me really says that I should get that out of the way before I try anything more complex.
So here's where I'm at thinking wise:
I had to "import" the sketch at the beginning of the code
Then I had to ask the user stuff (placement, etc)
Then I had to "instantiate" the sketch, which I understand to be "take the batter that's on deck and bring them to the plate" The "plate" being the transform I did, which was to transform it to the location of the mate connector the user picked.
To do an extrude I need a face, or a close loop of lines to start extruding. I struggled to get the face fed into the opextrude command, and my only guess is that it's similar to "instantiate" in that I need to define the face, or "put it on deck" as it were?
If I'm right is that something like "var this face from this sketch is now 'faceiwanttoexude.definition'?
And then in the opextrue I can say the entity that I want to extrude is faceiwanttoexude.definition?
You won't need to mess around with the definition to get your opExtrude working, the definition is just the way that all of the user inputs are exposed to the body of your custom feature.
Continuing the baseball metaphor, I would almost think of the instantiator as trading a player from another team. You know there is another team (part studio) out there, and you want a player from that team (the sketch). Before you call `instantiate()`, you don't have that player, but after, you do. You can make them into an outfielder or a pitcher or shortstop by changing the transform. Because we have cloning technology, the other team doesn't lose the player, and you can clone as many of them as you want
Before you call instantiate, there is the sketch does not exist, and after you call instantiate, the sketch exists in the part studio. Once it exists, you can query for it. Querying is the biggest learning curve of FeatureScript, so don't be discouraged if it takes a while to click. Here is what to do:
A few reasons why your code wasn't working:
will do exactly the same thing as:
The former just uses a variable (in this case a constant) to give a name to a commonly used piece of data, so that it is obvious that it is being used in more than one spot.
Ok, let me go through this line by line:
(doc I'm working on)
https://cad.onshape.com/documents/df9fc898ac3275697989261f/w/bdd0739a147106b6ab1dc4b1/e/b9b3376923d80f285da95cbe
See questions in bold
Ok, this confuses me... "const" is "constant" which is basically something I can store. I get that, but how can I store an instantiated thing if it hasn't been instantiated yet (because that's happening in the next section). And that aside what is this line actually saying? Is the name of the thing I'm storing (the name I'll reference later) right after "const" or is it the name that's in the quotation marks? I'm guessing by the later debug line below that asks for "instantiatorId" that the "name" is the thing right after "const"
As I said above, my understanding is that "const" stores stuff, and at this point I've already stored the instiantiatorID, so why am I doing it again here? If instantiate clones a thing (in this case a sketch) from one doc to another, isn't it already saved by way of instantiating it?
I was never able to get the extrude to work, which I though was going to be easy since I got the face to debug... However as you can see I'm not totally clear on how I got there so I know I'm missing something really obvious...
I'll keep hacking around at this.. And look, I really really appreciate this hand holding.
https://cad.onshape.com/documents/df9fc898ac3275697989261f/w/bdd0739a147106b6ab1dc4b1/e/1ab937e72bf67d36ad89dbb2<br>
I clearly don't know how to query faces
also you will have to define a direction for the opExtrude since the face is not a sketch
I tried it without the redundant query and I couldn't get the extrude to work:
The face debugs (I can see it in red) but the extrude never happens...
I did run through that tutorial, and maybe this is just me but it didn't really click for me. The only programming experience I have using BASIC back in the day, and now the programming I do is in G Code, which is very similar, and like BASIC very linear, as in things happen in order. I can hack around and do basic things in Arduino too, but only on a limited basis. The tutorial, while good isn't a challenge. It's just a walkthrough. This is why I'm trying to setup a challenge for myself so I can really get my head around how FS works.
FS seems like it's a very different way of thinking when compared to coding in BASIC or G Code. I had a similar thing happen years ago when I decided to learn Fusion, and then Onshape... Perviously I had extensively used AutoCAD and SketchUp, both direct, non timeline based modelers. Moving to Fusion/Onshape was really hard for me, but one day/model it all came together and I got it. I'm hoping that I can get there with FS, I just need to break my thought process again
I'm good at Onshape modeling, and I'm not at a point where the complexity of my models really demands automating repetitive tasks so that's why I'm trying to learn this.
Firstly, as Neil said, in your example you should just be able to do:
To answer your confusion above:
const instantiatorId = id + "instantiate"; // Store this so you can use it later
This is not storing the faces. It is storing an id, or an "identifier" which you will use both to create your faces, and then to find them later.
const instantiator = newInstantiator(instantiatorId);
You are not storing the `instantiatorId` again here. You are storing the instantiator itself, the object that is responsible for doing the work to get the sketch into your part studio. Notice that you are passing the `instantiatorId` into the new instantiator. What you are saying here is "create a new instantiator, and give it an identifier (`instantiatorId` which is equal to `id + "instantiate"`) that can later be used to find all of the things that this instantiator creates"
As you mentioned above, you get this code already. The important thing to see is that you are passing `instantiator` into both of the calls. So what you are saying first is "add this specific instance to the instantiator" (you could do this many times if you wanted many sketches). Then finally you are saying "let the instantiator do all the work to bring the instances I identified with `addInstance` into the part studio". It is not until this point (calling `instantiate` on the `instantiator`) that anything new is added to your part studio.
const sketchFaces = qCreatedBy(instantiatorId, EntityType.FACE);
I want to return to my simple example above, in attempt to show how there is nothing special about variables. In this contrived example, I will do an extrude, and then immediately delete the body created by that extrude:
The two pieces of code above to do exactly the same thing. Setting some variables along the way just helps us organize the code into logical segments, separating things out so that we are just doing one thing at a time.
Additionally, setting variables can ensure that no mistakes are made. By doing `const extrudeId = id + "extrude"`, and then using `extrudeId` in both spots where it is used ensures that both of the spots are definitely using the same identifier. In the second example I could easily make a typo, so that the first time I put `id + "extrude"` and the second time I accidentally type `id + "extrudee"`, which would then cause opDeleteBodies to fail because the query does not specify any bodies, because `id + "extrudee"` was not an identifier used to create anything.
The point is to take a piece of data, and give it a name so it's clear what that data is supposed to represent, and the data can be used in multiple spots later without having to recreate the data every time.
https://en.wikipedia.org/wiki/Variable_(computer_science)
This does not work because you are just telling the system to look for things created by the identifier "definition.fte". Putting it in quotes like this just makes it a literal string, with the text "definition.fte", this does not have any link back to the actual definition itself.
Doing something like `definition.fte` looks inside the `definition` map for the the field called `"fte"`. Doing something like `"definition.fte"` just makes a string containing that text, and does not have anything to do with the `definition` variable itself.
The identifier that creates the entities that are selected by the user is not available to you at all; you will not be able to/will not need to use `qCreatedBy` to find entities that are manually selected by the user because the system just passes you an appropriate query for those entities in the form of `definition.fte`. The point of qCreatedBy is to find entities that were created during the execution of your feature, which you have access to the id of (since you are the one who created and specified that id as part of the call that creates the entities)
If you did want to store definition.fte for use later under a simpler name, the right thing to do would just be:
const theface = definition.fte;
I think I'm getting the variables a bit more, I'm still fuzzy on some parts though, so this:
const sketchstorage = id + "instantiate"; // Store this so you can use it later
We're saying here "const sketchstorage..." this is essentially making an empty "file" into which we'll put stuff later. then we get to this "=id..." so I'm guessing we need to say that the variable "sketchstorage" is an "ID"? but then why the " + "instantiate""? Is the word instantiate there because we're saying we're going to put something into "sketchstorage" that is from an instantiator? or is the stuff in the quotations any text we want? (if so that's very confusing!)
(note that I changed the variable name because I had too many version of things that had "instantiate" on them and my brain was hurting)
const instantiator = newInstantiator(sketchstorage);
This one is starting to make a little more sense too, so "const instantiator" is making another variable into which we put the actual instantiator which is "newInstantiator" and whatever we get from that we store in "sketchstorage" which I declared above.
Now that we have a "place" to store what the instantiator is getting we have to "do the thing" which in this case is querying for the thing we want. So we start with a filter that catches all sketches, then bodies (which doesn't make sense, sketches aren't bodies but I'll go with it) then from the third level of the filter we ask for SketchObjects.YES. The result is one sketch because there is only one sketch in that part studio we're coming from.
The transform line puts it on the mate connector we got from the user that has a variable of "definition.placement"
Lastly we do this:
instantiate(context, instantiator);
Which is DO IT (but only do it in the object instiantator, don't "do it" anywhere else)
Ok, so on to the extrude which is where I had a sliver of luck. First the code that did work:
"direction" with that vector setup worked, I'm guessing because it's about as basic as it gets. So then I tried following your advice about using evPlane. I falied.
I tried a few things, one in the commented out line above, and something like this:
The thinking here was that it says in the help popup for EV plane that you can use a mate connector, and we already asked the user for one so I thought I'd try that.
I also tried this:
The logic there being that if this worked:
debug(context, sketchFaces);
Why couldn't I just extrude using the same method? Obviously not
I don't think that thinking of the id as a "file into which we'll put stuff into later" is a great analogy. The id passed into an operation is more like a label that you are using to identify all the changes made by that operation. You can think of the pipeline here as:
- Choose an id
- Tell the system to do something, using that id as a label for all those changes that are going to be made
- Ask the system what changes were made with that label
So it's not as if the id is some kind of magic box that your sketch is being put into. Really your sketch is just being put into the Part Studio, but it's as if it has a sticker on it that says "I was created using this identifier: ..."Let's address some of the specific confusions you've laid out:
To clear up what the `id + "..."` part means, let's look at what a blank custom feature looks like:
The `(context is Context, id is Id, definition is map)` are the three variables that are being passed to your feature by the system.
- `context` represents the state of the part studio. It is what you are changing when you instantiate with the instantiator, perform an extrude, or do anything else that changes the state of the part studio. It is also the thing that you ask questions of when running things like evOwnerSketchPlane or evPlane.
- `id` is the feature id. Each top level feature in the feature list has its own id in the system. If you run `println(id)`, you will see that the feature id is just a randomly generated string, like "F_ajkfdhasjdkfhas". I will come back to more description on this below.
- `definition` is the set of parameters specified by the user in the feature dialog.
The reason I point this out is to address the confusion of what it means to do `id + "someAdditionalString"`. The `id` piece is important; it contains the root feature id of the entire feature, which allows the system to know which geometric entities were created and edited by which features in the feature list. Doing `id + "someAdditionalString"` is a way of creating a more specific label, saying "the entities I am about to create belong to this feature as a whole, but more specifically to the 'someAdditionalString' part of the feature".An example that may help your understanding:
Here we see that using `+` on an id creates a more specific label the is a subset of the label on the left hand side of the `+` sign.
All the entities created by the whole feature will have the label of `id`. All the entities created by the first two extrudes still have the label `id`, but also have the label `id + "groupA"`, and only entities from the second extrude has the label `id + "groupA" + "2"`, but of course those extruded entities also have the labels `id + "groupA"` and just `id`, because the ids exist in the hierarchy I am describing.
The code above is also identical to:
I made a working example of this using the opSphere call here: https://cad.onshape.com/documents/0c9e3ab2635f23cc5a740e99/w/472a9f18fee23f41be91ceb9/e/a57f1ca04f7ed0c041fb1dae
To be continued... There are a few more things I want to answer, but I think this comment covers ids nicely.
It would be useful to screenshot the error messages that appear when the extrude (or anything else) does not work, and include them in your comment, so that I can explain what those errors mean. For example, if I do either of the direction calls that you have above, the error message looks like:
Which explains that opExtrude was expecting a Vector, but received a Plane instead. Clicking on the second line in the call stack (the line that says "35:9 Feature Studio 1"), will even bring you to the call that is failing in your Feature Studio.
https://cad.onshape.com/documents/df9fc898ac3275697989261f/w/bdd0739a147106b6ab1dc4b1/e/5e412733a40ae3e1296e5bb5
I tried as much as possible to figure this out by not looking at my previous attempt, which is why you'll see some of the names of things changed. I really wanted to avoid the temptation of copy/pasting stuff without understanding what it's doing.
I got the code to (compile?) with no errors, but it doesn't work in my part studio:
That error message is... greek to me...
I've got to be missing something dumb... I re-read the previous posts several times and if the answer is there (I'm sure it is) I'm just not seeing it...
The error message is saying that there should either be no transform (
definition.transform == undefined
) or the transform field should be aTransform
[1] (definition.transform is Transform
). At the moment, you are providing it with aVector
[2], which doesn't match either.[1]: Transform
[2]: Vector
In order to turn your vector into a
Transform
, you can use the functiontransform(translation is Vector)
[3].E.g:
"transform": transform(vector(0, 0, 1)),
[3]: transform(Vector)
IR for AS/NZS 1100