diff --git a/utils/files/file_data.py b/utils/files/file_data.py index fcc640a7321a6c21f94c3e9d3da939fe6a008339..087effa45607527f3d4ddaf9e3d16603e80c75f7 100644 --- a/utils/files/file_data.py +++ b/utils/files/file_data.py @@ -1,18 +1,34 @@ """ This module contains the File class. """ +import numpy as np class FaceNotGiven(Exception): """ Exception raised when no faces was given. """ +def parse_result_file(file_path): + lines = [] + x,y,z = [],[],[] + with open(file_path, "r") as f: + lines = f.readlines()[1:] + for line in lines: + line = line.replace(",", ".") + values = line.split("\t") + x.append(float(values[0])) + y.append(float(values[1])) + z.append(float(values[2])) + return x,y,z + class Object: """ This class is used to manage the data of the 3D object. """ - def __init__(self, vertices, faces=None): + def __init__(self, vertices, faces=None, result_file_path=None): self.vertices = vertices self.faces = faces + self.result_file_path = result_file_path + self.bruteforce_discretization_result = None self.x = [vertex[0] for vertex in vertices] self.y = [vertex[1] for vertex in vertices] self.z = [vertex[2] for vertex in vertices] @@ -44,10 +60,11 @@ class Object: :param sort: Sort the vertices by z coordinate :return: vertices """ + vertices = self.vertices if not sort else sorted(self.vertices, key=lambda vertex: vertex[2]) return vertices - def get_discrete_vertices(self, step:float = 0.1): + def get_discrete_vertices(self, step:float = 1): """ Discretize the vertices of the object. :param step: Step of the discretization @@ -57,7 +74,7 @@ class Object: splitted_data = [[]] for line in self.get_vertices(sort=True): # TODO check distance instead of equality - if line[2] >= current_interval: + if line[2] >= current_interval + step: splitted_data.append([]) current_interval += step splitted_data[-1].append(line) @@ -65,6 +82,20 @@ class Object: splitted_data = splitted_data[1:] return splitted_data + def get_discrete_vertices2(self, step:float = 1): + """ + fait un tour de boucle en plus + """ + cpt = 0 + L = [[]] + for vertex in self.get_vertices(sort=True): + step = 1 + L[-1].append(vertex) + if vertex[2] > cpt + step: + cpt += step + L.append([]) + return L + def get_faces(self)->list: """ Get the faces of the object. @@ -80,3 +111,56 @@ class Object: :return: Data of the object """ return {'verticies': self.vertices, 'faces': self.faces, 'x': self.x, 'y': self.y, 'z': self.z} + + def bruteforce_discretization(self): + """ + Discretize the object. + :param step: Step of the discretization + :return: Discretized object + """ + if self.bruteforce_discretization_result: + return self.bruteforce_discretization_result + if self.result_file_path is None: + raise Exception("No result file was given") + L = [] + splitted_data = [[]] + moyx, moyy, moyz = parse_result_file(self.result_file_path) + moy = moyx + verticies = self.get_vertices(sort=True) + position = 0 + while position < len(verticies): + print(position/len(verticies)*100,end="\r") + x = verticies[position][0] + y = verticies[position][1] + z = verticies[position][2] + L.append(x) + splitted_data[-1].append(verticies[position]) + m = np.mean(L) + if len(moy) > 0 and abs(m - moy[0]) < 0.000001: + moy.pop(0) + L = [] + splitted_data.append([]) + copyposition = position + while int(verticies[copyposition][2]) == int(verticies[copyposition-1][2]): + copyposition -= 1 + position += 1 + print(50*" ") + self.bruteforce_discretization_result = splitted_data + return splitted_data + + def export(self, file_path:str): + """ + Export the object in a file. + :param file_path: Path of the file + """ + with open(file_path, "w") as f: + cpt = 0 + for vertex in self.get_vertices(sort=True): + x = round(vertex[0], 6) + y = round(vertex[1], 6) + z = round(vertex[2], 6) + #f.write(f"{x}\t{y}\t{z}\n") + f.write(f"{cpt}\n") + f.write(f"{x}\n{y}\n{z}\n") + f.write(f"{15*'-'}\n") + \ No newline at end of file diff --git a/utils/files/parsers.py b/utils/files/parsers.py index d5e3f061b6fdc3048f8b8fff651f827e31175ba3..8633ebb1b69ef3306554272f1489ab514594deb7 100644 --- a/utils/files/parsers.py +++ b/utils/files/parsers.py @@ -3,7 +3,7 @@ This module contains functions to parse files. """ from utils.files.file_data import Object -def parse_obj_file(file_path:str,ratio:float = 1,normalised:str = '')->Object: +def parse_obj_file(file_path:str, result_file_path:str = None, ratio:float = 1,normalised:str = '')->Object: """ Parse an OBJ file and return a dict with the vertices and faces @@ -40,9 +40,9 @@ def parse_obj_file(file_path:str,ratio:float = 1,normalised:str = '')->Object: for count, value in enumerate(z): z[count] -= zmin - return Object(list(zip(x,y,z)), triangles) + return Object(list(zip(x,y,z)), triangles, result_file_path) -def parse_xyz_file(file_path: str, delimiter: str = ' ') -> dict: +def parse_xyz_file(file_path: str, result_file_path:str = None, delimiter: str = ' ',normalised:str = '') -> Object: """ Parses an xyz file and returns a dict containing the coordinates. @@ -53,7 +53,23 @@ def parse_xyz_file(file_path: str, delimiter: str = ' ') -> dict: x , y , z = [], [], [] with open(file_path, 'r') as f: data = f.readlines() - x = [float(line.split(delimiter)[0]) for line in data] - y = [float(line.split(delimiter)[1]) for line in data] - z = [float(line.split(delimiter)[2]) for line in data] - return Object(zip(x,y,z)) \ No newline at end of file + for line in data: + x.append(float(line.split(delimiter)[0])) + y.append(float(line.split(delimiter)[1])) + z.append(float(line.split(delimiter)[2])) + + if 'x' in normalised: + xmin = min(x) + for count, value in enumerate(x): + x[count] -= xmin + + if 'y' in normalised: + ymin = min(y) + for count, value in enumerate(y): + y[count] -= ymin + + if 'z' in normalised: + zmin = min(z) + for count, value in enumerate(z): + z[count] -= zmin + return Object(list(zip(x,y,z)), result_file_path=result_file_path) \ No newline at end of file