WEBVTT

1
00:00:00.440 --> 00:00:02.440
Hello and welcome to scripting for artists.

2
00:00:02.450 --> 00:00:06.390
My name is swollen and this episode is called roast. My add on.

3
00:00:06.400 --> 00:00:09.820
I've asked on social media for your add ons for me to roast

4
00:00:09.830 --> 00:00:12.570
so that we can go through it and see what is bad.

5
00:00:12.570 --> 00:00:14.780
What is good, how things can be improved.

6
00:00:14.780 --> 00:00:18.290
We look at a few different adults and in the end of this episode I

7
00:00:18.290 --> 00:00:22.260
will extract some general hints and tips for you to use in your own code

8
00:00:22.540 --> 00:00:25.500
on twitter Thompson says, hey thanks, that's great idea.

9
00:00:25.510 --> 00:00:28.740
Would be glad to have some pros inside about my coding.

10
00:00:28.750 --> 00:00:32.430
This first add on is a project manager for an M workflow and the

11
00:00:32.430 --> 00:00:35.860
other add on is a simple tool to reload images in the blend file,

12
00:00:35.860 --> 00:00:38.460
feel free to pick one if you have some time cheers,

13
00:00:38.640 --> 00:00:40.710
I will pick the second one first because that

14
00:00:40.710 --> 00:00:43.350
looks like something simple and nice to start with.

15
00:00:43.540 --> 00:00:47.840
So let's take a look at the code here we are on Git hub and the first thing

16
00:00:47.840 --> 00:00:49.910
I noticed is that it has a description which

17
00:00:49.910 --> 00:00:52.860
is good and the automatic reload for image textures.

18
00:00:53.840 --> 00:00:56.130
Then there is a bunch of files and there's a

19
00:00:56.130 --> 00:00:58.730
rip me that says it's blended to put 80 adults.

20
00:00:58.730 --> 00:01:01.820
So it's compatible with more modern blender versions.

21
00:01:01.820 --> 00:01:04.959
I'm assuming that it will also run on newer than 2.80.

22
00:01:05.440 --> 00:01:07.540
It can refresh all the images of the blend file.

23
00:01:07.540 --> 00:01:11.600
It can use the term or to fetch modified image file and reload them if needed.

24
00:01:11.610 --> 00:01:14.650
That is pretty handy and already I want to use it.

25
00:01:14.660 --> 00:01:18.530
It has a link to download and it has a little demo video.

26
00:01:18.540 --> 00:01:19.860
If you want to watch the video,

27
00:01:19.860 --> 00:01:23.660
I've put the link down below in the description so you can just click it there.

28
00:01:23.670 --> 00:01:27.500
I'm looking at all the files that are there and I wouldn't

29
00:01:27.510 --> 00:01:32.330
exactly know what to expect where there's developer utilize those functions.

30
00:01:32.340 --> 00:01:35.990
Um there is DEV I don't know how DEV

31
00:01:36.000 --> 00:01:39.550
differs from developer functions and then there is misc

32
00:01:40.240 --> 00:01:43.820
probably short for miscellaneous. So where would some function go?

33
00:01:43.820 --> 00:01:47.390
Would it be miscellaneous? Would it be deaf? Would it be developer do tails?

34
00:01:47.400 --> 00:01:51.930
Would it be functions? So I try to always avoid naming things.

35
00:01:51.940 --> 00:01:55.860
You tails or helpers or miscellaneous.

36
00:01:55.860 --> 00:01:59.300
Generally that's an indication that it's just a bag

37
00:01:59.300 --> 00:02:01.960
of stuff that is going to expand over time

38
00:02:02.240 --> 00:02:04.660
and that is not something you want in your source code.

39
00:02:05.340 --> 00:02:07.860
Now, let's take a look at the minute file,

40
00:02:08.740 --> 00:02:12.760
19 lines in the file and 71 source lines of code.

41
00:02:13.140 --> 00:02:16.810
It's a rather small file which can be pretty nice. So it gives a nice overview.

42
00:02:16.810 --> 00:02:18.930
It starts with them copyright information.

43
00:02:18.940 --> 00:02:24.060
GPL license of course, Bill info is all given even shows

44
00:02:24.440 --> 00:02:26.960
where you can find the settings for this add on

45
00:02:27.440 --> 00:02:32.360
that. The weak Euro. It has a track of your l importante pie so far. So good.

46
00:02:32.940 --> 00:02:37.530
Now it imports import lib and inspect from period and import developer you'd hills,

47
00:02:37.530 --> 00:02:39.800
which means from the current module,

48
00:02:39.800 --> 00:02:42.060
import the sub module called developer You tales.

49
00:02:42.440 --> 00:02:45.020
And then it tries to reload that this works.

50
00:02:45.020 --> 00:02:47.250
But generally the reloading scheme is a

51
00:02:47.250 --> 00:02:49.310
little bit different from multi file modules.

52
00:02:49.310 --> 00:02:51.350
But if this works for you, that's fine.

53
00:02:51.360 --> 00:02:54.620
Then we have modules is developing details set up adult modules.

54
00:02:54.620 --> 00:02:56.770
Path name be pointing locals.

55
00:02:56.780 --> 00:03:02.560
Okay, so magic is going on there and then classes and is an empty list. And then

56
00:03:02.840 --> 00:03:04.300
so this is basically,

57
00:03:04.300 --> 00:03:07.850
I'm guessing collecting all the python classes that need

58
00:03:07.850 --> 00:03:10.960
to be registered and unregistered from the sub modules.

59
00:03:11.340 --> 00:03:13.610
Usually I wouldn't do it in this way.

60
00:03:13.610 --> 00:03:17.360
I would give every stop module its own registered and unregistered function.

61
00:03:17.370 --> 00:03:22.180
And just call that from the top level function. That way there's no magic.

62
00:03:22.190 --> 00:03:25.260
It's all pretty clear where things are called from.

63
00:03:25.740 --> 00:03:28.760
Yeah, I'm not a I'm not a big fan of this kind of magic.

64
00:03:29.240 --> 00:03:32.480
And then there is from dot functions, import reload startup.

65
00:03:32.480 --> 00:03:36.540
So, from the sub module functions, it imports the reload startup thing.

66
00:03:36.550 --> 00:03:37.760
I think it's a function.

67
00:03:38.240 --> 00:03:39.760
Um

68
00:03:40.440 --> 00:03:40.950
Okay

69
00:03:41.640 --> 00:03:43.650
then, for the register, some

70
00:03:44.140 --> 00:03:46.860
properties are added which are all fine.

71
00:03:47.240 --> 00:03:51.090
And then for CLS in class is called register class. Yes.

72
00:03:51.090 --> 00:03:55.460
So, this uses this classes list that you define here

73
00:03:55.940 --> 00:03:58.630
and then registers everything. All right.

74
00:03:58.630 --> 00:04:02.860
And then the reload startup is added as a post load handler.

75
00:04:03.240 --> 00:04:09.070
The Dell CLS here is really not necessary because the only thing that does

76
00:04:09.070 --> 00:04:14.520
in python is it removes the CLS name but then on the next situation,

77
00:04:14.520 --> 00:04:17.140
CLS gets the next class assigned to it anyway.

78
00:04:17.140 --> 00:04:18.560
So then it exists again.

79
00:04:18.589 --> 00:04:22.050
This is not like C plus plus, where it would delete the actual object in memory.

80
00:04:22.240 --> 00:04:25.990
It just removes the name from the current name space so you can no longer use it

81
00:04:26.440 --> 00:04:30.130
because of all the magic. I still don't know what is defined where.

82
00:04:30.140 --> 00:04:32.710
So let's go and look at a different file.

83
00:04:32.720 --> 00:04:35.580
Let's take a look at operators and see what kind of operators.

84
00:04:35.580 --> 00:04:40.360
There are lots of stuff being imported more stuff from the uh Oh,

85
00:04:40.440 --> 00:04:44.370
if you have to import so many names from that module,

86
00:04:44.380 --> 00:04:47.760
I would rather just import the module itself,

87
00:04:47.940 --> 00:04:52.090
like from the import functions and then call functions, start update,

88
00:04:52.090 --> 00:04:54.250
viewer or functions don't get my dear.

89
00:04:54.260 --> 00:04:56.870
That way. It's easier to see again where things are coming from.

90
00:04:56.880 --> 00:05:03.710
This should be the core of the code. Oh, please. Just no, don't, no, don't do this.

91
00:05:03.720 --> 00:05:07.260
Like in the end your code python is based on inventing

92
00:05:07.540 --> 00:05:08.350
and

93
00:05:08.640 --> 00:05:12.060
if you write it like this, it's so hard to see what's going on.

94
00:05:12.070 --> 00:05:17.750
Um, so if length of modified list doesn't equal zero.

95
00:05:17.760 --> 00:05:21.610
So that means if there's stuff in there pointing automatically,

96
00:05:21.610 --> 00:05:24.910
can convert things to bullying for you.

97
00:05:24.920 --> 00:05:26.360
So, so a list.

98
00:05:26.360 --> 00:05:30.060
If it's empty is considered false and if it's not empty is considered true.

99
00:05:30.140 --> 00:05:33.270
So this means that you can say if modified list

100
00:05:33.280 --> 00:05:36.730
instead of if land modified list doesn't equal zero.

101
00:05:36.740 --> 00:05:40.650
I'm getting ahead of myself. Let's see. W M S context window manager.

102
00:05:40.650 --> 00:05:44.860
Okay, for enough. It's not used here is not used here. So that could be utilized.

103
00:05:44.860 --> 00:05:45.460
Lower.

104
00:05:45.740 --> 00:05:49.100
Um then modified list and missing list is really modified images.

105
00:05:49.100 --> 00:05:52.470
So I'm guessing that reloads all the modified images,

106
00:05:52.470 --> 00:05:54.350
like the images that were modified on disk.

107
00:05:54.440 --> 00:05:57.260
So it's nice to have that in a separate function. That's good.

108
00:05:57.940 --> 00:06:02.580
So then if there is images modified, we update our viewers, which is also nice.

109
00:06:02.590 --> 00:06:04.790
It also passed the context. It's also nice.

