From d3118e1d4b109a5be5c81a2d553ebef0f2734e51 Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 11 Apr 2022 02:35:31 +0200 Subject: [PATCH] Initial skeleton conversion of mdr_ed_mesh_utils. --- .../editor/addon/uv_editor/RectEditor.gd | 18 - .../editor/addon/uv_editor/RectView.gd | 250 ---- .../editor/addon/uv_editor/RectViewNode.gd | 418 ------ .../editor/addon/uv_editor/RectViewNode.tscn | 11 - .../editor/addon/uv_editor/UVEditor.tscn | 121 -- .../editor/addon/uv_editor/UVEditorPopup.gd | 15 - .../mdr_ed_mesh_utils.cpp} | 1233 ++++++++++------- .../editor/utilities/mdr_ed_mesh_utils.h | 153 ++ .../{addon => }/utilities/mesh_decompose.gd | 0 .../{addon => }/utilities/mesh_outline.gd | 0 10 files changed, 856 insertions(+), 1363 deletions(-) delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/RectEditor.gd delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/RectView.gd delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.gd delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.tscn delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/UVEditor.tscn delete mode 100644 modules/mesh_data_resource/editor/addon/uv_editor/UVEditorPopup.gd rename modules/mesh_data_resource/editor/{addon/utilities/mdred_mesh_utils.gd => utilities/mdr_ed_mesh_utils.cpp} (82%) create mode 100644 modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.h rename modules/mesh_data_resource/editor/{addon => }/utilities/mesh_decompose.gd (100%) rename modules/mesh_data_resource/editor/{addon => }/utilities/mesh_outline.gd (100%) diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/RectEditor.gd b/modules/mesh_data_resource/editor/addon/uv_editor/RectEditor.gd deleted file mode 100644 index b48f31f05..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/RectEditor.gd +++ /dev/null @@ -1,18 +0,0 @@ -tool -extends PanelContainer - -func set_plugin(plugin : EditorPlugin) -> void: - $ScrollContainer/MarginContainer/RectView.set_plugin(plugin) - -func set_mesh_data_resource(a : MeshDataResource) -> void: - $ScrollContainer/MarginContainer/RectView.set_mesh_data_resource(a) - -func set_mesh_data_instance(a : MeshDataInstance) -> void: - $ScrollContainer/MarginContainer/RectView.set_mesh_data_instance(a) - -func ok_pressed() -> void: - $ScrollContainer/MarginContainer/RectView.ok_pressed() - -func cancel_pressed() -> void: - $ScrollContainer/MarginContainer/RectView.cancel_pressed() - diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/RectView.gd b/modules/mesh_data_resource/editor/addon/uv_editor/RectView.gd deleted file mode 100644 index a4877ee2b..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/RectView.gd +++ /dev/null @@ -1,250 +0,0 @@ -tool -extends Control - -var MeshDecompose = preload("res://addons/mesh_data_resource_editor/utilities/mesh_decompose.gd") - -var rect_editor_node_scene : PackedScene = preload("res://addons/mesh_data_resource_editor/uv_editor/RectViewNode.tscn") - -export(NodePath) var zoom_widget_path : NodePath = "" - -export(NodePath) var mirror_horizontal_button_path : NodePath = "" -export(NodePath) var mirror_vertical_button_path : NodePath = "" - -export(NodePath) var rotate_left_button_path : NodePath = "" -export(NodePath) var rotate_amount_spinbox_path : NodePath = "" -export(NodePath) var rotate_right_button_path : NodePath = "" - -var _rect_scale : float = 1 - -var _mdr : MeshDataResource = null -var _background_texture : Texture = null - -var base_rect : Rect2 = Rect2(0, 0, 600, 600) -var edited_resource_current_size : Vector2 = Vector2() - -var _stored_uvs : PoolVector2Array = PoolVector2Array() - -var _plugin : EditorPlugin = null -var _undo_redo : UndoRedo = null - -var selected_rect : Control = null - -var rotation_amount : float = 45 - -func _enter_tree(): - var zoom_widget : Node = get_node_or_null(zoom_widget_path) - - if zoom_widget && !zoom_widget.is_connected("zoom_changed", self, "on_zoom_changed"): - zoom_widget.connect("zoom_changed", self, "on_zoom_changed") - - var mirror_horizontal_button : Button = get_node_or_null(mirror_horizontal_button_path) - if mirror_horizontal_button && !mirror_horizontal_button.is_connected("pressed", self, "on_mirror_horizontal_button_pressed"): - mirror_horizontal_button.connect("pressed", self, "on_mirror_horizontal_button_pressed") - - var mirror_vertical_button : Button = get_node_or_null(mirror_vertical_button_path) - if mirror_vertical_button && !mirror_vertical_button.is_connected("pressed", self, "on_mirror_vertical_button_pressed"): - mirror_vertical_button.connect("pressed", self, "on_mirror_vertical_button_pressed") - - var rotate_left_button : Button = get_node_or_null(rotate_left_button_path) - if rotate_left_button && !rotate_left_button.is_connected("pressed", self, "on_rotate_left_button_button_pressed"): - rotate_left_button.connect("pressed", self, "on_rotate_left_button_button_pressed") - - var rotate_amount_spinbox : SpinBox = get_node_or_null(rotate_amount_spinbox_path) - if rotate_amount_spinbox: - rotation_amount = rotate_amount_spinbox.value - if !rotate_amount_spinbox.is_connected("value_changed", self, "on_rotate_amount_spinbox_changed"): - rotate_amount_spinbox.connect("value_changed", self, "on_rotate_amount_spinbox_changed") - - var rotate_right_button : Button = get_node_or_null(rotate_right_button_path) - if rotate_right_button && !rotate_right_button.is_connected("pressed", self, "on_rotate_right_button_button_pressed"): - rotate_right_button.connect("pressed", self, "on_rotate_right_button_button_pressed") - - if !is_connected("visibility_changed", self, "on_visibility_changed"): - connect("visibility_changed", self, "on_visibility_changed") - -func on_mirror_horizontal_button_pressed() -> void: - if selected_rect && is_instance_valid(selected_rect): - selected_rect.mirror_horizontal() - -func on_mirror_vertical_button_pressed() -> void: - if selected_rect && is_instance_valid(selected_rect): - selected_rect.mirror_vertical() - -func on_rotate_left_button_button_pressed() -> void: - if selected_rect && is_instance_valid(selected_rect): - selected_rect.rotate_uvs(-rotation_amount) - -func on_rotate_amount_spinbox_changed(val : float) -> void: - rotation_amount = val - -func on_rotate_right_button_button_pressed() -> void: - if selected_rect && is_instance_valid(selected_rect): - selected_rect.rotate_uvs(rotation_amount) - -func set_plugin(plugin : EditorPlugin) -> void: - _plugin = plugin - - _undo_redo = _plugin.get_undo_redo() - -func on_visibility_changed() -> void: - if is_visible_in_tree(): - store_uvs() - call_deferred("refresh") - -func apply_zoom() -> void: - var rect : Rect2 = base_rect - edited_resource_current_size = rect.size - rect.position = rect.position * _rect_scale - rect.size = rect.size * _rect_scale - set_custom_minimum_size(rect.size) - - var p : MarginContainer = get_parent() as MarginContainer - - p.add_constant_override("margin_left", min(rect.size.x / 4.0, 50 * _rect_scale)) - p.add_constant_override("margin_right", min(rect.size.x / 4.0, 50 * _rect_scale)) - p.add_constant_override("margin_top", min(rect.size.y / 4.0, 50 * _rect_scale)) - p.add_constant_override("margin_bottom", min(rect.size.y / 4.0, 50 * _rect_scale)) - - for c in get_children(): - c.set_editor_rect_scale(_rect_scale) - -func on_zoom_changed(zoom : float) -> void: - _rect_scale = zoom - apply_zoom() - -func _draw(): - draw_rect(Rect2(Vector2(), get_size()), Color(0.2, 0.2, 0.2, 1)) - - if _background_texture: - draw_texture_rect_region(_background_texture, Rect2(Vector2(), get_size()), Rect2(Vector2(), _background_texture.get_size())) - -func refresh() -> void: - clear() - - var rect : Rect2 = base_rect - edited_resource_current_size = rect.size - rect.position = rect.position * _rect_scale - rect.size = rect.size * _rect_scale - set_custom_minimum_size(rect.size) - - apply_zoom() - - refresh_rects() - -func clear() -> void: - pass - -func refresh_rects() -> void: - clear_rects() - - if !_mdr: - return - - var partitions : Array = MeshDecompose.partition_mesh(_mdr) - - for p in partitions: - var s : Node = rect_editor_node_scene.instance() - - add_child(s) - s.set_editor_rect_scale(_rect_scale) - s.edited_resource_parent_size = edited_resource_current_size - s.set_edited_resource(_mdr, p) - -func clear_rects(): - for c in get_children(): - c.queue_free() - remove_child(c) - -func set_mesh_data_resource(a : MeshDataResource) -> void: - _mdr = a - -func set_mesh_data_instance(a : MeshDataInstance) -> void: - _background_texture = null - - if a: - _background_texture = a.texture - -func on_edited_resource_changed() -> void: - call_deferred("refresh") - -func get_uvs(mdr : MeshDataResource) -> PoolVector2Array: - if !_mdr: - return PoolVector2Array() - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return PoolVector2Array() - - if arrays[ArrayMesh.ARRAY_TEX_UV] == null: - return PoolVector2Array() - - return arrays[ArrayMesh.ARRAY_TEX_UV] - -func store_uvs() -> void: - _stored_uvs.resize(0) - - if !_mdr: - return - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return - - if arrays[ArrayMesh.ARRAY_TEX_UV] == null: - return - - # Make sure it gets copied - _stored_uvs.append_array(arrays[ArrayMesh.ARRAY_TEX_UV]) - -func apply_uvs(mdr : MeshDataResource, stored_uvs : PoolVector2Array) -> void: - if !_mdr: - return - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return - - if arrays[ArrayMesh.ARRAY_TEX_UV] == null: - return - - arrays[ArrayMesh.ARRAY_TEX_UV] = stored_uvs - - _mdr.array = arrays - -func ok_pressed() -> void: - _undo_redo.create_action("UV Editor Accept") - _undo_redo.add_do_method(self, "apply_uvs", _mdr, get_uvs(_mdr)) - _undo_redo.add_undo_method(self, "apply_uvs", _mdr, _stored_uvs) - _undo_redo.commit_action() - -func cancel_pressed() -> void: - if !_mdr: - return - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return - - # Make sure it gets copied - var uvs : PoolVector2Array = PoolVector2Array() - uvs.append_array(_stored_uvs) - - _undo_redo.create_action("UV Editor Cancel") - _undo_redo.add_do_method(self, "apply_uvs", _mdr, uvs) - _undo_redo.add_undo_method(self, "apply_uvs", _mdr, get_uvs(_mdr)) - _undo_redo.commit_action() - - _stored_uvs.resize(0) - -func set_selected(node : Control) -> void: - if selected_rect && is_instance_valid(selected_rect): - selected_rect.set_selected(false) - - selected_rect = node - - if selected_rect: - selected_rect.set_selected(true) diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.gd b/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.gd deleted file mode 100644 index fa5eb106b..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.gd +++ /dev/null @@ -1,418 +0,0 @@ -tool -extends MarginContainer - -enum DragType { - DRAG_NONE = 0, - DRAG_MOVE = 1, - DRAG_RESIZE_TOP = 1 << 1, - DRAG_RESIZE_RIGHT = 1 << 2, - DRAG_RESIZE_BOTTOM = 1 << 3, - DRAG_RESIZE_LEFT = 1 << 4 -}; - -var selected : bool = false - -var _mdr : MeshDataResource = null -var _indices : PoolIntArray = PoolIntArray() -var _uvs : PoolVector2Array = PoolVector2Array() -var _base_rect : Rect2 = Rect2(0, 0, 100, 100) -var _uv_min : Vector2 = Vector2() -var _uv_max : Vector2 = Vector2() - -var edited_resource_parent_size : Vector2 = Vector2() - -var _edited_resource_rect_border_color : Color = Color(0.8, 0.8, 0.8, 0.5) -var _edited_resource_rect_color : Color = Color(0.5, 0.5, 0.5, 0.2) -var _edited_resource_rect_selected_border_color : Color = Color(0.9, 0.9, 0.9, 0.8) -var _edited_resource_rect_selected_color : Color = Color(0.5, 0.5, 0.5, 0.4) -var _edited_resource_uv_mesh_color : Color = Color(1, 1, 1, 1) -var _editor_rect_border_size : int = 2 -var _edited_resource_font_color : Color = Color(0, 0, 0, 1) -var _editor_additional_text : String = "" - -var drag_type : int -var drag_offset : Vector2 -var drag_offset_far : Vector2 - -var _rect_scale : float = 1 - -func _draw(): - if selected: - draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_selected_color) - draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_selected_border_color, false, _editor_rect_border_size) - else: - draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_color) - draw_rect(Rect2(Vector2(), get_size()), _edited_resource_rect_border_color, false, _editor_rect_border_size) - - if _mdr && _uvs.size() > 0: - var c : Color = _edited_resource_uv_mesh_color - - for i in range(0, len(_indices), 3): - draw_line(_uvs[_indices[i]] * get_size(), _uvs[_indices[i + 1]] * get_size(), c, 1, false) - draw_line(_uvs[_indices[i + 1]] * get_size(), _uvs[_indices[i + 2]] * get_size(), c, 1, false) - draw_line(_uvs[_indices[i + 2]] * get_size(), _uvs[_indices[i]] * get_size(), c, 1, false) - -func mirror_horizontal() -> void: - var pia : PoolIntArray = PoolIntArray() - for index in _indices: - var found : bool = false - - for i in pia: - if i == index: - found = true - break - - if found: - continue - - pia.append(index) - - var uv : Vector2 = _uvs[index] - uv.x = 1.0 - uv.x - _uvs.set(index, uv) - - apply_uv() - update() - -func mirror_vertical() -> void: - var pia : PoolIntArray = PoolIntArray() - for index in _indices: - var found : bool = false - - for i in pia: - if i == index: - found = true - break - - if found: - continue - - pia.append(index) - - var uv : Vector2 = _uvs[index] - uv.y = 1.0 - uv.y - _uvs.set(index, uv) - - apply_uv() - update() - -func rotate_uvs(amount : float) -> void: - var t : Transform2D = Transform2D(deg2rad(amount), Vector2()) - - var pia : PoolIntArray = PoolIntArray() - for index in _indices: - var found : bool = false - - for i in pia: - if i == index: - found = true - break - - if found: - continue - - pia.append(index) - - var uv : Vector2 = _uvs[index] - uv = t.xform(uv) - _uvs.set(index, uv) - - - re_normalize_uvs() - apply_uv() - update() - -func refresh() -> void: - if !_mdr: - return - - var rect : Rect2 = _base_rect - rect.position *= _rect_scale - rect.size *= _rect_scale - - rect_position = rect.position - rect_size = rect.size - - update() - -func set_editor_rect_scale(rect_scale) -> void: - _rect_scale = rect_scale - - refresh() - -func set_edited_resource(mdr : MeshDataResource, indices : PoolIntArray): - _mdr = mdr - _indices = indices - _uvs.resize(0) - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return - - if arrays[ArrayMesh.ARRAY_TEX_UV] == null: - return - - # Make sure it gets copied - _uvs.append_array(arrays[ArrayMesh.ARRAY_TEX_UV]) - - set_up_base_rect() - - refresh() - -func set_up_base_rect() -> void: - _base_rect = Rect2() - - if !_mdr: - return - - if _uvs.size() == 0: - return - - var vmin : Vector2 = _uvs[_indices[0]] - var vmax : Vector2 = vmin - for i in range(1, _indices.size()): - var uv : Vector2 = _uvs[_indices[i]] - - if uv.x < vmin.x: - vmin.x = uv.x - - if uv.x > vmax.x: - vmax.x = uv.x - - if uv.y < vmin.y: - vmin.y = uv.y - - if uv.y > vmax.y: - vmax.y = uv.y - - _base_rect = Rect2(vmin.x, vmin.y, vmax.x - vmin.x, vmax.y - vmin.y) - _base_rect.position *= edited_resource_parent_size - _base_rect.size *= edited_resource_parent_size - - _uv_min = vmin - _uv_max = vmax - - normalize_uvs() - -func re_normalize_uvs() -> void: - if _uvs.size() == 0: - return - - var vmin : Vector2 = _uvs[_indices[0]] - var vmax : Vector2 = vmin - for i in range(1, _indices.size()): - var uv : Vector2 = _uvs[_indices[i]] - - if uv.x < vmin.x: - vmin.x = uv.x - - if uv.x > vmax.x: - vmax.x = uv.x - - if uv.y < vmin.y: - vmin.y = uv.y - - if uv.y > vmax.y: - vmax.y = uv.y - - var xmm : float = vmax.x - vmin.x - var ymm : float = vmax.y - vmin.y - - if xmm == 0: - xmm = 0.0000001 - - if ymm == 0: - ymm = 0.0000001 - - for i in range(_uvs.size()): - var uv : Vector2 = _uvs[i] - - uv.x -= vmin.x - uv.x /= xmm - - uv.y -= vmin.y - uv.y /= ymm - - _uvs[i] = uv - -func normalize_uvs() -> void: - var xmm : float = _uv_max.x - _uv_min.x - var ymm : float = _uv_max.y - _uv_min.y - - if xmm == 0: - xmm = 0.0000001 - - if ymm == 0: - ymm = 0.0000001 - - for i in range(_uvs.size()): - var uv : Vector2 = _uvs[i] - - uv.x -= _uv_min.x - uv.x /= xmm - - uv.y -= _uv_min.y - uv.y /= ymm - - _uvs[i] = uv - -func apply_uv() -> void: - if !_mdr: - return - - var rect : Rect2 = get_rect() - - #rect needs to be converted back - rect.position /= _rect_scale - rect.size /= _rect_scale - rect.position /= edited_resource_parent_size - rect.size /= edited_resource_parent_size - - var arrays : Array = _mdr.get_array() - - if arrays.size() != ArrayMesh.ARRAY_MAX: - return - - if arrays[ArrayMesh.ARRAY_TEX_UV] == null: - return - - var uvs : PoolVector2Array = arrays[ArrayMesh.ARRAY_TEX_UV] - - for index in _indices: - var uv : Vector2 = _uvs[index] - - uv = uv * rect.size + rect.position - - uvs[index] = uv - - _uv_min = rect.position - _uv_max = rect.position + rect.size - - _base_rect = get_rect() - - arrays[ArrayMesh.ARRAY_TEX_UV] = uvs - _mdr.array = arrays - - -#based on / ported from engine/scene/gui/dialogs.h and .cpp -func _notification(p_what : int) -> void: - if (p_what == NOTIFICATION_MOUSE_EXIT): - # Reset the mouse cursor when leaving the resizable window border. - if (_mdr && !drag_type): - if (get_default_cursor_shape() != CURSOR_ARROW): - set_default_cursor_shape(CURSOR_ARROW) - -#based on / ported from engine/scene/gui/dialogs.h and .cpp -func _gui_input(p_event : InputEvent) -> void: - if (p_event is InputEventMouseButton) && (p_event.get_button_index() == BUTTON_LEFT): - var mb : InputEventMouseButton = p_event as InputEventMouseButton - - if (mb.is_pressed()): - get_parent().set_selected(self) - - # Begin a possible dragging operation. - drag_type = _drag_hit_test(Vector2(mb.get_position().x, mb.get_position().y)) - - if (drag_type != DragType.DRAG_NONE): - drag_offset = get_global_mouse_position() - get_position() - - drag_offset_far = get_position() + get_size() - get_global_mouse_position() - - elif (drag_type != DragType.DRAG_NONE && !mb.is_pressed()): - # End a dragging operation. - - apply_uv() - - drag_type = DragType.DRAG_NONE - - if p_event is InputEventMouseMotion: - var mm : InputEventMouseMotion = p_event as InputEventMouseMotion - - if (drag_type == DragType.DRAG_NONE): - # Update the cursor while moving along the borders. - var cursor = CURSOR_ARROW - - var preview_drag_type : int = _drag_hit_test(Vector2(mm.get_position().x, mm.get_position().y)) - - var top_left : int = DragType.DRAG_RESIZE_TOP + DragType.DRAG_RESIZE_LEFT - var bottom_right : int = DragType.DRAG_RESIZE_BOTTOM + DragType.DRAG_RESIZE_RIGHT - var top_right : int = DragType.DRAG_RESIZE_TOP + DragType.DRAG_RESIZE_RIGHT - var bottom_left : int = DragType.DRAG_RESIZE_BOTTOM + DragType.DRAG_RESIZE_LEFT - - match (preview_drag_type): - DragType.DRAG_RESIZE_TOP: - cursor = CURSOR_VSIZE - DragType.DRAG_RESIZE_BOTTOM: - cursor = CURSOR_VSIZE - DragType.DRAG_RESIZE_LEFT: - cursor = CURSOR_HSIZE - DragType.DRAG_RESIZE_RIGHT: - cursor = CURSOR_HSIZE - top_left: - cursor = CURSOR_FDIAGSIZE - bottom_right: - cursor = CURSOR_FDIAGSIZE - top_right: - cursor = CURSOR_BDIAGSIZE - bottom_left: - cursor = CURSOR_BDIAGSIZE - - if (get_cursor_shape() != cursor): - set_default_cursor_shape(cursor); - - else: - # Update while in a dragging operation. - var global_pos : Vector2 = get_global_mouse_position() - - var rect : Rect2 = get_rect() - var min_size : Vector2 = get_combined_minimum_size() - - if (drag_type == DragType.DRAG_MOVE): - rect.position = global_pos - drag_offset - else: - if (drag_type & DragType.DRAG_RESIZE_TOP): - var bottom : int = rect.position.y + rect.size.y - var max_y : int = bottom - min_size.y - rect.position.y = min(global_pos.y - drag_offset.y, max_y) - rect.size.y = bottom - rect.position.y - elif (drag_type & DragType.DRAG_RESIZE_BOTTOM): - rect.size.y = global_pos.y - rect.position.y + drag_offset_far.y - - if (drag_type & DragType.DRAG_RESIZE_LEFT): - var right : int = rect.position.x + rect.size.x - var max_x : int = right - min_size.x - rect.position.x = min(global_pos.x - drag_offset.x, max_x) - rect.size.x = right - rect.position.x - elif (drag_type & DragType.DRAG_RESIZE_RIGHT): - rect.size.x = global_pos.x - rect.position.x + drag_offset_far.x - - set_size(rect.size) - set_position(rect.position) - -#based on / ported from engine/scene/gui/dialogs.h and .cpp -func _drag_hit_test(pos : Vector2) -> int: - var drag_type : int = DragType.DRAG_NONE - - var scaleborder_size : int = 5 #get_constant("scaleborder_size", "WindowDialog") - - var rect : Rect2 = get_rect() - - if (pos.y < (scaleborder_size)): - drag_type = DragType.DRAG_RESIZE_TOP - elif (pos.y >= (rect.size.y - scaleborder_size)): - drag_type = DragType.DRAG_RESIZE_BOTTOM - - if (pos.x < scaleborder_size): - drag_type |= DragType.DRAG_RESIZE_LEFT - elif (pos.x >= (rect.size.x - scaleborder_size)): - drag_type |= DragType.DRAG_RESIZE_RIGHT - - if (drag_type == DragType.DRAG_NONE): - drag_type = DragType.DRAG_MOVE - - return drag_type - -func set_selected(val : bool) -> void: - selected = val - update() diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.tscn b/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.tscn deleted file mode 100644 index 3746ada00..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/RectViewNode.tscn +++ /dev/null @@ -1,11 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectViewNode.gd" type="Script" id=1] - -[node name="RectViewNode" type="MarginContainer"] -margin_right = 1024.0 -margin_bottom = 600.0 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/UVEditor.tscn b/modules/mesh_data_resource/editor/addon/uv_editor/UVEditor.tscn deleted file mode 100644 index 2603514e7..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/UVEditor.tscn +++ /dev/null @@ -1,121 +0,0 @@ -[gd_scene load_steps=8 format=2] - -[ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectEditor.gd" type="Script" id=1] -[ext_resource path="res://addons/mesh_data_resource_editor/widgets/EditorZoomWidget.tscn" type="PackedScene" id=2] -[ext_resource path="res://addons/mesh_data_resource_editor/uv_editor/RectView.gd" type="Script" id=3] -[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_v_mirror.png" type="Texture" id=4] -[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_h_mirror.png" type="Texture" id=5] -[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_rot_right.png" type="Texture" id=6] -[ext_resource path="res://addons/mesh_data_resource_editor/icons/icon_rot_left.png" type="Texture" id=7] - -[node name="UVEditor" type="PanelContainer"] -anchor_right = 1.0 -anchor_bottom = 1.0 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="ScrollContainer" type="ScrollContainer" parent="."] -margin_left = 7.0 -margin_top = 7.0 -margin_right = 1017.0 -margin_bottom = 593.0 - -[node name="MarginContainer" type="MarginContainer" parent="ScrollContainer"] -margin_right = 700.0 -margin_bottom = 700.0 -custom_constants/margin_right = 50 -custom_constants/margin_top = 50 -custom_constants/margin_left = 50 -custom_constants/margin_bottom = 50 - -[node name="RectView" type="Control" parent="ScrollContainer/MarginContainer"] -margin_left = 50.0 -margin_top = 50.0 -margin_right = 650.0 -margin_bottom = 650.0 -rect_min_size = Vector2( 600, 600 ) -script = ExtResource( 3 ) -zoom_widget_path = NodePath("../../../Control/HBoxContainer/EditorZoomWidget") -mirror_horizontal_button_path = NodePath("../../../Control/HBoxContainer/HorizontalMirror") -mirror_vertical_button_path = NodePath("../../../Control/HBoxContainer/VerticalMirror") -rotate_left_button_path = NodePath("../../../Control/HBoxContainer/RotLeft") -rotate_amount_spinbox_path = NodePath("../../../Control/HBoxContainer/SpinBox") -rotate_right_button_path = NodePath("../../../Control/HBoxContainer/RotRight") - -[node name="Control" type="VBoxContainer" parent="."] -margin_left = 7.0 -margin_top = 7.0 -margin_right = 1017.0 -margin_bottom = 593.0 -mouse_filter = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="HBoxContainer" type="HBoxContainer" parent="Control"] -margin_right = 1010.0 -margin_bottom = 24.0 -mouse_filter = 2 -size_flags_horizontal = 3 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="EditorZoomWidget" parent="Control/HBoxContainer" instance=ExtResource( 2 )] -anchor_right = 0.0 -anchor_bottom = 0.0 -margin_right = 115.0 -margin_bottom = 24.0 -custom_constants/separation = -8 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="VSeparator2" type="VSeparator" parent="Control/HBoxContainer"] -margin_left = 119.0 -margin_right = 123.0 -margin_bottom = 24.0 - -[node name="HorizontalMirror" type="Button" parent="Control/HBoxContainer"] -margin_left = 127.0 -margin_right = 155.0 -margin_bottom = 24.0 -hint_tooltip = "Mirror the selected island horizontally.." -icon = ExtResource( 5 ) - -[node name="VerticalMirror" type="Button" parent="Control/HBoxContainer"] -margin_left = 159.0 -margin_right = 187.0 -margin_bottom = 24.0 -hint_tooltip = "Mirror the selected island vertically." -icon = ExtResource( 4 ) - -[node name="VSeparator" type="VSeparator" parent="Control/HBoxContainer"] -margin_left = 191.0 -margin_right = 195.0 -margin_bottom = 24.0 - -[node name="RotLeft" type="Button" parent="Control/HBoxContainer"] -margin_left = 199.0 -margin_right = 227.0 -margin_bottom = 24.0 -hint_tooltip = "Rotate left." -icon = ExtResource( 7 ) - -[node name="SpinBox" type="SpinBox" parent="Control/HBoxContainer"] -margin_left = 231.0 -margin_right = 305.0 -margin_bottom = 24.0 -hint_tooltip = "Rotate amount in degrees." -max_value = 360.0 -value = 45.0 -allow_greater = true -allow_lesser = true - -[node name="RotRight" type="Button" parent="Control/HBoxContainer"] -margin_left = 309.0 -margin_right = 337.0 -margin_bottom = 24.0 -hint_tooltip = "Rotate right." -icon = ExtResource( 6 ) diff --git a/modules/mesh_data_resource/editor/addon/uv_editor/UVEditorPopup.gd b/modules/mesh_data_resource/editor/addon/uv_editor/UVEditorPopup.gd deleted file mode 100644 index 32a9795a8..000000000 --- a/modules/mesh_data_resource/editor/addon/uv_editor/UVEditorPopup.gd +++ /dev/null @@ -1,15 +0,0 @@ -tool -extends ConfirmationDialog - -func _enter_tree(): - if !is_connected("confirmed", self, "on_ok_pressed"): - connect("confirmed", self, "on_ok_pressed") - - if !get_cancel().is_connected("pressed", self, "on_cancel_pressed"): - get_cancel().connect("pressed", self, "on_cancel_pressed") - -func on_ok_pressed() -> void: - $UVEditor.ok_pressed() - -func on_cancel_pressed() -> void: - $UVEditor.cancel_pressed() diff --git a/modules/mesh_data_resource/editor/addon/utilities/mdred_mesh_utils.gd b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.cpp similarity index 82% rename from modules/mesh_data_resource/editor/addon/utilities/mdred_mesh_utils.gd rename to modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.cpp index bd2fcd0f6..8b1801faa 100644 --- a/modules/mesh_data_resource/editor/addon/utilities/mdred_mesh_utils.gd +++ b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.cpp @@ -1,61 +1,249 @@ -tool -extends Object +/* +Copyright (c) 2019-2022 Péter Magyar -static func remove_triangle(mdr : MeshDataResource, triangle_index : int) -> void: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "mdr_ed_mesh_utils.h" + +int MDREDMeshUtils::SeamTriangleHelper::get_other_side_index(int index) { + /* + if side_index_1 == index: + return side_index_2 + else: + return side_index_1 + */ +} + +int MDREDMeshUtils::SeamTriangleHelper::get_side_index(int i) { + /* + if i == 1: + return side_index_1 + else: + return side_index_2 + */ +} +int MDREDMeshUtils::SeamTriangleHelper::get_side_index_cut() { + /* + if side_index_1_cut && side_index_2_cut: + return 3 + elif side_index_1_cut: + return 1 + elif side_index_2_cut: + return 2 + else: + return 0 + */ +} +int MDREDMeshUtils::SeamTriangleHelper::get_opposite_side_index_cut() { + /* + if side_index_1_cut && side_index_2_cut: + return 3 + elif side_index_1_cut: + return 2 + elif side_index_2_cut: + return 1 + else: + return 0 + */ +} +bool MDREDMeshUtils::SeamTriangleHelper::is_side_index_cut(int i) { + /* + if i == 1: + return side_index_1_cut + else: + return side_index_2_cut + */ +} + +bool MDREDMeshUtils::SeamTriangleHelper::is_the_same(SeamTriangleHelper h) { + /* + return is_triangle(h.i0, h.i1, h.i2) + */ +} + +bool MDREDMeshUtils::SeamTriangleHelper::is_triangle(int pi0, int pi1, int pi2) { + /* + if pi0 == i0 || pi0 == i1 || pi0 == i2: + if pi1 == i0 || pi1 == i1 || pi1 == i2: + if pi2 == i0 || pi2 == i1 || pi2 == i2: + return true + + return false + */ +} +bool MDREDMeshUtils::SeamTriangleHelper::is_neighbour_to(int index) { + /* + return (side_index_1 == index) || (side_index_2 == index) + */ +} + +bool MDREDMeshUtils::SeamTriangleHelper::needs_to_be_cut_near(int index) { + /* + if (side_index_1 == index): + return side_index_1_cut + + if (side_index_2 == index): + return side_index_2_cut + + return false + */ +} +bool MDREDMeshUtils::SeamTriangleHelper::has_cut() { + /* + return side_index_1_cut || side_index_2_cut + */ +} +bool MDREDMeshUtils::SeamTriangleHelper::both_sides_need_cut() { + /* + return side_index_1_cut && side_index_2_cut + */ +} + +void MDREDMeshUtils::SeamTriangleHelper::setup(int pi0, int pi1, int pi2, int porig_ind, int pindex_index, PoolIntArray seams) { + /* + processed = false + i0 = pi0 + i1 = pi1 + i2 = pi2 + orig_index = porig_ind + index_index = pindex_index + + if porig_ind == pi0: + side_index_1 = pi1 + side_index_2 = pi2 + elif porig_ind == pi1: + side_index_1 = pi0 + side_index_2 = pi2 + elif porig_ind == pi2: + side_index_1 = pi1 + side_index_2 = pi0 + + determine_cuts(seams) + */ +} + +void MDREDMeshUtils::SeamTriangleHelper::determine_cuts(PoolIntArray seams) { + /* + if orig_index < side_index_1: + side_index_1_cut = check_cut(orig_index, side_index_1, seams) + else: + side_index_1_cut = check_cut(side_index_1, orig_index, seams) + + if orig_index < side_index_2: + side_index_2_cut = check_cut(orig_index, side_index_2, seams) + else: + side_index_2_cut = check_cut(side_index_2, orig_index, seams) + */ +} +bool MDREDMeshUtils::SeamTriangleHelper::check_cut(int ind0, int ind1, PoolIntArray seams) { + /* + for stind in range(0, seams.size(), 2): + var si0 : int = seams[stind] + var si1 : int = seams[stind + 1] + + if (si0 == ind0) && (si1 == ind1): + return true + + return false + */ +} + +String MDREDMeshUtils::SeamTriangleHelper::_to_string() { + /* + return "[ TRI: " + str(i0) + ", " + str(i1) + ", " + str(i2) + " ]" + */ +} + +MDREDMeshUtils::SeamTriangleHelper::SeamTriangleHelper() { + i0 = 0; + i1 = 0; + i2 = 0; + orig_index = 0; + index_index = 0; + + side_index_1 = 0; + side_index_2 = 0; + side_index_1_cut = false; + side_index_2_cut = false; + + processed = false; +} + +void MDREDMeshUtils::remove_triangle(Ref mdr, int triangle_index) { + /* if triangle_index < 0: return - + var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return - + var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] # Just remove that triangle var i : int = triangle_index * 3 - + var i0 : int = indices[i] var i1 : int = indices[i + 1] var i2 : int = indices[i + 2] - + remove_seam_not_ordered(mdr, i0, i1) remove_seam_not_ordered(mdr, i1, i2) remove_seam_not_ordered(mdr, i2, i0) - + indices.remove(i) indices.remove(i) indices.remove(i) arrays[ArrayMesh.ARRAY_INDEX] = indices - - mdr.set_array(arrays) -static func add_triangulated_mesh_from_points_delaunay(mdr : MeshDataResource, selected_points : PoolVector3Array, last_known_camera_facing : Vector3) -> bool: + mdr.set_array(arrays) + */ +} +bool MDREDMeshUtils::add_triangulated_mesh_from_points_delaunay(Ref mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing) { + /* if selected_points.size() < 3: return false - + var tetrahedrons : PoolIntArray = MeshUtils.delaunay3d_tetrahedralize(selected_points) - + if tetrahedrons.size() == 0: # try randomly displacing the points a bit, it can help var rnd_selected_points : PoolVector3Array = PoolVector3Array() rnd_selected_points.append_array(selected_points) - + for i in range(rnd_selected_points.size()): rnd_selected_points[i] = rnd_selected_points[i] + (Vector3(randf(),randf(), randf()) * 0.1) - + tetrahedrons = MeshUtils.delaunay3d_tetrahedralize(rnd_selected_points) - + if tetrahedrons.size() == 0: print("add_triangulated_mesh_from_points_delaunay: tetrahedrons.size() == 0!") return false var st : SurfaceTool = SurfaceTool.new() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) for i in range(0, tetrahedrons.size(), 4): @@ -63,14 +251,14 @@ static func add_triangulated_mesh_from_points_delaunay(mdr : MeshDataResource, s var i1 : int = tetrahedrons[i + 1] var i2 : int = tetrahedrons[i + 2] var i3 : int = tetrahedrons[i + 3] - + var v0 : Vector3 = selected_points[i0] var v1 : Vector3 = selected_points[i1] var v2 : Vector3 = selected_points[i2] var v3 : Vector3 = selected_points[i3] - + var flip : bool = is_normal_similar(v0, v1, v2, last_known_camera_facing) - + var normal : Vector3 = get_face_normal(v0, v1, v2, flip) st.add_uv(Vector2(0, 1)) @@ -85,14 +273,14 @@ static func add_triangulated_mesh_from_points_delaunay(mdr : MeshDataResource, s st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(v3) - + var im3 : int = i if !flip: st.add_index(im3 + 0) st.add_index(im3 + 1) st.add_index(im3 + 2) - + st.add_index(im3 + 0) st.add_index(im3 + 2) st.add_index(im3 + 3) @@ -100,21 +288,23 @@ static func add_triangulated_mesh_from_points_delaunay(mdr : MeshDataResource, s st.add_index(im3 + 3) st.add_index(im3 + 2) st.add_index(im3 + 0) - + st.add_index(im3 + 2) st.add_index(im3 + 1) st.add_index(im3 + 0) - - merge_in_surface_tool(mdr, st) - - return true -static func add_triangulated_mesh_from_points(mdr : MeshDataResource, selected_points : PoolVector3Array, last_known_camera_facing : Vector3) -> void: + merge_in_surface_tool(mdr, st) + + return true + */ +} +void MDREDMeshUtils::add_triangulated_mesh_from_points(Ref mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing) { + /* if selected_points.size() < 3: return - + var st : SurfaceTool = SurfaceTool.new() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) var v0 : Vector3 = selected_points[0] @@ -122,9 +312,9 @@ static func add_triangulated_mesh_from_points(mdr : MeshDataResource, selected_p for i in range(2, selected_points.size()): var v2 : Vector3 = selected_points[i] - + var flip : bool = is_normal_similar(v0, v1, v2, last_known_camera_facing) - + var normal : Vector3 = get_face_normal(v0, v1, v2, flip) st.add_uv(Vector2(0, 1)) @@ -136,7 +326,7 @@ static func add_triangulated_mesh_from_points(mdr : MeshDataResource, selected_p st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(v2) - + var im3 : int = (i - 2) * 3 if !flip: @@ -147,20 +337,26 @@ static func add_triangulated_mesh_from_points(mdr : MeshDataResource, selected_p st.add_index(im3 + 2) st.add_index(im3 + 1) st.add_index(im3) - - merge_in_surface_tool(mdr, st) -# Appends a triangle to the mesh. It's created from miroring v2 to the ev0, and ev1 edge -static func append_triangle_to_tri_edge(mdr : MeshDataResource, ev0 : Vector3, ev1 : Vector3, v2 : Vector3) -> void: + merge_in_surface_tool(mdr, st) + */ +} + +// Appends a triangle to the mesh. It's created from miroring v2 to the ev0, and ev1 edge +void MDREDMeshUtils::append_triangle_to_tri_edge(Ref mdr, Vector3 ev0, Vector3 ev1, Vector3 v2) { + /* var vref : Vector3 = reflect_vertex(ev0, ev1, v2) add_triangle_at(mdr, ev1, ev0, vref, false) + */ +} -static func add_triangle_at(mdr : MeshDataResource, v0 : Vector3, v1 : Vector3, v2 : Vector3, flip : bool = false) -> void: +void MDREDMeshUtils::add_triangle_at(Ref mdr, Vector3 v0, Vector3 v1, Vector3 v2, bool flip = false) { + /* var st : SurfaceTool = SurfaceTool.new() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) - + var normal : Vector3 = get_face_normal(v0, v1, v2, flip) st.add_uv(Vector2(0, 1)) @@ -184,13 +380,17 @@ static func add_triangle_at(mdr : MeshDataResource, v0 : Vector3, v1 : Vector3, merge_in_surface_tool(mdr, st) -static func add_triangle(mdr : MeshDataResource) -> void: + */ +} + +void MDREDMeshUtils::add_triangle(Ref mdr) { + /* var st : SurfaceTool = SurfaceTool.new() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) - + var normal : Vector3 = get_face_normal(Vector3(-0.5, -0.5, 0), Vector3(0, 0.5, 0), Vector3(0.5, -0.5, 0)) - + st.add_uv(Vector2(0, 1)) st.add_normal(normal) st.add_vertex(Vector3(-0.5, -0.5, 0)) @@ -200,29 +400,34 @@ static func add_triangle(mdr : MeshDataResource) -> void: st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(Vector3(0.5, -0.5, 0)) - + st.add_index(0) st.add_index(1) st.add_index(2) - - merge_in_surface_tool(mdr, st) -# Appends a quad to the mesh. It's created to the opposite side of v2 to the ev0, and ev1 edge -static func append_quad_to_tri_edge(mdr : MeshDataResource, ev0 : Vector3, ev1 : Vector3, v2 : Vector3) -> void: + merge_in_surface_tool(mdr, st) + */ +} + +// Appends a quad to the mesh. It's created to the opposite side of v2 to the ev0, and ev1 edge +void MDREDMeshUtils::append_quad_to_tri_edge(Ref mdr, Vector3 ev0, Vector3 ev1, Vector3 v2) { + /* var vref : Vector3 = reflect_vertex(ev0, ev1, v2) var vproj : Vector3 = (vref - ev0).project(ev1 - ev0) var eoffs : Vector3 = (vref - ev0) - vproj - + var qv0 : Vector3 = ev0 var qv1 : Vector3 = ev0 + eoffs var qv2 : Vector3 = ev1 + eoffs var qv3 : Vector3 = ev1 add_quad_at(mdr, qv0, qv1, qv2, qv3, false) - -static func add_quad_at(mdr : MeshDataResource, v0 : Vector3, v1 : Vector3, v2 : Vector3, v3 : Vector3, flip : bool = false) -> void: + */ +} +void MDREDMeshUtils::add_quad_at(Ref mdr, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, bool flip = false) { + /* var st : SurfaceTool = SurfaceTool.new() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) var normal : Vector3 = get_face_normal(v0, v1, v2, flip) @@ -239,13 +444,13 @@ static func add_quad_at(mdr : MeshDataResource, v0 : Vector3, v1 : Vector3, v2 : st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(v3) - + if !flip: st.add_index(0) st.add_index(1) st.add_index(2) - + st.add_index(0) st.add_index(2) st.add_index(3) @@ -253,18 +458,21 @@ static func add_quad_at(mdr : MeshDataResource, v0 : Vector3, v1 : Vector3, v2 : st.add_index(2) st.add_index(1) st.add_index(0) - + st.add_index(3) st.add_index(2) st.add_index(0) merge_in_surface_tool(mdr, st) -static func add_quad(mdr : MeshDataResource) -> void: + */ +} +void MDREDMeshUtils::add_quad(Ref mdr) { + /* var st : SurfaceTool = SurfaceTool.new() - + var normal : Vector3 = get_face_normal(Vector3(-0.5, -0.5, 0), Vector3(-0.5, 0.5, 0), Vector3(0.5, 0.5, 0)) - + st.begin(Mesh.PRIMITIVE_TRIANGLES) st.add_uv(Vector2(0, 1)) @@ -279,7 +487,7 @@ static func add_quad(mdr : MeshDataResource) -> void: st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(Vector3(0.5, -0.5, 0)) - + st.add_index(0) st.add_index(1) st.add_index(2) @@ -288,20 +496,22 @@ static func add_quad(mdr : MeshDataResource) -> void: st.add_index(0) merge_in_surface_tool(mdr, st) - -static func add_box(mdr : MeshDataResource) -> void: + */ +} +void MDREDMeshUtils::add_box(Ref mdr) { + /* var st : SurfaceTool = SurfaceTool.new() - + var normal : Vector3 = Vector3() - + st.begin(Mesh.PRIMITIVE_TRIANGLES) - + var sgn : float = 1 #z for i in range(2): normal = get_face_normal(Vector3(-0.5, -0.5, sgn * 0.5), Vector3(-0.5, 0.5, sgn * 0.5), Vector3(0.5, 0.5, sgn * 0.5), sgn < 0) - + st.add_uv(Vector2(0, 1)) st.add_normal(normal) st.add_vertex(Vector3(-0.5, -0.5, sgn * 0.5)) @@ -314,13 +524,13 @@ static func add_box(mdr : MeshDataResource) -> void: st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(Vector3(0.5, -0.5, sgn * 0.5)) - + sgn *= -1 - + #x for i in range(2): normal = get_face_normal(Vector3(sgn * 0.5, -0.5, 0.5), Vector3(sgn * 0.5, 0.5, 0.5), Vector3(sgn * 0.5, 0.5, -0.5), sgn < 0) - + st.add_uv(Vector2(0, 1)) st.add_normal(normal) st.add_vertex(Vector3(sgn * 0.5, -0.5, 0.5)) @@ -333,13 +543,13 @@ static func add_box(mdr : MeshDataResource) -> void: st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(Vector3(sgn * 0.5, -0.5, -0.5)) - + sgn *= -1 #y for i in range(2): normal = get_face_normal(Vector3(-0.5, sgn * 0.5, 0.5), Vector3(-0.5, sgn * 0.5, -0.5), Vector3(0.5, sgn * 0.5, -0.5), sgn < 0) - + st.add_uv(Vector2(0, 1)) st.add_normal(normal) st.add_vertex(Vector3(-0.5, sgn * 0.5, 0.5)) @@ -352,12 +562,12 @@ static func add_box(mdr : MeshDataResource) -> void: st.add_uv(Vector2(1, 1)) st.add_normal(normal) st.add_vertex(Vector3(0.5, sgn * 0.5, 0.5)) - - + + sgn *= -1 - + var ind : int = 0 - + for i in range(3): st.add_index(ind + 0) st.add_index(ind + 1) @@ -365,41 +575,45 @@ static func add_box(mdr : MeshDataResource) -> void: st.add_index(ind + 2) st.add_index(ind + 3) st.add_index(ind + 0) - + ind += 4 - + st.add_index(ind + 0) st.add_index(ind + 2) st.add_index(ind + 1) st.add_index(ind + 0) st.add_index(ind + 3) st.add_index(ind + 2) - - ind += 4 - - merge_in_surface_tool(mdr, st) -static func merge_in_surface_tool(mdr : MeshDataResource, st : SurfaceTool, generate_normals_if_needed : bool = true, generate_tangents_if_needed : bool = true) -> void: + ind += 4 + + merge_in_surface_tool(mdr, st) + */ +} +void MDREDMeshUtils::merge_in_surface_tool(Ref mdr, Ref st, bool generate_normals_if_needed = true, bool generate_tangents_if_needed = true) { + /* var arrays : Array = get_arrays_prepared(mdr) - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if generate_normals_if_needed && arrays[ArrayMesh.ARRAY_NORMAL] == null: #st.generate_normals() generate_normals_mdr(mdr) - + if generate_tangents_if_needed && arrays[ArrayMesh.ARRAY_TANGENT] == null: st.generate_tangents() - - merge_in_arrays(mdr, st.commit_to_arrays()) -static func merge_in_arrays(mdr : MeshDataResource, merge : Array) -> void: + merge_in_arrays(mdr, st.commit_to_arrays()) + */ +} +void MDREDMeshUtils::merge_in_arrays(Ref mdr, Array merge) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + var vertices : PoolVector3Array var normals : PoolVector3Array var tangents : PoolRealArray @@ -412,31 +626,31 @@ static func merge_in_arrays(mdr : MeshDataResource, merge : Array) -> void: if arrays[ArrayMesh.ARRAY_VERTEX] != null: vertices = arrays[ArrayMesh.ARRAY_VERTEX] - + 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] - + if arrays[ArrayMesh.ARRAY_INDEX] != null: indices = arrays[ArrayMesh.ARRAY_INDEX] - + var merge_vertices : PoolVector3Array var merge_normals : PoolVector3Array var merge_tangents : PoolRealArray @@ -449,42 +663,42 @@ static func merge_in_arrays(mdr : MeshDataResource, merge : Array) -> void: if merge[ArrayMesh.ARRAY_VERTEX] != null: merge_vertices = merge[ArrayMesh.ARRAY_VERTEX] - + if merge[ArrayMesh.ARRAY_NORMAL] != null: merge_normals = merge[ArrayMesh.ARRAY_NORMAL] - + if merge[ArrayMesh.ARRAY_TANGENT] != null: merge_tangents = merge[ArrayMesh.ARRAY_TANGENT] - + if merge[ArrayMesh.ARRAY_COLOR] != null: merge_colors = merge[ArrayMesh.ARRAY_COLOR] - + if merge[ArrayMesh.ARRAY_TEX_UV] != null: merge_uv = merge[ArrayMesh.ARRAY_TEX_UV] - + if merge[ArrayMesh.ARRAY_TEX_UV2] != null: merge_uv2 = merge[ArrayMesh.ARRAY_TEX_UV2] - + if merge[ArrayMesh.ARRAY_BONES] != null: merge_bones = merge[ArrayMesh.ARRAY_BONES] - + if merge[ArrayMesh.ARRAY_WEIGHTS] != null: merge_weights = merge[ArrayMesh.ARRAY_WEIGHTS] - + if merge[ArrayMesh.ARRAY_INDEX] != null: merge_indices = merge[ArrayMesh.ARRAY_INDEX] - + #merge var ovc : int = vertices.size() vertices.append_array(merge_vertices) - + if arrays[ArrayMesh.ARRAY_NORMAL] != null: if merge_vertices.size() != merge_normals.size(): for i in range(merge_vertices.size()): normals.append(Vector3()) else: normals.append_array(merge_normals) - + if arrays[ArrayMesh.ARRAY_TANGENT] != null: if merge_vertices.size() != merge_tangents.size() * 4: for i in range(merge_vertices.size()): @@ -494,7 +708,7 @@ static func merge_in_arrays(mdr : MeshDataResource, merge : Array) -> void: merge_tangents.append(0) else: tangents.append_array(merge_tangents) - + if arrays[ArrayMesh.ARRAY_COLOR] != null: if merge_vertices.size() != merge_colors.size(): for i in range(merge_vertices.size()): @@ -538,125 +752,154 @@ static func merge_in_arrays(mdr : MeshDataResource, merge : Array) -> void: for i in range(merge_indices.size()): merge_indices[i] += ovc - + indices.append_array(merge_indices) - + #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 arrays[ArrayMesh.ARRAY_INDEX] = indices - - mdr.set_array(arrays) -static func get_arrays_prepared(mdr : MeshDataResource) -> Array: + mdr.set_array(arrays) + */ +} +Array MDREDMeshUtils::get_arrays_prepared(Ref mdr) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + arrays[ArrayMesh.ARRAY_VERTEX] = PoolVector3Array() arrays[ArrayMesh.ARRAY_NORMAL] = PoolVector3Array() arrays[ArrayMesh.ARRAY_TEX_UV] = PoolVector2Array() arrays[ArrayMesh.ARRAY_INDEX] = PoolIntArray() - - return arrays -# There are probably better ways to do this -static func should_flip_reflected_triangle(v0 : Vector3, v1 : Vector3, v2 : Vector3) -> bool: + return arrays + */ +} + +// There are probably better ways to do this +bool MDREDMeshUtils::should_flip_reflected_triangle(Vector3 v0, Vector3 v1, Vector3 v2) { + /* var reflected : Vector3 = reflect_vertex(v0, v1, v2) var nn : Vector3 = get_face_normal(v0, v1, v2) return should_triangle_flip(v0, v1, reflected, nn) - -static func reflect_vertex(v0 : Vector3, v1 : Vector3, v2 : Vector3) -> Vector3: + */ +} +Vector3 MDREDMeshUtils::reflect_vertex(Vector3 v0, Vector3 v1, Vector3 v2) { + /* return (v2 - v0).reflect((v1 - v0).normalized()) + v0 + */ +} -static func get_face_normal_arr_ti(verts : PoolVector3Array, indices : PoolIntArray, triangle_index : int, flipped : bool = false) -> Vector3: +Vector3 MDREDMeshUtils::get_face_normal_arr_ti(PoolVector3Array verts, PoolIntArray indices, int triangle_index, bool flipped = false) { + /* return get_face_normal_arr(verts, indices, triangle_index * 3, flipped) - -static func get_face_normal_arr(verts : PoolVector3Array, indices : PoolIntArray, index : int, flipped : bool = false) -> Vector3: + */ +} +Vector3 MDREDMeshUtils::get_face_normal_arr(PoolVector3Array verts, PoolIntArray indices, int index, bool flipped = false) { + /* var v0 : Vector3 = verts[indices[index]] var v1 : Vector3 = verts[indices[index + 1]] var v2 : Vector3 = verts[indices[index + 2]] - - return get_face_normal(v0, v1, v2, flipped) -static func get_face_normal(v0 : Vector3, v1 : Vector3, v2 : Vector3, flipped : bool = false) -> Vector3: + return get_face_normal(v0, v1, v2, flipped) + */ +} +Vector3 MDREDMeshUtils::get_face_normal(Vector3 v0, Vector3 v1, Vector3 v2, bool flipped = false) { + /* if !flipped: return Plane(v0, v1, v2).normal else: return Plane(v2, v1, v0).normal + */ +} -static func should_triangle_flip(v0 : Vector3, v1 : Vector3, v2 : Vector3, similar_dir_normal : Vector3) -> bool: +bool MDREDMeshUtils::should_triangle_flip(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal) { + /* var normal : Vector3 = get_face_normal(v0, v1, v2) - + var ndns : float = normal.dot(similar_dir_normal) - + return ndns < 0 + */ +} -static func is_normal_similar(v0 : Vector3, v1 : Vector3, v2 : Vector3, similar_dir_normal : Vector3) -> bool: +bool MDREDMeshUtils::is_normal_similar(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal) { + /* var normal : Vector3 = get_face_normal(v0, v1, v2) - - var ndns : float = normal.dot(similar_dir_normal) - - return ndns >= 0 -static func is_direction_similar(d0 : Vector3, d1 : Vector3) -> bool: + var ndns : float = normal.dot(similar_dir_normal) + + return ndns >= 0 + */ +} +bool MDREDMeshUtils::is_direction_similar(Vector3 d0, Vector3 d1) { + /* var ndns : float = d0.dot(d1) return ndns >= 0 + */ +} -static func flip_triangle_ti(mdr : MeshDataResource, triangle_index : int) -> void: +void MDREDMeshUtils::flip_triangle_ti(Ref mdr, int triangle_index) { + /* flip_triangle(mdr, triangle_index * 3) - -static func flip_triangle(mdr : MeshDataResource, index : int) -> void: + */ +} +void MDREDMeshUtils::flip_triangle(Ref mdr, int index) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return - + var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var i0 : int = indices[index] var i2 : int = indices[index + 2] - + indices[index] = i2 indices[index + 2] = i0 arrays[ArrayMesh.ARRAY_INDEX] = indices - - mdr.set_array(arrays) -static func add_into_surface_tool(mdr : MeshDataResource, st : SurfaceTool) -> void: + mdr.set_array(arrays) + */ +} +void MDREDMeshUtils::add_into_surface_tool(Ref mdr, Ref st) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + var vertices : PoolVector3Array var normals : PoolVector3Array var tangents : PoolRealArray @@ -669,258 +912,273 @@ static func add_into_surface_tool(mdr : MeshDataResource, st : SurfaceTool) -> v if arrays[ArrayMesh.ARRAY_VERTEX] != null: vertices = arrays[ArrayMesh.ARRAY_VERTEX] - + 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] - + if arrays[ArrayMesh.ARRAY_INDEX] != null: indices = arrays[ArrayMesh.ARRAY_INDEX] - + for i in range(vertices.size()): if normals.size() > 0: st.add_normal(normals[i]) - + if tangents.size() > 0: var ti : int = i * 4 st.add_tangent(Plane(tangents[ti], tangents[ti + 1], tangents[ti + 2], tangents[ti + 3])) - + if colors.size() > 0: st.add_color(colors[i]) - + if uv.size() > 0: st.add_uv(uv[i]) - + if uv2.size() > 0: st.add_uv2(uv2[i]) - + if bones.size() > 0: var bi : int = i * 4 - + var pia : PoolIntArray = PoolIntArray() - + pia.append(bones[bi]) pia.append(bones[bi + 1]) pia.append(bones[bi + 1]) pia.append(bones[bi + 1]) - + st.add_bones(pia) - + if weights.size() > 0: var bi : int = i * 4 - + var pia : PoolIntArray = PoolIntArray() - + pia.append(bones[bi]) pia.append(bones[bi + 1]) pia.append(bones[bi + 2]) pia.append(bones[bi + 3]) - + st.add_weight(pia) - + st.add_vertex(vertices[i]) for ind in indices: st.add_index(ind) + */ +} -static func generate_normals_arrs(arrays : Array) -> Array: +Array MDREDMeshUtils::generate_normals_arrs(Array arrays) { + /* if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return arrays - - + + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var normals : PoolVector3Array = PoolVector3Array() normals.resize(vertices.size()) var nc : PoolIntArray = PoolIntArray() nc.resize(vertices.size()) - + for i in range(vertices.size()): nc[i] = 0 - + for i in range(0, indices.size(), 3): var i0 : int = indices[i] var i1 : int = indices[i + 1] var i2 : int = indices[i + 2] - + var v0 : Vector3 = vertices[i0] var v1 : Vector3 = vertices[i1] var v2 : Vector3 = vertices[i2] - + var n = Plane(v0, v1, v2).normal - + if n.is_equal_approx(Vector3()): print("Warning face's normal is zero! " + str(Vector3(i0, i1, i2))) n = Vector3(0, 0, 1) - + if nc[i0] == 0: nc[i0] = 1 normals[i0] = n else: normals[i0] = lerp(normals[i0], n, 0.5).normalized() - + if nc[i1] == 0: nc[i1] = 1 normals[i1] = n else: normals[i1] = lerp(normals[i1], n, 0.5).normalized() - + if nc[i2] == 0: nc[i2] = 1 normals[i2] = n else: normals[i2] = lerp(normals[i2], n, 0.5).normalized() - + arrays[ArrayMesh.ARRAY_NORMAL] = normals return arrays - - -static func generate_normals_mdr(mdr : MeshDataResource) -> void: + */ +} +void MDREDMeshUtils::generate_normals_mdr(Ref mdr) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var normals : PoolVector3Array = PoolVector3Array() normals.resize(vertices.size()) var nc : PoolIntArray = PoolIntArray() nc.resize(vertices.size()) - + for i in range(vertices.size()): nc[i] = 0 - + for i in range(0, indices.size(), 3): var i0 : int = indices[i] var i1 : int = indices[i + 1] var i2 : int = indices[i + 2] - + var v0 : Vector3 = vertices[i0] var v1 : Vector3 = vertices[i1] var v2 : Vector3 = vertices[i2] - + var n = Plane(v0, v1, v2).normal - + if n.is_equal_approx(Vector3()): print("Warning face's normal is zero! " + str(Vector3(i0, i1, i2))) n = Vector3(0, 0, 1) - + if nc[i0] == 0: nc[i0] = 1 normals[i0] = n else: normals[i0] = lerp(normals[i0], n, 0.5).normalized() - + if nc[i1] == 0: nc[i1] = 1 normals[i1] = n else: normals[i1] = lerp(normals[i1], n, 0.5).normalized() - + if nc[i2] == 0: nc[i2] = 1 normals[i2] = n else: normals[i2] = lerp(normals[i2], n, 0.5).normalized() - + arrays[ArrayMesh.ARRAY_NORMAL] = normals mdr.array = arrays - -# Apparently surfacetool adds more verts during normal generation -# Keeping this here for now -static func generate_normals_surface_tool(mdr : MeshDataResource) -> void: + + */ +} + +// Apparently surfacetool adds more verts during normal generation +// Keeping this here for now +void MDREDMeshUtils::generate_normals_surface_tool(Ref mdr) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return - + var st : SurfaceTool = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) - + add_into_surface_tool(mdr, st) - + st.generate_normals() - - mdr.array = st.commit_to_arrays() -static func generate_tangents(mdr : MeshDataResource) -> void: + mdr.array = st.commit_to_arrays() + */ +} +void MDREDMeshUtils::generate_tangents(Ref mdr) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: arrays.resize(ArrayMesh.ARRAY_MAX) - + if arrays[ArrayMesh.ARRAY_INDEX] == null: return - + var st : SurfaceTool = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) - - add_into_surface_tool(mdr, st) - - st.generate_tangents() - - mdr.array = st.commit_to_arrays() -static func remove_used_vertices(arrays : Array) -> Array: + add_into_surface_tool(mdr, st) + + st.generate_tangents() + + mdr.array = st.commit_to_arrays() + */ +} + +Array MDREDMeshUtils::remove_used_vertices(Array arrays) { + /* 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: + remove_vertices(arrays, unused_indices) + + return arrays + */ +} + +Array MDREDMeshUtils::remove_vertices(Array arrays, PoolIntArray indices) { + /* if indices.size() == 0: return arrays - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] - + var normals : PoolVector3Array var tangents : PoolRealArray var colors : PoolColorArray @@ -931,39 +1189,39 @@ static func remove_vertices(arrays : Array, indices : PoolIntArray) -> Array: 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) @@ -987,399 +1245,308 @@ static func remove_vertices(arrays : Array, indices : PoolIntArray) -> Array: #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: + max_index = find_max_capped(indices, max_index) + + arrays[ArrayMesh.ARRAY_INDEX] = arr_indices + + return arrays + */ +} + +int MDREDMeshUtils::find_max(PoolIntArray arr) { + /* 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: + return m + */ +} +int MDREDMeshUtils::find_max_capped(PoolIntArray arr, int last) { + /* 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: + return m + */ +} + +PoolIntArray MDREDMeshUtils::order_seam_indices(PoolIntArray arr) { + /* var ret : PoolIntArray = PoolIntArray() - + if arr.size() == 0: return ret - + for i in range(0, arr.size(), 2): var index0 : int = arr[i] var index1 : int = arr[i + 1] - + if index0 > index1: var t : int = index1 index1 = index0 index0 = t - + ret.push_back(index0) ret.push_back(index1) - - return ret -static func add_seam_not_ordered(mdr : MeshDataResource, index0 : int, index1 : int) -> void: + return ret + */ +} + +void MDREDMeshUtils::add_seam_not_ordered(Ref mdr, int index0, int index1) { + /* if index0 > index1: add_seam(mdr, index1, index0) else: add_seam(mdr, index0, index1) - -static func remove_seam_not_ordered(mdr : MeshDataResource, index0 : int, index1 : int) -> void: + */ +} +void MDREDMeshUtils::remove_seam_not_ordered(Ref mdr, int index0, int index1) { + /* if index0 > index1: remove_seam(mdr, index1, index0) else: remove_seam(mdr, index0, index1) + */ +} -static func has_seam(mdr : MeshDataResource, index0 : int, index1 : int) -> bool: +bool MDREDMeshUtils::has_seam(Ref mdr, int index0, int index1) { + /* var seams : PoolIntArray = mdr.seams - + for i in range(0, seams.size(), 2): if seams[i] == index0 && seams[i + 1] == index1: return true - - return false -static func add_seam(mdr : MeshDataResource, index0 : int, index1 : int) -> void: + return false + */ +} +void MDREDMeshUtils::add_seam(Ref mdr, int index0, int index1) { + /* if has_seam(mdr, index0, index1): return - + var seams : PoolIntArray = mdr.seams seams.push_back(index0) seams.push_back(index1) mdr.seams = seams - -static func remove_seam(mdr : MeshDataResource, index0 : int, index1 : int) -> void: + */ +} +void MDREDMeshUtils::remove_seam(Ref mdr, int index0, int index1) { + /* if !has_seam(mdr, index0, index1): return - + var seams : PoolIntArray = mdr.seams - + for i in range(0, seams.size(), 2): if seams[i] == index0 && seams[i + 1] == index1: seams.remove(i) seams.remove(i) mdr.seams = seams return + */ +} -static func is_verts_equal(v0 : Vector3, v1 : Vector3) -> bool: +bool MDREDMeshUtils::is_verts_equal(Vector3 v0, Vector3 v1) { + /* return is_equal_approx(v0.x, v1.x) && is_equal_approx(v0.y, v1.y) && is_equal_approx(v0.z, v1.z) + */ +} - -static func points_to_seams(mdr : MeshDataResource, points : PoolVector3Array) -> void: +void MDREDMeshUtils::points_to_seams(Ref mdr, PoolVector3Array points) { + /* var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: return - + if arrays[ArrayMesh.ARRAY_VERTEX] == null: return - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var seams : PoolIntArray = PoolIntArray() - + for i in range(0, points.size(), 2): var p0 : Vector3 = points[i] var p1 : Vector3 = points[i + 1] - + for j in range(0, indices.size(), 3): var v0 : Vector3 = vertices[indices[j]] var v1 : Vector3 = vertices[indices[j + 1]] var v2 : Vector3 = vertices[indices[j + 2]] - + var p0_index : int = -1 - + if is_verts_equal(p0, v0): p0_index = indices[j] elif is_verts_equal(p0, v1): p0_index = indices[j + 1] elif is_verts_equal(p0, v2): p0_index = indices[j + 2] - + if p0_index == -1: continue - + var p1_index : int = -1 - + if is_verts_equal(p1, v0): p1_index = indices[j] elif is_verts_equal(p1, v1): p1_index = indices[j + 1] elif is_verts_equal(p1, v2): p1_index = indices[j + 2] - + if p1_index == -1: continue - + if p0_index == p1_index: continue - + if p0_index > p1_index: var t : int = p0_index p0_index = p1_index p1_index = t - + seams.push_back(p0_index) seams.push_back(p1_index) break - - mdr.seams = seams -static func seams_to_points(mdr : MeshDataResource) -> PoolVector3Array: + mdr.seams = seams + */ +} +PoolVector3Array MDREDMeshUtils::seams_to_points(Ref mdr) { + /* var points : PoolVector3Array = PoolVector3Array() - + var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: return points - + if arrays[ArrayMesh.ARRAY_VERTEX] == null: return points - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var seams : PoolIntArray = mdr.seams - + for s in seams: points.push_back(vertices[s]) - - return points -static func is_matching_seam(i0 : int, i1: int, si0 : int, si1: int) -> bool: + return points + */ +} +bool MDREDMeshUtils::is_matching_seam(int i0, int i1, int si0, int si1) { + /* if i0 > i1: var t : int = i0 i0 = i1 i1 = t - - return (i0 == si0) && (i1 == si1) -static func pool_int_arr_contains(arr : PoolIntArray, val : int) -> bool: + return (i0 == si0) && (i1 == si1) + */ +} + +bool MDREDMeshUtils::pool_int_arr_contains(PoolIntArray arr, int val) { + /* for a in arr: if a == val: return true - + return false + */ +} - -class SeamTriangleHelper: - var i0 : int = 0 - var i1 : int = 0 - var i2 : int = 0 - var orig_index : int = 0 - var index_index : int = 0 - - var side_index_1 : int = 0 - var side_index_2 : int = 0 - var side_index_1_cut : bool = false - var side_index_2_cut : bool = false - - var processed : bool = false - - func get_other_side_index(index : int) -> int: - if side_index_1 == index: - return side_index_2 - else: - return side_index_1 - - func get_side_index(i : int) -> int: - if i == 1: - return side_index_1 - else: - return side_index_2 - - func get_side_index_cut() -> int: - if side_index_1_cut && side_index_2_cut: - return 3 - elif side_index_1_cut: - return 1 - elif side_index_2_cut: - return 2 - else: - return 0 - - func get_opposite_side_index_cut() -> int: - if side_index_1_cut && side_index_2_cut: - return 3 - elif side_index_1_cut: - return 2 - elif side_index_2_cut: - return 1 - else: - return 0 - - func is_side_index_cut(i : int) -> bool: - if i == 1: - return side_index_1_cut - else: - return side_index_2_cut - - func is_the_same(h : SeamTriangleHelper) -> bool: - return is_triangle(h.i0, h.i1, h.i2) - - func is_triangle(pi0 : int, pi1 : int, pi2 : int) -> bool: - if pi0 == i0 || pi0 == i1 || pi0 == i2: - if pi1 == i0 || pi1 == i1 || pi1 == i2: - if pi2 == i0 || pi2 == i1 || pi2 == i2: - return true - - return false - - func is_neighbour_to(index : int) -> bool: - return (side_index_1 == index) || (side_index_2 == index) - - func needs_to_be_cut_near(index : int) -> bool: - if (side_index_1 == index): - return side_index_1_cut - - if (side_index_2 == index): - return side_index_2_cut - - return false - - func has_cut() -> bool: - return side_index_1_cut || side_index_2_cut - - func both_sides_need_cut() -> bool: - return side_index_1_cut && side_index_2_cut - - func setup(pi0 : int, pi1 : int, pi2 : int, porig_ind : int, pindex_index : int, seams : PoolIntArray) -> void: - processed = false - i0 = pi0 - i1 = pi1 - i2 = pi2 - orig_index = porig_ind - index_index = pindex_index - - if porig_ind == pi0: - side_index_1 = pi1 - side_index_2 = pi2 - elif porig_ind == pi1: - side_index_1 = pi0 - side_index_2 = pi2 - elif porig_ind == pi2: - side_index_1 = pi1 - side_index_2 = pi0 - - determine_cuts(seams) - - func determine_cuts(seams : PoolIntArray) -> void: - if orig_index < side_index_1: - side_index_1_cut = check_cut(orig_index, side_index_1, seams) - else: - side_index_1_cut = check_cut(side_index_1, orig_index, seams) - - if orig_index < side_index_2: - side_index_2_cut = check_cut(orig_index, side_index_2, seams) - else: - side_index_2_cut = check_cut(side_index_2, orig_index, seams) - - func check_cut(ind0 : int, ind1 : int, seams : PoolIntArray) -> bool: - for stind in range(0, seams.size(), 2): - var si0 : int = seams[stind] - var si1 : int = seams[stind + 1] - - if (si0 == ind0) && (si1 == ind1): - return true - - return false - - func _to_string(): - return "[ TRI: " + str(i0) + ", " + str(i1) + ", " + str(i2) + " ]" - -static func apply_seam(mdr : MeshDataResource) -> void: +void MDREDMeshUtils::apply_seam(Ref mdr) { + /* var points : PoolVector3Array = PoolVector3Array() - + var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: return - + if arrays[ArrayMesh.ARRAY_VERTEX] == null: return - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var new_indices : PoolIntArray = PoolIntArray() new_indices.append_array(indices) var seams : PoolIntArray = mdr.seams - + # Duplication happens later, as it requires lots of logic var duplicate_verts_indices : PoolIntArray = PoolIntArray() var new_vert_size : int = vertices.size() - + for i in range(vertices.size()): # first check if vertex is a part of at least 2 edge seams var test_seam_count : int = 0 for s in seams: if s == i: test_seam_count += 1 - + if test_seam_count >= 2: break - + if test_seam_count < 2: continue - + # Collect all triangles that use this vertex as SeamTriangleHelpers var triangles : Array = Array() for j in range(indices.size()): var i0 : int = indices[j] - + if i0 != i: continue @@ -1392,7 +1559,7 @@ static func apply_seam(mdr : MeshDataResource) -> void: var s : SeamTriangleHelper = SeamTriangleHelper.new() s.setup(i0, i1, i2, i0, j, seams) triangles.push_back(s) - + var triangle_arrays : Array = Array() while true: # First find a triangle that needs to be cut @@ -1400,24 +1567,24 @@ static func apply_seam(mdr : MeshDataResource) -> void: var tri_index : int = -1 for it in range(triangles.size()): tri = triangles[it] - + if tri.has_cut() && !tri.processed: tri_index = it break - + if tri_index == -1: #done break - + tri.processed = true if tri.both_sides_need_cut(): triangle_arrays.push_back([ tri ]) continue - + var collected_triangles : Array = Array() collected_triangles.push_back(tri) - + # Find all neighbours and set them to processed + update the index for them #var side_index : int = tri.get_side_index_cut() var neighbour_tri : SeamTriangleHelper = tri @@ -1426,14 +1593,14 @@ static func apply_seam(mdr : MeshDataResource) -> void: var tri_found : bool = true while tri_found: tri_found = false - + for ntri in triangles: if ntri.processed: continue - + if ntri.is_the_same(neighbour_tri): continue - + if ntri.is_neighbour_to(find_neighbour_for_edge): neighbour_tri = ntri find_neighbour_for_edge = neighbour_tri.get_other_side_index(find_neighbour_for_edge) @@ -1441,15 +1608,15 @@ static func apply_seam(mdr : MeshDataResource) -> void: neighbour_tri.processed = true tri_found = true collected_triangles.push_back(neighbour_tri) - + if neighbour_tri.has_cut(): # Done with this "strip" tri_found = false break - + triangle_arrays.push_back(collected_triangles) - + # triangle_arrays is guaranteed to have at least 2 entries # Skip processing the first strip, so we don't create unused verts for tind in range(1, triangle_arrays.size()): @@ -1459,99 +1626,103 @@ static func apply_seam(mdr : MeshDataResource) -> void: for tri in tris: new_indices[tri.index_index] = new_vert_size - + new_vert_size += 1 arrays[ArrayMesh.ARRAY_INDEX] = new_indices mdr.array = seam_apply_duplicate_vertices(arrays, duplicate_verts_indices) - - -static func apply_seam_old(mdr : MeshDataResource) -> void: + */ +} +void MDREDMeshUtils::apply_seam_old(Ref mdr) { + /* var points : PoolVector3Array = PoolVector3Array() - + var arrays : Array = mdr.get_array() - + if arrays.size() != ArrayMesh.ARRAY_MAX: return - + if arrays[ArrayMesh.ARRAY_VERTEX] == null: return - + var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] var indices : PoolIntArray = arrays[ArrayMesh.ARRAY_INDEX] var seams : PoolIntArray = mdr.seams - + # Duplication happens later, as it requires lots of logic var duplicate_verts_indices : PoolIntArray = PoolIntArray() var new_vert_size : int = vertices.size() - + for i in range(0, seams.size(), 2): var si0 : int = seams[i] var si1 : int = seams[i + 1] - + var first : bool = true for j in range(0, indices.size(), 3): var i0 : int = indices[j] var i1 : int = indices[j + 1] var i2 : int = indices[j + 2] - + var edge_int_tri_index : int = -1 - + if is_matching_seam(i0, i1, si0, si1): edge_int_tri_index = 0 elif is_matching_seam(i1, i2, si0, si1): edge_int_tri_index = 1 elif is_matching_seam(i2, i0, si0, si1): edge_int_tri_index = 2 - + if edge_int_tri_index == -1: continue - + if first: # Only split away the subsequent tris first = false continue - + if edge_int_tri_index == 0: duplicate_verts_indices.push_back(i0) duplicate_verts_indices.push_back(i1) - + indices.push_back(new_vert_size) indices.push_back(new_vert_size + 1) indices.push_back(i2) elif edge_int_tri_index == 1: duplicate_verts_indices.push_back(i1) duplicate_verts_indices.push_back(i2) - + indices.push_back(i0) indices.push_back(new_vert_size) indices.push_back(new_vert_size + 1) elif edge_int_tri_index == 2: duplicate_verts_indices.push_back(i0) duplicate_verts_indices.push_back(i2) - + indices.push_back(new_vert_size) indices.push_back(i1) indices.push_back(new_vert_size + 1) - + indices.remove(j) indices.remove(j) indices.remove(j) j -= 3 - + new_vert_size += 2 - + arrays[ArrayMesh.ARRAY_INDEX] = indices #mdr.array = arrays - - mdr.array = seam_apply_duplicate_vertices(arrays, duplicate_verts_indices) -# This will not touch the indices! -static func seam_apply_duplicate_vertices(arrays : Array, duplicate_verts_indices : PoolIntArray) -> Array: + mdr.array = seam_apply_duplicate_vertices(arrays, duplicate_verts_indices) + */ +} + +// This will not touch the indices! +Array MDREDMeshUtils::seam_apply_duplicate_vertices(Array arrays, PoolIntArray duplicate_verts_indices) { + /* var vertices : PoolVector3Array = arrays[ArrayMesh.ARRAY_VERTEX] - + var normals : PoolVector3Array var tangents : PoolRealArray var colors : PoolColorArray @@ -1562,38 +1733,38 @@ static func seam_apply_duplicate_vertices(arrays : Array, duplicate_verts_indice 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 duplicate_verts_indices: vertices.push_back(vertices[index]) - + if arrays[ArrayMesh.ARRAY_NORMAL] != null: normals.push_back(normals[index]) - + if arrays[ArrayMesh.ARRAY_TANGENT] != null: tangents.push_back(tangents[index]) tangents.push_back(tangents[index + 1]) tangents.push_back(tangents[index + 2]) tangents.push_back(tangents[index + 3]) - + if arrays[ArrayMesh.ARRAY_COLOR] != null: colors.push_back(colors[index]) @@ -1616,28 +1787,30 @@ static func seam_apply_duplicate_vertices(arrays : Array, duplicate_verts_indice weights.push_back(weights[index + 3]) #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 return arrays + */ +} diff --git a/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.h b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.h new file mode 100644 index 000000000..afdd61554 --- /dev/null +++ b/modules/mesh_data_resource/editor/utilities/mdr_ed_mesh_utils.h @@ -0,0 +1,153 @@ +#ifndef MDR_ED_MESH_UTILS_H +#define MDR_ED_MESH_UTILS_H + +/* +Copyright (c) 2019-2022 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "core/ustring.h" +#include "core/pool_vector.h" +#include "core/math/vector3.h" +#include "core/reference.h" +#include "core/array.h" + +class MeshDataResource; +class SurfaceTool; + +class MDREDMeshUtils { +public: + struct SeamTriangleHelper { + int i0; + int i1; + int i2; + int orig_index; + int index_index; + + int side_index_1; + int side_index_2; + bool side_index_1_cut; + bool side_index_2_cut; + + bool processed; + + int get_other_side_index(int index); + + int get_side_index(int i); + int get_side_index_cut(); + int get_opposite_side_index_cut(); + bool is_side_index_cut(int i); + + bool is_the_same(SeamTriangleHelper h); + + bool is_triangle(int pi0, int pi1, int pi2); + bool is_neighbour_to(int index); + + bool needs_to_be_cut_near(int index); + bool has_cut(); + bool both_sides_need_cut(); + + void setup(int pi0, int pi1, int pi2, int porig_ind, int pindex_index, PoolIntArray seams); + + void determine_cuts(PoolIntArray seams); + bool check_cut(int ind0, int ind1, PoolIntArray seams); + + String _to_string(); + + SeamTriangleHelper(); + }; + + static void remove_triangle(Ref mdr, int triangle_index); + static bool add_triangulated_mesh_from_points_delaunay(Ref mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing); + static void add_triangulated_mesh_from_points(Ref mdr, PoolVector3Array selected_points, Vector3 last_known_camera_facing); + + // Appends a triangle to the mesh. It's created from miroring v2 to the ev0, and ev1 edge + static void append_triangle_to_tri_edge(Ref mdr, Vector3 ev0, Vector3 ev1, Vector3 v2); + + static void add_triangle_at(Ref mdr, Vector3 v0, Vector3 v1, Vector3 v2, bool flip = false); + + static void add_triangle(Ref mdr); + + // Appends a quad to the mesh. It's created to the opposite side of v2 to the ev0, and ev1 edge + static void append_quad_to_tri_edge(Ref mdr, Vector3 ev0, Vector3 ev1, Vector3 v2); + static void add_quad_at(Ref mdr, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, bool flip = false); + static void add_quad(Ref mdr); + static void add_box(Ref mdr); + static void merge_in_surface_tool(Ref mdr, Ref st, bool generate_normals_if_needed = true, bool generate_tangents_if_needed = true); + static void merge_in_arrays(Ref mdr, Array merge); + static Array get_arrays_prepared(Ref mdr); + + // There are probably better ways to do this + static bool should_flip_reflected_triangle(Vector3 v0, Vector3 v1, Vector3 v2); + static Vector3 reflect_vertex(Vector3 v0, Vector3 v1, Vector3 v2); + + static Vector3 get_face_normal_arr_ti(PoolVector3Array verts, PoolIntArray indices, int triangle_index, bool flipped = false); + static Vector3 get_face_normal_arr(PoolVector3Array verts, PoolIntArray indices, int index, bool flipped = false); + static Vector3 get_face_normal(Vector3 v0, Vector3 v1, Vector3 v2, bool flipped = false); + + static bool should_triangle_flip(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal); + + static bool is_normal_similar(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 similar_dir_normal); + static bool is_direction_similar(Vector3 d0, Vector3 d1); + + static void flip_triangle_ti(Ref mdr, int triangle_index); + static void flip_triangle(Ref mdr, int index); + static void add_into_surface_tool(Ref mdr, Ref st); + + static Array generate_normals_arrs(Array arrays); + static void generate_normals_mdr(Ref mdr); + + // Apparently surfacetool adds more verts during normal generation + // Keeping this here for now + static void generate_normals_surface_tool(Ref mdr); + static void generate_tangents(Ref mdr); + + static Array remove_used_vertices(Array arrays); + + static Array remove_vertices(Array arrays, PoolIntArray indices); + + static int find_max(PoolIntArray arr); + static int find_max_capped(PoolIntArray arr, int last); + + static PoolIntArray order_seam_indices(PoolIntArray arr); + + static void add_seam_not_ordered(Ref mdr, int index0, int index1); + static void remove_seam_not_ordered(Ref mdr, int index0, int index1); + + static bool has_seam(Ref mdr, int index0, int index1); + static void add_seam(Ref mdr, int index0, int index1); + static void remove_seam(Ref mdr, int index0, int index1); + + static bool is_verts_equal(Vector3 v0, Vector3 v1); + + static void points_to_seams(Ref mdr, PoolVector3Array points); + static PoolVector3Array seams_to_points(Ref mdr); + static bool is_matching_seam(int i0, int i1, int si0, int si1); + + static bool pool_int_arr_contains(PoolIntArray arr, int val); + + static void apply_seam(Ref mdr); + static void apply_seam_old(Ref mdr); + + // This will not touch the indices! + static Array seam_apply_duplicate_vertices(Array arrays, PoolIntArray duplicate_verts_indices); +}; + +#endif diff --git a/modules/mesh_data_resource/editor/addon/utilities/mesh_decompose.gd b/modules/mesh_data_resource/editor/utilities/mesh_decompose.gd similarity index 100% rename from modules/mesh_data_resource/editor/addon/utilities/mesh_decompose.gd rename to modules/mesh_data_resource/editor/utilities/mesh_decompose.gd diff --git a/modules/mesh_data_resource/editor/addon/utilities/mesh_outline.gd b/modules/mesh_data_resource/editor/utilities/mesh_outline.gd similarity index 100% rename from modules/mesh_data_resource/editor/addon/utilities/mesh_outline.gd rename to modules/mesh_data_resource/editor/utilities/mesh_outline.gd