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

[BUG]: enable_rigidbody() for convex decomposition takes extremely long #632

Closed
Sodek93 opened this issue Jul 27, 2022 · 17 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@Sodek93
Copy link

Sodek93 commented Jul 27, 2022

Describe the bug

When using MeshObjectUtility.build_convex_decomposition_collision_shape() the runtime for any simulation increases exponentially.

General Information

  1. 2.3.0, updated 27/07/22 - branch: https://github.com/DLR-RM/BlenderProc/tree/test_decompose_with_caching

  2. On which operating system are you?
    Linux

  3. Have you checked the issue tracker to see if a similar issue has been opened?
    Yes

  4. Have you changed BlenderProc in any way besides the config file? If yes, are you sure that this change does not affect the problem you are having?
    Added custom modules to Blenderproc, didn't change anything in blenderproc itself.

To Reproduce
Steps to reproduce the behavior:

  1. Provide the full command you used to run BlenderProc:

blenderproc run script.py

  1. Provide the full python file, you used:
import blenderproc as bproc
import time

start=time.time()
obj_list=[]
cached_objects={}

##generating objects
for i in range(50):
    obj=bproc.loader.load_obj(("MUG.obj"),cached_objects)
    obj_list.append(obj[0])

##do convex_decomposition for objects
for i in range(50):
    obj_list[i].build_convex_decomposition_collision_shape("convex_decomposition",cached_objects=cached_objects)

print(time.time()-start)


  1. Provide a link to all 3D models you used, if they are from one of the publicly available supported datasets, provide the name or path so that it is possible to reproduce the error.
    happens for all .obj files (MUG.obj is attached)

Expected behavior
Using enable_rigidbody() shouldn't increase the runtime of the script by 30 times. ( See Additional context )

Additional context
While trying to figure out what slows my simulation down to 1000 sec(with convex decomposition) from about 30 sec(without convex decomposition) i found out that it is the line part.enable_rigidbody in MeshObjectUtility.build_convex_decomposition_collision_shape().
Unexpectedly this mostly comes from the line 241 in MeshObjectUtility.py, which calls:

part.enable_rigidbody(True,"CONVEX_HULL")

If i comment this line out my script runtime goes from 1000sec to 30 sec. But the convex shapes become useless obviously... ;-)

MUG_DATA.zip

@Sodek93 Sodek93 added the bug Something isn't working label Jul 27, 2022
@themasterlink
Copy link
Contributor

Hey,

@cornerfarmer what do you think if we change the duplicate function to include the children as well, this should be fixed, right?

Best,
Max

@cornerfarmer
Copy link
Member

It seems that its more the fault of the rigid body component. I am gonna take a look at it, if it can be included in the duplication or what exactly is taking so long when enabling it.

@cornerfarmer
Copy link
Member

So the rigid body component is already duplicated when duplicating its object. So, @themasterlink, you are right, duplicating children inside the duplicate function should solve this issue.

@cornerfarmer
Copy link
Member

Hey @Sodek93,

could you check whether #633 helps you?
When now duplicating the object after loading and enabling the rigid body element, the whole code only takes about 2.6s for me:

import blenderproc as bproc
import time

start=time.time()

obj = bproc.loader.load_obj(("examples/basics/basic/MUG.obj"))[0]
obj.enable_rigidbody(active=False, collision_shape="COMPOUND")
obj.build_convex_decomposition_collision_shape("convex_decomposition")

obj_list=[obj]
for i in range(50):
    obj_list.append(obj.duplicate())

print(time.time()-start)

@cornerfarmer cornerfarmer self-assigned this Jul 27, 2022
@themasterlink
Copy link
Contributor

Looks perfect :) Thanks @cornerfarmer

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

Hey @Sodek93,

could you check whether #633 helps you? When now duplicating the object after loading and enabling the rigid body element, the whole code only takes about 2.6s for me:

import blenderproc as bproc
import time

start=time.time()

obj = bproc.loader.load_obj(("examples/basics/basic/MUG.obj"))[0]
obj.enable_rigidbody(active=False, collision_shape="COMPOUND")
obj.build_convex_decomposition_collision_shape("convex_decomposition")

