0
$\begingroup$

I want to assign various properties to objects and then select all objects with a certain set of values for those properties.

The objects are graphs from tests (created with CSV Mesh Importer, so they are lines, not solids). They all have a value for, for example, length and width (not of the Blender object but of the object the test was done on). I want to then select all objects that have, say, length 5.3 and width 3.8.

I already found that I can group objects and then select the grouped objects. But for that I have to select one of the objects first. But I want to select the properties, and a set of them, and then select all objects that share that set of properties.

I also found Custom Properties, but I can't figure out how that works, and most explanations use Python, but I want to do it in the GUI. Also, I want to set the properties just once, and that is not what it seems to be meant for.

$\endgroup$
0
$\begingroup$

I don't think there is a way to do this without some Python. It is not very complicated though.

You can type C.object. and hit Ctrl+Space in the Python Console to see all the properties. Also they might be in C.object.data.. Once you know the property you wish to select your objects based on, you can run:

import bpy

for obj in bpy.context.scene.objects:
    # Note that floats may not be equal because of binary rounding errors so:
    if (obj.location[2] - 1.0694) < 0.0001 and (obj.location[2] - 1.0694) >= 0 : 
        obj.select = True
        bpy.context.scene.objects.active = obj #to make the last selected object active
    else:
        obj.select = False

Obviously you would change (obj.location[2] - 1.0694) < 0.0001 and (obj.location[2] - 1.0694) >= 0 to whatever statement comparing properties to your wanted values.

$\endgroup$
  • $\begingroup$ But there are at least two problems: I would then have to type all that again every time I want to make a selection. I will potentially do this hundreds of times, so that is no option. So I put that code in a file (obsel.py), with the following content: #!/usr/bin/python import bpy for obj in bpy.context.scene.objects: if obj.location[2]<100.0: obj.select = True else: obj.select = False I put that in the directory where the Blender file is and in the console in Blender typed python obsel.py, upon which I get a SyntaxError. $\endgroup$ – Dirk Nov 17 '18 at 12:38
  • $\begingroup$ Also, I would first have to assign custom properties (length, width) to the objects, and I don't know how to do that. $\endgroup$ – Dirk Nov 17 '18 at 12:39
  • $\begingroup$ Sorry, I am making a mess of the comments. Or rather, the site makes a mess of them, concatenating everything. (I'm new at this.) $\endgroup$ – Dirk Nov 17 '18 at 12:41
  • $\begingroup$ Ok, found a solution to the first problem: Open a text editor, Alt-O, select script and press Run Script. I can then alter the values there to change the selection. $\endgroup$ – Dirk Nov 17 '18 at 13:13
  • $\begingroup$ Sorry I skipped the explanation how to run it. That is what I meant - it should be run from the Text Editor. It is not that hard to make it into an operator if you needed to repeat it hundreds of times, you could then assign it to a hotkey. But I don't know what exactly you would need it to do and what properties you want to compare to what. $\endgroup$ – Martin Z Nov 17 '18 at 14:05
0
$\begingroup$

I can select objects based on a property now. But after 2 hours of searching, I still haven't figured out the first bit, how to assign a custom property. I tried this:

for obj in bpy.data.objects:
    obj.addProperty("length")

but then I get:

Attribute error: 'Object' object has no attribute 'addProperty'

And that's just assigning a property (I want to assign this to all objects). Next I'lll have to set the value (for objects I select by hand).

$\endgroup$
0
$\begingroup$

I have given up on Custom Properties and decided to set the z-values of various vertices to the values I want to give the graphs. I managed to make that work for one graph, but not for all selected graphs.

This is the relevant section of the code I wrote:

for obj in bpy.data.objects:
    if obj.select:
        print(obj)
        bpy.ops.object.mode_set(mode='EDIT')
        bm = bmesh.from_edit_mesh(obj.data)     # get bMesh representation
        for vertex in bm.verts:
            for var in vars:
                if vertex.index==var[0][0] and var[0][1]==1:    # If the vertex is on one of the var-locations and that var is marked to be set.
                    vertex.co[2]=var[2]                         # Set the vertex's z-value to the value for that variable in the variable-list.
                elif abs(vertex.co[2]-var[2])<precision:        # If the vertex's z-value already has one of the variable-values, that might be confusing, ...
                    vertex.co[2]=0.0                            # ... so set it to 0.
        bpy.ops.object.mode_set(mode='OBJECT')

Again, this works for the first graph, and in the console (from the print-line) I see the names of the first and second graph. But then I get 'the mesh must be in edit mode'. In the 3D view I see the first graph still is in edit mode, so apparently the line

bpy.ops.object.mode_set(mode='OBJECT')

doesn't work.

Correction: with this code it got stuck the first time, on the line bm = mesh....., whilst previously this only happened on the second pass. I must have changed something. Sorry, I always get lost in programming.

$\endgroup$

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.