1
$\begingroup$

Basically I want to find the edges for the default cube, so I can store their location, then use the locations to draw grease pencil strokes. I have been successful at figuring out how to print out the 12 edges with bmesh, but I don't know how to read the data format that bmesh has created to store the location data.

<BMEdge(0x00000263C41B0BB0), index=3, verts=(0x00000263C155E0B8/3, 0x00000263C155E080/2)>

Here is my simple script below.

import bpy, bmesh

# Store object data
me = bpy.context.object.data

# Create a new empty bmesh object
bm = bmesh.new()
# Use the method from_mesh to fill in the mesh
# with the active mesh.
bm.from_mesh(me)

# Create new grease pencil frame
# gp_layer = init_grease_pencil()
# gp_frame = gp_layer.frames.new(0)

edgeList = []
# Loop edges
for edge in bm.edges:
    print(edge)
    # prints 12 edges in the following format
    # <BMEdge(0x00000263C41B0BB0), index=3, verts=(0x00000263C155E0B8/3, 0x00000263C155E080/2)>

    # Store the edge coordinates here. 
    # E.g edgeList.append([p1, p2]) where p1 and p2 are the corner vertices.

bm.to_mesh(me)
bm.free()

# TODO
# Create new grease pencil stroke.
# Loop edgeList.
# Draw stroke base on the save coordinates.
$\endgroup$
2
$\begingroup$

You are very close

Can create the list in one fell swoop using list comprehension. (instead of edge_list.append(tuple(v.co for v in e.verts)) Used a tuple for vert coords as we really don't want to add or remove or sort or..

Python console code, notice don't need to print items as their repr is echoed.

>>> edge_list = [tuple(v.co for v in e.verts) for e in bm.edges]
>>> for verts in edge_list:
...     verts
...    

And result on default cube

(Vector((1.0, 0.9999999403953552, -1.0)), Vector((1.0, -1.0, -1.0)))
(Vector((1.0, 0.9999999403953552, -1.0)), Vector((-0.9999996423721313, 1.0000003576278687, -1.0)))
(Vector((1.0, 0.9999999403953552, -1.0)), Vector((1.0000004768371582, 0.999999463558197, 1.0)))
(Vector((1.0, -1.0, -1.0)), Vector((-1.0000001192092896, -0.9999998211860657, -1.0)))
(Vector((1.0, -1.0, -1.0)), Vector((0.9999993443489075, -1.0000005960464478, 1.0)))
(Vector((-1.0000001192092896, -0.9999998211860657, -1.0)), Vector((-0.9999996423721313, 1.0000003576278687, -1.0)))
(Vector((-1.0000001192092896, -0.9999998211860657, -1.0)), Vector((-1.0000003576278687, -0.9999996423721313, 1.0)))
(Vector((-0.9999996423721313, 1.0000003576278687, -1.0)), Vector((-0.9999999403953552, 1.0, 1.0)))
(Vector((1.0000004768371582, 0.999999463558197, 1.0)), Vector((0.9999993443489075, -1.0000005960464478, 1.0)))
(Vector((1.0000004768371582, 0.999999463558197, 1.0)), Vector((-0.9999999403953552, 1.0, 1.0)))
(Vector((0.9999993443489075, -1.0000005960464478, 1.0)), Vector((-1.0000003576278687, -0.9999996423721313, 1.0)))
(Vector((-1.0000003576278687, -0.9999996423721313, 1.0)), Vector((-0.9999999403953552, 1.0, 1.0)))

Notice these are in local coordinates of the mesh. To convert to globals, ob is the object with mesh as data

global_vert_co = ob.matrix_world @ v.co
$\endgroup$
2
  • $\begingroup$ Thanks for the answer! Whats the difference between local and global mesh data? If you don't mind me asking? $\endgroup$ – Inkplay_ May 22 '20 at 14:01
  • $\begingroup$ Mesh data is always local (data is always local bones bezier knots etc) Eg One corner of default cube is (1, 1, 1). When cube at default location (scene origin, no loc\n rotation and unit scale this is also its global coordinate. Transform the object location rotation scale and the global location will no longer match, eg move cube 1 right and the global loc of vert is (2, 1, 1) the local coord still (1, 1, 1). If we apply location to the mesh local location will match global again (2, 1, 1) and the object origin will be at scene origin. See en.wikipedia.org/wiki/Local_coordinates $\endgroup$ – batFINGER May 22 '20 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.