AU Class
AU Class
class - AU

Learning Lab: Extend the Viewer

このクラスを共有
ビデオ、プレゼンテーション スライド、配布資料のキーワードを検索する:

説明

Endless possibilities, that’s what we can do with the Forge Viewer. Want to learn the basics? This class will explore how to create custom extensions to interact with the Viewer. To attend this class, make sure to have a running Forge application with the Viewer, or you should have attended either "Upload and View Your Models with Forge" or "Connect to Fusion Team and BIM 360 Data.” Bring your own laptop or use the lab. This class requires basic knowledge of JavaScript.

主な学習内容

  • Discover the basics of Forge
  • Learn how to interact with the Viewer
  • Learn how to manipulate elements
  • Learn tips and tricks to extend the Viewer

スピーカー

  • Petr Broz さんのアバター
    Petr Broz
    Petr is a developer advocate at Autodesk. After joining the company in 2011 as a software developer, he contributed to a range of web-based platforms and applications such as 123D Online or Tinkercad. In 2018 he transitioned into the developer advocacy team where he has been helping customers create cutting-edge solutions using Autodesk Platform Services, with a primary focus on visualization and AR/VR.
  • Denis Grigor
    I like to know how everything works under the hood, so I am not afraid of low-level stuff like bits, buffers, pointers, stack, heap, threads, shaders and of course Math. Now I am slowly specializing on 3D for Web, from raw WebGL to libraries and frameworks with different levels of abstractions. I like to speak C++ (mostly with modern dialect) and Python, but I also started to like my new "tool” named Go.
Video Player is loading.
Current Time 0:00
Duration 0:00
Loaded: 0%
Stream Type LIVE
Remaining Time 0:00
 
