AU Class
AU Class
class - AU

Dynamo for Software Developers: C#, Python, and More—Workshop - Part 3 of 4

Compartir esta clase
Busque palabras clave en vídeos, diapositivas de presentación y materiales:

Descripción

Are the out of the box nodes in Dynamo not enough? Ever felt like you wanted a way to customize the Dynamo experience for not only your team but your clients? Then come join us for the Dynamo for Software Developers workshop! You’ll learn how to extend Dynamo by using code to develop on top of it. We will teach you when and how to use different development tools to build your own nodes using C# and Python. We will even teach you how to manipulate the Dynamo experience using extensions to build custom UI or interactions. Please note: This class is targeted at software developers with experience writing source code: We will not be covering entry level Dynamo. If you are a beginner or have never used Dynamo before consider attending the Dynamo Beginner session held during the main AU conference or invest in beginner training ahead of time.Participants will be paired at provided computers (1 computer for 2 participants). Includes the Tuesday AU General Session. Don’t forget to add the AU Full Conference Pass and sign up for the Wednesday evening DynaLightning talks and party.

Aprendizajes clave

  • Learn when and how to Use Python in Dynamo
  • Learn C# basics and how to use the Revit API in Dynamo
  • Learn how to build your own zero-touch, read-only nodes using C#
  • Learn how to control and manipulate the Dynamo UI and interactions using Extensions

Oradores

  • Avatar para Thomas Mahon
    Thomas Mahon
    Founding Director of Bimorph Consultancy, Software Engineer and computational design/BIM specialist. Creator of bimorphNodes. Authorized Autodesk Developer. Bimorph is a digital engineering firm transforming the way Architects, Engineers and Building Contractors realise buildings
  • Racel Williams
    Racel Williams is an AI Development Manager for the Building, Infrastructure, and Design Group. She has a B.S. in Marketing from the University of Florida and Master’s degrees in Architecture and Human-Computer Interaction from Georgia Tech where her research focus was Augmented Reality and Tangible Interaction. In 2013, she joined Autodesk as an intern where she developed a mobile AR prototype for in-situ annotation and visualization. After becoming full-time, she went on to become the UX Designer for FormIt, Dynamo, and other related projects. Later, she became the Product Owner of Dynamo and led the development team in shipping multiple versions of Dynamo. She has given numerous talks and workshops on Dynamo around the world. Currently, she is now helping Autodesk shape how the company will integrate AI and Machine Learning in AEC workflows by leading a team of ML researchers and engineers to build the next generation of AEC tools.
Video Player is loading.
Current Time 0:00
Duration 1:31:59
Loaded: 0.18%
Stream Type LIVE
Remaining Time 1:31:59
 
1x
  • Chapters
  • descriptions off, selected
  • en (Main), selected
Transcript

PRESENTER: Hello. Welcome back, everyone. So where we left off at the previous session, we finished our C# library, and it went Kaboom. It's not meant to do that. It's a mistake I did, not you guys. So it's me not you. So let's just fix it real quick because Tom will need that library for this next session he's doing with you. So I'm going to get you guys to change two lines of code real quick before we move into the exciting zero touch session, OK?

So if you just follow what I do to make sure that you guys have a correct version of the library. And go to the solution again. And under Geometry U tools, if you find line 26 where it says-- sorry, 25, where it says double step and there's an expression there. Instead of that expression, if you could just type 0.1 that would be helpful.

And just remember, if you don't do this code change, the next session might not work as intended because we're trying to generate the layout in this one and use it in the next one. So change it to 0.1 here. And then, go to the desk architects class, I think that's where it is. No, the desk arrangement class. And this desk count is actually incorrect at the minute. So you just have to swap the 0 and the desks count between each other in respect to the semicolon.

I always forget the order they're in. And I just put it the other way around. So after the question mark it should be 0, and then semicolon. And it should say this.desks.count.

And whilst we're in here, make sure that in the desk architect class you have this line that says desks.adddesk, which was what we were doing when we were coding.

AUDIENCE: [INAUDIBLE]

PRESENTER: Yes, the desk arrangement one. So now if you have all made these code changes, if we load it up in Dynamo, and we have the same workflow we had earlier, we're just making a rectangle, a surface from it, then we use the layout desks on surface. We're going to come back to the code in a second if you need to see it again. If you run this workflow now, you'll see it actually creates desks. And you can see that the desk arrangement was created at a specific date time. And it returns 121 desks, for example.

So if we go to the desk arrangement class and we actually scroll down and get the desks from the arrangement, when you run this, you would get 121 individual desks, which you can go back to the business side of it, go to desk, and interrogated for a, for example, origin. So you should get 121 Dynamo points now.

So you can see how our classes work, and we can decompose it into these things. Yes.

AUDIENCE: [INAUDIBLE]

PRESENTER: Yeah, I'm doing that now. So on the desk arrangement, it's line 21 that needs to be changed around a little bit. And the one before is in Geometry utils, line 25. Instead of an expression, it should just say double step is equal to 0.1. So remember how I gave you guys a hard time for not forgetting to check for things like dividing by 0? I was dividing by 0. Somehow. Don't know how. Yes.

AUDIENCE: [INAUDIBLE]

PRESENTER: Saying you can't open it? Failed to import library.

AUDIENCE: [INAUDIBLE]

PRESENTER: So if you get failed to load library in Dynamo, you need to go to Dynamo settings, manage paths, and make sure you remove the last path, the one that points to our DLL. Close Dynamo, start it again, and then import it again. This is a fairly new change in Dynamo where it remembers where it imported it from. So you need to make it forget it. I'm going to come in a second.

So everyone done these changes? All good?

AUDIENCE: [INAUDIBLE]

PRESENTER: So to import it into Dynamo you just go file, import library. And then, you find the DLL, which is in data sets, you'll find the session. It'll be-- if you've moved the folder to your desktop, it'll be on your desktop or wherever you're doing this from. If you go to C# fundamentals exercise four-- I'm using the complete one-- you go to the BIM folder, and there's a few more folders in there. And finally, you get to the Dynamodev.yellow. That's the file you're after.

So that's it. I'm going to hand it over to Tom now. Studio for a second? You can just swap it out when you need to. OK, anyone else having issues with the code? Have you tried running it inside Dynamo? Does it work? Sorry?

AUDIENCE: [INAUDIBLE]

PRESENTER: You go to Dynamo settings, yes. So if you guys have built the solution and then imported it into Dynamo and then you try to build again, make sure you have Dynamo closed.

TOM: And Revit.

PRESENTER: Because otherwise, we won't be able to actually build the solution again.

TOM: [INAUDIBLE] OK. Do you want me to start? OK, so this afternoon then we're going to be looking at zero touch nodes. Zero touch just describes the process. So this session then is, basically, going to be looking at what you've done in the previous session with Radu. Where of course, a lot of what he's done is really quite abstract, and there's nothing tangible that we've developed so far. You can actually see. Which can be, I guess, like a bit kind of alienating if you're new to programming.

So this next session is not only going to turn a lot of already used verbs in the last session into something more tangible in the form of Revit instances, namely desk instances within the model. But also, we're going to be looking at how we can actually create a set of zero touch nodes within Dynamo, and the whole process for actually setting that all up.

And I'll also explain how dynamic actually consumes compound libraries. And that process of importing those DLLs that you've already created so far today. And the generation of nodes in the library at the click of one button is what is known as zero touch. So zero touch really just describes the process of importing a compiled library written in C# to generate a library of nodes without you having to do anything other than just declare your classes and make them public. That's literally all you have to do with zero touch.

So [INAUDIBLE]. OK, so the plan for today then will be the following. As I said, we're to continue building more ready than the last session, we're going to use all the data, which we've generated using your desk class to output Revit instances. So basically, what we're going to do by the end of this session is the following.

We're going to have a set of nodes, called zero touch nodes, that are going to be able to compute the egress distance from each desk to a given point. I'm actually going to use Revit's brand new built in path of travel class. And this class just processes from two points an escape route through your building. And it will detect things like openings, i.e. doors, and work how best to create path to travel to wherever your target point is.

And we can actually visualize this. In our case, just using a set of Dynamo curves, which you can actually see on the screen now. So you notice that as I move my exit point, which is based on the end of that line, what it's going to do is it's going to recalculate the path of egress for me. And our libraries, which we're going to generate, which we'll then convert into nodes when we actually do the zero touch import, is then going to redraw all of these path of egress for us.

So you can see here with those six desks, and each of the six desks now has a path of egress. So by the end of this session, then, you're going to create the following. You're going to create a class called desk creator, where it's going to have one static method which will be called generate. What that method is going to do is it's going to take your desk assembly object you did in the previous session. It's going to take all the desk objects out of that assembly, and it's going to convert them into actual Revit desk instances inside your model.

After we've done that, we're then going to build two other libraries. One of them is called egress checker, with one method called get results, which is also going to be static, which is this method here. And this method returns a list of egress results, which is also going to be one or the other classes you'll be building today. And that class, again, it just built on some of the concepts which you learned with Friday's session this morning, which is declaring our class. Declaring a constructor.

We're also going to be looking at access modifiers so you guys can get a better understanding of what public, private, and also internal means. And once we've done all of that, the end result will be a range of query nodes under egress result, which enables you to, for example, check things like the path, also to identify which instance it refers to. So if you want to know out of those desks, which we're looking at inside the Revit model, which one of those desks refers to which path. You can do that as well just by simple index matching.

And then also, working out whether the egress result is valid. And we can specify what the maximum egress distance is. So perhaps in a real world context, maybe if you had some sort of regulation about minimum fire escape distances. And really, you could actually use this for anything. I mean, imagine if you're an MEP engineer, and perhaps you're trying to optimize ducting or pipe work in the building. You could even use this path of travel you even for that.

So when it comes to programming, try to think outside the box. Because there's many techniques inside the Revit API that enable you to do all kinds of things. And is really limited by your imagination. So today, we're going to show an example using desks, but as I said, you could actually apply this part of the API to many different problems within construction. All you've got to do is just think about it. And then, just use your creative intelligence.

OK, so let's get started then. First of all, just to reiterate what zero touch means. It literally means this. Where you see add ons inside of Dynamo, if you click on that button, it will ask you to find a DLL file. When you find the DLL file, so in our case, we're going to be generating a library called zero touch nodes. When we locate that file, I'm not going to find it on my computer, but if we find a DLL file and select it and click open, Dynamo will attempt to read any public class, any public constructor, any public property, and any public method, and it will convert those into nodes inside the library.

And then, you can place those nodes on the graph. And Dynamo will do all the hard work for you. It'll work out all the input ports, all the output ports, it just renders everything for you. That's why it's called zero touch. Because it's minimal effort. You just write your code, declare your classes, as I said, put whatever kind of properties and methods and constructors you want inside your classes, and then you just import it. Sure.

AUDIENCE: [INAUDIBLE]

TOM: All right, well, Python you can't actually create a compiled library. So the process of actually importing a library doesn't apply to Python. With Python, you just create a custom node using a [INAUDIBLE] file, and then you can just load those in. So there's a slightly different technique, but really the end result is the same thing. It's a set of custom nodes in the library. But yeah, the languages do have slightly different techniques for the generation of that library.

But for C#, it's zero touch import. Yeah, that's why I actually-- typically, when you hear zero touch mentioned, people usually say, I'm building a zero touch node. I'm being really pedantic here, but technically, that's not correct because it's actually describing a process of importing a library. But I mean, I guess there's no harm in calling it a zero touch node because it just means a node that's built in C#.

OK, so what I'd like you to do then is fire up Visual Studio 2019. And we're going to be opening up the zero touch nodes library. And you'll find that in the data set. So if you just go back to the [INAUDIBLE] developers data set. Find S3 zero touch. And we're going to be using the library which has got a start and end to it. So if you see a workshop template start, we're going to be working from there.

When you find zero touch nodes S there, if you can just open up that file. And when you open it, it will just be a very basic and minimal kind of project. And we're going to start writing all the classes. What we're going to do as well, just based on the progress which we've made so far this morning, and I want to avoid this mad rush at the end. I'm actually going to ask you to just literally drag and copy some of the classes straight over. But it's going to focus on building maybe two or three classes in today's session. So it's kind of manageable within the time I've got.

And that way, you're not going to miss out on anything. And crucially, you'll understand more of these concepts that we've been conveying for most of today. OK, so--

AUDIENCE: [INAUDIBLE]

TOM: Yeah, hang on. Is that better? With the Solution Explorer, I don't think you can make this any bigger. [INAUDIBLE] the Solution Explorer. I don't think you can make that any bigger, can you?

PRESENTER: Change the resolution.

TOM: OK, I think that's better. OK, so let me just remove this because that shouldn't be in there. All right, so what you should see is the following. You should see zero touch nodes solution at the very top. Properties and then references. And in references, just check if you've got the same problem I've got. If you see all of these rectangles that are yellow, just highlight all of those references. And what is going to remove them. Or what happened back in now just so it's not a problem.

And actually, it's probably better that we do have them because then you can see the techniques that we actually use developers for loading in the libraries. I'm going back to this morning's session with Python. In that boilerplate, you've got all of those imports, which load in things on the Revit API, and also Dynamo's libraries as well. There is an exact equivalent within C#, which I know Radu has already showed you. And that's just those using statements at the top of your files. So those using statements are the equivalent of import statements within Python.

So you could see the correlation between languages and why, really, if you learn one language, you've pretty much learned all of them. So I mean, there are nuances between the two, but really that's very true that all the languages, they all have very similar concepts. So that's why it's always worth mastering one language. Because you'll tend to find any other language. That'll be a lot easier.

OK, so to get things started then. The first of which we're going to create is that node which basically takes the desk assembly, the [INAUDIBLE] ability-- sorry, the desk arrangement object, that is going to read all of the desks that are in the original object. We're also going to to provide a desk type and a host level. And then, this node is going to help a bunch of Revit family instances as desks inside the model.

OK, so first of all, we know we want to create a class then called desk creator. So in Visual Studio, let's create a new folder to actually store this new class in. So where it says zero touch nodes just right click. Add new folder. And this new folder is going to be called family instance.

And inside that namespace-- so even as a folder, that will actually translate to a namespace within C# by default. But you don't have to use it if you don't want to, but we will today. We just want to add a new class. So right click on the folder, add, and then class. And this class is just going to be called desk creator.

OK, so the first thing that you want to do is, actually, just write a method. We don't need any constructors or any properties for this class. Just as a quick note, by default, every single class which you declare within C# always has what's called a default constructor. So you cannot declare a class without a constructor. The C# compiler will generate a construct for you, a default constructor, which is noteworthy for zero touch import.

Simply because if you do not declare your own constructor and you import this library, you'll end up with those constructors appearing your library. And they're just redundant nodes. They're going to do nothing because C# will auto generate the constructor for you. I'll actually show you as well, and then I'll show you how we just resolve the issue. Because it's a simple thing to do.

But it is just worth noting that you will see an additional node appearance on your library. And if you've done this before and you wonder why, it's because C# is doing it on your behalf.

OK, don't forget, if we don't mark our classes public, then Dynamo can't see it. So that's the next in which we need to do. So we should say public class desk creator. And the method which we're going to create, and I said, it's just one method for this class. It's just going to be called generate. So again, you notice that we mentioned this morning about being quite concise with the names of your variables. And that really extends to everything which you declare within your program. Name spaces, classes, methods, properties.

Try to be descriptive, and just make your code essentially self-describing. If you can achieve that-- and there is actually an art form to it, I would say that. Trying to think on the fly of a sensible name for your entire code base, it can be a challenge at times. But yeah, try to spend as much time practicing that as actually practicing the code. Because as I said, it can be a major barrier to your learning curve if you don't declare things in a sensible fashion.

OK, so we've got this creator, and we're going to create a new method called generate. So first of all, we need to decide on our axis modifier. So in most cases, we want Dynamo to see it. So it should be public. We then also need to add an optional modifier. So you've got axis modifiers and modifiers. And modifiers, again, they just change the behavior of whatever it is your declaring. So in our case, it's a method. And we actually just want to make this static.

So if you remember, when Radu was explaining what static meant, he meant you can only create one of a certain thing. There is a bit of a caveat there in the sense of if the static method returns instances and objects which aren't our method well, then it cannot return more than one object. But just remember the technique here. If we declare a public method inside our type-- so our type is desk creator-- and we make that static, that means that to call our method, we have to declare desk creator as the type, the operator, and then our method.

So to put it into Dynamo terms, all that means is when we place that node on the graph, we do not need to provide an instance of our desk creator. We can just place it on the graph, and then all we need to provide is the inputs into our method and nothing else. So if we use static, it means that we don't have to provide an instance of our own type. So our own type, in this case, is desk creator.

So we just leave it as static. We then need to decide on the return type. And in our case, it's going to be a list. Lists are always declared in C# with a capital L, and the chevrons. And inside there, we need to determine the type of element that it's going to return. Now, we are going to be returning wrapped Revit instances. So again, the concept's the same as this one with Python. And this is just going to be a list of family instances. But in actual fact, we could literally just use the superclass that Dynamo uses. The Dynamo element class.