110
00:06:04.800 --> 00:06:08.160
Uh I'm not sure why there is no context here. Maybe it's not necessary.

111
00:06:08.160 --> 00:06:11.440
Maybe uses the global context. I don't know there's a style conflict here.

112
00:06:11.440 --> 00:06:14.650
So using camel case here, using underscores

113
00:06:14.840 --> 00:06:16.690
um pick one and stick to it.

114
00:06:16.690 --> 00:06:19.880
And I would say pick the python style that's documented in pep eight,

115
00:06:19.880 --> 00:06:23.060
which means use the underscores here for functions then

116
00:06:23.840 --> 00:06:26.060
if there is no missing images,

117
00:06:27.440 --> 00:06:31.690
auto reload missing images, it's a false otherwise. Auto reload missing images.

118
00:06:31.690 --> 00:06:34.870
Is that true? Well, you can just rewrite this right here.

119
00:06:34.870 --> 00:06:38.750
I have the same following my code editor so I can show you what I mean

120
00:06:39.440 --> 00:06:42.860
first, I'll reinvent it. This is already a little bit nicer.

121
00:06:43.640 --> 00:06:46.760
Now, if we compare that, what happens to the F above that,

122
00:06:46.770 --> 00:06:52.030
we can see that if land modifier list is not zero, then we do something.

123
00:06:52.030 --> 00:06:52.170
So,

124
00:06:52.170 --> 00:06:57.690
first we check for whether that list has elements and then we have a very similarly

125
00:06:57.690 --> 00:07:00.130
looking if statement that checks for whether it's

126
00:07:00.130 --> 00:07:02.450
empty and this will cost you brain power.

127
00:07:03.040 --> 00:07:04.120
So I would say

128
00:07:04.730 --> 00:07:06.550
if modified lists,

129
00:07:07.040 --> 00:07:07.750
that's it.

130
00:07:07.760 --> 00:07:09.670
If modified list, update viewers,

131
00:07:09.670 --> 00:07:13.890
context if there is anything in their update viewers and this is

132
00:07:13.890 --> 00:07:17.320
way simpler and we can do something similar to this as well.

133
00:07:17.320 --> 00:07:20.300
But this checks whether it's empty so it's empty.

134
00:07:20.300 --> 00:07:25.660
It does this if it's not empty it does this. So this checks whether it's empty

135
00:07:26.240 --> 00:07:30.860
what you can just write it this if not missing list then said something false else.

136
00:07:30.860 --> 00:07:31.880
Said something true.

137
00:07:31.890 --> 00:07:35.010
I don't quite like the if not in combination with the else

138
00:07:35.060 --> 00:07:38.400
if you're going to handle both the true and the false cases

139
00:07:38.410 --> 00:07:42.460
anyway then you might as well get rid of the negation by

140
00:07:42.470 --> 00:07:44.660
swapping what is in the F and what's in the else?

141
00:07:45.540 --> 00:07:51.560
So I moved the equals falls down, I moved the equals true up and I remove them not here

142
00:07:52.340 --> 00:07:55.800
and now. What you have is two consecutive checks

143
00:07:55.970 --> 00:07:59.560
that do the same thing. If modified list, do something

144
00:07:59.940 --> 00:08:03.000
if missing list, do something else. Do the opposite.

145
00:08:03.200 --> 00:08:06.650
The cool thing about improvements like this is that it really helped

146
00:08:06.650 --> 00:08:10.060
the readability of your code and I actually do this a lot.

147
00:08:10.060 --> 00:08:14.280
Once I've written the code I will go back in and say, okay now that is working,

148
00:08:14.280 --> 00:08:17.440
can I improve it Can I clarify what's going on if you want.

149
00:08:17.440 --> 00:08:18.960
We can take this one step further

150
00:08:19.140 --> 00:08:21.870
because basically what this is saying is how to

151
00:08:21.870 --> 00:08:25.360
reload missing images when there are missing images.

152
00:08:25.370 --> 00:08:27.750
So we can write that as an expression.

153
00:08:29.740 --> 00:08:32.860
This does exactly the same thing

154
00:08:33.340 --> 00:08:36.470
if missing list is considered true bull.

155
00:08:36.470 --> 00:08:39.510
Missing list is true and assigns true to auto.

156
00:08:39.510 --> 00:08:43.610
Reload missing images and the same for when the list is empty it is or is it false?

157
00:08:43.620 --> 00:08:46.960
So this line expresses what you actually want.

158
00:08:46.970 --> 00:08:50.260
Also relook missing images when there are missing images.

159
00:08:50.740 --> 00:08:52.870
The rest of the coaches seems to be for debugging

160
00:08:52.870 --> 00:08:55.750
and here you can also see the issue with the imports

161
00:08:56.340 --> 00:09:02.040
if you import if you do from global variables import signed Kumar reloaded.

162
00:09:02.050 --> 00:09:05.550
Now here you all of a sudden have signed and reloaded and missing

163
00:09:06.040 --> 00:09:08.460
and it's hard to see where that comes from.

164
00:09:09.540 --> 00:09:10.930
Let's continue with the add on.