1x
  • Chapters
  • descriptions off, selected
  • subtitles off, selected
      Transcript

      PETR BROZ: I think we can get started. Thank you very much for coming to our lab, Extend the Viewer, where we want to show you a bit more how-- give you some more information about how you can extend the viewer experience. So once you're done with translating your models in the back end and getting the models back into your viewer, the viewer itself offers a set of APIs, as well, that you can use to customize the behavior and the user experience.

      The quick introduction-- my name is Petr Broz. I'm a Forge developer advocate. I've been working on different web projects with Autodesk, and as a late as my latest role, I'm helping other developers, such as you, build cool stuff with Forge.

      And I'm joined here today by Dennis Grigor, my colleague, my lab assistant. So if you have any questions, maybe individual, technical questions not really for the entire group, feel free to reach out to Dennis or to Shweta Nagaraja, as well, my colleague over there in the back. So feel free. Reach out. They're both extremely skilled and well-versed in Forge, both client and server side, and I'm sure they'll be happy to help.

      Before we start, I want to make sure that we are all level set. So show of hands, if you could help me out here-- how many of you are coming with an existing project that they built in one of the previous labs today? Do any of you have existing projects that they want to continue on? Or most of you are basically coming as blank slate. You want to start from scratch. Is that correct?

      That's good to know. So we'll do a super quick setup because, again, this is something that was covered in the previous labs. We want to mainly focus on really showing you how you can extend the viewer once you're all set up. But that's fine. We can get set up pretty quickly here.

      So for those of you who are not set up, I would ask you to open Visual Studio Code. You should have it installed on your machines. This is going to be our code environment that we're going to work with.

      AUDIENCE: Previous labs are recorded?

      PETR BROZ: I believe they are, yes. Yes, they will be available, as well, as far as I know, slides with audio. So again, for those of you who don't have a project to start with, I would recommend-- I think it would be good that we all start with the same code. Again, it doesn't really matter that much what the starting point is in terms of the back end implementation because we're going to be modifying the client side all the time anyway.

      But just to make sure that we're, again, on the same page, in case you run into any technical issues on the back end side so that we know what stack you're running, I would ask all of you to go to GitHub and find a Learn Forge GitHub repo. So one way would be if you just go online and Google "GitHub" and my name, "Petr Broz," and "Learn Forge view models," I believe.

      Or if you can-- I hope you can see the text here clearly, the first link that I minified. So if you go to https://bit.ly/37eFFii-- I guess it might be--

      AUDIENCE: So where is the-- where are the [INAUDIBLE]?

      PETR BROZ: These [INAUDIBLE]-- you don't have them yet. I'd like to send you to get GitHub, where you can download the code that's going to be our starting point. So again, maybe an easier way-- I hope I'm not going to stop anyone here. Simply go online and Google for GitHub "Petr Broz"-- P-E-T-R B-R-O-Z is my name-- and "Learn Forge."

      And hopefully-- I don't see my link here, which may complicate things a little bit.

      AUDIENCE: It's the third one.

      PETR BROZ: Was it the third one? This is also just GitHub Petr Broz. But anyway, if you're not able to use the bit.ly, the minified link, , just follow me here on GitHub. This is my name. This is my username on GitHub, just Petr Broz. This is how you'll find my account with all my Git repositories.

      And on here, on my page, if you go to Repositories and just search for "Learn Forge view models"-- this is going to be a project that we're going to be starting with. So the project is called learn.forge.viewmodels. It's basically forked from the official GitHub repository that we have on our official GitHub organization, Autodesk Forge, but I've added a couple more things to help you guys follow along the way and in case anybody starts falling behind. All the code changes that we're going to build today are all available in that Git repository.

      So once you are on the learn.forge.viewmodels GitHub repo, I would just ask you to switch-- here, using the dropdown branch, switch to nodejs branch, and this is going to be our starting point. So now we're looking at our Git repository, learn.forge.viewmodels, the standard sample that we use in our Learn Forge tutorial. And we switched to a branch called nodejs, so we're all going to be starting with a nodejs implementation of that sample.

      That sample has other programming languages, as well, in different branches. But here, for the sake of consistency so that if there are any questions, any problems we know what we're dealing with, we're going to use nodejs. Once you're here, I would ask you to use the green button to download the source code, this current state of the source code. Download it as a zip file, and uncompress it somewhere on your local drive.

      And if you have any questions, any problems along the way, let us know. Either reach out to me or to Dennis, or Shweta, or Augusto.

      AUDIENCE: [INAUDIBLE]

      PETR BROZ: Are we all good? Silence, I guess that means good. So next step, we're going to-- back in Visual Studio Code, you can use the-- I guess, if you're on Windows, it'll look slightly differently.

      But you should see a couple of options on the front page, including Open Folder. And if you don't see it on the Welcome page, you should be able to find it in the File menu, Open Folder. It's basically a way for you to navigate to that folder, to the source code that you just downloaded and unzipped.

      So let me do that here. I already have my code base prepared, but let me follow along with you here, as well, so that I can show you the rest of the process. So I'm going to navigate to my downloaded and uncompressed folder, and it should look-- it should look like this.

      So in the sidebar, if you switch to the very top icon here, the File Explorer, you should see some source code for the Learn Forge tutorial. Everyone good? Everybody has Visual Studio Code open in that folder? Awesome, very good.

      Now, next question-- how many of you have created Forge application credentials? Perfect. So those of you who don't-- there are only a couple of you, I've noticed. So if you don't have Forge credentials, please talk to Shweta, or Dennis, or Augusto. They'll show you how you can create.

      AUDIENCE: [INAUDIBLE]

      PETR BROZ: Raise hands. Who needs help with creating Forge application credentials? They'll be right with you. And for everybody else, I would suggest, to make our life a little easier-- Visual Studio Code, just like many other code editors, has a way to configure commands to be run for debugging, setting up things like environment variables. So let's do that today.

      In Visual Studio Code, I believe, on Windows, the shortcut's going to be Control Shift P. On MacBooks, it's Command Shift P. You should be able to open something called Command Palette. And in here, I'd like to ask you to run the command called Create launch.json or Open launch.json. So let me delete mine here so that we're all on the same page.

      If I say Open launch.json-- I don't want this one-- here, you should be offered a selection of programming languages that you want to configure in your launch config file. And since we downloaded a nodejs implementation of our sample, we're going to say nodejs.

      So this is our template. This is a template json configuration that Visual Studio Code prepares for us, and you can see it should pick up the right script that you want to run when debugging your project. So you should see-- as a program property in there, you should see workspacefolder/*js. This is the nodejs script that's the entry point to our server side application.

      And what we can do here is we can now define a couple of environment variables that will be required in order to successfully run this project. There's only two environment variables, the Forge Client ID and Forge Client Secret, and here I would ask you to use the Client ID and Secret that you have for your own Forge application. And I'm going to close this window and switch back.

      It should look it should look kind of like this. You don't have to use my credentials. I don't mind sharing them. They are just experimental. If you're a super fast and you don't want to create your own Forge app, you can just try and copy the Client ID and Secret from the screen over there, or just use yours. It's super easy to create a Forge app and get the credentials.

      So your launch.json should look kind of like this, so just specifying a program that we want to start. That's the entry point, the start of js scripts. And Forge Client ID and Forge Client Secret-- that's it. These are the only two environment variables that we will need to run this project.

      How are we doing? Good? No hands, so I'm guessing good. With this, you should now be able to launch your server and test it out locally. So if I go in the menu of Visual Studio Code, I say Debug and Start Debugging or I simply press F5, this should start your server locally, and it should start listening on port 3000. And what that means is that now, when you go to your favorite browser of your choice, hopefully not IE, you can go to localhost:3000 and see your application.

      This is the standard Learn Forge sample application that you would create if you followed our online tutorial. So this is, again, just to make sure that we're all level set and we're starting from the same point. Now, on the left-hand side, you may not see any buckets or any models. That's because if you're using your Forge application and you haven't created any buckets or haven't uploaded any objects yet, you need to do that now.

      So for those of you who don't have any model, let's Google another phrase. Let's Google "revit sample files." So if you don't have any file and you can't file Revit or invent a file of your own, feel free to download one of the official sample files, let's say, for Revit, and you can find them here.

      The very first result that comes up when you Google for "revit sample files" is going to be a collection of sample Revit projects. Maybe you can get the RSD basic sample project. So just download this Revit file to your machine, and we can then create a new bucket in your Learn Forge sample application. And you can upload that Revit file and translate.

      I'll show you how it's done. Yeah, I can go through the process so that you can follow along. So in our running application, again, you most likely won't see any bucket or objects there. You can create a new bucket using this bluish button. Just come up with the bucket name.

      One thing here-- it's important to note-- is that bucket names have to be globally unique. So if you just type in "test," it'll fail because it's very likely that somebody else in the past has already created a bucket called "test." So you can use a combination of your name and maybe today's date, so I can try something like PetrBrozau2019. And it looks like that worked pretty well, so I have a new bucket.

      And then when your bucket is ready, you can right click it and use it to upload a file. So that can be any of your own Revit or AutoCAD, 3D, if possible, CAD files, or the Revit file, the sample file that we just downloaded. So let me try it here real quick. Again, probably not necessary, but just so you know how to proceed, I'm going to take one of my sample files. Was that the RSD basic sample?

      This will upload a file to our bucket, but it will not make it available for viewing just yet. If I click on that file, I won't see any 3D or 2D data. And again, you would learn in the Learn Forge tutorial, the basic introductory tutorial, that uploading a file to Forge itself is not enough.

      We need to ask one of the Forge services, the model derivative service, to translate this file for us into a format that's optimized for viewing on the web. So we can do that now. You should see a-- but when you try and open your uploaded design file, you should see a comment of "This file is not translated yet" with a button that can trigger the translation.

      And now this is going to be it. Once this is done, once the file is translated and we can view it, we're all level set, and we can move on to the core of this presentation, which is the viewer extensions and viewer APIs. Let's try and reload. It's 17% complete. How's everybody doing? Good? Perfect.

      It may take a while because it looks like we're going to trigger a one big batch of translations. But our service is scaled pretty well, so we should be good. 76%-- how far are you? Are we racing?

      AUDIENCE: A question on bucket names?

      PETR BROZ: Yes.

      AUDIENCE: Those are unique to your application?

      PETR BROZ: No, globally. That's the important piece. Just like in AWS, if you familiar with S3 service in AWS, the same rules apply, just like the S3 bucket names must be globally unique, not clashing with any other application, any other product because they're basically the roots of a URL that is then used to contain everything else. So yeah, globally unique. Good question.

      AUDIENCE: So what happens when you create an empty one with no name?

      PETR BROZ: With no name? That should not go through. Have you tried?

      AUDIENCE: [INAUDIBLE]

      PETR BROZ: So you created an empty bucket, an empty name bucket? I'm not sure that's going to get created, but that would be cool.

      AUDIENCE: [INAUDIBLE]

      AUDIENCE: He wanted to assure that there are not questions when you are naming your bucket [INAUDIBLE]

      PETR BROZ: Oh, that is the answer. OK, so it's kind of empty. It's kind of empty, but not really empty. But it's cool. I remember that we discussed, yeah, adding a suffix under the hood. I wasn't sure if that was actually in place.

      So I'm down here with my model. I hope you guys were as successful as me. So we can now move to the good stuff. We can leave our project, our web page, open, and we're going to start implementing our extension.

      Oh, and as I mentioned before, if you get lost by any chance, if you start falling behind, don't worry. The GitHub repo that I navigated you to has one more special branch. That branch is called extend-viewer. So we copied our code from the nodejs branch, but there is another branch called extend-viewer. And like I said before, every single comment in this special branch basically follows the code changes that we will be making as part of this presentation.

      So, A, that means that you don't have to worry about typing something from screen if you don't want to, if you don't feel like doing race typing with me here on the stage. You can copy and paste the individual parts of code from GitHub here if you want. So if I switch to a branch called extend-viewer. And again, remember, we are on my GitHub profile, petrbroz, looking at a repository called learn.forge.viewmodels.

      And when I switch to extend-viewer branch and look at comments, you'll see all these basically done in one day. All these comments are the individual changes that I'm describing in the individual slides in my presentation. So keep this page open. You might find it helpful, again, if you don't want to retype things from my slides here from the screen. I think I will type it in, and we can see who's faster. You'll probably be faster.

      So let's start. What extensions we're going to do today? We have three extensions, three examples prepared for you. I think we'll have time to cover the first two, and the third one I would keep as-- either if we're super fast, we can go back to this at the end of our talk, of our lab. If not, it would be a cool homework. I'm not sure if you guys would be up for that, but it's available.

      Extension number one, super basic-- we wanted to show that extensions in the viewer can be at different levels. They can have different sets of features, and we wanted to start from the super-- the easiest extension possible, an extension that won't have any UI, any special, complex APIs.

      We will build an extension that will basically listen to a key press in our application, and if that key press is a single-digit string, if it's a number on your keyboard, we will switch to a different environment background in our viewer. That's going to be the entire behavior functionality of this first extension.

      So what we're going to do first in our editor in Visual Studio-- we're going to go to the public/js folder. This is where we keep all our JavaScript files that we're using on the client side. And to keep things nice and maybe even better reusable for you in the future, we're going to create, write our own first extension JavaScript file in a separate file.

      So in the js folder, create a new file, and call it-- not a folder, file. And call it something easy for you to remember. I think, for now, I'm just going to call it BackgroundToggleExtension. That's actually not super easy to remember, but it's the name I'm using in my Git repo in that extend-viewer branch, so to be consistent. You can use whichever name you want.

      And we're going to write our first extension, viewer extension. The way it works is the viewer code itself provides a couple of classes that you can subclass from and modify to provide your custom extension functionality. That original parent class that we will want to use lives in a namespace called Autodesk.Viewing, and the name of the class is just Extension.

      So what we're going to do is we're going to create a class that extends from Autodesk.Viewing.Extension. And we can use-- I think today we don't have to worry about any old JavaScript-style prototypes anymore. We can just use classes.

      So what I'm going to do-- I'm going to create a new class. I'm going to call it the same as I called my JavaScript file. So I'm going to call it "class BackgroundToggleExtension extends Autodesk.Viewing.Extension." And we have our first extension. It doesn't do much just yet. We'll need to modify it just a little bit.

      Let's add a constructor that we could use in the future to initialize class fields or instance fields if we wanted to. In the constructor, there are a couple of things that you will probably be doing every single time you create a new extension, setting up some default, some standard methods. A constructor is one of them.

      What you want to do is you want your new class to accept two parameters, Viewer and Options. This is typically how we write our extensions. We prepare them so that the viewer itself can pass an instance of itself, the viewer that we will be using for getting access to the individual APIs and some additional options that you might see there. And as you may know, the way to pass parameters to the parent class constructor is using a function call to something called "super."

      So we have our constructor ready, and now we're going to add two methods that we typically add to extensions that control, basically, the lifecycle of an extension. And those two methods are called load and unload. So we can just define them like this.

      By convention, these methods will be called by the viewer when it decides to load an extension or to unload it when it no longer needs it. And these extensions-- these methods should return a Boolean flag, indicating whether the loading or unloading process logic was successful.

      So typically, you will want to say-- return true-- yes, loading was successful, and unloading was successful, as well. And to make sure that our code is being hit, we can add some console logs and say, for example, BackgroundToggleExtension loaded, and Background Extension unloaded. This is our core skeleton for our first extension. Again, it's not doing much, just reporting that it's been loaded and unloaded, but we'll fix that very soon.

      And one more thing we need to do is-- just defining a class somewhere in the scope of the running web application is not enough. We need to let the viewer know that we will eventually ask it to load this extension under some code name, under some unique ID. And the way we do that is we reach into the Autodesk viewing namespace once again, and we find a-- we pick a global variable called the Extensions Manager.

      Now, be careful here. This is not a class. It's a constant, and that's why it's prepended with lowercase "the." So it's not just Extension Manager. It's the Extension Manager with lowercase T-H-E. And we're going to say-- on this instance, we're going to say, register extension-- call this method-- and pass in two objects. We're going to pass in a string, which is going to be the unique ID that we want to give to our extension and the class itself.

      So we can say-- I'm probably going to use the same name as the class, and then I'm going to pass in the class itself. That's our extension, the class itself defining the behavior, the logic encapsulated in the extension, as well as registering it for the viewer so that later on, as we're instantiating Viewer itself, we can ask it to pick this extension using the unique string that I used down there.

      So again, you can use your own unique idea if you want. Just remember that that's going to be the unique ID that you're going to be using later when actually asking the viewer to include its extension into its runtime.

      We have our first extension JavaScript file ready. Now we need to make sure that this file is actually pulled into our website when we get there. So in order to do that-- we have a very simple structure. We're not using any fancy bundling tools or anything. We basically just have a very standard static HTML with a couple of static JavaScript and CSS files.

      So in order to bring our new JavaScript file to the client, we need to add it to our HTML market. So go to Index HTML. It should be under your public folder. And you see there's already a couple of JavaScript files being included from our public folder, so we can just copy this line in the head markup and say that we want to bring in js/, in my case, BackgroundToggleExtension js, as well.

      That's it. Using just this line, we're just asking the web application to pull in one additional JavaScript file and execute it as soon as it gets downloaded. So basically, that means that this file is going to get downloaded to our browser, and it will immediately define this new class that you implemented in that file.

      And one last thing-- there is always this triplet of these three steps that I need to keep in mind to do, first of all, implement the actual class, second, make sure that the JavaScript file with the class is actually pulled down to the client. And the third thing that I need to remember is to actually ask my viewer to include this extension when it starts.

      And in this case, in our sample file, the viewer initialization code lives under the public folder, js folder, in a file called forgeviewer.js. Here, you should see code that looks like this. So this is the way the viewer on the client side is initialized. We have a function called initializer, again, living under the Autodesk.Viewing namespace, so we call Autodesk.Viewing.Initializer with some options that we want to use.

      And then we pass a function, a callback function, that's called as soon as the viewer is initialized. Because the viewer itself may depend on some additional resources. It may depend on-- it may need to download some, let's say, image files for the different backgrounds and stuff like that. So this is the reason we have this asynchronous step there. So we can give the viewer time to fetch all its dependencies and resources, and then we can proceed with the initialization. And the initialization happens inside the callback function.

      So here you see we are creating a new instance of Viewer, the GUI Viewer 3D. So that means this is an instance of our viewer, including the toolbar and everything, and then we're starting the viewer and opening some URN that we-- this method is called as soon as you click on one of your models in the sidebar.

      So what we want to do here is-- as of now, the GUI Viewer 3D class is instantiated with just one parameter, which is the HTML container where we want our viewer to live and run. But it can accept additional parameter, which can be a config file. So let's create a constant-- we can call it Config-- and pass it as a second parameter to our GUI Viewer 3D constructor.

      And in our Config file, there are different options you can pass in. In this case, we only need one. There's a property called extensions that we can pass in, which is basically an array of strings. And you probably know where I'm going with this. This is going to be the list of unique extension IDs that you want to load with your viewer.

      The reason this happens here is that we can have multiple viewers running at the same time on your web page, and you want different viewers to use different extensions. That's why the configuration happens here on the viewer level and not in, let's say, in the Options.

      AUDIENCE: [INAUDIBLE]

      PETR BROZ: It needs more? OK, like this? So in my case, I believe I called my extensions BackgroundToggleExtension. I'm just going to copy this string, and again, in your case, use whatever string ID you used for your own extension.

      And that's it. These are the three steps to do when creating a new extension. And don't worry. For the next extension, we won't have to worry, but we'll just copy the skeleton. So now we can do-- we can restart our sample server application, go back. And now--

      For those of you not familiar with this, most of the modern browsers have all sorts of tools, very useful tools, for developers. I'm using Chrome here, and in my case, on Mac, it's Option Command I. On Windows, that would be, I believe, Alt Shift I or Alt Control I to open dev tools. Or maybe so that we don't have to worry about shortcuts, you can find dev tools in the three-dot menu in Chrome if you have chrome open, More Tools, and Developer Tools.

      This is a way to basically open this view, which is, again, very helpful for developers. It allows you to navigate your markup, investigate markup, change it during runtime, run all sorts of JavaScript expressions, see how they resolve. But what I wanted to show you here-- if I switch to the Console tab, we're going to see all the console logs generated by this application. And if you remember, when I wrote-- when I created that load and unload method, I just added simple console logs there to report that the lifecycle-- that these points are actually hit when the viewer is initialized.

      So what I'm going to here-- I'm going to open my sample Revit file that I uploaded. And I'm not sure if you can see it here, but-- yeah, see? My BackgroundToggleExtension was loaded. So this is just a confirmation for us to know that, OK, when I instantiated the viewer and started it, it picked that class that we prepared, the BackgroundToggleExtension class, and ran its constructor and the load method.

      So now, to actually give it some life and some functionality, let's go back to our BackgroundToggleExtension, and we're going to add a new method that we're going to use as a handler for the key press events that we're going to be listening to. So create a new method, for example, under the load and unload methods, and call it on key press or in a similar way. And have it accept one parameter, ev for event, or just call it e, again, up to you.

      So what we're going to do here-- this method, we will set it up so that this method is called whenever we press a key on our keyboard and whenever that event is registered by JavaScript. So what we want to do here is we want to check if that button that we pressed is a number, and if it's a number, we want to use that number to switch to a different background image in the viewer.

      So what we're going to do is we're going to use a little bit of regular expressions. We can to just slash-- well, you'll see it. This is a relatively simple way of saying, test if the event.keyproperty, which is the string containing the key that's being pressed, if it's a single digit. The /d means any digit character, and by decorating with these symbols means that I want to match the whole string. So I want the whole string to be just a number.

      And if this test passes, we can extract the ID from the property. So parseInt is a built-in function, one of the couple of built-in JavaScript functions. This one is used to parse a string into an integer number.

      And now comes the magic moment. We're going to start using the Viewer APIs. So for each extension, Viewer will be available as a property of an instance called Viewer. So in this case, we can say dis.viewer, and we're going to use a method called setLightPreset.

      So this is our first use of Viewer APIs. So again, you will always be accessing those APIs from your extension through dis.viewer, because you probably don't need to store the reference anywhere else. You just want to used the instance that the extension is associated with because, again, as I mentioned before, you can have multiple instances of the viewer running on the same page. So this is a safe way to get back to the instance that actually owns this extension code.

      Let me double check with my presentation. So we've done all this, and we included our Background Toggle logic, yes. So that looks reasonably similar, setLightPreset. Now, one thing we need to do is somebody needs to call this method. We can do that in the load method. So when this extension is loaded, we can ask it to basically listen to any key press event in our web application and react to that.

      And the way to do that, typically, in JavaScript is by attaching an event listener to your window object. So hopefully Visual Studio Code will have some reasonable IntelliSense available for you. So if you type window.ad, you should see a recommendation here for something called add event listener. And even if you started typing the first parameter to this method, which is a string describing the event that you want to listen to, you should see key press in there.

      So you say, OK. By this code, you're saying, hey, JavaScript, whenever you detect an event on this application window, that's a key press event. React to it in some way. So here we could pass in a function that should be called. One problem, one thing we need to be careful about here is this darn context of the dis, this keyword in JavaScript. I'm sure many of you know what I'm talking about, but if you don't, just don't worry about that now.

      What I would just ask you to do is say this onKeyPress, where we're basically saying, whenever there is a key press event, please call this function. But we will use a special method that's available on the function object called bind. It looks kind of weird, but stay with me.

      This basically means that whenever there is a key press event triggered on the window, we will want our code to run the onKeyPress method with one slight change. If we left out the "bind this," our method would be called, but the keyword "this" inside would refer to the window, to something different. So that's the tricky part in JavaScript. By using [INAUDIBLE] bind this means, OK, yeah, whenever this key press event happens, call my onKeyPress method, but bind it to this, which means the instance of my extension.

      So by doing this, we're basically making sure that we're safe, we're on a good side so that later on, when the onKeyPress event is called, these four letters will actually refer to our extension object and not to something else, something unexpected.

      Now let's see. Restart our project. Go back to our demo application. Open one of our models, and start pressing numbers on our keyboard. I'm trying 6, 7, 8. So this is the behavior that you should all hopefully see now. If you don't--

      Anybody having any issues so far? We good? I have all my lab assistants on standby, eager to help. So like Jim [? Clancy ?] says, don't be bashful. We're good. We can all switch backgrounds, awesome. You're a great audience. Let's move on.

      Second extension-- here, we're going to look more at some of the more advanced APIs. So the Viewer APIs are not there just to allow you to change background. It would be kind of boring.

      You can do a lot of stuff with the APIs. You can use it to navigate and iterate through the scene of your models that you've loaded from the Model Derivative service. You can use it to see what objects have been selected. You can use it to modify their positions, even, if you wanted to. You can use it to modify their materials, give them color tints, some special color codes based on your proprietary values that you've computed. You can do a lot of stuff there.

      So let's take a look at a couple of examples of what you can do here. So as the extension number two, we're going to create an extension that will color code different components, different objects in our model based on some proprietary computation, some value that we compute based on properties attached to those geometries.

      Because that's one thing I forgot to mention. Using the Viewer APIs, you can not only navigate the scene of the model or the models that you're seeing in the viewer. You can also use it to programmatically access all the metadata and all the properties of those objects.

      So this is what we're going to use here. We're going to build an extension that will select certain objects in our model. It'll try and compute some arbitrary value using some form. in this case, we're going to be using a ratio of a surface area of each object and use it in percentage form. So we're going to color all the individual elements in that structural design that I downloaded. We're going to color code it based on the area value of those properties.

      So let's start by creating another extension and this time I think we don't have to go through the hassle. We can just copy and paste our original extension with [? BackgroundToggleExtension ?] So let me copy this entire thing and create a new JavaScript file.

      Again, I don't want to be messy. I'm going to be keeping every extensions in its own file. So I'm going to create an extensions called HeatmapExtension.js. And we should probably change a couple of things here. So I'm going to change the name of the class, HeatmapExtension. I'm going to use the Uname in our logs, in the load and unload method. I'll remove the key press event listener and the key press method. And I'll use that HeatmapExtension, again, as a string, as a unique name for my extension.

      So this is what it should look like, just copy and pasting the skeleton of the previous extensions. This time I'm calling it HeatmapExtension, and you're free to call it whatever you want. Just keep in mind that you'll need to use the proper string ID later on.

      So that was, if you remember, as I said, three steps. This was step number one. Step number two-- we need to make sure that this file will get downloaded to the client, as well. So once again, go to your Index of HTML file, and include your new extension script in there, as well. So I say, JavaScript/. And we have up IntelliSense here in the HTML, as well, so I'll want my HeatmapExtension to be pulled in. That was step number two.

      In step number three, I want my extension to be loaded when the viewer is instantiated. So go to your forgeviewer.js, and include the unique ID that you gave your new extension in the Config file in the extensions property list, as well.

      So again, this is all-- those are all the three steps for setting up an extension, making sure that it's loaded in the viewer. If I run my application again just to double check, I see both BackgroundToggleExtension loaded and HeatmapExtension loaded, so it's all looking good. We can now move to the important part of the extension.

      We're going to prepare a couple of methods to make it clean and reusable, not too [INAUDIBLE]. Like, we don't want to like write one large blob full of JavaScript function that will do everything and won't be reusable and understandable at all. So the functionality-- like I said, we will want to select some objects in the model. We will want to compute some information for them based on their properties, and we will want to color code them based on that information.

      Now, one more thing we wanted to show in this extension, as well, is Basic UI. So the Viewer API allows you to build all sorts of stuff. You can build property panels, custom panels, custom dialogs. For here, we're just going to add a toolbar button to the official toolbar in the viewer so that you can actually trigger the logic and this extension by clicking a button, as opposed to listening to a key press or something.

      If you're interested about the more advanced UI that you can build, that would be the third extension, that homework, that you can take a look at. It's also available on that GitHub repo, and it'll be available in your handout.

      So what we're going to do, set up the toolbar UI. Where we are? Here, HeatmapExtension. We're going to add one more method that can be overwritten from the superclass called onToolbarCreated. This is a method that the viewer will call as soon as it is done initializing the toolbar UI so that you don't have to worry about accidentally trying to insert something into a toolbar that does not exist yet.

      So the method is called onToolbarCreated. Here, we can create our new button and add it to the toolbar. Typically, you might have noticed, the toolbar in the viewer consists of a couple of groups, see? We have three groups here for navigation, for measurements, explode, stuff like that.

      You could potentially reuse these groups and insert your button into one of those, but it's a cleaner, nicer to just, whenever you're writing your own custom functionality extension, to put it in a separate container. And that's what we're going to do.

      We're going to define a new variable field on our extension instance. I'm going to call it _group, and we're going to say, this viewer toolbar getControl, which basically means this viewer is our viewer instance. Toolbar is a property on that instance containing all the UI content in the toolbar. And we're going to ask for control by providing its ID. We can call it MyCustomGroup.

      And if this group does not exist, we will create a new one and insert it. So this is a way to basically say, if I have a couple of extensions, I may want to group them into the same toolbar group. And this code will be managed that. It will handle that for us. Sorry. So if the group object is not defined, meaning that if our call to getControl didn't find anything in the toolbar, we will need to create a new one.

      So we'll say, this group is new. And again, we're creating a control group which is-- all these UI classes are not just in a Autodesk.Viewing namespace. They are in Autodesk.Viewing.UI namespace. So I know that-- I remember that control-- the class is called control group. You will find it on our def portal in the Viewer JavaScript Reference documentation.

      And we're going to create a MyCustomGroup. This is where we're passing in the ID. Again, we're giving our control group, our UI elements, a unique ID so that we can later on try and look it up. So we can create our group and add it back to the toolbar by using another method called addControl

      Let me switch to our slide here. This is where we are. So like I said, if the group with some unique ID that we're looking for is not available, we're going to create it using Autodesk.Viewing.UI control group, and we're going to insert it into the toolbar.

      And as the next step, we can create an actual button. So I tend to, again, store even the button-- additional UI components as instance fields here, as well. So we can say new Autodesk.Viewing.UI. Again, we are in the UI namespace. And I want to say-- this time, I want to instantiate a new button. You can give it a name. Let's say Heatmap button in this case.

      We will want to add this button to our group. So we can leverage the _group reference where we stored our new UI elements and say, addControl this button. This wouldn't be doing much just yet. Now we can start using some of the properties on the button instance. One of them is called onClick with uppercase C, and this is basically a function that's going to be called whenever you click that button. So for now, I'm just going to say, alert Hello World.

      And we can also use function called this button setToolTip. Be careful. There are both-- both T's are uppercase. And we can give this button a name. This is the name that will appear when you hover the button in the toolbar. So again, so far, this is not doing a lot, but we're taking baby steps. So we have a new button created, instantiated. We defined some simple logic to be handled when it's clicked. We gave it a name, and we added it to our control group in a toolbar.

      Now let me switch to our demo page real quick. And you should now see that there is a new button in our toolbar living in its own container, separate group. It doesn't show any image just yet. I don't think we have to worry about that now. It's our Heatmap button. When I click it, I get the alert that I used, that I defined in the onClick method.

      So now as a next step-- we're running out of time, so we probably won't be able to cover the entire thing. But as the next step, what we would like to do is we would like to collect some IDs of objects that we want to change and color code. So in order to do that, in my GitHub repo, in that extend-viewer branch, you'll see that I'm adding one more method called, I believe, collectLeafNodes or getLeafNodes.

      And this would be a method that I would use to traverse the scene of our currently loaded model and collect IDs of some objects that I want to work with later on. And in this case, I want to collect leaves, meaning I want to collect objects in the scene tree that don't have any more children, that are living at the very bottom of the scene tree.

      And in order to use this functionality, we will need to ask the viewer to give us access to the tree, which is in a synchronous operation. There is a method on the API, on the viewer, here, called getObjectTree. That method is asynchronous, meaning that it won't return to the object that you're asking for right away. It will return it to you in a callback.

      So in order to be able to make it easier to use this method later on, we're going to make it return a promise, which is a concept in JavaScript meaning returning a value that will be resolved or rejected eventually. So again, I'm not going to go into a lot of details. Unfortunately, we don't have time for that here.

      But what we do is we start the implementation of the body of this getLeafNodes method by returning a new promise object. And into the Promise class, we're passing in a function accepting two parameters, result and reject, that we will eventually call based on whether the async operation was successful or whether it failed. That's the concept with promises so that whoever calls to getLeafNodes function can then wait for either the moment it gets resolved or for the moment it gets rejected.

      So what we'll do here is-- we cannot use the view were straight away because, again, the meaning of this keyword inside has a different semantics. So we we'll want to cache the Viewer Reference outside of the promise and call it this way inside our promise. GetObjectTree-- this is our API call where we're asking the viewer to give us an object that can navigate the tree structure of the model. And this would eventually return a tree object in a callback.

      Unfortunately, I've been notified that we ran out of time. I really apologize for that. We got delayed a bit more at the beginning by setting up the app. It's just not something I was including in my test runs, so my apologies.

      If you have any quick questions now of something that's been covered up to this up to this point, I'd be more than happy to answer them for you. Otherwise, I would refer you to the code repository that we've been basically working through here and to the handout if you want to proceed and look at the rest of what we were supposed to implement here, meaning, again, navigating the scene and color coding objects based on their properties.

      And yes, and me and my colleagues will be at the answer bar in the Village for the rest of the day today, and-- I'm not sure about the others-- I'm also going to be here until the end of AU, where we're going to have our own Forge answer bar as part of the expo. So if you have any questions regarding the Viewer API, so something that was covered here, I'd be more than happy to explain those additional details to you in the rest of this week. So any last questions, quick questions? [INAUDIBLE], yes?

      AUDIENCE: I don't know if it's covered. I just have a question of whether or not-- you didn't use Viewer API [INAUDIBLE]? Like if I was going to grab the [INAUDIBLE] the element ID of the [INAUDIBLE]

      PETR BROZ: Oh, you mean the HTML ID. No, no, no, these are just unique IDs within the scope of the viewer.

      AUDIENCE: So if I wanted to attach a [INAUDIBLE] or whatever, is there anything that's going to allow me to actually go in and manipulate how the [INAUDIBLE]?

      PETR BROZ: You could. I think all these classes from the Autodesk.Viewing.UI namespace-- you would be able to drill inside those instances and find a reference to the actual HTML element, so that would be the way to go.

      So if there are no other questions, I thank you for your attention. Thank you for coming today. And again, we'll be at the Village today and in the expo for the rest of this week, for the rest of the AU. Thank you.

      ______
      icon-svg-close-thick

      Cookieの設定

      弊社にとって、お客様のプライバシーを守ることと最適な体験を提供することは、どちらも大変重要です。弊社では、お客様に合わせてカスタマイズした情報を提供し、並びにアプリケーションの開発に役立てることを目的に、本サイトのご利用方法についてのデータを収集しております。

      そこで、お客様のデータの収集と使用を許可いただけるかどうかをお答えください。

      弊社が利用しているサードパーティのサービスについての説明とプライバシー ステートメントも、併せてご確認ください。

      サイト動作に必須:オートデスクのサイトが正常に動作し、お客様へサービスを提供するために必要な機能です

      Cookie を有効にすることで、お客様の好みやログイン情報が記録され、このデータに基づき操作に対する応答や、ショッピング カートへの商品追加が最適化されます。

      使用感が向上:お客様に最適な情報が表示されます

      Cookie を有効にすることで、拡張機能が正常に動作し、サイト表示が個々に合わせてカスタマイズされます。お客様に最適な情報をお届けし、使用感を向上させるためのこうした設定は、オードデスクまたはサードパーティのサービス プロバイダーが行います。 Cookie が無効に設定されている場合、一部またはすべてのサービスをご利用いただけない場合があります。

      広告表示をカスタマイズ:お客様に関連する広告が表示されます

      Cookie を有効にすることで、サイトのご利用内容やご興味に関するデータが収集され、これに基づきお客様に関連する広告が表示されるなど、効率的な動作が可能になります。また、継続的にデータを収集することで、お客様のご興味にさらに関連する広告を配信することが可能になります。Cookie が無効に設定されている場合、お客様に関連しない広告が表示される可能性があります。

      icon-svg-close-thick

      サードパーティのサービス

      それぞれの情報で弊社が利用しているサードパーティのサービスと、オンラインで収集するお客様のデータの使用方法を詳しく説明いたします。

      icon-svg-hide-thick

      icon-svg-show-thick

      サイト動作に必須:オートデスクのサイトが正常に動作し、お客様へサービスを提供するために必要な機能です

      Qualtrics
      弊社はQualtricsを利用し、アンケート調査やオンライン フォームを通じてお客様が弊社にフィードバックを提供できるようにしています。アンケートの回答は無作為に選んだお客様にお願いしておりますが、お客様から自発的に弊社にフィードバックを提供することも可能です。データを収集する目的は、アンケートの回答前にお客様がとられた行動を、より正しく理解するためです。収集したデータは、発生していた可能性がある問題のトラブルシューティングに役立てさせていただきます。. Qualtrics プライバシー ポリシー
      Akamai mPulse
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Akamai mPulseを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Akamai mPulse プライバシー ポリシー
      Digital River
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Digital Riverを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Digital River プライバシー ポリシー
      Dynatrace
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Dynatraceを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Dynatrace プライバシー ポリシー
      Khoros
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Khorosを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Khoros プライバシー ポリシー
      Launch Darkly
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Launch Darklyを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Launch Darkly プライバシー ポリシー
      New Relic
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、New Relicを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. New Relic プライバシー ポリシー
      Salesforce Live Agent
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Salesforce Live Agentを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Salesforce Live Agent プライバシー ポリシー
      Wistia
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Wistiaを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Wistia プライバシー ポリシー
      Tealium
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Tealiumを利用しています。データには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Tealium プライバシー ポリシー<>
      Typepad Stats
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Typepad Statsを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Typepad Stats プライバシー ポリシー
      Geo Targetly
      当社では、Geo Targetly を使用して Web サイトの訪問者を最適な Web ページに誘導し、訪問者のいる場所に応じて調整したコンテンツを提供します。Geo Targetly は、Web サイト訪問者の IP アドレスを使用して、訪問者のデバイスのおおよその位置を特定します。このため、訪問者は (ほとんどの場合) 自分のローカル言語でコンテンツを閲覧できます。Geo Targetly プライバシー ポリシー
      SpeedCurve
      弊社は、SpeedCurve を使用して、Web ページの読み込み時間と画像、スクリプト、テキストなど後続の要素の応答性を計測することにより、お客様の Web サイト エクスペリエンスのパフォーマンスをモニタリングおよび計測します。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

      使用感が向上:お客様に最適な情報が表示されます

      Google Optimize
      弊社はGoogle Optimizeを利用して、弊社サイトの新機能をテストし、お客様に合わせた方法で機能を使えるようにしています。そのため弊社では、弊社サイトにアクセスしているお客様から、行動に関するデータを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID などが含まれます。機能のテストの結果によっては、お客様がご利用のサイトのバージョンが変わったり、サイトにアクセスするユーザの属性に応じて、パーソナライズされたコンテンツが表示されるようになる場合があります。. Google Optimize プライバシー ポリシー
      ClickTale
      弊社は、弊社サイトをご利用になるお客様が、どこで操作につまづいたかを正しく理解できるよう、ClickTaleを利用しています。弊社ではセッションの記録を基に、ページの要素を含めて、お客様がサイトでどのような操作を行っているかを確認しています。お客様の特定につながる個人情報は非表示にし、収集も行いません。. ClickTale プライバシー ポリシー
      OneSignal
      弊社は、OneSignalがサポートするサイトに広告を配置するために、OneSignalを利用しています。広告には、OneSignalのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、OneSignalがお客様から収集したデータを使用する場合があります。OneSignalに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. OneSignal プライバシー ポリシー
      Optimizely
      弊社はOptimizelyを利用して、弊社サイトの新機能をテストし、お客様に合わせた方法で機能を使えるようにしています。そのため弊社では、弊社サイトにアクセスしているお客様から、行動に関するデータを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID などが含まれます。機能のテストの結果によっては、お客様がご利用のサイトのバージョンが変わったり、サイトにアクセスするユーザの属性に応じて、パーソナライズされたコンテンツが表示されるようになる場合があります。. Optimizely プライバシー ポリシー
      Amplitude
      弊社はAmplitudeを利用して、弊社サイトの新機能をテストし、お客様に合わせた方法で機能を使えるようにしています。そのため弊社では、弊社サイトにアクセスしているお客様から、行動に関するデータを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID などが含まれます。機能のテストの結果によっては、お客様がご利用のサイトのバージョンが変わったり、サイトにアクセスするユーザの属性に応じて、パーソナライズされたコンテンツが表示されるようになる場合があります。. Amplitude プライバシー ポリシー
      Snowplow
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Snowplowを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Snowplow プライバシー ポリシー
      UserVoice
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、UserVoiceを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. UserVoice プライバシー ポリシー
      Clearbit
      Clearbit を使用すると、リアルタイムのデータ強化により、お客様に合わせてパーソナライズされた適切なエクスペリエンスを提供できます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。Clearbit プライバシー ポリシー
      YouTube
      YouTube はビデオ共有プラットフォームで、埋め込まれたビデオを当社のウェブ サイトで表示および共有することができます。YouTube は、視聴者のビデオのパフォーマンスの測定値を提供しています。 YouTube 社のプライバシー ポリシー

      icon-svg-hide-thick

      icon-svg-show-thick

      広告表示をカスタマイズ:お客様に関連する広告が表示されます

      Adobe Analytics
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Adobe Analyticsを利用しています。収集する情報には、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Adobe Analytics プライバシー ポリシー
      Google Analytics (Web Analytics)
      弊社は、弊社サイトでのお客様の行動に関するデータを収集するために、Google Analytics (Web Analytics)を利用しています。データには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。このデータを基にサイトのパフォーマンスを測定したり、オンラインでの操作のしやすさを検証して機能強化に役立てています。併せて高度な解析手法を使用し、メールでのお問い合わせやカスタマー サポート、営業へのお問い合わせで、お客様に最適な体験が提供されるようにしています。. Google Analytics (Web Analytics) プライバシー ポリシー<>
      Marketo
      弊社は、お客様に関連性のあるコンテンツを、適切なタイミングにメールで配信できるよう、Marketoを利用しています。そのため、お客様のオンラインでの行動や、弊社からお送りするメールへの反応について、データを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、メールの開封率、クリックしたリンクなどが含まれます。このデータに、他の収集先から集めたデータを組み合わせ、営業やカスタマー サービスへの満足度を向上させるとともに、高度な解析処理によって、より関連性の高いコンテンツを提供するようにしています。. Marketo プライバシー ポリシー
      Doubleclick
      弊社は、Doubleclickがサポートするサイトに広告を配置するために、Doubleclickを利用しています。広告には、Doubleclickのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Doubleclickがお客様から収集したデータを使用する場合があります。Doubleclickに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Doubleclick プライバシー ポリシー
      HubSpot
      弊社は、お客様に関連性のあるコンテンツを、適切なタイミングにメールで配信できるよう、HubSpotを利用しています。そのため、お客様のオンラインでの行動や、弊社からお送りするメールへの反応について、データを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、メールの開封率、クリックしたリンクなどが含まれます。. HubSpot プライバシー ポリシー
      Twitter
      弊社は、Twitterがサポートするサイトに広告を配置するために、Twitterを利用しています。広告には、Twitterのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Twitterがお客様から収集したデータを使用する場合があります。Twitterに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Twitter プライバシー ポリシー
      Facebook
      弊社は、Facebookがサポートするサイトに広告を配置するために、Facebookを利用しています。広告には、Facebookのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Facebookがお客様から収集したデータを使用する場合があります。Facebookに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Facebook プライバシー ポリシー
      LinkedIn
      弊社は、LinkedInがサポートするサイトに広告を配置するために、LinkedInを利用しています。広告には、LinkedInのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、LinkedInがお客様から収集したデータを使用する場合があります。LinkedInに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. LinkedIn プライバシー ポリシー
      Yahoo! Japan
      弊社は、Yahoo! Japanがサポートするサイトに広告を配置するために、Yahoo! Japanを利用しています。広告には、Yahoo! Japanのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Yahoo! Japanがお客様から収集したデータを使用する場合があります。Yahoo! Japanに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Yahoo! Japan プライバシー ポリシー
      Naver
      弊社は、Naverがサポートするサイトに広告を配置するために、Naverを利用しています。広告には、Naverのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Naverがお客様から収集したデータを使用する場合があります。Naverに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Naver プライバシー ポリシー
      Quantcast
      弊社は、Quantcastがサポートするサイトに広告を配置するために、Quantcastを利用しています。広告には、Quantcastのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Quantcastがお客様から収集したデータを使用する場合があります。Quantcastに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Quantcast プライバシー ポリシー
      Call Tracking
      弊社は、キャンペーン用にカスタマイズした電話番号を提供するために、Call Trackingを利用しています。カスタマイズした電話番号を使用することで、お客様は弊社の担当者にすぐ連絡できるようになり、弊社はサービスのパフォーマンスをより正確に評価できるようになります。弊社では、提供した電話番号を基に、サイトでのお客様の行動に関するデータを収集する場合があります。. Call Tracking プライバシー ポリシー
      Wunderkind
      弊社は、Wunderkindがサポートするサイトに広告を配置するために、Wunderkindを利用しています。広告には、Wunderkindのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Wunderkindがお客様から収集したデータを使用する場合があります。Wunderkindに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Wunderkind プライバシー ポリシー
      ADC Media
      弊社は、ADC Mediaがサポートするサイトに広告を配置するために、ADC Mediaを利用しています。広告には、ADC Mediaのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、ADC Mediaがお客様から収集したデータを使用する場合があります。ADC Mediaに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. ADC Media プライバシー ポリシー
      AgrantSEM
      弊社は、AgrantSEMがサポートするサイトに広告を配置するために、AgrantSEMを利用しています。広告には、AgrantSEMのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、AgrantSEMがお客様から収集したデータを使用する場合があります。AgrantSEMに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. AgrantSEM プライバシー ポリシー
      Bidtellect
      弊社は、Bidtellectがサポートするサイトに広告を配置するために、Bidtellectを利用しています。広告には、Bidtellectのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Bidtellectがお客様から収集したデータを使用する場合があります。Bidtellectに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Bidtellect プライバシー ポリシー
      Bing
      弊社は、Bingがサポートするサイトに広告を配置するために、Bingを利用しています。広告には、Bingのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Bingがお客様から収集したデータを使用する場合があります。Bingに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Bing プライバシー ポリシー
      G2Crowd
      弊社は、G2Crowdがサポートするサイトに広告を配置するために、G2Crowdを利用しています。広告には、G2Crowdのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、G2Crowdがお客様から収集したデータを使用する場合があります。G2Crowdに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. G2Crowd プライバシー ポリシー
      NMPI Display
      弊社は、NMPI Displayがサポートするサイトに広告を配置するために、NMPI Displayを利用しています。広告には、NMPI Displayのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、NMPI Displayがお客様から収集したデータを使用する場合があります。NMPI Displayに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. NMPI Display プライバシー ポリシー
      VK
      弊社は、VKがサポートするサイトに広告を配置するために、VKを利用しています。広告には、VKのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、VKがお客様から収集したデータを使用する場合があります。VKに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. VK プライバシー ポリシー
      Adobe Target
      弊社はAdobe Targetを利用して、弊社サイトの新機能をテストし、お客様に合わせた方法で機能を使えるようにしています。そのため弊社では、弊社サイトにアクセスしているお客様から、行動に関するデータを収集しています。収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID、お客様の Autodesk ID などが含まれます。機能のテストの結果によっては、お客様がご利用のサイトのバージョンが変わったり、サイトにアクセスするユーザの属性に応じて、パーソナライズされたコンテンツが表示されるようになる場合があります。. Adobe Target プライバシー ポリシー
      Google Analytics (Advertising)
      弊社は、Google Analytics (Advertising)がサポートするサイトに広告を配置するために、Google Analytics (Advertising)を利用しています。広告には、Google Analytics (Advertising)のデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Google Analytics (Advertising)がお客様から収集したデータを使用する場合があります。Google Analytics (Advertising)に提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Google Analytics (Advertising) プライバシー ポリシー
      Trendkite
      弊社は、Trendkiteがサポートするサイトに広告を配置するために、Trendkiteを利用しています。広告には、Trendkiteのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Trendkiteがお客様から収集したデータを使用する場合があります。Trendkiteに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Trendkite プライバシー ポリシー
      Hotjar
      弊社は、Hotjarがサポートするサイトに広告を配置するために、Hotjarを利用しています。広告には、Hotjarのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Hotjarがお客様から収集したデータを使用する場合があります。Hotjarに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Hotjar プライバシー ポリシー
      6 Sense
      弊社は、6 Senseがサポートするサイトに広告を配置するために、6 Senseを利用しています。広告には、6 Senseのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、6 Senseがお客様から収集したデータを使用する場合があります。6 Senseに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. 6 Sense プライバシー ポリシー
      Terminus
      弊社は、Terminusがサポートするサイトに広告を配置するために、Terminusを利用しています。広告には、Terminusのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、Terminusがお客様から収集したデータを使用する場合があります。Terminusに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. Terminus プライバシー ポリシー
      StackAdapt
      弊社は、StackAdaptがサポートするサイトに広告を配置するために、StackAdaptを利用しています。広告には、StackAdaptのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、StackAdaptがお客様から収集したデータを使用する場合があります。StackAdaptに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. StackAdapt プライバシー ポリシー
      The Trade Desk
      弊社は、The Trade Deskがサポートするサイトに広告を配置するために、The Trade Deskを利用しています。広告には、The Trade Deskのデータと、弊社サイトにアクセスしているお客様から弊社が収集する行動に関するデータの両方が使われます。弊社が収集するデータには、お客様がアクセスしたページ、ご利用中の体験版、再生したビデオ、購入した製品やサービス、お客様の IP アドレスまたはデバイスの ID が含まれます。この情報に併せて、The Trade Deskがお客様から収集したデータを使用する場合があります。The Trade Deskに提供しているデータを弊社が使用するのは、お客様のデジタル広告体験をより適切にカスタマイズし、関連性の高い広告をお客様に配信するためです。. 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

      オンライン体験の品質向上にぜひご協力ください

      オートデスクは、弊社の製品やサービスをご利用いただくお客様に、優れた体験を提供することを目指しています。これまでの画面の各項目で[はい]を選択したお客様については、弊社でデータを収集し、カスタマイズされた体験の提供とアプリケーションの品質向上に役立てさせていただきます。この設定は、プライバシー ステートメントにアクセスすると、いつでも変更できます。

      お客様の顧客体験は、お客様が自由に決められます。

      オートデスクはお客様のプライバシーを尊重します。オートデスクでは収集したデータを基に、お客様が弊社製品をどのように利用されているのか、お客様が関心を示しそうな情報は何か、オートデスクとの関係をより価値あるものにするには、どのような改善が可能かを理解するよう務めています。

      そこで、お客様一人ひとりに合わせた体験を提供するために、お客様のデータを収集し、使用することを許可いただけるかどうかお答えください。

      体験をカスタマイズすることのメリットにつきましては、本サイトのプライバシー設定の管理でご確認いただけます。弊社のプライバシー ステートメントでも、選択肢について詳しく説明しております。