Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release')
-rw-r--r--release/datafiles/splash.pngbin858406 -> 737984 bytes
-rw-r--r--release/scripts/modules/bpy_types.py6
-rw-r--r--release/scripts/modules/gpu_extras/presets.py21
-rw-r--r--release/scripts/modules/keyingsets_utils.py34
-rw-r--r--release/scripts/startup/bl_operators/userpref.py9
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py12
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py4
-rw-r--r--release/scripts/startup/bl_ui/space_info.py13
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py2
-rw-r--r--release/scripts/startup/keyingsets_builtins.py125
-rw-r--r--release/scripts/startup/nodeitems_builtins.py2
-rw-r--r--release/scripts/templates_py/operator_modal_draw.py9
13 files changed, 150 insertions, 93 deletions
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 70a68ce6847..babb3e30c6d 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 4ea8c88e8d9..aa540eeb23b 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -657,16 +657,14 @@ class Gizmo(StructRNA):
use_blend = color[3] < 1.0
if use_blend:
- # TODO: wrap GPU_blend from GPU state.
- from bgl import glEnable, glDisable, GL_BLEND
- glEnable(GL_BLEND)
+ gpu.state.blend_set('ALPHA')
with gpu.matrix.push_pop():
gpu.matrix.multiply_matrix(matrix)
batch.draw()
if use_blend:
- glDisable(GL_BLEND)
+ gpu.state.blend_set('NONE')
@staticmethod
def new_custom_shape(type, verts):
diff --git a/release/scripts/modules/gpu_extras/presets.py b/release/scripts/modules/gpu_extras/presets.py
index 81d515904a1..f490e1e74ba 100644
--- a/release/scripts/modules/gpu_extras/presets.py
+++ b/release/scripts/modules/gpu_extras/presets.py
@@ -57,12 +57,12 @@ def draw_circle_2d(position, color, radius, segments=32):
batch.draw()
-def draw_texture_2d(texture_id, position, width, height):
+def draw_texture_2d(texture, position, width, height):
"""
Draw a 2d texture.
- :arg texture_id: OpenGL id of the texture (e.g. :class:`bpy.types.Image.bindcode`).
- :type texture_id: int
+ :arg texture: GPUTexture to draw (e.g. gpu.texture.from_image(image) for :class:`bpy.types.Image`).
+ :type texture: :class:`gpu.types.GPUTexture`
:arg position: Position of the lower left corner.
:type position: 2D Vector
:arg width: Width of the image when drawn (not necessarily
@@ -72,7 +72,6 @@ def draw_texture_2d(texture_id, position, width, height):
:type height: float
"""
import gpu
- import bgl
from . batch import batch_for_shader
coords = ((0, 0), (1, 0), (1, 1), (0, 1))
@@ -83,14 +82,20 @@ def draw_texture_2d(texture_id, position, width, height):
{"pos": coords, "texCoord": coords},
)
- bgl.glActiveTexture(bgl.GL_TEXTURE0)
- bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id)
-
with gpu.matrix.push_pop():
gpu.matrix.translate(position)
gpu.matrix.scale((width, height))
shader = gpu.shader.from_builtin('2D_IMAGE')
shader.bind()
- shader.uniform_int("image", 0)
+
+ if isinstance(texture, int):
+ # Call the legacy bgl to not break the existing API
+ import bgl
+ bgl.glActiveTexture(bgl.GL_TEXTURE0)
+ bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture)
+ shader.uniform_int("image", 0)
+ else:
+ shader.uniform_sampler("image", texture)
+
batch.draw(shader)
diff --git a/release/scripts/modules/keyingsets_utils.py b/release/scripts/modules/keyingsets_utils.py
index 190f0282339..b7a15bbbc19 100644
--- a/release/scripts/modules/keyingsets_utils.py
+++ b/release/scripts/modules/keyingsets_utils.py
@@ -219,6 +219,40 @@ def RKS_GEN_scaling(_ksi, _context, ks, data):
else:
ks.paths.add(id_block, path)
+
+# Custom Properties
+def RKS_GEN_custom_props(_ksi, _context, ks, data):
+ # get id-block and path info
+ id_block, base_path, grouping = get_transform_generators_base_info(data)
+
+ # Only some RNA types can be animated.
+ prop_type_compat = {bpy.types.BoolProperty,
+ bpy.types.IntProperty,
+ bpy.types.FloatProperty}
+
+ # When working with a pose, 'id_block' is the armature object (which should
+ # get the animation data), whereas 'data' is the bone being keyed.
+ for cprop_name in data.keys():
+ # ignore special "_RNA_UI" used for UI editing
+ if cprop_name == "_RNA_UI":
+ continue
+
+ prop_path = '["%s"]' % bpy.utils.escape_identifier(cprop_name)
+ try:
+ rna_property = data.path_resolve(prop_path, False)
+ except ValueError as ex:
+ # This happens when a custom property is set to None. In that case it cannot
+ # be converted to an FCurve-compatible value, so we can't keyframe it anyway.
+ continue
+ if rna_property.rna_type not in prop_type_compat:
+ continue
+
+ path = "%s%s" % (base_path, prop_path)
+ if grouping:
+ ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping)
+ else:
+ ks.paths.add(id_block, path)
+
# ------
diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py
index 7547184dc04..f77f00d2234 100644
--- a/release/scripts/startup/bl_operators/userpref.py
+++ b/release/scripts/startup/bl_operators/userpref.py
@@ -99,6 +99,15 @@ class PREFERENCES_OT_copy_prev(Operator):
version = bpy.app.version
version_new = ((version[0] * 100) + version[1])
version_old = ((version[0] * 100) + version[1]) - 1
+
+ # Special case, remove when the version is > 3.0.
+ if version_new == 300:
+ version_new = 294
+ version_old = 293
+ else:
+ print("TODO: remove exception!")
+ # End special case.
+
# Ensure we only try to copy files from a point release.
# The check below ensures the second numbers match.
while (version_new % 100) // 10 == (version_old % 100) // 10:
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index c1d60a127d2..3064b33c7f7 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -821,6 +821,12 @@ class GreasePencilLayerMasksPanel:
col2.menu("GPENCIL_MT_layer_mask_menu", icon='ADD', text="")
col2.operator("gpencil.layer_mask_remove", icon='REMOVE', text="")
+ col2.separator()
+
+ sub = col2.column(align=True)
+ sub.operator("gpencil.layer_mask_move", icon='TRIA_UP', text="").type = 'UP'
+ sub.operator("gpencil.layer_mask_move", icon='TRIA_DOWN', text="").type = 'DOWN'
+
class GreasePencilLayerRelationsPanel:
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index aca7ba3c5ad..217ec248764 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -286,19 +286,17 @@ class MATERIAL_PT_lineart(MaterialButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
+ layout.use_property_split = True
mat = context.material
lineart = mat.lineart
layout.prop(lineart, "use_transparency")
- if lineart.use_transparency:
-
- layout.label(text="Transparency Masks:")
-
- row = layout.row(align=True)
- for i in range(8):
- row.prop(lineart, "use_transparency_mask", text=str(i), index=i, toggle=True)
+ row = layout.row(align=True, heading="Masks")
+ row.active = lineart.use_transparency
+ for i in range(8):
+ row.prop(lineart, "use_transparency_mask", text=str(i), index=i, toggle=True)
classes = (
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 033e6196323..4ea1ec26738 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -329,7 +329,9 @@ class OBJECT_PT_lineart(ObjectButtonsPanel, Panel):
row = layout.row(heading="Override Crease")
row.prop(lineart, "use_crease_override", text="")
- row.prop(lineart, "crease_threshold", slider=True, text="")
+ subrow = row.row()
+ subrow.active = lineart.use_crease_override
+ subrow.prop(lineart, "crease_threshold", slider=True, text="")
class OBJECT_PT_motion_paths(MotionPathButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index cd65980fc0d..3a97b104271 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -92,16 +92,15 @@ class INFO_MT_area(Menu):
layout.separator()
- layout.operator("screen.area_dupli", icon='WINDOW')
-
- layout.separator()
-
layout.operator("screen.screen_full_area")
layout.operator(
"screen.screen_full_area",
- text="Toggle Fullscreen Area",
- icon='FULLSCREEN_ENTER',
- ).use_hide_panels = True
+ text="Toggle Fullscreen Area").use_hide_panels = True
+ layout.operator("screen.area_dupli")
+
+ layout.separator()
+
+ layout.operator("screen.area_close")
class INFO_MT_context_menu(Menu):
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 04b7a11bde1..de78b88c0f6 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -570,7 +570,7 @@ class USERPREF_PT_system_sound(SystemPanel, CenterAlignMixIn, Panel):
layout.prop(system, "audio_device", expand=False)
sub = layout.grid_flow(row_major=False, columns=0, even_columns=False, even_rows=False, align=False)
- sub.active = system.audio_device not in {'NONE', 'Null'}
+ sub.active = system.audio_device not in {'NONE', 'None'}
sub.prop(system, "audio_channels", text="Channels")
sub.prop(system, "audio_mixing_buffer", text="Mixing Buffer")
sub.prop(system, "audio_sample_rate", text="Sample Rate")
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 012febc7cc7..83151a3480c 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -44,6 +44,7 @@ ANIM_KS_LOCATION_ID = "Location"
ANIM_KS_ROTATION_ID = "Rotation"
ANIM_KS_SCALING_ID = "Scaling"
ANIM_KS_LOC_ROT_SCALE_ID = "LocRotScale"
+ANIM_KS_LOC_ROT_SCALE_CPROP_ID = "LocRotScaleCProp"
ANIM_KS_AVAILABLE_ID = "Available"
ANIM_KS_WHOLE_CHARACTER_ID = "WholeCharacter"
ANIM_KS_WHOLE_CHARACTER_SELECTED_ID = "WholeCharacterSelected"
@@ -159,6 +160,22 @@ class BUILTIN_KSI_LocRotScale(KeyingSetInfo):
keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+# LocRotScaleCProp
+class BUILTIN_KSI_LocRotScaleCProp(KeyingSetInfo):
+ """Key location/rotation/scale as well as custom properties"""
+ bl_idname = ANIM_KS_LOC_ROT_SCALE_CPROP_ID
+ bl_label = "Location, Rotation, Scale & Custom Properties"
+
+ poll = keyingsets_utils.RKS_POLL_selected_items
+ iterator = keyingsets_utils.RKS_ITER_selected_item
+
+ def generate(self, context, ks, data):
+ keyingsets_utils.RKS_GEN_location(self, context, ks, data)
+ keyingsets_utils.RKS_GEN_rotation(self, context, ks, data)
+ keyingsets_utils.RKS_GEN_scaling(self, context, ks, data)
+ keyingsets_utils.RKS_GEN_custom_props(self, context, ks, data)
+
+
# RotScale
class BUILTIN_KSI_RotScale(KeyingSetInfo):
"""Insert a keyframe on each of the rotation and scale channels"""
@@ -350,7 +367,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo):
bl_label = "Available"
# poll - selected objects or selected object with animation data
- def poll(ksi, context):
+ def poll(self, context):
ob = context.active_object
if ob:
# TODO: this fails if one animation-less object is active, but many others are selected
@@ -366,14 +383,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo):
###############################
-
-# All properties that are likely to get animated in a character rig
-class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
- """Insert a keyframe for all properties that are likely to get animated in a character rig """ \
- """(useful when blocking out a shot)"""
- bl_idname = ANIM_KS_WHOLE_CHARACTER_ID
- bl_label = "Whole Character"
-
+class WholeCharacterMixin:
# these prefixes should be avoided, as they are not really bones
# that animators should be touching (or need to touch)
badBonePrefixes = (
@@ -387,38 +397,37 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
)
# poll - pose-mode on active object only
- def poll(ksi, context):
+ def poll(self, context):
return ((context.active_object) and (context.active_object.pose) and
(context.active_object.mode == 'POSE'))
# iterator - all bones regardless of selection
- def iterator(ksi, context, ks):
+ def iterator(self, context, ks):
for bone in context.active_object.pose.bones:
- if not bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes):
- ksi.generate(context, ks, bone)
+ if not bone.name.startswith(self.badBonePrefixes):
+ self.generate(context, ks, bone)
# generator - all unlocked bone transforms + custom properties
- def generate(ksi, context, ks, bone):
+ def generate(self, context, ks, bone):
# loc, rot, scale - only include unlocked ones
if not bone.bone.use_connect:
- ksi.doLoc(ks, bone)
+ self.doLoc(ks, bone)
if bone.rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
- ksi.doRot4d(ks, bone)
+ self.doRot4d(ks, bone)
else:
- ksi.doRot3d(ks, bone)
- ksi.doScale(ks, bone)
+ self.doRot3d(ks, bone)
+ self.doScale(ks, bone)
# bbone properties?
- ksi.doBBone(context, ks, bone)
+ self.doBBone(context, ks, bone)
# custom props?
- ksi.doCustomProps(ks, bone)
-
+ self.doCustomProps(ks, bone)
# ----------------
# helper to add some bone's property to the Keying Set
- def addProp(ksi, ks, bone, prop, index=-1, use_groups=True):
+ def addProp(self, ks, bone, prop, index=-1, use_groups=True):
# add the property name to the base path
id_path = bone.path_from_id()
id_block = bone.id_data
@@ -439,16 +448,16 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
# ----------------
# location properties
- def doLoc(ksi, ks, bone):
+ def doLoc(self, ks, bone):
if bone.lock_location == (False, False, False):
- ksi.addProp(ks, bone, "location")
+ self.addProp(ks, bone, "location")
else:
for i in range(3):
if not bone.lock_location[i]:
- ksi.addProp(ks, bone, "location", i)
+ self.addProp(ks, bone, "location", i)
# rotation properties
- def doRot4d(ksi, ks, bone):
+ def doRot4d(self, ks, bone):
# rotation mode affects the property used
if bone.rotation_mode == 'QUATERNION':
prop = "rotation_quaternion"
@@ -459,40 +468,40 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
if bone.lock_rotations_4d:
# can check individually
if (bone.lock_rotation == (False, False, False)) and (bone.lock_rotation_w is False):
- ksi.addProp(ks, bone, prop)
+ self.addProp(ks, bone, prop)
else:
if bone.lock_rotation_w is False:
- ksi.addProp(ks, bone, prop, 0) # w = 0
+ self.addProp(ks, bone, prop, 0) # w = 0
for i in range(3):
if not bone.lock_rotation[i]:
- ksi.addProp(ks, bone, prop, i + 1) # i + 1, since here x/y/z = 1,2,3, and w=0
+ self.addProp(ks, bone, prop, i + 1) # i + 1, since here x/y/z = 1,2,3, and w=0
elif True not in bone.lock_rotation:
# if axis-angle rotations get locked as eulers, then it's too messy to allow anything
# other than all open unless we keyframe the whole lot
- ksi.addProp(ks, bone, prop)
+ self.addProp(ks, bone, prop)
- def doRot3d(ksi, ks, bone):
+ def doRot3d(self, ks, bone):
if bone.lock_rotation == (False, False, False):
- ksi.addProp(ks, bone, "rotation_euler")
+ self.addProp(ks, bone, "rotation_euler")
else:
for i in range(3):
if not bone.lock_rotation[i]:
- ksi.addProp(ks, bone, "rotation_euler", i)
+ self.addProp(ks, bone, "rotation_euler", i)
# scale properties
- def doScale(ksi, ks, bone):
+ def doScale(self, ks, bone):
if bone.lock_scale == (0, 0, 0):
- ksi.addProp(ks, bone, "scale")
+ self.addProp(ks, bone, "scale")
else:
for i in range(3):
if not bone.lock_scale[i]:
- ksi.addProp(ks, bone, "scale", i)
+ self.addProp(ks, bone, "scale", i)
# ----------------
# bendy bone properties
- def doBBone(ksi, context, ks, pchan):
+ def doBBone(self, context, ks, pchan):
bone = pchan.bone
# This check is crude, but is the best we can do for now
@@ -500,12 +509,12 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
# (and the bone is a control bone). This may lead to some
# false positives...
if bone.bbone_segments > 1:
- keyingsets_utils.RKS_GEN_bendy_bones(ksi, context, ks, pchan)
+ keyingsets_utils.RKS_GEN_bendy_bones(self, context, ks, pchan)
# ----------------
# custom properties
- def doCustomProps(ksi, ks, bone):
+ def doCustomProps(self, ks, bone):
prop_type_compat = {bpy.types.BoolProperty,
bpy.types.IntProperty,
@@ -528,39 +537,34 @@ class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
# be converted to an FCurve-compatible value, so we can't keyframe it anyway.
continue
if rna_property.rna_type in prop_type_compat:
- ksi.addProp(ks, bone, prop_path)
+ self.addProp(ks, bone, prop_path)
elif prop_rna.is_animatable:
- ksi.addProp(ks, bone, prop)
+ self.addProp(ks, bone, prop)
-# All properties that are likely to get animated in a character rig, only selected bones.
+
+class BUILTIN_KSI_WholeCharacter(WholeCharacterMixin, KeyingSetInfo):
+ """Insert a keyframe for all properties that are likely to get animated in a character rig """ \
+ """(useful when blocking out a shot)"""
+ bl_idname = ANIM_KS_WHOLE_CHARACTER_ID
+ bl_label = "Whole Character"
-class BUILTIN_KSI_WholeCharacterSelected(KeyingSetInfo):
+class BUILTIN_KSI_WholeCharacterSelected(WholeCharacterMixin, KeyingSetInfo):
"""Insert a keyframe for all properties that are likely to get animated in a character rig """ \
"""(only selected bones)"""
bl_idname = ANIM_KS_WHOLE_CHARACTER_SELECTED_ID
bl_label = "Whole Character (Selected Bones Only)"
# iterator - all bones regardless of selection
- def iterator(ksi, context, ks):
+ def iterator(self, context, ks):
# Use either the selected bones, or all of them if none are selected.
bones = context.selected_pose_bones_from_active_object or context.active_object.pose.bones
for bone in bones:
- if bone.name.startswith(BUILTIN_KSI_WholeCharacter.badBonePrefixes):
+ if bone.name.startswith(self.badBonePrefixes):
continue
- ksi.generate(context, ks, bone)
-
- # Poor man's subclassing. Blender breaks when we actually subclass BUILTIN_KSI_WholeCharacter.
- poll = BUILTIN_KSI_WholeCharacter.poll
- generate = BUILTIN_KSI_WholeCharacter.generate
- addProp = BUILTIN_KSI_WholeCharacter.addProp
- doLoc = BUILTIN_KSI_WholeCharacter.doLoc
- doRot4d = BUILTIN_KSI_WholeCharacter.doRot4d
- doRot3d = BUILTIN_KSI_WholeCharacter.doRot3d
- doScale = BUILTIN_KSI_WholeCharacter.doScale
- doBBone = BUILTIN_KSI_WholeCharacter.doBBone
- doCustomProps = BUILTIN_KSI_WholeCharacter.doCustomProps
+ self.generate(context, ks, bone)
+
###############################
@@ -578,7 +582,7 @@ class BUILTIN_KSI_DeltaLocation(KeyingSetInfo):
iterator = keyingsets_utils.RKS_ITER_selected_objects
# generator - delta location channels only
- def generate(ksi, context, ks, data):
+ def generate(self, context, ks, data):
# get id-block and path info
id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data)
@@ -604,7 +608,7 @@ class BUILTIN_KSI_DeltaRotation(KeyingSetInfo):
iterator = keyingsets_utils.RKS_ITER_selected_objects
# generator - delta location channels only
- def generate(ksi, context, ks, data):
+ def generate(self, context, ks, data):
# get id-block and path info
id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data)
@@ -638,7 +642,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
iterator = keyingsets_utils.RKS_ITER_selected_objects
# generator - delta location channels only
- def generate(ksi, context, ks, data):
+ def generate(self, context, ks, data):
# get id-block and path info
id_block, base_path, grouping = keyingsets_utils.get_transform_generators_base_info(data)
@@ -664,6 +668,7 @@ classes = (
BUILTIN_KSI_Scaling,
BUILTIN_KSI_LocRot,
BUILTIN_KSI_LocRotScale,
+ BUILTIN_KSI_LocRotScaleCProp,
BUILTIN_KSI_LocScale,
BUILTIN_KSI_RotScale,
BUILTIN_KSI_DeltaLocation,
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index ab4d9353e1b..4584f799b95 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -498,6 +498,7 @@ geometry_node_categories = [
NodeItem("GeometryNodeAttributeSeparateXYZ"),
NodeItem("GeometryNodeAttributeRemove"),
NodeItem("GeometryNodeAttributeMapRange"),
+ NodeItem("GeometryNodeAttributeTransfer"),
]),
GeometryNodeCategory("GEO_COLOR", "Color", items=[
NodeItem("ShaderNodeValToRGB"),
@@ -550,6 +551,7 @@ geometry_node_categories = [
NodeItem("ShaderNodeMath"),
NodeItem("FunctionNodeBooleanMath"),
NodeItem("FunctionNodeFloatCompare"),
+ NodeItem("GeometryNodeSwitch"),
]),
GeometryNodeCategory("GEO_VECTOR", "Vector", items=[
NodeItem("ShaderNodeSeparateXYZ"),
diff --git a/release/scripts/templates_py/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py
index 1e185ecfe2b..16c6f6dbe22 100644
--- a/release/scripts/templates_py/operator_modal_draw.py
+++ b/release/scripts/templates_py/operator_modal_draw.py
@@ -1,5 +1,4 @@
import bpy
-import bgl
import blf
import gpu
from gpu_extras.batch import batch_for_shader
@@ -17,16 +16,16 @@ def draw_callback_px(self, context):
# 50% alpha, 2 pixel width line
shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glLineWidth(2)
+ gpu.state.blend_set('ALPHA')
+ gpu.state.line_width_set(2.0)
batch = batch_for_shader(shader, 'LINE_STRIP', {"pos": self.mouse_path})
shader.bind()
shader.uniform_float("color", (0.0, 0.0, 0.0, 0.5))
batch.draw(shader)
# restore opengl defaults
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
+ gpu.state.line_width_set(1.0)
+ gpu.state.blend_set('NONE')
class ModalDrawOperator(bpy.types.Operator):