math_vis: remove use of register_module
[blender-addons.git] / netrender / ui.py
blob7f65163f497143910b60814bb8557dfe6fd273f2
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 import bpy
20 import os
21 import time
23 import netrender
25 from netrender.utils import *
27 from bpy.props import PointerProperty, StringProperty, BoolProperty, EnumProperty, IntProperty, CollectionProperty
29 VERSION = b"0.5"
31 PATH_PREFIX = "/tmp/"
33 LAST_ADDRESS_TEST = 0
34 ADDRESS_TEST_TIMEOUT = 30
36 def base_poll(cls, context):
37 rd = context.scene.render
38 return (rd.use_game_engine==False) and (rd.engine in cls.COMPAT_ENGINES)
41 def init_file():
42 if netrender.init_file != bpy.data.filepath:
43 netrender.init_file = bpy.data.filepath
44 netrender.init_data = True
45 netrender.valid_address = False
47 def init_data(netsettings):
48 init_file()
50 if netrender.init_data:
51 netrender.init_data = False
53 netsettings.active_slave_index = 0
54 while(len(netsettings.slaves) > 0):
55 netsettings.slaves.remove(0)
57 netsettings.active_blacklisted_slave_index = 0
58 while(len(netsettings.slaves_blacklist) > 0):
59 netsettings.slaves_blacklist.remove(0)
61 netsettings.active_job_index = 0
62 while(len(netsettings.jobs) > 0):
63 netsettings.jobs.remove(0)
65 def verify_address(netsettings, force=False):
66 global LAST_ADDRESS_TEST
67 init_file()
69 if force or LAST_ADDRESS_TEST + ADDRESS_TEST_TIMEOUT < time.time():
70 LAST_ADDRESS_TEST = time.time()
72 try:
73 conn = clientConnection(netsettings, scan = False, timeout = 1)
74 except:
75 conn = None
77 if conn:
78 netrender.valid_address = True
79 conn.close()
80 else:
81 netrender.valid_address = False
83 return netrender.valid_address
85 class NeedValidAddress():
86 @classmethod
87 def poll(cls, context):
88 return super().poll(context) and verify_address(context.scene.network_render)
90 class NetRenderButtonsPanel():
91 bl_space_type = "PROPERTIES"
92 bl_region_type = "WINDOW"
93 bl_context = "render"
94 # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
96 @classmethod
97 def poll(cls, context):
98 rd = context.scene.render
99 return rd.engine == 'NET_RENDER' and rd.use_game_engine == False
101 # Setting panel, use in the scene for now.
102 class RENDER_PT_network_settings(NetRenderButtonsPanel, bpy.types.Panel):
103 bl_label = "Network Settings"
104 COMPAT_ENGINES = {'NET_RENDER'}
106 @classmethod
107 def poll(cls, context):
108 return super().poll(context)
110 def draw(self, context):
111 layout = self.layout
113 netsettings = context.scene.network_render
115 verify_address(netsettings)
117 layout.prop(netsettings, "mode", expand=True)
119 if netsettings.mode in {'RENDER_MASTER', 'RENDER_SLAVE'}:
120 layout.operator("render.netclientstart", icon='PLAY')
122 layout.prop(netsettings, "path")
124 row = layout.row()
126 split = layout.split(percentage=0.5)
128 col = split.column()
129 col.prop(netsettings, "server_address", text="Address")
131 col = split.column()
132 row = col.row()
133 row.prop(netsettings, "server_port", text="Port")
134 row.prop(netsettings, "use_ssl", text="SSL")
136 if netsettings.mode != "RENDER_MASTER":
137 layout.operator("render.netclientscan", icon='FILE_REFRESH', text="")
139 if not netrender.valid_address:
140 layout.label(text="No master at specified address")
143 if netsettings.use_ssl and netsettings.mode == "RENDER_MASTER":
144 layout.prop(netsettings, "cert_path", text="Certificate")
145 layout.prop(netsettings, "key_path", text="Key")
147 layout.operator("render.netclientweb", icon='QUESTION')
151 class RENDER_PT_network_slave_settings(NetRenderButtonsPanel, bpy.types.Panel):
152 bl_label = "Slave Settings"
153 COMPAT_ENGINES = {'NET_RENDER'}
155 @classmethod
156 def poll(cls, context):
157 scene = context.scene
158 return super().poll(context) and scene.network_render.mode == "RENDER_SLAVE"
160 def draw(self, context):
161 layout = self.layout
163 rd = context.scene.render
164 netsettings = context.scene.network_render
166 layout.prop(netsettings, "slave_tags", text="Tags")
167 layout.prop(netsettings, "slave_render")
168 layout.prop(netsettings, "slave_bake")
169 layout.prop(netsettings, "use_slave_clear")
170 layout.prop(netsettings, "use_slave_thumb")
171 layout.prop(netsettings, "use_slave_output_log")
172 layout.label(text="Threads:")
173 layout.prop(rd, "threads_mode", expand=True)
175 col = layout.column()
176 col.enabled = rd.threads_mode == 'FIXED'
177 col.prop(rd, "threads")
179 class RENDER_PT_network_master_settings(NetRenderButtonsPanel, bpy.types.Panel):
180 bl_label = "Master Settings"
181 COMPAT_ENGINES = {'NET_RENDER'}
183 @classmethod
184 def poll(cls, context):
185 scene = context.scene
186 return super().poll(context) and scene.network_render.mode == "RENDER_MASTER"
188 def draw(self, context):
189 layout = self.layout
191 netsettings = context.scene.network_render
193 layout.prop(netsettings, "use_master_broadcast")
194 layout.prop(netsettings, "use_master_force_upload")
195 layout.prop(netsettings, "use_master_clear")
197 class RENDER_PT_network_job(NetRenderButtonsPanel, bpy.types.Panel):
198 bl_label = "Job Settings"
199 COMPAT_ENGINES = {'NET_RENDER'}
201 @classmethod
202 def poll(cls, context):
203 scene = context.scene
204 return super().poll(context) and scene.network_render.mode == "RENDER_CLIENT"
206 def draw(self, context):
207 layout = self.layout
209 netsettings = context.scene.network_render
211 verify_address(netsettings)
213 if netsettings.server_address != "[default]":
214 layout.operator("render.netclientanim", icon='RENDER_ANIMATION')
215 layout.operator("render.netclientsend", icon='FILE_BLEND')
216 layout.operator("render.netclientsendbake", icon='PHYSICS')
217 layout.operator("render.netclientsendframe", icon='RENDER_STILL')
218 if netsettings.job_id:
219 row = layout.row()
220 row.operator("render.render", text="Get Image", icon='RENDER_STILL')
221 row.operator("render.render", text="Get Animation", icon='RENDER_ANIMATION').animation = True
223 layout.prop(netsettings, "job_type", text="Type")
224 layout.prop(netsettings, "job_name", text="Name")
225 layout.prop(netsettings, "job_category", text="Category")
226 layout.prop(netsettings, "job_tags", text="Tags")
227 layout.prop(netsettings, "job_render_engine", text="Engine")
229 if netsettings.job_render_engine == "OTHER":
230 layout.prop(netsettings, "job_render_engine_other", text="Other Engine")
232 row = layout.row()
233 row.prop(netsettings, "priority")
234 row.prop(netsettings, "chunks")
236 if netsettings.job_type == "JOB_BLENDER":
237 layout.prop(netsettings, "save_before_job")
241 class RENDER_PT_network_job_vcs(NetRenderButtonsPanel, bpy.types.Panel):
242 bl_label = "VCS Job Settings"
243 COMPAT_ENGINES = {'NET_RENDER'}
245 @classmethod
246 def poll(cls, context):
247 scene = context.scene
248 return (super().poll(context)
249 and scene.network_render.mode == "RENDER_CLIENT"
250 and scene.network_render.job_type == "JOB_VCS")
252 def draw(self, context):
253 layout = self.layout
255 netsettings = context.scene.network_render
257 layout.operator("render.netclientvcsguess", icon='FILE_REFRESH', text="")
259 layout.prop(netsettings, "vcs_system")
260 layout.prop(netsettings, "vcs_revision")
261 layout.prop(netsettings, "vcs_rpath")
262 layout.prop(netsettings, "vcs_wpath")
264 class RENDER_PT_network_slaves(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel):
265 bl_label = "Slaves Status"
266 COMPAT_ENGINES = {'NET_RENDER'}
268 @classmethod
269 def poll(cls, context):
270 netsettings = context.scene.network_render
271 return super().poll(context) and netsettings.mode == "RENDER_CLIENT"
273 def draw(self, context):
274 layout = self.layout
276 netsettings = context.scene.network_render
278 row = layout.row()
279 row.template_list("UI_UL_list", "net_render_slaves", netsettings, "slaves",
280 netsettings, "active_slave_index", rows=2)
282 sub = row.column(align=True)
283 sub.operator("render.netclientslaves", icon='FILE_REFRESH', text="")
284 sub.operator("render.netclientblacklistslave", icon='ZOOMOUT', text="")
286 if len(netrender.slaves) > netsettings.active_slave_index >= 0:
287 layout.separator()
289 slave = netrender.slaves[netsettings.active_slave_index]
291 layout.label(text="Name: " + slave.name)
292 layout.label(text="Address: " + slave.address[0])
293 layout.label(text="Seen: " + time.ctime(slave.last_seen))
294 layout.label(text="Stats: " + slave.stats)
296 class RENDER_PT_network_slaves_blacklist(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel):
297 bl_label = "Slaves Blacklist"
298 COMPAT_ENGINES = {'NET_RENDER'}
300 @classmethod
301 def poll(cls, context):
302 netsettings = context.scene.network_render
303 return super().poll(context) and netsettings.mode == "RENDER_CLIENT"
305 def draw(self, context):
306 layout = self.layout
308 netsettings = context.scene.network_render
310 row = layout.row()
311 row.template_list("UI_UL_list", "net_render_slaves_blacklist", netsettings, "slaves_blacklist",
312 netsettings, "active_blacklisted_slave_index", rows=2)
314 sub = row.column(align=True)
315 sub.operator("render.netclientwhitelistslave", icon='ZOOMOUT', text="")
317 if len(netrender.blacklist) > netsettings.active_blacklisted_slave_index >= 0:
318 layout.separator()
320 slave = netrender.blacklist[netsettings.active_blacklisted_slave_index]
322 layout.label(text="Name: " + slave.name)
323 layout.label(text="Address: " + slave.address[0])
324 layout.label(text="Seen: " + time.ctime(slave.last_seen))
325 layout.label(text="Stats: " + slave.stats)
327 class RENDER_PT_network_jobs(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel):
328 bl_label = "Jobs"
329 COMPAT_ENGINES = {'NET_RENDER'}
331 @classmethod
332 def poll(cls, context):
333 netsettings = context.scene.network_render
334 return super().poll(context) and netsettings.mode == "RENDER_CLIENT"
336 def draw(self, context):
337 layout = self.layout
339 netsettings = context.scene.network_render
341 row = layout.row()
342 row.template_list("UI_UL_list", "net_render", netsettings, "jobs", netsettings, "active_job_index", rows=2)
344 sub = row.column(align=True)
345 sub.operator("render.netclientstatus", icon='FILE_REFRESH', text="")
346 sub.operator("render.netclientcancel", icon='ZOOMOUT', text="")
347 sub.operator("render.netclientcancelall", icon='PANEL_CLOSE', text="")
348 sub.operator("render.netclientdownload", icon='RENDER_ANIMATION', text="")
350 if len(netrender.jobs) > netsettings.active_job_index >= 0:
351 layout.separator()
353 job = netrender.jobs[netsettings.active_job_index]
355 layout.label(text="Name: %s" % job.name)
356 layout.label(text="Length: %04i" % len(job))
357 layout.label(text="Done: %04i" % job.results[netrender.model.FRAME_DONE])
358 layout.label(text="Error: %04i" % job.results[netrender.model.FRAME_ERROR])
360 import bl_ui.properties_render as properties_render
361 class RENDER_PT_network_output(NeedValidAddress, NetRenderButtonsPanel, bpy.types.Panel):
362 bl_label = "Output"
363 COMPAT_ENGINES = {'NET_RENDER'}
365 @classmethod
366 def poll(cls, context):
367 netsettings = context.scene.network_render
368 return super().poll(context) and netsettings.mode == "RENDER_CLIENT"
370 draw = properties_render.RENDER_PT_output.draw
373 class NetRenderSlave(bpy.types.PropertyGroup):
374 @classmethod
375 def register(NetRenderSlave):
377 NetRenderSlave.name = StringProperty(
378 name="Name of the slave",
379 description="",
380 maxlen = 64,
381 default = "")
383 class NetRenderJob(bpy.types.PropertyGroup):
384 @classmethod
385 def register(NetRenderJob):
387 NetRenderJob.name = StringProperty(
388 name="Name of the job",
389 description="",
390 maxlen = 128,
391 default = "")
393 class NetRenderSettings(bpy.types.PropertyGroup):
394 @classmethod
395 def register(NetRenderSettings):
397 def address_update_callback(self, context):
398 netsettings = context.scene.network_render
399 verify_address(netsettings, True)
401 NetRenderSettings.server_address = StringProperty(
402 name="Server address",
403 description="IP or name of the master render server",
404 maxlen = 128,
405 default = "[default]",
406 update = address_update_callback)
408 NetRenderSettings.server_port = IntProperty(
409 name="Server port",
410 description="port of the master render server",
411 default = 8000,
412 min=1,
413 max=65535)
415 NetRenderSettings.use_master_broadcast = BoolProperty(
416 name="Broadcast",
417 description="broadcast master server address on local network",
418 default = True)
419 NetRenderSettings.use_ssl = BoolProperty(
420 name="use ssl",
421 description="use ssl encryption for communication",
422 default = False)
423 NetRenderSettings.cert_path = StringProperty(
424 name="CertPath",
425 description="Path to ssl certifcate",
426 maxlen = 128,
427 default = "",
428 subtype='FILE_PATH')
429 NetRenderSettings.key_path = StringProperty(
430 name="key",
431 description="Path to ssl key file",
432 maxlen = 128,
433 default = "",
434 subtype='FILE_PATH')
436 NetRenderSettings.use_slave_clear = BoolProperty(
437 name="Clear on exit",
438 description="delete downloaded files on exit",
439 default = True)
441 NetRenderSettings.use_slave_thumb = BoolProperty(
442 name="Generate thumbnails",
443 description="Generate thumbnails on slaves instead of master",
444 default = False)
446 NetRenderSettings.slave_tags = StringProperty(
447 name="Tags",
448 description="Tags to associate with the slave (semi-colon separated)",
449 maxlen = 256,
450 default = "")
452 NetRenderSettings.use_slave_output_log = BoolProperty(
453 name="Output render log on console",
454 description="Output render text log to console as well as sending it to the master",
455 default = True)
457 NetRenderSettings.slave_render = BoolProperty(
458 name="Render on slave",
459 description="Use slave for render jobs",
460 default = True)
462 NetRenderSettings.slave_bake = BoolProperty(
463 name="Bake on slave",
464 description="Use slave for baking jobs",
465 default = True)
467 NetRenderSettings.use_master_clear = BoolProperty(
468 name="Clear on exit",
469 description="Delete saved files on exit",
470 default = False)
472 NetRenderSettings.use_master_force_upload = BoolProperty(
473 name="Force Dependency Upload",
474 description="Force client to upload dependency files to master",
475 default = False)
477 default_path = os.environ.get("TEMP")
479 if not default_path:
480 if os.name == 'nt':
481 default_path = "c:/tmp/"
482 else:
483 default_path = "/tmp/"
484 elif not default_path.endswith(os.sep):
485 default_path += os.sep
487 NetRenderSettings.path = StringProperty(
488 name="Path",
489 description="Path for temporary files",
490 maxlen = 128,
491 default = default_path,
492 subtype='FILE_PATH')
494 NetRenderSettings.job_type = EnumProperty(
495 items=(
496 ("JOB_BLENDER", "Blender", "Standard Blender Job"),
497 ("JOB_PROCESS", "Process", "Custom Process Job"),
498 ("JOB_VCS", "VCS", "Version Control System Managed Job"),
500 name="Job Type",
501 description="Type of render job",
502 default="JOB_BLENDER")
504 NetRenderSettings.job_name = StringProperty(
505 name="Job name",
506 description="Name of the job",
507 maxlen = 128,
508 default = "[default]")
510 NetRenderSettings.job_category = StringProperty(
511 name="Job category",
512 description="Category of the job",
513 maxlen = 128,
514 default = "")
516 NetRenderSettings.job_tags = StringProperty(
517 name="Tags",
518 description="Tags to associate with the job (semi-colon separated)",
519 maxlen = 256,
520 default = "")
522 NetRenderSettings.job_render_engine = EnumProperty(
523 items = (
524 ("BLENDER_RENDER", "BLENDER", "Standard Blender Render"),
525 ("CYCLES", "CYCLES", "Cycle Render"),
526 ("OTHER", "OTHER", "Other non-default Render"),
528 name="render",
529 description="Render engine used to render this job",
530 default="BLENDER_RENDER")
532 NetRenderSettings.job_render_engine_other = StringProperty(
533 name="Render engine",
534 description="Render engine other than the builtin defaults (POVRAY_RENDER, ...)",
535 maxlen = 128,
536 default = "")
538 NetRenderSettings.save_before_job = BoolProperty(
539 name="Save Before Job",
540 description="Save current file before sending a job",
541 default = False)
543 NetRenderSettings.chunks = IntProperty(
544 name="Chunks",
545 description="Number of frame to dispatch to each slave in one chunk",
546 default = 5,
547 min=1,
548 max=65535)
550 NetRenderSettings.priority = IntProperty(
551 name="Priority",
552 description="Priority of the job",
553 default = 1,
554 min=1,
555 max=10)
557 NetRenderSettings.vcs_wpath = StringProperty(
558 name="Working Copy",
559 description="Path of the local working copy",
560 maxlen = 1024,
561 default = "")
563 NetRenderSettings.vcs_rpath = StringProperty(
564 name="Remote Path",
565 description="Path of the server copy (protocol specific)",
566 maxlen = 1024,
567 default = "")
569 NetRenderSettings.vcs_revision = StringProperty(
570 name="Revision",
571 description="Revision for this job",
572 maxlen = 256,
573 default = "")
575 NetRenderSettings.vcs_system = EnumProperty(
576 items= netrender.versioning.ITEMS,
577 name="VCS mode",
578 description="Version Control System",
579 default=netrender.versioning.ITEMS[0][0])
581 NetRenderSettings.job_id = StringProperty(
582 name="Network job id",
583 description="id of the last sent render job",
584 maxlen = 64,
585 default = "")
587 NetRenderSettings.active_slave_index = IntProperty(
588 name="Index of the active slave",
589 description="",
590 default = -1,
591 min= -1,
592 max=65535)
594 NetRenderSettings.active_blacklisted_slave_index = IntProperty(
595 name="Index of the active slave",
596 description="",
597 default = -1,
598 min= -1,
599 max=65535)
601 NetRenderSettings.active_job_index = IntProperty(
602 name="Index of the active job",
603 description="",
604 default = -1,
605 min= -1,
606 max=65535)
608 NetRenderSettings.mode = EnumProperty(
609 items=(
610 ("RENDER_CLIENT", "Client", "Act as render client"),
611 ("RENDER_MASTER", "Master", "Act as render master"),
612 ("RENDER_SLAVE", "Slave", "Act as render slave"),
614 name="Network mode",
615 description="Mode of operation of this instance",
616 default="RENDER_CLIENT")
618 NetRenderSettings.slaves = CollectionProperty(type=NetRenderSlave, name="Slaves", description="")
619 NetRenderSettings.slaves_blacklist = CollectionProperty(type=NetRenderSlave, name="Slaves Blacklist", description="")
620 NetRenderSettings.jobs = CollectionProperty(type=NetRenderJob, name="Job List", description="")
622 bpy.types.Scene.network_render = PointerProperty(type=NetRenderSettings, name="Network Render", description="Network Render Settings")
624 @classmethod
625 def unregister(cls):
626 del bpy.types.Scene.network_render