This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision | |||
|
blender:python:addons:start [2022/02/07 20:00] dwheele |
blender:python:addons:start [2022/02/07 20:03] (current) dwheele |
||
|---|---|---|---|
| Line 3: | Line 3: | ||
| * [[vertexdistribute|Vertex Distribute]] | * [[vertexdistribute|Vertex Distribute]] | ||
| * [[tonguegrooveseparator|Tongue and Groove Separator]] | * [[tonguegrooveseparator|Tongue and Groove Separator]] | ||
| - | |||
| - | ====== Vertex Distribute ====== | ||
| - | |||
| - | 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]) ** 2 | ||
| - | 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 and oppositeVertex. Have to use this | ||
| - | # 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() | ||
| - | |||
| - | # | ||
| - | | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | |||
| - | </ | ||