1
$\begingroup$

As I'm a Blender greenhorn, I need your help. Here is my problem:

I have a document added as plane. Next, I want to label certain points within the document. Afterwards, I transform (fold and rotate) the document. In the end, I want to read off the new positions of my labels. Moreover, the points should not be visible when rendering the image.

I am doing the transformation by rotating bones. This works great! (see picture)

enter image description here

However, I am struggling with the labeling of points (see example in the attached image) and reading off the new position.

I would appreciate any help :-)

Background:

I want to generate a training data set for my Neural Network.

Cheers,

Julian

$\endgroup$
4
  • $\begingroup$ Add a screenshot or a blend file with blend-exchange.giantcowfilms.com $\endgroup$ Jul 6, 2020 at 11:59
  • $\begingroup$ Related maybe(?) blender.stackexchange.com/q/882/30849 $\endgroup$
    – Leander
    Jul 6, 2020 at 15:46
  • $\begingroup$ hey @Leander, unfortunately not related as it about the vertices of an object e.g. cube. However, my points are "randomly" set within the plane (see picture). $\endgroup$
    – Julian
    Jul 7, 2020 at 7:28
  • $\begingroup$ I don't see why you could t add vertices at those points. $\endgroup$
    – Leander
    Jul 7, 2020 at 10:05

1 Answer 1

0
$\begingroup$

One thing you could try is creating separate vertex groups for each point you want to label and then using the following Python code in the script editor to get the positions for each vertex. Let me know if it works (or if it doesn't).

import bpy
import bmesh

ObjectName = "Plane"
VertexGroups = ["VGroup 1", "VGroup 2", "VGroup 3"]

obj = bpy.data.objects[ObjectName]
vGroupIndex = 0

def select_obj(obj):
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
    
def create_cube():
    bpyscene = bpy.context.scene
    mesh = bpy.data.meshes.new("Vertex")
    cube = bpy.data.objects.new("Vertex", mesh)
    bpyscene.collection.objects.link(cube)
    select_obj(cube)
    
    bm = bmesh.new()
    bmesh.ops.create_cube(bm, size=1.0)
    bm.to_mesh(mesh)
    bm.free()
    
    return cube
    

def get_vertices_in_group(a,index):
    vlist = []
    for v in a.data.vertices:
        for g in v.groups:
            if g.group == index:
                vlist.append(v.index)
    return vlist

def create_boxes():
    boxes = [];
    for vgi in VertexGroups:
        vg = obj.vertex_groups[vgi]
        box = create_cube()
        bpy.ops.object.constraint_add(type="COPY_LOCATION")
        box.constraints["Copy Location"].target = obj
        box.constraints["Copy Location"].subtarget = vg.name
        boxes.append(box);
    return boxes

def get_locations(boxes, should_delete):
    for box in boxes:
        print(" ")
        print(box.name)
        mat = box.matrix_local
        pos = (mat[0][3], mat[1][3], mat[2][3])
        print(pos)
        if should_delete:
            bpy.ops.object.select_all(action="DESELECT")
            select_obj(box)
            bpy.ops.object.delete(use_global=False)

boxes = create_boxes()
get_locations(boxes, True)

You can replace ObjectName with whatever your plane is called and VertexGroups with the list of the names of the vertex groups you end up using for each vertex.

The way it works is by creating a box for each vertex group named in the VertexGroup list, and then using the copy location constraint to move the box over to wherever the vertex is. Then it uses the box's matrix_local to find it's actual position (just checking the box's location doesn't take constrains into account and thus just returns (0,0,0))

It doesn't work to just find the vertices in the vertex groups and spit out their positions (vertex.co) because that only gives the position of the vertex relative to the object's origin as it is in edit mode (i.e. it won't account for armature poses, constraints, or even moving the mesh in object mode)

I doubt this is the fastest or best way to do this, but hopefully it will work well enough. Hope it helps, and let me know if it works (or if it doesn't)

$\endgroup$
7
  • $\begingroup$ thanks for you answer @ElliotThomas. I also had this idea in mind. However, adding vertices in the plane (i.e. document paper) messes up the rotation with the bones (pic will follow). Maybe there is a way to fix this problem so I can follow your approach. $\endgroup$
    – Julian
    Jul 7, 2020 at 6:59
  • $\begingroup$ @Julian, as I was trying to figure out what was causing the issue you were having, I realized that my script only gives the positions of the vertices without counting the deform caused by the bones. I've figured out a way to get around it, and I'm working on the script right now. Basically, I'm going to add boxes in object mode with the copy location modifier to copy the location of each vertex in the appropriate vertex groups. I'll then read the box.matrix_local to find it's true location and thus location of the vertex. $\endgroup$ Jul 8, 2020 at 12:43
  • $\begingroup$ @Julian I fixed my answer. If you just create new vertex groups and add vertices to those, it shouldn't affect the armature. I mean, if you go into edit mode, the mesh will go back to its original pose without regard to the armature, but once you go back to object mode, it will fix itself. $\endgroup$ Jul 8, 2020 at 13:41
  • $\begingroup$ I'll try as soon as possible (probably by tmrw). Thank you so much already :-) I'll let you know if it works! $\endgroup$
    – Julian
    Jul 8, 2020 at 13:47
  • $\begingroup$ First I have to apologize about saying that adding vertices messes up the rotation. I just had no clue about setting the vertex groups properly. Now I know how it works :-) About your idea ... I really like it! I think it does a quite nice job. However, it still returns (0,0,0) for the cube's position. I'll try to fix that. $\endgroup$
    – Julian
    Jul 9, 2020 at 8:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .