diff --git a/main.py b/main.py index 6a757a5d5c56755c43a20f8c9245181a6ae2bc01..68097d37cc63103781f4bf78cebcfa060f57b8e7 100644 --- a/main.py +++ b/main.py @@ -3,8 +3,9 @@ from utils.files import output from utils.files.input import ScannedObject from utils.math.position_manipulation import verticalise from utils.graph3D.visplot_render import render3D +import time -def get_raw_data(obj:ScannedObject, ndigits:int)->dict: +def get_raw_data(obj:ScannedObject, ndigits:int, delta_z:int = 1)->dict: """ Calculates data from the given object @@ -19,11 +20,11 @@ def get_raw_data(obj:ScannedObject, ndigits:int)->dict: - Xi-Xmoy : list of Xi-Xmoy values - Yi-Ymoy : list of Yi-Ymoy values """ - colones = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"] + columns = ["X (en mm)", "Y (en mm)", "Z (en mm)", "teta (en rad)", "rayon (en mm)","Xi-Xmoy","Yi-Ymoy"] data = {} - for colone in colones: - data[colone] = [] - for discrete_values in obj.get_discrete_vertices(): + for column in columns: + data[column] = [] + for discrete_values in obj.get_discrete_vertices(delta_z): 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)) @@ -35,7 +36,7 @@ def get_raw_data(obj:ScannedObject, ndigits:int)->dict: data["Yi-Ymoy"].append(round(y-mean_y, ndigits)) return data -def get_discrete_data(obj:ScannedObject, ndigits:int)->dict: +def get_discrete_data(obj:ScannedObject, ndigits:int,delta_z:int= 1)->dict: """ Calculates data from the given object @@ -48,11 +49,11 @@ def get_discrete_data(obj:ScannedObject, ndigits:int)->dict: - Rayon moyen (en mm) : list of mean radius values - Rayon ecart type (en mm) : list of radius standard deviation values """ - colones = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Delta z(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"] + columns = ["X moy (en mm)", "Y moy (en mm)", "Z moy (en mm)","Delta z(en mm)","Rayon moyen (en mm)","Rayon ecart type (en mm)"] data = {} - for colone in colones: - data[colone] = [] - for discrete_values in obj.get_discrete_vertices(): + for column in columns: + data[column] = [] + for discrete_values in obj.get_discrete_vertices(delta_z): 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)) @@ -66,12 +67,26 @@ def get_discrete_data(obj:ScannedObject, ndigits:int)->dict: def main(): # Create an object from the given file + total_time = time.time() + print("Loading file...") + t = time.time() obj = ScannedObject.from_obj_file("datasets/Barette/1 - BARETTE.obj") + print("File loaded in {} seconds".format(time.time()-t)) + t = time.time() + print("Verticalising object...") verticalise(obj) + print("Object verticalised in {} seconds".format(time.time()-t)) + t = time.time() + print("Normalising object...") obj.normalise() + print("Object normalised in {} seconds".format(time.time()-t)) # Calculate raw data and save it in a file - data = get_raw_data(obj, 6) + t = time.time() + data = get_raw_data(obj, 6,2) + print("Raw data calculated in {} seconds".format(time.time()-t)) + t = time.time() + print("Saving data...") output.save_output_file('analyse_brute.txt', output.format_data(data, '\t', @@ -82,9 +97,15 @@ def main(): "rayon (en mm)", "Xi-Xmoy", "Yi-Ymoy"] )) - + print("Data saved in {} seconds".format(time.time()-t)) + # Calculate discrete data and save it in a file - data = get_discrete_data(obj, 6) + t = time.time() + print("Calculating discrete data...") + data = get_discrete_data(obj, 6,2) + print("Discrete data calculated in {} seconds".format(time.time()-t)) + t = time.time() + print("Saving data...") output.save_output_file('analyse_rayon.txt', output.format_data(data, '\t', @@ -94,6 +115,8 @@ def main(): "Delta z(en mm)", "Rayon moyen (en mm)", "Rayon ecart type (en mm)"] )) + print("Data saved in {} seconds".format(time.time()-t)) + print("Total time : {} seconds".format(time.time()-total_time)) if __name__ == '__main__': main() \ No newline at end of file diff --git a/utils/files/input.py b/utils/files/input.py index 94412c881209295a6bbee935cdc30d2e3aad5199..bc6fd244808c3c21aef827e0cd7388b61b061991 100644 --- a/utils/files/input.py +++ b/utils/files/input.py @@ -19,9 +19,16 @@ 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 vertices: List of verticesm Ndarray of shape (n,2) + :param faces: List of faces, Ndarray of shape (n,2) :param result_file_path: Path to the result file (deprecated, used for the bruteforce discretization) + + :ivar vertices: List of vertices, Ndarray of shape (n,2) + :ivar faces: List of faces, Ndarray of shape (n,2) + :ivar result_file_path: Path to the result file (deprecated, used for the bruteforce discretization) + :ivar x: List of x values of the vertices + :ivar y: List of y values of the vertices + :ivar z: List of z values of the vertices :static method from_xyz_file(): Creates a ScannedObject from a .xyz file :static method from_obj_file(): Creates a ScannedObject from a .obj file diff --git a/utils/files/output.py b/utils/files/output.py index 3eca9abca6b4a4369bd4aca75c198f6a4b7dfc1e..ec1f1aba7adaff5a6592cb7c24cd01edcc9d06a5 100644 --- a/utils/files/output.py +++ b/utils/files/output.py @@ -32,7 +32,7 @@ def format_data(data:dict, separator:str, selected_columns:list = None) -> str: output += '\n' for i in range(len(data[selected_columns[0]])): for column in selected_columns: - output += str(data[column][i]).ljust(len(column)) + separator + output += str(data[column][i]).ljust(len(column) if len(column) > 6 else 7 ) + separator output += '\n' return output diff --git a/utils/graph2D/mpl_render.py b/utils/graph2D/mpl_render.py index dd6450fdbce88f7b364018ffe93634e86ac9cda1..9f78215a20cd1f9a7aa8f562d1fe8e6ca42c302e 100644 --- a/utils/graph2D/mpl_render.py +++ b/utils/graph2D/mpl_render.py @@ -10,12 +10,13 @@ def render2D(values:list): ax.plot(values) plt.show() -def cross_section(x:list,y:list): +def cross_section(x_values:list, y_values:list): """ - Render a 2D model using matplotlib - :param values: A list with the values + Render a 2D cross section using matplotlib + :param x: A list with the x values + :param y: A list with the y values """ fig = plt.figure() ax = fig.add_subplot() - ax.scatter(x,y) + ax.scatter(x_values,y_values) plt.show() \ No newline at end of file diff --git a/utils/graph2D/visplot_render.py b/utils/graph2D/visplot_render.py index 86627b172d37bacf4fd527c604d9603807be574d..31925ab063e575d04d305f62f8b30c138b3e3bfe 100644 --- a/utils/graph2D/visplot_render.py +++ b/utils/graph2D/visplot_render.py @@ -1,9 +1,11 @@ import vispy.plot as vp import numpy as np - - def render2D(values:list): + """ + Render a 2D plot using vispy + :param values: A list with the values + """ fig = vp.Fig(size=(600, 500), show=False) plotwidget = fig[0, 0] fig.title = "bollu" @@ -11,11 +13,15 @@ def render2D(values:list): plotwidget.colorbar(position="top", cmap="autumn") fig.show(run=True) - -def cross_section(x:list,y:list): +def cross_section(x_values:list, y_values:list): + """ + Render a 2D cross section using vispy + :param x: A list with the x values + :param y: A list with the y values + """ color = (0.3, 0.5, 0.8) fig = vp.Fig(show=False) - line = fig[0:4, 0:4].plot(np.column_stack((x,y)), symbol='o', width=0, + line = fig[0:4, 0:4].plot(np.column_stack((x_values,y_values)), symbol='o', width=0, face_color=color + (0.02,), edge_color=None, marker_size=8) line.set_gl_state(depth_test=False) diff --git a/utils/graph3D/mpl_render.py b/utils/graph3D/mpl_render.py index c4757fe36e03a2d20fa218cff61b668960bfcdda..1e2e32f50b3e372b59e0a0e8ec85f5cb50a63208 100644 --- a/utils/graph3D/mpl_render.py +++ b/utils/graph3D/mpl_render.py @@ -5,8 +5,8 @@ from utils.files.input import ScannedObject def render3D(obj:ScannedObject): """ - Render a 3D model using matplotlib poly3dcollection - :param data: A dict with the vertices and faces + Render a 3D model using matplotlib's Poly3dcollection + :param obj: A ScannedObject to be rendered """ fig = plt.figure() ax = fig.add_subplot(projection='3d') diff --git a/utils/graph3D/visplot_render.py b/utils/graph3D/visplot_render.py index d2cd0f24021018cb49a43ee2424a12b8c7382ec8..2dccf7f72462fd9576fbaee03a284daf982f8d3c 100644 --- a/utils/graph3D/visplot_render.py +++ b/utils/graph3D/visplot_render.py @@ -1,12 +1,15 @@ import numpy as np from vispy import app, scene from vispy.scene.visuals import Mesh -from vispy.scene import transforms from vispy.visuals.filters import ShadingFilter, WireframeFilter from utils.files.input import ScannedObject def render3D(obj:ScannedObject): + """ + Render a 3D model using vispy + :param obj: A ScannedObject to be rendered + """ vertices = np.asarray(obj.get_vertices()) faces = np.asarray(obj.get_faces()) canvas = scene.SceneCanvas(keys='interactive', bgcolor='white') diff --git a/utils/math/position_manipulation.py b/utils/math/position_manipulation.py index 53af77c58c384a20cf78291f9daf687b8b451734..94055f366d2945d98da95b77b9696705d9eaac6a 100644 --- a/utils/math/position_manipulation.py +++ b/utils/math/position_manipulation.py @@ -3,15 +3,19 @@ from utils.files.input import ScannedObject from utils.math.data_extraction import get_mean -def get_mass_properties(obj:ScannedObject): +def get_mass_properties(obj:ScannedObject)->tuple: ''' Evaluate and return a tuple with the following elements: - the volume - the position of the center of gravity (COG) - the inertia matrix expressed at the COG + :param obj: Object to analyse + :return: tuple(float, numpy.array, numpy.array) + + From numpy-stl:(https://pypi.org/project/numpy-stl/) + Documentation can be found here: + http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf - Documentation can be found here: - http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf ''' verts = np.asarray(obj.get_vertices()) @@ -66,6 +70,10 @@ def get_mass_properties(obj:ScannedObject): return volume, cog, inertia def verticalise(obj:ScannedObject): + """ + Rotate the object so that the principal axis of inertia is vertical + :param obj: Object to analyse + """ cog = get_mass_properties(obj) cog, inertia = get_mass_properties(obj)[1:] [val,vect] = np.linalg.eig(inertia)