Se necesita algoritmo de Python sencillo en la búsqueda de la caja delimitadora de mallas de un archivo obj
Pregunta
Estoy probando un problema de embalaje utilizando archivos Python y OBJ. Soy un novato en Python y no estoy seguro de cómo manipular los vértices de archivos OBJ para encontrar la caja de límite óptima. ¿Alguna muestra código Python para empezar? Aquí hay una caja simple de un archivo OBJ para comenzar con el que necesitaré encajar en un recipiente más grande. En resumen, puede objetar x encajar en objeto Y. Luego, en última instancia, cuántas x puede caber en Y con la solución más óptima, pero eso es para más tarde.
Aquí están los archivos .OBJ para las cajas pequeñas y más grandes PEQUEÑO:
# Rhino
v -5 -5 0 v -5 -5 5 v 0 -5 0 v 0 -5 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 F 4/4/4 2/2/2 1/1/1 3/3/3 v 0 -5 0 v 0 -5 5 v 0 0 0 v 0 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 1 0 0 vn 1 0 0 vn 1 0 0 vn 1 0 0 F 8/8/8 6/6/6 5/5/5 7/7/7 v 0 0 0 v 0 0 5 v -5 0 0 v -5 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 1 0 vn 0 1 0 vn 0 1 0 vn 0 1 0 F 12/12/12 10/10/10 9/9/9 11/11/11 v -5 0 0 v -5 0 5 v -5 -5 0 v -5 -5 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn -1 0 0 vn -1 0 0 vn -1 0 0 vn -1 0 0 F 16/16/16 14/14/14 13/13/13 15/15/15 v -5 -5 0 v 0 -5 0 v -5 0 0 v 0 0 0 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 0 -1 vn 0 0 -1 vn 0 0 -1 vn 0 0 -1 F 20/20/2018/18/18 17/17/17 19/19/19 v -5 -5 5 v -5 0 5 v 0 -5 5 v 0 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 F 24/24/24 22/22/22 21/21/21 23/23/23
Box más grande:
# Rhino
v 0 0 0 0 v 0 0 20 v 0 20 0 v 0 20 20 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn -1 -0 -0 vn -1 -0 -0 vn -1 -0 -0 vn -1 -0 -0 F 4/4/4 3/3/3 1/1/1 2/2/2 v 0 20 0 v 0 20 20 v 20 20 0 v 20 20 20 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 1 0 vn 0 1 0 vn 0 1 0 vn 0 1 0 F 8/8/8 7/7/7 5/5/5 6/6/6 v 20 20 0 v 20 20 20 v 20 0 0 v 20 0 20 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 1 0 0 vn 1 0 0 vn 1 0 0 vn 1 0 0 F 12/12/12 11/11/11 9/9/9 10/10/10 v 20 0 0 v 20 0 20 v 0 0 0 v 0 0 20 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 F 16/16/16 15/15/15 13/13/13/13 14/14/14 v 0 0 0 v 0 20 0 v 20 0 0 v 20 20 0 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn -0 -0 -1 vn -0 -0 -1 vn -0 -0 -1 vn -0 -0 -1 f 20/20/20 19/19/19 17/17/17 18/18/18/18 v 0 0 20 v 20 0 20 v 0 20 20 v 20 20 20 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 F 24/24/24 23/23/23 22/21/21 22/22/22
enter code here
Solución
primero para responder a la pregunta en su título:
- Cargar cada archivo de objeto como una lista de vértices, asumo que ya hsve algún código para cargar archivos .OBJ en Python (si no, podría ajustar este Función LoadOBJ () por ejemplo, haz que devuelva la variable VERTS)
- Para cada objeto, calcule el cuadro delimitador, por ejemplo.:
def verts_to_bbox(verts): xs = [v[0] for v in verts] ys = [v[1] for v in verts] zs = [v[2] for v in verts] return (min(xs), max(xs), min(ys), max(ys), min(zs), max(zs))
ahora para probar si un objeto 'se ajusta' en el otro.Básicamente, quiere saber si un cuadro de límite es igual o menor que el otro en todas las dimensiones, como le entiendo. Entonces,
- calcular para cada cuadro delimitador su tamaño en x, y y z dimensión, por ejemplo,
def bbox_size(bbox): # return tuple with sizes (dx, dy, dz) return (bbox[1] - bbox[0], bbox[3] - bbox[2], bbox[5] - bbox[4]) def fits_bbox(bigbox, smallbox): bdx, bdy, bdz = bbox_size(bigbox) sdx, sdy, sdz = bbox_size(smallbox) # return True if small box fits in bigbox in all three dimensions return (sdx<bdx and sdy<bdy and sdz<bdz)
buena suerte!
- calcular para cada cuadro delimitador su tamaño en x, y y z dimensión, por ejemplo,
Otros consejos
Querrá iterar a través de los datos de obj que buscan 'V y comprobando si las siguientes coordenadas x y y z y grabando el valor más alto y más bajo cada vez que lo encuentres.El siguiente código imprime el valor más alto y más bajo para cada dimensión y luego le da el cuadro delimitador de ese
obj = 'v -5 -5 0 v -5 -5 5 v 0 -5 0 v 0 -5 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 vn 0 -1 0 f 4/4/4 2/2/2 1/1/1 3/3/3 v 0 -5 0 v 0 -5 5 v 0 0 0 v 0 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 1 0 0 vn 1 0 0 vn 1 0 0 vn 1 0 0 f 8/8/8 6/6/6 5/5/5 7/7/7 v 0 0 0 v 0 0 5 v -5 0 0 v -5 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 1 0 vn 0 1 0 vn 0 1 0 vn 0 1 0 f 12/12/12 10/10/10 9/9/9 11/11/11 v -5 0 0 v -5 0 5 v -5 -5 0 v -5 -5 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn -1 0 0 vn -1 0 0 vn -1 0 0 vn -1 0 0 f 16/16/16 14/14/14 13/13/13 15/15/15 v -5 -5 0 v 0 -5 0 v -5 0 0 v 0 0 0 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 0 -1 vn 0 0 -1 vn 0 0 -1 vn 0 0 -1 f 20/20/20 18/18/18 17/17/17 19/19/19 v -5 -5 5 v -5 0 5 v 0 -5 5 v 0 0 5 vt 0 0 vt 0 1 vt 1 0 vt 1 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 vn 0 0 1 f 24/24/24 22/22/22 21/21/21 23/23/23'
elements = obj.split(' ')
x_min = 0.0
x_max = 0.0
y_min = 0.0
y_max = 0.0
z_min = 0.0
z_max = 0.0
i = 0
while i < len(elements):
if elements[i] == 'v':
#find min and max x value
if float(elements[i + 1]) < x_min:
x_min = float(elements[i + 1])
elif float(elements[i + 1]) > x_max:
x_max = float(elements[i + 1])
#find min and max y value
if float(elements[i + 2]) < y_min:
y_min = float(elements[i + 2])
elif float(elements[i + 2]) > y_max:
y_max = float(elements[i + 2])
#find min and max x value
if float(elements[i + 3]) < z_min:
z_min = float(elements[i + 3])
elif float(elements[i + 3]) > z_max:
z_max = float(elements[i + 3])
#incriment the counter int by 4 as we know the next 4 elements are not a vertex
i += 4
else:
i += 1
print 'x_min = ' + str(x_min)
print 'x_max = ' + str(x_max)
print 'y_min = ' + str(y_min)
print 'y_max = ' + str(y_max)
print 'z_min = ' + str(z_min)
print 'z_max = ' + str(z_max)
print ''
print 'x_widh = ' + (str(x_max - x_min))
print 'y_widh = ' + (str(y_max - y_min))
print 'z_widh = ' + (str(z_max - z_min))
y heres la salida que recibo
x_min = -5.0
x_max = 0.0
y_min = -5.0
y_max = 0.0
z_min = 0.0
z_max = 5.0
x_widh = 5.0
y_widh = 5.0
z_widh = 5.0
Espero que tenga sentido