Implemented the clean mesh action.

This commit is contained in:
Relintai 2022-01-27 20:34:49 +01:00
parent 4e1c6046b0
commit ce1c408bc2
5 changed files with 194 additions and 2 deletions

View File

@ -247,3 +247,6 @@ func onhandle_selection_type_back_toggled(on : bool):
func onhandle_selection_type_all_toggled(on : bool):
if on:
_plugin.handle_selection_type_all()
func _on_clean_mesh_pressed():
_plugin.clean_mesh()

View File

@ -754,7 +754,7 @@ size_flags_vertical = 3
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/GenTangents" to="." method="_on_GenTangents_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/RemDoubles" to="." method="_on_RemDoubles_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/MergeOptimize" to="." method="_on_MergeOptimize_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/Clean" to="." method="_on_MergeOptimize_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/Clean" to="." method="_on_clean_mesh_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/UVEditButton" to="." method="_on_uv_edit_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/ApplySeams" to="." method="_on_apply_seams_pressed"]
[connection signal="pressed" from="VBoxContainer/ScrollContainer/VBoxContainer2/Operations/Operations/UnwrapButton2" to="." method="_on_UnwrapButton_pressed"]

View File

@ -1550,7 +1550,34 @@ func apply_seam():
add_mesh_change_undo_redo(orig_arr, _mdr.array, "apply_seam")
enable_change_event()
func clean_mesh():
if !_mdr:
return
var arrays : Array = _mdr.array
if arrays.size() != ArrayMesh.ARRAY_MAX:
return arrays
if arrays[ArrayMesh.ARRAY_VERTEX] == null || arrays[ArrayMesh.ARRAY_INDEX] == null:
return arrays
var old_vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size()
disable_change_event()
var orig_arr : Array = copy_arrays(arrays)
arrays = MDRMeshUtils.remove_used_vertices(arrays)
var new_vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size()
add_mesh_change_undo_redo(orig_arr, arrays, "clean_mesh")
enable_change_event()
var d : int = old_vert_size - new_vert_size
print("MDRED: Removed " + str(d) + " unused vertices.")
func uv_unwrap() -> void:
if !_mdr:
return

View File

@ -276,3 +276,7 @@ func handle_selection_type_all():
func extrude():
if current_mesh_data_instance && current_mesh_data_instance.gizmo:
current_mesh_data_instance.gizmo.extrude()
func clean_mesh():
if current_mesh_data_instance && current_mesh_data_instance.gizmo:
current_mesh_data_instance.gizmo.clean_mesh()

View File

