WEBVTT

1
00:00:00.740 --> 00:00:04.770
Hello and welcome to another episode of scripting for artists. My name is civilian.

2
00:00:04.770 --> 00:00:08.100
And in this episode we will talk about modal operators.

3
00:00:08.109 --> 00:00:11.110
So the reasons free episodes of scripting for artists

4
00:00:11.110 --> 00:00:13.680
have been part of the open up project.

5
00:00:13.690 --> 00:00:17.110
You can read about this on blended at ERG in the new section.

6
00:00:17.170 --> 00:00:19.510
This open up project was all about providing some

7
00:00:19.510 --> 00:00:23.480
relief during the corona lockdown and slowly but steadily,

8
00:00:23.480 --> 00:00:27.480
at least here in the Netherlands things are opening up a little bit again.

9
00:00:27.490 --> 00:00:29.990
So this means the open up project is also coming to

10
00:00:29.990 --> 00:00:32.860
an end because this is the last episode for now.

11
00:00:32.870 --> 00:00:35.390
I wanted to do something a little bit more complex.

12
00:00:35.400 --> 00:00:37.580
So that is why we're looking at model operators.

13
00:00:37.580 --> 00:00:40.250
They are a bit more complex but there is a very powerful and

14
00:00:40.250 --> 00:00:43.450
they opened up a whole range of new possibilities for your adults.

15
00:00:44.440 --> 00:00:49.960
So first of all, what is Model? I looked it up on Dr go and it gives me some information.

16
00:00:49.960 --> 00:00:54.270
Some useful links. Well, you apparently Model is also kind of fabric.

17
00:00:54.280 --> 00:00:55.730
I'm not that interested in it.

18
00:00:55.740 --> 00:00:59.850
But the second link was to the Merriam Webster dictionary and it has

19
00:00:59.850 --> 00:01:04.620
all kinds of definitions from Model for example of or relating to modality.

20
00:01:04.620 --> 00:01:06.060
So let's take a look at that.

21
00:01:06.640 --> 00:01:10.480
A modality. The quality of state of being model. Yeah, well thank you very much.

22
00:01:10.490 --> 00:01:14.450
But it also says the classification of logical propositions

23
00:01:14.460 --> 00:01:17.130
according to their asserting or denying the possibility,

24
00:01:17.130 --> 00:01:20.760
impossibility, contingency or necessity of their content.

25
00:01:21.840 --> 00:01:25.550
I still don't quite get it. But it has something to do with logic.

26
00:01:25.560 --> 00:01:27.690
So let's take a look at another dictionary in this

27
00:01:27.690 --> 00:01:31.490
case the Oxford learner's dictionary and it says for modality.

28
00:01:31.500 --> 00:01:36.150
The particular way in which something exists is experienced or is done.

29
00:01:36.540 --> 00:01:41.390
And this starts to look more familiar. If you think about edit motor object mode

30
00:01:41.790 --> 00:01:45.960
it is a particular way in which blender exists at that moment.

31
00:01:46.440 --> 00:01:47.460
For example pressing G.

32
00:01:47.460 --> 00:01:51.600
In edit mode will move a vertex whereas an object mode it will move an

33
00:01:51.600 --> 00:01:55.500
object so things can have different meanings depending

34
00:01:55.500 --> 00:01:57.140
on the mode that blender is in.

35
00:01:57.420 --> 00:01:59.530
And this is also what a model operator does.

36
00:01:59.540 --> 00:02:04.260
It basically adds another mode to blender which is then defined by your operator.

37
00:02:04.340 --> 00:02:07.900
It can take over your complete blender interface and swallow

38
00:02:07.900 --> 00:02:10.509
up all the user input events that there are.

39
00:02:10.520 --> 00:02:13.320
Or it can just respond to one or two things and then

40
00:02:13.320 --> 00:02:16.140
pass on the rest of blender so that it behaves it's normal.

41
00:02:16.160 --> 00:02:19.350
Let's see what that looks like in code so that things become

42
00:02:19.350 --> 00:02:22.410
a bit more concrete to demonstrate how a model operator works.

43
00:02:22.410 --> 00:02:24.460
Have made a small little add on.