obj_list=[obj]
for i in range(50):
    obj_list.append(obj.duplicate())

print(time.time()-start)

I'll test right right away! Thank you guys :-)

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

This helped a lot and it is working as expected. Got my script runtime (more complex script) from about 1000 s to 300 s, which is obviously a huge step :-)

I'll investigate why my runtime goes down to 25s if i comment out following lines which are called in the for loop:

if [obj] in list(cached_objects.values()): #only do if object isn't a copy of already existing objects
  obj.enable_rigidbody(active=True, collision_shape="COMPOUND")
  obj.blend_obj.build_convex_decomposition_collision_shape("convex_decomposition")

@themasterlink
Copy link
Contributor

Hey,

can't you do this before you copy the object?

Best,
Max

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

Yes i can.

Testing need some time. I now have the problem that my object and its convex parts are not at the same position.
This could be an issue of my code, and not the solution you provided.

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

I need to use this command to clear parent of object but keep the position as [0,0,0]:

bpy.ops.object.parent_clear(type="CLEAR_KEEP_TRANSFORM")

If i rotate the object before using that command the convex decomposition parts are not alligned with die object itself. If i do it afterwards i have the problem that i have to rotate all parts of the convex decomposition after duplication.

@cornerfarmer
Copy link
Member

Can you please post a complete code example, so we can reproduce that?

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

I'll write a code that reproduces that.

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

nvm: i got the issue fixed with just rotation and position of the duplicated convex decompositions and the new Part to [0,0,0] before doing anything else with them.

This could be added into the duplicate() function but maybe won't be used by most other users.

def duplicate(self, duplicate_children: bool = True) -> "MeshObject":
        """ Duplicates the object.
        :param duplicate_children: If True, also all children objects are recursively duplicated.
        :return: A new mesh object, which is a duplicate of this object.
        """
        new_entity = self.blender_obj.copy()
        new_entity.data = self.blender_obj.data.copy()
        bpy.context.collection.objects.link(new_entity)

        duplicate_obj = MeshObject(new_entity)

        duplicate_obj.set_location([0,0,0])
        duplicate_obj.set_rotation_euler([0,0,0])

        if duplicate_children:
            for child in self.get_children():
                duplicate_child = child.duplicate(duplicate_children=duplicate_children)
                duplicate_child.set_parent(duplicate_obj)


        return duplicate_obj 

Is there a way to use bpy in the script i run with blenderproc cli? I cant give you a code that reproduces the issue without it.

@Sodek93
Copy link
Author

Sodek93 commented Jul 28, 2022

Hey @Sodek93,

could you check whether #633 helps you? When now duplicating the object after loading and enabling the rigid body element, the whole code only takes about 2.6s for me:

import blenderproc as bproc
import time

start=time.time()

obj = bproc.loader.load_obj(("examples/basics/basic/MUG.obj"))[0]
obj.enable_rigidbody(active=False, collision_shape="COMPOUND")
obj.build_convex_decomposition_collision_shape("convex_decomposition")

obj_list=[obj]
for i in range(50):
    obj_list.append(obj.duplicate())

print(time.time()-start)

The example upside works fine for me too,also takes 2.6 sec with 50 Objects, 36 sec for 200.

I realized that runtime still exponentially increases the more objects i have in scene... But it's now down to 500 sec (with about 50 mugs) after fixing the positioning issue. I'll check whats the difference between my code and the provided solution.

I'll provide an reproducing example tomorrow. If i skip copying the childs (convex parts) i am still down to 26 sec.

@Sodek93
Copy link
Author

Sodek93 commented Jul 29, 2022

I can't reproduce the issue for now... Can you keep this open so if i found a solution / can reproduce it i can post here? Otherwise i can start a new discussion if i found out what slows my runtime down so much more then in the given example.

@cornerfarmer
Copy link
Member

Hey @Sodek93,

I think i was able to reproduce the misalignment problem you describe. The convex child objects seemed to be misaligned, if the object's pose is changed after its convex decomposition and before duplicating it.

I updated the #633 PR respectively, so now it should work in all cases.

Regarding your still persisting performance issue: For now I will keep this issue open, so let us know if you can reproduce it.

@themasterlink
Copy link
Contributor

I assume this has been resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants