Description
Key Learnings
- Learn about building a construction history in Bifrost to turn a simple object (e.g., a cube) into a complete building with lots of detail.
- Learn how to use complex Bifrost compounds together with fundamental nodes to randomize polygon objects in order to create a natural look.
- Learn how to assign materials to Bifrost objects for realistic rendering.
Speakers
- Roland ReyerRoland Reyer has started in 1992 as an Application Engineer at Wavefront Technologies GmbH in Germany. He became an industry expert for the entire M&E product portfolio of Wavefront Technologies, later Alias | Wavefront, Alias and finally Autodesk. In his role as an application specialist he tested, showcased and trained Maya from its very first version. With over 25 years product and market experience, Roland now works at Autodesk as a Solutions Engineer for Maya, Arnold, Shotgun, Mudbox and Motionbuilder throughout Europe.
- John Paul GiancarloJohn Paul Giancarlo. JP is a 3D expert, who will expand our team by bringing his extensive knowledge as Visual Effects TD and Technical Lighting Artist with him. He brings wide-ranging knowledge of Shotgun, Arnold, Maya, MEL, 3dsMax and Nuke with him, which makes him a great contributor to help achieve our goals in Create, Connect and Compute in FY18 and beyond. John Paul has been working in the TV/Film Industry for over 15+ years. He started his career as a lighting artist for Brown Bag Films and quickly made the jump from TV series to commercials to be the studio 3D R&D Technical Director. He was instrumental in integrating Maya and Shotgun in Brownbags’ Pipeline and has worked on Emmy awarded TV show "DocMcStuffin" currently on Disney Jr, Octonauts on Cbeebeis, Peter Rabbit on Nick Jr, among others
ROLAND REYER: Hello My name is Roland Reyer. I'm a technical specialist at Autodesk Media and Entertainment in Europe. In this presentation, I would like to talk about procedural modeling using Maya and Bifrost. Now, we do have procedural modeling in Maya already, which is the normal construction history. So whenever you build something in Maya, in polygons, for example, you leave a trace of nodes in Maya that are the construction history.
You know that because you can sometimes remodel things that are further up in the construction history, and by that change, the outcome of the whole thing. But I'm talking about a different thing here. I'm talking about procedural modeling that works all alone. Without you doing anything, you feed something in, and it spits out a complete model, a complete building in this case. So we are talking about architectural modeling here. And in Bifrost, I have built a number of nodes that you can use to achieve these results and play around and to see how far you can push it, this procedural modeling.
So let's have a look at the safe harbor statement here. It basically says, whatever you see in this presentation, don't make your buying decisions based on this, what I'm presenting here. Because this collection of nodes that I'm presenting here are something that I personally have created and share with our users.
So a quick agenda-- we will talk. Or I will talk about procedural modeling, a little bit of a definition of procedural modeling. We will have some workflow examples actually, in Bifrost. We will also have a look at how to package these construction histories to use it anywhere else in your workflow. And of course, we will also talk about rendering these results here.
This whole idea of these nodes in Bifrost was not my own idea. I saw a presentation of my now colleague, Maxime Jeanmougin, who was a technical artist at that time in 2022. At PlatinumGames in Japan, and he presented something that blew me away.
He showed me these pictures here, where he said, we have a system in Bifrost where we can feed in a simple polygon block like this one here on the left side. And it spits out a complete building like you see on the right side. And you can even resize that block here on the left side. And the building will resize itself. It will rebuild itself using this construction history, this procedural modeling that I'm talking about.
The whole idea originally came from Akira Saito at Polyphony Digital in Japan. And he presented that in 2019 and showed this complete city of buildings. This whole city is made up of only three building recipes. You can see that here.
The building with a gray stripes, for example, is over here, is over here is over here. It's everywhere in the city. And when you count, you only see three recipes in different sizes, these buildings. And you can use that to populate games' cities, for example, where it's not important that every building has a construction inside. So it's only important to populate the whole city, but we can use it for our own purposes.
So what is a construction history? Construction history, as I mentioned already, is something that we have already in Maya. So it's a chain of operations. And we will build these operation, this chain with actual Bifrost nodes. So you will literally see a chain of operations, where the output of one node is the input of the next node and so on.
So we are daisy chaining these nodes together to build these operations. It has advantages because you can-- I mean these nodes are built so that you can build a construction history, and it really runs by itself. You don't have to touch it anymore. But you have some constraints here, that not everything that you do in interactive modeling is possible in the same way in this procedural modeling.
And of course, I do have examples. Currently, it's mainly made for architecture. So buildings in these background cities, that's the purpose at the moment. And of course, concept modeling for architectural visualizations is also one of the goals of this thing here.
So let's have a look at procedural modeling first. So procedural modeling, as I said, is a chain of operations. The blue ones here are these operations. And the yellow one is an input object. So a cube, for example, or a sphere or just a polygon plane of a certain shape, that's the input for this operation.
And then we hand it over from one operation to another one. There is, of course, something missing here. And those are the inputs. So of course, I want to input, or I want to influence this thing with parameters. So for example, for an extrude, I want to define how far my extrusion goes. And maybe there's an offset or something like that. So that would be a typical input.
So we do have these green arrows here as inputs. But there's another very important input that gets usually forgotten, and that is the selection. The selection is super, super important because we do that all the time interactively. We click on something and say, OK, I want to act on that thing.
And we forget that we did this click. We forget that we did the selection. And that is an important part in this procedural modeling because it also has to be procedural. You cannot just stop the whole process and say, hey user, can you give me a hint which window to extrude or which face or which polygon face, which one I should cut? So you have to define that in this whole process.
So the Bifrost workflow here would be to have operations like cutting operations. So this block of polygons here, for example, is cut into pieces like horizontal cuts and vertical cuts to create these windows here. And some of the windows are extruded inside. Some of the strips on this building here are extruded out and so on.
So we have a number of operations that we can use there. It's only very few. It's a very basic modeling toolbox, but it's procedural. It's fully procedural.
And then, you can use these nodes here. These are the actual nodes or some of the actual nodes. So we have a multi-cut, for example, we have an extrude, we have an instancing node and so on. So these are the nodes that you can use. And you see these terminal extensions on the nodes is there to have some diagnostic display so that you can have additional information displayed in this modeling process.
And then you chain them together in a way like this one here. So it's a long chain of nodes, where the object, the polygon object is handed over from one stage to the next one. And polygons are added or modified in the stages. And it can become quite big, as you see in the image below here, so it can be a big thing.
So let's have a look at the selection. So and actively, you would use your mouse cursor and simply click on the polygons and select them, and then, for example, start an extrusion. So now once you have extruded, these faces are still selected. But it's no longer the same faces. So these are the end faces of my extrusion.
The original faces were down here. And the extrude node has memorized or has stored the numbers of these faces. Now, in the next step, when I change the resolution of the original cube here, which I can still do in Maya, you will see the big problem that we have. Suddenly your extrusion jumps around on the resulting cube with lots of subdivisions.
That is because the end of these selected faces here is different. The starting faces are suddenly in a completely different place. So these four faces here at the beginning are suddenly here.
Maybe let's say it's facet number 0, 1, 2, and 3. And these four numbers are now here. And so the extrusion is in a place where you don't need it. This doesn't make any sense.
So the solution would be a procedural selection. So now we don't pick on these faces directly with our mouse cursor. We select them with their properties, for example, an orientation in a certain direction. Or in this case here with a box, say all the facets, all the blue facets that are within this box are going to be extruded. And then when I move this box around, the extrusion works on whatever faces are selected. even. When the resolution changes, when I turn it down very much, it still works because it just picks whatever is in the box and extrudes it.
So that is the principle of a procedural selection that allows you to do exactly that in the process of the whole modeling. And it's a disadvantage because it's not interactive at all, but it's automatic. It runs by itself. You don't have to stop and wait for the user to input something.
So we have a number of Bifrost selection nodes. And this acts upon so-called face tags. So face tags are something similar to component tags in Maya, where a component, like a face, a point, or an edge, get a name. So you can collect these things under a certain name.
Face or component. Tags in Maya are much broader than the face tags in Bifrost PPG in the procedural polygon generation. Face tags in my little world are just one name for every face. So a facet, a polygon can only have one name, one face tag, and that's it. So you can collect several face tags, but it's one name.
And for example, all the yellow ones here could be called yellow, for example. And all the blue ones could be called blue. But that's it. It's just one name for them, and I can collect them by saying, I want the yellow ones and the blue ones.
And then you can select the faces and give them face tags, By. The way, by selecting the normal, for example. If it points upwards, I want select these. I want some random selection. I want to select the size or the shape of the polygons and so on. So there's a whole bunch of nodes that do exactly that, select something for you so that you don't have to do it interactively.
And now let's jump right in and do an example here. This building here is similar to the building that my colleague Maxime Jeanmougin showed in his original presentation. And I was fascinated by the thing. That's the Washington building from New York, from Downtown Manhattan. There's a building that looks very much like this one here. So let's have a look at what that would be like in Maya.
So in Maya, I build a simple polygon block like this one here. It was a cube initially, so I can select it from here. It was a cube initially. And I did a bevel for the side edges here and some cuts for the top of the building to have a better-- or have it easier to build a roof. And I can still change the properties of the thing by for example, changing the input size of the whole cube. So the bevel will act after that.
So we have already, a construction history. But we have some more construction history here in the Bifrost window. You see the long chain of operations that act on exactly that cube. So that's the cube here that we feed into this whole chain.
And I have a note here, where I can switch on parts of this whole construction history to show you how it works. So for example, for the top of the building, we make an extrude, we make another extrude. And the third extrude to have some sort of a roof. And then we make a subdivision to get some sort of a penthouse look or something. We will come back to this thing later.
And then for the body of the building, we're going to subdivide it horizontally. So I'll call this a horizontal cut. It's subdivided vertically, of course. The vertical direction is subdivided, but it's a horizontal cut.
And the good thing here is I call this a sequence cut. So a sequence of sizes is cut into the building. And I can specify which of these sizes are flexible. So in this case, only the pink portion is flexible. And all other ones are rigid, so they maintain their sizes.
So in the next step, when I subdivide the pink portion to have floors for my apartments, then when we change the height, what happens to these floors? Hey, they re-subdivide by themselves. So they don't care how big the whole thing is.
They say, OK, I have these sizes here for the floor and the in-betweens, and I have to make as many subdivisions as possible. And if there's more space, I get more subdivisions. That's the beauty of the whole thing.
Now let's subdivide the whole thing vertically into windows or apartments or however you want to call it, entrances or so. And I cut through all of these elements here except a few. So some of them are spared.
So I cut through all of them to have the same subdivision in all levels of this building. And of course, I could say another level has another subdivision. Yeah, we can have a look at that later.
And now look what happens when I change the width of the whole building. It re-subdivides itself to have more of these apartments. And that is super, super cool because you can change the size after your whole modeling. So let's jump off over the next few steps here and have another concept, which is instancing.
So now in step number 15, I'm going to introduce some arches here. And I have to say. I can do arches procedurally already. So we have a node for that. But let's imagine you have to model these by hand, and you want to fit it into this window size that we have there. And that is exactly what the instancing node would do.
So these arches are brought into to enrich the whole model with some more complex stuff. Then we have a round one here. And we have these street level entrances that are modeled by hand because I didn't have an idea how to do that procedurally. And that's a cool thing because you can say, no matter what, I have this model here. I just plug it in. And whenever I change the size, the overall size of that building. I know that the building will re subdivide itself and just build more of these windows here.
And now comes the super coolest part. I can go in-- and let me zoom in a little bit-- and say, OK, instead of using this one, the original shape here, instead of using this original shape here, I'm going to use another shape and feed it into this whole construction history. Now look at that. Suddenly we have an L-shaped building. And there are no bevels on this L-shaped building. The actual object that's behind it is this one here, and I can unhide it and maybe close this one here.
And now I can say, hey, I want to model the faces here. So let me grab one of these polygons and move it around. And you see that the whole construction history still works. So I can do that and simply grab the faces directly and model the whole thing, depending on what I need here.
And since there are no bevels, there will be no round windows on the corner of the building, just because this feature is not there. We don't need it here. And that way, you can, in a fraction of seconds, you can make this whole building on a different shape, on a different starting shape. And you don't have to do anything when it builds it.
A fraction of a second, it's done. All the selections are done automatically. And the building works by itself.
So let's go back to our presentation here. That was the Washington building that I wanted to show you. And now we're going to jump into something more complex.
So the washing building is nice, but it's like a comic building. We want to do something that is more like a real world example. So I made this one here, this building, I call it apartment building with balconies and props that are inside these apartments, and so, which makes it a little bit more complex.
So let's have a look how that works. I'm going to load this complete scene here. And then we have a look at how this works. So let me close this first here and have a look at this whole building. And I can click on Rendering. And you see it renders the whole scene right away.
There is an image around this building. It's an HDR image. So it's image-based lighting. And it looks pretty good.
And you see that there are so many details and different sizes of the windows and the balconies and everything. The whole thing was made just from a simple cube. So it's basically one facet, one polygon that I start to subdivide and extrude and everything to build this whole building. So the complete building is procedural, starting from a single polygon, which is very cool because you can have different shapes of these polygons or these polygons on different orientations of other cubes. And it builds this whole facade, this whole front of the building just by itself.
You see that inside, there are curtains. That is something that are modeled by hand. I made a wavy curve and extruded it. That's the curtain here. But these curtains are placed randomly, left or right or in the middle. They are drawn or scaled horizontally.
And there are also chairs. So here on the side of the building, on the balconies, you see some chairs placed randomly on some of the balconies and some of these balconies over here. So also, on some of the loggias.
And you see some lights in the apartments. And that's also fully procedural. So don't touch it at all. It places lights by itself and says, OK, in so and so many percent of all apartments, I'm going to place a light on the ceiling or on the wall. It's going to be a warm white light.
So all of these things are clearly random and completely done by itself. It's all procedural. I don't have to do anything.
So let me stop the render and have a look at this model here. So you see, when I zoom out, it's just a block. And I use the front face of this cube to procedurally build this whole building. So let's go in and have a look at these apartments. And you see, we have these loggias here, these balconies that go in a little bit. And some of the apartments are just windows. It's just the front window.
And behind every apartment there's an empty cube of-- and furniture standing around. And so I didn't go that far. I can make it transparent so that you can look inside.
So you see that the rooms behind these balconies are larger ones. And behind the apartments, there's only a small cubicle, so to say. It's a very small space, just to give the illusion that there's something behind it.
So how does that work? Let's have a look how that works. So let me open my Bifrost graph editor again. And what I'm going to do here is to cut this off, cut the output off of this whole construction history, and then use the main input, which is just the cube here. So take this one here and remove the input. I go closer and create a new output and connect the two.
Here's my cube again, and maybe turn off transparency. So that's the initial cube that I create. So here in the outliner, you can see that's my initial cube. If I scale this, then this cube will also be scaled, even though it's now a Bifrost object that we see here. That is what comes out of the output.
So what I first do is to get the Maya face tags, all of them. So I'm just picking all of the face tags that are in the object. I don't see anything, so I'll include also, a diagnostic node, which shows me something, which shows me colors. That's the first thing. And also so-called face tags, so that is some writing directly on these polygons.
So here you see front, left, top. So these are the face tags that are automatically created when Maya creates a polygon, any kind of polygon, but especially the cube has these. So let's go in and subdivide this thing.
So I'm now starting with this building here to do exactly what I would do. So I create a call node called PPG multi-cut. And these nodes, all of these nodes, these PPG nodes need a name of something to act upon in this hack expression. And I would say here, I want to use the front facet. And it subdivides it, as you can see.
And maybe the front is still a little bit too big, so make it smaller here. And when we zoom closer, you see that we have a front_outer and a front_inner. Outer and inner, outer and inner. So it subdivides the whole front into outer and inner strips.
That's cool, yeah, but first of all, I want to change it a little bit. Why does it cut it in this direction? We see this red arrow here. That is the so-called selected edge. I have a direction vector here that points downwards, from the center of the polygon downwards, and it meets this edge, so that is my selected edge which defines where the cuts go.
So it's a horizontal subdivision with vertical cuts. When I say I want to use the next edge, then it takes this one, this edge here. I'm counting counterclockwise. Takes this edge here, so it makes horizontal cuts. It's a vertical subdivision.
So let's undo that. I just need one cut. So down here, we have a fixed number of subdivisions, just one cut. And I want to make the outer size a little bit larger. You see that the inner size is squeezable. And that is because of this one here, the flexible setting. They all can be flexible, but in this case, inner is totally correct.
So that way, I subdivide my building into the side strips where the balcony is going to be and into the inner part. And that needs names. So let me turn off the inherent source tech. So the front thing disappears, and the outer is going to be-- I'm going to call them left, right. And the inner I'm going to call main because the node gives a nice bright pink color.
So these colors are random. You don't have to take care of them. It just creates random colors based on the names.
So the main thing will be now what we extrude out. So we make a PPG extrude node, extrude. And again, we need to enter a name for the whole thing. Here, I'm going to say it's main. And that's what gets extruded.
So here's my extrude depth. I can set it. And I want to say the face will remain my main here. And the sides, I'm going to call concrete. Why? Because I already assigned in the name of the material to those pieces where I know that's going to be concrete.
I don't play with that anymore. That's going to be concrete. Just leave it.
So some more subdivisions, one more PPG multi-cut. And now we do a vertical subdivision, horizontal cuts. You're going to cut off the top and the bottom of the whole thing. So we say we want to cut the LR paths, as well as the main paths. You see that with a space, you can simply enter multiple names. And then say, OK, we want to cut horizontally, so vertical subdivision.
Again, we just need one subdivision. We want to set the outer to a specific size. So inner should be flexible. And now I have to inherit the names. I'm sorry, because otherwise, it will have all the wrong names or all the inner names here for these middle parts.
So I want to treat the outer ones, the outer ones separate from the inner one. And you see these red arrows accumulate. So I need to turn them off. Like this one here, this one, and the one here, so I'm going to-- no, not this one here. Those were my face tags.
So now I can subdivide the main part, actually, the side ones as well with another node called PPG sequence cut. And sequence cut is special because it cuts basically, the name that we want to use is something with inner. You see that I can use an asterisk as a wild card. So something with inner is my wild card here. I want to cut them horizontally and not with these ratios, with these size ratios.
I just want one specific cut. But I want to repeat it all the time. So it's just one cut, and loop it so that we have a lot of these.
And then I can say with the sequence scale, I can say, make it bigger so that my whole building has these balconies. And yeah, the names get a little bit long now. So I would finally then say, I want to rename these objects.
There's a bulk rename. And remember this workflow here. So the bulk rename, what it has is just an input for string or a string array input. So I can right mouse button on this input here. And you see that, and create a value node. And this value node is a string node where I can enter some string.
So I can say, for example, anything that is called LR with a wild card behind it, double point, I will call in the future, LR. So I renamed the side pieces here. And you see that didn't work. So let's remove it again.
This is outer, and this is the inner one. So let's say LR_inner and then a wild card. And then we rename it to LR. That's better. So the outer one here on top should be concrete. I will leave that to concrete.
And then the main inner one-- and I'll make another string node The main inner one should be just main. I must go in should be just main. And it's going to turn pink, nice and pink.
And the outer ones here, let's make a last one. Not going to bore you with this too much. So the last one here is anything that ends in outer is going to be concrete. So we have concrete tops.
So now let's concentrate on the mains again here. So this is the wire here. So PPG multi-cut again on the main, because now we do something very important here. We're going to cut this main thing horizontally. Horizontally, we just do one cut. We only want the start side to be there, so only the outer side here.
So I can change the outer side to something very small. And the outer, in this case here, so the names again, the outer is going to be concrete. I will not change that anymore. And the inner one is main.
So you see how I subdivide that building here. And now comes the most important part. So how do we make these apartments? There's still one arrow here, so let me remove that.
So how do we make these apartments horizontally? And the point here is that I do a PPG sequence cut, actually several sequence cuts. It's not just one. And we act on the facet called main. And now you see, here are my apartments, so to say.
So what I would do is to say I want a concrete piece. I want a window. I want a concrete piece, I want a loggia, I want a concrete piece and a window, concrete piece and a window concrete piece and a loggia.
And so what we need to do is to randomize the floors and say, OK, on these particular floors, we have this sequence. And on other floors, we have other sequences. And then we can address these names here directly.
So for example, when I say, OK, number 4, that's going to be a loggia. That's going to be one of these balconies. And we jump directly into the next example here. I don't know if I have a slide for that.
So I have a slide for that. How do we make such a loggia? And that is a very simple thing as well. And you can package this whole loggia once you've started it. So let's have a look at this one here.
This is one polygon made in Maya and subdivided, subdivided vertically, cut horizontally to have this concrete strip that we had under the main, and this apartment in the top. And what I have here, is these first two parts here, the multi-cut cuts the concrete off. And now we start with these nodes. Instead of creating them, I just turn them on so that you can see what happens here.
So the first thing is an extrude. And it goes deep, but shouldn't go too deep because what I first want is a little bit of balcony. This one, this little strip here is important. And the next extrude, that's going to be my loggia. So I'm going to extrude it inside. This is my loggia.
And I need to bring this floor down somehow. The problem is, when I do this now with an extrude downwards, I can totally do that. We will have, in the window, this will become the window here. We will have a horizontal cut in the window because every extrude says, OK, whatever you have here, from there on, extrude out.
So what we're going to do is to copy this back, the wind source here. We're going to copy it for the glass. Now turn it off. Now you see two objects on top of each other. And with this transform, I take the glass and move it down.
Look at this. So I'm moving the glass downwards, maybe not too much, maybe just -1.8 or so, so that we have one piece of glass. And now we can go back to the actual thing to the wind source and extrude it backwards again it on into the apartment. That's my apartment. And then I will select these floor faces here with this node, select faces by normal, and I will extrude them downwards.
And we extrude them downwards by how much? Exactly, very much like the glass, -1.8, so that we don't interfere with the next apartment below. And then we go and cut the glass vertically. Just a vertical cut, one here, one side here, one side here, and then the cut horizontally through both pieces, like here and like here.
And the next step will be an extrude to create these nice window frames that we already have seen in the renderer. That is all super cool. We can leave it there.
We can also go and do the thing for the handrail here. The loggia needs some security handrail. So here's a handrail. I place a piece of glass on top of my balcony and then some handrail on top and some sections here.
So when I now modify the original polygon plane, for example, by making it wider, like here width, making it wider, you see that we get more handrails because it re-subdivides-- actually not re-subdivides. The multi-instance creates more of these handrail supports. And what happens when I do subdivisions?
So for example, a horizontal subdivision, suddenly I have two apartments. Look at that. And add a vertical subdivision. Bing, now I have four apartments. That's so cool because it's all procedural already.
So I can now package this whole procedure, this whole construction history that I have here. I can package that, make one node out of it, and say, this is an apartment. So put it in my construction history, and say whatever I feed in when I give it a certain name, then this plane, this polygon plane will become an apartment like this one here or a window, a left window or a right window or something else.
So that is the whole concept. So let's go back to our presentation. That was the apartment unit, the loggia. And then I have a very simple example here of recipes, actually, just to show what it would look like, these recipes. So I have a few boxes here, and they are connected. Every box is connected to one of these recipes here.
So this simple block is building number 1. I can also say this first one here is fed into the other one. And suddenly, the first block becomes the second building. And the second building becomes the first recipe. So these are recipes. When I double click on them, you see a whole construction history in them.
So let's go back. So all of these three recipes make one building each. What about the colors? So far, we have seen these diagnostic colors. And that's an important part of the whole process. What about rendering?
So I can render these diagnostic colors as we see here. So this is the real rendering from Arnold with these diagnostic colors. I can also use this diagnostic shader to output different colors. So instead of doing these render random colors, I just say, OK, I'll use gray or white or black or whatever color I want on the surface.
But it's just one shader. It's not very fancy. It's not shiny or something.
In this apartment building here, what I did was to extract the polygons and assign a shader reference. So in Maya, you define that shader class, for example. And in Bifrost, you simply say these polygons that are spit out as a separate object, that's important. These polygons have the material glass or handrail or window frame, et cetera. You get the idea.
So that is something that we can also do in Bifrost. So it's called a bulk material assign, works like the bulk rename. You simply create nodes and say, these facets with these face tags have all the material glass, for example, or concrete or anything else. Good.
So that was a run through. Let me show you the final building. I'm really proud about this because it looks pretty good, as if I had done a lot of work. But it's easy. This whole construction that I made here was done in less than half a day.
So the most complicated thing was the placement of the curtains, to be honest. How do I place the curtains when I want to scale them a little bit up and down? That is something where it becomes programming. So even though it's visual programming, it's still programming. So I have to get into the technical things a little bit to become virtual and become a good modeler.
But that is what I called PPG, procedural polygon generation. In Maya, this was done in Maya 2024 with Bifrost 2.8. We already have Maya 2025 with Bifrost 2.11. I have a bunch of new nodes created that now work on all of these objects that make your life much easier and make it easier to create that stuff. Thank you very much for your attention, and let me know if you have any questions.