44
00:02:24.540 --> 00:02:27.710
It's just a silly little thing and the ingredients will look pretty familiar.

45
00:02:27.710 --> 00:02:29.900
But now it has a little info. It imports.

46
00:02:29.900 --> 00:02:34.050
Beep I it has the operator and then it registered and unregistered when needed.

47
00:02:35.240 --> 00:02:38.220
So of course the interesting bit is inside the operator.

48
00:02:38.220 --> 00:02:42.320
It starts in the same way as you're used to with bill I. D. Name br label.

49
00:02:42.320 --> 00:02:45.460
The naming is consistent with the I. D. Name your idea.

50
00:02:46.040 --> 00:02:49.160
But instead of an executed has a model and an invoke

51
00:02:49.540 --> 00:02:51.770
now mind you it could also have an execute function.

52
00:02:51.770 --> 00:02:54.940
It is not the lack of execute function that makes this model.

53
00:02:55.410 --> 00:02:57.600
The invoke function is called the blender whenever

54
00:02:57.600 --> 00:02:59.810
the operator is run from the user interface.

55
00:02:59.810 --> 00:03:03.470
So from a hotkey or a menu item or a button on a panel

56
00:03:03.650 --> 00:03:06.730
and this is the function where you would start the model operator.

57
00:03:06.830 --> 00:03:08.410
This invoke function does two things.

58
00:03:08.410 --> 00:03:11.740
It tells blenders Window manager that we should receive events.

59
00:03:11.940 --> 00:03:16.650
And then by returning running model it was blended that we want to run model

60
00:03:17.040 --> 00:03:19.680
and that's the basic of getting a model operator.

61
00:03:19.690 --> 00:03:23.870
Now when there is a window manager event like a mouse move click key,

62
00:03:23.870 --> 00:03:25.930
press anything like that.

63
00:03:25.940 --> 00:03:28.770
Our model function will be called and of course it gets the

64
00:03:28.770 --> 00:03:32.960
context but it will also get information about which event triggered it.

65
00:03:33.340 --> 00:03:37.320
So these events objects are documented in the python api reference that if you

66
00:03:37.320 --> 00:03:41.160
want to find that for the version of blender using at the moment just go

67
00:03:41.160 --> 00:03:45.360
to help and then python api reference and that will bring you here you search

68
00:03:45.360 --> 00:03:49.120
for event and then you find to be part of types of event structure.

69
00:03:49.130 --> 00:03:51.500
This has all kinds of useful properties that are set

70
00:03:51.500 --> 00:03:53.760
by blender before it sends the event to our code.

71
00:03:54.040 --> 00:03:57.190
So from movement of the mouth we have a few different options.

72
00:03:57.190 --> 00:03:59.000
We have mouths previous X.

73
00:03:59.010 --> 00:04:02.640
So as the previous location of the mouth combined that with mouse X.

74
00:04:02.650 --> 00:04:04.390
And then you get a sense of the motion

75
00:04:04.390 --> 00:04:07.330
that somebody did rather than the absolute position.

76
00:04:07.340 --> 00:04:09.230
There's the mouth region X,

77
00:04:09.230 --> 00:04:13.590
which is the region relative horizontal location of the mouse and there's mouth X.

78
00:04:13.590 --> 00:04:16.660
Which is the window relative horizontal location of the mouse.

79
00:04:17.339 --> 00:04:20.130
The most important property here is the type.

80
00:04:20.140 --> 00:04:22.250
This tells us what kind of event this is in

81
00:04:22.250 --> 00:04:24.480
the first place is the left miles is middle miles,

82
00:04:24.480 --> 00:04:27.240
right mouse keyboard, trackpad events here.

83
00:04:27.240 --> 00:04:28.380
Also the timer event.

84
00:04:28.380 --> 00:04:32.240
This one can be very important if you want to do something every once in a while.

85
00:04:32.250 --> 00:04:36.390
So that could be every second, every millisecond every 30 seconds.

86
00:04:36.390 --> 00:04:37.350
Just what you need

87
00:04:38.040 --> 00:04:42.300
back to our code. I want to print some different things based on the type of the event.

88
00:04:42.310 --> 00:04:48.370
So if event type is mouse move, then I just print mouse move with the mouse, X and