And for that, we're actually going to use a using statement. And we're going to explicitly define what I-- or rather, what this alias refers to inside Dynamo's Revit nodes library. So what I'd like you to do is just type using at the top. Whenever I use an alias-- and why you would use an alias, by the way, because I'm kind of jumping the gun here-- is to avoid namespace clashes.

So one of the issues in which you might find if you're say referencing the Revit API and the Revit nodes library, which is Dynamo's wrapper class for all the Revit elements. Because the names of types are the same, for example, [INAUDIBLE] war class, Revit API also has a war class. When you import both libraries, the compiler can't determine which of those types you're trying to find. It will say that you've got an ambiguous reference. Because it's looking at both libraries. You're saying, look at this library, look at this library. It finds two classes with two matching names. And it can't work out which when you're calling.

So aliases are actually a really convenient way for you to directly say, look, if I ever declare this alias in my code, then I'm referring explicitly to this type. And other compilers [INAUDIBLE] knows what you're referring to. So whenever I'm defining anything out of Revit nodes library, I always precede the type with the word Dynamo. Then it's very obvious. So in our case, it's just going to be called Dynamo [INAUDIBLE] equals-- so we need to declare an alias. I guess we'll have to declare a variable. You just use the assignment again.

And we need to reference Dynamo's Revit nodes library. Now, you notice that we've not actually added any reference to that library. So right now, the compiler doesn't even know it exists. So we do need to go ahead add that. So we've got references, right click, and then add reference.

And then, click on browse. And you need to go to your C drive program files and then Autodesk. So you can see at the top here, that's where I'm at. And let's find Revit 2020. Go to add ins and find Dynamo for Revit. And what we're looking for is a DLL file, a library file, called Revit nodes. And you'll find that inside a folder called Revit. So you just want to go to add ins, Dynamo for Revit, Revit, and inside here we'll find a library called Revit nodes. And we just want to add that. And then just say OK. So Revit nodes should automatically appear.

And going back to our alias, so once you've imported that library, we just want to do the following. We actually want to explicitly reference a type from that library. Now, I'll just type it out. And then after I've typed it out, I'll do a comparison actually viewing the API from Revit nodes, and I'll show you what I'm actually doing here. So I'd just like you to type the following. Type the word Revit, and operator elements, and operator again, element, and then just do a semicolon on the end. And you've just declared your first alias.

So you could see that we've got a namespace that's-- which Visual Studio quite conveniently is highlighting for us. And as soon as we declare a type, it then changed the color. So we're saying this alias is specifically pointing to this class from this namespace. And the compiler knows where the namespace is because we've just imported it.

So if I just double click on Revit nodes, it takes me to something called the object browser in Visual Studio. An object browser is basically your looking glass into any API. So you can look at Revit API, [INAUDIBLE] any language which you import, you're going to find this [INAUDIBLE] this library. So if we just expand Revit nodes, you'll find that there's actually a namespace called Revit.elements. And inside there, there's a class called element. This is literally what we're pointing our alias. It's that simple. So we just define a namespace. Namespace in Visual Studio always those curly brackets. And then classes are always these funny orange icons which you can see here.

OK, so inside our list, we do Dynamo element because this is the return type of our method. And we can finally declare the name of the method. And then, as it's a method, as you know, we've always got to open and close curved brackets. That's how we always declare a method. It's using curved brackets. And in the statement body of C#, again, is curly brackets.

So [INAUDIBLE] body is beneath the method that we've just declared, and curved brackets defines the method itself. Your [INAUDIBLE]. Has everyone compiled it? Have you got backup in case they haven't?

OK, we now need to define the input parameters for a method. So these are going to be the input ports that appear on the node after the zero touch import. So this is how the mechanism of zero touch actually works. It will read whatever your input parameter inside your method. Whatever name you give to each input parameter becomes the name that appears on the input port on the node. And similarly, the output is also declared by the return type for the method. So that, again, gives you more insights into the mechanism of zero touch import and what it actually means.

So the first input into this method is actually going to be what you create in Radu's session, which is the desk arrangement object. So as you know, with C# being a strongly typed language, we always have to declare the type before we can declare the variable name, or in this case, the input parameter. And for this, it's just going to be called desk arrangement.

OK, when we are reading all the desks that are stored in that desk arrangement, which as you know, at the moment, are abstract. We've just declared this class called desk, but we can't see anything yet. But that's what this method is actually going to do. It's going to return a bunch of desk instances for us. For that reason, we therefore want a Revit type. We want a family type. So when we actually instantiate new desk in instances, that is going to require a desk type. A bit like when you're using Revit normally. If you choose a desk or any kind of family, you always have to decide on what type you want.

And it's no different when you're making Revit API calls. In actual fact, it's what you do manually within Revit is now just what you do when you actually program. There's literally no difference whatsoever, which is why the rule stands that if you can do it in Revit manually, there's probably about a 99% you can't do it in the Revit API either.

So the Revit API doesn't give you, necessarily, like special magic powers. Depending on, perhaps, the user. It's more a means of enabling you to just automate and turn a repetitive or complex problem into something far more simple. Because you're getting the computer to do the hard work for you.

So for this, we need to input a type. But remember the rule of thumb, this is going to be input from Dynamo. So we all know it's wrapped here. Everything that comes in from Dynamo is always wrapped. For that reason, it's going to be a rapped Dynamo family type. So we also need to define an alias for this as well.

So at the top, let's just copy and paste that line. We'll call this one Dynamo family type. And just get rid of elements on the end of that. The operator [INAUDIBLE] family type. So you notice the suggestions that we're getting from IntelliSense. It's just unbelievably useful. And this is one of the big-- I mean, I'll be honest with you. It's kind of a dilemma between say Python and C#. Which one is easier? Generally it's C# because it's more verbose language. It's got a more steep learning curve.

But the farther you can be in [INAUDIBLE] whenever you C#, if perhaps you're developing quite a complex program that has maybe many classes or perhaps is solving a very complex problem. Generally speaking, C# might be the better option than Python in those cases. But both languages have got pros and cons, and they're both great. So I would say, if any language there you want to begin learning, Python is a good choice. It's a really good language.

OK, so we've got done the family type. So let's just provide that as the next input. The last input is just going to be the level where we actually want to host all of our desks on to. And again, this is going to come from Dynamo. So it's rapped, therefore, I'm going to create a new alias. And I'm just going to call that Dynamo level. And we'll add the alias in just a second.

So you just do Dynamo level and then just call it level. And then, we'll just add one more user statement at the top there.

OK, so your aliases should look like this by the time you're done. You should have three aliases at the top. Dynamo element, Dynamo family type, and Dynamo level. And they should all point to these specific types from Dynamo's Revit elements namespace. And this namespace lives inside the Revit nodes and library.

OK, so now we can start actually writing code. So remember what the objective here is we want to take that desk arrangement object from the previous session. We want to access all of the desk objects that are stored inside that desk arrangement. And then from the properties that are stored on each desk, for example, it's got a location point, it's also got dimensions. So a width and a length. We want to use the information to then generate these family instances within Revit.

So the first thing which we need to do is actually go back to referencing that boilerplate from the Python workshop. So if you guys just launch Visual Studio, or if you don't want to launch it, simply go back to the sample files, find Python, and open up the boilerplate. Either one is good. And we're just going to copy some lines of code out of this boilerplate. So believe it or not, there's actually even some crossovers with what we use in the boilerplate for Python, and also what we would typically copy from the boilerplate into C# as well.

So if you just open up the boilerplate. The lines of code which you want to copy into your code is that very first line at the top there. Just the document. So if you just copy that and paste it in. Remember this is a strongly typed language. So we can't get where it is declaring doc. And then equals, we have to declare the type. So in our case, it's just going to be document.

Again, I've already showed you this. You'll get input-- rather, you'll get hints or suggestions in terms of what user statements you haven't added but might need based on what you've just declared. So we click on this. Just be very careful here. You need to pick the right one. You need to make sure that you pick the one in the middle, which is Autodesk.Revit.db.document. So just make sure you pick that one.

And the document manager is actually coming from another library that you get with Dynamo that we haven't added to our solution yet. So this is actually coming from the Revit services library. So inside references, right click, add a reference. We should go to find it within the same folder, again, we do browse. So you just click on browse and then look in the same location as before. So Dynamo for Revit. And just find Revit services and then add. And then OK.

And when you hover over it now, you should be able to find the correct namespace from the [INAUDIBLE] library. So once you've done all of that, you should have the following. You should have the user statements for-- sorry, user directives for the Revit services systems, which is basically enabling us to use the document manager.

And then also, reference to the Revit API itself, which is this using directive at the top here. Yeah.

AUDIENCE: [INAUDIBLE]

TOM: What about in Visual Studio?

AUDIENCE: [INAUDIBLE]