165
00:09:10.940 --> 00:09:14.020
The next function is load front and immediately

166
00:09:14.020 --> 00:09:15.750
I see something that I really don't like

167
00:09:16.240 --> 00:09:17.950
area of a try except block

168
00:09:18.440 --> 00:09:22.470
and the except it's just a bare except so it will catch anything.

169
00:09:22.480 --> 00:09:25.710
This means it will also catch keyboard interrupt when the user

170
00:09:25.710 --> 00:09:29.330
presses control C to to break off some hanging operation.

171
00:09:29.340 --> 00:09:33.270
It will catch any error including the ones that you don't want to catch at all.

172
00:09:33.280 --> 00:09:38.270
And then this bit of code the race exception. It doesn't include anything anymore.

173
00:09:38.270 --> 00:09:40.920
So when the original exception would have provided

174
00:09:40.920 --> 00:09:43.360
some information as to what is going wrong.

175
00:09:43.440 --> 00:09:47.620
Maybe the fund cannot be loaded, maybe memories for maybe the font is corrupted.

176
00:09:47.620 --> 00:09:49.050
Maybe something else went wrong.

177
00:09:49.640 --> 00:09:50.450
You never know.

178
00:09:50.840 --> 00:09:51.040
Yeah,

179
00:09:51.440 --> 00:09:56.170
so just remove it Otherwise, this code is quite simple so that's all fine.

180
00:09:56.180 --> 00:09:56.710
Um,

181
00:09:56.720 --> 00:10:00.500
one last thing that I would really like to see is a bit of documentation about what

182
00:10:00.500 --> 00:10:05.310
self is in this case because when you just go through the code top to bottom,

183
00:10:05.310 --> 00:10:06.910
you have no idea what it is.

184
00:10:06.920 --> 00:10:11.120
Let's quickly go through the next operator. This is the actual reloading timer.

185
00:10:11.130 --> 00:10:14.800
So because this video has been going on for quite a bit already all go

186
00:10:14.800 --> 00:10:18.750
into a quick rose mode here we have os path joint of os path joined.

187
00:10:18.750 --> 00:10:21.030
That's not necessary. You can just do it like this.

188
00:10:21.030 --> 00:10:23.110
I wouldn't make regular python properties

189
00:10:23.110 --> 00:10:25.720
with lender properties except attribute error.

190
00:10:25.720 --> 00:10:26.960
No, just fix your code,

191
00:10:26.960 --> 00:10:30.340
make sure that there is no attribute error comparison to false, nope.

192
00:10:30.350 --> 00:10:31.960
Just do if not

193
00:10:32.540 --> 00:10:33.960
else after return.

194
00:10:33.970 --> 00:10:35.130
No, I wouldn't do it,

195
00:10:35.140 --> 00:10:37.250
you can just do this which means that you

196
00:10:37.250 --> 00:10:40.550
can just flip this condition around and then return,

197
00:10:40.550 --> 00:10:43.270
pass through an event this and that we can do again.

198
00:10:43.280 --> 00:10:46.760
There is, if something is not something else. Well you can just flip it

199
00:10:47.240 --> 00:10:50.700
and do that and now I've already invented the code twice this code,

200
00:10:50.710 --> 00:10:51.820
we've seen it before.

201
00:10:51.830 --> 00:10:54.770
No, don't do that where the function, put the code there,

202
00:10:54.770 --> 00:10:56.230
call it from two different places.

203
00:10:56.240 --> 00:10:58.560
The rest of the code pretty much follows the same style.

204
00:10:58.560 --> 00:11:01.110
So I won't go through that again. Thank you very much.

205
00:11:01.110 --> 00:11:05.150
Taunton for lending me your code to roast and let's move on to the next.

206
00:11:05.340 --> 00:11:10.970
So the next adult is by a cube and he is very to the point rose my add on. So here we go.

207
00:11:10.980 --> 00:11:14.160
It's called his own Git hub as well so we can scroll through it.

208
00:11:14.170 --> 00:11:18.580
I see a bunch of files including a rip me, which is nice. It has some examples.

209
00:11:18.590 --> 00:11:22.070
It shows what it can do. Germans like to call a projector. Beamer.

210
00:11:22.070 --> 00:11:23.810
Same in the Netherlands actually.

211
00:11:23.820 --> 00:11:28.350
Let's take a look at the innit pie because that's where it all starts import logging.

212
00:11:28.540 --> 00:11:32.370
Cool. Nice. Um, separate imports. That's also good.

213
00:11:32.380 --> 00:11:36.830
Bill info seems to be complete, nope. Don't do this.

214
00:11:36.840 --> 00:11:41.960
This configures the entire logging module of python and basically forces every

215
00:11:41.960 --> 00:11:45.850
user to have debug logging for everything in a specific format.

216
00:11:45.940 --> 00:11:46.830
This is really,

217
00:11:46.830 --> 00:11:48.940
that's something that you should leave to users

218
00:11:48.940 --> 00:11:52.010
or other developers to control on their system.

219
00:11:52.020 --> 00:11:56.160
Also, the log here is not used at all. So there's no point in creating it.

