General code cleanup
This commit is contained in:
parent
f55cdae99a
commit
39d68a8037
@ -1,68 +1,114 @@
|
||||
"""
|
||||
This module gives functions to assist tests
|
||||
"""
|
||||
import os
|
||||
import time
|
||||
import numpy as np
|
||||
from main import get_discrete_data, get_raw_data
|
||||
from utils.files import output
|
||||
from utils.files.input import ScannedObject
|
||||
|
||||
def check_discrete_data(expected_file, actual_file, ndigits=7,eps=0.00001) :
|
||||
def check_discrete_data(expected_file: str, actual_file: str, ndigits=7, eps=0.00001, silent: bool = False) -> dict:
|
||||
"""
|
||||
Compares the output of the main process with the reference output for the same file,
|
||||
|
||||
This function assume the passed paramters are the discretised one and not the raw,
|
||||
this function will not test that for the user>
|
||||
|
||||
:param expected_file: The reference file, the one we assume is correct
|
||||
:param actual_file: The output of the main process
|
||||
:param ndigits: The number of values to keep after the dot
|
||||
:param eps: the degree of precision we consider two values different
|
||||
:return: dict containing the average difference for each variable
|
||||
"""
|
||||
output_file = "check_discrete_data_full.txt"
|
||||
minimal_output_file = "check_discrete_data_minimal.txt"
|
||||
minimal_output_data = ""
|
||||
output_data = ""
|
||||
expected = []
|
||||
x,y,z,r,std = 0,0,0,0,0
|
||||
list_x_diffs, list_y_diffs, list_z_diffs, list_r_diffs, list_std_diffs = [], [], [], [], []
|
||||
|
||||
with open(expected_file, "r") as f:
|
||||
expected = f.readlines()[1:]
|
||||
expected = [line.replace(',','.').split('\t') for line in expected]
|
||||
expected = [line.replace(',', '.').split('\t') for line in expected]
|
||||
expected = [[float(x) for x in line] for line in expected]
|
||||
actual = []
|
||||
with open(actual_file, "r") as f:
|
||||
actual = f.readlines()[1:]
|
||||
actual = [line.split('\t') for line in actual]
|
||||
actual = [[float(x) for x in line if x != '\n'] for line in actual]
|
||||
for i in range(min(len(expected), len(actual))):
|
||||
x_diff = round(abs(expected[i][0] - actual[i][0]),ndigits)
|
||||
y_diff = round(abs(expected[i][1] - actual[i][1]),ndigits)
|
||||
z_diff = round(abs(expected[i][2] - actual[i][2]),ndigits)
|
||||
r_diff = round(abs(expected[i][3] - actual[i][3]),ndigits)
|
||||
std_diff = round(abs(expected[i][4] - actual[i][4]),ndigits)
|
||||
for point in range(min(len(expected), len(actual))):
|
||||
# Calculate the difference for each variable
|
||||
x_diff, y_diff, z_diff, r_diff, std_diff = round(abs(expected[point][0] - actual[point][0]), ndigits), round(abs(expected[point][1] - actual[point][1]), ndigits), round(
|
||||
abs(expected[point][2] - actual[point][2]), ndigits), round(abs(expected[point][3] - actual[point][3]), ndigits), round(abs(expected[point][4] - actual[point][4]), ndigits)
|
||||
|
||||
x += x_diff
|
||||
y += y_diff
|
||||
z += z_diff
|
||||
r += r_diff
|
||||
std += std_diff
|
||||
# Add the difference to their respective list
|
||||
list_x_diffs.append(x_diff)
|
||||
list_y_diffs.append(y_diff)
|
||||
list_z_diffs.append(z_diff)
|
||||
list_r_diffs.append(r_diff)
|
||||
list_std_diffs.append(std_diff)
|
||||
|
||||
line = f"{str(i).rjust(4)}:\t X: {str(x_diff).rjust(8)}\t Y: {str(y_diff).rjust(8)}\t Z: {str(z_diff).rjust(8)}\t R: {str(r_diff).rjust(8)}\t STD: {str(std_diff).rjust(8)}"
|
||||
# Format the line
|
||||
line = f"{str(point).rjust(4)}:\t X: {str(x_diff).rjust(8)}\t Y: {str(y_diff).rjust(8)}\t Z: {str(z_diff).rjust(8)}\t R: {str(r_diff).rjust(8)}\t STD: {str(std_diff).rjust(8)}"
|
||||
output_data += line + "\n"
|
||||
|
||||
# If one of the values is greater than epsilon, add the line to the minimal output file
|
||||
if x_diff > eps or y_diff > eps or z_diff > eps or r_diff > eps or std_diff > eps:
|
||||
minimal_output_data += line + "\n"
|
||||
|
||||
# Save output to file
|
||||
output.save_output_file(output_file, output_data)
|
||||
output.save_output_file(minimal_output_file, minimal_output_data)
|
||||
|
||||
x = round(x/len(expected),ndigits)
|
||||
y = round(y/len(expected),ndigits)
|
||||
z = round(z/len(expected),ndigits)
|
||||
r = round(r/len(expected),ndigits)
|
||||
std = round(std/len(expected),ndigits)
|
||||
print()
|
||||
print("Analyse données discretisées:")
|
||||
print(f"difference moyenne X: {x}")
|
||||
print(f"difference moyenne Y: {y}")
|
||||
print(f"difference moyenne Z: {z}")
|
||||
print(f"difference moyenne R: {r}")
|
||||
print(f"difference moyenne STD: {std}")
|
||||
print(f"diff globale des fichiers: {(x+y+z+r+std)/5}")
|
||||
print(f"Voir {output_file} pour plus de détails")
|
||||
print(f"Voir {minimal_output_file} pour les différences significatives")
|
||||
print("_"*80)
|
||||
# Print the results
|
||||
if not silent:
|
||||
x = round(sum(list_x_diffs)/len(expected), ndigits)
|
||||
y = round(sum(list_y_diffs)/len(expected), ndigits)
|
||||
z = round(sum(list_z_diffs)/len(expected), ndigits)
|
||||
r = round(sum(list_r_diffs)/len(expected), ndigits)
|
||||
std = round(sum(list_std_diffs)/len(expected), ndigits)
|
||||
print()
|
||||
print("Analyse données discretisées:")
|
||||
print(f"difference moyenne X: {x}")
|
||||
print(f"difference moyenne Y: {y}")
|
||||
print(f"difference moyenne Z: {z}")
|
||||
print(f"difference moyenne R: {r}")
|
||||
print(f"difference moyenne STD: {std}")
|
||||
print(f"diff globale des fichiers: {(x+y+z+r+std)/5}")
|
||||
print(f"Voir {output_file} pour plus de détails")
|
||||
print(f"Voir {minimal_output_file} pour les différences significatives")
|
||||
print("_"*80)
|
||||
return {
|
||||
"x": x,
|
||||
"y": y,
|
||||
"z": z,
|
||||
"r": r,
|
||||
"std": std}
|
||||
|
||||
def check_raw_data(expected_file, actual_file, ndigits=7,eps=0.00001) :
|
||||
def check_raw_data(expected_file, actual_file, ndigits=7, eps=0.00001, silent: bool = False) -> dict:
|
||||
"""
|
||||
Compares the output of the main process with the reference output for the same file,
|
||||
|
||||
This function assume the passed paramters are the raw one and not the discretised,
|
||||
this function will not test that for the user.
|
||||
|
||||
:param expected_file: The reference file, the one we assume is correct
|
||||
:param actual_file: The output of the main process
|
||||
:param ndigits: The number of values to keep after the dot
|
||||
:param eps: the degree of precision we consider two values different
|
||||
:return: dict containing the average difference for each variable
|
||||
"""
|
||||
output_file = "check_raw_data_full.txt"
|
||||
minimal_output_file = "check_raw_data_minimal.txt"
|
||||
minimal_output_data = ""
|
||||
output_data = ""
|
||||
expected = []
|
||||
x,y,z,t,r,xmoy,ymoy = 0,0,0,0,0,0,0
|
||||
list_x_diffs, list_y_diffs, list_z_diffs, list_teta_diffs, list_radius_diffs, list_xmoy_diffs, list_ymoy_diffs = [], [], [], [], [], [], []
|
||||
|
||||
with open(expected_file, "r") as f:
|
||||
expected = f.readlines()[1:]
|
||||
expected = [line.replace(',','.').split('\t') for line in expected]
|
||||
expected = [line.replace(',', '.').split('\t') for line in expected]
|
||||
expected = [[float(x) for x in line] for line in expected]
|
||||
actual = []
|
||||
with open(actual_file, "r") as f:
|
||||
@ -70,24 +116,24 @@ def check_raw_data(expected_file, actual_file, ndigits=7,eps=0.00001) :
|
||||
actual = [line.split('\t') for line in actual]
|
||||
actual = [[float(x) for x in line if x != '\n'] for line in actual]
|
||||
for i in range(min(len(expected), len(actual))):
|
||||
x_diff = round(abs(expected[i][0] - actual[i][0]),ndigits)
|
||||
y_diff = round(abs(expected[i][1] - actual[i][1]),ndigits)
|
||||
z_diff = round(abs(expected[i][2] - actual[i][2]),ndigits)
|
||||
t_diff = round(abs(expected[i][3] - actual[i][3]),ndigits)
|
||||
r_diff = round(abs(expected[i][4] - actual[i][4]),ndigits)
|
||||
xmoy_diff = round(abs(expected[i][5] - actual[i][5]),ndigits)
|
||||
ymoy_diff = round(abs(expected[i][6] - actual[i][6]),ndigits)
|
||||
# Calculate the absolute difference between expected and actual
|
||||
x_diff, y_diff, z_diff, t_diff, r_diff, xmoy_diff, ymoy_diff = round(abs(expected[i][0] - actual[i][0]), ndigits), round(abs(expected[i][1] - actual[i][1]), ndigits), round(abs(expected[i][2] - actual[i][2]), ndigits), round(
|
||||
abs(expected[i][3] - actual[i][3]), ndigits), round(abs(expected[i][4] - actual[i][4]), ndigits), round(abs(expected[i][5] - actual[i][5]), ndigits), round(abs(expected[i][6] - actual[i][6]), ndigits)
|
||||
|
||||
x += x_diff
|
||||
y += y_diff
|
||||
z += z_diff
|
||||
t += t_diff
|
||||
r += r_diff
|
||||
xmoy += xmoy_diff
|
||||
ymoy += ymoy_diff
|
||||
# Add each difference to its respctive list
|
||||
list_x_diffs.append(x_diff)
|
||||
list_y_diffs.append(y_diff)
|
||||
list_z_diffs.append(z_diff)
|
||||
list_teta_diffs.append(t_diff)
|
||||
list_radius_diffs.append(r_diff)
|
||||
list_xmoy_diffs.append(xmoy_diff)
|
||||
list_ymoy_diffs.append(ymoy_diff)
|
||||
|
||||
# Format the line
|
||||
line = f"{str(i).rjust(4)}:\t X: {str(x_diff).rjust(8)}\t Y: {str(y_diff).rjust(8)}\t Z: {str(z_diff).rjust(8)}\t T: {str(t_diff).rjust(8)}\t R: {str(r_diff).rjust(8)}\t Xmoy: {str(xmoy_diff).rjust(8)}\t Ymoy: {str(ymoy_diff).rjust(8)}"
|
||||
output_data += line + "\n"
|
||||
|
||||
# If the diff is greater than epsilon, add it to the minimal output file
|
||||
if x_diff > eps:
|
||||
minimal_output_data += f"{i} : X diff {x_diff}\n"
|
||||
if y_diff > eps:
|
||||
@ -102,26 +148,116 @@ def check_raw_data(expected_file, actual_file, ndigits=7,eps=0.00001) :
|
||||
minimal_output_data += f"{i} : Xi-Xmoy diff {xmoy_diff}\n"
|
||||
if ymoy_diff > eps:
|
||||
minimal_output_data += f"{i} : Yi-Ymoy diff{ymoy_diff}\n"
|
||||
|
||||
# Save output to file
|
||||
output.save_output_file(output_file, output_data)
|
||||
output.save_output_file(minimal_output_file, minimal_output_data)
|
||||
x = round(x/len(expected),ndigits)
|
||||
y = round(y/len(expected),ndigits)
|
||||
z = round(z/len(expected),ndigits)
|
||||
t = round(t/len(expected),ndigits)
|
||||
r = round(r/len(expected),ndigits)
|
||||
xmoy = round(xmoy/len(expected),ndigits)
|
||||
ymoy = round(ymoy/len(expected),ndigits)
|
||||
|
||||
|
||||
# Print the output
|
||||
if not silent:
|
||||
sum_x_diff = round(sum(list_x_diffs)/len(expected), ndigits)
|
||||
sum_y_diff = round(sum(list_y_diffs)/len(expected), ndigits)
|
||||
sum_z_diff = round(sum(list_z_diffs)/len(expected), ndigits)
|
||||
sum_teta_diff = round(sum(list_teta_diffs)/len(expected), ndigits)
|
||||
sum_radius_diff = round(sum(list_radius_diffs)/len(expected), ndigits)
|
||||
sum_xmoy_diff = round(sum(list_xmoy_diffs)/len(expected), ndigits)
|
||||
sum_ymoy_diffs = round(sum(list_ymoy_diffs)/len(expected), ndigits)
|
||||
print()
|
||||
print("Analyse données brutes :")
|
||||
print(f"diff moyenne de x : {sum_x_diff}")
|
||||
print(f"diff moyenne de y : {sum_y_diff}")
|
||||
print(f"diff moyenne de z : {sum_z_diff}")
|
||||
print(f"diff moyenne de t : {sum_teta_diff}")
|
||||
print(f"diff moyenne de r : {sum_radius_diff}")
|
||||
print(f"diff moyenne de xmoy : {sum_xmoy_diff}")
|
||||
print(f"diff moyenne de ymoy : {sum_ymoy_diffs}")
|
||||
print(
|
||||
f"diff gloabale des fichiers : {(sum_x_diff+sum_y_diff+sum_z_diff+sum_teta_diff+sum_radius_diff+sum_xmoy_diff+sum_ymoy_diffs)/7}")
|
||||
print(f"Voir {output_file} pour plus de détails")
|
||||
print(f"Voir {minimal_output_file} pour les différences significatives")
|
||||
print("_"*80)
|
||||
|
||||
return {"x": list_x_diffs,
|
||||
"y": list_y_diffs,
|
||||
"z": list_z_diffs,
|
||||
"teta": list_teta_diffs,
|
||||
"radius": list_radius_diffs,
|
||||
"xmoy": list_xmoy_diffs,
|
||||
"ymoy": list_ymoy_diffs}
|
||||
|
||||
def check_consistency(obj: ScannedObject, discretised_file_path: str):
|
||||
"""
|
||||
This function takes a obj file, and checks if the discretised result file
|
||||
respect what should be the correct discritisation
|
||||
|
||||
:param obj: The object to check
|
||||
:param discretised_file_path: The discetised file output
|
||||
"""
|
||||
obj.export("verification.txt")
|
||||
mean_list = []
|
||||
moyx, moyy, moyz = parse_result_file(discretised_file_path)
|
||||
moy = moyy
|
||||
verticies = obj.get_vertices(sort=True)
|
||||
position = 0
|
||||
while position < len(verticies) and len(moy) > 0:
|
||||
xi_value = verticies[position][0]
|
||||
yi_value = verticies[position][1]
|
||||
zi_value = verticies[position][2]
|
||||
mean_list.append(yi_value)
|
||||
mean = np.mean(mean_list)
|
||||
print(f"searching for {moy[0]}, currently at {position}", end="\r")
|
||||
if abs(mean - moy[0]) < 0.000001:
|
||||
moy.pop(0)
|
||||
mean_list = []
|
||||
copyposition = position
|
||||
if int(verticies[copyposition][2]) >= int(verticies[copyposition+1][2]):
|
||||
while int(verticies[copyposition][2]) == int(verticies[copyposition-1][2]):
|
||||
copyposition -= 1
|
||||
# Position +1 pour l'allignement des indices avec le numero de ligne
|
||||
# Position - copyposition + 1 car on se deplace seulement si, la condition est fasse aka, on bouge pas si on est aussi de la ou on doit etre
|
||||
print("line position :", position+1, "|should have stoped :", position - copyposition + 1,
|
||||
"position higher| Z difference :", verticies[position][2] - verticies[copyposition-1][2])
|
||||
position += 1
|
||||
|
||||
def test_get_raw_data(obj: ScannedObject, expected_file: str, ndigits: int = 6, eps: float = 0.0001):
|
||||
"""
|
||||
Test the get_raw_data function, mesure how long it takes to run it then
|
||||
checks if the values match with the exepected values
|
||||
|
||||
:param obj: the object to calculate the data from
|
||||
:param expected_file: reference output to check data against
|
||||
:param ndigits: The number of digits to keep after the comma
|
||||
:param eps: the degree of precision we consider two values different
|
||||
"""
|
||||
|
||||
# Calculate raw data and save it in a file
|
||||
now = time.time()
|
||||
data = get_raw_data(obj, ndigits)
|
||||
print()
|
||||
print("Analyse données brutes :")
|
||||
print(f"diff moyenne de x : {x}")
|
||||
print(f"diff moyenne de y : {y}")
|
||||
print(f"diff moyenne de z : {z}")
|
||||
print(f"diff moyenne de t : {t}")
|
||||
print(f"diff moyenne de r : {r}")
|
||||
print(f"diff moyenne de xmoy : {xmoy}")
|
||||
print(f"diff moyenne de ymoy : {ymoy}")
|
||||
print(f"diff gloabale des fichiers : {(x+y+z+t+r+xmoy+ymoy)/7}")
|
||||
print(f"Voir {output_file} pour plus de détails")
|
||||
print(f"Voir {minimal_output_file} pour les différences significatives")
|
||||
print("_"*80)
|
||||
print("Time to calculate raw data: ", time.time() - now)
|
||||
output.save_output_file('tmp_analyse_brute.txt', output.format_data(data, '\t', [
|
||||
"X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)", "Xi-Xmoy", "Yi-Ymoy"]))
|
||||
check_raw_data(expected_file, 'tmp_analyse_brute.txt', ndigits, eps)
|
||||
os.remove('tmp_analyse_brute.txt')
|
||||
|
||||
def test_get_discrete_data(obj: ScannedObject, expected_file: str, ndigits: int = 6, eps: float = 0.0001):
|
||||
"""
|
||||
Test the get_discrete_data function mesure how long it takes to run it then
|
||||
checks if the values match with the exepected values
|
||||
|
||||
:param obj: the object to calculate the data from
|
||||
:param expected_file: reference output to check data against
|
||||
:param ndigits: The number of digits to keep after the comma
|
||||
:param eps: the degree of precision we consider two values different
|
||||
"""
|
||||
|
||||
# Calculate discrete data and save it in a file
|
||||
now = time.time()
|
||||
data = get_discrete_data(obj, ndigits)
|
||||
print()
|
||||
print("Time to calculate discrete data: ", time.time() - now)
|
||||
output.save_output_file('tmp_analyse_discrete.txt', output.format_data(data, '\t', [
|
||||
"X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)", "Rayon moyen (en mm)", "Rayon ecart type (en mm)"]))
|
||||
check_discrete_data(
|
||||
expected_file, 'tmp_analyse_discrete.txt', ndigits, eps)
|
||||
os.remove('tmp_analyse_discrete.txt')
|
||||
|
||||
45
main.py
45
main.py
@ -1,9 +1,8 @@
|
||||
from utils.math import utils
|
||||
from utils.math import data_extraction
|
||||
from utils.files import output
|
||||
from utils.files import parsers
|
||||
from utils.files.file_data import Object
|
||||
from utils.files.input import ScannedObject
|
||||
|
||||
def get_raw_data(obj:Object, ndigits:int)->dict:
|
||||
def get_raw_data(obj:ScannedObject, ndigits:int)->dict:
|
||||
"""
|
||||
Calculates data from the given object
|
||||
|
||||
@ -23,18 +22,18 @@ def get_raw_data(obj:Object, ndigits:int)->dict:
|
||||
for colone in colones:
|
||||
data[colone] = []
|
||||
for discrete_values in obj.get_discrete_vertices():
|
||||
mean_x ,mean_y, mean_z = utils.get_x_y_z_mean(discrete_values)
|
||||
mean_x ,mean_y, mean_z = data_extraction.get_x_y_z_mean(discrete_values)
|
||||
for x,y,z in discrete_values:
|
||||
data["X (en mm)"].append(round(x, ndigits))
|
||||
data["Y (en mm)"].append(round(y, ndigits))
|
||||
data["Z (en mm)"].append(round(z, ndigits))
|
||||
data["teta (en rad)"].append(round(utils.get_teta_from_x_y(x,y,mean_x,mean_y), ndigits))
|
||||
data["rayon (en mm)"].append(round(utils.get_radius_from_x_y(x,y,mean_x,mean_y), ndigits))
|
||||
data["teta (en rad)"].append(round(data_extraction.get_teta_from_x_y(x,y,mean_x,mean_y), ndigits))
|
||||
data["rayon (en mm)"].append(round(data_extraction.get_radius_from_x_y(x,y,mean_x,mean_y), ndigits))
|
||||
data["Xi-Xmoy"].append(round(x-mean_x, ndigits))
|
||||
data["Yi-Ymoy"].append(round(y-mean_y, ndigits))
|
||||
return data
|
||||
|
||||
def get_discrete_data(obj:Object, ndigits:int)->dict:
|
||||
def get_discrete_data(obj:ScannedObject, ndigits:int)->dict:
|
||||
"""
|
||||
Calculates data from the given object
|
||||
|
||||
@ -51,29 +50,43 @@ def get_discrete_data(obj:Object, ndigits:int)->dict:
|
||||
data = {}
|
||||
for colone in colones:
|
||||
data[colone] = []
|
||||
cpt = 0
|
||||
for discrete_values in obj.get_discrete_vertices():
|
||||
x,y,z = utils.get_x_y_z_mean(discrete_values)
|
||||
x,y,z = data_extraction.get_x_y_z_mean(discrete_values)
|
||||
data["X moy (en mm)"].append(round(x, ndigits))
|
||||
data["Y moy (en mm)"].append(round(y, ndigits))
|
||||
data["Z moy (en mm)"].append(round(z, ndigits))
|
||||
data["Rayon moyen (en mm)"].append(round(utils.get_mean_radius(discrete_values), ndigits))
|
||||
data["Rayon ecart type (en mm)"].append(round(utils.get_radius_std(discrete_values), ndigits))
|
||||
data["Rayon moyen (en mm)"].append(round(data_extraction.get_mean_radius(discrete_values), ndigits))
|
||||
data["Rayon ecart type (en mm)"].append(round(data_extraction.get_radius_std(discrete_values), ndigits))
|
||||
return data
|
||||
|
||||
|
||||
def main():
|
||||
# Create an object from the given file
|
||||
obj = parsers.parse_xyz_file("test_cylindre.xyz",normalised='z')
|
||||
obj = ScannedObject.from_xyz_file("test_cylindre.xyz",normalised='z')
|
||||
|
||||
# Calculate raw data and save it in a file
|
||||
data = get_raw_data(obj, 6)
|
||||
output.save_output_file('analyse_brute.txt', output.format_data(data, '\t', ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"] ))
|
||||
output.save_output_file('analyse_brute.txt',
|
||||
output.format_data(data,
|
||||
'\t',
|
||||
["X (en mm)",
|
||||
"Y (en mm)",
|
||||
"Z (en mm)",
|
||||
"teta (en rad)",
|
||||
"rayon (en mm)",
|
||||
"Xi-Xmoy",
|
||||
"Yi-Ymoy"] ))
|
||||
|
||||
# Calculate discrete data and save it in a file
|
||||
data = get_discrete_data(obj, 6)
|
||||
output.save_output_file('analyse_rayon.txt', output.format_data(data, '\t', ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"] ))
|
||||
|
||||
output.save_output_file('analyse_rayon.txt',
|
||||
output.format_data(data,
|
||||
'\t',
|
||||
["X moy (en mm)",
|
||||
"Y moy (en mm)",
|
||||
"Z moy (en mm)",
|
||||
"Rayon moyen (en mm)",
|
||||
"Rayon ecart type (en mm)"] ))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,53 +0,0 @@
|
||||
from utils.files.parsers import parse_obj_file, parse_xyz_file
|
||||
import numpy as np
|
||||
|
||||
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
|
||||
|
||||
def verifier_coherance():
|
||||
obj = parse_obj_file("datasets/Barette/3 - BARETTE v1.obj",normalised='z')
|
||||
obj.export("verification.txt")
|
||||
#obj = parse_xyz_file("datasets/Barette/4 - BARETTE v1.xyz",normalised='')
|
||||
cpt = 0
|
||||
L = []
|
||||
moyx, moyy, moyz = parse_result_file("datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt")
|
||||
print(len(moyx),len(moyy),len(moyz))
|
||||
moy = moyx
|
||||
verticies = obj.get_vertices(sort=True)
|
||||
position = 0
|
||||
while position < len(verticies) and len(moy) > 0:
|
||||
x = verticies[position][0]
|
||||
y = verticies[position][1]
|
||||
z = verticies[position][2]
|
||||
L.append(x)
|
||||
m = np.mean(L)
|
||||
print(f"searching for {moy[0]}, currently at {position}",end="\r")
|
||||
if abs(m - moy[0]) < 0.000001:
|
||||
moy.pop(0)
|
||||
L = []
|
||||
copyposition = position
|
||||
if int(verticies[copyposition][2]) >= int(verticies[copyposition+1][2]):
|
||||
while int(verticies[copyposition][2]) == int(verticies[copyposition-1][2]):
|
||||
copyposition -= 1
|
||||
"""
|
||||
if verticies[position][2] - verticies[copyposition][2] > 1:
|
||||
copyposition = position + 1
|
||||
break
|
||||
"""
|
||||
# Position +1 pour l'allignement des indices avec le numero de ligne
|
||||
# Position - copyposition + 1 car on se deplace seulement si, la condition est fasse aka, on bouge pas si on est aussi de la ou on doit etre
|
||||
print("index :",position,"|should have stoped :",position - copyposition + 1,"position higher| Z difference :",verticies[position][2] - verticies[copyposition-1][2])
|
||||
position += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
verifier_coherance()
|
||||
72
test.py
72
test.py
@ -1,69 +1,37 @@
|
||||
import numpy as np
|
||||
from main import get_raw_data, get_discrete_data
|
||||
from utils.files.file_data import Object
|
||||
from utils.files.output import save_output_file, format_data
|
||||
from utils.files.parsers import parse_obj_file, parse_xyz_file
|
||||
from utils.files.input import ScannedObject
|
||||
from integration_tests import data_test
|
||||
import time
|
||||
import os
|
||||
|
||||
def test_get_raw_data(obj:Object, expected_file:str, ndigits:int = 6, eps:float = 0.0001):
|
||||
"""
|
||||
Test the get_raw_data function
|
||||
"""
|
||||
|
||||
# Calculate raw data and save it in a file
|
||||
now = time.time()
|
||||
data = get_raw_data(obj, ndigits)
|
||||
print()
|
||||
print("Time to calculate raw data: ", time.time() - now)
|
||||
save_output_file('tmp_analyse_brute.txt', format_data(data, '\t', ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"] ))
|
||||
data_test.check_raw_data(expected_file, 'tmp_analyse_brute.txt', ndigits, eps)
|
||||
os.remove('tmp_analyse_brute.txt')
|
||||
|
||||
def test_get_discrete_data(obj: Object,expected_file:str, ndigits:int = 6, eps:float = 0.0001):
|
||||
"""
|
||||
Test the get_discrete_data function
|
||||
"""
|
||||
|
||||
# Calculate discrete data and save it in a file
|
||||
now = time.time()
|
||||
data = get_discrete_data(obj, ndigits)
|
||||
print()
|
||||
print("Time to calculate discrete data: ", time.time() - now)
|
||||
save_output_file('tmp_analyse_discrete.txt', format_data(data, '\t', ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"] ))
|
||||
data_test.check_discrete_data(expected_file, 'tmp_analyse_discrete.txt', ndigits, eps)
|
||||
os.remove('tmp_analyse_discrete.txt')
|
||||
|
||||
def test():
|
||||
def test_differences():
|
||||
eps = 0.000001
|
||||
obj = ScannedObject.from_xyz_file("datasets/Barette/4 - BARETTE v1.xyz",
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt", normalised='z')
|
||||
|
||||
#obj = parse_obj_file("datasets/Barette/3 - BARETTE v1.obj",normalised='z')
|
||||
#obj = parse_xyz_file("datasets/Barette/4 - BARETTE v1.xyz",normalised='z')
|
||||
obj = parse_xyz_file("datasets/Barette/4 - BARETTE v1.xyz","datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt",normalised='z')
|
||||
data_test.test_get_raw_data(obj,
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse brute.txt",
|
||||
eps=eps)
|
||||
|
||||
test_get_raw_data(obj,
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse brute.txt",
|
||||
eps=eps)
|
||||
|
||||
test_get_discrete_data(obj,
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt",
|
||||
eps=eps)
|
||||
data_test.test_get_discrete_data(obj,
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt",
|
||||
eps=eps)
|
||||
|
||||
def show_diff_between_obj_and_xyz():
|
||||
obj1 = parse_obj_file("datasets/Barette/3 - BARETTE v1.obj",normalised='z')
|
||||
obj2 = parse_xyz_file("datasets/Barette/4 - BARETTE v1.xyz",normalised='z')
|
||||
|
||||
def show_diff_two_obj():
|
||||
obj1 = ScannedObject.from_obj_file(
|
||||
"datasets/Barette/3 - BARETTE v1.obj", normalised='z')
|
||||
obj2 = ScannedObject.from_xyz_file(
|
||||
"datasets/Barette/4 - BARETTE v1.xyz", normalised='z')
|
||||
obj2verts = obj2.get_vertices(sort=True)
|
||||
for count, values in enumerate(obj1.get_vertices(sort=True)):
|
||||
L = [abs(values[i] - obj2verts[count][i]) for i in range(len(values))]
|
||||
print(*L,sep="\t")
|
||||
print(*L, sep="\t")
|
||||
|
||||
|
||||
def count_elements_in_discrete_array():
|
||||
obj = parse_xyz_file("datasets/Barette/4 - BARETTE v1.xyz","datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt",normalised='z')
|
||||
obj = ScannedObject.from_xyz_file("datasets/Barette/4 - BARETTE v1.xyz",
|
||||
"datasets/Barette/BARETTE_Delta 1,0_analyse rayon.txt", normalised='z')
|
||||
cpt = 0
|
||||
for i in obj.bruteforce_discretization():
|
||||
print(f"nb of element in z{cpt} to z{cpt+1}:",len(i))
|
||||
print(f"nb of element in z{cpt} to z{cpt+1}:", len(i))
|
||||
cpt += 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -1,166 +0,0 @@
|
||||
"""
|
||||
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, 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]
|
||||
|
||||
def get_x(self)->list:
|
||||
"""
|
||||
Get the x coordinates of the object.
|
||||
return: x coordinates
|
||||
"""
|
||||
return self.x
|
||||
|
||||
def get_y(self)->list:
|
||||
"""
|
||||
Get the y coordinates of the object.
|
||||
return: y coordinates
|
||||
"""
|
||||
return self.y
|
||||
|
||||
def get_z(self)->list:
|
||||
"""
|
||||
Get the z coordinates of the object.
|
||||
return: z coordinates
|
||||
"""
|
||||
return self.z
|
||||
|
||||
def get_vertices(self, sort:bool = False):
|
||||
"""
|
||||
Get the vertices of the 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 = 1):
|
||||
"""
|
||||
Discretize the vertices of the object.
|
||||
:param step: Step of the discretization
|
||||
:return: Discretized vertices
|
||||
"""
|
||||
current_interval = int(min(self.get_z()))
|
||||
splitted_data = [[]]
|
||||
for line in self.get_vertices(sort=True):
|
||||
# TODO check distance instead of equality
|
||||
if line[2] >= current_interval + step:
|
||||
splitted_data.append([])
|
||||
current_interval += step
|
||||
splitted_data[-1].append(line)
|
||||
if splitted_data[0] == []:
|
||||
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.
|
||||
:return: faces
|
||||
"""
|
||||
if self.faces is None:
|
||||
raise FaceNotGiven('No faces was given')
|
||||
return self.faces
|
||||
|
||||
def get_data(self)->dict:
|
||||
"""
|
||||
Get the data of the 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")
|
||||
|
||||
318
utils/files/input.py
Normal file
318
utils/files/input.py
Normal file
@ -0,0 +1,318 @@
|
||||
"""
|
||||
This module contains the functions to parse the input files, and create a ScannedObject.
|
||||
"""
|
||||
import numpy as np
|
||||
from utils.files.output import save_output_file
|
||||
|
||||
|
||||
class FacesNotGiven(Exception):
|
||||
"""
|
||||
Exception raised when no faces was given.
|
||||
"""
|
||||
|
||||
class ResultFileNotGiven(Exception):
|
||||
"""
|
||||
Exception raised when no faces was given.
|
||||
"""
|
||||
|
||||
class ScannedObject:
|
||||
"""
|
||||
This class is used to manage the data of the 3D object.
|
||||
|
||||
:param vertices: List of vertices
|
||||
:param faces: List of faces
|
||||
:param result_file_path: Path to the result file (deprecated, used for the bruteforce discretization)
|
||||
|
||||
:static method from_xyz_file(): Creates a ScannedObject from a .xyz file
|
||||
:static method from_obj_file(): Creates a ScannedObject from a .obj file
|
||||
:method get_x(): Returns the x values of the vertices
|
||||
:method get_y(): Returns the y values of the vertices
|
||||
:method get_z(): Returns the z values of the vertices
|
||||
:method get_vertices(): Returns the vertices
|
||||
:method get_faces(): Returns the faces
|
||||
:method get_discrete_vertices(): Returns the discrete vertices
|
||||
:method get_data(): Returns the data
|
||||
:method export: Exports the data to a file
|
||||
|
||||
|
||||
:raises FacesNotGiven: If no faces was given
|
||||
:raises ResultFileNotGiven: If no result file was given
|
||||
|
||||
|
||||
:Example:
|
||||
|
||||
>>> from utils.files.input import ScannedObject
|
||||
>>> vertices = [(0,0,0), (1,0,0), (1,1,0), (0,1,0), (0,0,1), (1,0,1), (1,1,1), (0,1,1)]
|
||||
>>> faces = [(0,1,2), (0,2,3), (4,5,6), (4,6,7), (0,1,5), (0,4,5), (1,2,6), (1,5,6), (2,3,7), (2,6,7), (3,0,4), (3,7,4)]
|
||||
>>> obj = ScannedObject(vertices, faces)
|
||||
>>> obj.get_x()
|
||||
[0, 1, 1, 0, 0, 1, 1, 0]
|
||||
>>> obj.get_y()
|
||||
[0, 0, 1, 1, 0, 0, 1, 1]
|
||||
>>> obj.get_z()
|
||||
[0, 0, 0, 0, 1, 1, 1, 1]
|
||||
>>> obj.get_vertices()
|
||||
[(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0), (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]
|
||||
>>> obj.get_faces()
|
||||
[(0, 1, 2), (0, 2, 3), (4, 5, 6), (4, 6, 7), (0, 1, 5), (0, 4, 5), (1, 2, 6), (1, 5, 6), (2, 3, 7), (2, 6, 7), (3, 0, 4), (3, 7, 4)]
|
||||
>>> obj.get_discrete_vertices()
|
||||
[[(0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)]],[ (0, 0, 1), (1, 0, 1), (1, 1, 1), (0, 1, 1)]]
|
||||
#TODO Add and test exemples
|
||||
"""
|
||||
def __init__(self, vertices, faces=None, result_file_path=None):
|
||||
self.vertices = vertices
|
||||
self.faces = faces
|
||||
# Deprecated
|
||||
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]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_obj_file(file_path:str, result_file_path:str = None, ratio:float = 1,normalised:str = '')->'ScannedObject':
|
||||
"""
|
||||
Create an Object from an OBJ file.
|
||||
|
||||
:param file_path: Path to the OBJ file
|
||||
:param result_file_path: Path to the result file
|
||||
:param ratio: Ratio to apply to the vertices
|
||||
:param normalised: the axis to normalise
|
||||
:return: A ScannedObject
|
||||
"""
|
||||
with open(file_path, 'r') as f:
|
||||
x, y, z = [], [], []
|
||||
triangles = []
|
||||
data = f.readlines()
|
||||
for line in data :
|
||||
if line.startswith('f'):
|
||||
# Face indices start at 1, not 0
|
||||
triangles.append([int(line.split()[1])-1, int(line.split()[2])-1, int(line.split()[3])-1])
|
||||
elif line.startswith('v'):
|
||||
x.append(float(line.split()[1]) * ratio)
|
||||
y.append(float(line.split()[2]) * ratio)
|
||||
z.append(float(line.split()[3]) * ratio)
|
||||
|
||||
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 ScannedObject(list(zip(x,y,z)), triangles, result_file_path)
|
||||
|
||||
@staticmethod
|
||||
def from_xyz_file(file_path: str, result_file_path:str = None, delimiter: str = ' ',normalised:str = '')->'ScannedObject':
|
||||
"""
|
||||
Create an Object from an XYZ file.
|
||||
|
||||
:param file_path: Path to the XYZ file
|
||||
:param result_file_path: Path to the result file
|
||||
:param delimiter: The delimiter used in the xyz file.
|
||||
:param normalised: the axis to normalise
|
||||
:return: A ScannedObject
|
||||
"""
|
||||
x , y , z = [], [], []
|
||||
with open(file_path, 'r') as f:
|
||||
data = f.readlines()
|
||||
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 ScannedObject(list(zip(x,y,z)), result_file_path=result_file_path)
|
||||
|
||||
def get_x(self)->list:
|
||||
"""
|
||||
Get the x coordinates of the object.
|
||||
return: x coordinates
|
||||
"""
|
||||
return self.x
|
||||
|
||||
def get_y(self)->list:
|
||||
"""
|
||||
Get the y coordinates of the object.
|
||||
return: y coordinates
|
||||
"""
|
||||
return self.y
|
||||
|
||||
def get_z(self)->list:
|
||||
"""
|
||||
Get the z coordinates of the object.
|
||||
return: z coordinates
|
||||
"""
|
||||
return self.z
|
||||
|
||||
def get_vertices(self, sort:bool = False):
|
||||
"""
|
||||
Get the vertices of the 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 = 1):
|
||||
"""
|
||||
Discretize the vertices of the object.
|
||||
:param step: Step of the discretization
|
||||
:return: Discretized vertices
|
||||
"""
|
||||
current_interval = int(min(self.get_z()))
|
||||
splitted_data = [[]]
|
||||
for line in self.get_vertices(sort=True):
|
||||
# TODO check distance instead of equality
|
||||
if line[2] >= current_interval + step:
|
||||
splitted_data.append([])
|
||||
current_interval += step
|
||||
splitted_data[-1].append(line)
|
||||
return splitted_data
|
||||
|
||||
def get_discrete_vertices2(self, step:float = 1):
|
||||
"""
|
||||
Deprecated
|
||||
"""
|
||||
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_discrete_vertices3(self, step:float = 1):
|
||||
"""
|
||||
Deprecated
|
||||
"""
|
||||
cpt = 0
|
||||
L = [[]]
|
||||
z = min(self.get_z())
|
||||
sorted = self.get_vertices(sort=True)
|
||||
for index in range(len(sorted)):
|
||||
L[-1].append(sorted[index])
|
||||
if sorted[index][2] - z > step:
|
||||
z = sorted[index][2]
|
||||
L.append([])
|
||||
return L
|
||||
|
||||
|
||||
def get_faces(self)->list:
|
||||
"""
|
||||
Get the faces of the object.
|
||||
:return: faces
|
||||
"""
|
||||
if self.faces is None:
|
||||
raise FacesNotGiven('No faces was given')
|
||||
return self.faces
|
||||
|
||||
def get_data(self)->dict:
|
||||
"""
|
||||
Get the data of the 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):
|
||||
"""
|
||||
Deprecated
|
||||
TODO Remove this when its not needed anymore
|
||||
"""
|
||||
if self.bruteforce_discretization_result:
|
||||
return self.bruteforce_discretization_result
|
||||
if self.result_file_path is None:
|
||||
raise ResultFileNotGiven("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,separator:str="\t"):
|
||||
"""
|
||||
Export the object in a file.
|
||||
:param file_path: Path of the file
|
||||
:param separator: chars used to separate the values
|
||||
"""
|
||||
string = ''
|
||||
with open(file_path, "w") as f:
|
||||
for vertex in self.get_vertices(sort=True):
|
||||
x = round(vertex[0], 6)
|
||||
y = round(vertex[1], 6)
|
||||
z = round(vertex[2], 6)
|
||||
string+=f"{x}{separator}{y}{separator}{z}\n"
|
||||
save_output_file(file_path,string)
|
||||
|
||||
|
||||
def parse_result_file(file_path: str, separator: str = "\t")-> tuple:
|
||||
"""
|
||||
This functions parses the discretised output file to retreive the first
|
||||
three colunms. It is used to extract the means of x y z for the consistency
|
||||
check and the bruteforce_discretisation
|
||||
|
||||
:param file_path: Path of the file
|
||||
:param separator: chars used to separate the values
|
||||
:return: x, y, z
|
||||
|
||||
:Example:
|
||||
>>> parse_result_file("test.txt")
|
||||
([1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0])
|
||||
"""
|
||||
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(separator)
|
||||
x.append(float(values[0]))
|
||||
y.append(float(values[1]))
|
||||
z.append(float(values[2]))
|
||||
return x, y, z
|
||||
@ -1,3 +1,7 @@
|
||||
"""
|
||||
Deprecated
|
||||
"""
|
||||
|
||||
def denormalizeXYZ(filePath:str, output:str):
|
||||
"""
|
||||
Denormalize an XYZ file
|
||||
|
||||
@ -10,6 +10,19 @@ def format_data(data:dict, separator:str, selected_columns:list = None) -> str:
|
||||
:param selected_columns: Columns to be saved
|
||||
:param separator: Separator of the columns
|
||||
:return: Formatted data
|
||||
|
||||
Example:
|
||||
>>> data = {
|
||||
... 'col1': [1, 2, 3],
|
||||
... 'col2': [4, 5, 6],
|
||||
... 'col3': [7, 8, 9]
|
||||
... }
|
||||
>>> format_data(data, separator=';')
|
||||
'col1;col2;col3
|
||||
1 ;4 ;7
|
||||
2 ;5 ;8
|
||||
3 ;6 ;9
|
||||
'
|
||||
"""
|
||||
output = ''
|
||||
if selected_columns is None:
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
"""
|
||||
This module contains functions to parse files.
|
||||
"""
|
||||
from utils.files.file_data import 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
|
||||
|
||||
:param filePath: Path to the OBJ file
|
||||
:param ratio: Ratio to apply to the vertices
|
||||
:param cornered: If True, the vertices will be cornered
|
||||
:return: A dict with the vertices and faces
|
||||
"""
|
||||
with open(file_path, 'r') as f:
|
||||
x, y, z = [], [], []
|
||||
triangles = []
|
||||
data = f.readlines()
|
||||
for line in data :
|
||||
if line.startswith('f'):
|
||||
# Face indices start at 1, not 0
|
||||
triangles.append([int(line.split()[1])-1, int(line.split()[2])-1, int(line.split()[3])-1])
|
||||
elif line.startswith('v'):
|
||||
x.append(float(line.split()[1]) * ratio)
|
||||
y.append(float(line.split()[2]) * ratio)
|
||||
z.append(float(line.split()[3]) * ratio)
|
||||
|
||||
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)), triangles, result_file_path)
|
||||
|
||||
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.
|
||||
|
||||
:param file: The xyz file to be parsed.
|
||||
:param delimiter: The delimiter used in the xyz file.
|
||||
:return: A dictionary containing the coordinates.
|
||||
"""
|
||||
x , y , z = [], [], []
|
||||
with open(file_path, 'r') as f:
|
||||
data = f.readlines()
|
||||
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)
|
||||
11
utils/graph2D/plots.py
Normal file
11
utils/graph2D/plots.py
Normal file
@ -0,0 +1,11 @@
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
def render2D(values:list):
|
||||
"""
|
||||
Render a 2D model using matplotlib
|
||||
:param values: A list with the values
|
||||
"""
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot()
|
||||
ax.plot(values)
|
||||
plt.show()
|
||||
@ -7,6 +7,13 @@ import math
|
||||
def get_mean(values:list):
|
||||
"""
|
||||
Get the mean of the values.
|
||||
|
||||
:param values: values
|
||||
:return: mean of the values
|
||||
|
||||
:Example:
|
||||
>>> get_mean([1,2,3,4,5])
|
||||
3.0
|
||||
"""
|
||||
return np.mean(values)
|
||||
|
||||
@ -16,6 +23,10 @@ def get_standard_deviation(values:list):
|
||||
|
||||
:param values: values
|
||||
:return: standard deviation of the values
|
||||
|
||||
:Example:
|
||||
>>> get_standard_deviation([1,2,3,4,5])
|
||||
1.4142135623730951
|
||||
"""
|
||||
return np.std(values)
|
||||
|
||||
@ -26,6 +37,10 @@ def get_x_y_z_mean(discrete_values:list):
|
||||
:param x: x coordinates
|
||||
:param y: y coordinates
|
||||
:return: mean of x and y coordinates in the discrete range
|
||||
|
||||
:Example:
|
||||
>>> get_x_y_z_mean([(1,2,3),(4,5,6),(7,8,9)])
|
||||
(4.0, 5.0, 6.0)
|
||||
"""
|
||||
x = [vertex[0] for vertex in discrete_values]
|
||||
y = [vertex[1] for vertex in discrete_values]
|
||||
@ -41,6 +56,10 @@ def get_radius_from_x_y(xi:float, yi:float, x_mean:float, y_mean:float):
|
||||
:param x_mean: mean of x coordinates in the discrete range
|
||||
:param y_mean: mean of y coordinates in the discrete range
|
||||
:return: radius for this point
|
||||
|
||||
:Example:
|
||||
>>> get_radius_from_x_y(1,2,3,4)
|
||||
2.8284271247461903
|
||||
"""
|
||||
return np.sqrt(np.power((xi - x_mean), 2) + np.power((yi - y_mean), 2))
|
||||
|
||||
@ -50,6 +69,10 @@ def get_mean_radius(discrete_values:list):
|
||||
|
||||
:param discrete_values: discrete values
|
||||
:return: mean of the radius in the discrete range
|
||||
|
||||
:Example:
|
||||
>>> get_mean_radius([(1,2,3),(4,5,6),(7,8,9)])
|
||||
2.82842712474619
|
||||
"""
|
||||
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
||||
radius = []
|
||||
@ -63,6 +86,10 @@ def get_radius_std(discrete_values:list):
|
||||
|
||||
:param discrete_values: discrete values
|
||||
:return: standard deviation of the radius in the discrete range
|
||||
|
||||
:Example:
|
||||
>>> get_radius_std([(1,2,3),(4,5,6),(7,8,9)])
|
||||
2.8284271247461903
|
||||
"""
|
||||
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
||||
radius = []
|
||||
@ -76,6 +103,10 @@ def get_mean_teta(discrete_values:list):
|
||||
|
||||
:param discrete_values: discrete values
|
||||
:return: mean of the teta in the discrete range
|
||||
|
||||
:Example:
|
||||
>>> get_mean_teta([(1,2,3),(4,5,6),(7,8,9)])
|
||||
0.7853981633974483
|
||||
"""
|
||||
x_mean, y_mean, z_mean = get_x_y_z_mean(discrete_values)
|
||||
teta = []
|
||||
@ -92,5 +123,14 @@ def get_teta_from_x_y(xi:float, yi:float, x_mean:float, y_mean:float):
|
||||
:param x_mean: mean of x coordinates in the discrete range
|
||||
:param y_mean: mean of y coordinates in the discrete range
|
||||
:return: teta for this point
|
||||
|
||||
:Example:
|
||||
>>> get_teta_from_x_y(1,2,3,4)
|
||||
0.7853981633974483
|
||||
"""
|
||||
return math.atan((xi - x_mean)/(yi - y_mean))
|
||||
return math.atan((xi - x_mean)/(yi - y_mean))
|
||||
|
||||
#todo fix examples
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
Loading…
Reference in New Issue
Block a user