local wea = worldeditadditions -- ███████ █████ ██████ ███████ -- ██ ██ ██ ██ ██ -- █████ ███████ ██ █████ -- ██ ██ ██ ██ ██ -- ██ ██ ██ ██████ ███████ --- A single face of a Mesh. -- @class local Face = {} Face.__index = Face --- Creates a new face from a list of vertices. -- The list of vertices should be anti-clockwise. -- @param vertices Vector3[] A list of Vector3 vertices that define the face. function Face.new(vertices) local result = { vertices = vertices } setmetatable(result, Face) return result end --- Determines whether this face is equal to another face or not. -- @param a Face The first face to compare. -- @param b Face The second face to compare. -- @returns bool Whether the 2 faces are equal or not. function Face.equal(a, b) if #a.vertices ~= #b.vertices then return false end for i,vertex in ipairs(a) do if vertex ~= b.vertices[i] then return false end end return true end function Face.__eq(a, b) return Face.equal(a, b) end -- ███ ███ ███████ ███████ ██ ██ -- ████ ████ ██ ██ ██ ██ -- ██ ████ ██ █████ ███████ ███████ -- ██ ██ ██ ██ ██ ██ ██ -- ██ ██ ███████ ███████ ██ ██ --- A mesh of faces. -- @class local Mesh = {} Mesh.__index = Mesh --- Creates a new empty mesh object container. -- @returns Mesh function Mesh.new() local result = { faces = {} } setmetatable(result, Mesh) end --- Adds a face to this mesh. -- @param self Mesh The mesh instance to operate on. -- @param face Face The face to add. -- @returns void function Mesh.add_face(self, face) table.insert(self.faces, face) end --- Deduplicate the list of faces in this Mesh. -- Removes all faces that are exactly equal to one another. This reduces the -- filesize. -- @returns number The number of faces removed. function Mesh.dedupe(self) -- Find the faces to remove local toremove = {} for i,face_check in ipairs(self.faces) do for j,face_next in ipairs(self.faces) do if i ~= j -- If we're not comparing a face to itself... and face_check == face_next -- ....and the 2 faces are equal.... and not wea.table.contains(toremove, j) then -- ...and we haven't already marked it for removal... -- Mark it for removal table.insert(toremove, j) end end end -- Sort the list of indexes marked for removal from largest to smallest -- This way, removing smaller items doesn't alter the index of larger ones table.sort(toremove, function(a, b) return a > b end) -- Remove the faces marked for removal for i, remove_index in ipairs(toremove) do table.remove(self.faces, remove_index) end return #toremove end return Mesh, Face