diff --git a/modules/mesh_data_resource/SCsub b/modules/mesh_data_resource/SCsub index 230235940..d74823ade 100644 --- a/modules/mesh_data_resource/SCsub +++ b/modules/mesh_data_resource/SCsub @@ -27,6 +27,10 @@ if 'TOOLS_ENABLED' in env["CPPDEFINES"]: module_env.add_source_files(env.modules_sources,"plugin_gltf/editor_import_gltf_mdr.cpp") module_env.add_source_files(env.modules_sources,"plugin_gltf/editor_plugin_gltf_mdr.cpp") + module_env.add_source_files(env.modules_sources,"editor/utilities/mdr_ed_mesh_decompose.cpp") + #module_env.add_source_files(env.modules_sources,"editor/utilities/mdr_ed_mesh_outline.cpp") + #module_env.add_source_files(env.modules_sources,"editor/utilities/mdr_ed_mesh_utils.cpp") + module_env.add_source_files(env.modules_sources,"nodes/mesh_data_instance.cpp") module_env.add_source_files(env.modules_sources,"nodes/mesh_data_instance_2d.cpp") diff --git a/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.cpp b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.cpp index 00f8617a0..828776b6c 100644 --- a/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.cpp +++ b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.cpp @@ -22,199 +22,372 @@ SOFTWARE. #include "mdr_ed_mesh_decompose.h" +#include "modules/mesh_utils/mesh_utils.h" +#include "scene/resources/mesh.h" +#include "../../mesh_data_resource.h" + //you can use MeshUtils.merge_mesh_array(arr) to get optimalized handle points. Just get the vertices from it. -Array MDREDMeshDecompose::get_handle_vertex_to_vertex_map(Array arrays, PoolVector3Array handle_points) { - /* - var handle_to_vertex_map : Array - handle_to_vertex_map.resize(handle_points.size()) +Array MDREDMeshDecompose::get_handle_vertex_to_vertex_map(const Array &arrays, const PoolVector3Array &handle_points) { + Array handle_to_vertex_map; + handle_to_vertex_map.resize(handle_points.size()); - if handle_points.size() == 0: - return handle_to_vertex_map + if (handle_points.size() == 0) { + return handle_to_vertex_map; + } - if arrays.size() != ArrayMesh.ARRAY_MAX || arrays[ArrayMesh.ARRAY_INDEX] == null: - return handle_to_vertex_map + if (arrays.size() != ArrayMesh::ARRAY_MAX || arrays[ArrayMesh::ARRAY_INDEX].is_null()) { + return handle_to_vertex_map; + } - var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] + PoolVector3Array vertices = arrays[ArrayMesh::ARRAY_VERTEX]; - if vertices.size() == 0: - return handle_to_vertex_map + if (vertices.size() == 0) { + return handle_to_vertex_map; + } - for i in range(handle_points.size()): - var hv : Vector3 = handle_points[i] - var iarr : PoolIntArray = PoolIntArray() + for (int i = 0; i < handle_points.size(); ++i) { + Vector3 hv = handle_points[i]; + PoolIntArray iarr; - #find all verts that have the same position as the handle - for j in range(vertices.size()): - var vn : Vector3 = vertices[j] + //find all verts that have the same position as the handle + for (int j = 0; j < vertices.size(); ++j) { + Vector3 vn = vertices[j]; - if is_equal_approx(hv.x, vn.x) && is_equal_approx(hv.y, vn.y) && is_equal_approx(hv.z, vn.z): - iarr.append(j) + if (Math::is_equal_approx(hv.x, vn.x) && Math::is_equal_approx(hv.y, vn.y) && Math::is_equal_approx(hv.z, vn.z)) { + iarr.append(j); + } + } - handle_to_vertex_map[i] = iarr + handle_to_vertex_map[i] = iarr; + } - return handle_to_vertex_map - - */ + return handle_to_vertex_map; } //returns an array: //index 0 is the handle_points //index 1 is the handle_to_vertex_map -Array MDREDMeshDecompose::get_handle_edge_to_vertex_map(Array arrays) { - /* +Array MDREDMeshDecompose::get_handle_edge_to_vertex_map(const Array &arrays) { + Array handle_to_vertex_map; + PoolVector3Array handle_points; - */ + Array ret; + + if (arrays.size() != ArrayMesh::ARRAY_MAX || arrays[ArrayMesh::ARRAY_INDEX].is_null()) { + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; + } + + PoolVector3Array vertices = arrays[ArrayMesh::ARRAY_VERTEX]; + + if (vertices.size() == 0) { + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; + } + + Array arr; + arr.resize(ArrayMesh::ARRAY_MAX); + arr[ArrayMesh::ARRAY_VERTEX] = arrays[ArrayMesh::ARRAY_VERTEX]; + arr[ArrayMesh::ARRAY_INDEX] = arrays[ArrayMesh::ARRAY_INDEX]; + + Array optimized_arrays = MeshUtils::get_singleton()->merge_mesh_array(arr); + PoolVector3Array optimized_verts = optimized_arrays[ArrayMesh::ARRAY_VERTEX]; + PoolIntArray optimized_indices = optimized_arrays[ArrayMesh::ARRAY_INDEX]; + + Array vert_to_optimized_vert_map = get_handle_vertex_to_vertex_map(arrays, optimized_verts); + + Dictionary edge_map; + + for (int i = 0; i < optimized_indices.size(); i += 3) { + for (int j = 0; j < 3; ++j) { + int i0 = optimized_indices[i + j]; + int i1 = optimized_indices[i + ((j + 1) % 3)]; + + int ei0 = MIN(i0, i1); + int ei1 = MAX(i0, i1); + + if (!edge_map.has(ei0)) { + edge_map[ei0] = PoolIntArray(); + } + + PoolIntArray etm = edge_map[ei0]; + + PoolIntArray::Read r = etm.read(); + + bool found = false; + for (int i = 0; i < etm.size(); ++i) { + if (etm[i] == ei1) { + found = true; + break; + } + } + + r.release(); + + if (!found) { + etm.append(ei1); + edge_map[ei0] = etm; + } + } + } + + Array keys = edge_map.keys(); + + for (int k = 0; k < keys.size(); ++k) { + int key = keys[k]; + PoolIntArray indices = edge_map[key]; + + PoolIntArray::Read r = indices.read(); + + for (int i = 0; i < keys.size(); ++i) { + int indx = r[i]; + int ei0 = key; + int ei1 = indx; + + Vector3 v0 = optimized_verts[ei0]; + Vector3 v1 = optimized_verts[ei1]; + + Vector3 emid = v0.linear_interpolate(v1, 0.5); + handle_points.append(emid); + //int hindx = handle_points.size() - 1; + + PoolIntArray vm0 = vert_to_optimized_vert_map[ei0]; + PoolIntArray vm1 = vert_to_optimized_vert_map[ei1]; + + PoolIntArray vm = PoolIntArray(); + vm.append_array(vm0); + + PoolIntArray::Read vm1r = vm1.read(); + + for (int v = 0; v < vm1.size(); ++v) { + int vi = vm1r[v]; + bool found = false; + + PoolIntArray::Read vmr = vm.read(); + + for (int vrind = 0; vrind < vm.size(); ++vrind) { + int vit = vmr[vrind]; + if (vi == vit) { + found = true; + break; + } + } + + vmr.release(); + + if (!found) { + vm.append(vi); + } + } + + vm1r.release(); + + handle_to_vertex_map.append(vm); + } + } + + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; } //returns an array: //index 0 is the handle_points //index 1 is the handle_to_vertex_map -Array MDREDMeshDecompose::get_handle_face_to_vertex_map(Array arrays) { - /* - var handle_to_vertex_map : Array - var handle_points : PoolVector3Array +Array MDREDMeshDecompose::get_handle_face_to_vertex_map(const Array &arrays) { + Array handle_to_vertex_map; + PoolVector3Array handle_points; - if arrays.size() != ArrayMesh.ARRAY_MAX || arrays[ArrayMesh.ARRAY_INDEX] == null: - return [ handle_points, handle_to_vertex_map ] + Array ret; - var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] + if (arrays.size() != ArrayMesh::ARRAY_MAX || arrays[ArrayMesh::ARRAY_INDEX].is_null()) { + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; + } - if vertices.size() == 0: - return [ handle_points, handle_to_vertex_map ] + PoolVector3Array vertices = arrays[ArrayMesh::ARRAY_VERTEX]; - var arr : Array = Array() - arr.resize(ArrayMesh.ARRAY_MAX) - arr[ArrayMesh.ARRAY_VERTEX] = arrays[ArrayMesh.ARRAY_VERTEX] - arr[ArrayMesh.ARRAY_INDEX] = arrays[ArrayMesh.ARRAY_INDEX] + if (vertices.size() == 0) { + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; + } - var optimized_arrays : Array = MeshUtils.merge_mesh_array(arr) - var optimized_verts : PoolVector3Array = optimized_arrays[ArrayMesh.ARRAY_VERTEX] - var optimized_indices : PoolIntArray = optimized_arrays[ArrayMesh.ARRAY_INDEX] + Array arr; + arr.resize(ArrayMesh::ARRAY_MAX); + arr[ArrayMesh::ARRAY_VERTEX] = arrays[ArrayMesh::ARRAY_VERTEX]; + arr[ArrayMesh::ARRAY_INDEX] = arrays[ArrayMesh::ARRAY_INDEX]; - var vert_to_optimized_vert_map : Array = get_handle_vertex_to_vertex_map(arrays, optimized_verts) + Array optimized_arrays = MeshUtils::get_singleton()->merge_mesh_array(arr); + PoolVector3Array optimized_verts = optimized_arrays[ArrayMesh::ARRAY_VERTEX]; + PoolIntArray optimized_indices = optimized_arrays[ArrayMesh::ARRAY_INDEX]; - for i in range(0, optimized_indices.size(), 3): - var i0 : int = optimized_indices[i + 0] - var i1 : int = optimized_indices[i + 1] - var i2 : int = optimized_indices[i + 2] + Array vert_to_optimized_vert_map = get_handle_vertex_to_vertex_map(arrays, optimized_verts); - var v0 : Vector3 = optimized_verts[i0] - var v1 : Vector3 = optimized_verts[i1] - var v2 : Vector3 = optimized_verts[i2] + for (int i = 0; i < optimized_indices.size(); i += 3) { + int i0 = optimized_indices[i + 0]; + int i1 = optimized_indices[i + 1]; + int i2 = optimized_indices[i + 2]; - var pmid : Vector3 = v0 + v1 + v2 - pmid /= 3 - handle_points.append(pmid) + Vector3 v0 = optimized_verts[i0]; + Vector3 v1 = optimized_verts[i1]; + Vector3 v2 = optimized_verts[i2]; - var vm0 : PoolIntArray = vert_to_optimized_vert_map[i0] - var vm1 : PoolIntArray = vert_to_optimized_vert_map[i1] - var vm2 : PoolIntArray = vert_to_optimized_vert_map[i2] + Vector3 pmid = v0 + v1 + v2; + pmid /= 3; + handle_points.append(pmid); - var vm : PoolIntArray = PoolIntArray() - vm.append_array(vm0) + PoolIntArray vm0 = vert_to_optimized_vert_map[i0]; + PoolIntArray vm1 = vert_to_optimized_vert_map[i1]; + PoolIntArray vm2 = vert_to_optimized_vert_map[i2]; - for vi in vm1: - var found : bool = false - for vit in vm: - if vi == vit: - found = true - break + PoolIntArray vm = PoolIntArray(); + vm.append_array(vm0); - if !found: - vm.append(vi) + PoolIntArray::Read vm1r = vm1.read(); - for vi in vm2: - var found : bool = false - for vit in vm: - if vi == vit: - found = true - break + for (int v = 0; v < vm1.size(); ++v) { + int vi = vm1r[v]; + bool found = false; - if !found: - vm.append(vi) + PoolIntArray::Read vmr = vm.read(); - handle_to_vertex_map.append(vm) + for (int vrind = 0; vrind < vm.size(); ++vrind) { + int vit = vmr[vrind]; + if (vi == vit) { + found = true; + break; + } + } - return [ handle_points, handle_to_vertex_map ] - */ + vmr.release(); + + if (!found) { + vm.append(vi); + } + } + + vm1r.release(); + + PoolIntArray::Read vm2r = vm2.read(); + + for (int v = 0; v < vm2.size(); ++v) { + int vi = vm2r[v]; + bool found = false; + + PoolIntArray::Read vmr = vm.read(); + + for (int vrind = 0; vrind < vm.size(); ++vrind) { + int vit = vmr[vrind]; + if (vi == vit) { + found = true; + break; + } + } + + vmr.release(); + + if (!found) { + vm.append(vi); + } + } + + vm2r.release(); + + handle_to_vertex_map.append(vm); + } + + ret.append(handle_points); + ret.append(handle_to_vertex_map); + return ret; } + PoolVector3Array MDREDMeshDecompose::calculate_map_midpoints(Array mesh, Array vertex_map) { - /* - return PoolVector3Array() - */ + return PoolVector3Array(); } -bool MDREDMeshDecompose::pool_int_arr_contains(PoolIntArray arr, int val) { - /* - for a in arr: - if a == val: - return true - return false - */ +bool MDREDMeshDecompose::pool_int_arr_contains(const PoolIntArray &arr, const int val) { + PoolIntArray::Read r = arr.read(); + + for (int i = 0; i < arr.size(); ++i) { + if (r[i] == val) { + return true; + } + } + + return false; } + Array MDREDMeshDecompose::partition_mesh(Ref mdr) { - /* - var partitions : Array = Array() + Array partitions; - var arrays : Array = mdr.get_array() + Array arrays = mdr->get_array(); - if arrays.size() != ArrayMesh.ARRAY_MAX: - return partitions + if (arrays.size() != ArrayMesh::ARRAY_MAX) { + return partitions; + } - if arrays[ArrayMesh.ARRAY_INDEX] == null: - return partitions + if (arrays[ArrayMesh::ARRAY_INDEX].is_null()) { + return partitions; + } - var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] + PoolIntArray indices = arrays[ArrayMesh::ARRAY_INDEX]; - var triangle_count : int = indices.size() / 3 - var processed_triangles : PoolIntArray = PoolIntArray() + int triangle_count = indices.size() / 3; + PoolIntArray processed_triangles = PoolIntArray(); - while triangle_count != processed_triangles.size(): - var partition : PoolIntArray = PoolIntArray() + while (triangle_count != processed_triangles.size()) { + PoolIntArray partition = PoolIntArray(); - var first : bool = true - var triangle_added : bool = true - while triangle_added: - triangle_added = false - for i in range(indices.size()): - var triangle_index : int = i / 3 + bool first = true; + bool triangle_added = true; + while (triangle_added) { + triangle_added = false; + for (int i = 0; i < indices.size(); ++i) { + int triangle_index = i / 3; - if pool_int_arr_contains(processed_triangles, triangle_index): - continue + if (pool_int_arr_contains(processed_triangles, triangle_index)) { + continue; + } - if first: - first = false + if (first) { + first = false; - # We have to be at the 0th index of a triangle - partition.append(indices[i]) - partition.append(indices[i + 1]) - partition.append(indices[i + 2]) + // We have to be at the 0th index of a triangle + partition.append(indices[i]); + partition.append(indices[i + 1]); + partition.append(indices[i + 2]); - triangle_added = true - break + triangle_added = true; + break; + } - var index : int = indices[i] + int index = indices[i]; - if pool_int_arr_contains(partition, index): - processed_triangles.append(triangle_index) + if (pool_int_arr_contains(partition, index)) { + processed_triangles.append(triangle_index); - var tri_start_index : int = i - (i % 3) + int tri_start_index = i - (i % 3); - var i0 : int = indices[tri_start_index] - var i1 : int = indices[tri_start_index + 1] - var i2 : int = indices[tri_start_index + 2] + int i0 = indices[tri_start_index]; + int i1 = indices[tri_start_index + 1]; + int i2 = indices[tri_start_index + 2]; - partition.append(i0) - partition.append(i1) - partition.append(i2) + partition.append(i0); + partition.append(i1); + partition.append(i2); - triangle_added = true - break + triangle_added = true; + break; + } + } + } + partitions.append(partition); + } - partitions.append(partition) - - - return partitions - */ + return partitions; } diff --git a/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.h b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.h index cf8919893..5192b3ae6 100644 --- a/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.h +++ b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_decompose.h @@ -33,19 +33,19 @@ class MeshDataResource; class MDREDMeshDecompose { public: //you can use MeshUtils.merge_mesh_array(arr) to get optimalized handle points. Just get the vertices from it. - static Array get_handle_vertex_to_vertex_map(Array arrays, PoolVector3Array handle_points); + static Array get_handle_vertex_to_vertex_map(const Array &arrays, const PoolVector3Array &handle_points); //returns an array: //index 0 is the handle_points //index 1 is the handle_to_vertex_map - static Array get_handle_edge_to_vertex_map(Array arrays); + static Array get_handle_edge_to_vertex_map(const Array &arrays); //returns an array: //index 0 is the handle_points //index 1 is the handle_to_vertex_map - static Array get_handle_face_to_vertex_map(Array arrays); + static Array get_handle_face_to_vertex_map(const Array &arrays); static PoolVector3Array calculate_map_midpoints(Array mesh, Array vertex_map); - static bool pool_int_arr_contains(PoolIntArray arr, int val); + static bool pool_int_arr_contains(const PoolIntArray &arr, const int val); static Array partition_mesh(Ref mdr); };