0:02 hi everybody many of you think that it's
0:04 still very hard to create custom Revit
0:05 addings and I Want to Break Down The
0:07 Stereotype I want to take you step by
0:09 step for the process of creating new
0:11 tools for Revit but most importantly I
0:13 want you to feel what it's like to
0:15 create custom Revit addings once you
0:17 will create your first button you'll
0:19 want to create more you might even have
0:20 multiple ideas during this video for
0:23 your new tools that's how we all start
0:24 and the best way of learning is actually
0:27 by doing so let's get you into this
0:29 developers flow and create your first
0:32 custom par button in just a few minutes
0:34 but before we begin I actually expect
0:35 that you already have your own custom
0:38 parit extension created either with my
0:40 EF pit starter kit or you made it on
0:42 your own it only takes 2 minutes to
0:44 create your custom parit extension and
0:45 you can watch this video where I will
0:47 show you how to do that along with the
0:49 tour of my EFI RIT starter kit which is
0:52 absolutely free cuz there are a lot of
0:54 resources and code samples and I want
0:56 you to get the most out of it and now
0:59 let's create your first parid button I'm
1:00 going to create my button here in the
1:02 dev panel it's really good practice to
1:04 have a special panel where you create
1:06 new tools which can be unfinished and
1:07 once they finished you can move them
1:09 anywhere else by just moving the folder
1:11 so don't always stress where you're
1:13 going to create it to create it I'm
1:15 going to hold out and click on one of
1:17 these kind of place holder buttons and
1:18 it's going to open the folder where it's
1:21 located I can go one folder outside some
1:24 in my Dev panel and you can see in here
1:26 I have Dev button one two and three and
1:28 same is here going to go outside you
1:31 also see there a bunch of panels and I
1:32 also have here about resources
1:35 placeholder panel and death
1:37 panel so I'm going to go back to the
1:38 death panel and I'm just going to
1:39 duplicate one of the
1:43 buttons let's call it our first button
1:45 and most importantly make sure you spell
1:47 push button correctly if you cannot see
1:49 your button appear in pyit when we're
1:51 going to reload it it probably means
1:53 that you misspell this one push button
1:55 right here or maybe you haven't put a
1:58 script and an icon inside of there now
2:00 first of all let's place here an icon
2:02 and we also going to put some kind of
2:04 template inside of the script file so we
2:05 can actually continue creating our
2:07 button to place here an icon we can
2:09 actually go to resources and right here
2:12 we're going to go to icons8.com in here
2:13 we can get the free
2:16 resources in the search icons I'm going
2:18 to write here something like rename
2:20 because spoiler alert during this video
2:21 I'm going to show you how to rename your
2:23 views with py RIT and we're also going
2:25 to create little interface and so on but
2:26 you will see this in a
2:29 moment now in here I'm going to select
2:31 just a random icon I can click on the
2:33 download when you will be downloading
2:35 the icon make sure it's smaller than 96
2:37 by 96 pixels but you can always take it
2:40 smaller just to be safe now click on
2:42 download when it's ready just drag it
2:45 into the folder of your newly created
2:47 button now we can get rid of the
2:49 previous icon and rename this one to the
2:51 icon you could also create here a second
2:53 icon and call it icon the dark to have
2:55 different icons for the light and dark
2:57 theme but I don't want to do that I'll
3:00 be fine with just one icon now now we
3:01 have the icon let's open up the script
3:03 and change something there as well now
3:05 since I duplicated my existing button I
3:07 already have here some kind of template
3:09 but if you haven't done this we can go
3:12 to my EF pyit starter kit then here in
3:14 the templates have different templates
3:16 I'm going to click on py RIT minimum
3:18 template and here this is a very
3:20 simplified version we have some
3:22 description the name of the button a few
3:25 most important Imports a few variables
3:26 and just blocks for your main and
3:28 functions just going to copy that and
3:31 paste it here in my Buton Buton first of
3:33 all let's change the title in here I'm
3:35 going to call it rename
3:37 views then this is the description that
3:38 your user is going to see when they
3:40 hover over the button I'm just going to
3:42 quickly modify this and you can write
3:44 here anything you want but this is how I
3:46 prefer to do this first of all I like to
3:49 know the version and the date then in
3:50 here I'm going to write the description
3:52 of this button then depending on the
3:54 tool I like to describe how to use it
3:55 for example for this one I could write
3:56 something like click on the button then
3:59 select views Define renaming rules and
4:01 lastly rename views but it always
4:03 depends on how much information you want
4:05 to give to the users then for the update
4:07 it's good to track what kind of changes
4:08 you make but in this case I'm just going
4:11 to set the date and today is the release
4:13 of this tool then in here you can also
4:14 add some features that you are planning
4:16 to add later but I'm not going to be
4:18 planning anything for this tool all
4:20 right then in here we have our common
4:23 import our Autodesk import our P RIT
4:25 import and sometimes we need a list from
4:28 net Library this is how you get it and
4:30 here are our variables and here we're
4:33 going to write our code let's remove
4:36 function and now let's go to Revit then
4:38 we're going to go to P Revit tab I'm
4:40 going to click on this button right here
4:42 reload then on this menu say yes and
4:44 once it's reloaded when you're going to
4:46 go back to your toolbar you're going to
4:48 see a new button appear if you've done
4:50 everything correctly if you haven't done
4:51 anything correctly usually it's because
4:53 of the folder structure just make sure
4:55 that you put the right suffixes like
4:58 that push button that tab that panel all
5:01 of that also in the right order now
5:03 here's my button when I'm going to click
5:04 on it it just going to give me some kind
5:06 of print statement which is a template
5:08 has been developed by Eric frit which
5:11 comes from here on the bottom right we
5:13 don't need it let's remove it and now we
5:14 are ready to start coding but before
5:16 you're going to open your code editor I
5:18 want you to grab a piece of paper and a
5:19 pen we're going to do a little bit
5:22 brainstorming together to decide what
5:24 kind of tool are we creating as you
5:25 already understood from the name we're
5:27 going to rename our views by using fine
5:29 and replace logic this will help me to
5:31 introduce you to various RAV API concept
5:33 and also show you how to take a big tool
5:35 idea and break it down into smaller
5:38 manageable steps this is necessary as it
5:39 helps you to think more like a
5:40 programmer and you might discover some
5:42 hidden steps in between that you need to
5:45 address to avoid errors that's what we
5:47 also going to do and also a huge remark
5:49 here it doesn't need to be beautiful or
5:51 very detailed it just have to make sense
5:54 to you and also maybe it's just me but I
5:56 tend to rewrite the steps over and over
5:58 until they start making more sense to me
6:00 as it helps me to think about about the
6:02 problems and find a solution to them so
6:04 now let's think how should we rename our
6:06 view in Revit there are a few steps that
6:08 we need to do first of all we need to
6:10 grab a few views and there are two ways
6:12 we're going to do that first of all
6:13 we're going to try to get selected views
6:16 in the project browser in ravit UI and
6:17 if there is nothing selected then we're
6:19 going to select our views with the p
6:20 form and I'm going to show you how to
6:22 use it don't worry then we need to
6:24 define a few renaming rules such as what
6:26 do we want to find what we want to
6:28 replace it with the prefix the sufix and
6:30 all of that and then we will create a
6:32 new view name and we're going to rename
6:35 all of the views and also by looking at
6:37 this diagram you might realize that
6:39 there's actually extra step in between
6:41 because when we going to rename our
6:42 views we want to make sure that it's a
6:44 unique view name cuz otherwise we're
6:46 going to get an error saying that the
6:48 view name is not unique and it's not
6:50 going to rename it and we also might see
6:51 the red wall of text if you're not going
6:54 to use try and accept
6:56 statements all right and this is our
6:58 diagram this is what we're going to code
6:59 and you can use it as the comments in
7:01 your code or however you like it just
7:03 going to keep the paper in front of me
7:05 and follow along all right and now we're
7:08 going to go to the coding part let's
7:10 open our code editor and the first step
7:12 we're going to do is Select some views
7:15 let me zoom in as well so you can see it
7:17 better now as I mentioned in the diagram
7:18 we need first of all we're going to try
7:20 to get selected views and then we're
7:22 going to try to use the pirated form to
7:24 get the selected views the same as
7:27 getting our selected elements for that
7:28 we will need to make sure that we have
7:32 our UI do Define right here and can WR
7:36 here selected element IDs equals UI doc
7:38 selection and then there is a method
7:40 called get element
7:42 IDs now we want to take all of these
7:45 element IDs and convert it to selected
7:47 elements let's make it a list
7:49 comprehension I'm going to write dog get
7:51 element we're going to provide this
7:53 element IDs then in here we're going to
7:56 write for element ID in selected element
7:58 IDs so we're going to iterate for this
7:59 list I'm we're going to get the actual
8:02 element from the element ID now we don't
8:04 care really about all the selected
8:07 elements what we care about is selected
8:09 views so in here we're going to create
8:11 another Leist comprehension and there
8:12 we're going to write I want to get all
8:15 elements or element and selected
8:17 elements and in list comprehension we
8:19 can also make here an if statement and
8:22 in here I'm going to write if is subass
8:25 now we need to write type of the element
8:26 and we're going to provide
8:29 view this method right here will just
8:31 check if the type of the element is part
8:33 of the view or any of its children
8:35 classes cuz as you know in The
8:38 Inheritance hierarchy we have our view
8:40 and then there a lot of classes based on
8:42 it like view plan view section and all
8:44 of those classes so this will make sure
8:46 that we check if we have any views
8:48 selected and now let's add here a
8:50 comment that we're getting a views which
8:52 are selected in the project browser
8:54 however if you don't have anything
8:55 selected in the project browser we want
8:58 to get our views differently so this way
9:00 we're going to write if none
9:02 selected we're going to prompt select
9:05 views from parit forms and there is
9:07 something like select views I'm not sure
9:09 if that's how it's written but you will
9:11 see in a moment so we're going to just
9:13 write if not selected views then I'm
9:15 going to write selected views
9:18 equals and then in the import somewhere
9:19 right here you can see from pit we import
9:20 import
9:23 forms we're going to write here forms
9:26 and I'm going to write select views I
9:28 don't think I need to provide here any
9:30 arguments optionally I can provide my
9:32 title button name weave multiple all of
9:35 that but I can see that multiple is set
9:37 to true so I'm just going to leave it oh
9:39 and if you want to see the dock strings
9:41 can hold control and click on Q then
9:43 you're going to see this menu but to do
9:44 that you need to make sure that you set
9:47 your interpreter settings and it knows
9:49 where P rabit library is located in my
9:51 case right here I provided my RIT API
9:54 stops and right here I provided my pit
9:56 Masters pit lip folder this way P charm
9:58 knows about these functions and it can
10:00 read about them all right and before
10:01 we're going to go any further we need to
10:03 ensure that we have some views selected
10:05 again we're going to write if not
10:07 selected views and this time I'm going
10:10 to use forms alert I'm going to write
10:14 now views selected please try
10:16 again I'm going to write here exit
10:19 script equals to true this will make
10:21 sure that we stop execution of the code
10:23 we're not going to see anything further
10:25 for example let's write here print
10:28 done and if this is triggered we're
10:29 never going to see this print statement
10:32 done now let's open ravit and see if it
10:35 works I'm going to click on this button
10:37 and you will see I get a select menu I'm
10:39 like okay let's check everything and
10:42 click on select and it says no view
10:44 selected please try again probably means
10:46 that I messed up something let's come
10:48 back in here and right away I can see
10:50 right here because I use the variable
10:52 select views but in here accidentally I
10:54 wrote selected elements let's change
10:57 that and we're going to come back to
10:59 ravit now I'm going to click on it again
11:01 since I don't have anything selected I'm
11:03 supposed to get this menu and I do I'm
11:05 going to select all the
11:07 views right here the print statement
11:08 done means that I manag to select My
11:11 Views and the script continues but if
11:13 I'm going to click on here I don't
11:15 select anything and close it you're
11:17 going to get an alert no views selected
11:19 please try again but most importantly
11:21 it's going to stop execution of the code
11:22 and therefore we're not going to create
11:24 any errors we're not going to see any
11:27 wrong statements and so on and lastly we
11:29 can also select some views this way
11:32 right here click on rename views and
11:33 we're not supposed to see any form we're
11:35 just supposed to see the done because we
11:38 selected it on the first try right here
11:40 so this one worked and this one didn't
11:42 work didn't work and we continue with
11:45 the code CU we already have our selected
11:48 views all right selecting views is easy
11:49 let's go to the Second Step where we're
11:52 going to Define renaming rules at first
11:53 you can hardcode this values so we're
11:56 going to Define our fine replace sufix
11:58 prefix and we're going to create a
12:00 working script by using this values and
12:02 only then you can think about the UI
12:04 form because first of all you need to
12:06 make sure that it works before you start
12:08 thinking about how to make it pretty I
12:10 highly recommend you to create this MVP
12:12 which stands for minimum viable product
12:14 and it's just to prove your idea first
12:16 and then we can focus on optimizing and
12:19 make it look nicer and all of that
12:21 because you see in the past I've spent a
12:23 lot of hours making a nice forms for
12:25 something that apparently I couldn't do
12:28 at the time yet so make your MVP first
12:29 and once it working they you can focus
12:31 on all the forms and make it beautiful
12:35 all right now in my case I'm going to
12:37 look here for something like floor plan
12:38 and I'm going to replace it maybe with
12:40 level or anything else we're going to
12:42 change it later
12:45 anyway now the next step we need a
12:46 transaction because we are about to make
12:49 changes transactions in Revit API are
12:51 necessary to make any changes in your
12:53 Revit projects and that's great news for
12:55 the beginners because it just means that
12:57 you cannot mess up anything accidentally
12:59 in your projects while you explore ravit
13:01 API so you can feel safe and do whatever
13:04 you want with ravit API until you use
13:05 transactions cuz once you start using
13:07 them then you have to be really careful
13:10 what you do to define a transaction we
13:12 need to use the class
13:14 transaction I need to provide here a
13:16 document and the name of the change this
13:18 name is going to be shown in the undo
13:21 menu let's let's go to rename views and
13:23 sometimes it also might be a good idea
13:25 to put here some kind of prefix like e
13:27 if or maybe Pi so you know that it's
13:30 your Custom Tool
13:32 now we also need to Define here a
13:33 variable let's set T to equal
13:36 transaction and then we need to start
13:39 and we need to commit our
13:42 transactions let's also add here a few
13:44 icons and in here we're going to write
13:46 start transaction to make changes in the
13:48 project now we need to use this kind of
13:50 start and commit statements and we need
13:52 to put all our changes in between so
13:54 only if you're going to say for example
13:56 view name equals new name it's only
13:57 going to work if it's going to be
13:59 between start and commit and if you're
14:02 going to take it outside of it then
14:03 you're going to get an error that you
14:05 need a transaction to make it work all
14:07 right I'm going to remove it for
14:10 now and also a big note don't worry if
14:12 you make any changes between your start
14:14 and commit because it will be just roll
14:16 back which means just cancelled and
14:18 nothing will happen to your project so
14:19 whenever you have any issues you're
14:21 going to see the red text and usually
14:23 even your RIT won't crash you're just
14:24 going to see the message what's going
14:27 wrong and it's going to be canceled all
14:29 right we prepared our transaction now we
14:32 need to write for view in our selected
14:35 views and here two
14:37 things first of all we need to create
14:40 new view
14:42 name and then we need to rename our
14:45 views and also as you remember we need
14:46 to ensure that we have a unique view
14:49 name now to create a view name it's very
14:51 simple because we can read the existing
14:53 Name by using view name we're going to
14:58 write here old name equals view name now
14:59 the new name is going to be be our old
15:02 name we're going to write here replace
15:04 then we take our keyword for the find
15:05 keyword for the
15:07 replace and if you also work with suffix
15:10 and prefix we're just going to add it in
15:12 the end or we're going to add it in the
15:14 front and that's how we're going to
15:16 create a new name but we still don't
15:17 know if this name is going to be unique
15:19 enough and we're going to do this while
15:21 we are renaming cuz in here we're going
15:24 to set for example VI name equals new
15:27 name cuz this is a writable property and
15:28 we can see it in documentation right
15:31 there there it says get and set and set
15:33 means that we can write it like this I'm
15:35 going to assign a name if it's a unique
15:37 name it's going to work just fine but if
15:38 it's not we're going to get an error and
15:40 that's not good so for that we want to
15:42 use try and accept statements just to
15:44 catch our
15:47 errors and the way we're going to also
15:49 handle it I'm going to create here for I
15:51 in range of 20 so I'm going to give 20
15:54 tries to rename my view and every time
15:56 that I fail I'm going to do something
15:58 with a new name I'm going to write here
16:00 new name equals I'm going to keep adding
16:03 the star symbol in the end so for
16:04 example if you already have a view name
16:06 called floor plan it'll try to add one
16:08 star then the second the third and so on
16:10 so on so on until it reaches the
16:13 20 and the reason also I use the full
16:15 Loops cuz if we're going to use the
16:16 while loop and we forget to write The
16:18 Brak statements you're going to crash
16:19 your rabit cuz you're going to create an
16:21 infinite Loop and you cannot really
16:23 Escape that so therefore highly
16:24 recommend you to stick to the follow
16:27 Loops make here some kind of crazy
16:28 number and it's going to be still quick
16:31 to wait 200 times instead of waiting
16:33 this infinite Loop which never
16:35 ends all right and I think that we have
16:37 everything that we need and now let's
16:40 quickly recap what did we do so first of
16:42 all we select our views we either select
16:44 them in a project browser or we prompt
16:46 user to select by using p RIT forms
16:48 select views then we ensure that we have
16:50 some views before we're going to go any
16:52 further then we're going to Define our
16:54 renaming rules we're going to find our
16:55 floor plan we're going to replace it
16:57 with level just to make sure let's
16:59 actually make it EF level
17:01 in the prefix I'm going to add pre and
17:03 in the suix we're going to add maybe
17:04 something like
17:06 suf then we're going to start a
17:08 transaction and we're going to iterate
17:10 through all the selected views we need
17:12 to get our old name and we need to
17:14 Define our new name then we're going to
17:16 rename all of the views and then
17:18 eventually when it happens what's
17:19 important is that you make here a break
17:21 statement and before that we can also
17:23 make some print statement for example it
17:26 was this and it became this and let's
17:29 assign it this was old name and this is
17:32 our new name also I forgot to remove the
17:35 zero I don't want a 200 and again this
17:37 break statement if you don't do this
17:39 still going to work just going to kind
17:41 of rename it 20 times instead of one but
17:43 if you're going to put it here it's
17:45 going to stop executing this full loop
17:46 the moment is going to rename this view
17:48 So This is highly recommended to use The
17:50 Brak statement all right and in the end
17:52 we're going to write something like done
17:54 just so users know that we finished
17:56 renaming our views and maybe let's also
17:59 print 50 dashes
18:00 all right this is the code and you can
18:03 see it's not that complicated yes you do
18:05 need to know how to get your selections
18:07 what kind of forms available in py RIT
18:09 how to create transaction how to rename
18:11 it but this is things that you pick up
18:12 really quick and when you're going to
18:14 create your next tool you already know
18:16 about all of these Concepts you're just
18:17 going to have a look here and you're
18:20 easily going to replicate it now let's
18:22 go to ravit and see first of all I'm
18:23 going to select a few views like this in
18:25 my project browser and I'm going to
18:27 click on rename views and the moment I
18:29 do this you can see that they all added
18:32 the prefix suffix and floor plan was
18:34 replaced with the EF level and here are
18:37 the results this is what it was before
18:39 this is what happened after that and
18:40 listen guys understand that this is not
18:42 the most userfriendly experience right
18:44 to open your code change something here
18:46 most of you users will never do that I
18:49 know that for a fact instead of that I'm
18:51 going to put here like 2 a and this was
18:53 our version for the
18:55 development and now here I'm going to
18:59 create version 2 b
19:01 and I'm going to past snipp it right
19:03 here if you're going to write in Google
19:06 RPV Flex form eventually you're going to
19:08 end up on this website and in there you
19:09 have a very good example of how to
19:12 create custom forms first of all we need
19:13 to define components and you can see I
19:15 have a bunch of different labels right
19:17 here with the names and this is going to
19:18 be just shown as a text we're going to
19:20 see in the form prefix find replace and
19:23 so on and we're going to Define text
19:25 boxes this is where users can write
19:26 something and we're going to give names
19:28 to these text boxes so later on we can
19:30 actually get the values so we're going
19:32 to create a form we're going to show it
19:34 to the user then user going to interact
19:36 with it and we will be able to get the
19:37 values from the form and this is going
19:41 to be just a
19:43 dictionary so therefore we can get all
19:45 the values from dictionaries like this
19:47 and you can see all the keys we Define
19:50 them right here for the text boxes now I
19:52 think everything is exactly like I
19:54 wanted let's close this click on this button
19:56 button
19:58 again I'm going to select all of my views
19:59 views
20:02 click on select and now I get this form
20:04 as a prefix I'm just going to write ABC
20:07 and a Dash then in defined I'm actually
20:09 going to be looking for the EF with a
20:10 dash and I'm going to replace it with
20:12 nothing I just want to get rid of this
20:14 EF and in the suffix we're not going to
20:15 put anything and now we're going to
20:18 click on rename views and you can see
20:20 here are the print statements and All My
20:23 Views I changed I have my abc prefix EF
20:25 is gone and everything happened exactly
20:27 like I wanted all right then
20:28 congratulations now you know how to
20:30 create new Tools in pirate and it's just
20:32 the beginning as you will discover many
20:34 ideas that will help you in your daily
20:37 work start small and focus on quantity
20:39 over quality at first and over time
20:41 you'll create so many different tools
20:43 and have so much code examples that
20:45 creating new tools will be so much
20:47 easier in my case for example I can
20:49 create new tools where I copy paste more
20:52 than 80% of the code from previous tools
20:54 because I have so many examples already
20:56 and so will you I want to wish you keep
20:58 creating more cool tools and happy
21:00 coding and also I would like to ask you
21:02 for a favor if you've enjoyed my EFI
21:04 ravit starter kit it would make my day
21:06 if you would leave me a testimonial this
21:08 will help me promote this free stter kit
21:11 to even more people and motivate others
21:13 to give it a try and also I'll provide
21:15 you a nice reward if you decide to make
21:18 video testimonials so it's a win-win
21:20 situation you can leave this testimonial
21:23 by clicking here on leave a review or
21:24 going straight to this website and here
21:26 you can create your testimonial it's
21:30 100% appreciated and 0% % expected enjoy
21:32 your free pit starter kit and happy
21:36 coding it's 100% appreciated and 0%
21:39 expected enjoy this EF starter kit and
21:41 my name is Eric Fritz and I'll wish you