diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..4078c8f1f --- /dev/null +++ b/.clang-format @@ -0,0 +1,2 @@ +BasedOnStyle: Microsoft +ColumnLimit: 100 \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ddf7c6972..bbf4a3f8e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,4 +19,4 @@ infinigen/assets/fluid/* @karhankayan # Jerry will review all object assets except where specified below infinigen/assets/objects/* @JerryLingjieMei infinigen/assets/objects/creatures/* @araistrick -infinigen/assets/objects/trees/* @araistrick \ No newline at end of file +infinigen/assets/objects/trees/* @araistrick diff --git a/.gitmodules b/.gitmodules index 1534b356f..d6b7f095b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,18 +10,9 @@ [submodule "infinigen/datagen/customgt/dependencies/cnpy"] path = infinigen/datagen/customgt/dependencies/cnpy url = https://github.com/rogersce/cnpy.git -[submodule "infinigen/datagen/customgt/dependencies/indicators"] - path = infinigen/datagen/customgt/dependencies/indicators - url = https://github.com/p-ranav/indicators.git -[submodule "infinigen/datagen/customgt/dependencies/tinycolormap"] - path = infinigen/datagen/customgt/dependencies/tinycolormap - url = https://github.com/yuki-koyama/tinycolormap.git [submodule "infinigen/datagen/customgt/dependencies/glm"] path = infinigen/datagen/customgt/dependencies/glm url = https://github.com/g-truc/glm.git -[submodule "infinigen/datagen/customgt/dependencies/fast_obj"] - path = infinigen/datagen/customgt/dependencies/fast_obj - url = https://github.com/thisistherk/fast_obj.git [submodule "infinigen/datagen/customgt/dependencies/json"] path = infinigen/datagen/customgt/dependencies/json url = https://github.com/nlohmann/json.git diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f65c40263..032e3eda0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -106,3 +106,10 @@ v1.8.1 - Fix silent output from upload stage, remove export from upload - Reduce solving time spent on small objects +v1.8.2 +- Remove nonessential opengl_gt packages +- Fix CrabFactory crash, FruitContainerFactory unparent object, wall parts +- Fix nature particles not visible in render +- Add smbpy du and df commands +- Fix fineterrain not included in export for optimize_diskusage=True +- Update mesher_backend config name & default commands diff --git a/docs/ConfiguringInfinigen.md b/docs/ConfiguringInfinigen.md index b2a35e5e4..392a5abfc 100644 --- a/docs/ConfiguringInfinigen.md +++ b/docs/ConfiguringInfinigen.md @@ -172,7 +172,8 @@ We recommend this command as a starting point for generating high quality videos ```bash python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \ --pipeline_config slurm monocular_video cuda_terrain opengl_gt \ - --cleanup big_files --warmup_sec 60000 --config trailer_video high_quality_terrain + --cleanup big_files --warmup_sec 60000 --config trailer_video high_quality_terrain \ + -p fine_terrain.mesher_backend="OcMesher" ``` #### Creating large-scale stereo datasets @@ -219,7 +220,8 @@ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \ --pipeline_config slurm monocular_video cuda_terrain opengl_gt \ --cleanup big_files --warmup_sec 30000 --config trailer_video high_quality_terrain \ - --overrides camera.camera_pose_proposal.altitude=["uniform", 20, 30] + --overrides camera.camera_pose_proposal.altitude=["uniform", 20, 30] \ + -p fine_terrain.mesher_backend="OcMesher" ``` :bulb: The command shown is overriding `infinigen_examples/configs_nature/base.gin`'s default setting of `camera.camera_pose_proposal.altitude`. You can use a similar syntax to override any number of .gin config entries. Separate multiple entries with spaces. @@ -229,7 +231,8 @@ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_ python -m infinigen.datagen.manage_jobs --output_folder outputs/my_videos --num_scenes 500 \ --pipeline_config slurm monocular_video cuda_terrain opengl_gt \ --cleanup big_files --warmup_sec 30000 --config trailer_video high_quality_terrain \ - --pipeline_overrides iterate_scene_tasks.frame_range=[1,25] + --pipeline_overrides iterate_scene_tasks.frame_range=[1,25] \ + -p fine_terrain.mesher_backend="OcMesher" ``` :bulb: This command uses `--pipeline_overrides` rather than `--overrides` since it is providing a gin override to the `manage_jobs.py` process, not some part of the main `infinigen_examples/generate_nature.py` driver. diff --git a/infinigen/__init__.py b/infinigen/__init__.py index 6802bdf7d..607bf390c 100644 --- a/infinigen/__init__.py +++ b/infinigen/__init__.py @@ -6,7 +6,7 @@ import logging from pathlib import Path -__version__ = "1.8.1" +__version__ = "1.8.2" def repo_root(): diff --git a/infinigen/assets/objects/creatures/parts/crustacean/body.py b/infinigen/assets/objects/creatures/parts/crustacean/body.py index ddda30ce1..46dad76ff 100644 --- a/infinigen/assets/objects/creatures/parts/crustacean/body.py +++ b/infinigen/assets/objects/creatures/parts/crustacean/body.py @@ -60,7 +60,7 @@ def make_part(self, params) -> Part: displace_vertices(obj, lambda x, y, z: (0, 0, height_scale(x / x_length))) self.add_head(obj, params) - line = new_line(x_length) + line = new_line(1, x_length) line.location[0] -= x_length butil.apply_transform(line, loc=True) diff --git a/infinigen/assets/objects/tableware/fruit_container.py b/infinigen/assets/objects/tableware/fruit_container.py index 09ced21c1..9012d6d2b 100644 --- a/infinigen/assets/objects/tableware/fruit_container.py +++ b/infinigen/assets/objects/tableware/fruit_container.py @@ -41,7 +41,7 @@ def __init__(self, factory_seed=0): def apply(self, obj, selection=None): for obj in obj if isinstance(obj, Iterable) else [obj]: scale = uniform(0.06, 0.08) / self.shrink_rate - scatter_instances( + scattered = scatter_instances( base_obj=obj, collection=self.col, density=1e3, @@ -53,6 +53,7 @@ def apply(self, obj, selection=None): apply_geo=True, realize=True, ) + scattered.parent = obj class FruitContainerFactory(AssetFactory): diff --git a/infinigen/assets/scatters/ivy.py b/infinigen/assets/scatters/ivy.py index 4f57cfc59..310a43f0c 100644 --- a/infinigen/assets/scatters/ivy.py +++ b/infinigen/assets/scatters/ivy.py @@ -102,10 +102,14 @@ def apply(self, obj, selection=None): ) def end_index(nw): + if len(scatter_obj.data.vertices) == 0: + i = 0 + else: + i = np.random.randint(len(scatter_obj.data.vertices)) return nw.compare( "EQUAL", nw.new_node(Nodes.Index), - np.random.randint(len(scatter_obj.data.vertices)), + i, ) def weight(nw): @@ -135,7 +139,9 @@ def weight(nw): input_args=[end_index, weight, uniform(0.1, 0.15), uniform(0.1, 0.15)], ) fix_tree(scatter_obj) + surface.add_geomod(scatter_obj, geo_radius, apply=True, input_args=[0.005, 12]) + assign_material(scatter_obj, shaderfunc_to_material(shader_simple_brown)) surface.add_geomod(scatter_obj, geo_leaf, apply=True, input_args=[self.col]) diff --git a/infinigen/assets/weather/particles.py b/infinigen/assets/weather/particles.py index 463bb3835..300ebec1b 100644 --- a/infinigen/assets/weather/particles.py +++ b/infinigen/assets/weather/particles.py @@ -37,7 +37,9 @@ def spawn_emitter(follow_cam, mesh_type, size, offset, name=None): emitter.name = f"emitter({name=}, {mesh_type=})" emitter.hide_viewport = True - emitter.hide_render = True + emitter.hide_render = True # will be undone if any particle systems are added + + butil.put_in_collection(emitter, butil.get_collection("particles")) return emitter @@ -156,9 +158,12 @@ def generate( emitter, col, self.params, collision ) + system.name = repr(self) + system.settings.name = repr(self) + ".settings" + emitter.hide_render = False + logger.info(f"{self} baking particles") - particles.bake(emitter, system) - butil.put_in_collection(emitter, butil.get_collection("particles")) + particles.bake(emitter, system) return emitter diff --git a/infinigen/core/constraints/example_solver/annealing.py b/infinigen/core/constraints/example_solver/annealing.py index 71fc4ff93..7074a3a0d 100644 --- a/infinigen/core/constraints/example_solver/annealing.py +++ b/infinigen/core/constraints/example_solver/annealing.py @@ -63,6 +63,7 @@ def __init__( self.last_eval_result = None self.eval_memo = {} + self.stats = [] def save_stats(self, path): if len(self.stats) == 0: @@ -76,7 +77,7 @@ def save_stats(self, path): fig, ax1 = plt.subplots() ax1.set_xlabel("Iteration") ax1.set_ylabel("Score", color="C0") - ax1.plot(df["curr_iteration"], df["loss"], color="C0") + ax1.plot(np.arange(len(df)), df["loss"], color="C0") # ax2 = ax1.twinx() # ax2.set_ylabel('Move Time', color='C1') @@ -91,7 +92,6 @@ def save_stats(self, path): def reset(self, max_iters): self.curr_iteration = 0 - self.stats = [] self.curr_result = None self.best_loss = None self.eval_memo = {} diff --git a/infinigen/core/constraints/example_solver/room/decorate.py b/infinigen/core/constraints/example_solver/room/decorate.py index 1dc831721..b77a826a3 100644 --- a/infinigen/core/constraints/example_solver/room/decorate.py +++ b/infinigen/core/constraints/example_solver/room/decorate.py @@ -276,15 +276,30 @@ def room_walls(walls: list[bpy.types.Object], constants: RoomConstants, n_walls= i = np.argmax( read_edge_length(w) - 100 * (np.abs(co[u, -1] - co[v, -1]) > 0.1) ) - center = read_center(w)[:, :2] - u_ = co[np.newaxis, u[i], :2] - v_ = co[np.newaxis, v[i], :2] - alternative = ( - np.linalg.norm(center - u_, axis=-1) - + np.linalg.norm(center - v_, axis=-1) - - np.linalg.norm(u_ - v_, axis=-1) - < 0.1 + u_ = co[u[i]] + v_ = co[v[i]] + non_vertical = np.linalg.norm((co[u] - co[v])[:, :2], axis=-1) > 1e-2 + directional = ( + np.abs(np.cross((co[u] - co[v])[:, :2], (u_ - v_)[np.newaxis, :2])) + < 1e-4 ) + collinear = ( + np.abs(np.cross((co[u] - v_)[:, :2], (u_ - v_)[np.newaxis, :2])) + < 1e-4 + ) + collinear_ = ( + np.abs(np.cross((co[u] - u_)[:, :2], (u_ - v_)[np.newaxis, :2])) + < 1e-4 + ) + aligned = non_vertical & directional & collinear & collinear_ + with butil.ViewportMode(w, "EDIT"): + bm = bmesh.from_edit_mesh(w.data) + bm.faces.ensure_lookup_table() + alternative = np.zeros(len(bm.faces), dtype=int) + for f in bm.faces: + for e in f.edges: + if aligned[e.index]: + alternative[f.index] = 1 write_attr_data( w, "alternative", alternative, type="INT", domain="FACE" ) diff --git a/infinigen/core/constraints/example_solver/solve.py b/infinigen/core/constraints/example_solver/solve.py index 117ed6e37..f060c327a 100644 --- a/infinigen/core/constraints/example_solver/solve.py +++ b/infinigen/core/constraints/example_solver/solve.py @@ -189,7 +189,6 @@ def solve_objects( for j in ra: move_gen = self.choose_move_type(moves, j, n_steps) self.optim.step(consgraph, self.state, move_gen, filter_domain) - self.optim.save_stats(self.output_folder / f"optim_{desc}.csv") logger.info( f"Finished solving {desc_full}, added {len(self.state.objs) - n_start} " diff --git a/infinigen/core/execute_tasks.py b/infinigen/core/execute_tasks.py index b34f33f03..ba1755f61 100644 --- a/infinigen/core/execute_tasks.py +++ b/infinigen/core/execute_tasks.py @@ -308,7 +308,7 @@ def execute_tasks( col.hide_viewport = False if need_terrain_processing and ( - Task.Render in task or Task.GroundTruth in task or Task.MeshSave in task + Task.Render in task or Task.GroundTruth in task or Task.MeshSave in task or Task.Export in task ): terrain = Terrain( scene_seed, diff --git a/infinigen/core/placement/particles.py b/infinigen/core/placement/particles.py index 2b82609e9..00b6f9489 100644 --- a/infinigen/core/placement/particles.py +++ b/infinigen/core/placement/particles.py @@ -22,6 +22,9 @@ def bake(emitter, system): logger.info(f"Baking particles for {emitter.name=}") + hide_orig = emitter.hide_viewport + emitter.hide_viewport = False + with butil.SelectObjects(emitter): override = { "scene": bpy.context.scene, @@ -33,6 +36,8 @@ def bake(emitter, system): bpy.ops.ptcache.bake(override, bake=True) bpy.context.scene.frame_end -= 1 + emitter.hide_viewport = hide_orig + def configure_boids(system_config, settings): boids = system_config.boids @@ -92,10 +97,8 @@ def particle_system( if isinstance(subject, bpy.types.Collection): subject = as_particle_collection(subject) - emitter.name = f"particles:emitter({subject.name.split(':')[-1]})" - mod = emitter.modifiers.new(name="PARTICLE", type="PARTICLE_SYSTEM") - system = emitter.particle_systems[mod.name] + system = mod.particle_system emitter.show_instancer_for_viewport = False emitter.show_instancer_for_render = False diff --git a/infinigen/core/util/pipeline.py b/infinigen/core/util/pipeline.py index 5aba3e4ac..5b0d3e1a0 100644 --- a/infinigen/core/util/pipeline.py +++ b/infinigen/core/util/pipeline.py @@ -37,6 +37,7 @@ def _should_run_stage(self, name, use_chance, prereq): if not e["ran"]: logger.info(f"Skipping run_stage({name}...) due to unmet {prereq=}") return + with FixedSeed(int_hash((self.scene_seed, name, 0))): if not self.params.get(f"{name}_enabled", True): logger.debug(f"Not running {name} due to manually set not enabled") diff --git a/infinigen/datagen/customgt/CMakeLists.txt b/infinigen/datagen/customgt/CMakeLists.txt index c14932ba0..cbef0d7fb 100644 --- a/infinigen/datagen/customgt/CMakeLists.txt +++ b/infinigen/datagen/customgt/CMakeLists.txt @@ -7,20 +7,16 @@ endif() add_definitions(-D GLM_ENABLE_EXPERIMENTAL) add_definitions(-D PROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}) +include_directories(include/) include_directories(/usr/include/) # on linux include_directories(dependencies) # for cnpy -include_directories(dependencies/indicators/include) include_directories(dependencies/argparse/include) include_directories(dependencies/eigen) -include_directories(dependencies/tinycolormap/include) include_directories(dependencies/glm) include_directories(dependencies/json/single_include) include_directories(dependencies/glad/include) -include_directories(dependencies/scharstein_flow_viz) add_subdirectory(dependencies/cnpy) -add_subdirectory(dependencies/fast_obj) -add_subdirectory(dependencies/tinycolormap) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -39,17 +35,14 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") find_package(OpenGL REQUIRED COMPONENTS OpenGL EGL GLX) endif() -file(GLOB ADJACENT_SRC_FILES - "*.hpp" - "*.cpp" -) +file(GLOB ADJACENT_SRC_FILES "src/*.cpp") # This line was taken from https://stackoverflow.com/a/52137618/5057543 if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") link_libraries(stdc++fs) endif() -add_executable(customgt ${ADJACENT_SRC_FILES} dependencies/scharstein_flow_viz/colorcode.cpp dependencies/fast_obj/fast_obj.h dependencies/fast_obj/fast_obj.c dependencies/glad/src/glad.c dependencies/glad/src/glad_egl.c) +add_executable(customgt main.cpp ${ADJACENT_SRC_FILES} dependencies/glad/src/glad.c dependencies/glad/src/glad_egl.c) set_property(TARGET customgt PROPERTY CXX_STANDARD 17) diff --git a/infinigen/datagen/customgt/blender_object.cpp b/infinigen/datagen/customgt/blender_object.cpp deleted file mode 100644 index 12e9dbfd0..000000000 --- a/infinigen/datagen/customgt/blender_object.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. - -// Authors: Lahav Lipson - -#include "blender_object.hpp" -#include -#include -#include -#include -#include -#include -#include "utils.hpp" -#include "buffer_arrays.hpp" -using std::cout; -using std::endl; - -template -void set_regular_buffer(unsigned int &buffer, const std::vector &data_vec, int attrib_idx, int attrib_size, int attrib_stride){ - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, data_vec.size() * sizeof(T), data_vec.data(), GL_STATIC_DRAW); - - glEnableVertexAttribArray(attrib_idx); - static_assert(std::is_same::value || std::is_same::value); - if constexpr (std::is_same::value) - glVertexAttribPointer(attrib_idx, attrib_size, GL_FLOAT, GL_FALSE, attrib_stride * sizeof(T), 0); - else if constexpr (std::is_same::value) - glVertexAttribIPointer(attrib_idx, attrib_size, GL_INT, attrib_stride * sizeof(T), 0); -} - -void BaseBlenderObject::set_matrix_buffer(unsigned int &buffer, const std::vector &model_matrices_next, int attrib_idx){ - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), model_matrices_next.data(), GL_STATIC_DRAW); - - // vertex attributes - std::size_t vec4Size = sizeof(Eigen::RowVector4f); - for (int ii=0; ii<4; ii++){ - glEnableVertexAttribArray(ii+attrib_idx); - glVertexAttribPointer(ii+attrib_idx, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(ii * vec4Size)); - } - - for (int ii=0; ii<4; ii++) - glVertexAttribDivisor(ii+attrib_idx, 1); -} - -json BaseBlenderObject::compute_bbox(const std::vector &indices, const std::vector &vertex_lookup, const std::vector &instance_ids, const std::vector &model_matrices, const std::vector &tag_lookup, const int &attrib_stride){ - constexpr float inf = std::numeric_limits::infinity(); - Eigen::Vector3f max({-inf, -inf, -inf}), min({inf, inf, inf}); - for (const auto &idx : indices){ - for (int i=0; i<3; i++){ - max(i) = std::max(max(i), vertex_lookup[idx * attrib_stride + i]); - min(i) = std::min(min(i), vertex_lookup[idx * attrib_stride + i]); - } - } - - std::vector> json_serializable_instance_ids(num_instances); - std::vector json_serializable_model_matrices(num_instances); - for (int idx=0; idx unique_tags(tag_lookup.begin(), tag_lookup.end()); - - json output = { - {"instance_ids", json_serializable_instance_ids}, - {"model_matrices", json_serializable_model_matrices}, - {"tags", std::vector(unique_tags.begin(), unique_tags.end())}, - {"name", info.name}, - {"num_verts", info.num_verts}, - {"num_faces", info.num_faces}, - {"children", info.children}, - {"materials", info.materials}, - {"unapplied_modifiers", info.unapplied_modifiers}, - {"object_index", info.index} - }; - - if ((num_verts > 0) && ((max - min).norm() > 1e-4)){ - output["min"] = {min(0), min(1), min(2)}; - output["max"] = {max(0), max(1), max(2)}; - } else { - output["min"] = nullptr; - output["max"] = nullptr; - } - - return output; -} - -BaseBlenderObject::BaseBlenderObject(const BufferArrays ¤t_buf, const BufferArrays &next_buf, const std::vector &instance_ids, const ObjectInfo& object_info, const ObjectType tp, int attrib_stride) - : num_verts(current_buf.indices.size()), type(tp), info(object_info), num_instances(instance_ids.size()) { - - const std::vector &model_matrices = current_buf.get_instances(instance_ids); - const std::vector &model_matrices_next = next_buf.get_instances(instance_ids); - - MRASSERT(model_matrices.size() == num_instances, "Incorrect number of instances"); - MRASSERT(model_matrices_next.size() == num_instances, "Incorrect number of instances"); - const auto t1 = std::chrono::high_resolution_clock::now(); - - const auto &indices = current_buf.indices; - const auto &vertex_lookup = current_buf.lookup; - const auto &vertex_lookup_next = next_buf.lookup; - const auto &tag_lookup = current_buf.tag_lookup; - - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - // Vertices - glGenBuffers(1, &EBO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), indices.data(), GL_STATIC_DRAW); - indices_buf_size = indices.size()*sizeof(unsigned int); - lookup_buf_size = vertex_lookup.size() * sizeof(float); - - set_matrix_buffer(VBO_matrices, model_matrices, 0); - set_matrix_buffer(VBO_matrices_next, model_matrices_next, 4); - - set_regular_buffer(VBO, vertex_lookup, 8, 3, attrib_stride); - set_regular_buffer(VBO_next, vertex_lookup_next, 9, 3, attrib_stride); - - static_assert(sizeof(int)*3 == sizeof(InstanceID)); - glGenBuffers(1, &VBO_instance_ids); - glBindBuffer(GL_ARRAY_BUFFER, VBO_instance_ids); - glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(InstanceID), instance_ids.data(), GL_STATIC_DRAW); - glEnableVertexAttribArray(10); - glVertexAttribIPointer(10, 3, GL_INT, sizeof(InstanceID), 0); - glVertexAttribDivisor(10, 1); - - set_regular_buffer(VBO_tag, tag_lookup, 11, 1, 1); - - total_elapsed_sending += (std::chrono::high_resolution_clock::now() - t1); - num_draw_calls++; - - bounding_box = compute_bbox(indices, vertex_lookup, instance_ids, model_matrices, tag_lookup, attrib_stride); -} - -void BaseBlenderObject::draw(Shader &shader) const { - throw std::runtime_error("Base class draw() called!"); -} - -void BaseBlenderObject::print_stats() { - std::cout << "Spent " << total_elapsed_drawing.count() << "milliseconds in draw calls." << std::endl; - std::cout << "Spent " << total_elapsed_sending.count() << "milliseconds across " << num_draw_calls << " buffer calls." << std::endl; -} - -BaseBlenderObject::~BaseBlenderObject(){ - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, lookup_buf_size, nullptr, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VBO_next); - glBufferData(GL_ARRAY_BUFFER, lookup_buf_size, nullptr, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VBO_matrices); - glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), nullptr, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VBO_matrices_next); - glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), nullptr, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, VBO_instance_ids); - glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(int), nullptr, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_buf_size, nullptr, GL_STATIC_DRAW); - glDeleteVertexArrays(1, &VAO); - unsigned int to_delete[7] = {EBO, VBO, VBO_next, VBO_matrices, VBO_matrices_next, VBO_instance_ids, VBO_tag}; - glDeleteBuffers(7, to_delete); -} - -MeshBlenderObject::MeshBlenderObject(const BufferArrays ¤t_buf, const BufferArrays &next_buf, const std::vector &instance_ids, const ObjectInfo& object_info) - : BaseBlenderObject(current_buf, next_buf, instance_ids, object_info, Mesh, 3) { - glBindVertexArray(0); -} -MeshBlenderObject::~MeshBlenderObject(){} - -void MeshBlenderObject::draw(Shader &shader) const { - const auto t1 = std::chrono::high_resolution_clock::now(); - shader.setInt("object_index", info.index); - glBindVertexArray(VAO); - glDrawElementsInstanced(GL_LINES_ADJACENCY, num_verts, GL_UNSIGNED_INT, 0, num_instances); - glCheckError(); - total_elapsed_drawing += (std::chrono::high_resolution_clock::now() - t1); - glBindVertexArray(0); -} - - -CurvesBlenderObject::CurvesBlenderObject(const BufferArrays ¤t_buf, const BufferArrays &next_buf, const std::vector &instance_ids, const ObjectInfo& object_info) - : BaseBlenderObject(current_buf, next_buf, instance_ids, object_info, Hair, 4){ - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glEnableVertexAttribArray(12); // Radius - glVertexAttribPointer(12, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(sizeof(float)*3)); - glBindVertexArray(0); -} -CurvesBlenderObject::~CurvesBlenderObject(){} - -void CurvesBlenderObject::draw(Shader &shader) const { - const auto t1 = std::chrono::high_resolution_clock::now(); - glBindVertexArray(VAO); - glDrawElementsInstanced(GL_LINES_ADJACENCY, num_verts, GL_UNSIGNED_INT, 0, num_instances); - glCheckError(); - total_elapsed_drawing += (std::chrono::high_resolution_clock::now() - t1); - glBindVertexArray(0); -} diff --git a/infinigen/datagen/customgt/dependencies/fast_obj b/infinigen/datagen/customgt/dependencies/fast_obj deleted file mode 160000 index 85778da5f..000000000 --- a/infinigen/datagen/customgt/dependencies/fast_obj +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 85778da5fc320b7e52885f8e869edc079695cc79 diff --git a/infinigen/datagen/customgt/dependencies/indicators b/infinigen/datagen/customgt/dependencies/indicators deleted file mode 160000 index a5bc05f32..000000000 --- a/infinigen/datagen/customgt/dependencies/indicators +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a5bc05f32a9c719535054b7fa5306ce5c8d055d8 diff --git a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/README.txt b/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/README.txt deleted file mode 100644 index 33812c788..000000000 --- a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/README.txt +++ /dev/null @@ -1,40 +0,0 @@ -Some utilities for reading, writing, and color-coding .flo images - -Daniel Scharstein, 7/2/07 -updated 2/9/08 to fix bug in color_flow.cpp -updated 6/9/09 to make robust to NaN or constant 0 flow (thanks Jan Bouecke) - -See flowIO.cpp for sample code for reading and writing .flo files. -Here's an excerpt from this file describing the flow file format: - -// ".flo" file format used for optical flow evaluation -// -// Stores 2-band float image for horizontal (u) and vertical (v) flow components. -// Floats are stored in little-endian order. -// A flow value is considered "unknown" if either |u| or |v| is greater than 1e9. -// -// bytes contents -// -// 0-3 tag: "PIEH" in ASCII, which in little endian happens to be the float 202021.25 -// (just a sanity check that floats are represented correctly) -// 4-7 width as an integer -// 8-11 height as an integer -// 12-end data (width*height*2*4 bytes total) -// the float values for u and v, interleaved, in row order, i.e., -// u[row0,col0], v[row0,col0], u[row0,col1], v[row0,col1], ... -// - - -Once you have a .flo file, you can create a color coding of it using -color_flow - -Use colortest to visualize the encoding - - -To compile - -cd imageLib -make -cd .. -make -./colortest 10 colors.png diff --git a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.cpp b/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.cpp deleted file mode 100644 index 89f4d08f7..000000000 --- a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// colorcode.cpp -// -// Color encoding of flow vectors -// adapted from the color circle idea described at -// http://members.shaw.ca/quadibloc/other/colint.htm -// -// Daniel Scharstein, 4/2007 -// added tick marks and out-of-range coding 6/05/07 - -#include -#include -typedef unsigned char uchar; - -int ncols = 0; -#define MAXCOLS 60 -int colorwheel[MAXCOLS][3]; - - -void setcols(int r, int g, int b, int k) -{ - colorwheel[k][0] = r; - colorwheel[k][1] = g; - colorwheel[k][2] = b; -} - -void makecolorwheel() -{ - // relative lengths of color transitions: - // these are chosen based on perceptual similarity - // (e.g. one can distinguish more shades between red and yellow - // than between yellow and green) - int RY = 15; - int YG = 6; - int GC = 4; - int CB = 11; - int BM = 13; - int MR = 6; - ncols = RY + YG + GC + CB + BM + MR; - //printf("ncols = %d\n", ncols); - if (ncols > MAXCOLS) - exit(1); - int i; - int k = 0; - for (i = 0; i < RY; i++) setcols(255, 255*i/RY, 0, k++); - for (i = 0; i < YG; i++) setcols(255-255*i/YG, 255, 0, k++); - for (i = 0; i < GC; i++) setcols(0, 255, 255*i/GC, k++); - for (i = 0; i < CB; i++) setcols(0, 255-255*i/CB, 255, k++); - for (i = 0; i < BM; i++) setcols(255*i/BM, 0, 255, k++); - for (i = 0; i < MR; i++) setcols(255, 0, 255-255*i/MR, k++); -} - -void computeColor(float fx, float fy, uchar *pix) -{ - if (ncols == 0) - makecolorwheel(); - - float rad = sqrt(fx * fx + fy * fy); - rad = fminf(rad, 0.999); // Added by Lahav - - float a = atan2(-fy, -fx) / M_PI; - float fk = (a + 1.0) / 2.0 * (ncols-1); - int k0 = (int)fk; - int k1 = (k0 + 1) % ncols; - float f = fk - k0; - //f = 0; // uncomment to see original color wheel - for (int b = 0; b < 3; b++) { - float col0 = colorwheel[k0][b] / 255.0; - float col1 = colorwheel[k1][b] / 255.0; - float col = (1 - f) * col0 + f * col1; - if (rad <= 1) - col = 1 - rad * (1 - col); // increase saturation with radius - else - col *= .75; // out of range - pix[2 - b] = (int)(255.0 * col); - } -} diff --git a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.h b/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.h deleted file mode 100644 index ee99b6b5b..000000000 --- a/infinigen/datagen/customgt/dependencies/scharstein_flow_viz/colorcode.h +++ /dev/null @@ -1,4 +0,0 @@ - -typedef unsigned char uchar; - -void computeColor(float fx, float fy, uchar *pix); diff --git a/infinigen/datagen/customgt/dependencies/tinycolormap b/infinigen/datagen/customgt/dependencies/tinycolormap deleted file mode 160000 index 67198d2b2..000000000 --- a/infinigen/datagen/customgt/dependencies/tinycolormap +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67198d2b2b48ca5e97600c83b5c0f2310cfd4c03 diff --git a/infinigen/datagen/customgt/blender_object.hpp b/infinigen/datagen/customgt/include/blender_object.hpp similarity index 100% rename from infinigen/datagen/customgt/blender_object.hpp rename to infinigen/datagen/customgt/include/blender_object.hpp diff --git a/infinigen/datagen/customgt/buffer_arrays.hpp b/infinigen/datagen/customgt/include/buffer_arrays.hpp similarity index 100% rename from infinigen/datagen/customgt/buffer_arrays.hpp rename to infinigen/datagen/customgt/include/buffer_arrays.hpp diff --git a/infinigen/datagen/customgt/camera_view.hpp b/infinigen/datagen/customgt/include/camera_view.hpp similarity index 100% rename from infinigen/datagen/customgt/camera_view.hpp rename to infinigen/datagen/customgt/include/camera_view.hpp diff --git a/infinigen/datagen/customgt/io.hpp b/infinigen/datagen/customgt/include/io.hpp similarity index 93% rename from infinigen/datagen/customgt/io.hpp rename to infinigen/datagen/customgt/include/io.hpp index 2fa330557..5a4ed68a4 100644 --- a/infinigen/datagen/customgt/io.hpp +++ b/infinigen/datagen/customgt/include/io.hpp @@ -11,9 +11,6 @@ #include #include #include -#include -typedef tinycolormap::ColormapType clrmap; -#include #include "cnpy/cnpy.h" #include diff --git a/infinigen/datagen/customgt/load_blender_mesh.hpp b/infinigen/datagen/customgt/include/load_blender_mesh.hpp similarity index 100% rename from infinigen/datagen/customgt/load_blender_mesh.hpp rename to infinigen/datagen/customgt/include/load_blender_mesh.hpp diff --git a/infinigen/datagen/customgt/shader.hpp b/infinigen/datagen/customgt/include/shader.hpp similarity index 100% rename from infinigen/datagen/customgt/shader.hpp rename to infinigen/datagen/customgt/include/shader.hpp diff --git a/infinigen/datagen/customgt/string_tools.hpp b/infinigen/datagen/customgt/include/string_tools.hpp similarity index 100% rename from infinigen/datagen/customgt/string_tools.hpp rename to infinigen/datagen/customgt/include/string_tools.hpp diff --git a/infinigen/datagen/customgt/utils.hpp b/infinigen/datagen/customgt/include/utils.hpp similarity index 54% rename from infinigen/datagen/customgt/utils.hpp rename to infinigen/datagen/customgt/include/utils.hpp index aace92bff..a334583bc 100644 --- a/infinigen/datagen/customgt/utils.hpp +++ b/infinigen/datagen/customgt/include/utils.hpp @@ -11,9 +11,7 @@ #include #include #include -#include -typedef tinycolormap::ColormapType clrmap; -#include + #include "cnpy/cnpy.h" #include @@ -27,16 +25,9 @@ void glCheckError_(const char *file, int line); class loop_obj { public: const int x, y, j; - const std::shared_ptr progbar; - - loop_obj(int xc, int yc, int jc, std::shared_ptr pb) : x(xc), y(yc), j(jc), progbar(pb) {} - void progressbar() const {if (progbar) progbar->tick();} -}; -Eigen::Tensor compute_flow_viz(const Eigen::Tensor &input_image); + loop_obj(int x, int y, int j) : x(x), y(y), j(j) {} -Eigen::Tensor to_color_map(const Eigen::Tensor &input_image, const double &min_percentile, const double &max_percentile, const double &minval=1e-3, const clrmap &type=clrmap::Jet); - -Eigen::Tensor to_color_map(const Eigen::Tensor &input_image); +}; const std::vector image_iterator(const int width, const int height, const std::string desc=""); \ No newline at end of file diff --git a/infinigen/datagen/customgt/main.cpp b/infinigen/datagen/customgt/main.cpp index fb200361d..8ea128781 100644 --- a/infinigen/datagen/customgt/main.cpp +++ b/infinigen/datagen/customgt/main.cpp @@ -1,36 +1,37 @@ // Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. // Authors: Lahav Lipson - #include #if SYSTEM_NUM == 0 - #include - #include +#include +#include #elif SYSTEM_NUM == 1 - #include +#include #endif +#include + #include +#include #include +#include #include -#include -#include -#include #include -#include -#include #include -#include -#include +#include +#include #include -#include "shader.hpp" +#include + #include "blender_object.hpp" #include "camera_view.hpp" -#include "string_tools.hpp" +#include "io.hpp" #include "load_blender_mesh.hpp" +#include "shader.hpp" +#include "string_tools.hpp" #include "utils.hpp" -#include "io.hpp" #define FLOW 0 #define INVFLOW 1 @@ -43,36 +44,46 @@ using std::cout, std::cerr, std::endl; #if SYSTEM_NUM == 0 static const EGLint configAttribs[] = { - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_DEPTH_SIZE, 8, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + EGL_SURFACE_TYPE, + EGL_PBUFFER_BIT, + EGL_BLUE_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_RED_SIZE, + 8, + EGL_DEPTH_SIZE, + 8, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_BIT, EGL_NONE, - EGL_CONFORMANT, EGL_OPENGL_ES2_BIT, + EGL_CONFORMANT, + EGL_OPENGL_ES2_BIT, }; #elif SYSTEM_NUM == 1 -// glfw: whenever the window size changed (by OS or user resize) this callback function executes +// glfw: whenever the window size changed (by OS or user resize) this callback +// function executes // --------------------------------------------------------------------------------------------- -void framebuffer_size_callback(GLFWwindow* window, int width, int height) +void framebuffer_size_callback(GLFWwindow *window, int width, int height) { - // make sure the viewport matches the new window dimensions; note that width and - // height will be significantly larger than specified on retina displays. + // make sure the viewport matches the new window dimensions; note that width + // and height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } #endif template -std::vector read_buffer(GLenum color_attachment, const int width, const int height){ +std::vector read_buffer(GLenum color_attachment, const int width, const int height) +{ std::vector pixels(width * height * 4); static_assert(std::is_same::value || std::is_same::value); GLint format = 0, type = 0; glReadBuffer(color_attachment); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &format); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &type); - const std::string message = "type=" + std::to_string(type) + " format=" + std::to_string(format); - if constexpr(std::is_same::value) + const std::string message = + "type=" + std::to_string(type) + " format=" + std::to_string(format); + if constexpr (std::is_same::value) MRASSERT((type == GL_FLOAT) && (format == GL_RGBA), message); else MRASSERT((type == GL_INT) && (format == GL_RGBA_INTEGER), message); @@ -84,13 +95,15 @@ std::vector read_buffer(GLenum color_attachment, const int width, const int h #define XSTR(x) STR(x) #define STR(x) #x -bool sortBySecond(const std::pair &a, const std::pair &b) { +bool sortBySecond(const std::pair &a, + const std::pair &b) +{ return a.second < b.second; } -int main(int argc, char *argv[]) { - - const fs::path source_directory = XSTR(PROJECT_SOURCE_DIR) ; +int main(int argc, char *argv[]) +{ + const fs::path source_directory = XSTR(PROJECT_SOURCE_DIR); const auto cpp_path = source_directory / "main.cpp"; assert_exists(cpp_path); std::ifstream t(cpp_path.c_str()); @@ -99,8 +112,11 @@ int main(int argc, char *argv[]) { const auto file_text = buffer.str(); const std::regex regex{"VERSION \\\"([0-9\\.]+)\\\""}; std::smatch m; - if ((std::regex_search(file_text, m, regex)) && (VERSION != m[1])){ - std::cerr << "Error: The customgt executable is out-of-date, you need to re-compile it." << std::endl; + if ((std::regex_search(file_text, m, regex)) && (VERSION != m[1])) + { + std::cerr << "Error: The customgt executable is out-of-date, you need to " + "re-compile it." + << std::endl; exit(1); } @@ -108,17 +124,31 @@ int main(int argc, char *argv[]) { argparse::ArgumentParser program("main", VERSION); program.add_argument("--frame").required().help("Current frame").scan<'i', int>(); - program.add_argument("--dst_frame").required().help("destination frame for flow / point trajectory").scan<'i', int>(); + program.add_argument("--dst_frame") + .required() + .help("destination frame for flow / point trajectory") + .scan<'i', int>(); program.add_argument("--flow_only").default_value(0).help("if flow only").scan<'i', int>(); program.add_argument("--depth_only").default_value(0).help("if depth only").scan<'i', int>(); program.add_argument("--flow_type").default_value(FLOW).help("flow type").scan<'i', int>(); program.add_argument("-in", "--input_dir").required().help("The input/output dir"); - program.add_argument("-dst_in", "--dst_input_dir").required().help("The destination input/output dir"); + program.add_argument("-dst_in", "--dst_input_dir") + .required() + .help("The destination input/output dir"); program.add_argument("-out", "--output_dir").required().help("The input/output dir"); - program.add_argument("-lw", "--line_width").default_value(2).help("The width of the occlusion boundaries").scan<'i', int>(); - program.add_argument("-s", "--subdivide").default_value(2).help("How many times to subdivide").scan<'i', int>(); - program.add_argument("-nrf", "--normal_receptive_field").default_value(1).help("Receptive field of normal calculation (in px)").scan<'i', int>(); + program.add_argument("-lw", "--line_width") + .default_value(2) + .help("The width of the occlusion boundaries") + .scan<'i', int>(); + program.add_argument("-s", "--subdivide") + .default_value(2) + .help("How many times to subdivide") + .scan<'i', int>(); + program.add_argument("-nrf", "--normal_receptive_field") + .default_value(1) + .help("Receptive field of normal calculation (in px)") + .scan<'i', int>(); program.parse_args(argc, argv); const int occlusion_boundary_line_width = program.get("--line_width"); @@ -146,160 +176,175 @@ int main(int argc, char *argv[]) { assert_exists(camera_dir); assert_exists(dst_camera_dir); std::vector> camview_files, dst_camview_files; - for (const auto &entry : fs::directory_iterator(camera_dir)){ - const auto matches = match_regex("camview_([0-9]+_[0-9]+_[0-9]+_[0-9]+)", entry.path().stem().string()); + for (const auto &entry : fs::directory_iterator(camera_dir)) + { + const auto matches = + match_regex("camview_([0-9]+_[0-9]+_[0-9]+_[0-9]+)", entry.path().stem().string()); const auto output_suffix = matches[1]; MRASSERT(!matches.empty(), entry.path().string() + " did not match camview regex"); camview_files.push_back({entry, output_suffix}); } MRASSERT(!camview_files.empty(), "camview_files is empty"); - for (const auto &entry : fs::directory_iterator(dst_camera_dir)){ - const auto matches = match_regex("camview_([0-9]+_[0-9]+_[0-9]+_[0-9]+)", entry.path().stem().string()); + for (const auto &entry : fs::directory_iterator(dst_camera_dir)) + { + const auto matches = + match_regex("camview_([0-9]+_[0-9]+_[0-9]+_[0-9]+)", entry.path().stem().string()); const auto output_suffix = matches[1]; MRASSERT(!matches.empty(), entry.path().string() + " did not match camview regex"); dst_camview_files.push_back({entry, output_suffix}); } MRASSERT(!dst_camview_files.empty(), "dst_camview_files is empty"); - - std::sort(dst_camview_files.begin(), dst_camview_files.end(), sortBySecond); std::sort(camview_files.begin(), camview_files.end(), sortBySecond); - const auto image_shape = npz(camview_files[0].first).read_data("HW"); const int output_h = image_shape[0]; const int output_w = image_shape[1]; const int buffer_width = output_w * 2; const int buffer_height = output_h * 2; - if ((buffer_width > 10000) || (buffer_height > 10000)){ - cout << "The image size [" << buffer_width << " x " << buffer_height << "] is too large." << endl; + if ((buffer_width > 10000) || (buffer_height > 10000)) + { + cout << "The image size [" << buffer_width << " x " << buffer_height << "] is too large." + << endl; return 1; } - // Linux (works headless) - #if SYSTEM_NUM == 0 +// Linux (works headless) +#if SYSTEM_NUM == 0 - static const EGLint pbufferAttribs[] = { - EGL_WIDTH, buffer_width, - EGL_HEIGHT, buffer_height, - EGL_NONE, - }; + static const EGLint pbufferAttribs[] = { + EGL_WIDTH, buffer_width, EGL_HEIGHT, buffer_height, EGL_NONE, + }; - EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); - EGLint major, minor; + EGLint major, minor; - EGLBoolean res = eglInitialize(eglDpy, &major, &minor); - assert (res != EGL_FALSE); + EGLBoolean res = eglInitialize(eglDpy, &major, &minor); + assert(res != EGL_FALSE); - // 2. Select an appropriate configuration - EGLint numConfigs; - EGLConfig eglCfg; + // 2. Select an appropriate configuration + EGLint numConfigs; + EGLConfig eglCfg; - eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs); + eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs); - // 3. Create a surface - EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg, pbufferAttribs); // eglSurf + // 3. Create a surface + EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy, eglCfg, pbufferAttribs); // eglSurf - // 4. Bind the API - eglBindAPI(EGL_OPENGL_API); + // 4. Bind the API + eglBindAPI(EGL_OPENGL_API); - // 5. Create a context and make it current - const EGLint GiveMeGLES2[] = { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_CONTEXT_CLIENT_VERSION, 4, - EGL_CONTEXT_CLIENT_VERSION, 4, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; + // 5. Create a context and make it current + const EGLint GiveMeGLES2[] = {EGL_CONTEXT_CLIENT_VERSION, + 2, + EGL_CONTEXT_CLIENT_VERSION, + 4, + EGL_CONTEXT_CLIENT_VERSION, + 4, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; - EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL);//GiveMeGLES2); + EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, + NULL); // GiveMeGLES2); - eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx); + eglMakeCurrent(eglDpy, eglSurf, eglSurf, eglCtx); - GLADloadproc load = (GLADloadproc)eglGetProcAddress; - if (!gladLoadGLLoader(load)){ - cerr << "Failed to initialize GLAD" << endl; - return 188; - } + GLADloadproc load = (GLADloadproc)eglGetProcAddress; + if (!gladLoadGLLoader(load)) + { + cerr << "Failed to initialize GLAD" << endl; + return 188; + } - // MacOS, Windows? - #elif SYSTEM_NUM == 0 - - // glfw: initialize and configure - // ------------------------------ - glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - #ifdef __APPLE__ - std::cout << "Apple!" << std::endl; - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - #endif - - // glfw window creation - // -------------------- - GLFWwindow* window = glfwCreateWindow(buffer_width, buffer_height, "LearnOpenGL", NULL, NULL); - if (window == NULL) - { - std::cout << "Failed to create GLFW window" << std::endl; - glfwTerminate(); - return -1; - } - glfwMakeContextCurrent(window); - glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); +// MacOS, Windows? +#elif SYSTEM_NUM == 0 - // glad: load all OpenGL function pointers - // --------------------------------------- - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) - { - std::cout << "Failed to initialize GLAD" << std::endl; - return -1; - } - #endif + // glfw: initialize and configure + // ------------------------------ + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + +#ifdef __APPLE__ + std::cout << "Apple!" << std::endl; + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif + + // glfw window creation + // -------------------- + GLFWwindow *window = glfwCreateWindow(buffer_width, buffer_height, "LearnOpenGL", NULL, NULL); + if (window == NULL) + { + std::cout << "Failed to create GLFW window" << std::endl; + glfwTerminate(); + return -1; + } + glfwMakeContextCurrent(window); + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + // glad: load all OpenGL function pointers + // --------------------------------------- + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) + { + std::cout << "Failed to initialize GLAD" << std::endl; + return -1; + } +#endif std::vector camera_views; - for (int i = 0; i < camview_files.size(); i++) { + for (int i = 0; i < camview_files.size(); i++) + { auto &entry = camview_files[i]; auto &dst_entry = dst_camview_files[i]; - camera_views.push_back({entry.second, dst_entry.second, camera_dir, dst_camera_dir, output_w, output_h}); + camera_views.push_back( + {entry.second, dst_entry.second, camera_dir, dst_camera_dir, output_w, output_h}); } const auto glsl = source_directory / "glsl"; - Shader spineShader((glsl / "wings.vert").c_str(), (glsl / "spine.frag").c_str(), (glsl / "spine.geom").c_str()); - Shader wingsShader((glsl / "wings.vert").c_str(), (glsl / "wings.frag").c_str(), (glsl / "wings.geom").c_str()); - Shader hairShader((glsl / "hair.vert").c_str(), (glsl / "hair.frag").c_str(), (glsl / "hair.geom").c_str()); - Shader nextShader((glsl / "next_wings.vert").c_str(), (glsl / "wings.frag").c_str(), (glsl / "wings.geom").c_str()); + Shader spineShader((glsl / "wings.vert").c_str(), (glsl / "spine.frag").c_str(), + (glsl / "spine.geom").c_str()); + Shader wingsShader((glsl / "wings.vert").c_str(), (glsl / "wings.frag").c_str(), + (glsl / "wings.geom").c_str()); + Shader hairShader( + (glsl / "hair.vert").c_str(), (glsl / "hair.frag").c_str(), (glsl / "hair.geom").c_str()); + Shader nextShader((glsl / "next_wings.vert").c_str(), (glsl / "wings.frag").c_str(), + (glsl / "wings.geom").c_str()); glEnable(GL_DEPTH_TEST); glLineWidth(occlusion_boundary_line_width); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLint storage_buf_size; glGetIntegerv(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &storage_buf_size); - const size_t max_buf_size = (((size_t)storage_buf_size)+1) / (1024 * 1024); + const size_t max_buf_size = (((size_t)storage_buf_size) + 1) / (1024 * 1024); std::cout << "GL_MAX_SHADER_STORAGE_BLOCK_SIZE is " << max_buf_size << " MB." << endl; /* - Drawing the 3D meshes. Instances are small-ish so we draw them all at once. Non-instances are - larger so we draw them in chunks. Smaller stride -> smaller maxmimum memory. + Drawing the 3D meshes. Instances are small-ish so we draw them all at + once. Non-instances are larger so we draw them in chunks. Smaller stride + -> smaller maxmimum memory. */ - std::vector all_bboxes; - while (true) { - const auto some_object_model = load_blender_mesh(input_dir / frame_str / "mesh" / "saved_mesh.json", dst_input_dir / dst_frame_str / "mesh" / "saved_mesh.json"); + std::vector all_bboxes; + while (true) + { + const auto some_object_model = + load_blender_mesh(input_dir / frame_str / "mesh" / "saved_mesh.json", + dst_input_dir / dst_frame_str / "mesh" / "saved_mesh.json"); if (some_object_model == nullptr) break; if (some_object_model->type == Mesh) all_bboxes.push_back(some_object_model->bounding_box); - for (const auto &cd : camera_views){ - + for (const auto &cd : camera_views) + { // DEPTH glBindFramebuffer(GL_FRAMEBUFFER, cd.framebuffer); cd.activateShader(wingsShader); @@ -313,7 +358,6 @@ int main(int argc, char *argv[]) { cd.activateShader(wingsShader); - // OCCLUSION BOUNDARIES glBindFramebuffer(GL_FRAMEBUFFER, cd.framebuffer_ob); @@ -335,13 +379,13 @@ int main(int argc, char *argv[]) { if (some_object_model->type == Mesh) some_object_model->draw(wingsShader); - } } BaseBlenderObject::print_stats(); - for (const auto &cd : camera_views){ + for (const auto &cd : camera_views) + { glBindFramebuffer(GL_FRAMEBUFFER, cd.framebuffer); /* @@ -356,139 +400,154 @@ int main(int argc, char *argv[]) { Reading/Writing the depth map */ { - auto pixels = read_buffer(GL_COLOR_ATTACHMENT1, buffer_width, buffer_height); - Eigen::Tensor depth(buffer_height, buffer_width); - depth.setConstant(std::numeric_limits::max()); - Eigen::Tensor points_3d(buffer_height, buffer_width, 3); - points_3d.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Depth")){ - if (pixels[o.j+2] > 0){ - for (int k=0; k<3; k++) - points_3d(o.y, o.x,k) = pixels[o.j+k]; - depth(o.y, o.x) = pixels[o.j+2]; + auto pixels = read_buffer(GL_COLOR_ATTACHMENT1, buffer_width, buffer_height); + Eigen::Tensor depth(buffer_height, buffer_width); + depth.setConstant(std::numeric_limits::max()); + Eigen::Tensor points_3d(buffer_height, buffer_width, 3); + points_3d.setZero(); + for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Depth")) + { + if (pixels[o.j + 2] > 0) + { + for (int k = 0; k < 3; k++) + points_3d(o.y, o.x, k) = pixels[o.j + k]; + depth(o.y, o.x) = pixels[o.j + 2]; + } } - o.progressbar(); - } - if (depth_only || !flow_only) { - auto depth_color = to_color_map(depth, 0.0, 0.90); - imwrite(output_dir / ("Depth_" + cd.frame_string + ".png"), depth_color); - save_npy(output_dir / ("Depth_" + cd.frame_string + ".npy"), depth); - } - if (!depth_only) { - Eigen::Tensor flow3d; - /* - Reading/Writing the 3D optical flow - */ - pixels = read_buffer(GL_COLOR_ATTACHMENT2, buffer_width, buffer_height); - Eigen::Tensor next_points_3d(buffer_height, buffer_width, 3); - next_points_3d.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Optical Flow")){ - if (pixels[o.j+2] > 0){ - for (int k=0; k<3; k++) - next_points_3d(o.y, o.x,k) = pixels[o.j+k]; + if (depth_only || !flow_only) + { + save_npy(output_dir / ("Depth_" + cd.frame_string + ".npy"), depth); + } + if (!depth_only) + { + Eigen::Tensor flow3d; + /* + Reading/Writing the 3D optical flow + */ + pixels = read_buffer(GL_COLOR_ATTACHMENT2, buffer_width, buffer_height); + Eigen::Tensor next_points_3d(buffer_height, buffer_width, 3); + next_points_3d.setZero(); + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying Optical Flow")) + { + if (pixels[o.j + 2] > 0) + { + for (int k = 0; k < 3; k++) + next_points_3d(o.y, o.x, k) = pixels[o.j + k]; + } + } + flow3d = cd.project(next_points_3d) - cd.project(points_3d); + + std::string output_png, output_npy; + if (flow_type == FLOW) + { + output_png = "Flow3D_" + cd.frame_string + ".png"; + output_npy = "Flow3D_" + cd.frame_string + ".npy"; + } + else if (flow_type == INVFLOW) + { + output_png = "InvFlow3D_" + cd.dst_frame_string + ".png"; + output_npy = "InvFlow3D_" + cd.dst_frame_string + ".npy"; + } + else if (flow_type == TRAJ) + { + output_png = "PointTraj3D_" + cd.dst_frame_string + ".png"; + output_npy = "PointTraj3D_" + cd.dst_frame_string + ".npy"; + } + else if (flow_type == TRAJ) + { + output_png = "InvPointTraj3D_" + cd.frame_string + ".png"; + output_npy = "InvPointTraj3D_" + cd.frame_string + ".npy"; + } + else + assert(0); + + save_npy(output_dir / output_npy, flow3d); } - o.progressbar(); - } - flow3d = cd.project(next_points_3d) - cd.project(points_3d); - const auto flow_viz = compute_flow_viz(flow3d); - std::string output_png, output_npy; - if (flow_type == FLOW) { - output_png = "Flow3D_" + cd.frame_string + ".png"; - output_npy = "Flow3D_" + cd.frame_string + ".npy"; - } - else if (flow_type == INVFLOW) { - output_png = "InvFlow3D_" + cd.dst_frame_string + ".png"; - output_npy = "InvFlow3D_" + cd.dst_frame_string + ".npy"; - } - else if (flow_type == TRAJ) { - output_png = "PointTraj3D_" + cd.dst_frame_string + ".png"; - output_npy = "PointTraj3D_" + cd.dst_frame_string + ".npy"; - } - else if (flow_type == TRAJ) { - output_png = "InvPointTraj3D_" + cd.frame_string + ".png"; - output_npy = "InvPointTraj3D_" + cd.frame_string + ".npy"; - } - else assert(0); - imwrite(output_dir / output_png, flow_viz); - save_npy(output_dir / output_npy, flow3d); - } } /* Reading/Writing the geometry normal */ - if (!flow_only && ! depth_only) { - const auto pixels = read_buffer(GL_COLOR_ATTACHMENT7, buffer_width, buffer_height); - Eigen::Tensor geo_normals(output_h, output_w, 3); - geo_normals.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Geometry Surface Normals")){ - for (int k=0; k<3; k++) - geo_normals(o.y/2, o.x/2, k) += pixels[o.j+k]; - o.progressbar(); - } + if (!flow_only && !depth_only) + { + const auto pixels = + read_buffer(GL_COLOR_ATTACHMENT7, buffer_width, buffer_height); + Eigen::Tensor geo_normals(output_h, output_w, 3); + geo_normals.setZero(); + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Geometry Surface Normals")) + { + for (int k = 0; k < 3; k++) + geo_normals(o.y / 2, o.x / 2, k) += pixels[o.j + k]; + } - Eigen::Tensor geo_normal_color(output_h, output_w, 3); - geo_normal_color.setZero(); - for (const loop_obj &o : image_iterator(output_w, output_h, "")){ - const double norm = std::pow(std::pow(geo_normals(o.y, o.x, 0), 2) + std::pow(geo_normals(o.y, o.x, 1), 2) + std::pow(geo_normals(o.y, o.x, 2), 2), 0.5); - for (int k=0; k<3; k++){ - geo_normals(o.y, o.x, k) = geo_normals(o.y, o.x, k)/norm; - geo_normal_color(o.y, o.x, k) = ((geo_normals(o.y, o.x, k) + 1) * (255/2)); + Eigen::Tensor geo_normal_color(output_h, output_w, 3); + geo_normal_color.setZero(); + for (const loop_obj &o : image_iterator(output_w, output_h, "")) + { + const double norm = std::pow(std::pow(geo_normals(o.y, o.x, 0), 2) + + std::pow(geo_normals(o.y, o.x, 1), 2) + + std::pow(geo_normals(o.y, o.x, 2), 2), + 0.5); + for (int k = 0; k < 3; k++) + { + geo_normals(o.y, o.x, k) = geo_normals(o.y, o.x, k) / norm; + geo_normal_color(o.y, o.x, k) = ((geo_normals(o.y, o.x, k) + 1) * (255 / 2)); + } } + + imwrite(output_dir / ("SurfaceNormal_" + cd.frame_string + ".png"), geo_normal_color); + save_npy(output_dir / ("SurfaceNormal_" + cd.frame_string + ".npy"), geo_normals); } - - imwrite(output_dir / ("SurfaceNormal_" + cd.frame_string + ".png"), geo_normal_color); - save_npy(output_dir / ("SurfaceNormal_" + cd.frame_string + ".npy"), geo_normals); - } /* Reading/Writing the instance segmentation map */ - if (!flow_only && !depth_only) { + if (!flow_only && !depth_only) + { const auto pixels = read_buffer(GL_COLOR_ATTACHMENT6, buffer_width, buffer_height); Eigen::Tensor instance_seg(buffer_height, buffer_width, 3); instance_seg.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying instance segmentation masks")){ - for (int k=0; k<3; k++) + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying instance segmentation masks")) + { + for (int k = 0; k < 3; k++) instance_seg(o.y, o.x, k) = pixels[o.j + k]; - o.progressbar(); } - save_npy(output_dir / ("InstanceSegmentation_" + cd.frame_string + ".npy"), instance_seg); - - Eigen::Tensor instance_seg_2d(buffer_height, buffer_width); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height)) - instance_seg_2d(o.y, o.x) = long(instance_seg(o.y, o.x, 0) % 1000) + 1000 * long(instance_seg(o.y, o.x, 1) % 1000) + 1000000 * long(instance_seg(o.y, o.x, 2) % 1000); - imwrite(output_dir / ("InstanceSegmentation_" + cd.frame_string + ".png"), to_color_map(instance_seg_2d)); + save_npy( + output_dir / ("InstanceSegmentation_" + cd.frame_string + ".npy"), instance_seg); } /* Reading/Writing the object segmentation map */ - if (!flow_only && !depth_only) { + if (!flow_only && !depth_only) + { const auto pixels = read_buffer(GL_COLOR_ATTACHMENT4, buffer_width, buffer_height); Eigen::Tensor object_seg(buffer_height, buffer_width); object_seg.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying object segmentation masks")){ + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying object segmentation masks")) + { object_seg(o.y, o.x) = pixels[o.j]; - o.progressbar(); } save_npy(output_dir / ("ObjectSegmentation_" + cd.frame_string + ".npy"), object_seg); - imwrite(output_dir / ("ObjectSegmentation_" + cd.frame_string + ".png"), to_color_map(object_seg.cast())); } - if (!flow_only && !depth_only) { + if (!flow_only && !depth_only) + { const auto pixels = read_buffer(GL_COLOR_ATTACHMENT5, buffer_width, buffer_height); Eigen::Tensor tag_seg(buffer_height, buffer_width); tag_seg.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying tag segmentation mask")){ + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying tag segmentation mask")) + { tag_seg(o.y, o.x) = pixels[o.j]; - o.progressbar(); } save_npy(output_dir / ("TagSegmentation_" + cd.frame_string + ".npy"), tag_seg); - imwrite(output_dir / ("TagSegmentation_" + cd.frame_string + ".png"), to_color_map(tag_seg.cast())); } - // /* // Reading/Writing the face id map // */ @@ -496,24 +555,27 @@ int main(int argc, char *argv[]) { // Eigen::Tensor faceids(2, buffer_height, buffer_width, 3); // faceids.setZero(); // { - // const auto pixels = read_buffer(GL_COLOR_ATTACHMENT3, buffer_width, buffer_height); - // for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying face ids from first frame")){ + // const auto pixels = read_buffer(GL_COLOR_ATTACHMENT3, + // buffer_width, buffer_height); for (const loop_obj &o : + // image_iterator(buffer_width, buffer_height, "Copying face ids from + // first frame")){ // for (int k=0; k<3; k++) // faceids(0, o.y, o.x, k) = pixels[o.j+k]; - // o.progressbar(); // } // } // glBindFramebuffer(GL_FRAMEBUFFER, cd.framebuffer_next_faceids); // { - // const auto pixels = read_buffer(GL_COLOR_ATTACHMENT3, buffer_width, buffer_height); - // for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying face ids from second frame")){ + // const auto pixels = read_buffer(GL_COLOR_ATTACHMENT3, + // buffer_width, buffer_height); for (const loop_obj &o : + // image_iterator(buffer_width, buffer_height, "Copying face ids from + // second frame")){ // for (int k=0; k<3; k++) // faceids(1, o.y, o.x, k) = pixels[o.j+k]; - // o.progressbar(); // } // } - // Eigen::Array flow_occlusion(buffer_height, buffer_width); - // for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Calculating flow occlusion")){ + // Eigen::Array flow_occlusion(buffer_height, + // buffer_width); for (const loop_obj &o : image_iterator(buffer_width, + // buffer_height, "Calculating flow occlusion")){ // const float fx = flow3d(o.y, o.x, 0); // const float fy = flow3d(o.y, o.x, 1); // bool match_exists = false; @@ -521,44 +583,40 @@ int main(int argc, char *argv[]) { // for (int j=-1; j<=1; j++){ // const int next_x = o.x + lround(fx) + i; // const int next_y = o.y + lround(fy) + j; - // if ((0 <= next_y) && (next_y < buffer_height) && (0 <= next_x) && (next_x < buffer_width)){ + // if ((0 <= next_y) && (next_y < buffer_height) && (0 <= + // next_x) && (next_x < buffer_width)){ // const bool face_ids_match = ( - // (faceids(0, o.y, o.x, 0) == faceids(1, next_y, next_x, 0)) && - // (faceids(0, o.y, o.x, 1) == faceids(1, next_y, next_x, 1)) && - // (faceids(0, o.y, o.x, 2) == faceids(1, next_y, next_x, 2)) + // (faceids(0, o.y, o.x, 0) == faceids(1, next_y, + // next_x, 0)) && (faceids(0, o.y, o.x, 1) == + // faceids(1, next_y, next_x, 1)) && (faceids(0, o.y, + // o.x, 2) == faceids(1, next_y, next_x, 2)) // ); // match_exists = match_exists || face_ids_match; // } // } // } // flow_occlusion(o.y, o.x) = ((unsigned char)match_exists) * 255; - // o.progressbar(); // } - // imwrite(output_dir / ("Flow3DMask_" + cd.frame_string + ".png"), flow_occlusion); + // imwrite(output_dir / ("Flow3DMask_" + cd.frame_string + ".png"), + // flow_occlusion); // } /* // Reading/Writing the face size in m^2 - read_buffer(GL_COLOR_ATTACHMENT3, pixels, buffer_width, buffer_height); - auto face_size = Eigen::Tensor(output_h,output_w); - face_size.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Face-Sizes (in m^2)")){ - face_size(o.y/2, o.x/2) = pixels[o.j]/4; - o.progressbar(); + read_buffer(GL_COLOR_ATTACHMENT3, pixels, buffer_width, + buffer_height); auto face_size = Eigen::Tensor(output_h,output_w); face_size.setZero(); for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying Face-Sizes (in + m^2)")){ face_size(o.y/2, o.x/2) = pixels[o.j]/4; } - auto face_size_color = to_color_map(face_size, 0, 0.5, 0); - imwrite(output_dir / ("FaceSizeCM" + cd.frame_string + ".png"), face_size_color); // Reading/Writing the face size in pixels - read_buffer(GL_COLOR_ATTACHMENT4, pixels, buffer_width, buffer_height); - auto pixel_size = Eigen::Tensor(output_h,output_w); - pixel_size.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Face-Sizes (in pixels)")){ - pixel_size(o.y/2, o.x/2) = pixels[o.j]/4; - o.progressbar(); + read_buffer(GL_COLOR_ATTACHMENT4, pixels, buffer_width, + buffer_height); auto pixel_size = Eigen::Tensor(output_h,output_w); pixel_size.setZero(); for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying Face-Sizes (in + pixels)")){ pixel_size(o.y/2, o.x/2) = pixels[o.j]/4; } - auto pixel_size_color = to_color_map(pixel_size, 0, 0.5, 0); - imwrite(output_dir / ("FaceSizePX" + cd.frame_string + ".png"), pixel_size_color); */ @@ -567,17 +625,19 @@ int main(int argc, char *argv[]) { /* Reading/Writing the occlusion boundaries */ - if (!flow_only && !depth_only) { - const auto pixels = read_buffer(GL_COLOR_ATTACHMENT0, buffer_width, buffer_height); - Eigen::Array occlusion_boundaries(buffer_height,buffer_width); - occlusion_boundaries.setZero(); - for (const loop_obj &o : image_iterator(buffer_width, buffer_height, "Copying Occlusion Boundaries")){ - occlusion_boundaries(o.y, o.x) = pixels[o.j+1]*255; - o.progressbar(); + if (!flow_only && !depth_only) + { + const auto pixels = read_buffer(GL_COLOR_ATTACHMENT0, buffer_width, buffer_height); + Eigen::Array occlusion_boundaries(buffer_height, buffer_width); + occlusion_boundaries.setZero(); + for (const loop_obj &o : + image_iterator(buffer_width, buffer_height, "Copying Occlusion Boundaries")) + { + occlusion_boundaries(o.y, o.x) = pixels[o.j + 1] * 255; + } + imwrite(output_dir / ("OcclusionBoundaries_" + cd.frame_string + ".png"), + occlusion_boundaries); } - imwrite(output_dir / ("OcclusionBoundaries_" + cd.frame_string + ".png"), occlusion_boundaries); - } - } cout << "Done." << endl; } diff --git a/infinigen/datagen/customgt/shader.cpp b/infinigen/datagen/customgt/shader.cpp deleted file mode 100644 index 1c8b947e4..000000000 --- a/infinigen/datagen/customgt/shader.cpp +++ /dev/null @@ -1,290 +0,0 @@ -// Adapted from https://github.com/JoeyDeVries/LearnOpenGL/blob/master/src/7.in_practice/3.2d_game/0.full_source/shader.cpp license: CC BY 4.0 - -#include "shader.hpp" - -// Base class - -void ShaderBase::use() { - glUseProgram(ID); -} - -void ShaderBase::setFloat(const std::string& name, float value) const { - glUniform1f(glGetUniformLocation(ID, name.c_str()), value); -} - -void ShaderBase::setDouble(const std::string& name, double value) const { - glUniform1d(glGetUniformLocation(ID, name.c_str()), value); -} - -void ShaderBase::setBool(const std::string& name, bool value) const { - glUniform1i(glGetUniformLocation(ID, name.c_str()), int(value)); -} - -void ShaderBase::setInt(const std::string& name, int value) const { - glUniform1i(glGetUniformLocation(ID, name.c_str()), value); -} - -void ShaderBase::setUInt(const std::string& name, unsigned int value) const { - glUniform1ui(glGetUniformLocation(ID, name.c_str()), value); -} - -void ShaderBase::setVec2(const std::string& name, const glm::vec2& value) const { - glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setVec2(const std::string& name, float x, float y) const { - glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); -} - -void ShaderBase::setVec3(const std::string& name, const glm::vec3& value) const { - glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setVec3(const std::string& name, float x, float y, float z) const { - glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); -} - -void ShaderBase::setVec4(const std::string& name, const glm::vec4& value) const { - glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setVec4(const std::string& name, float x, float y, float z, float w) const { - glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); -} - -void ShaderBase::setDVec2(const std::string& name, const glm::dvec2& value) const { - glUniform2dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setDVec2(const std::string& name, double x, double y) const { - glUniform2d(glGetUniformLocation(ID, name.c_str()), x, y); -} - -void ShaderBase::setDVec3(const std::string& name, const glm::dvec3& value) const { - glUniform3dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setDVec3(const std::string& name, double x, double y, double z) const { - glUniform3d(glGetUniformLocation(ID, name.c_str()), x, y, z); -} - -void ShaderBase::setDVec4(const std::string& name, const glm::dvec4& value) const { - glUniform4dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setDVec4(const std::string& name, double x, double y, double z, double w) const { - glUniform4d(glGetUniformLocation(ID, name.c_str()), x, y, z, w); -} - -void ShaderBase::setIVec2(const std::string& name, const glm::ivec2& value) const { - glUniform2iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setIVec2(const std::string& name, int x, int y) const { - glUniform2i(glGetUniformLocation(ID, name.c_str()), x, y); -} - -void ShaderBase::setIVec3(const std::string& name, const glm::ivec3& value) const { - glUniform3iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setIVec3(const std::string& name, int x, int y, int z) const { - glUniform3i(glGetUniformLocation(ID, name.c_str()), x, y, z); -} - -void ShaderBase::setIVec4(const std::string& name, const glm::ivec4& value) const { - glUniform4iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setIVec4(const std::string& name, int x, int y, int z, int w) const { - glUniform4i(glGetUniformLocation(ID, name.c_str()), x, y, z, w); -} - -void ShaderBase::setUVec2(const std::string& name, const glm::uvec2& value) const { - glUniform2uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setUVec2(const std::string& name, unsigned int x, unsigned int y) const { - glUniform2ui(glGetUniformLocation(ID, name.c_str()), x, y); -} - -void ShaderBase::setUVec3(const std::string& name, const glm::uvec3& value) const { - glUniform3uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setUVec3(const std::string& name, unsigned int x, unsigned int y, unsigned int z) const { - glUniform3ui(glGetUniformLocation(ID, name.c_str()), x, y, z); -} - -void ShaderBase::setUVec4(const std::string& name, const glm::uvec4& value) const { - glUniform4uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); -} -void ShaderBase::setUVec4(const std::string& name, unsigned int x, unsigned int y, unsigned int z, unsigned int w) const { - glUniform4ui(glGetUniformLocation(ID, name.c_str()), x, y, z, w); -} - -void ShaderBase::setMat2(const std::string& name, const glm::mat2& mat) const { - glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); -} - -void ShaderBase::setMat3(const std::string& name, const glm::mat3& mat) const { - glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); -} - -void ShaderBase::setMat4(const std::string& name, const glm::mat4& mat) const { - glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); -} - -void ShaderBase::checkCompileErrors(unsigned int shader, std::string type) { - int success; - char infoLog[1024]; - if (type != "PROGRAM") { - glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(shader, 1024, NULL, infoLog); - std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; - } - } - else { - glGetProgramiv(shader, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(shader, 1024, NULL, infoLog); - std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl; - } - } -} - -// Child classes - -Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath, const GLchar* geometryPath) { - std::string vertexCode, fragmentCode, geometryCode; - std::ifstream vShaderFile, fShaderFile, gShaderFile; - - vShaderFile.open(vertexPath); - fShaderFile.open(fragmentPath); - gShaderFile.open(geometryPath); - std::stringstream vShaderStream, fShaderStream, gShaderStream; - - vShaderStream << vShaderFile.rdbuf(); - fShaderStream << fShaderFile.rdbuf(); - gShaderStream << gShaderFile.rdbuf(); - - vShaderFile.close(); - fShaderFile.close(); - gShaderFile.close(); - - vertexCode = vShaderStream.str(); - fragmentCode = fShaderStream.str(); - geometryCode = gShaderStream.str(); - - const char* vShaderCode = vertexCode.c_str(); - const char* fShaderCode = fragmentCode.c_str(); - const char* gShaderCode = geometryCode.c_str(); - - // Compiling the shaders - - unsigned int vertex, fragment, geometry; - - vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); - checkCompileErrors(vertex, "VERTEX"); - - fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); - checkCompileErrors(fragment, "FRAGMENT"); - - geometry = glCreateShader(GL_GEOMETRY_SHADER); - glShaderSource(geometry, 1, &gShaderCode, NULL); - glCompileShader(geometry); - checkCompileErrors(geometry, "GEOMETRY"); - - // Shader program - - ID = glCreateProgram(); - glAttachShader(ID, vertex); - glAttachShader(ID, fragment); - glAttachShader(ID, geometry); - glLinkProgram(ID); - checkCompileErrors(ID, "PROGRAM"); - - glDeleteShader(vertex); - glDeleteShader(fragment); - glDeleteShader(geometry); -} - -Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath) { - std::string vertexCode, fragmentCode; - std::ifstream vShaderFile, fShaderFile; - - vShaderFile.open(vertexPath); - fShaderFile.open(fragmentPath); - std::stringstream vShaderStream, fShaderStream; - - vShaderStream << vShaderFile.rdbuf(); - fShaderStream << fShaderFile.rdbuf(); - - vShaderFile.close(); - fShaderFile.close(); - - vertexCode = vShaderStream.str(); - fragmentCode = fShaderStream.str(); - - const char* vShaderCode = vertexCode.c_str(); - const char* fShaderCode = fragmentCode.c_str(); - - // Compiling the shaders - - unsigned int vertex, fragment; - // std::cout << "#10.5\n"; - - vertex = glCreateShader(GL_VERTEX_SHADER); - // std::cout << "#10.6\n"; - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); - checkCompileErrors(vertex, "VERTEX"); - - fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); - checkCompileErrors(fragment, "FRAGMENT"); - - // Shader program - - ID = glCreateProgram(); - glAttachShader(ID, vertex); - glAttachShader(ID, fragment); - glLinkProgram(ID); - checkCompileErrors(ID, "PROGRAM"); - - glDeleteShader(vertex); - glDeleteShader(fragment); -} - -ComputeShader::ComputeShader(const GLchar* path) { - std::string code; - std::ifstream shaderFile; - - shaderFile.open(path); - std::stringstream shaderStream; - - shaderStream << shaderFile.rdbuf(); - shaderFile.close(); - code = shaderStream.str(); - - const char* shaderCode = code.c_str(); - - // Compiling the shaders - - unsigned int shader = glCreateShader(GL_COMPUTE_SHADER); - glShaderSource(shader, 1, &shaderCode, NULL); - glCompileShader(shader); - checkCompileErrors(shader, "COMPUTE"); - - // Shader program - - ID = glCreateProgram(); - glAttachShader(ID, shader); - glLinkProgram(ID); - checkCompileErrors(ID, "PROGRAM"); - - glDeleteShader(shader); -} - -Shader::Shader() { - ID = 0; -} - -ComputeShader::ComputeShader() { - ID = 0; -} diff --git a/infinigen/datagen/customgt/src/blender_object.cpp b/infinigen/datagen/customgt/src/blender_object.cpp new file mode 100644 index 000000000..61ab68645 --- /dev/null +++ b/infinigen/datagen/customgt/src/blender_object.cpp @@ -0,0 +1,253 @@ +// Copyright (C) 2023, Princeton University. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. + +// Authors: Lahav Lipson + +#include "blender_object.hpp" + +#include + +#include +#include +#include +#include +#include + +#include "buffer_arrays.hpp" +#include "utils.hpp" +using std::cout; +using std::endl; + +template +void set_regular_buffer(unsigned int &buffer, const std::vector &data_vec, int attrib_idx, + int attrib_size, int attrib_stride) +{ + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, data_vec.size() * sizeof(T), data_vec.data(), GL_STATIC_DRAW); + + glEnableVertexAttribArray(attrib_idx); + static_assert(std::is_same::value || std::is_same::value); + if constexpr (std::is_same::value) + glVertexAttribPointer( + attrib_idx, attrib_size, GL_FLOAT, GL_FALSE, attrib_stride * sizeof(T), 0); + else if constexpr (std::is_same::value) + glVertexAttribIPointer(attrib_idx, attrib_size, GL_INT, attrib_stride * sizeof(T), 0); +} + +void BaseBlenderObject::set_matrix_buffer(unsigned int &buffer, + const std::vector &model_matrices_next, + int attrib_idx) +{ + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), + model_matrices_next.data(), GL_STATIC_DRAW); + + // vertex attributes + std::size_t vec4Size = sizeof(Eigen::RowVector4f); + for (int ii = 0; ii < 4; ii++) + { + glEnableVertexAttribArray(ii + attrib_idx); + glVertexAttribPointer( + ii + attrib_idx, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void *)(ii * vec4Size)); + } + + for (int ii = 0; ii < 4; ii++) + glVertexAttribDivisor(ii + attrib_idx, 1); +} + +json BaseBlenderObject::compute_bbox(const std::vector &indices, + const std::vector &vertex_lookup, + const std::vector &instance_ids, + const std::vector &model_matrices, + const std::vector &tag_lookup, const int &attrib_stride) +{ + constexpr float inf = std::numeric_limits::infinity(); + Eigen::Vector3f max({-inf, -inf, -inf}), min({inf, inf, inf}); + for (const auto &idx : indices) + { + for (int i = 0; i < 3; i++) + { + max(i) = std::max(max(i), vertex_lookup[idx * attrib_stride + i]); + min(i) = std::min(min(i), vertex_lookup[idx * attrib_stride + i]); + } + } + + std::vector> json_serializable_instance_ids(num_instances); + std::vector json_serializable_model_matrices(num_instances); + for (int idx = 0; idx < num_instances; idx++) + { + const auto instance_id = instance_ids[idx]; + json_serializable_instance_ids[idx] = {instance_id.n1, instance_id.n2, instance_id.n3}; + const auto m = model_matrices[idx]; + json_serializable_model_matrices[idx] = { + {m(0, 0), m(0, 1), m(0, 2), m(0, 3)}, + {m(1, 0), m(1, 1), m(1, 2), m(1, 3)}, + {m(2, 0), m(2, 1), m(2, 2), m(2, 3)}, + {m(3, 0), m(3, 1), m(3, 2), m(3, 3)}, + }; + } + + const std::set unique_tags(tag_lookup.begin(), tag_lookup.end()); + + json output = {{"instance_ids", json_serializable_instance_ids}, + {"model_matrices", json_serializable_model_matrices}, + {"tags", std::vector(unique_tags.begin(), unique_tags.end())}, + {"name", info.name}, + {"num_verts", info.num_verts}, + {"num_faces", info.num_faces}, + {"children", info.children}, + {"materials", info.materials}, + {"unapplied_modifiers", info.unapplied_modifiers}, + {"object_index", info.index}}; + + if ((num_verts > 0) && ((max - min).norm() > 1e-4)) + { + output["min"] = {min(0), min(1), min(2)}; + output["max"] = {max(0), max(1), max(2)}; + } + else + { + output["min"] = nullptr; + output["max"] = nullptr; + } + + return output; +} + +BaseBlenderObject::BaseBlenderObject(const BufferArrays ¤t_buf, const BufferArrays &next_buf, + const std::vector &instance_ids, + const ObjectInfo &object_info, const ObjectType tp, + int attrib_stride) + : num_verts(current_buf.indices.size()), type(tp), info(object_info), + num_instances(instance_ids.size()) +{ + const std::vector &model_matrices = current_buf.get_instances(instance_ids); + const std::vector &model_matrices_next = next_buf.get_instances(instance_ids); + + MRASSERT(model_matrices.size() == num_instances, "Incorrect number of instances"); + MRASSERT(model_matrices_next.size() == num_instances, "Incorrect number of instances"); + const auto t1 = std::chrono::high_resolution_clock::now(); + + const auto &indices = current_buf.indices; + const auto &vertex_lookup = current_buf.lookup; + const auto &vertex_lookup_next = next_buf.lookup; + const auto &tag_lookup = current_buf.tag_lookup; + + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + // Vertices + glGenBuffers(1, &EBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), + GL_STATIC_DRAW); + indices_buf_size = indices.size() * sizeof(unsigned int); + lookup_buf_size = vertex_lookup.size() * sizeof(float); + + set_matrix_buffer(VBO_matrices, model_matrices, 0); + set_matrix_buffer(VBO_matrices_next, model_matrices_next, 4); + + set_regular_buffer(VBO, vertex_lookup, 8, 3, attrib_stride); + set_regular_buffer(VBO_next, vertex_lookup_next, 9, 3, attrib_stride); + + static_assert(sizeof(int) * 3 == sizeof(InstanceID)); + glGenBuffers(1, &VBO_instance_ids); + glBindBuffer(GL_ARRAY_BUFFER, VBO_instance_ids); + glBufferData( + GL_ARRAY_BUFFER, num_instances * sizeof(InstanceID), instance_ids.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(10); + glVertexAttribIPointer(10, 3, GL_INT, sizeof(InstanceID), 0); + glVertexAttribDivisor(10, 1); + + set_regular_buffer(VBO_tag, tag_lookup, 11, 1, 1); + + total_elapsed_sending += (std::chrono::high_resolution_clock::now() - t1); + num_draw_calls++; + + bounding_box = compute_bbox( + indices, vertex_lookup, instance_ids, model_matrices, tag_lookup, attrib_stride); +} + +void BaseBlenderObject::draw(Shader &shader) const +{ + throw std::runtime_error("Base class draw() called!"); +} + +void BaseBlenderObject::print_stats() +{ + std::cout << "Spent " << total_elapsed_drawing.count() << "milliseconds in draw calls." + << std::endl; + std::cout << "Spent " << total_elapsed_sending.count() << "milliseconds across " + << num_draw_calls << " buffer calls." << std::endl; +} + +BaseBlenderObject::~BaseBlenderObject() +{ + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, lookup_buf_size, nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_next); + glBufferData(GL_ARRAY_BUFFER, lookup_buf_size, nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_matrices); + glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_matrices_next); + glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(Eigen::Matrix4f), nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO_instance_ids); + glBufferData(GL_ARRAY_BUFFER, num_instances * sizeof(int), nullptr, GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_buf_size, nullptr, GL_STATIC_DRAW); + glDeleteVertexArrays(1, &VAO); + unsigned int to_delete[7] = { + EBO, VBO, VBO_next, VBO_matrices, VBO_matrices_next, VBO_instance_ids, VBO_tag}; + glDeleteBuffers(7, to_delete); +} + +MeshBlenderObject::MeshBlenderObject(const BufferArrays ¤t_buf, const BufferArrays &next_buf, + const std::vector &instance_ids, + const ObjectInfo &object_info) + : BaseBlenderObject(current_buf, next_buf, instance_ids, object_info, Mesh, 3) +{ + glBindVertexArray(0); +} +MeshBlenderObject::~MeshBlenderObject() +{ +} + +void MeshBlenderObject::draw(Shader &shader) const +{ + const auto t1 = std::chrono::high_resolution_clock::now(); + shader.setInt("object_index", info.index); + glBindVertexArray(VAO); + glDrawElementsInstanced(GL_LINES_ADJACENCY, num_verts, GL_UNSIGNED_INT, 0, num_instances); + glCheckError(); + total_elapsed_drawing += (std::chrono::high_resolution_clock::now() - t1); + glBindVertexArray(0); +} + +CurvesBlenderObject::CurvesBlenderObject(const BufferArrays ¤t_buf, + const BufferArrays &next_buf, + const std::vector &instance_ids, + const ObjectInfo &object_info) + : BaseBlenderObject(current_buf, next_buf, instance_ids, object_info, Hair, 4) +{ + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glEnableVertexAttribArray(12); // Radius + glVertexAttribPointer( + 12, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(sizeof(float) * 3)); + glBindVertexArray(0); +} +CurvesBlenderObject::~CurvesBlenderObject() +{ +} + +void CurvesBlenderObject::draw(Shader &shader) const +{ + const auto t1 = std::chrono::high_resolution_clock::now(); + glBindVertexArray(VAO); + glDrawElementsInstanced(GL_LINES_ADJACENCY, num_verts, GL_UNSIGNED_INT, 0, num_instances); + glCheckError(); + total_elapsed_drawing += (std::chrono::high_resolution_clock::now() - t1); + glBindVertexArray(0); +} diff --git a/infinigen/datagen/customgt/buffer_arrays.cpp b/infinigen/datagen/customgt/src/buffer_arrays.cpp similarity index 60% rename from infinigen/datagen/customgt/buffer_arrays.cpp rename to infinigen/datagen/customgt/src/buffer_arrays.cpp index 093371e31..04f96ddfc 100644 --- a/infinigen/datagen/customgt/buffer_arrays.cpp +++ b/infinigen/datagen/customgt/src/buffer_arrays.cpp @@ -1,22 +1,26 @@ // Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. // Authors: Lahav Lipson #include "buffer_arrays.hpp" -#include -#include + #include #include +#include +#include + #include "utils.hpp" -template -std::vector triangulate_face(std::vector &polygon){ +template std::vector triangulate_face(std::vector &polygon) +{ std::vector output; const int num_tri_verts = ((int)(polygon.size()) - 2) * 3; output.reserve(num_tri_verts); - while (polygon.size() > 2){ + while (polygon.size() > 2) + { const T a = polygon.back(); polygon.pop_back(); const T b = polygon.back(); @@ -32,35 +36,40 @@ std::vector triangulate_face(std::vector &polygon){ return output; } -void curve_quartet(const float *verts, const float *radii, std::vector &point_lookup, std::vector &indices, int offs){ +void curve_quartet(const float *verts, const float *radii, std::vector &point_lookup, + std::vector &indices, int offs) +{ using Eigen::Vector3f, Eigen::Map; std::array P; - for (int pt=0; pt<5; pt++) - P[pt+1] = Map(verts+pt*3); // fill 1-5, still need 0 & 6 + for (int pt = 0; pt < 5; pt++) + P[pt + 1] = Map(verts + pt * 3); // fill 1-5, still need 0 & 6 P[0] = P[1] + (P[1] - P[2]); P[6] = P[5] + (P[5] - P[4]); - for (int p=0; p<7; p++){ + for (int p = 0; p < 7; p++) + { const auto v = P[p]; point_lookup.insert(point_lookup.end(), v.begin(), v.end()); - const int r = std::clamp(p-1, 0, 4); + const int r = std::clamp(p - 1, 0, 4); point_lookup.push_back(radii[r]); } - for (int seg=0; seg<4; seg++){ - for (int p=0; p<4; p++) + for (int seg = 0; seg < 4; seg++) + { + for (int p = 0; p < 4; p++) indices.push_back(offs + seg + p); } } -std::vector generate_buffer(const std::vector &indices){ - +std::vector generate_buffer(const std::vector &indices) +{ using std::unordered_map, std::map, std::set, std::vector; unordered_map>> edge_neighbors; - for (int i=0; i < indices.size(); i+=3){ - std::array tri = {indices[i], indices[i+1], indices[i+2]}; + for (int i = 0; i < indices.size(); i += 3) + { + std::array tri = {indices[i], indices[i + 1], indices[i + 2]}; std::sort(tri.begin(), tri.end()); edge_neighbors[tri[0]][tri[1]].insert(tri[2]); edge_neighbors[tri[0]][tri[2]].insert(tri[1]); @@ -68,20 +77,26 @@ std::vector generate_buffer(const std::vector &indic } vector vertices; - for (const auto &keyval : edge_neighbors){ + for (const auto &keyval : edge_neighbors) + { const uint &v1 = keyval.first; const map> &mapping = keyval.second; - for (const auto &v2_v3s : mapping){ + for (const auto &v2_v3s : mapping) + { const auto &v2 = v2_v3s.first; vector v3s; v3s.insert(v3s.end(), v2_v3s.second.begin(), v2_v3s.second.end()); RASSERT(v3s.size() == v2_v3s.second.size()); if (v3s.size() == 1) - v3s.push_back(v3s[0]); // i.e. treat dangling edges as two triangles folded together + v3s.push_back(v3s[0]); // i.e. treat dangling edges as two + // triangles folded together RASSERT(v3s.size() >= 2); - for (int i=0; i generate_buffer(const std::vector &indic } } return vertices; - } - -BufferArrays::BufferArrays(const npz &my_npz, std::string mesh_id, std::string obj_type, bool skip_indices){ +} +BufferArrays::BufferArrays(const npz &my_npz, std::string mesh_id, std::string obj_type, + bool skip_indices) +{ { const std::vector instance_ids = my_npz.read_data(mesh_id + "_instance_ids"); const auto mwd = my_npz.read_data(mesh_id + "_transformations"); - RASSERT((mwd.size()/16) == instance_ids.size()/3); - for (int i=0; i<(mwd.size()/16); i++) - model_mats[{instance_ids[i*3], instance_ids[i*3+1], instance_ids[i*3+2]}] = Eigen::Matrix(&mwd[i*16]); + RASSERT((mwd.size() / 16) == instance_ids.size() / 3); + for (int i = 0; i < (mwd.size() / 16); i++) + model_mats[{instance_ids[i * 3], instance_ids[i * 3 + 1], instance_ids[i * 3 + 2]}] = + Eigen::Matrix(&mwd[i * 16]); } - if (obj_type == "MESH") { - + if (obj_type == "MESH") + { lookup = my_npz.read_data(mesh_id + "_vertices"); - // const auto face_tag_lookup = my_npz.read_data(mesh_id + "_masktag"); - // tag_lookup.resize(lookup.size()); + // const auto face_tag_lookup = my_npz.read_data(mesh_id + + // "_masktag"); tag_lookup.resize(lookup.size()); tag_lookup = my_npz.read_data(mesh_id + "_masktag"); if (skip_indices) return; const auto loop_totals = my_npz.read_data(mesh_id + "_loop_totals"); - // MRASSERT(loop_totals.size() == face_tag_lookup.size(), "loop_totals.size() ["+std::to_string(loop_totals.size())+"] != tag_lookup.size() ["+std::to_string(face_tag_lookup.size())+"]"); + // MRASSERT(loop_totals.size() == face_tag_lookup.size(), + // "loop_totals.size() ["+std::to_string(loop_totals.size())+"] != + // tag_lookup.size() ["+std::to_string(face_tag_lookup.size())+"]"); const auto npy_data = my_npz.read_data(mesh_id + "_indices"); auto it = npy_data.begin(); int face_index = 0; - for (const int &polygon_size : loop_totals){ + for (const int &polygon_size : loop_totals) + { // const int face_id = face_tag_lookup[face_index++]; - std::vector polygon(it, it+polygon_size); + std::vector polygon(it, it + polygon_size); const std::vector triangles = triangulate_face(polygon); // for (const int &t : triangles) - // tag_lookup[t] = std::max(face_id, tag_lookup[t]); // tag is per-vertex, ideally should be per-face - indices.insert(indices.end(),triangles.begin(),triangles.end()); + // tag_lookup[t] = std::max(face_id, tag_lookup[t]); // tag is + // per-vertex, ideally should be per-face + indices.insert(indices.end(), triangles.begin(), triangles.end()); it += polygon_size; } indices = generate_buffer(indices); - - } else if (obj_type == "CURVES") { + } + else if (obj_type == "CURVES") + { const auto vert_data = my_npz.read_data(mesh_id + "_vertices"); const auto radii_data = my_npz.read_data(mesh_id + "_radii"); - const size_t num_hairs = vert_data.size() / (5*3); + const size_t num_hairs = vert_data.size() / (5 * 3); // std::cout << "We've got hair!: " << num_hairs << std::endl; - for (int hair_idx=0; hair_idx < num_hairs; hair_idx++) - curve_quartet(vert_data.data()+(hair_idx*5*3), radii_data.data()+(hair_idx*5), lookup, indices, hair_idx*7); - } else { + for (int hair_idx = 0; hair_idx < num_hairs; hair_idx++) + curve_quartet(vert_data.data() + (hair_idx * 5 * 3), radii_data.data() + (hair_idx * 5), + lookup, indices, hair_idx * 7); + } + else + { throw std::runtime_error(""); } } diff --git a/infinigen/datagen/customgt/camera_view.cpp b/infinigen/datagen/customgt/src/camera_view.cpp similarity index 65% rename from infinigen/datagen/customgt/camera_view.cpp rename to infinigen/datagen/customgt/src/camera_view.cpp index 98549560f..fd99f848e 100644 --- a/infinigen/datagen/customgt/camera_view.cpp +++ b/infinigen/datagen/customgt/src/camera_view.cpp @@ -1,27 +1,33 @@ // Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. // Authors: Lahav Lipson +#include "camera_view.hpp" -#include #include -#include "camera_view.hpp" +#include + #include "string_tools.hpp" #include "utils.hpp" using Eigen::Matrix4f, Eigen::Matrix3f, Eigen::Tensor; -unsigned int CameraView::create_framebuffer(){ +unsigned int CameraView::create_framebuffer() +{ unsigned int framebuffer; glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - constexpr GLenum color_attachments[8] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7}; + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + constexpr GLenum color_attachments[8] = { + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7}; constexpr bool is_float[8] = {false, true, true, false, false, false, false, true}; - constexpr size_t num_color_attachments = sizeof(color_attachments)/sizeof(GLenum); + constexpr size_t num_color_attachments = sizeof(color_attachments) / sizeof(GLenum); glDrawBuffers(num_color_attachments, color_attachments); unsigned int textureColorbuffers[num_color_attachments]; - for (int ai=0; ai -Eigen::Matrix load_matrix(const npz &camview, const std::string &key){ +template +Eigen::Matrix load_matrix(const npz &camview, const std::string &key) +{ const auto opengl_camera_pose_data = camview.read_data(key); const auto tmp = Eigen::Matrix(opengl_camera_pose_data.data()); return tmp.transpose().template cast(); } -CameraView::CameraView(const std::string fstr, const std::string dst_fstr, const fs::path input_dir, const fs::path dst_input_dir, const int width, const int height) : frame_string(fstr), dst_frame_string(dst_fstr), image_height(height), image_width(width), buffer_height(height*2), buffer_width(width*2) +CameraView::CameraView(const std::string fstr, const std::string dst_fstr, const fs::path input_dir, + const fs::path dst_input_dir, const int width, const int height) + : frame_string(fstr), dst_frame_string(dst_fstr), image_height(height), image_width(width), + buffer_height(height * 2), buffer_width(width * 2) { // Current Frame - const fs::path current_frame_cam_path = input_dir / ("camview_"+frame_string+".npz"); + const fs::path current_frame_cam_path = input_dir / ("camview_" + frame_string + ".npz"); const npz current_camview(current_frame_cam_path); // Y down Z forward (aka opencv) const Matrix4f opengl_camera_pose = load_matrix<4, 4>(current_camview, "T") * FLIP_Y_Z; - current_frame_view_matrix = glm::make_mat4(Matrix4f(opengl_camera_pose.inverse()).data()); // Y up Z back (aka blender/opengl) + current_frame_view_matrix = glm::make_mat4( + Matrix4f(opengl_camera_pose.inverse()).data()); // Y up Z back (aka blender/opengl) // Next Frame - const fs::path next_frame_cam_path = dst_input_dir / ("camview_"+dst_frame_string+".npz"); + const fs::path next_frame_cam_path = dst_input_dir / ("camview_" + dst_frame_string + ".npz"); const npz next_camview(next_frame_cam_path); const Matrix4f next_opengl_camera_pose = load_matrix<4, 4>(next_camview, "T") * FLIP_Y_Z; next_frame_view_matrix = glm::make_mat4(Matrix4f(next_opengl_camera_pose.inverse()).data()); @@ -74,21 +88,21 @@ CameraView::CameraView(const std::string fstr, const std::string dst_fstr, const const Matrix3f K_mat3x3 = load_matrix<3, 3>(current_camview, "K"); Matrix4f K_mat = Matrix4f::Identity(); buffer_over_image = 2; - K_mat.block<2,3>(0, 0) = buffer_over_image * K_mat3x3.block<2,3>(0, 0); + K_mat.block<2, 3>(0, 0) = buffer_over_image * K_mat3x3.block<2, 3>(0, 0); cc2img = glm::make_mat4(K_mat.data()); // maps opencv wc to img - fx = K_mat(0,0); - fy = K_mat(1,1); - cx = K_mat(0,2); - cy = K_mat(1,2); + fx = K_mat(0, 0); + fy = K_mat(1, 1); + cx = K_mat(0, 2); + cy = K_mat(1, 2); // Source https://stackoverflow.com/a/22312303/5057543 const double near = 0.1; const double far = 10000.0; projection = glm::mat4(0); projection[0][0] = fx / cx; projection[1][1] = fy / cy; - projection[2][2] = -(far+near)/(far-near); - projection[3][2] = -(2*far*near)/(far-near); + projection[2][2] = -(far + near) / (far - near); + projection[3][2] = -(2 * far * near) / (far - near); projection[2][3] = -1.0; framebuffer = create_framebuffer(); @@ -101,25 +115,32 @@ CameraView::CameraView(const std::string fstr, const std::string dst_fstr, const glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void CameraView::activateShader(Shader &shader) const { +void CameraView::activateShader(Shader &shader) const +{ shader.use(); shader.setMat4("projection", projection); - shader.setMat4("view", current_frame_view_matrix);// Y up Z back (aka blender/opengl) + shader.setMat4("view", + current_frame_view_matrix); // Y up Z back (aka blender/opengl) shader.setMat4("viewNext", next_frame_view_matrix); shader.setMat4("cc2img", cc2img); } -Tensor CameraView::project(const Tensor &cam_coords) const { +Tensor CameraView::project(const Tensor &cam_coords) const +{ const size_t width = cam_coords.dimension(1); const size_t height = cam_coords.dimension(0); Tensor output(height, width, 3); output.setZero(); - for (int x=0; x -#include +#include // or #include + +#include +#include #include #include -#include // or -#include "io.hpp" -#include "utils.hpp" + #include "cnpy/cnpy.h" -#include "colorcode.h" +#include "utils.hpp" + #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb/stb_image_write.h" - -void imwrite(const fs::path filepath, const Eigen::Array &image){ +void imwrite(const fs::path filepath, const Eigen::Array &image) +{ const int H = image.rows(); const int W = image.cols(); - std::vector color_data_vec(H*W); + std::vector color_data_vec(H * W); - for (int i = 0; i < W*H; i++) { - const int x = i%W; - const int y = i/W; - color_data_vec[i] = image(y,x); + for (int i = 0; i < W * H; i++) + { + const int x = i % W; + const int y = i / W; + color_data_vec[i] = image(y, x); } stbi_write_png(filepath.c_str(), W, H, 1, &color_data_vec[0], W); } -void imwrite(const fs::path filepath, const Eigen::Tensor &image){ +void imwrite(const fs::path filepath, const Eigen::Tensor &image) +{ const int H = image.dimension(0); const int W = image.dimension(1); - std::vector color_data_vec(H*W*3); + std::vector color_data_vec(H * W * 3); - for (int i = 0; i < W*H; i++) { - const int x = i%W; - const int y = i/W; - for (int k=0; k<3; k++) - color_data_vec[i*3 + k] = image(y,x,k); + for (int i = 0; i < W * H; i++) + { + const int x = i % W; + const int y = i / W; + for (int k = 0; k < 3; k++) + color_data_vec[i * 3 + k] = image(y, x, k); } - stbi_write_png(filepath.c_str(), W, H, 3, &color_data_vec[0], W*3); + stbi_write_png(filepath.c_str(), W, H, 3, &color_data_vec[0], W * 3); } -Eigen::MatrixXd read_npy(const fs::path filepath){ +Eigen::MatrixXd read_npy(const fs::path filepath) +{ assert_exists(filepath); const cnpy::NpyArray myarr = cnpy::npy_load(filepath.c_str()); const double *x = myarr.data(); - const std::vector v(x, x + myarr.num_bytes()/sizeof(double)); + const std::vector v(x, x + myarr.num_bytes() / sizeof(double)); const int W = myarr.shape[1]; const int H = myarr.shape[0]; - Eigen::ArrayXXd output_data(H,W); - for (int i=0; i +#include #include -#include //without .h -#include +#include #include #include #include -#include "string_tools.hpp" -#include "load_blender_mesh.hpp" + #include "buffer_arrays.hpp" +#include "string_tools.hpp" using json = nlohmann::json; -using namespace indicators; -using namespace indicators::option; -auto parse_json(const fs::path json_path){ +auto parse_json(const fs::path json_path) +{ const json data = json::parse(std::ifstream(json_path)); std::unordered_map output; - for (const auto &instance_item : data){ - if (instance_item.contains("filename") && (instance_item["object_type"] == "MESH")){ // Ignore CURVES objects, for now + for (const auto &instance_item : data) + { + if (instance_item.contains("filename") && (instance_item["object_type"] == "MESH")) + { // Ignore CURVES objects, for now const ObjectInfo ii(instance_item); MRASSERT(output.count(ii.mesh_id) == 0, ii.mesh_id); output[ii.mesh_id] = ii; @@ -32,22 +34,14 @@ auto parse_json(const fs::path json_path){ return output; } -std::shared_ptr load_blender_mesh(const fs::path src_json_path, const fs::path dst_json_path){ +std::shared_ptr load_blender_mesh(const fs::path src_json_path, + const fs::path dst_json_path) +{ assert_exists(src_json_path); assert_exists(dst_json_path); // Progress bar static int object_idx = 0; - static ProgressBar bar{ - BarWidth{20}, Start{"["}, End{"]"}, - ShowElapsedTime{true}, ShowRemainingTime{true}, - ForegroundColor{Color::blue}, - FontStyles{std::vector{FontStyle::bold}} - }; - if (object_idx == 0){ - bar.set_option(PrefixText{truncate(std::string("Loading..."), 20)}); - bar.set_progress(0); - } static std::unordered_map npz_lookup; @@ -63,8 +57,10 @@ std::shared_ptr load_blender_mesh(const fs::path src_json_pat static auto it = info_lookup.begin(); - if (current_buf.is_empty()){ - // while ((it != info_lookup.end()) && match_regex(".*errain.*", it->second.name).empty()) it++; + if (current_buf.is_empty()) + { + // while ((it != info_lookup.end()) && match_regex(".*errain.*", + // it->second.name).empty()) it++; if (it == info_lookup.end()) return nullptr; const std::string current_mesh_id = it->first; @@ -77,16 +73,22 @@ std::shared_ptr load_blender_mesh(const fs::path src_json_pat const npz ¤t_npz = npz_lookup.at(current_npz_path.string()); current_buf = BufferArrays(current_npz, current_mesh_id, current_obj.type); - bar.set_option(PrefixText{"Loading " + truncate(current_obj.name, 20) + " " + std::to_string(object_idx++) + "/" + std::to_string(info_lookup.size())}); + std::cout << "Loading " << truncate(current_obj.name, 20) << " "; + std::cout << std::to_string(object_idx++) << "/" << std::to_string(info_lookup.size()) + << std::endl; - if (next_info_lookup.count(current_mesh_id) > 0){ + if (next_info_lookup.count(current_mesh_id) > 0) + { next_obj = next_info_lookup.at(current_mesh_id); - const fs::path next_npz_path = fs::path(dst_json_path.parent_path()) / next_obj.npz_filename; + const fs::path next_npz_path = + fs::path(dst_json_path.parent_path()) / next_obj.npz_filename; if (npz_lookup.count(next_npz_path.string()) == 0) npz_lookup[next_npz_path.string()] = next_npz_path; const npz &next_npz = npz_lookup.at(next_npz_path.string()); next_buf = BufferArrays(next_npz, current_mesh_id, next_obj.type, true); - } else { + } + else + { next_buf = current_buf; } @@ -94,16 +96,21 @@ std::shared_ptr load_blender_mesh(const fs::path src_json_pat } std::shared_ptr new_obj; - if (current_obj.type == "MESH"){ + if (current_obj.type == "MESH") + { const auto instance_ids = current_buf.get_some_instance_ids(1e8); - new_obj = std::shared_ptr(new MeshBlenderObject(current_buf, next_buf, instance_ids, current_obj)); + new_obj = std::shared_ptr( + new MeshBlenderObject(current_buf, next_buf, instance_ids, current_obj)); current_buf.remove_instances(instance_ids); - } else if (current_obj.type == "CURVES"){ + } + else if (current_obj.type == "CURVES") + { const auto all_instance_ids = current_buf.get_some_instance_ids(); - new_obj = std::shared_ptr(new CurvesBlenderObject(current_buf, next_buf, all_instance_ids, current_obj)); + new_obj = std::shared_ptr( + new CurvesBlenderObject(current_buf, next_buf, all_instance_ids, current_obj)); current_buf.remove_instances(all_instance_ids); } - bar.set_progress((object_idx * 100)/info_lookup.size()); + RASSERT((object_idx == info_lookup.size()) == (it == info_lookup.end())); return new_obj; } diff --git a/infinigen/datagen/customgt/src/shader.cpp b/infinigen/datagen/customgt/src/shader.cpp new file mode 100644 index 000000000..ffc711327 --- /dev/null +++ b/infinigen/datagen/customgt/src/shader.cpp @@ -0,0 +1,345 @@ +// Adapted from +// https://github.com/JoeyDeVries/LearnOpenGL/blob/master/src/7.in_practice/3.2d_game/0.full_source/shader.cpp +// license: CC BY 4.0 + +#include "shader.hpp" + +// Base class + +void ShaderBase::use() +{ + glUseProgram(ID); +} + +void ShaderBase::setFloat(const std::string &name, float value) const +{ + glUniform1f(glGetUniformLocation(ID, name.c_str()), value); +} + +void ShaderBase::setDouble(const std::string &name, double value) const +{ + glUniform1d(glGetUniformLocation(ID, name.c_str()), value); +} + +void ShaderBase::setBool(const std::string &name, bool value) const +{ + glUniform1i(glGetUniformLocation(ID, name.c_str()), int(value)); +} + +void ShaderBase::setInt(const std::string &name, int value) const +{ + glUniform1i(glGetUniformLocation(ID, name.c_str()), value); +} + +void ShaderBase::setUInt(const std::string &name, unsigned int value) const +{ + glUniform1ui(glGetUniformLocation(ID, name.c_str()), value); +} + +void ShaderBase::setVec2(const std::string &name, const glm::vec2 &value) const +{ + glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setVec2(const std::string &name, float x, float y) const +{ + glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); +} + +void ShaderBase::setVec3(const std::string &name, const glm::vec3 &value) const +{ + glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setVec3(const std::string &name, float x, float y, float z) const +{ + glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); +} + +void ShaderBase::setVec4(const std::string &name, const glm::vec4 &value) const +{ + glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setVec4(const std::string &name, float x, float y, float z, float w) const +{ + glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); +} + +void ShaderBase::setDVec2(const std::string &name, const glm::dvec2 &value) const +{ + glUniform2dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setDVec2(const std::string &name, double x, double y) const +{ + glUniform2d(glGetUniformLocation(ID, name.c_str()), x, y); +} + +void ShaderBase::setDVec3(const std::string &name, const glm::dvec3 &value) const +{ + glUniform3dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setDVec3(const std::string &name, double x, double y, double z) const +{ + glUniform3d(glGetUniformLocation(ID, name.c_str()), x, y, z); +} + +void ShaderBase::setDVec4(const std::string &name, const glm::dvec4 &value) const +{ + glUniform4dv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setDVec4(const std::string &name, double x, double y, double z, double w) const +{ + glUniform4d(glGetUniformLocation(ID, name.c_str()), x, y, z, w); +} + +void ShaderBase::setIVec2(const std::string &name, const glm::ivec2 &value) const +{ + glUniform2iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setIVec2(const std::string &name, int x, int y) const +{ + glUniform2i(glGetUniformLocation(ID, name.c_str()), x, y); +} + +void ShaderBase::setIVec3(const std::string &name, const glm::ivec3 &value) const +{ + glUniform3iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setIVec3(const std::string &name, int x, int y, int z) const +{ + glUniform3i(glGetUniformLocation(ID, name.c_str()), x, y, z); +} + +void ShaderBase::setIVec4(const std::string &name, const glm::ivec4 &value) const +{ + glUniform4iv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setIVec4(const std::string &name, int x, int y, int z, int w) const +{ + glUniform4i(glGetUniformLocation(ID, name.c_str()), x, y, z, w); +} + +void ShaderBase::setUVec2(const std::string &name, const glm::uvec2 &value) const +{ + glUniform2uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setUVec2(const std::string &name, unsigned int x, unsigned int y) const +{ + glUniform2ui(glGetUniformLocation(ID, name.c_str()), x, y); +} + +void ShaderBase::setUVec3(const std::string &name, const glm::uvec3 &value) const +{ + glUniform3uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setUVec3(const std::string &name, unsigned int x, unsigned int y, + unsigned int z) const +{ + glUniform3ui(glGetUniformLocation(ID, name.c_str()), x, y, z); +} + +void ShaderBase::setUVec4(const std::string &name, const glm::uvec4 &value) const +{ + glUniform4uiv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); +} +void ShaderBase::setUVec4(const std::string &name, unsigned int x, unsigned int y, unsigned int z, + unsigned int w) const +{ + glUniform4ui(glGetUniformLocation(ID, name.c_str()), x, y, z, w); +} + +void ShaderBase::setMat2(const std::string &name, const glm::mat2 &mat) const +{ + glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); +} + +void ShaderBase::setMat3(const std::string &name, const glm::mat3 &mat) const +{ + glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); +} + +void ShaderBase::setMat4(const std::string &name, const glm::mat4 &mat) const +{ + glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); +} + +void ShaderBase::checkCompileErrors(unsigned int shader, std::string type) +{ + int success; + char infoLog[1024]; + if (type != "PROGRAM") + { + glGetShaderiv(shader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(shader, 1024, NULL, infoLog); + std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" + << infoLog + << "\n -- --------------------------------------------------- " + "-- " + << std::endl; + } + } + else + { + glGetProgramiv(shader, GL_LINK_STATUS, &success); + if (!success) + { + glGetProgramInfoLog(shader, 1024, NULL, infoLog); + std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" + << infoLog + << "\n -- --------------------------------------------------- " + "-- " + << std::endl; + } + } +} + +// Child classes + +Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath, const GLchar *geometryPath) +{ + std::string vertexCode, fragmentCode, geometryCode; + std::ifstream vShaderFile, fShaderFile, gShaderFile; + + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + gShaderFile.open(geometryPath); + std::stringstream vShaderStream, fShaderStream, gShaderStream; + + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + gShaderStream << gShaderFile.rdbuf(); + + vShaderFile.close(); + fShaderFile.close(); + gShaderFile.close(); + + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + geometryCode = gShaderStream.str(); + + const char *vShaderCode = vertexCode.c_str(); + const char *fShaderCode = fragmentCode.c_str(); + const char *gShaderCode = geometryCode.c_str(); + + // Compiling the shaders + + unsigned int vertex, fragment, geometry; + + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + checkCompileErrors(vertex, "VERTEX"); + + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + checkCompileErrors(fragment, "FRAGMENT"); + + geometry = glCreateShader(GL_GEOMETRY_SHADER); + glShaderSource(geometry, 1, &gShaderCode, NULL); + glCompileShader(geometry); + checkCompileErrors(geometry, "GEOMETRY"); + + // Shader program + + ID = glCreateProgram(); + glAttachShader(ID, vertex); + glAttachShader(ID, fragment); + glAttachShader(ID, geometry); + glLinkProgram(ID); + checkCompileErrors(ID, "PROGRAM"); + + glDeleteShader(vertex); + glDeleteShader(fragment); + glDeleteShader(geometry); +} + +Shader::Shader(const GLchar *vertexPath, const GLchar *fragmentPath) +{ + std::string vertexCode, fragmentCode; + std::ifstream vShaderFile, fShaderFile; + + vShaderFile.open(vertexPath); + fShaderFile.open(fragmentPath); + std::stringstream vShaderStream, fShaderStream; + + vShaderStream << vShaderFile.rdbuf(); + fShaderStream << fShaderFile.rdbuf(); + + vShaderFile.close(); + fShaderFile.close(); + + vertexCode = vShaderStream.str(); + fragmentCode = fShaderStream.str(); + + const char *vShaderCode = vertexCode.c_str(); + const char *fShaderCode = fragmentCode.c_str(); + + // Compiling the shaders + + unsigned int vertex, fragment; + // std::cout << "#10.5\n"; + + vertex = glCreateShader(GL_VERTEX_SHADER); + // std::cout << "#10.6\n"; + glShaderSource(vertex, 1, &vShaderCode, NULL); + glCompileShader(vertex); + checkCompileErrors(vertex, "VERTEX"); + + fragment = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment, 1, &fShaderCode, NULL); + glCompileShader(fragment); + checkCompileErrors(fragment, "FRAGMENT"); + + // Shader program + + ID = glCreateProgram(); + glAttachShader(ID, vertex); + glAttachShader(ID, fragment); + glLinkProgram(ID); + checkCompileErrors(ID, "PROGRAM"); + + glDeleteShader(vertex); + glDeleteShader(fragment); +} + +ComputeShader::ComputeShader(const GLchar *path) +{ + std::string code; + std::ifstream shaderFile; + + shaderFile.open(path); + std::stringstream shaderStream; + + shaderStream << shaderFile.rdbuf(); + shaderFile.close(); + code = shaderStream.str(); + + const char *shaderCode = code.c_str(); + + // Compiling the shaders + + unsigned int shader = glCreateShader(GL_COMPUTE_SHADER); + glShaderSource(shader, 1, &shaderCode, NULL); + glCompileShader(shader); + checkCompileErrors(shader, "COMPUTE"); + + // Shader program + + ID = glCreateProgram(); + glAttachShader(ID, shader); + glLinkProgram(ID); + checkCompileErrors(ID, "PROGRAM"); + + glDeleteShader(shader); +} + +Shader::Shader() +{ + ID = 0; +} + +ComputeShader::ComputeShader() +{ + ID = 0; +} diff --git a/infinigen/datagen/customgt/string_tools.cpp b/infinigen/datagen/customgt/src/string_tools.cpp similarity index 52% rename from infinigen/datagen/customgt/string_tools.cpp rename to infinigen/datagen/customgt/src/string_tools.cpp index 8cca609c9..4d6f5b7de 100644 --- a/infinigen/datagen/customgt/string_tools.cpp +++ b/infinigen/datagen/customgt/src/string_tools.cpp @@ -1,35 +1,41 @@ // Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. // Authors: Lahav Lipson +#include "string_tools.hpp" -#include #include -#include "string_tools.hpp" +#include -std::vector match_regex(const std::string &pattern, const std::string &input){ - const std::regex regex{pattern.c_str()}; - std::smatch m; - std::vector output; - if (std::regex_match(input, m, regex)){ - for (auto it : m) - output.push_back(it.str()); - } - return output; +std::vector match_regex(const std::string &pattern, const std::string &input) +{ + const std::regex regex{pattern.c_str()}; + std::smatch m; + std::vector output; + if (std::regex_match(input, m, regex)) + { + for (auto it : m) + output.push_back(it.str()); + } + return output; } -std::string increment_int_substr(const std::vector &patterns, const std::string &input_orig){ +std::string increment_int_substr(const std::vector &patterns, + const std::string &input_orig) +{ std::string input(input_orig); std::smatch res; - for (const auto pattern : patterns){ - std::string::const_iterator searchStart( input.cbegin() ); + for (const auto pattern : patterns) + { + std::string::const_iterator searchStart(input.cbegin()); std::regex exp(pattern.c_str()); - while ( std::regex_search( searchStart, input.cend(), res, exp ) ) + while (std::regex_search(searchStart, input.cend(), res, exp)) { std::string number = res[1]; - std::string new_number = zfill(number.size(), std::atoi(number.c_str())+1); + std::string new_number = zfill(number.size(), std::atoi(number.c_str()) + 1); input.replace(res[1].first, res[1].second, new_number); searchStart = res.suffix().first; @@ -37,5 +43,4 @@ std::string increment_int_substr(const std::vector &patterns, const } return input; - } \ No newline at end of file diff --git a/infinigen/datagen/customgt/src/utils.cpp b/infinigen/datagen/customgt/src/utils.cpp new file mode 100644 index 000000000..24354f1a9 --- /dev/null +++ b/infinigen/datagen/customgt/src/utils.cpp @@ -0,0 +1,82 @@ +// Copyright (C) 2023, Princeton University. +// This source code is licensed under the BSD 3-Clause license found in the +// LICENSE file in the root directory of this source tree. + +// Authors: Lahav Lipson + +#include "utils.hpp" + +#include + +#include +#include +#include +#include + +#include "cnpy/cnpy.h" + +void release_assert(const char *file, int line, bool condition, const std::string &msg) +{ + if (!condition) + throw std::runtime_error(std::string("Assertion failed: ") + file + " (" + + std::to_string(line) + ")\n" + msg + "\n"); +} + +void glCheckError_(const char *file, int line) +{ + GLenum errorCode; + while ((errorCode = glGetError()) != GL_NO_ERROR) + { + std::string error; + switch (errorCode) + { + case GL_INVALID_ENUM: + error = "INVALID_ENUM"; + break; + case GL_INVALID_VALUE: + error = "INVALID_VALUE"; + break; + case GL_INVALID_OPERATION: + error = "INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + error = "STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + error = "STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + error = "OUT_OF_MEMORY"; + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + error = "INVALID_FRAMEBUFFER_OPERATION"; + break; + } + std::cout << error << " | " << file << " (" << line << ")" << std::endl; + throw std::runtime_error(error + " | " + file + " (" + std::to_string(line) + ")\n"); + } +} + +const std::vector image_iterator(const int width, const int height, + const std::string desc) +{ + const size_t num_elements = width * height; + std::vector output; + output.reserve(num_elements); + size_t current_idx = 0; + int prev_percent = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + const int current_percent = ((++current_idx) * 100) / num_elements; + const bool should_tick = (current_percent > prev_percent); + output.push_back(loop_obj(x, y, (x + (height - y - 1) * width) * 4)); + prev_percent = current_percent; + } + } + assert(current_idx == num_elements); + assert(num_elements == output.size()); + assert(output.back().progbar); + return output; +} \ No newline at end of file diff --git a/infinigen/datagen/customgt/utils.cpp b/infinigen/datagen/customgt/utils.cpp deleted file mode 100644 index 1206a7141..000000000 --- a/infinigen/datagen/customgt/utils.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2023, Princeton University. -// This source code is licensed under the BSD 3-Clause license found in the LICENSE file in the root directory of this source tree. - -// Authors: Lahav Lipson - - -#include -#include -#include -#include -#include -#include "utils.hpp" -#include "cnpy/cnpy.h" -#include "colorcode.h" - -void release_assert(const char *file, int line, bool condition, const std::string &msg){ - if (!condition) - throw std::runtime_error(std::string("Assertion failed: ") + file + " (" + std::to_string(line) + ")\n" + msg + "\n"); -} - -void glCheckError_(const char *file, int line) -{ - GLenum errorCode; - while ((errorCode = glGetError()) != GL_NO_ERROR) - { - std::string error; - switch (errorCode) - { - case GL_INVALID_ENUM: error = "INVALID_ENUM"; break; - case GL_INVALID_VALUE: error = "INVALID_VALUE"; break; - case GL_INVALID_OPERATION: error = "INVALID_OPERATION"; break; - case GL_STACK_OVERFLOW: error = "STACK_OVERFLOW"; break; - case GL_STACK_UNDERFLOW: error = "STACK_UNDERFLOW"; break; - case GL_OUT_OF_MEMORY: error = "OUT_OF_MEMORY"; break; - case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break; - } - std::cout << error << " | " << file << " (" << line << ")" << std::endl; - throw std::runtime_error(error + " | " + file + " (" + std::to_string(line) + ")\n"); - } -} - -const std::vector image_iterator(const int width, const int height, const std::string desc){ - using namespace indicators; - std::shared_ptr bar(new ProgressBar{ - option::BarWidth{20}, - option::Start{"["}, - option::End{"]"}, - option::ShowElapsedTime{true}, - option::ShowRemainingTime{true}, - option::ForegroundColor{Color::blue}, - option::FontStyles{std::vector{FontStyle::bold}}, - option::PrefixText{desc} - }); - const size_t num_elements = width*height; - std::vector output; - output.reserve(num_elements); - size_t current_idx = 0; - int prev_percent = 0; - for (int y=0; y prev_percent); - output.push_back(loop_obj(x, y, (x+(height-y-1)*width) * 4, should_tick ? bar : nullptr)); - prev_percent = current_percent; - } - } - assert (current_idx == num_elements); - assert (num_elements == output.size()); - assert (output.back().progbar); - return output; -} - -Eigen::Tensor compute_flow_viz(const Eigen::Tensor &input_image){ - const int width = input_image.dimension(1); - const int height = input_image.dimension(0); - const double fac_x = (160.0/2) / width; - const double fac_y = (120.0/2) / height; - Eigen::Tensor output(height, width, 3); - output.setZero(); - - const int LEGEND_SIZE = 0; - - for (int y=0; y to_color_map(const Eigen::Tensor &input_image, const double &min_percentile, const double &max_percentile, const double &minval, const clrmap &type) { - std::vector all_nonzero_values; - const size_t width = input_image.dimension(1); - const size_t height = input_image.dimension(0); - all_nonzero_values.reserve(height*width); - for (int y=0; y minval) && (input_image(y,x) < 1e4)) - all_nonzero_values.push_back(input_image(y,x)); - } - } - std::sort(all_nonzero_values.begin(), all_nonzero_values.end()); - const double N = all_nonzero_values.size(); - const double cur_min = all_nonzero_values[int(N * min_percentile)]; - const double cur_max = all_nonzero_values[int(N * max_percentile) - 1]; - assert (cur_max > cur_min); - Eigen::Tensor output(height, width, 3); - output.setZero(); - for (int y=0; y minval) && (input_image(y,x) < 1e4)){ - const tinycolormap::Color color = tinycolormap::GetColor(value, type); - output(y,x,0) = color.r()*255; - output(y,x,1) = color.g()*255; - output(y,x,2) = color.b()*255; - } - } - } - return output; -} - - -Eigen::Tensor to_color_map(const Eigen::Tensor &input_image) { - std::vector all_nonzero_values; - const size_t width = input_image.dimension(1); - const size_t height = input_image.dimension(0); - Eigen::Tensor output(height, width, 3); - output.setZero(); - std::unordered_map int2double; - for (int y=0; y (rand()) / static_cast (RAND_MAX); - int2double[key] = value; - } - const tinycolormap::Color color = tinycolormap::GetColor(value, clrmap::Turbo); - output(y,x,0) = color.r()*255; - output(y,x,1) = color.g()*255; - output(y,x,2) = color.b()*255; - } - } - return output; -} diff --git a/infinigen/datagen/job_funcs.py b/infinigen/datagen/job_funcs.py index 7301d58a1..096ea5ce8 100644 --- a/infinigen/datagen/job_funcs.py +++ b/infinigen/datagen/job_funcs.py @@ -31,6 +31,12 @@ ) assert UPLOAD_UTIL_PATH.exists(), f"{UPLOAD_UTIL_PATH=} does not exist" +CUSTOMGT_PATH = Path(__file__).parent / "customgt" / "build" / "customgt" +if not CUSTOMGT_PATH.exists(): + logger.warning( + f"{CUSTOMGT_PATH=} does not exist, if opengl_gt is enabled it will fail" + ) + @gin.configurable def get_cmd( @@ -116,7 +122,21 @@ def queue_export( **kwargs, ): input_suffix = get_suffix(input_indices) - input_folder = f"{folder}/coarse{input_suffix}" + input_folder_priority_options = [ + f"fine{input_suffix}", + "fine", + f"coarse{input_suffix}", + "coarse", + ] + + for option in input_folder_priority_options: + input_folder = f"{folder}/{option}" + if (Path(input_folder) / "scene.blend").exists(): + break + else: + logger.warning( + f"No scene.blend found in {input_folder} for any of {input_folder_priority_options}" + ) cmd = ( get_cmd( @@ -482,13 +502,6 @@ def queue_mesh_save( return res, output_folder -process_mesh_path = Path(__file__).parent / "customgt" / "build" / "customgt" -if not process_mesh_path.exists(): - logger.warning( - f"{process_mesh_path=} does not exist, if opengl_gt is enabled it will fail" - ) - - @gin.configurable def queue_opengl( submit_cmd, @@ -548,26 +561,26 @@ def queue_opengl( f"{sys.executable} {infinigen.repo_root()/'infinigen/tools/process_static_meshes.py'} {input_folder} {point_trajectory_src_frame}" ) lines += [ - f"{process_mesh_path} -in {input_folder} -dst_in {input_folder} " - f"--frame {frame_idx} --dst_frame {frame_idx+1} -out {output_folder} " + f"{CUSTOMGT_PATH} --input_dir {input_folder} --dst_input_dir {input_folder} " + f"--frame {frame_idx} --dst_frame {frame_idx+1} --output_dir {output_folder} " for frame_idx in range(start_frame, end_frame + 1) ] # point trajectory lines += [ - f"{process_mesh_path} -in {input_folder} -dst_in {input_folder} " - f"--frame {point_trajectory_src_frame} --dst_frame {frame_idx} --flow_only 1 --flow_type 2 -out {output_folder} " + f"{CUSTOMGT_PATH} --input_dir {input_folder} --dst_input_dir {input_folder} " + f"--frame {point_trajectory_src_frame} --dst_frame {frame_idx} --flow_only 1 --flow_type 2 --output_dir {output_folder} " for frame_idx in range(start_frame, end_frame + 1) ] # depth of block end frame lines += [ - f"{process_mesh_path} -in {input_folder} -dst_in {input_folder} " - f"--frame {end_frame+1} --dst_frame {end_frame+1} --depth_only 1 -out {output_folder} " + f"{CUSTOMGT_PATH} --input_dir {input_folder} --dst_input_dir {input_folder} " + f"--frame {end_frame+1} --dst_frame {end_frame+1} --depth_only 1 --output_dir {output_folder} " ] # depth of point trajectory source frame lines += [ - f"{process_mesh_path} -in {input_folder} -dst_in {input_folder} " - f"--frame {point_trajectory_src_frame} --dst_frame {point_trajectory_src_frame} --depth_only 1 -out {output_folder} " + f"{CUSTOMGT_PATH} --input_dir {input_folder} --dst_input_dir {input_folder} " + f"--frame {point_trajectory_src_frame} --dst_frame {point_trajectory_src_frame} --depth_only 1 --output_dir {output_folder} " ] lines.append( diff --git a/infinigen/datagen/util/smb_client.py b/infinigen/datagen/util/smb_client.py index 6c6781a61..398d33d34 100644 --- a/infinigen/datagen/util/smb_client.py +++ b/infinigen/datagen/util/smb_client.py @@ -9,6 +9,7 @@ import argparse import logging import os +import re import subprocess import time import types @@ -153,6 +154,26 @@ def listdir(remote_path: Path, extras=False): yield from yield_dirfiles(data, extras, parent=remote_path) +def disk_usage(remote_path: Path): + data = run_command_stdout(f"recurse ON; du {remote_path}") + n_blocks, block_size, blocks_avail, file_bytes = map(int, re.findall(r"\d+", data)) + + gb_file = file_bytes / 1024**3 + msg = f"{gb_file:.2f} GB" + return msg + + +def disk_free(): + data = run_command_stdout("du infinigen") + data = data.splitlines()[1].strip() + n_blocks, block_size, blocks_avail = re.findall(r"\d+", data) + + gb_used = int(n_blocks) * int(block_size) / 1024**3 + gb_free = int(blocks_avail) * int(block_size) / 1024**3 + msg = f"Used: {gb_used:.2f} GB, Free: {gb_free:.2f} GB, Total: {gb_used + gb_free:.2f} GB" + return msg + + def run_command_stdout(command: str): smb_str = os.environ[SMB_AUTH_VARNAME] time.sleep(_SMB_RATELIMIT_DELAY) @@ -211,24 +232,6 @@ def mapfunc(f, its, args): executor.map_array(f, its) -def process_one(p: list[Path]): - res = commands[args.command](*p) - - p_summary = " ".join(str(pi) for pi in p) - - def result(r): - if args.verbose: - print(f"{args.command} {p_summary}: {r}") - else: - print(r) - - if isinstance(res, types.GeneratorType): - for r in res: - result(r) - else: - result(res) - - def resolve_globs(p: Path, args): def resolved(parts): if any(x in str(p) for x in args.exclude): @@ -259,9 +262,36 @@ def resolved(parts): "upload": upload, "mkdir": mkdir, "exists": check_exists, + "du": disk_usage, + "df": disk_free, } +def process_one(p: list[Path]): + p = [Path(pi) for pi in p] + + if args.command not in commands: + raise ValueError( + f"Unrecognized command {args.command}, options are {commands.keys()}" + ) + + res = commands[args.command](*p) + + p_summary = " ".join(str(pi) for pi in p) + + def result(r): + if args.verbose: + print(f"{p_summary} {r}") + else: + print(r) + + if isinstance(res, types.GeneratorType): + for r in res: + result(r) + else: + result(res) + + def main(args): n_globs = len([x for x in args.paths if "*" in str(x)]) if n_globs > 1: @@ -277,7 +307,7 @@ def main(args): if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("command", type=str, choices=list(commands.keys())) - parser.add_argument("paths", type=Path, nargs="+") + parser.add_argument("paths", type=Path, nargs="*") parser.add_argument("--exclude", type=str, nargs="+", default=[]) parser.add_argument("--n_workers", type=int, default=1) parser.add_argument("--slurm", action="store_true") diff --git a/infinigen/terrain/core.py b/infinigen/terrain/core.py index 79de8a2b5..b6ba877cd 100644 --- a/infinigen/terrain/core.py +++ b/infinigen/terrain/core.py @@ -202,11 +202,9 @@ def cleanup(self): for e in self.elements: self.elements[e].cleanup() - @gin.configurable() def export( self, - dynamic=False, - spherical=True, # false for OcMesher + mesher_backend="SphericalMesher", cameras=None, main_terrain_only=False, remove_redundant_attrs=True, @@ -221,13 +219,14 @@ def export( ] if opaque_elements != []: attributes_dict[TerrainNames.OpaqueTerrain] = set() - if dynamic: - if spherical: - mesher = OpaqueSphericalMesher(cameras, self.bounds) - else: + if mesher_backend == "SphericalMesher": + mesher = OpaqueSphericalMesher(cameras, self.bounds) + elif mesher_backend == "OcMesher": mesher = OcMesher(cameras, self.bounds) - else: + elif mesher_backend == "UniformMesher": mesher = UniformMesher(self.populated_bounds) + else: + raise ValueError("unrecognized mesher_backend") with Timer(f"meshing {TerrainNames.OpaqueTerrain}"): mesh = mesher([element for element in opaque_elements]) meshes_dict[TerrainNames.OpaqueTerrain] = mesh @@ -243,12 +242,12 @@ def export( ] for element in individual_transparent_elements: if not main_terrain_only or element.__class__.name == self.main_terrain: - if dynamic: + if mesher_backend in ["SphericalMesher", "OcMesher"]: special_args = {} if element.__class__.name == ElementNames.Atmosphere: special_args["pixels_per_cube"] = 100 special_args["inv_scale"] = 1 - if spherical: + if mesher_backend == "SphericalMesher": mesher = TransparentSphericalMesher( cameras, self.bounds, **special_args ) @@ -259,8 +258,10 @@ def export( simplify_occluded=False, **special_args, ) - else: + elif mesher_backend == "UniformMesher": mesher = UniformMesher(self.populated_bounds, enclosed=True) + else: + raise ValueError("unrecognized mesher_backend") with Timer(f"meshing {element.__class__.name}"): mesh = mesher([element]) meshes_dict[element.__class__.name] = mesh @@ -277,15 +278,16 @@ def export( ] if collective_transparent_elements != []: attributes_dict[TerrainNames.CollectiveTransparentTerrain] = set() - if dynamic: - if spherical: - mesher = TransparentSphericalMesher(cameras, self.bounds) - else: - mesher = CollectiveOcMesher( - cameras, self.bounds, simplify_occluded=False - ) - else: + if mesher_backend == "SphericalMesher": + mesher = TransparentSphericalMesher(cameras, self.bounds) + elif mesher_backend == "OcMesher": + mesher = CollectiveOcMesher( + cameras, self.bounds, simplify_occluded=False + ) + elif mesher_backend == "UniformMesher": mesher = UniformMesher(self.populated_bounds) + else: + raise ValueError("unrecognized mesher_backend") with Timer(f"meshing {TerrainNames.CollectiveTransparentTerrain}"): mesh = mesher( [element for element in collective_transparent_elements] @@ -296,7 +298,7 @@ def export( element.attributes ) - if main_terrain_only or dynamic: + if main_terrain_only or cameras is not None: for mesh_name in meshes_dict: mesh_name_unapplied = mesh_name if mesh_name + "_unapplied" in bpy.data.objects.keys(): @@ -327,7 +329,7 @@ def export( surface.mod_name ) - if dynamic: + if cameras is not None: if remove_redundant_attrs: for mesh_name in meshes_dict: if len(attributes_dict[mesh_name]) == 1: @@ -404,7 +406,7 @@ def surfaces_into_sdf(self): @gin.configurable def coarse_terrain(self): - coarse_meshes, attributes_dict = self.export() + coarse_meshes, attributes_dict = self.export(mesher_backend="UniformMesher") terrain_objs = {} for name in coarse_meshes: obj = coarse_meshes[name].export_blender(name) @@ -416,8 +418,8 @@ def coarse_terrain(self): self.apply_surface_templates(attributes_dict) self.surfaces_into_sdf() - # do second time to avoid surface application difference resulting in cloating rocks - coarse_meshes, _ = self.export(main_terrain_only=True) + # do second time to avoid surface application difference resulting in floating rocks + coarse_meshes, _ = self.export(main_terrain_only=True, mesher_backend="UniformMesher") main_mesh = coarse_meshes[self.main_terrain] # WaterCovered annotation @@ -444,7 +446,8 @@ def coarse_terrain(self): self.tag_terrain(self.terrain_objs[name]) return main_obj - def fine_terrain(self, output_folder, cameras, optimize_terrain_diskusage=True): + @gin.configurable + def fine_terrain(self, output_folder, cameras, optimize_terrain_diskusage=True, mesher_backend="SphericalMesher"): # redo sampling to achieve attribute -> surface correspondance self.sample_surface_templates() if (self.on_the_fly_asset_folder / Assets.Ocean).exists(): @@ -456,7 +459,7 @@ def fine_terrain(self, output_folder, cameras, optimize_terrain_diskusage=True): link_folder=self.on_the_fly_asset_folder / Assets.Ocean, ) self.surfaces_into_sdf() - fine_meshes, _ = self.export(dynamic=True, cameras=cameras) + fine_meshes, _ = self.export(mesher_backend=mesher_backend, cameras=cameras) for mesh_name in fine_meshes: obj = fine_meshes[mesh_name].export_blender(mesh_name + "_fine") if mesh_name not in hidden_in_viewport: diff --git a/infinigen/terrain/mesher/spherical_mesher.py b/infinigen/terrain/mesher/spherical_mesher.py index 69e126e26..2e47b1ceb 100644 --- a/infinigen/terrain/mesher/spherical_mesher.py +++ b/infinigen/terrain/mesher/spherical_mesher.py @@ -48,7 +48,7 @@ def __init__( cams = full_info[0] assert ( self.fov[0] < np.pi / 2 and self.fov[1] < np.pi / 2 - ), "the algorithm does not support larger-than-90-degree fov yet" + ), "`mesher_backend=SphericalMesher` does not support larger-than-90-degree fov yet. Please add `fine_terrain.mesher_backend = \"OcMesher\"` to your gin config." self.r_min = r_min self.complete_depth_test = complete_depth_test self.bounds = bounds diff --git a/infinigen/tools/export.py b/infinigen/tools/export.py index 8debf69ff..d865d4e05 100644 --- a/infinigen/tools/export.py +++ b/infinigen/tools/export.py @@ -761,7 +761,6 @@ def export_scene( task_uniqname=None, **kwargs, ): - bpy.ops.wm.open_mainfile(filepath=str(input_blend)) folder = output_folder / f"export_{input_blend.name}" folder.mkdir(exist_ok=True, parents=True) export_curr_scene(folder, **kwargs) diff --git a/infinigen_examples/configs_indoor/base_indoors.gin b/infinigen_examples/configs_indoor/base_indoors.gin index 9894140a8..019c593ed 100644 --- a/infinigen_examples/configs_indoor/base_indoors.gin +++ b/infinigen_examples/configs_indoor/base_indoors.gin @@ -11,12 +11,13 @@ SimulatedAnnealingSolver.final_temp = 0.001 SimulatedAnnealingSolver.finetune_pct = 0.15 SimulatedAnnealingSolver.max_invalid_candidates = 5 -render_image.use_dof = True +configure_render_cycles.num_samples = 16000 + animate_cameras.follow_poi_chance=0.0 camera.camera_pose_proposal.altitude = ("clip_gaussian", 1.5, 0.8, 0.5, 2.2) camera.camera_pose_proposal.pitch = ("clip_gaussian", 90, 15, 60, 95) camera.camera_pose_proposal.focal_length = 15 -export.spherical = False # spherical mesher doesnt support short focal length / wide fov +fine_terrain.mesher_backend = "OcMesher" # spherical mesher doesnt support short focal length / wide fov camera.spawn_camera_rigs.n_camera_rigs = 1 camera.spawn_camera_rigs.camera_rig_config = [ diff --git a/infinigen_examples/configs_nature/noisy_video.gin b/infinigen_examples/configs_nature/noisy_video.gin index 1d5e2ccb5..d5946bdf6 100644 --- a/infinigen_examples/configs_nature/noisy_video.gin +++ b/infinigen_examples/configs_nature/noisy_video.gin @@ -1,4 +1,4 @@ -export.spherical = False # use OcMesher +fine_terrain.mesher_backend = "OcMesher" AnimPolicyRandomWalkLookaround.speed = ("uniform", 3, 10) AnimPolicyRandomWalkLookaround.yaw_sampler = ("uniform", -50, 50) AnimPolicyRandomWalkLookaround.step_range = ('clip_gaussian', 1, 3, 0.6, 5) diff --git a/infinigen_examples/configs_nature/trailer_video.gin b/infinigen_examples/configs_nature/trailer_video.gin index 52d7ec78a..dfc993b7a 100644 --- a/infinigen_examples/configs_nature/trailer_video.gin +++ b/infinigen_examples/configs_nature/trailer_video.gin @@ -1,4 +1,4 @@ -export.spherical = False # use OcMesher +fine_terrain.mesher_backend = "OcMesher" AnimPolicyRandomWalkLookaround.speed = ('uniform', 0.5, 1) AnimPolicyRandomWalkLookaround.step_speed_mult = 1 AnimPolicyRandomWalkLookaround.yaw_sampler = ('uniform',-20, 20) diff --git a/infinigen_examples/generate_indoors.py b/infinigen_examples/generate_indoors.py index 94daa44de..337133fa7 100644 --- a/infinigen_examples/generate_indoors.py +++ b/infinigen_examples/generate_indoors.py @@ -291,6 +291,8 @@ def solve_small(): p.run_stage("solve_small", solve_small, use_chance=False, default=state) + solver.optim.save_stats(output_folder / "optim_records.csv") + p.run_stage( "populate_assets", populate.populate_state_placeholders, state, use_chance=False ) diff --git a/infinigen_examples/generate_nature.py b/infinigen_examples/generate_nature.py index 8cee43707..8f689dc61 100644 --- a/infinigen_examples/generate_nature.py +++ b/infinigen_examples/generate_nature.py @@ -658,10 +658,6 @@ def add_corals(target): camera_rigs[0], "cube", offset=Vector(), size=30 ) - butil.constrain_object( - cube_emitter, "COPY_LOCATION", use_offset=True, target=camera_rigs[0] - ) - def leaf_particles(): gen = weather.FallingParticles( leaves.LeafFactoryV2(randint(1e7)), @@ -669,7 +665,7 @@ def leaf_particles(): ) return gen(overhead_emitter) - p.run_stage("leaf_particles", leaf_particles, prereq="trees") + p.run_stage("leaf_particles", leaf_particles) def rain_particles(): gen = weather.FallingParticles(