diff --git a/.gitignore b/.gitignore index abaa5a21..f378ed1c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ -# Node rules: -## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -## Dependency directory -## Commenting this out is preferred by some people, see -## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git -node_modules - -# Book build output -_book - -# eBook build output -*.epub +# Node rules: +## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +## Dependency directory +## Commenting this out is preferred by some people, see +## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git +node_modules + +# Book build output +_book + +# eBook build output +*.epub *.mobi \ No newline at end of file diff --git a/.htaccess.txt b/.htaccess.txt index 5d3145d5..b5afa942 100644 --- a/.htaccess.txt +++ b/.htaccess.txt @@ -1,9 +1,9 @@ -# Git does not allow commiting .htaccess, so instructions here -# Put the following under DocumentRoot/.htaccess -RewriteEngine on -RewriteRule ^(ja) - [L] -RewriteRule ^(de) - [L] -RewriteRule ^(.*)$ /en/$1 [R=301,NC,L] - -# Put the following under DocumentRoot/en/.htaccess to prevent redirect forever +# Git does not allow commiting .htaccess, so instructions here +# Put the following under DocumentRoot/.htaccess +RewriteEngine on +RewriteRule ^(ja) - [L] +RewriteRule ^(de) - [L] +RewriteRule ^(.*)$ /en/$1 [R=301,NC,L] + +# Put the following under DocumentRoot/en/.htaccess to prevent redirect forever RewriteEngine on \ No newline at end of file diff --git a/01_Introduction/1-1_preface.md b/01_Introduction/1-1_preface.md index 126b84d7..161eef2f 100644 --- a/01_Introduction/1-1_preface.md +++ b/01_Introduction/1-1_preface.md @@ -1,44 +1,44 @@ -## 1.1 PREFACE - -###1.1.1 Welcome - -Welcome Text -- background, previous versions, ml dynamo activities -- our excitement to have developed this primer (where dynamo is going) -- the ambitions around the project (fundamental concepts, cross-disciplinary ie use the sandbox, -- this is guide to the current dynamo version -- team signature - -###1.1.2 About this Primer - -- this primer introduces you to... -- the first four chapters -- the quick arc of this version -- special thanks to Matt Jezyk, Zach Kron, and Colin McCrone - -###1.1.3 Software - -Dynamo 0.8 -(dynamo blurb) -_note about future primer chapters on revit, speedform, web_ - -###1.1.4 Resources - -*DynamoBIM* -(blurb about DynamoBIM) -http://dynamobim.org - -*Dynamo GitHub* -(to contribute...) -https://github.com/ikeough/Dynamo - - -###1.1.5 References - -*Wolfram MathWorld* -MathWorld is an online mathematics resource, assembled by Eric W. Weisstein with assistance from thousands of contributors. Since its contents first appeared online in 1995, MathWorld has emerged as a nexus of mathematical information in both the mathematics and educational communities. Its entries are extensively referenced in journals and books spanning all educational levels. -http://mathworld.wolfram.com/ - -*More Websites* - -*Books* +## 1.1 PREFACE + +###1.1.1 Welcome + +Welcome Text +- background, previous versions, ml dynamo activities +- our excitement to have developed this primer (where dynamo is going) +- the ambitions around the project (fundamental concepts, cross-disciplinary ie use the sandbox, +- this is guide to the current dynamo version +- team signature + +###1.1.2 About this Primer + +- this primer introduces you to... +- the first four chapters +- the quick arc of this version +- special thanks to Matt Jezyk, Zach Kron, and Colin McCrone + +###1.1.3 Software + +Dynamo 0.8 +(dynamo blurb) +_note about future primer chapters on revit, speedform, web_ + +###1.1.4 Resources + +*DynamoBIM* +(blurb about DynamoBIM) +http://dynamobim.org + +*Dynamo GitHub* +(to contribute...) +https://github.com/ikeough/Dynamo + + +###1.1.5 References + +*Wolfram MathWorld* +MathWorld is an online mathematics resource, assembled by Eric W. Weisstein with assistance from thousands of contributors. Since its contents first appeared online in 1995, MathWorld has emerged as a nexus of mathematical information in both the mathematics and educational communities. Its entries are extensively referenced in journals and books spanning all educational levels. +http://mathworld.wolfram.com/ + +*More Websites* + +*Books* diff --git a/01_Introduction/1-1_what_is_visual_programming.md b/01_Introduction/1-1_what_is_visual_programming.md index 44f2a1d5..ebb18c4d 100644 --- a/01_Introduction/1-1_what_is_visual_programming.md +++ b/01_Introduction/1-1_what_is_visual_programming.md @@ -1,62 +1,62 @@ -###What is Visual Programming? - -Designing frequently involves establishing visual, systemic, or geometric relationships between the parts of a design. More times than not, these relationships are developed by workflows that gets us from concept to result by way of rules. Perhaps without knowing it, we are working algorithmically - defining a step-by-step set of actions that follow a basic logic of input, processing, and output. Programming allows us to continue to work this way but by formalizing our algorithms. - -###Algorithms in Hand -While offering some powerful opportunities, the term **Algorithm** can carry some misconceptions with it. Algorithms can generate unexpected, wild, or cool things, but they are not magic. In fact, they are pretty plain, in and of themselves. Let's use a tangible example like an origami crane. We start with a square piece of paper (input), follow a series of folding steps (processing actions), and result in a crane (output). - -![Origami Crane](images/1-1/00-OrigamiCrane.png) - -So where is the Algorithm? It is the abstract set of steps, which we can represent in a couple of ways - either textually or graphically. - -**Textual Instructions:** -1. Start with a square piece of -paper, coloured side up. Fold in half and open. Then fold in half the other way. -2. Turn the paper over to the white side. Fold the paper in half, crease well and open, and then fold again in the other direction. -3. Using the creases you have made, Bring the top 3 corners of the model down to the bottom corner. Flatten model. -4. Fold top triangular flaps into the center and unfold. -5. Fold top of model downwards, crease well and unfold. -6. Open the uppermost flap of the model, bringing it upwards and pressing the sides of the model inwards at the same time. Flatten down, creasing well. -7. Turn model over and repeat Steps 4-6 on the other side. -8. Fold top flaps into the center. -9. Repeat on other side. -10. Fold both ‘legs’ of model up, crease very well, then unfold. -11. Inside Reverse Fold the “legs” along the creases you just made. -12. Inside Reverse Fold one side to make a head, then fold down the wings. -13. You now have a crane. - -**Graphical Instructions:** - -![Needs Update- Origami Crane](images/1-1/01-OrigamiCraneInstructions.png) - -###Programming Defined -Using either of these sets of instructions should result in a crane, and if you followed along yourself, you've applied an algorithm. The only difference is the way in which we read the formalization of that set of instructions and that leads us to **Programming**. Programming, frequently shortened from *Computer Programming*, is the act of formalizing the processing of a series of actions into an executable program. If we turned the above instructions for a creating crane into a format our computer can read and execute, we are Programming. - -The key to and first hurdle we will find in Programming, is that we have to rely on some form of abstraction to communicate effectively with our computer. That takes the form of any number of Programming Languages, such as Javascript, Python, or C. If we can write out a repeatable set of instructions, like for the origami crane, we only need to translate it for the computer. We are on our way to having the computer be able to make a crane or even a multitude of different cranes where each one varies slightly. This is the power of Programming - the computer will repeatedly execute whatever task, or set of tasks, we assign to it, without delay and without human error. - -####Visual Programming Defined ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Visual Programming - Circle Through Point.dyn](datasets/1-1/Visual Programming - Circle Through Point.dyn). A full list of example files can be found in the Appendix. - -If you were tasked with writing instructions for folding an origami crane, how would you go about it? Would you make them with graphics, text, or some combination of the two? - -If your answer contained graphics, then **Visual Programming** is definitely for you. The process is essentially the same for both Programming and Visual Programming. They utilize the same framework of formalization; however, we define the instructions and relationships of our program through a graphical (or "Visual") user interface. Instead of typing text bound by syntax, we connect pre-packaged nodes together. Here's a comparison of the same algorithm - "draw a circle through a point" - programmed with nodes versus code: - -**Visual Program:** - -![Basic Visual Program ](images/1-1/03-BasicVisualProgram.png) - -**Textual Program:** -``` -myPoint = Point.ByCoordinates(0.0,0.0,0.0); -x = 5.6; -y = 11.5; -attractorPoint = Point.ByCoordinates(x,y,0.0); -dist = myPoint.DistanceTo(attractorPoint); -myCircle = Circle.ByCenterPointRadius(myPoint,dist); -``` -The results of our algorithm: - -![Circle Through Point ](images/1-1/04-CircleThroughPoint.png) - -The visual characteristic to programming in such a way lowers the barrier to entry and frequently speaks to designers. Dynamo falls in the Visual Programming paradigm, but as we will see later, we can still use textual programming in the application as well. - +###What is Visual Programming? + +Designing frequently involves establishing visual, systemic, or geometric relationships between the parts of a design. More times than not, these relationships are developed by workflows that gets us from concept to result by way of rules. Perhaps without knowing it, we are working algorithmically - defining a step-by-step set of actions that follow a basic logic of input, processing, and output. Programming allows us to continue to work this way but by formalizing our algorithms. + +###Algorithms in Hand +While offering some powerful opportunities, the term **Algorithm** can carry some misconceptions with it. Algorithms can generate unexpected, wild, or cool things, but they are not magic. In fact, they are pretty plain, in and of themselves. Let's use a tangible example like an origami crane. We start with a square piece of paper (input), follow a series of folding steps (processing actions), and result in a crane (output). + +![Origami Crane](images/1-1/00-OrigamiCrane.png) + +So where is the Algorithm? It is the abstract set of steps, which we can represent in a couple of ways - either textually or graphically. + +**Textual Instructions:** +1. Start with a square piece of +paper, coloured side up. Fold in half and open. Then fold in half the other way. +2. Turn the paper over to the white side. Fold the paper in half, crease well and open, and then fold again in the other direction. +3. Using the creases you have made, Bring the top 3 corners of the model down to the bottom corner. Flatten model. +4. Fold top triangular flaps into the center and unfold. +5. Fold top of model downwards, crease well and unfold. +6. Open the uppermost flap of the model, bringing it upwards and pressing the sides of the model inwards at the same time. Flatten down, creasing well. +7. Turn model over and repeat Steps 4-6 on the other side. +8. Fold top flaps into the center. +9. Repeat on other side. +10. Fold both ‘legs’ of model up, crease very well, then unfold. +11. Inside Reverse Fold the “legs” along the creases you just made. +12. Inside Reverse Fold one side to make a head, then fold down the wings. +13. You now have a crane. + +**Graphical Instructions:** + +![Needs Update- Origami Crane](images/1-1/01-OrigamiCraneInstructions.png) + +###Programming Defined +Using either of these sets of instructions should result in a crane, and if you followed along yourself, you've applied an algorithm. The only difference is the way in which we read the formalization of that set of instructions and that leads us to **Programming**. Programming, frequently shortened from *Computer Programming*, is the act of formalizing the processing of a series of actions into an executable program. If we turned the above instructions for a creating crane into a format our computer can read and execute, we are Programming. + +The key to and first hurdle we will find in Programming, is that we have to rely on some form of abstraction to communicate effectively with our computer. That takes the form of any number of Programming Languages, such as Javascript, Python, or C. If we can write out a repeatable set of instructions, like for the origami crane, we only need to translate it for the computer. We are on our way to having the computer be able to make a crane or even a multitude of different cranes where each one varies slightly. This is the power of Programming - the computer will repeatedly execute whatever task, or set of tasks, we assign to it, without delay and without human error. + +####Visual Programming Defined +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Visual Programming - Circle Through Point.dyn](datasets/1-1/Visual Programming - Circle Through Point.dyn). A full list of example files can be found in the Appendix. + +If you were tasked with writing instructions for folding an origami crane, how would you go about it? Would you make them with graphics, text, or some combination of the two? + +If your answer contained graphics, then **Visual Programming** is definitely for you. The process is essentially the same for both Programming and Visual Programming. They utilize the same framework of formalization; however, we define the instructions and relationships of our program through a graphical (or "Visual") user interface. Instead of typing text bound by syntax, we connect pre-packaged nodes together. Here's a comparison of the same algorithm - "draw a circle through a point" - programmed with nodes versus code: + +**Visual Program:** + +![Basic Visual Program ](images/1-1/03-BasicVisualProgram.png) + +**Textual Program:** +``` +myPoint = Point.ByCoordinates(0.0,0.0,0.0); +x = 5.6; +y = 11.5; +attractorPoint = Point.ByCoordinates(x,y,0.0); +dist = myPoint.DistanceTo(attractorPoint); +myCircle = Circle.ByCenterPointRadius(myPoint,dist); +``` +The results of our algorithm: + +![Circle Through Point ](images/1-1/04-CircleThroughPoint.png) + +The visual characteristic to programming in such a way lowers the barrier to entry and frequently speaks to designers. Dynamo falls in the Visual Programming paradigm, but as we will see later, we can still use textual programming in the application as well. + diff --git a/01_Introduction/1-2_what_is_dynamo.md b/01_Introduction/1-2_what_is_dynamo.md index b478379d..2ff55c68 100644 --- a/01_Introduction/1-2_what_is_dynamo.md +++ b/01_Introduction/1-2_what_is_dynamo.md @@ -1,29 +1,29 @@ -##What is Dynamo? -Dynamo is, quite literally, what you make it. Working with Dynamo may include using the application, either in connection with other Autodesk software or not, engaging a Visual Programming process, or participating in a broad community of users and contributors. - -###The Application -Dynamo, the application, is a software that can be downloaded and run in either stand-alone "Sandbox" mode or as a plug-in for other software like Revit or Maya. It is described as: -> A visual programming tool that aims to be accessible to both non-programmers and programmers alike. It gives users the ability to visually script behavior, define custom pieces of logic, and script using various textual programming languages. - -![Dyanmo website-update number](images/1-2/00-DynamoHomepage.png) -> 1. See Dynamo in action with Revit -2. Download the installer - -###The Process -Once we've installed the application, Dynamo will enable us to work within a Visual Programming process wherein we connect elements together to define the relationships and the sequences of actions that compose custom algorithms. We can use our algorithms for a wide array of applications - from processing data to generating geometry - all in realtime and without writing a lick of ```code```. - -![A Visual Program](images/1-2/01-ProgramFlow.png) -> Add elements, connect, and we are off and running with creating Visual Programs. - -###The Community -Dynamo wouldn't be what it is without a strong group of avid users and active contributors. Engage the community by following the Blog, adding your work to the Gallery, or discussing Dynamo in the Forum. - -![The Forum](images/1-2/02-Community.png) - -###The Platform -Dynamo is envisioned as a visual programming tool for designers, allowing us to make tools that make use of external libraries or any Autodesk product that has an API. With Dynamo Studio we can can develop programs in a "Sandbox" style application - but the Dynamo ecosystem continues to grow. - -The source code for the project is open-source, enabling us to extend its functionality to our hearts content. Check out the project on Github and browse the Works in Progress of users customizing Dynamo. - -![The Repo](images/1-2/03-TheRepo.png) -> Browse, Fork, and start extending Dynamo for your needs +##What is Dynamo? +Dynamo is, quite literally, what you make it. Working with Dynamo may include using the application, either in connection with other Autodesk software or not, engaging a Visual Programming process, or participating in a broad community of users and contributors. + +###The Application +Dynamo, the application, is a software that can be downloaded and run in either stand-alone "Sandbox" mode or as a plug-in for other software like Revit or Maya. It is described as: +> A visual programming tool that aims to be accessible to both non-programmers and programmers alike. It gives users the ability to visually script behavior, define custom pieces of logic, and script using various textual programming languages. + +![Dyanmo website-update number](images/1-2/00-DynamoHomepage.png) +> 1. See Dynamo in action with Revit +2. Download the installer + +###The Process +Once we've installed the application, Dynamo will enable us to work within a Visual Programming process wherein we connect elements together to define the relationships and the sequences of actions that compose custom algorithms. We can use our algorithms for a wide array of applications - from processing data to generating geometry - all in realtime and without writing a lick of ```code```. + +![A Visual Program](images/1-2/01-ProgramFlow.png) +> Add elements, connect, and we are off and running with creating Visual Programs. + +###The Community +Dynamo wouldn't be what it is without a strong group of avid users and active contributors. Engage the community by following the Blog, adding your work to the Gallery, or discussing Dynamo in the Forum. + +![The Forum](images/1-2/02-Community.png) + +###The Platform +Dynamo is envisioned as a visual programming tool for designers, allowing us to make tools that make use of external libraries or any Autodesk product that has an API. With Dynamo Studio we can can develop programs in a "Sandbox" style application - but the Dynamo ecosystem continues to grow. + +The source code for the project is open-source, enabling us to extend its functionality to our hearts content. Check out the project on Github and browse the Works in Progress of users customizing Dynamo. + +![The Repo](images/1-2/03-TheRepo.png) +> Browse, Fork, and start extending Dynamo for your needs diff --git a/01_Introduction/1-3_dynamo_in_action.md b/01_Introduction/1-3_dynamo_in_action.md index fa99e176..2692e19a 100644 --- a/01_Introduction/1-3_dynamo_in_action.md +++ b/01_Introduction/1-3_dynamo_in_action.md @@ -1,7 +1,7 @@ -##DYNAMO IN ACTION - -From using Visual Programming for project workflows to developing customized tools, Dynamo is an integral aspect to a wide variety of exciting applications. - -Follow the Dynamo in Action board on Pinterest. - - +##DYNAMO IN ACTION + +From using Visual Programming for project workflows to developing customized tools, Dynamo is an integral aspect to a wide variety of exciting applications. + +Follow the Dynamo in Action board on Pinterest. + + diff --git a/01_Introduction/1-X_key_concepts.md b/01_Introduction/1-X_key_concepts.md index f3c36caf..c9777d88 100644 --- a/01_Introduction/1-X_key_concepts.md +++ b/01_Introduction/1-X_key_concepts.md @@ -1,9 +1,9 @@ -### 1.4 Key Concepts - -_Introduction Text_ - -####1.4.1 Numbers -####1.4.2 Parameters -####1.4.3 Constants -####1.4.4 Operators -####1.4.5 Functions +### 1.4 Key Concepts + +_Introduction Text_ + +####1.4.1 Numbers +####1.4.2 Parameters +####1.4.3 Constants +####1.4.4 Operators +####1.4.5 Functions diff --git a/01_Introduction/1_introduction.md b/01_Introduction/1_introduction.md index 443feb22..705b6f61 100644 --- a/01_Introduction/1_introduction.md +++ b/01_Introduction/1_introduction.md @@ -1,5 +1,5 @@ -#INTRODUCTION - -From its origins as an add-on for Building Information Modeling in Revit, Dynamo has matured to become many things. Above all else it is a platform, enabling designers to explore visual programming, solve problems, and make their own tools. Let's start our journey with Dynamo by setting some context - what is it and how do I approach using it? - -![Dynamo Ecosystem](images/1/1-cover.png) +#INTRODUCTION + +From its origins as an add-on for Building Information Modeling in Revit, Dynamo has matured to become many things. Above all else it is a platform, enabling designers to explore visual programming, solve problems, and make their own tools. Let's start our journey with Dynamo by setting some context - what is it and how do I approach using it? + +![Dynamo Ecosystem](images/1/1-cover.png) diff --git a/01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn b/01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn index b747cb6a..4579b652 100644 --- a/01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn +++ b/01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn @@ -1,81 +1,81 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 11.5011100116203 - - - - 28.6701555980507 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11.5011100116203 + + + + 28.6701555980507 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01_Introduction/images/.gitkeep b/01_Introduction/images/.gitkeep index 9901e584..c22a44b3 100644 --- a/01_Introduction/images/.gitkeep +++ b/01_Introduction/images/.gitkeep @@ -1 +1 @@ -# this directory was conjured with black magic :) +# this directory was conjured with black magic :) diff --git a/02_Hello-Dynamo/2-1_launching_dynamo.md b/02_Hello-Dynamo/2-1_launching_dynamo.md index 1b0e09fb..690aa068 100644 --- a/02_Hello-Dynamo/2-1_launching_dynamo.md +++ b/02_Hello-Dynamo/2-1_launching_dynamo.md @@ -1,54 +1,54 @@ -## Installing and Launching Dynamo - -Dynamo is an active open-source development project with downloadable installers for both official and pre-release, ie. "daily build" versions. Download the official release to get started, or contribute to what Dynamo becomes through the daily builds or Github project. - -### Downloading - -To download the official released version of Dynamo, visit the [Dynamo website](http://dynamobim.com/). Start the download immediately by clicking from the homepage or browse to the dedicated download page. - -![website homepage](images/2-1/01-DynamoHomepage.png) - -> 1. Watch a video on Computational Design with Dynamo for Architecture -> 2. Or browse to the download page - -Here you can download the "bleeding edge" development versions or go to the [Dynamo Github](https://github.com/DynamoDS/Dynamo) project. - -![website downloads page](images/2-1/02-DynamoDownload.png) - -> 1. Download the official release installer -> 2. Download the daily build installers -> 3. Get involved in the development of Dynamo on Github - -### Installing - -Browse to the directory of the downloaded installer and run the executable file. During the installation process, the setup allows you to customize the components that will be installed. - -![Setup Window](images/2-1/03-InstallSetup.png) - -> 1. Select the Components you want to install - -Here we need to decide if we want to include the components that connect Dynamo to other installed applications such as Revit. For more information on the Dynamo Platform, see **Chapter 1.2**. - -### Launching - -To launch Dynamo, browse to the Windows Start Menu > Dynamo > **Dynamo**. This will open the stand-alone version and present Dynamo's _Start Page_. On this page, we see the standard menus and toolbar as well as a collection of shortcuts that allow us to access file functionality or access additional resources. - -![NEEDS UPDATE - labels Dynamo start page](images/2-1/04-DynamoStartpage.png) - -> 1. Files - Start a new file or open an existing one -> 2. Recent - Scroll through your recent files -> 3. Samples - Check out the examples that come with the installation -> 4. Ask - Get direct access to the User Forum or Dynamo Website -> 5. Reference - Go further with additional learning resources -> 6. Code - Participate in the open-source development project - -Open the first sample file to open your first workspace and confirm Dynamo is working correctly. Click Samples > Basics > **Basics\_Basic01.dyn**. - -![NEEDS UPDATE - Basics_Basic01](images/2-1/05-Basics_Basic01.png) - -> 1. Confirm that the Execution Bar says "Automatic" or click Run -> 2. Follow the instructions and connect the **Number** Node to the **+** Node -> 3. Confirm that this Watch Node shows a result - -If this file successfully loads, you should be able to execute your first visual program with Dynamo. - +## Installing and Launching Dynamo + +Dynamo is an active open-source development project with downloadable installers for both official and pre-release, ie. "daily build" versions. Download the official release to get started, or contribute to what Dynamo becomes through the daily builds or Github project. + +### Downloading + +To download the official released version of Dynamo, visit the [Dynamo website](http://dynamobim.com/). Start the download immediately by clicking from the homepage or browse to the dedicated download page. + +![website homepage](images/2-1/01-DynamoHomepage.png) + +> 1. Watch a video on Computational Design with Dynamo for Architecture +> 2. Or browse to the download page + +Here you can download the "bleeding edge" development versions or go to the [Dynamo Github](https://github.com/DynamoDS/Dynamo) project. + +![website downloads page](images/2-1/02-DynamoDownload.png) + +> 1. Download the official release installer +> 2. Download the daily build installers +> 3. Get involved in the development of Dynamo on Github + +### Installing + +Browse to the directory of the downloaded installer and run the executable file. During the installation process, the setup allows you to customize the components that will be installed. + +![Setup Window](images/2-1/03-InstallSetup.png) + +> 1. Select the Components you want to install + +Here we need to decide if we want to include the components that connect Dynamo to other installed applications such as Revit. For more information on the Dynamo Platform, see **Chapter 1.2**. + +### Launching + +To launch Dynamo, browse to the Windows Start Menu > Dynamo > **Dynamo**. This will open the stand-alone version and present Dynamo's _Start Page_. On this page, we see the standard menus and toolbar as well as a collection of shortcuts that allow us to access file functionality or access additional resources. + +![NEEDS UPDATE - labels Dynamo start page](images/2-1/04-DynamoStartpage.png) + +> 1. Files - Start a new file or open an existing one +> 2. Recent - Scroll through your recent files +> 3. Samples - Check out the examples that come with the installation +> 4. Ask - Get direct access to the User Forum or Dynamo Website +> 5. Reference - Go further with additional learning resources +> 6. Code - Participate in the open-source development project + +Open the first sample file to open your first workspace and confirm Dynamo is working correctly. Click Samples > Basics > **Basics\_Basic01.dyn**. + +![NEEDS UPDATE - Basics_Basic01](images/2-1/05-Basics_Basic01.png) + +> 1. Confirm that the Execution Bar says "Automatic" or click Run +> 2. Follow the instructions and connect the **Number** Node to the **+** Node +> 3. Confirm that this Watch Node shows a result + +If this file successfully loads, you should be able to execute your first visual program with Dynamo. + diff --git a/02_Hello-Dynamo/2-2_the_dynamo_ui.md b/02_Hello-Dynamo/2-2_the_dynamo_ui.md index 78c35d9b..3532ddc4 100644 --- a/02_Hello-Dynamo/2-2_the_dynamo_ui.md +++ b/02_Hello-Dynamo/2-2_the_dynamo_ui.md @@ -1,111 +1,111 @@ -##The Dynamo User Interface - -The User Interface (UI) for Dynamo is organized into five main regions, the largest of which is the workspace where we compose our visual programs. - -![User Interface Regions](images/2-2/01-UI-Regions.png) - ->1. Menus -2. Toolbar -3. Library -4. Workspace -5. Execution Bar - -Let's dive deeper into the UI and explore the functionality of each region. - -####Menus - -The Dropdown Menus are a great place to find some of the basic functionality of the Dynamo application. Like most Windows software, actions related to managing files and operations for selection and content editing are found in the first two menus. The remaining menus are more specific to Dynamo. - -![Dropdown Menus](images/2-2/02-Menus.png) -> 1. File -2. Edit -3. View -4. Packages -5. Settings -6. Help - -####Toolbar - -Dynamo's Toolbar contains a series of buttons for quick access to working with files as well as Undo [Ctrl + Z] and Redo [Ctrl + Y] commands. On the far right is another button that will export a snapshot of the workspace, which is extremely useful for documentation and sharing. - -![Needs Update-split location Toolbar](images/2-2/03-Toolbar.png) - -> 1. New - Create a new .dyn file -2. Open - Open an existing .dyn (workspace) or .dyf (custom node) file -3. Save/Save As - Save your active .dyn or .dyf file -4. Undo - Undo your last action -5. Redo - Redo the next action -6. Export Workspace as Image - Export the visible workspace as a PNG file - -####Library -The Library contains all of the loaded Nodes, including the default Nodes that come with the installation as well as any additionally loaded Custom Nodes or Packages. The Nodes in the Library are organized hierarchically within libraries, categories, and, where appropriate, sub-categories based on whether the Nodes **Create** data, execute an **Action**, or **Query** data. - -#####Browsing -By default, the **Library** will contain eight categories of Nodes. **Core** and **Geometry** are great menus to begin exploring as they contain the largest quantity of Nodes. Browsing through these categories is the fastest way to understand the hierarchy of what we can add to our Workspace and the best way to discover new Nodes you haven't used before. - -> We will focus on the default collection of Nodes now, but note that we will extend this Library with Custom Nodes, additional libraries, and the Package Manager later. - -![NEEDS UPDATE-full width - Library Categories](images/2-2/04-LibraryCategories.png) ->1. Analyze -2. Built-in Functions -3. Core -4. Geometry -5. Migration -6. Office -7. Operators - -Browse the Library by clicking through the menus. Click the Geometry > Circle. Note the new portion of the menu that is revealed and specifically the **Create** and **Query** Labels. - -![NEEDS UPDATE-use full width - Browsing the Library](images/2-2/05-LibraryBrowsing.png) ->1. Library -2. Category -3. Subcategory: Create/Actions/Query -4. Node -5. Node Description and properties - this appears when hovering over the node icon. - -From the same Circle menu, hover your mouse over **ByCenterPointRadius**. The window reveals more detailed information about the Node beyond its name and icon. This offers us a quick way to understand what the Node does, what it will require for inputs, and what it will give as an output. - -![Node Pop Up Window](images/2-2/06-NodePopup.png) ->1. Description - plain language description of the Node -2. Icon - larger version of the icon in the Library Menu -3. Input(s) - name, data type, and data structure -4. Output(s) - data type and structure - -#####Searching -If you know with relative specificity which Node you want to add to your Workspace, the **Search** field is your best friend. When you are not editing settings or specifying values in the Workspace, the cursor is always present in this field. If you start typing, the Dynamo Library will reveal a selected best fit match (with breadcrumbs for where it can be found in the Node categories) and a list of alternate matches to the search. When you hit Enter, or click on the item in the truncated browser, the highlighted Node is added to the center of the Workspace. - -![Searching the Library](images/2-2/07-LibrarySearching.png) ->1. Search Field -2. Best Fit Result / Selected -3. Alternate Matches - -###Settings -From geometric to user settings, these options can be found in the **Settings** menu. Here you can opt in or out for sharing your user data to improve Dynamo as well as define the application's decimal point precision and geometry render quality. - -> Note: Remember that Dynamo's units are generic. - -![show menu](images/2-2/08-Settings.png) - ->1. Enabling Reporting - Options for sharing user data to improve Dynamo. -2. Number Format Options - Change the document settings for decimals. -3. Render Precision - Raise or lower the document render quality. -4. Show/Hide Geometry Edges - Toggle 3D geometry edges. -5. Show/Hide Preview Bubbles - Toggle data preview bubbles below nodes. -6. Manage Node and Package Paths - Manage file paths to make nodes and packages show up in the Library. -7. Enabling Experimental Features - Use beta features new in Dynamo. - -###Help -If you're stuck, check out the **Help** Menu. Here you can find the sample files that come with your installation as well as access one of the Dynamo reference websites through your internet browser. If you need to, check the version of Dynamo installed and whether it is up to date through the **About** option. - -![show menu](images/2-2/09-Help.png) - ->1. Getting Started - A brief introduction to using Dynamo. -2. Samples - Reference example files. -3. Report A Bug - Open an Issue on GitHub. -4. Go To Project Website - View the Dynamo Project on GitHub. -5. Go To Project Wiki - Visit the wiki for learning about development using the Dynamo API, supporting libraries and tools. -6. Display Start Page - Return to the Dynamo start page when within a document. -7. About - Dynamo Version data. - - - +##The Dynamo User Interface + +The User Interface (UI) for Dynamo is organized into five main regions, the largest of which is the workspace where we compose our visual programs. + +![User Interface Regions](images/2-2/01-UI-Regions.png) + +>1. Menus +2. Toolbar +3. Library +4. Workspace +5. Execution Bar + +Let's dive deeper into the UI and explore the functionality of each region. + +####Menus + +The Dropdown Menus are a great place to find some of the basic functionality of the Dynamo application. Like most Windows software, actions related to managing files and operations for selection and content editing are found in the first two menus. The remaining menus are more specific to Dynamo. + +![Dropdown Menus](images/2-2/02-Menus.png) +> 1. File +2. Edit +3. View +4. Packages +5. Settings +6. Help + +####Toolbar + +Dynamo's Toolbar contains a series of buttons for quick access to working with files as well as Undo [Ctrl + Z] and Redo [Ctrl + Y] commands. On the far right is another button that will export a snapshot of the workspace, which is extremely useful for documentation and sharing. + +![Needs Update-split location Toolbar](images/2-2/03-Toolbar.png) + +> 1. New - Create a new .dyn file +2. Open - Open an existing .dyn (workspace) or .dyf (custom node) file +3. Save/Save As - Save your active .dyn or .dyf file +4. Undo - Undo your last action +5. Redo - Redo the next action +6. Export Workspace as Image - Export the visible workspace as a PNG file + +####Library +The Library contains all of the loaded Nodes, including the default Nodes that come with the installation as well as any additionally loaded Custom Nodes or Packages. The Nodes in the Library are organized hierarchically within libraries, categories, and, where appropriate, sub-categories based on whether the Nodes **Create** data, execute an **Action**, or **Query** data. + +#####Browsing +By default, the **Library** will contain eight categories of Nodes. **Core** and **Geometry** are great menus to begin exploring as they contain the largest quantity of Nodes. Browsing through these categories is the fastest way to understand the hierarchy of what we can add to our Workspace and the best way to discover new Nodes you haven't used before. + +> We will focus on the default collection of Nodes now, but note that we will extend this Library with Custom Nodes, additional libraries, and the Package Manager later. + +![NEEDS UPDATE-full width - Library Categories](images/2-2/04-LibraryCategories.png) +>1. Analyze +2. Built-in Functions +3. Core +4. Geometry +5. Migration +6. Office +7. Operators + +Browse the Library by clicking through the menus. Click the Geometry > Circle. Note the new portion of the menu that is revealed and specifically the **Create** and **Query** Labels. + +![NEEDS UPDATE-use full width - Browsing the Library](images/2-2/05-LibraryBrowsing.png) +>1. Library +2. Category +3. Subcategory: Create/Actions/Query +4. Node +5. Node Description and properties - this appears when hovering over the node icon. + +From the same Circle menu, hover your mouse over **ByCenterPointRadius**. The window reveals more detailed information about the Node beyond its name and icon. This offers us a quick way to understand what the Node does, what it will require for inputs, and what it will give as an output. + +![Node Pop Up Window](images/2-2/06-NodePopup.png) +>1. Description - plain language description of the Node +2. Icon - larger version of the icon in the Library Menu +3. Input(s) - name, data type, and data structure +4. Output(s) - data type and structure + +#####Searching +If you know with relative specificity which Node you want to add to your Workspace, the **Search** field is your best friend. When you are not editing settings or specifying values in the Workspace, the cursor is always present in this field. If you start typing, the Dynamo Library will reveal a selected best fit match (with breadcrumbs for where it can be found in the Node categories) and a list of alternate matches to the search. When you hit Enter, or click on the item in the truncated browser, the highlighted Node is added to the center of the Workspace. + +![Searching the Library](images/2-2/07-LibrarySearching.png) +>1. Search Field +2. Best Fit Result / Selected +3. Alternate Matches + +###Settings +From geometric to user settings, these options can be found in the **Settings** menu. Here you can opt in or out for sharing your user data to improve Dynamo as well as define the application's decimal point precision and geometry render quality. + +> Note: Remember that Dynamo's units are generic. + +![show menu](images/2-2/08-Settings.png) + +>1. Enabling Reporting - Options for sharing user data to improve Dynamo. +2. Number Format Options - Change the document settings for decimals. +3. Render Precision - Raise or lower the document render quality. +4. Show/Hide Geometry Edges - Toggle 3D geometry edges. +5. Show/Hide Preview Bubbles - Toggle data preview bubbles below nodes. +6. Manage Node and Package Paths - Manage file paths to make nodes and packages show up in the Library. +7. Enabling Experimental Features - Use beta features new in Dynamo. + +###Help +If you're stuck, check out the **Help** Menu. Here you can find the sample files that come with your installation as well as access one of the Dynamo reference websites through your internet browser. If you need to, check the version of Dynamo installed and whether it is up to date through the **About** option. + +![show menu](images/2-2/09-Help.png) + +>1. Getting Started - A brief introduction to using Dynamo. +2. Samples - Reference example files. +3. Report A Bug - Open an Issue on GitHub. +4. Go To Project Website - View the Dynamo Project on GitHub. +5. Go To Project Wiki - Visit the wiki for learning about development using the Dynamo API, supporting libraries and tools. +6. Display Start Page - Return to the Dynamo start page when within a document. +7. About - Dynamo Version data. + + + diff --git a/02_Hello-Dynamo/2-3_the_workspace.md b/02_Hello-Dynamo/2-3_the_workspace.md index ee93e2af..51cd5599 100644 --- a/02_Hello-Dynamo/2-3_the_workspace.md +++ b/02_Hello-Dynamo/2-3_the_workspace.md @@ -1,82 +1,82 @@ -##The Workspace - -The Dynamo **Workspace** is where we develop our visual programs, but it's also where we preview any resulting geometry. Whether we are working in a Home Workspace or a Custom Node, we can navigate with our mouse or the buttons at top right. Toggling between modes at bottom right switches which preview we navigate. - -> Note: Nodes and geometry have a draw order so you may have objects rendered on top of each other. This can be confusing when adding multiple nodes in sequence as they may be rendered in the same position in the Workspace. - -![Workspace Regions](images/2-3/01-WorkspaceRegions.png) - ->1. Tabs -2. Zoom/Pan Buttons -3. Preview Mode -4. Double Clicking on the Workspace - -###Tabs -The active Workspace tab allows you to navigate and edit your program. When you open a new file, by default you are opening a new **Home** Workspace. You may also open a new **Custom Node** Workspace from the File Menu or by the *New Node by Selection* right click option when Nodes are selected (more eon this functionality later). - -![Tabs](images/2-3/02-Tabs.png) - -> Note: You may have only one Home Workspace open at a time; however, you may have multiple Custom Node Workspaces open in additional tabs. - -###Graph versus 3D Preview Navigation -In Dynamo, the Graph and the 3D results of the Graph (if we are creating geometry) are both rendered in the Workspace. By default the Graph is the active preview, so using the Navigation buttons or middle mouse button to pan and zoom will move us through the Graph. Toggling between active previews can be achieved three ways: - -![Navigation](images/2-3/03-PreviewNavigations.png) - -> 1. Preview Toggle Buttons in the Workspace -2. Right clicking in the Workspace and selecting *Switch to ... View* -3. Keyboard shortcut (Ctrl + B) - -The 3D Preview Navigation mode also gives us the ability for **Direct Manipulation** of points, exemplified in [Getting Started](http://dynamoprimer.com/02_Hello-Dynamo/2-6_the_quick_start_guide.html). - -###Zoom to Recenter - We can easily pan, zoom and rotate freely around models in 3D Preview Navigation mode. However, to zoom specifically on an object created by a geometry node, we can use the Zoom All icon with a single node selected. - -![Zoom to Recenter 1](images/2-3/03-ZoomToRecenter_1.jpg) -> 1. Select the node corresponding to the geometry that will center the view. -2. Switch to the 3D Preview Navigation. - -![Zoom to Recenter 2](images/2-3/03-ZoomToRecenter_2.jpg) -> 1. Click on the Zoom All icon in the top right. -2. The selected geometry will be centered inside the view. - -###Hello Mouse! - -Based on which Preview mode is active, your mouse buttons will act differently. In general, the left mouse click selects and specifies inputs, the right mouse click gives access to options, and the middle mouse click allows you to navigate the Workspace. The right mouse click will present us with options based on the context of where we are clicking. - -![Hello Mouse](images/2-3/04-HelloMouse.png) - ->1. Right Click on the Workspace. -2. Right Click on a Node. -3. Right Click on a Note. - -Here's a table of mouse interactions per Preview: - -**Mouse Action** | **Graph Preview** | **3D Preview** ---- | --- | --- -Left Click | Select | N/A -Right Click | Context Menu | Zoom Options -Middle Click | Pan | Pan -Scroll | Zoom In/Out | Zoom In/Out -Double Click | Create Code Block | N/A - -###In-Canvas Search - -Using the "In-Canvas Search" will add some serious speed to your Dynamo work-flow by providing you access to node descriptions and tool-tips without taking you away from your place on the graph! By just right-clicking, you can access all the useful functionality of the "Library Search" from wherever you happen to be working on the canvas. - -![In Canvas Search](images/2-3/05-InCanvasSearch.png) - ->1. Right click anywhere on the canvas to bring up the search feature. While the search bar is empty, the drop-down will be a preview menu. -2. As you type into the search bar, the drop-down menu will continuously update to show the most relevant search results. -3. Hover over the search results to bring up their corresponding descriptions and tool-tips. - -##Clean Up Node Layout -Keeping your Dynamo canvas organized becomes increasingly important as your files build in complexity. Although we have the **Align Selection** tool to work with small amounts of selected Nodes, Dynamo also features the **Cleanup Node Layout** tool to help with overall file cleanup. -####Before Node Cleanup -![Cleanup Node Layout](images/2-3/06-CleanupNodeLayout.png) ->1. Select the Nodes to be automatically organized, or leave all unselected to clean up all nodes in the file. -2. The Cleanup Node Layout feature is located under the Edit tab. -####After Node Cleanup -![Clean Layout Example](images/2-3/07-CleanupNodeLayout.png) ->1. The nodes will be automatically re-distributed and aligned, cleaning up any staggered or overlapping nodes and aligning them with neighboring nodes. - +##The Workspace + +The Dynamo **Workspace** is where we develop our visual programs, but it's also where we preview any resulting geometry. Whether we are working in a Home Workspace or a Custom Node, we can navigate with our mouse or the buttons at top right. Toggling between modes at bottom right switches which preview we navigate. + +> Note: Nodes and geometry have a draw order so you may have objects rendered on top of each other. This can be confusing when adding multiple nodes in sequence as they may be rendered in the same position in the Workspace. + +![Workspace Regions](images/2-3/01-WorkspaceRegions.png) + +>1. Tabs +2. Zoom/Pan Buttons +3. Preview Mode +4. Double Clicking on the Workspace + +###Tabs +The active Workspace tab allows you to navigate and edit your program. When you open a new file, by default you are opening a new **Home** Workspace. You may also open a new **Custom Node** Workspace from the File Menu or by the *New Node by Selection* right click option when Nodes are selected (more eon this functionality later). + +![Tabs](images/2-3/02-Tabs.png) + +> Note: You may have only one Home Workspace open at a time; however, you may have multiple Custom Node Workspaces open in additional tabs. + +###Graph versus 3D Preview Navigation +In Dynamo, the Graph and the 3D results of the Graph (if we are creating geometry) are both rendered in the Workspace. By default the Graph is the active preview, so using the Navigation buttons or middle mouse button to pan and zoom will move us through the Graph. Toggling between active previews can be achieved three ways: + +![Navigation](images/2-3/03-PreviewNavigations.png) + +> 1. Preview Toggle Buttons in the Workspace +2. Right clicking in the Workspace and selecting *Switch to ... View* +3. Keyboard shortcut (Ctrl + B) + +The 3D Preview Navigation mode also gives us the ability for **Direct Manipulation** of points, exemplified in [Getting Started](http://dynamoprimer.com/02_Hello-Dynamo/2-6_the_quick_start_guide.html). + +###Zoom to Recenter + We can easily pan, zoom and rotate freely around models in 3D Preview Navigation mode. However, to zoom specifically on an object created by a geometry node, we can use the Zoom All icon with a single node selected. + +![Zoom to Recenter 1](images/2-3/03-ZoomToRecenter_1.jpg) +> 1. Select the node corresponding to the geometry that will center the view. +2. Switch to the 3D Preview Navigation. + +![Zoom to Recenter 2](images/2-3/03-ZoomToRecenter_2.jpg) +> 1. Click on the Zoom All icon in the top right. +2. The selected geometry will be centered inside the view. + +###Hello Mouse! + +Based on which Preview mode is active, your mouse buttons will act differently. In general, the left mouse click selects and specifies inputs, the right mouse click gives access to options, and the middle mouse click allows you to navigate the Workspace. The right mouse click will present us with options based on the context of where we are clicking. + +![Hello Mouse](images/2-3/04-HelloMouse.png) + +>1. Right Click on the Workspace. +2. Right Click on a Node. +3. Right Click on a Note. + +Here's a table of mouse interactions per Preview: + +**Mouse Action** | **Graph Preview** | **3D Preview** +--- | --- | --- +Left Click | Select | N/A +Right Click | Context Menu | Zoom Options +Middle Click | Pan | Pan +Scroll | Zoom In/Out | Zoom In/Out +Double Click | Create Code Block | N/A + +###In-Canvas Search + +Using the "In-Canvas Search" will add some serious speed to your Dynamo work-flow by providing you access to node descriptions and tool-tips without taking you away from your place on the graph! By just right-clicking, you can access all the useful functionality of the "Library Search" from wherever you happen to be working on the canvas. + +![In Canvas Search](images/2-3/05-InCanvasSearch.png) + +>1. Right click anywhere on the canvas to bring up the search feature. While the search bar is empty, the drop-down will be a preview menu. +2. As you type into the search bar, the drop-down menu will continuously update to show the most relevant search results. +3. Hover over the search results to bring up their corresponding descriptions and tool-tips. + +##Clean Up Node Layout +Keeping your Dynamo canvas organized becomes increasingly important as your files build in complexity. Although we have the **Align Selection** tool to work with small amounts of selected Nodes, Dynamo also features the **Cleanup Node Layout** tool to help with overall file cleanup. +####Before Node Cleanup +![Cleanup Node Layout](images/2-3/06-CleanupNodeLayout.png) +>1. Select the Nodes to be automatically organized, or leave all unselected to clean up all nodes in the file. +2. The Cleanup Node Layout feature is located under the Edit tab. +####After Node Cleanup +![Clean Layout Example](images/2-3/07-CleanupNodeLayout.png) +>1. The nodes will be automatically re-distributed and aligned, cleaning up any staggered or overlapping nodes and aligning them with neighboring nodes. + diff --git a/02_Hello-Dynamo/2-4_the_workflow.md b/02_Hello-Dynamo/2-4_the_workflow.md index 70d2a447..dcdc922e 100644 --- a/02_Hello-Dynamo/2-4_the_workflow.md +++ b/02_Hello-Dynamo/2-4_the_workflow.md @@ -1,11 +1,11 @@ -## 2.4 The Workflow - -_Introduction Text_ - -###2.4.1 Navigation -####2.4.1.1 View Settings -####2.4.1.2 Graph versus geometry navigation -###2.4.2 Nodes -###2.4.3 Wires - -###2.4.4 Execution Bar – ie Running the Workspace +## 2.4 The Workflow + +_Introduction Text_ + +###2.4.1 Navigation +####2.4.1.1 View Settings +####2.4.1.2 Graph versus geometry navigation +###2.4.2 Nodes +###2.4.3 Wires + +###2.4.4 Execution Bar – ie Running the Workspace diff --git a/02_Hello-Dynamo/2-5_file_types_and_management.md b/02_Hello-Dynamo/2-5_file_types_and_management.md index d4607af1..3016bd4e 100644 --- a/02_Hello-Dynamo/2-5_file_types_and_management.md +++ b/02_Hello-Dynamo/2-5_file_types_and_management.md @@ -1,7 +1,7 @@ -## 2.5 File Types and Management - -Introduction Text - -* dyn -* dyf -* packages? +## 2.5 File Types and Management + +Introduction Text + +* dyn +* dyf +* packages? diff --git a/02_Hello-Dynamo/2-6_the_quick_start_guide.md b/02_Hello-Dynamo/2-6_the_quick_start_guide.md index da83ca19..47b4c0b1 100644 --- a/02_Hello-Dynamo/2-6_the_quick_start_guide.md +++ b/02_Hello-Dynamo/2-6_the_quick_start_guide.md @@ -1,80 +1,80 @@ -##GETTING STARTED - -Now that we have familiarized ourselves with the interface layout and navigating the Workspace, our next step is to understand the typical workflow for developing a graph in Dynamo. Let's get started by creating a dynamically sized circle and then create an array of circles with varying radii. - -###Defining Objectives and Relationships -Before we add anything to the Dynamo Workspace, it is key that we have a solid understanding of what we are trying to achieve and what the significant relationships will be. Remember that anytime we are connecting two Nodes, we are creating an explicit link between them - we may change the flow of data later, but once connected we've commited to that relationship. In this exercise we want to create a circle (*Objective*) where the radius input is defined by a distance to a nearby point (*Relationship*). - -![Hand Sketch of Circle](images/2-4/00-Hand-Sketch-of-Circle.png) - -> A point that defines a distance-based relationship is commonly referred to as an "Attractor." Here the distance to our Attractor Point will be used to specify how big our circle should be. - -###Adding Nodes to the Workspace -Now that we have our Objectives and Relationships sketched we can begin creating our graph. We need the Nodes that will represent the sequence of actions Dynamo will execute. Since we know we are trying to create a circle, let's start by locating a Node that does so. Using the Search field or browsing through the Library, we will find that there is more than one way to create a circle. - -![Browse and Search](images/2-4/01-BrowseAndSearch.png) -> 1. Browse to Geometry > Circle > **Circle.ByPointRadius** -2. Search > "Circle by Point..." - -Let's add the **Circle.ByPointRadius** Node to the Workspace by clicking on it in the Library - this should add the Node to the center of the Workspace. - -![Circle Added](images/2-4/02-CircleAdded.png) - -> 1. The Circle.ByPointandRadius Node in the Library -2. Clicking the Node in the Library adds it to the Workspace - -We also will need **Point.ByCoordinates**, **Number Input**, and **Number Slider** Nodes. - -![Objects Added](images/2-4/03-NodesAdded.png) - -> 1. Geometry > Point > **Point.ByCoordinates** -2. Geometry > Geometry > **DistanceTo** -2. Core > Input > **Number** -3. Core > Input > **Number Slider** - -###Connecting Nodes with Wires -Now that we have a few Nodes, we need to connect the Ports of the Nodes with Wires. These connections will define the flow of data. - -![Connections made](images/2-4/04-NodesConnected.png) -> 1. **Number** to **Point.ByCoordinates** -2. **Number Sliders** to **Point.ByCoordinates** -3. **Point.ByCoordinates** (2) to **DistanceTo** -4. **Point.ByCoordinates** and **DistanceTo** to **Circle.ByCenterPointRadius** - -###Executing the Program -With our Program Flow defined, all we need to do is tell Dynamo to execute it. Once our program is executed (either Automatically or when we click Run in Manual Mode), data will pass through the Wires, and we should see the results in the 3d Preview. - -![After Run](images/2-4/05-GraphExecuted.png) -> 1. (Click Run) - If the Execution Bar is in Manual Mode, we need to Click Run to execute the graph -2. Node Preview - Hovering your mouse over the box on the lower right corner of a Node will give you a pop-up of the results -3. 3D Preview - If any of our Nodes create geometry, we will see it in the 3D Preview. - -###Adding Detail -If our program is working, we should see a circle in the 3D Preview that is passing through our Attractor Point. This is great, but we may want to add more detail or more controls. Let's adjust the input to the circle Node so that we can calibrate the influence on the radius. Add another **Number Slider** to the Workspace, then double click on a blank area of the Workspace to add a **Code Block** Node. Edit the field in the Code Block, specifying ```X/Y```. - -![Code Block included](images/2-4/06-CodeBlock.png) ->1. **Code Block** -2. **DistanceTo** and **Number Slider** to **Code Block** -3. **Code Block** to **Circle.ByCenterPointRadius** - -###Adding complexity -Starting simple and building complexity is an effective way to incrementally develop our program. Once it is working for one circle, let's apply the power of the program to more than one circle. Instead of one center point, if we use a grid of points and accommodate the change in the resulting data structure, our program will now create many circles - each with a unique radius value defined by the calibrated distance to the Attractor Point. - -![Updated graph](images/2-4/07-AddingComplexity.png) ->1. Add a **Number Sequence** Node and replace the inputs of **Point.ByCoordinates** - Right Click Point.ByCoordinates and select Lacing > Cross Reference -2. Add a **Flatten** Node after Point.ByCoordinates -3. The 3D Preview will update with a grid of circles - -###Adjusting with Direct Manipulation -Sometimes numerical manipulation isn't the right approach. Now you can manually push and pull Point geometry when navigating in the background 3D preview. We can also control other geometry that was constructed by a point. For example, **Sphere.ByCenterPointRadius** is capable of Direct Manipulation as well. We can control the location of a point from a series of X, Y, and Z values with **Point.ByCoordinates**. With the Direct Manipulation approach, however, you are able to update the values of the sliders by manually moving the point in the **3D Preview Navigation** mode. This offers a more intuitive approach to controlling a set of discrete values that identify a point's location. - -![Selected Point](images/2-4/08-SelectedPoint.png) ->1. To use **Direct Manipulation**, select the panel of the point to be moved – arrows will appear over the point selected. -2. Switch to **3D Preview Navigation** mode. - -![Direct Point Manipulation](images/2-4/09-DirectPointManipulation.png) ->1. Hover over the point and the X, Y, and Z axes will appear. -2. Click and drag the colored arrow to move the corresponding axis, and the **Number Slider** values will update live with the manually moved point. - -![Updated Sliders](images/2-4/10-UpdatedSliders.png) ->1. Note that before **Direct Manipulation** only one slider was plugged into the **Point.ByCoordinates** component. When we manually move the point in the X-direction, Dynamo will automatically generate a new **Number Slider** for the X input. +##GETTING STARTED + +Now that we have familiarized ourselves with the interface layout and navigating the Workspace, our next step is to understand the typical workflow for developing a graph in Dynamo. Let's get started by creating a dynamically sized circle and then create an array of circles with varying radii. + +###Defining Objectives and Relationships +Before we add anything to the Dynamo Workspace, it is key that we have a solid understanding of what we are trying to achieve and what the significant relationships will be. Remember that anytime we are connecting two Nodes, we are creating an explicit link between them - we may change the flow of data later, but once connected we've commited to that relationship. In this exercise we want to create a circle (*Objective*) where the radius input is defined by a distance to a nearby point (*Relationship*). + +![Hand Sketch of Circle](images/2-4/00-Hand-Sketch-of-Circle.png) + +> A point that defines a distance-based relationship is commonly referred to as an "Attractor." Here the distance to our Attractor Point will be used to specify how big our circle should be. + +###Adding Nodes to the Workspace +Now that we have our Objectives and Relationships sketched we can begin creating our graph. We need the Nodes that will represent the sequence of actions Dynamo will execute. Since we know we are trying to create a circle, let's start by locating a Node that does so. Using the Search field or browsing through the Library, we will find that there is more than one way to create a circle. + +![Browse and Search](images/2-4/01-BrowseAndSearch.png) +> 1. Browse to Geometry > Circle > **Circle.ByPointRadius** +2. Search > "Circle by Point..." + +Let's add the **Circle.ByPointRadius** Node to the Workspace by clicking on it in the Library - this should add the Node to the center of the Workspace. + +![Circle Added](images/2-4/02-CircleAdded.png) + +> 1. The Circle.ByPointandRadius Node in the Library +2. Clicking the Node in the Library adds it to the Workspace + +We also will need **Point.ByCoordinates**, **Number Input**, and **Number Slider** Nodes. + +![Objects Added](images/2-4/03-NodesAdded.png) + +> 1. Geometry > Point > **Point.ByCoordinates** +2. Geometry > Geometry > **DistanceTo** +2. Core > Input > **Number** +3. Core > Input > **Number Slider** + +###Connecting Nodes with Wires +Now that we have a few Nodes, we need to connect the Ports of the Nodes with Wires. These connections will define the flow of data. + +![Connections made](images/2-4/04-NodesConnected.png) +> 1. **Number** to **Point.ByCoordinates** +2. **Number Sliders** to **Point.ByCoordinates** +3. **Point.ByCoordinates** (2) to **DistanceTo** +4. **Point.ByCoordinates** and **DistanceTo** to **Circle.ByCenterPointRadius** + +###Executing the Program +With our Program Flow defined, all we need to do is tell Dynamo to execute it. Once our program is executed (either Automatically or when we click Run in Manual Mode), data will pass through the Wires, and we should see the results in the 3d Preview. + +![After Run](images/2-4/05-GraphExecuted.png) +> 1. (Click Run) - If the Execution Bar is in Manual Mode, we need to Click Run to execute the graph +2. Node Preview - Hovering your mouse over the box on the lower right corner of a Node will give you a pop-up of the results +3. 3D Preview - If any of our Nodes create geometry, we will see it in the 3D Preview. + +###Adding Detail +If our program is working, we should see a circle in the 3D Preview that is passing through our Attractor Point. This is great, but we may want to add more detail or more controls. Let's adjust the input to the circle Node so that we can calibrate the influence on the radius. Add another **Number Slider** to the Workspace, then double click on a blank area of the Workspace to add a **Code Block** Node. Edit the field in the Code Block, specifying ```X/Y```. + +![Code Block included](images/2-4/06-CodeBlock.png) +>1. **Code Block** +2. **DistanceTo** and **Number Slider** to **Code Block** +3. **Code Block** to **Circle.ByCenterPointRadius** + +###Adding complexity +Starting simple and building complexity is an effective way to incrementally develop our program. Once it is working for one circle, let's apply the power of the program to more than one circle. Instead of one center point, if we use a grid of points and accommodate the change in the resulting data structure, our program will now create many circles - each with a unique radius value defined by the calibrated distance to the Attractor Point. + +![Updated graph](images/2-4/07-AddingComplexity.png) +>1. Add a **Number Sequence** Node and replace the inputs of **Point.ByCoordinates** - Right Click Point.ByCoordinates and select Lacing > Cross Reference +2. Add a **Flatten** Node after Point.ByCoordinates +3. The 3D Preview will update with a grid of circles + +###Adjusting with Direct Manipulation +Sometimes numerical manipulation isn't the right approach. Now you can manually push and pull Point geometry when navigating in the background 3D preview. We can also control other geometry that was constructed by a point. For example, **Sphere.ByCenterPointRadius** is capable of Direct Manipulation as well. We can control the location of a point from a series of X, Y, and Z values with **Point.ByCoordinates**. With the Direct Manipulation approach, however, you are able to update the values of the sliders by manually moving the point in the **3D Preview Navigation** mode. This offers a more intuitive approach to controlling a set of discrete values that identify a point's location. + +![Selected Point](images/2-4/08-SelectedPoint.png) +>1. To use **Direct Manipulation**, select the panel of the point to be moved – arrows will appear over the point selected. +2. Switch to **3D Preview Navigation** mode. + +![Direct Point Manipulation](images/2-4/09-DirectPointManipulation.png) +>1. Hover over the point and the X, Y, and Z axes will appear. +2. Click and drag the colored arrow to move the corresponding axis, and the **Number Slider** values will update live with the manually moved point. + +![Updated Sliders](images/2-4/10-UpdatedSliders.png) +>1. Note that before **Direct Manipulation** only one slider was plugged into the **Point.ByCoordinates** component. When we manually move the point in the X-direction, Dynamo will automatically generate a new **Number Slider** for the X input. diff --git a/02_Hello-Dynamo/2_hello_dynamo.md b/02_Hello-Dynamo/2_hello_dynamo.md index e8a6e0c0..3d12ebcd 100644 --- a/02_Hello-Dynamo/2_hello_dynamo.md +++ b/02_Hello-Dynamo/2_hello_dynamo.md @@ -1,5 +1,5 @@ -#HELLO DYNAMO! - -At its core, Dynamo is a platform for Visual Programming - it is a flexible and extensible design tool. Because it can operate as a stand-alone application or as an add-on to other design software, we can use it to develop a wide range of creative workflows. Let's install Dynamo and get started by reviewing the key features of the interface. - -![Hello Attractor](images/2/2-cover.png) +#HELLO DYNAMO! + +At its core, Dynamo is a platform for Visual Programming - it is a flexible and extensible design tool. Because it can operate as a stand-alone application or as an add-on to other design software, we can use it to develop a wide range of creative workflows. Let's install Dynamo and get started by reviewing the key features of the interface. + +![Hello Attractor](images/2/2-cover.png) diff --git a/02_Hello-Dynamo/images/.gitkeep b/02_Hello-Dynamo/images/.gitkeep index 9901e584..c22a44b3 100644 --- a/02_Hello-Dynamo/images/.gitkeep +++ b/02_Hello-Dynamo/images/.gitkeep @@ -1 +1 @@ -# this directory was conjured with black magic :) +# this directory was conjured with black magic :) diff --git a/03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md b/03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md index 592423f4..321c1d57 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md @@ -1,57 +1,57 @@ -##Nodes - -In Dynamo, **Nodes** are the objects you connect to form a Visual Program. Each **Node** performs an operation - sometimes that may be as simple as storing a number or it may be a more complex action such as creating or querying geometry. - -###Anatomy of a Node -Most Nodes in Dynamo are composed of five parts. While there are exceptions, such as Input Nodes, the anatomy of each Node can be described as follows: -![Node Breakdown Point by Coordinates](images/3-1/00-AnatomyOfANode.png) ->1. Name - The Name of the Node with a Category.Name naming convention -2. Main - The main body of the Node - Right-clicking here presents options at the level of the whole Node -3. Ports (In and Out) - The receptors for Wires that supply the input data to the Node as well as the results of the Node's action -4. Lacing Icon - Indicates the Lacing option specified for matching list inputs (more on that later) -5. Default Value - Right-click on an input Port - some Nodes have default values that can be used or not used. - -### Ports -The Inputs and Outputs for Nodes are called Ports and act as the receptors for Wires. Data comes into the Node through Ports on the left and flows out of the Node after it has executed its operation on the right. Ports expect to receive data of a certain type. For instance, connecting a number such as *2.75* to the Ports on a Point By Coordinates Node will successfully result in creating a Point; however, if we supply *"Red"* to the same Port it will result in an error. - -> Tip: Hover over a Port to see a tooltip containing the data type expected. - -![Port Labels-Point by Coordinates](images/3-1/01-Ports.png) ->1. Port Label -2. Tool Tip -3. Data Type -4. Default Value - -###States -Dynamo gives an indication of the state of the execution of your Visual Program by rendering Nodes with different color schemes based on each Node's status. Furthermore, hovering or right-clicking over the Name or Ports presents additional information and options. - -![States](images/3-1/02-States2.png) - ->1. Active - Nodes with a Dark Grey Name background are well-connected and have all of their inputs successfully connected -2. Inactive - Grey Nodes are inactive and need to be connected with Wires to be part of the Program Flow in the active Workspace -3. Error State - Red indicates that the Node is in an Error State -4. Freeze - A Transparent node has Freeze turned on, suspending the execution of the node -5. Selected - Currently selected Nodes have and Aqua highlight on their border -6. Warning - Yellow Nodes are in an Warning state, meaning they may have incorrect data types -7. Background Preview - Dark Grey indicates that the geometry preview is turned off - -If your Visual Program contains warning or errors, Dynamo will provide additional information about the problem. Any Node that is Yellow will also have a tooltip above the Name. Hover your mouse over the tooltip to expand it. - -> Tip: With this tooltip information in hand, examine the upstream Nodes to see if the data type or data structure required is in error. - -![Node Errors Tooltip](images/3-1/03-WarningTooltip.png) - -> 1. Warning Tooltip - "Null" or no data cannot be understood as a Double ie. a number -2. Use the Watch Node to examine the input data -3. Upstream the Number Node is storing "Red" not a number - - - - - - - - - - - +##Nodes + +In Dynamo, **Nodes** are the objects you connect to form a Visual Program. Each **Node** performs an operation - sometimes that may be as simple as storing a number or it may be a more complex action such as creating or querying geometry. + +###Anatomy of a Node +Most Nodes in Dynamo are composed of five parts. While there are exceptions, such as Input Nodes, the anatomy of each Node can be described as follows: +![Node Breakdown Point by Coordinates](images/3-1/00-AnatomyOfANode.png) +>1. Name - The Name of the Node with a Category.Name naming convention +2. Main - The main body of the Node - Right-clicking here presents options at the level of the whole Node +3. Ports (In and Out) - The receptors for Wires that supply the input data to the Node as well as the results of the Node's action +4. Lacing Icon - Indicates the Lacing option specified for matching list inputs (more on that later) +5. Default Value - Right-click on an input Port - some Nodes have default values that can be used or not used. + +### Ports +The Inputs and Outputs for Nodes are called Ports and act as the receptors for Wires. Data comes into the Node through Ports on the left and flows out of the Node after it has executed its operation on the right. Ports expect to receive data of a certain type. For instance, connecting a number such as *2.75* to the Ports on a Point By Coordinates Node will successfully result in creating a Point; however, if we supply *"Red"* to the same Port it will result in an error. + +> Tip: Hover over a Port to see a tooltip containing the data type expected. + +![Port Labels-Point by Coordinates](images/3-1/01-Ports.png) +>1. Port Label +2. Tool Tip +3. Data Type +4. Default Value + +###States +Dynamo gives an indication of the state of the execution of your Visual Program by rendering Nodes with different color schemes based on each Node's status. Furthermore, hovering or right-clicking over the Name or Ports presents additional information and options. + +![States](images/3-1/02-States2.png) + +>1. Active - Nodes with a Dark Grey Name background are well-connected and have all of their inputs successfully connected +2. Inactive - Grey Nodes are inactive and need to be connected with Wires to be part of the Program Flow in the active Workspace +3. Error State - Red indicates that the Node is in an Error State +4. Freeze - A Transparent node has Freeze turned on, suspending the execution of the node +5. Selected - Currently selected Nodes have and Aqua highlight on their border +6. Warning - Yellow Nodes are in an Warning state, meaning they may have incorrect data types +7. Background Preview - Dark Grey indicates that the geometry preview is turned off + +If your Visual Program contains warning or errors, Dynamo will provide additional information about the problem. Any Node that is Yellow will also have a tooltip above the Name. Hover your mouse over the tooltip to expand it. + +> Tip: With this tooltip information in hand, examine the upstream Nodes to see if the data type or data structure required is in error. + +![Node Errors Tooltip](images/3-1/03-WarningTooltip.png) + +> 1. Warning Tooltip - "Null" or no data cannot be understood as a Double ie. a number +2. Use the Watch Node to examine the input data +3. Upstream the Number Node is storing "Red" not a number + + + + + + + + + + + diff --git a/03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md b/03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md index adbd9de3..cfff61e4 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md @@ -1,75 +1,75 @@ -##Dynamo Library - -The **Dynamo Library** contains the Nodes we add to the Workspace to define Visual Programs for execution. In the Library, we can search for or browse to Nodes. The Nodes contained here - the basic Nodes installed, Custom Nodes we define, and Nodes from the Package Manager that we add to Dynamo - are organizaed hierachically by category. Let's review this organization and explore the key Nodes we will use frequently. - -###Library of Libraries -The Dynamo **Library** that we interface with in the application is actually a collection of functional libraries, each containing Nodes grouped by Category. While this may seem obtuse at first, it is a flexible framework for organizing the Nodes that come with the default installation of Dynamo - and it's even better down the road when we start extending this base functionality with Custom Nodes and additional Packages. - -####The Organizational Scheme -The **Library** section of the Dynamo UI is composed of hierarchically organized libraries. As we drill down into the Library, we are sequentially browsing a library, the library's categories, and the category's sub-categories to find the Node. - -![Library Hierarchy](images/3-3/00-LibraryBrowsing.png) - -> 1. The Library - The region of the Dynamo Interface -2. A Library - A collection of related Categories, such as **Geometry** -3. A Category - A collection of related Nodes such as everything related to **Circles** -4. A Subcategory - Breakdown of the Nodes within the Category, typically by **Create**, **Action**, or **Query** -5. A Node - The objects that are added to the Workspace to perform an action - -####Naming Conventions -The hierarchy of each library is reflected in the Name of Nodes added to the Workspace, which we can also use in the Search Field or with Code Blocks (which use the *Dynamo textual language*). Beyond using key words to try to find Nodes, we can type the hierarchy separated with a period. - -Typing in different portions of the Node's place in the Library hierarchy in the ```library.category.nodeName``` format returns different results: - -![Searching the Library - create from three "naming" pngs](images/3-3/01-LibrarySearching.png) - -> 1. ```library.category.nodeName``` -2. ```category.nodeName``` -3. ```nodeName``` or ```keyword``` - -Typically the Name of the Node in the Workspace will be rendered in the ```category.nodeName``` format, with some notable exceptions particularly in the Input and View Categories. Beware of similarly named Nodes and note the category difference: - -![Node Names](images/3-3/02-NodeNames.png) - -> 1. ```Point.ByCoordinates``` and ```UV.ByCoordinates``` have the same Name but come from different categories -2. Nodes from most libraries will include the category format -3. Notable exceptions include Built-in Functions, Core.Input, Core.View, and Operators - -###Frequently Used Nodes -With hundreds of Nodes included in the basic installation of Dynamo, which ones are essential for developing our Visual Programs? Let's focus on those that let us define our program's parameters (**Input**), see the results of a Node's action (**Watch**), and define inputs or functionality by way of a shortcut (**Code Block**). - -####Input -Input Nodes are the primary means for the User of our Visual Program - be that yourself or someone else - to interface with the key parameters. Here are the Nodes available in the Input Category of the Core Library: - -![Input Nodes](images/3-3/03-InputNodes.png) -> 1. Boolean -2. Number -3. String -4. Number Slider -5. Integer Slider -6. Directory Path -7. File Path - -####Watch -The Watch Nodes are essential to managing the data that is flowing through your Visual Program. While you can view the result of a Node through the Node data preview, you may want to keep it revealed in a **Watch** Node or see the geometry results through a **Watch3D** Node. Both of these are found in the View Category in the Core Library. - -> Tip: Occasionally the 3D Preview can be distracting when your Visual Program contains a lot of Nodes. Consider unchecking the Showing Background Preview option in the Settings Menu and using a Watch3D Node to preview your geometry. - -![Watch and Watch3D](images/3-3/04-WatchNodes.png) - -> 1. Watch - Note that when you select an item in the Watch Node it will be tagged in the Watch3D and 3D Previews -2. Watch3D - Grab the bottom right grip to resize and navigate with you mouse the same way you would in the 3D Preview - -####Code Block -**Code Block** Nodes can be used to define a block of code with lines separated by semi-colons. This can be as simple as ```X/Y```. We can also use Code Blocks as a short cut to defining a Number Input or call to another Node's functionality. The syntax to do so follows the Naming Convention of the Dynamo textual language, DesignScript, and is covered in Section 3.2.3. Let's try to make a Circle with this shortcut: - -![Code Block Shortcut](images/3-3/05-CodeBlock.png) - ->1. Double Click to create a **Code Block** Node -2. Type ```Circle.ByCenterPointRadius(x,y);``` -3. Clicking on the Workspace to clear the selection should add ```x``` and ```y``` inputs automatically -4. Create a **Point.ByCoordinates** Node and a **Number Slider** then connect them to the inputs of the Code Block -5. The result of executing the Visual Program should be a circle in the 3D Preview - - - +##Dynamo Library + +The **Dynamo Library** contains the Nodes we add to the Workspace to define Visual Programs for execution. In the Library, we can search for or browse to Nodes. The Nodes contained here - the basic Nodes installed, Custom Nodes we define, and Nodes from the Package Manager that we add to Dynamo - are organizaed hierachically by category. Let's review this organization and explore the key Nodes we will use frequently. + +###Library of Libraries +The Dynamo **Library** that we interface with in the application is actually a collection of functional libraries, each containing Nodes grouped by Category. While this may seem obtuse at first, it is a flexible framework for organizing the Nodes that come with the default installation of Dynamo - and it's even better down the road when we start extending this base functionality with Custom Nodes and additional Packages. + +####The Organizational Scheme +The **Library** section of the Dynamo UI is composed of hierarchically organized libraries. As we drill down into the Library, we are sequentially browsing a library, the library's categories, and the category's sub-categories to find the Node. + +![Library Hierarchy](images/3-3/00-LibraryBrowsing.png) + +> 1. The Library - The region of the Dynamo Interface +2. A Library - A collection of related Categories, such as **Geometry** +3. A Category - A collection of related Nodes such as everything related to **Circles** +4. A Subcategory - Breakdown of the Nodes within the Category, typically by **Create**, **Action**, or **Query** +5. A Node - The objects that are added to the Workspace to perform an action + +####Naming Conventions +The hierarchy of each library is reflected in the Name of Nodes added to the Workspace, which we can also use in the Search Field or with Code Blocks (which use the *Dynamo textual language*). Beyond using key words to try to find Nodes, we can type the hierarchy separated with a period. + +Typing in different portions of the Node's place in the Library hierarchy in the ```library.category.nodeName``` format returns different results: + +![Searching the Library - create from three "naming" pngs](images/3-3/01-LibrarySearching.png) + +> 1. ```library.category.nodeName``` +2. ```category.nodeName``` +3. ```nodeName``` or ```keyword``` + +Typically the Name of the Node in the Workspace will be rendered in the ```category.nodeName``` format, with some notable exceptions particularly in the Input and View Categories. Beware of similarly named Nodes and note the category difference: + +![Node Names](images/3-3/02-NodeNames.png) + +> 1. ```Point.ByCoordinates``` and ```UV.ByCoordinates``` have the same Name but come from different categories +2. Nodes from most libraries will include the category format +3. Notable exceptions include Built-in Functions, Core.Input, Core.View, and Operators + +###Frequently Used Nodes +With hundreds of Nodes included in the basic installation of Dynamo, which ones are essential for developing our Visual Programs? Let's focus on those that let us define our program's parameters (**Input**), see the results of a Node's action (**Watch**), and define inputs or functionality by way of a shortcut (**Code Block**). + +####Input +Input Nodes are the primary means for the User of our Visual Program - be that yourself or someone else - to interface with the key parameters. Here are the Nodes available in the Input Category of the Core Library: + +![Input Nodes](images/3-3/03-InputNodes.png) +> 1. Boolean +2. Number +3. String +4. Number Slider +5. Integer Slider +6. Directory Path +7. File Path + +####Watch +The Watch Nodes are essential to managing the data that is flowing through your Visual Program. While you can view the result of a Node through the Node data preview, you may want to keep it revealed in a **Watch** Node or see the geometry results through a **Watch3D** Node. Both of these are found in the View Category in the Core Library. + +> Tip: Occasionally the 3D Preview can be distracting when your Visual Program contains a lot of Nodes. Consider unchecking the Showing Background Preview option in the Settings Menu and using a Watch3D Node to preview your geometry. + +![Watch and Watch3D](images/3-3/04-WatchNodes.png) + +> 1. Watch - Note that when you select an item in the Watch Node it will be tagged in the Watch3D and 3D Previews +2. Watch3D - Grab the bottom right grip to resize and navigate with you mouse the same way you would in the 3D Preview + +####Code Block +**Code Block** Nodes can be used to define a block of code with lines separated by semi-colons. This can be as simple as ```X/Y```. We can also use Code Blocks as a short cut to defining a Number Input or call to another Node's functionality. The syntax to do so follows the Naming Convention of the Dynamo textual language, DesignScript, and is covered in Section 3.2.3. Let's try to make a Circle with this shortcut: + +![Code Block Shortcut](images/3-3/05-CodeBlock.png) + +>1. Double Click to create a **Code Block** Node +2. Type ```Circle.ByCenterPointRadius(x,y);``` +3. Clicking on the Workspace to clear the selection should add ```x``` and ```y``` inputs automatically +4. Create a **Point.ByCoordinates** Node and a **Number Slider** then connect them to the inputs of the Code Block +5. The result of executing the Visual Program should be a circle in the 3D Preview + + + diff --git a/03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md b/03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md index bc04a6e0..06b31cae 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md @@ -1,44 +1,44 @@ -##Wires - -Wires connect between Nodes to create relationships and establish the Flow of our Visual Program. We can think of them literally as electrical wires that carry pulses of data from one object to the next. - - -###Program Flow -Wires connect the output Port from one Node to the input Port of another Node. This directionality establishes the **Flow of Data** in the Visual Program. Although we can arrange our Nodes however we desire in the Workspace, because the output Ports are located on the right side of Nodes and the input Ports are on the left side, we can generally say that the Program Flow moves from left to right. - -![Program Flow](images/3-2/00-ProgramFlow.png) - -###Creating Wires -We create a Wire by left clicking our mouse on a Port and then left clicking on the port of another Node to create a connection. While we are in the process of making a connection, the Wire will appear dashed and will snap to become solid lines when successfully connected. The data will always flow through this Wire from output to input; however, we may create the wire in either direction in terms of the sequence of clicking on the connected Ports. - -> Tip: Before completing the connection with your second click, allow the Wire snap to a Port and hover your mouse there to see the Port tooltip. - -![Creating Wires](images/3-2/01-CreatingWires.png) ->1. Click on the ```seq``` output Port of the Number Sequence Node -2. As you are moving your mouse towards another Port, the Wire is dashed -3. Click on the ```y``` input Port of the Point.ByCoordiantes to complete the connection - -###Editing Wires -Frequently we will want to adjust the Program Flow in our Visual Program by editing the connections represented by the Wires. To edit a Wire, left click on the input Port of the Node that is already connected. You now have two options: - -![Editing Wires](images/3-2/02-EditingWires.png) - -> 1. Existing Wire -2. To change the connection to an input Port, left click on another input Port -3. To remove the Wire, pull the Wire away and left click on the Workspace - - -###Wire Previews -By default, our Wires will be previewed with a gray stroke. When a Node is selected, it will render any connecting Wire with the same aqua highlight as the Node. - -![Wire Preview](images/3-2/03-WirePreview.png) -> 1. Default Wire -2. Highlighted Wire - -Dynamo also allows us to customize how our Wires look in the Workspace through the View > Connectors Menu. Here we can toggle between Curve or Polyline Wires or turn them off all together. - -![Wire Connectors](images/3-2/04-WireConnectors.png) - -> 1. Connector Type: Curves -2. Connector Type: Polylines - +##Wires + +Wires connect between Nodes to create relationships and establish the Flow of our Visual Program. We can think of them literally as electrical wires that carry pulses of data from one object to the next. + + +###Program Flow +Wires connect the output Port from one Node to the input Port of another Node. This directionality establishes the **Flow of Data** in the Visual Program. Although we can arrange our Nodes however we desire in the Workspace, because the output Ports are located on the right side of Nodes and the input Ports are on the left side, we can generally say that the Program Flow moves from left to right. + +![Program Flow](images/3-2/00-ProgramFlow.png) + +###Creating Wires +We create a Wire by left clicking our mouse on a Port and then left clicking on the port of another Node to create a connection. While we are in the process of making a connection, the Wire will appear dashed and will snap to become solid lines when successfully connected. The data will always flow through this Wire from output to input; however, we may create the wire in either direction in terms of the sequence of clicking on the connected Ports. + +> Tip: Before completing the connection with your second click, allow the Wire snap to a Port and hover your mouse there to see the Port tooltip. + +![Creating Wires](images/3-2/01-CreatingWires.png) +>1. Click on the ```seq``` output Port of the Number Sequence Node +2. As you are moving your mouse towards another Port, the Wire is dashed +3. Click on the ```y``` input Port of the Point.ByCoordiantes to complete the connection + +###Editing Wires +Frequently we will want to adjust the Program Flow in our Visual Program by editing the connections represented by the Wires. To edit a Wire, left click on the input Port of the Node that is already connected. You now have two options: + +![Editing Wires](images/3-2/02-EditingWires.png) + +> 1. Existing Wire +2. To change the connection to an input Port, left click on another input Port +3. To remove the Wire, pull the Wire away and left click on the Workspace + + +###Wire Previews +By default, our Wires will be previewed with a gray stroke. When a Node is selected, it will render any connecting Wire with the same aqua highlight as the Node. + +![Wire Preview](images/3-2/03-WirePreview.png) +> 1. Default Wire +2. Highlighted Wire + +Dynamo also allows us to customize how our Wires look in the Workspace through the View > Connectors Menu. Here we can toggle between Curve or Polyline Wires or turn them off all together. + +![Wire Connectors](images/3-2/04-WireConnectors.png) + +> 1. Connector Type: Curves +2. Connector Type: Polylines + diff --git a/03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md b/03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md index f160851e..34e7aa6d 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md @@ -1,46 +1,46 @@ -##Managing Your Program - -Working within a Visual Programming process can be a powerful creative activity, but very quickly the Program Flow and key user inputs can be obscured by complexity and/or layout of the Workspace. Let's review some best practices for managing your program. - -###Alignment -Once we have added more than a few Nodes to the Workspace, we may want to re-organize the layout of the Nodes for clarity's sake. By selecting more than one Node and right-clicking on the Workspace, the pop up window includes an **Align Selection** menu with justification and distribution options in X and Y. - -![Align](images/3-4/00-Align.png) -> 1. Select more than one Node -2. Right-click on the Workspace -3. Use the **Align Selection** options - -###Notes -With some experience, we may be able to "read" the Visual Program by reviewing the Node Names and following the Program Flow. For users of all experience levels, it is also good practice to include plain language labels and descriptions. Dynamo has a **Notes** Node with an editable text field to do so. We can add Notes to the Workspace in two ways: - -![Notes](images/3-4/01-Notes01.png) -> 1. Browse to the menu File > Create Note -2. Use the keyboard shortcut Ctrl+W - -Once the Note is added to the Workspace a text field will pop up allowing us to edit the text in the Note. After they are created, we can edit the Note by double-clicking or right-clicking the Note Node. - -![Notes Edit](images/3-4/02-Notes02.png) - -###Grouping -When our Visual Program gets big, it is helpful to identify the larger steps that will be executed. We can highlight larger collections of Nodes with a **Group** to label them with a colored rectangle in the background and a title. There are three ways to make a Group with more than one Node selected: - -![Groups](images/3-4/04-Groups01.png) -> 1. Browse to the menu File > Create Group -2. Use the keyboard shortcut Ctrl+G -3. Right-click on the Workspace and select "Create Group" - -Once a Group is created we can edit its settings, such as the title and color. -![Group Settings](images/3-4/05-Groups02.png) - -> Tip: Using both Notes and Groups is an effective way to annotate your file and increase readability. - -Here's our program from Section 2.4 with Notes and Groups added: - -![Grouping Example](images/3-4/03-Groups00.png) - -> 1. Note: "Grid Parameters" -2. Note: "Grid Points" -3. Group: "Create a Grid of Points" -4. Group: "Create an Attractor Point" -5. Note: "Calibrate Distance Values" -6. Note: "Variable Grid of Circles" +##Managing Your Program + +Working within a Visual Programming process can be a powerful creative activity, but very quickly the Program Flow and key user inputs can be obscured by complexity and/or layout of the Workspace. Let's review some best practices for managing your program. + +###Alignment +Once we have added more than a few Nodes to the Workspace, we may want to re-organize the layout of the Nodes for clarity's sake. By selecting more than one Node and right-clicking on the Workspace, the pop up window includes an **Align Selection** menu with justification and distribution options in X and Y. + +![Align](images/3-4/00-Align.png) +> 1. Select more than one Node +2. Right-click on the Workspace +3. Use the **Align Selection** options + +###Notes +With some experience, we may be able to "read" the Visual Program by reviewing the Node Names and following the Program Flow. For users of all experience levels, it is also good practice to include plain language labels and descriptions. Dynamo has a **Notes** Node with an editable text field to do so. We can add Notes to the Workspace in two ways: + +![Notes](images/3-4/01-Notes01.png) +> 1. Browse to the menu File > Create Note +2. Use the keyboard shortcut Ctrl+W + +Once the Note is added to the Workspace a text field will pop up allowing us to edit the text in the Note. After they are created, we can edit the Note by double-clicking or right-clicking the Note Node. + +![Notes Edit](images/3-4/02-Notes02.png) + +###Grouping +When our Visual Program gets big, it is helpful to identify the larger steps that will be executed. We can highlight larger collections of Nodes with a **Group** to label them with a colored rectangle in the background and a title. There are three ways to make a Group with more than one Node selected: + +![Groups](images/3-4/04-Groups01.png) +> 1. Browse to the menu File > Create Group +2. Use the keyboard shortcut Ctrl+G +3. Right-click on the Workspace and select "Create Group" + +Once a Group is created we can edit its settings, such as the title and color. +![Group Settings](images/3-4/05-Groups02.png) + +> Tip: Using both Notes and Groups is an effective way to annotate your file and increase readability. + +Here's our program from Section 2.4 with Notes and Groups added: + +![Grouping Example](images/3-4/03-Groups00.png) + +> 1. Note: "Grid Parameters" +2. Note: "Grid Points" +3. Group: "Create a Grid of Points" +4. Group: "Create an Attractor Point" +5. Note: "Calibrate Distance Values" +6. Note: "Variable Grid of Circles" diff --git a/03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md b/03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md index 7fb300de..5738b831 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md @@ -1,41 +1,41 @@ -## Managing Your Data with Presets - -In the previous section we looked at managing programs by aligning, grouping, and annotating nodes to organize the Workspace. These best practices help to reduce some of the visual complexity of your graph. Now let's dive deeper and organize the complexity of content. Often, a Dynamo graph has a wide range of parameters which offer countless iterations. We want to organize the range of options so that we can make real design decisions - and this is where Presets come in. - -Imagine that you've created a Dynamo graph to share with a team so that each team member can explore the parametric model. Your team members have a range of experience with visual programming, so you want to offer some direction for them to explore different design schemes. The easiest, most user-friendly way to do this is with presets - you can set any number of parameters to define a specific design iteration. This allows you to reload previous schemes and work with them parametrically. - -###Presets - -Presets are a way to take the current value of a selection of input nodes and save them as a preset state. These states can be restored through the Edit>Presets menu. Presets can be used to create and compare design iterations. Presets are saved with the file, making them a useful tool for sharing or requesting feedback. They also allow another user to interact with the graph without having to search for the relevant inputs, or tune a set of values that work well together from a design perspective. - -![](images/3-5/presetsA.png) ->1. Preset 1 ->2. Preset 2 - -###Creating Presets - ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Prests.dyn](datasets/3-5/Presets.dyn). A full list of example files can be found in the Appendix. - -To create a preset, select one or more input nodes. Right-click the canvas and select "Create Preset from Selection", or press Control+T. -Let's take a look at an example. Below is a simple graph that creates a surface by lofting through a series of circles. - -![Create Preset](images/3-5/presetsB.png) ->1. The inputs of the graph are a series of sliders controlling the height and radii - -![Create Preset](images/3-5/presetsC.png) ->Select the input sliders and type Control+T - -![Create Preset](images/3-5/presetsD.png) ->Enter a name and description for the saved state in the dialog. Create several states with different input values. - -###Restoring Presets -To restore a saved preset, navigate to Edit>Presets>Restore Preset. This will set all the nodes in that state to the saved values. If a node in the state is no longer present in the graph (ie. if it has been deleted), all other nodes in the state will be set. - -![Restoring Presets](images/3-5/presetsE.png) - -###Deleting Presets -To delete a preset, navigate to Edit>Presets>Delete Preset. This will remove a state from the list of saved states. - -![Deleting Presets](images/3-5/presetsF.png) - +## Managing Your Data with Presets + +In the previous section we looked at managing programs by aligning, grouping, and annotating nodes to organize the Workspace. These best practices help to reduce some of the visual complexity of your graph. Now let's dive deeper and organize the complexity of content. Often, a Dynamo graph has a wide range of parameters which offer countless iterations. We want to organize the range of options so that we can make real design decisions - and this is where Presets come in. + +Imagine that you've created a Dynamo graph to share with a team so that each team member can explore the parametric model. Your team members have a range of experience with visual programming, so you want to offer some direction for them to explore different design schemes. The easiest, most user-friendly way to do this is with presets - you can set any number of parameters to define a specific design iteration. This allows you to reload previous schemes and work with them parametrically. + +###Presets + +Presets are a way to take the current value of a selection of input nodes and save them as a preset state. These states can be restored through the Edit>Presets menu. Presets can be used to create and compare design iterations. Presets are saved with the file, making them a useful tool for sharing or requesting feedback. They also allow another user to interact with the graph without having to search for the relevant inputs, or tune a set of values that work well together from a design perspective. + +![](images/3-5/presetsA.png) +>1. Preset 1 +>2. Preset 2 + +###Creating Presets + +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Prests.dyn](datasets/3-5/Presets.dyn). A full list of example files can be found in the Appendix. + +To create a preset, select one or more input nodes. Right-click the canvas and select "Create Preset from Selection", or press Control+T. +Let's take a look at an example. Below is a simple graph that creates a surface by lofting through a series of circles. + +![Create Preset](images/3-5/presetsB.png) +>1. The inputs of the graph are a series of sliders controlling the height and radii + +![Create Preset](images/3-5/presetsC.png) +>Select the input sliders and type Control+T + +![Create Preset](images/3-5/presetsD.png) +>Enter a name and description for the saved state in the dialog. Create several states with different input values. + +###Restoring Presets +To restore a saved preset, navigate to Edit>Presets>Restore Preset. This will set all the nodes in that state to the saved values. If a node in the state is no longer present in the graph (ie. if it has been deleted), all other nodes in the state will be set. + +![Restoring Presets](images/3-5/presetsE.png) + +###Deleting Presets +To delete a preset, navigate to Edit>Presets>Delete Preset. This will remove a state from the list of saved states. + +![Deleting Presets](images/3-5/presetsF.png) + ![](images/3-5/presets07.png) \ No newline at end of file diff --git a/03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md b/03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md index 1d40e7e1..9f7b876a 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md +++ b/03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md @@ -1,5 +1,5 @@ -#ANATOMY OF A VISUAL PROGRAM - -Dynamo enables us to create Visual Programs in a Workspace by connecting Nodes with Wires to specify the logical flow of the resulting Visual Program. This chapter introduces the elements of Visual Programs, the organization of the Nodes available in Dynamo's Libraries, the parts and states of Nodes, and best practices for your Workspaces. - -![Anatomy Main](images/3/The Anatomy of Visual Programming-01.png) +#ANATOMY OF A VISUAL PROGRAM + +Dynamo enables us to create Visual Programs in a Workspace by connecting Nodes with Wires to specify the logical flow of the resulting Visual Program. This chapter introduces the elements of Visual Programs, the organization of the Nodes available in Dynamo's Libraries, the parts and states of Nodes, and best practices for your Workspaces. + +![Anatomy Main](images/3/The Anatomy of Visual Programming-01.png) diff --git a/03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn b/03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn index 766de70f..b9a35e4f 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn +++ b/03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn @@ -1,274 +1,274 @@ - - - - - - - - - - - - - - - - - 18 - - - - 2.3 - - - - 1.3 - - - - 0.9 - - - - - - - - - - 1.1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 17 - - - - 5 - - - - 2.1 - - - - 3.7 - - - - 2.6 - - - - - - 4.7 - - - - 9.8 - - - - 10.9 - - - - 6.5 - - - - 10.9 - - - - - - 15 - - - - 8.9 - - - - 4.1 - - - - 5.9 - - - - 6.9 - - - - - - 20 - - - - 1.6 - - - - 4.4 - - - - 2 - - - - 4 - - - - - - 17 - - - - 3.9 - - - - 2.1 - - - - 2 - - - - 5.3 - - - - - - 6.7 - - - - 4.6 - - - - 11.4 - - - - 3.5 - - - - 9.6 - - - - - - 14 - - - - 5 - - - - 7.4 - - - - 3.1 - - - - 6.5 - - - - - - 18 - - - - 2.3 - - - - 1.3 - - - - 0.9 - - - - 1.1 - - - - - - - + + + + + + + + + + + + + + + + + 18 + + + + 2.3 + + + + 1.3 + + + + 0.9 + + + + + + + + + + 1.1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 17 + + + + 5 + + + + 2.1 + + + + 3.7 + + + + 2.6 + + + + + + 4.7 + + + + 9.8 + + + + 10.9 + + + + 6.5 + + + + 10.9 + + + + + + 15 + + + + 8.9 + + + + 4.1 + + + + 5.9 + + + + 6.9 + + + + + + 20 + + + + 1.6 + + + + 4.4 + + + + 2 + + + + 4 + + + + + + 17 + + + + 3.9 + + + + 2.1 + + + + 2 + + + + 5.3 + + + + + + 6.7 + + + + 4.6 + + + + 11.4 + + + + 3.5 + + + + 9.6 + + + + + + 14 + + + + 5 + + + + 7.4 + + + + 3.1 + + + + 6.5 + + + + + + 18 + + + + 2.3 + + + + 1.3 + + + + 0.9 + + + + 1.1 + + + + + + + \ No newline at end of file diff --git a/03_Anatomy-of-a-Dynamo-Definition/images/.gitkeep b/03_Anatomy-of-a-Dynamo-Definition/images/.gitkeep index 9901e584..c22a44b3 100644 --- a/03_Anatomy-of-a-Dynamo-Definition/images/.gitkeep +++ b/03_Anatomy-of-a-Dynamo-Definition/images/.gitkeep @@ -1 +1 @@ -# this directory was conjured with black magic :) +# this directory was conjured with black magic :) diff --git a/04_The-Building-Blocks-of-Programs/4-1_data.md b/04_The-Building-Blocks-of-Programs/4-1_data.md index deb09bc0..5c9c90d3 100644 --- a/04_The-Building-Blocks-of-Programs/4-1_data.md +++ b/04_The-Building-Blocks-of-Programs/4-1_data.md @@ -1,87 +1,87 @@ -##Data -Data is the stuff of our programs. It travels through Wires, supplying inputs for Nodes where it gets processed into a new form of output data. Let's review the definition of data, how it's structured, and begin using it in Dynamo. - -###What is Data? -Data is a set of values of qualitative or quantitative variables. The simplest form of data is numbers such as ```0```, ```3.14```, or ```17```. But data can also be of a number of different types: a variable representing changing numbers (```height```); characters (```myName```); geometry (```Circle```); or a list of data items (```1,2,3,5,8,13,...```). We need data to add to the input Ports of Dynamo's Nodes - we can have data without actions but we need data to process the actions that our Nodes represent. When we've added a Node to the Workspace, if it doesn't have any inputs supplied, the result will be a function, not the result of the action itself. - -![Data and Actions](images/4-1/00-DataAndActions.png) - -> 1. Simple Data -2. Data and Action (A Node) successfully executes -3. Action (A Node) without Data Inputs returns a generic function - -###Beware of Nulls -The ```'null'``` type represents the absence of data. While this is an abstract concept, you will likely come across this while working with Visual Programming. If an action doesn't create a valid result, the Node will return a null. Testing for nulls and removing nulls from data structure is a crucial part to creating robust programs. - -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Object-IsNull-Large.png) | Object.IsNull | obj | bool | - -###Data Structures -When we are Visual Programming, we can very quickly generate a lot of data and require a means of managing its hierarchy. This is the role of Data Structures, the organizational schemes in which we store data. The specifics of Data Structures and how to use them vary from programming language to programming language. In Dynamo, we add hierarchy to our data through Lists. We will explore this in depth in later chapters, but let's start simply: - -A list represents a collection of items placed into one structure of data: -* I have five fingers (*items*) on my hand (*list*). -* There are ten houses (*items*) on my street (*list*). - -![List Breakdown](images/4-1/01-ListBreakdown.png) - -> 1. A **Number Sequence** node defines a list of numbers by using a *start*, *amount*, and *step* input. With these nodes, we've created two separate lists of ten numbers, one which ranges from *100-109* and another which ranges from *0-9*. -2. The **List.GetItemAtIndex** node selects an item in a list at a specific index. When choosing *0*, we get the first item in the list (*100* in this case). -3. Applying the same process to the second list, we get a value of *0*, the first item in the list. -4. Now we merge the two lists into one by using the **List.Create** node. Notice that the node creates a *list of lists.* This changes the structure of the data. -5. When using **List.GetItemAtIndex** again, with index set to *0*, we get the first list in the list of lists. This is what it means to treat a list as an item, which is somewhat different from other scripting languages. We will get more advanced with list manipulation and data structure in later chapters. - -The key concept to understand about data hierarchy in Dynamo: **with respect to data structure, lists are regarded as items.** In other words, Dynamo functions with a top-down process for understanding data structures. What does this mean? Let's walk through it with an example. - -### Using Data to Make a Chain of Cylinders ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Data.dyn](datasets/4-1/Building Blocks of Programs - Data.dyn). A full list of example files can be found in the Appendix. - -In this first example, we assemble a shelled cylinder which walks through the geometry hierarchy discussed in this section. -![](images/4-1/1.png) -> 1. **Point.ByCoordinates -** after adding the node to canvas, we see a point at the origin of the Dynamo preview grid. The default values of the *x,y*, and *z* inputs are *0.0*, giving us a point at this location. - -![](images/4-1/2.png) -> 1. **Plane.ByOriginNormal -** The next step in the geometry hierarchy is a plane. There are several ways to construct a plane, and we are using an origin and normal for the input. The origin is the point node created in the previous step. -2. **Vector.ZAxis -** this is a unitized vector in the z direction. Notice there are not inputs, only a vector of [0,0,1] value. We use this as the *normal* input for the *Plane.ByOriginNormal* node. This gives us a rectangular plane in the Dynamo preview. - -![](images/4-1/3.png) -> 1. **Circle.ByPlaneRadius -** Stepping up the hierarchy, we now create a curve from the plane in our previous step. After plugging into the node, we get a circle at the origin. The default radius on the node is value of *1*. - -![](images/4-1/4.png) -> 1. **Curve.Extrude -** Now we make this thing pop by giving it some depth and going in the third dimension. This node creates a surface from a curve by extruding it. The default distance on the node is *1*, and we should see a cylinder in the viewport. - -![](images/4-1/5.png) -> 1. **Surface.Thicken -** This node gives us a closed solid by offsetting the surface a given distance and closing the form. The default thickness value is *1*, and we see a shelled cylinder in the viewport in line with these values. - -![](images/4-1/6.png) -> 1. **Number Slider -** Rather than using the default values for all of these inputs, let's add some parametric control to the model. -2. **Domain Edit - **after adding the number slider to the canvas, click the caret in the top left to reveal the domain options. -3. **Min/Max/Step -** change the *min*, *max*, and *step* values to *0*,*2*, and *0.01* respectively. We are doing this to control the size of the overall geometry. - -![](images/4-1/7.png) -> 1. **Number Sliders -** In all of the default inputs, let's copy and paste this number slider (select the slider, hit Ctrl+C, then Ctrl+V) several times, until all of the inputs with defaults have a slider instead. Some of the slider values will have to be larger than zero to get the definition to work (ie: you need an extrusion depth in order to have a surface to thicken). - -We've now created a parametric shelled cylinder with these sliders. Try to flex some of these parameters and see the geometry update dynamically in the Dynamo viewport. - -![](images/4-1/8.png) -> 1. **Number Sliders -** taking this a step further, we've added a lot of sliders to the canvas, and need to clean up the interface of the tool we just created. Right click on one slider, select "Rename..." and change each slider to the appropriate name for its parameter. You can reference the image above for names. - -At this point, we've created an awesome thickening cylinder thing. This is one object currently, let's look at how to create an array of cylinders that remains dynamically linked. To do this, we're going to create a list of cylinders, rather than working with a single item. - -![](images/4-1/9.png) -> 1. **Addition (+) -** Our goal is to add a row of cylinders next to the cylinder we've created. If we want to add one cylinder adjacent to the current one, we need to consider both radius of the cylinder and the thickness of its shell. We get this number by adding the two values of the sliders. - -![](images/4-1/10.png) -> This step is more involved so let's walk through it slowly: the end goal is to create a list of numbers which define the locations of each cylinder in a row. -1. **Multiplication -** First, we want to multiply the value from the previous step by 2. The value from the previous step represents a radius, and we want to move the cylinder the full diameter. -2. **Number Sequence -** we create an array of numbers with this node. The first input is the *multiplication* node from the previous step into the *step* value. The *start* value can be set to *0.0* using a *number* node. -3. **Integer Slider - ** For the *amount* value, we connect an integer slider. This will define how many cylinders are created. -4. **Output - ** This list shows us the distance moved for each cylinder in the array, and is parametrically driven by the original sliders. - -![](images/4-1/11.png) -> 1. This step is simple enough - plug the sequence defined in the previous step into the *x* input of the original *Point.ByCoordinates*. This will replace the slider *pointX* which we can delete. We now see an array of cylinders in the viewport (make sure the integer slider is larger than 0). - -![](images/4-1/12.png) -> The chain of cylinders is still dynamically linked to all of the sliders. Flex each slider to watch the definition update! - +##Data +Data is the stuff of our programs. It travels through Wires, supplying inputs for Nodes where it gets processed into a new form of output data. Let's review the definition of data, how it's structured, and begin using it in Dynamo. + +###What is Data? +Data is a set of values of qualitative or quantitative variables. The simplest form of data is numbers such as ```0```, ```3.14```, or ```17```. But data can also be of a number of different types: a variable representing changing numbers (```height```); characters (```myName```); geometry (```Circle```); or a list of data items (```1,2,3,5,8,13,...```). We need data to add to the input Ports of Dynamo's Nodes - we can have data without actions but we need data to process the actions that our Nodes represent. When we've added a Node to the Workspace, if it doesn't have any inputs supplied, the result will be a function, not the result of the action itself. + +![Data and Actions](images/4-1/00-DataAndActions.png) + +> 1. Simple Data +2. Data and Action (A Node) successfully executes +3. Action (A Node) without Data Inputs returns a generic function + +###Beware of Nulls +The ```'null'``` type represents the absence of data. While this is an abstract concept, you will likely come across this while working with Visual Programming. If an action doesn't create a valid result, the Node will return a null. Testing for nulls and removing nulls from data structure is a crucial part to creating robust programs. + +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Object-IsNull-Large.png) | Object.IsNull | obj | bool | + +###Data Structures +When we are Visual Programming, we can very quickly generate a lot of data and require a means of managing its hierarchy. This is the role of Data Structures, the organizational schemes in which we store data. The specifics of Data Structures and how to use them vary from programming language to programming language. In Dynamo, we add hierarchy to our data through Lists. We will explore this in depth in later chapters, but let's start simply: + +A list represents a collection of items placed into one structure of data: +* I have five fingers (*items*) on my hand (*list*). +* There are ten houses (*items*) on my street (*list*). + +![List Breakdown](images/4-1/01-ListBreakdown.png) + +> 1. A **Number Sequence** node defines a list of numbers by using a *start*, *amount*, and *step* input. With these nodes, we've created two separate lists of ten numbers, one which ranges from *100-109* and another which ranges from *0-9*. +2. The **List.GetItemAtIndex** node selects an item in a list at a specific index. When choosing *0*, we get the first item in the list (*100* in this case). +3. Applying the same process to the second list, we get a value of *0*, the first item in the list. +4. Now we merge the two lists into one by using the **List.Create** node. Notice that the node creates a *list of lists.* This changes the structure of the data. +5. When using **List.GetItemAtIndex** again, with index set to *0*, we get the first list in the list of lists. This is what it means to treat a list as an item, which is somewhat different from other scripting languages. We will get more advanced with list manipulation and data structure in later chapters. + +The key concept to understand about data hierarchy in Dynamo: **with respect to data structure, lists are regarded as items.** In other words, Dynamo functions with a top-down process for understanding data structures. What does this mean? Let's walk through it with an example. + +### Using Data to Make a Chain of Cylinders +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Data.dyn](datasets/4-1/Building Blocks of Programs - Data.dyn). A full list of example files can be found in the Appendix. + +In this first example, we assemble a shelled cylinder which walks through the geometry hierarchy discussed in this section. +![](images/4-1/1.png) +> 1. **Point.ByCoordinates -** after adding the node to canvas, we see a point at the origin of the Dynamo preview grid. The default values of the *x,y*, and *z* inputs are *0.0*, giving us a point at this location. + +![](images/4-1/2.png) +> 1. **Plane.ByOriginNormal -** The next step in the geometry hierarchy is a plane. There are several ways to construct a plane, and we are using an origin and normal for the input. The origin is the point node created in the previous step. +2. **Vector.ZAxis -** this is a unitized vector in the z direction. Notice there are not inputs, only a vector of [0,0,1] value. We use this as the *normal* input for the *Plane.ByOriginNormal* node. This gives us a rectangular plane in the Dynamo preview. + +![](images/4-1/3.png) +> 1. **Circle.ByPlaneRadius -** Stepping up the hierarchy, we now create a curve from the plane in our previous step. After plugging into the node, we get a circle at the origin. The default radius on the node is value of *1*. + +![](images/4-1/4.png) +> 1. **Curve.Extrude -** Now we make this thing pop by giving it some depth and going in the third dimension. This node creates a surface from a curve by extruding it. The default distance on the node is *1*, and we should see a cylinder in the viewport. + +![](images/4-1/5.png) +> 1. **Surface.Thicken -** This node gives us a closed solid by offsetting the surface a given distance and closing the form. The default thickness value is *1*, and we see a shelled cylinder in the viewport in line with these values. + +![](images/4-1/6.png) +> 1. **Number Slider -** Rather than using the default values for all of these inputs, let's add some parametric control to the model. +2. **Domain Edit - **after adding the number slider to the canvas, click the caret in the top left to reveal the domain options. +3. **Min/Max/Step -** change the *min*, *max*, and *step* values to *0*,*2*, and *0.01* respectively. We are doing this to control the size of the overall geometry. + +![](images/4-1/7.png) +> 1. **Number Sliders -** In all of the default inputs, let's copy and paste this number slider (select the slider, hit Ctrl+C, then Ctrl+V) several times, until all of the inputs with defaults have a slider instead. Some of the slider values will have to be larger than zero to get the definition to work (ie: you need an extrusion depth in order to have a surface to thicken). + +We've now created a parametric shelled cylinder with these sliders. Try to flex some of these parameters and see the geometry update dynamically in the Dynamo viewport. + +![](images/4-1/8.png) +> 1. **Number Sliders -** taking this a step further, we've added a lot of sliders to the canvas, and need to clean up the interface of the tool we just created. Right click on one slider, select "Rename..." and change each slider to the appropriate name for its parameter. You can reference the image above for names. + +At this point, we've created an awesome thickening cylinder thing. This is one object currently, let's look at how to create an array of cylinders that remains dynamically linked. To do this, we're going to create a list of cylinders, rather than working with a single item. + +![](images/4-1/9.png) +> 1. **Addition (+) -** Our goal is to add a row of cylinders next to the cylinder we've created. If we want to add one cylinder adjacent to the current one, we need to consider both radius of the cylinder and the thickness of its shell. We get this number by adding the two values of the sliders. + +![](images/4-1/10.png) +> This step is more involved so let's walk through it slowly: the end goal is to create a list of numbers which define the locations of each cylinder in a row. +1. **Multiplication -** First, we want to multiply the value from the previous step by 2. The value from the previous step represents a radius, and we want to move the cylinder the full diameter. +2. **Number Sequence -** we create an array of numbers with this node. The first input is the *multiplication* node from the previous step into the *step* value. The *start* value can be set to *0.0* using a *number* node. +3. **Integer Slider - ** For the *amount* value, we connect an integer slider. This will define how many cylinders are created. +4. **Output - ** This list shows us the distance moved for each cylinder in the array, and is parametrically driven by the original sliders. + +![](images/4-1/11.png) +> 1. This step is simple enough - plug the sequence defined in the previous step into the *x* input of the original *Point.ByCoordinates*. This will replace the slider *pointX* which we can delete. We now see an array of cylinders in the viewport (make sure the integer slider is larger than 0). + +![](images/4-1/12.png) +> The chain of cylinders is still dynamically linked to all of the sliders. Flex each slider to watch the definition update! + diff --git a/04_The-Building-Blocks-of-Programs/4-2_math.md b/04_The-Building-Blocks-of-Programs/4-2_math.md index 0ae2b7a4..6007f5b9 100644 --- a/04_The-Building-Blocks-of-Programs/4-2_math.md +++ b/04_The-Building-Blocks-of-Programs/4-2_math.md @@ -1,75 +1,75 @@ -##Math -If the simplest form of data is numbers, the easiest way to relate those numbers is through Mathematics. From simple operators like divide to trigonometric functions, to more complex formulas, Math is a great way to start exploring numeric relationships and patterns. - -###Arithmetic Operators -Operators are a set of components that use algebraic functions with two numeric input values, which result in one output value (addition, subtraction, multiplication, division, etc.). These can be found under Operators>Actions. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/add-Large.png) | Add | + | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/sub-Large.png) | Subtract | - | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/mul-Large.png) | Multiply | * | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/div-Large.png) | Divide | / | var[]...[], var[]...[] | var[]...[] | - -###Parametric Formula ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Math.dyn](datasets/4-2/Building Blocks of Programs - Math.dyn). A full list of example files can be found in the Appendix. - -From Operators, the next logical step is to combine operators and variables to form a more complex relationship through **Formulas**. Let's make a Formula that can be controlled by input parameters, like sliders. - -![](images/4-2/4-2-5/01.png) ->1. **Number Sequence:** define a number sequence based on three inputs: *start, amount* and *step*. This sequence represents the 't' in the parametric equation, so we want to use a list that's large enough to define a spiral. - -The step above has created a list of numbers to define the parametric domain. The golden spiral is defined as the equation: ![](images/4-2/4-2-5/x.gif)=![](images/4-2/4-2-5/goldenSpiral.gif) and -![](images/4-2/4-2-5/y.gif)=![](images/4-2/4-2-5/goldenSpiral2.gif). The group of Nodes below represent this equation in visual programming form. - -![](images/4-2/4-2-5/02.png) -> When stepping through the group of Nodes, try to pay attention to the parallel between the visual program and written equation. -1. **Number Slider:** Add two number sliders to the canvas. These sliders will represent the *a* and the *b* variables of the parametric equation. These represent a constant which is flexible, or parameters which we can adjust towards a desired outcome. -2. ** * :** The multiplication Node is represented by an asterisk. We'll use this repeatedly to connect multiplying variables -3. **Math.RadiansToDegrees:** The '*t*' values need to be translated to degrees for their evaluation in the trigonometric functions. Remember, Dynamo defaults to degrees for evaluating these functions. -4. **Math.Pow:** as a function of the '*t*' and the number '*e*' this creates the Fibonacci sequence. -5. **Math.Cos and Math.Sin:** These two trigonmetric functions will differentiate the x-coordinate and the y-coordinate, respectively, of each parametric point. -6. **Watch: **We now see that our output is two lists, these will be the *x* and *y* coordinates of the points used to generate the spiral. - -###From Formula to Geometry -Now, the bulk of Nodes from the previous step will work fine, but it is a lot of work. To create a more efficient workflow, have a look at **Code Blocks** (section 3.3.2.3) to define a string of Dynamo expressions into one node. In this next series of steps, we'll look at using the parametric equation to draw the Fibonacci spiral. -![](images/4-2/4-2-5/03.png) -> 1. **Point.ByCoordinates:** Connect the upper multiplication node into the '*x*' input and the lower into the '*y*' input. We now see a parametric spiral of points on the screen. - -![](images/4-2/4-2-5/03aaa.png) -> 1. **Polycurve.ByPoints:** Connect Point.ByCoordinates from the previous step into *points*. We can leave *connectLastToFirst* without an input because we aren't making a closed curve. This creates a spiral which passes through each point defined in the previous step. - -We've now completed the Fibonacci Spiral! Let's take this further into two separate exercises from here, which we'll call the Nautilus and the Sunflower. These are abstractions of natural systems, but the two different applications of the Fibonacci spiral will be well represented. - -###From Spiral to Nautilus - -![](images/4-2/4-2-5/03.png) -> 1. As a jumping-off point, let's start with the same step from the previous exercise: creating a spiral array of points with the **Point.ByCoordinates** Node. - -![](images/4-2/4-2-5/03aa.png) -> 1. **Polycurve.ByPoints:** Again, this is the Node from the pervious exercise, which we'll use as a reference. -2. **Circle.ByCenterPointRadius:** We'll use a circle Node here with the same inputs as the previous step. The radius value defaults to *1.0*, so we see an immediate output of circles. It becomes immediately legible how the points diverge further from the origin. - -![](images/4-2/4-2-5/03a.png) -> 1. **Circle.ByCenterPointRadius:** To create a more dynamic array of circles, we plug the original number sequence (the '*t*' sequence) into the radius value. -2. **Number Sequence:** This is the original array of '*t*'. By plugging this into the radius value, the circle centers are still diverging further from the origin, but the radius of the circles is increasing, creating a funky Fibonacci circle graph. Bonus points if you make it 3D! - -###From Nautilus to Phyllotaxis Pattern -Now that we've made a circular Nautilus shell, let's jump into parametric grids. We're going to use a basic rotate on the Fibonacci Spiral to create a Fibonacci grid, and the result is modeled after the [growth of sunflower seeds.](http://ms.unimelb.edu.au/~segerman/papers/sunflower_spiral_fibonacci_metric.pdf) - -![](images/4-2/4-2-5/03.png) -> 1. Again, as a jumping-off point, let's start with the same step from the previous exercise: creating a spiral array of points with the **Point.ByCoordinates** Node. - -![](images/4-2/4-2-5/04.png) -> 1. **Geometry.Rotate:** There are several Geometry.Rotate options; be certain you've chosen the Node with *geometry*,*basePlane*, and *degrees* as its inputs. Connect **Point.ByCoordinates** into the geometry input. -2. **Plane.XY:** Connect to the *basePlane* input. We will rotate around the origin, which is the same location as the base of the spiral. -3. **Number Range:** For our degree input, we want to create multiple rotations. We can do this quickly with a Number Range component. Connect this into the *degrees* input. -4. **Number:** And to define the range of numbers, add three number nodes to the canvas in vertical order. From top to bottom, assign values of *0.0,360.0,* and *120.0* respectively. These are driving the rotation of the spiral. Notice the output results from the **Number Range** node after connecting the three number nodes to the Node. - -Our output is beginning to resemble a whirlpool. Let's adjust some of the **Number Range** parameters and see how the results change: -![](images/4-2/4-2-5/05.png) -> 1. Change the step size of the **Number Range** node from *120.0* to *36.0*. Notice that this is creating more rotations and is therefore giving us a denser grid. - -![](images/4-2/4-2-5/06.png) -> 1. Change the step size of the **Number Range** node from *36.0* to *3.6*. This now gives us a much denser grid, and the directionality of the spiral is unclear. Ladies and gentlemen, we've created a sunflower. - +##Math +If the simplest form of data is numbers, the easiest way to relate those numbers is through Mathematics. From simple operators like divide to trigonometric functions, to more complex formulas, Math is a great way to start exploring numeric relationships and patterns. + +###Arithmetic Operators +Operators are a set of components that use algebraic functions with two numeric input values, which result in one output value (addition, subtraction, multiplication, division, etc.). These can be found under Operators>Actions. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/add-Large.png) | Add | + | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/sub-Large.png) | Subtract | - | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/mul-Large.png) | Multiply | * | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/div-Large.png) | Divide | / | var[]...[], var[]...[] | var[]...[] | + +###Parametric Formula +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Math.dyn](datasets/4-2/Building Blocks of Programs - Math.dyn). A full list of example files can be found in the Appendix. + +From Operators, the next logical step is to combine operators and variables to form a more complex relationship through **Formulas**. Let's make a Formula that can be controlled by input parameters, like sliders. + +![](images/4-2/4-2-5/01.png) +>1. **Number Sequence:** define a number sequence based on three inputs: *start, amount* and *step*. This sequence represents the 't' in the parametric equation, so we want to use a list that's large enough to define a spiral. + +The step above has created a list of numbers to define the parametric domain. The golden spiral is defined as the equation: ![](images/4-2/4-2-5/x.gif)=![](images/4-2/4-2-5/goldenSpiral.gif) and +![](images/4-2/4-2-5/y.gif)=![](images/4-2/4-2-5/goldenSpiral2.gif). The group of Nodes below represent this equation in visual programming form. + +![](images/4-2/4-2-5/02.png) +> When stepping through the group of Nodes, try to pay attention to the parallel between the visual program and written equation. +1. **Number Slider:** Add two number sliders to the canvas. These sliders will represent the *a* and the *b* variables of the parametric equation. These represent a constant which is flexible, or parameters which we can adjust towards a desired outcome. +2. ** * :** The multiplication Node is represented by an asterisk. We'll use this repeatedly to connect multiplying variables +3. **Math.RadiansToDegrees:** The '*t*' values need to be translated to degrees for their evaluation in the trigonometric functions. Remember, Dynamo defaults to degrees for evaluating these functions. +4. **Math.Pow:** as a function of the '*t*' and the number '*e*' this creates the Fibonacci sequence. +5. **Math.Cos and Math.Sin:** These two trigonmetric functions will differentiate the x-coordinate and the y-coordinate, respectively, of each parametric point. +6. **Watch: **We now see that our output is two lists, these will be the *x* and *y* coordinates of the points used to generate the spiral. + +###From Formula to Geometry +Now, the bulk of Nodes from the previous step will work fine, but it is a lot of work. To create a more efficient workflow, have a look at **Code Blocks** (section 3.3.2.3) to define a string of Dynamo expressions into one node. In this next series of steps, we'll look at using the parametric equation to draw the Fibonacci spiral. +![](images/4-2/4-2-5/03.png) +> 1. **Point.ByCoordinates:** Connect the upper multiplication node into the '*x*' input and the lower into the '*y*' input. We now see a parametric spiral of points on the screen. + +![](images/4-2/4-2-5/03aaa.png) +> 1. **Polycurve.ByPoints:** Connect Point.ByCoordinates from the previous step into *points*. We can leave *connectLastToFirst* without an input because we aren't making a closed curve. This creates a spiral which passes through each point defined in the previous step. + +We've now completed the Fibonacci Spiral! Let's take this further into two separate exercises from here, which we'll call the Nautilus and the Sunflower. These are abstractions of natural systems, but the two different applications of the Fibonacci spiral will be well represented. + +###From Spiral to Nautilus + +![](images/4-2/4-2-5/03.png) +> 1. As a jumping-off point, let's start with the same step from the previous exercise: creating a spiral array of points with the **Point.ByCoordinates** Node. + +![](images/4-2/4-2-5/03aa.png) +> 1. **Polycurve.ByPoints:** Again, this is the Node from the pervious exercise, which we'll use as a reference. +2. **Circle.ByCenterPointRadius:** We'll use a circle Node here with the same inputs as the previous step. The radius value defaults to *1.0*, so we see an immediate output of circles. It becomes immediately legible how the points diverge further from the origin. + +![](images/4-2/4-2-5/03a.png) +> 1. **Circle.ByCenterPointRadius:** To create a more dynamic array of circles, we plug the original number sequence (the '*t*' sequence) into the radius value. +2. **Number Sequence:** This is the original array of '*t*'. By plugging this into the radius value, the circle centers are still diverging further from the origin, but the radius of the circles is increasing, creating a funky Fibonacci circle graph. Bonus points if you make it 3D! + +###From Nautilus to Phyllotaxis Pattern +Now that we've made a circular Nautilus shell, let's jump into parametric grids. We're going to use a basic rotate on the Fibonacci Spiral to create a Fibonacci grid, and the result is modeled after the [growth of sunflower seeds.](http://ms.unimelb.edu.au/~segerman/papers/sunflower_spiral_fibonacci_metric.pdf) + +![](images/4-2/4-2-5/03.png) +> 1. Again, as a jumping-off point, let's start with the same step from the previous exercise: creating a spiral array of points with the **Point.ByCoordinates** Node. + +![](images/4-2/4-2-5/04.png) +> 1. **Geometry.Rotate:** There are several Geometry.Rotate options; be certain you've chosen the Node with *geometry*,*basePlane*, and *degrees* as its inputs. Connect **Point.ByCoordinates** into the geometry input. +2. **Plane.XY:** Connect to the *basePlane* input. We will rotate around the origin, which is the same location as the base of the spiral. +3. **Number Range:** For our degree input, we want to create multiple rotations. We can do this quickly with a Number Range component. Connect this into the *degrees* input. +4. **Number:** And to define the range of numbers, add three number nodes to the canvas in vertical order. From top to bottom, assign values of *0.0,360.0,* and *120.0* respectively. These are driving the rotation of the spiral. Notice the output results from the **Number Range** node after connecting the three number nodes to the Node. + +Our output is beginning to resemble a whirlpool. Let's adjust some of the **Number Range** parameters and see how the results change: +![](images/4-2/4-2-5/05.png) +> 1. Change the step size of the **Number Range** node from *120.0* to *36.0*. Notice that this is creating more rotations and is therefore giving us a denser grid. + +![](images/4-2/4-2-5/06.png) +> 1. Change the step size of the **Number Range** node from *36.0* to *3.6*. This now gives us a much denser grid, and the directionality of the spiral is unclear. Ladies and gentlemen, we've created a sunflower. + diff --git a/04_The-Building-Blocks-of-Programs/4-3_logic.md b/04_The-Building-Blocks-of-Programs/4-3_logic.md index 93d7fdef..d752422f 100644 --- a/04_The-Building-Blocks-of-Programs/4-3_logic.md +++ b/04_The-Building-Blocks-of-Programs/4-3_logic.md @@ -1,73 +1,73 @@ -##Logic -**Logic**, or more specifically, **Conditional Logic**, allows us to specify an action or set of actions based on a test. After evaluating the test, we will have a Boolean value representing ```True``` or ```False``` that we can use to control the Program Flow. - -###Booleans -Numeric variables can store a whole range of different numbers. Boolean variables can only store two values referred to as True or False, Yes or No, 1 or 0. We rarely use booleans to perform calculations because of their limited range. - -###Conditional Statements -The "If" statement is a key concept in programming: "If *this* is true, then *that* happens, otherwise *something else* happens. The resulting action of the statement is driven by a boolean value. There are multiple ways to define an "If" statement in Dynamo: - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCoreNodesUI-Logic-If-Large.png) | If | If | test, true, false | result| -| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | IF(x,y,z) | x, y, z | result | -| ![](../images/icons/Dynamo-Nodes-CodeBlockNodeModel-Large.png) | Code Block | (x?y:z)| x, y, z | result| -Let's go over a brief example on each of these three nodes in action using the conditional "If" statement: - -![](images/4-3/IFs.png) -> In this image, the *boolean* is set to *true*, which means that the result is a string reading: *"this is the result if true".* The three Nodes creating the *If* statement are working identically here. - -![](images/4-3/IFs2.png) -> Again, the Nodes are working identically. If the *boolean* is changed to *false*, our result is the number *Pi*, as defined in the original *If* statement. - -###Filtering a List ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Logic.dyn](datasets/4-3/Building Blocks of Programs - Logic.dyn). A full list of example files can be found in the Appendix. - -Let's use logic to separate a list of numbers into a list of even numbers and a list of odd numbers. - -![](images/4-3/01.png) -> 1. **Number Range -** add a number range to the canvas. -2. **Numbers -** add three number nodes to the canvas. The value for each number node should be: *0.0* for *start*, *10.0* for *end*, and *1.0* for *step*. -3. **Output - ** our output is a list of 11 numbers ranging from 0-10. -4. **Modulo (%)-** *Number Range* into *x* and *2.0* into *y*. This calculates the remainder for each number in the list divided by 2. The output from this list gives us a list of values alternating between 0 and 1. -5. **Equality Test (==) -** add an equality test to the canvas. Plug *modulo* output into the *x* input and *0.0* into the *y* input. -6. **Watch -** The output of the equality test is a list of values alternating between true and false. These are the values used to separate the items in the list. *0* (or *true*) represents even numbers and (*1*, or *false*) represents odd numbers. -6. **List.FilterByBoolMask -** this Node will filter the values into two different lists based on the input boolean. Plug the original *number range* into the *list* input and the *equality test** output into the *mask* input. The *in* output represents true values while the *out* output represents false values. -7. **Watch - ** as a result, we now have a list of even numbers and a list of odd numbers. We've used logical operators to separate lists into patterns! - -###From Logic to Geometry -Building off of the logic established in the first exercise, let's apply this setup into a modeling operation. - -![](images/4-3/02.png) -> 1. We'll jump off from the previous exercise with the same Nodes. The only exceptions: -2. We've changed the format. -3. The input values have changed. -4. We've unplugged the in list input into *List.FilterByBoolMask*. We'll put these Nodes aside for now, but they'll come in handy later in the exercise. - -![](images/4-3/03.png) -> Let's begin by connecting the Nodes together as shown in the image above. This group of Nodes represents a parametric equation to define a line curve. A few notes: -1. The **first slider** should have a min of 1, a max of 4, and a step of 0.01. -2. The **second slider** should have a min of 0, a max of 1, and a step of 0.01. -3. **PolyCurve.ByPoints -** if the above Node diagram is copied, the result is a sine curve in the Dynamo Preview viewport. - -The method here for the inputs: use number nodes for more static properties and number sliders on the more flexible ones. We want to keep the original number range that we're defining in the beginning of this step. However, the sine curve that we create here should have some flexibility. We can move these sliders to watch the curve update its frequency and amplitude. - -![](images/4-3/04.png) -> We're going to jump around a bit in the definition, so let's look at the end result so that we can reference what we're getting at. The first two steps are made separately, we now want to connect the two. We'll use the base sine curve to drive the location of the zipper components, and we'll use the true/false logic to alternate between little boxes and larger boxes. - -![](images/4-3/05.png) -> 1. **Math.RemapRange - ** Using the number sequence created in step 01, let's create a new series of numbers by remapping the range. The original numbers from step 01 range from 0-100. These numbers range from 0 to 1 by the *newMin* and *newMax* inputs respectively. - -![](images/4-3/06.png) -> 1. **Curve.PointAtParameter - ** Plug *Polycurve.ByPoints* (from step 2) into *curve* and *Math.RemapRange* into *param*. This step creates points along the curve. We remapped the numbers to 0 to 1 because the input of *param* is looking for values in this range. A value of *0* represents the start point, a value of *1* represents the end points. All numbers in between evaluate within the *[0,1]* range. - -![](images/4-3/07.png) -> 1. **List.FilterByBoolMask - ** Plug *Curve.PointAtParameter* from the previous step into the *list* input. -2. **Watch -** a watch node for *in* and a watch node for *out* shows that we have two lists representing even indices and odd indices. These points are ordered in the same way on the curve, which we demonstrate in the next step. - -![](images/4-3/08.png) -> 1. **Cuboid.ByLengths -** recreate the connections seen in the image above to get a zipper along the sine curve. A cuboid is just a box here, and we're defining its size based on the curve point in the center of hte box. The logic of the even/odd divide should now be clear in the model. - -![](images/4-3/matrix.png) -> 1. **Number Slider -** stepping back to the beginning of the definition, we can flex the number slider and watch the zipper update. The top row of images represents a range values for the top number slider. This is the frequency of the wave. -2. **Number Slider -** the bottom row of images represents a range of values for the bottom slider. This is the amplitude of the wave. +##Logic +**Logic**, or more specifically, **Conditional Logic**, allows us to specify an action or set of actions based on a test. After evaluating the test, we will have a Boolean value representing ```True``` or ```False``` that we can use to control the Program Flow. + +###Booleans +Numeric variables can store a whole range of different numbers. Boolean variables can only store two values referred to as True or False, Yes or No, 1 or 0. We rarely use booleans to perform calculations because of their limited range. + +###Conditional Statements +The "If" statement is a key concept in programming: "If *this* is true, then *that* happens, otherwise *something else* happens. The resulting action of the statement is driven by a boolean value. There are multiple ways to define an "If" statement in Dynamo: + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCoreNodesUI-Logic-If-Large.png) | If | If | test, true, false | result| +| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | IF(x,y,z) | x, y, z | result | +| ![](../images/icons/Dynamo-Nodes-CodeBlockNodeModel-Large.png) | Code Block | (x?y:z)| x, y, z | result| +Let's go over a brief example on each of these three nodes in action using the conditional "If" statement: + +![](images/4-3/IFs.png) +> In this image, the *boolean* is set to *true*, which means that the result is a string reading: *"this is the result if true".* The three Nodes creating the *If* statement are working identically here. + +![](images/4-3/IFs2.png) +> Again, the Nodes are working identically. If the *boolean* is changed to *false*, our result is the number *Pi*, as defined in the original *If* statement. + +###Filtering a List +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Logic.dyn](datasets/4-3/Building Blocks of Programs - Logic.dyn). A full list of example files can be found in the Appendix. + +Let's use logic to separate a list of numbers into a list of even numbers and a list of odd numbers. + +![](images/4-3/01.png) +> 1. **Number Range -** add a number range to the canvas. +2. **Numbers -** add three number nodes to the canvas. The value for each number node should be: *0.0* for *start*, *10.0* for *end*, and *1.0* for *step*. +3. **Output - ** our output is a list of 11 numbers ranging from 0-10. +4. **Modulo (%)-** *Number Range* into *x* and *2.0* into *y*. This calculates the remainder for each number in the list divided by 2. The output from this list gives us a list of values alternating between 0 and 1. +5. **Equality Test (==) -** add an equality test to the canvas. Plug *modulo* output into the *x* input and *0.0* into the *y* input. +6. **Watch -** The output of the equality test is a list of values alternating between true and false. These are the values used to separate the items in the list. *0* (or *true*) represents even numbers and (*1*, or *false*) represents odd numbers. +6. **List.FilterByBoolMask -** this Node will filter the values into two different lists based on the input boolean. Plug the original *number range* into the *list* input and the *equality test** output into the *mask* input. The *in* output represents true values while the *out* output represents false values. +7. **Watch - ** as a result, we now have a list of even numbers and a list of odd numbers. We've used logical operators to separate lists into patterns! + +###From Logic to Geometry +Building off of the logic established in the first exercise, let's apply this setup into a modeling operation. + +![](images/4-3/02.png) +> 1. We'll jump off from the previous exercise with the same Nodes. The only exceptions: +2. We've changed the format. +3. The input values have changed. +4. We've unplugged the in list input into *List.FilterByBoolMask*. We'll put these Nodes aside for now, but they'll come in handy later in the exercise. + +![](images/4-3/03.png) +> Let's begin by connecting the Nodes together as shown in the image above. This group of Nodes represents a parametric equation to define a line curve. A few notes: +1. The **first slider** should have a min of 1, a max of 4, and a step of 0.01. +2. The **second slider** should have a min of 0, a max of 1, and a step of 0.01. +3. **PolyCurve.ByPoints -** if the above Node diagram is copied, the result is a sine curve in the Dynamo Preview viewport. + +The method here for the inputs: use number nodes for more static properties and number sliders on the more flexible ones. We want to keep the original number range that we're defining in the beginning of this step. However, the sine curve that we create here should have some flexibility. We can move these sliders to watch the curve update its frequency and amplitude. + +![](images/4-3/04.png) +> We're going to jump around a bit in the definition, so let's look at the end result so that we can reference what we're getting at. The first two steps are made separately, we now want to connect the two. We'll use the base sine curve to drive the location of the zipper components, and we'll use the true/false logic to alternate between little boxes and larger boxes. + +![](images/4-3/05.png) +> 1. **Math.RemapRange - ** Using the number sequence created in step 01, let's create a new series of numbers by remapping the range. The original numbers from step 01 range from 0-100. These numbers range from 0 to 1 by the *newMin* and *newMax* inputs respectively. + +![](images/4-3/06.png) +> 1. **Curve.PointAtParameter - ** Plug *Polycurve.ByPoints* (from step 2) into *curve* and *Math.RemapRange* into *param*. This step creates points along the curve. We remapped the numbers to 0 to 1 because the input of *param* is looking for values in this range. A value of *0* represents the start point, a value of *1* represents the end points. All numbers in between evaluate within the *[0,1]* range. + +![](images/4-3/07.png) +> 1. **List.FilterByBoolMask - ** Plug *Curve.PointAtParameter* from the previous step into the *list* input. +2. **Watch -** a watch node for *in* and a watch node for *out* shows that we have two lists representing even indices and odd indices. These points are ordered in the same way on the curve, which we demonstrate in the next step. + +![](images/4-3/08.png) +> 1. **Cuboid.ByLengths -** recreate the connections seen in the image above to get a zipper along the sine curve. A cuboid is just a box here, and we're defining its size based on the curve point in the center of hte box. The logic of the even/odd divide should now be clear in the model. + +![](images/4-3/matrix.png) +> 1. **Number Slider -** stepping back to the beginning of the definition, we can flex the number slider and watch the zipper update. The top row of images represents a range values for the top number slider. This is the frequency of the wave. +2. **Number Slider -** the bottom row of images represents a range of values for the bottom slider. This is the amplitude of the wave. diff --git a/04_The-Building-Blocks-of-Programs/4-4_strings.md b/04_The-Building-Blocks-of-Programs/4-4_strings.md index 2feae799..271fe2ca 100644 --- a/04_The-Building-Blocks-of-Programs/4-4_strings.md +++ b/04_The-Building-Blocks-of-Programs/4-4_strings.md @@ -1,82 +1,82 @@ -##Strings -Formally, a **String** is a sequence of characters representing a literal constant or some type of variable. Informally, a string is programming lingo for text. We've worked with numbers, both integers and decimal numbers, to drive parameters and we can do the same with text. - -###Creating Strings -Strings can be used for a wide range of applications, including defining custom parameters, annotating documentation sets, and parsing through text-based data sets. The string Node is located in the Core>Input Category. - -![String Examples](images/4-4/4-4-1-005.png) -> The sample Nodes above are strings. A number can be represented as a string, as can a letter, or an entire array of text. - -###Querying Strings ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Strings.dyn](datasets/4-5/Building Blocks of Programs - Strings.dyn). A full list of example files can be found in the Appendix. - -You can parse through large amounts of data quickly by querying strings. We'll talk about some basic operations which can speed up a workflow and help for software interoperability. - -The image below considers a string of data coming from an external spreadsheet. The string represents the vertices of a rectangle in the XY-Plane. Let's break down some string split operations in miniature exercise: - -![StringSplit](images/4-4/4-4-1-001.png) -> 1. The ";" separator splits each vertex of the rectangle. This creates a list with 4 items for each vertex. - -![StringSplit](images/4-4/4-4-1-003.png) -> 1. By hitting the "*+*" in the middle of the Node, we create new separator. -2. Add a "*,*" string to the canvas and plug in to the new separator input. -3. Our result is now a list of ten items. The Node first splits based on *separator0*, then based on *separator1*. - -While the list of items above may look like numbers, they are still regarded as individual strings in Dynamo. In order to create points, their data type needs to be converted from a string to a Number. This is done with the String.ToNumber Node - -![StringSplit](images/4-4/4-4-1-002.png) -> 1. This Node is straightforward. Plug the String.Split results into the input. The output doesn't look different, but the data type is now a *number* instead of a *string*. - -![StringToNumber](images/4-4/4-4-1-004.png) -> 1. With some basic additional operations, we now have a rectangle drawn at the origin based on the original string input. - -###Manipulating Strings -Since a string is a generic text object, they host a wide range of applications. Let's take a look at some of the major actions in the Core>String Category in Dynamo: - -This is a method of merging two strings together in order. This takes each literal string in a list and creates one merged string. - -![Concatenate](images/4-4/4-4-1-007.png) -> The image above represents the concatenation of three strings: -1. Add or subtract strings to the concatenation by clicking the +/- buttons int he center of the Node. -2. The output gives one concatenated string, with spaces and punctuation included. - -The join method is very similar to concatenate, except it has an added layer of punctuation. - -If you've worked in Excel, you may have come across a CSV file. This stands for comma-separated values. One could use a comma (or in this case, two dashes) as the separator with the join Node in order to create a similar data structure: -![Concatenate](images/4-4/4-4-1-006.png) -> The image above represents the joining of two strings: -1. The separator input allows one to create a string which divides the joined strings. - -###Working with Strings -In this exercise, we're going to use methods of querying and manipulating strings to deconstruct the final stanza of Robert Frost's [Stopping By Woods on a Snowy Evening](http://www.poetryfoundation.org/poem/171621). Not the most practical application, but it will help us to grasp conceptual string actions as we apply them to legible lines of rhythm and rhyme. - -![Split String](images/4-4/4-4-4/00.png) -> Let's begin with a basic string split of the stanza. We first notice that the writing is formatted based on commas. We'll use this format to separate each line into individual items. -1. The base string is pasted into a string node. -2. Another string node is used to denote the separator. In this case, we're using a comma. -3. A String.Split Node is added to the canvas and connected to the two strings. -4. The output shows that we've now separated the lines into individual elements. - -![Split String](images/4-4/4-4-4/01.png) -> Now, let's get to the good part of the poem: the last two lines. The original stanza was one item of data. We separated this data into individual items in the first step. Now we need to do a search for the text we're looking for. And while we *can* do this by selecting the last two items of the list, if this were an entire book, we wouldn't want to read through everything and manually isolate the elements. -1. Instead of manually searching, we use a String.Contains Node to perform a search for a set of characters. This is the similar to doing the "Find" command in a word processor. In this case, we get a return of "true" or "false" if that substring is found within the item. -2. In the "searchFor" input, we define a substring that we're looking for within the stanza. Let's use a string node with the text "And miles". -3. The output gives us a list of falses and trues. We'll use this boolean logic to filter the elements in the next step. - -![Split String](images/4-4/4-4-4/02.png) ->1. List.FilterByBoolMask is the Node we want to use to cull out the falses and trues. The "in" output return the statements with a "mask" input of "true, while the "out" output return those which are "false". -2. Our output from the "in" is as expected, giving us the final two lines of the stanza. - -![Split String](images/4-4/4-4-4/03.png) ->Now, we want to drive home the repetition of the stanza by merging the two lines together. When viewing the output of the previous step, we notice that there are two items in the list: -1. Using two List.GetItemAtIndex Nodes, we can isolate the items using the values of 0 and 1 as the index input. -2. The output for each Node gives us, in order, the final two lines. - -![Split String](images/4-4/4-4-4/04.png) ->To merge these two items into one, we use the String.Join Node: -1. After adding the String.Join Node, we notice that we need a separator. -2. To create the separator, we add a string node to the canvas and type in a comma. -3. The final output has merged the last two items into one. - -This may seem like a lot of work to isolate the last two lines; and it's true, string operations often require some up front work. But they are scalable, and they can be applied to large datasets with relative ease. If you are working parametrically with spreadsheets and interoperability, be sure to keep string operations in mind. - +##Strings +Formally, a **String** is a sequence of characters representing a literal constant or some type of variable. Informally, a string is programming lingo for text. We've worked with numbers, both integers and decimal numbers, to drive parameters and we can do the same with text. + +###Creating Strings +Strings can be used for a wide range of applications, including defining custom parameters, annotating documentation sets, and parsing through text-based data sets. The string Node is located in the Core>Input Category. + +![String Examples](images/4-4/4-4-1-005.png) +> The sample Nodes above are strings. A number can be represented as a string, as can a letter, or an entire array of text. + +###Querying Strings +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Strings.dyn](datasets/4-5/Building Blocks of Programs - Strings.dyn). A full list of example files can be found in the Appendix. + +You can parse through large amounts of data quickly by querying strings. We'll talk about some basic operations which can speed up a workflow and help for software interoperability. + +The image below considers a string of data coming from an external spreadsheet. The string represents the vertices of a rectangle in the XY-Plane. Let's break down some string split operations in miniature exercise: + +![StringSplit](images/4-4/4-4-1-001.png) +> 1. The ";" separator splits each vertex of the rectangle. This creates a list with 4 items for each vertex. + +![StringSplit](images/4-4/4-4-1-003.png) +> 1. By hitting the "*+*" in the middle of the Node, we create new separator. +2. Add a "*,*" string to the canvas and plug in to the new separator input. +3. Our result is now a list of ten items. The Node first splits based on *separator0*, then based on *separator1*. + +While the list of items above may look like numbers, they are still regarded as individual strings in Dynamo. In order to create points, their data type needs to be converted from a string to a Number. This is done with the String.ToNumber Node + +![StringSplit](images/4-4/4-4-1-002.png) +> 1. This Node is straightforward. Plug the String.Split results into the input. The output doesn't look different, but the data type is now a *number* instead of a *string*. + +![StringToNumber](images/4-4/4-4-1-004.png) +> 1. With some basic additional operations, we now have a rectangle drawn at the origin based on the original string input. + +###Manipulating Strings +Since a string is a generic text object, they host a wide range of applications. Let's take a look at some of the major actions in the Core>String Category in Dynamo: + +This is a method of merging two strings together in order. This takes each literal string in a list and creates one merged string. + +![Concatenate](images/4-4/4-4-1-007.png) +> The image above represents the concatenation of three strings: +1. Add or subtract strings to the concatenation by clicking the +/- buttons int he center of the Node. +2. The output gives one concatenated string, with spaces and punctuation included. + +The join method is very similar to concatenate, except it has an added layer of punctuation. + +If you've worked in Excel, you may have come across a CSV file. This stands for comma-separated values. One could use a comma (or in this case, two dashes) as the separator with the join Node in order to create a similar data structure: +![Concatenate](images/4-4/4-4-1-006.png) +> The image above represents the joining of two strings: +1. The separator input allows one to create a string which divides the joined strings. + +###Working with Strings +In this exercise, we're going to use methods of querying and manipulating strings to deconstruct the final stanza of Robert Frost's [Stopping By Woods on a Snowy Evening](http://www.poetryfoundation.org/poem/171621). Not the most practical application, but it will help us to grasp conceptual string actions as we apply them to legible lines of rhythm and rhyme. + +![Split String](images/4-4/4-4-4/00.png) +> Let's begin with a basic string split of the stanza. We first notice that the writing is formatted based on commas. We'll use this format to separate each line into individual items. +1. The base string is pasted into a string node. +2. Another string node is used to denote the separator. In this case, we're using a comma. +3. A String.Split Node is added to the canvas and connected to the two strings. +4. The output shows that we've now separated the lines into individual elements. + +![Split String](images/4-4/4-4-4/01.png) +> Now, let's get to the good part of the poem: the last two lines. The original stanza was one item of data. We separated this data into individual items in the first step. Now we need to do a search for the text we're looking for. And while we *can* do this by selecting the last two items of the list, if this were an entire book, we wouldn't want to read through everything and manually isolate the elements. +1. Instead of manually searching, we use a String.Contains Node to perform a search for a set of characters. This is the similar to doing the "Find" command in a word processor. In this case, we get a return of "true" or "false" if that substring is found within the item. +2. In the "searchFor" input, we define a substring that we're looking for within the stanza. Let's use a string node with the text "And miles". +3. The output gives us a list of falses and trues. We'll use this boolean logic to filter the elements in the next step. + +![Split String](images/4-4/4-4-4/02.png) +>1. List.FilterByBoolMask is the Node we want to use to cull out the falses and trues. The "in" output return the statements with a "mask" input of "true, while the "out" output return those which are "false". +2. Our output from the "in" is as expected, giving us the final two lines of the stanza. + +![Split String](images/4-4/4-4-4/03.png) +>Now, we want to drive home the repetition of the stanza by merging the two lines together. When viewing the output of the previous step, we notice that there are two items in the list: +1. Using two List.GetItemAtIndex Nodes, we can isolate the items using the values of 0 and 1 as the index input. +2. The output for each Node gives us, in order, the final two lines. + +![Split String](images/4-4/4-4-4/04.png) +>To merge these two items into one, we use the String.Join Node: +1. After adding the String.Join Node, we notice that we need a separator. +2. To create the separator, we add a string node to the canvas and type in a comma. +3. The final output has merged the last two items into one. + +This may seem like a lot of work to isolate the last two lines; and it's true, string operations often require some up front work. But they are scalable, and they can be applied to large datasets with relative ease. If you are working parametrically with spreadsheets and interoperability, be sure to keep string operations in mind. + diff --git a/04_The-Building-Blocks-of-Programs/4-5_color.md b/04_The-Building-Blocks-of-Programs/4-5_color.md index 4c282d37..330f5cbe 100644 --- a/04_The-Building-Blocks-of-Programs/4-5_color.md +++ b/04_The-Building-Blocks-of-Programs/4-5_color.md @@ -1,132 +1,132 @@ -##Color -Color is a great data type for creating compelling visuals as well as for rendering difference in the output from your Visual Program. When working with abstract data and varying numbers, sometimes it's difficult to see what's changing and to what degree. This is a great application for colors. - -###Creating Colors -Colors in Dynamo are created using ARGB inputs.This corresponds to the Alpha, Red, Green, and Blue channels. The alpha represents the *transparency* of the color, while the other three are used as primary colors to generate the whole spectrum of color in concert. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Color-ByARGB-Large.png) | ARGB Color | Color.ByARGB | A,R,G,B | color | - -###Querying Color Values -The colors in the table below query the properties used to define the color: Alpha, Red, Green, and Blue. Note that the Color.Components Node gives us all four as different outputs, which makes this Node preferable for querying the properties of a color. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Color-Alpha-Large.png) | Alpha | Color.Alpha | color | A | -| ![](../images/icons/DSCore-Color-Red-Large.png) | Red | Color.Red | color | R | -| ![](../images/icons/DSCore-Color-Green-Large.png) | Green | Color.Green | color | G | -| ![](../images/icons/DSCore-Color-Blue-Large.png) | Blue | Color.Blue | color | B | -| ![](../images/icons/DSCore-Color-Components-Large.png) | Components | Color.Components | color | A,R,G,B | - -The colors in the table below correspond to the **HSB color space**. Dividing the color into hue, saturation, and brightness is arguably more intuitive for how we interpret color: What color should it be? How colorful should it be? And how light or dark should the color be? This is the breakdown of hue, saturation, and brightness respectively. - -| Icon | Query Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Color-Hue-Large.png) | Hue | Color.Hue | color | Hue | -| ![](../images/icons/DSCore-Color-Saturation-Large.png) | Saturation | Color.Saturation | color | Saturation | -| ![](../images/icons/DSCore-Color-Brightness-Large.png) | Brightness | Color.Brightness | color | Brightness | - -###Color Range -The color range is similar to the **Remap Range** Node from section 4.2: it remaps a list of numbers into another domain. But instead of mapping to a *number* domain, it maps to a *color gradient* based on input numbers ranging from 0 to 1. - -The current Node works well, but it can be a little awkward to get everything working the first time around. The best way to become familiar with the color gradient is to test it out interactively. Let's do a quick exercise to review how to setup a gradient with output colors corresponding to numbers. - -![](images/4-5/range.png) ->1. **Define three colors: ** Using a code block node, define *red, green*, and *blue* by plugging in the appropriate combinations of *0* and *255*. -2. **Create list:** Merge the three colors into one list. -3. **Define Indices: ** Create a list to define the grip positions of each color (ranging from 0 to 1). Notice the value of 0.75 for green. This places the green color 3/4 of the way across the horizontal gradient in the color range slider. -4. **Code Block: ** Input values (between 0 and 1) to translate to colors. - -### Color Preview -The **Display.ByGeometry** Node gives us the ability to color geometry in the Dynamo viewport. This is helpful for separating different types of geometry, demonstrating a parametric concept, or defining an analysis legend for simulation. The inputs are simple: geometry and color. To create a gradient like the image above, the color input is connected to the **color range** Node. - -![](images/4-5/cuboids.png) - - -###Color Exercise ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Color.dyn](datasets/4-5/Building Blocks of Programs - Color.dyn). A full list of example files can be found in the Appendix. - -This exercise focuses on controlling color parametrically in parallel with geometry. The geometry is a basic helix, which we define below using the **Code Block** (3.2.3). This is a quick and easy way to create a parametric function; and since our focus is on color (rather than geometry), we use the code block to efficiently create the helix without cluttering the canvas. We will use the code block more frequently as the primer moves to more advanced material. - -![](images/4-5/4-5-5/11.png) -> 1. **Code Block:** Define the two code blocks with the formulas above. This is a quick parametric method for creating a spiral. -2. **Point.ByCoordinates:**Plug the three outputs from the code block into the coordinates for the Node. - -We now see an array of points creating a helix. The next step is to create a curve through the points so that we can visualize the helix. - -![](images/4-5/4-5-5/10.png) -> 1. **PolyCurve.ByPoints:** Connect the *Point.ByCoordinates* output into the *points* input for the Node. We get a helical curve. -2. **Curve.PointAtParameter:** Connect the *PolyCurve.ByPoints* output into the *curve* input. The purpose of this step is to create a parametric attractor point which slides along the curve. Since the curve is evaluating a point at parameter, we'll need to input a *param* value between 0 and 1. -3. **Number Slider:** After adding to the canvas, change the *min* value to *0.0*, the *max* value to *1.0*, and the *step* value to *.01*. Plug the slider output into the *param* input for *Curve.PointAtParameter*. We now see a point along the length of the helix, represented by a percentage of the slider (0 at the start point, 1 at the end point). - -With the reference point created, we now compare the distance from the reference point to the original points defining the helix. This distance value will drive geometry as well as color. - -![](images/4-5/4-5-5/09.png) -> 1. **Geometry.DistanceTo:** Connect *Curve.PointAtParameter* output into the *input*. Connect *Point.ByCoordinates* into the *geometry input. -2. **Watch:** The resultant output shows a list of distances from each helical point to the reference point along the curve. - -Our next step is to drive parameters with the list of distances from the helical points to the reference point. We use these distance values to define the radii of a series of spheres along the curve. In order to keep the spheres a suitable size, we need to *remap* the values for distance. - -![](images/4-5/4-5-5/08.png) -> 1. **Math.RemapRange:** Connect *Geometry.DistanceTo* output into the numbers input. -2. **Code Block:** connect a code block with a value of *0.01* into the *newMin* input and a code block with a value of *1* into the *newMax* input. -3. **Watch:** connect the *Math.RemapRange* output into one Node and the *Geometry.DistanceTo* output into another. Compare the results. - -This step has remapped the list of distance to be a smaller range. We can edit the *newMin* and *newMax* values however we see fit. The values will remap and will have the same *distribution ratio* across the domain. - -![](images/4-5/4-5-5/07.png) -> 1. **Sphere.ByCenterPointRadius:** connect the *Math.RemapRange* output into the *radius* input and the original *Point.ByCoordinates* output into the *centerPoint* input. - -![](images/4-5/4-5-5/06.png) -> 1. **Number Slider:** change the value of the number slider and watch the size of the spheres update. We now have a parametric jig. - -The size of the spheres demonstrates the parametric array defined by a reference point along the curve. Let's use the same concept for the sphere radius to drive their color. - -![](images/4-5/4-5-5/05.png) -> 1. **Color Range:** Add top the canvas. When hovering over the *value* input, we notice that the numbers requested are between 0 and 1. We need to remap the numbers from the *Geometry.DistanceTo* output so that they are compatible with this domain. - 2. **Sphere.ByCenterPointRadius:** For the time being, let's disable the preview on this Node (*Right Click > Preview*) - -![](images/4-5/4-5-5/04.png) -> 1. **Math.RemapRange:** This process should look familiar. Connect the *Geometry.DistanceTo* output into the numbers input. -2. **Code Block:** Similar to an earlier step, create a value of *0* for the *newMin* input and a value of *1* for the *newMax* input. Notice that we are able to define two outputs from one code block in this case. -3. **Color Range:** Connect the *Math.RemapRange* output into the *value* input. - -![](images/4-5/4-5-5/03.png) -> 1. **Color.ByARGB:** This is what we'll do to create two colors. While this process may look awkward, it's the same as RGB colors in another software, we're just using visual programming to do it. -2. **Code Block:** create two values of *0* and *255*. Plug the two outputs into the two *Color.ByARGB* inputs in agreement with the image above (or create your favorite two colors). -3. **Color Range:** The *colors* input requests a list of colors. We need to create this list from the two colors created in the previous step. -4. **List.Create:** merge the two colors into one list. Plug the output into the *colors* input for *Color Range*. - -![](images/4-5/4-5-5/02.png) -> 1. **Display.ByGeometryColor:** Connect *Sphere.ByCenterPointRadius* into the *geometry* input and the *Color Range* into the *color* input. We now have a smooth gradient across the domain of the curve. - -![](images/4-5/4-5-5/01.png) -> If we change the value of the *number slider* from earlier in the definition, the colors and sizes update. Colors and radius size are directly related in this case: we now have a visual link between two parameters! - - -### Color On Surfaces -The **Display.BySurfaceColors** node gives us the ability to map data across a surface using color! This functionality introduces some exciting possibilities for visualizing data obtained through discrete analysis like solar, energy, and proximity. Applying color to a surface in Dynamo is similar to applying a texture to a material in other CAD environments. Let's demonstrate how to use this tool in the brief exercise below. - - -![](images/4-5/4-5-5/12.PNG) - - -###Color on Surfaces Exercise ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - ColorOnSurface.zip](datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.zip). A full list of example files can be found in the Appendix. - -![](images/4-5/4-5-5/13.png) -> First, we need to create (or reference) a surface to use as an input for the **Display.BySurfaceColors** node. For this example we are lofting between a sine and cosine curve. -1. This **Group** of nodes is creating points along the Z-axis then displacing them based on sine and cosine functions. The two point lists are then used to generate NURBS curves. -2. **Surface.ByLoft**: generate an interpolated surface between the list of NURBS curves. - - -![](images/4-5/4-5-5/14.png) ->1. **File Path**: select an image file to sample for pixel data downstream -2. use **File.FromPath** to convert the file path to a file then pass into **Image.ReadFromFile** to output an image for sampling -3. **Image.Pixels**: input an image and provide a sample value to use along the x and y dimensions of the image. -4. **Slider**: provide sample values for **Image.Pixels** -5. **Display.BySurfaceColors**: map array of color values across surface along X and Y respectively - -![](images/4-5/4-5-5/15.PNG) +##Color +Color is a great data type for creating compelling visuals as well as for rendering difference in the output from your Visual Program. When working with abstract data and varying numbers, sometimes it's difficult to see what's changing and to what degree. This is a great application for colors. + +###Creating Colors +Colors in Dynamo are created using ARGB inputs.This corresponds to the Alpha, Red, Green, and Blue channels. The alpha represents the *transparency* of the color, while the other three are used as primary colors to generate the whole spectrum of color in concert. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Color-ByARGB-Large.png) | ARGB Color | Color.ByARGB | A,R,G,B | color | + +###Querying Color Values +The colors in the table below query the properties used to define the color: Alpha, Red, Green, and Blue. Note that the Color.Components Node gives us all four as different outputs, which makes this Node preferable for querying the properties of a color. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Color-Alpha-Large.png) | Alpha | Color.Alpha | color | A | +| ![](../images/icons/DSCore-Color-Red-Large.png) | Red | Color.Red | color | R | +| ![](../images/icons/DSCore-Color-Green-Large.png) | Green | Color.Green | color | G | +| ![](../images/icons/DSCore-Color-Blue-Large.png) | Blue | Color.Blue | color | B | +| ![](../images/icons/DSCore-Color-Components-Large.png) | Components | Color.Components | color | A,R,G,B | + +The colors in the table below correspond to the **HSB color space**. Dividing the color into hue, saturation, and brightness is arguably more intuitive for how we interpret color: What color should it be? How colorful should it be? And how light or dark should the color be? This is the breakdown of hue, saturation, and brightness respectively. + +| Icon | Query Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Color-Hue-Large.png) | Hue | Color.Hue | color | Hue | +| ![](../images/icons/DSCore-Color-Saturation-Large.png) | Saturation | Color.Saturation | color | Saturation | +| ![](../images/icons/DSCore-Color-Brightness-Large.png) | Brightness | Color.Brightness | color | Brightness | + +###Color Range +The color range is similar to the **Remap Range** Node from section 4.2: it remaps a list of numbers into another domain. But instead of mapping to a *number* domain, it maps to a *color gradient* based on input numbers ranging from 0 to 1. + +The current Node works well, but it can be a little awkward to get everything working the first time around. The best way to become familiar with the color gradient is to test it out interactively. Let's do a quick exercise to review how to setup a gradient with output colors corresponding to numbers. + +![](images/4-5/range.png) +>1. **Define three colors: ** Using a code block node, define *red, green*, and *blue* by plugging in the appropriate combinations of *0* and *255*. +2. **Create list:** Merge the three colors into one list. +3. **Define Indices: ** Create a list to define the grip positions of each color (ranging from 0 to 1). Notice the value of 0.75 for green. This places the green color 3/4 of the way across the horizontal gradient in the color range slider. +4. **Code Block: ** Input values (between 0 and 1) to translate to colors. + +### Color Preview +The **Display.ByGeometry** Node gives us the ability to color geometry in the Dynamo viewport. This is helpful for separating different types of geometry, demonstrating a parametric concept, or defining an analysis legend for simulation. The inputs are simple: geometry and color. To create a gradient like the image above, the color input is connected to the **color range** Node. + +![](images/4-5/cuboids.png) + + +###Color Exercise +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - Color.dyn](datasets/4-5/Building Blocks of Programs - Color.dyn). A full list of example files can be found in the Appendix. + +This exercise focuses on controlling color parametrically in parallel with geometry. The geometry is a basic helix, which we define below using the **Code Block** (3.2.3). This is a quick and easy way to create a parametric function; and since our focus is on color (rather than geometry), we use the code block to efficiently create the helix without cluttering the canvas. We will use the code block more frequently as the primer moves to more advanced material. + +![](images/4-5/4-5-5/11.png) +> 1. **Code Block:** Define the two code blocks with the formulas above. This is a quick parametric method for creating a spiral. +2. **Point.ByCoordinates:**Plug the three outputs from the code block into the coordinates for the Node. + +We now see an array of points creating a helix. The next step is to create a curve through the points so that we can visualize the helix. + +![](images/4-5/4-5-5/10.png) +> 1. **PolyCurve.ByPoints:** Connect the *Point.ByCoordinates* output into the *points* input for the Node. We get a helical curve. +2. **Curve.PointAtParameter:** Connect the *PolyCurve.ByPoints* output into the *curve* input. The purpose of this step is to create a parametric attractor point which slides along the curve. Since the curve is evaluating a point at parameter, we'll need to input a *param* value between 0 and 1. +3. **Number Slider:** After adding to the canvas, change the *min* value to *0.0*, the *max* value to *1.0*, and the *step* value to *.01*. Plug the slider output into the *param* input for *Curve.PointAtParameter*. We now see a point along the length of the helix, represented by a percentage of the slider (0 at the start point, 1 at the end point). + +With the reference point created, we now compare the distance from the reference point to the original points defining the helix. This distance value will drive geometry as well as color. + +![](images/4-5/4-5-5/09.png) +> 1. **Geometry.DistanceTo:** Connect *Curve.PointAtParameter* output into the *input*. Connect *Point.ByCoordinates* into the *geometry input. +2. **Watch:** The resultant output shows a list of distances from each helical point to the reference point along the curve. + +Our next step is to drive parameters with the list of distances from the helical points to the reference point. We use these distance values to define the radii of a series of spheres along the curve. In order to keep the spheres a suitable size, we need to *remap* the values for distance. + +![](images/4-5/4-5-5/08.png) +> 1. **Math.RemapRange:** Connect *Geometry.DistanceTo* output into the numbers input. +2. **Code Block:** connect a code block with a value of *0.01* into the *newMin* input and a code block with a value of *1* into the *newMax* input. +3. **Watch:** connect the *Math.RemapRange* output into one Node and the *Geometry.DistanceTo* output into another. Compare the results. + +This step has remapped the list of distance to be a smaller range. We can edit the *newMin* and *newMax* values however we see fit. The values will remap and will have the same *distribution ratio* across the domain. + +![](images/4-5/4-5-5/07.png) +> 1. **Sphere.ByCenterPointRadius:** connect the *Math.RemapRange* output into the *radius* input and the original *Point.ByCoordinates* output into the *centerPoint* input. + +![](images/4-5/4-5-5/06.png) +> 1. **Number Slider:** change the value of the number slider and watch the size of the spheres update. We now have a parametric jig. + +The size of the spheres demonstrates the parametric array defined by a reference point along the curve. Let's use the same concept for the sphere radius to drive their color. + +![](images/4-5/4-5-5/05.png) +> 1. **Color Range:** Add top the canvas. When hovering over the *value* input, we notice that the numbers requested are between 0 and 1. We need to remap the numbers from the *Geometry.DistanceTo* output so that they are compatible with this domain. + 2. **Sphere.ByCenterPointRadius:** For the time being, let's disable the preview on this Node (*Right Click > Preview*) + +![](images/4-5/4-5-5/04.png) +> 1. **Math.RemapRange:** This process should look familiar. Connect the *Geometry.DistanceTo* output into the numbers input. +2. **Code Block:** Similar to an earlier step, create a value of *0* for the *newMin* input and a value of *1* for the *newMax* input. Notice that we are able to define two outputs from one code block in this case. +3. **Color Range:** Connect the *Math.RemapRange* output into the *value* input. + +![](images/4-5/4-5-5/03.png) +> 1. **Color.ByARGB:** This is what we'll do to create two colors. While this process may look awkward, it's the same as RGB colors in another software, we're just using visual programming to do it. +2. **Code Block:** create two values of *0* and *255*. Plug the two outputs into the two *Color.ByARGB* inputs in agreement with the image above (or create your favorite two colors). +3. **Color Range:** The *colors* input requests a list of colors. We need to create this list from the two colors created in the previous step. +4. **List.Create:** merge the two colors into one list. Plug the output into the *colors* input for *Color Range*. + +![](images/4-5/4-5-5/02.png) +> 1. **Display.ByGeometryColor:** Connect *Sphere.ByCenterPointRadius* into the *geometry* input and the *Color Range* into the *color* input. We now have a smooth gradient across the domain of the curve. + +![](images/4-5/4-5-5/01.png) +> If we change the value of the *number slider* from earlier in the definition, the colors and sizes update. Colors and radius size are directly related in this case: we now have a visual link between two parameters! + + +### Color On Surfaces +The **Display.BySurfaceColors** node gives us the ability to map data across a surface using color! This functionality introduces some exciting possibilities for visualizing data obtained through discrete analysis like solar, energy, and proximity. Applying color to a surface in Dynamo is similar to applying a texture to a material in other CAD environments. Let's demonstrate how to use this tool in the brief exercise below. + + +![](images/4-5/4-5-5/12.PNG) + + +###Color on Surfaces Exercise +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Building Blocks of Programs - ColorOnSurface.zip](datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.zip). A full list of example files can be found in the Appendix. + +![](images/4-5/4-5-5/13.png) +> First, we need to create (or reference) a surface to use as an input for the **Display.BySurfaceColors** node. For this example we are lofting between a sine and cosine curve. +1. This **Group** of nodes is creating points along the Z-axis then displacing them based on sine and cosine functions. The two point lists are then used to generate NURBS curves. +2. **Surface.ByLoft**: generate an interpolated surface between the list of NURBS curves. + + +![](images/4-5/4-5-5/14.png) +>1. **File Path**: select an image file to sample for pixel data downstream +2. use **File.FromPath** to convert the file path to a file then pass into **Image.ReadFromFile** to output an image for sampling +3. **Image.Pixels**: input an image and provide a sample value to use along the x and y dimensions of the image. +4. **Slider**: provide sample values for **Image.Pixels** +5. **Display.BySurfaceColors**: map array of color values across surface along X and Y respectively + +![](images/4-5/4-5-5/15.PNG) >Close-up preview of the output surface with resolution of 400x300 samples \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md b/04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md index 2bee9812..cda4e0e2 100644 --- a/04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md +++ b/04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md @@ -1,5 +1,5 @@ -#THE BUILDING BLOCKS OF PROGRAMS - -Once we are ready to dive deeper into developing Visual Programs, we will need a deeper understanding of the building blocks we will use. This chapter introduces fundamental concepts around data - the stuff that travels through the Wires of our Dynamo program. - -![Building Blocks Main](images/4/The Building Blocks of Program-01.png) +#THE BUILDING BLOCKS OF PROGRAMS + +Once we are ready to dive deeper into developing Visual Programs, we will need a deeper understanding of the building blocks we will use. This chapter introduces fundamental concepts around data - the stuff that travels through the Wires of our Dynamo program. + +![Building Blocks Main](images/4/The Building Blocks of Program-01.png) diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn index ef2fba9f..1c32ee21 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn @@ -1,84 +1,84 @@ - - - - - 0.04 - - - - 0 - - - - - - - - - - - - - - - - - - - - 0.95 - - - - 1.74 - - - - 1.49 - - - - - - 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + 0.04 + + + + 0 + + + + + + + + + + + + + + + + + + + + 0.95 + + + + 1.74 + + + + 1.49 + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn index 955fcf91..39a7667b 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn @@ -1,132 +1,132 @@ - - - - - - - 149 - - - - - - - - - - - 0.259 - - - - 0.128 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + 149 + + + + + + + + + + + 0.259 + + + + 0.128 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn index 3dd537ae..e7f13e8f 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn @@ -1,173 +1,173 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - 0.59 - - - - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + 0.59 + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn index f13ede60..b9280b52 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn @@ -1,78 +1,78 @@ - - - - - - The woods are lovely,dark and deep,But I have promises to keep,And miles to go before I sleep,And miles to go before I sleep. - - - - - , - - - - - - - And miles - - - - - - - - - - - - - - , - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + The woods are lovely,dark and deep,But I have promises to keep,And miles to go before I sleep,And miles to go before I sleep. + + + + + , + + + + + + + And miles + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn index 14028a19..1f9b77b1 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn @@ -1,126 +1,126 @@ - - - - - - - - - - - - - - - - - 0.3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + 0.3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.dyn b/04_The-Building-Blocks-of-Programs/datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.dyn index 9557f4dd..ec0fc1eb 100644 --- a/04_The-Building-Blocks-of-Programs/datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.dyn +++ b/04_The-Building-Blocks-of-Programs/datasets/4-5/BuildingBlocks of Programs - ColorOnSurface.dyn @@ -1,63 +1,63 @@ - - - - - - - - - - - 16.4 - - - - 2.6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + 16.4 + + + + 2.6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04_The-Building-Blocks-of-Programs/images/.gitkeep b/04_The-Building-Blocks-of-Programs/images/.gitkeep index 9901e584..c22a44b3 100644 --- a/04_The-Building-Blocks-of-Programs/images/.gitkeep +++ b/04_The-Building-Blocks-of-Programs/images/.gitkeep @@ -1 +1 @@ -# this directory was conjured with black magic :) +# this directory was conjured with black magic :) diff --git a/05_Geometry-for-Computational-Design/5-1_geometry-overview.md b/05_Geometry-for-Computational-Design/5-1_geometry-overview.md index 673894fd..39ba2eea 100644 --- a/05_Geometry-for-Computational-Design/5-1_geometry-overview.md +++ b/05_Geometry-for-Computational-Design/5-1_geometry-overview.md @@ -1,53 +1,53 @@ -## Geometry Overview -**Geometry** is the language for design. When a programming language or environment has a geometry kernel at its core, we can unlock the possibilities for designing precise and robust models, automating design routines, and generating design iterations with algorithms. - -### The Basics -Geometry, traditionally defined, is the study of shape, size, relative position of figures, and the properties of space. This field has a rich history going back thousands of years. With the advent and popularization of the computer, we gained a powerful tool in defining, exploring, and generating geometry. It is now so easy to calculate the result of complex geometric interactions, the fact that we are doing so is almost transparent. - -![Stanford Bunny](images/5-1/StanfordBunny.png) -> If you're curious to see how diverse and complex geometry can get using the power of your computer, do a quick web search for the Stanford Bunny - a canonical model used to test algorithms. - -Understanding geometry in the context of algorithms, computing, and complexity, may sound daunting; however, there are a few key, and relatively simple, principles that we can establish as fundamentals to start building towards more advanced applications: - -1. Geometry is **Data** - to the computer and Dynamo, a Bunny not all that different from a number. -2. Geometry relies on **Abstraction** - fundamentally, geometric elements are described by numbers, relationships, and formulas within a given spatial coordinate system -3. Geometry has a **Hierarchy** - points come together to make lines, lines come together to make surfaces, and so on -4. Geometry simultaneously describes both **the Part and the Whole** - when we have a curve, it is both the shape as well as all the possible points along it - -In practice, these principles mean that we need to be aware of what we are working with (what type of geometry, how was it created, etc.) so that we can fluidly compose, decompose, and recompose different geometries as we develop more complex models. - -### Stepping through the Hierarchy -Let's take a moment to look at the relationship between the Abstract and Hierarchical descriptions of Geometry. Because these two concepts are related, but not always obvious at first, we can quickly arrive at a conceptual roadblock once we start developing deeper workflows or models. For starters, let's use dimensionality as an easy descriptor of the "stuff" we model. The number of dimensions required to describe a shape gives us a window into how Geometry is organized hierarchically. - -![Computational Geometry](images/5-1/GeometryDimensionality.png) -> 1. A **Point** (defined by coordinates) doesn't have any dimensions to it - it's just numbers describing each coordinate -2. A **Line** (defined by two points) now has *one* dimension - we can "walk" the line either forward (positive direction) or backward (negative direction) -3. A **Plane** (defined by two lines) has *two* dimensions - walking more left or more right is now possible -4. A **Box** (defined by two planes) has *three* dimensions - we can define a position relative to up or down - -Dimensionality is a convenient way to start categorizing Geometry but it's not necessarily the best. After all, we don't model with only Points, Lines, Planes, and Boxes - what if I want something curvy? Furthermore, there is a whole other category of Geometric types that are completely abstract ie. they define properties like orientation, volume, or relationships between parts. We can't really grab a hold of a Vector so how do we define it relative to what we see in space? A more detailed categorization of the geometric hierarchy should accommodate the difference between Abstract Types or "Helpers," each of which we can group by what they help do and types that help describe the shape of model elements. - -![Geometry Hierarchy](images/5-1/GeometryHierarchy.jpg) - -### Geometry in Dynamo Studio - -So what does this mean for using Dynamo? Understanding the Geometry types and how they are related will allow us to navigate the collection of **Geometry Nodes** available to us in the Library. The Geometry Nodes are organized alphabetically as opposed to hierarchically - here they are displayed similar to their layout in the Dynamo interface. - -![Geometry in Dynamo](images/5-1/GeometryOrganization2.png) - -Additionally, making models in Dynamo and connecting the preview of what we see in the Background Preview to the flow of data in our graph should become more intuitive over time. - - -![Geometry in Dynamo](images/5-1/GeometryInDynamo.png) -> 1. Note the assumed coordinate system rendered by the grid and colored axes -3. Selected Nodes will render the corresponding geometry (if the Node creates geometry) in the background the highlight color - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Geometry Overview.dyn](datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn). A full list of example files can be found in the Appendix. - -### Going Further with Geometry -Creating models in Dynamo is not limited to what we can generate with Nodes. Here are some key ways to take your process to the next level with Geometry: - -1. Dynamo allows you to import files - try using a CSV for point clouds or SAT for bringing in surfaces -2. When working with Revit, we can reference Revit elements to use in Dynamo -3. The Dynamo Package Manager offers additional functionality for extended geometry types and operations - check out the [Mesh Toolkit](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) package - +## Geometry Overview +**Geometry** is the language for design. When a programming language or environment has a geometry kernel at its core, we can unlock the possibilities for designing precise and robust models, automating design routines, and generating design iterations with algorithms. + +### The Basics +Geometry, traditionally defined, is the study of shape, size, relative position of figures, and the properties of space. This field has a rich history going back thousands of years. With the advent and popularization of the computer, we gained a powerful tool in defining, exploring, and generating geometry. It is now so easy to calculate the result of complex geometric interactions, the fact that we are doing so is almost transparent. + +![Stanford Bunny](images/5-1/StanfordBunny.png) +> If you're curious to see how diverse and complex geometry can get using the power of your computer, do a quick web search for the Stanford Bunny - a canonical model used to test algorithms. + +Understanding geometry in the context of algorithms, computing, and complexity, may sound daunting; however, there are a few key, and relatively simple, principles that we can establish as fundamentals to start building towards more advanced applications: + +1. Geometry is **Data** - to the computer and Dynamo, a Bunny not all that different from a number. +2. Geometry relies on **Abstraction** - fundamentally, geometric elements are described by numbers, relationships, and formulas within a given spatial coordinate system +3. Geometry has a **Hierarchy** - points come together to make lines, lines come together to make surfaces, and so on +4. Geometry simultaneously describes both **the Part and the Whole** - when we have a curve, it is both the shape as well as all the possible points along it + +In practice, these principles mean that we need to be aware of what we are working with (what type of geometry, how was it created, etc.) so that we can fluidly compose, decompose, and recompose different geometries as we develop more complex models. + +### Stepping through the Hierarchy +Let's take a moment to look at the relationship between the Abstract and Hierarchical descriptions of Geometry. Because these two concepts are related, but not always obvious at first, we can quickly arrive at a conceptual roadblock once we start developing deeper workflows or models. For starters, let's use dimensionality as an easy descriptor of the "stuff" we model. The number of dimensions required to describe a shape gives us a window into how Geometry is organized hierarchically. + +![Computational Geometry](images/5-1/GeometryDimensionality.png) +> 1. A **Point** (defined by coordinates) doesn't have any dimensions to it - it's just numbers describing each coordinate +2. A **Line** (defined by two points) now has *one* dimension - we can "walk" the line either forward (positive direction) or backward (negative direction) +3. A **Plane** (defined by two lines) has *two* dimensions - walking more left or more right is now possible +4. A **Box** (defined by two planes) has *three* dimensions - we can define a position relative to up or down + +Dimensionality is a convenient way to start categorizing Geometry but it's not necessarily the best. After all, we don't model with only Points, Lines, Planes, and Boxes - what if I want something curvy? Furthermore, there is a whole other category of Geometric types that are completely abstract ie. they define properties like orientation, volume, or relationships between parts. We can't really grab a hold of a Vector so how do we define it relative to what we see in space? A more detailed categorization of the geometric hierarchy should accommodate the difference between Abstract Types or "Helpers," each of which we can group by what they help do and types that help describe the shape of model elements. + +![Geometry Hierarchy](images/5-1/GeometryHierarchy.jpg) + +### Geometry in Dynamo Studio + +So what does this mean for using Dynamo? Understanding the Geometry types and how they are related will allow us to navigate the collection of **Geometry Nodes** available to us in the Library. The Geometry Nodes are organized alphabetically as opposed to hierarchically - here they are displayed similar to their layout in the Dynamo interface. + +![Geometry in Dynamo](images/5-1/GeometryOrganization2.png) + +Additionally, making models in Dynamo and connecting the preview of what we see in the Background Preview to the flow of data in our graph should become more intuitive over time. + + +![Geometry in Dynamo](images/5-1/GeometryInDynamo.png) +> 1. Note the assumed coordinate system rendered by the grid and colored axes +3. Selected Nodes will render the corresponding geometry (if the Node creates geometry) in the background the highlight color + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Geometry Overview.dyn](datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn). A full list of example files can be found in the Appendix. + +### Going Further with Geometry +Creating models in Dynamo is not limited to what we can generate with Nodes. Here are some key ways to take your process to the next level with Geometry: + +1. Dynamo allows you to import files - try using a CSV for point clouds or SAT for bringing in surfaces +2. When working with Revit, we can reference Revit elements to use in Dynamo +3. The Dynamo Package Manager offers additional functionality for extended geometry types and operations - check out the [Mesh Toolkit](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) package + diff --git a/05_Geometry-for-Computational-Design/5-2_vectors.md b/05_Geometry-for-Computational-Design/5-2_vectors.md index 7f401ebb..e7600544 100644 --- a/05_Geometry-for-Computational-Design/5-2_vectors.md +++ b/05_Geometry-for-Computational-Design/5-2_vectors.md @@ -1,67 +1,67 @@ -## Vectors, Planes, and Coordinate Systems -Vectors, Planes, and Coordinate Systems make up the primary group of Abstract Geometry Types. They help us define location, orientation, and the spatial context for other geometry that describe shapes. If I say that I'm in New York City at 42nd Street and Broadway (Coordinate System), standing on the street level (Plane), looking North (Vector), I've just used these "Helpers" to define where I am. The same goes for a phone case product or a skyscraper - we need this context to develop our model. - -![Vectors, Planes, and Coordinates](images/5-2/VectorsPlanesCoodinates.png) - - -### What's a Vector? - -A vector is a geometric quantity describing Direction and Magnitude. Vectors are abstract; ie. they represent a quantity, not a geometrical element. Vectors can be easily confused with Points because they both are composed of a list of values. There is a key difference though: Points describe a position in a given coordinate system while Vectors describe a relative difference in position which is the same as saying "direction." - -![Vector Details](images/5-2/Vector-Detailed.png) - -If the idea of relative difference is confusing, think of the Vector AB as "I'm standing at Point A, looking toward Point B." The direction, from here (A) to there (B), is our Vector. - -Breaking down Vectors further into their parts using the same AB notation: - -![Vector](images/5-2/Vector.png) -> 1. The **Start Point** of the Vector is called the **Base**. -2. The **End Point **of the Vector is called the **Tip** or the **Sense**. -3. Vector AB is not the same as Vector BA - that would point in the opposite direction. - -If you're ever in need of comic relief regarding Vectors (and their abstract definition), watch the classic comedy Airplane and listen for the oft-quoted tongue-in cheek line: - -> *Roger, Roger. What's our vector, Victor?* - -Vectors are a key component to our models in Dynamo. Note that, because they are in the Abstract category of "Helpers," when we create a Vector, we won't see anything in the Background Preview. - -![Vectors in Dynamo](images/5-2/Dynamo-Vector.png) -> 1. We can use a line as a stand in for a Vector preview. - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Vectors.dyn](datasets/5-2/Geometry for Computational Design - Vectors.dyn). A full list of example files can be found in the Appendix. - -### What's a Plane? - -Planes are two-dimensional abstract "Helpers." More specifically, Planes are conceptually “flat,” extending infinitely in two directions. Usually they are rendered as a smaller rectangle near their origin. - -![Plane](images/5-2/Plane.png) - -You might be thinking, "Wait! Origin? That sounds like a Coordinate System... like the one I use to model in my CAD software!" - -And you're correct! Most modeling software take advantage of construction planes or "levels" to define a local two-dimentional context to draft in. XY, XZ, YZ -or- North, Southeast, Plan might sound more familiar. These are all Planes, defining an infinite "flat" context. Planes don't have depth, but they do help us describe direction as well - each Plane has an Origin, X Direction, Y Direction, and a Z (Up) Direction. - -![Planes in Dynamo](images/5-2/Dynamo-Plane.png) -> 1. Although they are abstract, Planes do have an origin position so we can locate them in space. -2. In Dynamo, Planes are rendered in the Background Preview. - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Planes.dyn](datasets/5-2/Geometry for Computational Design - Plane.dyn). A full list of example files can be found in the Appendix. - -### What's a Coordinate System? - -If we are comfortable with Planes, we are a small step away from understanding Coordinate Systems. A Plane has all the same parts as a Coordinate System, provided it is a standard "Euclidean" or "XYZ" Coordinate System. - -There are other, however, alternative Coordinate Systems such as Cylindrical or Spherical. As we will see in later sections, Coordinate Systems can also be applied to other Geometry types to define a position on that geometry. - -![Coordinate System](images/5-2/CoordinateSystem.png) -> Add alternative coordinate systems - cylindrical, spherical - -![Planes in Dynamo](images/5-2/Dynamo-CoordinateSystem.png) - -> 1. Although they are abstract, Coordinate Systems also have an origin position so we can locate them in space. -2. In Dynamo, Coordinate Systems are rendered in the Background Preview as a point (origin) and lines defining the axes (X is red, Y is green, and Z is blue following convention). - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Coordinate System.dyn](datasets/5-2/Geometry for Computational Design - Coordinate System.dyn). A full list of example files can be found in the Appendix. - - - - +## Vectors, Planes, and Coordinate Systems +Vectors, Planes, and Coordinate Systems make up the primary group of Abstract Geometry Types. They help us define location, orientation, and the spatial context for other geometry that describe shapes. If I say that I'm in New York City at 42nd Street and Broadway (Coordinate System), standing on the street level (Plane), looking North (Vector), I've just used these "Helpers" to define where I am. The same goes for a phone case product or a skyscraper - we need this context to develop our model. + +![Vectors, Planes, and Coordinates](images/5-2/VectorsPlanesCoodinates.png) + + +### What's a Vector? + +A vector is a geometric quantity describing Direction and Magnitude. Vectors are abstract; ie. they represent a quantity, not a geometrical element. Vectors can be easily confused with Points because they both are composed of a list of values. There is a key difference though: Points describe a position in a given coordinate system while Vectors describe a relative difference in position which is the same as saying "direction." + +![Vector Details](images/5-2/Vector-Detailed.png) + +If the idea of relative difference is confusing, think of the Vector AB as "I'm standing at Point A, looking toward Point B." The direction, from here (A) to there (B), is our Vector. + +Breaking down Vectors further into their parts using the same AB notation: + +![Vector](images/5-2/Vector.png) +> 1. The **Start Point** of the Vector is called the **Base**. +2. The **End Point **of the Vector is called the **Tip** or the **Sense**. +3. Vector AB is not the same as Vector BA - that would point in the opposite direction. + +If you're ever in need of comic relief regarding Vectors (and their abstract definition), watch the classic comedy Airplane and listen for the oft-quoted tongue-in cheek line: + +> *Roger, Roger. What's our vector, Victor?* + +Vectors are a key component to our models in Dynamo. Note that, because they are in the Abstract category of "Helpers," when we create a Vector, we won't see anything in the Background Preview. + +![Vectors in Dynamo](images/5-2/Dynamo-Vector.png) +> 1. We can use a line as a stand in for a Vector preview. + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Vectors.dyn](datasets/5-2/Geometry for Computational Design - Vectors.dyn). A full list of example files can be found in the Appendix. + +### What's a Plane? + +Planes are two-dimensional abstract "Helpers." More specifically, Planes are conceptually “flat,” extending infinitely in two directions. Usually they are rendered as a smaller rectangle near their origin. + +![Plane](images/5-2/Plane.png) + +You might be thinking, "Wait! Origin? That sounds like a Coordinate System... like the one I use to model in my CAD software!" + +And you're correct! Most modeling software take advantage of construction planes or "levels" to define a local two-dimentional context to draft in. XY, XZ, YZ -or- North, Southeast, Plan might sound more familiar. These are all Planes, defining an infinite "flat" context. Planes don't have depth, but they do help us describe direction as well - each Plane has an Origin, X Direction, Y Direction, and a Z (Up) Direction. + +![Planes in Dynamo](images/5-2/Dynamo-Plane.png) +> 1. Although they are abstract, Planes do have an origin position so we can locate them in space. +2. In Dynamo, Planes are rendered in the Background Preview. + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Planes.dyn](datasets/5-2/Geometry for Computational Design - Plane.dyn). A full list of example files can be found in the Appendix. + +### What's a Coordinate System? + +If we are comfortable with Planes, we are a small step away from understanding Coordinate Systems. A Plane has all the same parts as a Coordinate System, provided it is a standard "Euclidean" or "XYZ" Coordinate System. + +There are other, however, alternative Coordinate Systems such as Cylindrical or Spherical. As we will see in later sections, Coordinate Systems can also be applied to other Geometry types to define a position on that geometry. + +![Coordinate System](images/5-2/CoordinateSystem.png) +> Add alternative coordinate systems - cylindrical, spherical + +![Planes in Dynamo](images/5-2/Dynamo-CoordinateSystem.png) + +> 1. Although they are abstract, Coordinate Systems also have an origin position so we can locate them in space. +2. In Dynamo, Coordinate Systems are rendered in the Background Preview as a point (origin) and lines defining the axes (X is red, Y is green, and Z is blue following convention). + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Coordinate System.dyn](datasets/5-2/Geometry for Computational Design - Coordinate System.dyn). A full list of example files can be found in the Appendix. + + + + diff --git a/05_Geometry-for-Computational-Design/5-3_points.md b/05_Geometry-for-Computational-Design/5-3_points.md index 243d7940..c27d28ea 100644 --- a/05_Geometry-for-Computational-Design/5-3_points.md +++ b/05_Geometry-for-Computational-Design/5-3_points.md @@ -1,28 +1,28 @@ -## Points -If Geometry is the language of a model, then Points are the alphabet. Points are the foundation upon which all other geometry is created - we need at least two Points to create a Curve, we need at least three Points to make a Polygon or a Mesh Face, and so on. Defining the position, order, and relationship among Points (try a Sine Function) allows us to define higher order geometry like things we recognize as Circles or Curves. - -![Point to Curve](images/5-3/PointsAsBuildingBlocks-1.png) ->1. A Circle using the functions ```x=r*cos(t)``` and ```y=r*sin(t)``` -2. A Sine Curve using the functions ```x=(t)``` and ```y=r*sin(t)``` -### What's a Point? -A Point is defined by nothing more than one or more values called coordinates. How many coordinate values we need to define the Point depends upon the Coordinate System or context in which it resides. The most common kind of Point in Dynamo exists in our three-dimensional World Coordinate System and has three coordinates [X,Y,Z]. - -![Point](images/5-3/Point.png) - -### Point as Coordinates -Points can exist in a two-dimensional Coordinate System as well. Convention has different letter notation depending upon what kind of space we are working with - we might be using [X,Y] on a Plane or [U,V] if we are on a surface. - -![Point as Coordinates](images/5-3/Coordinates.png) -> 1. A Point in Euclidean Coordinate System: [X,Y,Z] -2. A Point in a Curve Parameter Coordinate System: [t] -3. A Point in a Surface Parameter Coordinate System: [U,V] - -Although it might seem counter intuitive, Parameters for both Curves and Surfaces are continuous and extend beyond the edge of the given geometry. Since the shapes that define the Parameter Space reside in a three-dimensional World Coordinate System, we can always translate a Parametric Coordinate into a "World" Coordinate. The point [0.2, 0.5] on the surface for example is the same as point [1.8, 2.0, 4.1] in world coordinates. - - -![Points in Dynamo](images/5-3/Dynamo-Points.png) -> 1. Point in assumed World XYZ Coordinates -2. Point relative to a given Coordinate System (Cylindrical) -3. Point as UV Coordinate on a Surface - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Points.dyn](datasets/5-3/Geometry for Computational Design - Points.dyn). A full list of example files can be found in the Appendix. +## Points +If Geometry is the language of a model, then Points are the alphabet. Points are the foundation upon which all other geometry is created - we need at least two Points to create a Curve, we need at least three Points to make a Polygon or a Mesh Face, and so on. Defining the position, order, and relationship among Points (try a Sine Function) allows us to define higher order geometry like things we recognize as Circles or Curves. + +![Point to Curve](images/5-3/PointsAsBuildingBlocks-1.png) +>1. A Circle using the functions ```x=r*cos(t)``` and ```y=r*sin(t)``` +2. A Sine Curve using the functions ```x=(t)``` and ```y=r*sin(t)``` +### What's a Point? +A Point is defined by nothing more than one or more values called coordinates. How many coordinate values we need to define the Point depends upon the Coordinate System or context in which it resides. The most common kind of Point in Dynamo exists in our three-dimensional World Coordinate System and has three coordinates [X,Y,Z]. + +![Point](images/5-3/Point.png) + +### Point as Coordinates +Points can exist in a two-dimensional Coordinate System as well. Convention has different letter notation depending upon what kind of space we are working with - we might be using [X,Y] on a Plane or [U,V] if we are on a surface. + +![Point as Coordinates](images/5-3/Coordinates.png) +> 1. A Point in Euclidean Coordinate System: [X,Y,Z] +2. A Point in a Curve Parameter Coordinate System: [t] +3. A Point in a Surface Parameter Coordinate System: [U,V] + +Although it might seem counter intuitive, Parameters for both Curves and Surfaces are continuous and extend beyond the edge of the given geometry. Since the shapes that define the Parameter Space reside in a three-dimensional World Coordinate System, we can always translate a Parametric Coordinate into a "World" Coordinate. The point [0.2, 0.5] on the surface for example is the same as point [1.8, 2.0, 4.1] in world coordinates. + + +![Points in Dynamo](images/5-3/Dynamo-Points.png) +> 1. Point in assumed World XYZ Coordinates +2. Point relative to a given Coordinate System (Cylindrical) +3. Point as UV Coordinate on a Surface + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Points.dyn](datasets/5-3/Geometry for Computational Design - Points.dyn). A full list of example files can be found in the Appendix. diff --git a/05_Geometry-for-Computational-Design/5-4_curves.md b/05_Geometry-for-Computational-Design/5-4_curves.md index 62e01c7e..6c435ab6 100644 --- a/05_Geometry-for-Computational-Design/5-4_curves.md +++ b/05_Geometry-for-Computational-Design/5-4_curves.md @@ -1,65 +1,65 @@ -## Curves -Curves are the first Geometric Data Type we've covered that have a more familiar set of shape descriptive properties - How curvey or straight? How long or short? And remember that Points are still our building blocks for defining anything from a line to a spline and all the Curve types in between. - -![Curve Types](images/5-4/CurveTypes.png) -> 1. Line -2. Polyline -3. Arc -4. Circle -5. Ellipse -6. NURBS Curve -7. Polycurve - -### What's a Curve? -The term **Curve** is generally a catch-all for all different sort of curved (even if straight) shapes. Capital "C" Curve is the parent categorization for all of those shape types - Lines, Circles, Splines, etc. More technically, a Curve describes every possible Point that can be found by inputting "t" into a collection of functions, which may range from the simple (```x = -1.26*t, y = t```) to functions involving calculus. No matter what kind of Curve we are working with, this **Parameter** called "t" is a property we can evaluate. Furthermore, regardless of the look of the shape, all Curves also have a start point and end point, which coincidentally align with the minimum and maximum t values used to create the Curve. This also helps us understand its directionality. - -![Curve Parameter](images/5-4/CurveParameter.png) -> It's important to note that Dynamo assumes that the domain of "t" values for a Curve is understood to be 0.0 to 1.0. - -All Curves also possess a number of properties or characteristics which can be used to describe or analyze them. When the distance between the start and end points is zero, the curve is "closed." Also, every curve has a number of control-points, if all these points are located in the same plane, the curve is "planar." Some properties apply to the curve as a whole, while others only apply to specific points along the curve. For example, planarity is a global property while a tangent vector at a given t value are a local property. - -### Lines -**Lines** are the simplest form of Curves. They may not look curvy but they are in fact Curves - just without any curvature. There are a few different ways to create Lines, the most intuitive being from Point A to Point B. The shape of the Line AB will be drawn between the points but mathematically it extends infinitely in both directions. - -![Line](images/5-4/Line.png) - -When we connect two Lines together, we have a **Polyline**. Here we have a straightforward representation of what a Control Point is. Editing any of these point locations will change the shape of the Polyline. If the Polyline is closed, we have a Polygon. If the Polygon's edge lengths are all equal, it is described as regular. - -![Polyline + Polygon](images/5-4/Polyline.jpg) - -### Arcs, Circles, Ellipse Arcs, and Ellipses -As we add more complexity to the Parametric Functions that define a shape, we can take one step further from a Line to create an **Arc**, **Circle**, **Ellipse Arc**, or **Ellipse** by describing one or two radii. The differences between the Arc version and the Circle or Ellipse is only whether or not the shape is closed. - -![Arcs + Circles](images/5-4/Arcs+Circles.png) - -### NURBS + Polycurves -**NURBS** (Non-uniform Rational Basis Splines) are mathematical representations that can accurately model any shape from a simple two dimensional Line, Circle, Arc, or Rectangle to the most complex three-dimensional free-form organic Curve. Because of their flexibility (relatively few control points, yet smooth interpolation based on Degree settings) and precision (bound by a robust math), NURBS models can be used in any process from illustration and animation to manufacturing. - -![NURBS Curve](images/5-4/NURBScurve.png) - -**Degree**: The Degree of the Curve determines the range of influence the Control Points have on a Curve; where the higher the degree, the larger the range. The Degree is a positive whole number. This number is usually 1, 2, 3 or 5, but can be any positive whole number. NURBS lines and polylines are usually Degree 1 and most free-form Curves are Degree 3 or 5. - -**Control Points**: The Control Points are a list of at least Degree+1 Points. One of the easiest ways to change the shape of a NURBS Curve is to move its Control Points. - -**Weight**: Control Points have an associated number called a Weight. Weights are usually positive numbers. When a Curve’s Control Points all have the same weight (usually 1), the Curve is called non-rational, otherwise the Curve is called rational. Most NURBS curves are non-rational. - -**Knots**: Knots are a list of (Degree+N-1) numbers, where N is the number of Control Points. The Knots are used together with the weights to control the influence of the Control Points on the resulting Curve. One use for Knots is to create kinks at certain points in the curve. - -![NURBS Curve Degree](images/5-4/NURBScurve_Degree.png) -> 1. Degree = 1 -2. Degree = 2 -3. Degree = 3 - -Note that the higher the degree value, the more Control Points are used to interpolate the resulting Curve. - -Let's make a sine curve in Dynamo using two different methods to create NURBS Curves to compare the results. - - -![NURBS in Dynamo](images/5-4/Dynamo_Curves.png) -> 1. *NurbsCurve.ByControlPoints* uses the List of Points as Control Points -2. *NurbsCurve.ByPoints* draws a Curve through the List of Points - ->Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Curves.dyn](datasets/5-4/Geometry for Computational Design - Curves.dyn). A full list of example files can be found in the Appendix. - - - +## Curves +Curves are the first Geometric Data Type we've covered that have a more familiar set of shape descriptive properties - How curvey or straight? How long or short? And remember that Points are still our building blocks for defining anything from a line to a spline and all the Curve types in between. + +![Curve Types](images/5-4/CurveTypes.png) +> 1. Line +2. Polyline +3. Arc +4. Circle +5. Ellipse +6. NURBS Curve +7. Polycurve + +### What's a Curve? +The term **Curve** is generally a catch-all for all different sort of curved (even if straight) shapes. Capital "C" Curve is the parent categorization for all of those shape types - Lines, Circles, Splines, etc. More technically, a Curve describes every possible Point that can be found by inputting "t" into a collection of functions, which may range from the simple (```x = -1.26*t, y = t```) to functions involving calculus. No matter what kind of Curve we are working with, this **Parameter** called "t" is a property we can evaluate. Furthermore, regardless of the look of the shape, all Curves also have a start point and end point, which coincidentally align with the minimum and maximum t values used to create the Curve. This also helps us understand its directionality. + +![Curve Parameter](images/5-4/CurveParameter.png) +> It's important to note that Dynamo assumes that the domain of "t" values for a Curve is understood to be 0.0 to 1.0. + +All Curves also possess a number of properties or characteristics which can be used to describe or analyze them. When the distance between the start and end points is zero, the curve is "closed." Also, every curve has a number of control-points, if all these points are located in the same plane, the curve is "planar." Some properties apply to the curve as a whole, while others only apply to specific points along the curve. For example, planarity is a global property while a tangent vector at a given t value are a local property. + +### Lines +**Lines** are the simplest form of Curves. They may not look curvy but they are in fact Curves - just without any curvature. There are a few different ways to create Lines, the most intuitive being from Point A to Point B. The shape of the Line AB will be drawn between the points but mathematically it extends infinitely in both directions. + +![Line](images/5-4/Line.png) + +When we connect two Lines together, we have a **Polyline**. Here we have a straightforward representation of what a Control Point is. Editing any of these point locations will change the shape of the Polyline. If the Polyline is closed, we have a Polygon. If the Polygon's edge lengths are all equal, it is described as regular. + +![Polyline + Polygon](images/5-4/Polyline.jpg) + +### Arcs, Circles, Ellipse Arcs, and Ellipses +As we add more complexity to the Parametric Functions that define a shape, we can take one step further from a Line to create an **Arc**, **Circle**, **Ellipse Arc**, or **Ellipse** by describing one or two radii. The differences between the Arc version and the Circle or Ellipse is only whether or not the shape is closed. + +![Arcs + Circles](images/5-4/Arcs+Circles.png) + +### NURBS + Polycurves +**NURBS** (Non-uniform Rational Basis Splines) are mathematical representations that can accurately model any shape from a simple two dimensional Line, Circle, Arc, or Rectangle to the most complex three-dimensional free-form organic Curve. Because of their flexibility (relatively few control points, yet smooth interpolation based on Degree settings) and precision (bound by a robust math), NURBS models can be used in any process from illustration and animation to manufacturing. + +![NURBS Curve](images/5-4/NURBScurve.png) + +**Degree**: The Degree of the Curve determines the range of influence the Control Points have on a Curve; where the higher the degree, the larger the range. The Degree is a positive whole number. This number is usually 1, 2, 3 or 5, but can be any positive whole number. NURBS lines and polylines are usually Degree 1 and most free-form Curves are Degree 3 or 5. + +**Control Points**: The Control Points are a list of at least Degree+1 Points. One of the easiest ways to change the shape of a NURBS Curve is to move its Control Points. + +**Weight**: Control Points have an associated number called a Weight. Weights are usually positive numbers. When a Curve’s Control Points all have the same weight (usually 1), the Curve is called non-rational, otherwise the Curve is called rational. Most NURBS curves are non-rational. + +**Knots**: Knots are a list of (Degree+N-1) numbers, where N is the number of Control Points. The Knots are used together with the weights to control the influence of the Control Points on the resulting Curve. One use for Knots is to create kinks at certain points in the curve. + +![NURBS Curve Degree](images/5-4/NURBScurve_Degree.png) +> 1. Degree = 1 +2. Degree = 2 +3. Degree = 3 + +Note that the higher the degree value, the more Control Points are used to interpolate the resulting Curve. + +Let's make a sine curve in Dynamo using two different methods to create NURBS Curves to compare the results. + + +![NURBS in Dynamo](images/5-4/Dynamo_Curves.png) +> 1. *NurbsCurve.ByControlPoints* uses the List of Points as Control Points +2. *NurbsCurve.ByPoints* draws a Curve through the List of Points + +>Download the example file that accompanies this image (Right click and "Save Link As..."): [Geometry for Computational Design - Curves.dyn](datasets/5-4/Geometry for Computational Design - Curves.dyn). A full list of example files can be found in the Appendix. + + + diff --git a/05_Geometry-for-Computational-Design/5-5_surfaces.md b/05_Geometry-for-Computational-Design/5-5_surfaces.md index f61fa0c3..60987e01 100644 --- a/05_Geometry-for-Computational-Design/5-5_surfaces.md +++ b/05_Geometry-for-Computational-Design/5-5_surfaces.md @@ -1,70 +1,70 @@ -## Surfaces -As we move from using Curves to using Surfaces in a model, we can now begin to represent objects we see in our three dimensional world. While Curves are not always planar ie. they are three dimensional, the space they define is always bound to one dimension. Surfaces give us another dimension and a collection of additional properties we can use within other modeling operations. - -### What's a Surface? -A Surface is a mathematical shape defined by a function and two parameters, Instead of ```t``` for Curves, we use ```U``` and ```V``` to describe the corresponding parameter space. This means we have more geometrical data to draw from when working with this type of Geometry. For example, Curves have tangent vectors and normal planes (which can rotate or twist along the curve's length), whereas Surfaces have normal vectors and tangent planes that will be consistent in their orientation. - -![Surface](images/5-5/Surface.png) -> 1. Surface -2. U Isocurve -3. V Isocurve -4. UV Coordinate -5. Perpendicular Plane -6. Normal Vector - -**Surface Domain**: A surface domain is defined as the range of (U,V) parameters that evaluate into a three dimensional point on that surface. The domain in each dimension (U or V) is usually described as two numbers (U Min to U Max) and (V Min to V Max). - -![Surface](images/5-5/SurfaceParameter.png) - -Although the shape of the Surface by not look "rectangular" and it locally may have a tighter or looser set of isocurves, the "space" defined by its domain is always two dimensional. In Dynamo, Surfaces are always understood to have a domain defined by a minimum of 0.0 and maximum of 1.0 in both U and V directions. Planar or trimmed Surfaces may have different domains. - -**Isocurve** (or Isoparametric Curve): A curve defined by a constant U or V value on the surface and a domain of values for the corresponding other U or V direction. - -**UV Coordinate**: The Point in UV Parameter Space defined by U, V, and sometimes W. - -![Surface Coordinate](images/5-5/SurfaceCoordinate.png) - -**Perpendicular Plane**: A Plane that is perpendicular to both U and V Isocurves at a given UV Coordinate. - -**Normal Vector**: A Vector defining the direction of "up" relative to the Perpendicular Plane. - - -### NURBS Surfaces -**NURBS Surfaces** are very similar to NURBS curves. You can think of NURBS Surfaces as a grid of NURBS Curves that go in two directions. The shape of a NURBS Surface is defined by a number of control points and the degree of that surface in the U and V directions. The same algorithms are used to calculate shape, normals, tangents, curvatures and other properties by way of control points, weights and degree. - - -![NURBS Surface](images/5-5/NURBSsurface.png) - -In the case of NURBS surfaces, there are two directions implied by the geometry, because NURBS surfaces are, regardless of the shape we see, rectangular grids of control points. And even though these directions are often arbitrary relative to the world coordinate system, we will use them frequently to analyze our models or generate other geometry based on the Surface. - -![NURBS Surface](images/5-5/NURBSsurface-Degree.jpg) -> 1. Degree (U,V) = (3,3) -2. Degree (U,V) = (3,1) -3. Degree (U,V) = (1,2) -4. Degree (U,V) = (1,1) - -### Polysurfaces -**Polysurfaces** are composed of Surfaces that are joined across an edge. Polysurfaces offer more than two dimensional UV definition in that we can now move through the connected shapes by way of their Topology. - ->While "Topology" generally describes a concept around how parts are connected and/or related Topology in Dynamo is also a type of Geometry. Specifically it is a parent category for Surfaces, Polysurfaces, and Solids. - -![PolySurface](images/5-5/PolySurface.png) - -Sometimes called patches, joining Surfaces in this manner allows us to make more complex shapes as well as define detail across the seam. Conveniently we can apply a fillet or chamfer operation to the edges of a Polysurface. - -Let's import and evaluate a Surface at a Parameter in Dynamo to see what kind of information we can extract. - - - -![Surfaces in Dynamo](images/5-5/Dynamo_Surfaces.png) -> 1. *Surface.PointAtParameter* returns the Point at a given UV Coordinate -2. *Surface.NormalAtParameter* returns the Normal Vector at a given UV Coordinate -3. *Surface.GetIsoline* returns the Isoparametric Curve at a U or V Coordinate - note the isoDirection input. - ->Download the example files that accompanies this image (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Geometry for Computational Design - Surfaces.dyn](datasets/5-5/Geometry for Computational Design - Surfaces.dyn) -2. [Surface.sat](datasets/5-5/Surface.sat) - - - - +## Surfaces +As we move from using Curves to using Surfaces in a model, we can now begin to represent objects we see in our three dimensional world. While Curves are not always planar ie. they are three dimensional, the space they define is always bound to one dimension. Surfaces give us another dimension and a collection of additional properties we can use within other modeling operations. + +### What's a Surface? +A Surface is a mathematical shape defined by a function and two parameters, Instead of ```t``` for Curves, we use ```U``` and ```V``` to describe the corresponding parameter space. This means we have more geometrical data to draw from when working with this type of Geometry. For example, Curves have tangent vectors and normal planes (which can rotate or twist along the curve's length), whereas Surfaces have normal vectors and tangent planes that will be consistent in their orientation. + +![Surface](images/5-5/Surface.png) +> 1. Surface +2. U Isocurve +3. V Isocurve +4. UV Coordinate +5. Perpendicular Plane +6. Normal Vector + +**Surface Domain**: A surface domain is defined as the range of (U,V) parameters that evaluate into a three dimensional point on that surface. The domain in each dimension (U or V) is usually described as two numbers (U Min to U Max) and (V Min to V Max). + +![Surface](images/5-5/SurfaceParameter.png) + +Although the shape of the Surface by not look "rectangular" and it locally may have a tighter or looser set of isocurves, the "space" defined by its domain is always two dimensional. In Dynamo, Surfaces are always understood to have a domain defined by a minimum of 0.0 and maximum of 1.0 in both U and V directions. Planar or trimmed Surfaces may have different domains. + +**Isocurve** (or Isoparametric Curve): A curve defined by a constant U or V value on the surface and a domain of values for the corresponding other U or V direction. + +**UV Coordinate**: The Point in UV Parameter Space defined by U, V, and sometimes W. + +![Surface Coordinate](images/5-5/SurfaceCoordinate.png) + +**Perpendicular Plane**: A Plane that is perpendicular to both U and V Isocurves at a given UV Coordinate. + +**Normal Vector**: A Vector defining the direction of "up" relative to the Perpendicular Plane. + + +### NURBS Surfaces +**NURBS Surfaces** are very similar to NURBS curves. You can think of NURBS Surfaces as a grid of NURBS Curves that go in two directions. The shape of a NURBS Surface is defined by a number of control points and the degree of that surface in the U and V directions. The same algorithms are used to calculate shape, normals, tangents, curvatures and other properties by way of control points, weights and degree. + + +![NURBS Surface](images/5-5/NURBSsurface.png) + +In the case of NURBS surfaces, there are two directions implied by the geometry, because NURBS surfaces are, regardless of the shape we see, rectangular grids of control points. And even though these directions are often arbitrary relative to the world coordinate system, we will use them frequently to analyze our models or generate other geometry based on the Surface. + +![NURBS Surface](images/5-5/NURBSsurface-Degree.jpg) +> 1. Degree (U,V) = (3,3) +2. Degree (U,V) = (3,1) +3. Degree (U,V) = (1,2) +4. Degree (U,V) = (1,1) + +### Polysurfaces +**Polysurfaces** are composed of Surfaces that are joined across an edge. Polysurfaces offer more than two dimensional UV definition in that we can now move through the connected shapes by way of their Topology. + +>While "Topology" generally describes a concept around how parts are connected and/or related Topology in Dynamo is also a type of Geometry. Specifically it is a parent category for Surfaces, Polysurfaces, and Solids. + +![PolySurface](images/5-5/PolySurface.png) + +Sometimes called patches, joining Surfaces in this manner allows us to make more complex shapes as well as define detail across the seam. Conveniently we can apply a fillet or chamfer operation to the edges of a Polysurface. + +Let's import and evaluate a Surface at a Parameter in Dynamo to see what kind of information we can extract. + + + +![Surfaces in Dynamo](images/5-5/Dynamo_Surfaces.png) +> 1. *Surface.PointAtParameter* returns the Point at a given UV Coordinate +2. *Surface.NormalAtParameter* returns the Normal Vector at a given UV Coordinate +3. *Surface.GetIsoline* returns the Isoparametric Curve at a U or V Coordinate - note the isoDirection input. + +>Download the example files that accompanies this image (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Geometry for Computational Design - Surfaces.dyn](datasets/5-5/Geometry for Computational Design - Surfaces.dyn) +2. [Surface.sat](datasets/5-5/Surface.sat) + + + + diff --git a/05_Geometry-for-Computational-Design/5-6_solids.md b/05_Geometry-for-Computational-Design/5-6_solids.md index 1f09845c..85d5ff52 100644 --- a/05_Geometry-for-Computational-Design/5-6_solids.md +++ b/05_Geometry-for-Computational-Design/5-6_solids.md @@ -1,74 +1,74 @@ -## Solids -If we want to construct more complex models that cannot be created from a single surface or if we want to define an explicit volume, we must now venture into the realm of Solids (and Polysurfaces). Even a simple cube is complex enough to need six surfaces, one per face. Solids give access to two key concepts that Surfaces do not - a more refined topological description (faces, edges, vertices) and Boolean operations. - -### What's a Solid? -Solids consist of one or more Surfaces that contain volume by way of a closed boundary that defines "in" or "out." Regardless of how many of these Surfaces there are, they must form a "watertight" volume to be considered a Solid. Solids can be created by joining Surfaces or Polysurfaces together or by using operations such as loft, sweep, and revolve. Sphere, Cube, Cone and Cylinder primitives are also Solids. A Cube with at least one face removed counts as a Polysurface, which has some similar properties, but it is not a Solid. - -![Solids](images/5-6/Primitives.png) -> 1. A Plane is made of a single Surface and is not a Solid. -2. A Sphere is made of one Surface but *is* a Solid. -3. A Cone is made of two surfaces joined together to make a Solid. -4. A Cylinder is made of three surfaces joined together to make a Solid. -5. A Cube is made of six surfaces joined together to make a Solid. - -### Topology -Solids are made up of three types of elements: Vertices, Edges, and Faces. Faces are the surfaces that make up the Solid. Edges are the Curves that define the connection between adjacent faces, and vertices are the start and end points of those Curves. These elements can be queried using the Topology nodes. - -![Topology](images/5-6/Solid-topology.png) - ->1. Faces -2. Edges -3. Vertices - -### Operations -Solids can be modified by filleting or chamfering their edges to eliminate sharp corners and angles. The chamfer operation creates a ruled surface between two faces, while a fillet blends between faces to maintain tangency. -![](images/5-6/SolidOperations.png) ->1. Solid Cube -2. Chamfered Cube -3. Filleted Cube - -### Boolean Operations -Solid Boolean operations are methods for combining two or more Solids. A single Boolean operation actually means performing four operations: -1. **Intersect** two or more objects. -2. **Split** them at the intersections. -3. **Delete** unwanted portions of the geometry. -4. **Join** everything back together. - -This makes Solid Booleans a powerful time-saving process. There are three Solid Boolean operations that distinguish which parts of the geometry are kept. -![Solid Boolean](images/5-6/SolidBooleans.png) -> 1. **Union:** Remove the overlapping portions of the Solids and join them into a single Solid. -2. **Difference:** Subtract one Solid from another. The Solid to be subtracted is referred to as a tool. Note that you could switch which Solid is the tool to keep the inverse volume. -3. **Intersection:** Keep only the intersecting volume of the two Solids. - -In addition to these three operations, Dynamo has **Solid.DifferenceAll** and **Solid.UnionAll** nodes for performing difference and union operations with multiple Solids. -![](images/5-6/BooleanAll.png) -> 1. **UnionAll:** Union operation with sphere and outward-facing cones -2. **DifferenceAll:** Difference operation with sphere and inward-facing cones - -Let's use a few Boolean operations to create a spiky ball. - -![](images/5-6/spikyBallExample.png) -> 1. **Sphere.ByCenterPointRadius**: Create the base Solid. -2. **Topology.Faces**, **Face.SurfaceGeometry**: Query the faces of the Solid and convert to surface geometry—in this case, the Sphere has only one Face. -3. **Cone.ByPointsRadii**: Construct cones using points on the surface. -4. **Solid.UnionAll**: Union the Cones and the Sphere. -5. **Topology.Edges**: Query the edges of the new Solid -6. **Solid.Fillet**: Fillet the Edges of the spiky ball - -> Download the example files that accompany this image (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Geometry for Computational Design - Solids.dyn](datasets/5-6/Geometry for Computational Design - Solids.dyn) - -### Freezing -Boolean operations are complex and can be slow to calculate. Use Freeze functionality to suspend the execution of selected nodes and affected downstream nodes. - -![Freezing](images/5-6/freeze-01.png) -> Use the right-click contextual menu to Freeze the Solid Union operation - -![Freezing](images/5-6/freeze-02.png) -> The selected node and all downstream nodes will preview in a light grey ghosted mode, and affected wires will be displayed as dashed lines. The affected geometry preview will also be ghosted. You can now change values upstream without calculating the boolean union. - -![Freezing](images/5-6/freeze-03.png) -> To unfreeze the nodes, right-click and uncheck Freeze. - -![Freezing](images/5-6/freeze-04.png) -> All affected nodes and associated geometry previews will update and revert to the standard preview mode. - +## Solids +If we want to construct more complex models that cannot be created from a single surface or if we want to define an explicit volume, we must now venture into the realm of Solids (and Polysurfaces). Even a simple cube is complex enough to need six surfaces, one per face. Solids give access to two key concepts that Surfaces do not - a more refined topological description (faces, edges, vertices) and Boolean operations. + +### What's a Solid? +Solids consist of one or more Surfaces that contain volume by way of a closed boundary that defines "in" or "out." Regardless of how many of these Surfaces there are, they must form a "watertight" volume to be considered a Solid. Solids can be created by joining Surfaces or Polysurfaces together or by using operations such as loft, sweep, and revolve. Sphere, Cube, Cone and Cylinder primitives are also Solids. A Cube with at least one face removed counts as a Polysurface, which has some similar properties, but it is not a Solid. + +![Solids](images/5-6/Primitives.png) +> 1. A Plane is made of a single Surface and is not a Solid. +2. A Sphere is made of one Surface but *is* a Solid. +3. A Cone is made of two surfaces joined together to make a Solid. +4. A Cylinder is made of three surfaces joined together to make a Solid. +5. A Cube is made of six surfaces joined together to make a Solid. + +### Topology +Solids are made up of three types of elements: Vertices, Edges, and Faces. Faces are the surfaces that make up the Solid. Edges are the Curves that define the connection between adjacent faces, and vertices are the start and end points of those Curves. These elements can be queried using the Topology nodes. + +![Topology](images/5-6/Solid-topology.png) + +>1. Faces +2. Edges +3. Vertices + +### Operations +Solids can be modified by filleting or chamfering their edges to eliminate sharp corners and angles. The chamfer operation creates a ruled surface between two faces, while a fillet blends between faces to maintain tangency. +![](images/5-6/SolidOperations.png) +>1. Solid Cube +2. Chamfered Cube +3. Filleted Cube + +### Boolean Operations +Solid Boolean operations are methods for combining two or more Solids. A single Boolean operation actually means performing four operations: +1. **Intersect** two or more objects. +2. **Split** them at the intersections. +3. **Delete** unwanted portions of the geometry. +4. **Join** everything back together. + +This makes Solid Booleans a powerful time-saving process. There are three Solid Boolean operations that distinguish which parts of the geometry are kept. +![Solid Boolean](images/5-6/SolidBooleans.png) +> 1. **Union:** Remove the overlapping portions of the Solids and join them into a single Solid. +2. **Difference:** Subtract one Solid from another. The Solid to be subtracted is referred to as a tool. Note that you could switch which Solid is the tool to keep the inverse volume. +3. **Intersection:** Keep only the intersecting volume of the two Solids. + +In addition to these three operations, Dynamo has **Solid.DifferenceAll** and **Solid.UnionAll** nodes for performing difference and union operations with multiple Solids. +![](images/5-6/BooleanAll.png) +> 1. **UnionAll:** Union operation with sphere and outward-facing cones +2. **DifferenceAll:** Difference operation with sphere and inward-facing cones + +Let's use a few Boolean operations to create a spiky ball. + +![](images/5-6/spikyBallExample.png) +> 1. **Sphere.ByCenterPointRadius**: Create the base Solid. +2. **Topology.Faces**, **Face.SurfaceGeometry**: Query the faces of the Solid and convert to surface geometry—in this case, the Sphere has only one Face. +3. **Cone.ByPointsRadii**: Construct cones using points on the surface. +4. **Solid.UnionAll**: Union the Cones and the Sphere. +5. **Topology.Edges**: Query the edges of the new Solid +6. **Solid.Fillet**: Fillet the Edges of the spiky ball + +> Download the example files that accompany this image (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Geometry for Computational Design - Solids.dyn](datasets/5-6/Geometry for Computational Design - Solids.dyn) + +### Freezing +Boolean operations are complex and can be slow to calculate. Use Freeze functionality to suspend the execution of selected nodes and affected downstream nodes. + +![Freezing](images/5-6/freeze-01.png) +> Use the right-click contextual menu to Freeze the Solid Union operation + +![Freezing](images/5-6/freeze-02.png) +> The selected node and all downstream nodes will preview in a light grey ghosted mode, and affected wires will be displayed as dashed lines. The affected geometry preview will also be ghosted. You can now change values upstream without calculating the boolean union. + +![Freezing](images/5-6/freeze-03.png) +> To unfreeze the nodes, right-click and uncheck Freeze. + +![Freezing](images/5-6/freeze-04.png) +> All affected nodes and associated geometry previews will update and revert to the standard preview mode. + diff --git a/05_Geometry-for-Computational-Design/5-7_meshes.md b/05_Geometry-for-Computational-Design/5-7_meshes.md index d00b3963..ed0d88df 100644 --- a/05_Geometry-for-Computational-Design/5-7_meshes.md +++ b/05_Geometry-for-Computational-Design/5-7_meshes.md @@ -1,79 +1,79 @@ -## Meshes -In the field of computational modeling, Meshes are one of the most pervasive forms of representing 3D geometry. Mesh geometry can be a light-weight and flexible alternative to working with NURBS, and Meshes are used in everything from rendering and visualizations to digital fabrication and 3D printing. - -### What's a Mesh? -A Mesh is a collection of quadrilaterals and triangles that represents a surface or solid geometry. Like Solids, the structure of a Mesh object includes vertices, edges, and faces. There are additional properties that make Meshes unique as well, such as normals. - -![Mesh Elements](images/5-7/MeshElements2.png) - -> 1. Mesh vertices -2. Mesh edges *Edges with only one adjoining face are called "Naked." All other edges are "Clothed" -3. Mesh faces - -### Mesh Elements -Dynamo defines Meshes using a Face-Vertex data structure. At its most basic level, this structure is simply a collection of points which are grouped into polygons. The points of a Mesh are called vertices, while the surface-like polygons are called faces. To create a Mesh we need a list of vertices and a system of grouping those vertices into faces called an index group. - -![](images/5-7/meshFacesVertices.png) - -> 1. List of vertices -2. List of index groups to define faces - -####Vertices + Vertex Normals -The vertices of a Mesh are simply a list of points. The index of the vertices is very important when constructing a Mesh, or getting information about the structure of a Mesh. For each vertex, there is also a corresponding vertex normal (vector) which describes the average direction of the attached faces and helps us understand the "in" and "out" orientation of the Mesh. - -![Vertices + Normals](images/5-7/vertexNormals.png) - ->1. Vertices -2. Vertex Normals - - -####Faces -A face is an ordered list of three or four vertices. The “surface” representation of a Mesh face is therefore implied according to the position of the vertices being indexed. We already have the list of vertices that make up the Mesh, so instead of providing individual points to define a face, we simply use the index of the vertices. This also allows us to use the same vertex in more than one face. - -![](images/5-7/meshFaces.png) - -> 1. A quad face made with indices 0, 1, 2, and 3 -2. A triangle face made with indices 1, 4, and 2 -Note that the index groups can be shifted in their order - as long as the sequence is ordered in a counter-clockwise manner, the face will be defined correctly - -### Meshes versus NURBS Surfaces -How is Mesh geometry different from NURBS geometry? When might you want to use one instead of the other? - -####Parameterization - -In a previous chapter, we saw that NURBS surfaces are defined by a series of NURBS curves going in two directions. These directions are labeled ``U`` and ``V``, and allow a NURBs surface to be parameterized according to a two-dimensional surface domain. The curves themselves are stored as equations in the computer, allowing the resulting surfaces to be calculated to an arbitrarily small degree of precision. It can be difficult, however, to combine multiple NURBS surfaces together. Joining two NURBS surfaces will result in a polysurface, where different sections of the geometry will have different UV parameters and curve definitions. - -![Control Points](images/5-7/NURBSvsMESH-01.jpg) -> 1. Surface -2. Isoparametric (Isoparm) Curve -3. Surface Control Point -4. Surface Control Polygon -5. Isoparametric Point -6. Surface Frame -7. Mesh -8. Naked Edge -9. Mesh Network -10. Mesh Edges -11. Vertex Normal -12. Mesh Face / Mesh Face Normal - -Meshes, on the other hand, are comprised of a discrete number of exactly defined vertices and faces. The network of vertices generally cannot be defined by simple ``UV`` coordinates, and because the faces are discrete the amount of precision is built into the Mesh and can only be changed by refining the Mesh and adding more faces. The lack of mathematical descriptions allows Meshes to more flexibly handle complex geometry within a single Mesh. - - -###Local versus Global Influence - -Another important difference is the extent to which a local change in Mesh or NURBS geometry affects the entire form. Moving one vertex of a Mesh only affects the faces that are adjacent to that vertex. In NURBS surfaces, the extent of the influence is more complicated and depends on the degree of the surface as well as the weights and knots of the control points. In general, however, moving a single control point in a NURBS surface creates a smoother, more extensive change in geometry. - -![Editing](images/5-7/NURBSvsMESH-02.jpg) - -> 1. NURBS Surface - moving a control point has influence that extends across the shape -2. Mesh geometry - moving a vertex has influence only on adjacent elements - -One analogy that can be helpful is to compare a vector image (composed of lines and curves) with a raster image (composed of individual pixels). If you zoom into a vector image, the curves remain crisp and clear, while zooming into a raster image results in seeing individual pixels become larger. In this analogy, NURBS surfaces can be compared to a vector image because there is a smooth mathematical relationship, while a Mesh behaves similarly to a raster image with a set resolution. - -### Mesh Toolkit -Dynamo's mesh capabilities can be extended by installing the [Mesh Toolkit](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) package. The Dynamo Mesh Toolkit provides tools to import Meshes from external file formats, create a Mesh from Dynamo geometry objects, and manually build Meshes by their vertices and indices. The library also provides tools to modify Meshes, repair Meshes, or extract horizontal slices for use in fabrication. - -See chapter 10.2 for an example using Mesh Toolkit. - -![Mesh Toolkit](images/5-7/MeshToolKit.png) +## Meshes +In the field of computational modeling, Meshes are one of the most pervasive forms of representing 3D geometry. Mesh geometry can be a light-weight and flexible alternative to working with NURBS, and Meshes are used in everything from rendering and visualizations to digital fabrication and 3D printing. + +### What's a Mesh? +A Mesh is a collection of quadrilaterals and triangles that represents a surface or solid geometry. Like Solids, the structure of a Mesh object includes vertices, edges, and faces. There are additional properties that make Meshes unique as well, such as normals. + +![Mesh Elements](images/5-7/MeshElements2.png) + +> 1. Mesh vertices +2. Mesh edges *Edges with only one adjoining face are called "Naked." All other edges are "Clothed" +3. Mesh faces + +### Mesh Elements +Dynamo defines Meshes using a Face-Vertex data structure. At its most basic level, this structure is simply a collection of points which are grouped into polygons. The points of a Mesh are called vertices, while the surface-like polygons are called faces. To create a Mesh we need a list of vertices and a system of grouping those vertices into faces called an index group. + +![](images/5-7/meshFacesVertices.png) + +> 1. List of vertices +2. List of index groups to define faces + +####Vertices + Vertex Normals +The vertices of a Mesh are simply a list of points. The index of the vertices is very important when constructing a Mesh, or getting information about the structure of a Mesh. For each vertex, there is also a corresponding vertex normal (vector) which describes the average direction of the attached faces and helps us understand the "in" and "out" orientation of the Mesh. + +![Vertices + Normals](images/5-7/vertexNormals.png) + +>1. Vertices +2. Vertex Normals + + +####Faces +A face is an ordered list of three or four vertices. The “surface” representation of a Mesh face is therefore implied according to the position of the vertices being indexed. We already have the list of vertices that make up the Mesh, so instead of providing individual points to define a face, we simply use the index of the vertices. This also allows us to use the same vertex in more than one face. + +![](images/5-7/meshFaces.png) + +> 1. A quad face made with indices 0, 1, 2, and 3 +2. A triangle face made with indices 1, 4, and 2 +Note that the index groups can be shifted in their order - as long as the sequence is ordered in a counter-clockwise manner, the face will be defined correctly + +### Meshes versus NURBS Surfaces +How is Mesh geometry different from NURBS geometry? When might you want to use one instead of the other? + +####Parameterization + +In a previous chapter, we saw that NURBS surfaces are defined by a series of NURBS curves going in two directions. These directions are labeled ``U`` and ``V``, and allow a NURBs surface to be parameterized according to a two-dimensional surface domain. The curves themselves are stored as equations in the computer, allowing the resulting surfaces to be calculated to an arbitrarily small degree of precision. It can be difficult, however, to combine multiple NURBS surfaces together. Joining two NURBS surfaces will result in a polysurface, where different sections of the geometry will have different UV parameters and curve definitions. + +![Control Points](images/5-7/NURBSvsMESH-01.jpg) +> 1. Surface +2. Isoparametric (Isoparm) Curve +3. Surface Control Point +4. Surface Control Polygon +5. Isoparametric Point +6. Surface Frame +7. Mesh +8. Naked Edge +9. Mesh Network +10. Mesh Edges +11. Vertex Normal +12. Mesh Face / Mesh Face Normal + +Meshes, on the other hand, are comprised of a discrete number of exactly defined vertices and faces. The network of vertices generally cannot be defined by simple ``UV`` coordinates, and because the faces are discrete the amount of precision is built into the Mesh and can only be changed by refining the Mesh and adding more faces. The lack of mathematical descriptions allows Meshes to more flexibly handle complex geometry within a single Mesh. + + +###Local versus Global Influence + +Another important difference is the extent to which a local change in Mesh or NURBS geometry affects the entire form. Moving one vertex of a Mesh only affects the faces that are adjacent to that vertex. In NURBS surfaces, the extent of the influence is more complicated and depends on the degree of the surface as well as the weights and knots of the control points. In general, however, moving a single control point in a NURBS surface creates a smoother, more extensive change in geometry. + +![Editing](images/5-7/NURBSvsMESH-02.jpg) + +> 1. NURBS Surface - moving a control point has influence that extends across the shape +2. Mesh geometry - moving a vertex has influence only on adjacent elements + +One analogy that can be helpful is to compare a vector image (composed of lines and curves) with a raster image (composed of individual pixels). If you zoom into a vector image, the curves remain crisp and clear, while zooming into a raster image results in seeing individual pixels become larger. In this analogy, NURBS surfaces can be compared to a vector image because there is a smooth mathematical relationship, while a Mesh behaves similarly to a raster image with a set resolution. + +### Mesh Toolkit +Dynamo's mesh capabilities can be extended by installing the [Mesh Toolkit](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) package. The Dynamo Mesh Toolkit provides tools to import Meshes from external file formats, create a Mesh from Dynamo geometry objects, and manually build Meshes by their vertices and indices. The library also provides tools to modify Meshes, repair Meshes, or extract horizontal slices for use in fabrication. + +See chapter 10.2 for an example using Mesh Toolkit. + +![Mesh Toolkit](images/5-7/MeshToolKit.png) diff --git a/05_Geometry-for-Computational-Design/5-8_importing.md b/05_Geometry-for-Computational-Design/5-8_importing.md index a331a907..3401817a 100644 --- a/05_Geometry-for-Computational-Design/5-8_importing.md +++ b/05_Geometry-for-Computational-Design/5-8_importing.md @@ -1,47 +1,47 @@ -## Importing Geometry -There are several ways to import geometry into Dynamo. We've demonstrated importing meshes using *Mesh Toolkit* in the previous section - we can also import Solid models from .SAT files. With these processes, we can develop geometry in another platform, load it into Dynamo, and apply parametric operations through visual programming. - -Another method for importing geometry uses a process called *ATF Translation*. In this case, we can import not just geometry, but a file's structure. For example, we can choose which layers of a .DWG to import rather than importing the entire model. We'll demonstrate this below in more detail. - -###Importing Geometry from a DWG file - -Nodes for importing a DWG into the Dynamo environment are found under the *Translation* tab (Note: the these tools are only available in [Dynamo Studio](http://www.autodesk.com/products/dynamo-studio/overview)). The following examples show a series of components used to browse for a file, import the file contents, and convert it into usable Dynamo geometry. Dynamo also gives us the ability to filter and select specific objects to import from a DWG file - which we'll demonstrate below. For more information on Importing Geometry from a DWG File, read Ben Goh's [blog post here](http://dynamobim.org/dwg-import-in-dynamo-studio-0-9-1/). - -###Get Imported Objects -The simplest way to import DWG into Dynamo Studio is to import the entire file into the workspace: - -![GetImportedObjects](images/5-8/GetImportedObjects.jpg) - ->1. Use the File Path component to browse for the DWG file to be imported into Dynamo. -2. Connect to **FileLoader.FromPath** to read the file. -3. Use the **FileLoader.GetImportedObjects** component to parse the geometry into Dynamo Studio. -4. **ImportedObject.ConvertToGeometries** will convert the objects into usable geometry in the Dyanamo workspace. - -As shown in the above image, all types of geometry in the DWG file - surfaces, meshes, curves and lines - are imported into Dynamo. - -### Object Filter -To specify which geometries are imported from the DWG file, additional **ObjectFilter** nodes can be added to the definition. The **ObjectFilter** node is compatible with either a **FileLoader** or a list of **ImportedObject**, and outputs an **ImportedObject** list. - -The following images show the conditional statements within each **ObjectFilter** node. Any **ImportedObject** that satisfies any of the listed conditions will pass through the filter. Filtering can be based on layer label (i.e. layer name), geometry type, diffuse color, etc., and can be used in conjunction with other filters to refine the selection. - -![ObjectFilter1](images/5-8/ObjectFilter01.jpg) - ->1. Replace **FileLoader.GetImportedObjects** with **ObjectFilter** to search for specific conditions in the DWG file. – in this case only surface geometry will be imported, removing all curve and line geometry visible in the previous image. -2. Connect Filter to **ImportedObject.ConvertToGeometries** to import the filtered geometry. - -By adding two filters with different conditional statements, we can divide the list of geometry into multiple streams: - -![ObjectFilter2](images/5-8/ObjectFilter02.jpg) - ->1. Replace **FileLoader.GetImportedObjects** with two **ObjectFilter** modules of different conditional statements. This will separate the geometry from one file into two different streams. -2. Connect Filter to **ImportedObject.ConvertToGeometries** to import the filtered geometry. -3. Connect **ImportedObject.ConvertToGeometries** to **Display.ByGeometryColor** to visualize each stream in a different color. - -###Explicit Object Selection - -The **ObjectSelector** node gives us an alternative method to importing objects from the DWG file. Instead of using filters, this method will give us the ability to choose specifically which objects and layers will be imported into Dynamo. - -![Point to Curve](images/5-8/ObjectSelector.jpg) ->1. Replace **FileLoader.GetImportedObjects** with **ObjectSelector** to call for specific layers and objects within a DWG file. -2. Connect Filter to **ImportedObject.ConvertToGeometries**. - +## Importing Geometry +There are several ways to import geometry into Dynamo. We've demonstrated importing meshes using *Mesh Toolkit* in the previous section - we can also import Solid models from .SAT files. With these processes, we can develop geometry in another platform, load it into Dynamo, and apply parametric operations through visual programming. + +Another method for importing geometry uses a process called *ATF Translation*. In this case, we can import not just geometry, but a file's structure. For example, we can choose which layers of a .DWG to import rather than importing the entire model. We'll demonstrate this below in more detail. + +###Importing Geometry from a DWG file + +Nodes for importing a DWG into the Dynamo environment are found under the *Translation* tab (Note: the these tools are only available in [Dynamo Studio](http://www.autodesk.com/products/dynamo-studio/overview)). The following examples show a series of components used to browse for a file, import the file contents, and convert it into usable Dynamo geometry. Dynamo also gives us the ability to filter and select specific objects to import from a DWG file - which we'll demonstrate below. For more information on Importing Geometry from a DWG File, read Ben Goh's [blog post here](http://dynamobim.org/dwg-import-in-dynamo-studio-0-9-1/). + +###Get Imported Objects +The simplest way to import DWG into Dynamo Studio is to import the entire file into the workspace: + +![GetImportedObjects](images/5-8/GetImportedObjects.jpg) + +>1. Use the File Path component to browse for the DWG file to be imported into Dynamo. +2. Connect to **FileLoader.FromPath** to read the file. +3. Use the **FileLoader.GetImportedObjects** component to parse the geometry into Dynamo Studio. +4. **ImportedObject.ConvertToGeometries** will convert the objects into usable geometry in the Dyanamo workspace. + +As shown in the above image, all types of geometry in the DWG file - surfaces, meshes, curves and lines - are imported into Dynamo. + +### Object Filter +To specify which geometries are imported from the DWG file, additional **ObjectFilter** nodes can be added to the definition. The **ObjectFilter** node is compatible with either a **FileLoader** or a list of **ImportedObject**, and outputs an **ImportedObject** list. + +The following images show the conditional statements within each **ObjectFilter** node. Any **ImportedObject** that satisfies any of the listed conditions will pass through the filter. Filtering can be based on layer label (i.e. layer name), geometry type, diffuse color, etc., and can be used in conjunction with other filters to refine the selection. + +![ObjectFilter1](images/5-8/ObjectFilter01.jpg) + +>1. Replace **FileLoader.GetImportedObjects** with **ObjectFilter** to search for specific conditions in the DWG file. – in this case only surface geometry will be imported, removing all curve and line geometry visible in the previous image. +2. Connect Filter to **ImportedObject.ConvertToGeometries** to import the filtered geometry. + +By adding two filters with different conditional statements, we can divide the list of geometry into multiple streams: + +![ObjectFilter2](images/5-8/ObjectFilter02.jpg) + +>1. Replace **FileLoader.GetImportedObjects** with two **ObjectFilter** modules of different conditional statements. This will separate the geometry from one file into two different streams. +2. Connect Filter to **ImportedObject.ConvertToGeometries** to import the filtered geometry. +3. Connect **ImportedObject.ConvertToGeometries** to **Display.ByGeometryColor** to visualize each stream in a different color. + +###Explicit Object Selection + +The **ObjectSelector** node gives us an alternative method to importing objects from the DWG file. Instead of using filters, this method will give us the ability to choose specifically which objects and layers will be imported into Dynamo. + +![Point to Curve](images/5-8/ObjectSelector.jpg) +>1. Replace **FileLoader.GetImportedObjects** with **ObjectSelector** to call for specific layers and objects within a DWG file. +2. Connect Filter to **ImportedObject.ConvertToGeometries**. + diff --git a/05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md b/05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md index 4f0379d0..1495527f 100644 --- a/05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md +++ b/05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md @@ -1,5 +1,5 @@ -# GEOMETRY FOR COMPUTATIONAL DESIGN - -As a Visual Programming environment, Dynamo enables you to craft the way that data is processed. Data is numbers or text, but so is Geometry. As understood by the Computer, Geometry - or sometimes called Computational Geometry - is the data we can use to create beautiful, intricate, or performance-driven models. To do so, we need to understand the ins and outs of the various types of Geometry we can use. - -![IMAGE](images/5/Geometry for Computational Design-01.png) +# GEOMETRY FOR COMPUTATIONAL DESIGN + +As a Visual Programming environment, Dynamo enables you to craft the way that data is processed. Data is numbers or text, but so is Geometry. As understood by the Computer, Geometry - or sometimes called Computational Geometry - is the data we can use to create beautiful, intricate, or performance-driven models. To do so, we need to understand the ins and outs of the various types of Geometry we can use. + +![IMAGE](images/5/Geometry for Computational Design-01.png) diff --git a/05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn b/05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn index bcbc0770..f94db015 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn @@ -1,44 +1,44 @@ - - - - - - - - - - - - - - 2 - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + 2 + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn index e124387c..bb39f0e7 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn @@ -1,34 +1,34 @@ - - - - - - - - - - 0.6 - - - - -0.2 - - - - 0.9 - - - - - - - - - - - - - - - + + + + + + + + + + 0.6 + + + + -0.2 + + + + 0.9 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn index a93bd144..4204cb01 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn @@ -1,62 +1,62 @@ - - - - - - - - - - - - - - - - 0.6 - - - - -0.2 - - - - 0.9 - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + 0.6 + + + + -0.2 + + + + 0.9 + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn index bbda84ba..66ec52aa 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn @@ -1,56 +1,56 @@ - - - - - - - - - - - - - - - - - - - 0.5 - - - - -0.1 - - - - 0.5 - - - - 5.5 - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + 0.5 + + + + -0.1 + + + + 0.5 + + + + 5.5 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn b/05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn index b5811ac8..6d8c27ca 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn @@ -1,67 +1,67 @@ - - - - - - - - - - 1.3 - - - - - - - - - - - - - - 0.33 - - - - 0.59 - - - - - - - - - -1.2 - - - - -1.6 - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + 1.3 + + + + + + + + + + + + + + 0.33 + + + + 0.59 + + + + + + + + + -1.2 + + + + -1.6 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn b/05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn index f294bb68..de6070fb 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn @@ -1,43 +1,43 @@ - - - - - - - - - - - 8 - - - - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + 8 + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn b/05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn index 5f1732a2..0a058564 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn @@ -1,64 +1,64 @@ - - - - - C:\Users\gAkos\Documents\GitHub\dynamo-primer\05_Geometry-for-Computational-Design\datasets\Surface.sat - - - - - - - - - - - - 0.61 - - - - 0.33 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + C:\Users\gAkos\Documents\GitHub\dynamo-primer\05_Geometry-for-Computational-Design\datasets\Surface.sat + + + + + + + + + + + + 0.61 + + + + 0.33 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/datasets/5-6/Geometry for Computational Design - Solids.dyn b/05_Geometry-for-Computational-Design/datasets/5-6/Geometry for Computational Design - Solids.dyn index a190edf4..ee377568 100644 --- a/05_Geometry-for-Computational-Design/datasets/5-6/Geometry for Computational Design - Solids.dyn +++ b/05_Geometry-for-Computational-Design/datasets/5-6/Geometry for Computational Design - Solids.dyn @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-1/Geometry for Computational Design - Geometry Overview.dyn b/05_Geometry-for-Computational-Design/images/5-1/Geometry for Computational Design - Geometry Overview.dyn index bcbc0770..f94db015 100644 --- a/05_Geometry-for-Computational-Design/images/5-1/Geometry for Computational Design - Geometry Overview.dyn +++ b/05_Geometry-for-Computational-Design/images/5-1/Geometry for Computational Design - Geometry Overview.dyn @@ -1,44 +1,44 @@ - - - - - - - - - - - - - - 2 - - - - - - - - 2 - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + 2 + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Coordinate System.dyn b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Coordinate System.dyn index e124387c..bb39f0e7 100644 --- a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Coordinate System.dyn +++ b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Coordinate System.dyn @@ -1,34 +1,34 @@ - - - - - - - - - - 0.6 - - - - -0.2 - - - - 0.9 - - - - - - - - - - - - - - - + + + + + + + + + + 0.6 + + + + -0.2 + + + + 0.9 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Plane.dyn b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Plane.dyn index a93bd144..4204cb01 100644 --- a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Plane.dyn +++ b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Plane.dyn @@ -1,62 +1,62 @@ - - - - - - - - - - - - - - - - 0.6 - - - - -0.2 - - - - 0.9 - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + 0.6 + + + + -0.2 + + + + 0.9 + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Vectors.dyn b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Vectors.dyn index bbda84ba..66ec52aa 100644 --- a/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Vectors.dyn +++ b/05_Geometry-for-Computational-Design/images/5-2/Geometry for Computational Design - Vectors.dyn @@ -1,56 +1,56 @@ - - - - - - - - - - - - - - - - - - - 0.5 - - - - -0.1 - - - - 0.5 - - - - 5.5 - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + 0.5 + + + + -0.1 + + + + 0.5 + + + + 5.5 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-3/Geometry for Computational Design - Points.dyn b/05_Geometry-for-Computational-Design/images/5-3/Geometry for Computational Design - Points.dyn index b5811ac8..6d8c27ca 100644 --- a/05_Geometry-for-Computational-Design/images/5-3/Geometry for Computational Design - Points.dyn +++ b/05_Geometry-for-Computational-Design/images/5-3/Geometry for Computational Design - Points.dyn @@ -1,67 +1,67 @@ - - - - - - - - - - 1.3 - - - - - - - - - - - - - - 0.33 - - - - 0.59 - - - - - - - - - -1.2 - - - - -1.6 - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + 1.3 + + + + + + + + + + + + + + 0.33 + + + + 0.59 + + + + + + + + + -1.2 + + + + -1.6 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-4/Geometry for Computational Design - Curves.dyn b/05_Geometry-for-Computational-Design/images/5-4/Geometry for Computational Design - Curves.dyn index f294bb68..de6070fb 100644 --- a/05_Geometry-for-Computational-Design/images/5-4/Geometry for Computational Design - Curves.dyn +++ b/05_Geometry-for-Computational-Design/images/5-4/Geometry for Computational Design - Curves.dyn @@ -1,43 +1,43 @@ - - - - - - - - - - - 8 - - - - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + 8 + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-5/Geometry for Computational Design - Surfaces.dyn b/05_Geometry-for-Computational-Design/images/5-5/Geometry for Computational Design - Surfaces.dyn index 5f1732a2..0a058564 100644 --- a/05_Geometry-for-Computational-Design/images/5-5/Geometry for Computational Design - Surfaces.dyn +++ b/05_Geometry-for-Computational-Design/images/5-5/Geometry for Computational Design - Surfaces.dyn @@ -1,64 +1,64 @@ - - - - - C:\Users\gAkos\Documents\GitHub\dynamo-primer\05_Geometry-for-Computational-Design\datasets\Surface.sat - - - - - - - - - - - - 0.61 - - - - 0.33 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + C:\Users\gAkos\Documents\GitHub\dynamo-primer\05_Geometry-for-Computational-Design\datasets\Surface.sat + + + + + + + + + + + + 0.61 + + + + 0.33 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/05_Geometry-for-Computational-Design/images/5-6/Geometry for Computational Design - Solids.dyn b/05_Geometry-for-Computational-Design/images/5-6/Geometry for Computational Design - Solids.dyn index a190edf4..ee377568 100644 --- a/05_Geometry-for-Computational-Design/images/5-6/Geometry for Computational Design - Solids.dyn +++ b/05_Geometry-for-Computational-Design/images/5-6/Geometry for Computational Design - Solids.dyn @@ -1,49 +1,49 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/6-1_whats-a-list.md b/06_Designing-with-Lists/6-1_whats-a-list.md index 6c7cf2b7..8dbef86b 100644 --- a/06_Designing-with-Lists/6-1_whats-a-list.md +++ b/06_Designing-with-Lists/6-1_whats-a-list.md @@ -1,94 +1,94 @@ -## What's a List? -A list is a collection of elements, or items. Take a bunch of bananas, for example. Each banana is an item within the list (or bunch). It's easier to pick up a bunch of bananas rather than each banana individually, and the same holds for grouping elements by parametric relationships in a data structure. - -![Bananas](images/6-1/Bananas_white_background_DS.jpg) -> Photo by [Augustus Binu](https://commons.wikimedia.org/wiki/File:Bananas_white_background_DS.jpg?fastcci_from=11404890&c1=11404890&d1=15&s=200&a=list). - -When we buy groceries, we put all of the purchased items into a bag. This bag is also a list. If we're making banana bread, we need 3 bunches of bananas (we're making a *lot* of banana bread). The bag represents a list of banana bunches and each bunch represents a list of bananas. The bag is a list of lists (two-dimensional) and the banana is a list (one-dimensional). - -In Dynamo, list data is ordered, and the first item in each list has an index "0". Below, we'll discuss how lists are defined in Dynamo and how multiple lists relate to one another. - -## Zero-Based Indices - -One thing that might seem odd at first is that the first index of a list -is always 0; not 1. So, when we talk about the first item of a list, we actually mean -the item that corresponds to index 0. - -For example, if you were to count the number of fingers we have on our right -hand, chances are that you would have counted from 1 to 5. However, if you were to put your fingers in a list, Dynamo would have given them indices from 0 to 4. While this may seem a little strange to programming beginners, the zero-based index is standard practice in most computation systems. - -![items](images/6-1/items.png) - -Note that we still have 5 items in the list; it’s just that the list is using a zero-based -counting system. And the items being stored in the list don’t just have to be -numbers. They can be any data type that Dynamo supports, such as points, -curves, surfaces, families, etc. - -Often times the easiest way to take a look at the type of data stored in a list -is to connect a watch node to another node's output. By default, the watch node automatically shows all indices to the left side of the list and displays the data items on the right. - -These indices are a crucial element when working with lists. - -### Inputs and Outputs -Pertaining to lists, inputs and outputs vary depending on the Dynamo node being used. As an example, let's use a list of 5 points and connect this output to two different Dynamo nodes: *PolyCurve.ByPoints* and *Circle.ByCenterPointRadius*: - -![Input Examples](images/6-2/PolyCurve.Inputs.png) -> 1. The *points* input for *PolyCurve.ByPoints* is looking for *"Point[]"*. This represents a list of points. -2. The output for *PolyCurve.ByPoints* is a single PolyCurve created from a list of five points. -3. The *centerPoint* input for *Circle.ByCenterPointRadius* asks for *"Point"*. -4. The output for *Circle.ByCenterPointRadius* is a list of five circles, whose centers correspond to the original list of points. - -The input data for *PolyCurve.ByPoints* and *Circle.ByCenterPointRadius* are the same, however the Polycurve node gives us one polycurve while the Circle node gives us 5 circles with centers at each point. Intuitively this makes sense: the polycurve is drawn as a curve connecting the 5 points, while the circles create a different circle at each point. So what's happening with the data? - -Hovering over the *points* input for *Polycurve.ByPoints*, we see that the input is looking for *"Point[]"*. Notice the brackets at the end. This represents a list of points, and to create a polycurve, the input needs to be a list for each polycurve. This node will therefore condense each list into one polycurve. - -On the other hand, the *centerPoint* input for *Circle.ByCenterPointRadius* asks for *"Point"*. This node looks for one point, as an item, to define the center point of the circle. This is why we get five circles from the input data. Recognizing these difference with inputs in Dynamo helps to better understand how the nodes are operating when managing data. - - - - - -###Lacing -Data matching is a problem without a clean solution. It occurs when a node has access to differently sized inputs. Changing the data matching algorithm can lead to vastly different results. - -Imagine a node which creates line segments between points (Line.ByStartPointEndPoint). It will have two input parameters which both supply point coordinates: - -![Input Examples](images/6-1/laceBase.jpg) - -As you can see there are different ways in which we can draw lines between these sets of points. Lacing options are found by right-clicking the center of a node and choosing the "Lacing" menu. - -###Base File ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Lacing.dyn](datasets/6-1/Lacing.dyn). A full list of example files can be found in the Appendix. - -To demonstrate the lacing operations below, we'll use this base file to define shortest list, longest list, and cross product. - -![Input Examples](images/6-1/lacing.png) - > 1. We'll change the lacing on *Point.ByCoordinates*, but won't change anything else about the graph above. - -####Shortest List -The simplest way is to connect the inputs one-on-one until one of the streams runs dry. This is called the “Shortest List” algorithm. This is the default behavior for Dynamo nodes: - -![Input Examples](images/6-1/shortestListDiagram.png) - -![Input Examples](images/6-1/shortestList.png) -> By changing the lacing to *shortest list*, we get a basic diagonal line composed of five points. Five points is the length of the lesser list, so the shortest list lacing stops after it reaches the end of one list. - -####Longest List -The “Longest List” algorithm keeps connecting inputs, reusing elements, until all streams run dry: - -![Input Examples](images/6-1/longestListDiagram.png) - -![Input Examples](images/6-1/longestList.png) -> By changing the lacing to *longest list*, we get a diagonal line which extends vertically. By the same method as the concept diagram, the last item in the list of 5 items will be repeated to reach the length of the longer list. - -####Cross Product -Finally, the “Cross Product” method makes all possible connections: - -![Input Examples](images/6-1/crossProductDiagram.png) - -![Input Examples](images/6-1/crossProduct.png) -> By changing the lacing to *Cross Product*, we get every combination between each list, giving us a 5x10 grid of points. This is an equivalent data structure to the cross product as shown in the concept diagram above, except our data is now a list of lists. By connecting a polycurve, we can see that each list is defined by its X-Value, giving us a row of vertical lines. - - - - +## What's a List? +A list is a collection of elements, or items. Take a bunch of bananas, for example. Each banana is an item within the list (or bunch). It's easier to pick up a bunch of bananas rather than each banana individually, and the same holds for grouping elements by parametric relationships in a data structure. + +![Bananas](images/6-1/Bananas_white_background_DS.jpg) +> Photo by [Augustus Binu](https://commons.wikimedia.org/wiki/File:Bananas_white_background_DS.jpg?fastcci_from=11404890&c1=11404890&d1=15&s=200&a=list). + +When we buy groceries, we put all of the purchased items into a bag. This bag is also a list. If we're making banana bread, we need 3 bunches of bananas (we're making a *lot* of banana bread). The bag represents a list of banana bunches and each bunch represents a list of bananas. The bag is a list of lists (two-dimensional) and the banana is a list (one-dimensional). + +In Dynamo, list data is ordered, and the first item in each list has an index "0". Below, we'll discuss how lists are defined in Dynamo and how multiple lists relate to one another. + +## Zero-Based Indices + +One thing that might seem odd at first is that the first index of a list +is always 0; not 1. So, when we talk about the first item of a list, we actually mean +the item that corresponds to index 0. + +For example, if you were to count the number of fingers we have on our right +hand, chances are that you would have counted from 1 to 5. However, if you were to put your fingers in a list, Dynamo would have given them indices from 0 to 4. While this may seem a little strange to programming beginners, the zero-based index is standard practice in most computation systems. + +![items](images/6-1/items.png) + +Note that we still have 5 items in the list; it’s just that the list is using a zero-based +counting system. And the items being stored in the list don’t just have to be +numbers. They can be any data type that Dynamo supports, such as points, +curves, surfaces, families, etc. + +Often times the easiest way to take a look at the type of data stored in a list +is to connect a watch node to another node's output. By default, the watch node automatically shows all indices to the left side of the list and displays the data items on the right. + +These indices are a crucial element when working with lists. + +### Inputs and Outputs +Pertaining to lists, inputs and outputs vary depending on the Dynamo node being used. As an example, let's use a list of 5 points and connect this output to two different Dynamo nodes: *PolyCurve.ByPoints* and *Circle.ByCenterPointRadius*: + +![Input Examples](images/6-2/PolyCurve.Inputs.png) +> 1. The *points* input for *PolyCurve.ByPoints* is looking for *"Point[]"*. This represents a list of points. +2. The output for *PolyCurve.ByPoints* is a single PolyCurve created from a list of five points. +3. The *centerPoint* input for *Circle.ByCenterPointRadius* asks for *"Point"*. +4. The output for *Circle.ByCenterPointRadius* is a list of five circles, whose centers correspond to the original list of points. + +The input data for *PolyCurve.ByPoints* and *Circle.ByCenterPointRadius* are the same, however the Polycurve node gives us one polycurve while the Circle node gives us 5 circles with centers at each point. Intuitively this makes sense: the polycurve is drawn as a curve connecting the 5 points, while the circles create a different circle at each point. So what's happening with the data? + +Hovering over the *points* input for *Polycurve.ByPoints*, we see that the input is looking for *"Point[]"*. Notice the brackets at the end. This represents a list of points, and to create a polycurve, the input needs to be a list for each polycurve. This node will therefore condense each list into one polycurve. + +On the other hand, the *centerPoint* input for *Circle.ByCenterPointRadius* asks for *"Point"*. This node looks for one point, as an item, to define the center point of the circle. This is why we get five circles from the input data. Recognizing these difference with inputs in Dynamo helps to better understand how the nodes are operating when managing data. + + + + + +###Lacing +Data matching is a problem without a clean solution. It occurs when a node has access to differently sized inputs. Changing the data matching algorithm can lead to vastly different results. + +Imagine a node which creates line segments between points (Line.ByStartPointEndPoint). It will have two input parameters which both supply point coordinates: + +![Input Examples](images/6-1/laceBase.jpg) + +As you can see there are different ways in which we can draw lines between these sets of points. Lacing options are found by right-clicking the center of a node and choosing the "Lacing" menu. + +###Base File +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Lacing.dyn](datasets/6-1/Lacing.dyn). A full list of example files can be found in the Appendix. + +To demonstrate the lacing operations below, we'll use this base file to define shortest list, longest list, and cross product. + +![Input Examples](images/6-1/lacing.png) + > 1. We'll change the lacing on *Point.ByCoordinates*, but won't change anything else about the graph above. + +####Shortest List +The simplest way is to connect the inputs one-on-one until one of the streams runs dry. This is called the “Shortest List” algorithm. This is the default behavior for Dynamo nodes: + +![Input Examples](images/6-1/shortestListDiagram.png) + +![Input Examples](images/6-1/shortestList.png) +> By changing the lacing to *shortest list*, we get a basic diagonal line composed of five points. Five points is the length of the lesser list, so the shortest list lacing stops after it reaches the end of one list. + +####Longest List +The “Longest List” algorithm keeps connecting inputs, reusing elements, until all streams run dry: + +![Input Examples](images/6-1/longestListDiagram.png) + +![Input Examples](images/6-1/longestList.png) +> By changing the lacing to *longest list*, we get a diagonal line which extends vertically. By the same method as the concept diagram, the last item in the list of 5 items will be repeated to reach the length of the longer list. + +####Cross Product +Finally, the “Cross Product” method makes all possible connections: + +![Input Examples](images/6-1/crossProductDiagram.png) + +![Input Examples](images/6-1/crossProduct.png) +> By changing the lacing to *Cross Product*, we get every combination between each list, giving us a 5x10 grid of points. This is an equivalent data structure to the cross product as shown in the concept diagram above, except our data is now a list of lists. By connecting a polycurve, we can see that each list is defined by its X-Value, giving us a row of vertical lines. + + + + diff --git a/06_Designing-with-Lists/6-2_working-with-lists.md b/06_Designing-with-Lists/6-2_working-with-lists.md index e4227c00..37ba6cbd 100644 --- a/06_Designing-with-Lists/6-2_working-with-lists.md +++ b/06_Designing-with-Lists/6-2_working-with-lists.md @@ -1,130 +1,130 @@ -## Working with Lists -Now that we've established what a list is, let's talk about operations we can perform on it. Imagine a list as a deck of playing cards. A deck is the list and each playing card represents an item. - -![cards](images/6-2/Playing_cards_modified.jpg) -> Photo by [Christian Gidlöf](https://commons.wikimedia.org/wiki/File:Playing_cards_modified.jpg) - -What **queries** can we make from the list? This accesses existing properties. -* Number of cards in the deck? 52. -* Number of suits? 4. -* Material? Paper. -* Length? 3.5" or 89mm. -* Width? 2.5" or 64mm. - -What **actions** can we perform on the list? This changes the list based on a given operation. -* We can shuffle the deck. -* We can sort the deck by value. -* We can sort the deck by suit. -* We can split the deck. -* We can partition the deck by dealing out individual hands. -* We can select a specific card in the deck. - -All of the operations listed above have analogous Dynamo nodes for working with lists of generic data. The lessons below will demonstrate some of the fundamental operations we can perform on lists. - -##List Operations -The image below is the base graph we will be using to demonstrate basic list operations. We'll explore how to manage data within a list and demonstrate the visual results. - -#### Exercise - List Operations ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Operations.dyn](datasets/6-2/List-Operations.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-2/Exercise/40.png) -> 1. Begin with a *code block* with a value of ```500; -``` -2. Plug into the *x* input of a *Point.ByCoordinates* node. -3. Plug the node from the previous step into the origin input of a *Plane.ByOriginNormal* node. -4. Using a *Circle.ByPlaneRadius* node, plug the node from the previous step into the plane input. -5. Using *code block*, designate a value of ```50; -``` for the *radius*. This is the first circle we'll create. -6. With a *Geometry.Translate* node, move the circle up 100 units in the Z direction. -7. With a *code block* node, define a range of ten numbers between 0 and 1 with this line of code: ```0..1..#10; -``` -8. Plug the code block from the previous step into the *param* input of two *Curve.PointAtParameter* nodes. Plug *Circle.ByPlaneRadius* into the curve input of the top node, and *Geometry.Translate* into the curve input of the node beneath it. -9. Using a *Line.ByStartPointEndPoint*, connect the two *Curve.PointAtParameter *nodes. - -![Exercise](images/6-2/Exercise/38.png) ->1. A *Watch3D* node shows the results of the *Line.ByStartPointEndPoint*. We are drawing lines between two circles to represent basic list operations and will use this base Dynamo graph to walk through the list actions below. - -###List.Count -![Count](images/6-2/count.png) -> The *List.Count* node is straightforward: it counts the number of values in a list and returns that number. This node gets more nuanced as we work with lists of lists, but we'll demonstrate that in the coming sections. - -#### Exercise - List.Count ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Count.dyn](datasets/6-2/List-Count.dyn). A full list of example files can be found in the Appendix. - -![Count](images/6-2/Exercise/35.png) -> 1. The *List.Count* node returns the number of lines in the *Line.ByStartPointEndPoint* node. The value is 10 in this case, which agrees with the number of points created from the original *code block* node. - -###List.GetItemAtIndex -![index](images/6-2/index.png) -> *List.GetItemAtIndex* is a fundamental way to query an item in the list. In the image above, we are using an index of *"2"* to query the point labeled* "C"*. - -#### Exercise - List.GetItemAtIndex ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-GetItemAtIndex.dyn](datasets/6-2/List-GetItemAtIndex.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-2/Exercise/33.png) ->1. Using the *List.GetItemAtIndex* node, we are selecting index *"0"*, or the first item in the list of lines. -2. The *Watch3D* node reveals that we've selected one line. Note: to get the image above, be sure to disable the preview of *Line.ByStartPointEndPoint*. - -###List.Reverse -![reverse](images/6-2/reverse.png) -> *List.Reverse* reverses the order of all of the items in a list. - -#### Exercise - List.Reverse ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Reverse.dyn](datasets/6-2/List-Reverse.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-2/Exercise/34.png) ->1. To properly visualize the reversed list of lines, create more lines by changing the code block to ```0..1..#100; -``` -2. Insert a *List.Reverse* node in between *Curve.PointAtParameter* and *Line.ByStartPointEndPoint* for one of the list of points. -3. The *Watch3D* nodes show two different results. The first one shows the result without a reversed list. The lines connect vertically to neighboring points. The reversed list, however, will connect all of the points to the opposing order in the other list. - - -###List.ShiftIndices -![shift](images/6-2/shift.png) -> *List.ShiftIndices* is a good tool for creating twists or helical patterns, or any other similar data manipulation. This node shifts the items in a list a given number of indices. - -#### Exercise - List.ShiftIndices ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-ShiftIndices.dyn](datasets/6-2/List-ShiftIndices.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-2/Exercise/31.png) ->1. In the same process as the reverse list, insert a *List.ShiftIndices* into the *Curve.PointAtParameter* and *Line.ByStartPointEndPoint*. -2. Using a *code block*, designated a value of *"1"* to shift the list one index. -3. Notice that the change is subtle, but all of the lines in the lower *Watch3D* node have shifted one index when connecting to the other set of points. - -![Exercise](images/6-2/Exercise/32.png) ->1. By changing to *code block* to a larger value, *"30"* for example, we notice a significant difference in the diagonal lines. The shift is working like a camera's iris in this case, creating a twist in the original cylindrical form. - -###List.FilterByBooleanMask -![cull](images/6-2/cull2.png) -> *List.FilterByBooleanMask* will remove certain items based on a list of booleans, or values reading "true" or "false". - -#### Exercise - List.FilterByBooleanMask ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-FilterByBooleanMask.dyn](datasets/6-2/List-FilterByBooleanMask.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-2/Exercise/30.png) -> In order to create a list of values reading "true" or "false", we need to a little more work... -1. Using a *code block*, define an expression with the syntax: ```0..List.Count(list); -```. Connect the *Curve.PointAtParameter* node to the *list* input. We'll walk through this setup more in the code block chapter, but the line of code in this case is giving us a list representing each index of the *Curve.PointAtParameter* node. -3. Using a *"%"* (modulus) node, connect the output of the *code block* into the *x* input, and a value of *4* into the *y* input. This will give us the remainder when dividing the list of indices by 4. Modulus is a really helpful node for pattern creation. All values will read as the possible remainders of 4: 0, 1, 2, 3. -4. From the *modulus* node, we know that a value of 0 means that the index is divisible by 4 (0,4,8,etc...). By using a *"=="* node, we can test for the divisibility by testing it against a value of *"0"*. -5. The *Watch* node reveals just this: we have a true/false pattern which reads: *true,false,false,false...*. -6. Using this true/false pattern, connect to the mask input of two *List.FilterByBooleanMask* nodes. -7. Connect the *Curve.PointAtParameter* node into each list input for the *List.FilterByBooleanMask*. -8. The output of *Filter.ByBooleanMask* reads *"in"* and *"out"*. *"In"* represents values which had a mask value of *"true"* while *"out"* represents values which had a value of *"false"*. By plugging the *"in"* outputs into the *startPoint* and *endPoint* inputs of a *Line.ByStartPointEndPoint* node, we've created a filtered list of lines. -9. The *Watch3D* node reveals that we have fewer lines than points. We've selected only 25% of the nodes by filtering only the true values! - - - - - - - - - - - - - - - - +## Working with Lists +Now that we've established what a list is, let's talk about operations we can perform on it. Imagine a list as a deck of playing cards. A deck is the list and each playing card represents an item. + +![cards](images/6-2/Playing_cards_modified.jpg) +> Photo by [Christian Gidlöf](https://commons.wikimedia.org/wiki/File:Playing_cards_modified.jpg) + +What **queries** can we make from the list? This accesses existing properties. +* Number of cards in the deck? 52. +* Number of suits? 4. +* Material? Paper. +* Length? 3.5" or 89mm. +* Width? 2.5" or 64mm. + +What **actions** can we perform on the list? This changes the list based on a given operation. +* We can shuffle the deck. +* We can sort the deck by value. +* We can sort the deck by suit. +* We can split the deck. +* We can partition the deck by dealing out individual hands. +* We can select a specific card in the deck. + +All of the operations listed above have analogous Dynamo nodes for working with lists of generic data. The lessons below will demonstrate some of the fundamental operations we can perform on lists. + +##List Operations +The image below is the base graph we will be using to demonstrate basic list operations. We'll explore how to manage data within a list and demonstrate the visual results. + +#### Exercise - List Operations +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Operations.dyn](datasets/6-2/List-Operations.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-2/Exercise/40.png) +> 1. Begin with a *code block* with a value of ```500; +``` +2. Plug into the *x* input of a *Point.ByCoordinates* node. +3. Plug the node from the previous step into the origin input of a *Plane.ByOriginNormal* node. +4. Using a *Circle.ByPlaneRadius* node, plug the node from the previous step into the plane input. +5. Using *code block*, designate a value of ```50; +``` for the *radius*. This is the first circle we'll create. +6. With a *Geometry.Translate* node, move the circle up 100 units in the Z direction. +7. With a *code block* node, define a range of ten numbers between 0 and 1 with this line of code: ```0..1..#10; +``` +8. Plug the code block from the previous step into the *param* input of two *Curve.PointAtParameter* nodes. Plug *Circle.ByPlaneRadius* into the curve input of the top node, and *Geometry.Translate* into the curve input of the node beneath it. +9. Using a *Line.ByStartPointEndPoint*, connect the two *Curve.PointAtParameter *nodes. + +![Exercise](images/6-2/Exercise/38.png) +>1. A *Watch3D* node shows the results of the *Line.ByStartPointEndPoint*. We are drawing lines between two circles to represent basic list operations and will use this base Dynamo graph to walk through the list actions below. + +###List.Count +![Count](images/6-2/count.png) +> The *List.Count* node is straightforward: it counts the number of values in a list and returns that number. This node gets more nuanced as we work with lists of lists, but we'll demonstrate that in the coming sections. + +#### Exercise - List.Count +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Count.dyn](datasets/6-2/List-Count.dyn). A full list of example files can be found in the Appendix. + +![Count](images/6-2/Exercise/35.png) +> 1. The *List.Count* node returns the number of lines in the *Line.ByStartPointEndPoint* node. The value is 10 in this case, which agrees with the number of points created from the original *code block* node. + +###List.GetItemAtIndex +![index](images/6-2/index.png) +> *List.GetItemAtIndex* is a fundamental way to query an item in the list. In the image above, we are using an index of *"2"* to query the point labeled* "C"*. + +#### Exercise - List.GetItemAtIndex +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-GetItemAtIndex.dyn](datasets/6-2/List-GetItemAtIndex.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-2/Exercise/33.png) +>1. Using the *List.GetItemAtIndex* node, we are selecting index *"0"*, or the first item in the list of lines. +2. The *Watch3D* node reveals that we've selected one line. Note: to get the image above, be sure to disable the preview of *Line.ByStartPointEndPoint*. + +###List.Reverse +![reverse](images/6-2/reverse.png) +> *List.Reverse* reverses the order of all of the items in a list. + +#### Exercise - List.Reverse +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-Reverse.dyn](datasets/6-2/List-Reverse.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-2/Exercise/34.png) +>1. To properly visualize the reversed list of lines, create more lines by changing the code block to ```0..1..#100; +``` +2. Insert a *List.Reverse* node in between *Curve.PointAtParameter* and *Line.ByStartPointEndPoint* for one of the list of points. +3. The *Watch3D* nodes show two different results. The first one shows the result without a reversed list. The lines connect vertically to neighboring points. The reversed list, however, will connect all of the points to the opposing order in the other list. + + +###List.ShiftIndices +![shift](images/6-2/shift.png) +> *List.ShiftIndices* is a good tool for creating twists or helical patterns, or any other similar data manipulation. This node shifts the items in a list a given number of indices. + +#### Exercise - List.ShiftIndices +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-ShiftIndices.dyn](datasets/6-2/List-ShiftIndices.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-2/Exercise/31.png) +>1. In the same process as the reverse list, insert a *List.ShiftIndices* into the *Curve.PointAtParameter* and *Line.ByStartPointEndPoint*. +2. Using a *code block*, designated a value of *"1"* to shift the list one index. +3. Notice that the change is subtle, but all of the lines in the lower *Watch3D* node have shifted one index when connecting to the other set of points. + +![Exercise](images/6-2/Exercise/32.png) +>1. By changing to *code block* to a larger value, *"30"* for example, we notice a significant difference in the diagonal lines. The shift is working like a camera's iris in this case, creating a twist in the original cylindrical form. + +###List.FilterByBooleanMask +![cull](images/6-2/cull2.png) +> *List.FilterByBooleanMask* will remove certain items based on a list of booleans, or values reading "true" or "false". + +#### Exercise - List.FilterByBooleanMask +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [List-FilterByBooleanMask.dyn](datasets/6-2/List-FilterByBooleanMask.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-2/Exercise/30.png) +> In order to create a list of values reading "true" or "false", we need to a little more work... +1. Using a *code block*, define an expression with the syntax: ```0..List.Count(list); +```. Connect the *Curve.PointAtParameter* node to the *list* input. We'll walk through this setup more in the code block chapter, but the line of code in this case is giving us a list representing each index of the *Curve.PointAtParameter* node. +3. Using a *"%"* (modulus) node, connect the output of the *code block* into the *x* input, and a value of *4* into the *y* input. This will give us the remainder when dividing the list of indices by 4. Modulus is a really helpful node for pattern creation. All values will read as the possible remainders of 4: 0, 1, 2, 3. +4. From the *modulus* node, we know that a value of 0 means that the index is divisible by 4 (0,4,8,etc...). By using a *"=="* node, we can test for the divisibility by testing it against a value of *"0"*. +5. The *Watch* node reveals just this: we have a true/false pattern which reads: *true,false,false,false...*. +6. Using this true/false pattern, connect to the mask input of two *List.FilterByBooleanMask* nodes. +7. Connect the *Curve.PointAtParameter* node into each list input for the *List.FilterByBooleanMask*. +8. The output of *Filter.ByBooleanMask* reads *"in"* and *"out"*. *"In"* represents values which had a mask value of *"true"* while *"out"* represents values which had a value of *"false"*. By plugging the *"in"* outputs into the *startPoint* and *endPoint* inputs of a *Line.ByStartPointEndPoint* node, we've created a filtered list of lines. +9. The *Watch3D* node reveals that we have fewer lines than points. We've selected only 25% of the nodes by filtering only the true values! + + + + + + + + + + + + + + + + diff --git a/06_Designing-with-Lists/6-3_lists-of-lists.md b/06_Designing-with-Lists/6-3_lists-of-lists.md index e2399785..ce05f9b7 100644 --- a/06_Designing-with-Lists/6-3_lists-of-lists.md +++ b/06_Designing-with-Lists/6-3_lists-of-lists.md @@ -1,273 +1,273 @@ -## Lists of Lists -Let's add one more tier to the hierarchy. If we take the deck of cards from the original example and create a box which contains multiple decks, the box now represents a list of decks, and each deck represents a list of cards. This is a list of lists. For the analogy in this section, the red box below contains a list of coin rolls, and each roll contains a list of pennies. - -![Coins](images/6-3/coins-521245_640.jpg) -> Photo by [Dori](https://commons.wikimedia.org/wiki/File:Stack_of_coins_0214.jpg). - -What **queries** can we make from the list of lists? This accesses existing properties. -* Number of coin types? 2. -* Coin type values? $0.01 and $0.25. -* Material of quarters? 75% copper and 25% nickel. -* Material of pennies? 97.5% zinc and 2.5% copper. - -What **actions** can we perform on the list of lists? This changes the list of lists based on a given operation. -* Select a specific stack of quarters or pennies. -* Select a specific quarter or penny. -* Rearrange the stacks of quarters and pennies. -* Shuffle the stacks together. - -Again, Dynamo has an analagous node for each one of the operations above. Since we're working with abstract data and not physical objects, we need a set of rules to govern how we move up and down the data hierarchy. - -When dealing with lists of lists, the data is layered and complex, but this provides an opportunity to do some awesome parametric operations. Let's break down the fundamentals and discuss a few more operations in the lessons below. - -##Top-Down Hierarchy - -The fundamental concept to learn from this section: **Dynamo treats lists as objects in and of themselves**. This top-down hierarchy is developed with object-oriented programming in mind. Rather than selecting sub-elements with a command like List.GetItemAtIndex, Dynamo will select that index of the main list in the data structure. And that item can be another list. Let's break it down with an example image: - -#### Exercise - Top-Down Hierarchy ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Top-Down-Hierarchy.dyn](datasets/6-3/Top-Down-Hierarchy.dyn). A full list of example files can be found in the Appendix. - -![top-down](images/6-3/top-down.png) ->1. With *code block*, we've defined two ranges:``` -0..2; -0..3; -``` -2. These ranges are connected to a *Point.ByCoordinates* node with lacing set to *"Cross Product"*. This creates a grid of points, and also returns a list of lists as an output. -3. Notice that the *Watch* node gives 3 lists with 4 items in each list. -4. When using *List.GetItemAtIndex*, with an index of 0, Dynamo selects the first list and all of its contents. Other programs may select the first item of every list in the data structure, but Dynamo employs a top-down hierarchy when dealing with data. - -###Flatten and List.Flatten -Flatten removes all tiers of data from a data structure. This is helpful when the data hierarchies are not necessary for your operation, but it can be risky because it removes information. The example below shows the result of flattening a list of data. - -#### Exercise - Flatten ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Flatten.dyn](datasets/6-3/Flatten.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-3/Exercise/Flatten-31.png) -> 1. Insert one line of code to define a range in *code block*:``` --250..-150..#4; -``` -2. Plugging the *code block* into the *x* and *y* input of a *Point.ByCoordinates* node, we set the lacing to *"Cross Product"* to get a grid of points. -3. The *Watch* node shows that we have a list of lists. -4. A *PolyCurve.ByPoints* node will reference each list and create a respective polycurve. Notice in the Dynamo preview that we have four polycurve representing each row in the grid. - -![Exercise](images/6-3/Exercise/Flatten-30.png) ->1. By inserting a *flatten* before the polycurve node, we've created one single list for all of the points. The polycurve node references a list to create one curve, and since all of the points are on one list, we get one zig-zag polycurve which runs throughout the entire list of points. - -There are also options for flattening isolated tiers of data. Using the List.Flatten node, you can define a set number of data tiers to flatten from the top of the hierarchy. This is a really helpful tool if you're struggling with complex data structures which are not necessarily relevant to your workflow. And another option is to use the flatten node as a function in List.Map. We'll discuss [List.Map](#listmap-and-listcombine) more below. - -###Chop -When parametric modeling, there are also times where you'll want to add more data structure to an existing list. There are many nodes available for this as well, and chop is the most basic version. With chop, we can partition a list into sublists with a set number of items. - -#### Exercise - List.Chop ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Chop.dyn](datasets/6-3/Chop.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). - -![Chop](images/6-3/chop-01.jpg) -> A *List.Chop *with a *subLength* of 2 creates 4 lists with 2 items each. - -The chop command divides lists based on a given list length. In some ways, chop is the opposite of flatten: rather than removing data structure, it adds new tiers to it. This is a helpful tool for geometric operations like the example below. - -![Exercise](images/6-3/Exercise/Chop-00.png) - -###List.Map and List.Combine -A List.Map/Combine applies a set function to an input list, but one step down in the hierarchy. Combinations are the same as Maps, except combinations can have multiple inputs corresponding to the input of a given function. - -#### Exercise - List.Map -*Note: This exercise was created with a previous version of Dynamo. Much of the List.Map functionality has been resolved with the addition of the List@Level feature. For more information, see [List@Level](#listlevel) below.* - ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Map.dyn](datasets/6-3/Map.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). - -As a quick introduction, let's review the List.Count node from a previous section. - -![Exercise](images/6-2/count.png) -> The *List.Count* node counts all of the items in a list. We'll use this to demonstrate how *List.Map* works. - -![Exercise](images/6-3/Exercise/A/05.png) -> 1. Insert two lines of code into the *code block*: -``` --50..50..#Nx; --50..50..#Ny; -``` -After typing in this code, the code block will create two inputs for Nx and Ny. -2. With two *integer sliders*, define the *Nx* and *Ny* values by connecting them to the *code block*. -3. Connect each line of the code block into the respective *X* and *Y* inputs of a *Point.ByCoordinates* node. Right click the node, select "Lacing", and choose *"Cross Product"*. This creates a grid of points. Because we defined the range from -50 to 50, we are spanning the default Dynamo grid. -4. A *Watch* node reveals the points created. Notice the data structure. We've created a list of lists. Each list represents a row of points of the grid. - -![Exercise](images/6-3/Exercise/A/04.png) -> 1. Attach a *List.Count* node to the output of the watch node from the previous step. -2. Connect a *Watch* node to the List.Count output. - -Notice that the List.Count node gives a value of 5. This is equal to the "Nx" variable as defined in the code block. Why is this? - -* First, the Point.ByCoordinates node uses the "x" input as the primary input for creating lists. When Nx is 5 and Ny is 3, we get a list of 5 lists, each with 3 items. -* Since Dynamo treats lists as objects in and of themselves, a List.Count node is applied to the main list in the hierarchy. The result is a value of 5, or, the number of lists in the main list. - -![Exercise](images/6-3/Exercise/A/03.png) -> 1. By using a *List.Map* node, we take a step down in the hierarchy and perform a *"function"* at this level. -2. Notice that the *List.Count* node has no input. It is being used as a function, so the *List.Count* node will be applied to every individual list one step down in the hierarchy. The blank input of *List.Count* corresponds to the list input of *List.Map*. -3. The results of *List.Count* now gives a list of 5 items, each with a value of 3. This represents the length of each sublist. - -#### Exercise - List.Combine -*Note: This exercise was created with a previous version of Dynamo. Much of the List.Combine functionality has been resolved with the addition of the List@Level feature. For more information, see [List@Level](#listlevel) below.* - ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Combine.dyn](datasets/6-3/Combine.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). - -In this exercise, we'll use a similar logic to List.Map, but with multiple elements. In this case, we want to divide a list of curves by a unique number of points. - -![Exercise](images/6-3/Exercise/Combine-33.png) -> 1. Using the *code block*, define a range using the syntax: ```..20..#4; -``` and a value of ```20; -``` below that line. -2. Connect the *code block* to two *Point.ByCoordinates* nodes. -3. Create a *Line.ByStartPointEndPoint* from the *Point.ByCoordinates* nodes. -4. The *Watch* node shows four lines. - -![Exercise](images/6-3/Exercise/Combine-32.png) -> 1. Below the graph for line creation, we want to use *code block *to create four distinct ranges to divide the lines uniquely. We do this with the following lines of code: -``` -0..1..#3; -0..1..#4; -0..1..#5; -0..1..#6; -``` -2. With a *List.Create* node, we merge the four lines from the *code block* into one list. -3. The *Watch* node reveals a list of lists. - -![Exercise](images/6-3/Exercise/Combine-31.png) -> 1. *Curve.PointAtParameter* will not work by connecting the lines directly into the *parameter* values. We need to step one level down on the hierarchy. For this, we'll use *List.Combine*. - -![Exercise](images/6-3/Exercise/Combine-30.png) -> By using *List.Combine*, we can successfully divide each line by the given ranges. This gets a little tricky, so we'll break it down in-depth. -1. First, add a *Curve.PointAtParameter* node to the canvas. This will be the *"function" *or *"combinator"* that we apply to *List.Combine* node. More on that in a second. -2. Add a *List.Combine* node to the canvas. Hit the *"+"* or *"-"* to add or subtract inputs. In this case, we'll use the default two inputs on the node. -3. We want to plug the *Curve.PointAtParameter* node into the *"comb"* input of *List.Combine*. And one more important node: be sure to right-click the *"param" *input of *Curve.PointAtParameter* and uncheck *"use default value"*. Default values in Dynamo inputs have to be removed when running a node as a function. In other words, we should consider default values as having additional nodes wired to them. Because of this, we need to remove the default values in this case. -4. We know we have two inputs, the lines and the parameters to create points. But how do we connect them to the *List.Combine* inputs and in what order? -5. The empty inputs of *Curve.PointAtParameter*, from top-to-bottom need to be filled in the combinator in the same order. So, the lines are plugged into *list1* of *List.Combine*. -6. Following suit, the parameter values are plugged into the *list2* input of *List.Combine*. -7. The *Watch* node and the Dynamo preview shows us that we have 4 lines, each divided based on the *code block* ranges. - -### List@Level -An alternative to List.Map, the List@Level feature allows you to directly select which level of list you want to work with right at the input port of the node. This feature can be applied to any incoming input of a node and will allow you access the levels of your lists quicker and easier than other methods. Just tell the node what level of the list you want to use as the input and let the node do the rest. - -#### List@Level Exercise -In this exercise, we will use the List@Level feature to isolate a specific level of data. - -> Download the example file that accompanies this exercise \(Right click and "Save Link As..."\): [List@Level](datasets/6-3/Listatlevel.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). - -![List@Level](images/6-3/Exercise/ListAtLevel-01.png) ->1. We will start with a simple 3D grid of points. -2. Since the grid is constructed with a Range for X, Y and Z, we know that the data is structured with 3 tiers: an X List, Y List and Z List. -3. These tiers exist at different **Levels**. The Levels are indicated at the bottom of the Preview Bubble. The list Levels columns correspond to the list data above to help identify which level to work within. -4. The List Levels are organized in reverse order so that the lowest level data is always in “L1”. This will help ensure that your graphs will work as planned, even if anything is changed upstream. - -![List@Level](images/6-3/Exercise/ListAtLevel-02.png) ->1. To use the List@Level function, click '>'. Inside this menu, you will see two checkboxes. -2. **Use Levels** - This enables the List@Level functionality. After clicking on this option, you will be able to click through and select the input list levels you want the node to use. With this menu, you can quickly try out different level options by clicking up or down. -3. **Keep list structure** – If enabled, you will have the option to keep that input’s level structure. Sometimes, you may have purposefully organized your data into sublists. By checking this option, you can keep your list organization intact and not lose any information. - -With our simple 3D grid, we can access and visualize the list structure by toggling through the List Levels. Each List Level and index combination will return a different set of points from our original 3D set. - -![List@Level](images/6-3/Exercise/ListAtLevel-03.png) ->1. “@L2” in DesignScript allows us to select only the List at Level 2. -2. The List at Level 2 with the index 0 includes only the first set of Y points, returning only the XZ grid. -3. If we change the Level filter to “L1”, we will be able to see everything in the first List Level. The List at Level 1 with the index 0 includes all of our 3D points in a flat list. -4. If we try the same for “L3” we will see only the third List Level points. The List at Level 3 with the index 0 includes only the first set of Z points, returning only an XY grid. -5. If we try the same for “L4” we will see only the third List Level points. The List at Level 4 with the index 0 includes only the first set of X points, returning only an YZ grid. - -Although this particular example can also be created with List.Map, List@Level greatly simplifies the interaction, making it easy to access the node data. Take a look below at a comparison between a List.Map and List@Level methods: - -![List@Level-vs-ListMap](images/6-3/Exercise/listAtLevel_comparison.png) ->1. Although both methods will give us access to the same points, the List@Level method allows us to easily toggle between layers of data within a single node. -2. To access a point grid with List.Map, we will need a List.GetItemAtIndex node alongside the List.Map. For every list level that we are stepping down, we will need to use an additional List.Map node. Depending on the complexity of your lists, this could require you to add a significant amount of List.Map Nodes to your graph to access the right level of information. -3. In this example, a List.GetItemAtIndex node with a List.Map node reurns the same set of points with the same list structure as the List.GetItemAtIndex with '@L3' selected. - -###Transpose -Transpose is a fundamental function when dealing with lists of lists. Just as in spreadsheet programs, a transpose flips the columns and rows of a data structure. We'll demonstrate this with a basic matrix below, and in the following section, we'll demonstrate how a transpose can be use to create geometric relationships. - -![Transpose](images/6-3/transpose1.jpg) - -#### Exercise - List.Transpose ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Transpose.dyn](datasets/6-3/Transpose.dyn). A full list of example files can be found in the Appendix. - -![Exercise](images/6-3/Exercise/A/02.png) -> Let's delete the *List.Count* nodes from the previous exercise and move on to some geometry to see how the data structured. -1. Connect a *PolyCurve.ByPoints* to the output of the watch node from *Point.ByCoordinates*. -2. The output shows 5 polycurves, and we can see the curves in our Dynamo preview. The Dynamo node is looking for a list of points (or a list of lists of points in this case) and creating a single polycurve from them. Essentially, each list has converted to a curve in the data structure. - -![Exercise](images/6-3/Exercise/A/01.png) -> 1. If we want to isolate one row of curves, we use the *List.GetItemAtIndex* node. -2. Using a *code block* value of 2, query the 3rd element in the main list. -3. The *PolyCurve.ByPoints* gives us one curve, since only one list is connected to the node. - -![Exercise](images/6-3/Exercise/A/00.png) -> 1. A *List.Transpose* node will switch all of the items with all of the lists in a list of lists. This sounds complicated, but it's the same logic as transpose in Microsoft Excel: switching columns with rows in a data structure. -2. Notice the abstract result: the transpose changed the list structure from a 5 lists with 3 items each to 3 lists with 5 items each. -3. Notice the geometric result: using *PolyCurve.ByPoints*, we get 3 polycurves in the perpendicular direction to the original curves. - -###Code Block Creation -Code block shorthand uses "{}" to define a list. This is a much faster and more fluid way to create list than the List.Create node. Code block is discussed in more detail in Chapter 7. Reference the image below to note how a list with multiple expressions can be defined with code block. - -![CB](images/6-3/cbCreation.png) - - -###Code Block Query -Code block shorthand is uses "[]" as a quick and easy way to select specific items that you want from a complex data structure. Code blocks are discussed in more detail in Chapter 7. Reference the image below to note how a list with multiple data types can be queried with code block. - -![CB](images/6-3/cbQuery.png) - -###Exercise - Querying and Inserting Data ->Download the example file that accompanies this exercise (Right click and "Save Link As..."): [ReplaceItems.dyn](datasets/6-3/ReplaceItems.dyn). A full list of example files can be found in the Appendix. - -This exercise uses some of the logic established in the previous one to edit a surface. Our goal here is intuitive, but the data structure navigation will be more involved. We want to articulate a surface by moving a control point. - -![Exercise](images/6-3/Exercise/B/06.png) -> 1. Begin with the string of nodes above. We are creating a basic surface which spans the default Dynamo grid. -2. Using *code block*, insert these two lines of code and connect to the *u* and *v* inputs of *Surface.PointAtParameter*, respectively: -``` --50..50..#3; --50..50..#5; -``` -3. Be sure to set the Lacing of *Surface.PointAtParameter* to *"Cross Product"*. -4. The *Watch* node show that we have a list of 3 lists, each with 5 items. - -![Exercise](images/6-3/Exercise/B/05.png) -> In this step, we want to query the central point in the grid we've created. To do this we'll select the middle point in the middle list. Makes sense, right? -1. To confirm that this is the correct point, we can also click through the watch node items to confirm that we're targeting the correct one. -2. Using *code block*, we'll write a basic line of code for querying a list of lists: -```points[1][2];``` -3. Using *Geometry.Translate*, we'll move the selected point up in the *Z* direction by *20* units. - -![Exercise](images/6-3/Exercise/B/04.png) -> 1. Let's also select the middle row of points with a *List.GetItemAtIndex* node. Note: Similar to a previous step, we can also query the list with *code block*, using a line of ```points[1];``` - -![Exercise](images/6-3/Exercise/B/03.png) -> So far we've successfully queried the center point and moved it upward. Now we want need to insert this moved point back into the original data structure. -1. First, we want to replace the item of the list we isolated in a previous step. -2. Using *List.ReplaceItemAtIndex*, we'll replace the middle item by using and index of *"2"*, with the replacement item connected to the moved point (*Geometry.Translate*). -3. The output shows that we've input the moved point into the middle item of the list. - -![Exercise](images/6-3/Exercise/B/02.png) -> Now that we've modified the list, we need to insert this list back into the original data structure: the list of lists. -1. Following the same logic, use *List.ReplaceItemAtIndex* to replace the middle list with the our modified list. -2. Notice that the *code blocks* defining the index for these two nodes are 1 and 2, which matches the original query from the *code block* (*points[1][2]*). -3. By selecting the list at *index 1*, we see the data structure highlighted in the Dynamo preview. We successfully merged the moved point into the original data structure. - -![Exercise](images/6-3/Exercise/B/01.png) -> There are many ways to make a surface from this set of points. In this case, we're going to create a surface by lofting curves together. -1. Create a *NurbsCurve.ByPoints* node and connect the new data structure to create three nurbs curves. - -![Exercise](images/6-3/Exercise/B/00.png) -> 1. Connect a *Surface.ByLoft* to the output from *NurbsCurve.ByPoints*. We now have a modified surface. We can change the original *Z* value of Geometry. Translate and watch the geometry update! - - - - - - - - - - - - - - +## Lists of Lists +Let's add one more tier to the hierarchy. If we take the deck of cards from the original example and create a box which contains multiple decks, the box now represents a list of decks, and each deck represents a list of cards. This is a list of lists. For the analogy in this section, the red box below contains a list of coin rolls, and each roll contains a list of pennies. + +![Coins](images/6-3/coins-521245_640.jpg) +> Photo by [Dori](https://commons.wikimedia.org/wiki/File:Stack_of_coins_0214.jpg). + +What **queries** can we make from the list of lists? This accesses existing properties. +* Number of coin types? 2. +* Coin type values? $0.01 and $0.25. +* Material of quarters? 75% copper and 25% nickel. +* Material of pennies? 97.5% zinc and 2.5% copper. + +What **actions** can we perform on the list of lists? This changes the list of lists based on a given operation. +* Select a specific stack of quarters or pennies. +* Select a specific quarter or penny. +* Rearrange the stacks of quarters and pennies. +* Shuffle the stacks together. + +Again, Dynamo has an analagous node for each one of the operations above. Since we're working with abstract data and not physical objects, we need a set of rules to govern how we move up and down the data hierarchy. + +When dealing with lists of lists, the data is layered and complex, but this provides an opportunity to do some awesome parametric operations. Let's break down the fundamentals and discuss a few more operations in the lessons below. + +##Top-Down Hierarchy + +The fundamental concept to learn from this section: **Dynamo treats lists as objects in and of themselves**. This top-down hierarchy is developed with object-oriented programming in mind. Rather than selecting sub-elements with a command like List.GetItemAtIndex, Dynamo will select that index of the main list in the data structure. And that item can be another list. Let's break it down with an example image: + +#### Exercise - Top-Down Hierarchy +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Top-Down-Hierarchy.dyn](datasets/6-3/Top-Down-Hierarchy.dyn). A full list of example files can be found in the Appendix. + +![top-down](images/6-3/top-down.png) +>1. With *code block*, we've defined two ranges:``` +0..2; +0..3; +``` +2. These ranges are connected to a *Point.ByCoordinates* node with lacing set to *"Cross Product"*. This creates a grid of points, and also returns a list of lists as an output. +3. Notice that the *Watch* node gives 3 lists with 4 items in each list. +4. When using *List.GetItemAtIndex*, with an index of 0, Dynamo selects the first list and all of its contents. Other programs may select the first item of every list in the data structure, but Dynamo employs a top-down hierarchy when dealing with data. + +###Flatten and List.Flatten +Flatten removes all tiers of data from a data structure. This is helpful when the data hierarchies are not necessary for your operation, but it can be risky because it removes information. The example below shows the result of flattening a list of data. + +#### Exercise - Flatten +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Flatten.dyn](datasets/6-3/Flatten.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-3/Exercise/Flatten-31.png) +> 1. Insert one line of code to define a range in *code block*:``` +-250..-150..#4; +``` +2. Plugging the *code block* into the *x* and *y* input of a *Point.ByCoordinates* node, we set the lacing to *"Cross Product"* to get a grid of points. +3. The *Watch* node shows that we have a list of lists. +4. A *PolyCurve.ByPoints* node will reference each list and create a respective polycurve. Notice in the Dynamo preview that we have four polycurve representing each row in the grid. + +![Exercise](images/6-3/Exercise/Flatten-30.png) +>1. By inserting a *flatten* before the polycurve node, we've created one single list for all of the points. The polycurve node references a list to create one curve, and since all of the points are on one list, we get one zig-zag polycurve which runs throughout the entire list of points. + +There are also options for flattening isolated tiers of data. Using the List.Flatten node, you can define a set number of data tiers to flatten from the top of the hierarchy. This is a really helpful tool if you're struggling with complex data structures which are not necessarily relevant to your workflow. And another option is to use the flatten node as a function in List.Map. We'll discuss [List.Map](#listmap-and-listcombine) more below. + +###Chop +When parametric modeling, there are also times where you'll want to add more data structure to an existing list. There are many nodes available for this as well, and chop is the most basic version. With chop, we can partition a list into sublists with a set number of items. + +#### Exercise - List.Chop +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Chop.dyn](datasets/6-3/Chop.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). + +![Chop](images/6-3/chop-01.jpg) +> A *List.Chop *with a *subLength* of 2 creates 4 lists with 2 items each. + +The chop command divides lists based on a given list length. In some ways, chop is the opposite of flatten: rather than removing data structure, it adds new tiers to it. This is a helpful tool for geometric operations like the example below. + +![Exercise](images/6-3/Exercise/Chop-00.png) + +###List.Map and List.Combine +A List.Map/Combine applies a set function to an input list, but one step down in the hierarchy. Combinations are the same as Maps, except combinations can have multiple inputs corresponding to the input of a given function. + +#### Exercise - List.Map +*Note: This exercise was created with a previous version of Dynamo. Much of the List.Map functionality has been resolved with the addition of the List@Level feature. For more information, see [List@Level](#listlevel) below.* + +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Map.dyn](datasets/6-3/Map.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). + +As a quick introduction, let's review the List.Count node from a previous section. + +![Exercise](images/6-2/count.png) +> The *List.Count* node counts all of the items in a list. We'll use this to demonstrate how *List.Map* works. + +![Exercise](images/6-3/Exercise/A/05.png) +> 1. Insert two lines of code into the *code block*: +``` +-50..50..#Nx; +-50..50..#Ny; +``` +After typing in this code, the code block will create two inputs for Nx and Ny. +2. With two *integer sliders*, define the *Nx* and *Ny* values by connecting them to the *code block*. +3. Connect each line of the code block into the respective *X* and *Y* inputs of a *Point.ByCoordinates* node. Right click the node, select "Lacing", and choose *"Cross Product"*. This creates a grid of points. Because we defined the range from -50 to 50, we are spanning the default Dynamo grid. +4. A *Watch* node reveals the points created. Notice the data structure. We've created a list of lists. Each list represents a row of points of the grid. + +![Exercise](images/6-3/Exercise/A/04.png) +> 1. Attach a *List.Count* node to the output of the watch node from the previous step. +2. Connect a *Watch* node to the List.Count output. + +Notice that the List.Count node gives a value of 5. This is equal to the "Nx" variable as defined in the code block. Why is this? + +* First, the Point.ByCoordinates node uses the "x" input as the primary input for creating lists. When Nx is 5 and Ny is 3, we get a list of 5 lists, each with 3 items. +* Since Dynamo treats lists as objects in and of themselves, a List.Count node is applied to the main list in the hierarchy. The result is a value of 5, or, the number of lists in the main list. + +![Exercise](images/6-3/Exercise/A/03.png) +> 1. By using a *List.Map* node, we take a step down in the hierarchy and perform a *"function"* at this level. +2. Notice that the *List.Count* node has no input. It is being used as a function, so the *List.Count* node will be applied to every individual list one step down in the hierarchy. The blank input of *List.Count* corresponds to the list input of *List.Map*. +3. The results of *List.Count* now gives a list of 5 items, each with a value of 3. This represents the length of each sublist. + +#### Exercise - List.Combine +*Note: This exercise was created with a previous version of Dynamo. Much of the List.Combine functionality has been resolved with the addition of the List@Level feature. For more information, see [List@Level](#listlevel) below.* + +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Combine.dyn](datasets/6-3/Combine.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). + +In this exercise, we'll use a similar logic to List.Map, but with multiple elements. In this case, we want to divide a list of curves by a unique number of points. + +![Exercise](images/6-3/Exercise/Combine-33.png) +> 1. Using the *code block*, define a range using the syntax: ```..20..#4; +``` and a value of ```20; +``` below that line. +2. Connect the *code block* to two *Point.ByCoordinates* nodes. +3. Create a *Line.ByStartPointEndPoint* from the *Point.ByCoordinates* nodes. +4. The *Watch* node shows four lines. + +![Exercise](images/6-3/Exercise/Combine-32.png) +> 1. Below the graph for line creation, we want to use *code block *to create four distinct ranges to divide the lines uniquely. We do this with the following lines of code: +``` +0..1..#3; +0..1..#4; +0..1..#5; +0..1..#6; +``` +2. With a *List.Create* node, we merge the four lines from the *code block* into one list. +3. The *Watch* node reveals a list of lists. + +![Exercise](images/6-3/Exercise/Combine-31.png) +> 1. *Curve.PointAtParameter* will not work by connecting the lines directly into the *parameter* values. We need to step one level down on the hierarchy. For this, we'll use *List.Combine*. + +![Exercise](images/6-3/Exercise/Combine-30.png) +> By using *List.Combine*, we can successfully divide each line by the given ranges. This gets a little tricky, so we'll break it down in-depth. +1. First, add a *Curve.PointAtParameter* node to the canvas. This will be the *"function" *or *"combinator"* that we apply to *List.Combine* node. More on that in a second. +2. Add a *List.Combine* node to the canvas. Hit the *"+"* or *"-"* to add or subtract inputs. In this case, we'll use the default two inputs on the node. +3. We want to plug the *Curve.PointAtParameter* node into the *"comb"* input of *List.Combine*. And one more important node: be sure to right-click the *"param" *input of *Curve.PointAtParameter* and uncheck *"use default value"*. Default values in Dynamo inputs have to be removed when running a node as a function. In other words, we should consider default values as having additional nodes wired to them. Because of this, we need to remove the default values in this case. +4. We know we have two inputs, the lines and the parameters to create points. But how do we connect them to the *List.Combine* inputs and in what order? +5. The empty inputs of *Curve.PointAtParameter*, from top-to-bottom need to be filled in the combinator in the same order. So, the lines are plugged into *list1* of *List.Combine*. +6. Following suit, the parameter values are plugged into the *list2* input of *List.Combine*. +7. The *Watch* node and the Dynamo preview shows us that we have 4 lines, each divided based on the *code block* ranges. + +### List@Level +An alternative to List.Map, the List@Level feature allows you to directly select which level of list you want to work with right at the input port of the node. This feature can be applied to any incoming input of a node and will allow you access the levels of your lists quicker and easier than other methods. Just tell the node what level of the list you want to use as the input and let the node do the rest. + +#### List@Level Exercise +In this exercise, we will use the List@Level feature to isolate a specific level of data. + +> Download the example file that accompanies this exercise \(Right click and "Save Link As..."\): [List@Level](datasets/6-3/Listatlevel.dyn). A full list of example files can be found in the [Appendix](../Appendix/A_appendix.md). + +![List@Level](images/6-3/Exercise/ListAtLevel-01.png) +>1. We will start with a simple 3D grid of points. +2. Since the grid is constructed with a Range for X, Y and Z, we know that the data is structured with 3 tiers: an X List, Y List and Z List. +3. These tiers exist at different **Levels**. The Levels are indicated at the bottom of the Preview Bubble. The list Levels columns correspond to the list data above to help identify which level to work within. +4. The List Levels are organized in reverse order so that the lowest level data is always in “L1”. This will help ensure that your graphs will work as planned, even if anything is changed upstream. + +![List@Level](images/6-3/Exercise/ListAtLevel-02.png) +>1. To use the List@Level function, click '>'. Inside this menu, you will see two checkboxes. +2. **Use Levels** - This enables the List@Level functionality. After clicking on this option, you will be able to click through and select the input list levels you want the node to use. With this menu, you can quickly try out different level options by clicking up or down. +3. **Keep list structure** – If enabled, you will have the option to keep that input’s level structure. Sometimes, you may have purposefully organized your data into sublists. By checking this option, you can keep your list organization intact and not lose any information. + +With our simple 3D grid, we can access and visualize the list structure by toggling through the List Levels. Each List Level and index combination will return a different set of points from our original 3D set. + +![List@Level](images/6-3/Exercise/ListAtLevel-03.png) +>1. “@L2” in DesignScript allows us to select only the List at Level 2. +2. The List at Level 2 with the index 0 includes only the first set of Y points, returning only the XZ grid. +3. If we change the Level filter to “L1”, we will be able to see everything in the first List Level. The List at Level 1 with the index 0 includes all of our 3D points in a flat list. +4. If we try the same for “L3” we will see only the third List Level points. The List at Level 3 with the index 0 includes only the first set of Z points, returning only an XY grid. +5. If we try the same for “L4” we will see only the third List Level points. The List at Level 4 with the index 0 includes only the first set of X points, returning only an YZ grid. + +Although this particular example can also be created with List.Map, List@Level greatly simplifies the interaction, making it easy to access the node data. Take a look below at a comparison between a List.Map and List@Level methods: + +![List@Level-vs-ListMap](images/6-3/Exercise/listAtLevel_comparison.png) +>1. Although both methods will give us access to the same points, the List@Level method allows us to easily toggle between layers of data within a single node. +2. To access a point grid with List.Map, we will need a List.GetItemAtIndex node alongside the List.Map. For every list level that we are stepping down, we will need to use an additional List.Map node. Depending on the complexity of your lists, this could require you to add a significant amount of List.Map Nodes to your graph to access the right level of information. +3. In this example, a List.GetItemAtIndex node with a List.Map node reurns the same set of points with the same list structure as the List.GetItemAtIndex with '@L3' selected. + +###Transpose +Transpose is a fundamental function when dealing with lists of lists. Just as in spreadsheet programs, a transpose flips the columns and rows of a data structure. We'll demonstrate this with a basic matrix below, and in the following section, we'll demonstrate how a transpose can be use to create geometric relationships. + +![Transpose](images/6-3/transpose1.jpg) + +#### Exercise - List.Transpose +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [Transpose.dyn](datasets/6-3/Transpose.dyn). A full list of example files can be found in the Appendix. + +![Exercise](images/6-3/Exercise/A/02.png) +> Let's delete the *List.Count* nodes from the previous exercise and move on to some geometry to see how the data structured. +1. Connect a *PolyCurve.ByPoints* to the output of the watch node from *Point.ByCoordinates*. +2. The output shows 5 polycurves, and we can see the curves in our Dynamo preview. The Dynamo node is looking for a list of points (or a list of lists of points in this case) and creating a single polycurve from them. Essentially, each list has converted to a curve in the data structure. + +![Exercise](images/6-3/Exercise/A/01.png) +> 1. If we want to isolate one row of curves, we use the *List.GetItemAtIndex* node. +2. Using a *code block* value of 2, query the 3rd element in the main list. +3. The *PolyCurve.ByPoints* gives us one curve, since only one list is connected to the node. + +![Exercise](images/6-3/Exercise/A/00.png) +> 1. A *List.Transpose* node will switch all of the items with all of the lists in a list of lists. This sounds complicated, but it's the same logic as transpose in Microsoft Excel: switching columns with rows in a data structure. +2. Notice the abstract result: the transpose changed the list structure from a 5 lists with 3 items each to 3 lists with 5 items each. +3. Notice the geometric result: using *PolyCurve.ByPoints*, we get 3 polycurves in the perpendicular direction to the original curves. + +###Code Block Creation +Code block shorthand uses "{}" to define a list. This is a much faster and more fluid way to create list than the List.Create node. Code block is discussed in more detail in Chapter 7. Reference the image below to note how a list with multiple expressions can be defined with code block. + +![CB](images/6-3/cbCreation.png) + + +###Code Block Query +Code block shorthand is uses "[]" as a quick and easy way to select specific items that you want from a complex data structure. Code blocks are discussed in more detail in Chapter 7. Reference the image below to note how a list with multiple data types can be queried with code block. + +![CB](images/6-3/cbQuery.png) + +###Exercise - Querying and Inserting Data +>Download the example file that accompanies this exercise (Right click and "Save Link As..."): [ReplaceItems.dyn](datasets/6-3/ReplaceItems.dyn). A full list of example files can be found in the Appendix. + +This exercise uses some of the logic established in the previous one to edit a surface. Our goal here is intuitive, but the data structure navigation will be more involved. We want to articulate a surface by moving a control point. + +![Exercise](images/6-3/Exercise/B/06.png) +> 1. Begin with the string of nodes above. We are creating a basic surface which spans the default Dynamo grid. +2. Using *code block*, insert these two lines of code and connect to the *u* and *v* inputs of *Surface.PointAtParameter*, respectively: +``` +-50..50..#3; +-50..50..#5; +``` +3. Be sure to set the Lacing of *Surface.PointAtParameter* to *"Cross Product"*. +4. The *Watch* node show that we have a list of 3 lists, each with 5 items. + +![Exercise](images/6-3/Exercise/B/05.png) +> In this step, we want to query the central point in the grid we've created. To do this we'll select the middle point in the middle list. Makes sense, right? +1. To confirm that this is the correct point, we can also click through the watch node items to confirm that we're targeting the correct one. +2. Using *code block*, we'll write a basic line of code for querying a list of lists: +```points[1][2];``` +3. Using *Geometry.Translate*, we'll move the selected point up in the *Z* direction by *20* units. + +![Exercise](images/6-3/Exercise/B/04.png) +> 1. Let's also select the middle row of points with a *List.GetItemAtIndex* node. Note: Similar to a previous step, we can also query the list with *code block*, using a line of ```points[1];``` + +![Exercise](images/6-3/Exercise/B/03.png) +> So far we've successfully queried the center point and moved it upward. Now we want need to insert this moved point back into the original data structure. +1. First, we want to replace the item of the list we isolated in a previous step. +2. Using *List.ReplaceItemAtIndex*, we'll replace the middle item by using and index of *"2"*, with the replacement item connected to the moved point (*Geometry.Translate*). +3. The output shows that we've input the moved point into the middle item of the list. + +![Exercise](images/6-3/Exercise/B/02.png) +> Now that we've modified the list, we need to insert this list back into the original data structure: the list of lists. +1. Following the same logic, use *List.ReplaceItemAtIndex* to replace the middle list with the our modified list. +2. Notice that the *code blocks* defining the index for these two nodes are 1 and 2, which matches the original query from the *code block* (*points[1][2]*). +3. By selecting the list at *index 1*, we see the data structure highlighted in the Dynamo preview. We successfully merged the moved point into the original data structure. + +![Exercise](images/6-3/Exercise/B/01.png) +> There are many ways to make a surface from this set of points. In this case, we're going to create a surface by lofting curves together. +1. Create a *NurbsCurve.ByPoints* node and connect the new data structure to create three nurbs curves. + +![Exercise](images/6-3/Exercise/B/00.png) +> 1. Connect a *Surface.ByLoft* to the output from *NurbsCurve.ByPoints*. We now have a modified surface. We can change the original *Z* value of Geometry. Translate and watch the geometry update! + + + + + + + + + + + + + + diff --git a/06_Designing-with-Lists/6-4_n-dimensional-lists.md b/06_Designing-with-Lists/6-4_n-dimensional-lists.md index a78bc6d1..faddb64a 100644 --- a/06_Designing-with-Lists/6-4_n-dimensional-lists.md +++ b/06_Designing-with-Lists/6-4_n-dimensional-lists.md @@ -1,168 +1,168 @@ -## n-Dimensional Lists -Further down the rabbit-hole, let's add even more tiers to hierarchy. Data structure can expand far beyond a two-dimensional list of lists. Since lists are items in and of themselves in Dynamo, we can create data with as many dimensions as possible. - -The analogy we'll work with here are Russian Nesting Dolls. Each list can be regarded as one container holding multiple items. Each list has its own properties and is also regarded as its own object. - -![Dolls](images/6-4/145493363_fc9ff5164f_o.jpg) -> A set of Russian Nesting Dolls (Photo by [Zeta](https://www.flickr.com/photos/beppezizzi/145493363)) is an analogy for n-Dimensional lists. Each layer represents a list, and each list contains items within it. In Dynamo's case, each container can have multiple containers inside (representing the items of each list). - -n-Dimensional lists are difficult to explain visually, but we've set up a few exercises in this chapter which focus on working with lists which venture beyond two dimensions. - -##Mapping and Combinations -Mapping is arguably the most complex part of data management in Dynamo, and is especially relevant when working with complex hierarchies of lists. With the series of exercises below, we'll demonstrate when to use mapping and combinations as data becomes multi-dimensional. - -Preliminary introductions to List.Map and List.Combine can be found in the previous section. In the last exercise below, we'll use these nodes on a complex data structure. - -###Exercise - 2D Lists - Basic ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1.[n-Dimensional-Lists.dyn](datasets/6-4/n-Dimensional-Lists.dyn) -2.[n-Dimensional-Lists.sat](datasets/6-4/n-Dimensional-Lists.sat) - - -This exercise is the first in a series of three which focuses on articulating imported geometry. Each part in this series of exercises will increase in the complexity of data structure. - -![Exercise](images/6-4/Exercise/A/04.png) -> 1. Let's begin with the .sat file in the exercise file folder. We can grab this file using the *File Path* node. -2. With *Geometry.ImportFromSAT*, the geometry is imported into our Dynamo preview as two surfaces. - -![Exercise](images/6-4/Exercise/A/03.png) -> For this exercise, we want to keep it simple and work with one of the surfaces. -1. Let's select the index of *1 *to grab the upper surface. We do this with *List.GetItemAtIndex* node. - -![Exercise](images/6-4/Exercise/A/02.png) -> The next step is to divide the surface into a grid of points. -1. Using *code block*, insert these two lines of code: -``` -0..1..#10; -0..1..#5; -``` -2. With the *Surface.PointAtParameter*, connect the two code block values to *u *and *v*. Change the *lacing* of this node to *"Cross Product"*. -3. The output reveals the data structure, which is also visible in the Dynamo preview. - -![Exercise](images/6-4/Exercise/A/01.png) -> 1. To get a look at how the data structure is organized, let's connect a *NurbsCurve.ByPoints* to the output of *Surface.PointAtParameter*. -2. Notice we have ten curves running vertically along the surface. - -![Exercise](images/6-4/Exercise/A/00.png) -> 1. A basic *List.Transpose* will flip the columns and rows of a list of lists. -2. Connecting the output of *List.Transpose* to *NurbsCurve.ByPoints*, we now get five curves running horizontally across the surface. - - -###Exercise - 2D Lists - Advanced -Let's increase the complexity. Suppose we wanted to perform an operation on the curves created from the previous exercise. Perhaps we want to relate these curves to another surface and loft between them. This requires more attention to data structure, but the underlying logic is the same. - -![Exercise](images/6-4/Exercise/B/07.png) -> 1. Begin with a step from the previous exercise, isolating the upper surface of the imported geometry with the *List.GetItemAtIndex* node. - -![Exercise](images/6-4/Exercise/B/06.png) -> 1. Using *Surface.Offset*, offset the surface by a value of *10*. - -![Exercise](images/6-4/Exercise/B/05.png) -> 1. In the same manner as the previous exercise, define a *code block* with these two lines of code: -``` -0..1..#10; -0..1..#5; -``` -2. Connect these outputs to two *Surface.PointAtParameter *nodes, each with *lacing* set to *"Cross Product"*. One of these nodes is connected to the original surface, while the other is connected to the offset surface. - -![Exercise](images/6-4/Exercise/B/04.png) -> 1. As in the previous exercise, connect the outputs to two *NurbsCurve.ByPoints* nodes. -2. Our Dynamo preview shows two curves, corresponding to two surfaces. - -![Exercise](images/6-4/Exercise/B/03.png) -> 1. By using *List.Create*, we can combine the two sets of curves into one list of lists. -2. Notice from the output, we have two lists with ten items each, representing each connect set of nurbs curves. -3. By performing a *Surface.ByLoft*, we can visually make sense of this data structure. The node lofts all of the curves in each sublist. - -![Exercise](images/6-4/Exercise/B/02.png) -> 1. By using *List.Transpose*, remember, we are flipping all of the columns and rows. This node will transfer two lists of ten curves into ten lists of two curves. We now have each nurbs curve related to the neighboring curve on the other surface. -2. Using *Surface.ByLoft*, we arrive at a ribbed structure. - -![Exercise](images/6-4/Exercise/B/01.png) -> 1. An alternative to *List.Transpose* uses *List.Combine*. This will operate a *"combinator"* on each sublist. -2. In this case, we're using *List.Create *as the *"combinator"*, which will create a list of each item in the sublists. -3. Using the *Surface.ByLoft* node, we get the same surfaces as in the previous step. Transpose is easier to use in this case, but when the data structure becomes even more complex, *List.Combine* is more reliable. - -![Exercise](images/6-4/Exercise/B/00.png) -> 1. Stepping back a few steps, if we want to switch the orientation of the curves in the ribbed structure, we want to use a List.Transpose before connect to *NurbsCurve.ByPoints*. This will flip the columns and rows, giving us 5 horizontal ribs. - - -###Exercise - 3D Lists -Now, we're going to go even one step further. In this exercise, we'll work with both imported surfaces, creating a complex data hierarchy. Still, our aim is to complete the same operation with the same underlying logic. - -![Exercise](images/6-4/Exercise/C/12.png) -> 1. Begin with the imported file from previous exercise. - -![Exercise](images/6-4/Exercise/C/11.png) -> 1. As in the previous exercise, use the *Surface.Offset* node to offset by a value of *10*. -2. Notice from the output, that we've created two surfaces with the offset node. - -![Exercise](images/6-4/Exercise/C/10.png) -> 1. In the same manner as the previous exercise, define a code block with these two lines of code: -``` -0..1..#20; -0..1..#10; -``` -2. Connect these outputs to two *Surface.PointAtParameter* nodes, each with lacing set to *"Cross Product"*. One of these nodes is connected to the original surfaces, while the other is connected to the offset surfaces. - -![Exercise](images/6-4/Exercise/C/09.png) -> 1. As in the previous exercise, connect the outputs to two *NurbsCurve.ByPoints* nodes. -2. Looking at the output of the *NurbsCurve.ByPoints*, notice that this is a list of two lists, which is more complex than the previous exercise. The data is categorized by the underlying surface, so we've added another tier to the data structured. -3. Notice that things become more complex in the *Surface.PointAtParameter* node. In this case we have a list of lists of lists. - -![Exercise](images/6-4/Exercise/C/08.png) -> 1. Using the *List.Create* node, we merge the nurbs curves into one data structure, creating a list of lists of lists. -2. By connecting a *Surface.ByLoft* node, we get a version of the original surfaces, as they each remain in their own list as created from the original data structure. - -![Exercise](images/6-4/Exercise/C/07.png) -> 1. In the previous exercise, we were able to use a *List.Transpose* to create a ribbed structure. This won't work here. A transpose should be used on a two-dimensional list, and since we have a three-dimensional list, an operation of "flipping columns and rows" won't work as easily. Remember, lists are objects, so *List.Transpose* will flip our lists with out sublists, but won't flip the nurbs curves one list further down in the hierarchy. - -![Exercise](images/6-4/Exercise/C/06.png) -> 1. *List.Combine* will work better for us here. We want to use *List.Map* and *List.Combine* nodes when we get to more complex data structures. -2. Using *List.Create *as the *"combinator"*, we create a data structure that will work better for us. - -![Exercise](images/6-4/Exercise/C/05.png) -> 1. The data structure still needs to be transposed at one step down on the hierarchy. To do this we'll use *List.Map*. This is working like *List.Combine*, except with one input list, rather than two or more. -2. The function we'll apply to *List.Map* is *List.Transpose*, which will flip the columns and rows of the sublists within our main list. - -![Exercise](images/6-4/Exercise/C/04.png) -> 1. Finally, we can loft the nurbs curves together with a proper data hierarchy, giving us a ribbed structure. - -![Exercise](images/6-4/Exercise/C/03.png) -> 1. Let's add some depth to the geometry with a *Surface.Thicken* node. - -![Exercise](images/6-4/Exercise/C/02.png) -> 1. It'll be nice to add a surface backing two this structure, so we'll use *List.GetItemAtIndex* to select the back surface from the lofted surfaces from the previous steps. - -![Exercise](images/6-4/Exercise/C/01.png) -> 1. And thickening these selected surfaces, our articulation is complete. - -![Exercise](images/6-4/Exercise/C/00.png) -> Not the most comfortable rocking chair ever, but it's got a lot of data going on. - -![Exercise](images/6-4/Exercise/C/32.png) -> Last step, let's reverse the direction of the striated members. As we used transpose in the previous exercise, we'll do something similar here. -1. Since we have one more tier to the hierarchy, so we need to use *List.Map* with a *List.Tranpose* function to change the direction of our nurbs curves. - -![Exercise](images/6-4/Exercise/C/31.png) -> 1. We may want to increase the number of treads, so we can change the code block to -``` -0..1..#20; -0..1..#10; -``` - -![Exercise](images/6-4/Exercise/C/30.png) -> The first version of the rocking chair was sleek, so our second model offers an off-road, sport-utility version of recumbency. - - - - - - - - - - - - - +## n-Dimensional Lists +Further down the rabbit-hole, let's add even more tiers to hierarchy. Data structure can expand far beyond a two-dimensional list of lists. Since lists are items in and of themselves in Dynamo, we can create data with as many dimensions as possible. + +The analogy we'll work with here are Russian Nesting Dolls. Each list can be regarded as one container holding multiple items. Each list has its own properties and is also regarded as its own object. + +![Dolls](images/6-4/145493363_fc9ff5164f_o.jpg) +> A set of Russian Nesting Dolls (Photo by [Zeta](https://www.flickr.com/photos/beppezizzi/145493363)) is an analogy for n-Dimensional lists. Each layer represents a list, and each list contains items within it. In Dynamo's case, each container can have multiple containers inside (representing the items of each list). + +n-Dimensional lists are difficult to explain visually, but we've set up a few exercises in this chapter which focus on working with lists which venture beyond two dimensions. + +##Mapping and Combinations +Mapping is arguably the most complex part of data management in Dynamo, and is especially relevant when working with complex hierarchies of lists. With the series of exercises below, we'll demonstrate when to use mapping and combinations as data becomes multi-dimensional. + +Preliminary introductions to List.Map and List.Combine can be found in the previous section. In the last exercise below, we'll use these nodes on a complex data structure. + +###Exercise - 2D Lists - Basic +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1.[n-Dimensional-Lists.dyn](datasets/6-4/n-Dimensional-Lists.dyn) +2.[n-Dimensional-Lists.sat](datasets/6-4/n-Dimensional-Lists.sat) + + +This exercise is the first in a series of three which focuses on articulating imported geometry. Each part in this series of exercises will increase in the complexity of data structure. + +![Exercise](images/6-4/Exercise/A/04.png) +> 1. Let's begin with the .sat file in the exercise file folder. We can grab this file using the *File Path* node. +2. With *Geometry.ImportFromSAT*, the geometry is imported into our Dynamo preview as two surfaces. + +![Exercise](images/6-4/Exercise/A/03.png) +> For this exercise, we want to keep it simple and work with one of the surfaces. +1. Let's select the index of *1 *to grab the upper surface. We do this with *List.GetItemAtIndex* node. + +![Exercise](images/6-4/Exercise/A/02.png) +> The next step is to divide the surface into a grid of points. +1. Using *code block*, insert these two lines of code: +``` +0..1..#10; +0..1..#5; +``` +2. With the *Surface.PointAtParameter*, connect the two code block values to *u *and *v*. Change the *lacing* of this node to *"Cross Product"*. +3. The output reveals the data structure, which is also visible in the Dynamo preview. + +![Exercise](images/6-4/Exercise/A/01.png) +> 1. To get a look at how the data structure is organized, let's connect a *NurbsCurve.ByPoints* to the output of *Surface.PointAtParameter*. +2. Notice we have ten curves running vertically along the surface. + +![Exercise](images/6-4/Exercise/A/00.png) +> 1. A basic *List.Transpose* will flip the columns and rows of a list of lists. +2. Connecting the output of *List.Transpose* to *NurbsCurve.ByPoints*, we now get five curves running horizontally across the surface. + + +###Exercise - 2D Lists - Advanced +Let's increase the complexity. Suppose we wanted to perform an operation on the curves created from the previous exercise. Perhaps we want to relate these curves to another surface and loft between them. This requires more attention to data structure, but the underlying logic is the same. + +![Exercise](images/6-4/Exercise/B/07.png) +> 1. Begin with a step from the previous exercise, isolating the upper surface of the imported geometry with the *List.GetItemAtIndex* node. + +![Exercise](images/6-4/Exercise/B/06.png) +> 1. Using *Surface.Offset*, offset the surface by a value of *10*. + +![Exercise](images/6-4/Exercise/B/05.png) +> 1. In the same manner as the previous exercise, define a *code block* with these two lines of code: +``` +0..1..#10; +0..1..#5; +``` +2. Connect these outputs to two *Surface.PointAtParameter *nodes, each with *lacing* set to *"Cross Product"*. One of these nodes is connected to the original surface, while the other is connected to the offset surface. + +![Exercise](images/6-4/Exercise/B/04.png) +> 1. As in the previous exercise, connect the outputs to two *NurbsCurve.ByPoints* nodes. +2. Our Dynamo preview shows two curves, corresponding to two surfaces. + +![Exercise](images/6-4/Exercise/B/03.png) +> 1. By using *List.Create*, we can combine the two sets of curves into one list of lists. +2. Notice from the output, we have two lists with ten items each, representing each connect set of nurbs curves. +3. By performing a *Surface.ByLoft*, we can visually make sense of this data structure. The node lofts all of the curves in each sublist. + +![Exercise](images/6-4/Exercise/B/02.png) +> 1. By using *List.Transpose*, remember, we are flipping all of the columns and rows. This node will transfer two lists of ten curves into ten lists of two curves. We now have each nurbs curve related to the neighboring curve on the other surface. +2. Using *Surface.ByLoft*, we arrive at a ribbed structure. + +![Exercise](images/6-4/Exercise/B/01.png) +> 1. An alternative to *List.Transpose* uses *List.Combine*. This will operate a *"combinator"* on each sublist. +2. In this case, we're using *List.Create *as the *"combinator"*, which will create a list of each item in the sublists. +3. Using the *Surface.ByLoft* node, we get the same surfaces as in the previous step. Transpose is easier to use in this case, but when the data structure becomes even more complex, *List.Combine* is more reliable. + +![Exercise](images/6-4/Exercise/B/00.png) +> 1. Stepping back a few steps, if we want to switch the orientation of the curves in the ribbed structure, we want to use a List.Transpose before connect to *NurbsCurve.ByPoints*. This will flip the columns and rows, giving us 5 horizontal ribs. + + +###Exercise - 3D Lists +Now, we're going to go even one step further. In this exercise, we'll work with both imported surfaces, creating a complex data hierarchy. Still, our aim is to complete the same operation with the same underlying logic. + +![Exercise](images/6-4/Exercise/C/12.png) +> 1. Begin with the imported file from previous exercise. + +![Exercise](images/6-4/Exercise/C/11.png) +> 1. As in the previous exercise, use the *Surface.Offset* node to offset by a value of *10*. +2. Notice from the output, that we've created two surfaces with the offset node. + +![Exercise](images/6-4/Exercise/C/10.png) +> 1. In the same manner as the previous exercise, define a code block with these two lines of code: +``` +0..1..#20; +0..1..#10; +``` +2. Connect these outputs to two *Surface.PointAtParameter* nodes, each with lacing set to *"Cross Product"*. One of these nodes is connected to the original surfaces, while the other is connected to the offset surfaces. + +![Exercise](images/6-4/Exercise/C/09.png) +> 1. As in the previous exercise, connect the outputs to two *NurbsCurve.ByPoints* nodes. +2. Looking at the output of the *NurbsCurve.ByPoints*, notice that this is a list of two lists, which is more complex than the previous exercise. The data is categorized by the underlying surface, so we've added another tier to the data structured. +3. Notice that things become more complex in the *Surface.PointAtParameter* node. In this case we have a list of lists of lists. + +![Exercise](images/6-4/Exercise/C/08.png) +> 1. Using the *List.Create* node, we merge the nurbs curves into one data structure, creating a list of lists of lists. +2. By connecting a *Surface.ByLoft* node, we get a version of the original surfaces, as they each remain in their own list as created from the original data structure. + +![Exercise](images/6-4/Exercise/C/07.png) +> 1. In the previous exercise, we were able to use a *List.Transpose* to create a ribbed structure. This won't work here. A transpose should be used on a two-dimensional list, and since we have a three-dimensional list, an operation of "flipping columns and rows" won't work as easily. Remember, lists are objects, so *List.Transpose* will flip our lists with out sublists, but won't flip the nurbs curves one list further down in the hierarchy. + +![Exercise](images/6-4/Exercise/C/06.png) +> 1. *List.Combine* will work better for us here. We want to use *List.Map* and *List.Combine* nodes when we get to more complex data structures. +2. Using *List.Create *as the *"combinator"*, we create a data structure that will work better for us. + +![Exercise](images/6-4/Exercise/C/05.png) +> 1. The data structure still needs to be transposed at one step down on the hierarchy. To do this we'll use *List.Map*. This is working like *List.Combine*, except with one input list, rather than two or more. +2. The function we'll apply to *List.Map* is *List.Transpose*, which will flip the columns and rows of the sublists within our main list. + +![Exercise](images/6-4/Exercise/C/04.png) +> 1. Finally, we can loft the nurbs curves together with a proper data hierarchy, giving us a ribbed structure. + +![Exercise](images/6-4/Exercise/C/03.png) +> 1. Let's add some depth to the geometry with a *Surface.Thicken* node. + +![Exercise](images/6-4/Exercise/C/02.png) +> 1. It'll be nice to add a surface backing two this structure, so we'll use *List.GetItemAtIndex* to select the back surface from the lofted surfaces from the previous steps. + +![Exercise](images/6-4/Exercise/C/01.png) +> 1. And thickening these selected surfaces, our articulation is complete. + +![Exercise](images/6-4/Exercise/C/00.png) +> Not the most comfortable rocking chair ever, but it's got a lot of data going on. + +![Exercise](images/6-4/Exercise/C/32.png) +> Last step, let's reverse the direction of the striated members. As we used transpose in the previous exercise, we'll do something similar here. +1. Since we have one more tier to the hierarchy, so we need to use *List.Map* with a *List.Tranpose* function to change the direction of our nurbs curves. + +![Exercise](images/6-4/Exercise/C/31.png) +> 1. We may want to increase the number of treads, so we can change the code block to +``` +0..1..#20; +0..1..#10; +``` + +![Exercise](images/6-4/Exercise/C/30.png) +> The first version of the rocking chair was sleek, so our second model offers an off-road, sport-utility version of recumbency. + + + + + + + + + + + + + diff --git a/06_Designing-with-Lists/6_designing-with-lists.md b/06_Designing-with-Lists/6_designing-with-lists.md index 00b4737e..3e8b5c37 100644 --- a/06_Designing-with-Lists/6_designing-with-lists.md +++ b/06_Designing-with-Lists/6_designing-with-lists.md @@ -1,5 +1,5 @@ -# Designing with Lists - -Lists are the way we organize data. On your computer's operating system, you have files and folders. In Dynamo, we can regard these as items and lists, respectively. Like your operating system, there are many ways to create, modify, and query data. In this chapter, we'll break down how lists are managed in Dynamo. - -![IMAGE](images/6/Designing with Lists-01.png) +# Designing with Lists + +Lists are the way we organize data. On your computer's operating system, you have files and folders. In Dynamo, we can regard these as items and lists, respectively. Like your operating system, there are many ways to create, modify, and query data. In this chapter, we'll break down how lists are managed in Dynamo. + +![IMAGE](images/6/Designing with Lists-01.png) diff --git a/06_Designing-with-Lists/datasets/6-1/Lacing.dyn b/06_Designing-with-Lists/datasets/6-1/Lacing.dyn index ff2d0c74..20aea1bc 100644 --- a/06_Designing-with-Lists/datasets/6-1/Lacing.dyn +++ b/06_Designing-with-Lists/datasets/6-1/Lacing.dyn @@ -1,28 +1,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-Count.dyn b/06_Designing-with-Lists/datasets/6-2/List-Count.dyn index a75e322b..d4621391 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-Count.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-Count.dyn @@ -1,55 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn b/06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn index 8161ec31..672dd6dd 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn @@ -1,70 +1,70 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn b/06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn index e3881489..fd8616ab 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn @@ -1,55 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-Operations.dyn b/06_Designing-with-Lists/datasets/6-2/List-Operations.dyn index e5c6a5c1..5bbabf52 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-Operations.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-Operations.dyn @@ -1,51 +1,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn b/06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn index 781b460b..18abba05 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn @@ -1,56 +1,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn b/06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn index da22479b..65aa4fed 100644 --- a/06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn +++ b/06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn @@ -1,58 +1,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Chop.dyn b/06_Designing-with-Lists/datasets/6-3/Chop.dyn index b5e17fdf..7ce55ab7 100644 --- a/06_Designing-with-Lists/datasets/6-3/Chop.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Chop.dyn @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Combine.dyn b/06_Designing-with-Lists/datasets/6-3/Combine.dyn index da7464a0..0b1ff0e5 100644 --- a/06_Designing-with-Lists/datasets/6-3/Combine.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Combine.dyn @@ -1,43 +1,43 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Flatten.dyn b/06_Designing-with-Lists/datasets/6-3/Flatten.dyn index c9cb394b..d7e31030 100644 --- a/06_Designing-with-Lists/datasets/6-3/Flatten.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Flatten.dyn @@ -1,36 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Listatlevel.dyn b/06_Designing-with-Lists/datasets/6-3/Listatlevel.dyn index ad9aa786..c42e43aa 100644 --- a/06_Designing-with-Lists/datasets/6-3/Listatlevel.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Listatlevel.dyn @@ -1,126 +1,126 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Map.dyn b/06_Designing-with-Lists/datasets/6-3/Map.dyn index 30e43e47..57c4b500 100644 --- a/06_Designing-with-Lists/datasets/6-3/Map.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Map.dyn @@ -1,48 +1,48 @@ - - - - - - - - - - - - - - 5 - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + 5 + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn b/06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn index c10d1f1b..ceb26f8b 100644 --- a/06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn +++ b/06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn @@ -1,54 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn b/06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn index 3b9e7c7b..18b9ae37 100644 --- a/06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn @@ -1,36 +1,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-3/Transpose.dyn b/06_Designing-with-Lists/datasets/6-3/Transpose.dyn index 29d5bfd8..ad149f50 100644 --- a/06_Designing-with-Lists/datasets/6-3/Transpose.dyn +++ b/06_Designing-with-Lists/datasets/6-3/Transpose.dyn @@ -1,48 +1,48 @@ - - - - - - - - - - - - - - 5 - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + 5 + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn b/06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn index 932dd5f3..f5f6a63d 100644 --- a/06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn +++ b/06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat - - - C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat + + + C:\node\Dynamo-Primer-20150701\dynamo-primer\06_Designing-with-Lists\datasets\6-4\n-Dimensional-Lists.sat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/06_Designing-with-Lists/images/6-1/urls.txt b/06_Designing-with-Lists/images/6-1/urls.txt index 8b645dc1..01b4b722 100644 --- a/06_Designing-with-Lists/images/6-1/urls.txt +++ b/06_Designing-with-Lists/images/6-1/urls.txt @@ -1,5 +1,5 @@ -https://commons.wikimedia.org/wiki/File:Nina_Rusa._Mu%C3%B1eca_Rusa.JPG -https://commons.wikimedia.org/wiki/File:Bananas_white_background_DS.jpg?fastcci_from=11404890&c1=11404890&d1=15&s=200&a=list -https://commons.wikimedia.org/wiki/File:Playing_cards_modified.jpg -https://pixabay.com/en/coins-stacked-pennies-quarters-521245/ +https://commons.wikimedia.org/wiki/File:Nina_Rusa._Mu%C3%B1eca_Rusa.JPG +https://commons.wikimedia.org/wiki/File:Bananas_white_background_DS.jpg?fastcci_from=11404890&c1=11404890&d1=15&s=200&a=list +https://commons.wikimedia.org/wiki/File:Playing_cards_modified.jpg +https://pixabay.com/en/coins-stacked-pennies-quarters-521245/ https://www.flickr.com/photos/beppezizzi/145493363 \ No newline at end of file diff --git a/07_Code-Block/7-1_what-is-a-code-block.md b/07_Code-Block/7-1_what-is-a-code-block.md index a8f0066d..78f7f9b4 100644 --- a/07_Code-Block/7-1_what-is-a-code-block.md +++ b/07_Code-Block/7-1_what-is-a-code-block.md @@ -1,26 +1,26 @@ -## What's a Code Block? -Code blocks are a window deep into DesignScript, the programming language at the heart of Dynamo. Built from scratch to support exploratory design workflows, DesignScript is a readable and concise language that offers both immediate feedback to small bits of code and also scales to large and complex interactions. DesignScript also forms the backbone of the engine that drives most aspects of Dynamo “under the hood”. Because nearly all of the functionality found in Dynamo nodes and interactions have a one-to-one relationship with the scripting language, there are unique opportunities to move between node-based interactions and scripting in a fluid way. -![Code Block Intro](images/7-1/daisy.png) -For beginners, nodes can be automatically converted to text syntax to aid in learning DesignScript or simply to reduce the size of larger sections of graphs. This is done using a process called "Node to Code", which is outlined in more detail in the [DesignScript Syntax section](7-2_Design-Script-syntax.md). More experienced users can use Code Blocks to create customized mashups of existing functionality and user authored relationships using many standard coding paradigms. In between the beginner and advanced user, there are a huge number of shortcuts and code snippets that will accelerate your designs. While the term 'code block' may be a little intimidating to non-programmers, it is both easy to use and robust. A beginner can use the code block efficiently with minimal coding, and an advanced user can define scripted definitions to be recalled elsewhere in a Dynamo definition. - -###Code Block: A brief overview -In short, code blocks are a text-scripting interface within a visual-scripting environment. They can be used as numbers, strings, formulas, and other data types. The code block is designed for Dynamo, so one can define arbitrary variables in the code block, and those variables are automatically added to the inputs of the node: - -With code blocks, a user has the flexibility to decide how to specify inputs. Here are several different ways to make a basic point with coordinates *(10, 5, 0)*: -![Flexibility](images/7-2/flexibility.png) - -As you learn more of the available functions in the library, you might even find that typing “Point.ByCoordinates” is faster than searching in the library and finding the proper node. When you type in *"Point."* for example, Dynamo will display a list of possible functions to apply to a Point. This makes the scripting more intuitive and will help with learning how to apply functions in Dynamo. - -### Creating Code Block Nodes -The code block can be found in *Core>Input>Actions>Code Block*. But even faster, just double click on the canvas and the code block appears. This node is used so often, it's given full double-click privileges. - -![Code Block Intro](images/7-1/uicb.png) - -### Numbers, strings, and formulas - -Code blocks are also flexible towards data types. The user can quickly define numbers, strings, and formulas and the code block will deliver the desired output. - -In the image below, you can see the "old school" way of doing things is a little long-winded: the user searches for the intended node in the interface, adds the node to the canvas, and then inputs the data. With code block, the user can double-click on the canvas to pull up the node, and type in the correct data type with basic syntax. -![Obsolete Nodes](images/7-3/obsolete01.png) -> The *number*, *string*, and *formula* nodes are three examples of Dynamo nodes which are arguably obsolete in comparison to the *code block*. - +## What's a Code Block? +Code blocks are a window deep into DesignScript, the programming language at the heart of Dynamo. Built from scratch to support exploratory design workflows, DesignScript is a readable and concise language that offers both immediate feedback to small bits of code and also scales to large and complex interactions. DesignScript also forms the backbone of the engine that drives most aspects of Dynamo “under the hood”. Because nearly all of the functionality found in Dynamo nodes and interactions have a one-to-one relationship with the scripting language, there are unique opportunities to move between node-based interactions and scripting in a fluid way. +![Code Block Intro](images/7-1/daisy.png) +For beginners, nodes can be automatically converted to text syntax to aid in learning DesignScript or simply to reduce the size of larger sections of graphs. This is done using a process called "Node to Code", which is outlined in more detail in the [DesignScript Syntax section](7-2_Design-Script-syntax.md). More experienced users can use Code Blocks to create customized mashups of existing functionality and user authored relationships using many standard coding paradigms. In between the beginner and advanced user, there are a huge number of shortcuts and code snippets that will accelerate your designs. While the term 'code block' may be a little intimidating to non-programmers, it is both easy to use and robust. A beginner can use the code block efficiently with minimal coding, and an advanced user can define scripted definitions to be recalled elsewhere in a Dynamo definition. + +###Code Block: A brief overview +In short, code blocks are a text-scripting interface within a visual-scripting environment. They can be used as numbers, strings, formulas, and other data types. The code block is designed for Dynamo, so one can define arbitrary variables in the code block, and those variables are automatically added to the inputs of the node: + +With code blocks, a user has the flexibility to decide how to specify inputs. Here are several different ways to make a basic point with coordinates *(10, 5, 0)*: +![Flexibility](images/7-2/flexibility.png) + +As you learn more of the available functions in the library, you might even find that typing “Point.ByCoordinates” is faster than searching in the library and finding the proper node. When you type in *"Point."* for example, Dynamo will display a list of possible functions to apply to a Point. This makes the scripting more intuitive and will help with learning how to apply functions in Dynamo. + +### Creating Code Block Nodes +The code block can be found in *Core>Input>Actions>Code Block*. But even faster, just double click on the canvas and the code block appears. This node is used so often, it's given full double-click privileges. + +![Code Block Intro](images/7-1/uicb.png) + +### Numbers, strings, and formulas + +Code blocks are also flexible towards data types. The user can quickly define numbers, strings, and formulas and the code block will deliver the desired output. + +In the image below, you can see the "old school" way of doing things is a little long-winded: the user searches for the intended node in the interface, adds the node to the canvas, and then inputs the data. With code block, the user can double-click on the canvas to pull up the node, and type in the correct data type with basic syntax. +![Obsolete Nodes](images/7-3/obsolete01.png) +> The *number*, *string*, and *formula* nodes are three examples of Dynamo nodes which are arguably obsolete in comparison to the *code block*. + diff --git a/07_Code-Block/7-2_Design-Script-syntax.md b/07_Code-Block/7-2_Design-Script-syntax.md index 44a7194f..26fd2fcc 100644 --- a/07_Code-Block/7-2_Design-Script-syntax.md +++ b/07_Code-Block/7-2_Design-Script-syntax.md @@ -1,141 +1,141 @@ -## DesignScript Syntax -You may have noticed a common theme in the names of nodes in Dynamo: each node uses a *"."* syntax without spaces. This is because the text at the top of each node respresents the actual syntax for scripting, and the *"."* (or *dot notation*) separates an element from the possible methods we can call. This creates an easy translation from visual scripting to text-based scripting. - -![NodeNames](images/7-2/apple.jpg) - -As a general analogy for the dot notation, how can we deal with a parametric apple in Dynamo? Below are a few methods we'll run on the apple before deciding to eat it. (Note: these are not actual Dynamo methods): - -| Humanly Readible | Dot Notation | Output | -| -- | -- | -| What color is the apple? | Apple.color | red -| Is the apple ripe? | Apple.isRipe | true | -| How much does the apple weigh? | Apple.weight | 6 oz. | -| Where did the apple come from? | Apple.parent | tree | -| What does the apple create? | Apple.children | seeds | -| Is this apple locally grown? | Apple.distanceFromOrchard | 60 mi. | - -I don't know about you, but judging by the outputs in the table above, this looks like one tasty apple. I think I'll *Apple.eat() *it. - -###Dot Notation in Code Block -With the apple analogy in mind, let's look at *Point.ByCoordinates* and show how we can create a point using the code block: - -![NodeNames](images/7-2/cbn02.png) -> The *code block* syntax ```Point.ByCoordinates(0,10); -``` -gives the same result as a *Point.ByCoordinates* node in Dynamo, except we're able to create a point using one node. This is more efficient than the connecting a separate node into *"X"* and *"Y"*. -1. By using *Point.ByCoordinates* in the code block, we are specifying the inputs in the same order as the out-of-the-box node *(X,Y)*. - - -###Calling Nodes -You can call any regular node in the library through a Code Block as long as the node isn’t a special *“UI” node*: those with a special user interface feature. For instance, you can call *Circle.ByCenterPointRadius*, but it wouldn’t make much sense to call a *Watch 3D* node. - -Regular nodes (most of your library), generally come in three types: - -* **Create** - Create (or construct) something -* **Action** - Perform an action on something -* **Query** - Get a property of something that already exists - -You’ll find that the library is organized with these categories in mind. Methods, or nodes, of these three types are treated differently when invoked within a Code Block. - -![NodeNames](images/7-2/cbn12.png) - -####Create -The "Create" category will construct geometry from scratch. We input values in the code block from left-to-right. These inputs are in the same order as the inputs on the node from top-to-bottom: -![NodeNames](images/7-2/demo1.png) -> Comparing the *Line.ByStartPointEndPoint* node and the corresponding syntax in the code block, we get the same results. - -####Action - -An action is something you do to an object of that type. Dynamo uses *dot notation*, common to many coding languages, to apply an action to a thing. Once you have the thing, type a dot then the name of the action. The action-type method’s input is placed in parentheses just like create-type methods, only you don’t have to specify the first input you see on the corresponding node. Instead, we specify the element upon which we are performing the action: - -![NodeNames](images/7-2/cbn04.png) - - -> 1. The *Point.Add *node is an action-type node, so the syntax works a little differently. -2. The inputs are (1) the *point*, and (2) the *vector* to add to it. In a *Code Block*, we've named the point (the thing) *“pt”*. To add a vector named *“vec” *to *“pt”*, we would write *pt.Add(vec)*, or: thing, dot, action. The Add action only has one input, or all the inputs from the *Point.Add *node minus the first one. The first input for the *Point.Add *node is the point itself. - -####Query - -Query-type methods get a property of an object. Since the object itself is the input, you don’t have to specify any inputs. No parentheses required. - -![NodeNames](images/7-2/cbn05.png) - -### How About Lacing? -Lacing with nodes is somewhat different from lacing with code block. With nodes, the user right clicks on the node and selects the lacing option to perform. With code block, the user has much more control as to how the data is structured. The code block shorthand method uses *replication guides* to set how several one-dimensional lists should be paired. Numbers in angled brackets "<>" define the hierarchy of the resulting nested list: <1>,<2>,<3>, etc. -![Lacing](images/7-2/lacing.png) - -> 1. In this example, we use a shorthand to define two ranges (more on shorthand in the following section of this chapter). In short, ```0..1; -``` is equivalent to ```{0,1} -``` and ```-3..-7 -```is equivalent to ``` -{-3,-4,-5,-6,-7}```. The result gives us lists of 2 x-values and 5 y-values. If we don’t use replication guides with these mismatched lists, we get a list of two points, which is the length of the shortest list. Using replication guides, we can find all of the possible combinations of 2 and 5 coordinates (or, a **Cross Product**). -2. Using the syntax ```Point.ByCoordinates(x_vals<1>,y_vals<2>); -``` we get **two** lists with **five** items in each list. -3. Using the syntax ```Point.ByCoordinates(x_vals<2>,y_vals<1>); -``` we get **five** lists with **two** items in each list. - - -With this notation, we can also specify which list will be dominant: 2 lists of 5 things or 5 lists of 2 things. In the example, changing the order of the replication guides makes the result a list of rows of points or a list of columns of points in a grid. - -###Node to Code -While the code block methods above may take some getting used to, there is a feature in Dynamo called "Node to Code" which will make the process easier. To use this feature, select an array of nodes in your Dynamo graph, right-click on the canvas and select "Node to Code". Dynamo condenses these nodes into a code block, with all of the inputs and outputs! Not only is this a great tool for learning code block, but it also allows you to work with a more efficient and parametric Dynamo graph. We'll conclude the exercise below by using "Node to Code", so don't miss it. - -![Lacing](images/7-2/nodeToCode.jpg) - -### Exercise ->Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Dynamo-Syntax_Attractor-Surface.dyn](datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn) - -To show the power of code block, we are going to translate an existing attractor field definition into code block form. Working with an existing definition demonstrates how code block relates to visual scripting, and is helpful for learning DesignScript syntax. -![Exercise](images/7-2/Exercise/01.png) -> Begin by recreating the definition in the image above (or by opening the sample file). -1. Notice that the lacing on *Point.ByCoordinates* has been set to *Cross Product*. -2. Each point in a grid is moved up in the Z direction based on its distance to the reference point. -3. A surface is recreated and thickened, creating a bulge in the geometry relative to the distance to the reference point. - -![Exercise](images/7-2/Exercise/07.png) ->1. Starting from the beginning, let's define the reference point first: ```Point.ByCoordinates(x,y,0); -```. We use the same *Point.ByCoordinates* syntax as is specified on the top of the reference point node. -2. The variables *x* and *y* are inserted into the code block so that we may update these dynamically with sliders. -3. Add some *sliders* to the *code block* inputs which range from *-50* to *50*. This way, we can span across the default Dynamo grid. - -![Exercise](images/7-2/Exercise/06.png) ->1. In the second line of the *code block*, we define a shorthand to replace the number sequence node: ```coordsXY = (-50..50..#11); -``` -. We'll discuss this more in the next section. For now, notice that this shorthand is equivalent to the *Number Sequence* node in the visual script. - -![Exercise](images/7-2/Exercise/05.png) ->1. Now, we want to create a grid of points from the *coordsXY* sequence. To do this, we want to use the *Point.ByCoordinates* syntax, but also need to initiate a *Cross Product* of the list in the same manner that we did in the visual script. To do this, we type the line: ```gridPts = Point.ByCoordinates(coordsXY<1>,coordsXY<2>,0); -```. The angled brackets denote the cross product reference. -2. Notice in the *Watch3D* node that we have a grid of points across the Dynamo grid. - -![Exercise](images/7-2/Exercise/04.png) ->1. Now for the tricky part: We want to move the grid of points up based on their distance to the reference point. First, let's call this new set of points *transPts*. And since a translation is an action on an existing element, rather than using ```Geometry.Translate... -```, we use ```gridPts.Translate -```. -2. Reading from the actual node on the canvas, we see that there are three inputs. The geometry to translate is already declared because we are performing the action on that element (with *gridPts.Translate*). The remaining two inputs will be inserted into the parentheses of the function: *direction* and *distance*. -3. The direction is simple enough, we use a ```Vector.ZAxis() -``` to move vertically. -4. The distance between the reference point and each grid point still needs to be calculated, so we do this as an action to the reference point in the same manner: ```refPt.DistanceTo(gridPts) -``` -5. The final line of code gives us the translated points: ```transPts = gridPts.Translate(Vector.ZAxis(),refPt.DistanceTo(gridPts)); -``` - -![Exercise](images/7-2/Exercise/03.png) ->1. We now have a grid of points with the appropriate data structure to create a Nurbs Surface. We construct the surface using ```srf = NurbsSurface.ByControlPoints(transPts); -``` - - -![Exercise](images/7-2/Exercise/02.png) ->1. And finally, to add some depth to the surface, we construct a solid using ```solid = srf.Thicken(5); -``` In this case we thickened the surface by 5 units in the code, but we could always declare this as a variable (calling it *thickness* for example) and then control that value with a slider. - - -###Simplify the Graph with "Node to Code" -The "Node to Code" feature automates the entire exercise that we just completed with the click of a button. Not only is this powerful for creating custom definitions and reusable code blocks, but it is also a really helpful tool to learn how to script in Dynamo: - -![Exercise](images/7-2/Exercise/09.png) -> 1. Start with the existing visual script from step 1 of the exercise. Select all of the nodes, right click on the canvas, and select *"Node to Code"*. Simple as that. - -![Exercise](images/7-2/Exercise/08.png) -> Dynamo has automated a text based version of the visual graph, lacing and all. Test this out on your visual scripts and release the power of the code block! - +## DesignScript Syntax +You may have noticed a common theme in the names of nodes in Dynamo: each node uses a *"."* syntax without spaces. This is because the text at the top of each node respresents the actual syntax for scripting, and the *"."* (or *dot notation*) separates an element from the possible methods we can call. This creates an easy translation from visual scripting to text-based scripting. + +![NodeNames](images/7-2/apple.jpg) + +As a general analogy for the dot notation, how can we deal with a parametric apple in Dynamo? Below are a few methods we'll run on the apple before deciding to eat it. (Note: these are not actual Dynamo methods): + +| Humanly Readible | Dot Notation | Output | +| -- | -- | +| What color is the apple? | Apple.color | red +| Is the apple ripe? | Apple.isRipe | true | +| How much does the apple weigh? | Apple.weight | 6 oz. | +| Where did the apple come from? | Apple.parent | tree | +| What does the apple create? | Apple.children | seeds | +| Is this apple locally grown? | Apple.distanceFromOrchard | 60 mi. | + +I don't know about you, but judging by the outputs in the table above, this looks like one tasty apple. I think I'll *Apple.eat() *it. + +###Dot Notation in Code Block +With the apple analogy in mind, let's look at *Point.ByCoordinates* and show how we can create a point using the code block: + +![NodeNames](images/7-2/cbn02.png) +> The *code block* syntax ```Point.ByCoordinates(0,10); +``` +gives the same result as a *Point.ByCoordinates* node in Dynamo, except we're able to create a point using one node. This is more efficient than the connecting a separate node into *"X"* and *"Y"*. +1. By using *Point.ByCoordinates* in the code block, we are specifying the inputs in the same order as the out-of-the-box node *(X,Y)*. + + +###Calling Nodes +You can call any regular node in the library through a Code Block as long as the node isn’t a special *“UI” node*: those with a special user interface feature. For instance, you can call *Circle.ByCenterPointRadius*, but it wouldn’t make much sense to call a *Watch 3D* node. + +Regular nodes (most of your library), generally come in three types: + +* **Create** - Create (or construct) something +* **Action** - Perform an action on something +* **Query** - Get a property of something that already exists + +You’ll find that the library is organized with these categories in mind. Methods, or nodes, of these three types are treated differently when invoked within a Code Block. + +![NodeNames](images/7-2/cbn12.png) + +####Create +The "Create" category will construct geometry from scratch. We input values in the code block from left-to-right. These inputs are in the same order as the inputs on the node from top-to-bottom: +![NodeNames](images/7-2/demo1.png) +> Comparing the *Line.ByStartPointEndPoint* node and the corresponding syntax in the code block, we get the same results. + +####Action + +An action is something you do to an object of that type. Dynamo uses *dot notation*, common to many coding languages, to apply an action to a thing. Once you have the thing, type a dot then the name of the action. The action-type method’s input is placed in parentheses just like create-type methods, only you don’t have to specify the first input you see on the corresponding node. Instead, we specify the element upon which we are performing the action: + +![NodeNames](images/7-2/cbn04.png) + + +> 1. The *Point.Add *node is an action-type node, so the syntax works a little differently. +2. The inputs are (1) the *point*, and (2) the *vector* to add to it. In a *Code Block*, we've named the point (the thing) *“pt”*. To add a vector named *“vec” *to *“pt”*, we would write *pt.Add(vec)*, or: thing, dot, action. The Add action only has one input, or all the inputs from the *Point.Add *node minus the first one. The first input for the *Point.Add *node is the point itself. + +####Query + +Query-type methods get a property of an object. Since the object itself is the input, you don’t have to specify any inputs. No parentheses required. + +![NodeNames](images/7-2/cbn05.png) + +### How About Lacing? +Lacing with nodes is somewhat different from lacing with code block. With nodes, the user right clicks on the node and selects the lacing option to perform. With code block, the user has much more control as to how the data is structured. The code block shorthand method uses *replication guides* to set how several one-dimensional lists should be paired. Numbers in angled brackets "<>" define the hierarchy of the resulting nested list: <1>,<2>,<3>, etc. +![Lacing](images/7-2/lacing.png) + +> 1. In this example, we use a shorthand to define two ranges (more on shorthand in the following section of this chapter). In short, ```0..1; +``` is equivalent to ```{0,1} +``` and ```-3..-7 +```is equivalent to ``` +{-3,-4,-5,-6,-7}```. The result gives us lists of 2 x-values and 5 y-values. If we don’t use replication guides with these mismatched lists, we get a list of two points, which is the length of the shortest list. Using replication guides, we can find all of the possible combinations of 2 and 5 coordinates (or, a **Cross Product**). +2. Using the syntax ```Point.ByCoordinates(x_vals<1>,y_vals<2>); +``` we get **two** lists with **five** items in each list. +3. Using the syntax ```Point.ByCoordinates(x_vals<2>,y_vals<1>); +``` we get **five** lists with **two** items in each list. + + +With this notation, we can also specify which list will be dominant: 2 lists of 5 things or 5 lists of 2 things. In the example, changing the order of the replication guides makes the result a list of rows of points or a list of columns of points in a grid. + +###Node to Code +While the code block methods above may take some getting used to, there is a feature in Dynamo called "Node to Code" which will make the process easier. To use this feature, select an array of nodes in your Dynamo graph, right-click on the canvas and select "Node to Code". Dynamo condenses these nodes into a code block, with all of the inputs and outputs! Not only is this a great tool for learning code block, but it also allows you to work with a more efficient and parametric Dynamo graph. We'll conclude the exercise below by using "Node to Code", so don't miss it. + +![Lacing](images/7-2/nodeToCode.jpg) + +### Exercise +>Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Dynamo-Syntax_Attractor-Surface.dyn](datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn) + +To show the power of code block, we are going to translate an existing attractor field definition into code block form. Working with an existing definition demonstrates how code block relates to visual scripting, and is helpful for learning DesignScript syntax. +![Exercise](images/7-2/Exercise/01.png) +> Begin by recreating the definition in the image above (or by opening the sample file). +1. Notice that the lacing on *Point.ByCoordinates* has been set to *Cross Product*. +2. Each point in a grid is moved up in the Z direction based on its distance to the reference point. +3. A surface is recreated and thickened, creating a bulge in the geometry relative to the distance to the reference point. + +![Exercise](images/7-2/Exercise/07.png) +>1. Starting from the beginning, let's define the reference point first: ```Point.ByCoordinates(x,y,0); +```. We use the same *Point.ByCoordinates* syntax as is specified on the top of the reference point node. +2. The variables *x* and *y* are inserted into the code block so that we may update these dynamically with sliders. +3. Add some *sliders* to the *code block* inputs which range from *-50* to *50*. This way, we can span across the default Dynamo grid. + +![Exercise](images/7-2/Exercise/06.png) +>1. In the second line of the *code block*, we define a shorthand to replace the number sequence node: ```coordsXY = (-50..50..#11); +``` +. We'll discuss this more in the next section. For now, notice that this shorthand is equivalent to the *Number Sequence* node in the visual script. + +![Exercise](images/7-2/Exercise/05.png) +>1. Now, we want to create a grid of points from the *coordsXY* sequence. To do this, we want to use the *Point.ByCoordinates* syntax, but also need to initiate a *Cross Product* of the list in the same manner that we did in the visual script. To do this, we type the line: ```gridPts = Point.ByCoordinates(coordsXY<1>,coordsXY<2>,0); +```. The angled brackets denote the cross product reference. +2. Notice in the *Watch3D* node that we have a grid of points across the Dynamo grid. + +![Exercise](images/7-2/Exercise/04.png) +>1. Now for the tricky part: We want to move the grid of points up based on their distance to the reference point. First, let's call this new set of points *transPts*. And since a translation is an action on an existing element, rather than using ```Geometry.Translate... +```, we use ```gridPts.Translate +```. +2. Reading from the actual node on the canvas, we see that there are three inputs. The geometry to translate is already declared because we are performing the action on that element (with *gridPts.Translate*). The remaining two inputs will be inserted into the parentheses of the function: *direction* and *distance*. +3. The direction is simple enough, we use a ```Vector.ZAxis() +``` to move vertically. +4. The distance between the reference point and each grid point still needs to be calculated, so we do this as an action to the reference point in the same manner: ```refPt.DistanceTo(gridPts) +``` +5. The final line of code gives us the translated points: ```transPts = gridPts.Translate(Vector.ZAxis(),refPt.DistanceTo(gridPts)); +``` + +![Exercise](images/7-2/Exercise/03.png) +>1. We now have a grid of points with the appropriate data structure to create a Nurbs Surface. We construct the surface using ```srf = NurbsSurface.ByControlPoints(transPts); +``` + + +![Exercise](images/7-2/Exercise/02.png) +>1. And finally, to add some depth to the surface, we construct a solid using ```solid = srf.Thicken(5); +``` In this case we thickened the surface by 5 units in the code, but we could always declare this as a variable (calling it *thickness* for example) and then control that value with a slider. + + +###Simplify the Graph with "Node to Code" +The "Node to Code" feature automates the entire exercise that we just completed with the click of a button. Not only is this powerful for creating custom definitions and reusable code blocks, but it is also a really helpful tool to learn how to script in Dynamo: + +![Exercise](images/7-2/Exercise/09.png) +> 1. Start with the existing visual script from step 1 of the exercise. Select all of the nodes, right click on the canvas, and select *"Node to Code"*. Simple as that. + +![Exercise](images/7-2/Exercise/08.png) +> Dynamo has automated a text based version of the visual graph, lacing and all. Test this out on your visual scripts and release the power of the code block! + diff --git a/07_Code-Block/7-3_shorthand.md b/07_Code-Block/7-3_shorthand.md index ee55906d..9db49f5c 100644 --- a/07_Code-Block/7-3_shorthand.md +++ b/07_Code-Block/7-3_shorthand.md @@ -1,177 +1,177 @@ - - -## Shorthand -There are a few basic shorthand methods in the code block which, simply put, make data management *a lot* easier. We'll break down the basics below and discuss how this shorthand can be used both for creating and querying data. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Data TypeStandard Dynamo Code Block Equilvalent
Numbers
Strings
Sequences
Ranges
Get Item at Index
Create List
Concatenate Strings
Conditional Statements
- -###Additional Syntax -| Node(s) | Code Block Equivalent | Note | -| -- | -- | -- | -| Any operator (+, &&, >=, Not, etc.) |+, &&, >=, !, etc.| Note that “Not” becomes “!” but the node is called “Not” to distinguish from “Factorial”| -| Boolean True | true; | Note lower case | -| Boolean False | false; | Note lower case | - -### Ranges -The method for defining ranges and sequences can be reduced to basic shorthand. Use the image below as a guide to the ".." syntax for defining a list of numerical data with code block. After getting the hang of this notation, creating numerical data is a really efficient process: -![Obsolete Ranges](images/7-3/obsolete02.png) -> 1. In this example, a number range is replaced by basic code block syntax defining the ```beginning..end..step-size; -```. Represented numerically, we get: ```0..10..1; -``` -2. Notice that the syntax ```0..10..1; -``` is equivalent to ```0..10; -```. A step-size of 1 is the default value for the shorthand notation. So ```0..10; -``` will give a sequence from 0 to 10 with a step-size of 1. -3. The *number sequence* example is similar, except we use a *"#"* to state that we want 15 values in the list, rather than a list which goes up to 15. In this case, we are defining: ```beginning..#ofSteps..step-size: -```. The actual syntax for the sequence is ```0..#15..2 -``` -4. Using the *"#"* from the previous step, we now place it in the *"step-size"* portion of the syntax. Now, we have a *number range* spanning from the *"beginning"* to the *"end"* and the *"step-size"* notation evenly distributes a number of values between the two: ```beginning..end..#ofSteps -``` - -### Advanced Ranges -Creating advanced ranges allows us to work with list of lists in a simple fashion. In the examples below, we're isolating a variable from the primary range notation, and creating another range of that list. -![Ranges](images/7-3/03.png) ->1. Creating nested ranges, compare the notation with a *"#"* vs. the notation without. The same logic applies as in basic ranges, except it gets a little more complex. -2. We can define a sub-range at any place within the primary range, and notice that we can have two sub-ranges as well. -3. By controlling the *"end"* value in a range, we create more ranges of differing lengths. - -![Ranges](images/7-3/02.png) -> As a logic exercise, compare the two shorthands above and try to parse through how *subranges* and the *"#"* notation drive the resultant output. - -### Make lists and get items from a list -In addition to making lists with shorthand, we can also create lists on the fly. These list can contain a wide range of element types and can also be queried (remember, lists are objects in themselves). To summarize, with code block you make lists with braces (a.k.a. “curly brackets”) and you query items from a list with brackets (a.k.a. “square brackets”): - -![Querying Lists](images/7-3/cbn07.png) ->1. Create lists quickly with strings and query them using the item index. -2. Create lists with variables and query using the range shorthand notation. - -And manging with nested lists is a similar process. Be aware of the list order and recall using multiple sets of square brackets: - -![Querying Lists](images/7-3/cbn08.png) -> 1. Define a list of lists. -2. Query a list with single bracket notation. -3. Query an item with double bracket notation. - - - - -### Exercise ->Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Obsolete-Nodes_Sine-Surface.dyn](datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn) - -In this exercise, we will flex our new shorthand skills to create a funky-cool eggshell surface defined by ranges and formulas. During this exercise, notice how we use code block and existing Dynamo nodes in tandem: we use the code block for the heavy data lifting while the Dynamo nodes are visually laid out for legibility of the definition. - -![Exercise](images/7-3/Exercise/13.png) -> Start by creating a surface by connecting the nodes above. Instead of using a number node to define width and length, double click on the canvas and type ```100; -``` into a code block. - - -![Exercise](images/7-3/Exercise/12.png) ->1. Define a range between 0 and 1 with 50 divisions by typing ```0..1..#50 -``` into a code block. -2. Connect the range into *Surface.PointAtParameter*, which takes *u* and *v* values between 0 and 1 across the surface. Remember to change the *Lacing* to *Cross Product* by right clicking on the *Surface.PointAtParameter* node. - - -![Exercise](images/7-3/Exercise/11.png) -> In this step, we employ our first function to move the grid of points up in the Z. This grid will drive a generated surface based on the underlying function. -1. Add the visual nodes to the canvas as shown in the image above. -2. Rather than using a formula node, we use a code block with the line: ```(0..Math.Sin(x*360)..#50)*5; -```. To quickly break this down, we're defining a range with a formula inside of it. This formula is the Sine function. The sine function receives degree inputs in Dynamo, so in order to get a full sine wave, we multiple our *x* values (this is the range input from 0 to 1) by *360*. Next we want the same number of divisions as control grid points for each row, so we define fifty subdivisions with *#50*. Finally, the multiplier of 5 simply increases the amplitude of translation so that we can see the effect in the Dynamo Preview. - - -![Exercise](images/7-3/Exercise/06.png) -> 1. While the previous code block worked fine, it wasn't completely parametric. We want to dynamically drive its parameters, so we'll replace the line from the previous step with ```(0..Math.Sin(x*360*cycles)..#List.Count(x))*amp; -```. This gives us the ability to define these values based on inputs. - -![Exercise](images/7-3/Exercise/10.png) ->1. By changing the sliders (ranging from 0 to 10), we get some interesting results. - -![Exercise](images/7-3/Exercise/09.png) ->1. By doing a transpose on the number range, we reverse the direction of the curtain wave: ```transposeList = List.Transpose(sineList); -``` - -![Exercise](images/7-3/Exercise/07.png) ->1. We get a distorted eggshell surface when we add the sineList and the tranposeList: ```eggShellList = sineList+transposeList; -``` - -![Exercise](images/7-3/Exercise/05.png) ->1. Changing the sliders again let's us calm the waters of this algorithm. - -![Exercise](images/7-3/Exercise/04.png) ->1. Last, let's query isolated parts of the data with the code block. To regenerate the surface with a specific range of points, add the code block above between the *Geometry.Translate* and *NurbsSurface.ByPoints* node. This has the line of text: ```sineStrips[0..15..1]; -```. This will select the first 16 rows of points (out of 50). Recreating the surface, we can see that we've generated an isolated portion of the grid of points. - - -![Exercise](images/7-3/Exercise/03.png) ->1. In the final step, to make this code block more parametric, we drive the query by using a slider ranging from 0 to 1. We do this with this line of code: ```sineStrips[0..((List.Count(sineStrips)-1)*u)]; -```. This may seem confusing, but the line of code gives us a quick way to scale the length of the list into a multiplier between 0 and 1. - - -![Exercise](images/7-3/Exercise/02.png) ->1. A value of *.53* on the slider creates a surface just past the midpoint of the grid. - -![Exercise](images/7-3/Exercise/01.png) ->1. And as expected, a slider of *1* creates a surface from the full grid of points. - -![Exercise](images/7-3/Exercise/00.png) -> Looking at the resultant visual graph, we can highlight the code blocks and see each of their functions. -1. The first code block replaces the *Number* node. -2. The second code block replaces the *Number Range* node. -3. The third code block replaces the *Formula* node (as well as *List.Transpose*, *List.Count* and *Number Range*). -4. The fourth code block queries a list of lists, replacing the *List.GetItemAtIndex* node. - - - - - - - - + + +## Shorthand +There are a few basic shorthand methods in the code block which, simply put, make data management *a lot* easier. We'll break down the basics below and discuss how this shorthand can be used both for creating and querying data. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Data TypeStandard Dynamo Code Block Equilvalent
Numbers
Strings
Sequences
Ranges
Get Item at Index
Create List
Concatenate Strings
Conditional Statements
+ +###Additional Syntax +| Node(s) | Code Block Equivalent | Note | +| -- | -- | -- | +| Any operator (+, &&, >=, Not, etc.) |+, &&, >=, !, etc.| Note that “Not” becomes “!” but the node is called “Not” to distinguish from “Factorial”| +| Boolean True | true; | Note lower case | +| Boolean False | false; | Note lower case | + +### Ranges +The method for defining ranges and sequences can be reduced to basic shorthand. Use the image below as a guide to the ".." syntax for defining a list of numerical data with code block. After getting the hang of this notation, creating numerical data is a really efficient process: +![Obsolete Ranges](images/7-3/obsolete02.png) +> 1. In this example, a number range is replaced by basic code block syntax defining the ```beginning..end..step-size; +```. Represented numerically, we get: ```0..10..1; +``` +2. Notice that the syntax ```0..10..1; +``` is equivalent to ```0..10; +```. A step-size of 1 is the default value for the shorthand notation. So ```0..10; +``` will give a sequence from 0 to 10 with a step-size of 1. +3. The *number sequence* example is similar, except we use a *"#"* to state that we want 15 values in the list, rather than a list which goes up to 15. In this case, we are defining: ```beginning..#ofSteps..step-size: +```. The actual syntax for the sequence is ```0..#15..2 +``` +4. Using the *"#"* from the previous step, we now place it in the *"step-size"* portion of the syntax. Now, we have a *number range* spanning from the *"beginning"* to the *"end"* and the *"step-size"* notation evenly distributes a number of values between the two: ```beginning..end..#ofSteps +``` + +### Advanced Ranges +Creating advanced ranges allows us to work with list of lists in a simple fashion. In the examples below, we're isolating a variable from the primary range notation, and creating another range of that list. +![Ranges](images/7-3/03.png) +>1. Creating nested ranges, compare the notation with a *"#"* vs. the notation without. The same logic applies as in basic ranges, except it gets a little more complex. +2. We can define a sub-range at any place within the primary range, and notice that we can have two sub-ranges as well. +3. By controlling the *"end"* value in a range, we create more ranges of differing lengths. + +![Ranges](images/7-3/02.png) +> As a logic exercise, compare the two shorthands above and try to parse through how *subranges* and the *"#"* notation drive the resultant output. + +### Make lists and get items from a list +In addition to making lists with shorthand, we can also create lists on the fly. These list can contain a wide range of element types and can also be queried (remember, lists are objects in themselves). To summarize, with code block you make lists with braces (a.k.a. “curly brackets”) and you query items from a list with brackets (a.k.a. “square brackets”): + +![Querying Lists](images/7-3/cbn07.png) +>1. Create lists quickly with strings and query them using the item index. +2. Create lists with variables and query using the range shorthand notation. + +And manging with nested lists is a similar process. Be aware of the list order and recall using multiple sets of square brackets: + +![Querying Lists](images/7-3/cbn08.png) +> 1. Define a list of lists. +2. Query a list with single bracket notation. +3. Query an item with double bracket notation. + + + + +### Exercise +>Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Obsolete-Nodes_Sine-Surface.dyn](datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn) + +In this exercise, we will flex our new shorthand skills to create a funky-cool eggshell surface defined by ranges and formulas. During this exercise, notice how we use code block and existing Dynamo nodes in tandem: we use the code block for the heavy data lifting while the Dynamo nodes are visually laid out for legibility of the definition. + +![Exercise](images/7-3/Exercise/13.png) +> Start by creating a surface by connecting the nodes above. Instead of using a number node to define width and length, double click on the canvas and type ```100; +``` into a code block. + + +![Exercise](images/7-3/Exercise/12.png) +>1. Define a range between 0 and 1 with 50 divisions by typing ```0..1..#50 +``` into a code block. +2. Connect the range into *Surface.PointAtParameter*, which takes *u* and *v* values between 0 and 1 across the surface. Remember to change the *Lacing* to *Cross Product* by right clicking on the *Surface.PointAtParameter* node. + + +![Exercise](images/7-3/Exercise/11.png) +> In this step, we employ our first function to move the grid of points up in the Z. This grid will drive a generated surface based on the underlying function. +1. Add the visual nodes to the canvas as shown in the image above. +2. Rather than using a formula node, we use a code block with the line: ```(0..Math.Sin(x*360)..#50)*5; +```. To quickly break this down, we're defining a range with a formula inside of it. This formula is the Sine function. The sine function receives degree inputs in Dynamo, so in order to get a full sine wave, we multiple our *x* values (this is the range input from 0 to 1) by *360*. Next we want the same number of divisions as control grid points for each row, so we define fifty subdivisions with *#50*. Finally, the multiplier of 5 simply increases the amplitude of translation so that we can see the effect in the Dynamo Preview. + + +![Exercise](images/7-3/Exercise/06.png) +> 1. While the previous code block worked fine, it wasn't completely parametric. We want to dynamically drive its parameters, so we'll replace the line from the previous step with ```(0..Math.Sin(x*360*cycles)..#List.Count(x))*amp; +```. This gives us the ability to define these values based on inputs. + +![Exercise](images/7-3/Exercise/10.png) +>1. By changing the sliders (ranging from 0 to 10), we get some interesting results. + +![Exercise](images/7-3/Exercise/09.png) +>1. By doing a transpose on the number range, we reverse the direction of the curtain wave: ```transposeList = List.Transpose(sineList); +``` + +![Exercise](images/7-3/Exercise/07.png) +>1. We get a distorted eggshell surface when we add the sineList and the tranposeList: ```eggShellList = sineList+transposeList; +``` + +![Exercise](images/7-3/Exercise/05.png) +>1. Changing the sliders again let's us calm the waters of this algorithm. + +![Exercise](images/7-3/Exercise/04.png) +>1. Last, let's query isolated parts of the data with the code block. To regenerate the surface with a specific range of points, add the code block above between the *Geometry.Translate* and *NurbsSurface.ByPoints* node. This has the line of text: ```sineStrips[0..15..1]; +```. This will select the first 16 rows of points (out of 50). Recreating the surface, we can see that we've generated an isolated portion of the grid of points. + + +![Exercise](images/7-3/Exercise/03.png) +>1. In the final step, to make this code block more parametric, we drive the query by using a slider ranging from 0 to 1. We do this with this line of code: ```sineStrips[0..((List.Count(sineStrips)-1)*u)]; +```. This may seem confusing, but the line of code gives us a quick way to scale the length of the list into a multiplier between 0 and 1. + + +![Exercise](images/7-3/Exercise/02.png) +>1. A value of *.53* on the slider creates a surface just past the midpoint of the grid. + +![Exercise](images/7-3/Exercise/01.png) +>1. And as expected, a slider of *1* creates a surface from the full grid of points. + +![Exercise](images/7-3/Exercise/00.png) +> Looking at the resultant visual graph, we can highlight the code blocks and see each of their functions. +1. The first code block replaces the *Number* node. +2. The second code block replaces the *Number Range* node. +3. The third code block replaces the *Formula* node (as well as *List.Transpose*, *List.Count* and *Number Range*). +4. The fourth code block queries a list of lists, replacing the *List.GetItemAtIndex* node. + + + + + + + + diff --git a/07_Code-Block/7-4_functions.md b/07_Code-Block/7-4_functions.md index bc2cd74b..4d6d590b 100644 --- a/07_Code-Block/7-4_functions.md +++ b/07_Code-Block/7-4_functions.md @@ -1,122 +1,122 @@ -## Code Block Functions -Functions can be created in a code block and recalled elsewhere in a Dynamo definition. This creates another layer of control in a parametric file, and can be viewed as a text-based version of a custom node. In this case, the "parent" code block is readily accessible and can be located anywhere on the graph. No wires needed! - -### Parent -The first line has the key word “def”, then the function name, then the names of inputs in parentheses. Braces define the body of the function. Return a value with “return =”. Code Blocks that define a function do not have input or output ports because they are called from other Code Blocks. -![Parents](images/7-4/21.png) -``` -/*This is a multi-line comment, -which continues for -multiple lines*/ - -def FunctionName(input1,input2) -{ -//This is a comment -sum = input1+input2; -return = sum; -}; -``` - -### Children -Call the function with another Code Block in the same file by giving the name and the same number of arguments. It works just like the out-of-the-box nodes in your library. - -![Children](images/7-4/20.png) -``` -FunctionName(in1,in2); -``` - - - - - -### Exercise ->Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Functions_SphereByZ.dyn](datasets/7-4/Functions_SphereByZ.dyn) - -In this exercise, we will make a generic definition that will create spheres from an input list of points. The radius of these spheres are driven by the Z property of each point. - -![Exercise](images/7-4/Exercise/11.png) -> Let's begin with a number range of ten values spanning from 0 to 100. Plug these into a *Point.ByCoordinates* nodes to create a diagonal line. - -![Exercise](images/7-4/Exercise/10.png) ->1. Create a *code block* and introduce our definition by using the line of code: -``` -def sphereByZ(inputPt){ -}; -``` - The *inputPt* is the name we've given to represent the points that will drive the function. As of now, the function isn't doing anything, but we'll build up this function in the steps to come. - -![Exercise](images/7-4/Exercise/09.png) ->1. Adding to the *code block* function, we place a comment and a *sphereRadius* variable which queries the *Z* position of each point. Remember, *inputPt.Z* does not need parenetheses as a method. This is a *query* of an existing element's properties, so no inputs are necessary: -``` -def sphereByZ(inputPt,radiusRatio) -{ -//get Z Value, use it to drive radius of sphere -sphereRadius=inputPt.Z; -}; -``` - -![Exercise](images/7-4/Exercise/08.png) ->1. Now, let's recall the function we've created in another *code block*. If we double-click on the canvas to create a new *code block*, and type in *sphereB*, we notice that Dynamo suggest the *sphereByZ* function that we've defined. Your function has been added to the intellisense library! Pretty cool. - -![Exercise](images/7-4/Exercise/07.png) ->1. Now we call the function and create a variable called *Pt* to plug in the points created in the earlier steps: -```sphereByZ(Pt) -``` -2. We notice from the output that we have all null values. Why is this? When we defined the function, we are calculating the *sphereRadius* variable, but we did not define what the function should *return* as an *output*. We can fix this in the next step. - -![Exercise](images/7-4/Exercise/06.png) ->1. An important step, we need to define the output of the function by adding the line ```return = sphereRadius; -``` to the *sphereByZ* function. -2. Now we see that the output of the *code block* gives us the Z coordinates of each point. - - -![Exercise](images/7-4/Exercise/05.png) -> Let's create actual spheres now by editing the *Parent* function. -1. We first define a sphere with the line of code: -```sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius); -``` -2. Next, we change the return value to be the *sphere* instead of the *sphereRadius*: ```return = sphere; -```. This gives us some giant spheres in our Dynamo preview! - - -![Exercise](images/7-4/Exercise/04.png) ->1. To temper the size of these spheres, let's update the *sphereRadius* value by adding a divider: ```sphereRadius = inputPt.Z/20; -```. Now we can see the separate spheres and start to make sense of the relationship between radius and Z value. - -![Exercise](images/7-4/Exercise/03.png) ->1. On the *Point.ByCoordinates* node, by changing the lacing from *Shortest List* to *Cross Product*, we create a grid of points. The *sphereByZ* function is still in full effect, so the points all create spheres with radii based on Z values. - -![Exercise](images/7-4/Exercise/02.png) ->1. And just to test the waters, we plug the original list of numbers into the X input for *Point.ByCoordinates*. We now have a cube of spheres. -2. Note: if this takes a long time to calculate on your computer, try to change *#10* to something like *#5*. - -![Exercise](images/7-4/Exercise/01.png) -> 1. Remember, the *sphereByZ* function we've created is a generic function, so we can recall the helix from an earlier lesson and apply the function to it. - -![Exercise](images/7-4/Exercise/20.png) -> One final step: let's drive the radius ratio with a user defined parameter. To do this, we need to create a new input for the function and also replace the *20* divider with a parameter. -1. Update the *sphereByZ* definition to: -``` -def sphereByZ(inputPt,radiusRatio) -{ -//get Z Value, use it to drive radius of sphere -sphereRadius=inputPt.Z/radiusRatio; -//Define Sphere Geometry -sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius); -//Define output for function -return = sphere; -};``` -2. Update the children code blocks by adding a *ratio* variable to the input: ```sphereByZ(Pt,ratio); -``` -Plug a slider into the newly created code block input and vary the size of the radii based on the radius ratio. - - - - - - - - - - - +## Code Block Functions +Functions can be created in a code block and recalled elsewhere in a Dynamo definition. This creates another layer of control in a parametric file, and can be viewed as a text-based version of a custom node. In this case, the "parent" code block is readily accessible and can be located anywhere on the graph. No wires needed! + +### Parent +The first line has the key word “def”, then the function name, then the names of inputs in parentheses. Braces define the body of the function. Return a value with “return =”. Code Blocks that define a function do not have input or output ports because they are called from other Code Blocks. +![Parents](images/7-4/21.png) +``` +/*This is a multi-line comment, +which continues for +multiple lines*/ + +def FunctionName(input1,input2) +{ +//This is a comment +sum = input1+input2; +return = sum; +}; +``` + +### Children +Call the function with another Code Block in the same file by giving the name and the same number of arguments. It works just like the out-of-the-box nodes in your library. + +![Children](images/7-4/20.png) +``` +FunctionName(in1,in2); +``` + + + + + +### Exercise +>Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Functions_SphereByZ.dyn](datasets/7-4/Functions_SphereByZ.dyn) + +In this exercise, we will make a generic definition that will create spheres from an input list of points. The radius of these spheres are driven by the Z property of each point. + +![Exercise](images/7-4/Exercise/11.png) +> Let's begin with a number range of ten values spanning from 0 to 100. Plug these into a *Point.ByCoordinates* nodes to create a diagonal line. + +![Exercise](images/7-4/Exercise/10.png) +>1. Create a *code block* and introduce our definition by using the line of code: +``` +def sphereByZ(inputPt){ +}; +``` + The *inputPt* is the name we've given to represent the points that will drive the function. As of now, the function isn't doing anything, but we'll build up this function in the steps to come. + +![Exercise](images/7-4/Exercise/09.png) +>1. Adding to the *code block* function, we place a comment and a *sphereRadius* variable which queries the *Z* position of each point. Remember, *inputPt.Z* does not need parenetheses as a method. This is a *query* of an existing element's properties, so no inputs are necessary: +``` +def sphereByZ(inputPt,radiusRatio) +{ +//get Z Value, use it to drive radius of sphere +sphereRadius=inputPt.Z; +}; +``` + +![Exercise](images/7-4/Exercise/08.png) +>1. Now, let's recall the function we've created in another *code block*. If we double-click on the canvas to create a new *code block*, and type in *sphereB*, we notice that Dynamo suggest the *sphereByZ* function that we've defined. Your function has been added to the intellisense library! Pretty cool. + +![Exercise](images/7-4/Exercise/07.png) +>1. Now we call the function and create a variable called *Pt* to plug in the points created in the earlier steps: +```sphereByZ(Pt) +``` +2. We notice from the output that we have all null values. Why is this? When we defined the function, we are calculating the *sphereRadius* variable, but we did not define what the function should *return* as an *output*. We can fix this in the next step. + +![Exercise](images/7-4/Exercise/06.png) +>1. An important step, we need to define the output of the function by adding the line ```return = sphereRadius; +``` to the *sphereByZ* function. +2. Now we see that the output of the *code block* gives us the Z coordinates of each point. + + +![Exercise](images/7-4/Exercise/05.png) +> Let's create actual spheres now by editing the *Parent* function. +1. We first define a sphere with the line of code: +```sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius); +``` +2. Next, we change the return value to be the *sphere* instead of the *sphereRadius*: ```return = sphere; +```. This gives us some giant spheres in our Dynamo preview! + + +![Exercise](images/7-4/Exercise/04.png) +>1. To temper the size of these spheres, let's update the *sphereRadius* value by adding a divider: ```sphereRadius = inputPt.Z/20; +```. Now we can see the separate spheres and start to make sense of the relationship between radius and Z value. + +![Exercise](images/7-4/Exercise/03.png) +>1. On the *Point.ByCoordinates* node, by changing the lacing from *Shortest List* to *Cross Product*, we create a grid of points. The *sphereByZ* function is still in full effect, so the points all create spheres with radii based on Z values. + +![Exercise](images/7-4/Exercise/02.png) +>1. And just to test the waters, we plug the original list of numbers into the X input for *Point.ByCoordinates*. We now have a cube of spheres. +2. Note: if this takes a long time to calculate on your computer, try to change *#10* to something like *#5*. + +![Exercise](images/7-4/Exercise/01.png) +> 1. Remember, the *sphereByZ* function we've created is a generic function, so we can recall the helix from an earlier lesson and apply the function to it. + +![Exercise](images/7-4/Exercise/20.png) +> One final step: let's drive the radius ratio with a user defined parameter. To do this, we need to create a new input for the function and also replace the *20* divider with a parameter. +1. Update the *sphereByZ* definition to: +``` +def sphereByZ(inputPt,radiusRatio) +{ +//get Z Value, use it to drive radius of sphere +sphereRadius=inputPt.Z/radiusRatio; +//Define Sphere Geometry +sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius); +//Define output for function +return = sphere; +};``` +2. Update the children code blocks by adding a *ratio* variable to the input: ```sphereByZ(Pt,ratio); +``` +Plug a slider into the newly created code block input and vary the size of the radii based on the radius ratio. + + + + + + + + + + + diff --git a/07_Code-Block/7_Code-Blocks-and-Design-Script.md b/07_Code-Block/7_Code-Blocks-and-Design-Script.md index 2ff13009..44cf1565 100644 --- a/07_Code-Block/7_Code-Blocks-and-Design-Script.md +++ b/07_Code-Block/7_Code-Blocks-and-Design-Script.md @@ -1,5 +1,5 @@ -# Code Blocks and DesignScript - -The code block is a unique feature in Dynamo that dynamically links a visual programming environment with a text-based one. The code-block has access to all of the Dynamo nodes and can define an entire graph in one node. Read this chapter closely, as the code block is a fundamental building block of Dynamo. - -![IMAGE](images/7/Code Blocks-01.png) +# Code Blocks and DesignScript + +The code block is a unique feature in Dynamo that dynamically links a visual programming environment with a text-based one. The code-block has access to all of the Dynamo nodes and can define an entire graph in one node. Read this chapter closely, as the code block is a fundamental building block of Dynamo. + +![IMAGE](images/7/Code Blocks-01.png) diff --git a/07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn b/07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn index 0cd3b877..79be5b88 100644 --- a/07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn +++ b/07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn @@ -1,106 +1,106 @@ - - - - - - - - - - - - - - -3.59999999999999 - - - - - 50 - - - - - -3.59999999999999 - - - - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -3.59999999999999 - - - - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + -3.59999999999999 + + + + + 50 + + + + + -3.59999999999999 + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -3.59999999999999 + + + + 50 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn b/07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn index 38a72ce5..8832668b 100644 --- a/07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn +++ b/07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn @@ -1,133 +1,133 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - 2 - - - - 8 - - - - - - 1 - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + 2 + + + + 8 + + + + + + 1 + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn b/07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn index de9ca6b5..f5d9681e 100644 --- a/07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn +++ b/07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn @@ -1,55 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/8-1_The-Revit-Connection.md b/08_Dynamo-for-Revit/8-1_The-Revit-Connection.md index 412166e4..433b36ec 100644 --- a/08_Dynamo-for-Revit/8-1_The-Revit-Connection.md +++ b/08_Dynamo-for-Revit/8-1_The-Revit-Connection.md @@ -1,36 +1,36 @@ -## The Revit Connection -![Connection](images/8-1/link.png) -Dynamo for Revit extends building information modeling with the data and logic environment of a graphical algorithm editor. Its flexibility, coupled with a robust Revit database, offers a new perspective for BIM. - -This chapter focuses on the Dynamo workflows for BIM. Sections are primarily exercise-based, since jumping right into a project is the best way to get familiar with a graphical algorithm editor for BIM. But first, let's talk about the beginnings of the program. - -####History of Dynamo -![History](images/8-1/earlyScreenshot.png) -> With a dedicated team of developers and a passionate community, the project has come a long way from its humble beginnings. - -Dynamo was originally created to streamline AEC workflows in Revit. While Revit creates a robust database for every project, it can be difficult for an average user to access this information outside of the constraints of the interface. Revit hosts a comprehensive API (Application Program Interface), allowing third-party developers to create custom tools. And programmers have been using this API for years, but text-based scripting isn't accessible to everyone. Dynamo seeks to democratize Revit data through an approachable graphical algorithm editor. - -Using the core Dynamo nodes in tandem with custom Revit ones, a user can substantially expand parametric workflows for interoperability, documentation, analysis, and generation. With Dynamo, tedious workflows can be automated while design explorations can thrive. - - -### Running Dynamo in Revit -![Connection](images/8-1/01.png) ->1. In a Revit projector family editor, navigate to Addins and click *Dynamo*. Take note: Dynamo will run only in the file in which it was opened. - -![Connection](images/8-1/00.png) ->1. When openinig Dynamo in Revit, there is a new category called *"Revit"*. This is a comprehensive addition to the UI which offers nodes specifically catering to Revit workflows.* - -**Note - By using the Revit-specific family of nodes, the Dynamo graph will only work when opening in Dynamo for Revit. If a Dynamo for Revit graph is opened in Dynamo Sandbox for example, the Revit nodes will be missing.* - -### Freezing Nodes -Since Revit is a platform which provides robust project management, parametric operations in Dynamo can be complex and slow to calculate. If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). - -### Community -Since Dynamo was originally created for AEC, its large and growing community is a great resource for learning from and connecting with experts in the industry. Dynamo’s community is made of architects, engineers, programmers, and designers who all have a passion for sharing and making. - -Dynamo is an open-source project that is constantly evolving, and a lot of development is Revit-related. If you're new to the game, get on the discussion forum and start [posting questions](http://dynamobim.org/forums/forum/dyn/)! If you're a programmer and want to get involved in Dynamo's development, check out the [github page.](https://github.com/DynamoDS/Dynamo). Also, a great resource for third-party libraries is the [Dynamo package manager](http://dynamopackages.com/). Many of these packages are made with AEC in mind, and we'll take a look at third-party packages for panelization in this chapter. - -![Blog](images/8-1/blog.png) -> Dynamo also maintains an active [blog](http://dynamobim.com/blog/). Read up on recent posts to learn about the latest developments! - - +## The Revit Connection +![Connection](images/8-1/link.png) +Dynamo for Revit extends building information modeling with the data and logic environment of a graphical algorithm editor. Its flexibility, coupled with a robust Revit database, offers a new perspective for BIM. + +This chapter focuses on the Dynamo workflows for BIM. Sections are primarily exercise-based, since jumping right into a project is the best way to get familiar with a graphical algorithm editor for BIM. But first, let's talk about the beginnings of the program. + +####History of Dynamo +![History](images/8-1/earlyScreenshot.png) +> With a dedicated team of developers and a passionate community, the project has come a long way from its humble beginnings. + +Dynamo was originally created to streamline AEC workflows in Revit. While Revit creates a robust database for every project, it can be difficult for an average user to access this information outside of the constraints of the interface. Revit hosts a comprehensive API (Application Program Interface), allowing third-party developers to create custom tools. And programmers have been using this API for years, but text-based scripting isn't accessible to everyone. Dynamo seeks to democratize Revit data through an approachable graphical algorithm editor. + +Using the core Dynamo nodes in tandem with custom Revit ones, a user can substantially expand parametric workflows for interoperability, documentation, analysis, and generation. With Dynamo, tedious workflows can be automated while design explorations can thrive. + + +### Running Dynamo in Revit +![Connection](images/8-1/01.png) +>1. In a Revit projector family editor, navigate to Addins and click *Dynamo*. Take note: Dynamo will run only in the file in which it was opened. + +![Connection](images/8-1/00.png) +>1. When openinig Dynamo in Revit, there is a new category called *"Revit"*. This is a comprehensive addition to the UI which offers nodes specifically catering to Revit workflows.* + +**Note - By using the Revit-specific family of nodes, the Dynamo graph will only work when opening in Dynamo for Revit. If a Dynamo for Revit graph is opened in Dynamo Sandbox for example, the Revit nodes will be missing.* + +### Freezing Nodes +Since Revit is a platform which provides robust project management, parametric operations in Dynamo can be complex and slow to calculate. If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). + +### Community +Since Dynamo was originally created for AEC, its large and growing community is a great resource for learning from and connecting with experts in the industry. Dynamo’s community is made of architects, engineers, programmers, and designers who all have a passion for sharing and making. + +Dynamo is an open-source project that is constantly evolving, and a lot of development is Revit-related. If you're new to the game, get on the discussion forum and start [posting questions](http://dynamobim.org/forums/forum/dyn/)! If you're a programmer and want to get involved in Dynamo's development, check out the [github page.](https://github.com/DynamoDS/Dynamo). Also, a great resource for third-party libraries is the [Dynamo package manager](http://dynamopackages.com/). Many of these packages are made with AEC in mind, and we'll take a look at third-party packages for panelization in this chapter. + +![Blog](images/8-1/blog.png) +> Dynamo also maintains an active [blog](http://dynamobim.com/blog/). Read up on recent posts to learn about the latest developments! + + diff --git a/08_Dynamo-for-Revit/8-2_Selecting.md b/08_Dynamo-for-Revit/8-2_Selecting.md index 6906417f..0a0e7372 100644 --- a/08_Dynamo-for-Revit/8-2_Selecting.md +++ b/08_Dynamo-for-Revit/8-2_Selecting.md @@ -1,116 +1,116 @@ -## Selecting -Revit is a data-rich environment. This gives us a range of selection abilities which expands far beyond "point-and-click". We can query the Revit database and dynamically link Revit elements to Dynamo geometry while performing parametric operations. - -![UI](images/8-2/selectionUI.png) -> The Revit library in the UI offers a "Selection" category which enables multiple ways to select geometry. - -To select Revit elements properly, it's important to have a full-understanding of the Revit element hierarchy. Want to select all the walls in a project? Select by category. Want to select every Eames chair in your mid-century modern lobby? Select by family. Before jumping into an exercise, let's do a quick review of the Revit hierarchy. - -#### Revit Hierarchy -![UI](images/8-2/hierarchy.png) - -Remember the taxonomy from Biology? Kingdom, Phylum, Class, Order, Family, Genus, Species? Revit elements are categorized in a similar manner. On a basic level, the Revit hierarchy can be broken down into Categories, Families, Types*, and Instances. An instance is an individual model element (with a unique ID) while a category defines a generic group (like "walls" or "floors"). With the Revit database organized in this manner, we can select one element and choose all similar elements based on a specified level in the hierarchy. - -**Note - Types in Revit are defined differently from types in programming. In Revit, a type refers to a branch of the hierarchy, rather than a "data type".* -#### Database Navigation with Dynamo nodes -The three images below breakdown the main categories for Revit element selection in Dynamo. These are great tools to use in combination, and we'll explore some of these in the following exercises. - -![UI](images/8-2/pointandclick.png) -> *Point-and-click* is the easiest way to directly select a Revit element. You can select a full model element, or parts of its topology (like a face or an edge). This remains dynamically linked to that Revit object, so when the Revit file updates its location or parameters, the referenced Dynamo element will update in the graph. - -![UI](images/8-2/dropdown.png) -> *Dropdown menus* create a list of all accessible elements in a Revit project. You can use this to reference Revit elements which are not necessarily visible in a view. This is a great tool for querying existing elements or creating new ones in a Revit project or family editor. - -![UI](images/8-2/allelements.png) -> You can also select Revit element by specific tiers in the *Revit hierarchy*. This is a powerful option for customizing large arrays of data in preparation for documentation or generative instantiation and customization. - -With the three images above in mind, let's dive into an exercise which selects elements from a basic Revit project in preparation for the parametric applications we'll create in the remaining sections of this chapter. - -### Exercise ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Selecting.dyn](datasets/8-2/Selecting.dyn) -2. [ARCH-Selecing-BaseFile.rvt](datasets/8-2/ARCH-Selecting-BaseFile.rvt) - -![Exercise](images/8-2/Exercise/12.png) -> In this example Revit file, we have three element types of a simple building. We're going to use this as an example for selecting Revit elements within the context of the Revit hierachy: -1. Building Mass -2. Trusses (Adaptive Components) -3. Beams (Structural Framing) - -![Exercise](images/8-2/Exercise/11.png) -> What conclusions can we draw from the elements currently in the Revit project view? And how far down the hierarchy do we need to go to select the appropriate elements? This will of course become a more complex task when working on a large project. There are a lot of options available: we can select elements by categories, levels, families, instances, etc. -1. Since we're working with a basic setup, let's select the building mass by choosing *"Mass"* in the Categories dropdown node. This can be found in the Revit>Selection tab. -2. The output of the Mass category is just the category itself. We need to select the elements. To do this, we use the *"All Elements of Category"* node. -3. A *Watch* node reveals that we've selected the BldgMass. - -At this point, notice that we don't see any geometry in Dynamo. We've selected a Revit element, but have not converted the element into Dynamo geometry. This is an important separation. If you were to select a large number of elements, you don't want to preview all of them in Dynamo because this would slow everything down. Dynamo is a tool to manage a Revit project without necessarily performing geometry operations, and we'll look at that in the next section of this chapter. - -In this case, we're working with simple geometry, so we want to bring the geometry into the Dynamo preview. The "BldgMass" in the watch node above has a green number* next to it. This represents the element's ID and tells us that we are dealing with a Revit element, not Dynamo geometry.The next step is to convert this Revit element into geometry in Dynamo. - -![Exercise](images/8-2/Exercise/10.png) -> 1. Using the *Element.Faces* node, we get a list of surfaces representing each face of the Revit Mass. We can now see the geometry in the Dynamo viewport and start to reference the face for parametric operations. - -![Exercise](images/8-2/Exercise/09.png) -> Here's an alternative method. In this case, we're stepping away from selecting via the Revit Hierarchy *("All Elements of Category")* and electing to explicitly select geometry in Revit. -1. Using the *"Select Model Element"* node, click the *"select" *(or *"change"*) button. In the Revit viewport, select the desired element. In this case, we're selecting the building mass. -2. Rather than *Element.Faces*, we can select the full mass as one solid geometry using *Element.Geometry*. This selects all of the geometry contained within that mass. -3. Using *Geometry.Explode,* we can get the list of surfaces again. These two nodes work the same as *Element.Faces* but offer alternative options for delving into the geometry of a Revit element. - -![Exercise](images/8-2/Exercise/08.png) -> 1. Using some basic list operations, we can query a face of interest. -2. First, the *List.Count* node reveals that we're working with 23 surfaces in the mass. -3. Referencing this number, we change the Maximum value of an *integer slider *to *"22"*. -4. Using *List.GetItemAtIndex*, we input the lists and the *integer slider *for the *index*. Sliding through with the selected, we stop when we get to *index 9* and have isolated the main facade hosts the trusses. - -![Exercise](images/8-2/Exercise/07.png) -> 1. The previous step was a little cumbersome. We can do this much faster with the *"Select Face"* node. This allows us to isolate a face that is not an element itself in the Revit project. The same interaction applies as *"Select Model Element"*, except we select the surface rather than the full element. - -![Exercise](images/8-2/Exercise/selectFaces.png) -> Suppose we want to isolate the main facade walls of the building. We can use the *"Select Faces"* node to do this. Click the "Select" button and then select the four main facades in Revit. - -![Exercise](images/8-2/Exercise/finishButton-01.png) -> 1. After selecting the four walls, make sure you click the *"Finish"* button in Revit. - -![Exercise](images/8-2/Exercise/06.png) -> 1. The faces are now imported into Dynamo as surfaces. - -![Exercise](images/8-2/Exercise/05.png) -> 1. Now, let's take a look at the beams over the atrium. Using the *"Select Model Element"* node, select one of the beams. -2. Plug the beam element into the *Element.Geometry* node and we now have the beam in the Dynamo viewport. -3. We can zoom in on the geometry with a *Watch3D* node (if you don't see the beam in Watch 3D, right click and hit "zoom to fit"). - -![Exercise](images/8-2/Exercise/04.png) -> A question that may come up often in Revit/Dynamo workflows: how do I select one element and get all similar elements? Since the selected Revit element contains all of its hierarchical information, we can query its family type and select all elements of that type. -1. Plug the beam element into a *FamilyInstance.Symbol** node. -2. The *Watch* node reveals that the output is now a family symbol rather than a Revit element. -3. *FamilyInstance.Symbol* is a simple query, so we can do this in the code block just as easily with ``` -x.Symbol;``` - and get the same results. - -**Note - a family symbol is Revit API terminology for family type. Since this may cause some confusion, it will be updated in upcoming releases.* - -![Exercise](images/8-2/Exercise/03.png) -> 1. To select the remaining beams, we use the *"All Elements of Family Type"* node. -2. The watch node shows that we've selected five revit elements. - -![Exercise](images/8-2/Exercise/02.png) -> 1. We can convert all of these five elements to Dynamo geometry too. - -What if we had 500 beams? Converting all of these elements into Dynamo geometry would be really slow. If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). - -In any case, if we were to import 500 beams, do we need all of the surfaces to perform the intended parametric operation? Or can we extract basic information from the beams and perform generative tasks with fundamental geometry? This is a question that we'll keep in mind as we walk through this chapter. For example, let's take a look at the truss system: - -![Exercise](images/8-2/Exercise/01.png) -> Using the same graph of nodes, select the truss element rather than the beam element. Before doing this, delete the Element.Geometry from the previous step. - -![Exercise](images/8-2/Exercise/00.png) -> 1. In the *Watch* node, we can see that we have a list of adaptive components selected from Revit. We want to extract the basic information, so we're start with the adaptive points. -2. Plug the *"All Elements of Family Type"* node into the *"AdaptiveComponent.Location"* node. This gives us a list of lists, each with three points which represent the adaptive point locations. -3. Connecting a *"Polygon.ByPoints"* node returns a polycurve. We can see this in the Dynamo viewport. By this method, we've visualized the geometry of one element and abstracted the geometry of the remaining array of elements (which could be larger in number than this example). - -**Tip: if you click on the green number of a Revit element in Dynamo, the Revit viewport will zoom to that element.* - - - - - +## Selecting +Revit is a data-rich environment. This gives us a range of selection abilities which expands far beyond "point-and-click". We can query the Revit database and dynamically link Revit elements to Dynamo geometry while performing parametric operations. + +![UI](images/8-2/selectionUI.png) +> The Revit library in the UI offers a "Selection" category which enables multiple ways to select geometry. + +To select Revit elements properly, it's important to have a full-understanding of the Revit element hierarchy. Want to select all the walls in a project? Select by category. Want to select every Eames chair in your mid-century modern lobby? Select by family. Before jumping into an exercise, let's do a quick review of the Revit hierarchy. + +#### Revit Hierarchy +![UI](images/8-2/hierarchy.png) + +Remember the taxonomy from Biology? Kingdom, Phylum, Class, Order, Family, Genus, Species? Revit elements are categorized in a similar manner. On a basic level, the Revit hierarchy can be broken down into Categories, Families, Types*, and Instances. An instance is an individual model element (with a unique ID) while a category defines a generic group (like "walls" or "floors"). With the Revit database organized in this manner, we can select one element and choose all similar elements based on a specified level in the hierarchy. + +**Note - Types in Revit are defined differently from types in programming. In Revit, a type refers to a branch of the hierarchy, rather than a "data type".* +#### Database Navigation with Dynamo nodes +The three images below breakdown the main categories for Revit element selection in Dynamo. These are great tools to use in combination, and we'll explore some of these in the following exercises. + +![UI](images/8-2/pointandclick.png) +> *Point-and-click* is the easiest way to directly select a Revit element. You can select a full model element, or parts of its topology (like a face or an edge). This remains dynamically linked to that Revit object, so when the Revit file updates its location or parameters, the referenced Dynamo element will update in the graph. + +![UI](images/8-2/dropdown.png) +> *Dropdown menus* create a list of all accessible elements in a Revit project. You can use this to reference Revit elements which are not necessarily visible in a view. This is a great tool for querying existing elements or creating new ones in a Revit project or family editor. + +![UI](images/8-2/allelements.png) +> You can also select Revit element by specific tiers in the *Revit hierarchy*. This is a powerful option for customizing large arrays of data in preparation for documentation or generative instantiation and customization. + +With the three images above in mind, let's dive into an exercise which selects elements from a basic Revit project in preparation for the parametric applications we'll create in the remaining sections of this chapter. + +### Exercise +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Selecting.dyn](datasets/8-2/Selecting.dyn) +2. [ARCH-Selecing-BaseFile.rvt](datasets/8-2/ARCH-Selecting-BaseFile.rvt) + +![Exercise](images/8-2/Exercise/12.png) +> In this example Revit file, we have three element types of a simple building. We're going to use this as an example for selecting Revit elements within the context of the Revit hierachy: +1. Building Mass +2. Trusses (Adaptive Components) +3. Beams (Structural Framing) + +![Exercise](images/8-2/Exercise/11.png) +> What conclusions can we draw from the elements currently in the Revit project view? And how far down the hierarchy do we need to go to select the appropriate elements? This will of course become a more complex task when working on a large project. There are a lot of options available: we can select elements by categories, levels, families, instances, etc. +1. Since we're working with a basic setup, let's select the building mass by choosing *"Mass"* in the Categories dropdown node. This can be found in the Revit>Selection tab. +2. The output of the Mass category is just the category itself. We need to select the elements. To do this, we use the *"All Elements of Category"* node. +3. A *Watch* node reveals that we've selected the BldgMass. + +At this point, notice that we don't see any geometry in Dynamo. We've selected a Revit element, but have not converted the element into Dynamo geometry. This is an important separation. If you were to select a large number of elements, you don't want to preview all of them in Dynamo because this would slow everything down. Dynamo is a tool to manage a Revit project without necessarily performing geometry operations, and we'll look at that in the next section of this chapter. + +In this case, we're working with simple geometry, so we want to bring the geometry into the Dynamo preview. The "BldgMass" in the watch node above has a green number* next to it. This represents the element's ID and tells us that we are dealing with a Revit element, not Dynamo geometry.The next step is to convert this Revit element into geometry in Dynamo. + +![Exercise](images/8-2/Exercise/10.png) +> 1. Using the *Element.Faces* node, we get a list of surfaces representing each face of the Revit Mass. We can now see the geometry in the Dynamo viewport and start to reference the face for parametric operations. + +![Exercise](images/8-2/Exercise/09.png) +> Here's an alternative method. In this case, we're stepping away from selecting via the Revit Hierarchy *("All Elements of Category")* and electing to explicitly select geometry in Revit. +1. Using the *"Select Model Element"* node, click the *"select" *(or *"change"*) button. In the Revit viewport, select the desired element. In this case, we're selecting the building mass. +2. Rather than *Element.Faces*, we can select the full mass as one solid geometry using *Element.Geometry*. This selects all of the geometry contained within that mass. +3. Using *Geometry.Explode,* we can get the list of surfaces again. These two nodes work the same as *Element.Faces* but offer alternative options for delving into the geometry of a Revit element. + +![Exercise](images/8-2/Exercise/08.png) +> 1. Using some basic list operations, we can query a face of interest. +2. First, the *List.Count* node reveals that we're working with 23 surfaces in the mass. +3. Referencing this number, we change the Maximum value of an *integer slider *to *"22"*. +4. Using *List.GetItemAtIndex*, we input the lists and the *integer slider *for the *index*. Sliding through with the selected, we stop when we get to *index 9* and have isolated the main facade hosts the trusses. + +![Exercise](images/8-2/Exercise/07.png) +> 1. The previous step was a little cumbersome. We can do this much faster with the *"Select Face"* node. This allows us to isolate a face that is not an element itself in the Revit project. The same interaction applies as *"Select Model Element"*, except we select the surface rather than the full element. + +![Exercise](images/8-2/Exercise/selectFaces.png) +> Suppose we want to isolate the main facade walls of the building. We can use the *"Select Faces"* node to do this. Click the "Select" button and then select the four main facades in Revit. + +![Exercise](images/8-2/Exercise/finishButton-01.png) +> 1. After selecting the four walls, make sure you click the *"Finish"* button in Revit. + +![Exercise](images/8-2/Exercise/06.png) +> 1. The faces are now imported into Dynamo as surfaces. + +![Exercise](images/8-2/Exercise/05.png) +> 1. Now, let's take a look at the beams over the atrium. Using the *"Select Model Element"* node, select one of the beams. +2. Plug the beam element into the *Element.Geometry* node and we now have the beam in the Dynamo viewport. +3. We can zoom in on the geometry with a *Watch3D* node (if you don't see the beam in Watch 3D, right click and hit "zoom to fit"). + +![Exercise](images/8-2/Exercise/04.png) +> A question that may come up often in Revit/Dynamo workflows: how do I select one element and get all similar elements? Since the selected Revit element contains all of its hierarchical information, we can query its family type and select all elements of that type. +1. Plug the beam element into a *FamilyInstance.Symbol** node. +2. The *Watch* node reveals that the output is now a family symbol rather than a Revit element. +3. *FamilyInstance.Symbol* is a simple query, so we can do this in the code block just as easily with ``` +x.Symbol;``` + and get the same results. + +**Note - a family symbol is Revit API terminology for family type. Since this may cause some confusion, it will be updated in upcoming releases.* + +![Exercise](images/8-2/Exercise/03.png) +> 1. To select the remaining beams, we use the *"All Elements of Family Type"* node. +2. The watch node shows that we've selected five revit elements. + +![Exercise](images/8-2/Exercise/02.png) +> 1. We can convert all of these five elements to Dynamo geometry too. + +What if we had 500 beams? Converting all of these elements into Dynamo geometry would be really slow. If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). + +In any case, if we were to import 500 beams, do we need all of the surfaces to perform the intended parametric operation? Or can we extract basic information from the beams and perform generative tasks with fundamental geometry? This is a question that we'll keep in mind as we walk through this chapter. For example, let's take a look at the truss system: + +![Exercise](images/8-2/Exercise/01.png) +> Using the same graph of nodes, select the truss element rather than the beam element. Before doing this, delete the Element.Geometry from the previous step. + +![Exercise](images/8-2/Exercise/00.png) +> 1. In the *Watch* node, we can see that we have a list of adaptive components selected from Revit. We want to extract the basic information, so we're start with the adaptive points. +2. Plug the *"All Elements of Family Type"* node into the *"AdaptiveComponent.Location"* node. This gives us a list of lists, each with three points which represent the adaptive point locations. +3. Connecting a *"Polygon.ByPoints"* node returns a polycurve. We can see this in the Dynamo viewport. By this method, we've visualized the geometry of one element and abstracted the geometry of the remaining array of elements (which could be larger in number than this example). + +**Tip: if you click on the green number of a Revit element in Dynamo, the Revit viewport will zoom to that element.* + + + + + diff --git a/08_Dynamo-for-Revit/8-3_Editing.md b/08_Dynamo-for-Revit/8-3_Editing.md index 2592bdc1..37c90da2 100644 --- a/08_Dynamo-for-Revit/8-3_Editing.md +++ b/08_Dynamo-for-Revit/8-3_Editing.md @@ -1,70 +1,70 @@ -## Editing -A powerful feature of Dynamo is that you can edit parameters on a parametric level. For example, a generative algorithm or the results of a simulation can be used to drive the parameters of an array of elements. This way, a set of instances from the same family can have custom properties in your Revit project. -### Type and Instance Parameters -![Exercise](images/8-5/Exercise/32.png) -> 1. Instance parameters define the aperture of the panels on the roof surface, ranging from an Aperture Ratio of 0.1 to 0.4. -2. Type-based parameters are applied to every element on the surface because they are the same family type. The material of each panel, for example, can be driven by a type-based parameter. - -![Exercise](images/8-3/params.png) ->1. If you've set up a Revit family before, remember that you have to assign a parameter type (string, number, dimension, etc.) Be sure to use the correct data type when assigning parameters from Dynamo. -2. You can also use Dynamo in combination with parametric constraints defined in a Revit family's properties. - -As a quick review of parameters in Revit, we recall that there are type parameters and instance parameters. Both can be edited from Dynamo, but we'll work with instance parameters in the exercise below. - -Note: As you discover the wide-reaching application of editing parameters, you may want to edit a large quantity of elements in Revit with Dynamo. This can be a *computationally expensive* operation, meaning that it can be slow. If you're editing a large number of elements, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). - -#### Units -As of version 0.8, Dynamo is fundamentally unitless. This allows Dynamo to remain an abstract visual programming environment. Dynamo nodes that interact with Revit dimensions will reference The Revit project's units. For example, if you are setting a length parameter in Revit from Dynamo, the number in Dynamo for the value will correspond to the default units in the Revit project. The exercise below works in meters. - -![Exercise](images/8-3/units.png) -> For a quick conversion of units, use the *"Convert Between Units"* node. This is a handy tool for converting Length, Area, and Volume units on the fly. - -### Exercise ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Editing.dyn](datasets/8-3/Editing.dyn) -2. [ARCH-Editing-BaseFile.rvt](datasets/8-3/ARCH-Editing-BaseFile.rvt) - -This exercise focuses on editing Revit elements without performing geometric operation in Dynamo. We're not importing Dynamo geometry here, just editing parameters in a Revit project. This exercise is basic, and to the more advanced Revit users, notice that these are instance parameters of a mass, but the same logic can be applied to an array of elements to customize on a large scale. This is all done with the "Element.SetParameterByName" node. - -![Exercise](images/8-3/Exercise/04.png) -> Begin with the example Revit file for this section. We've removed the structural elements and adaptive trusses from the previous section. In this exercise, we will focus on a parametric rig in Revit and manipulating in Dynamo. -1. Selecting the building in Mass in Revit, we see an array of instance parameters in the properties panel. - -![Exercise](images/8-3/Exercise/03.png) -> 1. Select the building mass with the *"Select Model Element"* node. -2. We can query all of the parameters of this mass with the *"Element.Parmaters"* node. This includes type and instance parameters. - -![Exercise](images/8-3/Exercise/32.png) -> 1. Reference the *Element.Parameters* node to find target parameters. Or, we can view the properties panel from the previous step to choose which parameter names we want to edit. In this case, we are looking for the parameters which affect the large geometric moves on the building mass. -2. We will make changes to the Revit element using the *Element.SetParameterByName* node. -3. Using the *code block*, we define a list of these parameters, with quotes around each item to denote a string. We can also use the List.Create node with a series of *"string"* nodes connected to multiple inputs. Code block is simply faster and easier. Just make sure that the string matches the exact name in Revit, case-specific: ```{"BldgWidth","BldgLength","BldgHeight", "AtriumOffset", "InsideOffset","LiftUp"}; -``` - -![Exercise](images/8-3/Exercise/31.png) -> 1. We also want to designate values for each parameter. Add six *"integer sliders"* to the canvas and rename to the corresponding parameter in the list. Also, set the values of each slider to the image above. In order from top-to-bottom: ```62,92,25,22,8,12 -``` -2. Define another *code block* with a list of the same length as the parameter names. In this case, we name variables (without quotes) which create inputs for the *code block.* Plug the *sliders* into each respective input: ```{bw,bl,bh,ao,io.lu}; -``` -3. Connect the *code block *to the *"Element.SetParameterByName*"* node. With run automatically checked, we will automatically see results. - -**Note - this demonstration works with instance parameters, but not type parameters.* - -![Exercise](images/8-3/Exercise/01.png) -Just as in Revit, many of these parameters are dependent on each other. There are of course combinations where the geometry may break. We can remedy this issue with defined formulas in the parameter properties, or we can setup a similar logic with math operations in Dynamo (this is an additional challenge if you'd like to expand on the exercise). -> 1. This combination gives a funky new design to the building mass: ```100,92,100,25,13,51.4 -``` - -![Exercise](images/8-3/Exercise/30.png) -> 1. Let's copy the graph and focus on the facade glazing which will house the truss system. We isolate four parameters in this case: ``` {"DblSkin_SouthOffset","DblSkin_MidOffset","DblSkin_NorthOffset","Facade Bend Location"}; -``` -2. Additionally, we create *number sliders* and rename to the appropriate parameters. The first three sliders from top-to-bottom should be remapped to a domain of [0,10], while the final slider, *"Facade Bend Location"*, should be remapped to a domain of [0,1]. These values, from top-to-bottom should start with these values (although they're arbitrary): ```2.68,2.64,2.29,0.5 -``` -3. Define a new *code block *and connect the sliders: ```{so,mo,no,fbl}; -``` - - - -![Exercise](images/8-3/Exercise/00.png) -> 1. By changing the *sliders* in this part of the graph, we can make the facade glazing much more substantial: ```9.98,10.0,9.71,0.31 -``` - +## Editing +A powerful feature of Dynamo is that you can edit parameters on a parametric level. For example, a generative algorithm or the results of a simulation can be used to drive the parameters of an array of elements. This way, a set of instances from the same family can have custom properties in your Revit project. +### Type and Instance Parameters +![Exercise](images/8-5/Exercise/32.png) +> 1. Instance parameters define the aperture of the panels on the roof surface, ranging from an Aperture Ratio of 0.1 to 0.4. +2. Type-based parameters are applied to every element on the surface because they are the same family type. The material of each panel, for example, can be driven by a type-based parameter. + +![Exercise](images/8-3/params.png) +>1. If you've set up a Revit family before, remember that you have to assign a parameter type (string, number, dimension, etc.) Be sure to use the correct data type when assigning parameters from Dynamo. +2. You can also use Dynamo in combination with parametric constraints defined in a Revit family's properties. + +As a quick review of parameters in Revit, we recall that there are type parameters and instance parameters. Both can be edited from Dynamo, but we'll work with instance parameters in the exercise below. + +Note: As you discover the wide-reaching application of editing parameters, you may want to edit a large quantity of elements in Revit with Dynamo. This can be a *computationally expensive* operation, meaning that it can be slow. If you're editing a large number of elements, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing). + +#### Units +As of version 0.8, Dynamo is fundamentally unitless. This allows Dynamo to remain an abstract visual programming environment. Dynamo nodes that interact with Revit dimensions will reference The Revit project's units. For example, if you are setting a length parameter in Revit from Dynamo, the number in Dynamo for the value will correspond to the default units in the Revit project. The exercise below works in meters. + +![Exercise](images/8-3/units.png) +> For a quick conversion of units, use the *"Convert Between Units"* node. This is a handy tool for converting Length, Area, and Volume units on the fly. + +### Exercise +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Editing.dyn](datasets/8-3/Editing.dyn) +2. [ARCH-Editing-BaseFile.rvt](datasets/8-3/ARCH-Editing-BaseFile.rvt) + +This exercise focuses on editing Revit elements without performing geometric operation in Dynamo. We're not importing Dynamo geometry here, just editing parameters in a Revit project. This exercise is basic, and to the more advanced Revit users, notice that these are instance parameters of a mass, but the same logic can be applied to an array of elements to customize on a large scale. This is all done with the "Element.SetParameterByName" node. + +![Exercise](images/8-3/Exercise/04.png) +> Begin with the example Revit file for this section. We've removed the structural elements and adaptive trusses from the previous section. In this exercise, we will focus on a parametric rig in Revit and manipulating in Dynamo. +1. Selecting the building in Mass in Revit, we see an array of instance parameters in the properties panel. + +![Exercise](images/8-3/Exercise/03.png) +> 1. Select the building mass with the *"Select Model Element"* node. +2. We can query all of the parameters of this mass with the *"Element.Parmaters"* node. This includes type and instance parameters. + +![Exercise](images/8-3/Exercise/32.png) +> 1. Reference the *Element.Parameters* node to find target parameters. Or, we can view the properties panel from the previous step to choose which parameter names we want to edit. In this case, we are looking for the parameters which affect the large geometric moves on the building mass. +2. We will make changes to the Revit element using the *Element.SetParameterByName* node. +3. Using the *code block*, we define a list of these parameters, with quotes around each item to denote a string. We can also use the List.Create node with a series of *"string"* nodes connected to multiple inputs. Code block is simply faster and easier. Just make sure that the string matches the exact name in Revit, case-specific: ```{"BldgWidth","BldgLength","BldgHeight", "AtriumOffset", "InsideOffset","LiftUp"}; +``` + +![Exercise](images/8-3/Exercise/31.png) +> 1. We also want to designate values for each parameter. Add six *"integer sliders"* to the canvas and rename to the corresponding parameter in the list. Also, set the values of each slider to the image above. In order from top-to-bottom: ```62,92,25,22,8,12 +``` +2. Define another *code block* with a list of the same length as the parameter names. In this case, we name variables (without quotes) which create inputs for the *code block.* Plug the *sliders* into each respective input: ```{bw,bl,bh,ao,io.lu}; +``` +3. Connect the *code block *to the *"Element.SetParameterByName*"* node. With run automatically checked, we will automatically see results. + +**Note - this demonstration works with instance parameters, but not type parameters.* + +![Exercise](images/8-3/Exercise/01.png) +Just as in Revit, many of these parameters are dependent on each other. There are of course combinations where the geometry may break. We can remedy this issue with defined formulas in the parameter properties, or we can setup a similar logic with math operations in Dynamo (this is an additional challenge if you'd like to expand on the exercise). +> 1. This combination gives a funky new design to the building mass: ```100,92,100,25,13,51.4 +``` + +![Exercise](images/8-3/Exercise/30.png) +> 1. Let's copy the graph and focus on the facade glazing which will house the truss system. We isolate four parameters in this case: ``` {"DblSkin_SouthOffset","DblSkin_MidOffset","DblSkin_NorthOffset","Facade Bend Location"}; +``` +2. Additionally, we create *number sliders* and rename to the appropriate parameters. The first three sliders from top-to-bottom should be remapped to a domain of [0,10], while the final slider, *"Facade Bend Location"*, should be remapped to a domain of [0,1]. These values, from top-to-bottom should start with these values (although they're arbitrary): ```2.68,2.64,2.29,0.5 +``` +3. Define a new *code block *and connect the sliders: ```{so,mo,no,fbl}; +``` + + + +![Exercise](images/8-3/Exercise/00.png) +> 1. By changing the *sliders* in this part of the graph, we can make the facade glazing much more substantial: ```9.98,10.0,9.71,0.31 +``` + diff --git a/08_Dynamo-for-Revit/8-4_Creating.md b/08_Dynamo-for-Revit/8-4_Creating.md index 64555e28..2261f48c 100644 --- a/08_Dynamo-for-Revit/8-4_Creating.md +++ b/08_Dynamo-for-Revit/8-4_Creating.md @@ -1,126 +1,126 @@ -## Creating -You can create an array of Revit elements in Dynamo with full parametric control. The Revit nodes in Dynamo offer the ability to import elements from generic geometries to specific category types (like walls and floors). In this section, we'll focus on importing parametrically flexible elements with adaptive components. - -![Creation](images/8-4/creation.png) -### Adaptive Components -An adaptive component is a flexible family category which lends itself well to generative applications. Upon instantiation, you can create a complex geometric element which is driven by the fundamental location of adaptive points. - -![AdaptiveComponent](images/8-4/ac.png) -> An example of a three-point adaptive component in the family editor. This generates a truss which is defined by the position of each adaptive point. In the exercise below, we'll use this component to generate a series of trusses across a facade. - -#### Principles of Interoperability -The adaptive component is a good example for best practices of interoperability. We can create an array of adaptive components by defining the fundamental adaptive points. And, when transferring this data to other programs, we have the ability to reduce the geometry to simple data. Importing and exporting with a program like Excel follows a similar logic. - -Suppose a facade consultant wants to know the location of the truss elements without needing to parse through fully articulated geometry. In preparation for fabrication, the consultant can reference the location of adaptive points to regenerate geometry in a program like Inventor. - -The workflow we'll setup in the exercise below allows us to access all of this data while creating the definition for Revit element creation. By this process, we can merge conceptualization, documentation, and fabrication into a seamless workflow. This creates a more intelligent and efficient process for interoperability. - -#### Multiple Elements and Lists - -![Exercise](images/8-4/Exercise/03.png) - -The exercise below will walk through how Dynamo references data for Revit element creation. To generate multiple adaptive components, we define a list of lists, where each list has three points representing each point of the adaptive component. We'll keep this in mind as we manage the data structures in Dynamo. - -### Exercise -> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Creating.dyn](datasets/8-4/Creating.dyn) -2. [ARCH-Creating-BaseFile.rvt](datasets/8-4/ARCH-Creating-BaseFile.rvt) - -![Exercise](images/8-4/Exercise/10.png) -> Beginning with the example file from this section (or continuing with the Revit file from the previous session), we see the same Revit mass. -1. This is the file as opened. -2. This is the truss system we'll created with Dynamo, linked intelligently to the Revit mass. - -![Exercise](images/8-4/Exercise/08.png) -> We've used the *"Select Model Element"* and *"Select Face"* nodes, now we're taking one step further down in the geometry hierarchy and using *"Select Edge"*. With the Dynamo solver set to run *"Automatic"*, the graph will continually update to changes in the Revit file. The edge we are selecting is tied dynamically to the Revit element topology. As long as the topology* does not change, the connection remains linked between Revit and Dynamo. -1. Select the top most curve of the glazing facade. This spans the full length of the building. If you're having trouble selecting the edge, remember to choose the selection in Revit by hovering over the edge and hitting *"Tab"* until the desired edge is highlighted. -2. Using two *"Select Edge"* nodes, select each edge representing the cant at the middle of the facade. -3. Do the same for the bottom edges of the facade in Revit. -4. The *Watch* nodes reveal that we now have lines in Dynamo. This is automatically converted to Dynamo geometry since the edges themselves are not Revit elements. These curves are the references we'll use to instantiate adaptive trusses across the facade. - -**Note - to keep a consistent topology, we're referring to a model that does not have additional faces or edges added. While parameters can change its shape, the way it which it is built remains consistent.* - -![Exercise](images/8-4/Exercise/07.png) -> We first need to join the curves and merge them into one list. This way we can *"group"* the curves to perform geometry operations. -1. Create a list for the two curves at the middle of the facade. -2. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. -3. Create a list for the two curves at the bottom of the facade. -4. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. -5. Finally, join the three main curves (one line and two polycurves) into one list. - -![Exercise](images/8-4/Exercise/06.png) -> We want to take advantage of the top curve, which is a line, and represents the full span of the facade. We'll create planes along this line to intersect with the set of curves we've grouped together in a list. -1. With a *code block*, define a range using the syntax: ```0..1..#numberOfTrusses; -``` -2. Plug an *integer slider *into the input for the code block. As you could have guessed, this will represent the number of trusses. Notice that the slider controls the number of items in the range defined from *0 *to *1*. -3. Plug the *code block* into the *param* input of a *"Curve.PlaneAtParameter"* node, and plug the top edge into the *curve* input. This will give us ten planes, evenly distributed across the span of the facade. - -![Exercise](images/8-4/Exercise/05.png) -> A plane is an abstract piece of geometry, representing a two dimensional space which is infinite. Planes are great for contouring and intersecting, as we are setting up in this step. -1. Using the *Geometry.Intersect* node, plug the *Curve.PlaneAtParameter* into the *entity* input of the *Geometry.Intersect* node. Plug the main *List.Create* node into the *geometry* input. We now see points in the Dynamo viewport representing the intersection of each curve with the defined planes. - -![Exercise](images/8-4/Exercise/04.png) -> Notice the output is a list of lists of lists. Too many lists for our purposes. We want to do a partial flatten here. We need to take one step down on the list and flatten the result. To do this, we use the *List.Map* operation, as discussed in the list chapter of the primer. -1. Plug the *Geometry.Intersect* node into the list input of *List.Map*. -2. Plug a *Flatten* node into the f(x) input of *List.Map*. The results gives 3 list, each with a count equal to the number of trusses. -3. We need to change this data. If we want to instantiate the truss, we have to use the same number of adaptive points as defined in the family. This is a three point adaptive component, so instead of three lists with 10 items each (numberOfTrusses), we want 10 lists of three items each. This way we can create 10 adaptive components. -3. Plug the *List.Map* into a *List.Transpose* node. Now we have the desired data output. -4. To confirm that the data is correct, add a *Polygon.ByPoints* node to the canvas and double check with the Dynamo preview. - -![Exercise](images/8-4/Exercise/03.png) -> In the same way we created the polygons, we array the adaptive components. -1. Add an *AdaptiveComponent.ByPoints* node to the canvas, plug the *List.Transpose* node into the *points* input. -2. Using a *Family Types* node, select the *"AdaptiveTruss"* family, and plug this into the *familySymbol* input of the *AdaptiveComponent.ByPoints* node. - -![Exercise](images/8-4/Exercise/02.png) -> Checking in Revit, we now have the ten trusses evenly spaced across the facade! - -![Exercise](images/8-4/Exercise/01.png) -> 1. "Flexing" the graph, we turn up the *numberOfTrusses* to *40* by changing the *slider*. Lots of trusses, not very realistic, but the parametric link is working. - -![Exercise](images/8-4/Exercise/00.png) -> 1. Taming the truss system, let's compromise with a value of *15* for *numberOfTrusses*. - -![Exercise](images/8-4/Exercise/00a.png) -> And for the final test, by selecting the mass in Revit and editing instance parameters, we can change the form of the building and watch the truss follow suit. Remember, this Dynamo graph has to be open in order to see this update, and the link will be broken as soon as it's closed. - - -### DirectShape Elements -Another method for importing parametric Dynamo geometry into Revit is with DirectShape. In summary, the DirectShape element and related classes support the ability to store externally created geometric shapes in a Revit document. The geometry can include closed solids or meshes. DirectShape is primarily intended for importing shapes from other data formats such as IFC or STEP where not enough information is available to create a "real" Revit element. Like the IFC and STEP workflow, the DirectShape functionality works well with importing Dynamo created geometries into Revit projects as real elements. - -Let's walk through and exercise for importing Dynamo geometry as a DirectShape into our Revit project. Using this method, we can assign an imported geometry's category, material, and name - all while maintaining a parametric link to our Dynamo graph. - -### Exercise -> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [DirectShape.dyn](datasets/8-4/DirectShape.dyn) -2. [ARCH-DirectShape-BaseFile.rvt](datasets/8-4/ARCH-DirectShape-BaseFile.rvt) - -![Exercise](images/8-4/Exercise/DS-05.png) -> Begin by opening the sample file for this lesson - ARCH-DirectShape-BaseFile.rvt. -1. In the 3D view, we see our building mass from the previous lesson. -2. Along the edge of the atrium is one reference curve, we'll use this as a curve to reference in Dynamo. -3. Along the opposing edge of the atrium is another reference curve which we'll reference in Dynamo as well. - -![Exercise](images/8-4/Exercise/DS-04.png) ->1. To reference our geometry in Dynamo, we'll use *Select Model Element* for each member in Revit. Select the mass in Revit and import the geometry into Dynamo by Using *Element.Faces* - the mass should now be visible in your Dynamo preview. -2. Import one reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. -3. Import the other reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. - -![Exercise](images/8-4/Exercise/DS-03.png) ->1. Zooming out and panning to the right in the sample graph, we see a large group of nodes - these are geometric operations which generate the trellis roof structure visible in the Dynamo preview. These nodes are generating using the *Node to Code* functionality as discussed in the [code block section](../07_Code-Block/7-2_Design-Script-syntax.md#Node) of the primer. -2. The structure is driven by three major parameters - Diagonal Shift, Camber, and Radius. - -![Exercise](images/8-4/Exercise/DS-06.png) ->Zooming a close-up look of the parameters for this graph. We can flex these to get different geometry outputs. - -![Exercise](images/8-4/Exercise/DS-02.png) ->1. Dropping the *DirectShape.ByGeometry* node onto the canvas, we see that it has four inputs: **geometry, category, material**, and **name**. -2. Geometry will be the solid created from the geometry creation portion of the graph -3. The category input is chosen using the dropdwon *Categories* node. In this case we'll use "Structural Framing". -4. The material input is selected through the array of nodes above - although it can be more simply defined as "Default" in this case. - -![Exercise](images/8-4/Exercise/DS-01.png) ->After running Dynamo, back in Revit, we have the imported geometry on the roof in our project. This is a structural framing element, rather than a generic model. The parametric link to Dynamo remains intact. - -![Exercise](images/8-4/Exercise/DS-00.png) +## Creating +You can create an array of Revit elements in Dynamo with full parametric control. The Revit nodes in Dynamo offer the ability to import elements from generic geometries to specific category types (like walls and floors). In this section, we'll focus on importing parametrically flexible elements with adaptive components. + +![Creation](images/8-4/creation.png) +### Adaptive Components +An adaptive component is a flexible family category which lends itself well to generative applications. Upon instantiation, you can create a complex geometric element which is driven by the fundamental location of adaptive points. + +![AdaptiveComponent](images/8-4/ac.png) +> An example of a three-point adaptive component in the family editor. This generates a truss which is defined by the position of each adaptive point. In the exercise below, we'll use this component to generate a series of trusses across a facade. + +#### Principles of Interoperability +The adaptive component is a good example for best practices of interoperability. We can create an array of adaptive components by defining the fundamental adaptive points. And, when transferring this data to other programs, we have the ability to reduce the geometry to simple data. Importing and exporting with a program like Excel follows a similar logic. + +Suppose a facade consultant wants to know the location of the truss elements without needing to parse through fully articulated geometry. In preparation for fabrication, the consultant can reference the location of adaptive points to regenerate geometry in a program like Inventor. + +The workflow we'll setup in the exercise below allows us to access all of this data while creating the definition for Revit element creation. By this process, we can merge conceptualization, documentation, and fabrication into a seamless workflow. This creates a more intelligent and efficient process for interoperability. + +#### Multiple Elements and Lists + +![Exercise](images/8-4/Exercise/03.png) + +The exercise below will walk through how Dynamo references data for Revit element creation. To generate multiple adaptive components, we define a list of lists, where each list has three points representing each point of the adaptive component. We'll keep this in mind as we manage the data structures in Dynamo. + +### Exercise +> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Creating.dyn](datasets/8-4/Creating.dyn) +2. [ARCH-Creating-BaseFile.rvt](datasets/8-4/ARCH-Creating-BaseFile.rvt) + +![Exercise](images/8-4/Exercise/10.png) +> Beginning with the example file from this section (or continuing with the Revit file from the previous session), we see the same Revit mass. +1. This is the file as opened. +2. This is the truss system we'll created with Dynamo, linked intelligently to the Revit mass. + +![Exercise](images/8-4/Exercise/08.png) +> We've used the *"Select Model Element"* and *"Select Face"* nodes, now we're taking one step further down in the geometry hierarchy and using *"Select Edge"*. With the Dynamo solver set to run *"Automatic"*, the graph will continually update to changes in the Revit file. The edge we are selecting is tied dynamically to the Revit element topology. As long as the topology* does not change, the connection remains linked between Revit and Dynamo. +1. Select the top most curve of the glazing facade. This spans the full length of the building. If you're having trouble selecting the edge, remember to choose the selection in Revit by hovering over the edge and hitting *"Tab"* until the desired edge is highlighted. +2. Using two *"Select Edge"* nodes, select each edge representing the cant at the middle of the facade. +3. Do the same for the bottom edges of the facade in Revit. +4. The *Watch* nodes reveal that we now have lines in Dynamo. This is automatically converted to Dynamo geometry since the edges themselves are not Revit elements. These curves are the references we'll use to instantiate adaptive trusses across the facade. + +**Note - to keep a consistent topology, we're referring to a model that does not have additional faces or edges added. While parameters can change its shape, the way it which it is built remains consistent.* + +![Exercise](images/8-4/Exercise/07.png) +> We first need to join the curves and merge them into one list. This way we can *"group"* the curves to perform geometry operations. +1. Create a list for the two curves at the middle of the facade. +2. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. +3. Create a list for the two curves at the bottom of the facade. +4. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. +5. Finally, join the three main curves (one line and two polycurves) into one list. + +![Exercise](images/8-4/Exercise/06.png) +> We want to take advantage of the top curve, which is a line, and represents the full span of the facade. We'll create planes along this line to intersect with the set of curves we've grouped together in a list. +1. With a *code block*, define a range using the syntax: ```0..1..#numberOfTrusses; +``` +2. Plug an *integer slider *into the input for the code block. As you could have guessed, this will represent the number of trusses. Notice that the slider controls the number of items in the range defined from *0 *to *1*. +3. Plug the *code block* into the *param* input of a *"Curve.PlaneAtParameter"* node, and plug the top edge into the *curve* input. This will give us ten planes, evenly distributed across the span of the facade. + +![Exercise](images/8-4/Exercise/05.png) +> A plane is an abstract piece of geometry, representing a two dimensional space which is infinite. Planes are great for contouring and intersecting, as we are setting up in this step. +1. Using the *Geometry.Intersect* node, plug the *Curve.PlaneAtParameter* into the *entity* input of the *Geometry.Intersect* node. Plug the main *List.Create* node into the *geometry* input. We now see points in the Dynamo viewport representing the intersection of each curve with the defined planes. + +![Exercise](images/8-4/Exercise/04.png) +> Notice the output is a list of lists of lists. Too many lists for our purposes. We want to do a partial flatten here. We need to take one step down on the list and flatten the result. To do this, we use the *List.Map* operation, as discussed in the list chapter of the primer. +1. Plug the *Geometry.Intersect* node into the list input of *List.Map*. +2. Plug a *Flatten* node into the f(x) input of *List.Map*. The results gives 3 list, each with a count equal to the number of trusses. +3. We need to change this data. If we want to instantiate the truss, we have to use the same number of adaptive points as defined in the family. This is a three point adaptive component, so instead of three lists with 10 items each (numberOfTrusses), we want 10 lists of three items each. This way we can create 10 adaptive components. +3. Plug the *List.Map* into a *List.Transpose* node. Now we have the desired data output. +4. To confirm that the data is correct, add a *Polygon.ByPoints* node to the canvas and double check with the Dynamo preview. + +![Exercise](images/8-4/Exercise/03.png) +> In the same way we created the polygons, we array the adaptive components. +1. Add an *AdaptiveComponent.ByPoints* node to the canvas, plug the *List.Transpose* node into the *points* input. +2. Using a *Family Types* node, select the *"AdaptiveTruss"* family, and plug this into the *familySymbol* input of the *AdaptiveComponent.ByPoints* node. + +![Exercise](images/8-4/Exercise/02.png) +> Checking in Revit, we now have the ten trusses evenly spaced across the facade! + +![Exercise](images/8-4/Exercise/01.png) +> 1. "Flexing" the graph, we turn up the *numberOfTrusses* to *40* by changing the *slider*. Lots of trusses, not very realistic, but the parametric link is working. + +![Exercise](images/8-4/Exercise/00.png) +> 1. Taming the truss system, let's compromise with a value of *15* for *numberOfTrusses*. + +![Exercise](images/8-4/Exercise/00a.png) +> And for the final test, by selecting the mass in Revit and editing instance parameters, we can change the form of the building and watch the truss follow suit. Remember, this Dynamo graph has to be open in order to see this update, and the link will be broken as soon as it's closed. + + +### DirectShape Elements +Another method for importing parametric Dynamo geometry into Revit is with DirectShape. In summary, the DirectShape element and related classes support the ability to store externally created geometric shapes in a Revit document. The geometry can include closed solids or meshes. DirectShape is primarily intended for importing shapes from other data formats such as IFC or STEP where not enough information is available to create a "real" Revit element. Like the IFC and STEP workflow, the DirectShape functionality works well with importing Dynamo created geometries into Revit projects as real elements. + +Let's walk through and exercise for importing Dynamo geometry as a DirectShape into our Revit project. Using this method, we can assign an imported geometry's category, material, and name - all while maintaining a parametric link to our Dynamo graph. + +### Exercise +> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [DirectShape.dyn](datasets/8-4/DirectShape.dyn) +2. [ARCH-DirectShape-BaseFile.rvt](datasets/8-4/ARCH-DirectShape-BaseFile.rvt) + +![Exercise](images/8-4/Exercise/DS-05.png) +> Begin by opening the sample file for this lesson - ARCH-DirectShape-BaseFile.rvt. +1. In the 3D view, we see our building mass from the previous lesson. +2. Along the edge of the atrium is one reference curve, we'll use this as a curve to reference in Dynamo. +3. Along the opposing edge of the atrium is another reference curve which we'll reference in Dynamo as well. + +![Exercise](images/8-4/Exercise/DS-04.png) +>1. To reference our geometry in Dynamo, we'll use *Select Model Element* for each member in Revit. Select the mass in Revit and import the geometry into Dynamo by Using *Element.Faces* - the mass should now be visible in your Dynamo preview. +2. Import one reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. +3. Import the other reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. + +![Exercise](images/8-4/Exercise/DS-03.png) +>1. Zooming out and panning to the right in the sample graph, we see a large group of nodes - these are geometric operations which generate the trellis roof structure visible in the Dynamo preview. These nodes are generating using the *Node to Code* functionality as discussed in the [code block section](../07_Code-Block/7-2_Design-Script-syntax.md#Node) of the primer. +2. The structure is driven by three major parameters - Diagonal Shift, Camber, and Radius. + +![Exercise](images/8-4/Exercise/DS-06.png) +>Zooming a close-up look of the parameters for this graph. We can flex these to get different geometry outputs. + +![Exercise](images/8-4/Exercise/DS-02.png) +>1. Dropping the *DirectShape.ByGeometry* node onto the canvas, we see that it has four inputs: **geometry, category, material**, and **name**. +2. Geometry will be the solid created from the geometry creation portion of the graph +3. The category input is chosen using the dropdwon *Categories* node. In this case we'll use "Structural Framing". +4. The material input is selected through the array of nodes above - although it can be more simply defined as "Default" in this case. + +![Exercise](images/8-4/Exercise/DS-01.png) +>After running Dynamo, back in Revit, we have the imported geometry on the roof in our project. This is a structural framing element, rather than a generic model. The parametric link to Dynamo remains intact. + +![Exercise](images/8-4/Exercise/DS-00.png) >1. If we "flex" the Dynamo graph by changing the "Diagonal Shift" parameter to "-2", we just run Dynamo again and get a new imported DirectShape! \ No newline at end of file diff --git a/08_Dynamo-for-Revit/8-5_Customizing.md b/08_Dynamo-for-Revit/8-5_Customizing.md index cf33d1c9..515e65b6 100644 --- a/08_Dynamo-for-Revit/8-5_Customizing.md +++ b/08_Dynamo-for-Revit/8-5_Customizing.md @@ -1,122 +1,122 @@ -## Customizing -While we previously looked at editing a basic building mass, we want to dive deeper into the Dynamo/Revit link by editing a large number of elements in one go. Customizing on a large scale becomes more complex as data structures require more advanced list operations. However, the underlying principles behind their execution is fundamentally the same. Let's study some opportunities for analysis from a set of adaptive components. - -#### Point Location -Suppose we've created a range of adaptive components and want to edit parameters based on their point locations. The points, for example, could drive a thickness parameter which is related to the area of the element. Or, they could drive an opacity parameter related to solar exposure throughout the year. Dynamo allows the connection of analysis to parameters in a few easy steps, and we'll explore a basic version in the exercise below. - -![Points](images/8-5/points.png) -> Query the adaptive points of a selected adaptive component by using the *AdaptiveComponent.Locations* node. This allows us to work with an abstracted version of a Revit element for analysis. - -By extracting the point location of adaptive components, we can run a range of analysis for that element. A four-point adaptive component will allow you to study the deviation from plane for a given panel for example. - -#### Solar Orientation Analysis -![Points](images/8-5/points.png) -> Use remapping to map a set of a data into a parameter range. This is fundamental tool used in a parametric model, and we'll demonstrate it in the exercise below. - -Using Dynamo, the point locations of adaptive components can be used to create a best-fit plane each element. We can also query the sun position in the Revit file and study the plane's relative orientation to the sun in comparison to other adaptive components. Let's set that up in the exercise below by creating an algorithmic roofscape. - -### Exercise ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Customizing.dyn](datasets/8-5/Customizing.dyn) -2. [ARCH-Customizing-BaseFile.rvt](datasets/8-5/ARCH-Customizing-BaseFile.rvt) - - -This exercise will expand on the techniques demonstrated in the previous section. In this case, we are defining a parametric surface from Revit elements, instantiating four-point adaptive components and then editing them based on orientation to the sun. - -![Exercise](images/8-5/Exercise/00.png) -> 1. Beginning by selecting two edges with the *"Select Edge"* node. The two edges are the long spans of the atrium. -2. Combine the two edges into one list with the *List.Create* node. -3. Create a surface between the two edges with a *Surface.ByLoft*. - -![Exercise](images/8-5/Exercise/01.png) -> 1. Using *code block*, define a range from 0 to 1 with 10 evenly spaced values: ```0..1..#10; -``` -2. Plug the *code block* into the *u *and *v* inputs of a *Surface.PointAtParameter* node, and plug the *Surface.ByLoft* node into the *surface* input. Right click the node and change the *lacing* to *Cross Product*. This will give a gird of points on the surface. - -This grid of points serves as the control points for a parametrically defined surface. We want to extract the u and v positions of each one of these points so that we can plug them into a parametric formula and keep the same data structure. We can do this by querying the parameter locations of the points we just created. - -![Exercise](images/8-5/Exercise/02.png) -> 1. Add a *Surface.ParameterAtPoint* node to the canvas, connect the inputs as shown above. -2. Query the *u* values of these parameters with the *UV.U* node. -3. Query the *v* values of these parameters with the *UV.V *node. -4. The outputs show the corresponding *u* and *v* values for every point of the surface. We now have a range from *0* to *1* for each value, in the proper data structure, so we're ready to apply a parametric algorithm. - -![Exercise](images/8-5/Exercise/03.png) -> 1. Add a *code block* to the canvas and enter the code: ``` -Math.Sin(u*180)*Math.Sin(v*180)*w;``` This is a parametric function which creates a sine mound from a flat surface. -2. The *u* input connects to *UV.U*. -3. The *v* input connects to *UV.V*. -4. The *w* input represents the *amplitude* of the shape, so we attach a *number slider* to it. - - -![Exercise](images/8-5/Exercise/04.png) -> 1. Now, we have a list of values as defined by the algorithm. Let's use this list of values to move the points up in the *+Z* direction. Using *Geometry.Translate*, plug the *code block *into *zTranslation* and the *Surface.PointAtParameter* into the *geometry* input. You should see the new points displayed in the Dynamo preview. -2. Finally, we create a surface with the *NurbsSurface.ByPoints* node, plugging the node from the previous step into the points input. We have ourselves a parametric surface. Feel free to drag the slider to watch the mound shrink and grow. - -With the parametric surface, we want to define a way to panelize it in order to array four-point adaptive components. Dynamo does not have out-of-the-box functionality for surface panelization, so we can look to the community for helpful Dynamo packages. - -![Exercise](images/8-5/Exercise/05a.png) -> 1. Go to *Packages>Search for a Package...* -2. Search for *"LunchBox"* and download *"LunchBox for Dynamo"*. This is a really helpful set of tools for geometry operations such as this. - -![Exercise](images/8-5/Exercise/07.png) -> 1. After downloading, you now have full access to the LunchBox suite. Search for *"Quad Grid"* and select *"LunchBox Quad Grid By Face"*. Plug the parametric surface into the *surface* input and set the *U* and *V* divisions to *15*. You should see a quad-paneled surface in your Dynamo preview. - -![Exercise](images/8-5/Exercise/customNode.png) -> If you're curious about its setup, you can double click on the *Lunch Box* node and see how it's made. - -![Exercise](images/8-5/Exercise/08.png) -> Back in Revit, let's take a quick look at the adaptive component we're using here. No need to follow along, but this is the roof panel we're going to instantiate. It is a four-point adaptive component which is a crude representation of an ETFE system. The aperture of the center void is on a parameter called *"ApertureRatio"*. - -![Exercise](images/8-5/Exercise/09.png) -> 1. We're about to instantiate a lot of geometry in Revit, so make sure to turn the Dynamo solver to *"Manual"*. -2. Add a *Family Types* node to the canvas and select *"ROOF-PANEL-4PT"*. -3. Add an *AdaptiveComponent.ByPoints* node to the canvas, connect *Panel Pts* from the *"LunchBox Quad Grid by Face"* output into the *points* input. Connect the *Family Types* node to the *familySymbol* input. -4. Hit *Run*. Revit will have to *think* for a bit while the geometry is being created. If it takes too long, reduce the *code block's '15'* to a lower number. This will reduce the number of panels on the roof. - -*Note: If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing).* - -![Exercise](images/8-5/Exercise/31.png) -> Back in Revit, we have the array of panels on the roof. - -![Exercise](images/8-5/Exercise/30.png) -> Zooming in, we can get a closer look at their surface qualities. - -###Analysis - -![Exercise](images/8-5/Exercise/16.png) -> 1. Continuing from the previous step, let's go further and drive the aperture of each panel based on its exposure to the sun. Zooming into Revit and select one panel, we see in the properties bar that there is a parameter called *"Aperture Ratio"*. The family is setup so that the aperture ranges, roughly, from *0.05* to *0.45*. - -![Exercise](images/8-5/Exercise/17.png) -> 1. If we turn on the solar path, we can see the current sun location in Revit. - -![Exercise](images/8-5/Exercise/13.png) -> 1. We can reference this sun location using the *SunSettings.Current* node. -2. Plug the Sun settings into *Sunsetting.SunDirection* to get the solar vector. -3. From the *Panel Pts* used to create the adaptive components, use *Plane.ByBestFitThroughPoints* to approximate a plane for the component. -4. Query the *normal* of this plane. -5. Use the *dot product* to calculate solar orientation. The dot product is a formula which determines how parallel or anti-parallel two vectors may be. So we're taking the plane normal of each adaptive component and comparing it to the solar vector to roughly simulate solar orientation. -6. Take the *absolute value* of the result. This ensures that the dot product is accurate if the plane normal is facing the reverse direction. -7. Hit *Run*. - -![Exercise](images/8-5/Exercise/14.png) -> 1. Looking at the *dot product*, we have a wide range of numbers. We want to use their relative distribution, but we need to condense the numbers into the appropriate range of the *"Aperture Ratio"* parameter we plan to edit. -2. The *Math.RemapRange* is a great tool for this. It takes an input list and remaps its bounds into two target values. -3. Define the target values as *0.15* and *0.45* in a *code block*. -4. Hit *Run*. - - -![Exercise](images/8-5/Exercise/33.png) -> 1. Connect the remapped values into a *Element.SetParameterByName* node. -2. Connect the string *"Aperture Ratio"* into the *parameterName* input. -3. Connect the *adaptive components* into the *element* input. -4. Hit *Run*. - - -![Exercise](images/8-5/Exercise/21.png) -> Back in Revit, from a distance we can make out the affect of the solar orientation on the aperture of the ETFE panels. - -![Exercise](images/8-5/Exercise/32.png) -> Zooming in, we see that the ETFE panels are more closed as the face the sun. Our target here is to reduce overheating from solar exposure. If we wanted to let in more light based on solar exposure, we just have to switch the domain on *Math.RemapRange*. - - +## Customizing +While we previously looked at editing a basic building mass, we want to dive deeper into the Dynamo/Revit link by editing a large number of elements in one go. Customizing on a large scale becomes more complex as data structures require more advanced list operations. However, the underlying principles behind their execution is fundamentally the same. Let's study some opportunities for analysis from a set of adaptive components. + +#### Point Location +Suppose we've created a range of adaptive components and want to edit parameters based on their point locations. The points, for example, could drive a thickness parameter which is related to the area of the element. Or, they could drive an opacity parameter related to solar exposure throughout the year. Dynamo allows the connection of analysis to parameters in a few easy steps, and we'll explore a basic version in the exercise below. + +![Points](images/8-5/points.png) +> Query the adaptive points of a selected adaptive component by using the *AdaptiveComponent.Locations* node. This allows us to work with an abstracted version of a Revit element for analysis. + +By extracting the point location of adaptive components, we can run a range of analysis for that element. A four-point adaptive component will allow you to study the deviation from plane for a given panel for example. + +#### Solar Orientation Analysis +![Points](images/8-5/points.png) +> Use remapping to map a set of a data into a parameter range. This is fundamental tool used in a parametric model, and we'll demonstrate it in the exercise below. + +Using Dynamo, the point locations of adaptive components can be used to create a best-fit plane each element. We can also query the sun position in the Revit file and study the plane's relative orientation to the sun in comparison to other adaptive components. Let's set that up in the exercise below by creating an algorithmic roofscape. + +### Exercise +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Customizing.dyn](datasets/8-5/Customizing.dyn) +2. [ARCH-Customizing-BaseFile.rvt](datasets/8-5/ARCH-Customizing-BaseFile.rvt) + + +This exercise will expand on the techniques demonstrated in the previous section. In this case, we are defining a parametric surface from Revit elements, instantiating four-point adaptive components and then editing them based on orientation to the sun. + +![Exercise](images/8-5/Exercise/00.png) +> 1. Beginning by selecting two edges with the *"Select Edge"* node. The two edges are the long spans of the atrium. +2. Combine the two edges into one list with the *List.Create* node. +3. Create a surface between the two edges with a *Surface.ByLoft*. + +![Exercise](images/8-5/Exercise/01.png) +> 1. Using *code block*, define a range from 0 to 1 with 10 evenly spaced values: ```0..1..#10; +``` +2. Plug the *code block* into the *u *and *v* inputs of a *Surface.PointAtParameter* node, and plug the *Surface.ByLoft* node into the *surface* input. Right click the node and change the *lacing* to *Cross Product*. This will give a gird of points on the surface. + +This grid of points serves as the control points for a parametrically defined surface. We want to extract the u and v positions of each one of these points so that we can plug them into a parametric formula and keep the same data structure. We can do this by querying the parameter locations of the points we just created. + +![Exercise](images/8-5/Exercise/02.png) +> 1. Add a *Surface.ParameterAtPoint* node to the canvas, connect the inputs as shown above. +2. Query the *u* values of these parameters with the *UV.U* node. +3. Query the *v* values of these parameters with the *UV.V *node. +4. The outputs show the corresponding *u* and *v* values for every point of the surface. We now have a range from *0* to *1* for each value, in the proper data structure, so we're ready to apply a parametric algorithm. + +![Exercise](images/8-5/Exercise/03.png) +> 1. Add a *code block* to the canvas and enter the code: ``` +Math.Sin(u*180)*Math.Sin(v*180)*w;``` This is a parametric function which creates a sine mound from a flat surface. +2. The *u* input connects to *UV.U*. +3. The *v* input connects to *UV.V*. +4. The *w* input represents the *amplitude* of the shape, so we attach a *number slider* to it. + + +![Exercise](images/8-5/Exercise/04.png) +> 1. Now, we have a list of values as defined by the algorithm. Let's use this list of values to move the points up in the *+Z* direction. Using *Geometry.Translate*, plug the *code block *into *zTranslation* and the *Surface.PointAtParameter* into the *geometry* input. You should see the new points displayed in the Dynamo preview. +2. Finally, we create a surface with the *NurbsSurface.ByPoints* node, plugging the node from the previous step into the points input. We have ourselves a parametric surface. Feel free to drag the slider to watch the mound shrink and grow. + +With the parametric surface, we want to define a way to panelize it in order to array four-point adaptive components. Dynamo does not have out-of-the-box functionality for surface panelization, so we can look to the community for helpful Dynamo packages. + +![Exercise](images/8-5/Exercise/05a.png) +> 1. Go to *Packages>Search for a Package...* +2. Search for *"LunchBox"* and download *"LunchBox for Dynamo"*. This is a really helpful set of tools for geometry operations such as this. + +![Exercise](images/8-5/Exercise/07.png) +> 1. After downloading, you now have full access to the LunchBox suite. Search for *"Quad Grid"* and select *"LunchBox Quad Grid By Face"*. Plug the parametric surface into the *surface* input and set the *U* and *V* divisions to *15*. You should see a quad-paneled surface in your Dynamo preview. + +![Exercise](images/8-5/Exercise/customNode.png) +> If you're curious about its setup, you can double click on the *Lunch Box* node and see how it's made. + +![Exercise](images/8-5/Exercise/08.png) +> Back in Revit, let's take a quick look at the adaptive component we're using here. No need to follow along, but this is the roof panel we're going to instantiate. It is a four-point adaptive component which is a crude representation of an ETFE system. The aperture of the center void is on a parameter called *"ApertureRatio"*. + +![Exercise](images/8-5/Exercise/09.png) +> 1. We're about to instantiate a lot of geometry in Revit, so make sure to turn the Dynamo solver to *"Manual"*. +2. Add a *Family Types* node to the canvas and select *"ROOF-PANEL-4PT"*. +3. Add an *AdaptiveComponent.ByPoints* node to the canvas, connect *Panel Pts* from the *"LunchBox Quad Grid by Face"* output into the *points* input. Connect the *Family Types* node to the *familySymbol* input. +4. Hit *Run*. Revit will have to *think* for a bit while the geometry is being created. If it takes too long, reduce the *code block's '15'* to a lower number. This will reduce the number of panels on the roof. + +*Note: If Dynamo is taking a long time to calculate nodes, you may want to use the "freeze" node functionality in order to pause the execution of Revit operations while you develop your graph. For more information on freezing nodes, check out the "Freezing" section in the [solids chapter](../05_Geometry-for-Computational-Design/5-6_solids.md#freezing).* + +![Exercise](images/8-5/Exercise/31.png) +> Back in Revit, we have the array of panels on the roof. + +![Exercise](images/8-5/Exercise/30.png) +> Zooming in, we can get a closer look at their surface qualities. + +###Analysis + +![Exercise](images/8-5/Exercise/16.png) +> 1. Continuing from the previous step, let's go further and drive the aperture of each panel based on its exposure to the sun. Zooming into Revit and select one panel, we see in the properties bar that there is a parameter called *"Aperture Ratio"*. The family is setup so that the aperture ranges, roughly, from *0.05* to *0.45*. + +![Exercise](images/8-5/Exercise/17.png) +> 1. If we turn on the solar path, we can see the current sun location in Revit. + +![Exercise](images/8-5/Exercise/13.png) +> 1. We can reference this sun location using the *SunSettings.Current* node. +2. Plug the Sun settings into *Sunsetting.SunDirection* to get the solar vector. +3. From the *Panel Pts* used to create the adaptive components, use *Plane.ByBestFitThroughPoints* to approximate a plane for the component. +4. Query the *normal* of this plane. +5. Use the *dot product* to calculate solar orientation. The dot product is a formula which determines how parallel or anti-parallel two vectors may be. So we're taking the plane normal of each adaptive component and comparing it to the solar vector to roughly simulate solar orientation. +6. Take the *absolute value* of the result. This ensures that the dot product is accurate if the plane normal is facing the reverse direction. +7. Hit *Run*. + +![Exercise](images/8-5/Exercise/14.png) +> 1. Looking at the *dot product*, we have a wide range of numbers. We want to use their relative distribution, but we need to condense the numbers into the appropriate range of the *"Aperture Ratio"* parameter we plan to edit. +2. The *Math.RemapRange* is a great tool for this. It takes an input list and remaps its bounds into two target values. +3. Define the target values as *0.15* and *0.45* in a *code block*. +4. Hit *Run*. + + +![Exercise](images/8-5/Exercise/33.png) +> 1. Connect the remapped values into a *Element.SetParameterByName* node. +2. Connect the string *"Aperture Ratio"* into the *parameterName* input. +3. Connect the *adaptive components* into the *element* input. +4. Hit *Run*. + + +![Exercise](images/8-5/Exercise/21.png) +> Back in Revit, from a distance we can make out the affect of the solar orientation on the aperture of the ETFE panels. + +![Exercise](images/8-5/Exercise/32.png) +> Zooming in, we see that the ETFE panels are more closed as the face the sun. Our target here is to reduce overheating from solar exposure. If we wanted to let in more light based on solar exposure, we just have to switch the domain on *Math.RemapRange*. + + diff --git a/08_Dynamo-for-Revit/8-6_Documenting.md b/08_Dynamo-for-Revit/8-6_Documenting.md index 041b191b..4029329f 100644 --- a/08_Dynamo-for-Revit/8-6_Documenting.md +++ b/08_Dynamo-for-Revit/8-6_Documenting.md @@ -1,104 +1,104 @@ -## Documenting -Editing parameters for documentation follows suit with the lessons learned in prior sections. In this section, we'll look at editing parameters which don't affect the geometric properties of an element, but instead prepare a Revit file for documentation. - -#### Deviation -In the exercise below, we'll use a basic deviation from plane node to create a Revit sheet for documentation. Each panel on our parametrically defined roof structure has a different value for deviation, and we want to call out the range of values using color and by scheduling out the adaptive points to hand off to a facade consultant, engineer, or contractor. - -![deviation](images/8-6/deviation.png) -> The deviation from plane node will calculate the distance that the set of four points varies from the best-fit plane between them. This is a quick and easy way to study constructability. - -### Exercise ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Documenting.dyn](datasets/8-6/Documenting.dyn) -2. [ARCH-Documenting-BaseFile.rvt](datasets/8-6/ARCH-Documenting-BaseFile.rvt) - -Start with the Revit file for this section (or continue from the previous section). This file has an array of ETFE panels on the roof. We'll reference these panels for this exercise. - -![Exercise](images/8-6/Exercise/17.png) -> 1. Add a *Family Types* node to the canvas and choose *"ROOF-PANEL-4PT"*. -2. Plug this node into a Select *All Elements of Family Type* node to get all of the elements from Revit into Dynamo. - -![Exercise](images/8-6/Exercise/16.png) -> 1. Query the location of adaptive points for each element with the *AdaptiveComponent.Locations* node. -2. Create a polygon from these four points with the *Polygon.ByPoints* node. Notice we now have an abstract version of the paneled system in Dynamo without having to import the full geometry of the Revit element. -3. Calculate planar deviation with the *Polygon.PlaneDeviation* node. - -![Exercise](images/8-6/Exercise/15.png) -> Just for kicks, like the previous exercise, let's set the *aperture ratio *of each panel based on its planar deviation. -1. Add an *Element.SetParameterByName* node to the canvas and connect the adaptive components to the *element* input. Connect a *code block* reading *"Aperture Ratio"* into the *parameterName* input. -2. We cannot directly connect the deviation results into the value input because we need to remap the values to the parameter range. - -![Exercise](images/8-6/Exercise/14.png) -> 1. Using *Math.RemapRange*, remap the deviation values to a domain between *.15 *and *.45*. -2. Plug these results into the value input for *Element.SetParameterByName*. - -![Exercise](images/8-6/Exercise/13.png) -> Back in Revit we can *kind of* make sense of the change in aperture across the surface. - -![Exercise](images/8-6/Exercise/13a.png) -> Zooming in, it becomes more clear that the closed panels are weighted towards the corners of the surface. The open corners are towards the top. The corners represent areas of larger deviation while bulge has minimal curvature, so this makes sense. - -###Color and Documentation -Setting the Aperture Ratio doesn't clearly demonstrate the deviation of panels on the roof, and we're also changing the geometry of the actual element. Suppose we just want to study the deviation from the standpoint of fabrication feasibility. It would be helpful to color the panels based on deviation range for our documentation. We can do that with the series of steps below, and in a very similar process to the steps above. - -![Exercise](images/8-6/Exercise/11.png) -> 1. Remove the *Element.SetParameterByName* nodes and add *Element.OverrideColorInView*. -2. Add a *Color Range* node to the canvas and plug into the color input of *Element.OverrideColorInView*. We still have to connect the deviation values to the color range in order to create the gradient. -3. Hovering over the *value* input, we can see that the values for the input must be between *0* and *1* in order to map a color to each value. We need to remap the deviation values to this range. - -![Exercise](images/8-6/Exercise/10.png) -> 1. Using *Math.RemapRange*, remap the planar deviation values to a range between* 0* and *1* (note: you can use the *"MapTo"* node to define a source domains as well). -2. Plug the results into a *Color Range* node. -3. Notice our output is a range of colors instead of a range of numbers. -4. If you're set to Manual, hit *Run*. You should be able to get away with being set to Automatic from this point forward. - -![Exercise](images/8-6/Exercise/09.png) -> Back in Revit, we see a much more legible gradient which is representative of planar deviation based on our color range. But what if we want to customized the colors? Notice that the minimum deviation values are represented in red, which seems to be the opposite of what we'd expect. We want to have maximum deviation to be red, with minimum deviation represented by a calmer color. Let's go back to Dynamo and fix this. - -![Exercise](images/8-6/Exercise/08.png) -> 1. Using a *code block*, add two numbers on two different lines: -```0;``` and ```255;```. -2. Create a red and blue color by plugging the appropriate values into two *Color.ByARGB* nodes. -3. Create a list from these two colors. -4. Plug this list into the *colors* input of the *Color Range*, and watch the custom color range update. - - -![Exercise](images/8-6/Exercise/07.png) -> Back in Revit, we can now make better sense of areas of maximum deviation in the corners. Remember, this node is for overriding a color in a view, so it can be really helpful if we had a particular sheet in the set of drawings which focuses on a particular type of analysis. - -###Scheduling - -![Exercise](images/8-6/Exercise/06.png) -> 1. Selecting one ETFE panel in Revit, we see that there are four instance parameters, *XYZ1, XYZ2, XYZ3,* and *XYZ4*. These are all blank after they're correctly. These are text-based parameters and need values. We'll use Dynamo to write the adaptive point locations to each parameter. This helps interoperability if the geometry needs to be sent to an engineer of facade consultant. - -![Exercise](images/8-6/Exercise/03.png) -> In a sample sheet, we have a large, empty schedule. The XYZ parameters are shared parameters in the Revit file, which allows us to add them to the schedule. - -![Exercise](images/8-6/Exercise/02.png) -> Zooming in, the XYZ parameters are yet to be filled in. The first two parameters are taken care of by Revit. - -![Exercise](images/8-6/Exercise/05.png) -> To write in these values, we'll do a complex list operation. The graph itself is simple, but the concepts build heavily from the list mapping as discussed in the list chapter. -1. Select all the adaptive components with two nodes. -2. Extract the locations of each points with *AdaptiveComponent.Locations*. -3. Convert these points to strings. Remember, the parameter is text-based so we need to input the correct data type. -4. Create a list of the four strings which define the parameters to change: *XYZ1, XYZ2, XYZ3,* and *XYZ4*. -5. Plug this list into the *parameterName* input of *Element.SetParameterByName*. -6. Connect *Element.SetParameterByName* into the the *combinator* input of *List.Combine.* -7. Connect the *adaptive components* into *list1*. -8. Connect *String* from Object into *list2*. -9. We are list mapping here, because we are writing four values for each element, which creates a complex data structure. The *List.Combine* node defines an operation one step down in the data hierarchy. This is why element and value inputs are left blank. *List.Combine* is connecting the sublists of its inputs into the empty inputs of *List.SetParameterByName*, based on the order in which they are connected. - -![Exercise](images/8-6/Exercise/04.png) -> Selecting a panel in Revit, we see now that we have string values for each parameter. Realistically, we would create a simpler format to write a point (X,Y,Z). This can be done with string operations in Dynamo, but we're bypassing that here to stay within the scope of this chapter. - -![Exercise](images/8-6/Exercise/01.png) -> A view of the sample schedule with parameters filled in. - -![Exercise](images/8-6/Exercise/00.png) -> Each ETFE panel now has the XYZ coordinates written for each adaptive point, representing the corners of each panel for fabrication. - - - - - +## Documenting +Editing parameters for documentation follows suit with the lessons learned in prior sections. In this section, we'll look at editing parameters which don't affect the geometric properties of an element, but instead prepare a Revit file for documentation. + +#### Deviation +In the exercise below, we'll use a basic deviation from plane node to create a Revit sheet for documentation. Each panel on our parametrically defined roof structure has a different value for deviation, and we want to call out the range of values using color and by scheduling out the adaptive points to hand off to a facade consultant, engineer, or contractor. + +![deviation](images/8-6/deviation.png) +> The deviation from plane node will calculate the distance that the set of four points varies from the best-fit plane between them. This is a quick and easy way to study constructability. + +### Exercise +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Documenting.dyn](datasets/8-6/Documenting.dyn) +2. [ARCH-Documenting-BaseFile.rvt](datasets/8-6/ARCH-Documenting-BaseFile.rvt) + +Start with the Revit file for this section (or continue from the previous section). This file has an array of ETFE panels on the roof. We'll reference these panels for this exercise. + +![Exercise](images/8-6/Exercise/17.png) +> 1. Add a *Family Types* node to the canvas and choose *"ROOF-PANEL-4PT"*. +2. Plug this node into a Select *All Elements of Family Type* node to get all of the elements from Revit into Dynamo. + +![Exercise](images/8-6/Exercise/16.png) +> 1. Query the location of adaptive points for each element with the *AdaptiveComponent.Locations* node. +2. Create a polygon from these four points with the *Polygon.ByPoints* node. Notice we now have an abstract version of the paneled system in Dynamo without having to import the full geometry of the Revit element. +3. Calculate planar deviation with the *Polygon.PlaneDeviation* node. + +![Exercise](images/8-6/Exercise/15.png) +> Just for kicks, like the previous exercise, let's set the *aperture ratio *of each panel based on its planar deviation. +1. Add an *Element.SetParameterByName* node to the canvas and connect the adaptive components to the *element* input. Connect a *code block* reading *"Aperture Ratio"* into the *parameterName* input. +2. We cannot directly connect the deviation results into the value input because we need to remap the values to the parameter range. + +![Exercise](images/8-6/Exercise/14.png) +> 1. Using *Math.RemapRange*, remap the deviation values to a domain between *.15 *and *.45*. +2. Plug these results into the value input for *Element.SetParameterByName*. + +![Exercise](images/8-6/Exercise/13.png) +> Back in Revit we can *kind of* make sense of the change in aperture across the surface. + +![Exercise](images/8-6/Exercise/13a.png) +> Zooming in, it becomes more clear that the closed panels are weighted towards the corners of the surface. The open corners are towards the top. The corners represent areas of larger deviation while bulge has minimal curvature, so this makes sense. + +###Color and Documentation +Setting the Aperture Ratio doesn't clearly demonstrate the deviation of panels on the roof, and we're also changing the geometry of the actual element. Suppose we just want to study the deviation from the standpoint of fabrication feasibility. It would be helpful to color the panels based on deviation range for our documentation. We can do that with the series of steps below, and in a very similar process to the steps above. + +![Exercise](images/8-6/Exercise/11.png) +> 1. Remove the *Element.SetParameterByName* nodes and add *Element.OverrideColorInView*. +2. Add a *Color Range* node to the canvas and plug into the color input of *Element.OverrideColorInView*. We still have to connect the deviation values to the color range in order to create the gradient. +3. Hovering over the *value* input, we can see that the values for the input must be between *0* and *1* in order to map a color to each value. We need to remap the deviation values to this range. + +![Exercise](images/8-6/Exercise/10.png) +> 1. Using *Math.RemapRange*, remap the planar deviation values to a range between* 0* and *1* (note: you can use the *"MapTo"* node to define a source domains as well). +2. Plug the results into a *Color Range* node. +3. Notice our output is a range of colors instead of a range of numbers. +4. If you're set to Manual, hit *Run*. You should be able to get away with being set to Automatic from this point forward. + +![Exercise](images/8-6/Exercise/09.png) +> Back in Revit, we see a much more legible gradient which is representative of planar deviation based on our color range. But what if we want to customized the colors? Notice that the minimum deviation values are represented in red, which seems to be the opposite of what we'd expect. We want to have maximum deviation to be red, with minimum deviation represented by a calmer color. Let's go back to Dynamo and fix this. + +![Exercise](images/8-6/Exercise/08.png) +> 1. Using a *code block*, add two numbers on two different lines: +```0;``` and ```255;```. +2. Create a red and blue color by plugging the appropriate values into two *Color.ByARGB* nodes. +3. Create a list from these two colors. +4. Plug this list into the *colors* input of the *Color Range*, and watch the custom color range update. + + +![Exercise](images/8-6/Exercise/07.png) +> Back in Revit, we can now make better sense of areas of maximum deviation in the corners. Remember, this node is for overriding a color in a view, so it can be really helpful if we had a particular sheet in the set of drawings which focuses on a particular type of analysis. + +###Scheduling + +![Exercise](images/8-6/Exercise/06.png) +> 1. Selecting one ETFE panel in Revit, we see that there are four instance parameters, *XYZ1, XYZ2, XYZ3,* and *XYZ4*. These are all blank after they're correctly. These are text-based parameters and need values. We'll use Dynamo to write the adaptive point locations to each parameter. This helps interoperability if the geometry needs to be sent to an engineer of facade consultant. + +![Exercise](images/8-6/Exercise/03.png) +> In a sample sheet, we have a large, empty schedule. The XYZ parameters are shared parameters in the Revit file, which allows us to add them to the schedule. + +![Exercise](images/8-6/Exercise/02.png) +> Zooming in, the XYZ parameters are yet to be filled in. The first two parameters are taken care of by Revit. + +![Exercise](images/8-6/Exercise/05.png) +> To write in these values, we'll do a complex list operation. The graph itself is simple, but the concepts build heavily from the list mapping as discussed in the list chapter. +1. Select all the adaptive components with two nodes. +2. Extract the locations of each points with *AdaptiveComponent.Locations*. +3. Convert these points to strings. Remember, the parameter is text-based so we need to input the correct data type. +4. Create a list of the four strings which define the parameters to change: *XYZ1, XYZ2, XYZ3,* and *XYZ4*. +5. Plug this list into the *parameterName* input of *Element.SetParameterByName*. +6. Connect *Element.SetParameterByName* into the the *combinator* input of *List.Combine.* +7. Connect the *adaptive components* into *list1*. +8. Connect *String* from Object into *list2*. +9. We are list mapping here, because we are writing four values for each element, which creates a complex data structure. The *List.Combine* node defines an operation one step down in the data hierarchy. This is why element and value inputs are left blank. *List.Combine* is connecting the sublists of its inputs into the empty inputs of *List.SetParameterByName*, based on the order in which they are connected. + +![Exercise](images/8-6/Exercise/04.png) +> Selecting a panel in Revit, we see now that we have string values for each parameter. Realistically, we would create a simpler format to write a point (X,Y,Z). This can be done with string operations in Dynamo, but we're bypassing that here to stay within the scope of this chapter. + +![Exercise](images/8-6/Exercise/01.png) +> A view of the sample schedule with parameters filled in. + +![Exercise](images/8-6/Exercise/00.png) +> Each ETFE panel now has the XYZ coordinates written for each adaptive point, representing the corners of each panel for fabrication. + + + + + diff --git a/08_Dynamo-for-Revit/8_Dynamo-for-Revit.md b/08_Dynamo-for-Revit/8_Dynamo-for-Revit.md index 0058a77a..f7390b76 100644 --- a/08_Dynamo-for-Revit/8_Dynamo-for-Revit.md +++ b/08_Dynamo-for-Revit/8_Dynamo-for-Revit.md @@ -1,5 +1,5 @@ -# Dynamo for Revit - -While Dynamo is a flexible environment, designed to port into a wide range of programs, it was originally created for use with Revit. A visual program creates robust options for a Building Information Model (BIM). Dynamo offers a whole suite of nodes specifically designed for Revit, as well as third-party libraries from a thriving AEC community. This chapter focuses on the basics of using Dynamo in Revit. - -![IMAGE](images/8/Dynamo for Revit-01.png) +# Dynamo for Revit + +While Dynamo is a flexible environment, designed to port into a wide range of programs, it was originally created for use with Revit. A visual program creates robust options for a Building Information Model (BIM). Dynamo offers a whole suite of nodes specifically designed for Revit, as well as third-party libraries from a thriving AEC community. This chapter focuses on the basics of using Dynamo in Revit. + +![IMAGE](images/8/Dynamo for Revit-01.png) diff --git a/08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn b/08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn index 6ac7ae5e..9473ffe2 100644 --- a/08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn +++ b/08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn @@ -1,118 +1,118 @@ - - - - - - - - - - - - - - - - 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-3/Editing.dyn b/08_Dynamo-for-Revit/datasets/8-3/Editing.dyn index 6fcf60c0..305683b8 100644 --- a/08_Dynamo-for-Revit/datasets/8-3/Editing.dyn +++ b/08_Dynamo-for-Revit/datasets/8-3/Editing.dyn @@ -1,82 +1,82 @@ - - - - - - - - - - - 2.29 - - - - 2.68 - - - - 2.64 - - - - 8 - - - - 62 - - - - 0.5 - - - - 22 - - - - 25 - - - - 92 - - - - - - - - - 12 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + 2.29 + + + + 2.68 + + + + 2.64 + + + + 8 + + + + 62 + + + + 0.5 + + + + 22 + + + + 25 + + + + 92 + + + + + + + + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-4/ARCH-DirectShape-BaseFile.rvt b/08_Dynamo-for-Revit/datasets/8-4/ARCH-DirectShape-BaseFile.rvt index e463afee..c59fad85 100644 --- a/08_Dynamo-for-Revit/datasets/8-4/ARCH-DirectShape-BaseFile.rvt +++ b/08_Dynamo-for-Revit/datasets/8-4/ARCH-DirectShape-BaseFile.rvt @@ -1,126 +1,126 @@ -## Creating -You can create an array of Revit elements in Dynamo with full parametric control. The Revit nodes in Dynamo offer the ability to import elements from generic geometries to specific category types (like walls and floors). In this section, we'll focus on importing parametrically flexible elements with adaptive components. - -![Creation](images/8-4/creation.png) -### Adaptive Components -An adaptive component is a flexible family category which lends itself well to generative applications. Upon instantiation, you can create a complex geometric element which is driven by the fundamental location of adaptive points. - -![AdaptiveComponent](images/8-4/ac.png) -> An example of a three-point adaptive component in the family editor. This generates a truss which is defined by the position of each adaptive point. In the exercise below, we'll use this component to generate a series of trusses across a facade. - -#### Principles of Interoperability -The adaptive component is a good example for best practices of interoperability. We can create an array of adaptive components by defining the fundamental adaptive points. And, when transferring this data to other programs, we have the ability to reduce the geometry to simple data. Importing and exporting with a program like Excel follows a similar logic. - -Suppose a facade consultant wants to know the location of the truss elements without needing to parse through fully articulated geometry. In preparation for fabrication, the consultant can reference the location of adaptive points to regenerate geometry in a program like Inventor. - -The workflow we'll setup in the exercise below allows us to access all of this data while creating the definition for Revit element creation. By this process, we can merge conceptualization, documentation, and fabrication into a seamless workflow. This creates a more intelligent and efficient process for interoperability. - -#### Multiple Elements and Lists - -![Exercise](images/8-4/Exercise/03.png) - -The exercise below will walk through how Dynamo references data for Revit element creation. To generate multiple adaptive components, we define a list of lists, where each list has three points representing each point of the adaptive component. We'll keep this in mind as we manage the data structures in Dynamo. - -### Exercise -> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [Creating.dyn](datasets/8-4/Creating.dyn) -2. [ARCH-Creating-BaseFile.rvt](datasets/8-4/ARCH-Creating-BaseFile.rvt) - -![Exercise](images/8-4/Exercise/10.png) -> Beginning with the example file from this section (or continuing with the Revit file from the previous session), we see the same Revit mass. -1. This is the file as opened. -2. This is the truss system we'll created with Dynamo, linked intelligently to the Revit mass. - -![Exercise](images/8-4/Exercise/08.png) -> We've used the *"Select Model Element"* and *"Select Face"* nodes, now we're taking one step further down in the geometry hierarchy and using *"Select Edge"*. With the Dynamo solver set to run *"Automatic"*, the graph will continually update to changes in the Revit file. The edge we are selecting is tied dynamically to the Revit element topology. As long as the topology* does not change, the connection remains linked between Revit and Dynamo. -1. Select the top most curve of the glazing facade. This spans the full length of the building. If you're having trouble selecting the edge, remember to choose the selection in Revit by hovering over the edge and hitting *"Tab"* until the desired edge is highlighted. -2. Using two *"Select Edge"* nodes, select each edge representing the cant at the middle of the facade. -3. Do the same for the bottom edges of the facade in Revit. -4. The *Watch* nodes reveal that we now have lines in Dynamo. This is automatically converted to Dynamo geometry since the edges themselves are not Revit elements. These curves are the references we'll use to instantiate adaptive trusses across the facade. - -**Note - to keep a consistent topology, we're referring to a model that does not have additional faces or edges added. While parameters can change its shape, the way it which it is built remains consistent.* - -![Exercise](images/8-4/Exercise/07.png) -> We first need to join the curves and merge them into one list. This way we can *"group"* the curves to perform geometry operations. -1. Create a list for the two curves at the middle of the facade. -2. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. -3. Create a list for the two curves at the bottom of the facade. -4. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. -5. Finally, join the three main curves (one line and two polycurves) into one list. - -![Exercise](images/8-4/Exercise/06.png) -> We want to take advantage of the top curve, which is a line, and represents the full span of the facade. We'll create planes along this line to intersect with the set of curves we've grouped together in a list. -1. With a *code block*, define a range using the syntax: ```0..1..#numberOfTrusses; -``` -2. Plug an *integer slider *into the input for the code block. As you could have guessed, this will represent the number of trusses. Notice that the slider controls the number of items in the range defined from *0 *to *1*. -3. Plug the *code block* into the *param* input of a *"Curve.PlaneAtParameter"* node, and plug the top edge into the *curve* input. This will give us ten planes, evenly distributed across the span of the facade. - -![Exercise](images/8-4/Exercise/05.png) -> A plane is an abstract piece of geometry, representing a two dimensional space which is infinite. Planes are great for contouring and intersecting, as we are setting up in this step. -1. Using the *Geometry.Intersect* node, plug the *Curve.PlaneAtParameter* into the *entity* input of the *Geometry.Intersect* node. Plug the main *List.Create* node into the *geometry* input. We now see points in the Dynamo viewport representing the intersection of each curve with the defined planes. - -![Exercise](images/8-4/Exercise/04.png) -> Notice the output is a list of lists of lists. Too many lists for our purposes. We want to do a partial flatten here. We need to take one step down on the list and flatten the result. To do this, we use the *List.Map* operation, as discussed in the list chapter of the primer. -1. Plug the *Geometry.Intersect* node into the list input of *List.Map*. -2. Plug a *Flatten* node into the f(x) input of *List.Map*. The results gives 3 list, each with a count equal to the number of trusses. -3. We need to change this data. If we want to instantiate the truss, we have to use the same number of adaptive points as defined in the family. This is a three point adaptive component, so instead of three lists with 10 items each (numberOfTrusses), we want 10 lists of three items each. This way we can create 10 adaptive components. -3. Plug the *List.Map* into a *List.Transpose* node. Now we have the desired data output. -4. To confirm that the data is correct, add a *Polygon.ByPoints* node to the canvas and double check with the Dynamo preview. - -![Exercise](images/8-4/Exercise/03.png) -> In the same way we created the polygons, we array the adaptive components. -1. Add an *AdaptiveComponent.ByPoints* node to the canvas, plug the *List.Transpose* node into the *points* input. -2. Using a *Family Types* node, select the *"AdaptiveTruss"* family, and plug this into the *familySymbol* input of the *AdaptiveComponent.ByPoints* node. - -![Exercise](images/8-4/Exercise/02.png) -> Checking in Revit, we now have the ten trusses evenly spaced across the facade! - -![Exercise](images/8-4/Exercise/01.png) -> 1. "Flexing" the graph, we turn up the *numberOfTrusses* to *40* by changing the *slider*. Lots of trusses, not very realistic, but the parametric link is working. - -![Exercise](images/8-4/Exercise/00.png) -> 1. Taming the truss system, let's compromise with a value of *15* for *numberOfTrusses*. - -![Exercise](images/8-4/Exercise/00a.png) -> And for the final test, by selecting the mass in Revit and editing instance parameters, we can change the form of the building and watch the truss follow suit. Remember, this Dynamo graph has to be open in order to see this update, and the link will be broken as soon as it's closed. - - -### DirectShape Elements -Another method for importing parametric Dynamo geometry into Revit is with DirectShape. In summary, the DirectShape element and related classes support the ability to store externally created geometric shapes in a Revit document. The geometry can include closed solids or meshes. DirectShape is primarily intended for importing shapes from other data formats such as IFC or STEP where not enough information is available to create a "real" Revit element. Like the IFC and STEP workflow, the DirectShape functionality works well with importing Dynamo created geometries into Revit projects as real elements. - -Let's walk through and exercise for importing Dynamo geometry as a DirectShape into our Revit project. Using this method, we can assign an imported geometry's category, material, and name - all while maintaining a parametric link to our Dynamo graph. - -### Exercise -> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. -1. [DirectShape.dyn](datasets/8-4/DirectShape.dyn) -2. [ARCH-DirectShape-BaseFile.rvt](datasets/8-4/ARCH-DirectShape-BaseFile.rvt) - -![Exercise](images/8-4/Exercise/DS-05.png) -> Begin by opening the sample file for this lesson - ARCH-DirectShape-BaseFile.rvt. -1. In the 3D view, we see our building mass from the previous lesson. -2. Along the edge of the atrium is one reference curve, we'll use this as a curve to reference in Dynamo. -3. Along the opposing edge of the atrium is another reference curve which we'll reference in Dynamo as well. - -![Exercise](images/8-4/Exercise/DS-04.png) ->1. To reference our geometry in Dynamo, we'll use *Select Model Element* for each member in Revit. Select the mass in Revit and import the geometry into Dynamo by Using *Element.Faces* - the mass should now be visible in your Dynamo preview. -2. Import one reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. -3. Import the other reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. - -![Exercise](images/8-4/Exercise/DS-03.png) ->1. Zooming out and panning to the right in the sample graph, we see a large group of nodes - these are geometric operations which generate the trellis roof structure visible in the Dynamo preview. These nodes are generating using the *Node to Code* functionality as discussed in the [code block section](../07_Code-Block/7-2_Design-Script-syntax.md#Node) of the primer. -2. The structure is driven by three major parameters - Diagonal Shift, Camber, and Radius. - -![Exercise](images/8-4/Exercise/DS-06.png) ->Zooming a close-up look of the parameters for this graph. We can flex these to get different geometry outputs. - -![Exercise](images/8-4/Exercise/DS-02.png) ->1. Dropping the *DirectShape.ByGeometry* node onto the canvas, we see that it has four inputs: **geometry, category, material**, and **name**. -2. Geometry will be the solid created from the geometry creation portion of the graph -3. The category input is chosen using the dropdwon *Categories* node. In this case we'll use "Structural Framing". -4. The material input is selected through the array of nodes above - although it can be more simply defined as "Default" in this case. - -![Exercise](images/8-4/Exercise/DS-01.png) ->After running the solver, back in Revit, we have the imported geometry on the roof in our project. This is a structural framing element, rather than a generic model. The parametric link to Dynamo remains intact. - -![Exercise](images/8-4/Exercise/DS-00.png) +## Creating +You can create an array of Revit elements in Dynamo with full parametric control. The Revit nodes in Dynamo offer the ability to import elements from generic geometries to specific category types (like walls and floors). In this section, we'll focus on importing parametrically flexible elements with adaptive components. + +![Creation](images/8-4/creation.png) +### Adaptive Components +An adaptive component is a flexible family category which lends itself well to generative applications. Upon instantiation, you can create a complex geometric element which is driven by the fundamental location of adaptive points. + +![AdaptiveComponent](images/8-4/ac.png) +> An example of a three-point adaptive component in the family editor. This generates a truss which is defined by the position of each adaptive point. In the exercise below, we'll use this component to generate a series of trusses across a facade. + +#### Principles of Interoperability +The adaptive component is a good example for best practices of interoperability. We can create an array of adaptive components by defining the fundamental adaptive points. And, when transferring this data to other programs, we have the ability to reduce the geometry to simple data. Importing and exporting with a program like Excel follows a similar logic. + +Suppose a facade consultant wants to know the location of the truss elements without needing to parse through fully articulated geometry. In preparation for fabrication, the consultant can reference the location of adaptive points to regenerate geometry in a program like Inventor. + +The workflow we'll setup in the exercise below allows us to access all of this data while creating the definition for Revit element creation. By this process, we can merge conceptualization, documentation, and fabrication into a seamless workflow. This creates a more intelligent and efficient process for interoperability. + +#### Multiple Elements and Lists + +![Exercise](images/8-4/Exercise/03.png) + +The exercise below will walk through how Dynamo references data for Revit element creation. To generate multiple adaptive components, we define a list of lists, where each list has three points representing each point of the adaptive component. We'll keep this in mind as we manage the data structures in Dynamo. + +### Exercise +> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [Creating.dyn](datasets/8-4/Creating.dyn) +2. [ARCH-Creating-BaseFile.rvt](datasets/8-4/ARCH-Creating-BaseFile.rvt) + +![Exercise](images/8-4/Exercise/10.png) +> Beginning with the example file from this section (or continuing with the Revit file from the previous session), we see the same Revit mass. +1. This is the file as opened. +2. This is the truss system we'll created with Dynamo, linked intelligently to the Revit mass. + +![Exercise](images/8-4/Exercise/08.png) +> We've used the *"Select Model Element"* and *"Select Face"* nodes, now we're taking one step further down in the geometry hierarchy and using *"Select Edge"*. With the Dynamo solver set to run *"Automatic"*, the graph will continually update to changes in the Revit file. The edge we are selecting is tied dynamically to the Revit element topology. As long as the topology* does not change, the connection remains linked between Revit and Dynamo. +1. Select the top most curve of the glazing facade. This spans the full length of the building. If you're having trouble selecting the edge, remember to choose the selection in Revit by hovering over the edge and hitting *"Tab"* until the desired edge is highlighted. +2. Using two *"Select Edge"* nodes, select each edge representing the cant at the middle of the facade. +3. Do the same for the bottom edges of the facade in Revit. +4. The *Watch* nodes reveal that we now have lines in Dynamo. This is automatically converted to Dynamo geometry since the edges themselves are not Revit elements. These curves are the references we'll use to instantiate adaptive trusses across the facade. + +**Note - to keep a consistent topology, we're referring to a model that does not have additional faces or edges added. While parameters can change its shape, the way it which it is built remains consistent.* + +![Exercise](images/8-4/Exercise/07.png) +> We first need to join the curves and merge them into one list. This way we can *"group"* the curves to perform geometry operations. +1. Create a list for the two curves at the middle of the facade. +2. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. +3. Create a list for the two curves at the bottom of the facade. +4. Join the two curves into a Polycurve by plugging the *List.Create* component into a *Polycurve.ByJoinedCurves* node. +5. Finally, join the three main curves (one line and two polycurves) into one list. + +![Exercise](images/8-4/Exercise/06.png) +> We want to take advantage of the top curve, which is a line, and represents the full span of the facade. We'll create planes along this line to intersect with the set of curves we've grouped together in a list. +1. With a *code block*, define a range using the syntax: ```0..1..#numberOfTrusses; +``` +2. Plug an *integer slider *into the input for the code block. As you could have guessed, this will represent the number of trusses. Notice that the slider controls the number of items in the range defined from *0 *to *1*. +3. Plug the *code block* into the *param* input of a *"Curve.PlaneAtParameter"* node, and plug the top edge into the *curve* input. This will give us ten planes, evenly distributed across the span of the facade. + +![Exercise](images/8-4/Exercise/05.png) +> A plane is an abstract piece of geometry, representing a two dimensional space which is infinite. Planes are great for contouring and intersecting, as we are setting up in this step. +1. Using the *Geometry.Intersect* node, plug the *Curve.PlaneAtParameter* into the *entity* input of the *Geometry.Intersect* node. Plug the main *List.Create* node into the *geometry* input. We now see points in the Dynamo viewport representing the intersection of each curve with the defined planes. + +![Exercise](images/8-4/Exercise/04.png) +> Notice the output is a list of lists of lists. Too many lists for our purposes. We want to do a partial flatten here. We need to take one step down on the list and flatten the result. To do this, we use the *List.Map* operation, as discussed in the list chapter of the primer. +1. Plug the *Geometry.Intersect* node into the list input of *List.Map*. +2. Plug a *Flatten* node into the f(x) input of *List.Map*. The results gives 3 list, each with a count equal to the number of trusses. +3. We need to change this data. If we want to instantiate the truss, we have to use the same number of adaptive points as defined in the family. This is a three point adaptive component, so instead of three lists with 10 items each (numberOfTrusses), we want 10 lists of three items each. This way we can create 10 adaptive components. +3. Plug the *List.Map* into a *List.Transpose* node. Now we have the desired data output. +4. To confirm that the data is correct, add a *Polygon.ByPoints* node to the canvas and double check with the Dynamo preview. + +![Exercise](images/8-4/Exercise/03.png) +> In the same way we created the polygons, we array the adaptive components. +1. Add an *AdaptiveComponent.ByPoints* node to the canvas, plug the *List.Transpose* node into the *points* input. +2. Using a *Family Types* node, select the *"AdaptiveTruss"* family, and plug this into the *familySymbol* input of the *AdaptiveComponent.ByPoints* node. + +![Exercise](images/8-4/Exercise/02.png) +> Checking in Revit, we now have the ten trusses evenly spaced across the facade! + +![Exercise](images/8-4/Exercise/01.png) +> 1. "Flexing" the graph, we turn up the *numberOfTrusses* to *40* by changing the *slider*. Lots of trusses, not very realistic, but the parametric link is working. + +![Exercise](images/8-4/Exercise/00.png) +> 1. Taming the truss system, let's compromise with a value of *15* for *numberOfTrusses*. + +![Exercise](images/8-4/Exercise/00a.png) +> And for the final test, by selecting the mass in Revit and editing instance parameters, we can change the form of the building and watch the truss follow suit. Remember, this Dynamo graph has to be open in order to see this update, and the link will be broken as soon as it's closed. + + +### DirectShape Elements +Another method for importing parametric Dynamo geometry into Revit is with DirectShape. In summary, the DirectShape element and related classes support the ability to store externally created geometric shapes in a Revit document. The geometry can include closed solids or meshes. DirectShape is primarily intended for importing shapes from other data formats such as IFC or STEP where not enough information is available to create a "real" Revit element. Like the IFC and STEP workflow, the DirectShape functionality works well with importing Dynamo created geometries into Revit projects as real elements. + +Let's walk through and exercise for importing Dynamo geometry as a DirectShape into our Revit project. Using this method, we can assign an imported geometry's category, material, and name - all while maintaining a parametric link to our Dynamo graph. + +### Exercise +> Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. +1. [DirectShape.dyn](datasets/8-4/DirectShape.dyn) +2. [ARCH-DirectShape-BaseFile.rvt](datasets/8-4/ARCH-DirectShape-BaseFile.rvt) + +![Exercise](images/8-4/Exercise/DS-05.png) +> Begin by opening the sample file for this lesson - ARCH-DirectShape-BaseFile.rvt. +1. In the 3D view, we see our building mass from the previous lesson. +2. Along the edge of the atrium is one reference curve, we'll use this as a curve to reference in Dynamo. +3. Along the opposing edge of the atrium is another reference curve which we'll reference in Dynamo as well. + +![Exercise](images/8-4/Exercise/DS-04.png) +>1. To reference our geometry in Dynamo, we'll use *Select Model Element* for each member in Revit. Select the mass in Revit and import the geometry into Dynamo by Using *Element.Faces* - the mass should now be visible in your Dynamo preview. +2. Import one reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. +3. Import the other reference curve into Dynamo by using *Select Model Element* and *CurveElement.Curve*. + +![Exercise](images/8-4/Exercise/DS-03.png) +>1. Zooming out and panning to the right in the sample graph, we see a large group of nodes - these are geometric operations which generate the trellis roof structure visible in the Dynamo preview. These nodes are generating using the *Node to Code* functionality as discussed in the [code block section](../07_Code-Block/7-2_Design-Script-syntax.md#Node) of the primer. +2. The structure is driven by three major parameters - Diagonal Shift, Camber, and Radius. + +![Exercise](images/8-4/Exercise/DS-06.png) +>Zooming a close-up look of the parameters for this graph. We can flex these to get different geometry outputs. + +![Exercise](images/8-4/Exercise/DS-02.png) +>1. Dropping the *DirectShape.ByGeometry* node onto the canvas, we see that it has four inputs: **geometry, category, material**, and **name**. +2. Geometry will be the solid created from the geometry creation portion of the graph +3. The category input is chosen using the dropdwon *Categories* node. In this case we'll use "Structural Framing". +4. The material input is selected through the array of nodes above - although it can be more simply defined as "Default" in this case. + +![Exercise](images/8-4/Exercise/DS-01.png) +>After running the solver, back in Revit, we have the imported geometry on the roof in our project. This is a structural framing element, rather than a generic model. The parametric link to Dynamo remains intact. + +![Exercise](images/8-4/Exercise/DS-00.png) >1. If we "flex" the Dynamo graph by changing the "Diagonal Shift" parameter to "-2", we just run the solver again and get a new imported DirectShape! \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-4/Creating.dyn b/08_Dynamo-for-Revit/datasets/8-4/Creating.dyn index 55bcb7b1..aebffb6a 100644 --- a/08_Dynamo-for-Revit/datasets/8-4/Creating.dyn +++ b/08_Dynamo-for-Revit/datasets/8-4/Creating.dyn @@ -1,68 +1,68 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-4/DirectShape.dyn b/08_Dynamo-for-Revit/datasets/8-4/DirectShape.dyn index 198b3168..0d5a7fd1 100644 --- a/08_Dynamo-for-Revit/datasets/8-4/DirectShape.dyn +++ b/08_Dynamo-for-Revit/datasets/8-4/DirectShape.dyn @@ -1,157 +1,157 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3 - - - - - 0.2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDEuMC4wLjY2MCUyQyUyMEN1bHR1cmUlM0RuZXV0cmFsJTJDJTIwUHVibGljS2V5VG9rZW4lM0RudWxsIj4NCjxOdW1iZXJPZkVsZW1lbnRzPjE8L051bWJlck9mRWxlbWVudHM+DQo8QmFzZS0wX0hhc0RhdGE+dHJ1ZTwvQmFzZS0wX0hhc0RhdGE+DQo8QmFzZS0wX0RhdGEgaWQ9InJlZi0zIj5QRk5QUVZBdFJVNVdPa1Z1ZG1Wc2IzQmxJSGh0Ykc1ek9uaHphVDBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01TOVlUVXhUWTJobGJXRXRhVzV6ZEdGdVkyVWlJSGh0Ykc1ek9uaHpaRDBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01TOVlUVXhUWTJobGJXRWlJSGh0Ykc1ek9sTlBRVkF0UlU1RFBTSm9kSFJ3T2k4dmMyTm9aVzFoY3k1NGJXeHpiMkZ3TG05eVp5OXpiMkZ3TDJWdVkyOWthVzVuTHlJZ2VHMXNibk02VTA5QlVDMUZUbFk5SW1oMGRIQTZMeTl6WTJobGJXRnpMbmh0YkhOdllYQXViM0puTDNOdllYQXZaVzUyWld4dmNHVXZJaUI0Yld4dWN6cGpiSEk5SW1oMGRIQTZMeTl6WTJobGJXRnpMbTFwWTNKdmMyOW1kQzVqYjIwdmMyOWhjQzlsYm1OdlpHbHVaeTlqYkhJdk1TNHdJaUJUVDBGUUxVVk9WanBsYm1OdlpHbHVaMU4wZVd4bFBTSm9kSFJ3T2k4dmMyTm9aVzFoY3k1NGJXeHpiMkZ3TG05eVp5OXpiMkZ3TDJWdVkyOWthVzVuTHlJK0RRbzhVMDlCVUMxRlRsWTZRbTlrZVQ0TkNqeGhNVHBFYVhKbFkzUlRhR0Z3WlZOMFlYUmxJR2xrUFNKeVpXWXRNU0lnZUcxc2JuTTZZVEU5SW1oMGRIQTZMeTl6WTJobGJXRnpMbTFwWTNKdmMyOW1kQzVqYjIwdlkyeHlMMjV6WVhOelpXMHZVbVYyYVhRdVJXeGxiV1Z1ZEhNdlVtVjJhWFJPYjJSbGN5VXlReVV5TUZabGNuTnBiMjRsTTBReExqQXVNQzQyTmpBbE1rTWxNakJEZFd4MGRYSmxKVE5FYm1WMWRISmhiQ1V5UXlVeU1GQjFZbXhwWTB0bGVWUnZhMlZ1SlRORWJuVnNiQ0krRFFvOGMzUnlhVzVuU1VRZ2FXUTlJbkpsWmkweklqNDFZMlkyTkRBNVlpMDVNV1E1TFRRNFpqTXRZbVZoTnkxaVpHRmxOMlk1WkdNNFlqWXRNREF3TlRRME9EUThMM04wY21sdVowbEVQZzBLUEdsdWRFbEVQak0wTlRJeU1Ed3ZhVzUwU1VRK0RRbzhjM2x1WTBsa0lHbGtQU0p5WldZdE5DSStNamszTmpCaE9XTXRZbVF3WXkwME4ySTFMVGhsTldNdE9UWTVOemMwWmpZMVlUTm1QQzl6ZVc1alNXUStEUW84YldGMFpYSnBZV3hKWkQ0eU5Ed3ZiV0YwWlhKcFlXeEpaRDROQ2p3dllURTZSR2x5WldOMFUyaGhjR1ZUZEdGMFpUNE5Dand2VTA5QlVDMUZUbFk2UW05a2VUNE5Dand2VTA5QlVDMUZUbFk2Ulc1MlpXeHZjR1UrRFFvPTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 + + + + + 0.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDEuMC4wLjY2MCUyQyUyMEN1bHR1cmUlM0RuZXV0cmFsJTJDJTIwUHVibGljS2V5VG9rZW4lM0RudWxsIj4NCjxOdW1iZXJPZkVsZW1lbnRzPjE8L051bWJlck9mRWxlbWVudHM+DQo8QmFzZS0wX0hhc0RhdGE+dHJ1ZTwvQmFzZS0wX0hhc0RhdGE+DQo8QmFzZS0wX0RhdGEgaWQ9InJlZi0zIj5QRk5QUVZBdFJVNVdPa1Z1ZG1Wc2IzQmxJSGh0Ykc1ek9uaHphVDBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01TOVlUVXhUWTJobGJXRXRhVzV6ZEdGdVkyVWlJSGh0Ykc1ek9uaHpaRDBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01TOVlUVXhUWTJobGJXRWlJSGh0Ykc1ek9sTlBRVkF0UlU1RFBTSm9kSFJ3T2k4dmMyTm9aVzFoY3k1NGJXeHpiMkZ3TG05eVp5OXpiMkZ3TDJWdVkyOWthVzVuTHlJZ2VHMXNibk02VTA5QlVDMUZUbFk5SW1oMGRIQTZMeTl6WTJobGJXRnpMbmh0YkhOdllYQXViM0puTDNOdllYQXZaVzUyWld4dmNHVXZJaUI0Yld4dWN6cGpiSEk5SW1oMGRIQTZMeTl6WTJobGJXRnpMbTFwWTNKdmMyOW1kQzVqYjIwdmMyOWhjQzlsYm1OdlpHbHVaeTlqYkhJdk1TNHdJaUJUVDBGUUxVVk9WanBsYm1OdlpHbHVaMU4wZVd4bFBTSm9kSFJ3T2k4dmMyTm9aVzFoY3k1NGJXeHpiMkZ3TG05eVp5OXpiMkZ3TDJWdVkyOWthVzVuTHlJK0RRbzhVMDlCVUMxRlRsWTZRbTlrZVQ0TkNqeGhNVHBFYVhKbFkzUlRhR0Z3WlZOMFlYUmxJR2xrUFNKeVpXWXRNU0lnZUcxc2JuTTZZVEU5SW1oMGRIQTZMeTl6WTJobGJXRnpMbTFwWTNKdmMyOW1kQzVqYjIwdlkyeHlMMjV6WVhOelpXMHZVbVYyYVhRdVJXeGxiV1Z1ZEhNdlVtVjJhWFJPYjJSbGN5VXlReVV5TUZabGNuTnBiMjRsTTBReExqQXVNQzQyTmpBbE1rTWxNakJEZFd4MGRYSmxKVE5FYm1WMWRISmhiQ1V5UXlVeU1GQjFZbXhwWTB0bGVWUnZhMlZ1SlRORWJuVnNiQ0krRFFvOGMzUnlhVzVuU1VRZ2FXUTlJbkpsWmkweklqNDFZMlkyTkRBNVlpMDVNV1E1TFRRNFpqTXRZbVZoTnkxaVpHRmxOMlk1WkdNNFlqWXRNREF3TlRRME9EUThMM04wY21sdVowbEVQZzBLUEdsdWRFbEVQak0wTlRJeU1Ed3ZhVzUwU1VRK0RRbzhjM2x1WTBsa0lHbGtQU0p5WldZdE5DSStNamszTmpCaE9XTXRZbVF3WXkwME4ySTFMVGhsTldNdE9UWTVOemMwWmpZMVlUTm1QQzl6ZVc1alNXUStEUW84YldGMFpYSnBZV3hKWkQ0eU5Ed3ZiV0YwWlhKcFlXeEpaRDROQ2p3dllURTZSR2x5WldOMFUyaGhjR1ZUZEdGMFpUNE5Dand2VTA5QlVDMUZUbFk2UW05a2VUNE5Dand2VTA5QlVDMUZUbFk2Ulc1MlpXeHZjR1UrRFFvPTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn b/08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn index 80c4da41..f33c0d84 100644 --- a/08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn +++ b/08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn @@ -1,116 +1,116 @@ - - - - - - - - - - - - - - - - - - - - - - - - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4yLjIwMzIlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU1pNHlNRE15SlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK04yWXhaVFkyWVRBdE4yTTJNeTAwWVRGaExUazFPR0l0T1daaU5UbGhaV0V5TlRVeExUQXdNRFUwWXpZMlBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHpORGN5TXpnOEwybHVkRWxFUGcwS1BDOWhNVHBUWlhKcFlXeHBlbUZpYkdWSlpENE5Dand2VTA5QlVDMUZUbFk2UW05a2VUNE5Dand2VTA5QlVDMUZUbFk2Ulc1MlpXeHZjR1UrRFFvPTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K - - + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4yLjIwMzIlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU1pNHlNRE15SlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK04yWXhaVFkyWVRBdE4yTTJNeTAwWVRGaExUazFPR0l0T1daaU5UbGhaV0V5TlRVeExUQXdNRFUwWXpZMlBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHpORGN5TXpnOEwybHVkRWxFUGcwS1BDOWhNVHBUWlhKcFlXeHBlbUZpYkdWSlpENE5Dand2VTA5QlVDMUZUbFk2UW05a2VUNE5Dand2VTA5QlVDMUZUbFk2Ulc1MlpXeHZjR1UrRFFvPTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K + + \ No newline at end of file diff --git a/08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn b/08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn index edbbd6e9..00150f08 100644 --- a/08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn +++ b/08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/9-1_Introduction.md b/09_Custom-Nodes/9-1_Introduction.md index 5d52074f..bfd4fbb4 100644 --- a/09_Custom-Nodes/9-1_Introduction.md +++ b/09_Custom-Nodes/9-1_Introduction.md @@ -1,54 +1,54 @@ -## Custom Nodes -Dynamo offers many core nodes for a wide-range of visual programming tasks. Sometimes a quicker, more elegant, or more easily shared solution is to build your own nodes. These can be reused among different projects, they make your graph clearer and cleaner, and they can be pushed to the package manager and shared with the global Dynamo community. - -![](images/9-1/cn.jpg) - -###Cleaning up Your Graph - -Custom Nodes are constructed by nesting other nodes and custom nodes inside of a "Dynamo Custom Node," which we can think of conceptually as a container. When this container node is executed in your graph, everything inside it will be executed to allow you to reuse and share a useful combination of nodes. - -###Adapting to Change -When you have multiple copies of a custom node in your graph, you can update all of them by editing the base custom node. This allows you to update your graph seamlessly by adapting to any changes that may occur in workflow or design. - -###Work Sharing -Arguably the best feature of custom nodes is their work sharing capabilities. If a "power user" creates a complex Dynamo graph and hands it off to a designer who is new to Dynamo, he/she can condense the graph to the bare essentials for design interaction. The custom node can be opened to edit the internal graph, but the "container" can be kept simple. With this process, custom nodes allow Dynamo users to design a graph that is clean and intuitive. - -![](images/9-1/customNodeDiagram.jpg) - -###Many Ways to Build a Node -There are a wide variety of ways to build custom nodes in Dynamo. In the examples in this chapter, we'll create custom nodes directly from the Dynamo UI. If you are a programmer and you are interested in C# or Zero-Touch formatting, you can reference [this page ](https://github.com/DynamoDS/Dynamo/wiki/How-To-Create-Your-Own-Nodes)on the Dynamo Wiki for a more in-depth review. - -### Custom Node Environment -Let's jump into the custom node environment and make a simple node to calculate a percentage. The custom node environment is different from the Dynamo graph environment, but the interaction is fundamentally the same. With that said, let's create our first custom node! - -![Custom Nodes Intro](images/9-1/CustomNodes01.png) - -> To create a Custom Node from scratch, Launch Dynamo and select Custom Node, or type Ctrl + Shift + N from the canvas. - -![Custom Nodes Dialog](images/9-1/CustomNodes02.png) - -> Assign a name, description, and category in the Custom Node Properties dialog. -1. **Name:** Percentage -2. **Description**: Calculate the percentage of one value in relation to another. -3. **Category:** Core.Math - -![Custom Nodes Canvas](images/9-1/CustomNodes03.png) - -> This will open a canvas with a yellow background, indicating that you are working inside a custom node. In this canvas you have access to all of the core Dynamo nodes, as well as the **Input** and **Output** nodes, which label the data flowing into and out of the custom node. They can be found in *Core>Input*. - -![Custom Nodes Canvas](images/9-1/CustomNodes04.png) - -> 1. **Inputs:** input nodes create input ports on the custom node. The syntax for an input node is *input_name : datatype = default_value(optional).* - ->2. **Outputs:** Similar to inputs, these will create and name output ports on the custom node. -> Consider adding a **Custom Comment** to your Input and Output ports to hint at the Input and Output types. This is discussed in more detail in the [Creating Custom Nodes section](9-2_Creating.md). - -You can save this custom node as a .dyf (as opposed to the standard .dyn) file and it will automatically be added to your session and future sessions. You will find the custom node in your library in the category that is specified in the custom node's properties. - -![Add to Library](images/9-1/CustomNodes05.png) - -> Left: The Core > Math category of the default library -Right: Core > Math with the new custom node - -###Moving Forward -Now that we've created our first custom node, the next sections will dive deeper into custom node functionality and how to publish generic workflows. In the following section, we'll look at developing a custom node that transfers geometry from one surface to another. +## Custom Nodes +Dynamo offers many core nodes for a wide-range of visual programming tasks. Sometimes a quicker, more elegant, or more easily shared solution is to build your own nodes. These can be reused among different projects, they make your graph clearer and cleaner, and they can be pushed to the package manager and shared with the global Dynamo community. + +![](images/9-1/cn.jpg) + +###Cleaning up Your Graph + +Custom Nodes are constructed by nesting other nodes and custom nodes inside of a "Dynamo Custom Node," which we can think of conceptually as a container. When this container node is executed in your graph, everything inside it will be executed to allow you to reuse and share a useful combination of nodes. + +###Adapting to Change +When you have multiple copies of a custom node in your graph, you can update all of them by editing the base custom node. This allows you to update your graph seamlessly by adapting to any changes that may occur in workflow or design. + +###Work Sharing +Arguably the best feature of custom nodes is their work sharing capabilities. If a "power user" creates a complex Dynamo graph and hands it off to a designer who is new to Dynamo, he/she can condense the graph to the bare essentials for design interaction. The custom node can be opened to edit the internal graph, but the "container" can be kept simple. With this process, custom nodes allow Dynamo users to design a graph that is clean and intuitive. + +![](images/9-1/customNodeDiagram.jpg) + +###Many Ways to Build a Node +There are a wide variety of ways to build custom nodes in Dynamo. In the examples in this chapter, we'll create custom nodes directly from the Dynamo UI. If you are a programmer and you are interested in C# or Zero-Touch formatting, you can reference [this page ](https://github.com/DynamoDS/Dynamo/wiki/How-To-Create-Your-Own-Nodes)on the Dynamo Wiki for a more in-depth review. + +### Custom Node Environment +Let's jump into the custom node environment and make a simple node to calculate a percentage. The custom node environment is different from the Dynamo graph environment, but the interaction is fundamentally the same. With that said, let's create our first custom node! + +![Custom Nodes Intro](images/9-1/CustomNodes01.png) + +> To create a Custom Node from scratch, Launch Dynamo and select Custom Node, or type Ctrl + Shift + N from the canvas. + +![Custom Nodes Dialog](images/9-1/CustomNodes02.png) + +> Assign a name, description, and category in the Custom Node Properties dialog. +1. **Name:** Percentage +2. **Description**: Calculate the percentage of one value in relation to another. +3. **Category:** Core.Math + +![Custom Nodes Canvas](images/9-1/CustomNodes03.png) + +> This will open a canvas with a yellow background, indicating that you are working inside a custom node. In this canvas you have access to all of the core Dynamo nodes, as well as the **Input** and **Output** nodes, which label the data flowing into and out of the custom node. They can be found in *Core>Input*. + +![Custom Nodes Canvas](images/9-1/CustomNodes04.png) + +> 1. **Inputs:** input nodes create input ports on the custom node. The syntax for an input node is *input_name : datatype = default_value(optional).* + +>2. **Outputs:** Similar to inputs, these will create and name output ports on the custom node. +> Consider adding a **Custom Comment** to your Input and Output ports to hint at the Input and Output types. This is discussed in more detail in the [Creating Custom Nodes section](9-2_Creating.md). + +You can save this custom node as a .dyf (as opposed to the standard .dyn) file and it will automatically be added to your session and future sessions. You will find the custom node in your library in the category that is specified in the custom node's properties. + +![Add to Library](images/9-1/CustomNodes05.png) + +> Left: The Core > Math category of the default library +Right: Core > Math with the new custom node + +###Moving Forward +Now that we've created our first custom node, the next sections will dive deeper into custom node functionality and how to publish generic workflows. In the following section, we'll look at developing a custom node that transfers geometry from one surface to another. diff --git a/09_Custom-Nodes/9-2_Creating.md b/09_Custom-Nodes/9-2_Creating.md index dd6de8b9..811f52a3 100644 --- a/09_Custom-Nodes/9-2_Creating.md +++ b/09_Custom-Nodes/9-2_Creating.md @@ -1,79 +1,79 @@ -## Creating a Custom Node -Dynamo offers several different methods for creating custom nodes. You can build custom nodes from scratch, from an existing graph, or explicitly in C#. In this section we will cover building a custom node in the Dynamo UI from an existing graph. This method is ideal for cleaning up the workspace, as well as packaging a sequence of nodes to reuse elsewhere. - -###Custom Nodes for UV Mapping -In the image below, we map a point from one surface to another using UV coordinates. We'll use this concept to create a panelized surface which references curves in the XY plane. We'll create quad panels for our panelization here, but using the same logic, we can create a wide variety of panels with UV mapping. This is a great opportunity for custom node development because we will be able to repeat a similar process more easily in this graph or in other Dynamo workflows. - -![](images/9-2/uvMap2-01-01.jpg) - -### Creating a Custom Node from an Existing Graph - -> Download and unzip the example files for this exercise (Right click and choose "Save Link As..."). A full list of example files can be found in the Appendix. [UV-CustomNode.zip](datasets/9-2/UV-CustomNode.zip) - -Let’s start by creating a graph that we want to nest into a custom node. In this example, we will create a graph that maps polygons from a base surface to a target surface, using UV coordinates. This UV mapping process is something we use frequently, making it a good candidate for a custom node. For more information on surfaces and UV space, see section 5.5. The complete graph is *UVmapping_Custom-Node.dyn* from the .zip file downloaded above. - -![Exercise](images/9-2/UVmapping01.png) -> 1. **Code Block:** Create a range of 10 numbers between 45 and negative 45 using a code block. -2. **Point.ByCoordinates:** Connect the output of the Code Block to the ‘x’ and ‘y’ inputs and set the lacing to cross-reference. You should now have a grid of points. -3. **Plane.ByOriginNormal:** Connect the *‘Point’* output to the *‘origin’* input to create a plane at each of the points. The default normal vector of (0,0,1) will be used. -4. **Rectangle.ByWidthLength:** Connect the planes from the previous step into the *‘plane’* input, and use a Code Block with a value of *10* to specify the width and length. - -You should now see a grid of rectangles. Let’s map these rectangles to a target surface using UV coordinates. - -![Exercise](images/9-2/UVmapping02.png) ->1. **Polygon.Points:** Connect the Rectangle output from the previous step to the *‘polygon’* input to extract the corner points of each rectangle. These are the points that we will map to the target surface. -2. **Rectangle.ByWidthLength:** Use a Code Block with a value of *100* to specify the width and length of a rectangle. This will be the boundary of our base surface. -3. **Surface.ByPatch:** Connect the Rectangle from the previous step to the *‘closedCurve’* input to create a base surface. -4. **Surface.UVParameterAtPoint:** Connect the *‘Point’* output of the *Polygon.Points* node and the *‘Surface’* output of the *Surface.ByPatch* node to return the UV parameter at each point. - -Now that we have a base surface and a set of UV coordinates, we can import a target surface and map the points between surfaces. - -![Exercise](images/9-2/UVmapping03.png) ->1. **File Path:** Select the file path of the surface you want to import. The file type should be .SAT. Click the *"Browse..."* button and navigate to the *UVmapping_srf.sat* file from the .zip file downloaded above. -2. **Geometry.ImportFromSAT:** Connect the file path to import the surface. You should see the imported surface in the geometry preview. -3. **UV:** Connect the UV parameter output to a *UV.U* and a *UV.V* node. -4. **Surface.PointAtParameter:** Connect the imported surface as well as the u and v coordinates. You should now see a grid of 3D points on the target surface. - -The final step is to use the 3D points to construct rectangular surface patches. - -![Exercise](images/9-2/UVmapping04.png) ->1. **PolyCurve.ByPoints:** Connect the points on the surface to construct a polycurve through the points. -2. **Boolean:** Add a Boolean to the workspace and connect it to the *‘connectLastToFirst’* input and toggle to True to close the polycurves. You should now see rectangles mapped to the surface. -3. **Surface.ByPatch:** Connect the polycurves to the *‘closedCurve’* input to construct surface patches. - -Now let’s select the nodes that we want to nest into a Custom Node, thinking about what we want to be the inputs and outputs of our node. We want our Custom Node to be as flexible as possible, so it should be able to map any polygons, not just rectangles. - -![Exercise](images/9-2/UVmapping05.png) -> Select the above nodes (beginning with *Polygon.Points*), right click on the workspace and select *‘node from selection’*. - -![Exercise](images/9-2/UVmapping06.png) -> In the Custom Node Properties dialog, assign a name, description, and category to the Custom Node. - -![Exercise](images/9-2/UVmapping07.png) -> The Custom Node has considerably cleaned up the workspace. Notice that the inputs and outputs have been named based on the original nodes. Let’s edit the Custom Node to make the names more descriptive. - -![Exercise](images/9-2/UVmapping08.png) -> Double click the Custom Node to edit it. This will open a workspace with a yellow background representing the inside of the node. -1. **Inputs:** Change the input names to *baseSurface* and *targetSurface*. -2. **Outputs:** Add an additional output for the mapped polygons. - ->Save the custom node and return to the home workspace. - -![Exercise](images/9-2/UVmapping09.png) -> The **MapPolygonsToSurface** node reflects the changes we just made. - -We can also add to the robustness of the Custom Node by adding in **Custom Comments**. Comments can help to hint at the input and output types or explain the functionality of the node. Comments will appear when the user hovers over an input or output of a Custom Node. - -![Custom Comment](images/9-2/UVmapping_Custom1.jpg) -> Double click the Custom Node to edit it. This will re-open the yellow background workspace. -1. Begin editing the Input Code Block. To start a Comment, type "//" followed by the comment text. Type anything that may help to clarify the Node - Here we will describe the *targetSurface*. -2. Let's also set the default value for the *inputSurface* by setting the input type equal to a value. Here, we will set the default value to the original Surface.ByPatch set. - -![Custom Comment](images/9-2/UVmapping_Custom1_.jpg) -> Comments can also be applied to the Outputs. Begin editing the text in the Output Code Block. To start a Comment, type "//" followed by the comment text. Here we will clarify the *Polygons* and the *surfacePatches* Outputs by adding a more in-depth description. - - -![Custom Comment](images/9-2/UVmapping_Custom2.jpg) -> -1. Hover over the Custom Node Inputs to see the Comments. -2. With the default value set on our *inputSurface*, we can also run the definition without a surface input. +## Creating a Custom Node +Dynamo offers several different methods for creating custom nodes. You can build custom nodes from scratch, from an existing graph, or explicitly in C#. In this section we will cover building a custom node in the Dynamo UI from an existing graph. This method is ideal for cleaning up the workspace, as well as packaging a sequence of nodes to reuse elsewhere. + +###Custom Nodes for UV Mapping +In the image below, we map a point from one surface to another using UV coordinates. We'll use this concept to create a panelized surface which references curves in the XY plane. We'll create quad panels for our panelization here, but using the same logic, we can create a wide variety of panels with UV mapping. This is a great opportunity for custom node development because we will be able to repeat a similar process more easily in this graph or in other Dynamo workflows. + +![](images/9-2/uvMap2-01-01.jpg) + +### Creating a Custom Node from an Existing Graph + +> Download and unzip the example files for this exercise (Right click and choose "Save Link As..."). A full list of example files can be found in the Appendix. [UV-CustomNode.zip](datasets/9-2/UV-CustomNode.zip) + +Let’s start by creating a graph that we want to nest into a custom node. In this example, we will create a graph that maps polygons from a base surface to a target surface, using UV coordinates. This UV mapping process is something we use frequently, making it a good candidate for a custom node. For more information on surfaces and UV space, see section 5.5. The complete graph is *UVmapping_Custom-Node.dyn* from the .zip file downloaded above. + +![Exercise](images/9-2/UVmapping01.png) +> 1. **Code Block:** Create a range of 10 numbers between 45 and negative 45 using a code block. +2. **Point.ByCoordinates:** Connect the output of the Code Block to the ‘x’ and ‘y’ inputs and set the lacing to cross-reference. You should now have a grid of points. +3. **Plane.ByOriginNormal:** Connect the *‘Point’* output to the *‘origin’* input to create a plane at each of the points. The default normal vector of (0,0,1) will be used. +4. **Rectangle.ByWidthLength:** Connect the planes from the previous step into the *‘plane’* input, and use a Code Block with a value of *10* to specify the width and length. + +You should now see a grid of rectangles. Let’s map these rectangles to a target surface using UV coordinates. + +![Exercise](images/9-2/UVmapping02.png) +>1. **Polygon.Points:** Connect the Rectangle output from the previous step to the *‘polygon’* input to extract the corner points of each rectangle. These are the points that we will map to the target surface. +2. **Rectangle.ByWidthLength:** Use a Code Block with a value of *100* to specify the width and length of a rectangle. This will be the boundary of our base surface. +3. **Surface.ByPatch:** Connect the Rectangle from the previous step to the *‘closedCurve’* input to create a base surface. +4. **Surface.UVParameterAtPoint:** Connect the *‘Point’* output of the *Polygon.Points* node and the *‘Surface’* output of the *Surface.ByPatch* node to return the UV parameter at each point. + +Now that we have a base surface and a set of UV coordinates, we can import a target surface and map the points between surfaces. + +![Exercise](images/9-2/UVmapping03.png) +>1. **File Path:** Select the file path of the surface you want to import. The file type should be .SAT. Click the *"Browse..."* button and navigate to the *UVmapping_srf.sat* file from the .zip file downloaded above. +2. **Geometry.ImportFromSAT:** Connect the file path to import the surface. You should see the imported surface in the geometry preview. +3. **UV:** Connect the UV parameter output to a *UV.U* and a *UV.V* node. +4. **Surface.PointAtParameter:** Connect the imported surface as well as the u and v coordinates. You should now see a grid of 3D points on the target surface. + +The final step is to use the 3D points to construct rectangular surface patches. + +![Exercise](images/9-2/UVmapping04.png) +>1. **PolyCurve.ByPoints:** Connect the points on the surface to construct a polycurve through the points. +2. **Boolean:** Add a Boolean to the workspace and connect it to the *‘connectLastToFirst’* input and toggle to True to close the polycurves. You should now see rectangles mapped to the surface. +3. **Surface.ByPatch:** Connect the polycurves to the *‘closedCurve’* input to construct surface patches. + +Now let’s select the nodes that we want to nest into a Custom Node, thinking about what we want to be the inputs and outputs of our node. We want our Custom Node to be as flexible as possible, so it should be able to map any polygons, not just rectangles. + +![Exercise](images/9-2/UVmapping05.png) +> Select the above nodes (beginning with *Polygon.Points*), right click on the workspace and select *‘node from selection’*. + +![Exercise](images/9-2/UVmapping06.png) +> In the Custom Node Properties dialog, assign a name, description, and category to the Custom Node. + +![Exercise](images/9-2/UVmapping07.png) +> The Custom Node has considerably cleaned up the workspace. Notice that the inputs and outputs have been named based on the original nodes. Let’s edit the Custom Node to make the names more descriptive. + +![Exercise](images/9-2/UVmapping08.png) +> Double click the Custom Node to edit it. This will open a workspace with a yellow background representing the inside of the node. +1. **Inputs:** Change the input names to *baseSurface* and *targetSurface*. +2. **Outputs:** Add an additional output for the mapped polygons. + +>Save the custom node and return to the home workspace. + +![Exercise](images/9-2/UVmapping09.png) +> The **MapPolygonsToSurface** node reflects the changes we just made. + +We can also add to the robustness of the Custom Node by adding in **Custom Comments**. Comments can help to hint at the input and output types or explain the functionality of the node. Comments will appear when the user hovers over an input or output of a Custom Node. + +![Custom Comment](images/9-2/UVmapping_Custom1.jpg) +> Double click the Custom Node to edit it. This will re-open the yellow background workspace. +1. Begin editing the Input Code Block. To start a Comment, type "//" followed by the comment text. Type anything that may help to clarify the Node - Here we will describe the *targetSurface*. +2. Let's also set the default value for the *inputSurface* by setting the input type equal to a value. Here, we will set the default value to the original Surface.ByPatch set. + +![Custom Comment](images/9-2/UVmapping_Custom1_.jpg) +> Comments can also be applied to the Outputs. Begin editing the text in the Output Code Block. To start a Comment, type "//" followed by the comment text. Here we will clarify the *Polygons* and the *surfacePatches* Outputs by adding a more in-depth description. + + +![Custom Comment](images/9-2/UVmapping_Custom2.jpg) +> +1. Hover over the Custom Node Inputs to see the Comments. +2. With the default value set on our *inputSurface*, we can also run the definition without a surface input. diff --git a/09_Custom-Nodes/9-3_Library.md b/09_Custom-Nodes/9-3_Library.md index 16942fbd..7d1a3cab 100644 --- a/09_Custom-Nodes/9-3_Library.md +++ b/09_Custom-Nodes/9-3_Library.md @@ -1,39 +1,39 @@ - - -##Adding to Your Library -We've just created a custom node and applied it to a specific process in our Dynamo graph. And we like this node so much, we want to keep it in our Dynamo library to reference in other graphs. To do this, we'll publish the node locally. This is a similar process to publishing a package, which we'll walk through in more detail in the next chapter. - -###Publishing a Custom Node Locally -Let's move forward with the custom node that we created in the previous section. By publishing a node locally, the node will be accessible in your Dynamo library when you open a new session. Without publishing a node, a Dynamo graph which references a custom node must also have that custom node in its folder (or the custom node must be imported into Dynamo using *File>Import Library*). - ->Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [PointsToSurface.dyf](datasets/9-3/PointsToSurface.dyf) - -![](images/9-3/AddingToLibrary- 05.png) -> After opening the PointsToSurface custom node, we see the graph above in the Dynamo Custom Node Editor. You can also open up a custom node by double clicking on it in the Dynamo Graph Editor. - -![](images/9-3/AddingToLibrary- 04.png) -> 1. To Publish a custom node locally, simply right click on the canvas and select *"Publish This Custom Node..."* - -![](images/9-3/AddingToLibrary- 03.png) -> Fill out the relevant information similar to the image above and select *"Publish Locally".*. Note that the Group field defines the main element accessible from the Dynamo menu. - -![](images/9-3/AddingToLibrary- 02.png) -> Choose a folder to house all of the custom nodes that you plan on publishing locally. Dynamo will check this folder each time it loads, so make sure the folder is in a permanent place. Navigate to this folder and choose *"Select Folder".* Your Dynamo node is now published locally, and will remain in your Dynamo Toolbar each time you load the program! - -![](images/9-3/AddingToLibrary- 01.png) -> 1. To check on the custom node folder location, go to *Settings > Manage Node and Package Paths...* - -![](images/9-3/AddingToLibrary- 00.png) -> In this window we see two paths: *AppData\Roaming\Dynamo...* refers to the default location of Dynamo Packages installed online. *Documents\DynamoCustomNodes...* refers to the location of custom nodes we've published locally. * -1. You may want to move your local folder path down in the list order above (by selecting the folder path and clicking on the down arrow to the left of the path names). The top folder is the default path for package installs. So by keeping the default Dynamo package install path as the default folder, online packages will be separated from your locally published nodes.* - -![](images/9-3/AddingToLibrary- 00A.png) -> We switched the order of the path names in order to have Dynamo's default path as the package install location. - -![](images/9-3/AddingToLibrary- 06.png) -> Navigating to this local folder, we can find the original custom node in the *".dyf"* folder, which is the extension for a Dynamo Custom Node file. We can edit the file in this folder and the node will update in the UI. We can also add more nodes to the main *DynamoCustomNode* folder and Dynamo will add them to your library at restart! - -![](images/9-3/library.png) + + +##Adding to Your Library +We've just created a custom node and applied it to a specific process in our Dynamo graph. And we like this node so much, we want to keep it in our Dynamo library to reference in other graphs. To do this, we'll publish the node locally. This is a similar process to publishing a package, which we'll walk through in more detail in the next chapter. + +###Publishing a Custom Node Locally +Let's move forward with the custom node that we created in the previous section. By publishing a node locally, the node will be accessible in your Dynamo library when you open a new session. Without publishing a node, a Dynamo graph which references a custom node must also have that custom node in its folder (or the custom node must be imported into Dynamo using *File>Import Library*). + +>Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [PointsToSurface.dyf](datasets/9-3/PointsToSurface.dyf) + +![](images/9-3/AddingToLibrary- 05.png) +> After opening the PointsToSurface custom node, we see the graph above in the Dynamo Custom Node Editor. You can also open up a custom node by double clicking on it in the Dynamo Graph Editor. + +![](images/9-3/AddingToLibrary- 04.png) +> 1. To Publish a custom node locally, simply right click on the canvas and select *"Publish This Custom Node..."* + +![](images/9-3/AddingToLibrary- 03.png) +> Fill out the relevant information similar to the image above and select *"Publish Locally".*. Note that the Group field defines the main element accessible from the Dynamo menu. + +![](images/9-3/AddingToLibrary- 02.png) +> Choose a folder to house all of the custom nodes that you plan on publishing locally. Dynamo will check this folder each time it loads, so make sure the folder is in a permanent place. Navigate to this folder and choose *"Select Folder".* Your Dynamo node is now published locally, and will remain in your Dynamo Toolbar each time you load the program! + +![](images/9-3/AddingToLibrary- 01.png) +> 1. To check on the custom node folder location, go to *Settings > Manage Node and Package Paths...* + +![](images/9-3/AddingToLibrary- 00.png) +> In this window we see two paths: *AppData\Roaming\Dynamo...* refers to the default location of Dynamo Packages installed online. *Documents\DynamoCustomNodes...* refers to the location of custom nodes we've published locally. * +1. You may want to move your local folder path down in the list order above (by selecting the folder path and clicking on the down arrow to the left of the path names). The top folder is the default path for package installs. So by keeping the default Dynamo package install path as the default folder, online packages will be separated from your locally published nodes.* + +![](images/9-3/AddingToLibrary- 00A.png) +> We switched the order of the path names in order to have Dynamo's default path as the package install location. + +![](images/9-3/AddingToLibrary- 06.png) +> Navigating to this local folder, we can find the original custom node in the *".dyf"* folder, which is the extension for a Dynamo Custom Node file. We can edit the file in this folder and the node will update in the UI. We can also add more nodes to the main *DynamoCustomNode* folder and Dynamo will add them to your library at restart! + +![](images/9-3/library.png) > Dynamo will now load each time with *"PointsToSurface"* in the *"DynamoPrimer"* group of your Dynamo library. \ No newline at end of file diff --git a/09_Custom-Nodes/9-4_Python.md b/09_Custom-Nodes/9-4_Python.md index c3fb9c54..e8815737 100644 --- a/09_Custom-Nodes/9-4_Python.md +++ b/09_Custom-Nodes/9-4_Python.md @@ -1,221 +1,221 @@ - - -##Python -![](images/9-4/pythonlogo.png) -Python is a widely used programming language whose popularity has a lot to do with its style of syntax. It's highly readable, which makes it easier to learn than many other languages. Python supports modules and packages, and can be embedded into existing applications. The examples in this section assume a basic familiarity with Python. For information about how to get up and running with Python, a good resource is the ["Getting Started"](https://www.python.org/about/gettingstarted/) page on [Python.org](https://www.python.org/). - -###Visual vs. Textual Programming -Why would you use textual programming in Dynamo's visual programming environment? As we discussed in chapter 1.1, visual programming has many advantages. It allows you to create programs without learning special syntax in an intuitive visual interface. However, a visual program can become cluttered, and can at times fall short in functionality. For example, Python offers much more achieveable methods for writing conditional statements (if/then) and looping. Python is a powerful tool that can extend the capabilities of Dynamo and allow you to replace many nodes with a few concise lines of code. - -**Visual Program:** -![](images/9-4/python-nodes.png) - -**Textual Program:** -``` -import clr -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * - -solid = IN[0] -seed = IN[1] -xCount = IN[2] -yCount = IN[3] - -solids = [] - -yDist = solid.BoundingBox.MaxPoint.Y-solid.BoundingBox.MinPoint.Y -xDist = solid.BoundingBox.MaxPoint.X-solid.BoundingBox.MinPoint.X - -for i in xRange: - for j in yRange: - fromCoord = solid.ContextCoordinateSystem - toCoord = fromCoord.Rotate(solid.ContextCoordinateSystem.Origin,Vector.ByCoordinates(0,0,1),(90*(i+j%val))) - vec = Vector.ByCoordinates((xDist*i),(yDist*j),0) - toCoord = toCoord.Translate(vec) - solids.append(solid.Transform(fromCoord,toCoord)) - -OUT = solids -``` - -###The Python Node -Like code blocks, Python nodes are a scripting interface within a visual programming environment. -The Python node can be found under *Core>Scripting* in the library. Double clicking the node opens the python script editor (you can also right click on the node and select *Edit...*). - -![Script Editor](images/9-4/Exercise/Python/python04.png) - -> You’ll notice some boilerplate text at the top, which is meant to help you reference the libraries you’ll need. Inputs are stored in the IN array. Values are returned to Dynamo by assigning them to the OUT variable. - -The Autodesk.DesignScript.Geometry library allows you to use dot notation similar to Code Blocks. For more information on Dynamo syntax, refer to chapter 7.2 as well as the [DesignScript Guide](http://dynamobim.org/wp-content/uploads/forum-assets/colin-mccroneautodesk-com/07/10/Dynamo_language_guide_version_1.pdf). Typing a geometry type such as 'Point.' will bring up a list of methods for creating and querying points. - -![](images/9-4/Exercise/Python/python14.png) - -> Methods include constructors such as *ByCoordinates*, actions like *Add*, and queries like *X*, *Y* and *Z* coordinates. - - -###Exercise - ->Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Python_Custom-Node.dyn](datasets/9-4/Python-CustomNode.dyn) - -In this example, we will write a python script that creates patterns from a solid module, and turn it into a custom node. -First, let’s create our solid module using Dynamo nodes. - -![](images/9-4/Exercise/Python/python01.png) - -> 1. **Rectangle.ByWidthLength:** Create a rectangle that will be the base of our solid. -2. **Surface.ByPatch:** Connect the rectangle to the ‘*closedCurve*’ input to create the bottom surface. - -![](images/9-4/Exercise/Python/python02.png) ->1. **Geometry.Translate:** Connect the rectangle to the ‘*geometry*’ input to move it up, using a code block to specify the base thickness of our solid. -2. **Polygon.Points:** Query the translated rectangle to extract the corner points. -3. **Geometry.Translate:** Use a code block to create a list of four values corresponding to the four points, translating one corner of the solid up. -4. **Polygon.ByPoints:** Use the translated points to reconstruct the top polygon. -5. **Surface.ByPatch:** Connect the polygon to create the top surface. - -Now that we have our top and bottom surfaces, let’s loft between the two profiles to create the sides of the solid. - -![](images/9-4/Exercise/Python/python03.png) ->1. **List.Create:** Connect the bottom rectangle and the top polygon to the index inputs. -2. **Surface.ByLoft:** Loft the two profiles to create the sides of the solid. -3. **List.Create:** Connect the top, side, and bottom surfaces to the index inputs to create a list of surfaces. -4. **Solid.ByJoinedSurfaces:** Join the surfaces to create the solid module. - -Now that we have our solid, let’s drop a Python Script node onto the workspace. - -![](images/9-4/Exercise/Python/python05.png) -> To add additional inputs to the node, close the editor and click the + icon on the node. The inputs are named IN[0], IN[1], etc. to indicate that they represent items in a list. - -Let’s start by defining our inputs and output. Double click the node to open the python editor. - -![](images/9-4/Exercise/Python/python06.png) -``` -import clr -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * - -#The solid module to be arrayed -solid = IN[0] -#A number that determines which rotation pattern to use -seed = IN[1] -#The number of solids to array in the X and Y axes -xCount = IN[2] -yCount = IN[3] - -#Create an empty list for the arrayed solids -solids = [] - -#Assign your output to the OUT variable. -OUT = solids -``` - -This code will make more sense as we progress in the exercise. Next we need to think about what information is required in order to array our solid module. First, we will need to know the dimensions of the solid to determine the translation distance. Due to a bounding box bug, we will have to use the edge curve geometry to create a bounding box. - -![](images/9-4/Exercise/Python/python07.png) -> A look at the Python node in Dynamo. Notice that we're using the same syntax as we see in the titles of the nodes in Dynamo. The commented code is below. - -``` -import clr -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * - -#Inputs -solid = IN[0] -seed = IN[1] -xCount = IN[2] -yCount = IN[3] - -#Create an empty list for the arrayed solids -solids = [] -# Create an empty list for the edge curves -crvs = [] - -#Loop through edges and append corresponding curve geometry to the list -for edge in solid.Edges: - crvs.append(edge.CurveGeometry) - -#Get the bounding box of the curves -bbox = BoundingBox.ByGeometry(crvs) - -#Get the X and Y translation distance based on the bounding box -yDist = bbox.MaxPoint.Y-bbox.MinPoint.Y -xDist = bbox.MaxPoint.X-bbox.MinPoint.X - -#Assign your output to the OUT variable. -OUT = solids -``` - -Since we will be both translating and rotating the solid modules, let’s use the Geometry.Transform operation. By looking at the Geometry.Transform node, we know that we will need a source coordinate system and a target coordinate system to transform the solid. The source is the context coordinate system of our solid, while the target will be a different coordinate system for each arrayed module. That means we will have to loop through the x and y values to transform the coordinate system differently each time. - -![](images/9-4/Exercise/Python/python15.png) -> A look at the Python node in Dynamo. The commented code is below. - -``` -import clr -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * - -#Inputs -solid = IN[0] -seed = IN[1] -xCount = IN[2] -yCount = IN[3] - -#Create an empty list for the arrayed solids -solids = [] -# Create an empty list for the edge curves -crvs = [] - -#Loop through edges and append corresponding curve geometry to the list -for edge in solid.Edges: - crvs.append(edge.CurveGeometry) - -#Get the bounding box of the curves -bbox = BoundingBox.ByGeometry(crvs) - -#Get the X and Y translation distance based on the bounding box -yDist = bbox.MaxPoint.Y-bbox.MinPoint.Y -xDist = bbox.MaxPoint.X-bbox.MinPoint.X - -#get the source coordinate system -fromCoord = solid.ContextCoordinateSystem - -#Loop through X and Y -for i in range(xCount): - for j in range(yCount): - #Rotate and translate the coordinate system - toCoord = fromCoord.Rotate(solid.ContextCoordinateSystem.Origin,Vector.ByCoordinates(0,0,1),(90*(i+j%seed))) - vec = Vector.ByCoordinates((xDist*i),(yDist*j),0) - toCoord = toCoord.Translate(vec) - #Transform the solid from the source coord system to the target coord system and append to the list - solids.append(solid.Transform(fromCoord,toCoord)) - -``` - -![](images/9-4/Exercise/Python/python09.png) - -> Save the Python script by clicking ‘Accept Changes’ and plug the input values into the node. You should see a pattern of solids. - -![](images/9-4/Exercise/Python/python10.png) - -> Try changing the seed value to create different patterns. You can also change the parameters of the solid module itself for different effects. - -Now that we have created a useful python script, let’s save it as a custom node. Select the python script node, right-click and select ‘New Node From Selection.’ - -![](images/9-4/Exercise/Python/python11.png) - -> Assign a name, description, and category. - -This will open a new workspace in which to edit the custom node. - -![](images/9-4/Exercise/Python/python12.png) - -> 1. **Inputs:** Change the input names to be more descriptive and add data types and default values. -2. **Output:** Change the output name -Save the node as a .dyf file. - -![](images/9-4/Exercise/Python/python13.png) - -> The custom node reflects the changes we just made. - - + + +##Python +![](images/9-4/pythonlogo.png) +Python is a widely used programming language whose popularity has a lot to do with its style of syntax. It's highly readable, which makes it easier to learn than many other languages. Python supports modules and packages, and can be embedded into existing applications. The examples in this section assume a basic familiarity with Python. For information about how to get up and running with Python, a good resource is the ["Getting Started"](https://www.python.org/about/gettingstarted/) page on [Python.org](https://www.python.org/). + +###Visual vs. Textual Programming +Why would you use textual programming in Dynamo's visual programming environment? As we discussed in chapter 1.1, visual programming has many advantages. It allows you to create programs without learning special syntax in an intuitive visual interface. However, a visual program can become cluttered, and can at times fall short in functionality. For example, Python offers much more achieveable methods for writing conditional statements (if/then) and looping. Python is a powerful tool that can extend the capabilities of Dynamo and allow you to replace many nodes with a few concise lines of code. + +**Visual Program:** +![](images/9-4/python-nodes.png) + +**Textual Program:** +``` +import clr +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * + +solid = IN[0] +seed = IN[1] +xCount = IN[2] +yCount = IN[3] + +solids = [] + +yDist = solid.BoundingBox.MaxPoint.Y-solid.BoundingBox.MinPoint.Y +xDist = solid.BoundingBox.MaxPoint.X-solid.BoundingBox.MinPoint.X + +for i in xRange: + for j in yRange: + fromCoord = solid.ContextCoordinateSystem + toCoord = fromCoord.Rotate(solid.ContextCoordinateSystem.Origin,Vector.ByCoordinates(0,0,1),(90*(i+j%val))) + vec = Vector.ByCoordinates((xDist*i),(yDist*j),0) + toCoord = toCoord.Translate(vec) + solids.append(solid.Transform(fromCoord,toCoord)) + +OUT = solids +``` + +###The Python Node +Like code blocks, Python nodes are a scripting interface within a visual programming environment. +The Python node can be found under *Core>Scripting* in the library. Double clicking the node opens the python script editor (you can also right click on the node and select *Edit...*). + +![Script Editor](images/9-4/Exercise/Python/python04.png) + +> You’ll notice some boilerplate text at the top, which is meant to help you reference the libraries you’ll need. Inputs are stored in the IN array. Values are returned to Dynamo by assigning them to the OUT variable. + +The Autodesk.DesignScript.Geometry library allows you to use dot notation similar to Code Blocks. For more information on Dynamo syntax, refer to chapter 7.2 as well as the [DesignScript Guide](http://dynamobim.org/wp-content/uploads/forum-assets/colin-mccroneautodesk-com/07/10/Dynamo_language_guide_version_1.pdf). Typing a geometry type such as 'Point.' will bring up a list of methods for creating and querying points. + +![](images/9-4/Exercise/Python/python14.png) + +> Methods include constructors such as *ByCoordinates*, actions like *Add*, and queries like *X*, *Y* and *Z* coordinates. + + +###Exercise + +>Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Python_Custom-Node.dyn](datasets/9-4/Python-CustomNode.dyn) + +In this example, we will write a python script that creates patterns from a solid module, and turn it into a custom node. +First, let’s create our solid module using Dynamo nodes. + +![](images/9-4/Exercise/Python/python01.png) + +> 1. **Rectangle.ByWidthLength:** Create a rectangle that will be the base of our solid. +2. **Surface.ByPatch:** Connect the rectangle to the ‘*closedCurve*’ input to create the bottom surface. + +![](images/9-4/Exercise/Python/python02.png) +>1. **Geometry.Translate:** Connect the rectangle to the ‘*geometry*’ input to move it up, using a code block to specify the base thickness of our solid. +2. **Polygon.Points:** Query the translated rectangle to extract the corner points. +3. **Geometry.Translate:** Use a code block to create a list of four values corresponding to the four points, translating one corner of the solid up. +4. **Polygon.ByPoints:** Use the translated points to reconstruct the top polygon. +5. **Surface.ByPatch:** Connect the polygon to create the top surface. + +Now that we have our top and bottom surfaces, let’s loft between the two profiles to create the sides of the solid. + +![](images/9-4/Exercise/Python/python03.png) +>1. **List.Create:** Connect the bottom rectangle and the top polygon to the index inputs. +2. **Surface.ByLoft:** Loft the two profiles to create the sides of the solid. +3. **List.Create:** Connect the top, side, and bottom surfaces to the index inputs to create a list of surfaces. +4. **Solid.ByJoinedSurfaces:** Join the surfaces to create the solid module. + +Now that we have our solid, let’s drop a Python Script node onto the workspace. + +![](images/9-4/Exercise/Python/python05.png) +> To add additional inputs to the node, close the editor and click the + icon on the node. The inputs are named IN[0], IN[1], etc. to indicate that they represent items in a list. + +Let’s start by defining our inputs and output. Double click the node to open the python editor. + +![](images/9-4/Exercise/Python/python06.png) +``` +import clr +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * + +#The solid module to be arrayed +solid = IN[0] +#A number that determines which rotation pattern to use +seed = IN[1] +#The number of solids to array in the X and Y axes +xCount = IN[2] +yCount = IN[3] + +#Create an empty list for the arrayed solids +solids = [] + +#Assign your output to the OUT variable. +OUT = solids +``` + +This code will make more sense as we progress in the exercise. Next we need to think about what information is required in order to array our solid module. First, we will need to know the dimensions of the solid to determine the translation distance. Due to a bounding box bug, we will have to use the edge curve geometry to create a bounding box. + +![](images/9-4/Exercise/Python/python07.png) +> A look at the Python node in Dynamo. Notice that we're using the same syntax as we see in the titles of the nodes in Dynamo. The commented code is below. + +``` +import clr +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * + +#Inputs +solid = IN[0] +seed = IN[1] +xCount = IN[2] +yCount = IN[3] + +#Create an empty list for the arrayed solids +solids = [] +# Create an empty list for the edge curves +crvs = [] + +#Loop through edges and append corresponding curve geometry to the list +for edge in solid.Edges: + crvs.append(edge.CurveGeometry) + +#Get the bounding box of the curves +bbox = BoundingBox.ByGeometry(crvs) + +#Get the X and Y translation distance based on the bounding box +yDist = bbox.MaxPoint.Y-bbox.MinPoint.Y +xDist = bbox.MaxPoint.X-bbox.MinPoint.X + +#Assign your output to the OUT variable. +OUT = solids +``` + +Since we will be both translating and rotating the solid modules, let’s use the Geometry.Transform operation. By looking at the Geometry.Transform node, we know that we will need a source coordinate system and a target coordinate system to transform the solid. The source is the context coordinate system of our solid, while the target will be a different coordinate system for each arrayed module. That means we will have to loop through the x and y values to transform the coordinate system differently each time. + +![](images/9-4/Exercise/Python/python15.png) +> A look at the Python node in Dynamo. The commented code is below. + +``` +import clr +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * + +#Inputs +solid = IN[0] +seed = IN[1] +xCount = IN[2] +yCount = IN[3] + +#Create an empty list for the arrayed solids +solids = [] +# Create an empty list for the edge curves +crvs = [] + +#Loop through edges and append corresponding curve geometry to the list +for edge in solid.Edges: + crvs.append(edge.CurveGeometry) + +#Get the bounding box of the curves +bbox = BoundingBox.ByGeometry(crvs) + +#Get the X and Y translation distance based on the bounding box +yDist = bbox.MaxPoint.Y-bbox.MinPoint.Y +xDist = bbox.MaxPoint.X-bbox.MinPoint.X + +#get the source coordinate system +fromCoord = solid.ContextCoordinateSystem + +#Loop through X and Y +for i in range(xCount): + for j in range(yCount): + #Rotate and translate the coordinate system + toCoord = fromCoord.Rotate(solid.ContextCoordinateSystem.Origin,Vector.ByCoordinates(0,0,1),(90*(i+j%seed))) + vec = Vector.ByCoordinates((xDist*i),(yDist*j),0) + toCoord = toCoord.Translate(vec) + #Transform the solid from the source coord system to the target coord system and append to the list + solids.append(solid.Transform(fromCoord,toCoord)) + +``` + +![](images/9-4/Exercise/Python/python09.png) + +> Save the Python script by clicking ‘Accept Changes’ and plug the input values into the node. You should see a pattern of solids. + +![](images/9-4/Exercise/Python/python10.png) + +> Try changing the seed value to create different patterns. You can also change the parameters of the solid module itself for different effects. + +Now that we have created a useful python script, let’s save it as a custom node. Select the python script node, right-click and select ‘New Node From Selection.’ + +![](images/9-4/Exercise/Python/python11.png) + +> Assign a name, description, and category. + +This will open a new workspace in which to edit the custom node. + +![](images/9-4/Exercise/Python/python12.png) + +> 1. **Inputs:** Change the input names to be more descriptive and add data types and default values. +2. **Output:** Change the output name +Save the node as a .dyf file. + +![](images/9-4/Exercise/Python/python13.png) + +> The custom node reflects the changes we just made. + + diff --git a/09_Custom-Nodes/9-5_Python-Revit.md b/09_Custom-Nodes/9-5_Python-Revit.md index 4fc88b44..0a442cc0 100644 --- a/09_Custom-Nodes/9-5_Python-Revit.md +++ b/09_Custom-Nodes/9-5_Python-Revit.md @@ -1,183 +1,183 @@ - - -##Python and Revit - -Now that we've demonstrated how to use Python scripts in Dynamo, let's take a look at connecting Revit libraries into the scripting environment. Remember, we imported our Dynamo core nodes with the first three lines in the block of code below. To import the Revit nodes, Revit elements, and the Revit document manager, we only have to add a few more lines: - -``` -import clr -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * - -# Import RevitNodes -clr.AddReference("RevitNodes") -import Revit - -# Import Revit elements -from Revit.Elements import * - -# Import DocumentManager -clr.AddReference("RevitServices") -import RevitServices -from RevitServices.Persistence import DocumentManager - -import System -``` - -This gives us access to the Revit API and offers custom scripting for any Revit task. By combining the process of visual programming with Revit API scripting, collaboration and tool development improve significantly. For example, a BIM manager and a schematic designer can work together on the same graph. In this collaboration, they can improve design and execution of the model. - -![Exercise](images/9-4/pythonRevit.png) - -###Platform Specific APIs - -The plan behind the Dynamo Project is to widen the scope of platform implementation. As Dynamo adds more programs to the docket, users will gain access to platform-specific APIs from the Python scripting environment. While Revit is the case study for this section, we can anticipate more chapters in the future which offer comprehensive tutorials on scripting in other platforms. Additionally, there are many [IronPython](http://ironpython.net/) libraries accessible now which can be imported into Dynamo! - -The examples below demonstrate ways to implement Revit-specific operations from Dynamo using Python. For a more detailed review on Python's relationship to Dynamo and Revit, refer to the [Dynamo Wiki page](https://github.com/DynamoDS/Dynamo/wiki/Python-0.6.3-to-0.7.x-Migration). Another useful resource for Python and Revit is the [Revit Python Shell ](https://github.com/architecture-building-systems/revitpythonshell) Project. - -### Exercise 01 ->Create a new Revit Project. Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-Doc.dyn](datasets/9-5/Revit-Doc.dyn) - -In these exercises, we'll explore elementary Python scripts in Dynamo for Revit. The exercise will focus on dealing with Revit files and elements, as well as the communication between Revit and Dynamo. - -![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 10.png) -> This is a cut and dry method for retrieving the *doc*, *uiapp*, and *app* of the Revit file linked to your Dynamo sesson. Programmers who have worked in the Revit API before may notice the items in the watch list. If these items do not look familiar, that's okay; we'll be using other examples in the exercises below. - -Here is how we're importing Revit Services and retrieving the document data in Dynamo: -![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 06.png) -> A look at the Python node in Dynamo. The commented code is below. - -``` -import clr -# Import DocumentManager -clr.AddReference("RevitServices") -import RevitServices -from RevitServices.Persistence import DocumentManager - -doc = DocumentManager.Instance.CurrentDBDocument -uiapp = DocumentManager.Instance.CurrentUIApplication -app = uiapp.Application - -#Assign your output to the OUT variable -#OUT is defined as a list of three items -OUT=[doc,uiapp,app] -``` - - -### Exercise 02 ->Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-ReferenceCurve.dyn](datasets/9-5/Revit-ReferenceCurve.dyn) - -In this exercise, we'll make a simple Model Curve in Revit using the Dynamo Python node. - -![](images/9-4/Exercise/Revit/Images/RevitPython - 08.png) - -> Begin with the set of nodes in the image above. We'll first create two reference points in Revit from Dynamo nodes. - -> Begin by creating a new Conceptual Mass family in Revit. Launch Dynamo and create the set of nodes in the image above. We'll first create two reference point in Revit from Dynamo nodes. -1. **Important note - when performing Revit operations, be certain that the run mode has been set to "Manual". Otherwise the program will crash.** -2. Create a code block and give it a value of "0;". -3. Plug this value into a ReferencePoint.ByCoordinates node for X,Y, and Z inputs. -4. Create three sliders, ranging from -100 to 100 with a step size of 1. -5. Connect each slider to a ReferencePoint.ByCoordinates node. -6. Add a Python node to the workspace, click the "+" button on the node to add another input and plug the two references points into each input. Open the Python node. - -![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 07.png) -> A look at the Python node in Dynamo. The commented code is below. -1. **System.Array:** Revit needs a System Array as an input (rather than a Python list). This is just one more line of code, but paying attention to argument types will facilitate Python programming in Revit. - -``` -import clr - -# Import RevitNodes -clr.AddReference("RevitNodes") -import Revit -# Import Revit elements -from Revit.Elements import * -import System - -#define inputs -startRefPt = IN[0] -endRefPt = IN[1] - -#define system array to match with required inputs -refPtArray = System.Array[ReferencePoint]([startRefPt, endRefPt]) -#create curve by reference points in Revit -OUT = CurveByPoints.ByReferencePoints(refPtArray) - -``` - -![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 09.png) -> From Dynamo, we've created two reference points with a line connecting them using Python. Let's take this a little further in the next exercise. - -### Exercise 03 ->Download and unzip the example files that accompany this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-StructuralFraming.zip](datasets/9-5/Revit-StructuralFraming.zip) - ->This exercise keeps it simple, but drives home the topics of connecting data and geometry from Revit to Dynamo and back. Let's begin by opening Revit-StructuralFraming.rvt. Once opened, load Dynamo and open the file Revit-StructuralFraming.dyn. - -![](images/9-4/Exercise/Revit/Images/RevitPython - 04.png) -> This Revit file is about as basic as it gets. Two reference curves: one drawn on Level 1 and the other drawn on Level 2. We want to get these curves into Dynamo and maintain a live link. - -![](images/9-4/Exercise/Revit/Images/RevitPython - 01a.png) -> In this file we have a set of nodes plugging into five inputs of a Python node. -1. **Select Model Element Nodes:** Hit the select button for each and select a corresponding curve in Revit. -2. **Code Block:** using the syntax *"0..1..#x;"*, connect an integer slider ranging from 0 to 20 into the *x* input. This designates the number of beams to draw between the two curves. -3. **Structural Framing Types:** We'll choose the default W12x26 beam here from the dropdown menu. -4. **Levels:** select "Level 1". - -![](images/9-4/Exercise/Revit/Images/RevitPython - 00.png) -> This code in Python is a little more dense, but the comments within the code describe what's happening in the process: - -``` -import clr -#import Dynamo Geometry -clr.AddReference('ProtoGeometry') -from Autodesk.DesignScript.Geometry import * -# Import RevitNodes -clr.AddReference("RevitNodes") -import Revit -# Import Revit elements -from Revit.Elements import * -import System - -#Query Revit elements and convert them to Dynamo Curves -crvA=IN[0].Curves[0] -crvB=IN[1].Curves[0] - -#Define input Parameters -framingType=IN[3] -designLevel=IN[4] - -#Define "out" as a list -OUT=[] - -for val in IN[2]: - #Define Dynamo Points on each curve - ptA=Curve.PointAtParameter(crvA,val) - ptB=Curve.PointAtParameter(crvB,val) - #Create Dynamo line - beamCrv=Line.ByStartPointEndPoint(ptA,ptB) - #create Revit Element from Dynamo Curves - beam = StructuralFraming.BeamByCurve(beamCrv,designLevel,framingType) - #convert Revit Element into list of Dynamo Surfaces - OUT.append(beam.Faces) - -``` -![](images/9-4/Exercise/Revit/Images/RevitPython - 03.png) -> In Revit, we have an array of beams spanning the two curves as structural elements. Note: this isn't a realistic example...the structural elements are used as an example for native Revit instances created from Dynamo. -![](images/9-4/Exercise/Revit/Images/RevitPython - 05.png) -> In Dynamo, we can see the results as well. The beams in the Watch3D node refer to the geometry queried from the Revit elements. - -Notice that we have a continuous process of translating data from the Revit Environment to the Dynamo Environment. In summary, here's how the process plays out: - -1. Select Revit element -2. Convert Revit element to Dynamo Curve -3. Divide Dynamo curve into a series of Dynamo points -4. Use the Dynamo points between two curves to create Dynamo lines -5. Create Revit beams by referencing Dynamo lines -6. Output Dynamo surfaces by querying the geometry of Revit beams - -This may sound a little heavy handed, but the script makes it as simple as editing the curve in Revit and re-running the solver (although you may have to delete the previous beams when doing so). - -![](images/9-4/Exercise/Revit/Images/RevitPython - 01.png) -> With an update to the reference curves in Revit, we get a new array of beams. + + +##Python and Revit + +Now that we've demonstrated how to use Python scripts in Dynamo, let's take a look at connecting Revit libraries into the scripting environment. Remember, we imported our Dynamo core nodes with the first three lines in the block of code below. To import the Revit nodes, Revit elements, and the Revit document manager, we only have to add a few more lines: + +``` +import clr +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * + +# Import RevitNodes +clr.AddReference("RevitNodes") +import Revit + +# Import Revit elements +from Revit.Elements import * + +# Import DocumentManager +clr.AddReference("RevitServices") +import RevitServices +from RevitServices.Persistence import DocumentManager + +import System +``` + +This gives us access to the Revit API and offers custom scripting for any Revit task. By combining the process of visual programming with Revit API scripting, collaboration and tool development improve significantly. For example, a BIM manager and a schematic designer can work together on the same graph. In this collaboration, they can improve design and execution of the model. + +![Exercise](images/9-4/pythonRevit.png) + +###Platform Specific APIs + +The plan behind the Dynamo Project is to widen the scope of platform implementation. As Dynamo adds more programs to the docket, users will gain access to platform-specific APIs from the Python scripting environment. While Revit is the case study for this section, we can anticipate more chapters in the future which offer comprehensive tutorials on scripting in other platforms. Additionally, there are many [IronPython](http://ironpython.net/) libraries accessible now which can be imported into Dynamo! + +The examples below demonstrate ways to implement Revit-specific operations from Dynamo using Python. For a more detailed review on Python's relationship to Dynamo and Revit, refer to the [Dynamo Wiki page](https://github.com/DynamoDS/Dynamo/wiki/Python-0.6.3-to-0.7.x-Migration). Another useful resource for Python and Revit is the [Revit Python Shell ](https://github.com/architecture-building-systems/revitpythonshell) Project. + +### Exercise 01 +>Create a new Revit Project. Download the example file that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-Doc.dyn](datasets/9-5/Revit-Doc.dyn) + +In these exercises, we'll explore elementary Python scripts in Dynamo for Revit. The exercise will focus on dealing with Revit files and elements, as well as the communication between Revit and Dynamo. + +![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 10.png) +> This is a cut and dry method for retrieving the *doc*, *uiapp*, and *app* of the Revit file linked to your Dynamo sesson. Programmers who have worked in the Revit API before may notice the items in the watch list. If these items do not look familiar, that's okay; we'll be using other examples in the exercises below. + +Here is how we're importing Revit Services and retrieving the document data in Dynamo: +![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 06.png) +> A look at the Python node in Dynamo. The commented code is below. + +``` +import clr +# Import DocumentManager +clr.AddReference("RevitServices") +import RevitServices +from RevitServices.Persistence import DocumentManager + +doc = DocumentManager.Instance.CurrentDBDocument +uiapp = DocumentManager.Instance.CurrentUIApplication +app = uiapp.Application + +#Assign your output to the OUT variable +#OUT is defined as a list of three items +OUT=[doc,uiapp,app] +``` + + +### Exercise 02 +>Download the example files that accompanies this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-ReferenceCurve.dyn](datasets/9-5/Revit-ReferenceCurve.dyn) + +In this exercise, we'll make a simple Model Curve in Revit using the Dynamo Python node. + +![](images/9-4/Exercise/Revit/Images/RevitPython - 08.png) + +> Begin with the set of nodes in the image above. We'll first create two reference points in Revit from Dynamo nodes. + +> Begin by creating a new Conceptual Mass family in Revit. Launch Dynamo and create the set of nodes in the image above. We'll first create two reference point in Revit from Dynamo nodes. +1. **Important note - when performing Revit operations, be certain that the run mode has been set to "Manual". Otherwise the program will crash.** +2. Create a code block and give it a value of "0;". +3. Plug this value into a ReferencePoint.ByCoordinates node for X,Y, and Z inputs. +4. Create three sliders, ranging from -100 to 100 with a step size of 1. +5. Connect each slider to a ReferencePoint.ByCoordinates node. +6. Add a Python node to the workspace, click the "+" button on the node to add another input and plug the two references points into each input. Open the Python node. + +![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 07.png) +> A look at the Python node in Dynamo. The commented code is below. +1. **System.Array:** Revit needs a System Array as an input (rather than a Python list). This is just one more line of code, but paying attention to argument types will facilitate Python programming in Revit. + +``` +import clr + +# Import RevitNodes +clr.AddReference("RevitNodes") +import Revit +# Import Revit elements +from Revit.Elements import * +import System + +#define inputs +startRefPt = IN[0] +endRefPt = IN[1] + +#define system array to match with required inputs +refPtArray = System.Array[ReferencePoint]([startRefPt, endRefPt]) +#create curve by reference points in Revit +OUT = CurveByPoints.ByReferencePoints(refPtArray) + +``` + +![Exercise](images/9-4/Exercise/Revit/Images/RevitPython - 09.png) +> From Dynamo, we've created two reference points with a line connecting them using Python. Let's take this a little further in the next exercise. + +### Exercise 03 +>Download and unzip the example files that accompany this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Revit-StructuralFraming.zip](datasets/9-5/Revit-StructuralFraming.zip) + +>This exercise keeps it simple, but drives home the topics of connecting data and geometry from Revit to Dynamo and back. Let's begin by opening Revit-StructuralFraming.rvt. Once opened, load Dynamo and open the file Revit-StructuralFraming.dyn. + +![](images/9-4/Exercise/Revit/Images/RevitPython - 04.png) +> This Revit file is about as basic as it gets. Two reference curves: one drawn on Level 1 and the other drawn on Level 2. We want to get these curves into Dynamo and maintain a live link. + +![](images/9-4/Exercise/Revit/Images/RevitPython - 01a.png) +> In this file we have a set of nodes plugging into five inputs of a Python node. +1. **Select Model Element Nodes:** Hit the select button for each and select a corresponding curve in Revit. +2. **Code Block:** using the syntax *"0..1..#x;"*, connect an integer slider ranging from 0 to 20 into the *x* input. This designates the number of beams to draw between the two curves. +3. **Structural Framing Types:** We'll choose the default W12x26 beam here from the dropdown menu. +4. **Levels:** select "Level 1". + +![](images/9-4/Exercise/Revit/Images/RevitPython - 00.png) +> This code in Python is a little more dense, but the comments within the code describe what's happening in the process: + +``` +import clr +#import Dynamo Geometry +clr.AddReference('ProtoGeometry') +from Autodesk.DesignScript.Geometry import * +# Import RevitNodes +clr.AddReference("RevitNodes") +import Revit +# Import Revit elements +from Revit.Elements import * +import System + +#Query Revit elements and convert them to Dynamo Curves +crvA=IN[0].Curves[0] +crvB=IN[1].Curves[0] + +#Define input Parameters +framingType=IN[3] +designLevel=IN[4] + +#Define "out" as a list +OUT=[] + +for val in IN[2]: + #Define Dynamo Points on each curve + ptA=Curve.PointAtParameter(crvA,val) + ptB=Curve.PointAtParameter(crvB,val) + #Create Dynamo line + beamCrv=Line.ByStartPointEndPoint(ptA,ptB) + #create Revit Element from Dynamo Curves + beam = StructuralFraming.BeamByCurve(beamCrv,designLevel,framingType) + #convert Revit Element into list of Dynamo Surfaces + OUT.append(beam.Faces) + +``` +![](images/9-4/Exercise/Revit/Images/RevitPython - 03.png) +> In Revit, we have an array of beams spanning the two curves as structural elements. Note: this isn't a realistic example...the structural elements are used as an example for native Revit instances created from Dynamo. +![](images/9-4/Exercise/Revit/Images/RevitPython - 05.png) +> In Dynamo, we can see the results as well. The beams in the Watch3D node refer to the geometry queried from the Revit elements. + +Notice that we have a continuous process of translating data from the Revit Environment to the Dynamo Environment. In summary, here's how the process plays out: + +1. Select Revit element +2. Convert Revit element to Dynamo Curve +3. Divide Dynamo curve into a series of Dynamo points +4. Use the Dynamo points between two curves to create Dynamo lines +5. Create Revit beams by referencing Dynamo lines +6. Output Dynamo surfaces by querying the geometry of Revit beams + +This may sound a little heavy handed, but the script makes it as simple as editing the curve in Revit and re-running the solver (although you may have to delete the previous beams when doing so). + +![](images/9-4/Exercise/Revit/Images/RevitPython - 01.png) +> With an update to the reference curves in Revit, we get a new array of beams. diff --git a/09_Custom-Nodes/9_Custom-Nodes.md b/09_Custom-Nodes/9_Custom-Nodes.md index 32cb7c89..7b294e36 100644 --- a/09_Custom-Nodes/9_Custom-Nodes.md +++ b/09_Custom-Nodes/9_Custom-Nodes.md @@ -1,5 +1,5 @@ -# Custom Nodes - -Out of the box, Dynamo has a lot of functionality stored in its Library of Nodes. For those frequently used routines or that special graph you want to share with the community, Custom Nodes are a great way to extend Dynamo even further. - -![IMAGE](images/9/customNodes_cover01.png) +# Custom Nodes + +Out of the box, Dynamo has a lot of functionality stored in its Library of Nodes. For those frequently used routines or that special graph you want to share with the community, Custom Nodes are a great way to extend Dynamo even further. + +![IMAGE](images/9/customNodes_cover01.png) diff --git a/09_Custom-Nodes/datasets/9-2/MapPolygonsToSurface.dyf b/09_Custom-Nodes/datasets/9-2/MapPolygonsToSurface.dyf index 8d77724a..a01b10b2 100644 --- a/09_Custom-Nodes/datasets/9-2/MapPolygonsToSurface.dyf +++ b/09_Custom-Nodes/datasets/9-2/MapPolygonsToSurface.dyf @@ -1,69 +1,69 @@ - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-2/UVmapping_Custom-Node.dyn b/09_Custom-Nodes/datasets/9-2/UVmapping_Custom-Node.dyn index 8f2027ac..e7c8ad14 100644 --- a/09_Custom-Nodes/datasets/9-2/UVmapping_Custom-Node.dyn +++ b/09_Custom-Nodes/datasets/9-2/UVmapping_Custom-Node.dyn @@ -1,105 +1,105 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\UVmapping_srf.sat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\UVmapping_srf.sat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-2/UVmapping_srf.sat b/09_Custom-Nodes/datasets/9-2/UVmapping_srf.sat index 91586fb7..246fc5c1 100644 --- a/09_Custom-Nodes/datasets/9-2/UVmapping_srf.sat +++ b/09_Custom-Nodes/datasets/9-2/UVmapping_srf.sat @@ -1,279 +1,279 @@ -700 0 1 0 -4 LibG 19 ASM 219.0.0.5600 NT 24 Wed Sep 16 15:26:33 2015 -1000 9.9999999999999995e-007 1e-010 -body $-1 -1 $-1 $1 $-1 $-1 # -lump $-1 -1 $-1 $-1 $2 $0 # -shell $-1 -1 $-1 $-1 $-1 $3 $-1 $1 # -face $-1 -1 $-1 $-1 $4 $2 $-1 $5 forward double out # -loop $-1 -1 $-1 $-1 $6 $3 # -spline-surface $-1 -1 $-1 forward { exactsur full nubs 3 3 open open none none 8 8 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 95.998851476614703 -46.291405132247149 -4.7254435371388164 - 95.998851476614703 -44.09049474484658 -6.6337010245266654 - 95.998851476614689 -38.302222155948904 -8.6323588745761288 - 95.998851476614689 -24.999999999999986 -7.5911689942537413 - 95.998851476614689 -8.6824088833465183 -2.9979867750741973 - 95.998851476614689 8.6824088833465183 2.9979867750741973 - 95.998851476614689 25.000000000000011 7.5911689942537475 - 95.998851476614689 38.302222155948911 8.6323588745761288 - 95.998851476614689 44.09049474484658 6.6337010245266654 - 95.998851476614689 46.291405132247149 4.7254435371388164 - 103.27105669325775 -46.291405132247149 -7.2286775549284696 - 103.27105669325775 -44.09049474484658 -10.147806301191494 - 103.27105669325773 -38.302222155948904 -13.2052236689127 - 103.27105669325773 -24.999999999999986 -11.612478806096661 - 103.27105669325773 -8.6824088833465183 -4.5861260515818127 - 103.27105669325773 8.6824088833465183 4.5861260515818127 - 103.27105669325773 25.000000000000011 11.61247880609667 - 103.27105669325773 38.302222155948911 13.2052236689127 - 103.27105669325773 44.09049474484658 10.147806301191494 - 103.27105669325773 46.291405132247149 7.2286775549284696 - 114.90658503988658 -46.291405132247142 -12.797194587388756 - 114.90658503988658 -44.09049474484658 -17.965035912127128 - 114.90658503988658 -38.302222155948904 -23.377694685779865 - 114.90658503988658 -24.999999999999982 -20.557999688646696 - 114.90658503988658 -8.6824088833465183 -8.1189881604791125 - 114.90658503988658 8.6824088833465183 8.1189881604791125 - 114.90658503988658 25.000000000000011 20.557999688646706 - 114.90658503988658 38.302222155948911 23.377694685779865 - 114.90658503988658 44.09049474484658 17.965035912127128 - 114.90658503988658 46.291405132247142 12.797194587388756 - 132.3598775598299 -46.291405132247142 -15.162020563664511 - 132.3598775598299 -44.09049474484658 -21.284840366112061 - 132.3598775598299 -38.302222155948904 -27.697718053468346 - 132.3598775598299 -24.999999999999982 -24.356964481437323 - 132.3598775598299 -8.6824088833465183 -9.6193165310344302 - 132.3598775598299 8.6824088833465183 9.6193165310344302 - 132.3598775598299 25.000000000000011 24.356964481437338 - 132.3598775598299 38.302222155948911 27.69771805346835 - 132.3598775598299 44.09049474484658 21.284840366112064 - 132.3598775598299 46.291405132247142 15.162020563664512 - 149.81317007977319 -46.291405132247142 -6.8092450149740849 - 149.81317007977319 -44.09049474484658 -9.5589959497086099 - 149.81317007977316 -38.302222155948904 -12.439011528167599 - 149.81317007977316 -24.999999999999982 -10.938683157612271 - 149.81317007977316 -8.6824088833465183 -4.3200233676884832 - 149.81317007977316 8.6824088833465183 4.3200233676884832 - 149.81317007977316 25.000000000000011 10.93868315761228 - 149.81317007977316 38.302222155948911 12.439011528167599 - 149.81317007977319 44.09049474484658 9.5589959497086099 - 149.81317007977319 46.291405132247142 6.8092450149740849 - 167.26646259971648 -46.291405132247142 6.8092450149740804 - 167.26646259971648 -44.09049474484658 9.5589959497086046 - 167.26646259971648 -38.302222155948904 12.43901152816759 - 167.26646259971648 -24.999999999999982 10.938683157612266 - 167.26646259971648 -8.6824088833465183 4.3200233676884814 - 167.26646259971648 8.6824088833465183 -4.3200233676884814 - 167.26646259971648 25.000000000000011 -10.938683157612274 - 167.26646259971648 38.302222155948911 -12.43901152816759 - 167.26646259971648 44.09049474484658 -9.5589959497086046 - 167.26646259971648 46.291405132247142 -6.8092450149740804 - 184.71975511965979 -46.291405132247142 15.162020563664512 - 184.71975511965979 -44.09049474484658 21.284840366112064 - 184.71975511965979 -38.302222155948904 27.697718053468353 - 184.71975511965979 -24.999999999999982 24.356964481437331 - 184.71975511965979 -8.6824088833465183 9.6193165310344337 - 184.71975511965979 8.6824088833465183 -9.6193165310344337 - 184.71975511965979 25.000000000000011 -24.356964481437341 - 184.71975511965979 38.302222155948911 -27.697718053468353 - 184.71975511965979 44.09049474484658 -21.284840366112064 - 184.71975511965979 46.291405132247142 -15.162020563664512 - 202.17304763960311 -46.291405132247142 12.797194587388752 - 202.17304763960311 -44.09049474484658 17.965035912127124 - 202.17304763960308 -38.302222155948904 23.377694685779861 - 202.17304763960308 -24.999999999999982 20.557999688646689 - 202.17304763960308 -8.6824088833465183 8.1189881604791108 - 202.17304763960308 8.6824088833465183 -8.1189881604791108 - 202.17304763960308 25.000000000000011 -20.557999688646706 - 202.17304763960308 38.302222155948911 -23.377694685779858 - 202.17304763960308 44.09049474484658 -17.965035912127121 - 202.17304763960308 46.291405132247142 -12.79719458738875 - 213.80857598623197 -46.291405132247142 7.2286775549284696 - 213.80857598623197 -44.09049474484658 10.147806301191494 - 213.80857598623192 -38.302222155948904 13.2052236689127 - 213.80857598623192 -24.999999999999982 11.612478806096661 - 213.80857598623192 -8.6824088833465183 4.5861260515818127 - 213.80857598623192 8.6824088833465183 -4.5861260515818127 - 213.80857598623192 25.000000000000007 -11.612478806096671 - 213.80857598623192 38.302222155948911 -13.205223668912698 - 213.80857598623192 44.09049474484658 -10.147806301191492 - 213.80857598623192 46.291405132247142 -7.2286775549284696 - 221.08078120287502 -46.291405132247142 4.7254435371388173 - 221.08078120287502 -44.09049474484658 6.6337010245266663 - 221.08078120287496 -38.302222155948904 8.6323588745761288 - 221.08078120287496 -24.999999999999982 7.5911689942537421 - 221.08078120287496 -8.6824088833465183 2.9979867750741973 - 221.08078120287496 8.6824088833465183 -2.9979867750741973 - 221.08078120287496 25.000000000000007 -7.5911689942537492 - 221.08078120287496 38.302222155948911 -8.6323588745761288 - 221.08078120287496 44.09049474484658 -6.6337010245266654 - 221.08078120287496 46.291405132247142 -4.7254435371388173 - 0 - - 0 - 0 - 6 2 3 4 5 6 7 - 0 - 0 - 6 2 3 4 5 6 7 - F 1 F 0 F 1 F 0 } I I I I # -coedge $-1 -1 $-1 $7 $8 $-1 $9 forward $4 $10 # -coedge $-1 -1 $-1 $11 $6 $-1 $12 forward $4 $13 # -coedge $-1 -1 $-1 $6 $11 $-1 $14 reversed $4 $15 # -edge $-1 -1 $-1 $16 1 $17 8 $6 $18 forward @7 unknown # -pcurve $-1 -1 $-1 0 forward { exppc nubs 1 open 2 - 1 1 8 1 - 1 1 - 8 1 - 0 - spline forward { ref 0 } I I I I - } 0 0 # -coedge $-1 -1 $-1 $8 $7 $-1 $19 reversed $4 $20 # -edge $-1 -1 $-1 $17 1 $21 8 $7 $22 forward @7 unknown # -pcurve $-1 -1 $-1 0 forward { exppc nubs 1 open 2 - 1 1 8 1 - 8 1 - 8 8 - 0 - spline forward { ref 0 } I I I I - } 0 0 # -edge $-1 -1 $-1 $16 1 $23 8 $8 $24 forward @7 unknown # -pcurve $-1 -1 $-1 0 reversed { exppc nubs 1 open 2 - 1 1 8 1 - 1 1 - 1 8 - 0 - spline forward { ref 0 } I I I I - } 0 0 # -vertex $-1 -1 $-1 $14 $25 # -vertex $-1 -1 $-1 $12 $26 # -intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 95.998851476614703 -46.291405132247149 -4.7254435371388164 - 95.998851476614703 -44.09049474484658 -6.6337010245266654 - 95.998851476614689 -38.302222155948904 -8.6323588745761288 - 95.998851476614689 -24.999999999999986 -7.5911689942537413 - 95.998851476614689 -8.6824088833465183 -2.9979867750741973 - 95.998851476614689 8.6824088833465183 2.9979867750741973 - 95.998851476614689 25.000000000000011 7.5911689942537475 - 95.998851476614689 38.302222155948911 8.6323588745761288 - 95.998851476614689 44.09049474484658 6.6337010245266654 - 95.998851476614689 46.291405132247149 4.7254435371388164 - 0 - - spline forward { ref 0 } I I I I - null_surface - nubs 1 open 2 - 1 1 8 1 - 1 1 - 8 1 - - nullbs - I I - 0 - 0 - 6 2 3 4 5 6 7 - surf1 } I I # -edge $-1 -1 $-1 $23 1 $21 8 $11 $27 forward @7 unknown # -pcurve $-1 -1 $-1 0 reversed { exppc nubs 1 open 2 - 1 1 8 1 - 1 8 - 8 8 - 0 - spline forward { ref 0 } I I I I - } 0 0 # -vertex $-1 -1 $-1 $12 $28 # -intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 95.998851476614689 46.291405132247149 4.7254435371388164 - 103.27105669325773 46.291405132247149 7.2286775549284696 - 114.90658503988658 46.291405132247142 12.797194587388756 - 132.3598775598299 46.291405132247142 15.162020563664512 - 149.81317007977319 46.291405132247142 6.8092450149740849 - 167.26646259971648 46.291405132247142 -6.8092450149740804 - 184.71975511965979 46.291405132247142 -15.162020563664512 - 202.17304763960308 46.291405132247142 -12.79719458738875 - 213.80857598623192 46.291405132247142 -7.2286775549284696 - 221.08078120287496 46.291405132247142 -4.7254435371388173 - 0 - - spline forward { ref 0 } I I I I - null_surface - nubs 1 open 2 - 1 1 8 1 - 8 1 - 8 8 - - nullbs - I I - 0 - 0 - 6 2 3 4 5 6 7 - surf1 } I I # -vertex $-1 -1 $-1 $14 $29 # -intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 95.998851476614703 -46.291405132247149 -4.7254435371388164 - 103.27105669325775 -46.291405132247149 -7.2286775549284696 - 114.90658503988658 -46.291405132247142 -12.797194587388756 - 132.3598775598299 -46.291405132247142 -15.162020563664511 - 149.81317007977319 -46.291405132247142 -6.8092450149740849 - 167.26646259971648 -46.291405132247142 6.8092450149740804 - 184.71975511965979 -46.291405132247142 15.162020563664512 - 202.17304763960311 -46.291405132247142 12.797194587388752 - 213.80857598623197 -46.291405132247142 7.2286775549284696 - 221.08078120287502 -46.291405132247142 4.7254435371388173 - 0 - - spline forward { ref 0 } I I I I - null_surface - nubs 1 open 2 - 1 1 8 1 - 1 1 - 1 8 - - nullbs - I I - 0 - 0 - 6 2 3 4 5 6 7 - surf1 } I I # -point $-1 -1 $-1 95.998851476614703 -46.291405132247149 -4.7254435371388164 # -point $-1 -1 $-1 95.998851476614689 46.291405132247149 4.7254435371388164 # -intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 - 1 3 2 1 3 1 4 1 5 1 - 6 1 7 1 8 3 - 221.08078120287502 -46.291405132247142 4.7254435371388173 - 221.08078120287502 -44.09049474484658 6.6337010245266663 - 221.08078120287496 -38.302222155948904 8.6323588745761288 - 221.08078120287496 -24.999999999999982 7.5911689942537421 - 221.08078120287496 -8.6824088833465183 2.9979867750741973 - 221.08078120287496 8.6824088833465183 -2.9979867750741973 - 221.08078120287496 25.000000000000007 -7.5911689942537492 - 221.08078120287496 38.302222155948911 -8.6323588745761288 - 221.08078120287496 44.09049474484658 -6.6337010245266654 - 221.08078120287496 46.291405132247142 -4.7254435371388173 - 0 - - spline forward { ref 0 } I I I I - null_surface - nubs 1 open 2 - 1 1 8 1 - 1 8 - 8 8 - - nullbs - I I - 0 - 0 - 6 2 3 4 5 6 7 - surf1 } I I # -point $-1 -1 $-1 221.08078120287496 46.291405132247142 -4.7254435371388173 # -point $-1 -1 $-1 221.08078120287502 -46.291405132247142 4.7254435371388173 # +700 0 1 0 +4 LibG 19 ASM 219.0.0.5600 NT 24 Wed Sep 16 15:26:33 2015 +1000 9.9999999999999995e-007 1e-010 +body $-1 -1 $-1 $1 $-1 $-1 # +lump $-1 -1 $-1 $-1 $2 $0 # +shell $-1 -1 $-1 $-1 $-1 $3 $-1 $1 # +face $-1 -1 $-1 $-1 $4 $2 $-1 $5 forward double out # +loop $-1 -1 $-1 $-1 $6 $3 # +spline-surface $-1 -1 $-1 forward { exactsur full nubs 3 3 open open none none 8 8 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 95.998851476614703 -46.291405132247149 -4.7254435371388164 + 95.998851476614703 -44.09049474484658 -6.6337010245266654 + 95.998851476614689 -38.302222155948904 -8.6323588745761288 + 95.998851476614689 -24.999999999999986 -7.5911689942537413 + 95.998851476614689 -8.6824088833465183 -2.9979867750741973 + 95.998851476614689 8.6824088833465183 2.9979867750741973 + 95.998851476614689 25.000000000000011 7.5911689942537475 + 95.998851476614689 38.302222155948911 8.6323588745761288 + 95.998851476614689 44.09049474484658 6.6337010245266654 + 95.998851476614689 46.291405132247149 4.7254435371388164 + 103.27105669325775 -46.291405132247149 -7.2286775549284696 + 103.27105669325775 -44.09049474484658 -10.147806301191494 + 103.27105669325773 -38.302222155948904 -13.2052236689127 + 103.27105669325773 -24.999999999999986 -11.612478806096661 + 103.27105669325773 -8.6824088833465183 -4.5861260515818127 + 103.27105669325773 8.6824088833465183 4.5861260515818127 + 103.27105669325773 25.000000000000011 11.61247880609667 + 103.27105669325773 38.302222155948911 13.2052236689127 + 103.27105669325773 44.09049474484658 10.147806301191494 + 103.27105669325773 46.291405132247149 7.2286775549284696 + 114.90658503988658 -46.291405132247142 -12.797194587388756 + 114.90658503988658 -44.09049474484658 -17.965035912127128 + 114.90658503988658 -38.302222155948904 -23.377694685779865 + 114.90658503988658 -24.999999999999982 -20.557999688646696 + 114.90658503988658 -8.6824088833465183 -8.1189881604791125 + 114.90658503988658 8.6824088833465183 8.1189881604791125 + 114.90658503988658 25.000000000000011 20.557999688646706 + 114.90658503988658 38.302222155948911 23.377694685779865 + 114.90658503988658 44.09049474484658 17.965035912127128 + 114.90658503988658 46.291405132247142 12.797194587388756 + 132.3598775598299 -46.291405132247142 -15.162020563664511 + 132.3598775598299 -44.09049474484658 -21.284840366112061 + 132.3598775598299 -38.302222155948904 -27.697718053468346 + 132.3598775598299 -24.999999999999982 -24.356964481437323 + 132.3598775598299 -8.6824088833465183 -9.6193165310344302 + 132.3598775598299 8.6824088833465183 9.6193165310344302 + 132.3598775598299 25.000000000000011 24.356964481437338 + 132.3598775598299 38.302222155948911 27.69771805346835 + 132.3598775598299 44.09049474484658 21.284840366112064 + 132.3598775598299 46.291405132247142 15.162020563664512 + 149.81317007977319 -46.291405132247142 -6.8092450149740849 + 149.81317007977319 -44.09049474484658 -9.5589959497086099 + 149.81317007977316 -38.302222155948904 -12.439011528167599 + 149.81317007977316 -24.999999999999982 -10.938683157612271 + 149.81317007977316 -8.6824088833465183 -4.3200233676884832 + 149.81317007977316 8.6824088833465183 4.3200233676884832 + 149.81317007977316 25.000000000000011 10.93868315761228 + 149.81317007977316 38.302222155948911 12.439011528167599 + 149.81317007977319 44.09049474484658 9.5589959497086099 + 149.81317007977319 46.291405132247142 6.8092450149740849 + 167.26646259971648 -46.291405132247142 6.8092450149740804 + 167.26646259971648 -44.09049474484658 9.5589959497086046 + 167.26646259971648 -38.302222155948904 12.43901152816759 + 167.26646259971648 -24.999999999999982 10.938683157612266 + 167.26646259971648 -8.6824088833465183 4.3200233676884814 + 167.26646259971648 8.6824088833465183 -4.3200233676884814 + 167.26646259971648 25.000000000000011 -10.938683157612274 + 167.26646259971648 38.302222155948911 -12.43901152816759 + 167.26646259971648 44.09049474484658 -9.5589959497086046 + 167.26646259971648 46.291405132247142 -6.8092450149740804 + 184.71975511965979 -46.291405132247142 15.162020563664512 + 184.71975511965979 -44.09049474484658 21.284840366112064 + 184.71975511965979 -38.302222155948904 27.697718053468353 + 184.71975511965979 -24.999999999999982 24.356964481437331 + 184.71975511965979 -8.6824088833465183 9.6193165310344337 + 184.71975511965979 8.6824088833465183 -9.6193165310344337 + 184.71975511965979 25.000000000000011 -24.356964481437341 + 184.71975511965979 38.302222155948911 -27.697718053468353 + 184.71975511965979 44.09049474484658 -21.284840366112064 + 184.71975511965979 46.291405132247142 -15.162020563664512 + 202.17304763960311 -46.291405132247142 12.797194587388752 + 202.17304763960311 -44.09049474484658 17.965035912127124 + 202.17304763960308 -38.302222155948904 23.377694685779861 + 202.17304763960308 -24.999999999999982 20.557999688646689 + 202.17304763960308 -8.6824088833465183 8.1189881604791108 + 202.17304763960308 8.6824088833465183 -8.1189881604791108 + 202.17304763960308 25.000000000000011 -20.557999688646706 + 202.17304763960308 38.302222155948911 -23.377694685779858 + 202.17304763960308 44.09049474484658 -17.965035912127121 + 202.17304763960308 46.291405132247142 -12.79719458738875 + 213.80857598623197 -46.291405132247142 7.2286775549284696 + 213.80857598623197 -44.09049474484658 10.147806301191494 + 213.80857598623192 -38.302222155948904 13.2052236689127 + 213.80857598623192 -24.999999999999982 11.612478806096661 + 213.80857598623192 -8.6824088833465183 4.5861260515818127 + 213.80857598623192 8.6824088833465183 -4.5861260515818127 + 213.80857598623192 25.000000000000007 -11.612478806096671 + 213.80857598623192 38.302222155948911 -13.205223668912698 + 213.80857598623192 44.09049474484658 -10.147806301191492 + 213.80857598623192 46.291405132247142 -7.2286775549284696 + 221.08078120287502 -46.291405132247142 4.7254435371388173 + 221.08078120287502 -44.09049474484658 6.6337010245266663 + 221.08078120287496 -38.302222155948904 8.6323588745761288 + 221.08078120287496 -24.999999999999982 7.5911689942537421 + 221.08078120287496 -8.6824088833465183 2.9979867750741973 + 221.08078120287496 8.6824088833465183 -2.9979867750741973 + 221.08078120287496 25.000000000000007 -7.5911689942537492 + 221.08078120287496 38.302222155948911 -8.6323588745761288 + 221.08078120287496 44.09049474484658 -6.6337010245266654 + 221.08078120287496 46.291405132247142 -4.7254435371388173 + 0 + + 0 + 0 + 6 2 3 4 5 6 7 + 0 + 0 + 6 2 3 4 5 6 7 + F 1 F 0 F 1 F 0 } I I I I # +coedge $-1 -1 $-1 $7 $8 $-1 $9 forward $4 $10 # +coedge $-1 -1 $-1 $11 $6 $-1 $12 forward $4 $13 # +coedge $-1 -1 $-1 $6 $11 $-1 $14 reversed $4 $15 # +edge $-1 -1 $-1 $16 1 $17 8 $6 $18 forward @7 unknown # +pcurve $-1 -1 $-1 0 forward { exppc nubs 1 open 2 + 1 1 8 1 + 1 1 + 8 1 + 0 + spline forward { ref 0 } I I I I + } 0 0 # +coedge $-1 -1 $-1 $8 $7 $-1 $19 reversed $4 $20 # +edge $-1 -1 $-1 $17 1 $21 8 $7 $22 forward @7 unknown # +pcurve $-1 -1 $-1 0 forward { exppc nubs 1 open 2 + 1 1 8 1 + 8 1 + 8 8 + 0 + spline forward { ref 0 } I I I I + } 0 0 # +edge $-1 -1 $-1 $16 1 $23 8 $8 $24 forward @7 unknown # +pcurve $-1 -1 $-1 0 reversed { exppc nubs 1 open 2 + 1 1 8 1 + 1 1 + 1 8 + 0 + spline forward { ref 0 } I I I I + } 0 0 # +vertex $-1 -1 $-1 $14 $25 # +vertex $-1 -1 $-1 $12 $26 # +intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 95.998851476614703 -46.291405132247149 -4.7254435371388164 + 95.998851476614703 -44.09049474484658 -6.6337010245266654 + 95.998851476614689 -38.302222155948904 -8.6323588745761288 + 95.998851476614689 -24.999999999999986 -7.5911689942537413 + 95.998851476614689 -8.6824088833465183 -2.9979867750741973 + 95.998851476614689 8.6824088833465183 2.9979867750741973 + 95.998851476614689 25.000000000000011 7.5911689942537475 + 95.998851476614689 38.302222155948911 8.6323588745761288 + 95.998851476614689 44.09049474484658 6.6337010245266654 + 95.998851476614689 46.291405132247149 4.7254435371388164 + 0 + + spline forward { ref 0 } I I I I + null_surface + nubs 1 open 2 + 1 1 8 1 + 1 1 + 8 1 + + nullbs + I I + 0 + 0 + 6 2 3 4 5 6 7 + surf1 } I I # +edge $-1 -1 $-1 $23 1 $21 8 $11 $27 forward @7 unknown # +pcurve $-1 -1 $-1 0 reversed { exppc nubs 1 open 2 + 1 1 8 1 + 1 8 + 8 8 + 0 + spline forward { ref 0 } I I I I + } 0 0 # +vertex $-1 -1 $-1 $12 $28 # +intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 95.998851476614689 46.291405132247149 4.7254435371388164 + 103.27105669325773 46.291405132247149 7.2286775549284696 + 114.90658503988658 46.291405132247142 12.797194587388756 + 132.3598775598299 46.291405132247142 15.162020563664512 + 149.81317007977319 46.291405132247142 6.8092450149740849 + 167.26646259971648 46.291405132247142 -6.8092450149740804 + 184.71975511965979 46.291405132247142 -15.162020563664512 + 202.17304763960308 46.291405132247142 -12.79719458738875 + 213.80857598623192 46.291405132247142 -7.2286775549284696 + 221.08078120287496 46.291405132247142 -4.7254435371388173 + 0 + + spline forward { ref 0 } I I I I + null_surface + nubs 1 open 2 + 1 1 8 1 + 8 1 + 8 8 + + nullbs + I I + 0 + 0 + 6 2 3 4 5 6 7 + surf1 } I I # +vertex $-1 -1 $-1 $14 $29 # +intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 95.998851476614703 -46.291405132247149 -4.7254435371388164 + 103.27105669325775 -46.291405132247149 -7.2286775549284696 + 114.90658503988658 -46.291405132247142 -12.797194587388756 + 132.3598775598299 -46.291405132247142 -15.162020563664511 + 149.81317007977319 -46.291405132247142 -6.8092450149740849 + 167.26646259971648 -46.291405132247142 6.8092450149740804 + 184.71975511965979 -46.291405132247142 15.162020563664512 + 202.17304763960311 -46.291405132247142 12.797194587388752 + 213.80857598623197 -46.291405132247142 7.2286775549284696 + 221.08078120287502 -46.291405132247142 4.7254435371388173 + 0 + + spline forward { ref 0 } I I I I + null_surface + nubs 1 open 2 + 1 1 8 1 + 1 1 + 1 8 + + nullbs + I I + 0 + 0 + 6 2 3 4 5 6 7 + surf1 } I I # +point $-1 -1 $-1 95.998851476614703 -46.291405132247149 -4.7254435371388164 # +point $-1 -1 $-1 95.998851476614689 46.291405132247149 4.7254435371388164 # +intcurve-curve $-1 -1 $-1 forward { parcur full nubs 3 open 8 + 1 3 2 1 3 1 4 1 5 1 + 6 1 7 1 8 3 + 221.08078120287502 -46.291405132247142 4.7254435371388173 + 221.08078120287502 -44.09049474484658 6.6337010245266663 + 221.08078120287496 -38.302222155948904 8.6323588745761288 + 221.08078120287496 -24.999999999999982 7.5911689942537421 + 221.08078120287496 -8.6824088833465183 2.9979867750741973 + 221.08078120287496 8.6824088833465183 -2.9979867750741973 + 221.08078120287496 25.000000000000007 -7.5911689942537492 + 221.08078120287496 38.302222155948911 -8.6323588745761288 + 221.08078120287496 44.09049474484658 -6.6337010245266654 + 221.08078120287496 46.291405132247142 -4.7254435371388173 + 0 + + spline forward { ref 0 } I I I I + null_surface + nubs 1 open 2 + 1 1 8 1 + 1 8 + 8 8 + + nullbs + I I + 0 + 0 + 6 2 3 4 5 6 7 + surf1 } I I # +point $-1 -1 $-1 221.08078120287496 46.291405132247142 -4.7254435371388173 # +point $-1 -1 $-1 221.08078120287502 -46.291405132247142 4.7254435371388173 # End-of-ACIS-data \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-2/backup/MapPolygonsToSurface.dyf.0.backup b/09_Custom-Nodes/datasets/9-2/backup/MapPolygonsToSurface.dyf.0.backup index 8d77724a..a01b10b2 100644 --- a/09_Custom-Nodes/datasets/9-2/backup/MapPolygonsToSurface.dyf.0.backup +++ b/09_Custom-Nodes/datasets/9-2/backup/MapPolygonsToSurface.dyf.0.backup @@ -1,69 +1,69 @@ - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-2/backup/UVmapping_Custom-Node.dyn.0.backup b/09_Custom-Nodes/datasets/9-2/backup/UVmapping_Custom-Node.dyn.0.backup index 8f2027ac..e7c8ad14 100644 --- a/09_Custom-Nodes/datasets/9-2/backup/UVmapping_Custom-Node.dyn.0.backup +++ b/09_Custom-Nodes/datasets/9-2/backup/UVmapping_Custom-Node.dyn.0.backup @@ -1,105 +1,105 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\UVmapping_srf.sat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\UVmapping_srf.sat + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf b/09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf index 7f4cc018..5ba778f9 100644 --- a/09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf +++ b/09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf @@ -1,53 +1,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn b/09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn index f12bf1a6..c81605bf 100644 --- a/09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn +++ b/09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn @@ -1,120 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-4/Python_Custom-Node.dyn b/09_Custom-Nodes/datasets/9-4/Python_Custom-Node.dyn index f12bf1a6..c81605bf 100644 --- a/09_Custom-Nodes/datasets/9-4/Python_Custom-Node.dyn +++ b/09_Custom-Nodes/datasets/9-4/Python_Custom-Node.dyn @@ -1,120 +1,120 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-4/patternFromSolidModule.dyf b/09_Custom-Nodes/datasets/9-4/patternFromSolidModule.dyf index 85c8c46a..60cd65d5 100644 --- a/09_Custom-Nodes/datasets/9-4/patternFromSolidModule.dyf +++ b/09_Custom-Nodes/datasets/9-4/patternFromSolidModule.dyf @@ -1,90 +1,90 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn b/09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn index 071b8411..05dc9daf 100644 --- a/09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn +++ b/09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn @@ -1,35 +1,35 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn b/09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn index d92e0f95..14782ff5 100644 --- a/09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn +++ b/09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn @@ -1,71 +1,71 @@ - - - - - - - - - - - - - - 2.6 - - - - - - - - - 2.9 - - - - 3.3 - - - - - - - - - - - - - - - - - - - - - - PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4zLjIyNTYlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU15NHlNalUySlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK05XVmxOelZtTW1RdE5HUTFOaTAwWmpWbExUazBOemt0TVdRME56TmxaVFkxWkdZeUxUQXdNREF5TjJWaVBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHhNREl4T1R3dmFXNTBTVVErRFFvOEwyRXhPbE5sY21saGJHbDZZV0pzWlVsa1BnMEtQQzlUVDBGUUxVVk9WanBDYjJSNVBnMEtQQzlUVDBGUUxVVk9WanBGYm5abGJHOXdaVDROQ2c9PTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K - - - PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4zLjIyNTYlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU15NHlNalUySlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK05XVmxOelZtTW1RdE5HUTFOaTAwWmpWbExUazBOemt0TVdRME56TmxaVFkxWkdZeUxUQXdNREF5TjJWaFBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHhNREl4T0R3dmFXNTBTVVErRFFvOEwyRXhPbE5sY21saGJHbDZZV0pzWlVsa1BnMEtQQzlUVDBGUUxVVk9WanBDYjJSNVBnMEtQQzlUVDBGUUxVVk9WanBGYm5abGJHOXdaVDROQ2c9PTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K - - + + + + + + + + + + + + + + 2.6 + + + + + + + + + 2.9 + + + + 3.3 + + + + + + + + + + + + + + + + + + + + + + PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4zLjIyNTYlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU15NHlNalUySlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK05XVmxOelZtTW1RdE5HUTFOaTAwWmpWbExUazBOemt0TVdRME56TmxaVFkxWkdZeUxUQXdNREF5TjJWaVBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHhNREl4T1R3dmFXNTBTVVErRFFvOEwyRXhPbE5sY21saGJHbDZZV0pzWlVsa1BnMEtQQzlUVDBGUUxVVk9WanBDYjJSNVBnMEtQQzlUVDBGUUxVVk9WanBGYm5abGJHOXdaVDROQ2c9PTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K + + + PFNPQVAtRU5WOkVudmVsb3BlIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOlNPQVAtRU5DPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyIgeG1sbnM6U09BUC1FTlY9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3NvYXAvZW52ZWxvcGUvIiB4bWxuczpjbHI9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vc29hcC9lbmNvZGluZy9jbHIvMS4wIiBTT0FQLUVOVjplbmNvZGluZ1N0eWxlPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy9zb2FwL2VuY29kaW5nLyI+DQo8U09BUC1FTlY6Qm9keT4NCjxhMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXIgaWQ9InJlZi0xIiB4bWxuczphMT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9jbHIvbnNhc3NlbS9Qcm90b0NvcmUvUHJvdG9Db3JlJTJDJTIwVmVyc2lvbiUzRDAuOC4zLjIyNTYlMkMlMjBDdWx0dXJlJTNEbmV1dHJhbCUyQyUyMFB1YmxpY0tleVRva2VuJTNEbnVsbCI+DQo8TnVtYmVyT2ZFbGVtZW50cz4xPC9OdW1iZXJPZkVsZW1lbnRzPg0KPEJhc2UtMF9IYXNEYXRhPnRydWU8L0Jhc2UtMF9IYXNEYXRhPg0KPEJhc2UtMF9EYXRhIGlkPSJyZWYtMyI+UEZOUFFWQXRSVTVXT2tWdWRtVnNiM0JsSUhodGJHNXpPbmh6YVQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0V0YVc1emRHRnVZMlVpSUhodGJHNXpPbmh6WkQwaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNUzlZVFV4VFkyaGxiV0VpSUhodGJHNXpPbE5QUVZBdFJVNURQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SWdlRzFzYm5NNlUwOUJVQzFGVGxZOUltaDBkSEE2THk5elkyaGxiV0Z6TG5odGJITnZZWEF1YjNKbkwzTnZZWEF2Wlc1MlpXeHZjR1V2SWlCNGJXeHVjenBqYkhJOUltaDBkSEE2THk5elkyaGxiV0Z6TG0xcFkzSnZjMjltZEM1amIyMHZjMjloY0M5bGJtTnZaR2x1Wnk5amJISXZNUzR3SWlCVFQwRlFMVVZPVmpwbGJtTnZaR2x1WjFOMGVXeGxQU0pvZEhSd09pOHZjMk5vWlcxaGN5NTRiV3h6YjJGd0xtOXlaeTl6YjJGd0wyVnVZMjlrYVc1bkx5SStEUW84VTA5QlVDMUZUbFk2UW05a2VUNE5DanhoTVRwVFpYSnBZV3hwZW1GaWJHVkpaQ0JwWkQwaWNtVm1MVEVpSUhodGJHNXpPbUV4UFNKb2RIUndPaTh2YzJOb1pXMWhjeTV0YVdOeWIzTnZablF1WTI5dEwyTnNjaTl1YzJGemMyVnRMMUpsZG1sMFUyVnlkbWxqWlhNdVVHVnljMmx6ZEdWdVkyVXZVbVYyYVhSVFpYSjJhV05sY3lVeVF5VXlNRlpsY25OcGIyNGxNMFF3TGpndU15NHlNalUySlRKREpUSXdRM1ZzZEhWeVpTVXpSRzVsZFhSeVlXd2xNa01sTWpCUWRXSnNhV05MWlhsVWIydGxiaVV6Ukc1MWJHd2lQZzBLUEhOMGNtbHVaMGxFSUdsa1BTSnlaV1l0TXlJK05XVmxOelZtTW1RdE5HUTFOaTAwWmpWbExUazBOemt0TVdRME56TmxaVFkxWkdZeUxUQXdNREF5TjJWaFBDOXpkSEpwYm1kSlJENE5DanhwYm5SSlJENHhNREl4T0R3dmFXNTBTVVErRFFvOEwyRXhPbE5sY21saGJHbDZZV0pzWlVsa1BnMEtQQzlUVDBGUUxVVk9WanBDYjJSNVBnMEtQQzlUVDBGUUxVVk9WanBGYm5abGJHOXdaVDROQ2c9PTwvQmFzZS0wX0RhdGE+DQo8QmFzZS0wX0hhc05lc3RlZERhdGE+ZmFsc2U8L0Jhc2UtMF9IYXNOZXN0ZWREYXRhPg0KPC9hMTpDYWxsU2l0ZV94MDAyQl9UcmFjZVNlcmlhbGlzZXJIZWxwZXI+DQo8L1NPQVAtRU5WOkJvZHk+DQo8L1NPQVAtRU5WOkVudmVsb3BlPg0K + + \ No newline at end of file diff --git a/09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.dyn b/09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.dyn index eac74cff..c9ff764e 100644 --- a/09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.dyn +++ b/09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.dyn @@ -1,88 +1,88 @@ - - - - - - - - - - - 11 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + 11 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/10_Packages/10-1_Introduction.md b/10_Packages/10-1_Introduction.md index 8a074c21..c5ae1291 100644 --- a/10_Packages/10-1_Introduction.md +++ b/10_Packages/10-1_Introduction.md @@ -1,69 +1,69 @@ -##Packages -In short, a Package is a collection of Custom Nodes. The Dynamo Package Manager is a portal for the community to download any package which has been published online. These toolsets are developed by third parties in order to extend Dynamo's core functionality, accessible to all, and ready to download at the click of the button. - -![](images/10-1/dpm.png) - -An open-source project such as Dynamo thrives on this type of community involvement. With dedicated third party developers, Dynamo is able to extend its reach to workflows across a range of industries. For this reason, the Dynamo team has made concerted efforts to streamline package development and publishing (which will be discussed in more detail in the following sections). - -###Installing a Package -The easiest way to install a package is by using the Packages toolbar in your Dynamo interface. Let's jump right into it and install one now. In this quick example, we'll install a popular package for creating quad panels on a grid. -![](images/10-1/AddingToLibrary- 01.png) ->1. In Dynamo, go to *Packages>Search For a Package...* - -![](images/10-1/AddingToLibrary- 00.png) -> In the search bar, let's search for "quads from rectangular grid". After a few moments, you should see all of the packages which match this search query. We want to select the first package with the matching name. -1. Click on the download arrow to the left of the package name and the package will install. Done! - -![](images/10-1/buildz.png) ->1. Notice that we now have another group in our Dynamo library called *"buildz"*. This name refers to the [developer](http://buildz.blogspot.com/) of the package, and the custom node is placed in this group. We can begin to use this right away. - -![](images/10-1/example.png) -> With a quick code block operation to define a rectangular grid, we've create a list of rectangular panels. - -###Package Folders -The example above focuses on a package with one custom node, but you use the same process for downloading packages with several custom nodes and supporting data files. Let's demonstrate that now with a more comprehensive package: Dynamo Unfold. - -![](images/10-1/unfold.png) -> As in the example above, begin by selecting *Packages>Search for a Package...*. This time, we'll search for *"DynamoUnfold"*, one word, minding the caps. When we see the packages, download by clicking the arrow to the left of the package name. Dynamo Unfold will now be installed in your Dynamo Library. - -![](images/10-1/unfoldLibrary.png) -> In the Dynamo Library, we have a *DynamoUnfold* Group with multiple categories and custom nodes. - -![](images/10-1/manage.png) -> Now, let's take a look at the package's file structure. Select *"Packages>Manage Packages..."* in Dynamo. We'll see the window above with the two libraries we've installed. Click the button on the right of *DynamoUnfold* and select *"Show Root Directory".* - -![](images/10-1/rd1.png) -> This will take us to the package's root directory. Notice that we have 3 folders and a file. -1. The *bin* folder houses .dll files. This Dynamo package was developed using Zero-Touch, so the custom nodes are held in this folder. -2. The *dyf* folder houses the custom nodes. This package was not developed using Dynamo custom nodes, so this folder is empty for this package. -3. The extra folder houses all additional files, including our example files. -4. The pkg file is a basic text file defining the package settings. We can ignore this for now. - -![](images/10-1/rd2.png) -> Opening the *"extra"* folder, we see a bunch of example files that were downloaded with the install. Not all packages have example files, but this is where you can find them if they are part of a package. Let's open up *"SphereUnfold"*. - -![](images/10-1/sphereUnfold.png) -> After opening the file and hitting *"Run"* on the solver, we have an unfolded sphere! Example files like these are helpful for learning how to work with a new Dynamo package. - -###Dynamo Package Manager -Another way to discover Dynamo packages is to explore the [Dynamo Package Manager](http://dynamopackages.com/) online. This is a good way to browse for packages, since the repository sorts packages in order of download count and popularity. Also, it's an easy way to gather information on recent updates for packages, as some Dynamo packages are subjected to versioning and dependencies of Dynamo builds. - -![](images/10-1/dpm2.png) -> By clicking on *"Quads from Rectangular Grid"* in the Dynamo Package Manager, you can see its descriptions, versions, the developer, and possible dependencies. - -You can also download the package files from the Dynamo Package Manager, but doing so directly from Dynamo is a more seamless process. - -###Where are Files Stored Locally? -If you do download files from the Dynamo package manager, or if you would like to see where all of your package files are kept, click on *Settings>Manage Node and Package Paths...*. By clicking on the ellipsis next to the folder directory, you can copy the root folder and delve into the package in your explorer window. By default, packages are installed in a location similar to this folder path: *C:/Users/[username]/AppData/Roaming/Dynamo/[Dynamo Version]*. - -###Going Further with Packages -The Dynamo community is constantly growing and evolving. By exploring the Dynamo Package Manager from time to time, you'll find some exciting new developments. In the following sections, we'll take a more in-depth look at packages, from the end-user perspective to authorship of your own Dynamo Package. - - - - - - - - - +##Packages +In short, a Package is a collection of Custom Nodes. The Dynamo Package Manager is a portal for the community to download any package which has been published online. These toolsets are developed by third parties in order to extend Dynamo's core functionality, accessible to all, and ready to download at the click of the button. + +![](images/10-1/dpm.png) + +An open-source project such as Dynamo thrives on this type of community involvement. With dedicated third party developers, Dynamo is able to extend its reach to workflows across a range of industries. For this reason, the Dynamo team has made concerted efforts to streamline package development and publishing (which will be discussed in more detail in the following sections). + +###Installing a Package +The easiest way to install a package is by using the Packages toolbar in your Dynamo interface. Let's jump right into it and install one now. In this quick example, we'll install a popular package for creating quad panels on a grid. +![](images/10-1/AddingToLibrary- 01.png) +>1. In Dynamo, go to *Packages>Search For a Package...* + +![](images/10-1/AddingToLibrary- 00.png) +> In the search bar, let's search for "quads from rectangular grid". After a few moments, you should see all of the packages which match this search query. We want to select the first package with the matching name. +1. Click on the download arrow to the left of the package name and the package will install. Done! + +![](images/10-1/buildz.png) +>1. Notice that we now have another group in our Dynamo library called *"buildz"*. This name refers to the [developer](http://buildz.blogspot.com/) of the package, and the custom node is placed in this group. We can begin to use this right away. + +![](images/10-1/example.png) +> With a quick code block operation to define a rectangular grid, we've create a list of rectangular panels. + +###Package Folders +The example above focuses on a package with one custom node, but you use the same process for downloading packages with several custom nodes and supporting data files. Let's demonstrate that now with a more comprehensive package: Dynamo Unfold. + +![](images/10-1/unfold.png) +> As in the example above, begin by selecting *Packages>Search for a Package...*. This time, we'll search for *"DynamoUnfold"*, one word, minding the caps. When we see the packages, download by clicking the arrow to the left of the package name. Dynamo Unfold will now be installed in your Dynamo Library. + +![](images/10-1/unfoldLibrary.png) +> In the Dynamo Library, we have a *DynamoUnfold* Group with multiple categories and custom nodes. + +![](images/10-1/manage.png) +> Now, let's take a look at the package's file structure. Select *"Packages>Manage Packages..."* in Dynamo. We'll see the window above with the two libraries we've installed. Click the button on the right of *DynamoUnfold* and select *"Show Root Directory".* + +![](images/10-1/rd1.png) +> This will take us to the package's root directory. Notice that we have 3 folders and a file. +1. The *bin* folder houses .dll files. This Dynamo package was developed using Zero-Touch, so the custom nodes are held in this folder. +2. The *dyf* folder houses the custom nodes. This package was not developed using Dynamo custom nodes, so this folder is empty for this package. +3. The extra folder houses all additional files, including our example files. +4. The pkg file is a basic text file defining the package settings. We can ignore this for now. + +![](images/10-1/rd2.png) +> Opening the *"extra"* folder, we see a bunch of example files that were downloaded with the install. Not all packages have example files, but this is where you can find them if they are part of a package. Let's open up *"SphereUnfold"*. + +![](images/10-1/sphereUnfold.png) +> After opening the file and hitting *"Run"* on the solver, we have an unfolded sphere! Example files like these are helpful for learning how to work with a new Dynamo package. + +###Dynamo Package Manager +Another way to discover Dynamo packages is to explore the [Dynamo Package Manager](http://dynamopackages.com/) online. This is a good way to browse for packages, since the repository sorts packages in order of download count and popularity. Also, it's an easy way to gather information on recent updates for packages, as some Dynamo packages are subjected to versioning and dependencies of Dynamo builds. + +![](images/10-1/dpm2.png) +> By clicking on *"Quads from Rectangular Grid"* in the Dynamo Package Manager, you can see its descriptions, versions, the developer, and possible dependencies. + +You can also download the package files from the Dynamo Package Manager, but doing so directly from Dynamo is a more seamless process. + +###Where are Files Stored Locally? +If you do download files from the Dynamo package manager, or if you would like to see where all of your package files are kept, click on *Settings>Manage Node and Package Paths...*. By clicking on the ellipsis next to the folder directory, you can copy the root folder and delve into the package in your explorer window. By default, packages are installed in a location similar to this folder path: *C:/Users/[username]/AppData/Roaming/Dynamo/[Dynamo Version]*. + +###Going Further with Packages +The Dynamo community is constantly growing and evolving. By exploring the Dynamo Package Manager from time to time, you'll find some exciting new developments. In the following sections, we'll take a more in-depth look at packages, from the end-user perspective to authorship of your own Dynamo Package. + + + + + + + + + diff --git a/10_Packages/10-2_Mesh-Toolkit.md b/10_Packages/10-2_Mesh-Toolkit.md index fc630c52..1f892bb7 100644 --- a/10_Packages/10-2_Mesh-Toolkit.md +++ b/10_Packages/10-2_Mesh-Toolkit.md @@ -1,49 +1,49 @@ -##Package Case Study – Mesh Toolkit - -The Dynamo Mesh Toolkit provides tools to import meshes from external file formats, create a mesh from Dynamo geometry objects, and manually build meshes by their vertices and indices. The library also provides tools to modify meshes, repair meshes, or extract horizontal slices for use in fabrication. - -![Import Mesh](images/10-3/mtIntro.png) - -The Dynamo Mesh Toolkit is part of Autodesk's ongoing mesh research, and as such will continue to grow over the coming years. Expect new methods to appear on the toolkit frequently, and feel free to reach out to the Dynamo team with comments, bugs, and suggestions for new features. - -###Meshes vs. Solids -The exercise below demonstrates some basic mesh operations using the Mesh Toolkit. In the exercise, we intersect a mesh with a series of planes, which can be computationally expensive using solids. Unlike a solid, a mesh has a set "resolution" and is not defined mathematically, but topologically, and we can define this resolution based on the task at hand. For more details on mesh to solid relationships, you can reference the[ Geometry For Computation Design](../05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md) chapter in this primer. For a more thorough examination of Mesh Toolkit, you can reference the [Dynamo Wiki page.](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) Let's jump into the package in the exercise below. - -###Install Mesh Toolkit -![Import Mesh](images/10-3/mt.png) -> In Dynamo, go to *Packages > Search for Packages...* in the top menu bar. In the search field, type *"MeshToolkit"*, all one word, minding the caps. Click the download arrow for the appropriate package for your version of Dynamo. Simple as that! - -### Exercise ->Download and unzip the example files for this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [MeshToolkit.zip](datasets/10-2/MeshToolkit.zip) - -Begin by opening *Mesh-Toolkit_Intersect-Mesh.dyn in Dynamo.* In this example, we will look at the Intersect node in the mesh toolkit. We will import a mesh and intersect it with a series of input planes to create slices. This is the starting point for preparing the model for fabrication on a laser cutter, waterjet cutter, or CNC mill. - -![Import Mesh](images/10-3/contour01.png) ->1. **File Path:** Locate the mesh file to import (*stanford_bunny_tri.obj*). Supported file types are .mix and .obj -2. **Mesh.ImportFile:** Connect the file path to import the mesh - -![Intersect](images/10-3/contour02.png) -> 1. **Point.ByCoordinates:** Construct a point – this will be the center of an arc. -2. **Arc.ByCenterPointRadiusAngle:** Construct an arc around the point. This curve will be used to position a series of planes. - -![Intersect](images/10-3/contour03.png) -> 1. Code Block: Create a range of numbers between zero and one. -2. **Curve.PointAtParameter:** Connect the arc to the *‘curve’* input and the code block output to the *‘param’* input to extract a series of points along the curve. -3. **Curve.TangentAtParameter:** Connect the same inputs as the previous node. -4. **Plane.ByOriginNormal:** Connect the points to the *‘origin’* input and the vectors to the *‘normal’* input to create a series of planes at each point. - -You should now see a series of planes oriented along the arc. Next, we will use these planes to intersect the mesh. - -![Intersect](images/10-3/contour04.png) -> 1. **Mesh.Intersect:** Intersect the planes with the imported mesh, creating a series of polycurve contours. -2. **PolyCurve.Curves:** Break the polycurves into their curve fragments. -3. **Curve.EndPoint:** Extract the end points of each curve. -4. **NurbsCurve.ByPoints:** Use the points to construct a nurbs curve. Use a Boolean node set to *True* to close the curves. - -![Intersect](images/10-3/contour05.png) -> 1. **Surface.ByPatch:** Construct surface patches for each contour to create “slices” of the mesh. - -![Intersect](images/10-3/contour06.png) -> Add a second set of slices for a waffle/egg-crate effect. - +##Package Case Study – Mesh Toolkit + +The Dynamo Mesh Toolkit provides tools to import meshes from external file formats, create a mesh from Dynamo geometry objects, and manually build meshes by their vertices and indices. The library also provides tools to modify meshes, repair meshes, or extract horizontal slices for use in fabrication. + +![Import Mesh](images/10-3/mtIntro.png) + +The Dynamo Mesh Toolkit is part of Autodesk's ongoing mesh research, and as such will continue to grow over the coming years. Expect new methods to appear on the toolkit frequently, and feel free to reach out to the Dynamo team with comments, bugs, and suggestions for new features. + +###Meshes vs. Solids +The exercise below demonstrates some basic mesh operations using the Mesh Toolkit. In the exercise, we intersect a mesh with a series of planes, which can be computationally expensive using solids. Unlike a solid, a mesh has a set "resolution" and is not defined mathematically, but topologically, and we can define this resolution based on the task at hand. For more details on mesh to solid relationships, you can reference the[ Geometry For Computation Design](../05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md) chapter in this primer. For a more thorough examination of Mesh Toolkit, you can reference the [Dynamo Wiki page.](https://github.com/DynamoDS/Dynamo/wiki/Dynamo-Mesh-Toolkit) Let's jump into the package in the exercise below. + +###Install Mesh Toolkit +![Import Mesh](images/10-3/mt.png) +> In Dynamo, go to *Packages > Search for Packages...* in the top menu bar. In the search field, type *"MeshToolkit"*, all one word, minding the caps. Click the download arrow for the appropriate package for your version of Dynamo. Simple as that! + +### Exercise +>Download and unzip the example files for this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [MeshToolkit.zip](datasets/10-2/MeshToolkit.zip) + +Begin by opening *Mesh-Toolkit_Intersect-Mesh.dyn in Dynamo.* In this example, we will look at the Intersect node in the mesh toolkit. We will import a mesh and intersect it with a series of input planes to create slices. This is the starting point for preparing the model for fabrication on a laser cutter, waterjet cutter, or CNC mill. + +![Import Mesh](images/10-3/contour01.png) +>1. **File Path:** Locate the mesh file to import (*stanford_bunny_tri.obj*). Supported file types are .mix and .obj +2. **Mesh.ImportFile:** Connect the file path to import the mesh + +![Intersect](images/10-3/contour02.png) +> 1. **Point.ByCoordinates:** Construct a point – this will be the center of an arc. +2. **Arc.ByCenterPointRadiusAngle:** Construct an arc around the point. This curve will be used to position a series of planes. + +![Intersect](images/10-3/contour03.png) +> 1. Code Block: Create a range of numbers between zero and one. +2. **Curve.PointAtParameter:** Connect the arc to the *‘curve’* input and the code block output to the *‘param’* input to extract a series of points along the curve. +3. **Curve.TangentAtParameter:** Connect the same inputs as the previous node. +4. **Plane.ByOriginNormal:** Connect the points to the *‘origin’* input and the vectors to the *‘normal’* input to create a series of planes at each point. + +You should now see a series of planes oriented along the arc. Next, we will use these planes to intersect the mesh. + +![Intersect](images/10-3/contour04.png) +> 1. **Mesh.Intersect:** Intersect the planes with the imported mesh, creating a series of polycurve contours. +2. **PolyCurve.Curves:** Break the polycurves into their curve fragments. +3. **Curve.EndPoint:** Extract the end points of each curve. +4. **NurbsCurve.ByPoints:** Use the points to construct a nurbs curve. Use a Boolean node set to *True* to close the curves. + +![Intersect](images/10-3/contour05.png) +> 1. **Surface.ByPatch:** Construct surface patches for each contour to create “slices” of the mesh. + +![Intersect](images/10-3/contour06.png) +> Add a second set of slices for a waffle/egg-crate effect. + You may have noticed that the intersection operations calculate faster with a mesh vs. a comparable solid. Workflows such as the one demonstrated in this exercise lend themselves well to working with meshes. \ No newline at end of file diff --git a/10_Packages/10-3_Creating.md b/10_Packages/10-3_Creating.md index 746bd148..614af8f7 100644 --- a/10_Packages/10-3_Creating.md +++ b/10_Packages/10-3_Creating.md @@ -1,72 +1,72 @@ -##Developing a Package - -Dynamo offers a variety of ways to create a package for your personal use or for sharing with the Dynamo community. In the case study below, we'll walk through how a package is setup by deconstructing an existing one. This case study builds on lessons from the previous chapter, providing a set of custom nodes for mapping geometry, by UV coordinates, from one Dynamo surface to another. - -###MapToSurface -In the previous chapter, we explored ways for panelizing a surface in Dynamo based on curves defined in the XY plane. This case study extends these concepts for more complex geometry. We're going to install this package as built in order to demonstrate how it was developed. In the next section, we'll demonstrate how this package was published. - -###Installing the Package -![](images/10-4/Creating/Packages - 14.png) -> This is the easy part. In Dynamo, navigate to *"Packages>Search for a Package..."* - -![](images/10-4/Creating/Packages - 13.png) -> Search for the package *"MapToSurface"* (all one word). -1. When the package is found, click on the big download error to the left of the package name. This will install the package into Dynamo. - -![](images/10-4/Publishing/packages - ui.png) -> 1. After installing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. With the package now installed, let's walk through how it's setup. - -###Custom Nodes -The package we're creating uses 5 custom nodes that we've built for reference. Let's walk through what each node does below. Some custom nodes build off of other custom nodes, and the graphs have a layout for other users to understand in a straightforward manner. - -![](images/10-4/Creating/Packages - 12.png) -> This is a simple package with five custom nodes. In the steps below, we'll briefly talk about each custom node's setup. - -![](images/10-4/Creating/Packages - 11.png) -> **PointsToSurface:** This is a basic custom node, and one from which all of the other mapping nodes are based. Simply put, the node maps a point from a source surface UV coordinate to the location of the target surface UV coordinate. And since points are the most primitive geometry, from which more complex geometry is built, we can use this logic to map 2D, and even 3D geometry from one surface to another. - -![](images/10-4/Creating/Packages - 10.png) -> **PolygonsToSurface:** the logic of extending mapped points from 1D geometry to 2D geometry is demonstrated simply with polygons here. Notice that we have nested the *"PointsToSurface"* node into this custom node. This way we can map the points of each polygon to the surface, and then regenerate the polygon from those mapped points. By maintaining the proper data structure (a list of lists of points), we're able to keep the polygons separate after they're reduced to a set of points. - -![](images/10-4/Creating/Packages - 09.png) -> **NurbsCrvtoSurface:** The same logic applies here as in the *"PolygonsToSurface"* node. But instead of mapping polygonal points, we're mapping control points of a nurbs curve. - -![](images/10-4/Creating/Packages - 08.png) -> **OffsetPointsToSurface:** This node gets a little more complex, but the concept is simple: like the *"PointsToSurface"* node, this node maps points from one surface to another. However, it also considers points which are not on the original source surface, gets their distance to the closest UV parameter, and maps this distance to the target surface normal at the corresponding UV coordinate. This will make more sense when looking at the example files. - -![](images/10-4/Creating/Packages - 07.png) -> **SampleSrf:** This is a simple node which creates a parametric surface to map from the source grid to an undulating surface in the example files. - -###Example Files -The example files can be found in the package's root folder (In Dynamo, navigate this folder by going to *Packages>Manage Packages...*). - -![](images/10-4/Publishing/packages - showRoot.png) -> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* - -With the root directory open, navigate to the *"extra"* folder, which houses all of the files in the package which are not custom nodes. This is where examples files (if they exist) are stored for Dynamo packages. The screenshots below discuss the concepts demonstrated in each example file. - -![](images/10-4/Creating/Packages - 06.png) -> **01-PanelingWithPolygons:** This example file demonstrates how *"PointsToSurface"* may be used to panelize a surface based on a grid of rectangles. This should look familiar, as we demonstrated a similar workflow in the previous chapter ("Custom Nodes"). - -![](images/10-4/Creating/Packages - 05.png) -> **02-PanelingWithPolygons-II:** Using a similar workflow, this exercise file shows a setup for mapping circles (or polygons representing circles) from one surface to another. This uses the *"PolygonsToSurface"* node. - -![](images/10-4/Creating/Packages - 04.png) -> **03-NurbsCrvsAndSurface:** This example file adds some complexity by working with the "NurbsCrvToSurface" node. The target surface is offset a given distance and the nurbs curve is mapped to the original target surface and the offset surface. From there, the two mapped curves are lofted to create a surface, which is then thickened. This resulting solid has an undulation that is representative of the target surface normals. - -![](images/10-4/Creating/Packages - 03A.png) -> **04-PleatedPolysurface-OffsetPoints:** This example file demonstrates how to map a pleated polysurface from a source surface to a target surface. The source and target surface are a rectangular surface spanning the grid and a revolved surface, respectively. - -![](images/10-4/Creating/Packages - 03.png) -> **04-PleatedPolysurface-OffsetPoints:** The source polysurface mapped from the source surface to the target surface. - -![](images/10-4/Creating/Packages - 01.png) -> **05-SVG-Import:** Since the custom nodes are able to map different types of curves, this last file references an SVG file exported from Illustrator and maps the imported curves to a target surface - -![](images/10-4/Creating/Packages - 00.png) -> **05-SVG-Import:** Using Python, the SVG curves are translated from SVG format to Dynamo polycurves. - -![](images/10-4/Creating/Packages - 02.png) -> **05-SVG-Import:** The imported curves are mapped to a target surface. This allows us to explicitly (point-and-click) design a panelization in illustrator, import into Dynamo, and apply to a target surface. - - +##Developing a Package + +Dynamo offers a variety of ways to create a package for your personal use or for sharing with the Dynamo community. In the case study below, we'll walk through how a package is setup by deconstructing an existing one. This case study builds on lessons from the previous chapter, providing a set of custom nodes for mapping geometry, by UV coordinates, from one Dynamo surface to another. + +###MapToSurface +In the previous chapter, we explored ways for panelizing a surface in Dynamo based on curves defined in the XY plane. This case study extends these concepts for more complex geometry. We're going to install this package as built in order to demonstrate how it was developed. In the next section, we'll demonstrate how this package was published. + +###Installing the Package +![](images/10-4/Creating/Packages - 14.png) +> This is the easy part. In Dynamo, navigate to *"Packages>Search for a Package..."* + +![](images/10-4/Creating/Packages - 13.png) +> Search for the package *"MapToSurface"* (all one word). +1. When the package is found, click on the big download error to the left of the package name. This will install the package into Dynamo. + +![](images/10-4/Publishing/packages - ui.png) +> 1. After installing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. With the package now installed, let's walk through how it's setup. + +###Custom Nodes +The package we're creating uses 5 custom nodes that we've built for reference. Let's walk through what each node does below. Some custom nodes build off of other custom nodes, and the graphs have a layout for other users to understand in a straightforward manner. + +![](images/10-4/Creating/Packages - 12.png) +> This is a simple package with five custom nodes. In the steps below, we'll briefly talk about each custom node's setup. + +![](images/10-4/Creating/Packages - 11.png) +> **PointsToSurface:** This is a basic custom node, and one from which all of the other mapping nodes are based. Simply put, the node maps a point from a source surface UV coordinate to the location of the target surface UV coordinate. And since points are the most primitive geometry, from which more complex geometry is built, we can use this logic to map 2D, and even 3D geometry from one surface to another. + +![](images/10-4/Creating/Packages - 10.png) +> **PolygonsToSurface:** the logic of extending mapped points from 1D geometry to 2D geometry is demonstrated simply with polygons here. Notice that we have nested the *"PointsToSurface"* node into this custom node. This way we can map the points of each polygon to the surface, and then regenerate the polygon from those mapped points. By maintaining the proper data structure (a list of lists of points), we're able to keep the polygons separate after they're reduced to a set of points. + +![](images/10-4/Creating/Packages - 09.png) +> **NurbsCrvtoSurface:** The same logic applies here as in the *"PolygonsToSurface"* node. But instead of mapping polygonal points, we're mapping control points of a nurbs curve. + +![](images/10-4/Creating/Packages - 08.png) +> **OffsetPointsToSurface:** This node gets a little more complex, but the concept is simple: like the *"PointsToSurface"* node, this node maps points from one surface to another. However, it also considers points which are not on the original source surface, gets their distance to the closest UV parameter, and maps this distance to the target surface normal at the corresponding UV coordinate. This will make more sense when looking at the example files. + +![](images/10-4/Creating/Packages - 07.png) +> **SampleSrf:** This is a simple node which creates a parametric surface to map from the source grid to an undulating surface in the example files. + +###Example Files +The example files can be found in the package's root folder (In Dynamo, navigate this folder by going to *Packages>Manage Packages...*). + +![](images/10-4/Publishing/packages - showRoot.png) +> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* + +With the root directory open, navigate to the *"extra"* folder, which houses all of the files in the package which are not custom nodes. This is where examples files (if they exist) are stored for Dynamo packages. The screenshots below discuss the concepts demonstrated in each example file. + +![](images/10-4/Creating/Packages - 06.png) +> **01-PanelingWithPolygons:** This example file demonstrates how *"PointsToSurface"* may be used to panelize a surface based on a grid of rectangles. This should look familiar, as we demonstrated a similar workflow in the previous chapter ("Custom Nodes"). + +![](images/10-4/Creating/Packages - 05.png) +> **02-PanelingWithPolygons-II:** Using a similar workflow, this exercise file shows a setup for mapping circles (or polygons representing circles) from one surface to another. This uses the *"PolygonsToSurface"* node. + +![](images/10-4/Creating/Packages - 04.png) +> **03-NurbsCrvsAndSurface:** This example file adds some complexity by working with the "NurbsCrvToSurface" node. The target surface is offset a given distance and the nurbs curve is mapped to the original target surface and the offset surface. From there, the two mapped curves are lofted to create a surface, which is then thickened. This resulting solid has an undulation that is representative of the target surface normals. + +![](images/10-4/Creating/Packages - 03A.png) +> **04-PleatedPolysurface-OffsetPoints:** This example file demonstrates how to map a pleated polysurface from a source surface to a target surface. The source and target surface are a rectangular surface spanning the grid and a revolved surface, respectively. + +![](images/10-4/Creating/Packages - 03.png) +> **04-PleatedPolysurface-OffsetPoints:** The source polysurface mapped from the source surface to the target surface. + +![](images/10-4/Creating/Packages - 01.png) +> **05-SVG-Import:** Since the custom nodes are able to map different types of curves, this last file references an SVG file exported from Illustrator and maps the imported curves to a target surface + +![](images/10-4/Creating/Packages - 00.png) +> **05-SVG-Import:** Using Python, the SVG curves are translated from SVG format to Dynamo polycurves. + +![](images/10-4/Creating/Packages - 02.png) +> **05-SVG-Import:** The imported curves are mapped to a target surface. This allows us to explicitly (point-and-click) design a panelization in illustrator, import into Dynamo, and apply to a target surface. + + diff --git a/10_Packages/10-3_Developing.md b/10_Packages/10-3_Developing.md index d8079cd3..ab0f3daf 100644 --- a/10_Packages/10-3_Developing.md +++ b/10_Packages/10-3_Developing.md @@ -1,77 +1,77 @@ -##Developing a Package - -Dynamo offers a variety of ways to create a package for your personal use or for sharing with the Dynamo community. In the case study below, we'll walk through how a package is set up by deconstructing an existing one. This case study builds on lessons from the previous chapter, providing a set of custom nodes for mapping geometry, by UV coordinates, from one Dynamo surface to another. - -###MapToSurface -We're going to work with a sample package which demonstrates the UV mapping of points from one surface to another. We've already built the fundamentals of the tool in the [Creating a Custom Node](../09_Custom-Nodes/9-2_Creating.md) section of this primer. The files below demonstrate how we can take the concept of UV Mapping and develop a set of tools for a publishable library. - -![](images/10-4/uvMap.png) -> In this image, we map a point from one surface to another using UV coordinates. The package is based on this concept, but with more complex geometry. - -###Installing the Package -In the previous chapter, we explored ways for panelizing a surface in Dynamo based on curves defined in the XY plane. This case study extends these concepts for more dimensions of geometry. We're going to install this package as built in order to demonstrate how it was developed. In the next section, we'll demonstrate how this package was published. - -![](images/10-4/Creating/Packages - 14.png) -> This is the easy part. In Dynamo, navigate to *"Packages>Search for a Package..."* - -![](images/10-4/Creating/Packages - 13.png) -> Search for the package *"MapToSurface"* (all one word). -1. When the package is found, click on the big download arrow to the left of the package name. This will install the package into Dynamo. - -![](images/10-4/Publishing/packages - ui.png) -> 1. After installing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. With the package now installed, let's walk through how it's set up. - -###Custom Nodes -The package we're creating uses five custom nodes that we've built for reference. Let's walk through what each node does below. Some custom nodes build off of other custom nodes, and the graphs have a layout for other users to understand in a straightforward manner. - -![](images/10-4/Creating/Packages - 12.png) -> This is a simple package with five custom nodes. In the steps below, we'll briefly talk about each custom node's setup. - -![](images/10-4/Creating/Packages - 11.png) -> **PointsToSurface:** This is a basic custom node, and one from which all of the other mapping nodes are based. Simply put, the node maps a point from a source surface UV coordinate to the location of the target surface UV coordinate. And since points are the most primitive geometry, from which more complex geometry is built, we can use this logic to map 2D, and even 3D geometry from one surface to another. - -![](images/10-4/Creating/Packages - 10.png) -> **PolygonsToSurface:** the logic of extending mapped points from 1D geometry to 2D geometry is demonstrated simply with polygons here. Notice that we have nested the *"PointsToSurface"* node into this custom node. This way we can map the points of each polygon to the surface, and then regenerate the polygon from those mapped points. By maintaining the proper data structure (a list of lists of points), we're able to keep the polygons separate after they're reduced to a set of points. - -![](images/10-4/Creating/Packages - 09.png) -> **NurbsCrvtoSurface:** The same logic applies here as in the *"PolygonsToSurface"* node. But instead of mapping polygonal points, we're mapping control points of a nurbs curve. - -![](images/10-4/Creating/Packages - 08.png) -> **OffsetPointsToSurface:** This node gets a little more complex, but the concept is simple: like the *"PointsToSurface"* node, this node maps points from one surface to another. However, it also considers points which are not on the original source surface, gets their distance to the closest UV parameter, and maps this distance to the target surface normal at the corresponding UV coordinate. This will make more sense when looking at the example files. - -![](images/10-4/Creating/Packages - 07.png) -> **SampleSrf:** This is a simple node which creates a parametric surface to map from the source grid to an undulating surface in the example files. - -###Example Files -The example files can be found in the package's root folder (In Dynamo, navigate to this folder by going to *Packages>Manage Packages...*). - -![](images/10-4/Publishing/packages - showRoot.png) -> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* - -With the root directory open, navigate to the *"extra"* folder, which houses all of the files in the package which are not custom nodes. This is where examples files (if they exist) are stored for Dynamo packages. The screenshots below discuss the concepts demonstrated in each example file. - -![](images/10-4/Creating/Packages - 06.png) -> **01-PanelingWithPolygons:** This example file demonstrates how *"PointsToSurface"* may be used to panelize a surface based on a grid of rectangles. This should look familiar, as we demonstrated a similar workflow in the [previous chapter](../09_Custom-Nodes/9-2_Creating.md). - -![](images/10-4/Creating/Packages - 05.png) -> **02-PanelingWithPolygons-II:** Using a similar workflow, this exercise file shows a setup for mapping circles (or polygons representing circles) from one surface to another. This uses the *"PolygonsToSurface"* node. - -![](images/10-4/Creating/Packages - 04.png) -> **03-NurbsCrvsAndSurface:** This example file adds some complexity by working with the "NurbsCrvToSurface" node. The target surface is offset a given distance and the nurbs curve is mapped to the original target surface and the offset surface. From there, the two mapped curves are lofted to create a surface, which is then thickened. This resulting solid has an undulation that is representative of the target surface normals. - -![](images/10-4/Creating/Packages - 03A.png) -> **04-PleatedPolysurface-OffsetPoints:** This example file demonstrates how to map a pleated polysurface from a source surface to a target surface. The source and target surface are a rectangular surface spanning the grid and a revolved surface, respectively. - -![](images/10-4/Creating/Packages - 03.png) -> **04-PleatedPolysurface-OffsetPoints:** The source polysurface mapped from the source surface to the target surface. - -![](images/10-4/Creating/Packages - 01.png) -> **05-SVG-Import:** Since the custom nodes are able to map different types of curves, this last file references an SVG file exported from Illustrator and maps the imported curves to a target surface. - -![](images/10-4/Creating/Packages - 00.png) -> **05-SVG-Import:** By parsing through the syntax of a .svg file, curves are translated from .xml format to Dynamo polycurves. - -![](images/10-4/Creating/Packages - 02.png) -> **05-SVG-Import:** The imported curves are mapped to a target surface. This allows us to explicitly (point-and-click) design a panelization in Illustrator, import into Dynamo, and apply to a target surface. - - +##Developing a Package + +Dynamo offers a variety of ways to create a package for your personal use or for sharing with the Dynamo community. In the case study below, we'll walk through how a package is set up by deconstructing an existing one. This case study builds on lessons from the previous chapter, providing a set of custom nodes for mapping geometry, by UV coordinates, from one Dynamo surface to another. + +###MapToSurface +We're going to work with a sample package which demonstrates the UV mapping of points from one surface to another. We've already built the fundamentals of the tool in the [Creating a Custom Node](../09_Custom-Nodes/9-2_Creating.md) section of this primer. The files below demonstrate how we can take the concept of UV Mapping and develop a set of tools for a publishable library. + +![](images/10-4/uvMap.png) +> In this image, we map a point from one surface to another using UV coordinates. The package is based on this concept, but with more complex geometry. + +###Installing the Package +In the previous chapter, we explored ways for panelizing a surface in Dynamo based on curves defined in the XY plane. This case study extends these concepts for more dimensions of geometry. We're going to install this package as built in order to demonstrate how it was developed. In the next section, we'll demonstrate how this package was published. + +![](images/10-4/Creating/Packages - 14.png) +> This is the easy part. In Dynamo, navigate to *"Packages>Search for a Package..."* + +![](images/10-4/Creating/Packages - 13.png) +> Search for the package *"MapToSurface"* (all one word). +1. When the package is found, click on the big download arrow to the left of the package name. This will install the package into Dynamo. + +![](images/10-4/Publishing/packages - ui.png) +> 1. After installing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. With the package now installed, let's walk through how it's set up. + +###Custom Nodes +The package we're creating uses five custom nodes that we've built for reference. Let's walk through what each node does below. Some custom nodes build off of other custom nodes, and the graphs have a layout for other users to understand in a straightforward manner. + +![](images/10-4/Creating/Packages - 12.png) +> This is a simple package with five custom nodes. In the steps below, we'll briefly talk about each custom node's setup. + +![](images/10-4/Creating/Packages - 11.png) +> **PointsToSurface:** This is a basic custom node, and one from which all of the other mapping nodes are based. Simply put, the node maps a point from a source surface UV coordinate to the location of the target surface UV coordinate. And since points are the most primitive geometry, from which more complex geometry is built, we can use this logic to map 2D, and even 3D geometry from one surface to another. + +![](images/10-4/Creating/Packages - 10.png) +> **PolygonsToSurface:** the logic of extending mapped points from 1D geometry to 2D geometry is demonstrated simply with polygons here. Notice that we have nested the *"PointsToSurface"* node into this custom node. This way we can map the points of each polygon to the surface, and then regenerate the polygon from those mapped points. By maintaining the proper data structure (a list of lists of points), we're able to keep the polygons separate after they're reduced to a set of points. + +![](images/10-4/Creating/Packages - 09.png) +> **NurbsCrvtoSurface:** The same logic applies here as in the *"PolygonsToSurface"* node. But instead of mapping polygonal points, we're mapping control points of a nurbs curve. + +![](images/10-4/Creating/Packages - 08.png) +> **OffsetPointsToSurface:** This node gets a little more complex, but the concept is simple: like the *"PointsToSurface"* node, this node maps points from one surface to another. However, it also considers points which are not on the original source surface, gets their distance to the closest UV parameter, and maps this distance to the target surface normal at the corresponding UV coordinate. This will make more sense when looking at the example files. + +![](images/10-4/Creating/Packages - 07.png) +> **SampleSrf:** This is a simple node which creates a parametric surface to map from the source grid to an undulating surface in the example files. + +###Example Files +The example files can be found in the package's root folder (In Dynamo, navigate to this folder by going to *Packages>Manage Packages...*). + +![](images/10-4/Publishing/packages - showRoot.png) +> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* + +With the root directory open, navigate to the *"extra"* folder, which houses all of the files in the package which are not custom nodes. This is where examples files (if they exist) are stored for Dynamo packages. The screenshots below discuss the concepts demonstrated in each example file. + +![](images/10-4/Creating/Packages - 06.png) +> **01-PanelingWithPolygons:** This example file demonstrates how *"PointsToSurface"* may be used to panelize a surface based on a grid of rectangles. This should look familiar, as we demonstrated a similar workflow in the [previous chapter](../09_Custom-Nodes/9-2_Creating.md). + +![](images/10-4/Creating/Packages - 05.png) +> **02-PanelingWithPolygons-II:** Using a similar workflow, this exercise file shows a setup for mapping circles (or polygons representing circles) from one surface to another. This uses the *"PolygonsToSurface"* node. + +![](images/10-4/Creating/Packages - 04.png) +> **03-NurbsCrvsAndSurface:** This example file adds some complexity by working with the "NurbsCrvToSurface" node. The target surface is offset a given distance and the nurbs curve is mapped to the original target surface and the offset surface. From there, the two mapped curves are lofted to create a surface, which is then thickened. This resulting solid has an undulation that is representative of the target surface normals. + +![](images/10-4/Creating/Packages - 03A.png) +> **04-PleatedPolysurface-OffsetPoints:** This example file demonstrates how to map a pleated polysurface from a source surface to a target surface. The source and target surface are a rectangular surface spanning the grid and a revolved surface, respectively. + +![](images/10-4/Creating/Packages - 03.png) +> **04-PleatedPolysurface-OffsetPoints:** The source polysurface mapped from the source surface to the target surface. + +![](images/10-4/Creating/Packages - 01.png) +> **05-SVG-Import:** Since the custom nodes are able to map different types of curves, this last file references an SVG file exported from Illustrator and maps the imported curves to a target surface. + +![](images/10-4/Creating/Packages - 00.png) +> **05-SVG-Import:** By parsing through the syntax of a .svg file, curves are translated from .xml format to Dynamo polycurves. + +![](images/10-4/Creating/Packages - 02.png) +> **05-SVG-Import:** The imported curves are mapped to a target surface. This allows us to explicitly (point-and-click) design a panelization in Illustrator, import into Dynamo, and apply to a target surface. + + diff --git a/10_Packages/10-4_Publishing.md b/10_Packages/10-4_Publishing.md index 8d389a5a..e134d68b 100644 --- a/10_Packages/10-4_Publishing.md +++ b/10_Packages/10-4_Publishing.md @@ -1,60 +1,60 @@ -##Publishing a Package - -In the previous sections, we dove into the details of how our *MapToSurface* package is set up with custom nodes and example files. But how do we publish a package that has been developed locally? This case study demonstrates how to publish a package from a set of files in a local folder. -![](images/10-4/Creating/Packages - 12.png) -There are many ways to publish a package. Below is the process that we advise:** publish locally, develop locally, and then publish online**. We'll start with a folder containing all of the files in the package. - -###Uninstalling a Package -Before we jump into publishing the MapToSurface package, if you installed the package from the previous lesson, uninstall it so that you're not working with identical packages. - -![](images/10-4/Publishing/Packages - 01.png) -> Begin by going to *Packages>Manage Packages...* - -![](images/10-4/Publishing/uninstall.png) -> Select the button corresponding to *"MapToSurface"* and select *"Uninstall..."*. Then restart Dynamo. When reopening, when you check the *"Manage Packages"* window, the *MapToSurface* should no longer be there. Now we're ready to start from the beginning! - -###Publishing a Package Locally - -*Note: As of writing this, Dynamo package publication is only enabled in Dynamo Studio or Dynamo for Revit. Dynamo Sandbox does not have publishing functionality.* - ->Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [MapToSurface.zip](datasets/10-4/MapToSurface.zip) - -![](images/10-4/Publishing/Packages - 08.png) -> This is the first submission for our package, and we've placed all of the example files and custom nodes into one folder. With this folder prepared, we're ready to upload to the Dynamo Package Manager. -1. This folder contains five custom nodes (.dyf). -2. This folder also contains five example files (.dyn) and one imported vector file (.svg). These files will serve as introductory exercises to show the user how to work with the custom nodes. - -![](images/10-4/Publishing/Packages - 07.png) -> In Dynamo, begin by clicking *Packages>Publish New Package...* - -![](images/10-4/Publishing/Packages - 03.png) -> In the *"Publish a Dynamo Package"* window, we've filled out the relevant forms on the left of the window. -1. By clicking *"Add File"*, we've also added the files from the folder structure on the right side of the screen (to add files which are not .dyf files, be sure to change your file type in the browser window to **"All Files(*.*)"**. Notice that we've added every file, custom node (.dyf) or example file (.dyn), indiscriminately. Dynamo will categories these items when we publish the package. -2. The "Group" field defines which group to find the custom nodes in the Dynamo UI. -3. Publish by clicking "Publish Locally". If you're following along, be certain to click *"Publish Locally"* and **not** *"Publish Online"*; we don't want a bunch of duplicate packages on the Package Manager. - -![](images/10-4/Publishing/packages - ui.png) -> 1. After publishing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. - -![](images/10-4/Publishing/Packages - 01.png) -> Now let's look at the root directory to see how Dynamo has formatted the package we just created. Do this by clicking *Packages>Manage Packages...* - -![](images/10-4/Publishing/packages - showRoot.png) -> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* - -![](images/10-4/Publishing/Packages - 02.png) -> Notice that the root directory is in the local location of your package (remember, we published the package "locally"). Dynamo is currently referencing this folder to read custom nodes. It's therefore important to locally publish the directory to a permanent folder location (ie: not your desktop). Here is the Dynamo package folder breakdown: -1. The *bin* folder houses .dll files created with C# or Zero-Touch libraries. We don't have any for this package so this folder is blank for this example. -2. The *dyf* folder houses the custom nodes. Opening this will reveal all of the custom nodes (.dyf files) for this package. -3. The extra folder houses all additional files. These files are likely to be Dynamo Files (.dyn) or any additional files required (.svg, .xls, .jpeg, .sat, etc.). -4. The pkg file is a basic text file defining the package settings. This is automated in Dynamo, but can be edited if you want to get into the details. - -###Publishing a Package Online - -![](images/10-4/Publishing/Packages - 00.png) -> **Note: please do not follow along with this step unless you are actually publishing a package of your own!** -1. When you're ready to publish, in the "Manage Packages" window, select the button the right of MapToSurface and choose *Publish...* -2. If you're updating a package that has already been published, choose "Publish Version" and Dynamo will update your package online based on the new files in that package's root directory. Simple as that! - -###Publish Version... -When you update the files in your published package's root folder, you can publish a new version of the package by selecting *"Publish Version..."* in the *Manage Packages* window. This is a seamless way to make necessary updates to your content and share with the community. *Publish Version* will only work if you're the maintainer of the package. +##Publishing a Package + +In the previous sections, we dove into the details of how our *MapToSurface* package is set up with custom nodes and example files. But how do we publish a package that has been developed locally? This case study demonstrates how to publish a package from a set of files in a local folder. +![](images/10-4/Creating/Packages - 12.png) +There are many ways to publish a package. Below is the process that we advise:** publish locally, develop locally, and then publish online**. We'll start with a folder containing all of the files in the package. + +###Uninstalling a Package +Before we jump into publishing the MapToSurface package, if you installed the package from the previous lesson, uninstall it so that you're not working with identical packages. + +![](images/10-4/Publishing/Packages - 01.png) +> Begin by going to *Packages>Manage Packages...* + +![](images/10-4/Publishing/uninstall.png) +> Select the button corresponding to *"MapToSurface"* and select *"Uninstall..."*. Then restart Dynamo. When reopening, when you check the *"Manage Packages"* window, the *MapToSurface* should no longer be there. Now we're ready to start from the beginning! + +###Publishing a Package Locally + +*Note: As of writing this, Dynamo package publication is only enabled in Dynamo Studio or Dynamo for Revit. Dynamo Sandbox does not have publishing functionality.* + +>Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [MapToSurface.zip](datasets/10-4/MapToSurface.zip) + +![](images/10-4/Publishing/Packages - 08.png) +> This is the first submission for our package, and we've placed all of the example files and custom nodes into one folder. With this folder prepared, we're ready to upload to the Dynamo Package Manager. +1. This folder contains five custom nodes (.dyf). +2. This folder also contains five example files (.dyn) and one imported vector file (.svg). These files will serve as introductory exercises to show the user how to work with the custom nodes. + +![](images/10-4/Publishing/Packages - 07.png) +> In Dynamo, begin by clicking *Packages>Publish New Package...* + +![](images/10-4/Publishing/Packages - 03.png) +> In the *"Publish a Dynamo Package"* window, we've filled out the relevant forms on the left of the window. +1. By clicking *"Add File"*, we've also added the files from the folder structure on the right side of the screen (to add files which are not .dyf files, be sure to change your file type in the browser window to **"All Files(*.*)"**. Notice that we've added every file, custom node (.dyf) or example file (.dyn), indiscriminately. Dynamo will categories these items when we publish the package. +2. The "Group" field defines which group to find the custom nodes in the Dynamo UI. +3. Publish by clicking "Publish Locally". If you're following along, be certain to click *"Publish Locally"* and **not** *"Publish Online"*; we don't want a bunch of duplicate packages on the Package Manager. + +![](images/10-4/Publishing/packages - ui.png) +> 1. After publishing, the custom nodes should be available under the "DynamoPrimer" group or your Dynamo Library. + +![](images/10-4/Publishing/Packages - 01.png) +> Now let's look at the root directory to see how Dynamo has formatted the package we just created. Do this by clicking *Packages>Manage Packages...* + +![](images/10-4/Publishing/packages - showRoot.png) +> In the manage packages window, click on the three vertical dots to the right of *"MapToSurface"* and choose *"Show Root Directory".* + +![](images/10-4/Publishing/Packages - 02.png) +> Notice that the root directory is in the local location of your package (remember, we published the package "locally"). Dynamo is currently referencing this folder to read custom nodes. It's therefore important to locally publish the directory to a permanent folder location (ie: not your desktop). Here is the Dynamo package folder breakdown: +1. The *bin* folder houses .dll files created with C# or Zero-Touch libraries. We don't have any for this package so this folder is blank for this example. +2. The *dyf* folder houses the custom nodes. Opening this will reveal all of the custom nodes (.dyf files) for this package. +3. The extra folder houses all additional files. These files are likely to be Dynamo Files (.dyn) or any additional files required (.svg, .xls, .jpeg, .sat, etc.). +4. The pkg file is a basic text file defining the package settings. This is automated in Dynamo, but can be edited if you want to get into the details. + +###Publishing a Package Online + +![](images/10-4/Publishing/Packages - 00.png) +> **Note: please do not follow along with this step unless you are actually publishing a package of your own!** +1. When you're ready to publish, in the "Manage Packages" window, select the button the right of MapToSurface and choose *Publish...* +2. If you're updating a package that has already been published, choose "Publish Version" and Dynamo will update your package online based on the new files in that package's root directory. Simple as that! + +###Publish Version... +When you update the files in your published package's root folder, you can publish a new version of the package by selecting *"Publish Version..."* in the *Manage Packages* window. This is a seamless way to make necessary updates to your content and share with the community. *Publish Version* will only work if you're the maintainer of the package. diff --git a/10_Packages/10-5_Zero-Touch.md b/10_Packages/10-5_Zero-Touch.md index 7d6978fb..bee9a725 100644 --- a/10_Packages/10-5_Zero-Touch.md +++ b/10_Packages/10-5_Zero-Touch.md @@ -1,230 +1,230 @@ - - -## What is Zero-Touch? - -Zero-Touch Importing refers to a simple point-and-click method for importing C# libraries. Dynamo will read the public methods of a *.dll* file and convert them to Dynamo nodes. You can use Zero-Touch to develop your own custom nodes and packages, and to import external libraries into the Dynamo environment. - -![](images/10-5/annotate.jpg) - -With Zero-Touch, you can actually import a library which was not necessarily developed for Dynamo and create a suite of new nodes. The current Zero-Touch functionality demonstrates the cross-platform mentality of the Dynamo Project. - -This section demonstrates how to use Zero-Touch to import a third party library. For information on developing your own Zero-Touch Library, reference the [Dynamo wiki page](https://github.com/DynamoDS/Dynamo/wiki/Zero-Touch-Plugin-Development). - -###Zero-Touch Packages -Zero-touch packages are a good complement to user-defined custom nodes. A few packages which use C# libraries are listed in the table below. For more detailed information on packages, visit the [Packages section ](../Appendix/A-3_packages.md)in the Appendix. - - - - - - - - - - - - - - - - - - - - - - - - -
Logo/ImageName
Mesh Toolkit
Dynamo Unfold
Rhynamo
Optimo
- - -### Case Study - Importing AForge -In this case study, we'll show how to import the [AForge](http://www.aforgenet.com/) external *.dll* library. AForge is a robust library which offers a range of functionality from image processing to artificial intelligence. We'll reference the imaging class in AForge to do a few image processing exercises below. - - ->Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Zero-Touch-Examples.zip](datasets/10-5/Zero-Touch-Examples.zip). - -> 1. Let's beging by downloading AForge. On the [AForge download page](http://www.aforgenet.com/framework/downloads.html), select *[Download Installer]* and install after download has completed. - -![Exercise](images/10-5/import.png) ->1. In Dynamo, create a new file and select *File > Import Library...* - -![Exercise](images/10-5/folder.png) ->1. In the pop-up window, navigate to the release folder in your Dynamo install. This will likely be in a folder similar to this one: *C:\Program Files (x86)\AForge.NET\Framework\Release*. -2. **AForge.Imaging.dll:** We only want to use this one file from the AForge library for this case study. Select this *.dll* and hit *"Open".* - -![Exercise](images/10-5/library.png) ->1. Back in Dynamo, you should see an *"AForge" *group of nodes added to your Library Toolbar. We now have access to the AForge imaging library from our visual program! - -### Exercise 1 - Edge Detection - -Now that the library's imported, we'll start off simple with this first exercise. We'll do some basic image processing on a sample image to show how AForge image filters. We'll use the *"Watch Image"* node to show our results and apply filters in Dynamo similar to those in Photoshop. - ->Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [ZeroTouchImages.zip](datasets/10-5/ZeroTouchImages.zip) - -Now that the library's imported, we'll start off simple with this first exercise (*01-EdgeDetection.dyn*). We'll do some basic image processing on a sample image to show how AForge image filters. We'll use the *"Watch Image"* node to show our results and apply filters in Dynamo similar to those in Photoshop - -![Exercise](images/10-5/Exercise/AForge- 23.png) -> First, we want to import an image to work with. Add a *File Path* node to the canvas and select "soapbubbles.jpg" from the downloaded exercise folder (photo cred: [flickr](https://www.flickr.com/photos/wwworks/667298782)). - -![Exercise](images/10-5/Exercise/AForge- 21.png) -> 1. The File Path node simply provides a String of the path to the image we've selected. We need to convert this File Path to an image in the Dynamo environment. -2. Connect the File Path node to the File.FromPath node. -3. To convert this File into an Image, we'll use the Image.ReadFromFile node. -4. Last, let's see the result! Drop a Watch Image node onto the canvas and connect to Image.ReadFromFile. We haven't used AForge yet, but we've successfully imported and image into Dynamo. - -![Exercise](images/10-5/Exercise/AForge- 18.png) -> Under AForge.Imaging.AForge.Filters (in the navigation menu), you'll notice that there is a wide array of filters available. We're going to use one of these filters now to desaturate an image based on threshold values. -1. Drop three sliders onto the canvas, change their ranges to be from 0 to 1 and their step values to be 0.01. -2. Add the Grayscale.Grayscale node to the canvas. This is an AForge filter which applies a grayscale filter to an image. Connect the three sliders from step 1 into cr, cg, and cb. Change the top and bottom sliders to have a value of 1 and the middle slider to have a value of 0. -3. In order to apply the Grayscale filter, we need an action to perform on our image. For this, we use IFilter.Apply. Connect the image into the image input and Grayscale.Grayscale into the iFilter input. -4. Plugging into a Watch Image node, we get a desaturated image. - -![Exercise](images/10-5/Exercise/AForge- 19.png) -> We can have control over how to desaturate this image based on threshold values for red, green, and blue. These are defined by the inputs to the Grayscale.Grayscale node. Notice that the image looks pretty dim - this is because the green value is set to 0 from our slider. -1. Change the top and bottom sliders to have a value of 0 and the middle slider to have a value of 1. This way we get a more legible desaturated image. - -![Exercise](images/10-5/Exercise/AForge- 17.png) -> Let's use the desaturated image, and apply another filter on top of it. The desaturated image has some contrast, so we we're going to test some edge detection. -1. Add a SobelEdgeDetector.SobelEdgeDetector node to the canvas. Connect this as the IFilter to a new IFilter node, and connect the desaturated image to the image input of the IFilter node. -2. The Sobel Edge Detector has highlighted the edges in a new image. - -![Exercise](images/10-5/Exercise/AForge- 16.png) -> Zooming in, the edge detector has called out the outlines of the bubbles with pixels. The AForge library has tools to take results like this and create Dynamo geometry. We'll explore that in the next exercise. - -### Exercise 2 - Rectangle Creation - ->Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [ZeroTouchImages.zip](datasets/10-5/ZeroTouchImages.zip) - -Now that we're introduced to some basic image processing, let's use an image to drive Dynamo geometry! On an elementary level, in this exercise we're aiming to do a *"Live Trace"* of an image using AForge and Dynamo. We're going to keep it simple and extract rectangles from a reference image, but there are tools available in AForge for more complex operations. We'll be working with *02-RectangleCreation.dyn* from the downloaded exercise files. - -![Exercise](images/10-5/Exercise/AForge- 15.png) -> 1. With the File Path node, navigate to grid.jpg in the exercise folder. -2. Connect the remaining series of nodes above to reveal a course parametric grid. - -In this next step, we want to reference the white squares in the image and convert them to actual Dynamo geometry. AForge has a lot of powerful Computer Vision tools, and here we're going to use a particularly important one for the library called [BlobCounter](http://www.aforgenet.com/framework/docs/html/d7d5c028-7a23-e27d-ffd0-5df57cbd31a6.htm). - -![Exercise](images/10-5/Exercise/AForge- 14.png) -> 1. After adding a BlobCounter to the canvas, we need a way to process the image (similar to the IFilter tool in the previous exercise). Unfortunately the "Process Image" node is not immediately visible in the Dynamo library. This is because the function may not be visible in the AForge source code. In order to fix this, we'll need to find a work-around. - -![Exercise](images/10-5/Exercise/AForge- 13.png) -> 1. Add a Python node to the canvas. - -``` -import clr -clr.AddReference('AForge.Imaging') -from AForge.Imaging import * - -bc= BlobCounter() -bc.ProcessImage(IN[0]) -OUT=bc - -``` -> Add the code above to the Python node. This code imports the AForge library and then processes the imported image. - -![Exercise](images/10-5/Exercise/AForge- 11.png) -> Connecting the image output to the Python node input, we get an AForge.Imaging.BlobCounter result from the Python node. - -The next steps will do some tricks that demonstrate familiarity with the [AForge Imaging API](http://www.aforgenet.com/framework/docs/html/d087503e-77da-dc47-0e33-788275035a90.htm). It's not necessary to learn all of this for Dynamo work. This is more of a demonstration of working with external libraries within the flexibility of the Dynamo environment. - -![Exercise](images/10-5/Exercise/AForge- 10.png) -> 1. Connect the output of the Python script to BlobCounterBase.GetObjectRectangles. This reads objects in an image, based on a threshold value, and extracts quantified rectangles from the pixel space. - -![Exercise](images/10-5/Exercise/AForge- 09.png) -> 1. Adding another Python node to the canvas, connect to the GetObjectRectangles, and input the code below. This will create an organized list of Dynamo objects. - -``` -OUT = [] -for rec in IN[0]: - subOUT=[] - subOUT.append(rec.X) - subOUT.append(rec.Y) - subOUT.append(rec.Width) - subOUT.append(rec.Height) - OUT.append(subOUT) - ``` - -![Exercise](images/10-5/Exercise/AForge- 06.png) -> 1. Transpose the output of the Python node from the previous step. This creates 4 lists, each representing X,Y, Width, and Height for each rectangle. ->2. Using Code Block, we organize the data into a structure that accommodates the Rectangle.ByCornerPoints node (code below). - -``` -recData; -x0=List.GetItemAtIndex(recData,0); -y0=List.GetItemAtIndex(recData,1); -width=List.GetItemAtIndex(recData,2); -height=List.GetItemAtIndex(recData,3); -x1=x0+width; -y1=y0+height; -p0=Autodesk.Point.ByCoordinates(x0,y0); -p1=Autodesk.Point.ByCoordinates(x0,y1); -p2=Autodesk.Point.ByCoordinates(x1,y1); -p3=Autodesk.Point.ByCoordinates(x1,y0); -``` - -![Exercise](images/10-5/Exercise/AForge- 05.png) -> Zooming out, we have an array of rectangles representing the white squares in the image. Through programming, we've done something (roughly) similar to a live trace in Illustrator! - -![Exercise](images/10-5/Exercise/AForge- 04.png) -> We still need some cleanup, however. Zooming in, we can see that we have a bunch of small, unwanted rectangles. - -![Exercise](images/10-5/Exercise/AForge- 03.png) -> 1. We get rid of the unwanted rectangles by inserting a Python node in between the GetObjectRectangles node and another Python node. The node's code is below, and removes all rectangles which are below a given size. - -``` -rectangles=IN[0] -OUT=[] -for rec in rectangles: - if rec.Width>8 and rec.Height>8: - OUT.append(rec) - ``` - -![Exercise](images/10-5/Exercise/AForge- 01.png) -> With the superfluous rectangles gone, just for kicks, let's create a surface from these rectangles and extrude them by a distance based on their areas. - -![Exercise](images/10-5/Exercise/AForge- 00.png) -> 1. Last, change the both_sides input to false and we get an extrusion in one direction. Dip this baby in resin and you've got yourself one super nerdy table. - -These are basic examples, but the concepts outlined here are transferable to exciting real-world applications. Computer vision can be used for a whole host of processes. To name a few: barcode readers, perspective matching, [projection mapping](https://www.youtube.com/watch?v=XSR0Xady02o), and [augmented reality](http://aforgenet.com/aforge/articles/gratf_ar/). For more advanced topics with AForge related to this exercise, have a read through [this article](http://aforgenet.com/articles/shape_checker/). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +## What is Zero-Touch? + +Zero-Touch Importing refers to a simple point-and-click method for importing C# libraries. Dynamo will read the public methods of a *.dll* file and convert them to Dynamo nodes. You can use Zero-Touch to develop your own custom nodes and packages, and to import external libraries into the Dynamo environment. + +![](images/10-5/annotate.jpg) + +With Zero-Touch, you can actually import a library which was not necessarily developed for Dynamo and create a suite of new nodes. The current Zero-Touch functionality demonstrates the cross-platform mentality of the Dynamo Project. + +This section demonstrates how to use Zero-Touch to import a third party library. For information on developing your own Zero-Touch Library, reference the [Dynamo wiki page](https://github.com/DynamoDS/Dynamo/wiki/Zero-Touch-Plugin-Development). + +###Zero-Touch Packages +Zero-touch packages are a good complement to user-defined custom nodes. A few packages which use C# libraries are listed in the table below. For more detailed information on packages, visit the [Packages section ](../Appendix/A-3_packages.md)in the Appendix. + + + + + + + + + + + + + + + + + + + + + + + + +
Logo/ImageName
Mesh Toolkit
Dynamo Unfold
Rhynamo
Optimo
+ + +### Case Study - Importing AForge +In this case study, we'll show how to import the [AForge](http://www.aforgenet.com/) external *.dll* library. AForge is a robust library which offers a range of functionality from image processing to artificial intelligence. We'll reference the imaging class in AForge to do a few image processing exercises below. + + +>Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Zero-Touch-Examples.zip](datasets/10-5/Zero-Touch-Examples.zip). + +> 1. Let's beging by downloading AForge. On the [AForge download page](http://www.aforgenet.com/framework/downloads.html), select *[Download Installer]* and install after download has completed. + +![Exercise](images/10-5/import.png) +>1. In Dynamo, create a new file and select *File > Import Library...* + +![Exercise](images/10-5/folder.png) +>1. In the pop-up window, navigate to the release folder in your Dynamo install. This will likely be in a folder similar to this one: *C:\Program Files (x86)\AForge.NET\Framework\Release*. +2. **AForge.Imaging.dll:** We only want to use this one file from the AForge library for this case study. Select this *.dll* and hit *"Open".* + +![Exercise](images/10-5/library.png) +>1. Back in Dynamo, you should see an *"AForge" *group of nodes added to your Library Toolbar. We now have access to the AForge imaging library from our visual program! + +### Exercise 1 - Edge Detection + +Now that the library's imported, we'll start off simple with this first exercise. We'll do some basic image processing on a sample image to show how AForge image filters. We'll use the *"Watch Image"* node to show our results and apply filters in Dynamo similar to those in Photoshop. + +>Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [ZeroTouchImages.zip](datasets/10-5/ZeroTouchImages.zip) + +Now that the library's imported, we'll start off simple with this first exercise (*01-EdgeDetection.dyn*). We'll do some basic image processing on a sample image to show how AForge image filters. We'll use the *"Watch Image"* node to show our results and apply filters in Dynamo similar to those in Photoshop + +![Exercise](images/10-5/Exercise/AForge- 23.png) +> First, we want to import an image to work with. Add a *File Path* node to the canvas and select "soapbubbles.jpg" from the downloaded exercise folder (photo cred: [flickr](https://www.flickr.com/photos/wwworks/667298782)). + +![Exercise](images/10-5/Exercise/AForge- 21.png) +> 1. The File Path node simply provides a String of the path to the image we've selected. We need to convert this File Path to an image in the Dynamo environment. +2. Connect the File Path node to the File.FromPath node. +3. To convert this File into an Image, we'll use the Image.ReadFromFile node. +4. Last, let's see the result! Drop a Watch Image node onto the canvas and connect to Image.ReadFromFile. We haven't used AForge yet, but we've successfully imported and image into Dynamo. + +![Exercise](images/10-5/Exercise/AForge- 18.png) +> Under AForge.Imaging.AForge.Filters (in the navigation menu), you'll notice that there is a wide array of filters available. We're going to use one of these filters now to desaturate an image based on threshold values. +1. Drop three sliders onto the canvas, change their ranges to be from 0 to 1 and their step values to be 0.01. +2. Add the Grayscale.Grayscale node to the canvas. This is an AForge filter which applies a grayscale filter to an image. Connect the three sliders from step 1 into cr, cg, and cb. Change the top and bottom sliders to have a value of 1 and the middle slider to have a value of 0. +3. In order to apply the Grayscale filter, we need an action to perform on our image. For this, we use IFilter.Apply. Connect the image into the image input and Grayscale.Grayscale into the iFilter input. +4. Plugging into a Watch Image node, we get a desaturated image. + +![Exercise](images/10-5/Exercise/AForge- 19.png) +> We can have control over how to desaturate this image based on threshold values for red, green, and blue. These are defined by the inputs to the Grayscale.Grayscale node. Notice that the image looks pretty dim - this is because the green value is set to 0 from our slider. +1. Change the top and bottom sliders to have a value of 0 and the middle slider to have a value of 1. This way we get a more legible desaturated image. + +![Exercise](images/10-5/Exercise/AForge- 17.png) +> Let's use the desaturated image, and apply another filter on top of it. The desaturated image has some contrast, so we we're going to test some edge detection. +1. Add a SobelEdgeDetector.SobelEdgeDetector node to the canvas. Connect this as the IFilter to a new IFilter node, and connect the desaturated image to the image input of the IFilter node. +2. The Sobel Edge Detector has highlighted the edges in a new image. + +![Exercise](images/10-5/Exercise/AForge- 16.png) +> Zooming in, the edge detector has called out the outlines of the bubbles with pixels. The AForge library has tools to take results like this and create Dynamo geometry. We'll explore that in the next exercise. + +### Exercise 2 - Rectangle Creation + +>Download and unzip the example files that accompany this package case study (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [ZeroTouchImages.zip](datasets/10-5/ZeroTouchImages.zip) + +Now that we're introduced to some basic image processing, let's use an image to drive Dynamo geometry! On an elementary level, in this exercise we're aiming to do a *"Live Trace"* of an image using AForge and Dynamo. We're going to keep it simple and extract rectangles from a reference image, but there are tools available in AForge for more complex operations. We'll be working with *02-RectangleCreation.dyn* from the downloaded exercise files. + +![Exercise](images/10-5/Exercise/AForge- 15.png) +> 1. With the File Path node, navigate to grid.jpg in the exercise folder. +2. Connect the remaining series of nodes above to reveal a course parametric grid. + +In this next step, we want to reference the white squares in the image and convert them to actual Dynamo geometry. AForge has a lot of powerful Computer Vision tools, and here we're going to use a particularly important one for the library called [BlobCounter](http://www.aforgenet.com/framework/docs/html/d7d5c028-7a23-e27d-ffd0-5df57cbd31a6.htm). + +![Exercise](images/10-5/Exercise/AForge- 14.png) +> 1. After adding a BlobCounter to the canvas, we need a way to process the image (similar to the IFilter tool in the previous exercise). Unfortunately the "Process Image" node is not immediately visible in the Dynamo library. This is because the function may not be visible in the AForge source code. In order to fix this, we'll need to find a work-around. + +![Exercise](images/10-5/Exercise/AForge- 13.png) +> 1. Add a Python node to the canvas. + +``` +import clr +clr.AddReference('AForge.Imaging') +from AForge.Imaging import * + +bc= BlobCounter() +bc.ProcessImage(IN[0]) +OUT=bc + +``` +> Add the code above to the Python node. This code imports the AForge library and then processes the imported image. + +![Exercise](images/10-5/Exercise/AForge- 11.png) +> Connecting the image output to the Python node input, we get an AForge.Imaging.BlobCounter result from the Python node. + +The next steps will do some tricks that demonstrate familiarity with the [AForge Imaging API](http://www.aforgenet.com/framework/docs/html/d087503e-77da-dc47-0e33-788275035a90.htm). It's not necessary to learn all of this for Dynamo work. This is more of a demonstration of working with external libraries within the flexibility of the Dynamo environment. + +![Exercise](images/10-5/Exercise/AForge- 10.png) +> 1. Connect the output of the Python script to BlobCounterBase.GetObjectRectangles. This reads objects in an image, based on a threshold value, and extracts quantified rectangles from the pixel space. + +![Exercise](images/10-5/Exercise/AForge- 09.png) +> 1. Adding another Python node to the canvas, connect to the GetObjectRectangles, and input the code below. This will create an organized list of Dynamo objects. + +``` +OUT = [] +for rec in IN[0]: + subOUT=[] + subOUT.append(rec.X) + subOUT.append(rec.Y) + subOUT.append(rec.Width) + subOUT.append(rec.Height) + OUT.append(subOUT) + ``` + +![Exercise](images/10-5/Exercise/AForge- 06.png) +> 1. Transpose the output of the Python node from the previous step. This creates 4 lists, each representing X,Y, Width, and Height for each rectangle. +>2. Using Code Block, we organize the data into a structure that accommodates the Rectangle.ByCornerPoints node (code below). + +``` +recData; +x0=List.GetItemAtIndex(recData,0); +y0=List.GetItemAtIndex(recData,1); +width=List.GetItemAtIndex(recData,2); +height=List.GetItemAtIndex(recData,3); +x1=x0+width; +y1=y0+height; +p0=Autodesk.Point.ByCoordinates(x0,y0); +p1=Autodesk.Point.ByCoordinates(x0,y1); +p2=Autodesk.Point.ByCoordinates(x1,y1); +p3=Autodesk.Point.ByCoordinates(x1,y0); +``` + +![Exercise](images/10-5/Exercise/AForge- 05.png) +> Zooming out, we have an array of rectangles representing the white squares in the image. Through programming, we've done something (roughly) similar to a live trace in Illustrator! + +![Exercise](images/10-5/Exercise/AForge- 04.png) +> We still need some cleanup, however. Zooming in, we can see that we have a bunch of small, unwanted rectangles. + +![Exercise](images/10-5/Exercise/AForge- 03.png) +> 1. We get rid of the unwanted rectangles by inserting a Python node in between the GetObjectRectangles node and another Python node. The node's code is below, and removes all rectangles which are below a given size. + +``` +rectangles=IN[0] +OUT=[] +for rec in rectangles: + if rec.Width>8 and rec.Height>8: + OUT.append(rec) + ``` + +![Exercise](images/10-5/Exercise/AForge- 01.png) +> With the superfluous rectangles gone, just for kicks, let's create a surface from these rectangles and extrude them by a distance based on their areas. + +![Exercise](images/10-5/Exercise/AForge- 00.png) +> 1. Last, change the both_sides input to false and we get an extrusion in one direction. Dip this baby in resin and you've got yourself one super nerdy table. + +These are basic examples, but the concepts outlined here are transferable to exciting real-world applications. Computer vision can be used for a whole host of processes. To name a few: barcode readers, perspective matching, [projection mapping](https://www.youtube.com/watch?v=XSR0Xady02o), and [augmented reality](http://aforgenet.com/aforge/articles/gratf_ar/). For more advanced topics with AForge related to this exercise, have a read through [this article](http://aforgenet.com/articles/shape_checker/). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/10_Packages/10-Packages.md b/10_Packages/10-Packages.md index 8666742f..3a213331 100644 --- a/10_Packages/10-Packages.md +++ b/10_Packages/10-Packages.md @@ -1,5 +1,5 @@ -# Packages - -Once you have created a few Custom Nodes the very next step is to begin organizing and publishing them by way of Packages - a convenient way to store and share your nodes with the Dynamo Community. - -![IMAGE](images/10/packages_cover01.png) +# Packages + +Once you have created a few Custom Nodes the very next step is to begin organizing and publishing them by way of Packages - a convenient way to store and share your nodes with the Dynamo Community. + +![IMAGE](images/10/packages_cover01.png) diff --git a/10_Packages/datasets/10-2/Mesh-Toolkit_Intersect-Mesh.dyn b/10_Packages/datasets/10-2/Mesh-Toolkit_Intersect-Mesh.dyn index 66d04c48..5e988d88 100644 --- a/10_Packages/datasets/10-2/Mesh-Toolkit_Intersect-Mesh.dyn +++ b/10_Packages/datasets/10-2/Mesh-Toolkit_Intersect-Mesh.dyn @@ -1,163 +1,163 @@ - - - - - - C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\stanford_bunny_tri.obj - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + C:\Users\Mode Lab_01\Documents\MODE LAB\CONSULTING\AUTODESK\DYNAMO PRIMER\stanford_bunny_tri.obj + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/11_Web_Experience/11-1_Introduction.md b/11_Web_Experience/11-1_Introduction.md index dd48c46e..426edbb4 100644 --- a/11_Web_Experience/11-1_Introduction.md +++ b/11_Web_Experience/11-1_Introduction.md @@ -1,8 +1,8 @@ -##Dynamo Web Experience - -You can now experience Dynamo on the web beginning with the 'Send to Web' feature available in Dynamo Studio. The 'Send to Web' feature allows others to interact with your scripts via a pared down interface, the Customizer view, consisting of allowable inputs such as sliders, numbers, and booleans. This makes your scripts accessible to a wider group of users who may not be familiar with Dynamo or Visual Programming. - -![](images/Web_01.png) -> Dynamo on the Web - - +##Dynamo Web Experience + +You can now experience Dynamo on the web beginning with the 'Send to Web' feature available in Dynamo Studio. The 'Send to Web' feature allows others to interact with your scripts via a pared down interface, the Customizer view, consisting of allowable inputs such as sliders, numbers, and booleans. This makes your scripts accessible to a wider group of users who may not be familiar with Dynamo or Visual Programming. + +![](images/Web_01.png) +> Dynamo on the Web + + diff --git a/11_Web_Experience/11-2_Send_to_Web.md b/11_Web_Experience/11-2_Send_to_Web.md index f8b51000..49ebdd29 100644 --- a/11_Web_Experience/11-2_Send_to_Web.md +++ b/11_Web_Experience/11-2_Send_to_Web.md @@ -1,50 +1,50 @@ -##Send to Web (with Dynamo Studio) - -Publishing your files to the web is quick and easy with Dynamo Studio. However, you may want to spend some time selecting and labeling your inputs and making your file user-friendly. If you need to download Dynamo Studio, please visit the [Autodesk website](http://www.autodesk.com/products/dynamo-studio/overview) for more information. - -###Exercise: Preparing to 'Send to Web' - ->Download the example files for this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Download the Attractor Scale Example](datasets/Attractor Scale.dyn) - -In this exercise, we will publish a Dynamo graph to the web. This file creates a grid of rectangles that are scaled based on an attractor and mapped from a base to a target surface. Surface patches are created from each rectangle, and colored based on their distance from the attractor. - -![](images/publishing_00.png) ->This is the customizer we are going to make. View this example on the [web](dynamo.autodesk.com/share/572a49033a47345a0407e803). - -To prepare your script for publishing, first decide which inputs will be accessible to users. Allowable inputs include sliders, numbers, strings, and booleans. Code Blocks and File Paths cannot be used as inputs. Turn off “Is Input” via the context menu on any inputs that you don’t want to be exposed in the Customizer view. Make sure any slider inputs have reasonable minimum and maximum values. - - -![](images/publishing_01.png) ->Uncheck “Is Input” via the context menu on any inputs that you don't want to be exposed in the Customizer. - -Second, ensure that your inputs are clearly labelled. - -![](images/publishing_02.png) ->Label the inputs by double clicking the node name to edit it. - -Include preview geometry that makes your script easy to understand. In this example, a sphere shows the attractor location, and surfaces are colored based on their distance to the attractor. This makes the attractor influence easy to visualize and understand. - -![](images/publishing_03.png) - -###Publish Your File - -When you are ready to publish your file, select “Send to Web” from the File menu. - -![](images/publishing_04.jpg) - -Enter a description of your file and any instructions needed to get started. -Once your file is published, you can send a link to anyone with an Autodesk account. The file will be published with the current input values and previews. - -![](images/publishing_05.jpg) - ->View this example on the [web](dynamo.autodesk.com/share/572a49033a47345a0407e803) - -###Managing Published Files - -To manage your published scripts, visit https://dynamo.autodesk.com and sign in to your account. Select “Manage” from the drop down in the top right. On this page, you can edit, share, or delete workspaces that you have already published. This page is also accessible via "Manage Web Workspaces" in the Dynamo Studio File menu. - -![](images/publishing_07.png) ->1. Edit Workspace -2. Delete Workspace -3. Share Link - +##Send to Web (with Dynamo Studio) + +Publishing your files to the web is quick and easy with Dynamo Studio. However, you may want to spend some time selecting and labeling your inputs and making your file user-friendly. If you need to download Dynamo Studio, please visit the [Autodesk website](http://www.autodesk.com/products/dynamo-studio/overview) for more information. + +###Exercise: Preparing to 'Send to Web' + +>Download the example files for this exercise (Right click and "Save Link As..."). A full list of example files can be found in the Appendix. [Download the Attractor Scale Example](datasets/Attractor Scale.dyn) + +In this exercise, we will publish a Dynamo graph to the web. This file creates a grid of rectangles that are scaled based on an attractor and mapped from a base to a target surface. Surface patches are created from each rectangle, and colored based on their distance from the attractor. + +![](images/publishing_00.png) +>This is the customizer we are going to make. View this example on the [web](dynamo.autodesk.com/share/572a49033a47345a0407e803). + +To prepare your script for publishing, first decide which inputs will be accessible to users. Allowable inputs include sliders, numbers, strings, and booleans. Code Blocks and File Paths cannot be used as inputs. Turn off “Is Input” via the context menu on any inputs that you don’t want to be exposed in the Customizer view. Make sure any slider inputs have reasonable minimum and maximum values. + + +![](images/publishing_01.png) +>Uncheck “Is Input” via the context menu on any inputs that you don't want to be exposed in the Customizer. + +Second, ensure that your inputs are clearly labelled. + +![](images/publishing_02.png) +>Label the inputs by double clicking the node name to edit it. + +Include preview geometry that makes your script easy to understand. In this example, a sphere shows the attractor location, and surfaces are colored based on their distance to the attractor. This makes the attractor influence easy to visualize and understand. + +![](images/publishing_03.png) + +###Publish Your File + +When you are ready to publish your file, select “Send to Web” from the File menu. + +![](images/publishing_04.jpg) + +Enter a description of your file and any instructions needed to get started. +Once your file is published, you can send a link to anyone with an Autodesk account. The file will be published with the current input values and previews. + +![](images/publishing_05.jpg) + +>View this example on the [web](dynamo.autodesk.com/share/572a49033a47345a0407e803) + +###Managing Published Files + +To manage your published scripts, visit https://dynamo.autodesk.com and sign in to your account. Select “Manage” from the drop down in the top right. On this page, you can edit, share, or delete workspaces that you have already published. This page is also accessible via "Manage Web Workspaces" in the Dynamo Studio File menu. + +![](images/publishing_07.png) +>1. Edit Workspace +2. Delete Workspace +3. Share Link + diff --git a/11_Web_Experience/11-3_Customizer_View.md b/11_Web_Experience/11-3_Customizer_View.md index e08bb4b9..fef8cb37 100644 --- a/11_Web_Experience/11-3_Customizer_View.md +++ b/11_Web_Experience/11-3_Customizer_View.md @@ -1,47 +1,47 @@ -##The Customizer View - -The Dynamo Customizer view allows others to interact with your Dynamo scripts on the web via a simplified, curated interface consisting of inputs such as sliders, numbers, and booleans. - -By condensing complex graphs into a simple interface, the Customizer view makes your scripts accessible to a wider community of users who may not be familiar with Dynamo, Visual Programming, or 3D modeling. Anyone with an Autodesk account can access your Dynamo script in a Customizer View through a shared link, allowing them to interact with your script without a Dynamo license. - -In the Customizer view, users can export geometry as an STL mesh for rapid prototyping, or as a Dynamo file. - -![](images/customizer_00.png) ->Customizer View examples available at https://dynamo.autodesk.com/ - -###Customizer View UI - -The Customizer view consists of a menu bar, a flyout menu containing a description of the file and user inputs, and a 3D view, similar to the Dynamo workspace. - -![](images/customizer_01.png) -> 1. Menu Bar -2. Controls -3. 3D Preview - -###The Customizer View's Menu - -The Customizer Menu Bar includes file information, navigation controls, and download options. - -![](images/customizer_02.png) ->1. Title - The name of the file -2. Author - The owner of the file -3. Zoom to Extent - Zoom to the extent of the geometry -4. Zoom In/Out - Control the zoom -5. Pan/Orbit - Toggle between orbit and pan -6. Download - Save the file as an STL or DYN -7. Feedback - Send comments, suggestions, or issues -8. Manage/About - Useful information about Dynamo -9. Logout - Log out of your account and exit the Customizer view - -###Controls - -The controls menu contains the inputs to the Dynamo script including numbers, sliders, strings, and booleans, as well as a short description of the file. The controls will reflect the various inputs found in the original Dynamo file and will change depending on the script. This menu can be collapsed by clicking the arrow icon. - -![](images/customizer_03.png) ->1. Collapse/expand controls -2. File Description -2. Number Input -2. Number Sliders -3. Boolean -4. Strings -5. Integer Slider +##The Customizer View + +The Dynamo Customizer view allows others to interact with your Dynamo scripts on the web via a simplified, curated interface consisting of inputs such as sliders, numbers, and booleans. + +By condensing complex graphs into a simple interface, the Customizer view makes your scripts accessible to a wider community of users who may not be familiar with Dynamo, Visual Programming, or 3D modeling. Anyone with an Autodesk account can access your Dynamo script in a Customizer View through a shared link, allowing them to interact with your script without a Dynamo license. + +In the Customizer view, users can export geometry as an STL mesh for rapid prototyping, or as a Dynamo file. + +![](images/customizer_00.png) +>Customizer View examples available at https://dynamo.autodesk.com/ + +###Customizer View UI + +The Customizer view consists of a menu bar, a flyout menu containing a description of the file and user inputs, and a 3D view, similar to the Dynamo workspace. + +![](images/customizer_01.png) +> 1. Menu Bar +2. Controls +3. 3D Preview + +###The Customizer View's Menu + +The Customizer Menu Bar includes file information, navigation controls, and download options. + +![](images/customizer_02.png) +>1. Title - The name of the file +2. Author - The owner of the file +3. Zoom to Extent - Zoom to the extent of the geometry +4. Zoom In/Out - Control the zoom +5. Pan/Orbit - Toggle between orbit and pan +6. Download - Save the file as an STL or DYN +7. Feedback - Send comments, suggestions, or issues +8. Manage/About - Useful information about Dynamo +9. Logout - Log out of your account and exit the Customizer view + +###Controls + +The controls menu contains the inputs to the Dynamo script including numbers, sliders, strings, and booleans, as well as a short description of the file. The controls will reflect the various inputs found in the original Dynamo file and will change depending on the script. This menu can be collapsed by clicking the arrow icon. + +![](images/customizer_03.png) +>1. Collapse/expand controls +2. File Description +2. Number Input +2. Number Sliders +3. Boolean +4. Strings +5. Integer Slider diff --git a/11_Web_Experience/datasets/Attractor Scale.dyn b/11_Web_Experience/datasets/Attractor Scale.dyn index 016261cc..2fe18389 100644 --- a/11_Web_Experience/datasets/Attractor Scale.dyn +++ b/11_Web_Experience/datasets/Attractor Scale.dyn @@ -1,397 +1,397 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0.5 - - - - 0.5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - 0.1 - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - , - - - - 255,0,255 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - , - - - - - 0,0,255 - - - - 15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.5 + + + + 0.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + 0.1 + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + , + + + + 255,0,255 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + 0,0,255 + + + + 15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/11_Web_Experience/old/datasets/11-1/Pattern_Rotation.dyn b/11_Web_Experience/old/datasets/11-1/Pattern_Rotation.dyn index b45820de..953369b6 100644 --- a/11_Web_Experience/old/datasets/11-1/Pattern_Rotation.dyn +++ b/11_Web_Experience/old/datasets/11-1/Pattern_Rotation.dyn @@ -1,118 +1,118 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/11_Web_Experience/old/datasets/11-2/PeakAndTroughSrf.dyf b/11_Web_Experience/old/datasets/11-2/PeakAndTroughSrf.dyf index 55937e29..5aff8228 100644 --- a/11_Web_Experience/old/datasets/11-2/PeakAndTroughSrf.dyf +++ b/11_Web_Experience/old/datasets/11-2/PeakAndTroughSrf.dyf @@ -1,34 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/11_Web_Experience/old/datasets/11-2/UV-Mapping.dyn b/11_Web_Experience/old/datasets/11-2/UV-Mapping.dyn index 03bb931c..ba7a137e 100644 --- a/11_Web_Experience/old/datasets/11-2/UV-Mapping.dyn +++ b/11_Web_Experience/old/datasets/11-2/UV-Mapping.dyn @@ -1,88 +1,88 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Appendix/A-1_resources.md b/Appendix/A-1_resources.md index be95c2ae..5cb07bed 100644 --- a/Appendix/A-1_resources.md +++ b/Appendix/A-1_resources.md @@ -1,74 +1,74 @@ -# Resources -**Dynamo Wiki** - -"This wiki is for learning about development using the Dynamo API, supporting libraries and tools." - -https://github.com/DynamoDS/Dynamo/wiki - -**Dynamo Blog** - -This blog is the most up-to-date collection of articles from the Dynamo team, discussing new features, workflows, and all things Dynamo. - -http://dynamobim.com/blog/ - -**DesignScript Guide** - -Programming languages are created to express ideas, usually involving logic and calculation. In addition to these objectives, the Dynamo textual language (formerly DesignScript) has been created to express design intentions. It is generally recognized that computational designing is exploratory, and Dynamo tries to support this: we hope you find the language flexible and fast enough to take a design from concept, through design iterations, to your final form. This manual is structured to give a user with no knowledge of either programming or architectural geometry full exposure to a variety of topics in these two intersecting disciplines. - -http://dynamobim.org/wp-content/uploads/forum-assets/colin-mccroneautodesk-com/07/10/Dynamo_language_guide_version_1.pdf - -**The Dynamo Primer Project** - -The Dynamo Primer is an open source project, initiated by Matt Jezyk and the Dynamo Development team at Autodesk. The first version of the primer was developed by Mode Lab. To contribute, fork the repo, add your content, and submit a pull request. - -https://github.com/DynamoDS/DynamoPrimer - -**Zero Touch Plugin Development for Dynamo** - -This page outlines the process of developing a custom Dynamo node in C# using the "Zero Touch" interface. In most cases, C# static methods and Classes can be imported without modification. If your library only needs to call functions, and not construct new objects, this can be achieved very easily with static methods. When Dynamo loads your DLL, it will strip off the namespace of your classes, and expose all static methods as nodes. - -https://github.com/DynamoDS/Dynamo/wiki/Zero-Touch-Plugin-Development - -**Python for Beginners** - -Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. Python combines remarkable power with very clear syntax. It has interfaces to many system calls and libraries, as well as to various window systems, and is extensible in C or C++. It is also usable as an extension language for applications that need a programmable interface. Finally, Python is portable: it runs on many Unix variants, on the Mac, and on Windows 2000 and later. The Beginner’s Guide to Python links to other introductory tutorials and resources for learning Python. - -https://www.python.org/about/gettingstarted - -**AForge** - -AForge.NET is an open source C# framework designed for developers and researchers in the fields of Computer Vision and Artificial Intelligence - image processing, neural networks, genetic algorithms, fuzzy logic, machine learning, robotics, etc. - -http://www.aforgenet.com/framework/ - -**Wolfram MathWorld** - -MathWorld is an online mathematics resource, assembled by Eric W. Weisstein with assistance from thousands of contributors. Since its contents first appeared online in 1995, MathWorld has emerged as a nexus of mathematical information in both the mathematics and educational communities. Its entries are extensively referenced in journals and books spanning all educational levels. - -http://mathworld.wolfram.com/ - -###Revit Resources - -**buildz** - -"These posts are mainly about the Revit platform, with recommendations on how to enjoy it." - -http://buildz.blogspot.com/ - -**Nathan's Revit API Notebook** - -"This notebook attempts to remedy a few 'resource deficiencies' in learning and applying the Revit API in the context of a design workflow" - -http://wiki.theprovingground.org/revit-api - -**Revit Python Shell** - -"The RevitPythonShell adds an IronPython interpreter to Autodesk Revit and Vasari." This project pre-dates Dynamo and is a great reference for Python development. -RPS Project: https://github.com/architecture-building-systems/revitpythonshell -Developer's Blog: http://darenatwork.blogspot.com/ - -**The Building Coder** - -A robust catalogue of Revit API workflows from one of the leading experts in BIM. - +# Resources +**Dynamo Wiki** + +"This wiki is for learning about development using the Dynamo API, supporting libraries and tools." + +https://github.com/DynamoDS/Dynamo/wiki + +**Dynamo Blog** + +This blog is the most up-to-date collection of articles from the Dynamo team, discussing new features, workflows, and all things Dynamo. + +http://dynamobim.com/blog/ + +**DesignScript Guide** + +Programming languages are created to express ideas, usually involving logic and calculation. In addition to these objectives, the Dynamo textual language (formerly DesignScript) has been created to express design intentions. It is generally recognized that computational designing is exploratory, and Dynamo tries to support this: we hope you find the language flexible and fast enough to take a design from concept, through design iterations, to your final form. This manual is structured to give a user with no knowledge of either programming or architectural geometry full exposure to a variety of topics in these two intersecting disciplines. + +http://dynamobim.org/wp-content/uploads/forum-assets/colin-mccroneautodesk-com/07/10/Dynamo_language_guide_version_1.pdf + +**The Dynamo Primer Project** + +The Dynamo Primer is an open source project, initiated by Matt Jezyk and the Dynamo Development team at Autodesk. The first version of the primer was developed by Mode Lab. To contribute, fork the repo, add your content, and submit a pull request. + +https://github.com/DynamoDS/DynamoPrimer + +**Zero Touch Plugin Development for Dynamo** + +This page outlines the process of developing a custom Dynamo node in C# using the "Zero Touch" interface. In most cases, C# static methods and Classes can be imported without modification. If your library only needs to call functions, and not construct new objects, this can be achieved very easily with static methods. When Dynamo loads your DLL, it will strip off the namespace of your classes, and expose all static methods as nodes. + +https://github.com/DynamoDS/Dynamo/wiki/Zero-Touch-Plugin-Development + +**Python for Beginners** + +Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. Python combines remarkable power with very clear syntax. It has interfaces to many system calls and libraries, as well as to various window systems, and is extensible in C or C++. It is also usable as an extension language for applications that need a programmable interface. Finally, Python is portable: it runs on many Unix variants, on the Mac, and on Windows 2000 and later. The Beginner’s Guide to Python links to other introductory tutorials and resources for learning Python. + +https://www.python.org/about/gettingstarted + +**AForge** + +AForge.NET is an open source C# framework designed for developers and researchers in the fields of Computer Vision and Artificial Intelligence - image processing, neural networks, genetic algorithms, fuzzy logic, machine learning, robotics, etc. + +http://www.aforgenet.com/framework/ + +**Wolfram MathWorld** + +MathWorld is an online mathematics resource, assembled by Eric W. Weisstein with assistance from thousands of contributors. Since its contents first appeared online in 1995, MathWorld has emerged as a nexus of mathematical information in both the mathematics and educational communities. Its entries are extensively referenced in journals and books spanning all educational levels. + +http://mathworld.wolfram.com/ + +###Revit Resources + +**buildz** + +"These posts are mainly about the Revit platform, with recommendations on how to enjoy it." + +http://buildz.blogspot.com/ + +**Nathan's Revit API Notebook** + +"This notebook attempts to remedy a few 'resource deficiencies' in learning and applying the Revit API in the context of a design workflow" + +http://wiki.theprovingground.org/revit-api + +**Revit Python Shell** + +"The RevitPythonShell adds an IronPython interpreter to Autodesk Revit and Vasari." This project pre-dates Dynamo and is a great reference for Python development. +RPS Project: https://github.com/architecture-building-systems/revitpythonshell +Developer's Blog: http://darenatwork.blogspot.com/ + +**The Building Coder** + +A robust catalogue of Revit API workflows from one of the leading experts in BIM. + http://thebuildingcoder.typepad.com/ \ No newline at end of file diff --git a/Appendix/A-2_index-of-nodes.md b/Appendix/A-2_index-of-nodes.md index 6f5b3e44..d2bb4175 100644 --- a/Appendix/A-2_index-of-nodes.md +++ b/Appendix/A-2_index-of-nodes.md @@ -1,289 +1,289 @@ - - - - -# INDEX OF NODES - -##### This index provides additional information on all the nodes used in this primer, as well as other components you might find useful. This is just an introduction to some of the 500 nodes available in Dynamo. - - - -Bulitin Functions --- - -|||| -|--|--|--| -|![IMAGE](images/A-2/Count.Large.png)|**Count**
Returns number of items in the specified list.|![IMAGE](images/nodes/Count.png) -|![IMAGE](images/A-2/Flatten.Large.png)|**Flatten**
Returns the flattened 1D list of the multidimensional input list.|![IMAGE](images/nodes/Flatten.png) -|![IMAGE](images/A-2/Map.Large.png)|**Map**
Maps a value into an input range|![IMAGE](images/nodes/Map.png) - -Core --- - -####Core.Color -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/DSCore.Color.ByARGB.Large.png)|**Color.ByARGB**
Construct a color by alpha, red, green, and blue components.|![IMAGE](images/nodes/Color.ByARGB.png) -|![IMAGE](images/A-2/DSCoreNodesUI.ColorRange.Large.png)|**Color Range**
Get a color from a color gradient between a start color and an end color.|![IMAGE](images/nodes/ColorRange.png) -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.Color.Brightness.Large.png)|**Color.Brightness**
Gets the brightness value for this color.|![IMAGE](images/nodes/Color.Brightness.png) -|![IMAGE](images/A-2/DSCore.Color.Components.Large.png)|**Color.Components**
Lists the components for the color in the order: alpha, red, green, blue.|![IMAGE](images/nodes/Color.Components.png) -|![IMAGE](images/A-2/DSCore.Color.Saturation.Large.png)|**Color.Saturation**
Gets the saturation value for this color|![IMAGE](images/nodes/Color.Saturation.png) -|![IMAGE](images/A-2/DSCore.Color.Hue.Large.png)|**Color.Hue**
Gets the hue value for this color.|![IMAGE](images/nodes/Color.Hue.png) -||QUERY|| -|![IMAGE](images/A-2/DSCore.Color.Alpha.Large.png)|**Color.Alpha**
Find the alpha component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Alpha.png) -|![IMAGE](images/A-2/DSCore.Color.Blue.Large.png)|**Color.Blue**
Find the blue component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Blue.png) -|![IMAGE](images/A-2/DSCore.Color.Green.Large.png)|**Color.Green**
Find the green component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Green.png) -|![IMAGE](images/A-2/DSCore.Color.Red.Large.png)|**Color.Red**
Find the red component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Red.png) - -####Core.Display -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Display.ByGeometryColor.png)|**Display.ByGeometryColor**
Displays geometry using a color.|![IMAGE](images/nodes/Display.ByGeometryColor.png) - -####Core.Input -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCoreNodesUI.BoolSelector.Large.png)|**Boolean**
Selection between a true and false.|![IMAGE](images/nodes/Boolean.png) -|![IMAGE](images/A-2/Dynamo.Nodes.CodeBlockNodeModel.Large.png)|**Code Block**
Allows for DesignScript code to be authored directly.|![IMAGE](images/nodes/CodeBlock.png) -|![IMAGE](images/A-2/DSCore.File.Directory.Large.png)|**Directory Path**
Allows you to select a directory on the system to get its path|![IMAGE](images/nodes/DirectoryPath.png) -|![IMAGE](images/A-2/DSCore.File.Filename.Large.png)|**File Path**
Allows you to select a file on the system to get its filename.|![IMAGE](images/nodes/FilePath.png) -|![IMAGE](images/A-2/DSCoreNodesUI.Input.IntegerSlider.Large.png)|**Integer Slider**
A slider that produces integer values.|![IMAGE](images/nodes/IntegerSlider.png) -|![IMAGE](images/A-2/Dynamo.Nodes.DoubleInput.Large.png)|**Number**
Creates a number.|![IMAGE](images/nodes/Number.png) -|![IMAGE](images/A-2/DSCoreNodesUI.Input.DoubleSlider.Large.png)|**Number Slider**
A slider that produces numeric values.|![IMAGE](images/nodes/NumberSlider.png) -|![IMAGE](images/A-2/Dynamo.Nodes.StringInput.Large.png)|**String**
Creates a string.|![IMAGE](images/nodes/String.png) - -####Core.List -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/DSCore.List.Create.Large.png)|**List.Create**
Makes a new list out of the given inputs.|![IMAGE](images/nodes/List.Create.png) -|![IMAGE](images/A-2/DSCore.List.Combine.Large.png)|**List.Combine**
Applies a combinator to each element in two sequences|![IMAGE](images/nodes/List.Combine.png) -|![IMAGE](images/A-2/DSCoreNodesUI.NumberRange.Large.png)|**Number Range**
Creates a sequence of numbers in the specified range.|![IMAGE](images/nodes/NumberRange.png) -|![IMAGE](images/A-2/DSCoreNodesUI.NumberSeq.Large.png)|**Number Sequence**
Creates a sequence of numbers.|![IMAGE](images/nodes/NumberSequence.png) -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.List.Chop.Large.png)|**List.Chop**
Chop a list into a set of lists each containing the given amount of items.|![IMAGE](images/nodes/List.Chop.png) -|![IMAGE](images/A-2/DSCore.List.Count.Large.png)|**List.Count**
Gets the number of items stored in the given list.|![IMAGE](images/nodes/List.Count.png) -|![IMAGE](images/A-2/DSCore.List.Flatten.Large.png)|**List.Flatten**
Flattens a nested list of lists by a certain amount.|![IMAGE](images/nodes/List.Flatten.png) -|![IMAGE](images/A-2/DSCore.List.FilterByBoolMask.Large.png)|**List.FilterByBoolMask**
Filters a sequence by looking up corresponding indices in a separate list of booleans.|![IMAGE](images/nodes/List.FilterByBoolMask.png) -|![IMAGE](images/A-2/DSCore.List.GetItemAtIndex.Large.png)|**List.GetItemAtIndex**
Gets an item from the given list that's located at the specified index.|![IMAGE](images/nodes/List.GetItemAtIndex.png) -|![IMAGE](images/A-2/DSCore.List.Map.Large.png)|**List.Map**
Applies a function over all elements of a list, generating a new list from the results|![IMAGE](images/nodes/List.Map.png) -|![IMAGE](images/A-2/DSCore.List.Reverse.Large.png)|**List.Reverse**
Creates a new list containing the items of the given list but in reverse order|![IMAGE](images/nodes/List.Reverse.png) -|![IMAGE](images/A-2/DSCore.List.ReplaceItemAtIndex.Large.png)|**List.ReplaceItemAtIndex**
Replace an item from the given list that's located at the specified index|![IMAGE](images/nodes/List.ReplaceItemAtIndex.png) -|![IMAGE](images/A-2/DSCore.List.ShiftIndices.Large.png)|**List.ShiftIndices**
Shifts indices in the list to the right by the given amount|![IMAGE](images/nodes/List.ShiftIndices.png) -|![IMAGE](images/A-2/DSCore.List.TakeEveryNthItem.Large.png)|**List.TakeEveryNthItem**
Fetches items from the given list at indices that are multiples of the given value, after the given offset.|![IMAGE](images/nodes/List.TakeEveryNthItem.png) -|![IMAGE](images/A-2/DSCore.List.Transpose.Large.png)|**List.Transpose**
Swaps rows and columns in a list of lists. If there are some rows that are shorter than others, null values are inserted as place holders in the resultant array such that it is always rectangular|![IMAGE](images/nodes/List.Transpose.png) - -####Core.Logic -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCoreNodesUI.Logic.If.Large.png)|**If**
Conditional statement. Checks the boolean value of the test input. If the test input is true, the result outputs the true input, otherwise the result outputs the false input.|![IMAGE](images/nodes/If.png) - - - -####Core.Math -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.Math.Cos.Large.png)|**Math.Cos**
Fines the cosine of an angle.|![IMAGE](images/nodes/Math.Cos.png) -|![IMAGE](images/A-2/DSCore.Math.DegreesToRadians.Large.png)|**Math.DegreesToRadians**
Converts an angle in degrees to an angle in radians.|![IMAGE](images/nodes/Math.DegreesToRadians.png) -|![IMAGE](images/A-2/DSCore.Math.Pow.Large.png)|**Math.Pow**
Raises a number to the specified power.|![IMAGE](images/nodes/Math.Pow.png) -|![IMAGE](images/A-2/DSCore.Math.RadiansToDegrees.Large.png)|**Math.RadiansToDegrees**
Converts an angle in radians to an angle in degrees.|![IMAGE](images/nodes/Math.RadiansToDegrees.png) -|![IMAGE](images/A-2/DSCore.Math.RemapRange.Large.png)|**Math.RemapRange**
Adjusts the range of a list of numbers while preserving the distribution ratio.|![IMAGE](images/nodes/Math.RemapRange.png) -|![IMAGE](images/A-2/DSCore.Math.Sin.Large.png)|**Math.Sin**
Finds the sine of an angle.|![IMAGE](images/nodes/Math.Sin.png) - - - -####Core.Object -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.Object.IsNull.Large.png)|**Object.IsNull**
Determines if the given object is null.|![IMAGE](images/nodes/Object.IsNull.png) - -####Core.Scripting -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.Scripting.Formula.Large.png)|**Formula**
Evaluates mathematical formulas. Uses NCalc for evaluation. See http://ncalc.codeplex.com |![IMAGE](images/nodes/Formula.png) - -####Core.String -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/DSCore.String.Concat.Large.png)|**String.Concat**
Concatenates multiple strings into a single string.|![IMAGE](images/nodes/String.Concat.png) -|![IMAGE](images/A-2/DSCore.String.Contains.Large.png)|**String.Contains**
Determines if the given string contains the given substring.|![IMAGE](images/nodes/String.Contains.png) -|![IMAGE](images/A-2/DSCore.String.Join.Large.png)|**String.Join**
Concatenates multiple strings into a single string, inserting the given separator between each joined string.|![IMAGE](images/nodes/String.Join.png) -|![IMAGE](images/A-2/DSCore.String.Split.Large.png)|**String.Split**
Divides a single string into a list of strings, with divisions determined by the given separater strings.|![IMAGE](images/nodes/String.Split.png) -|![IMAGE](images/A-2/DSCore.String.ToNumber.Large.png)|**String.ToNumber**
Converts a string to an integer or a double.|![IMAGE](images/nodes/String.ToNumber.png) - - -####Core.View -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/Dynamo.Nodes.Watch.Large.png)|**View.Watch**
Visualize the output of node.|![IMAGE](images/nodes/Watch.png) -|![IMAGE](images/A-2/Dynamo.Nodes.Watch3D.Large.png)|**View.Watch 3D**
Shows a dynamic preview of geometry.|![IMAGE](images/nodes/Watch3D.png) - -Geometry --- - -####Geometry.Circle -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Circle.ByCenterPointRadius.Large.png)|**Circle.ByCenterPointRadius**
Creates a Circle with input center Point and radius in the world XY plane, with world Z as normal.|![IMAGE](images/nodes/Circle.ByCenterPointRadius.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Circle.ByPlaneRadius.Large.png)|**Circle.ByPlaneRadius**
Create a Circle centered at the input Plane origin (root), lying in the input Plane, with given radius.|![IMAGE](images/nodes/Circle.ByPlaneRadius.png) - -####Geometry.CoordinateSystem -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.CoordinateSystem.ByOrigin.Point.Large.png)|**CoordinateSystem.ByOrigin**
Create a CoordinateSystem with origin at input Point, with X and Y Axes set as WCS X and Y axes|![IMAGE](images/nodes/CoordinateSystem.ByOrigin.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.CoordinateSystem.ByCylindricalCoordinates.Large.png)|**CoordinateSystem.ByCyclindricalCoordinates**
Creates a CoordinateSystem at the specified cylindrical coordinate parameters with respet to the specified coordinate system|![IMAGE](images/nodes/CoordinateSystem.ByCylindricalCoordinates.png) - - -####Geometry.Cuboid -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Cuboid.ByLengths.Point-double-double-double.Large.png)|**Cuboid.ByLengths** (origin)
Create a Cuboid centered at input Point, with specified width, length, and height.|![IMAGE](images/nodes/Cuboid.ByLengths_Origin.png) - - -####Geometry.Curve -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Curve.Extrude.double.Large.png)|**Curve.Extrude** (distance)
Extrudes a Curve in the normal Vector direction.|![IMAGE](images/nodes/Curve.Extrude_Distance.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Curve.PointAtParameter.Large.png)|**Curve.PointAtParameter**
Get a Point on the Curve at a specified parameter between StartParameter() and EndParameter().|![IMAGE](images/nodes/Curve.PointAtParameter.png) - -####Geometry.Geometry -|||| -|--|--|--| -||ACTIONS|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.DistanceTo.Large.png)|**Geometry.DistanceTo**
Obtain the distance from this Geometry to another.|![IMAGE](images/nodes/Geometry.DistanceTo.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Explode.Large.png)|**Geometry.Explode**
Separates compound or non-separated elements into their component parts|![IMAGE](images/nodes/Geometry.Explode.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.ImportFromSAT.var.Large.png)|**Geometry.ImportFromSAT**
List of imported geometries|![IMAGE](images/nodes/Geometry.ImportFromSAT.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.Rotate.Plane-double.Large.png)|**Geometry.Rotate** (basePlane)
Rotates an object around the Plane origin and normal by a specified degree.|![IMAGE](images/nodes/Geometry.Rotate_BasePlane.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.Translate.Vector-double.Large.png)|**Geometry.Translate**
Translates any geometry type by the given distance in the given direction.|![IMAGE](images/nodes/Geometry.Translate.png) - -####Geometry.Line -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByBestFitThroughPoints.Large.png)|**Line.ByBestFitThroughPoints**
Creates a Line best approximating a scatter plot of Points.|![IMAGE](images/nodes/Line.ByBestFitThroughPoints.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByStartPointDirectionLength.Large.png)|**Line.ByStartPointDirectionLength**
Create a straight Line starting at Point, extending in Vector direction by specified length.|![IMAGE](images/nodes/Line.ByStartPointDirectionLength.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint.Large.png)|**Line.ByStartPointEndPoint**
Creates a straight Line between two input Points.|![IMAGE](images/nodes/Line.ByStartPointEndPoint.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByTangency.Large.png)|**Line.ByTangency**
Create a Line tangent to the input Curve, positioned at the parameter Point of the input Curve.|![IMAGE](images/nodes/Line.ByTangency.png) -||QUERY|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.Direction.Large.png)|**Line.Direction**
The direction of the Curve.|![IMAGE](images/nodes/Line.Direction.png) - -####Geometry.NurbsCurve -|||| -|--|--|--| -||Create|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsCurve.ByControlPoints.Point1-int.Large.png)|**NurbsCurve.ByControlPoints**
Create a BSplineCurve by using explicit control points.|![IMAGE](images/nodes/NurbsCurve.ByControlPoints.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsCurve.ByPoints.Point1-int.Large.png)|**NurbsCurve.ByPoints**
Create a BSplineCurve by interpolating between points|![IMAGE](images/nodes/NurbsCurve.ByPoints.png)qcomm - -####Geometry.NurbsSurface -|||| -|--|--|--| -||Create|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsSurface.ByControlPoints.Large.png)|**NurbsSurface.ByControlPoints**
Create a NurbsSurface by using explicit control Points with specified U and V degrees.|![IMAGE](images/nodes/NurbsSurface.ByControlPoints.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsSurface.ByPoints.Large.png)|**NurbsSurface.ByPoints**
Creates a NurbsSurface with specified interpolated points and U and V degrees. The resultant surface will pass through all of the points.|![IMAGE](images/nodes/NurbsSurface.ByPoints.png) - -####Geometry.Plane -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Plane.ByOriginNormal.Large.png)|**Plane.ByOriginNormal**
Create a Plane centered at root Point, with input normal Vector.|![IMAGE](images/nodes/Plane.ByOriginNormal.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Plane.XY.Large.png)|**Plane.XY**
Creates a plane in the world XY|![IMAGE](images/nodes/Plane.XY.png) - -####Geometry.Point -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCartesianCoordinates.Large.png)|**Point.ByCartesianCoordinates**
Form a Point in th egiven coordinate system with 3 cartesian coordinates|![IMAGE](images/nodes/Point.ByCartesianCoordinates.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCoordinates.double-double.Large.png)|**Point.ByCoordinates** (2d)
Form a Point in the XY plane given two 2 Cartesian coordinates. The Z component is 0.|![IMAGE](images/nodes/Point.ByCoordinates_2D.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCoordinates.double-double-double.Large.png)|**Point.ByCoordinates** (3d)
Form a Point given 3 Cartesian coordinates.|![IMAGE](images/nodes/Point.ByCoordinates_3D.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Origin.Large.png)|**Point.Origin**
Get the Origin point (0,0,0)|![IMAGE](images/nodes/Point.Origin.png) -||ACTIONS|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Add.Large.png)|**Point.Add**
Add a vector to a point. The same as Translate (Vector).|![IMAGE](images/nodes/Point.Add.png) -||QUERY|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.X.Large.png)|**Point.X**
Get the X component of a point|![IMAGE](images/nodes/Point.X.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Y.Large.png)|**Point.Y**
Get the Y component of a point|![IMAGE](images/nodes/Point.Y.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.X.Large.png)|**Point.Z**
Get the Z component of a point|![IMAGE](images/nodes/Point.Z.png) - - -####Geometry.Polycurve -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.PolyCurve.ByPoints.Large.png)|**Polycurve.ByPoints**
Make PolyCurve from sequence of lines connecting points. For closed curve last point should be in the same location as the start point.|![IMAGE](images/nodes/PolyCurve.ByPoints.png) - -####Geometry.Rectangle -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Rectangle.ByWidthHeight.Plane-double-double.Large.png)|**Rectangle.ByWidthLength** (Plane)
Create a Rectangle centered at input Plane root, with input width (Plane X axis length) and (Plane Y axis length).|![IMAGE](images/nodes/Rectangle.ByWidthLength.png) - -####Geometry.Sphere -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Sphere.ByCenterPointRadius.Large.png)|**Sphere.ByCenterPointRadius**
Create a Solid Sphere centered at the input Point, with given radius.|![IMAGE](images/nodes/Sphere.ByCenterPointRadius.png) - -####Geometry.Surface -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.ByLoft.Curve1.Large.png)|**Surface.ByLoft**
Create a Surface by lofting between input cross section Curves|![IMAGE](images/nodes/Surface.ByLoft.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.ByPatch.Large.png)|**Surface.ByPatch**
Create a Surface by filling in the interior of a closed boundary defined by input Curves.|![IMAGE](images/nodes/Surface.ByPatch.png) -||ACTIONS|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.Offset.Large.png)|**Surface.Offset**
Offset Surface in direction of Surface normal by specified distance|![IMAGE](images/nodes/Surface.Offset.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.PointAtParameter.Large.png)|**Surface.PointAtParameter**
Return the Point at a specified U and V parameters.|![IMAGE](images/nodes/Surface.PointAtParameter.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.Thicken.double.Large.png)|**Surface.Thicken**
Thicken Surface into a Solid, extruding in the direction of Surface normals on both sides of the Surface.|![IMAGE](images/nodes/Surface.Thicken.png) - -####Geometry.UV -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.UV.ByCoordinates.Large.png)|**UV.ByCoordinates**
Create a UV from two doubles.|![IMAGE](images/nodes/UV.ByCoordinates.png) - -####Geometry.Vector -|||| -|--|--|--| -||CREATE|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.ByCoordinates.double-double-double.Large.png)|**Vector.ByCoordinates**
Form a Vector by 3 Euclidean coordinates|![IMAGE](images/nodes/Vector.ByCoordinates.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.XAxis.Large.png)|**Vector.XAxis**
Gets the canonical X axis Vector (1,0,0)|![IMAGE](images/nodes/Vector.XAxis.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.YAxis.Large.png)|**Vector.YAxis**
Gets the canonical Y axis Vector (0,1,0)|![IMAGE](images/nodes/Vector.YAxis.png) -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.ZAxis.Large.png)|**Vector.ZAxis**
Gets the canonical Z axis Vector (0,0,1)|![IMAGE](images/nodes/Vector.ZAxis.png) -||ACTIONS|| -|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.Normalized.Large.png)|**Vector.Normalized**
Get the normalized version of a vector|![IMAGE](images/nodes/Vector.Normalized.png) - - - -Operators --- -|||| -|--|--|--| -|![IMAGE](images/A-2/add.Large.png)|**+**
Addition|![IMAGE](images/nodes/Addition.png) -|![IMAGE](images/A-2/sub.Large.png)|**-**
Subtraction|![IMAGE](images/nodes/Subtraction.png) -|![IMAGE](images/A-2/mul.Large.png)|**\***
Multiplication|![IMAGE](images/nodes/Multiplication.png) -|![IMAGE](images/A-2/div.Large.png)|**/**
Division|![IMAGE](images/nodes/Division.png) -|![IMAGE](images/A-2/mod.Large.png)|**%**
Modular Division finds the remainder of the first input after dividing by the second input|![IMAGE](images/nodes/ModularDivision.png) -|![IMAGE](images/A-2/lt.Large.png)|**<**
Less Than|![IMAGE](images/nodes/LessThan.png) -|![IMAGE](images/A-2/gt.Large.png)|**>**
Greater Than|![IMAGE](images/nodes/GreaterThan.png) -|![IMAGE](images/A-2/eq.Large.png)|**==**
Equality tests for equality between two values.|![IMAGE](images/nodes/Equality.png) + + + + +# INDEX OF NODES + +##### This index provides additional information on all the nodes used in this primer, as well as other components you might find useful. This is just an introduction to some of the 500 nodes available in Dynamo. + + + +Bulitin Functions +-- + +|||| +|--|--|--| +|![IMAGE](images/A-2/Count.Large.png)|**Count**
Returns number of items in the specified list.|![IMAGE](images/nodes/Count.png) +|![IMAGE](images/A-2/Flatten.Large.png)|**Flatten**
Returns the flattened 1D list of the multidimensional input list.|![IMAGE](images/nodes/Flatten.png) +|![IMAGE](images/A-2/Map.Large.png)|**Map**
Maps a value into an input range|![IMAGE](images/nodes/Map.png) + +Core +-- + +####Core.Color +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/DSCore.Color.ByARGB.Large.png)|**Color.ByARGB**
Construct a color by alpha, red, green, and blue components.|![IMAGE](images/nodes/Color.ByARGB.png) +|![IMAGE](images/A-2/DSCoreNodesUI.ColorRange.Large.png)|**Color Range**
Get a color from a color gradient between a start color and an end color.|![IMAGE](images/nodes/ColorRange.png) +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.Color.Brightness.Large.png)|**Color.Brightness**
Gets the brightness value for this color.|![IMAGE](images/nodes/Color.Brightness.png) +|![IMAGE](images/A-2/DSCore.Color.Components.Large.png)|**Color.Components**
Lists the components for the color in the order: alpha, red, green, blue.|![IMAGE](images/nodes/Color.Components.png) +|![IMAGE](images/A-2/DSCore.Color.Saturation.Large.png)|**Color.Saturation**
Gets the saturation value for this color|![IMAGE](images/nodes/Color.Saturation.png) +|![IMAGE](images/A-2/DSCore.Color.Hue.Large.png)|**Color.Hue**
Gets the hue value for this color.|![IMAGE](images/nodes/Color.Hue.png) +||QUERY|| +|![IMAGE](images/A-2/DSCore.Color.Alpha.Large.png)|**Color.Alpha**
Find the alpha component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Alpha.png) +|![IMAGE](images/A-2/DSCore.Color.Blue.Large.png)|**Color.Blue**
Find the blue component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Blue.png) +|![IMAGE](images/A-2/DSCore.Color.Green.Large.png)|**Color.Green**
Find the green component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Green.png) +|![IMAGE](images/A-2/DSCore.Color.Red.Large.png)|**Color.Red**
Find the red component of a color, 0 to 255.|![IMAGE](images/nodes/Color.Red.png) + +####Core.Display +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Display.ByGeometryColor.png)|**Display.ByGeometryColor**
Displays geometry using a color.|![IMAGE](images/nodes/Display.ByGeometryColor.png) + +####Core.Input +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCoreNodesUI.BoolSelector.Large.png)|**Boolean**
Selection between a true and false.|![IMAGE](images/nodes/Boolean.png) +|![IMAGE](images/A-2/Dynamo.Nodes.CodeBlockNodeModel.Large.png)|**Code Block**
Allows for DesignScript code to be authored directly.|![IMAGE](images/nodes/CodeBlock.png) +|![IMAGE](images/A-2/DSCore.File.Directory.Large.png)|**Directory Path**
Allows you to select a directory on the system to get its path|![IMAGE](images/nodes/DirectoryPath.png) +|![IMAGE](images/A-2/DSCore.File.Filename.Large.png)|**File Path**
Allows you to select a file on the system to get its filename.|![IMAGE](images/nodes/FilePath.png) +|![IMAGE](images/A-2/DSCoreNodesUI.Input.IntegerSlider.Large.png)|**Integer Slider**
A slider that produces integer values.|![IMAGE](images/nodes/IntegerSlider.png) +|![IMAGE](images/A-2/Dynamo.Nodes.DoubleInput.Large.png)|**Number**
Creates a number.|![IMAGE](images/nodes/Number.png) +|![IMAGE](images/A-2/DSCoreNodesUI.Input.DoubleSlider.Large.png)|**Number Slider**
A slider that produces numeric values.|![IMAGE](images/nodes/NumberSlider.png) +|![IMAGE](images/A-2/Dynamo.Nodes.StringInput.Large.png)|**String**
Creates a string.|![IMAGE](images/nodes/String.png) + +####Core.List +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/DSCore.List.Create.Large.png)|**List.Create**
Makes a new list out of the given inputs.|![IMAGE](images/nodes/List.Create.png) +|![IMAGE](images/A-2/DSCore.List.Combine.Large.png)|**List.Combine**
Applies a combinator to each element in two sequences|![IMAGE](images/nodes/List.Combine.png) +|![IMAGE](images/A-2/DSCoreNodesUI.NumberRange.Large.png)|**Number Range**
Creates a sequence of numbers in the specified range.|![IMAGE](images/nodes/NumberRange.png) +|![IMAGE](images/A-2/DSCoreNodesUI.NumberSeq.Large.png)|**Number Sequence**
Creates a sequence of numbers.|![IMAGE](images/nodes/NumberSequence.png) +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.List.Chop.Large.png)|**List.Chop**
Chop a list into a set of lists each containing the given amount of items.|![IMAGE](images/nodes/List.Chop.png) +|![IMAGE](images/A-2/DSCore.List.Count.Large.png)|**List.Count**
Gets the number of items stored in the given list.|![IMAGE](images/nodes/List.Count.png) +|![IMAGE](images/A-2/DSCore.List.Flatten.Large.png)|**List.Flatten**
Flattens a nested list of lists by a certain amount.|![IMAGE](images/nodes/List.Flatten.png) +|![IMAGE](images/A-2/DSCore.List.FilterByBoolMask.Large.png)|**List.FilterByBoolMask**
Filters a sequence by looking up corresponding indices in a separate list of booleans.|![IMAGE](images/nodes/List.FilterByBoolMask.png) +|![IMAGE](images/A-2/DSCore.List.GetItemAtIndex.Large.png)|**List.GetItemAtIndex**
Gets an item from the given list that's located at the specified index.|![IMAGE](images/nodes/List.GetItemAtIndex.png) +|![IMAGE](images/A-2/DSCore.List.Map.Large.png)|**List.Map**
Applies a function over all elements of a list, generating a new list from the results|![IMAGE](images/nodes/List.Map.png) +|![IMAGE](images/A-2/DSCore.List.Reverse.Large.png)|**List.Reverse**
Creates a new list containing the items of the given list but in reverse order|![IMAGE](images/nodes/List.Reverse.png) +|![IMAGE](images/A-2/DSCore.List.ReplaceItemAtIndex.Large.png)|**List.ReplaceItemAtIndex**
Replace an item from the given list that's located at the specified index|![IMAGE](images/nodes/List.ReplaceItemAtIndex.png) +|![IMAGE](images/A-2/DSCore.List.ShiftIndices.Large.png)|**List.ShiftIndices**
Shifts indices in the list to the right by the given amount|![IMAGE](images/nodes/List.ShiftIndices.png) +|![IMAGE](images/A-2/DSCore.List.TakeEveryNthItem.Large.png)|**List.TakeEveryNthItem**
Fetches items from the given list at indices that are multiples of the given value, after the given offset.|![IMAGE](images/nodes/List.TakeEveryNthItem.png) +|![IMAGE](images/A-2/DSCore.List.Transpose.Large.png)|**List.Transpose**
Swaps rows and columns in a list of lists. If there are some rows that are shorter than others, null values are inserted as place holders in the resultant array such that it is always rectangular|![IMAGE](images/nodes/List.Transpose.png) + +####Core.Logic +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCoreNodesUI.Logic.If.Large.png)|**If**
Conditional statement. Checks the boolean value of the test input. If the test input is true, the result outputs the true input, otherwise the result outputs the false input.|![IMAGE](images/nodes/If.png) + + + +####Core.Math +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.Math.Cos.Large.png)|**Math.Cos**
Fines the cosine of an angle.|![IMAGE](images/nodes/Math.Cos.png) +|![IMAGE](images/A-2/DSCore.Math.DegreesToRadians.Large.png)|**Math.DegreesToRadians**
Converts an angle in degrees to an angle in radians.|![IMAGE](images/nodes/Math.DegreesToRadians.png) +|![IMAGE](images/A-2/DSCore.Math.Pow.Large.png)|**Math.Pow**
Raises a number to the specified power.|![IMAGE](images/nodes/Math.Pow.png) +|![IMAGE](images/A-2/DSCore.Math.RadiansToDegrees.Large.png)|**Math.RadiansToDegrees**
Converts an angle in radians to an angle in degrees.|![IMAGE](images/nodes/Math.RadiansToDegrees.png) +|![IMAGE](images/A-2/DSCore.Math.RemapRange.Large.png)|**Math.RemapRange**
Adjusts the range of a list of numbers while preserving the distribution ratio.|![IMAGE](images/nodes/Math.RemapRange.png) +|![IMAGE](images/A-2/DSCore.Math.Sin.Large.png)|**Math.Sin**
Finds the sine of an angle.|![IMAGE](images/nodes/Math.Sin.png) + + + +####Core.Object +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.Object.IsNull.Large.png)|**Object.IsNull**
Determines if the given object is null.|![IMAGE](images/nodes/Object.IsNull.png) + +####Core.Scripting +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.Scripting.Formula.Large.png)|**Formula**
Evaluates mathematical formulas. Uses NCalc for evaluation. See http://ncalc.codeplex.com |![IMAGE](images/nodes/Formula.png) + +####Core.String +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/DSCore.String.Concat.Large.png)|**String.Concat**
Concatenates multiple strings into a single string.|![IMAGE](images/nodes/String.Concat.png) +|![IMAGE](images/A-2/DSCore.String.Contains.Large.png)|**String.Contains**
Determines if the given string contains the given substring.|![IMAGE](images/nodes/String.Contains.png) +|![IMAGE](images/A-2/DSCore.String.Join.Large.png)|**String.Join**
Concatenates multiple strings into a single string, inserting the given separator between each joined string.|![IMAGE](images/nodes/String.Join.png) +|![IMAGE](images/A-2/DSCore.String.Split.Large.png)|**String.Split**
Divides a single string into a list of strings, with divisions determined by the given separater strings.|![IMAGE](images/nodes/String.Split.png) +|![IMAGE](images/A-2/DSCore.String.ToNumber.Large.png)|**String.ToNumber**
Converts a string to an integer or a double.|![IMAGE](images/nodes/String.ToNumber.png) + + +####Core.View +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/Dynamo.Nodes.Watch.Large.png)|**View.Watch**
Visualize the output of node.|![IMAGE](images/nodes/Watch.png) +|![IMAGE](images/A-2/Dynamo.Nodes.Watch3D.Large.png)|**View.Watch 3D**
Shows a dynamic preview of geometry.|![IMAGE](images/nodes/Watch3D.png) + +Geometry +-- + +####Geometry.Circle +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Circle.ByCenterPointRadius.Large.png)|**Circle.ByCenterPointRadius**
Creates a Circle with input center Point and radius in the world XY plane, with world Z as normal.|![IMAGE](images/nodes/Circle.ByCenterPointRadius.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Circle.ByPlaneRadius.Large.png)|**Circle.ByPlaneRadius**
Create a Circle centered at the input Plane origin (root), lying in the input Plane, with given radius.|![IMAGE](images/nodes/Circle.ByPlaneRadius.png) + +####Geometry.CoordinateSystem +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.CoordinateSystem.ByOrigin.Point.Large.png)|**CoordinateSystem.ByOrigin**
Create a CoordinateSystem with origin at input Point, with X and Y Axes set as WCS X and Y axes|![IMAGE](images/nodes/CoordinateSystem.ByOrigin.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.CoordinateSystem.ByCylindricalCoordinates.Large.png)|**CoordinateSystem.ByCyclindricalCoordinates**
Creates a CoordinateSystem at the specified cylindrical coordinate parameters with respet to the specified coordinate system|![IMAGE](images/nodes/CoordinateSystem.ByCylindricalCoordinates.png) + + +####Geometry.Cuboid +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Cuboid.ByLengths.Point-double-double-double.Large.png)|**Cuboid.ByLengths** (origin)
Create a Cuboid centered at input Point, with specified width, length, and height.|![IMAGE](images/nodes/Cuboid.ByLengths_Origin.png) + + +####Geometry.Curve +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Curve.Extrude.double.Large.png)|**Curve.Extrude** (distance)
Extrudes a Curve in the normal Vector direction.|![IMAGE](images/nodes/Curve.Extrude_Distance.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Curve.PointAtParameter.Large.png)|**Curve.PointAtParameter**
Get a Point on the Curve at a specified parameter between StartParameter() and EndParameter().|![IMAGE](images/nodes/Curve.PointAtParameter.png) + +####Geometry.Geometry +|||| +|--|--|--| +||ACTIONS|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.DistanceTo.Large.png)|**Geometry.DistanceTo**
Obtain the distance from this Geometry to another.|![IMAGE](images/nodes/Geometry.DistanceTo.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Explode.Large.png)|**Geometry.Explode**
Separates compound or non-separated elements into their component parts|![IMAGE](images/nodes/Geometry.Explode.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.ImportFromSAT.var.Large.png)|**Geometry.ImportFromSAT**
List of imported geometries|![IMAGE](images/nodes/Geometry.ImportFromSAT.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.Rotate.Plane-double.Large.png)|**Geometry.Rotate** (basePlane)
Rotates an object around the Plane origin and normal by a specified degree.|![IMAGE](images/nodes/Geometry.Rotate_BasePlane.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Geometry.Translate.Vector-double.Large.png)|**Geometry.Translate**
Translates any geometry type by the given distance in the given direction.|![IMAGE](images/nodes/Geometry.Translate.png) + +####Geometry.Line +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByBestFitThroughPoints.Large.png)|**Line.ByBestFitThroughPoints**
Creates a Line best approximating a scatter plot of Points.|![IMAGE](images/nodes/Line.ByBestFitThroughPoints.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByStartPointDirectionLength.Large.png)|**Line.ByStartPointDirectionLength**
Create a straight Line starting at Point, extending in Vector direction by specified length.|![IMAGE](images/nodes/Line.ByStartPointDirectionLength.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByStartPointEndPoint.Large.png)|**Line.ByStartPointEndPoint**
Creates a straight Line between two input Points.|![IMAGE](images/nodes/Line.ByStartPointEndPoint.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.ByTangency.Large.png)|**Line.ByTangency**
Create a Line tangent to the input Curve, positioned at the parameter Point of the input Curve.|![IMAGE](images/nodes/Line.ByTangency.png) +||QUERY|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Line.Direction.Large.png)|**Line.Direction**
The direction of the Curve.|![IMAGE](images/nodes/Line.Direction.png) + +####Geometry.NurbsCurve +|||| +|--|--|--| +||Create|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsCurve.ByControlPoints.Point1-int.Large.png)|**NurbsCurve.ByControlPoints**
Create a BSplineCurve by using explicit control points.|![IMAGE](images/nodes/NurbsCurve.ByControlPoints.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsCurve.ByPoints.Point1-int.Large.png)|**NurbsCurve.ByPoints**
Create a BSplineCurve by interpolating between points|![IMAGE](images/nodes/NurbsCurve.ByPoints.png)qcomm + +####Geometry.NurbsSurface +|||| +|--|--|--| +||Create|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsSurface.ByControlPoints.Large.png)|**NurbsSurface.ByControlPoints**
Create a NurbsSurface by using explicit control Points with specified U and V degrees.|![IMAGE](images/nodes/NurbsSurface.ByControlPoints.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.NurbsSurface.ByPoints.Large.png)|**NurbsSurface.ByPoints**
Creates a NurbsSurface with specified interpolated points and U and V degrees. The resultant surface will pass through all of the points.|![IMAGE](images/nodes/NurbsSurface.ByPoints.png) + +####Geometry.Plane +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Plane.ByOriginNormal.Large.png)|**Plane.ByOriginNormal**
Create a Plane centered at root Point, with input normal Vector.|![IMAGE](images/nodes/Plane.ByOriginNormal.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Plane.XY.Large.png)|**Plane.XY**
Creates a plane in the world XY|![IMAGE](images/nodes/Plane.XY.png) + +####Geometry.Point +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCartesianCoordinates.Large.png)|**Point.ByCartesianCoordinates**
Form a Point in th egiven coordinate system with 3 cartesian coordinates|![IMAGE](images/nodes/Point.ByCartesianCoordinates.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCoordinates.double-double.Large.png)|**Point.ByCoordinates** (2d)
Form a Point in the XY plane given two 2 Cartesian coordinates. The Z component is 0.|![IMAGE](images/nodes/Point.ByCoordinates_2D.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.ByCoordinates.double-double-double.Large.png)|**Point.ByCoordinates** (3d)
Form a Point given 3 Cartesian coordinates.|![IMAGE](images/nodes/Point.ByCoordinates_3D.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Origin.Large.png)|**Point.Origin**
Get the Origin point (0,0,0)|![IMAGE](images/nodes/Point.Origin.png) +||ACTIONS|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Add.Large.png)|**Point.Add**
Add a vector to a point. The same as Translate (Vector).|![IMAGE](images/nodes/Point.Add.png) +||QUERY|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.X.Large.png)|**Point.X**
Get the X component of a point|![IMAGE](images/nodes/Point.X.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.Y.Large.png)|**Point.Y**
Get the Y component of a point|![IMAGE](images/nodes/Point.Y.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Point.X.Large.png)|**Point.Z**
Get the Z component of a point|![IMAGE](images/nodes/Point.Z.png) + + +####Geometry.Polycurve +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.PolyCurve.ByPoints.Large.png)|**Polycurve.ByPoints**
Make PolyCurve from sequence of lines connecting points. For closed curve last point should be in the same location as the start point.|![IMAGE](images/nodes/PolyCurve.ByPoints.png) + +####Geometry.Rectangle +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Rectangle.ByWidthHeight.Plane-double-double.Large.png)|**Rectangle.ByWidthLength** (Plane)
Create a Rectangle centered at input Plane root, with input width (Plane X axis length) and (Plane Y axis length).|![IMAGE](images/nodes/Rectangle.ByWidthLength.png) + +####Geometry.Sphere +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Sphere.ByCenterPointRadius.Large.png)|**Sphere.ByCenterPointRadius**
Create a Solid Sphere centered at the input Point, with given radius.|![IMAGE](images/nodes/Sphere.ByCenterPointRadius.png) + +####Geometry.Surface +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.ByLoft.Curve1.Large.png)|**Surface.ByLoft**
Create a Surface by lofting between input cross section Curves|![IMAGE](images/nodes/Surface.ByLoft.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.ByPatch.Large.png)|**Surface.ByPatch**
Create a Surface by filling in the interior of a closed boundary defined by input Curves.|![IMAGE](images/nodes/Surface.ByPatch.png) +||ACTIONS|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.Offset.Large.png)|**Surface.Offset**
Offset Surface in direction of Surface normal by specified distance|![IMAGE](images/nodes/Surface.Offset.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.PointAtParameter.Large.png)|**Surface.PointAtParameter**
Return the Point at a specified U and V parameters.|![IMAGE](images/nodes/Surface.PointAtParameter.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Surface.Thicken.double.Large.png)|**Surface.Thicken**
Thicken Surface into a Solid, extruding in the direction of Surface normals on both sides of the Surface.|![IMAGE](images/nodes/Surface.Thicken.png) + +####Geometry.UV +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.UV.ByCoordinates.Large.png)|**UV.ByCoordinates**
Create a UV from two doubles.|![IMAGE](images/nodes/UV.ByCoordinates.png) + +####Geometry.Vector +|||| +|--|--|--| +||CREATE|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.ByCoordinates.double-double-double.Large.png)|**Vector.ByCoordinates**
Form a Vector by 3 Euclidean coordinates|![IMAGE](images/nodes/Vector.ByCoordinates.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.XAxis.Large.png)|**Vector.XAxis**
Gets the canonical X axis Vector (1,0,0)|![IMAGE](images/nodes/Vector.XAxis.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.YAxis.Large.png)|**Vector.YAxis**
Gets the canonical Y axis Vector (0,1,0)|![IMAGE](images/nodes/Vector.YAxis.png) +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.ZAxis.Large.png)|**Vector.ZAxis**
Gets the canonical Z axis Vector (0,0,1)|![IMAGE](images/nodes/Vector.ZAxis.png) +||ACTIONS|| +|![IMAGE](images/A-2/Autodesk.DesignScript.Geometry.Vector.Normalized.Large.png)|**Vector.Normalized**
Get the normalized version of a vector|![IMAGE](images/nodes/Vector.Normalized.png) + + + +Operators +-- +|||| +|--|--|--| +|![IMAGE](images/A-2/add.Large.png)|**+**
Addition|![IMAGE](images/nodes/Addition.png) +|![IMAGE](images/A-2/sub.Large.png)|**-**
Subtraction|![IMAGE](images/nodes/Subtraction.png) +|![IMAGE](images/A-2/mul.Large.png)|**\***
Multiplication|![IMAGE](images/nodes/Multiplication.png) +|![IMAGE](images/A-2/div.Large.png)|**/**
Division|![IMAGE](images/nodes/Division.png) +|![IMAGE](images/A-2/mod.Large.png)|**%**
Modular Division finds the remainder of the first input after dividing by the second input|![IMAGE](images/nodes/ModularDivision.png) +|![IMAGE](images/A-2/lt.Large.png)|**<**
Less Than|![IMAGE](images/nodes/LessThan.png) +|![IMAGE](images/A-2/gt.Large.png)|**>**
Greater Than|![IMAGE](images/nodes/GreaterThan.png) +|![IMAGE](images/A-2/eq.Large.png)|**==**
Equality tests for equality between two values.|![IMAGE](images/nodes/Equality.png) diff --git a/Appendix/A-3_packages.md b/Appendix/A-3_packages.md index 1fbf38ca..92894125 100644 --- a/Appendix/A-3_packages.md +++ b/Appendix/A-3_packages.md @@ -1,193 +1,193 @@ - - -##Dynamo Packages -Here are a list of some of the more popular packages in the Dynamo community. Developers, please add to the list! Remember, the [Dynamo Primer](https://github.com/DynamoDS/DynamoPrimer) is open-source! - - - - - - - - - - - - -
- - - ARCHI-LAB - - Visit the Official archi-lab Site -
archi-lab is a collection of over 50+ custom packages that vastly extend Dynamo's ability to interact with Revit. Nodes contained in archi-lab package vary from basic list operations to advanced Analysis Visualization Framework nodes for Revit. - -
- - - - - - - - - - - -
BUMBLEBEE FOR DYNAMOVisit the Official BumbleBee Site
Bumblebee is an Excel and Dynamo interoperability plugin that vastly improves Dynamo’s ability to read and write Excel files.
- - - - - - - - - - - - - -
CLOCKWORK FOR DYNAMOVisit the Clockwork For Dynamo GitHub
Clockwork is a collection of custom nodes for the Dynamo visual programming environment. It contains many Revit-related nodes, but also lots of nodes for various other purposes such as list management, mathematical operations, string operations, unit conversions, geometric operations (mainly bounding boxes, meshes, planes, points, surfaces, UVs and vectors) and paneling.
- - - - - - - - - - - -
DYNAMO SAPVisit the DynamoSAP Project at Core Studio
DynamoSAP is a parametric interface for SAP2000, built on top of Dynamo. The project enables designers and engineers to generatively author and analyze structural systems in SAP, using Dynamo to drive the SAP model. The project prescribes a few common workflows which are described in the included sample files, and provides a wide range of opportunities for automation of typical tasks in SAP.
- - - - - - - - - - - -
DYNAMO UNFOLDVisit the DynamoUnfold GitHub
This library extends Dynamo/Revit functionality by enabling users to unfold surface and poly-surface geometry. The library allows users to first translate surfaces into planar tessellated topology, then unfold them using Protogeometry tools in Dynamo. This package also includes some experimental nodes as well as a few basic sample files.
- - - - - - - - - - - -
DYNASTRATORDownload Dynastrator at the Package Manager
Import vector art from Illustrator or the web using .svg. This allows you to import manually created drawings into Dynamo for parametric operations.
- - - - - - - - - - - -
ENERGY ANALYSIS FOR DYNAMOVisit the Energy Analysis for Dynamo Project on GitHub
Energy Analysis for Dynamo allows for parametric energy modeling and whole-building energy analysis workflows in Dynamo 0.8. Energy Analysis for Dynamo allows the user to configure the energy model from Autodesk Revit, submit to Green Building Studio for DOE2 energy analysis, and dig into the results returned from the analysis. The package is being developed by Thornton Tomasetti's CORE studio.
- - - - - - - - - - - -
FIREFLY FOR DYNAMODownload Firefly at the Dynamo Package Manager
Firefly is a collection of nodes which enable dynamo to talk to input/output devices, like the Arduino micro controller. Because the data flow happens “live”, Firefly opens up many opportunities for interactive prototyping between the digital and physical worlds through web cams, mobile phones, game controllers, sensors and more.
- - - - - - - - - - - -
LUNCHBOX FOR DYNAMOCheckout Lunchbox for Dynamo on the Proving Ground
LunchBox is a collection of reusable geometry and data management nodes. The tools have been tested with Dynamo 0.8.1 and Revit 2016. The tool includes nodes for surface paneling, geometry, Revit data collection, and more!
- - - - - - - - - - - -
MANTIS SHRIMPVisit the official Mantis Shrimp site.
Mantis Shrimp is an interoperability project that allows you to easily import Grasshopper and/or Rhino geometry into Dynamo.
- - - - - - - - - - - -
MESH TOOLKITVisit the Dynamo Mesh Toolkit GitHub
The Dynamo Mesh Toolkit provides many useful tools for working with mesh geometry. The functionality of this package includes the ability to import meshes from external file formats, generate meshes from pre-existing Dynamo geometry objects, and manually build meshes through vertices and connectivity information. Additionally, this toolkit includes tools to modify and repair mesh geometry.
- - - - - - - - - - - - - -
OPTIMOVisit the Optimo GitHub
Optimo provides dynamo users with the capability to optimize self-defined design problems by using various evolutionary algorithms. Users can define the problem objective or set of objectives as well as specific fitness functions.
- - - - - - - - - - - - - -
RHYNAMOVisit the Rhynamo Bitbucket
The Rhynamo node library provides users with the ability to read and write Rhino 3DM files from within Dynamo. Rhynamo translates Rhino geometry into usable Dynamo geometry by using McNeel’s OpenNURBS library allowing for new workflows that can exchange geometry and data fluidly between Rhino and Revit. This package also contains some experimental nodes that allow for “live” access to the Rhino command line.
- - - - - - - - - - - - - -
RHYTHMVisit Rhythm on GitHub
At first glance, Rhythm isn't anything special. It does not involve any sophisticated code or anything of that nature. What Rhythm does represent though, is the result of practical thinking and diligence. The idea is this package helps users maintain Rhythm in Revit with Dynamo. Rhythm primarily consists of out of the box Dynamo nodes used in clever ways as they apply to the Revit environment.
- + + +##Dynamo Packages +Here are a list of some of the more popular packages in the Dynamo community. Developers, please add to the list! Remember, the [Dynamo Primer](https://github.com/DynamoDS/DynamoPrimer) is open-source! + + + + + + + + + + + + +
+ + + ARCHI-LAB + + Visit the Official archi-lab Site +
archi-lab is a collection of over 50+ custom packages that vastly extend Dynamo's ability to interact with Revit. Nodes contained in archi-lab package vary from basic list operations to advanced Analysis Visualization Framework nodes for Revit. + +
+ + + + + + + + + + + +
BUMBLEBEE FOR DYNAMOVisit the Official BumbleBee Site
Bumblebee is an Excel and Dynamo interoperability plugin that vastly improves Dynamo’s ability to read and write Excel files.
+ + + + + + + + + + + + + +
CLOCKWORK FOR DYNAMOVisit the Clockwork For Dynamo GitHub
Clockwork is a collection of custom nodes for the Dynamo visual programming environment. It contains many Revit-related nodes, but also lots of nodes for various other purposes such as list management, mathematical operations, string operations, unit conversions, geometric operations (mainly bounding boxes, meshes, planes, points, surfaces, UVs and vectors) and paneling.
+ + + + + + + + + + + +
DYNAMO SAPVisit the DynamoSAP Project at Core Studio
DynamoSAP is a parametric interface for SAP2000, built on top of Dynamo. The project enables designers and engineers to generatively author and analyze structural systems in SAP, using Dynamo to drive the SAP model. The project prescribes a few common workflows which are described in the included sample files, and provides a wide range of opportunities for automation of typical tasks in SAP.
+ + + + + + + + + + + +
DYNAMO UNFOLDVisit the DynamoUnfold GitHub
This library extends Dynamo/Revit functionality by enabling users to unfold surface and poly-surface geometry. The library allows users to first translate surfaces into planar tessellated topology, then unfold them using Protogeometry tools in Dynamo. This package also includes some experimental nodes as well as a few basic sample files.
+ + + + + + + + + + + +
DYNASTRATORDownload Dynastrator at the Package Manager
Import vector art from Illustrator or the web using .svg. This allows you to import manually created drawings into Dynamo for parametric operations.
+ + + + + + + + + + + +
ENERGY ANALYSIS FOR DYNAMOVisit the Energy Analysis for Dynamo Project on GitHub
Energy Analysis for Dynamo allows for parametric energy modeling and whole-building energy analysis workflows in Dynamo 0.8. Energy Analysis for Dynamo allows the user to configure the energy model from Autodesk Revit, submit to Green Building Studio for DOE2 energy analysis, and dig into the results returned from the analysis. The package is being developed by Thornton Tomasetti's CORE studio.
+ + + + + + + + + + + +
FIREFLY FOR DYNAMODownload Firefly at the Dynamo Package Manager
Firefly is a collection of nodes which enable dynamo to talk to input/output devices, like the Arduino micro controller. Because the data flow happens “live”, Firefly opens up many opportunities for interactive prototyping between the digital and physical worlds through web cams, mobile phones, game controllers, sensors and more.
+ + + + + + + + + + + +
LUNCHBOX FOR DYNAMOCheckout Lunchbox for Dynamo on the Proving Ground
LunchBox is a collection of reusable geometry and data management nodes. The tools have been tested with Dynamo 0.8.1 and Revit 2016. The tool includes nodes for surface paneling, geometry, Revit data collection, and more!
+ + + + + + + + + + + +
MANTIS SHRIMPVisit the official Mantis Shrimp site.
Mantis Shrimp is an interoperability project that allows you to easily import Grasshopper and/or Rhino geometry into Dynamo.
+ + + + + + + + + + + +
MESH TOOLKITVisit the Dynamo Mesh Toolkit GitHub
The Dynamo Mesh Toolkit provides many useful tools for working with mesh geometry. The functionality of this package includes the ability to import meshes from external file formats, generate meshes from pre-existing Dynamo geometry objects, and manually build meshes through vertices and connectivity information. Additionally, this toolkit includes tools to modify and repair mesh geometry.
+ + + + + + + + + + + + + +
OPTIMOVisit the Optimo GitHub
Optimo provides dynamo users with the capability to optimize self-defined design problems by using various evolutionary algorithms. Users can define the problem objective or set of objectives as well as specific fitness functions.
+ + + + + + + + + + + + + +
RHYNAMOVisit the Rhynamo Bitbucket
The Rhynamo node library provides users with the ability to read and write Rhino 3DM files from within Dynamo. Rhynamo translates Rhino geometry into usable Dynamo geometry by using McNeel’s OpenNURBS library allowing for new workflows that can exchange geometry and data fluidly between Rhino and Revit. This package also contains some experimental nodes that allow for “live” access to the Rhino command line.
+ + + + + + + + + + + + + +
RHYTHMVisit Rhythm on GitHub
At first glance, Rhythm isn't anything special. It does not involve any sophisticated code or anything of that nature. What Rhythm does represent though, is the result of practical thinking and diligence. The idea is this package helps users maintain Rhythm in Revit with Dynamo. Rhythm primarily consists of out of the box Dynamo nodes used in clever ways as they apply to the Revit environment.
+ diff --git a/Appendix/A-4_example-files.md b/Appendix/A-4_example-files.md index 6ad5dc2b..ec79ffe6 100644 --- a/Appendix/A-4_example-files.md +++ b/Appendix/A-4_example-files.md @@ -1,106 +1,106 @@ -##Dynamo Example Files - -#####These example files accompany the Dynamo Primer, and are organized according to Chapter and Section. ->Right click files and use "Save Link As..." - - - - - -####Introduction#### -|Section|Download File| -|--|--| -|What is Visual Programming|[Visual Programming - Circle Through Point.dyn](../01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn) - -####Anatomy of a Dynamo Definition#### - -|Section|Download File| -|--|--| -|Presets|[Presets.dyn](../03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn) - - -####The Building Blocks of Programs#### - -|Section|Download File| -|--|--| -|Data|[Building Blocks of Programs - Data.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn) -|Math|[Building Blocks of Programs - Math.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn) -|Logic|[Building Blocks of Programs - Logic.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn) -|Strings|[Building Blocks of Programs - Strings.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn) -|Color|[Building Blocks of Programs - Color.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn) - -####Geometry for Computational Design#### -|Section|Download File| -|--|--| -|Geometry Overview|[Geometry for Computational Design - Geometry Overview.dyn](../05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn) -|Vectors|[Geometry for Computational Design - Vectors.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn) -||[Geometry for Computational Design - Plane.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn) -||[Geometry for Computational Design - Coordinate System.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn) -|Points|[Geometry for Computational Design - Points.dyn](../05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn) -|Curves|[Geometry for Computational Design - Curves.dyn](../05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn) -|Surfaces|[Geometry for Computational Design - Surfaces.dyn](../05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn) -||[Surface.sat](../05_Geometry-for-Computational-Design/datasets/5-5/Surface.sat) - -####Designing with Lists#### -|Section|Download File| -|--|--| -|What's a List|[Lacing.dyn](../06_Designing-with-Lists/datasets/6-1/Lacing.dyn) -|Working with Lists|[List-Count.dyn](../06_Designing-with-Lists/datasets/6-2/List-Count.dyn) -||[List-FilterByBooleanMask.dyn](../06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn) -||[List-GetItemAtIndex.dyn](../06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn) -||[List-Operations.dyn](../06_Designing-with-Lists/datasets/6-2/List-Operations.dyn) -||[List-Reverse.dyn](../06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn) -||[List-ShiftIndices.dyn](../06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn) -|Lists of Lists|[Chop.dyn](../06_Designing-with-Lists/datasets/6-3/Chop.dyn) -||[Combine.dyn](../06_Designing-with-Lists/datasets/6-3/Combine.dyn) -||[Flatten.dyn](../06_Designing-with-Lists/datasets/6-3/Flatten.dyn) -||[Map.dyn](../06_Designing-with-Lists/datasets/6-3/Map.dyn) -||[ReplaceItems.dyn](../06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn) -||[Top-Down-Hierarchy.dyn](../06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn) -||[Transpose.dyn](../06_Designing-with-Lists/datasets/6-3/Transpose.dyn) -|n-Dimensional Lists|[n-Dimensional-Lists.dyn](../06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn) -||[n-Dimensional-Lists.sat](../06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.sat) - - -####Code Blocks and DesignScript#### -|Section|Download File| -|--|--| -|DesignScript Syntax|[Dynamo-Syntax_Attractor-Surface.dyn](../07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn) -|Shorthand|[Obsolete-Nodes_Sine-Surface.dyn](../07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn) -|Functions|[Functions_SphereByZ.dyn](../07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn) - -####Dynamo for Revit#### -|Section|Download File| -|--|--| -|Selecting|[Selecting.dyn](../08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn) -||[ARCH-Selecing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-2/ARCH-Selecting-BaseFile.rvt) -|Editing|[Editing.dyn](../08_Dynamo-for-Revit/datasets/8-3/Editing.dyn) -||[ARCH-Editing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-3/ARCH-Editing-BaseFile.rvt) -|Creating|[Creating.dyn](../08_Dynamo-for-Revit/datasets/8-4/Creating.dyn) -||[ARCH-Creating-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-4/ARCH-Creating-BaseFile.rvt) -|Customizing|[Customizing.dyn](../08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn) -||[ARCH-Customizing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-5/ARCH-Customizing-BaseFile.rvt) -|Documenting|[Documenting.dyn](../08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn) -||[ARCH-Documenting-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-6/ARCH-Documenting-BaseFile.rvt) - -####Custom Nodes#### -|Section|Download File| -|--|--| -|Creating a Custom Node|[UV-CustomNode.zip](../09_Custom-Nodes/datasets/9-2/UV-CustomNode.zip) -|Publishing to Your Library|[PointsToSurface.dyf](../09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf) -|Python Nodes|[Python-CustomNode.dyn](../09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn) -|Python and Revit|[Revit-Doc.dyn](../09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn) -|Python and Revit|[Revit-ReferenceCurve.dyn](../09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn) -|Python and Revit|[Revit-StructuralFraming.zip](../09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.zip) - -####Packages#### -|Section|Download File| -|--|--| -|Package Case Study - Mesh Toolkit|[MeshToolkit.zip](../10_Packages/datasets/10-2/MeshToolkit.zip) -|Publishing a Package|[MapToSurface.zip](../10_Packages/datasets/10-4/MapToSurface.zip) +##Dynamo Example Files + +#####These example files accompany the Dynamo Primer, and are organized according to Chapter and Section. +>Right click files and use "Save Link As..." + + + + + +####Introduction#### +|Section|Download File| +|--|--| +|What is Visual Programming|[Visual Programming - Circle Through Point.dyn](../01_Introduction/datasets/1-1/Visual Programming - Circle Through Point.dyn) + +####Anatomy of a Dynamo Definition#### + +|Section|Download File| +|--|--| +|Presets|[Presets.dyn](../03_Anatomy-of-a-Dynamo-Definition/datasets/3-5/Presets.dyn) + + +####The Building Blocks of Programs#### + +|Section|Download File| +|--|--| +|Data|[Building Blocks of Programs - Data.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-1/Building Blocks of Programs - Data.dyn) +|Math|[Building Blocks of Programs - Math.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-2/Building Blocks of Programs - Math.dyn) +|Logic|[Building Blocks of Programs - Logic.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-3/Building Blocks of Programs - Logic.dyn) +|Strings|[Building Blocks of Programs - Strings.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-4/Building Blocks of Programs - Strings.dyn) +|Color|[Building Blocks of Programs - Color.dyn](../04_The-Building-Blocks-of-Programs/datasets/4-5/Building Blocks of Programs - Color.dyn) + +####Geometry for Computational Design#### +|Section|Download File| +|--|--| +|Geometry Overview|[Geometry for Computational Design - Geometry Overview.dyn](../05_Geometry-for-Computational-Design/datasets/5-1/Geometry for Computational Design - Geometry Overview.dyn) +|Vectors|[Geometry for Computational Design - Vectors.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Vectors.dyn) +||[Geometry for Computational Design - Plane.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Plane.dyn) +||[Geometry for Computational Design - Coordinate System.dyn](../05_Geometry-for-Computational-Design/datasets/5-2/Geometry for Computational Design - Coordinate System.dyn) +|Points|[Geometry for Computational Design - Points.dyn](../05_Geometry-for-Computational-Design/datasets/5-3/Geometry for Computational Design - Points.dyn) +|Curves|[Geometry for Computational Design - Curves.dyn](../05_Geometry-for-Computational-Design/datasets/5-4/Geometry for Computational Design - Curves.dyn) +|Surfaces|[Geometry for Computational Design - Surfaces.dyn](../05_Geometry-for-Computational-Design/datasets/5-5/Geometry for Computational Design - Surfaces.dyn) +||[Surface.sat](../05_Geometry-for-Computational-Design/datasets/5-5/Surface.sat) + +####Designing with Lists#### +|Section|Download File| +|--|--| +|What's a List|[Lacing.dyn](../06_Designing-with-Lists/datasets/6-1/Lacing.dyn) +|Working with Lists|[List-Count.dyn](../06_Designing-with-Lists/datasets/6-2/List-Count.dyn) +||[List-FilterByBooleanMask.dyn](../06_Designing-with-Lists/datasets/6-2/List-FilterByBooleanMask.dyn) +||[List-GetItemAtIndex.dyn](../06_Designing-with-Lists/datasets/6-2/List-GetItemAtIndex.dyn) +||[List-Operations.dyn](../06_Designing-with-Lists/datasets/6-2/List-Operations.dyn) +||[List-Reverse.dyn](../06_Designing-with-Lists/datasets/6-2/List-Reverse.dyn) +||[List-ShiftIndices.dyn](../06_Designing-with-Lists/datasets/6-2/List-ShiftIndices.dyn) +|Lists of Lists|[Chop.dyn](../06_Designing-with-Lists/datasets/6-3/Chop.dyn) +||[Combine.dyn](../06_Designing-with-Lists/datasets/6-3/Combine.dyn) +||[Flatten.dyn](../06_Designing-with-Lists/datasets/6-3/Flatten.dyn) +||[Map.dyn](../06_Designing-with-Lists/datasets/6-3/Map.dyn) +||[ReplaceItems.dyn](../06_Designing-with-Lists/datasets/6-3/ReplaceItems.dyn) +||[Top-Down-Hierarchy.dyn](../06_Designing-with-Lists/datasets/6-3/Top-Down-Hierarchy.dyn) +||[Transpose.dyn](../06_Designing-with-Lists/datasets/6-3/Transpose.dyn) +|n-Dimensional Lists|[n-Dimensional-Lists.dyn](../06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.dyn) +||[n-Dimensional-Lists.sat](../06_Designing-with-Lists/datasets/6-4/n-Dimensional-Lists.sat) + + +####Code Blocks and DesignScript#### +|Section|Download File| +|--|--| +|DesignScript Syntax|[Dynamo-Syntax_Attractor-Surface.dyn](../07_Code-Block/datasets/7-2/Dynamo-Syntax_Attractor-Surface.dyn) +|Shorthand|[Obsolete-Nodes_Sine-Surface.dyn](../07_Code-Block/datasets/7-3/Obsolete-Nodes_Sine-Surface.dyn) +|Functions|[Functions_SphereByZ.dyn](../07_Code-Block/datasets/7-4/Functions_SphereByZ.dyn) + +####Dynamo for Revit#### +|Section|Download File| +|--|--| +|Selecting|[Selecting.dyn](../08_Dynamo-for-Revit/datasets/8-2/Selecting.dyn) +||[ARCH-Selecing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-2/ARCH-Selecting-BaseFile.rvt) +|Editing|[Editing.dyn](../08_Dynamo-for-Revit/datasets/8-3/Editing.dyn) +||[ARCH-Editing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-3/ARCH-Editing-BaseFile.rvt) +|Creating|[Creating.dyn](../08_Dynamo-for-Revit/datasets/8-4/Creating.dyn) +||[ARCH-Creating-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-4/ARCH-Creating-BaseFile.rvt) +|Customizing|[Customizing.dyn](../08_Dynamo-for-Revit/datasets/8-5/Customizing.dyn) +||[ARCH-Customizing-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-5/ARCH-Customizing-BaseFile.rvt) +|Documenting|[Documenting.dyn](../08_Dynamo-for-Revit/datasets/8-6/Documenting.dyn) +||[ARCH-Documenting-BaseFile.rvt](../08_Dynamo-for-Revit/datasets/8-6/ARCH-Documenting-BaseFile.rvt) + +####Custom Nodes#### +|Section|Download File| +|--|--| +|Creating a Custom Node|[UV-CustomNode.zip](../09_Custom-Nodes/datasets/9-2/UV-CustomNode.zip) +|Publishing to Your Library|[PointsToSurface.dyf](../09_Custom-Nodes/datasets/9-3/PointsToSurface.dyf) +|Python Nodes|[Python-CustomNode.dyn](../09_Custom-Nodes/datasets/9-4/Python-CustomNode.dyn) +|Python and Revit|[Revit-Doc.dyn](../09_Custom-Nodes/datasets/9-5/Revit-Doc.dyn) +|Python and Revit|[Revit-ReferenceCurve.dyn](../09_Custom-Nodes/datasets/9-5/Revit-ReferenceCurve.dyn) +|Python and Revit|[Revit-StructuralFraming.zip](../09_Custom-Nodes/datasets/9-5/Revit-StructuralFraming.zip) + +####Packages#### +|Section|Download File| +|--|--| +|Package Case Study - Mesh Toolkit|[MeshToolkit.zip](../10_Packages/datasets/10-2/MeshToolkit.zip) +|Publishing a Package|[MapToSurface.zip](../10_Packages/datasets/10-4/MapToSurface.zip) |Zero-Touch Importing|[ZeroTouchImages.zip](../10_Packages/datasets/10-5/ZeroTouchImages.zip) \ No newline at end of file diff --git a/Appendix/A_appendix.md b/Appendix/A_appendix.md index b61c7a35..61f37b4f 100644 --- a/Appendix/A_appendix.md +++ b/Appendix/A_appendix.md @@ -1,4 +1,4 @@ -# Appendix - -In this section, you can find additional resources for taking your Dynamo game one step further. We've also added an index of important nodes, a collection of useful packages, and a repository of the example files in this primer. Please feel free to add to this section...remember, the [Dynamo Primer](https://github.com/DynamoDS/DynamoPrimer) is open source! -![IMAGE](images/A/a-cover.png) +# Appendix + +In this section, you can find additional resources for taking your Dynamo game one step further. We've also added an index of important nodes, a collection of useful packages, and a repository of the example files in this primer. Please feel free to add to this section...remember, the [Dynamo Primer](https://github.com/DynamoDS/DynamoPrimer) is open source! +![IMAGE](images/A/a-cover.png) diff --git a/Archive/color.md b/Archive/color.md index 5f491a13..5bc8190d 100644 --- a/Archive/color.md +++ b/Archive/color.md @@ -1,46 +1,46 @@ -## Color - - -### Creating -**Color.ByARGB -** Colors in Dynamo are created using ARGB inputs. This corresponds to the Alpha, Red, Green, and Blue values. The alpha represents the *transparency* of the color, while the other three are used as primary colors to generate the whole spectrum of color in concert. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Color-ByARGB-Large.png) | ARGB Color | Color.ByARGB | A,R,G,B | color | - - -### Querying -**RGB Space -** The colors in the table below query the properties used to define the color: Alpha, Red, Green, and Blue. Note that the Color.Components node gives us all four as different outputs, which makes this node preferable for querying the properties of a color. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Color-Alpha-Large.png) | Alpha | Color.Alpha | color | A | -| ![](../images/icons/DSCore-Color-Red-Large.png) | Red | Color.Red | color | R | -| ![](../images/icons/DSCore-Color-Green-Large.png) | Green | Color.Green | color | G | -| ![](../images/icons/DSCore-Color-Blue-Large.png) | Blue | Color.Blue | color | B | -| ![](../images/icons/DSCore-Color-Components-Large.png) | Components | Color.Components | color | A,R,G,B | - -**HSB Space - ** The colors in the table below correspond to the HSB color space. Dividing the color into hue, saturation, and brightness is arguably more intuitive for how we interpret color: What color should it be? How colorful should it be? And how light or dark should the color be? This is the breakdown of hue, saturation, and brightness respectively. - -| Icon | Query Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Color-Hue-Large.png) | Hue | Color.Hue | color | Hue | -| ![](../images/icons/DSCore-Color-Saturation-Large.png) | Saturation | Color.Saturation | color | Saturation | -| ![](../images/icons/DSCore-Color-Brightness-Large.png) | Brightness | Color.Brightness | color | Brightness | - -### Color Range -The color range is similar to the **Remap Range** node from section 4.2: it remaps a list of numbers into another domain. But instead of mapping to a *number* domain, it maps to a *color gradient* based on input numbers ranging from 0 to 1. - -The current node works well, but it can be a little awkward to get everything working the first time around. Below is a miniature exercise for how to setup a gradient with output colors corresponding to numbers. - -![](images/4-5/range.png) ->1. **Define three colors: ** Using a code block node, define *red, green*, and *blue* by plugging in the appropriate combinations of *0* and *255*. -2. **Create list:** Merge the three colors into one list. -3. **Define Indices: ** Create a list to define the grip positions of each color (ranging from 0 to 1). Notice the value of 0.75 for green. This places the green color 3/4 of the way across the horizontal gradient in the color range slider. -4. **Code Block: ** Input values (between 0 and 1) to translate to colors. - -The best way to become familiar with the color gradient is to test it out interactively. See the Color Exercise at the end of this section to try it in action. -### Color Preview -![](images/4-5/cuboids.png) - -The **Display.ByGeometry** node gives us the ability to color geometry in the Dynamo viewport. This is helpful for separating different types of geometry, demonstrating a parametric concept, or defining an analysis legend for simulation. The inputs are simple: geometry and color. To createa a gradient like the image above, the color input is connected to the **color range** node. Both of these batteries are discussed in the Color exercise at the end of this section. +## Color + + +### Creating +**Color.ByARGB -** Colors in Dynamo are created using ARGB inputs. This corresponds to the Alpha, Red, Green, and Blue values. The alpha represents the *transparency* of the color, while the other three are used as primary colors to generate the whole spectrum of color in concert. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Color-ByARGB-Large.png) | ARGB Color | Color.ByARGB | A,R,G,B | color | + + +### Querying +**RGB Space -** The colors in the table below query the properties used to define the color: Alpha, Red, Green, and Blue. Note that the Color.Components node gives us all four as different outputs, which makes this node preferable for querying the properties of a color. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Color-Alpha-Large.png) | Alpha | Color.Alpha | color | A | +| ![](../images/icons/DSCore-Color-Red-Large.png) | Red | Color.Red | color | R | +| ![](../images/icons/DSCore-Color-Green-Large.png) | Green | Color.Green | color | G | +| ![](../images/icons/DSCore-Color-Blue-Large.png) | Blue | Color.Blue | color | B | +| ![](../images/icons/DSCore-Color-Components-Large.png) | Components | Color.Components | color | A,R,G,B | + +**HSB Space - ** The colors in the table below correspond to the HSB color space. Dividing the color into hue, saturation, and brightness is arguably more intuitive for how we interpret color: What color should it be? How colorful should it be? And how light or dark should the color be? This is the breakdown of hue, saturation, and brightness respectively. + +| Icon | Query Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Color-Hue-Large.png) | Hue | Color.Hue | color | Hue | +| ![](../images/icons/DSCore-Color-Saturation-Large.png) | Saturation | Color.Saturation | color | Saturation | +| ![](../images/icons/DSCore-Color-Brightness-Large.png) | Brightness | Color.Brightness | color | Brightness | + +### Color Range +The color range is similar to the **Remap Range** node from section 4.2: it remaps a list of numbers into another domain. But instead of mapping to a *number* domain, it maps to a *color gradient* based on input numbers ranging from 0 to 1. + +The current node works well, but it can be a little awkward to get everything working the first time around. Below is a miniature exercise for how to setup a gradient with output colors corresponding to numbers. + +![](images/4-5/range.png) +>1. **Define three colors: ** Using a code block node, define *red, green*, and *blue* by plugging in the appropriate combinations of *0* and *255*. +2. **Create list:** Merge the three colors into one list. +3. **Define Indices: ** Create a list to define the grip positions of each color (ranging from 0 to 1). Notice the value of 0.75 for green. This places the green color 3/4 of the way across the horizontal gradient in the color range slider. +4. **Code Block: ** Input values (between 0 and 1) to translate to colors. + +The best way to become familiar with the color gradient is to test it out interactively. See the Color Exercise at the end of this section to try it in action. +### Color Preview +![](images/4-5/cuboids.png) + +The **Display.ByGeometry** node gives us the ability to color geometry in the Dynamo viewport. This is helpful for separating different types of geometry, demonstrating a parametric concept, or defining an analysis legend for simulation. The inputs are simple: geometry and color. To createa a gradient like the image above, the color input is connected to the **color range** node. Both of these batteries are discussed in the Color exercise at the end of this section. diff --git a/Archive/core.md b/Archive/core.md index 3b616f93..92b85441 100644 --- a/Archive/core.md +++ b/Archive/core.md @@ -1 +1 @@ -# Core +# Core diff --git a/Archive/data.md b/Archive/data.md index 5a6ca98d..e1f2861a 100644 --- a/Archive/data.md +++ b/Archive/data.md @@ -1,121 +1,121 @@ -## Data - -### Types -#### Numbers -| Icon | Name | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/Dynamo-Nodes-DoubleInput-Large.png) | Number | Number Box | double | - -Simply put, a number node allows one to add a number to the canvas by typing it in the number box. This can be an integer, decimal, negative number, etc. There are other options for adding numbers to the canvas, including sliders, which we'll demonstrate in the exercise at the end of this section. -#### Booleans -| Icon | Name | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCoreNodesUI-BoolSelector-Large.png) | Boolean | True/False | boolean | -Numeric variables can store a whole range of different numbers. Boolean -variables can only store two values referred to as Yes or No, True or False, -1 or 0. Obviously we never use booleans to perform calculations because of their -limited range. We use booleans to evaluate conditions. -#### Strings -| Icon | Name | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/Dynamo-Nodes-StringInput-Large.png) | String | Text Box | string | -A string is programming lingo for text. We know that number can drive parameters, and we can do the same with text, which we demonstrate in section 4.4. -## Geometry -![](images/4-1/CompGeom-01-Dimensionality-01.png) -#####Points - -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-ByCoordinates-double-double-double-Large.png) | Point.ByCoordinates | x,y,z | Point | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-ByCylindricalCoordinates-Large.png) | Point.ByCylindricalCoordinates | cs,angle,elevation,radius | Point | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-BySphericalCoordinates-Large.png) | Point.BySphericalCoordinates | cs,phi,theta,radius | Point | - -A point is a location in space. For this primer, our coordinate system is X,Y, and Z. A point has a value for X, a value for Y, and a value for Z. - - -#####Vectors -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ByCoordinates-double-double-double-Large.png) | Vector.ByCoordinates | x,y,z | Vector | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ByTwoPoints-Large.png) | Vector.ByTwoPoints| start,end | Vector | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-XAxis-Large.png) | Vector.XAxis | none | Vector | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-YAxis-Large.png) | Vector.YAxis | none | Vector | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ZAxis-Large.png) | Vector.ZAxis | none | Vector | - -A vector is a geometric quantity describing Direction and Magnitude. Vectors are abstract; ie. they represent a quantity, not a geometrical element. - -#####Planes -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-ByThreePoints-Large.png) | Vector.ByCoordinates | p1,p2,p3 | Plane | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-ByOriginNormal-Large.png) | Vector.ByTwoPoints| origin,normal | Plane | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-XY-Large.png) | Plane.XY | none | Plane | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-XZ-Large.png) | Plane.XZ | none | Plane | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-YZ-Large.png) | Plane.YZ | none | Plane | - -Planes are “Flat” and extend infinitely in two directions, defining a local coordinate system. - -#####Nurbs -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-NurbsSurface-ControlPoints-Large.png) | NurbsSurface.ByControlPoints | ControlVertices,uDegree,vDegree | NurbsSurface | -| ![](../images/icons/Autodesk-DesignScript-Geometry-NurbsCurve-ByControlPoints-Point1-Large.png) | NurbsCurve.ByControlPoints | points | NurbsCurve | - -NURBS (non-uniform rational B-splines) are mathematical representations that can accurately model any shape from a simple 2D line, circle, arc, or box to the most complex 3D free-form organic surface or solid. They are created with rational algorithms and are infinitely differentiable. - -#####Meshes -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Mesh-ByPointsFaceIndices-Large.png) | Mesh.ByPointsFaceIndices | vertexPositions,indices | Mesh | - -A mesh is a collection of vertices, edges and faces which define a polyhedral object. Meshes are often used for rendering and animation, and are generally 'lighter weight' than nurbs (meaning, they have smaller file sizes and render more quickly). The tradeoff is that meshes are limited in their resolution. - -#####Meshes vs. Nurbs -Generally, we can say that Nurbs are to Meshes as Vectors are to Pixels. They are significantly different geometry types, and using the propery geometry type for surfaces is critical for parametric modeling and file management. - -![nurbs and meshes](images/4-1/4-1-1/4-1-1-Mesh-Nurb.png) - -#####Surfaces -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByLoft-Curve1-Curve-Large.png) | Surface.ByLoft | crossSections | Surface | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByPatch-Large.png) | Surface.ByPatch| closedCurve | Surface | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByPerimeterPoints-Large.png) | Surface.ByPerimeterPoints | points | Surface | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-BySweep-Large.png) | Surface.BySweep| profile,path | Surface | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByRevolve-Large.png) | Surface.ByRevolve | profile,axisOrigin,axisDirection,startAngle,sweepAngle | Surface | - -A surface is two-dimensional topological manifold. Rather than deciphering what that means, let's just saw a surface is geometry that does not have thickness. This is how a surface is different from a solid. - -#####Solids -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByUnion-Large.png) | Solid.ByUnion | solids | Solid | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByJoinedSurfaces-Large.png) | Solid.ByJoinedSurfaces| facesOfSolid | Solid | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByLoft-Curve1-Large.png) | Solid.ByLoft | crossSections | Solid | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-BySweep-Large.png) | Solid.BySweep| profile,path | Solid | -| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByRevolve-Large.png) | Solid.ByRevolve | profile,axisOrigin,axisDirection,startAngle,sweepAngle | Solid | - -A solid is three-dimensional geometry. A solid has thickness and can exist in the real world, unlike surfaces, curves, vectors, and points (at least as far as we can see). In Dynamo, a solid can be defined as a collection of surfaces, called a polysurface. - -##### "Null" -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Object-IsNull-Large.png) | Object.IsNull | obj | bool | - -The 'null' object represents the absense of data. This is abstract, but you will likely come across this while working with visual programming. Testing for nulls and removing nulls from data structure is a crucial part to creating robust parametric models. -### 4.1.2 Hierarchy -#### Item(s) - -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-List-GetItemAtIndex-Large.png) | List.GetItemAtIndex | list,index | var[]...[] | - -Simply put, an item represents one single value, whether by itself or as part of a list. This can be any data type. - -#### List(s) -| Icon | Name/Syntax | Inputs | Outputs | -| -- | -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-List-Create-Large.png) | List.Create | index0, index1... | list | - - - +## Data + +### Types +#### Numbers +| Icon | Name | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/Dynamo-Nodes-DoubleInput-Large.png) | Number | Number Box | double | + +Simply put, a number node allows one to add a number to the canvas by typing it in the number box. This can be an integer, decimal, negative number, etc. There are other options for adding numbers to the canvas, including sliders, which we'll demonstrate in the exercise at the end of this section. +#### Booleans +| Icon | Name | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCoreNodesUI-BoolSelector-Large.png) | Boolean | True/False | boolean | +Numeric variables can store a whole range of different numbers. Boolean +variables can only store two values referred to as Yes or No, True or False, +1 or 0. Obviously we never use booleans to perform calculations because of their +limited range. We use booleans to evaluate conditions. +#### Strings +| Icon | Name | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/Dynamo-Nodes-StringInput-Large.png) | String | Text Box | string | +A string is programming lingo for text. We know that number can drive parameters, and we can do the same with text, which we demonstrate in section 4.4. +## Geometry +![](images/4-1/CompGeom-01-Dimensionality-01.png) +#####Points + +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-ByCoordinates-double-double-double-Large.png) | Point.ByCoordinates | x,y,z | Point | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-ByCylindricalCoordinates-Large.png) | Point.ByCylindricalCoordinates | cs,angle,elevation,radius | Point | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Point-BySphericalCoordinates-Large.png) | Point.BySphericalCoordinates | cs,phi,theta,radius | Point | + +A point is a location in space. For this primer, our coordinate system is X,Y, and Z. A point has a value for X, a value for Y, and a value for Z. + + +#####Vectors +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ByCoordinates-double-double-double-Large.png) | Vector.ByCoordinates | x,y,z | Vector | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ByTwoPoints-Large.png) | Vector.ByTwoPoints| start,end | Vector | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-XAxis-Large.png) | Vector.XAxis | none | Vector | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-YAxis-Large.png) | Vector.YAxis | none | Vector | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Vector-ZAxis-Large.png) | Vector.ZAxis | none | Vector | + +A vector is a geometric quantity describing Direction and Magnitude. Vectors are abstract; ie. they represent a quantity, not a geometrical element. + +#####Planes +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-ByThreePoints-Large.png) | Vector.ByCoordinates | p1,p2,p3 | Plane | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-ByOriginNormal-Large.png) | Vector.ByTwoPoints| origin,normal | Plane | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-XY-Large.png) | Plane.XY | none | Plane | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-XZ-Large.png) | Plane.XZ | none | Plane | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Plane-YZ-Large.png) | Plane.YZ | none | Plane | + +Planes are “Flat” and extend infinitely in two directions, defining a local coordinate system. + +#####Nurbs +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-NurbsSurface-ControlPoints-Large.png) | NurbsSurface.ByControlPoints | ControlVertices,uDegree,vDegree | NurbsSurface | +| ![](../images/icons/Autodesk-DesignScript-Geometry-NurbsCurve-ByControlPoints-Point1-Large.png) | NurbsCurve.ByControlPoints | points | NurbsCurve | + +NURBS (non-uniform rational B-splines) are mathematical representations that can accurately model any shape from a simple 2D line, circle, arc, or box to the most complex 3D free-form organic surface or solid. They are created with rational algorithms and are infinitely differentiable. + +#####Meshes +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Mesh-ByPointsFaceIndices-Large.png) | Mesh.ByPointsFaceIndices | vertexPositions,indices | Mesh | + +A mesh is a collection of vertices, edges and faces which define a polyhedral object. Meshes are often used for rendering and animation, and are generally 'lighter weight' than nurbs (meaning, they have smaller file sizes and render more quickly). The tradeoff is that meshes are limited in their resolution. + +#####Meshes vs. Nurbs +Generally, we can say that Nurbs are to Meshes as Vectors are to Pixels. They are significantly different geometry types, and using the propery geometry type for surfaces is critical for parametric modeling and file management. + +![nurbs and meshes](images/4-1/4-1-1/4-1-1-Mesh-Nurb.png) + +#####Surfaces +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByLoft-Curve1-Curve-Large.png) | Surface.ByLoft | crossSections | Surface | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByPatch-Large.png) | Surface.ByPatch| closedCurve | Surface | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByPerimeterPoints-Large.png) | Surface.ByPerimeterPoints | points | Surface | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-BySweep-Large.png) | Surface.BySweep| profile,path | Surface | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Surface-ByRevolve-Large.png) | Surface.ByRevolve | profile,axisOrigin,axisDirection,startAngle,sweepAngle | Surface | + +A surface is two-dimensional topological manifold. Rather than deciphering what that means, let's just saw a surface is geometry that does not have thickness. This is how a surface is different from a solid. + +#####Solids +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByUnion-Large.png) | Solid.ByUnion | solids | Solid | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByJoinedSurfaces-Large.png) | Solid.ByJoinedSurfaces| facesOfSolid | Solid | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByLoft-Curve1-Large.png) | Solid.ByLoft | crossSections | Solid | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-BySweep-Large.png) | Solid.BySweep| profile,path | Solid | +| ![](../images/icons/Autodesk-DesignScript-Geometry-Solid-ByRevolve-Large.png) | Solid.ByRevolve | profile,axisOrigin,axisDirection,startAngle,sweepAngle | Solid | + +A solid is three-dimensional geometry. A solid has thickness and can exist in the real world, unlike surfaces, curves, vectors, and points (at least as far as we can see). In Dynamo, a solid can be defined as a collection of surfaces, called a polysurface. + +##### "Null" +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Object-IsNull-Large.png) | Object.IsNull | obj | bool | + +The 'null' object represents the absense of data. This is abstract, but you will likely come across this while working with visual programming. Testing for nulls and removing nulls from data structure is a crucial part to creating robust parametric models. +### 4.1.2 Hierarchy +#### Item(s) + +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-List-GetItemAtIndex-Large.png) | List.GetItemAtIndex | list,index | var[]...[] | + +Simply put, an item represents one single value, whether by itself or as part of a list. This can be any data type. + +#### List(s) +| Icon | Name/Syntax | Inputs | Outputs | +| -- | -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-List-Create-Large.png) | List.Create | index0, index1... | list | + + + diff --git a/Archive/logic.md b/Archive/logic.md index 8205d77a..7476cda9 100644 --- a/Archive/logic.md +++ b/Archive/logic.md @@ -1,75 +1,75 @@ -## Logic - -### Booleans -Numeric variables can store a whole range of different numbers. Boolean -variables can only store two values referred to as Yes or No, True or False, -1 or 0. Obviously we never use booleans to perform calculations because of their -limited range. We use booleans to evaluate conditions. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCoreNodesUI-BoolSelector-Large.png) | Boolean | -- | True/False Radio Button | Boolean | -> The boolean Node in Dynamo is a basic radio button, toggling between true and false. - -At the most basic level, Dynamo has a boolean Node which functions as a light switch for logical operations. This is a fundamental element for making conditional evaluation. - -### "If" -The "If" statement is a key concept in programming: "If *this* is true, then *that* happens, otherwise *something else* happens. The statement's decision is driven by a boolean, and the two results are defined by the user. There are multiple ways to define an "If" statement in Dynamo: - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCoreNodesUI-Logic-If-Large.png) | If | If | test, true, false | result| -| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | IF(x,y,z) | x, y, z | result | -| ![](../images/icons/Dynamo-Nodes-CodeBlockNodeModel-Large.png) | Code Block | (x?y:z)| x, y, z | result| -Let's go over a brief example on each of these three nodes in action using the conditional "If" statement: - -![](images/4-3/Ifs.png) -> In this image, the *boolean* is set to *true*, which means that the result is a string reading: *"this is the result if true".* The three Nodes creating the *If* statement are working identically here. - -![](images/4-3/Ifs2.png) -> Again, the Nodes are working identically. If the *boolean* is changed to *false*, our result is the number *Pi*, as defined in the original *If* statement. - -### Relational Operators -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/lt-Large.png) | Less Than | < | x,y | boolean(s)| -| ![](../images/icons/le-Large.png) | Less Than or Equal To | <=| x, y | boolean(s) | -| ![](../images/icons/gt-Large.png) |Greater Than |>| x, y | boolean(s)| -| ![](../images/icons/ge-Large.png) | Greater Than or Equal To | >=| x, y | boolean(s)| -| ![](../images/icons/eq-Large.png) | Equal To | ==| x, y | boolean(s)| -| ![](../images/icons/nq-Large.png) | Not Equal To | !=| x| boolean(s)| -Relational operators receive one or more inputs, and output a boolean depending on the result of a specific test. In summary, these are the "*greater than, less than*" tests. The demo below gives us an example. - -![](images/4-3/largesmall.png) -> The result of each test is a boolean. In the *less than* test, *2* is indeed *less than 5*, o the result is *true*. In the *greater than* test, *2* is not *greater than 5*, so the result is *false*. - -### Logic Gates -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Logic-And-Large.png) | And | && | x, y | boolean(s)| -| ![](../images/icons/and-Large.png) | And | And | bool0,bool1... | boolean(s) | -| ![](../images/icons/or-Large.png) | Or |//| x, y | boolean(s)| -| ![](../images/icons/DSCore-Logic-Or-Large.png) | Or| Or| bool0, bool1... | boolean(s)| -| ![](../images/icons/DSCore-Logic-Xor-Large.png) | Xor |Logic.Xor| a, b | boolean(s)| -| ![](../images/icons/Not-Large.png) | Not |Not| x | boolean(s)| -In its simplest form, a logic gate receives two booleans and outputs one boolean. These are based on fundamental sets, much like a [Venn Diagram](http://en.wikipedia.org/wiki/Venn_diagram). Dynamo uses the basic gates of *And*, *Or*, and *Xor*. - -**And/&& -** In the table above, the two Nodes for *And* may be confusing. Here is how they're different: - -![](images/4-3/andand.png) -> The *&&* Node receives two inputs. The *And* Node receives two inputs by default (middle icon), but one can click the *+/-* to add or subtract more inputs (right icon with 4 inputs). Other than that, the two are functionally identical. So go with *And* Node. - -**Xor -** This Node returns a true value if and only if *one* of the values is *true*. - - -![](images/4-3/onetrue.png) -> This image show the four combinations of two booleans. If both values are *true*, a *false* is returned. If both values are *false*, a *false* is also returned. The *true* value is return if and only if *one* of the values is *true*. This rounds out the three main logic gates for two booleans. - - -### Filter - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-List-FilterByBoolMask-Large.png) | Filter By Boolean Mask | List.FilterByBoolMask | list, mask | in, out| - -*List.FilterByBoolMask* is a great tool for geometry operations. After conducting a conditional test on an array of elements, one can parse through those elements with this node. In the exercise below, we demonstrate this in detail. +## Logic + +### Booleans +Numeric variables can store a whole range of different numbers. Boolean +variables can only store two values referred to as Yes or No, True or False, +1 or 0. Obviously we never use booleans to perform calculations because of their +limited range. We use booleans to evaluate conditions. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCoreNodesUI-BoolSelector-Large.png) | Boolean | -- | True/False Radio Button | Boolean | +> The boolean Node in Dynamo is a basic radio button, toggling between true and false. + +At the most basic level, Dynamo has a boolean Node which functions as a light switch for logical operations. This is a fundamental element for making conditional evaluation. + +### "If" +The "If" statement is a key concept in programming: "If *this* is true, then *that* happens, otherwise *something else* happens. The statement's decision is driven by a boolean, and the two results are defined by the user. There are multiple ways to define an "If" statement in Dynamo: + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCoreNodesUI-Logic-If-Large.png) | If | If | test, true, false | result| +| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | IF(x,y,z) | x, y, z | result | +| ![](../images/icons/Dynamo-Nodes-CodeBlockNodeModel-Large.png) | Code Block | (x?y:z)| x, y, z | result| +Let's go over a brief example on each of these three nodes in action using the conditional "If" statement: + +![](images/4-3/Ifs.png) +> In this image, the *boolean* is set to *true*, which means that the result is a string reading: *"this is the result if true".* The three Nodes creating the *If* statement are working identically here. + +![](images/4-3/Ifs2.png) +> Again, the Nodes are working identically. If the *boolean* is changed to *false*, our result is the number *Pi*, as defined in the original *If* statement. + +### Relational Operators +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/lt-Large.png) | Less Than | < | x,y | boolean(s)| +| ![](../images/icons/le-Large.png) | Less Than or Equal To | <=| x, y | boolean(s) | +| ![](../images/icons/gt-Large.png) |Greater Than |>| x, y | boolean(s)| +| ![](../images/icons/ge-Large.png) | Greater Than or Equal To | >=| x, y | boolean(s)| +| ![](../images/icons/eq-Large.png) | Equal To | ==| x, y | boolean(s)| +| ![](../images/icons/nq-Large.png) | Not Equal To | !=| x| boolean(s)| +Relational operators receive one or more inputs, and output a boolean depending on the result of a specific test. In summary, these are the "*greater than, less than*" tests. The demo below gives us an example. + +![](images/4-3/largesmall.png) +> The result of each test is a boolean. In the *less than* test, *2* is indeed *less than 5*, o the result is *true*. In the *greater than* test, *2* is not *greater than 5*, so the result is *false*. + +### Logic Gates +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Logic-And-Large.png) | And | && | x, y | boolean(s)| +| ![](../images/icons/and-Large.png) | And | And | bool0,bool1... | boolean(s) | +| ![](../images/icons/or-Large.png) | Or |//| x, y | boolean(s)| +| ![](../images/icons/DSCore-Logic-Or-Large.png) | Or| Or| bool0, bool1... | boolean(s)| +| ![](../images/icons/DSCore-Logic-Xor-Large.png) | Xor |Logic.Xor| a, b | boolean(s)| +| ![](../images/icons/Not-Large.png) | Not |Not| x | boolean(s)| +In its simplest form, a logic gate receives two booleans and outputs one boolean. These are based on fundamental sets, much like a [Venn Diagram](http://en.wikipedia.org/wiki/Venn_diagram). Dynamo uses the basic gates of *And*, *Or*, and *Xor*. + +**And/&& -** In the table above, the two Nodes for *And* may be confusing. Here is how they're different: + +![](images/4-3/andand.png) +> The *&&* Node receives two inputs. The *And* Node receives two inputs by default (middle icon), but one can click the *+/-* to add or subtract more inputs (right icon with 4 inputs). Other than that, the two are functionally identical. So go with *And* Node. + +**Xor -** This Node returns a true value if and only if *one* of the values is *true*. + + +![](images/4-3/onetrue.png) +> This image show the four combinations of two booleans. If both values are *true*, a *false* is returned. If both values are *false*, a *false* is also returned. The *true* value is return if and only if *one* of the values is *true*. This rounds out the three main logic gates for two booleans. + + +### Filter + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-List-FilterByBoolMask-Large.png) | Filter By Boolean Mask | List.FilterByBoolMask | list, mask | in, out| + +*List.FilterByBoolMask* is a great tool for geometry operations. After conducting a conditional test on an array of elements, one can parse through those elements with this node. In the exercise below, we demonstrate this in detail. diff --git a/Archive/math.md b/Archive/math.md index 7b7c5b54..e92730b1 100644 --- a/Archive/math.md +++ b/Archive/math.md @@ -1,169 +1,169 @@ -## Math - -## Constants - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-PI-Large.png) | Pi | Math.PI | none | double | - -**Pi -** is a mathematical constant which represents the ratio of circle's circumference to its diameter. The value is commonly used in trigonmetric functions and is one of the more prevalent constants used in parametric modeling. A rounded value for *Pi* is *3.14159*. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-E-Large.png) | e | Math.E | none | double | - -**e -** The number *e* is a mathematical constant which is based on the natural logarithm. Like *pi*, *e* is an irrational number which is commonly used in mathematics. The number is fundamental to growth prediction, and shows itself often in the fields of biology and economics. A rounded value for *e* is *2.71828*. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-GoldenRatio-Large.png) | phi | Math.GoldenRatio | none | double | - - -**φ: The Golden Ratio - **Another irrational constant, the golden ratio defines that two quantities are in the golden ratio if their ratio is the same as the ratio of their sum to the larger of the two quantities. This ratio appears often in geometry and biological systems, and is considered for a wide-range of applications ranging from the practical to the aesthetic. A rounded value for *φ* is *1.61804*. - -## Arithmetic Operators -Operators are a set of components that use -algebraic functions with two numeric input values, which result in one output -value (addition, subtraction, multiplication, division, etc.). - -You use the Math Operators to perform arithmetical -actions on a set of numbers. These can be found under Operators>Actions. - -**Addition, Subtraction, Multiplication, Division -** These four operators are commonplace. Let's look at a few other operators which dive deeper: - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/add-Large.png) | Add | + | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/sub-Large.png) | Subtract | - | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/mul-Large.png) | Multiply | * | var[]...[], var[]...[] | var[]...[] | -| ![](../images/icons/div-Large.png) | Divide | / | var[]...[], var[]...[] | var[]...[] | - -**Power -** Exponentiation, or the power operator, involves two numbers: the base number (x) and the power (y). The power of x to the y is defined as x repeatedly multiplied by itself for a total of y times. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Pow-Large.png) | Power | Math.Pow | number, power | var[]...[] | -``` -2 ^ 3 = 2 x 2 x 2 = 8``` - -**Square Root - **The square root of x referes to the number z such that z^2=x. This operator is commonplace in a wide-range of geometric applications, most notably the [Pythagorean Theorem](http://en.wikipedia.org/wiki/Pythagorean_theorem). - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Sqrt-Large.png) | Square Root | Math.Sqrt | number | double | -``` -Sqrt(4) = 2``` - -**Absolute Value -**The absolute value of a number refers to its non-negative value. This operator comes in handy when parametrically, especially when a calculation concerns itself with scalar values rather than vectors (ie speed vs. velocity). - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Abs-double-Large.png) | Absolute Value | Math.Abs | number | double | - -``` -|-10| = 10 and |10| = 10``` - -**Modulo -** The modulo operation refers to the remainder after a division. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/mod-Large.png) | Modulo | % | var[]...[],var[]...[] | var[]...[] | - -``` -11 % 6 = 5 (6 goes into 11 once, and has a remainder, or modulo, of 5)``` - -While this may not seem like much, the modulo is a great tool for creating patterns. The image below demonstrates how quickly one can parse out even and odd numbers with pure operations: -![](images/4-2/4-2-2/mod1.png) - -**Ceiling, Floor, Round -** The ceiling, floor, and round operation refer to methods for reducing a decimal (or float) number to an integer. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Ceiling-Large.png) | Ceiling | Math.Ceiling | number | int | -| ![](../images/icons/DSCore-Math-Floor-Large.png) | Floor | Math.Floor | number | int | -| ![](../images/icons/DynamoUnits-SIUnit-Round-Large.png) | Round | Math.Round | number | int | -``` -11/6 = 1.833``` - -The floor represents the lower bound of the integer within the decimal range. -``` -Floor(11/6) = Floor(1.833) = 1``` - -The ceiling represents the upper bound. -``` -Ceil(11/6) = Ceil(1.833) = 2``` - -The round operations will 'round' to the closest number in the range. -``` -Round(11/6) = Round(1.833) = 2``` - -## Functions -**Remap Range -**This is one of the most important functions in parametric modeling. The component maps a set of values in one domain into another domain, while maintaining the same distribution ratio. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-RemapRange-Large.png) | Remap Range | Math.RemapRange | numbers, newMin, newMax | var[]...[] | - -**Average -** Determines the average (mean) of a list of numbers. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Average-Large.png) | Average | Math.Average | numbers | double | - -**Sum -** Determines the sum of a list of numbers. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Sum-Large.png) | Sum | Math.Sum | values | double | - -**Random/RandomList -**Create a random number or a random list of numbers. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-Random-double-double-Large.png) | Random | Math.Random | seed | double | -| ![](../images/icons/DSCore-Math-RandomList-Large.png) | Random List | Math.RandomList | amount | var[]...[] | - -### Trigonometric Functions -In summary, trigonometric functions are functions of an angle, relating the angles of a triangle to the lengths of its sides. The input in Dynamo is degrees. - -| Icon | Name| Syntax| Ratio | Formula | -| -- | -- | -- | -- | -- | -| ![](../images/icons/DSCore-Math-Sin-Large.png) | sine| Math.Sin | opposite/hypotenuse | ![](images/4-2/sin.png) | -| ![](../images/icons/DSCore-Math-Cos-Large.png) | cosine | Math.Cos | adjacent/hypotenuse | ![](images/4-2/cos.png) | -| ![](../images/icons/DSCore-Math-Tan-Large.png) | tangent | Math.Tan | opposite/adjacent | ![](images/4-2/tan.png) | - - -### Inverse Trigonometric Functions - -Inverse trigonometric functions use a ratio as an input, with the resultant output being an angle. The output in Dynamo is degrees. These are less commonly used in modeling. - -| Icon | Name| Syntax| Formula | -| -- | -- | -- | -- | -| ![](../images/icons/DSCore-Math-ASin-Large.png) | arcsine| Math.Asin | ![](images/4-2/asin.png) | -| ![](../images/icons/DSCore-Math-Acos-Large.png) | arccosine | Math.Acos | ![](images/4-2/acos.png) | -| ![](../images/icons/DSCore-Math-Atan-Large.png) | arctangent | Math.Atan | ![](images/4-2/atan.png) | - -### Hyperbolic Functions -Even less common in trigonometry are the hyperbolic functions, which are analogs to the trigonometric functions. These functions have applications in physics, fluid dynamics, and complex analysis, but are outside of the scope of this primer. - -| Icon | Name| Syntax| Formula | -| -- | -- | -- | -- | -| ![](../images/icons/DSCore-Math-Sinh-Large.png) | sinh | Math.Sinh | ![](images/4-2/sinh.png) | -| ![](../images/icons/DSCore-Math-Cosh-Large.png) | cosh | Math.Cosh | ![](images/4-2/cosh.png) | -| ![](../images/icons/DSCore-Math-Tanh-Large.png) | tanh | Math.Tanh | ![](images/4-2/tanh.png)![](images/4-2/tanh2.png) | - -**Math.RadiansToDegrees/Math.DegreesToRadians -**Convert Radians to Degrees. This is a handy node for quickly converting angle units. Dynamo works in degrees by default for inputs and outputs. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-Math-RadiansToDegrees-Large.png) | Radians To Degrees | Math.RadiansToDegrees | radians | degrees | -| ![](../images/icons/DSCore-Math-DegreesToRadians-Large.png) | Degrees to Radians | Math.DegreesToRadians | degrees | radians | - -### Formula -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | Formula | Text box | objects, numbers,strings,lists... | - -**Formula - **All of the functions described above, and many more, can be defined explicitly in the formula node. This node is compatible with a range of expressions, as well as conditional statements and other equations. - -For a similar node which expands this ability even further, check out the **code block**. The code block will be discussed in detail in a future section. +## Math + +## Constants + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-PI-Large.png) | Pi | Math.PI | none | double | + +**Pi -** is a mathematical constant which represents the ratio of circle's circumference to its diameter. The value is commonly used in trigonmetric functions and is one of the more prevalent constants used in parametric modeling. A rounded value for *Pi* is *3.14159*. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-E-Large.png) | e | Math.E | none | double | + +**e -** The number *e* is a mathematical constant which is based on the natural logarithm. Like *pi*, *e* is an irrational number which is commonly used in mathematics. The number is fundamental to growth prediction, and shows itself often in the fields of biology and economics. A rounded value for *e* is *2.71828*. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-GoldenRatio-Large.png) | phi | Math.GoldenRatio | none | double | + + +**φ: The Golden Ratio - **Another irrational constant, the golden ratio defines that two quantities are in the golden ratio if their ratio is the same as the ratio of their sum to the larger of the two quantities. This ratio appears often in geometry and biological systems, and is considered for a wide-range of applications ranging from the practical to the aesthetic. A rounded value for *φ* is *1.61804*. + +## Arithmetic Operators +Operators are a set of components that use +algebraic functions with two numeric input values, which result in one output +value (addition, subtraction, multiplication, division, etc.). + +You use the Math Operators to perform arithmetical +actions on a set of numbers. These can be found under Operators>Actions. + +**Addition, Subtraction, Multiplication, Division -** These four operators are commonplace. Let's look at a few other operators which dive deeper: + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/add-Large.png) | Add | + | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/sub-Large.png) | Subtract | - | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/mul-Large.png) | Multiply | * | var[]...[], var[]...[] | var[]...[] | +| ![](../images/icons/div-Large.png) | Divide | / | var[]...[], var[]...[] | var[]...[] | + +**Power -** Exponentiation, or the power operator, involves two numbers: the base number (x) and the power (y). The power of x to the y is defined as x repeatedly multiplied by itself for a total of y times. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Pow-Large.png) | Power | Math.Pow | number, power | var[]...[] | +``` +2 ^ 3 = 2 x 2 x 2 = 8``` + +**Square Root - **The square root of x referes to the number z such that z^2=x. This operator is commonplace in a wide-range of geometric applications, most notably the [Pythagorean Theorem](http://en.wikipedia.org/wiki/Pythagorean_theorem). + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Sqrt-Large.png) | Square Root | Math.Sqrt | number | double | +``` +Sqrt(4) = 2``` + +**Absolute Value -**The absolute value of a number refers to its non-negative value. This operator comes in handy when parametrically, especially when a calculation concerns itself with scalar values rather than vectors (ie speed vs. velocity). + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Abs-double-Large.png) | Absolute Value | Math.Abs | number | double | + +``` +|-10| = 10 and |10| = 10``` + +**Modulo -** The modulo operation refers to the remainder after a division. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/mod-Large.png) | Modulo | % | var[]...[],var[]...[] | var[]...[] | + +``` +11 % 6 = 5 (6 goes into 11 once, and has a remainder, or modulo, of 5)``` + +While this may not seem like much, the modulo is a great tool for creating patterns. The image below demonstrates how quickly one can parse out even and odd numbers with pure operations: +![](images/4-2/4-2-2/mod1.png) + +**Ceiling, Floor, Round -** The ceiling, floor, and round operation refer to methods for reducing a decimal (or float) number to an integer. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Ceiling-Large.png) | Ceiling | Math.Ceiling | number | int | +| ![](../images/icons/DSCore-Math-Floor-Large.png) | Floor | Math.Floor | number | int | +| ![](../images/icons/DynamoUnits-SIUnit-Round-Large.png) | Round | Math.Round | number | int | +``` +11/6 = 1.833``` + +The floor represents the lower bound of the integer within the decimal range. +``` +Floor(11/6) = Floor(1.833) = 1``` + +The ceiling represents the upper bound. +``` +Ceil(11/6) = Ceil(1.833) = 2``` + +The round operations will 'round' to the closest number in the range. +``` +Round(11/6) = Round(1.833) = 2``` + +## Functions +**Remap Range -**This is one of the most important functions in parametric modeling. The component maps a set of values in one domain into another domain, while maintaining the same distribution ratio. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-RemapRange-Large.png) | Remap Range | Math.RemapRange | numbers, newMin, newMax | var[]...[] | + +**Average -** Determines the average (mean) of a list of numbers. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Average-Large.png) | Average | Math.Average | numbers | double | + +**Sum -** Determines the sum of a list of numbers. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Sum-Large.png) | Sum | Math.Sum | values | double | + +**Random/RandomList -**Create a random number or a random list of numbers. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-Random-double-double-Large.png) | Random | Math.Random | seed | double | +| ![](../images/icons/DSCore-Math-RandomList-Large.png) | Random List | Math.RandomList | amount | var[]...[] | + +### Trigonometric Functions +In summary, trigonometric functions are functions of an angle, relating the angles of a triangle to the lengths of its sides. The input in Dynamo is degrees. + +| Icon | Name| Syntax| Ratio | Formula | +| -- | -- | -- | -- | -- | +| ![](../images/icons/DSCore-Math-Sin-Large.png) | sine| Math.Sin | opposite/hypotenuse | ![](images/4-2/sin.png) | +| ![](../images/icons/DSCore-Math-Cos-Large.png) | cosine | Math.Cos | adjacent/hypotenuse | ![](images/4-2/cos.png) | +| ![](../images/icons/DSCore-Math-Tan-Large.png) | tangent | Math.Tan | opposite/adjacent | ![](images/4-2/tan.png) | + + +### Inverse Trigonometric Functions + +Inverse trigonometric functions use a ratio as an input, with the resultant output being an angle. The output in Dynamo is degrees. These are less commonly used in modeling. + +| Icon | Name| Syntax| Formula | +| -- | -- | -- | -- | +| ![](../images/icons/DSCore-Math-ASin-Large.png) | arcsine| Math.Asin | ![](images/4-2/asin.png) | +| ![](../images/icons/DSCore-Math-Acos-Large.png) | arccosine | Math.Acos | ![](images/4-2/acos.png) | +| ![](../images/icons/DSCore-Math-Atan-Large.png) | arctangent | Math.Atan | ![](images/4-2/atan.png) | + +### Hyperbolic Functions +Even less common in trigonometry are the hyperbolic functions, which are analogs to the trigonometric functions. These functions have applications in physics, fluid dynamics, and complex analysis, but are outside of the scope of this primer. + +| Icon | Name| Syntax| Formula | +| -- | -- | -- | -- | +| ![](../images/icons/DSCore-Math-Sinh-Large.png) | sinh | Math.Sinh | ![](images/4-2/sinh.png) | +| ![](../images/icons/DSCore-Math-Cosh-Large.png) | cosh | Math.Cosh | ![](images/4-2/cosh.png) | +| ![](../images/icons/DSCore-Math-Tanh-Large.png) | tanh | Math.Tanh | ![](images/4-2/tanh.png)![](images/4-2/tanh2.png) | + +**Math.RadiansToDegrees/Math.DegreesToRadians -**Convert Radians to Degrees. This is a handy node for quickly converting angle units. Dynamo works in degrees by default for inputs and outputs. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-Math-RadiansToDegrees-Large.png) | Radians To Degrees | Math.RadiansToDegrees | radians | degrees | +| ![](../images/icons/DSCore-Math-DegreesToRadians-Large.png) | Degrees to Radians | Math.DegreesToRadians | degrees | radians | + +### Formula +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCoreNodesUI-Formula-Large.png) | Formula | Formula | Text box | objects, numbers,strings,lists... | + +**Formula - **All of the functions described above, and many more, can be defined explicitly in the formula node. This node is compatible with a range of expressions, as well as conditional statements and other equations. + +For a similar node which expands this ability even further, check out the **code block**. The code block will be discussed in detail in a future section. diff --git a/Archive/strings.md b/Archive/strings.md index 1c952e0f..ebdf8f64 100644 --- a/Archive/strings.md +++ b/Archive/strings.md @@ -1,71 +1,71 @@ -## Strings - -### Creating Strings -**String - ** Formally, a String is a sequence of characters representing a literal constant or some type of variable. Informally, a string is programming lingo for text. We've worked with numbers, both integers and decimal numbers, to drive parameters and we can do the same with text. -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/Dynamo-Nodes-StringInput-Large.png) | String | String | Text Box | string | - - -Strings can be used for a wide range of applications, including defining custom parameters, annotating documentation sets, and parsing through text-based data sets. The string Node is located in the Core>Input Category. - - -![String Examples](images/4-4/4-4-1-005.png) -> The sample batteries above are strings. A number can be represented as a string, as can a letter, or an entire array of text. - -### Querying Strings -You can parse through large amounts of data quickly by querying strings. We'll talk about some basic operations which can speed up a workflow and help for software interoperability. - -**String.Split - **This action splits one string into an array of strings, based on a separator. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-String-Split-Large.png) | String Split | String.Split | str, separator(s) | string[] | - -The image below considers a string of data coming from an external spreadsheet. The string represents the vertices of a rectangle in the XY-Plane. Let's break down some string split operations in miniature exercise: - -![StringSplit](images/4-4/4-4-1-001.png) -> 1. The ";" separator splits each vertex of the rectangle. This creates a list with 4 items for each vertex. - -![StringSplit](images/4-4/4-4-1-003.png) -> 1. By hitting the "*+*" in the middle of the node, we create new separator. -2. Add a "*,*" string to the canvas and plug in to the new separator input. -3. Our result is now a list of ten items. The node first splits based on *separator0*, then based on *separator1*. - -**String.ToNumber - ** While the list of items above may look like numbers, they are still regarded as individual strings in Dynamo. In order to create points, their data type needs to be converted from a string to a number. This is done with the String.ToNumber node: - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-String-ToNumber-Large.png) | String To Number | String.ToNumber | str | str[]...[] | - -![StringSplit](images/4-4/4-4-1-002.png) -> 1. This node is straightforward. Plug the String.Split results into the input. The output doesn't look different, but the data type is now a *number* instead of a *string*. - -![StringToNumber](images/4-4/4-4-1-004.png) -> 1. With some basic additional operations, we now have a rectangle drawn at the origin based on the original string input. - -### Manipulating Strings -Since a string is a generic text object, they host a wide range of applications. Let's take a look at some of the major actions in the Core>String Category in Dynamo: - - -**Concatenate - **This is a method of merging two strings together in order. This takes each literal string in a list and creates one merged string. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-String-Concat-Large.png) | Concatenate | String.Concat | string(s) | string | - -![Concatenate](images/4-4/4-4-1-007.png) -> The image above represents the concatenation of three strings: -1. Add or subtract strings to the concatenation by clicking the +/- buttons int he center of the node. -2. The output gives one concatenated string, with spaces and punctuation included. - -**Join - ** The join method is very similar to concatenate, except it has an added layer of punctuation. - -| Icon | Name | Syntax| Inputs | Outputs | -| -- | -- | -- | -- | -- | -- |-- | -| ![](../images/icons/DSCore-String-Join-Large.png) | String Join | String.Join | separator, string (s) | string | - -If you've worked in Excel, you may have come across a CSV file. This stands for comma-separated values. One could use a comma (or in this case, two dashes) as the separator with the join node in order to create a similar data structure: -![Concatenate](images/4-4/4-4-1-006.png) -> The image above represents the joining of two strings: -1. The separator input allows one to create a string which divides the joined strings. +## Strings + +### Creating Strings +**String - ** Formally, a String is a sequence of characters representing a literal constant or some type of variable. Informally, a string is programming lingo for text. We've worked with numbers, both integers and decimal numbers, to drive parameters and we can do the same with text. +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/Dynamo-Nodes-StringInput-Large.png) | String | String | Text Box | string | + + +Strings can be used for a wide range of applications, including defining custom parameters, annotating documentation sets, and parsing through text-based data sets. The string Node is located in the Core>Input Category. + + +![String Examples](images/4-4/4-4-1-005.png) +> The sample batteries above are strings. A number can be represented as a string, as can a letter, or an entire array of text. + +### Querying Strings +You can parse through large amounts of data quickly by querying strings. We'll talk about some basic operations which can speed up a workflow and help for software interoperability. + +**String.Split - **This action splits one string into an array of strings, based on a separator. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-String-Split-Large.png) | String Split | String.Split | str, separator(s) | string[] | + +The image below considers a string of data coming from an external spreadsheet. The string represents the vertices of a rectangle in the XY-Plane. Let's break down some string split operations in miniature exercise: + +![StringSplit](images/4-4/4-4-1-001.png) +> 1. The ";" separator splits each vertex of the rectangle. This creates a list with 4 items for each vertex. + +![StringSplit](images/4-4/4-4-1-003.png) +> 1. By hitting the "*+*" in the middle of the node, we create new separator. +2. Add a "*,*" string to the canvas and plug in to the new separator input. +3. Our result is now a list of ten items. The node first splits based on *separator0*, then based on *separator1*. + +**String.ToNumber - ** While the list of items above may look like numbers, they are still regarded as individual strings in Dynamo. In order to create points, their data type needs to be converted from a string to a number. This is done with the String.ToNumber node: + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-String-ToNumber-Large.png) | String To Number | String.ToNumber | str | str[]...[] | + +![StringSplit](images/4-4/4-4-1-002.png) +> 1. This node is straightforward. Plug the String.Split results into the input. The output doesn't look different, but the data type is now a *number* instead of a *string*. + +![StringToNumber](images/4-4/4-4-1-004.png) +> 1. With some basic additional operations, we now have a rectangle drawn at the origin based on the original string input. + +### Manipulating Strings +Since a string is a generic text object, they host a wide range of applications. Let's take a look at some of the major actions in the Core>String Category in Dynamo: + + +**Concatenate - **This is a method of merging two strings together in order. This takes each literal string in a list and creates one merged string. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-String-Concat-Large.png) | Concatenate | String.Concat | string(s) | string | + +![Concatenate](images/4-4/4-4-1-007.png) +> The image above represents the concatenation of three strings: +1. Add or subtract strings to the concatenation by clicking the +/- buttons int he center of the node. +2. The output gives one concatenated string, with spaces and punctuation included. + +**Join - ** The join method is very similar to concatenate, except it has an added layer of punctuation. + +| Icon | Name | Syntax| Inputs | Outputs | +| -- | -- | -- | -- | -- | -- |-- | +| ![](../images/icons/DSCore-String-Join-Large.png) | String Join | String.Join | separator, string (s) | string | + +If you've worked in Excel, you may have come across a CSV file. This stands for comma-separated values. One could use a comma (or in this case, two dashes) as the separator with the join node in order to create a similar data structure: +![Concatenate](images/4-4/4-4-1-006.png) +> The image above represents the joining of two strings: +1. The separator input allows one to create a string which divides the joined strings. diff --git a/README.md b/README.md index 4f5443e2..954f6cef 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,79 @@ -#The Dynamo Primer -##For Dynamo v1.0 - -![Dynamo Logo](images/dynamo_logo_dark-trim.png) - -> Dynamo is an open source visual programming platform for designers. - -### Welcome -You have just opened the Dynamo Primer, a comprehensive guide to visual programming in Autodesk Dynamo Studio. This primer is an on-going project to share the fundamentals of programming. Topics include working with computational geometry, best practices for rules-based design, cross-disciplinary programming applications, and more with the Dynamo Platform. - -The power of Dynamo can be found in a wide variety of design-related activities. Dynamo enables an expanding list of readily accessible ways for you to get started: -* **Explore** visual programming for the first time -* **Connect** workflows in various software -* **Engage** an active community of users, contributors, and developers -* **Develop** an open-source platform for continued improvement - -In the midst of this activity and exciting opportunity for working with Dynamo, we need a document of the same caliber, the Dynamo Primer. - -Version 1.0 of this Primer includes the first ten chapters developed by Mode Lab. These chapters focus on the essentials you will need to get up and running developing your own visual programs with Dynamo and key insights on how to take Dynamo further. Here's what you can expect to learn from the primer: - -* **Context** - What exactly is "Visual Programming" and what are the concepts I need to understand to dive in to Dynamo? -* **Getting Started** - How do I get Dynamo and create my first program? -* **What's in a Program** - What are the functional parts of Dynamo and how do I use them? -* **Building Blocks** - What is "Data" and what are some fundamental types I can start using in my programs? -* **Geometry for Design** - How do I work with geometric elements in Dynamo? -* **Lists, Lists, Lists** - How to do I manage and coordinate my data structures? -* **Code in Nodes** - How can I start extending Dynamo with my own code? -* **Computational BIM** - How can I use Dynamo with a Revit model? -* **Custom Nodes** - How can I create my own nodes? -* **Packages** - How can I share my tools with the community? - -This is an exciting time to be learning about, working with, and developing for Dynamo. Let's get started! - ---- - -### Open Source -The Dynamo Primer project is open source! We're dedicated to providing quality content and appreciate any feedback you may have. If you would like to report an issue on anything at all, please post them on our git hub issue page: https://github.com/DynamoDS/DynamoPrimer/issues - -If you would like to contribute a new section, edits, or anything else to this project, check out the github repo to get started: https://github.com/DynamoDS/DynamoPrimer. - ---- -### The Dynamo Primer Project -The Dynamo Primer is an open source project, initiated by Matt Jezyk and the Dynamo Development team at Autodesk. - -**Mode Lab** was commissioned to write the First Edition of the primer. The team continues to work with Autodesk to provide updates in parallel with Dynamo's development. - -[](http://modelab.is) - -### Acknowledgments - -A special thanks to Ian Keough for initiating and guiding the Dynamo project. - -Thank you to Matt Jezyk, Ian Keough, Zach Kron, and Colin McCrone for enthusiastic collaboration and the opportunity to participate on a wide array of Dynamo projects. - -### Software and Resources -**Dynamo** The current stable release of Dynamo is Version 1.1.0. - -http://dynamobim.com/download/ - -**DynamoBIM** The best source for additional information, learning content, and forums is the DynamoBIM website. - -http://dynamobim.org - -**Dynamo GitHub** Dynamo is an open-source development project on Github. To contribute, check out DynamoDS. - -https://github.com/DynamoDS/Dynamo - -**Contact** Let us know about any issues with this document. - -Dynamo@autodesk.com - -### License -Copyright 2017 Autodesk - -Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +#The Dynamo Primer +##For Dynamo v1.0 + +![Dynamo Logo](images/dynamo_logo_dark-trim.png) + +> Dynamo is an open source visual programming platform for designers. + +### Welcome +You have just opened the Dynamo Primer, a comprehensive guide to visual programming in Autodesk Dynamo Studio. This primer is an on-going project to share the fundamentals of programming. Topics include working with computational geometry, best practices for rules-based design, cross-disciplinary programming applications, and more with the Dynamo Platform. + +The power of Dynamo can be found in a wide variety of design-related activities. Dynamo enables an expanding list of readily accessible ways for you to get started: +* **Explore** visual programming for the first time +* **Connect** workflows in various software +* **Engage** an active community of users, contributors, and developers +* **Develop** an open-source platform for continued improvement + +In the midst of this activity and exciting opportunity for working with Dynamo, we need a document of the same caliber, the Dynamo Primer. + +Version 1.0 of this Primer includes the first ten chapters developed by Mode Lab. These chapters focus on the essentials you will need to get up and running developing your own visual programs with Dynamo and key insights on how to take Dynamo further. Here's what you can expect to learn from the primer: + +* **Context** - What exactly is "Visual Programming" and what are the concepts I need to understand to dive in to Dynamo? +* **Getting Started** - How do I get Dynamo and create my first program? +* **What's in a Program** - What are the functional parts of Dynamo and how do I use them? +* **Building Blocks** - What is "Data" and what are some fundamental types I can start using in my programs? +* **Geometry for Design** - How do I work with geometric elements in Dynamo? +* **Lists, Lists, Lists** - How to do I manage and coordinate my data structures? +* **Code in Nodes** - How can I start extending Dynamo with my own code? +* **Computational BIM** - How can I use Dynamo with a Revit model? +* **Custom Nodes** - How can I create my own nodes? +* **Packages** - How can I share my tools with the community? + +This is an exciting time to be learning about, working with, and developing for Dynamo. Let's get started! + +--- + +### Open Source +The Dynamo Primer project is open source! We're dedicated to providing quality content and appreciate any feedback you may have. If you would like to report an issue on anything at all, please post them on our git hub issue page: https://github.com/DynamoDS/DynamoPrimer/issues + +If you would like to contribute a new section, edits, or anything else to this project, check out the github repo to get started: https://github.com/DynamoDS/DynamoPrimer. + +--- +### The Dynamo Primer Project +The Dynamo Primer is an open source project, initiated by Matt Jezyk and the Dynamo Development team at Autodesk. + +**Mode Lab** was commissioned to write the First Edition of the primer. The team continues to work with Autodesk to provide updates in parallel with Dynamo's development. + +[](http://modelab.is) + +### Acknowledgments + +A special thanks to Ian Keough for initiating and guiding the Dynamo project. + +Thank you to Matt Jezyk, Ian Keough, Zach Kron, and Colin McCrone for enthusiastic collaboration and the opportunity to participate on a wide array of Dynamo projects. + +### Software and Resources +**Dynamo** The current stable release of Dynamo is Version 1.1.0. + +http://dynamobim.com/download/ + +**DynamoBIM** The best source for additional information, learning content, and forums is the DynamoBIM website. + +http://dynamobim.org + +**Dynamo GitHub** Dynamo is an open-source development project on Github. To contribute, check out DynamoDS. + +https://github.com/DynamoDS/Dynamo + +**Contact** Let us know about any issues with this document. + +Dynamo@autodesk.com + +### License +Copyright 2017 Autodesk + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/SUMMARY.md b/SUMMARY.md index fb2bc858..b2d3f087 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,72 +1,72 @@ -# Summary - -* [About](README.md) -* [Introduction](01_Introduction/1_introduction.md) - * [What is Visual Programming?](01_Introduction/1-1_what_is_visual_programming.md) - * [What is Dynamo?](01_Introduction/1-2_what_is_dynamo.md) - * [Dynamo in Action](01_Introduction/1-3_dynamo_in_action.md) -* [Hello Dynamo!](02_Hello-Dynamo/2_hello_dynamo.md) - * [Installing and Launching Dynamo](02_Hello-Dynamo/2-1_launching_dynamo.md) - * [The User Interface](02_Hello-Dynamo/2-2_the_dynamo_ui.md) - * [The Workspace](02_Hello-Dynamo/2-3_the_workspace.md) - * [Getting Started](02_Hello-Dynamo/2-6_the_quick_start_guide.md) -* [The Anatomy of a Visual Program](03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md) - * [Nodes](03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md) - * [Wires](03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md) - * [Library](03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md) - * [Managing Your Program](03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md) - * [Managing Your Data with Presets](03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md) -* [The Building Blocks of Programs](04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md) - * [Data](04_The-Building-Blocks-of-Programs/4-1_data.md) - * [Math](04_The-Building-Blocks-of-Programs/4-2_math.md) - * [Logic](04_The-Building-Blocks-of-Programs/4-3_logic.md) - * [Strings](04_The-Building-Blocks-of-Programs/4-4_strings.md) - * [Color](04_The-Building-Blocks-of-Programs/4-5_color.md) -* [Geometry for Computational Design](05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md) - * [Geometry Overview](05_Geometry-for-Computational-Design/5-1_geometry-overview.md) - * [Vectors](05_Geometry-for-Computational-Design/5-2_vectors.md) - * [Points](05_Geometry-for-Computational-Design/5-3_points.md) - * [Curves](05_Geometry-for-Computational-Design/5-4_curves.md) - * [Surfaces](05_Geometry-for-Computational-Design/5-5_surfaces.md) - * [Solids](05_Geometry-for-Computational-Design/5-6_solids.md) - * [Meshes](05_Geometry-for-Computational-Design/5-7_meshes.md) - * [Importing Geometry](05_Geometry-for-Computational-Design/5-8_importing.md) -* [Designing with Lists](06_Designing-with-Lists/6_designing-with-lists.md) - * [What's a List](06_Designing-with-Lists/6-1_whats-a-list.md) - * [Working with Lists](06_Designing-with-Lists/6-2_working-with-lists.md) - * [Lists of Lists](06_Designing-with-Lists/6-3_lists-of-lists.md) - * [n-Dimensional Lists](06_Designing-with-Lists/6-4_n-dimensional-lists.md) -* [Code Blocks and DesignScript](07_Code-Block/7_Code-Blocks-and-Design-Script.md) - * [What's a Code Block](07_Code-Block/7-1_what-is-a-code-block.md) - * [DesignScript Syntax](07_Code-Block/7-2_Design-Script-syntax.md) - * [Shorthand](07_Code-Block/7-3_shorthand.md) - * [Functions](07_Code-Block/7-4_functions.md) -* [Dynamo for Revit](08_Dynamo-for-Revit/8_Dynamo-for-Revit.md) - * [The Revit Connection](08_Dynamo-for-Revit/8-1_The-Revit-Connection.md) - * [Selecting](08_Dynamo-for-Revit/8-2_Selecting.md) - * [Editing](08_Dynamo-for-Revit/8-3_Editing.md) - * [Creating](08_Dynamo-for-Revit/8-4_Creating.md) - * [Customizing](08_Dynamo-for-Revit/8-5_Customizing.md) - * [Documenting](08_Dynamo-for-Revit/8-6_Documenting.md) -* [Custom Nodes](09_Custom-Nodes/9_Custom-Nodes.md) - * [Custom Node Introduction](09_Custom-Nodes/9-1_Introduction.md) - * [Creating a Custom Node](09_Custom-Nodes/9-2_Creating.md) - * [Publishing to Your Library](09_Custom-Nodes/9-3_Library.md) - * [Python Nodes](09_Custom-Nodes/9-4_Python.md) - * [Python and Revit](09_Custom-Nodes/9-5_Python-Revit.md) -* [Packages](10_Packages/10-Packages.md) - * [Package Introduction](10_Packages/10-1_Introduction.md) - * [Package Case Study - Mesh Toolkit](10_Packages/10-2_Mesh-Toolkit.md) - * [Developing a Package](10_Packages/10-3_Developing.md) - * [Publishing a Package](10_Packages/10-4_Publishing.md) - * [Zero-Touch Importing](10_Packages/10-5_Zero-Touch.md) -* [Web Experience](11_Web_Experience/11-1_Introduction.md) - * [Web Experience Introduction](11_Web_Experience/11-1_Introduction.md) - * [Send to Web](11_Web_Experience/11-2_Send_to_Web.md) - * [Customizer View](11_Web_Experience/11-3_Customizer_View.md) -* [Appendix](Appendix/A_appendix.md) - * [Resources](Appendix/A-1_resources.md) - * [Index of Nodes](Appendix/A-2_index-of-nodes.md) - * [Useful Packages](Appendix/A-3_packages.md) - * [Example Files](Appendix/A-4_example-files.md) - +# Summary + +* [About](README.md) +* [Introduction](01_Introduction/1_introduction.md) + * [What is Visual Programming?](01_Introduction/1-1_what_is_visual_programming.md) + * [What is Dynamo?](01_Introduction/1-2_what_is_dynamo.md) + * [Dynamo in Action](01_Introduction/1-3_dynamo_in_action.md) +* [Hello Dynamo!](02_Hello-Dynamo/2_hello_dynamo.md) + * [Installing and Launching Dynamo](02_Hello-Dynamo/2-1_launching_dynamo.md) + * [The User Interface](02_Hello-Dynamo/2-2_the_dynamo_ui.md) + * [The Workspace](02_Hello-Dynamo/2-3_the_workspace.md) + * [Getting Started](02_Hello-Dynamo/2-6_the_quick_start_guide.md) +* [The Anatomy of a Visual Program](03_Anatomy-of-a-Dynamo-Definition/3_anatomy-of-a-dynamo-definition.md) + * [Nodes](03_Anatomy-of-a-Dynamo-Definition/3-1_dynamo_nodes.md) + * [Wires](03_Anatomy-of-a-Dynamo-Definition/3-3_wiring_programs.md) + * [Library](03_Anatomy-of-a-Dynamo-Definition/3-2_dynamo_libraries.md) + * [Managing Your Program](03_Anatomy-of-a-Dynamo-Definition/3-4_best_practices.md) + * [Managing Your Data with Presets](03_Anatomy-of-a-Dynamo-Definition/3-5_presets.md) +* [The Building Blocks of Programs](04_The-Building-Blocks-of-Programs/4_the-building-blocks-of-programs.md) + * [Data](04_The-Building-Blocks-of-Programs/4-1_data.md) + * [Math](04_The-Building-Blocks-of-Programs/4-2_math.md) + * [Logic](04_The-Building-Blocks-of-Programs/4-3_logic.md) + * [Strings](04_The-Building-Blocks-of-Programs/4-4_strings.md) + * [Color](04_The-Building-Blocks-of-Programs/4-5_color.md) +* [Geometry for Computational Design](05_Geometry-for-Computational-Design/5_geometry-for-computational-design.md) + * [Geometry Overview](05_Geometry-for-Computational-Design/5-1_geometry-overview.md) + * [Vectors](05_Geometry-for-Computational-Design/5-2_vectors.md) + * [Points](05_Geometry-for-Computational-Design/5-3_points.md) + * [Curves](05_Geometry-for-Computational-Design/5-4_curves.md) + * [Surfaces](05_Geometry-for-Computational-Design/5-5_surfaces.md) + * [Solids](05_Geometry-for-Computational-Design/5-6_solids.md) + * [Meshes](05_Geometry-for-Computational-Design/5-7_meshes.md) + * [Importing Geometry](05_Geometry-for-Computational-Design/5-8_importing.md) +* [Designing with Lists](06_Designing-with-Lists/6_designing-with-lists.md) + * [What's a List](06_Designing-with-Lists/6-1_whats-a-list.md) + * [Working with Lists](06_Designing-with-Lists/6-2_working-with-lists.md) + * [Lists of Lists](06_Designing-with-Lists/6-3_lists-of-lists.md) + * [n-Dimensional Lists](06_Designing-with-Lists/6-4_n-dimensional-lists.md) +* [Code Blocks and DesignScript](07_Code-Block/7_Code-Blocks-and-Design-Script.md) + * [What's a Code Block](07_Code-Block/7-1_what-is-a-code-block.md) + * [DesignScript Syntax](07_Code-Block/7-2_Design-Script-syntax.md) + * [Shorthand](07_Code-Block/7-3_shorthand.md) + * [Functions](07_Code-Block/7-4_functions.md) +* [Dynamo for Revit](08_Dynamo-for-Revit/8_Dynamo-for-Revit.md) + * [The Revit Connection](08_Dynamo-for-Revit/8-1_The-Revit-Connection.md) + * [Selecting](08_Dynamo-for-Revit/8-2_Selecting.md) + * [Editing](08_Dynamo-for-Revit/8-3_Editing.md) + * [Creating](08_Dynamo-for-Revit/8-4_Creating.md) + * [Customizing](08_Dynamo-for-Revit/8-5_Customizing.md) + * [Documenting](08_Dynamo-for-Revit/8-6_Documenting.md) +* [Custom Nodes](09_Custom-Nodes/9_Custom-Nodes.md) + * [Custom Node Introduction](09_Custom-Nodes/9-1_Introduction.md) + * [Creating a Custom Node](09_Custom-Nodes/9-2_Creating.md) + * [Publishing to Your Library](09_Custom-Nodes/9-3_Library.md) + * [Python Nodes](09_Custom-Nodes/9-4_Python.md) + * [Python and Revit](09_Custom-Nodes/9-5_Python-Revit.md) +* [Packages](10_Packages/10-Packages.md) + * [Package Introduction](10_Packages/10-1_Introduction.md) + * [Package Case Study - Mesh Toolkit](10_Packages/10-2_Mesh-Toolkit.md) + * [Developing a Package](10_Packages/10-3_Developing.md) + * [Publishing a Package](10_Packages/10-4_Publishing.md) + * [Zero-Touch Importing](10_Packages/10-5_Zero-Touch.md) +* [Web Experience](11_Web_Experience/11-1_Introduction.md) + * [Web Experience Introduction](11_Web_Experience/11-1_Introduction.md) + * [Send to Web](11_Web_Experience/11-2_Send_to_Web.md) + * [Customizer View](11_Web_Experience/11-3_Customizer_View.md) +* [Appendix](Appendix/A_appendix.md) + * [Resources](Appendix/A-1_resources.md) + * [Index of Nodes](Appendix/A-2_index-of-nodes.md) + * [Useful Packages](Appendix/A-3_packages.md) + * [Example Files](Appendix/A-4_example-files.md) + diff --git a/book.json b/book.json index eaa8ff98..6cce30d6 100644 --- a/book.json +++ b/book.json @@ -1,52 +1,52 @@ -{ - "gitbook": "2.6.x", - "plugins": [ - "-sharing", - "ga", - { - "name": "dynamo", - "version": "git+https://github.com/masself/gitbook-plugin-dynamo.git" - } - ], - "pluginsConfig": { - "ga": { - "token": "UA-52186525-3" - }, - "dynamo": { - "customLinks":[ - { - "label": "Download", - "icon": "fa fa-file-pdf-o fa-lg", - "url": "http://dynamoprimer.com/en/Appendix/DynamoPrimer-Print.pdf" - }], - "languages":[ - { - "label": "Deutsch", - "code":"de", - "url": "http://dynamoprimer.com/de" - }, - { - "label": "日本語", - "code": "ja", - "url": "http://dynamoprimer.com/ja" - }, - { - "label": "", - "code": "", - "url": "" - }, - { - "label": "", - "code": "", - "url": "" - } - ], - "currentLanguage":{ - "code":"en", - "url":"http://dynamoprimer.com/en", - "switchLangLabel":"Languages" - }, - "favicon":"/images/icons/favicon.ico" - } - } -} +{ + "gitbook": "2.6.x", + "plugins": [ + "-sharing", + "ga", + { + "name": "dynamo", + "version": "git+https://github.com/masself/gitbook-plugin-dynamo.git" + } + ], + "pluginsConfig": { + "ga": { + "token": "UA-52186525-3" + }, + "dynamo": { + "customLinks":[ + { + "label": "Download", + "icon": "fa fa-file-pdf-o fa-lg", + "url": "http://dynamoprimer.com/en/Appendix/DynamoPrimer-Print.pdf" + }], + "languages":[ + { + "label": "Deutsch", + "code":"de", + "url": "http://dynamoprimer.com/de" + }, + { + "label": "日本語", + "code": "ja", + "url": "http://dynamoprimer.com/ja" + }, + { + "label": "", + "code": "", + "url": "" + }, + { + "label": "", + "code": "", + "url": "" + } + ], + "currentLanguage":{ + "code":"en", + "url":"http://dynamoprimer.com/en", + "switchLangLabel":"Languages" + }, + "favicon":"/images/icons/favicon.ico" + } + } +} diff --git a/styles/ebook.css b/styles/ebook.css index 0ee00627..7d4925b7 100644 --- a/styles/ebook.css +++ b/styles/ebook.css @@ -1 +1 @@ -/* CSS for ebook */ +/* CSS for ebook */ diff --git a/styles/print.css b/styles/print.css index 21052b64..11675e83 100644 --- a/styles/print.css +++ b/styles/print.css @@ -1 +1 @@ -/* CSS for print */ +/* CSS for print */ diff --git a/styles/website.css b/styles/website.css index ecec1a9b..3982b913 100644 --- a/styles/website.css +++ b/styles/website.css @@ -1,161 +1,161 @@ -/* CSS for website */ -@import url(http://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700); -@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700); - - -/* - Main -*/ -body { - text-rendering: optimizeLegibility; - font-smoothing: antialiased; - font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - color: #323232; -} - -h1,h2,h3,h4,h5,h6{ - font-family: 'Roboto Slab', serif; - font-weight: 100; -} - -.book .book-body .page-wrapper .page-inner section.normal h1, .book .book-body .page-wrapper .page-inner section.normal h2, .book .book-body .page-wrapper .page-inner section.normal h3, .book .book-body .page-wrapper .page-inner section.normal h4, .book .book-body .page-wrapper .page-inner section.normal h5, .book .book-body .page-wrapper .page-inner section.normal h6{ - font-weight: 500; - margin: 100px 0 15px 0; - padding: 0; -} - -.book .book-body .page-wrapper .page-inner section.normal h2 { - padding-bottom: 15px; - font-size: 36px; - line-height: 1.225; - border-bottom: 1px solid #ddd; - font-family: 'Roboto Slab', serif; - margin-bottom: 40px; - font-weight: 300; -} - -.book .book-body .page-wrapper .page-inner section.normal strong { - font-weight: 600; -} - - -/* - Main Nav -*/ -.book .book-header{ - font-family: "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; - overflow: visible; - height: 50px; - padding: 0 8px; - z-index: 2; - font-size: .85em; - color: #7e888b; - background: #454545; -} - -.book .book-header h1{ - opacity: 1; -} - -.book .book-header h1 a{ - color: transparent; - opacity: 1; - background-image: url('../images/logo.png'); - background-repeat: no-repeat; - background-position: center center; - display: inline-block; -} - -.book .book-header h1 a:hover{ - color: transparent; -} - -.book .book-header .btn { - display: block; - height: 50px; - padding: 0 15px; - border-bottom: 0; - color: #ccc; - text-transform: uppercase; - line-height: 50px; - -webkit-box-shadow: none!important; - box-shadow: none!important; - position: relative; - font-size: 20px; -} - -.book .book-header .btn:hover { - position: relative; - text-decoration: none; - color: #fff; - background: 0 -} - -.book .book-header #font-settings-wrapper, -.book .book-header .btn[aria-label="Share"]{ - display: none; -} - -.book .book-summary .book-search{ - background-color: #f1f1f1; -} - -/* - Sidebar Left -*/ -.book .book-summary{ - border-right: 0; -} - -.book .book-summary ul.summary li a, -.book .book-summary ul.summary li span { - display: block; - padding: 10px 15px; - border-bottom: 0; - color: #323232; - background: transparent; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - position: relative; - font-family: 'Roboto Slab', serif; - font-size: 13px; - - outline:none; -} - -.book .book-summary ul.summary li.active>a, .book .book-summary ul.summary li a:hover { - color: #5eb7e5; - background: transparent; - text-decoration: none; -} - - -/* - Inner Content -*/ -.book .book-body .page-wrapper .page-inner section.normal{ -padding: 60px 0; -} - - - - - - - - - - - - - - - - - - - - - +/* CSS for website */ +@import url(http://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700); +@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700); + + +/* + Main +*/ +body { + text-rendering: optimizeLegibility; + font-smoothing: antialiased; + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + color: #323232; +} + +h1,h2,h3,h4,h5,h6{ + font-family: 'Roboto Slab', serif; + font-weight: 100; +} + +.book .book-body .page-wrapper .page-inner section.normal h1, .book .book-body .page-wrapper .page-inner section.normal h2, .book .book-body .page-wrapper .page-inner section.normal h3, .book .book-body .page-wrapper .page-inner section.normal h4, .book .book-body .page-wrapper .page-inner section.normal h5, .book .book-body .page-wrapper .page-inner section.normal h6{ + font-weight: 500; + margin: 100px 0 15px 0; + padding: 0; +} + +.book .book-body .page-wrapper .page-inner section.normal h2 { + padding-bottom: 15px; + font-size: 36px; + line-height: 1.225; + border-bottom: 1px solid #ddd; + font-family: 'Roboto Slab', serif; + margin-bottom: 40px; + font-weight: 300; +} + +.book .book-body .page-wrapper .page-inner section.normal strong { + font-weight: 600; +} + + +/* + Main Nav +*/ +.book .book-header{ + font-family: "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + overflow: visible; + height: 50px; + padding: 0 8px; + z-index: 2; + font-size: .85em; + color: #7e888b; + background: #454545; +} + +.book .book-header h1{ + opacity: 1; +} + +.book .book-header h1 a{ + color: transparent; + opacity: 1; + background-image: url('../images/logo.png'); + background-repeat: no-repeat; + background-position: center center; + display: inline-block; +} + +.book .book-header h1 a:hover{ + color: transparent; +} + +.book .book-header .btn { + display: block; + height: 50px; + padding: 0 15px; + border-bottom: 0; + color: #ccc; + text-transform: uppercase; + line-height: 50px; + -webkit-box-shadow: none!important; + box-shadow: none!important; + position: relative; + font-size: 20px; +} + +.book .book-header .btn:hover { + position: relative; + text-decoration: none; + color: #fff; + background: 0 +} + +.book .book-header #font-settings-wrapper, +.book .book-header .btn[aria-label="Share"]{ + display: none; +} + +.book .book-summary .book-search{ + background-color: #f1f1f1; +} + +/* + Sidebar Left +*/ +.book .book-summary{ + border-right: 0; +} + +.book .book-summary ul.summary li a, +.book .book-summary ul.summary li span { + display: block; + padding: 10px 15px; + border-bottom: 0; + color: #323232; + background: transparent; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + position: relative; + font-family: 'Roboto Slab', serif; + font-size: 13px; + + outline:none; +} + +.book .book-summary ul.summary li.active>a, .book .book-summary ul.summary li a:hover { + color: #5eb7e5; + background: transparent; + text-decoration: none; +} + + +/* + Inner Content +*/ +.book .book-body .page-wrapper .page-inner section.normal{ +padding: 60px 0; +} + + + + + + + + + + + + + + + + + + + + +