89
00:04:48.540 --> 00:04:53.540
Y coordinates. If the event type is left mouse, I say left click at X and Y.

90
00:04:53.550 --> 00:04:56.800
Else if the event type is in this set and this is a

91
00:04:56.800 --> 00:05:00.330
quick and easy way to just check for a bunch of different values.

92
00:05:00.340 --> 00:05:04.230
So if it's either right mouse or escape, I just say right click stopping,

93
00:05:04.240 --> 00:05:05.540
it may also be escape.

94
00:05:05.550 --> 00:05:07.100
I don't care. This is fine.

95
00:05:07.110 --> 00:05:08.440
Then it says return finished,

96
00:05:08.440 --> 00:05:11.370
which tells blender that we want to stop the model operators.

97
00:05:11.370 --> 00:05:14.630
So at this time it will no longer be receiving any events.

98
00:05:14.640 --> 00:05:16.220
If that does not happen,

99
00:05:16.230 --> 00:05:19.600
it returns running model just like the invoke function did

100
00:05:19.610 --> 00:05:22.160
to indicate that it should still be kept running.

101
00:05:22.840 --> 00:05:25.020
Let's see what we can get into print.

102
00:05:25.030 --> 00:05:29.240
Have installed the add on and enabled it in the user preferences as you can see.

103
00:05:29.250 --> 00:05:32.580
So here we are in blender and I've also put my terminal

104
00:05:32.590 --> 00:05:35.240
on the screen so you can see what it prints Now.

105
00:05:35.250 --> 00:05:37.360
This is still without are operated running.

106
00:05:37.360 --> 00:05:41.220
You can see that the menu items and everything is responding to our clicks.

107
00:05:41.230 --> 00:05:43.030
This problem normally responds.

108
00:05:43.040 --> 00:05:47.690
I pressed F3 to go through the search box and then I looked for the silly example,

109
00:05:47.700 --> 00:05:50.060
I press enter so you can see that it already

110
00:05:50.060 --> 00:05:53.160
received its first mouth move event in the terminal.

111
00:05:53.640 --> 00:05:55.670
And when I move the mouse it keeps going.

112
00:05:55.680 --> 00:05:57.540
Remember the difference between the window

113
00:05:57.540 --> 00:06:00.130
relative and the region relative coordinates.

114
00:06:00.140 --> 00:06:02.940
Three D view port is a region. The outline is a region.

115
00:06:02.940 --> 00:06:04.530
The properties panel is a region.

116
00:06:04.540 --> 00:06:08.490
So if you want to do something that is relative to the three D view port.

117
00:06:08.500 --> 00:06:11.660
The region relative coordinates will probably be what you need.

118
00:06:11.840 --> 00:06:14.400
Now I'm printing the window relative coordinates.

119
00:06:14.400 --> 00:06:16.500
So that means that so that means that

120
00:06:16.510 --> 00:06:20.580
in the bottom right corner the coordinates are 00

121
00:06:20.590 --> 00:06:25.360
and in the top right we get to what is almost the resolution of my desktop.

122
00:06:25.840 --> 00:06:28.940
One thing you may have noticed is that blender doesn't respond anymore

123
00:06:28.940 --> 00:06:32.500
to these mouths over is because we swallowed up all the events.

124
00:06:32.510 --> 00:06:38.760
Also when a middle click and drag to change the view port, it doesn't do anything

125
00:06:39.240 --> 00:06:43.560
but it does show a left click and right click and then it stops and now

126
00:06:44.740 --> 00:06:49.700
it's back to normal Again, our operator has stopped and blender responds as usual.

127
00:06:49.710 --> 00:06:54.460
One thing you might notice is that one click caused to print statements

128
00:06:55.040 --> 00:06:57.610
so the print isn't exactly correct.

129
00:06:57.620 --> 00:06:59.150
It's not a left click,

130
00:06:59.160 --> 00:07:04.130
it's the mouse down and then the mouse up event that you receive again the python,

131
00:07:04.130 --> 00:07:06.190
api documentation to the rescue.

132
00:07:06.200 --> 00:07:08.560
There is a value property that will tell you more

133
00:07:08.560 --> 00:07:10.850
about the type of event that you're looking at.

