This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
blender:python:addons:start [2022/02/07 18:27] dwheele |
blender:python:addons:start [2022/02/07 20:03] (current) dwheele |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== | + | ====== |
| - | At this point (2/7/2022), this works as a script run in a Blender Text window, but isn't completed into a full add on. This allows you to select 3 or more Vertexes, select one point as the Active vertex, and they will be placed into alignment and distributed, | + | |
| - | + | | |
| - | The mode set to OBJECT then to EDIT should not be necessary, but without it, the change is not visible within the 3D View window. Later I may be able to fix this. | + | |
| - | + | ||
| - | To do this quickly, I found a copy of articles: one to determine the Active vertex, and one to determine the selected Vertexes. There probably is an easier way. But this does work. | + | |
| - | + | ||
| - | This code is contained within my file " | + | |
| - | + | ||
| - | <code python> | + | |
| - | import bpy | + | |
| - | import bmesh | + | |
| - | import math | + | |
| - | + | ||
| - | mode = bpy.context.active_object.mode | + | |
| - | bpy.ops.object.mode_set(mode=' | + | |
| - | bpy.ops.object.mode_set(mode=' | + | |
| - | ob = bpy.context.object | + | |
| - | me = ob.data | + | |
| - | bm = bmesh.new() | + | |
| - | bm.from_mesh(me) | + | |
| - | + | ||
| - | def bmesh_vert_active(bm): | + | |
| - | if bm.select_history: | + | |
| - | elem = bm.select_history[-1] | + | |
| - | if isinstance(elem, | + | |
| - | return elem | + | |
| - | return None | + | |
| - | + | ||
| - | + | ||
| - | def distance_between_vertexes(vert1, | + | |
| - | myDistance = 0 | + | |
| - | for i in range(3): | + | |
| - | myDistance += (vert1.co[i] - vert2.co[i]) | + | |
| - | return math.sqrt(myDistance) | + | |
| - | + | ||
| - | def vertsAreEqual(vert1, | + | |
| - | if (vert1 == None or vert2 == None): | + | |
| - | return False | + | |
| - | for i in range(3): | + | |
| - | if abs(vert1.co[i] - vert2.co[i]) > .00001: | + | |
| - | # print(" | + | |
| - | return False | + | |
| - | return True | + | |
| - | + | ||
| - | # For now, we'll do this the simple way. We can find the " | + | |
| - | # " | + | |
| - | # We'll distribute between these two points. | + | |
| - | + | ||
| - | def main(): | + | |
| - | + | ||
| - | activeVertex = bmesh_vert_active(bm) | + | |
| - | if (activeVertex == None): | + | |
| - | print(" | + | |
| - | return | + | |
| - | + | ||
| - | + | ||
| - | # bpy.ops.object.mode_set(mode=' | + | |
| - | + | ||
| - | + | ||
| - | # bpy.ops.object.mode_set(mode=' | + | |
| - | + | ||
| - | # bpy.ops.object.mode_set(mode=' | + | |
| - | # we need to switch from Edit mode to Object mode so the selection gets updated | + | |
| - | # selectedVerts = [v for v in bpy.context.active_object.data.vertices if v.select] | + | |
| - | selectedVerts = [v for v in bm.verts if v.select] | + | |
| - | for v in selectedVerts: | + | |
| - | print(" | + | |
| - | if (len(selectedVerts) < 3): | + | |
| - | print (" | + | |
| - | else: | + | |
| - | print (" | + | |
| - | print(" | + | |
| - | # Find farthest vertex from the Active vertex | + | |
| - | oppositeVertex = None | + | |
| - | oppositeVertexDistance = 0 | + | |
| - | + | ||
| - | for v in selectedVerts: | + | |
| - | d2verts = distance_between_vertexes(activeVertex, | + | |
| - | if d2verts > oppositeVertexDistance: | + | |
| - | oppositeVertex = v | + | |
| - | oppositeVertexDistance = d2verts | + | |
| - | # I have the oppositeVertex now | + | |
| - | print(" | + | |
| - | + | ||
| - | # Calculate amounts to change | + | |
| - | changeAmount = [0,0,0] | + | |
| - | + | ||
| - | for i in range(3): | + | |
| - | changeAmount[i] = oppositeVertex.co[i] - activeVertex.co[i] | + | |
| - | + | ||
| - | print(" | + | |
| - | + | ||
| - | # Now we can change the vertex(s) in between the outer 2 vertexes | + | |
| - | # Remove activeVertex | + | |
| - | # syntax because activeVertex is a BMVert | + | |
| - | print(" | + | |
| - | middleVerts = [] | + | |
| - | for v in selectedVerts: | + | |
| - | if vertsAreEqual(activeVertex, | + | |
| - | pass | + | |
| - | else: | + | |
| - | # Append a tuple | + | |
| - | middleVerts.append((distance_between_vertexes(activeVertex, | + | |
| - | + | ||
| - | print(" | + | |
| - | + | ||
| - | + | ||
| - | # A function that returns the ' | + | |
| - | + | ||
| - | for mvTuple in middleVerts: | + | |
| - | print(" | + | |
| - | + | ||
| - | # Index is used to calculate distributed new distance | + | |
| - | index = 0 | + | |
| - | for mvTuple in sorted(middleVerts): | + | |
| - | for xyz in range(3): | + | |
| - | # Distance between activeVertex and this middleVert | + | |
| - | mvTuple[1].co[xyz] = activeVertex.co[xyz] + changeAmount[xyz]*(1+index)/ | + | |
| - | + | ||
| - | index = index + 1 | + | |
| - | + | ||
| - | print(" | + | |
| - | for mvTuple in middleVerts: | + | |
| - | print(" | + | |
| - | + | ||
| - | + | ||
| - | bpy.ops.object.mode_set(mode=' | + | |
| - | bm.to_mesh(me) | + | |
| - | bm.free() | + | |
| - | + | ||
| - | bpy.ops.object.mode_set(mode=mode) | + | |
| - | + | ||
| - | main() | + | |
| - | + | ||
| - | # | + | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | </ | + | |