Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function bproc.object.sample_poses() seems not to work with child objects #1064

Open
ErikDerGute opened this issue Feb 12, 2024 · 5 comments
Labels
question Question, not yet a bug ;)

Comments

@ErikDerGute
Copy link

Describe the issue

Hello guys,

i would like to use the bproc.object.sample_poses() function to arrange my objects without collisions to run the physics simulation afterwards. When ich use my "default" objects everything works fine. As soon as i add to an object a child object an error occurs. Some models for example are in the .zip archive, because git don't support .blend files.

The error:

Could not place Cube without a collision.
Error: Python: Traceback (most recent call last):
File "/Users/eriktzschoppe/Documents/Masterarbeit/datengenerierung/pipeline.py", line 104, in
bp.object.sample_poses(instrument_model, sample_pose_func=sample_pose)
File "/Users/eriktzschoppe/BlenderProc/blenderproc/python/object/ObjectPoseSampler.py", line 76, in sample_poses
no_collision = CollisionUtility.check_intersections(obj, bvh_cache, cur_objects_to_check_collisions, [])
File "/Users/eriktzschoppe/BlenderProc/blenderproc/python/utility/CollisionUtility.py", line 50, in check_intersections
intersection, bvh_cache = CollisionUtility.check_mesh_intersection(obj, collision_obj,
File "/Users/eriktzschoppe/BlenderProc/blenderproc/python/utility/CollisionUtility.py", line 162, in check_mesh_intersection
inter = CollisionUtility.is_point_inside_object(obj1, obj1_BVHtree,
File "/Users/eriktzschoppe/BlenderProc/blenderproc/python/utility/CollisionUtility.py", line 199, in is_point_inside_object
p2 = nearest - point
AttributeError: Vector subtraction: (NoneType - Vector) invalid type for this operation

Thanks!

Minimal code example

import blenderproc as bp
import numpy as np
import bpy
import os

bp.init()

def load_blender_files_from_path(data_path):
    instruments = []
    file_name = []

    for name in os.listdir(data_path):

        if name.endswith(".blend"):
            file_name.append(os.path.join(data_path, name)) 
    
    for i in range(len(file_name)):
        objs = file_name[i]
        tmp = bp.loader.load_blend(objs, obj_types=['MESH'])

        checker = False
        for parts in tmp:
            if 'part' in parts.get_name():
                checker = True 
        print(checker)
        if checker is True:
            for counter, parts in enumerate(tmp):
                if 'part' in parts.get_name():
                    tmp_move_part = counter
                elif 'part' and 'kp' not in parts.get_name():
                    tmp_rigid_part = counter
                if 'nadel_halter' in parts.get_name():
                    max_rotation = 15
                else:
                    max_rotation = 55
            rotation = 30 #np.random.uniform(0, max_rotation, 1)

            tmp[tmp_move_part].set_rotation_euler([0, 0, np.deg2rad(rotation)])
            # get all parent objects
            key_points = tmp[tmp_move_part].get_children()
            for key_point in key_points:
                # set new parent to rigid part
                key_point.set_parent(tmp[tmp_rigid_part])
            tmp[tmp_rigid_part].join_with_other_objects([tmp[tmp_move_part]])

            instruments.extend([tmp[tmp_rigid_part]])
        else:
            for counter, parts in enumerate(tmp):
                if 'kp' not in parts.get_name():
                    adult_id = counter
            key_points = tmp[adult_id].get_children()
            for key_point in key_points:
                key_point.set_parent(tmp[adult_id])
            instruments.extend([tmp[adult_id]])

    return instruments

def sample_pose(obj: bp.types.MeshObject):
    obj.set_location(np.random.uniform([-0.05, -0.05, 0], [0.05, 0.05, 0]))
    obj.set_rotation_euler(bp.sampler.uniformSO3())

instrument_model = load_blender_files_from_path(data_path)

bp.object.sample_poses(instrument_model, sample_pose_func=sample_pose)

Files required to run the code

Archiv.zip

Expected behavior

Place the objects without collision.

BlenderProc version

2.7.0

@ErikDerGute ErikDerGute added the question Question, not yet a bug ;) label Feb 12, 2024
@ErikDerGute
Copy link
Author

Edit: Maybe I forgot to mention that also with the param "objects_to_check_collisions" set to the child objects it doesn't work.

@tsrobcvai
Copy link

tsrobcvai commented Apr 9, 2024

I also met this problem. Hi, have you figured out the solution? Thanks!

@ErikDerGute
Copy link
Author

ErikDerGute commented Apr 9, 2024

Hi, unfortunately not really, but there's a quick and dirty workaround. As the child objects are paired to the corresponding parent object, there is no need to set the location separately. My workaround was to simply skip the child objects inside the function. In my case I know the names of my child objects, so is just customized the function like:

    for obj in objects_to_sample:
        if 'kp' in obj.get_name():
            continue
        # Store the obejct's initial pose in case we need to place it back
        if mode_on_failure == 'initial_pose':
            initial_location = obj.get_location()
            initial_rotation = obj.get_rotation_euler()

in ObjectPoseSample.py line 54. If you don't know your child object names, it should also be possible to do something like:
if obj is "child object" -> continue.
Hope this is useful for you.

@cornerfarmer
Copy link
Member

Hey @ErikDerGute,

I think the main problem at least with the example you gave in your initial post is that you are using objects with no volume (the circle) which are not supported by blenders collision check.
If the circle should not take part in the collision checks at all, then I recommend to remove it from the objects_to_sample and also the objects_to_check_collisions parameter.

@ErikDerGute
Copy link
Author

Thanks for your reply. As I said in my previous edit I removed the child objects from the objects_to_check_collisions and also only sample the parent objects. Maybe I did something wrong back then. Regardless of this it's not a problem for me anymore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question, not yet a bug ;)
Projects
None yet
Development

No branches or pull requests

3 participants