134
00:07:10.860 --> 00:07:12.760
Let's add this to our print statement

135
00:07:13.340 --> 00:07:18.300
who are in the code. We know it's about the left mouse so we can leave the left in there.

136
00:07:18.300 --> 00:07:23.450
But here we just do event value at a certain location.

137
00:07:23.940 --> 00:07:26.760
And then instead of right click, let's just say

138
00:07:27.140 --> 00:07:30.460
event type, event value

139
00:07:30.940 --> 00:07:32.650
and we'll still be stopping there.

140
00:07:34.740 --> 00:07:35.850
Reload the script.

141
00:07:37.140 --> 00:07:38.100
Rerun it.

142
00:07:38.410 --> 00:07:39.960
The mouse move hasn't changed.

143
00:07:40.840 --> 00:07:43.150
But you can see there is a left press and left

144
00:07:43.150 --> 00:07:46.860
release and then a right mouse press we can run it again

145
00:07:47.540 --> 00:07:49.340
like press left release

146
00:07:49.460 --> 00:07:53.270
and from your press escape we can escape, press and then it's over.

147
00:07:53.280 --> 00:07:55.790
So that's the basics of modal operators.

148
00:07:55.790 --> 00:07:58.160
Let's start looking at something a bit more useful.

149
00:07:58.170 --> 00:08:01.000
We're going to follow what is pretty much in the template.

150
00:08:01.000 --> 00:08:04.360
So if you go to the scripting tab in blender and then templates python,

151
00:08:04.370 --> 00:08:07.760
you will find a bunch of examples for modal operators.

152
00:08:07.940 --> 00:08:11.010
So we're going to do is follow the view through the operator.

153
00:08:11.010 --> 00:08:14.670
But I'm going to do things in a slightly different way than is in this code.

154
00:08:14.680 --> 00:08:18.350
And then you can just make up your mind about which approach you like more

155
00:08:18.740 --> 00:08:21.300
First a little demo of what it does.

156
00:08:21.310 --> 00:08:25.540
I've run the code in the template and then press F three simple view operator.

157
00:08:25.550 --> 00:08:26.090
You presenter?

158
00:08:26.090 --> 00:08:27.970
It starts in the top left corner,

159
00:08:27.970 --> 00:08:31.260
you can see the offset which is now moving if I

160
00:08:31.260 --> 00:08:34.429
move the mouse in the X direction of the window,

161
00:08:34.440 --> 00:08:36.440
it also moves the view port in the X.

162
00:08:36.440 --> 00:08:37.549
Direction of the world.

163
00:08:37.840 --> 00:08:39.460
And the same for why?

164
00:08:40.539 --> 00:08:43.480
Now if I rotate then you can see the difference

165
00:08:44.740 --> 00:08:46.510
are moving the X direction and you can see

166
00:08:46.510 --> 00:08:49.460
that the movement is still in the world X direction

167
00:08:49.670 --> 00:08:51.550
and the same for the Y direction.

168
00:08:53.240 --> 00:08:57.550
If a right click we end up where we started off so that's a council

169
00:08:58.140 --> 00:09:00.160
and of course left click is confirmed.

170
00:09:00.540 --> 00:09:04.920
So let's look at the invoke function. It does a bit more than we did in our code.

171
00:09:04.930 --> 00:09:07.720
Of course, this only works in the three D view Putin.

172
00:09:07.720 --> 00:09:11.340
That's the first thing that's being checked on if contacts of space data,

173
00:09:11.340 --> 00:09:12.920
that type equals for you three D.

174
00:09:12.920 --> 00:09:13.930
Then the work is done.

175
00:09:13.940 --> 00:09:18.370
Otherwise a warning is shown and the operator is canceled personally.

176
00:09:18.380 --> 00:09:20.060
I would flip this.

177
00:09:21.440 --> 00:09:21.640
Yeah,

178
00:09:22.040 --> 00:09:22.240
yeah.

179
00:09:22.640 --> 00:09:25.060
Into if it's not three D.

180
00:09:25.840 --> 00:09:29.950
Give a warning stop and then invent the whole thing.

181
00:09:30.940 --> 00:09:33.470
So now that we know it's a three D view port,

