properties_physics_smoke.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. # ##### BEGIN GPL LICENSE BLOCK #####
  2. #
  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.
  7. #
  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.
  12. #
  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.
  16. #
  17. # ##### END GPL LICENSE BLOCK #####
  18. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import (
  21. Panel,
  22. )
  23. from bl_ui.properties_physics_common import (
  24. point_cache_ui,
  25. effector_weights_ui,
  26. )
  27. class PhysicButtonsPanel:
  28. bl_space_type = 'PROPERTIES'
  29. bl_region_type = 'WINDOW'
  30. bl_context = "physics"
  31. @staticmethod
  32. def poll_smoke(context):
  33. ob = context.object
  34. if not ((ob and ob.type == 'MESH') and (context.smoke)):
  35. return False
  36. md = context.smoke
  37. return md and (context.smoke.smoke_type != 'NONE') and (bpy.app.build_options.mod_smoke)
  38. @staticmethod
  39. def poll_smoke_domain(context):
  40. if not PhysicButtonsPanel.poll_smoke(context):
  41. return False
  42. md = context.smoke
  43. return md and (md.smoke_type == 'DOMAIN')
  44. class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
  45. bl_label = "Smoke"
  46. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  47. @classmethod
  48. def poll(cls, context):
  49. ob = context.object
  50. return (ob and ob.type == 'MESH') and (context.engine in cls.COMPAT_ENGINES) and (context.smoke)
  51. def draw(self, context):
  52. layout = self.layout
  53. layout.use_property_split = True
  54. if not bpy.app.build_options.mod_smoke:
  55. col = layout.column(align=True)
  56. col.alignment = 'RIGHT'
  57. col.label(text="Built without Smoke modifier")
  58. return
  59. md = context.smoke
  60. layout.prop(md, "smoke_type")
  61. class PHYSICS_PT_smoke_settings(PhysicButtonsPanel, Panel):
  62. bl_label = "Settings"
  63. bl_parent_id = 'PHYSICS_PT_smoke'
  64. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  65. @classmethod
  66. def poll(cls, context):
  67. if not PhysicButtonsPanel.poll_smoke(context):
  68. return False
  69. return (context.engine in cls.COMPAT_ENGINES)
  70. def draw(self, context):
  71. layout = self.layout
  72. layout.use_property_split = True
  73. md = context.smoke
  74. ob = context.object
  75. if md.smoke_type == 'DOMAIN':
  76. domain = md.domain_settings
  77. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  78. col = flow.column()
  79. col.enabled = (not domain.point_cache.is_baked)
  80. col.prop(domain, "resolution_max", text="Resolution Divisions")
  81. col.prop(domain, "time_scale", text="Time Scale")
  82. col.separator()
  83. col = flow.column()
  84. sub = col.row()
  85. sub.enabled = (not domain.point_cache.is_baked)
  86. sub.prop(domain, "collision_extents", text="Border Collisions")
  87. # This can be tweaked after baking, for render.
  88. col.prop(domain, "clipping", text="Empty Space")
  89. elif md.smoke_type == 'FLOW':
  90. flow_smoke = md.flow_settings
  91. col = layout.column()
  92. col.prop(flow_smoke, "smoke_flow_type", expand=False)
  93. col.separator()
  94. flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
  95. col = flow.column()
  96. if flow_smoke.smoke_flow_type != 'OUTFLOW':
  97. col.prop(flow_smoke, "smoke_flow_source", expand=False, text="Flow Source")
  98. if flow_smoke.smoke_flow_source == 'PARTICLES':
  99. col.prop_search(
  100. flow_smoke, "particle_system", ob, "particle_systems",
  101. text="Particle System"
  102. )
  103. else:
  104. col.prop(flow_smoke, "surface_distance")
  105. col.prop(flow_smoke, "volume_density")
  106. col = flow.column()
  107. col.prop(flow_smoke, "use_absolute")
  108. if flow_smoke.smoke_flow_type in {'SMOKE', 'BOTH'}:
  109. col.prop(flow_smoke, "density")
  110. col.prop(flow_smoke, "temperature", text="Temperature Diff.")
  111. col.separator()
  112. col = flow.column()
  113. col.prop(flow_smoke, "smoke_color")
  114. if flow_smoke.smoke_flow_type in {'FIRE', 'BOTH'}:
  115. col.prop(flow_smoke, "fuel_amount")
  116. col.prop(flow_smoke, "subframes", text="Sampling Subframes")
  117. col.separator()
  118. col.prop_search(flow_smoke, "density_vertex_group", ob, "vertex_groups", text="Vertex Group")
  119. elif md.smoke_type == 'COLLISION':
  120. coll = md.coll_settings
  121. col = layout.column()
  122. col.prop(coll, "collision_type")
  123. class PHYSICS_PT_smoke_settings_initial_velocity(PhysicButtonsPanel, Panel):
  124. bl_label = "Initial Velocity"
  125. bl_parent_id = 'PHYSICS_PT_smoke_settings'
  126. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  127. @classmethod
  128. def poll(cls, context):
  129. if not PhysicButtonsPanel.poll_smoke(context):
  130. return False
  131. md = context.smoke
  132. return (md and (md.smoke_type == 'FLOW')
  133. and md.flow_settings and md.flow_settings.smoke_flow_type != 'OUTFLOW'
  134. and context.engine in cls.COMPAT_ENGINES)
  135. def draw_header(self, context):
  136. md = context.smoke
  137. flow_smoke = md.flow_settings
  138. self.layout.prop(flow_smoke, "use_initial_velocity", text="")
  139. def draw(self, context):
  140. layout = self.layout
  141. layout.use_property_split = True
  142. flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
  143. md = context.smoke
  144. flow_smoke = md.flow_settings
  145. flow.active = flow_smoke.use_initial_velocity
  146. col = flow.column(align=True)
  147. col.prop(flow_smoke, "velocity_factor")
  148. if flow_smoke.smoke_flow_source == 'MESH':
  149. col = flow.column()
  150. col.prop(flow_smoke, "velocity_normal")
  151. # sub.prop(flow_smoke, "velocity_random")
  152. class PHYSICS_PT_smoke_settings_particle_size(PhysicButtonsPanel, Panel):
  153. bl_label = "Particle Size"
  154. bl_parent_id = 'PHYSICS_PT_smoke_settings'
  155. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  156. @classmethod
  157. def poll(cls, context):
  158. if not PhysicButtonsPanel.poll_smoke(context):
  159. return False
  160. md = context.smoke
  161. return (md and (md.smoke_type == 'FLOW')
  162. and md.flow_settings and md.flow_settings.smoke_flow_type != 'OUTFLOW'
  163. and md.flow_settings.smoke_flow_source == 'PARTICLES'
  164. and context.engine in cls.COMPAT_ENGINES)
  165. def draw_header(self, context):
  166. md = context.smoke
  167. flow_smoke = md.flow_settings
  168. self.layout.prop(flow_smoke, "use_particle_size", text="")
  169. def draw(self, context):
  170. layout = self.layout
  171. layout.use_property_split = True
  172. md = context.smoke
  173. flow_smoke = md.flow_settings
  174. layout.active = flow_smoke.use_particle_size
  175. layout.prop(flow_smoke, "particle_size")
  176. class PHYSICS_PT_smoke_behavior(PhysicButtonsPanel, Panel):
  177. bl_label = "Behavior"
  178. bl_parent_id = 'PHYSICS_PT_smoke_settings'
  179. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  180. @classmethod
  181. def poll(cls, context):
  182. if not PhysicButtonsPanel.poll_smoke_domain(context):
  183. return False
  184. return (context.engine in cls.COMPAT_ENGINES)
  185. def draw(self, context):
  186. layout = self.layout
  187. layout.use_property_split = True
  188. md = context.smoke
  189. domain = md.domain_settings
  190. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  191. flow.enabled = (not domain.point_cache.is_baked)
  192. col = flow.column()
  193. col.prop(domain, "alpha")
  194. col.prop(domain, "beta", text="Temperature Diff.")
  195. col = flow.column()
  196. col.prop(domain, "vorticity")
  197. class PHYSICS_PT_smoke_behavior_dissolve(PhysicButtonsPanel, Panel):
  198. bl_label = "Dissolve"
  199. bl_parent_id = 'PHYSICS_PT_smoke_behavior'
  200. bl_options = {'DEFAULT_CLOSED'}
  201. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  202. @classmethod
  203. def poll(cls, context):
  204. if not PhysicButtonsPanel.poll_smoke_domain(context):
  205. return False
  206. return (context.engine in cls.COMPAT_ENGINES)
  207. def draw_header(self, context):
  208. md = context.smoke
  209. domain = md.domain_settings
  210. self.layout.prop(domain, "use_dissolve_smoke", text="")
  211. def draw(self, context):
  212. layout = self.layout
  213. layout.use_property_split = True
  214. md = context.smoke
  215. domain = md.domain_settings
  216. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  217. flow.enabled = (not domain.point_cache.is_baked)
  218. layout.active = domain.use_dissolve_smoke
  219. col = flow.column()
  220. col.prop(domain, "dissolve_speed", text="Time")
  221. col = flow.column()
  222. col.prop(domain, "use_dissolve_smoke_log", text="Slow")
  223. class PHYSICS_PT_smoke_flow_texture(PhysicButtonsPanel, Panel):
  224. bl_label = "Texture"
  225. bl_parent_id = 'PHYSICS_PT_smoke'
  226. bl_options = {'DEFAULT_CLOSED'}
  227. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  228. @classmethod
  229. def poll(cls, context):
  230. if not PhysicButtonsPanel.poll_smoke(context):
  231. return False
  232. md = context.smoke
  233. return (md and (md.smoke_type == 'FLOW')
  234. and (md.flow_settings.smoke_flow_source == 'MESH')
  235. and (context.engine in cls.COMPAT_ENGINES))
  236. def draw_header(self, context):
  237. md = context.smoke
  238. flow_smoke = md.flow_settings
  239. self.layout.prop(flow_smoke, "use_texture", text="")
  240. def draw(self, context):
  241. layout = self.layout
  242. layout.use_property_split = True
  243. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  244. ob = context.object
  245. flow_smoke = context.smoke.flow_settings
  246. sub = flow.column()
  247. sub.active = flow_smoke.use_texture
  248. sub.prop(flow_smoke, "noise_texture")
  249. sub.prop(flow_smoke, "texture_map_type", text="Mapping")
  250. col = flow.column()
  251. sub = col.column()
  252. sub.active = flow_smoke.use_texture
  253. if flow_smoke.texture_map_type == 'UV':
  254. sub.prop_search(flow_smoke, "uv_layer", ob.data, "uv_layers")
  255. if flow_smoke.texture_map_type == 'AUTO':
  256. sub.prop(flow_smoke, "texture_size")
  257. sub.prop(flow_smoke, "texture_offset")
  258. class PHYSICS_PT_smoke_fire(PhysicButtonsPanel, Panel):
  259. bl_label = "Flames"
  260. bl_parent_id = 'PHYSICS_PT_smoke'
  261. bl_options = {'DEFAULT_CLOSED'}
  262. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  263. @classmethod
  264. def poll(cls, context):
  265. if not PhysicButtonsPanel.poll_smoke_domain(context):
  266. return False
  267. return (context.engine in cls.COMPAT_ENGINES)
  268. def draw(self, context):
  269. layout = self.layout
  270. layout.use_property_split = True
  271. domain = context.smoke.domain_settings
  272. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  273. flow.enabled = (not domain.point_cache.is_baked)
  274. col = flow.column()
  275. col.prop(domain, "burning_rate", text="Reaction Speed")
  276. col.prop(domain, "flame_smoke")
  277. col.prop(domain, "flame_vorticity")
  278. col.separator()
  279. col = flow.column(align=True)
  280. col.prop(domain, "flame_ignition", text="Temperature Ignition")
  281. col.prop(domain, "flame_max_temp")
  282. col.separator()
  283. sub = col.column()
  284. sub.prop(domain, "flame_smoke_color")
  285. class PHYSICS_PT_smoke_adaptive_domain(PhysicButtonsPanel, Panel):
  286. bl_label = "Adaptive Domain"
  287. bl_parent_id = 'PHYSICS_PT_smoke'
  288. bl_options = {'DEFAULT_CLOSED'}
  289. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  290. @classmethod
  291. def poll(cls, context):
  292. if not PhysicButtonsPanel.poll_smoke_domain(context):
  293. return False
  294. return (context.engine in cls.COMPAT_ENGINES)
  295. def draw_header(self, context):
  296. md = context.smoke.domain_settings
  297. self.layout.prop(md, "use_adaptive_domain", text="")
  298. def draw(self, context):
  299. layout = self.layout
  300. layout.use_property_split = True
  301. domain = context.smoke.domain_settings
  302. layout.active = domain.use_adaptive_domain
  303. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  304. flow.enabled = (not domain.point_cache.is_baked)
  305. col = flow.column()
  306. col.prop(domain, "additional_res", text="Add Resolution")
  307. col.prop(domain, "adapt_margin")
  308. col.separator()
  309. col = flow.column()
  310. col.prop(domain, "adapt_threshold", text="Threshold")
  311. class PHYSICS_PT_smoke_highres(PhysicButtonsPanel, Panel):
  312. bl_label = "High Resolution"
  313. bl_parent_id = 'PHYSICS_PT_smoke'
  314. bl_options = {'DEFAULT_CLOSED'}
  315. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  316. @classmethod
  317. def poll(cls, context):
  318. if not PhysicButtonsPanel.poll_smoke_domain(context):
  319. return False
  320. return (context.engine in cls.COMPAT_ENGINES)
  321. def draw_header(self, context):
  322. md = context.smoke.domain_settings
  323. self.layout.prop(md, "use_high_resolution", text="")
  324. def draw(self, context):
  325. layout = self.layout
  326. layout.use_property_split = True
  327. md = context.smoke.domain_settings
  328. layout.active = md.use_high_resolution
  329. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  330. col = flow.column()
  331. col.enabled = not md.point_cache.is_baked
  332. col.prop(md, "amplify", text="Resolution Divisions")
  333. col.prop(md, "highres_sampling", text="Flow Sampling")
  334. col.separator()
  335. col = flow.column()
  336. col.enabled = not md.point_cache.is_baked
  337. col.prop(md, "noise_type", text="Noise Method")
  338. col.prop(md, "strength")
  339. layout.prop(md, "show_high_resolution")
  340. class PHYSICS_PT_smoke_collections(PhysicButtonsPanel, Panel):
  341. bl_label = "Collections"
  342. bl_parent_id = 'PHYSICS_PT_smoke'
  343. bl_options = {'DEFAULT_CLOSED'}
  344. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  345. @classmethod
  346. def poll(cls, context):
  347. if not PhysicButtonsPanel.poll_smoke_domain(context):
  348. return False
  349. return (context.engine in cls.COMPAT_ENGINES)
  350. def draw(self, context):
  351. layout = self.layout
  352. layout.use_property_split = True
  353. domain = context.smoke.domain_settings
  354. col = layout.column()
  355. col.prop(domain, "fluid_collection", text="Flow")
  356. # col = layout.column()
  357. # col.prop(domain, "effector_collection", text="Effector")
  358. col.prop(domain, "collision_collection", text="Collision")
  359. class PHYSICS_PT_smoke_cache(PhysicButtonsPanel, Panel):
  360. bl_label = "Cache"
  361. bl_parent_id = 'PHYSICS_PT_smoke'
  362. bl_options = {'DEFAULT_CLOSED'}
  363. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  364. @classmethod
  365. def poll(cls, context):
  366. if not PhysicButtonsPanel.poll_smoke_domain(context):
  367. return False
  368. return (context.engine in cls.COMPAT_ENGINES)
  369. def draw(self, context):
  370. layout = self.layout
  371. layout.use_property_split = True
  372. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  373. domain = context.smoke.domain_settings
  374. cache_file_format = domain.cache_file_format
  375. col = flow.column()
  376. col.prop(domain, "cache_file_format")
  377. if cache_file_format == 'POINTCACHE':
  378. col = flow.column()
  379. col.prop(domain, "point_cache_compress_type", text="Compression")
  380. col.separator()
  381. elif cache_file_format == 'OPENVDB':
  382. if not bpy.app.build_options.openvdb:
  383. row = layout.row(align=True)
  384. row.alignment = 'RIGHT'
  385. row.label(text="Built without OpenVDB support")
  386. return
  387. col = flow.column()
  388. col.prop(domain, "openvdb_cache_compress_type", text="Compression")
  389. col.prop(domain, "data_depth", text="Data Depth")
  390. col.separator()
  391. cache = domain.point_cache
  392. point_cache_ui(self, cache, (cache.is_baked is False), 'SMOKE')
  393. class PHYSICS_PT_smoke_field_weights(PhysicButtonsPanel, Panel):
  394. bl_label = "Field Weights"
  395. bl_parent_id = 'PHYSICS_PT_smoke'
  396. bl_options = {'DEFAULT_CLOSED'}
  397. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  398. @classmethod
  399. def poll(cls, context):
  400. if not PhysicButtonsPanel.poll_smoke_domain(context):
  401. return False
  402. return (context.engine in cls.COMPAT_ENGINES)
  403. def draw(self, context):
  404. domain = context.smoke.domain_settings
  405. effector_weights_ui(self, domain.effector_weights, 'SMOKE')
  406. class PHYSICS_PT_smoke_viewport_display(PhysicButtonsPanel, Panel):
  407. bl_label = "Viewport Display"
  408. bl_parent_id = 'PHYSICS_PT_smoke'
  409. bl_options = {'DEFAULT_CLOSED'}
  410. @classmethod
  411. def poll(cls, context):
  412. return (PhysicButtonsPanel.poll_smoke_domain(context))
  413. def draw(self, context):
  414. layout = self.layout
  415. layout.use_property_split = True
  416. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  417. domain = context.smoke.domain_settings
  418. col = flow.column()
  419. col.prop(domain, "display_thickness")
  420. col.separator()
  421. col.prop(domain, "slice_method", text="Slicing")
  422. slice_method = domain.slice_method
  423. axis_slice_method = domain.axis_slice_method
  424. do_axis_slicing = (slice_method == 'AXIS_ALIGNED')
  425. do_full_slicing = (axis_slice_method == 'FULL')
  426. col = col.column()
  427. col.enabled = do_axis_slicing
  428. col.prop(domain, "axis_slice_method")
  429. col = flow.column()
  430. sub = col.column()
  431. sub.enabled = not do_full_slicing and do_axis_slicing
  432. sub.prop(domain, "slice_axis")
  433. sub.prop(domain, "slice_depth")
  434. row = col.row()
  435. row.enabled = do_full_slicing or not do_axis_slicing
  436. row.prop(domain, "slice_per_voxel")
  437. col.prop(domain, "display_interpolation")
  438. class PHYSICS_PT_smoke_viewport_display_color(PhysicButtonsPanel, Panel):
  439. bl_label = "Color Mapping"
  440. bl_parent_id = 'PHYSICS_PT_smoke_viewport_display'
  441. bl_options = {'DEFAULT_CLOSED'}
  442. @classmethod
  443. def poll(cls, context):
  444. return (PhysicButtonsPanel.poll_smoke_domain(context))
  445. def draw_header(self, context):
  446. md = context.smoke.domain_settings
  447. self.layout.prop(md, "use_color_ramp", text="")
  448. def draw(self, context):
  449. layout = self.layout
  450. layout.use_property_split = True
  451. domain = context.smoke.domain_settings
  452. col = layout.column()
  453. col.enabled = domain.use_color_ramp
  454. col.prop(domain, "coba_field")
  455. col.use_property_split = False
  456. col = col.column()
  457. col.template_color_ramp(domain, "color_ramp", expand=True)
  458. class PHYSICS_PT_smoke_viewport_display_debug(PhysicButtonsPanel, Panel):
  459. bl_label = "Debug Velocity"
  460. bl_parent_id = 'PHYSICS_PT_smoke_viewport_display'
  461. bl_options = {'DEFAULT_CLOSED'}
  462. @classmethod
  463. def poll(cls, context):
  464. return (PhysicButtonsPanel.poll_smoke_domain(context))
  465. def draw_header(self, context):
  466. md = context.smoke.domain_settings
  467. self.layout.prop(md, "show_velocity", text="")
  468. def draw(self, context):
  469. layout = self.layout
  470. layout.use_property_split = True
  471. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=True)
  472. domain = context.smoke.domain_settings
  473. col = flow.column()
  474. col.enabled = domain.show_velocity
  475. col.prop(domain, "vector_display_type", text="Display As")
  476. col.prop(domain, "vector_scale")
  477. classes = (
  478. PHYSICS_PT_smoke,
  479. PHYSICS_PT_smoke_settings,
  480. PHYSICS_PT_smoke_settings_initial_velocity,
  481. PHYSICS_PT_smoke_settings_particle_size,
  482. PHYSICS_PT_smoke_behavior,
  483. PHYSICS_PT_smoke_behavior_dissolve,
  484. PHYSICS_PT_smoke_adaptive_domain,
  485. PHYSICS_PT_smoke_cache,
  486. PHYSICS_PT_smoke_field_weights,
  487. PHYSICS_PT_smoke_fire,
  488. PHYSICS_PT_smoke_flow_texture,
  489. PHYSICS_PT_smoke_collections,
  490. PHYSICS_PT_smoke_highres,
  491. PHYSICS_PT_smoke_viewport_display,
  492. PHYSICS_PT_smoke_viewport_display_color,
  493. PHYSICS_PT_smoke_viewport_display_debug,
  494. )
  495. if __name__ == "__main__": # only for live edit.
  496. from bpy.utils import register_class
  497. for cls in classes:
  498. register_class(cls)