220
00:11:56.540 --> 00:11:59.520
Nice. Separate registered and unregistered our functions per module.

221
00:11:59.520 --> 00:12:04.310
That's what I like to see. So let's take a look at the operators. There was only one.

222
00:12:04.320 --> 00:12:08.510
It sets the render engines with cycles. Let's take a look at the projector itself.

223
00:12:08.510 --> 00:12:09.650
I kind of expected

224
00:12:09.840 --> 00:12:13.780
an operator that add new projector to the scene.

225
00:12:13.790 --> 00:12:16.950
In the same way that we added a monkey grid to the at mesh menu.

226
00:12:17.240 --> 00:12:19.580
Again, you call logging the basic conflict,

227
00:12:19.590 --> 00:12:22.070
which again overrides the configuration that you

228
00:12:22.070 --> 00:12:23.950
have just said in a different modules.

229
00:12:23.950 --> 00:12:26.470
So this is really a weird way of going about things.

230
00:12:26.480 --> 00:12:29.690
As I said before, I'm not a fan of modules being called helper.

231
00:12:29.690 --> 00:12:33.310
Util miscellaneous, that kind of stuff. But let's take a look at these.

232
00:12:33.320 --> 00:12:37.460
Get projectors gets the context and only selected which defaults to false.

233
00:12:37.740 --> 00:12:41.810
But when you look at the references, you only call it with only selected is true.

234
00:12:41.820 --> 00:12:45.190
So why not just name the function gets selected projectors and

235
00:12:45.190 --> 00:12:48.850
have it over with random color Alpha equals false as default.

236
00:12:48.850 --> 00:12:49.920
You only use it twice.

237
00:12:49.920 --> 00:12:52.940
So why not remove the default and just pass alpha

238
00:12:52.940 --> 00:12:54.820
is true and the alpha is false and then you

239
00:12:54.820 --> 00:13:00.250
have it explicitly said what I do like is that you say alpha is true and not just true.

240
00:13:00.260 --> 00:13:03.810
This makes it much clearer what is going on in that particular call.

241
00:13:03.820 --> 00:13:07.320
So on to the rest of the code, you define some stuff which is nice,

242
00:13:07.320 --> 00:13:08.600
but I'm not here to be nice

243
00:13:08.870 --> 00:13:13.680
then projector. Ot change color randomly. First operator that we see.

244
00:13:13.690 --> 00:13:16.060
Why is this not in the operator's module?

245
00:13:16.070 --> 00:13:19.350
There's something weird going on because the poll method only allows the

246
00:13:19.360 --> 00:13:22.950
operator to be called when the number of selected projectors equals one.

247
00:13:23.040 --> 00:13:24.360
But then you select.

248
00:13:24.370 --> 00:13:27.770
But then here you take all the projectors and just look over them.

249
00:13:27.770 --> 00:13:31.760
So if you have more than one selected, it would actually work blender being blender.

250
00:13:31.760 --> 00:13:34.780
This is basically the difference between working on the active object of

251
00:13:34.780 --> 00:13:38.550
working on the selection and this code seems to confuse the two.

252
00:13:38.560 --> 00:13:40.760
Then with a function create project textures.

253
00:13:40.940 --> 00:13:43.620
You construct an image name from the resolution, which is fine.

254
00:13:43.630 --> 00:13:47.210
Then you check whether the images there and then you use an

255
00:13:47.220 --> 00:13:50.860
operator to actually create the image if it doesn't exist yet.

256
00:13:51.740 --> 00:13:55.180
The problem with this approach is that this operator may create

257
00:13:55.180 --> 00:13:57.380
an image with a different name than you give it.

258
00:13:57.390 --> 00:14:01.260
Even image with that name already exists. It will just append 001.

259
00:14:01.270 --> 00:14:04.580
That means that this line might actually access the wrong image.

260
00:14:04.590 --> 00:14:08.260
Now the chances of that happening are pretty much zero because of the line before it.

261
00:14:08.340 --> 00:14:10.500
But I would never use this. Anyway.

262
00:14:10.510 --> 00:14:13.670
Here we have decoded my editor so I can show you some changes that I would do.

263
00:14:13.680 --> 00:14:17.870
So instead of putting this in the f I would just say image is this?

264
00:14:17.880 --> 00:14:21.310
This get function basically means give me the image with that name.

265
00:14:21.320 --> 00:14:24.350
If it doesn't exist, don't throw an error but just return none.

266
00:14:24.360 --> 00:14:29.760
If not image, then create a new image. What you can do like this,

267
00:14:30.640 --> 00:14:33.290
This creates the exact same image except that it gives you

268
00:14:33.290 --> 00:14:35.680
a reference to that data block that it just created.

269
00:14:35.690 --> 00:14:38.310
So even when that name was unavailable and they

270
00:14:38.310 --> 00:14:40.980
choose something else or something completely different happened.

271
00:14:40.990 --> 00:14:44.200
You get the actual image data block that you're interested in

272
00:14:44.330 --> 00:14:46.240
and then you can set properties on it.

273
00:14:46.250 --> 00:14:46.830
In this,

274
00:14:46.870 --> 00:14:50.230
in this case we have to set the generated type because we can't pass that directly