182
00:09:33.480 --> 00:09:37.750
we can access context of space data and call it the three D.

183
00:09:37.760 --> 00:09:39.660
And then we can get the three D. Region.

184
00:09:40.040 --> 00:09:43.350
So a space is made up of regions and in the three D view

185
00:09:43.350 --> 00:09:46.690
port case a region is the three D view but also a header,

186
00:09:46.690 --> 00:09:49.090
maybe a full term, maybe some panels on the sides.

187
00:09:49.100 --> 00:09:50.780
And we have to have the three D view port.

188
00:09:50.780 --> 00:09:53.500
If you want to change its camera around then changing the three

189
00:09:53.500 --> 00:09:56.950
D view port camera only works if you're actually looking through it,

190
00:09:56.960 --> 00:09:58.760
if you're looking through the same camera,

191
00:09:59.040 --> 00:10:00.940
this whole thing has to do something different.

192
00:10:00.940 --> 00:10:04.150
It would have to move the same camera around to fix that it

193
00:10:04.150 --> 00:10:08.890
just switches it over to perspective you and then finally we have to store

194
00:10:08.900 --> 00:10:12.940
the initial location of the mouse so that we can track the motion

195
00:10:12.940 --> 00:10:17.250
of the mouse relative to the point where it was when this operator started

196
00:10:17.460 --> 00:10:21.780
and then we have to remember the original location of the view port camera so

197
00:10:21.780 --> 00:10:25.370
that we can restore that when we right click and it has to be cancelled.

198
00:10:25.380 --> 00:10:29.950
And then finally we have the known bit which is registering this operator as

199
00:10:29.950 --> 00:10:34.700
a model operator and then returning running model as a side note in python,

200
00:10:34.710 --> 00:10:38.090
it's possible to just write stuff to self dot something.

201
00:10:38.100 --> 00:10:42.860
You don't have to declare it as a property, you can just add a new property like this.

202
00:10:43.740 --> 00:10:47.680
So these kind of things would not be stored by blender if you do this on an object.

203
00:10:47.690 --> 00:10:50.110
So it's very limited in its use but for

204
00:10:50.110 --> 00:10:53.370
storing temporary data on an operator like this,

205
00:10:53.380 --> 00:10:54.150
it's fine.

206
00:10:54.540 --> 00:10:56.650
Now let's look at the model function and the

207
00:10:56.650 --> 00:10:58.660
structure of this is pretty much the same as

208
00:10:58.660 --> 00:11:03.470
we did before we look at different event types and then execute a little bit of code.

209
00:11:03.480 --> 00:11:05.510
We can change some things around in this code

210
00:11:05.510 --> 00:11:07.810
to make it a little bit easier to understand.

211
00:11:07.820 --> 00:11:12.750
This bit is only used down here, so let's move it there.

212
00:11:13.040 --> 00:11:14.480
It's the same thing as before.

213
00:11:14.490 --> 00:11:18.310
It just gets the three D view port region so that the view

214
00:11:18.310 --> 00:11:22.240
location that is the camera that is used for the view port,

215
00:11:22.250 --> 00:11:24.380
The location of it is set back to the

216
00:11:24.390 --> 00:11:27.620
initial location when we press right mouse or escape.

217
00:11:27.630 --> 00:11:29.420
This causes it to cancel it,

218
00:11:29.420 --> 00:11:32.240
then clears the header text that is set while

219
00:11:32.240 --> 00:11:35.150
we're moving the mouse and then it returns council.

220
00:11:35.150 --> 00:11:39.050
So that tells blender that this operator is no longer supposed to be running

221
00:11:39.350 --> 00:11:41.160
in the case of the left mouse.

222
00:11:41.240 --> 00:11:45.180
All that's done is that the offset taxes removed from the header.

223
00:11:45.220 --> 00:11:47.880
And then blender is told that we're finished

224
00:11:47.890 --> 00:11:51.750
because during the interaction during the mouse move we're

225
00:11:51.750 --> 00:11:55.050
already changing the view port confirming doesn't need to

226
00:11:55.050 --> 00:11:57.560
do anything because the view port already changed.

227
00:11:57.580 --> 00:11:59.860
And then finally we get to the interesting bit.