TOM: All right. That is because-- sorry, yeah I've jumped the gun there. OK, so it's because I've already got the library available. So you guys need to import the compiled library from Radu's session. So if you're seeing desk arrangement in red like what I've got there, you just need to add that library into your references. So for that, if you just do add reference, browse, and what you want to do is browse the BIM folder from Radu's session. So I'll just show you that on my machine as well.

If you go straight to exercise four and go to complete-- or rather, if you should just check your-- if you create your own solution, OK? If you go to the location, I just said, you're not going to find anything in there. So you guys want to compile your own solutions. And when you compile, you'll find it inside the BIM debug folder. So inside here, you should find a DLL called Dynamodev.dll, and you want to add that as a reference into you solution.

And Radu, have we got that library available in case they haven't-- they can't compile?

[INTERPOSING VOICES]

PRESENTER: It's on the GitHub page. And the C# Fundamentals. There is a DLL straight up on GitHub. I've just pushed it. So in case you need it, we can download it straight from there.

TOM: Has anybody not got access to that file? So you should looking for Dynamodev.dll. If you haven't got it, then just raise your hand and I'll show you on screen now how you can get that file.

AUDIENCE: [INAUDIBLE]

TOM: OK, great. So mine is out of date. So if you guys got it in there, that's great. Load that file in, and we're good to go. Thanks, Radu. OK.

Right, so once you-- let me just add my reference back in again. Once you add that, and then you should no longer see the warning on that type. You should be able to just find it without any issue whatsoever. OK. I don't think I'm going to need your file. I think I actually just removed that reference and lost it.

OK, so we've got the document object declared. The next thing in which we need to do is open up a transaction. I didn't actually explain what the transaction is for in the Python section, but we did actually use one. And again, we're going to just copy that straight from the boilerplate.

So if you go back to your boilerplate, and there's just two lines of code, which we're going to copy. And it's just going to be the ones which say transaction manager, ensure, and transaction. And the one below says transaction done. So I just want you to copy those lines of code, and paste them into your brand new method.

And I want you to see the issue with these hashes. Because C# does not use hashes for comments, actually uses double slashes. [INAUDIBLE] C# it's like that. That'll restore that, or rather rectify that issue if it does kick up a fuss. So when you paste this in, remember, again, with anything C#, we always have to terminate each statement that we make with the same kernel. And then we just want to import the namespace that stores the transaction manager, which I believe also comes from remote services.

Districts and more transaction is very quickly. Whenever you create something inside Revit, you've probably noticed there are certain features which have a little tick box. So if you're creating a floor, you will have a little tick box in Revit. And you have either a red x or a green tick to either accept any modification or any creation of a floor. Revit will check, perhaps, [INAUDIBLE] a valid profile. And then if it's valid, it will then create the object for you. And if it's not, it wouldn't allow you to create it.

That's actually creating what's known as a transaction behind the scenes for you. And that transaction just protects Revit and the Revit database from any invalid changes that might break your model. And as a developer, whenever you make any of the three following things, a new element, a modification to an element, or deletion of an element, you always have to declare those actions between the lines of your transaction.

So you have to open up a transaction, make all of your changes, and then close the transaction to submit that to the database. And then, it's either going to fail or it's going to work if you've written your code correctly. So the transaction is just a context required by Revit to enable you to make modifications to its database. That's all it's there for.

And again, a bit like this morning when I said there are some things which you really just don't have to concern yourself with, and I would say one of them is transactions. If you always remember to copy these lines of code into your node, and if you always remember that if you're making any of those three specific actions that I just mentioned, and those actions are declared between your transactions, then you've got nothing to worry about.

You can just focus on the problem and just not even worry about all these nuances and formalities of the Revit API. But that's what the transactions there for. So we're opening at the top and we're closing at the bottom. And everything which we're about to do now is going to be declared within that transaction.

So the first thing in which we want to do is we want to create a family type that matches the properties of one of the desks inside the desk arrangement object. So the desk object that is stored inside-- the desk arrangement in which you created with Radu, that stores width and length. And I think it's actually just those two properties that are specific.

Now, in the real world, when you're using Revit, if you want to declare any family type, like diligent Revit users do, they always duplicate the type, give it a brand new name, and then they go ahead and use that type throughout the rest of their project. It's no different assigned to the Revit API context either. As I said, what you do inside Revit normally is what you should also be doing within the KPI context as well.

So for that reason, we want to not modify an existing desk type with the width and length properties of the desk, and so there's is going to be an arrangement object. What we want to do is just create a brand new one with a name that we give it. And for that, I've already created a class for you. And I don't want you to write this. What I'd rather you do is open up the data set. And I'd like you to just literally drag and drop it into your solution. So if you just go to S3 zero touch. Go to the completed project, and you'll find a folder called family type. And I'd like you just to drag and drop that in.

We could spend time running this all out. But really, it's going to serve little purpose because it really just reinforces concepts which you've already been taught through this exercise. So just for expediency and so we can just focus on the egress checking as well, I'd like you to just drag and drop this in there.

But all this class-- or rather, this namespace contains a class, and all this class does is create a brand new family type for you with a name that you give it. So just do the following. That for which this family type, drag it, drop it onto zero touch nodes, and it will now magically appear inside your solution. And you've just got one new class called family type creator. And this, by the way, is a private class, and it's got a internal static method.

So the reason why I've declared it as private, and I've declared the method as internal, is for the following reasons. First of all, I do not want this to appear as a node inside the Dynamo library. So as a developer, you can actually make a decision as to what you want the end user to have access to. And that's what you would use these access modifiers for. So public would always display in the library. Private and internal will never display in the library. And private can only be seen within the type.

So for example, I'll show you exactly what this means. If we could just go back to desk creator. And what we're going to do is we're going to call the family type creator method to generate any family type. So for this, I just want you to do the following. Declare a family symbol. We'll just call this new desk type. Equal sign. And we're just going to say family type creator.

If it can't find the type, just hover over it and just accept the user statement it suggests. And when we do that operator, there's one method that's called desk. And it just takes a family symbol, the desk arrangement object, and then a name for our new type. And this will actually appear inside Revit after we've complete this. So it is serving a purpose beyond our node.

OK, so the first input then is the family type. Now, we actually are parsing this family type into our method. It's at the top here. So we just want to copy that. And then parsing to there. There was a problem though. There is a rapped element, and this method here is actually calling a Revit API method, which is why one of the input parameters for the method that I have declared is a family symbol. And the simplest way to do that within C# is just give it to operator, and then just use this internal element.

In theory, you could do this with Python. But Python has a number of other methods which can be used. Named [INAUDIBLE] use this morning, which was like unwrap element. You can use those methods in C#, but you'll find that the vast majority of zero touch node developers who will use elements coming from Dynamo almost always use the internal element just as a property, which is what I always use as well.

So internal element is literally returning the family type as an unwrapped element. There was one other catch. This is basically returning the type. I'm going to have to get technical again. I'm sorry, but I'm going to have to do it. It's returning the type as its base class. So what I mean by that, if you go to the Revit API, you [INAUDIBLE] on screen and find family symbol, which is what we're currently declaring.

Did I say families? OK, sorry. I was going to check my code. OK, so declare a family symbol type. So we can find that inside the Revit API. In Visual Studio, if you expand all of these drop downs, there is a significance to this. It's basically representing this concept which, again, Radu I think, covered in his session of inheritance. So within when the C#-- well, actually, within a number of different programming languages. This concept of inheritance kind of works like how inheritance works with humans or any living thing.

When you inherit from another class, the class which inherits from the other class will basically have all of the same properties and all the same methods available to it. You don't have to declare them again. So for example, you might want to declare a class called, I don't know, human. And that human might have certain attributes like age, and I don't know, eye color.

And then, you might have two subclasses called male and female. And you might want to inherit from that human class. That means that you can then assign a eye color, and-- [INAUDIBLE] something, to those classes. And all you would need to do is modify the human class. And because of the inheritance, any modifications the top hierarchy will then feed down into the other classes.

That's what inheritance means. And that hierarchy is actually shown within Visual Studio. So whenever you use internal element, the only downside with internal element is it will always return the base class-- or rather, it will return the type as its base class. And what we need to do is we need to up cast it to its actual type. This might seem a bit confusing. This is a more technical C# stuff.

But the long and short of it is each class has its own unique set of properties. And the [INAUDIBLE] describing, by the way, does have a term. Sorry, I'm getting technical, but it's called polymorphism. And that's where you can declare certain types, and those types can be used across multiple different other types through inheritance. That's kind of the ins and outs of it.