275
00:14:50.230 --> 00:14:54.850
to the new function and this can just use image dot use fake user is true.

276
00:14:54.860 --> 00:14:57.450
I think this reads a little bit nicer and also it

277
00:14:57.450 --> 00:15:00.580
makes less assumptions about what's going on behind the scenes.

278
00:15:00.820 --> 00:15:02.880
The next function is called at projector.

279
00:15:02.880 --> 00:15:05.000
No tree to spot which I think is quite a

280
00:15:05.000 --> 00:15:07.590
good name because it exactly says what it's doing.

281
00:15:07.600 --> 00:15:11.650
It is documented as this function turns the spotlight into a projector

282
00:15:11.840 --> 00:15:13.650
and this is the first time that we learn

283
00:15:13.650 --> 00:15:16.370
that a projector is actually modeled as a spotlight.

284
00:15:16.380 --> 00:15:18.410
This is actually something that I would have expected in

285
00:15:18.410 --> 00:15:20.840
read me and not in the middle of some code.

286
00:15:20.850 --> 00:15:23.020
So when we scroll down what I notice is

287
00:15:23.020 --> 00:15:25.150
that there is a comparison with the blender version.

288
00:15:25.160 --> 00:15:26.570
I think this is a good idea.

289
00:15:26.580 --> 00:15:29.560
The only thing is that the index here on the inputs area you

290
00:15:29.560 --> 00:15:32.610
can also use a string for that here in inputs instead of writing

291
00:15:32.610 --> 00:15:35.800
three you can also write the string scale the rest of the atom

292
00:15:35.800 --> 00:15:39.430
is boring because it codes were written is pretty clear what it's doing.

293
00:15:39.470 --> 00:15:42.810
The only comment that I have is that it could use a few more comments.

294
00:15:42.820 --> 00:15:46.540
So let's move on to the final adult that I will be roasting today.

295
00:15:46.580 --> 00:15:49.130
Ambi is wondering how long a book are you going to

296
00:15:49.130 --> 00:15:51.810
write well and not as long as your ad on.

297
00:15:51.820 --> 00:15:55.950
He made the blended texture tools a blender add on for simple image manipulation

298
00:15:56.140 --> 00:16:00.220
and I wish that the source code was as simple as that description.

299
00:16:00.230 --> 00:16:04.740
So looking at the file's I already noticed that there is a get sub module in here.

300
00:16:04.750 --> 00:16:08.270
Get some modules are a way to combine multiple Git repositories

301
00:16:08.270 --> 00:16:11.650
into one project and I think for a blender add on.

302
00:16:11.650 --> 00:16:15.200
This may actually be overkilled. Let's start again at the end of pie.

303
00:16:15.210 --> 00:16:17.460
Free software that is very nice.

304
00:16:17.640 --> 00:16:20.470
And now we have some import magic.

305
00:16:20.480 --> 00:16:23.130
Numpy is a python library that allows you to do number

306
00:16:23.130 --> 00:16:25.800
crunching and it's good at handling large amount of data.

307
00:16:25.800 --> 00:16:28.000
So think it's a good choice for this particular

308
00:16:28.000 --> 00:16:30.140
adult because it has to deal with images.

309
00:16:30.150 --> 00:16:33.390
But then the rest there is apparently Q Pie is basically a

310
00:16:33.390 --> 00:16:36.850
library that allows you to do the same operations as Numpy but then

311
00:16:36.850 --> 00:16:40.100
include a on your GPU again I think it's a good choice

312
00:16:40.100 --> 00:16:43.410
to use here but the way that it's handled is really weird.

313
00:16:43.420 --> 00:16:46.290
Coulda active is set to false or true depending

314
00:16:46.290 --> 00:16:48.250
on whether cue point was loaded or not.

315
00:16:48.260 --> 00:16:51.560
To me this coat looks like it's trying to use cup i if it exists

316
00:16:51.560 --> 00:16:56.350
from the system and it can be loaded and otherwise fall back to Numpy instead.

317
00:16:56.360 --> 00:16:57.030
However,

318
00:16:57.030 --> 00:17:01.060
that's not how this reads is really confusing and in the end I don't

319
00:17:01.060 --> 00:17:03.400
know what is going to be used by the rest of the code.

320
00:17:03.940 --> 00:17:06.180
Let me give you an example of how I would do this.

321
00:17:06.190 --> 00:17:06.960
So first of all,

322
00:17:06.960 --> 00:17:09.500
I'm going to assume that we want to use Q pie unless

323
00:17:09.500 --> 00:17:11.910
that's not available and then we want to use an umpire.

324
00:17:11.920 --> 00:17:16.270
But in the end the code is going to be using either one or the other library.

325
00:17:16.339 --> 00:17:19.440
So the trying import occupy is fine.

326
00:17:19.450 --> 00:17:23.880
But let's import it as np importing Numpy S n p is

327
00:17:23.880 --> 00:17:27.319
really common because that prefix is used a lot in your code.

328
00:17:27.329 --> 00:17:30.450
And the difference between two and five letters is going to be considerable

329
00:17:30.460 --> 00:17:33.660
given the number of implications that you have on a typical line.