228
00:11:59.940 --> 00:12:02.290
What should happen when the mouse is moving

229
00:12:02.540 --> 00:12:04.590
this line is already doing a lot.

230
00:12:04.600 --> 00:12:08.320
So let's split that up into a few easily digested parts.

231
00:12:08.330 --> 00:12:12.720
First of all it's converting event of mouse X and event miles wide to

232
00:12:12.720 --> 00:12:16.500
a vector so that we can do some three D math with it.

233
00:12:16.660 --> 00:12:21.210
Of course the camera location in the three D view port Is a 3D position.

234
00:12:21.210 --> 00:12:24.140
So there's a vector and converting things to a vector.

235
00:12:24.140 --> 00:12:26.850
Makes all those computations a little bit easier.

236
00:12:27.740 --> 00:12:27.940
Yeah

237
00:12:28.740 --> 00:12:30.260
so we have a mass position.

238
00:12:32.740 --> 00:12:33.060
Okay.

239
00:12:34.840 --> 00:12:35.040
Yeah.

240
00:12:35.740 --> 00:12:35.950
Okay.

241
00:12:37.840 --> 00:12:41.350
Which is the vector consisting of mouse X miles y

242
00:12:41.360 --> 00:12:44.460
and zero because we don't have a three dimensional mouse.

243
00:12:45.640 --> 00:12:45.880
Yeah

244
00:12:46.840 --> 00:12:52.980
the amount that the mouse moved by is self that initial mouse minus mouse position.

245
00:12:52.990 --> 00:12:55.950
So that is the difference between the starting position of

246
00:12:55.960 --> 00:12:58.060
the mouse and the current position of the mouse.

247
00:13:00.330 --> 00:13:05.050
And then finally we scale the mouse movement because otherwise you would move

248
00:13:05.060 --> 00:13:08.740
at around one blender unit for every pixel that you move your mouse.

249
00:13:08.750 --> 00:13:11.770
So how do you get to this number? Well that's just trial and error.

250
00:13:11.780 --> 00:13:16.490
You first tried without the scaling and then you see that things move way too quickly

251
00:13:16.500 --> 00:13:19.960
and then he starts killing it down and you get to something that works for you

252
00:13:20.340 --> 00:13:22.560
finally self executed called.

253
00:13:22.840 --> 00:13:25.620
Normally blender would do this for us and it will

254
00:13:25.620 --> 00:13:28.820
still do this when we call this operator from python.

255
00:13:28.830 --> 00:13:33.810
However, there is nothing stopping us from calling execute ourselves as well.

256
00:13:33.960 --> 00:13:37.660
We'll take a look at what execute is doing exactly in a moment

257
00:13:37.940 --> 00:13:41.750
and then finally the header taxes said to offset with the X,

258
00:13:41.750 --> 00:13:44.960
y and z coordinates of self offset.

259
00:13:45.640 --> 00:13:48.090
This notation is called percent formatting.

260
00:13:48.100 --> 00:13:51.750
It consists of a format string than a percent and then one

261
00:13:51.750 --> 00:13:54.930
or more things that are supposed to go into the format string.

262
00:13:54.940 --> 00:13:58.920
So in this case our format string has three fields they start with a percent.

263
00:13:58.930 --> 00:14:02.170
The end with an f to indicate a floating point and 30.0.4 in

264
00:14:02.170 --> 00:14:05.350
there means that we want to have four decimals in the number.

265
00:14:05.740 --> 00:14:08.620
So let's take a look at that offset and the execute

266
00:14:08.620 --> 00:14:11.750
function because those are the final parts we haven't seen yet.

267
00:14:11.760 --> 00:14:14.910
The offset is a property as we've seen before.

268
00:14:14.920 --> 00:14:18.420
It's a float vector property and this is imported here

269
00:14:18.430 --> 00:14:21.200
as from b point props import flood vector property.

270
00:14:21.210 --> 00:14:25.750
So it's just a shorter version of writing be pie dot props dot flood vector property.

271
00:14:25.940 --> 00:14:28.410
So the name is offset the sizes three,

272
00:14:28.420 --> 00:14:32.400
which means that we have three values in our float vector.