We need to cast this element to the family symbol. And to cast, you just use curve brackets. It needs to be at the front of the type that you're declaring. And then you just simply input the type that you want to cast to. You can only cast, by the way, if the type which you're attempting to cast is from that class. So if it's not from that class or that type, then this will fail. But in our case, we know it's definitely family type. It's just being cast to its base class, to its element. We just need to up cast it to its actual type for the purposes of satisfying the inputs for this method.

OK, I know that was probably really confusing. The best thing to do is, if that is confusing, just-- with C#, get into it. And when you hit these barriers, you will end up having the time to really draw into what all this actually means. What casting means, what inheritance means, and [INAUDIBLE] slung together. But for today's workshop, let us leave it at that, and then look at the next input.

We want our desk arrangement object. This is really easy. We just literally pass the desk arrangement object. And the last in which it wants is a string to name the new desk type. And for this, we can just call it in quotes, because remember we're declaring a string, so strings are always declared within quotes. I'm just going to call AU Vegas 2019 desk. And then at the very end, a semicolon.

OK, so we call the family symbol sorted. That is basically going to take the properties from our desk object, and then output any symbol for us. OK, the next one which we need to do then is create our new desk instance. And for that, we're going to jump into the Revit API and actually have a look for a method that does this.

So if you double click on Revit API from your references-- by the way, if you haven't added this reference yet, I appreciate some of [INAUDIBLE]. I've got it in there. We just do add references again. Browse. And you just want to go to Autodesk Revit 2020. And the Revit API is going to be right down the bottom of the folder. And there's loads of files in there, so I'd suggest pressing R a few times on your keyboard. And it will basically take you all the way down to the DLLs at the very bottom.

And you're looking for the following DLL file. It's that one there. Just be careful because there are some other files in there that looks very similar like Revit API UI, which you might accidentally select. Just make sure that it's that file what you're adding into your solution.

OK, so once you add that, I've already got mine added, so I'm not going to add it again. And click OK. You'll then get the Revit API appearing in the menu here. One thing which I would suggest you do as well is just highlight all of those references apart from Dynamo dev. And where it says copy local, just set that to false. And all that prevents is the Revit API, which is a massive library, from being copied over into your BIM folder when you compile and you don't need it.

So whenever you execute any zero touch node, you do not need any of the references to Dynamo. So Revit nodes, Revit services, you don't need those DLLs as part of your zero touch node package. And you also need any references to the Revit API. And it just copies over a lot of junk that you don't need. So always set that to false.

OK, right so we've got that now configured. So if we just jump into the Revit API by double clicking on it, we go to the object browser. And what we're looking for is a method to create a new family instance, which to give you guys a big start, you'll find inside the Revit.creation namespace. There's a class called item factory banks. And inside there, you'll find a method for creating a new instance. And all we're looking for is a method for creating a new instance that has the following types of inputs.

A point, a host level, and, actually, that's pretty much all we need. And of course the family type. So that means the first two we can't use. And the reason, by the way, why we're seeing what appears to be like a duplicate here is a concept in programming known as overloads. And all an overload is the same method, which has been declared as you can see here. That it's all the same name.

And what distinguishes that method from the next is this input signature. So all of the input parameters and the method, they make it unique. And this is why is allowed within C#. Because if you had the same input parameters and the same name, you would not be able to compile that library. C# wouldn't allow you. So all we're looking for then is the overload, which has a point, a symbol, and a level. And the moment we're looking for I believe is this one here. So yeah, it is this one. Yep.

So we know that we're looking for a new family instance. There is a bit of a trick to this to actually call this method, which when I first started using Revit API, I really had to be taught it. So I'm going to teach you now. Because it's really counter intuitive. The reason why it's counter-intuitive is because the core of set of classes in the API, you'll find inside this namespace here. And what we need is a method from this other namespace. The question is, how can we actually declare or call this method given that we need the item factory based method?

Well, there is a quick way of doing this, and I'll teach you it now. It's to do the following. Declare the following. We're just going to say document factory. This is actually going to be an alias, so just bear with me. And we'll just call this doc factory, OK? Equals and then let's do doc.create.

And what that's doing is it's going to instantiate a brand new object for us. That object, confusingly, is also called a document. But that document is actually in a different namespace and it has a different purpose. A bit like you can have two people called Tom, but they're not the same person. And that is also true when it comes to programming on the condition they're in different namespaces spaces. So you can't declare a document inside one namespace, and then document again in another namespace and have them mean two different things.

So in this case, it's acceptable. And that document object inside the creation namespace has a different purpose. And that purpose is to basically just generate stuff, which is what we're doing here. So I've got document factory here. We don't always have to declare aliases, by the way. We can do a little trick within C#. We can also use the word var. And all var does is it tells the compiler, you work it out. This is what we want assigned to the variable, and you work out what it is based on what we've assigned to it.

It's a nice shortcut. But if you're perhaps just starting out with C#, you might find that strongly typing everything just helps with your learning curve. And then use var on the future. But I'll let you decide liking it. Everyone's different. I'll be honest with you, for 10 years I strongly typed everything. I never used var. It's only recently where I've started to get more comfortable using it. It's purely up to you.

But let's use it today just to keep things flank [INAUDIBLE] for today's workshop. OK, so now all we're going to do is we're going to iterate through all of the desks in our desk arrangement object using a four each loop, which is what Radu already showed you. And in that four each loop we're going to create all of our new desk instances. So let's declare a four each.

We're going to be accessing all of the desks, so the desk arrangement object. So I'm just going to copy that because that's actually going to be what we're going to be iterating over. And we just want to do the following. We just want to say, for each desk in deskarrangement.desks.

And if you get any warnings that it doesn't know what desk is, again, I think you know the trick now. Just hover over it and wait for it to suggest a user statement. Sorry, I keep saying statement. User directive. And just accept the one in which it suggests.

OK, so we won't do the following. We just want to create all of the input parameters for that method that we're going to use to create a new family instance with. So if you remember, the method, which we're going to use is the method that takes a point, a symbol, a host, which would be our level, and then just whether it's the structural type or not. So I'm just going to copy that.

This is more just to show you guys what we're actually doing. But in theory, this isn't strictly that necessary. But what we want to do is the following. We want to create our new desk. So if we just call it new desk. This, as you know, is going to be a family symbol-- sorry, a family instance. So we do need to just declare that before. So it should look something like this.

So family instance. New desk.

And that's what we're going to call this method. Now, this method we need to use the dock factory to call. So we have to do dock factory door new family instance. And that's the purpose of this dock factory object. Imagine this kind of like a little workman that's going to go off and do something useful for you. You give him an instruction, you're like, look, I want to create some new desks. Can you do it for me? And he's like, yeah sure. So you just give him that method and he's going to run off and do it for you. That's what that document factories actually doing it's just it's there to enable you to generate stuff inside the model.

OK, so now we can set about providing all of the inputs. The first thing which it wants is a location, and that is an xyz. An xyz is a point inside the Revit API. And if you remember, in your desk object, you have actually got a point. So if we were to do desk.point-- sorry, it's an origin I think. Yeah.

You'll notice that it's not actually xyz. You'll notice that it's actually a Dynamo geometry point, which of course, is not the same thing as an xyz. So we actually need to convert this point into a Revit API point before we can use the insiders method. So for that, we just want to convert it. And there is actually a method which we can use to do this and it's very convenient.

So first of all, we just want to do xyz. We can just call this origin point. Equals, and then, it's just going to be desk.origin. And then, the help method, which we want to use, which is I believe coming from-- I think it's the proto geometry library. Just due two xyz. And that's going to convert that Dynamo point into a Revit API xyz.

Again, sorry we've not added the [INAUDIBLE] library either. So we just need to add that. So again, just inside of references, add a reference. And if you just browse-- we just want to go back to the add ins holder on Revit 2020. Find Dynamo forever. And inside that folder, you're going to find a library called proto geometry. So just to add that library there into your solution.

So yeah, it's in Dynamo forever. And as soon as you add that, then all these issues are going to go away, OK? Other than-- just adding the reference to the [INAUDIBLE] library. OK, so your syntax at this point should look a bit like this. You should see origin point and your calling to xyz on a desk origin. That's going to be passed as the first input into this method. So that's what [INAUDIBLE] the first input. The next one is in what's a family symbol. We've already called that, it's up here. So we just need to parse that in.

It wants a host, which as you know, is going to be that level that we've already provided as an input into our method. So again, we just copy it and we just do internal element. We'll also need to cast this as well to a level as well. But the level we have to do with the family type. So if we do internal element, we have to cast this to a level. Otherwise, it won't work.

Because, as I said, internal element returns the base class element, which is not the same thing as the subclass element, which is what we actually want to target. And the structural type is actually just from enum. And if you just do the .operator on the [INAUDIBLE] type, you might fully qualify like what I've got here with the namespace, or rather just import this namespace using directive at the top there.

