/* 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 "mdi_gizmo.h" void MDIGizmo::setup() { /* get_spatial_node().connect("mesh_data_resource_changed", self, "on_mesh_data_resource_changed") on_mesh_data_resource_changed(get_spatial_node().mesh_data) */ } void MDIGizmo::set_editor_plugin(EditorPlugin *editor_plugin) { /* _editor_plugin = editor_plugin _undo_redo = _editor_plugin.get_undo_redo() */ } void MDIGizmo::set_handle(int index, Camera *camera, Vector2 point) { /* var relative : Vector2 = point - previous_point if !_handle_drag_op: relative = Vector2() _handle_drag_op = true if edit_mode == EditMode.EDIT_MODE_SCALE: _drag_op_accumulator = Vector3(1, 1, 1) else: _drag_op_accumulator = Vector3() _drag_op_accumulator_quat = Quat() _drag_op_orig_verices = copy_mdr_verts_array() setup_op_drag_indices() _drag_op_pivot = get_drag_op_pivot() if edit_mode == EditMode.EDIT_MODE_NONE: return elif edit_mode == EditMode.EDIT_MODE_TRANSLATE: var ofs : Vector3 = Vector3() ofs = camera.get_global_transform().basis.x if (axis_constraint & AxisConstraint.X) != 0: ofs.x *= relative.x * 0.01 else: ofs.x = 0 if (axis_constraint & AxisConstraint.Y) != 0: ofs.y = relative.y * -0.01 else: ofs.y = 0 if (axis_constraint & AxisConstraint.Z) != 0: ofs.z *= relative.x * 0.01 else: ofs.z = 0 _drag_op_accumulator += ofs add_to_all_selected(_drag_op_accumulator) apply() redraw() elif edit_mode == EditMode.EDIT_MODE_SCALE: var r : float = ((relative.x + relative.y) * 0.05) var vs : Vector3 = Vector3() if (axis_constraint & AxisConstraint.X) != 0: vs.x = r if (axis_constraint & AxisConstraint.Y) != 0: vs.y = r if (axis_constraint & AxisConstraint.Z) != 0: vs.z = r _drag_op_accumulator += vs var b : Basis = Basis().scaled(_drag_op_accumulator) var t : Transform = Transform(Basis(), _drag_op_pivot) t *= Transform(b, Vector3()) t *= Transform(Basis(), _drag_op_pivot).inverse() mul_all_selected_with_transform(t) apply() redraw() elif edit_mode == EditMode.EDIT_MODE_ROTATE: var yrot : Quat = Quat(Vector3(0, 1, 0), relative.x * 0.01) var xrot : Quat = Quat(camera.get_global_transform().basis.x, relative.y * 0.01) _drag_op_accumulator_quat *= yrot _drag_op_accumulator_quat *= xrot _drag_op_accumulator_quat = _drag_op_accumulator_quat.normalized() var b : Basis = Basis(_drag_op_accumulator_quat) var t : Transform = Transform(Basis(), _drag_op_pivot) t *= Transform(b, Vector3()) t *= Transform(Basis(), _drag_op_pivot).inverse() mul_all_selected_with_transform(t) apply() redraw() previous_point = point */ } void MDIGizmo::redraw() { /* clear() if !_mdr: return if _mdr.array.size() != ArrayMesh.ARRAY_MAX: return if !get_plugin(): return var handles_material : SpatialMaterial = get_plugin().get_material("handles", self) var material = get_plugin().get_material("main", self) var seam_material = get_plugin().get_material("seam", self) _mesh_outline_generator.setup(_mdr) if selection_mode == SelectionMode.SELECTION_MODE_EDGE: _mesh_outline_generator.generate_mark_edges(visual_indicator_outline, visual_indicator_handle) elif selection_mode == SelectionMode.SELECTION_MODE_FACE: _mesh_outline_generator.generate_mark_faces(visual_indicator_outline, visual_indicator_handle) else: _mesh_outline_generator.generate(visual_indicator_outline, visual_indicator_handle) if visual_indicator_outline || visual_indicator_handle: add_lines(_mesh_outline_generator.lines, material, false) if visual_indicator_seam: add_lines(_mesh_outline_generator.seam_lines, seam_material, false) if _selected_points.size() > 0: var vs : PoolVector3Array = PoolVector3Array() for i in _selected_points: vs.append(_handle_points[i]) add_handles(vs, handles_material) */ } void MDIGizmo::apply() { /* if !_mdr: return disable_change_event() var arrs : Array = _mdr.array arrs[ArrayMesh.ARRAY_VERTEX] = _vertices arrs[ArrayMesh.ARRAY_INDEX] = _indices _mdr.array = arrs enable_change_event() */ } void MDIGizmo::select_all() { /* if _selected_points.size() == _handle_points.size(): return _selected_points.resize(_handle_points.size()) for i in range(_selected_points.size()): _selected_points[i] = i redraw() */ } bool MDIGizmo::selection_click(int index, Camera *camera, const Ref &event) { /* if handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_FRONT: return selection_click_select_front_or_back(index, camera, event) elif handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_BACK: return selection_click_select_front_or_back(index, camera, event) else: return selection_click_select_through(index, camera, event) return false */ } bool MDIGizmo::is_point_visible(Vector3 point_orig, Vector3 camera_pos, Transform gt) { /* var point : Vector3 = gt.xform(point_orig) # go from the given point to the origin (camera_pos -> camera) var dir : Vector3 = camera_pos - point dir = dir.normalized() # Might need to reduce z fighting #point += dir * 0.5 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] v0 = gt.xform(v0) v1 = gt.xform(v1) v2 = gt.xform(v2) var res = Geometry.ray_intersects_triangle(point, dir, v0, v1, v2) if res is Vector3: return false return true */ } void MDIGizmo::selection_click_select_front_or_back(int index, Camera *camera, const Ref &event) { /* var gt : Transform = get_spatial_node().global_transform var ray_from : Vector3 = camera.global_transform.origin var gpoint : Vector2 = event.get_position() var grab_threshold : float = 8 # select vertex var closest_idx : int = -1 var closest_dist : float = 1e10 for i in range(_handle_points.size()): var vert_pos_3d : Vector3 = gt.xform(_handle_points[i]) var vert_pos_2d : Vector2 = camera.unproject_position(vert_pos_3d) var dist_3d : float = ray_from.distance_to(vert_pos_3d) var dist_2d : float = gpoint.distance_to(vert_pos_2d) if (dist_2d < grab_threshold && dist_3d < closest_dist): var point_visible : bool = is_point_visible(_handle_points[i], ray_from, gt) if handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_FRONT: if !point_visible: continue elif handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_BACK: if point_visible: continue closest_dist = dist_3d closest_idx = i if (closest_idx >= 0): for si in range(_selected_points.size()): if _selected_points[si] == closest_idx: if event.alt || event.control: _selected_points.remove(si) return true return false if event.alt || event.control: return false if event.shift: _selected_points.append(closest_idx) else: # Select new point only _selected_points.resize(0) _selected_points.append(closest_idx) apply() redraw() else: # Don't unselect all if either control or shift is held down if event.shift || event.control || event.alt: return false if _selected_points.size() == 0: return false #Unselect all _selected_points.resize(0) redraw() */ } void MDIGizmo::selection_click_select_through(int index, Camera *camera, const Ref &event) { /* var gt : Transform = get_spatial_node().global_transform var ray_from : Vector3 = camera.global_transform.origin var gpoint : Vector2 = event.get_position() var grab_threshold : float = 8 # select vertex var closest_idx : int = -1 var closest_dist : float = 1e10 for i in range(_handle_points.size()): var vert_pos_3d : Vector3 = gt.xform(_handle_points[i]) var vert_pos_2d : Vector2 = camera.unproject_position(vert_pos_3d) var dist_3d : float = ray_from.distance_to(vert_pos_3d) var dist_2d : float = gpoint.distance_to(vert_pos_2d) if (dist_2d < grab_threshold && dist_3d < closest_dist): closest_dist = dist_3d closest_idx = i if (closest_idx >= 0): for si in range(_selected_points.size()): if _selected_points[si] == closest_idx: if event.alt || event.control: _selected_points.remove(si) return true return false if event.alt || event.control: return false if event.shift: _selected_points.append(closest_idx) else: # Select new point only _selected_points.resize(0) _selected_points.append(closest_idx) apply() redraw() else: # Don't unselect all if either control or shift is held down if event.shift || event.control || event.alt: return false if _selected_points.size() == 0: return false #Unselect all _selected_points.resize(0) redraw() */ } void MDIGizmo::selection_drag(int index, Camera *camera, const Ref &event) { /* if handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_FRONT: selection_drag_rect_select_front_back(index, camera, event) elif handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_BACK: selection_drag_rect_select_front_back(index, camera, event) else: selection_drag_rect_select_through(index, camera, event) */ } void MDIGizmo::selection_drag_rect_select_front_back(int index, Camera *camera, const Ref &event) { /* var gt : Transform = get_spatial_node().global_transform var ray_from : Vector3 = camera.global_transform.origin var mouse_pos : Vector2 = event.get_position() var rect_size : Vector2 = _rect_drag_start_point - mouse_pos rect_size.x = abs(rect_size.x) rect_size.y = abs(rect_size.y) var rect : Rect2 = Rect2(_rect_drag_start_point, rect_size) # This is needed so selection works even when you drag from bottom to top, and from right to left var rect_ofs : Vector2 = _rect_drag_start_point - mouse_pos if rect_ofs.x > 0: rect.position.x -= rect_ofs.x if rect_ofs.y > 0: rect.position.y -= rect_ofs.y var selected : PoolIntArray = PoolIntArray() for i in range(_handle_points.size()): var vert_pos_3d : Vector3 = gt.xform(_handle_points[i]) var vert_pos_2d : Vector2 = camera.unproject_position(vert_pos_3d) if rect.has_point(vert_pos_2d): var point_visible : bool = is_point_visible(_handle_points[i], ray_from, gt) if handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_FRONT: if !point_visible: continue elif handle_selection_type == HandleSelectionType.HANDLE_SELECTION_TYPE_BACK: if point_visible: continue selected.push_back(i) if event.alt || event.control: for isel in selected: for i in range(_selected_points.size()): if _selected_points[i] == isel: _selected_points.remove(i) break redraw() return if event.shift: for isel in selected: if !pool_int_arr_contains(_selected_points, isel): _selected_points.push_back(isel) redraw() return _selected_points.resize(0) _selected_points.append_array(selected) redraw() */ } void MDIGizmo::selection_drag_rect_select_through(int index, Camera *camera, const Ref &event) { /* var gt : Transform = get_spatial_node().global_transform var mouse_pos : Vector2 = event.get_position() var rect_size : Vector2 = _rect_drag_start_point - mouse_pos rect_size.x = abs(rect_size.x) rect_size.y = abs(rect_size.y) var rect : Rect2 = Rect2(_rect_drag_start_point, rect_size) # This is needed so selection works even when you drag from bottom to top, and from right to left var rect_ofs : Vector2 = _rect_drag_start_point - mouse_pos if rect_ofs.x > 0: rect.position.x -= rect_ofs.x if rect_ofs.y > 0: rect.position.y -= rect_ofs.y var selected : PoolIntArray = PoolIntArray() for i in range(_handle_points.size()): var vert_pos_3d : Vector3 = gt.xform(_handle_points[i]) var vert_pos_2d : Vector2 = camera.unproject_position(vert_pos_3d) if rect.has_point(vert_pos_2d): selected.push_back(i) if event.alt || event.control: for isel in selected: for i in range(_selected_points.size()): if _selected_points[i] == isel: _selected_points.remove(i) break redraw() return if event.shift: for isel in selected: if !pool_int_arr_contains(_selected_points, isel): _selected_points.push_back(isel) redraw() return _selected_points.resize(0) _selected_points.append_array(selected) redraw() */ } bool MDIGizmo::forward_spatial_gui_input(int index, Camera *camera, const Ref &event) { /* _last_known_camera_facing = camera.transform.basis.xform(Vector3(0, 0, -1)) if event is InputEventMouseButton: if event.get_button_index() == BUTTON_LEFT: if _handle_drag_op: if !event.is_pressed(): _handle_drag_op = false # If a handle was being dragged only run these if _mdr && _mdr.array.size() == ArrayMesh.ARRAY_MAX && _mdr.array[ArrayMesh.ARRAY_VERTEX] != null && _mdr.array[ArrayMesh.ARRAY_VERTEX].size() == _drag_op_orig_verices.size(): _undo_redo.create_action("Drag") _undo_redo.add_do_method(self, "apply_vertex_array", _mdr, _mdr.array[ArrayMesh.ARRAY_VERTEX]) _undo_redo.add_undo_method(self, "apply_vertex_array", _mdr, _drag_op_orig_verices) _undo_redo.commit_action() # Dont consume the event here, because the handles will get stuck # to the mouse pointer if we return true return false if !event.is_pressed(): # See whether we should check for a click or a selection box var mouse_pos : Vector2 = event.get_position() var rect_size : Vector2 = _rect_drag_start_point - mouse_pos rect_size.x = abs(rect_size.x) rect_size.y = abs(rect_size.y) var had_rect_drag : bool = false if rect_size.x > _rect_drag_min_ofset || rect_size.y > _rect_drag_min_ofset: had_rect_drag = true if !had_rect_drag: return selection_click(index, camera, event) else: selection_drag(index, camera, event) # Always return false here, so the drag rect thing disappears in the editor return false else: # event is pressed _rect_drag = true _rect_drag_start_point = event.get_position() return false */ } void MDIGizmo::add_to_all_selected(Vector3 ofs) { /* for i in _selected_points: var v : Vector3 = _handle_points[i] v += ofs _handle_points.set(i, v) for indx in _drag_op_indices: var v : Vector3 = _drag_op_orig_verices[indx] v += ofs _vertices.set(indx, v) */ } void MDIGizmo::mul_all_selected_with_basis(Basis b) { /* for i in _selected_points: var v : Vector3 = _handle_points[i] v = b * v _handle_points.set(i, v) for indx in _drag_op_indices: var v : Vector3 = _drag_op_orig_verices[indx] v = b * v _vertices.set(indx, v) */ } void MDIGizmo::mul_all_selected_with_transform(Transform t) { /* for i in _selected_points: var v : Vector3 = _handle_points[i] v = t * v _handle_points.set(i, v) for indx in _drag_op_indices: var v : Vector3 = _drag_op_orig_verices[indx] v = t * v _vertices.set(indx, v) */ } void MDIGizmo::mul_all_selected_with_transform_acc(Transform t) { /* for i in _selected_points: var v : Vector3 = _handle_points[i] v = t * v _handle_points.set(i, v) for indx in _drag_op_indices: var v : Vector3 = _vertices[indx] v = t * v _vertices.set(indx, v) */ } void MDIGizmo::set_translate() { /* edit_mode = EditMode.EDIT_MODE_TRANSLATE */ } void MDIGizmo::set_scale() { /* edit_mode = EditMode.EDIT_MODE_SCALE */ } void MDIGizmo::set_rotate() { /* edit_mode = EditMode.EDIT_MODE_ROTATE */ } void MDIGizmo::set_edit_mode(int em) { /* edit_mode = em */ } void MDIGizmo::set_axis_x(bool on) { /* if on: axis_constraint |= AxisConstraint.X else: if (axis_constraint & AxisConstraint.X) != 0: axis_constraint ^= AxisConstraint.X */ } void MDIGizmo::set_axis_y(bool on) { /* if on: axis_constraint |= AxisConstraint.Y else: if (axis_constraint & AxisConstraint.Y) != 0: axis_constraint ^= AxisConstraint.Y */ } void MDIGizmo::set_axis_z(bool on) { /* if on: axis_constraint |= AxisConstraint.Z else: if (axis_constraint & AxisConstraint.Z) != 0: axis_constraint ^= AxisConstraint.Z */ } void MDIGizmo::set_selection_mode_vertex() { /* if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: return selection_mode = SelectionMode.SELECTION_MODE_VERTEX _selected_points.resize(0) recalculate_handle_points() redraw() */ } void MDIGizmo::set_selection_mode_edge() { /* if selection_mode == SelectionMode.SELECTION_MODE_EDGE: return selection_mode = SelectionMode.SELECTION_MODE_EDGE _selected_points.resize(0) recalculate_handle_points() redraw() */ } void MDIGizmo::set_selection_mode_face() { /* if selection_mode == SelectionMode.SELECTION_MODE_FACE: return selection_mode = SelectionMode.SELECTION_MODE_FACE _selected_points.resize(0) recalculate_handle_points() redraw() */ } void MDIGizmo::_notification(int what) { /* if what == NOTIFICATION_PREDELETE: if self != null && get_plugin(): get_plugin().unregister_gizmo(self) */ } void MDIGizmo::recalculate_handle_points() { /* if !_mdr: _handle_points.resize(0) _handle_to_vertex_map.resize(0) return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: _handle_points.resize(0) _handle_to_vertex_map.resize(0) return var arr : Array = Array() arr.resize(ArrayMesh.ARRAY_MAX) arr[ArrayMesh.ARRAY_VERTEX] = mdr_arr[ArrayMesh.ARRAY_VERTEX] arr[ArrayMesh.ARRAY_INDEX] = mdr_arr[ArrayMesh.ARRAY_INDEX] if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: var merged_arrays : Array = MeshUtils.merge_mesh_array(arr) _handle_points = merged_arrays[ArrayMesh.ARRAY_VERTEX] _handle_to_vertex_map = MeshDecompose.get_handle_vertex_to_vertex_map(mdr_arr, _handle_points) elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: var result : Array = MeshDecompose.get_handle_edge_to_vertex_map(arr) _handle_points = result[0] _handle_to_vertex_map = result[1] elif selection_mode == SelectionMode.SELECTION_MODE_FACE: var result : Array = MeshDecompose.get_handle_face_to_vertex_map(arr) _handle_points = result[0] _handle_to_vertex_map = result[1] */ } void MDIGizmo::on_mesh_data_resource_changed(Ref mdr) { /* if _mdr: _mdr.disconnect("changed", self, "on_mdr_changed") _mdr = mdr if _mdr && _mdr.array.size() == ArrayMesh.ARRAY_MAX && _mdr.array[ArrayMesh.ARRAY_VERTEX] != null: _vertices = _mdr.array[ArrayMesh.ARRAY_VERTEX] _indices = _mdr.array[ArrayMesh.ARRAY_INDEX] else: _vertices.resize(0) _indices.resize(0) if _mdr: _mdr.connect("changed", self, "on_mdr_changed") recalculate_handle_points() redraw() */ } void MDIGizmo::on_mdr_changed() { /* if _mdr && _mdr.array.size() == ArrayMesh.ARRAY_MAX && _mdr.array[ArrayMesh.ARRAY_VERTEX] != null: _vertices = _mdr.array[ArrayMesh.ARRAY_VERTEX] _indices = _mdr.array[ArrayMesh.ARRAY_INDEX] else: _vertices.resize(0) _indices.resize(0) recalculate_handle_points() redraw() */ } void MDIGizmo::disable_change_event() { /* _mdr.disconnect("changed", self, "on_mdr_changed") */ } void MDIGizmo::enable_change_event(bool update = true) { /* _mdr.connect("changed", self, "on_mdr_changed") if update: on_mdr_changed() */ } void MDIGizmo::add_triangle() { /* if _mdr: var orig_arr = copy_arrays(_mdr.array) MDRMeshUtils.add_triangle(_mdr) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Triangle") */ } void MDIGizmo::add_quad() { /* if _mdr: var orig_arr = copy_arrays(_mdr.array) MDRMeshUtils.add_quad(_mdr) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Quad") */ } bool MDIGizmo::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) */ } Vector3 find_other_vertex_for_edge(int edge, Vector3 v0) { /* var ps : PoolIntArray = _handle_to_vertex_map[edge] var vert : Vector3 = Vector3() for i in range(ps.size()): vert = _vertices[ps[i]] if !is_verts_equal(v0, vert): return vert return v0 */ } Array MDIGizmo::MDIGizmo::split_edge_indices(int edge) { /* var ps : PoolIntArray = _handle_to_vertex_map[edge] if ps.size() == 0: return [ ] var v0 : Vector3 = _vertices[ps[0]] var v0ei : PoolIntArray = PoolIntArray() v0ei.append(ps[0]) var v1ei : PoolIntArray = PoolIntArray() for i in range(1, ps.size()): var vert : Vector3 = _vertices[ps[i]] if is_verts_equal(v0, vert): v0ei.append(ps[i]) else: v1ei.append(ps[i]) return [ v0ei, v1ei ] */ } bool MDIGizmo::pool_int_arr_contains(PoolIntArray arr, int val) { /* for a in arr: if a == val: return true return false */ } PoolIntArray MDIGizmo::find_triangles_for_edge(int edge) { /* var eisarr : Array = split_edge_indices(edge) if eisarr.size() == 0: return PoolIntArray() # these should have the same size var v0ei : PoolIntArray = eisarr[0] var v1ei : PoolIntArray = eisarr[1] var res : PoolIntArray = PoolIntArray() 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] if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2): if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2): res.append(i / 3) return res */ } int MDIGizmo::find_first_triangle_for_edge(int edge) { /* var eisarr : Array = split_edge_indices(edge) if eisarr.size() == 0: return -1 # these should have the same size var v0ei : PoolIntArray = eisarr[0] var v1ei : PoolIntArray = eisarr[1] var res : PoolIntArray = PoolIntArray() 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] if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2): if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2): return i / 3 return -1 */ } void MDIGizmo::add_triangle_to_edge(int edge) { /* var triangle_index : int = find_first_triangle_for_edge(edge) var inds : int = triangle_index * 3 var ti0 : int = _indices[inds] var ti1 : int = _indices[inds + 1] var ti2 : int = _indices[inds + 2] var ps : PoolIntArray = _handle_to_vertex_map[edge] if ps.size() == 0: return var ei0 : int = 0 var ei1 : int = 0 var erefind : int = 0 if !pool_int_arr_contains(ps, ti0): ei0 = ti1 ei1 = ti2 erefind = ti0 elif !pool_int_arr_contains(ps, ti1): ei0 = ti0 ei1 = ti2 erefind = ti1 elif !pool_int_arr_contains(ps, ti2): ei0 = ti0 ei1 = ti1 erefind = ti2 var fo : Vector3 = MDRMeshUtils.get_face_normal(_vertices[ti0], _vertices[ti1], _vertices[ti2]) var fn : Vector3 = MDRMeshUtils.get_face_normal(_vertices[ei0], _vertices[ei1], _vertices[erefind]) if fo.dot(fn) < 0: var t : int = ei0 ei0 = ei1 ei1 = t MDRMeshUtils.append_triangle_to_tri_edge(_mdr, _vertices[ei0], _vertices[ei1], _vertices[erefind]) */ } void MDIGizmo::add_quad_to_edge(int edge) { /* var triangle_index : int = find_first_triangle_for_edge(edge) var inds : int = triangle_index * 3 var ti0 : int = _indices[inds] var ti1 : int = _indices[inds + 1] var ti2 : int = _indices[inds + 2] var ps : PoolIntArray = _handle_to_vertex_map[edge] if ps.size() == 0: return var ei0 : int = 0 var ei1 : int = 0 var erefind : int = 0 if !pool_int_arr_contains(ps, ti0): ei0 = ti1 ei1 = ti2 erefind = ti0 elif !pool_int_arr_contains(ps, ti1): ei0 = ti0 ei1 = ti2 erefind = ti1 elif !pool_int_arr_contains(ps, ti2): ei0 = ti0 ei1 = ti1 erefind = ti2 var fo : Vector3 = MDRMeshUtils.get_face_normal(_vertices[ti0], _vertices[ti1], _vertices[ti2]) var fn : Vector3 = MDRMeshUtils.get_face_normal(_vertices[ei0], _vertices[ei1], _vertices[erefind]) if fo.dot(fn) < 0: var t : int = ei0 ei0 = ei1 ei1 = t MDRMeshUtils.append_quad_to_tri_edge(_mdr, _vertices[ei0], _vertices[ei1], _vertices[erefind]) */ } void MDIGizmo::add_triangle_at() { /* if !_mdr: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: #todo pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: disable_change_event() var orig_arr = copy_arrays(_mdr.array) for sp in _selected_points: add_triangle_to_edge(sp) _selected_points.resize(0) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Triangle At") enable_change_event() else: add_triangle() */ } void MDIGizmo::add_quad_at() { /* if !_mdr: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: #todo pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: disable_change_event() var orig_arr = copy_arrays(_mdr.array) for sp in _selected_points: add_quad_to_edge(sp) _selected_points.resize(0) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Quad At") enable_change_event() else: add_quad() */ } void MDIGizmo::extrude() { /* if !_mdr: return if _mdr.array.size() != ArrayMesh.ARRAY_MAX || _mdr.array[ArrayMesh.ARRAY_VERTEX] == null: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: disable_change_event() var orig_arr = copy_arrays(_mdr.array) var original_size : int = orig_arr[ArrayMesh.ARRAY_VERTEX].size() for sp in _selected_points: add_quad_to_edge(sp) var arr : Array = _mdr.array # Note: This algorithm depends heavily depends on the inner workings of add_quad_to_edge! var new_verts : PoolVector3Array = arr[ArrayMesh.ARRAY_VERTEX] # every 4 vertex is a quad # 1 ---- 2 # | | # | | # 0 ---- 3 # vertex 1, and 2 are the created new ones, 0, and 3 are duplicated from the original edge # Don't reallocate it every time var found_verts : PoolIntArray = PoolIntArray() # Go through every new created 0th vertex for i in range(original_size, new_verts.size(), 4): var v0 : Vector3 = new_verts[i] found_verts.resize(0) # Find a pair for it (has to be the 3th). for j in range(original_size, new_verts.size(), 4): if i == j: continue # +3 offset to 3rd vert var v3 : Vector3 = new_verts[j + 3] if is_verts_equal(v0, v3): # +2 offset to 2rd vert found_verts.append(j + 2) if found_verts.size() == 0: continue # Also append the first vertex index to simplify logic found_verts.append(i + 1) # Calculate avg var vavg : Vector3 = Vector3() for ind in found_verts: vavg += new_verts[ind] vavg /= found_verts.size() # set back for ind in found_verts: new_verts[ind] = vavg arr[ArrayMesh.ARRAY_VERTEX] = new_verts _mdr.array = arr _selected_points.resize(0) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Extrude") enable_change_event() # The selection alo will take care of the duplicates var new_handle_points : PoolVector3Array = PoolVector3Array() for i in range(original_size, new_verts.size(), 4): var vavg : Vector3 = new_verts[i + 1] vavg += new_verts[i + 2] vavg /= 2 new_handle_points.append(vavg) select_handle_points(new_handle_points) else: add_quad() */ } void MDIGizmo::add_box() { /* if _mdr: var orig_arr = copy_arrays(_mdr.array) MDRMeshUtils.add_box(_mdr) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Add Box") */ } void MDIGizmo::split() { } void MDIGizmo::disconnect_action() { } int MDIGizmo::get_first_triangle_index_for_vertex(int indx) { /* for i in range(_indices.size()): if _indices[i] == indx: return i / 3 return -1 */ } void MDIGizmo::create_face() { /* if !_mdr: return if _selected_points.size() <= 2: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: disable_change_event() var orig_arr = copy_arrays(_mdr.array) var points : PoolVector3Array = PoolVector3Array() for sp in _selected_points: points.push_back(_handle_points[sp]) if points.size() == 3: var i0 : int = _handle_to_vertex_map[_selected_points[0]][0] var i1 : int = _handle_to_vertex_map[_selected_points[1]][0] var i2 : int = _handle_to_vertex_map[_selected_points[2]][0] var v0 : Vector3 = points[0] var v1 : Vector3 = points[1] var v2 : Vector3 = points[2] var tfn : Vector3 = Vector3() if orig_arr[ArrayMesh.ARRAY_NORMAL] != null && orig_arr[ArrayMesh.ARRAY_NORMAL].size() == orig_arr[ArrayMesh.ARRAY_VERTEX].size(): var normals : PoolVector3Array = orig_arr[ArrayMesh.ARRAY_NORMAL] tfn += normals[i0] tfn += normals[i1] tfn += normals[i2] tfn /= 3 tfn = tfn.normalized() else: tfn = MDRMeshUtils.get_face_normal(_vertices[i0], _vertices[i1], _vertices[i2]) var flip : bool = !MDRMeshUtils.should_triangle_flip(v0, v1, v2, tfn) MDRMeshUtils.add_triangle_at(_mdr, v0, v1, v2, flip) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face") enable_change_event() return if !MDRMeshUtils.add_triangulated_mesh_from_points_delaunay(_mdr, points, _last_known_camera_facing): enable_change_event() return add_mesh_change_undo_redo(orig_arr, _mdr.array, "Create Face") #_selected_points.resize(0) enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } Array MDIGizmo::split_face_indices(int face) { /* var ps : PoolIntArray = _handle_to_vertex_map[face] if ps.size() == 0: return [ ] var v0 : Vector3 = _vertices[ps[0]] var v1 : Vector3 = Vector3() var v1found : bool = false var v0ei : PoolIntArray = PoolIntArray() v0ei.append(ps[0]) var v1ei : PoolIntArray = PoolIntArray() var v2ei : PoolIntArray = PoolIntArray() for i in range(1, ps.size()): var vert : Vector3 = _vertices[ps[i]] if is_verts_equal(v0, vert): v0ei.append(ps[i]) else: if v1found: if is_verts_equal(v1, vert): v1ei.append(ps[i]) else: v2ei.append(ps[i]) else: v1found = true v1 = _vertices[ps[i]] v1ei.append(ps[i]) return [ v0ei, v1ei, v2ei ] */ } int MDIGizmo::find_first_triangle_index_for_face(int face) { /* var split_indices_arr : Array = split_face_indices(face) if split_indices_arr.size() == 0: return -1 var v0ei : PoolIntArray = split_indices_arr[0] var v1ei : PoolIntArray = split_indices_arr[1] var v2ei : PoolIntArray = split_indices_arr[2] var tri_index : int = -1 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] if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2): if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2): if pool_int_arr_contains(v2ei, i0) || pool_int_arr_contains(v2ei, i1) || pool_int_arr_contains(v2ei, i2): return i / 3 return -1 */ } void MDIGizmo::delete_selected() { /* if !_mdr: return if _selected_points.size() == 0: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: #todo pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: #todo pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: disable_change_event() var orig_arr = copy_arrays(_mdr.array) var triangle_indexes : Array = Array() for sp in _selected_points: var triangle_index : int = find_first_triangle_index_for_face(sp) triangle_indexes.append(triangle_index) #delete in reverse triangle index order triangle_indexes.sort() for i in range(triangle_indexes.size() - 1, -1, -1): var triangle_index : int = triangle_indexes[i] MDRMeshUtils.remove_triangle(_mdr, triangle_index) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Delete") _selected_points.resize(0) enable_change_event() */ } void MDIGizmo::generate_normals() { /* if !_mdr: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var orig_seams = copy_pool_int_array(_mdr.seams) var seam_points : PoolVector3Array = MDRMeshUtils.seams_to_points(_mdr) MDRMeshUtils.generate_normals_mdr(_mdr) MDRMeshUtils.points_to_seams(_mdr, seam_points) add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Generate Normals") enable_change_event() */ } void MDIGizmo::generate_tangents() { /* if !_mdr: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var orig_seams = copy_pool_int_array(_mdr.seams) var seam_points : PoolVector3Array = MDRMeshUtils.seams_to_points(_mdr) MDRMeshUtils.generate_tangents(_mdr) MDRMeshUtils.points_to_seams(_mdr, seam_points) add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Generate Tangents") enable_change_event() */ } void MDIGizmo::remove_doubles() { /* if !_mdr: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var orig_seams = copy_pool_int_array(_mdr.seams) var seam_points : PoolVector3Array = MDRMeshUtils.seams_to_points(_mdr) var merged_arrays : Array = MeshUtils.remove_doubles(mdr_arr) _mdr.array = merged_arrays MDRMeshUtils.points_to_seams(_mdr, seam_points) add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Remove Doubles") enable_change_event() */ } void MDIGizmo::merge_optimize() { /* if !_mdr: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var orig_seams = copy_pool_int_array(_mdr.seams) var seam_points : PoolVector3Array = MDRMeshUtils.seams_to_points(_mdr) var merged_arrays : Array = MeshUtils.merge_mesh_array(mdr_arr) _mdr.array = merged_arrays MDRMeshUtils.points_to_seams(_mdr, seam_points) add_mesh_seam_change_undo_redo(orig_arr, orig_seams, _mdr.array, _mdr.seams, "Merge Optimize") enable_change_event() */ } void MDIGizmo::connect_to_first_selected() { /* if !_mdr: return if _selected_points.size() < 2: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var vertices : PoolVector3Array = mdr_arr[ArrayMesh.ARRAY_VERTEX] if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: var mpos : Vector3 = _handle_points[_selected_points[0]] for i in range(1, _selected_points.size()): var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]] for indx in ps: vertices[indx] = mpos _selected_points.resize(0) mdr_arr[ArrayMesh.ARRAY_VERTEX] = vertices _mdr.array = mdr_arr add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to first selected") enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } void MDIGizmo::connect_to_avg() { /* if !_mdr: return if _selected_points.size() < 2: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var orig_arr = copy_arrays(_mdr.array) var vertices : PoolVector3Array = mdr_arr[ArrayMesh.ARRAY_VERTEX] if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: var mpos : Vector3 = Vector3() for sp in _selected_points: mpos += _handle_points[sp] mpos /= _selected_points.size() for i in range(_selected_points.size()): var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]] for indx in ps: vertices[indx] = mpos _selected_points.resize(0) mdr_arr[ArrayMesh.ARRAY_VERTEX] = vertices _mdr.array = mdr_arr add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to average") enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } void MDIGizmo::connect_to_last_selected() { /* if !_mdr: return if _selected_points.size() < 2: return var orig_arr = copy_arrays(_mdr.array) var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var vertices : PoolVector3Array = mdr_arr[ArrayMesh.ARRAY_VERTEX] if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: var mpos : Vector3 = _handle_points[_selected_points[_selected_points.size() - 1]] for i in range(0, _selected_points.size() - 1): var ps : PoolIntArray = _handle_to_vertex_map[_selected_points[i]] for indx in ps: vertices[indx] = mpos _selected_points.resize(0) mdr_arr[ArrayMesh.ARRAY_VERTEX] = vertices _mdr.array = mdr_arr add_mesh_change_undo_redo(orig_arr, _mdr.array, "Connect to last selected") enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } PoolIntArray MDIGizmo::get_first_index_pair_for_edge(int edge) { /* var ret : PoolIntArray = PoolIntArray() var eisarr : Array = split_edge_indices(edge) if eisarr.size() == 0: return ret # these should have the same size var v0ei : PoolIntArray = eisarr[0] var v1ei : PoolIntArray = eisarr[1] var res : PoolIntArray = PoolIntArray() 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] if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2): if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2): if pool_int_arr_contains(v0ei, i0): ret.push_back(i0) elif pool_int_arr_contains(v0ei, i1): ret.push_back(i1) elif pool_int_arr_contains(v0ei, i2): ret.push_back(i2) if pool_int_arr_contains(v1ei, i0): ret.push_back(i0) elif pool_int_arr_contains(v1ei, i1): ret.push_back(i1) elif pool_int_arr_contains(v1ei, i2): ret.push_back(i2) return ret return ret */ } PoolIntArray MDIGizmo::get_all_index_pairs_for_edge(int edge) { /* var ret : PoolIntArray = PoolIntArray() var eisarr : Array = split_edge_indices(edge) if eisarr.size() == 0: return ret # these should have the same size var v0ei : PoolIntArray = eisarr[0] var v1ei : PoolIntArray = eisarr[1] var res : PoolIntArray = PoolIntArray() 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] if pool_int_arr_contains(v0ei, i0) || pool_int_arr_contains(v0ei, i1) || pool_int_arr_contains(v0ei, i2): if pool_int_arr_contains(v1ei, i0) || pool_int_arr_contains(v1ei, i1) || pool_int_arr_contains(v1ei, i2): if pool_int_arr_contains(v0ei, i0): ret.push_back(i0) elif pool_int_arr_contains(v0ei, i1): ret.push_back(i1) elif pool_int_arr_contains(v0ei, i2): ret.push_back(i2) if pool_int_arr_contains(v1ei, i0): ret.push_back(i0) elif pool_int_arr_contains(v1ei, i1): ret.push_back(i1) elif pool_int_arr_contains(v1ei, i2): ret.push_back(i2) return ret */ } void MDIGizmo::mark_seam() { /* if !_mdr: return if _selected_points.size() == 0: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: disable_change_event() var prev_seams : PoolIntArray = copy_pool_int_array(_mdr.seams) for se in _selected_points: var eis : PoolIntArray = MDRMeshUtils.order_seam_indices(get_first_index_pair_for_edge(se)) if eis.size() == 0: continue MDRMeshUtils.add_seam(_mdr, eis[0], eis[1]) _undo_redo.create_action("mark_seam") _undo_redo.add_do_method(self, "set_seam", _mdr, copy_pool_int_array(_mdr.seams)) _undo_redo.add_undo_method(self, "set_seam", _mdr, prev_seams) _undo_redo.commit_action() enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } void MDIGizmo::unmark_seam() { /* if !_mdr: return if _selected_points.size() == 0: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: disable_change_event() var prev_seams : PoolIntArray = copy_pool_int_array(_mdr.seams) for se in _selected_points: var eis : PoolIntArray = MDRMeshUtils.order_seam_indices(get_all_index_pairs_for_edge(se)) if eis.size() == 0: continue MDRMeshUtils.remove_seam(_mdr, eis[0], eis[1]) _undo_redo.create_action("unmark_seam") _undo_redo.add_do_method(self, "set_seam", _mdr, copy_pool_int_array(_mdr.seams)) _undo_redo.add_undo_method(self, "set_seam", _mdr, prev_seams) _undo_redo.commit_action() enable_change_event() elif selection_mode == SelectionMode.SELECTION_MODE_FACE: pass */ } void MDIGizmo::set_seam(Ref mdr, PoolIntArray arr) { /* mdr.seams = arr */ } void MDIGizmo::apply_seam() { /* if !_mdr: return disable_change_event() var orig_arr : Array = copy_arrays(_mdr.array) MDRMeshUtils.apply_seam(_mdr) add_mesh_change_undo_redo(orig_arr, _mdr.array, "apply_seam") enable_change_event() */ } void MDIGizmo::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.") */ } void MDIGizmo::uv_unwrap() { /* if !_mdr: return var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return disable_change_event() var uvs : PoolVector2Array = MeshUtils.uv_unwrap(mdr_arr) if uvs.size() != mdr_arr[ArrayMesh.ARRAY_VERTEX].size(): print("Error: Could not unwrap mesh!") enable_change_event(false) return var orig_arr : Array = copy_arrays(mdr_arr) mdr_arr[ArrayMesh.ARRAY_TEX_UV] = uvs add_mesh_change_undo_redo(orig_arr, mdr_arr, "uv_unwrap") enable_change_event() */ } void MDIGizmo::flip_selected_faces() { /* if !_mdr: return if _selected_points.size() == 0: return if selection_mode == SelectionMode.SELECTION_MODE_VERTEX: pass elif selection_mode == SelectionMode.SELECTION_MODE_EDGE: pass elif selection_mode == SelectionMode.SELECTION_MODE_FACE: disable_change_event() var orig_arr = copy_arrays(_mdr.array) for sp in _selected_points: var triangle_index : int = find_first_triangle_index_for_face(sp) MDRMeshUtils.flip_triangle_ti(_mdr, triangle_index) add_mesh_change_undo_redo(orig_arr, _mdr.array, "Flip Faces") enable_change_event() */ } void MDIGizmo::add_mesh_change_undo_redo(Array orig_arr, Array new_arr, String action_name) { /* _undo_redo.create_action(action_name) var nac : Array = copy_arrays(new_arr) _undo_redo.add_do_method(self, "apply_mesh_change", _mdr, nac) _undo_redo.add_undo_method(self, "apply_mesh_change", _mdr, orig_arr) _undo_redo.commit_action() */ } void MDIGizmo::add_mesh_seam_change_undo_redo(Array orig_arr, PoolIntArray orig_seams, Array new_arr, PoolIntArray new_seams, String action_name) { /* _undo_redo.create_action(action_name) var nac : Array = copy_arrays(new_arr) _undo_redo.add_do_method(self, "apply_mesh_change", _mdr, nac) _undo_redo.add_undo_method(self, "apply_mesh_change", _mdr, orig_arr) _undo_redo.add_do_method(self, "set_seam", _mdr, copy_pool_int_array(new_seams)) _undo_redo.add_undo_method(self, "set_seam", _mdr, orig_seams) _undo_redo.commit_action() */ } void MDIGizmo::apply_mesh_change(Ref mdr, Array arr) { /* if !mdr: return mdr.array = copy_arrays(arr) */ } void MDIGizmo::apply_vertex_array(Ref mdr, PoolVector3Array verts) { /* if !mdr: return var mdr_arr : Array = mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX: return mdr_arr[ArrayMesh.ARRAY_VERTEX] = verts mdr.array = mdr_arr */ } Array MDIGizmo::copy_arrays(Array arr) { /* return arr.duplicate(true) */ } PoolIntArray MDIGizmo::copy_pool_int_array(PoolIntArray pia) { /* var ret : PoolIntArray = PoolIntArray() ret.resize(pia.size()) for i in range(pia.size()): ret[i] = pia[i] return ret */ } PoolVector3Array MDIGizmo::copy_mdr_verts_array() { /* var ret : PoolVector3Array = PoolVector3Array() if !_mdr: return ret var mdr_arr : Array = _mdr.array if mdr_arr.size() != ArrayMesh.ARRAY_MAX || mdr_arr[ArrayMesh.ARRAY_VERTEX] == null || mdr_arr[ArrayMesh.ARRAY_VERTEX].size() == 0: return ret var vertices : PoolVector3Array = mdr_arr[ArrayMesh.ARRAY_VERTEX] ret.append_array(vertices) return ret */ } void MDIGizmo::setup_op_drag_indices() { /* _drag_op_indices.resize(0) for sp in _selected_points: var pi : PoolIntArray = _handle_to_vertex_map[sp] for indx in pi: if !pool_int_arr_contains(_drag_op_indices, indx): _drag_op_indices.append(indx) */ } Vector3 MDIGizmo::get_drag_op_pivot() { /* if pivot_type == PivotTypes.PIVOT_TYPE_AVERAGED: var avg : Vector3 = Vector3() for indx in _drag_op_indices: avg += _vertices[indx] avg /= _drag_op_indices.size() return avg elif pivot_type == PivotTypes.PIVOT_TYPE_MDI_ORIGIN: return Vector3() elif pivot_type == PivotTypes.PIVOT_TYPE_WORLD_ORIGIN: return get_spatial_node().to_local(Vector3()) return Vector3() */ } void MDIGizmo::select_handle_points(PoolVector3Array points) { /* _selected_points.resize(0) for p in points: for i in range(_handle_points.size()): if is_verts_equal(p, _handle_points[i]): if !pool_int_arr_contains(_selected_points, i): _selected_points.push_back(i) redraw() */ } void MDIGizmo::set_pivot_averaged() { /* pivot_type = PivotTypes.PIVOT_TYPE_AVERAGED */ } void MDIGizmo::set_pivot_mdi_origin() { /* pivot_type = PivotTypes.PIVOT_TYPE_MDI_ORIGIN */ } void MDIGizmo::set_pivot_world_origin() { /* pivot_type = PivotTypes.PIVOT_TYPE_WORLD_ORIGIN */ } void MDIGizmo::transfer_state_from(EditorSpatialGizmo *other) { /* edit_mode = other.edit_mode pivot_type = other.pivot_type axis_constraint = other.axis_constraint selection_mode = other.selection_mode handle_selection_type = other.handle_selection_type visual_indicator_outline = other.visual_indicator_outline visual_indicator_seam = other.visual_indicator_seam visual_indicator_handle = other.visual_indicator_handle */ } void MDIGizmo::visual_indicator_outline_set(bool on) { /* visual_indicator_outline = on redraw() */ } void MDIGizmo::visual_indicator_seam_set(bool on) { /* visual_indicator_seam = on redraw() */ } void MDIGizmo::visual_indicator_handle_set(bool on) { /* visual_indicator_handle = on redraw() */ } void MDIGizmo::handle_selection_type_front() { /* handle_selection_type = HandleSelectionType.HANDLE_SELECTION_TYPE_FRONT */ } void MDIGizmo::handle_selection_type_back() { /* handle_selection_type = HandleSelectionType.HANDLE_SELECTION_TYPE_BACK */ } void MDIGizmo::handle_selection_type_all() { /* handle_selection_type = HandleSelectionType.HANDLE_SELECTION_TYPE_ALL */ } MDIGizmo::MDIGizmo() { gizmo_size = 3.0; edit_mode = EDIT_MODE_TRANSLATE; pivot_type = PIVOT_TYPE_AVERAGED; axis_constraint = AXIS_CONSTRAINT_X | AXIS_CONSTRAINT_Y | AXIS_CONSTRAINT_Z; selection_mode = SELECTION_MODE_VERTEX; handle_selection_type = HANDLE_SELECTION_TYPE_FRONT; visual_indicator_outline = true; visual_indicator_seam = true; visual_indicator_handle = true; _last_known_camera_facing = Vector3(0, 0, -1); _rect_drag = false; _rect_drag_min_ofset = 10; _mesh_outline_generator.instance(); _handle_drag_op = false; _editor_plugin = nullptr; _undo_redo = nullptr; } MDIGizmo::~MDIGizmo() { } void MDIGizmo::_bind_methods() { }