273
00:14:32.410 --> 00:14:36.560
And this is because the view port camera position is of course three dimensional.

274
00:14:36.740 --> 00:14:39.490
And then finally we look at the execute function again,

275
00:14:39.500 --> 00:14:42.090
it gets the 3D region from the context.

276
00:14:42.100 --> 00:14:44.180
What's going on here is a little bit confusing

277
00:14:44.180 --> 00:14:47.740
because the property type is float vector property,

278
00:14:47.900 --> 00:14:52.550
but the value that it produces is not a vector, it is something else.

279
00:14:52.640 --> 00:14:54.870
So that means that if we want to do some vector math,

280
00:14:54.870 --> 00:14:56.810
you first have to convert it to a vector.

281
00:14:56.820 --> 00:14:58.260
So that's what's happening here.

282
00:14:58.270 --> 00:15:00.610
It's converted to a vector and then it's added

283
00:15:00.610 --> 00:15:02.970
to the initial location of the view port camera.

284
00:15:02.980 --> 00:15:05.360
And that new location is then assigned to the view

285
00:15:05.360 --> 00:15:08.500
location property of the three D view port region.

286
00:15:08.510 --> 00:15:12.730
So as a quick overview in the invoke, we did some preparatory work,

287
00:15:12.740 --> 00:15:15.560
we registered that this is a model operator.

288
00:15:15.570 --> 00:15:17.920
Then in the model function when the mouse moved,

289
00:15:17.920 --> 00:15:21.060
we computed an offset and then in the execute function,

290
00:15:21.070 --> 00:15:24.010
we add that offset to the initial location of the view

291
00:15:24.010 --> 00:15:27.350
port camera to compute the new view port camera location.

292
00:15:27.740 --> 00:15:32.140
Now, I wanted to show you how we could call it, execute function from python.

293
00:15:32.150 --> 00:15:35.750
But the problem is that in the console you can see that

294
00:15:35.760 --> 00:15:38.890
the operator is there and that we can even pass an offset.

295
00:15:38.900 --> 00:15:42.560
But if you try to use it, let's see what happens

296
00:15:42.940 --> 00:15:46.140
if you do it like this, then you get an error.

297
00:15:46.160 --> 00:15:50.290
That space console object doesn't have an attribute region three D.

298
00:15:50.300 --> 00:15:53.160
And that is because currently when you run it here,

299
00:15:53.740 --> 00:15:56.600
the context is set to the console.

300
00:15:56.610 --> 00:16:00.360
So context of space data is a space console and

301
00:16:00.360 --> 00:16:02.760
other space few three D in the error message.

302
00:16:02.760 --> 00:16:08.370
You can see that the execute function is actually corporate blender 1 18 is the

303
00:16:08.370 --> 00:16:13.860
problematic one and that is indeed getting few three D dot region three D.

304
00:16:13.940 --> 00:16:18.290
A console doesn't have original 3D property. So that is the issue here.

305
00:16:18.300 --> 00:16:22.870
But it does show the idea behind it that you can have an execute function on there,

306
00:16:22.870 --> 00:16:27.560
that you can call from Python and then invoke to get something that is interactive.

307
00:16:28.040 --> 00:16:32.740
As I said in the beginning, a model operator takes over all of blender

308
00:16:32.940 --> 00:16:36.360
but it's also possible to do that selectively whether

309
00:16:36.360 --> 00:16:39.020
an event should be passed through to blender itself

310
00:16:39.030 --> 00:16:41.540
or should be used by the modal operator that's

311
00:16:41.540 --> 00:16:44.570
determined by the return value of your model function.

312
00:16:44.740 --> 00:16:49.470
This operator now only responds to mouse motion and we cannot zoom in or out.

313
00:16:49.740 --> 00:16:53.080
So let's say we want to allow the scroll wheel up

314
00:16:53.090 --> 00:16:56.170
and scroll wheel down to be passed through to blender so

315
00:16:56.170 --> 00:16:59.280
that blender can take care of the zooming for us and

316
00:16:59.280 --> 00:17:02.280
then all the other events that they're still gobbled up.

317
00:17:02.280 --> 00:17:05.920
So you can't do shift a to get the AD menu for example,