But the operator, and this is a non-starter was just a desk. So we can just define it as nonstructural. You might be thinking, well, that's really weird. We're creating a desk. Why do we even have to define the structural type? This is just the Revit API for you. Those methods can be used to place any family type. So when you're placing a family type that perhaps gives Revit structure, then that implies a meaning. In our case, when placing desks it's got no meaning whatsoever.

But I guess the utility of having one method that can be used in many different ways overrides the fact that it's just one input which we just have to provide. So we just say non-structural.

OK, so now we create the new desk. The next in which we need to do is the following. We just needed to store this new family instance, this new desk, in a list, wrap it, and then we just want to return it. So above our four each we want to, of course, declare a list. So if we just do list share forms inside here, we're just going to store some Dynamo elements.

We're just going to use that alias again as a Dynamo element. We're just going to call this new desks. And what we want to assign to this is, of course, just a new empty list, which is achieved quite simply just by doing the following. So new list, and it's the same type again. So you can see the difference between Python and C#. C# is way more verbose. And there's almost like repetition if you look at what we're declaring here, which you might find a bit off putting. But it's just the way that C# works. And it does have a lot of benefits as well, particular when you're developing complex programs.

OK, so new desk then. We can just type here. .operator and C# uses the word-- sorry, the method add on list to add elements into the list. And we just want to provide the new desk into the list. And we can call 2DS type on this as well. So it's no different from Python.

The benefit here is, of course, if it gives you the method, by the way, I'll unwrap a 2DS time keeper because it will avoid clashes with the Revit API. So 2DS type parsing the new desk. And you can see there-- the great thing about being in Visual Studio is it's telling us what that input parameter for this method is, whether it's Revit earned or not. It's not Revit earned because we're generating it in our code. So of course, the input here should be false. So your code should look something like that by the time you're done.

And the last thing you need to do just to keep this method happy is return the new desks. And in C#, the key word that you're looking for is return. And then you always declare what you want to return after the return keyword like that. So that method is going to take our desk arrangement object from Radu's session. It's going to extract all the desks that are stored in that arrangement. It's going to use the origin points from each of those desks to define the origin points of any family instances.

And out of this method, we're going to have a bunch of Revit family instances that are then representing those abstract desktop objects that you just did with Radu in the previous session. So I believe we can just go ahead and compile this. And then, throw Radu's onto the graph, throw [INAUDIBLE] the graph, and we should be able to see a bunch of desks. So if you just get a build and then build solution.

So if everything is correct, you should see that it succeeded. How long have we got? Radu, how long have we got? OK. OK, right so if everyone's compiled, let's just open up Revit 2020. OK, thanks.

We're going to be using that same sample file from this morning's session. So if you've not got that file open, if you just open up that file. And it is stored inside the Python folder, which I know is not the best place to put it, but it's in there. So if you just open up that file from this morning.

One of the things you can do [INAUDIBLE], if you click on start, I can't remember if I can figure this [INAUDIBLE] do this, which I apologize for if that is the case. But generally, what you can do is you can click start, that I'll compile-- OK, it won't work because it's not configured. When you click start you'll compile your project and then launch Dynamo for you. Sorry, it will launch Revit for you, then you can launch Dynamo.

But I've got another handout which you'll find on the Dynamo forum called [INAUDIBLE] zero touch no development. And all of the information is in there for configuring Visual Studio to basically make your life a bit easier when it comes to compiling.

But yeah, it doesn't matter too much. So we just opened up Dynamo. We're actually going to import our library. So why I find this quite convenient is after you've built your project, generally, what you'll find is a location of where the DLL is actually stored. So in my case, it's this mass mailing address here. So if I jump back into Dynamo, do new, and then if I add it into the project or then mine is already showing up from a previous session.

But when you add it, you should now see a DLL called desk creator with a method called generate. And you should see this. If you see two nodes, then that's what I was discussing when the session first started. There's a public constructor that gets created on your behalf by C# when you compile. And it will appear in the menu. This is actually referencing a different library. So if you just bear with me a second. I'm going to just restart this.

Has anyone managed to import it, and have they got node? No? OK, I'll show you on my screen. [INAUDIBLE]. OK, I can't just show you my library. But if you guys have managed to import your DLLs, then what you're going to find is under family instance, there's going to be two different nodes. One of them is going to be the constructor, and the other one's going to be your generate method. What you would need to do is the following. Because you don't want that constructor to appear in the library because it's redundant. It's doing nothing for you. So what you need to do is the following.

[INAUDIBLE] declare the constructor, and that's all you need to do. So all you're doing is you're actually explicitly declaring the constructor for this class. But crucially, you're defining it as private. So that while the constructor is still going to get generated when you compile your code, all that means is the node is not going to appear within the library when you import it.

I can't show you this because this is referencing a different library that I generated before we started today's session. So it's a bit unfortunate. And I don't waste any time removing this and reloading Revit again. But you would see it in there.

So what we need to do now then is use Radu's-- or rather, all the information which you create with Radu this morning to parse the desk arrangement object. And then, from there, we can then basically create all of our desks. So I'm just going to load Radu's library now.

PRESENTER: You guys should have no issues loading this because you've compiled it on your machines, and you had it running earlier. But Tom is catching up. So I'll go to 2019.

TOM: It should work now. I think it was pulling in some old reference, which is why it wasn't loading on my machine. But on your guy's machines, they should work without an issue.

Five minutes. The egress we'll have to skip.

Right [INAUDIBLE]

It wasn't working. And then, I was trying to remove and I was in a different location.

PRESENTER: You take a break and I can get it to work in the break room?

TOM: [INAUDIBLE] reference library. [INAUDIBLE]

PRESENTER: In case you guys are wondering, when we write code for these things, you usually ended up spending about 60% of your time fixing things not relating to code. So this is quite representative of the actual experience of coding, which is getting your machine to behave.

TOM: Yeah, I think we should be back on track now. So yeah, the issue I had is I've compiled this library a few times in the lead up to this workshop. Those files were just interfering with the files which we're just doing now. So I've just removed all of that information out of Dynamo, and it should work now.

Has anyone else managed to successfully import their DLLs in any case? No? OK, just watch here, then I'll show you what happens. And as you know, all these files are on GitHub. So if you just want to download what we've developed and compile this test yourself. And if you want to-- well, I mean, do whatever you like with them. Reverse engineer them or read through these exercises, then by all means, you can do that.

OK, so that's my desk create generate node. All I need to do now then is provide the family type and the level. So for this, I'll just do ordinary nodes. Family type, choose the desk. So for this, I'm just going to use out of the box desks. So I'm just going to find-- I don't know, down order. Sorry, how many types? The level as well that I want to place these desks onto. Let's go level two.

And then, the last which we need to do is provide the desk arrangement object, which as you know, is going to come from the Dynamo dev. So for that-- thanks. Now we've got desk arrangement. So using the constructor parse a bunch of desks and the surface. So for the surface, we can just actually [INAUDIBLE] that [INAUDIBLE] room. So I'm in level two now. I'll just pick any room. Down, that's fine. I'm going to convert this room into a surface.

Why is that? Thanks. Yeah, sorry. Radu was just mentioning where his desk [INAUDIBLE]. So I don't need any of that. OK, fingers crossed they should hopefully work. I didn't say that. OK, doesn't like it has worked. Oh, I know why. It's because it's not visible in SVA. So if I change the visibility, I should see all the desks. Hopefully.

PRESENTER: Stephanie Kramer.

TOM: Yeah, I'll switch to level one.

Is Stephanie filming?

[INAUDIBLE] is under the floor. [INAUDIBLE]

All right, cool. Yeah, we're going to take a break. We'll figure this one out either under the host level or something. It's [INAUDIBLE] the desk underneath the floor. But they're being generated. That's the good news. We just need to find out where they are being generated.

So we're going to a break now. We'll find all the issues. And then when you all return, we'll show you the end result.

PRESENTER: So end result after the break. And then after the break, we also do the last session, which is on extensions, which is hacky cool stuff where we break Dynamo completely. If we haven't broken it enough for today.

______
icon-svg-close-thick

Preferencias de cookies

Su privacidad es muy importante para nosotros y esperamos que su experiencia sea la mejor posible. Cuando recopilamos los datos sobre el uso que hace de este sitio, lo hacemos para personalizar la información y para crear aplicaciones.

¿Podemos recopilar y usar sus datos?

Obtenga más información acerca de los servicios de terceros que usamos y de nuestra Declaración de privacidad.

Estrictamente necesarias: Obligatorias para que nuestro sitio funcione y podemos ofrecerle nuestros servicios

