Restricción de distancia entre objetos en Blender

franalive - 20/10/2023 21:40
Hola, amigos. Me gustaría saber si hay alguna forma de establecer distancia entre varios objetos. Necesito que todos los objetos que tengo en escena estén a una distancia específica entre sí. Sé que existe la restricción de distancia, pero como allí debo seleccionar un objeto específico que quiero mantener esa distancia, no me sirve. Yo necesito algo más general, que en la escena todos los objetos tengan una distancia mínima entre ellos, entre todos los objetos de la escena, no solo uno en específico. Espero puedan ayudarme. Muchas gracias.
3dpoder - 21/10/2023 05:47
Podrías intentarlo con un script Python que debería establecer de forma automatizada la distancia entre objetos.

[CODE]import bpy

def mantener_distancia(objetos, distancia_minima):
for objeto in objetos:
for otro_objeto in objetos:
if objeto != otro_objeto:
distancia = objeto.location.distance_to(otro_objeto.location)
if distancia < distancia_minima:
objeto.location += otro_objeto.location - objeto.location * (distancia_minima - distancia)

if __name__ == "__main__":
objetos = bpy.data.objects
distancia_minima = 5
mantener_distancia(objetos, distancia_minima)
[/CODE]

Este código itera sobre todos los objetos de la escena y calcula la distancia entre cada par de objetos. Si la distancia es menor que la distancia mínima deseada, el script mueve uno de los objetos para que se aleje del otro.

Para utilizar este script, simplemente agrega el código a un archivo de Python. Luego, puedes ejecutar el script desde el menú Scripting > Run Script.

Un saludo.
3dpoder - 21/10/2023 05:55
Se puede hacer lo mismo mediante nodos. Para ello, podemos utilizar el nodo Distance para calcular la distancia entre dos objetos. Luego, podemos utilizar el nodo Vector Math para mover uno de los objetos para que se aleje del otro.

Aquí hay un ejemplo de cómo hacerlo:



El nodo Distance calculará la distancia entre el objeto actual y el objeto especificado. El nodo Vector Math calculará el vector que apunta desde el objeto actual al objeto especificado. El nodo Transform moverá el objeto actual en la dirección del vector calculado.


Sí, se puede hacer lo mismo mediante nodos. Para ello, podemos utilizar el nodo Distance para calcular la distancia entre dos objetos. Luego, podemos utilizar el nodo Vector Math para mover uno de los objetos para que se aleje del otro.

Aquí hay un ejemplo de cómo hacerlo:



El nodo Distance calculará la distancia entre el objeto actual y el objeto especificado. El nodo Vector Math calculará el vector que apunta desde el objeto actual al objeto especificado. El nodo Transform moverá el objeto actual en la dirección del vector calculado.

Aquí hay un ejemplo de un árbol de nodos que puedes utilizar:

[CODE]Geometry(object1) --> Distance --> Vector Math --> Transform(object1)
Geometry(object2) --> Distance --> Vector Math --> Transform(object2)[/CODE]

Este árbol de nodos moverá los objetos 1 y 2 para que se mantengan a una distancia mínima de 5 unidades.

Este es solo un ejemplo. Se puede modificar el árbol de nodos para adaptarlo a tus necesidades específicas. Por ejemplo, puedes agregar una lógica para evitar que los objetos se choquen entre sí.

Otras opciones

Además del método mencionado anteriormente, también puede utilizar los nodos Point Instancer o Instancer para establecer distancia entre varios objetos.

Point Instancer

El nodo Point Instancer puede utilizarse para crear una instancia de un objeto en cada punto de un objeto base. Puedes utilizar este nodo para crear una distribución uniforme de objetos.

Instancer

El nodo Instancer puede utilizarse para crear una instancia de un objeto en cada punto de un objeto base. Puedes utilizar este nodo para crear una distribución personalizada de objetos.

Un saludo.
3dpoder - 21/10/2023 05:58
El nodo Point Instancer puede utilizarse para crear una instancia de un objeto en cada punto de un objeto base. Puedes utilizar este nodo para crear una distribución uniforme de objetos.

Para establecer distancia entre objetos con Point Instancer, sigue estos pasos:



El nodo Point Instancer creará una instancia del objeto especificado en cada punto del objeto de forma base. La distancia entre cada instancia y el objeto de forma base será la distancia mínima especificada.

Aquí hay un ejemplo de cómo hacerlo:



El resultado será que el nodo Point Instancer creará 10 instancias del cubo en el plano, espaciadas a una distancia de 5 unidades entre sí.
Soliman - 21/10/2023 07:08
[video=youtube_share;-pNc0AS_Buc]https://youtu.be/-pNc0AS_Buc[/video]

[CODE]
import bpy
import math


# Lista de objetos seleccionados
selected_objects = bpy.context.selected_objects


if len(selected_objects) < 2:
print("Selecciona al menos dos objetos para mantener la distancia.")
else:
# Ordena los objetos por su posición en el eje especificado
selected_objects.sort(key=lambda obj: obj.location[0]) # Cambia [0] al eje que desees alinear (0:X, 1:Y, 2:Z)


# Distancia deseada entre los objetos
desired_distance = 5.0 # Cambia esto al valor de distancia que desees


# Posiciona los objetos para mantener la distancia deseada
for i in range(1, len(selected_objects)):
obj = selected_objects[i]
prev_obj = selected_objects[i - 1]


# Calcula la distancia actual entre los objetos
current_distance = (obj.location - prev_obj.location).length


# Calcula el desplazamiento necesario para mantener la distancia deseada
displacement = (desired_distance - current_distance)


# Aplica el desplazamiento al objeto actual
obj.location.x += displacement
[/CODE]

-- IMÁGENES ADJUNTAS --

🖼️

Estamos trabajando para mostrar las imágenes del foro

Adjunto #246754

3dpoder - 21/10/2023 10:52
El código que puse al principio, es el que se utilizaba en el addon Auto-Distance Between Objects, que ya no está disponible para descarga en GitHub, da error, pero supongo que según la versión que utilicemos, funcionará o no.
Soliman - 21/10/2023 15:46
[QUOTE=3dpoder;1021574]El código que puse al principio, es el que se utilizaba en el addon Auto-Distance Between Objects, que ya no está disponible para descarga en GitHub, da error, pero supongo que según la versión que utilicemos, funcionará o no.[/QUOTE]

El problema es ese, que como han ido cambiando los valores de Python, los scripts más antiguos ya no valen para versiones modernas... :(