New answers tagged

1

I don't think you can do that easily. I'll show you one solution but I hope there is an easier way. Related Q&A We're going to use a modal operator that runs when you click on the property field and loops until you release the mouse button. import bpy class DRAGGABLEPROP_OT_subscribe(bpy.types.Operator): bl_idname = "draggableprop.subscribe&...


2

OpenMesh version of Nathan Reed and lemon: import numpy as np import openmesh as om from vedo import * def array_angle(array1, array2): """ INPUT: N x 2/3/... """ res = np.sum(array1 * array2, axis=1) res /= np.linalg.norm(array1, axis=1) res /= np.linalg.norm(array2, axis=1) res = np.clip(res, -...


1

If I understand well the context you're describing, you just need to replace: filepath = os.path.join(os.path.dirname( os.path.abspath(__file__)), self.blend) by: filepath = os.path.join(os.path.dirname( os.path.abspath(__file__)), self.blend + ".blend") The reason is the os.path.isfile won't recognize a file path if it does not includes ...


0

Here's the answer which solved my problem. I need to find out area in view 3d and other related info pack those things into override variable and put that variable at the first input of edge_slide function. import bpy def view3d_find( return_area = False ): for area in bpy.context.window.screen.areas: if area.type == 'VIEW_3D': v3d = ...


1

I don't know if this is the correct way to do it, but I can tell you that it works.. Just put the name of your addon, as if you were using the search engine bpy.ops.screen.userpref_show() bpy.data.window_managers["WinMan"].addon_search = "node wrangler"


1

For an EnumProperty on a bpy.types.Object, I had text corruption with storing the items array in a global. A global string cache worked better for me. StringCache = {} def InternStr(s): global StringCache if s not in StringCache: StringCache[s] = s return StringCache[s] def getEnumStuff(self, context): items = [] for x in ...: ...


0

pose_bone.matrix is the transform from bone-local-space to armature-space (not world-space). It is the real transform, after constraints, drivers, etc. are applied. So you can get the transform relative to the bone's parent by first transforming into armature space with pbone.matrix, then transforming from armature space in pbone.parent's space with pbone....


0

You are correct. By using matrix.to_euler() the bone's rotation is presented in world space. Using rotation_euler would give you the bone's rotation in the bone's local space.


2

Besides setting all three at once, bone.rotation_euler = [x,y,z], if you want to change all the bones at once, you can use foreach_set to do them in a batch data = [] for bone in bones: rot_x = 30.0 rot_y = 30.0 rot_z = 30.0 data += [rot_x, rot_y, rot_z] bones.foreach_set("rotation_euler", data) However this doesn't cause an update ...


1

If by "slow" you mean slow to write, then how about using Python's tuple assignment: bone.rotation_euler = 30.0, 30.0, 30.0 Since all values are the same, you can use a list multiplication: bone.rotation_euler = [30.0]*3 And in this case you could use 30 instead of 30.0 - the value would be still converted to float: >>> my_object....


0

This will do for feet or inches, but it needs to be cleaned up if you want to properly handle all units. Between the dims = line and the result += line insert if bpy.context.scene.unit_settings.system == "IMPERIAL": dims = dims * 3.281 # Meters to feet if bpy.context.scene.unit_settings.length_unit == "INCHES": ...


1

you should apply the new origin to each of the selected objects. Get a list of the selected objects and apply the origin with a for loop. This is a sample code: C = bpy.context O = bpy.ops # get list of selected objects objs = C.selected_objects for obj in objs: # make current object as active C.view_layer.objects.active = obj # apply origin ...


1

I guess you need to wait a little bit for the dependency graph to update. It might not work for your script but if it doesn't rely on the data to be available right away you can use Application Timers with a very short time span so it executes on the next update cycle. import bpy def print_stats(): print(bpy.context.scene.statistics(bpy.context....


2

Just parent your object to the camera (adjust the position one time manually) and it will stay forever in the middle. Like this: result:


1

There are some rules you need to follow as to sculpt an object. In order to sculpt the body of your object as it is on your picture you have to make all the objects one. Then there is the problem that every ball and arm, although now they are one object, their previous geometry as a whole has nothing to do with one item's geometry. When you sculpt an ...


0

Quaternion data-types need 4 float values while euler rotation data-types need only 3 values and the default size for FloatVectorProperty is 3 ; so together with subtype argument that should be set to QUATERNION we should also set the size argument to 4 and the field now holds a quaternion data-type.


0

This script here will go through all the actions and push them down to NLA strips. The context has to be changed during selection of the actions. Im not sure why but it works.Using Blender 2.9 for action in bpy.data.actions: bpy.ops.object.mode_set(mode='OBJECT') bpy.context.area.type = 'DOPESHEET_EDITOR' bpy.context....


1

You need to make some changes to switch to the image editor. Here is a version of the class that will work: class HelloWorldPanel(bpy.types.Panel): """Creates a Panel in the Object properties window""" bl_label = "label" bl_idname = "OBJECT_PT_hello" bl_space_type = 'IMAGE_EDITOR' ...


0

vertices can be keyframed using '.keyframe_insert' - pass the vertices you want to keyframe at a given frame in the function below. def keyframe(vert, frame): for index in range(3): vert.keyframe_insert("co", index=index, frame=frame, group="location")


0

You can use the modifier_copy_to_selected operator with a context override : object_to_copy_from = bpy.context.active_object objects_to_copy_to = bpy.context.selected_objects override = { "active_object": object_to_copy_from, "selected_objects": objects_to_copy_to } bpy.ops.object.modifier_copy_to_selected(override, modifier=...


3

You can get an existing node group using: ng = bpy.data.node_groups['your node group'] Adding a Geometry Node modifier: modifier=o.modifiers.new("MyName", "NODES") (where o is your object) The modifier is added, but adding it also creates a new node group that you can delete by: bpy.data.node_groups.remove(modifier.node_group) Then ...


1

I found the following three settings, please point out any errors: Normal(World Space) in Geometry Node Normal(Object Space) in Texture Coordinate Node You can convert to Camera Space by


1

Quaternion has an axis-angle constructor which can be used. Quaternion(Vector((obj.rotation_axis_angle[1], obj.rotation_axis_angle[2], obj.rotation_axis_angle[3])), obj.rotation_axis_angle[0])


1

The syntax of Python allows you to add no more than one dot operator to a function return, so you can't add a second one. Further, if you do add one dot operator, you can't access the return value from the function anymore, and so can't use the dot operator on it again. Thus, bpy.context.active_object.modifiers.new(type="SCREW", name="Your ...


1

That is the correct path on Windows, but Python require uses backslash ('\') as a special character, so you can either write the string as r"C:\Windows\Fonts\comic.ttf" or as C:\\Windows\\Fonts\\comic.ttf. That is, you can either use the r prefix to tell Python to not use backslash as a special character or you can "escape" the backslash ...


1

OK, since nobody gave me a better solution, I did it my way and it worked, so I decided to post it back here in case anyone wants to do it too. [My case] We have 20+ machines working with the same version of Blender on a local server. Since I'm making changes to the original Blender add-ons (like for example added features to OBJ Importer/Exporter and so on)....


3

Operators only work with primitive properties as arguments (why you're not keeping the PointerProperty inside the operator). Not sure why it's not working, but my guess is operators aren't good at using the PointerProperty as part of its arguments. May need to check if there's an existing bug for this... A simple workaround is to only store the prop as its ...


2

Although the exact functionality of the Stored Views add-on doesn't cut it, we're going to leverage it in our own script. Since it's shipped with Blender for free, we can assume pretty much everybody has access to it. We're going to add a Panel in the View Layer properties to display our minimalistic interface. It should have 2 buttons (Operators), one to ...


5

I'm not sure if there's a way to do that. One alternative is to have your addon register some code to be run when a file is loaded that fixes up the library paths to their new location. bl_info = { "name" : "Test", "blender" : (2, 93, 0), } import bpy from bpy.app.handlers import persistent import os @persistent def ...


4

If you want this to be portable, independent of OS versions or Blender release versions, you can use code like what I have below. It's based on Python's platform data from the sys library and Blender's Directory Layout from the Blender manual. Replace your dir = ... with this code. It will only work for standard installations. There's no way to deal with ...


1

When I run Intersect(Boolean) as you wrote to your object, the left geometry is created (2.91.0). If you really want it that way, the same result on the right side by script. import bpy obj = bpy.data.objects["Figure"] bpy.context.view_layer.objects.active = obj # active object bpy.ops.object.mode_set(mode='OBJECT') obj.data.polygons[1].select = ...


2

There are two ways to go about this in Blender. The recommended portable way is to create a modal operator. Modal Operators is a good free tutorial and this answer gives a minimal implementation that I quote here. class VIEW3D_OT_process_input(bpy.types.Operator): """Process input while Control key is pressed.""" ...


0

Of course there is. This script requires that you've already made the grid your active object: import bpy import bmesh # Get a mesh from an object and make it a bmesh object = bpy.context.object if object and object.type == 'MESH': # Create a bmesh from the object if object.mode == 'OBJECT': bm = bmesh.new() bm.from_mesh(object....


6

The method for obtaining the diffuse color varies depending on what render engine you are using. For EEVEE and Cycles, diffuse_color isn't used and you need to find the color input of the shader node. For example, if you have the very simple setup of a Principled BSDF feeding the Material Output Surface Input, you need to find the Base Color input of the ...


7

That's a common misunderstanding of the material system. Material.diffuse_color property is used for solid viewport shading (or renders created with the workbench engine) and does not affect the (final) rendering of all other engines, the main reason why you can find that property in the Viewport Display panel: Due to the nature of node based materials (and ...


5

The Python API changed in 3.0 and the addon needs to be updated. You should report the problem to the addon author so they can fix it. Specifically the second arg to user_resource is now keyword-only so this line addons_path = bpy.utils.user_resource('SCRIPTS', "addons") needs to become addons_path = bpy.utils.user_resource('SCRIPTS', path="...


0

The variable name is showing in the last line of the popup bpy.data.scenes["Scene'].eeve.use_taa_reprojection. The only way to get the label is from the source code, because labels only appear as arguments to layout functions, for example, here's the source for the Cycles equivalent: heading = layout.column(align=False, heading="Viewport&...


0

Found the nudge I needed after a little more research and use of dir(). This previous question was very helpful: How to set Freestyle line set setting using python?


Top 50 recent answers are included