Estas cookies nos permiten registrar sus preferencias o su información de inicio de sesión, responder a sus solicitudes o gestionar la compra de los artículos de su carrito de la compra.

Mejora de la experiencia: Nos permite mostrar la información relevante

Estas cookies nos permiten ofrecerle funcionalidades y personalización mejoradas. Las podemos establecer nosotros, asi como los proveedores terceros cuyos servicios se utilizan para proporcionar información y experiencias adaptadas a sus necesidades. Si no acepta estas cookies, es posible que todos estos servicios o parte de ellos no estén disponibles.

Personalización de la publicidad: Nos permite ofrecer publicidad dirigida

Estas cookies recopilan datos sobre usted en función de sus actividades e intereses para mostrar los anuncios relevantes y realizar un seguimiento de su eficacia. Al recopilar estos datos, los anuncios que le mostraremos se adaptarán mejor a sus intereses. Si no acepta estas cookies, la publicidad que verá será de menos interés para usted.

icon-svg-close-thick

SERVICIOS DE TERCEROS

Obtenga más información sobre los servicios de terceros que utilizamos en cada categoría, y sobre el uso que hacemos de los datos que recopilamos de usted en Internet.

icon-svg-hide-thick

icon-svg-show-thick

Estrictamente necesarias: Obligatorias para que nuestro sitio funcione y podemos ofrecerle nuestros servicios

Qualtrics
Utilizamos los servicios de Qualtrics para que pueda enviarnos sus comentarios a través de encuestas o formularios de Internet. Puede participar en una encuesta tras ser seleccionado al azar o puede decidir enviarnos sus comentarios voluntariamente. Recopilamos datos para comprender mejor la actividad que ha llevado a cabo antes de rellenar una encuesta. Esto nos ayuda a solucionar problemas que haya podido encontrar. Política de privacidad de Qualtrics
Akamai mPulse
Utilizamos los servicios de Akamai mPulse para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Akamai mPulse
Digital River
Utilizamos los servicios de Digital River para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Digital River
Dynatrace
Utilizamos los servicios de Dynatrace para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Dynatrace
Khoros
Utilizamos los servicios de Khoros para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Khoros
Launch Darkly
Utilizamos los servicios de Launch Darkly para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Launch Darkly
New Relic
Utilizamos los servicios de New Relic para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de New Relic
Salesforce Live Agent
Utilizamos los servicios de Salesforce Live Agent para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Salesforce Live Agent
Wistia
Utilizamos los servicios de Wistia para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Wistia
Tealium
Utilizamos los servicios de Tealium para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Tealium
Upsellit
Utilizamos los servicios de Upsellit para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Upsellit
CJ Affiliates
Utilizamos los servicios de CJ Affiliates para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de CJ Affiliates
Commission Factory
Utilizamos los servicios de Commission Factory para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Commission Factory
Google Analytics (Strictly Necessary)
Utilizamos los servicios de Google Analytics (Strictly Necessary) para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Google Analytics (Strictly Necessary)
Typepad Stats
Utilizamos los servicios de Typepad Stats para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Typepad Stats
Geo Targetly
Usamos Geo Targetly para dirigir a los visitantes del sitio web a la página web más adecuada y/u ofrecer contenido personalizado según su ubicación. Geo Targetly utiliza la dirección IP de los visitantes del sitio web para determinar la ubicación aproximada del dispositivo de los mismos. Esto ayuda a garantizar que los visitantes vean el contenido en el que probablemente es su idioma local.Política de privacidad de Geo Targetly
SpeedCurve
Utilizamos SpeedCurve para supervisar y medir el rendimiento de su experiencia con el sitio web midiendo los tiempos de carga de la página web, así como la capacidad de respuesta de elementos posteriores como imágenes, secuencias de comandos y texto.Política de privacidad de SpeedCurve
Qualified
Qualified is the Autodesk Live Chat agent platform. This platform provides services to allow our customers to communicate in real-time with Autodesk support. We may collect unique ID for specific browser sessions during a chat. Qualified Privacy Policy

icon-svg-hide-thick

icon-svg-show-thick

Mejora de la experiencia: Nos permite mostrar la información relevante

Google Optimize
Utilizamos los servicios de Google Optimize para probar nuevas características en nuestros sitios y ofrecerle una experiencia personalizada con esas características. Para ello, recopilamos datos de comportamiento mientras visita nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk, entre otros. Puede que acceda a una versión diferente de nuestros sitios debido a las pruebas de características que hacemos, o que vea contenido personalizado en función de su perfil de visitante. Política de privacidad de Google Optimize
ClickTale
Utilizamos los servicios de ClickTale para entender mejor en qué áreas de nuestros sitios puede experimentar problemas. Grabamos las sesiones para ver cómo interactúa con nuestros sitios, incluido cualquier elemento de las páginas. Su información personal identificable se enmascara y no se recopila. Política de privacidad de ClickTale
OneSignal
Utilizamos los servicios de OneSignal para mostrar publicidad digital en sitios respaldados por OneSignal. Los anuncios se basan tanto en datos de OneSignal como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que OneSignal haya recopilado de usted. Utilizamos los datos que suministramos a OneSignal para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de OneSignal
Optimizely
Utilizamos los servicios de Optimizely para probar nuevas características en nuestros sitios y ofrecerle una experiencia personalizada con esas características. Para ello, recopilamos datos de comportamiento mientras visita nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk, entre otros. Puede que acceda a una versión diferente de nuestros sitios debido a las pruebas de características que hacemos, o que vea contenido personalizado en función de su perfil de visitante. Política de privacidad de Optimizely
Amplitude
Utilizamos los servicios de Amplitude para probar nuevas características en nuestros sitios y ofrecerle una experiencia personalizada con esas características. Para ello, recopilamos datos de comportamiento mientras visita nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk, entre otros. Puede que acceda a una versión diferente de nuestros sitios debido a las pruebas de características que hacemos, o que vea contenido personalizado en función de su perfil de visitante. Política de privacidad de Amplitude
Snowplow
Utilizamos los servicios de Snowplow para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Snowplow
UserVoice
Utilizamos los servicios de UserVoice para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de UserVoice
Clearbit
Clearbit permite el enriquecimiento de datos en tiempo real para proporcionar una experiencia personalizada y relevante a nuestros clientes. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Política de privacidad de Clearbit
YouTube
YouTube es una plataforma de uso compartido de videos que permite a los usuarios ver y compartir vídeos insertados en nuestros sitios web. YouTube proporciona métricas de audiencia sobre el rendimiento de los vídeos. Política de privacidad de YouTube

icon-svg-hide-thick

icon-svg-show-thick

Personalización de la publicidad: Nos permite ofrecer publicidad dirigida