318
00:17:05.920 --> 00:17:09.450
while you're also moving around, this is quite simple to do

319
00:17:09.640 --> 00:17:13.770
first. We have to figure out what event of type is that belongs to the scroll wheel.

320
00:17:13.839 --> 00:17:15.760
So either you look that up in the python,

321
00:17:15.760 --> 00:17:18.910
api reference or you do like me and you just added print

322
00:17:18.910 --> 00:17:22.630
statement that prints out all the event of types that you see.

323
00:17:22.640 --> 00:17:26.930
So by that you can figure out that it will up mouse and well down mouse.

324
00:17:26.930 --> 00:17:28.720
Those are the events were interested in.

325
00:17:28.730 --> 00:17:31.900
Now if the event is of any of these two types,

326
00:17:31.910 --> 00:17:34.740
we can just return paths for this tells blender.

327
00:17:34.750 --> 00:17:36.700
Just use the event is normal.

328
00:17:36.710 --> 00:17:40.300
This we could also do for the mouse move we could do also about

329
00:17:40.300 --> 00:17:45.080
default and then the model operator would be more like an addition to blenders,

330
00:17:45.080 --> 00:17:46.170
regular behavior

331
00:17:46.440 --> 00:17:49.290
rather than taking over all of the user interface.

332
00:17:49.300 --> 00:17:52.740
And this is up to you to determine what your adult should do.

333
00:17:52.750 --> 00:17:55.090
An example of passing through all the events you

334
00:17:55.090 --> 00:17:58.830
can find in the timer example also in templates,

335
00:17:58.830 --> 00:18:00.930
python and than operator.

336
00:18:00.930 --> 00:18:05.140
Model timer using a timer is basically the same as you've seen before,

337
00:18:05.140 --> 00:18:09.880
is just adding yet another registration function and of course when you stop,

338
00:18:09.880 --> 00:18:13.610
you also have to unregistered your timer this time it's the execute

339
00:18:13.610 --> 00:18:17.380
function that returns running model So you can start a model operator

340
00:18:17.380 --> 00:18:21.450
not only from an invoke but also from an execute and here

341
00:18:21.450 --> 00:18:25.690
you see self timer equals window manager of the event timer.

342
00:18:25.700 --> 00:18:26.170
Ad,

343
00:18:26.840 --> 00:18:29.620
this is the number of seconds between timer events that

344
00:18:29.620 --> 00:18:31.530
you want to have and you have to pass the

345
00:18:31.530 --> 00:18:34.320
window so that it knows which window your operator belongs

346
00:18:34.320 --> 00:18:37.960
to and then model handler ad and return running model.

347
00:18:37.970 --> 00:18:40.130
And then when you want to cancel your timer,

348
00:18:40.140 --> 00:18:43.140
you have to tell the Window manager instead of event timer.

349
00:18:43.140 --> 00:18:48.240
Ad, you say event timer removed with the thing that you got from event timer.

350
00:18:48.240 --> 00:18:51.210
Ad and in your model function you will get an event with

351
00:18:51.210 --> 00:18:54.060
typist timer and there you can do all kinds of stuff.

352
00:18:54.070 --> 00:18:57.830
We can see here in the model function is that by default it returns passed through.

353
00:18:57.840 --> 00:19:01.140
So this does not get in the way of your blender usage,

354
00:19:01.150 --> 00:19:05.660
except that it changes the theme all the time, so it might get in the way after all.

355
00:19:06.040 --> 00:19:09.220
So this is it for this episode of scripting for artists.

356
00:19:09.230 --> 00:19:12.660
If you have any questions or remarks, please leave a comment below.

357
00:19:12.670 --> 00:19:16.390
If you want to get more help or you want to just talk about

358
00:19:16.390 --> 00:19:20.940
what are good approaches when it comes to add ons and python and scripting

359
00:19:20.950 --> 00:19:26.090
pop over to blender dot chat is the official blender chat platform and there

360
00:19:26.090 --> 00:19:29.270
is the python channel where you can ask all these kind of questions,

361
00:19:29.270 --> 00:19:31.560
as many people helping each other out over there.

362
00:19:31.840 --> 00:19:35.050
In any case, this is it for now, See you later.