330
00:17:33.660 --> 00:17:37.810
So let's just keep using that mp and use Q pie as a drop in replacement.

331
00:17:37.820 --> 00:17:39.690
So we're going to try to import Q pie.

332
00:17:40.040 --> 00:17:44.900
And if that fails, they were going to import Numpy both will end up as the mp name.

333
00:17:44.900 --> 00:17:46.620
So once this is done,

334
00:17:46.630 --> 00:17:51.560
we can just say mp dot something and it will use whatever was loaded here.

335
00:17:51.640 --> 00:17:54.600
This immediately shows the reader of what is going on

336
00:17:54.600 --> 00:17:57.160
here and what is the intention behind this code.

337
00:17:57.640 --> 00:17:57.920
Now,

338
00:17:57.920 --> 00:18:01.920
I've already looked ahead a little bit and the kuna Active is only used in

339
00:18:01.920 --> 00:18:06.680
one place that places here in the adam preferences and says if cuba activist false.

340
00:18:06.680 --> 00:18:13.520
Well instead of this we can now just right if np dot name equals numpy this avoids the

341
00:18:13.520 --> 00:18:15.300
whole keeping track of what was loaded and was

342
00:18:15.300 --> 00:18:17.670
not because python already does that for us.

343
00:18:18.340 --> 00:18:21.030
So coupon is a library that you can install.

344
00:18:21.040 --> 00:18:23.440
It doesn't come bundled with blender so and be

345
00:18:23.440 --> 00:18:25.620
made an operator that can download it for us,

346
00:18:25.620 --> 00:18:26.590
which is pretty nice.

347
00:18:26.600 --> 00:18:31.000
But the way he does it not so much from sub process import coal.

348
00:18:31.010 --> 00:18:34.550
I wouldn't do that because then you have coal name that is just in your name,

349
00:18:34.550 --> 00:18:35.350
space there

350
00:18:35.540 --> 00:18:38.700
and you get these kind of calls that called coal and is

351
00:18:38.700 --> 00:18:42.250
not immediately obvious that it is actually calling a sub process.

352
00:18:42.250 --> 00:18:46.480
So I would always say imports of process and that's a process that coal However,

353
00:18:46.480 --> 00:18:49.450
a sub process that call doesn't check any errors.

354
00:18:49.460 --> 00:18:53.060
So it could be completely failing and you wouldn't know.

355
00:18:53.440 --> 00:18:54.360
So instead of this,

356
00:18:54.360 --> 00:18:58.780
use a process of run with check equals true as a parameter then at least it

357
00:18:58.780 --> 00:19:00.510
will stop your pointing code from running any

358
00:19:00.510 --> 00:19:03.830
further when the download or the install fails.

359
00:19:03.840 --> 00:19:06.250
In this case you have a double problem because

360
00:19:06.260 --> 00:19:09.720
you already said cuba actively true before importing QP.

361
00:19:09.730 --> 00:19:13.480
So even when all of this failed input your pin will fail again.

362
00:19:13.490 --> 00:19:17.770
But then you have cute active already set to true and then your state is all messed up.

363
00:19:18.140 --> 00:19:20.450
Let's browse through the code a bit more.

364
00:19:21.240 --> 00:19:24.730
I see a lot of small functions that do something very specific,

365
00:19:24.730 --> 00:19:28.510
which is kind of nice but the naming is a bit strange.

366
00:19:28.520 --> 00:19:29.360
What is big?

367
00:19:29.740 --> 00:19:32.470
What does the neighbor average do, what does it return?

368
00:19:32.470 --> 00:19:35.460
There is no documentation at all about any of the types.

369
00:19:35.460 --> 00:19:39.370
There is no type of notations that explain what is returned or what is expected.

370
00:19:39.380 --> 00:19:43.560
Especially when you're using short variable names here. Like oh I and d

371
00:19:44.280 --> 00:19:45.470
I don't know what's going on

372
00:19:45.750 --> 00:19:47.160
a roll zero

373
00:19:47.740 --> 00:19:48.850
Was a role zero.

374
00:19:49.340 --> 00:19:51.170
Why is it different from a roll one

375
00:19:52.640 --> 00:19:57.220
and why is a role zero Different from ad roll zero here,

376
00:19:57.220 --> 00:20:00.780
if you have a comment that needs to explain what the parameters mean.

377
00:20:00.780 --> 00:20:04.220
Just name the parameters differently instead of SSP

378
00:20:04.230 --> 00:20:06.950
named stories instead of intense named intensity.

379
00:20:07.440 --> 00:20:09.930
So the convolution is an image operation.

380
00:20:10.050 --> 00:20:13.310
And here there is a problem because it doesn't tell us whether

381
00:20:13.310 --> 00:20:17.550
the source image is changed or whether a new images returned.

382
00:20:17.600 --> 00:20:19.790
This is something that permits through this code.

383
00:20:19.800 --> 00:20:21.620
Also this grayscale function,

384
00:20:21.650 --> 00:20:24.110
does it turn the given image into a grayscale image

385
00:20:24.120 --> 00:20:26.850
or does it return a grayscale copy of the image.