Adobe Analytics
Utilizamos los servicios de Adobe Analytics para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Adobe Analytics
Google Analytics (Web Analytics)
Utilizamos los servicios de Google Analytics (Web Analytics) para recopilar datos acerca de su actividad en nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Utilizamos estos datos para poder medir el rendimiento de nuestro sitio web y determinar el grado de facilidad de su experiencia en Internet a fin de mejorar nuestras características. También empleamos sistemas avanzados de análisis para optimizar su experiencia con los servicios de correo electrónico, atención al cliente y ventas. Política de privacidad de Google Analytics (Web Analytics)
AdWords
Utilizamos los servicios de AdWords para mostrar publicidad digital en sitios respaldados por AdWords. Los anuncios se basan tanto en datos de AdWords como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que AdWords haya recopilado de usted. Utilizamos los datos que suministramos a AdWords para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de AdWords
Marketo
Utilizamos los servicios de Marketo para enviarle contenido más relevante y oportuno por correo electrónico. Para ello, recopilamos datos sobre su actividad en Internet y el modo en que interactúa con los correos electrónicos que enviamos. Los datos recopilados pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, la tasa de apertura de correos y los vínculos seleccionados, entre otros. Puede que combinemos estos datos con datos obtenidos a través de otras fuentes a fin de mejorar su experiencia de compra o con el servicio de atención al cliente, además de ofrecerle contenido más relevante en función de procesos avanzados de análisis. Política de privacidad de Marketo
Doubleclick
Utilizamos los servicios de Doubleclick para mostrar publicidad digital en sitios respaldados por Doubleclick. Los anuncios se basan tanto en datos de Doubleclick como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Doubleclick haya recopilado de usted. Utilizamos los datos que suministramos a Doubleclick para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Doubleclick
HubSpot
Utilizamos los servicios de HubSpot para enviarle contenido más relevante y oportuno por correo electrónico. Para ello, recopilamos datos sobre su actividad en Internet y el modo en que interactúa con los correos electrónicos que enviamos. Los datos recopilados pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, la tasa de apertura de correos y los vínculos seleccionados, entre otros. Política de privacidad de HubSpot
Twitter
Utilizamos los servicios de Twitter para mostrar publicidad digital en sitios respaldados por Twitter. Los anuncios se basan tanto en datos de Twitter como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Twitter haya recopilado de usted. Utilizamos los datos que suministramos a Twitter para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Twitter
Facebook
Utilizamos los servicios de Facebook para mostrar publicidad digital en sitios respaldados por Facebook. Los anuncios se basan tanto en datos de Facebook como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Facebook haya recopilado de usted. Utilizamos los datos que suministramos a Facebook para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Facebook
LinkedIn
Utilizamos los servicios de LinkedIn para mostrar publicidad digital en sitios respaldados por LinkedIn. Los anuncios se basan tanto en datos de LinkedIn como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que LinkedIn haya recopilado de usted. Utilizamos los datos que suministramos a LinkedIn para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de LinkedIn
Yahoo! Japan
Utilizamos los servicios de Yahoo! Japan para mostrar publicidad digital en sitios respaldados por Yahoo! Japan. Los anuncios se basan tanto en datos de Yahoo! Japan como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Yahoo! Japan haya recopilado de usted. Utilizamos los datos que suministramos a Yahoo! Japan para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Yahoo! Japan
Naver
Utilizamos los servicios de Naver para mostrar publicidad digital en sitios respaldados por Naver. Los anuncios se basan tanto en datos de Naver como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Naver haya recopilado de usted. Utilizamos los datos que suministramos a Naver para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Naver
Quantcast
Utilizamos los servicios de Quantcast para mostrar publicidad digital en sitios respaldados por Quantcast. Los anuncios se basan tanto en datos de Quantcast como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Quantcast haya recopilado de usted. Utilizamos los datos que suministramos a Quantcast para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Quantcast
Call Tracking
Utilizamos los servicios de Call Tracking para proporcionar números de teléfono personalizados como parte de nuestras campañas. De este modo, podrá acceder más rápido a nuestros agentes y ayudarnos a medir mejor nuestro rendimiento. Puede que recopilemos datos acerca de su actividad en nuestros sitios en función del número de teléfono facilitado. Política de privacidad de Call Tracking
Wunderkind
Utilizamos los servicios de Wunderkind para mostrar publicidad digital en sitios respaldados por Wunderkind. Los anuncios se basan tanto en datos de Wunderkind como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Wunderkind haya recopilado de usted. Utilizamos los datos que suministramos a Wunderkind para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Wunderkind
ADC Media
Utilizamos los servicios de ADC Media para mostrar publicidad digital en sitios respaldados por ADC Media. Los anuncios se basan tanto en datos de ADC Media como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que ADC Media haya recopilado de usted. Utilizamos los datos que suministramos a ADC Media para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de ADC Media
AgrantSEM
Utilizamos los servicios de AgrantSEM para mostrar publicidad digital en sitios respaldados por AgrantSEM. Los anuncios se basan tanto en datos de AgrantSEM como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que AgrantSEM haya recopilado de usted. Utilizamos los datos que suministramos a AgrantSEM para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de AgrantSEM
Bidtellect
Utilizamos los servicios de Bidtellect para mostrar publicidad digital en sitios respaldados por Bidtellect. Los anuncios se basan tanto en datos de Bidtellect como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Bidtellect haya recopilado de usted. Utilizamos los datos que suministramos a Bidtellect para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Bidtellect
Bing
Utilizamos los servicios de Bing para mostrar publicidad digital en sitios respaldados por Bing. Los anuncios se basan tanto en datos de Bing como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Bing haya recopilado de usted. Utilizamos los datos que suministramos a Bing para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Bing
G2Crowd
Utilizamos los servicios de G2Crowd para mostrar publicidad digital en sitios respaldados por G2Crowd. Los anuncios se basan tanto en datos de G2Crowd como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que G2Crowd haya recopilado de usted. Utilizamos los datos que suministramos a G2Crowd para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de G2Crowd
NMPI Display
Utilizamos los servicios de NMPI Display para mostrar publicidad digital en sitios respaldados por NMPI Display. Los anuncios se basan tanto en datos de NMPI Display como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que NMPI Display haya recopilado de usted. Utilizamos los datos que suministramos a NMPI Display para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de NMPI Display
VK
Utilizamos los servicios de VK para mostrar publicidad digital en sitios respaldados por VK. Los anuncios se basan tanto en datos de VK como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que VK haya recopilado de usted. Utilizamos los datos que suministramos a VK para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de VK
Adobe Target
Utilizamos los servicios de Adobe Target para probar nuevas características en nuestros sitios y ofrecerle una experiencia personalizada con esas características. Para ello, recopilamos datos de comportamiento mientras visita nuestros sitios. Estos datos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado, su dirección IP o ID de dispositivo, y su ID de Autodesk, entre otros. Puede que acceda a una versión diferente de nuestros sitios debido a las pruebas de características que hacemos, o que vea contenido personalizado en función de su perfil de visitante. Política de privacidad de Adobe Target
Google Analytics (Advertising)
Utilizamos los servicios de Google Analytics (Advertising) para mostrar publicidad digital en sitios respaldados por Google Analytics (Advertising). Los anuncios se basan tanto en datos de Google Analytics (Advertising) como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Google Analytics (Advertising) haya recopilado de usted. Utilizamos los datos que suministramos a Google Analytics (Advertising) para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Google Analytics (Advertising)
Trendkite
Utilizamos los servicios de Trendkite para mostrar publicidad digital en sitios respaldados por Trendkite. Los anuncios se basan tanto en datos de Trendkite como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Trendkite haya recopilado de usted. Utilizamos los datos que suministramos a Trendkite para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Trendkite
Hotjar
Utilizamos los servicios de Hotjar para mostrar publicidad digital en sitios respaldados por Hotjar. Los anuncios se basan tanto en datos de Hotjar como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Hotjar haya recopilado de usted. Utilizamos los datos que suministramos a Hotjar para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Hotjar
6 Sense
Utilizamos los servicios de 6 Sense para mostrar publicidad digital en sitios respaldados por 6 Sense. Los anuncios se basan tanto en datos de 6 Sense como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que 6 Sense haya recopilado de usted. Utilizamos los datos que suministramos a 6 Sense para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de 6 Sense
Terminus
Utilizamos los servicios de Terminus para mostrar publicidad digital en sitios respaldados por Terminus. Los anuncios se basan tanto en datos de Terminus como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que Terminus haya recopilado de usted. Utilizamos los datos que suministramos a Terminus para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de Terminus
StackAdapt
Utilizamos los servicios de StackAdapt para mostrar publicidad digital en sitios respaldados por StackAdapt. Los anuncios se basan tanto en datos de StackAdapt como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que StackAdapt haya recopilado de usted. Utilizamos los datos que suministramos a StackAdapt para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de StackAdapt
The Trade Desk
Utilizamos los servicios de The Trade Desk para mostrar publicidad digital en sitios respaldados por The Trade Desk. Los anuncios se basan tanto en datos de The Trade Desk como en datos de comportamiento que recopilamos mientras visita nuestros sitios. Los datos que recopilamos pueden incluir páginas que haya visitado, versiones de prueba que haya iniciado, vídeos que haya reproducido, compras que haya efectuado y su dirección IP o ID de dispositivo. Esta información puede combinarse con los datos que The Trade Desk haya recopilado de usted. Utilizamos los datos que suministramos a The Trade Desk para personalizar aún más su experiencia con la publicidad digital y mostrarle anuncios más relevantes. Política de privacidad de The Trade Desk
RollWorks
We use RollWorks to deploy digital advertising on sites supported by RollWorks. Ads are based on both RollWorks data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that RollWorks has collected from you. We use the data that we provide to RollWorks to better customize your digital advertising experience and present you with more relevant ads. RollWorks Privacy Policy

¿Está seguro de que desea disfrutar de una experiencia limitada en Internet?

Nos gustaría proporcionarle una experiencia óptima. Si selecciona “Sí” para las categorías que aparecían en la pantalla anterior, recopilaremos y utilizaremos sus datos para personalizar su experiencia y desarrollar mejores aplicaciones. Para cambiar su configuración en cualquier momento, consulte nuestra declaración de privacidad

Su experiencia. Su elección.

Nos importa su privacidad. Los datos que recopilamos nos ayudan a comprender la forma en que se usan nuestros productos, la información que le podría interesar y lo que podemos mejorar para que su interacción con Autodesk le resulte más provechosa.

¿Podemos recopilar y usar sus datos para adaptar su experiencia?

Explore las ventajas de una experiencia personalizada mediante la administración de la configuración de privacidad de este sitio o visite nuestra Declaración de privacidad para conocer mejor las distintas opciones.