@ -861,6 +861,164 @@ static func generate_tangents(mdr : MeshDataResource) -> void:
mdr.array = st.commit_to_arrays()
static func remove_used_vertices(arrays : Array) -> Array:
if arrays.size() != ArrayMesh.ARRAY_MAX:
return arrays
if arrays[ArrayMesh.ARRAY_VERTEX] == null || arrays[ArrayMesh.ARRAY_INDEX] == null:
return arrays
var vert_size : int = arrays[ArrayMesh.ARRAY_VERTEX].size()
var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX]
var unused_indices : PoolIntArray = PoolIntArray()
for i in range(vert_size):
if !pool_int_arr_contains(indices, i):
unused_indices.append(i)
remove_vertices(arrays, unused_indices)
return arrays
static func remove_vertices(arrays : Array, indices : PoolIntArray) -> Array:
if indices.size() == 0:
return arrays
var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX]
var normals : PoolVector3Array
var tangents : PoolRealArray
var colors : PoolColorArray
var uv : PoolVector2Array
var uv2 : PoolVector2Array
var bones : PoolRealArray
var weights : PoolRealArray
if arrays[ArrayMesh.ARRAY_NORMAL] != null:
normals = arrays[ArrayMesh.ARRAY_NORMAL]
if arrays[ArrayMesh.ARRAY_TANGENT] != null:
tangents = arrays[ArrayMesh.ARRAY_TANGENT]
if arrays[ArrayMesh.ARRAY_COLOR] != null:
colors = arrays[ArrayMesh.ARRAY_COLOR]
if arrays[ArrayMesh.ARRAY_TEX_UV] != null:
uv = arrays[ArrayMesh.ARRAY_TEX_UV]
if arrays[ArrayMesh.ARRAY_TEX_UV2] != null:
uv2 = arrays[ArrayMesh.ARRAY_TEX_UV2]
if arrays[ArrayMesh.ARRAY_BONES] != null:
bones = arrays[ArrayMesh.ARRAY_BONES]
if arrays[ArrayMesh.ARRAY_WEIGHTS] != null:
weights = arrays[ArrayMesh.ARRAY_WEIGHTS]
for index in indices:
vertices.remove(index)
if arrays[ArrayMesh.ARRAY_NORMAL] != null:
normals.remove(index)
if arrays[ArrayMesh.ARRAY_TANGENT] != null:
var tindex : int = index * 4
tangents.remove(tindex)
tangents.remove(tindex)
tangents.remove(tindex)
tangents.remove(tindex)
if arrays[ArrayMesh.ARRAY_COLOR] != null:
colors.remove(index)
if arrays[ArrayMesh.ARRAY_TEX_UV] != null:
uv.remove(index)
if arrays[ArrayMesh.ARRAY_TEX_UV2] != null:
uv2.remove(index)
if arrays[ArrayMesh.ARRAY_BONES] != null:
bones.remove(index)
bones.remove(index)
bones.remove(index)
bones.remove(index)
if arrays[ArrayMesh.ARRAY_WEIGHTS] != null:
weights.remove(index)
weights.remove(index)
weights.remove(index)
weights.remove(index)
#write back
arrays[ArrayMesh.ARRAY_VERTEX] = vertices
if arrays[ArrayMesh.ARRAY_NORMAL] != null:
arrays[ArrayMesh.ARRAY_NORMAL] = normals
if arrays[ArrayMesh.ARRAY_TANGENT] != null:
arrays[ArrayMesh.ARRAY_TANGENT] = tangents
if arrays[ArrayMesh.ARRAY_COLOR] != null:
arrays[ArrayMesh.ARRAY_COLOR] = colors
if arrays[ArrayMesh.ARRAY_TEX_UV] != null:
arrays[ArrayMesh.ARRAY_TEX_UV] = uv
if arrays[ArrayMesh.ARRAY_TEX_UV2] != null:
arrays[ArrayMesh.ARRAY_TEX_UV2] = uv2
if arrays[ArrayMesh.ARRAY_BONES] != null:
arrays[ArrayMesh.ARRAY_BONES] = bones
if arrays[ArrayMesh.ARRAY_WEIGHTS] != null:
arrays[ArrayMesh.ARRAY_WEIGHTS] = weights
if arrays[ArrayMesh.ARRAY_INDEX] == null:
return arrays
#udpate indices
var arr_indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX]
var max_index : int = find_max(indices)
for k in range(indices.size()):
for i in range(arr_indices.size()):
var ai : int = arr_indices[i]
if ai >= max_index:
arr_indices[i] = ai - 1
max_index = find_max_capped(indices, max_index)
arrays[ArrayMesh.ARRAY_INDEX] = arr_indices
return arrays
static func find_max(arr : PoolIntArray) -> int:
var m : int = arr[0]
for v in arr:
if v > m:
m = v
return m
static func find_max_capped(arr : PoolIntArray, last : int) -> int:
var m : int = 0
for v in arr:
if v < last:
m = v
break
for v in arr:
if v > m && v < last:
m = v
return m
static func order_seam_indices(arr : PoolIntArray) -> PoolIntArray:
var ret : PoolIntArray = PoolIntArray()
@ -1021,7 +1179,7 @@ static func pool_int_arr_contains(arr : PoolIntArray, val : int) -> bool:
return true
return false
class SeamTriangleHelper:
var i0 : int = 0