386
00:20:27.040 --> 00:20:29.750
This should be documented well because it

387
00:20:29.750 --> 00:20:32.050
really helps you understand what's going on.

388
00:20:32.840 --> 00:20:36.560
So having scrolled down about 1000 lines of code.

389
00:20:36.940 --> 00:20:41.350
We get to these classes which are set classes of image operator generator.

390
00:20:41.740 --> 00:20:45.590
And this is starting to turn into a bit of code smell.

391
00:20:45.600 --> 00:20:48.930
It has one function called generate and then it

392
00:20:48.930 --> 00:20:53.770
sets certain keys in self props to blender properties

393
00:20:54.640 --> 00:20:58.600
and it sets the prefix, it sets info and category

394
00:20:58.810 --> 00:21:01.910
and then it has soft payload which is a lambda function.

395
00:21:01.920 --> 00:21:04.380
I won't even go into a lambda function actually is

396
00:21:04.380 --> 00:21:06.960
I want to know which this image operator generator is.

397
00:21:07.340 --> 00:21:11.450
I found it here in a different file and it's a subplot operator generator.

398
00:21:11.840 --> 00:21:15.220
And it gets somehow a master name which it

399
00:21:15.220 --> 00:21:18.860
passes to begin then it says 49 point equals falls

400
00:21:19.340 --> 00:21:21.860
cause that generate function that we already saw.

401
00:21:22.240 --> 00:21:27.060
Then in the end it sets its own name to image. Ot and then self name.

402
00:21:27.940 --> 00:21:30.550
So it doesn't even

403
00:21:31.640 --> 00:21:32.360
wait. But

404
00:21:32.840 --> 00:21:38.060
here you don't have a name at all. So I don't even know where this name comes from

405
00:21:39.040 --> 00:21:41.220
and then it calls created up which I guess

406
00:21:41.220 --> 00:21:44.510
creates the blender operator and then it says self

407
00:21:44.510 --> 00:21:48.450
dot org dot 1st 99 point equal self force

408
00:21:48.450 --> 00:21:51.160
an empire which was already set to false hair.

409
00:21:53.440 --> 00:21:57.150
I found the operator generator inside the get stop module.

410
00:21:57.160 --> 00:22:00.090
So here we have the begin and it gets the

411
00:22:00.090 --> 00:22:02.840
master name which is then assigned to the parent name.

412
00:22:02.840 --> 00:22:06.670
So apparently the parent is the master. I don't know what that means even

413
00:22:07.240 --> 00:22:11.670
um, it says self payload instead of having a payload function.

414
00:22:12.140 --> 00:22:12.640
Um,

415
00:22:12.650 --> 00:22:15.010
then it's such a bunch of other things to empty but

416
00:22:15.010 --> 00:22:17.660
not the name that is only set in in the end

417
00:22:18.640 --> 00:22:23.950
and there is a creator oB function that dynamically creates a new class.

418
00:22:24.340 --> 00:22:28.270
I think this is clever code but it's a bit too clever.

419
00:22:28.740 --> 00:22:33.040
It is so hard to follow. And especially when you go into a blender

420
00:22:33.240 --> 00:22:35.360
and these operators have been registered

421
00:22:35.840 --> 00:22:39.110
and then you want to search for where that operator was created.

422
00:22:39.110 --> 00:22:40.360
You will never find it.

423
00:22:40.840 --> 00:22:44.110
That naming convention of having category in capitals and then

424
00:22:44.120 --> 00:22:47.260
underscore O T underscore and then the rest of the identifier

425
00:22:47.840 --> 00:22:50.700
that is very useful because that is used all over the place.

426
00:22:50.700 --> 00:22:55.220
If you have Bp dot upstart something that's something you can apply those rules

427
00:22:55.220 --> 00:22:58.210
and then you have the class name given a name of something in blender.

428
00:22:58.210 --> 00:23:02.450
It's pretty easy to find it in the source code and with this structure,

429
00:23:02.940 --> 00:23:04.160
that name is nowhere.

430
00:23:04.170 --> 00:23:06.840
I think the advantage of this code is that

431
00:23:06.840 --> 00:23:09.920
it is pretty easy to add new operators personally.

432
00:23:09.920 --> 00:23:13.560
I would make the code just a little bit larger type of bit more

433
00:23:13.940 --> 00:23:18.040
but then have everything there where it's supposed to be easily findable,

434
00:23:18.040 --> 00:23:20.640
easily understandable how things are created.

435
00:23:20.700 --> 00:23:22.960
Okay, we made it to the end.

436
00:23:22.970 --> 00:23:25.280
I hope you have enjoyed this rising as much as

437
00:23:25.280 --> 00:23:28.770
I have so as a final thought name things well,

438
00:23:28.780 --> 00:23:31.960
so that you don't have to use your brain later on when you're trying to read it,

439
00:23:32.440 --> 00:23:36.930
return early and flip those conditions and see if it makes a difference.

440
00:23:36.970 --> 00:23:38.600
So that's it for this episode.

441
00:23:38.600 --> 00:23:42.360
If you have any questions or comments, leave them below, and I will see you soon.


