diff --git a/pkgs/development/python-modules/bpycv/bpycv-test.py b/pkgs/development/python-modules/bpycv/bpycv-test.py new file mode 100644 index 000000000000..94e1bb122c77 --- /dev/null +++ b/pkgs/development/python-modules/bpycv/bpycv-test.py @@ -0,0 +1,76 @@ +# based on https://github.com/DIYer22/bpycv/blob/c576e01622d87eb3534f73bf1a5686bd2463de97/example/ycb_demo.py +import bpy +import bpycv + +import os +import glob +import random + +example_data_dir = os.environ['BPY_EXAMPLE_DATA'] + +models = sorted(glob.glob(os.path.join(example_data_dir, "model", "*", "*.obj"))) +cat_id_to_model_path = dict(enumerate(sorted(models), 1)) + +distractors = sorted(glob.glob(os.path.join(example_data_dir, "distractor", "*.obj"))) + +bpycv.clear_all() +bpy.context.scene.frame_set(1) +bpy.context.scene.render.engine = "CYCLES" +bpy.context.scene.cycles.samples = 32 +bpy.context.scene.render.resolution_y = 1024 +bpy.context.scene.render.resolution_x = 1024 + +# A transparency stage for holding rigid body +stage = bpycv.add_stage(transparency=True) + +bpycv.set_cam_pose(cam_radius=1, cam_deg=45) + +hdri_dir = os.path.join(example_data_dir, "background_and_light") +hdri_manager = bpycv.HdriManager( + hdri_dir=hdri_dir, download=False +) # if download is True, will auto download .hdr file from HDRI Haven +hdri_path = hdri_manager.sample() +bpycv.load_hdri_world(hdri_path, random_rotate_z=True) + +# load 5 objects +for index in range(5): + cat_id = random.choice(list(cat_id_to_model_path)) + model_path = cat_id_to_model_path[cat_id] + obj = bpycv.load_obj(model_path) + obj.location = ( + random.uniform(-0.2, 0.2), + random.uniform(-0.2, 0.2), + random.uniform(0.1, 0.3), + ) + obj.rotation_euler = [random.uniform(-3.1415, 3.1415) for _ in range(3)] + # set each instance a unique inst_id, which is used to generate instance annotation. + obj["inst_id"] = cat_id * 1000 + index + with bpycv.activate_obj(obj): + bpy.ops.rigidbody.object_add() + +# load 6 distractors +for index in range(6): + distractor_path = random.choice(distractors) + target_size = random.uniform(0.1, 0.3) + distractor = bpycv.load_distractor(distractor_path, target_size=target_size) + distractor.location = ( + random.uniform(-0.2, 0.2), + random.uniform(-0.2, 0.2), + random.uniform(0.1, 0.3), + ) + distractor.rotation_euler = [random.uniform(-3.1415, 3.1415) for _ in range(3)] + with bpycv.activate_obj(distractor): + bpy.ops.rigidbody.object_add() + +# run pyhsic engine for 20 frames +for i in range(20): + bpy.context.scene.frame_set(bpy.context.scene.frame_current + 1) + +# render image, instance annoatation and depth in one line code +result = bpycv.render_data() + +dataset_dir = "./dataset" +result.save(dataset_dir=dataset_dir, fname="0", save_blend=True) +print(f'Save to "{dataset_dir}"') +print(f'Open "{dataset_dir}/vis/" to see visualize result.') + diff --git a/pkgs/development/python-modules/bpycv/default.nix b/pkgs/development/python-modules/bpycv/default.nix new file mode 100644 index 000000000000..7a88a4078f0b --- /dev/null +++ b/pkgs/development/python-modules/bpycv/default.nix @@ -0,0 +1,62 @@ +{ lib +, buildPythonPackage +, fetchPypi +, fetchFromGitHub +, fetchurl +, writeText +, blender +, minexr +, beautifulsoup4 +, zcs +, requests +, opencv3 +, boxx +}: + +buildPythonPackage rec { + pname = "bpycv"; + version = "0.2.43"; + + src = fetchPypi { + inherit pname version; + sha256 = "sha256-6LXhKuNkX3yKeZARLXmOVNAUQhJghtzKhnszJ1G/a8U="; + }; + + propagatedBuildInputs = [ + beautifulsoup4 + minexr + zcs + requests + opencv3 + boxx + ]; + + postPatch = '' + sed -i 's/opencv-python//g' requirements.txt + ''; + + # pythonImportsCheck = [ "bpycv" ]; # this import depends on bpy that is only available inside blender + checkInputs = [ blender ]; + checkPhase = let + bpycv_example_data = fetchFromGitHub { + owner = "DIYer22"; + repo = "bpycv_example_data"; + sha256 = "sha256-dGb6KvbXTGTu5f4AqhA+i4AwTqBoR5SdXk0vsMEcD3Q="; + rev = "6ce0e65c107d572011394da16ffdf851e988dbb4"; + }; + in '' + TEMPDIR=$(mktemp -d) + pushd $TEMPDIR + cp -r ${bpycv_example_data} example_data + chmod +w -R example_data + BPY_EXAMPLE_DATA=${bpycv_example_data} blender -b -P ${./bpycv-test.py} + popd + ''; + + meta = with lib; { + description = "Computer vision utils for Blender"; + homepage = "https://github.com/DIYer22/bpycv"; + license = licenses.mit; + maintainers = with maintainers; [ lucasew ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 6ab59cdf54a6..01455f9c9c29 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -1302,6 +1302,8 @@ in { bottleneck = callPackage ../development/python-modules/bottleneck { }; + bpycv = callPackage ../development/python-modules/bpycv {}; + bpython = callPackage ../development/python-modules/bpython { }; braceexpand = callPackage ../development/python-modules/braceexpand { };