Skip to content
Snippets Groups Projects
Commit 533077d8 authored by Djalim Simaila's avatar Djalim Simaila
Browse files

Finished verticalisation

parent af36b95e
No related branches found
No related tags found
1 merge request!63D Verticalisation
......@@ -193,7 +193,7 @@ def check_consistency(obj: ScannedObject, discretised_file_path: str):
:param obj: The object to check
:param discretised_file_path: The discetised file output
"""
obj.export("verification.txt")
obj.export_xyz("verification.txt")
mean_list = []
moyx, moyy, moyz = parse_result_file(discretised_file_path)
moy = moyy
......
from utils.math import data_extraction
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
def get_raw_data(obj:ScannedObject, ndigits:int)->dict:
"""
......@@ -46,7 +48,7 @@ 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)","Rayon moyen (en mm)","Rayon ecart type (en mm)"]
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)"]
data = {}
for colone in colones:
data[colone] = []
......@@ -55,15 +57,19 @@ def get_discrete_data(obj:ScannedObject, ndigits:int)->dict:
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))
first = discrete_values[0]
last = discrete_values[-1]
data["Delta z(en mm)"].append(round(last[2]-first[2],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 = ScannedObject.from_xyz_file("test_cylindre.xyz",normalised='z')
obj = ScannedObject.from_obj_file("datasets/Barette/1 - BARETTE.obj")
verticalise(obj)
obj.normalise()
# Calculate raw data and save it in a file
data = get_raw_data(obj, 6)
output.save_output_file('analyse_brute.txt',
......@@ -85,6 +91,7 @@ def main():
["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)"] ))
......
vispy==0.12.2
PyQt5==5.15.9
numpy==1.24.2
\ No newline at end of file
......@@ -60,15 +60,15 @@ class ScannedObject:
#TODO Add and test exemples
"""
def __init__(self, vertices, faces=None, result_file_path=None):
self.vertices = vertices
self.faces = faces
self.vertices = np.asarray(vertices)
self.faces = np.asarray(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]
self.x = np.asarray([vertex[0] for vertex in vertices])
self.y = np.asarray([vertex[1] for vertex in vertices])
self.z = np.asarray([vertex[2] for vertex in vertices])
@staticmethod
......@@ -225,16 +225,56 @@ class ScannedObject:
L.append([])
return L
def get_faces(self)->list:
def get_faces(self,resolved:bool = False)->list:
"""
Get the faces of the object.
:return: faces
"""
if self.faces is None:
raise FacesNotGiven('No faces was given')
if resolved:
return self.vertices[self.faces]
return self.faces
def update_from_faces(self,faces:list):
"""
Update the object from the faces.
:param faces: Faces to update the object from
"""
cpt = 0
vertex_dict = {}
new_vertices = []
new_faces = []
for face in faces:
new_faces.append([])
for vertex in face:
vertex = tuple(vertex)
if vertex not in vertex_dict:
vertex_dict[vertex] = cpt
cpt += 1
new_vertices.append(vertex)
new_faces[-1].append(vertex_dict[vertex])
self.vertices = np.asarray(new_vertices)
self.faces = np.asarray(new_faces)
self.x = self.vertices[:,0]
self.y = self.vertices[:,1]
self.z = self.vertices[:,2]
self.normalise()
def normalise(self, axis:str = 'z'):
"""
Normalise the object.
:param axis: Axis to normalise
"""
if 'x' in axis:
self.x -= min(self.x)
if 'y' in axis:
self.y -= min(self.y)
if 'z' in axis:
self.z -= min(self.z)
self.vertices = np.asarray(list(zip(self.x,self.y,self.z)))
def get_data(self)->dict:
"""
Get the data of the object.
......@@ -258,7 +298,7 @@ class ScannedObject:
verticies = self.get_vertices(sort=True)
position = 0
while position < len(verticies):
print(position/len(verticies)*100,end="\r")
print('progression :',position/len(verticies)*100,end="\r")
x = verticies[position][0]
y = verticies[position][1]
z = verticies[position][2]
......@@ -277,7 +317,7 @@ class ScannedObject:
self.bruteforce_discretization_result = splitted_data
return splitted_data
def export(self, file_path:str,separator:str="\t"):
def export_xyz(self, file_path:str,separator:str="\t"):
"""
Export the object in a file.
:param file_path: Path of the file
......@@ -292,6 +332,25 @@ class ScannedObject:
string+=f"{x}{separator}{y}{separator}{z}\n"
save_output_file(file_path,string)
def export_obj(self,file_path):
"""
Export the object in a file.
:param file_path: Path of the file
"""
string = ''
with open(file_path, "w") as f:
for vertex in self.get_vertices():
x = round(vertex[0], 6)
y = round(vertex[1], 6)
z = round(vertex[2], 6)
string+=f"v {x} {y} {z}\n"
for face in self.get_faces():
string+="f "
for vertex in face:
string+=f"{vertex+1} "
string+="\n"
save_output_file(file_path,string)
def parse_result_file(file_path: str, separator: str = "\t")-> tuple:
"""
......
import numpy as np
from utils.files.input import ScannedObject
from utils.math.data_extraction import get_mean
def get_mass_properties(obj:ScannedObject):
'''
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
Documentation can be found here:
http://www.geometrictools.com/Documentation/PolyhedralMassProperties.pdf
'''
verts = np.asarray(obj.get_vertices())
faces = np.asarray(obj.get_faces())
faces = verts[faces]
x = np.asarray([[point[0] for point in faces] for faces in faces])
y = np.asarray([[point[1] for point in faces] for faces in faces])
z = np.asarray([[point[2] for point in faces] for faces in faces])
def subexpression(x):
w0, w1, w2 = x[:, 0], x[:, 1], x[:, 2]
temp0 = w0 + w1
f1 = temp0 + w2
temp1 = w0 * w0
temp2 = temp1 + w1 * temp0
f2 = temp2 + w2 * f1
f3 = w0 * temp1 + w1 * temp2 + w2 * f2
g0 = f2 + w0 * (f1 + w0)
g1 = f2 + w1 * (f1 + w1)
g2 = f2 + w2 * (f1 + w2)
return f1, f2, f3, g0, g1, g2
x0, x1, x2 = x[:, 0], x[:, 1], x[:, 2]
y0, y1, y2 = y[:, 0], y[:, 1], y[:, 2]
z0, z1, z2 = z[:, 0], z[:, 1], z[:, 2]
a1, b1, c1 = x1 - x0, y1 - y0, z1 - z0
a2, b2, c2 = x2 - x0, y2 - y0, z2 - z0
d0, d1, d2 = b1 * c2 - b2 * c1, a2 * c1 - a1 * c2, a1 * b2 - a2 * b1
f1x, f2x, f3x, g0x, g1x, g2x = subexpression(x)
f1y, f2y, f3y, g0y, g1y, g2y = subexpression(y)
f1z, f2z, f3z, g0z, g1z, g2z = subexpression(z)
intg = np.zeros((10))
intg[0] = sum(d0 * f1x)
intg[1:4] = sum(d0 * f2x), sum(d1 * f2y), sum(d2 * f2z)
intg[4:7] = sum(d0 * f3x), sum(d1 * f3y), sum(d2 * f3z)
intg[7] = sum(d0 * (y0 * g0x + y1 * g1x + y2 * g2x))
intg[8] = sum(d1 * (z0 * g0y + z1 * g1y + z2 * g2y))
intg[9] = sum(d2 * (x0 * g0z + x1 * g1z + x2 * g2z))
intg /= np.array([6, 24, 24, 24, 60, 60, 60, 120, 120, 120])
volume = intg[0]
cog = intg[1:4] / volume
cogsq = cog ** 2
inertia = np.zeros((3, 3))
inertia[0, 0] = intg[5] + intg[6] - volume * (cogsq[1] + cogsq[2])
inertia[1, 1] = intg[4] + intg[6] - volume * (cogsq[2] + cogsq[0])
inertia[2, 2] = intg[4] + intg[5] - volume * (cogsq[0] + cogsq[1])
inertia[0, 1] = inertia[1, 0] = -(intg[7] - volume * cog[0] * cog[1])
inertia[1, 2] = inertia[2, 1] = -(intg[8] - volume * cog[1] * cog[2])
inertia[0, 2] = inertia[2, 0] = -(intg[9] - volume * cog[2] * cog[0])
return volume, cog, inertia
def verticalise(obj:ScannedObject):
cog = get_mass_properties(obj)
cog, inertia = get_mass_properties(obj)[1:]
[val,vect] = np.linalg.eig(inertia)
if np.linalg.det(vect) < 0:
vect[:,2] = - vect[:,2]
rot = vect.T
faces = obj.get_faces(True)
theta = -np.pi/2
R_y = np.array([[np.cos(theta), 0, np.sin(theta)],
[0, 1, 0],
[-np.sin(theta), 0, np.cos(theta)]])
for face,_ in enumerate(faces):
for vertex in range(3):
faces[face][vertex] = rot@(faces[face][vertex] - cog)
faces[face][vertex] = R_y@(faces[face][vertex])
obj.update_from_faces(faces)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment