-->

Menú principal

miércoles, 21 de diciembre de 2022

Diseño de una nave industrial con el programa OpenSCAD en 3D

 El programa OpenSCAD es un software para crear objetos CAD 3D sólidos.

Es un software gratuito y está disponible para Linux/UNIX, MS Windows y Mac OS X. En su página web dispone de amplios tutoriales, bibliotecas, libros, trucos, etc. Utiliza una serie de instrucciones para realizar las diferentes figuras en 3D. Lo mejor es empezar a practicar y ver su funcionamiento.
    El resultado que queremos obtener es una nave con cercha tipo Prat de 20 metros de longitud, seis pórticos separados 5 metros entre ellos y también vamos a dibujar las zapatas y la vigas de atado. Obtendremos una nave industrial similar a la que se muestra en la siguiente imagen:

    Para diseñar la nave industrial con cercha tipo Prat vamos a empezar dibujando los pilares del primer pórtico, para ello introducimos el primer comando que nos va a dibujar el pilar izquierdo, de esta forma:

cube ([20,20,600]);   

Con este comando obtenemos el primer pilar de seis metros de altura y de sección cuadrada de 20 cm de lado, situado en el origen de coordenadas.
    Procedemos a dibujar el pilar derecho situado a 20 metros de distancia con el comando:

translate ([2000,0,0]) cube ([20,20,600]);

Para ellos desplazamos el punto donde se va colocar el pilar mediante el comando "translate" y obtenmos el siguiente resultado al presionar el botón "Previsualizar":

    Ahora tenemos que dibujar el cordón inferior de la cercha, que será un larguero que une los dos pilares por su parte superior. Utilizamos el comando:

translate ([0,0,600]) cube ([2020,20,20]);

    Trasladamos el punto donde vamos a dibujar el larguero a la parte superior del primer pilar, y se verá:

    Ahora tenemos que dibujar el cordón superior, pero primero vamos a dibujar el montante central con una altura de 3 metros situado sobre el centro del cordón inferior, con el siguiente comando:

translate ([1000,0,600]) cube ([20,20,300]);

    Para ellos movemos el punto de arranque a 10 metros del eje X y a 6 metros en el eje Z, el resultado es:

    Ahora vamos a dibujar la parte izquierda del cordón superior con el siguiente comando:

translate ([0,0,600]) rotate([0,-16,0]) cube ([1055,20,20]);

    Hemos tenido que incorporar la sentencia rotate para girar el perfil 16 grados sobre el eje Y en sentido contrario a las agujas del reloj. La longitud del perfil nos da 10,55 metros. El resultado es:

    Ahora procedemos a dibujar la parte derecha del cordón superior, con el comando:

translate ([2020,0,620]) rotate([0,-164,0]) cube ([1055,20,20]);

    Para ello nos desplazamos a la parte superior del pilar derecho, y giramos 164º en sentido contrario a las agujas del reloj sobre el eje Y, obteniendo el siguiente resultado:

    Como vemos la cercha va tomando forma, ahora hay que dibujar los montantes y las diagonales.
//Primer montante izquierda
translate ([333,0,600]) cube ([20,20,110]);


//Segundo montante izquierda
translate ([666,0,600]) cube ([20,20,210]);


//Tercer montante derecha
translate ([1333,0,600]) cube ([20,20,210]);


//Cuarto montante derecha
translate ([1666,0,600]) cube ([20,20,110]);


Ahora dibujamos las diagonales que faltan, para ellos utilizamos los siguientes comandos:
//Primera diagonal izquierda
translate ([1020,0,620]) rotate([0,-151,0])cube ([380,20,20]);
//Primera diagonal derecha
translate ([1000,0,600]) rotate([0,-28,0])cube ([390,20,20]);
//Segunda diagonal izquierda
translate ([680,0,630]) rotate([0,-167,0])cube ([340,20,20]);
//Segunda diagonal derecha
translate ([1350,0,613]) rotate([0,-14,0])cube ([340,20,20]);


    Ahora tenemos que dibujar el segundo pórtico separado a cinco metros de distancia en el eje Y. Son las mismas instrucciones, solo tenemos que cambiar la coordenada Y a 500 en todos los comandos "translate".

//2º cercha
translate([0,500,0]) cube ([20,20,600]);
translate ([2000,500,0]) cube ([20,20,600]);
translate ([0,500,600]) cube ([2020,20,20]);
translate ([1000,500,600]) cube ([20,20,300]);
translate ([0,500,600]) rotate([0,-16,0]) cube ([1055,20,20]);
translate ([2020,500,620]) rotate([0,-164,0]) cube ([1055,20,20]);
translate ([333,500,600]) cube ([20,20,110]);
translate ([666,500,600]) cube ([20,20,210]);
translate ([1333,500,600]) cube ([20,20,210]);
translate ([1666,500,600]) cube ([20,20,110]);
translate ([1020,500,620]) rotate([0,-151,0]) cube ([380,20,20]);
translate ([1000,500,600]) rotate([0,-28,0]) cube ([390,20,20]);
translate ([680,500,630]) rotate([0,-167,0]) cube ([340,20,20]);
translate ([1350,500,613]) rotate([0,-14,0]) cube ([340,20,20]);


    Dibujamos el tercer pórtico cambiando la coordenada Y del comando "translate" a 1000 en todos:

//3º cercha
translate([0,1000,0]) cube ([20,20,600]);
translate ([2000,1000,0]) cube ([20,20,600]);
translate ([0,1000,600]) cube ([2020,20,20]);
translate ([1000,1000,600]) cube ([20,20,300]);
translate ([0,1000,600]) rotate([0,-16,0])cube ([1055,20,20]);
translate ([2020,1000,620]) rotate([0,-164,0])cube ([1055,20,20]);
translate ([333,1000,600]) cube ([20,20,110]);
translate ([666,1000,600]) cube ([20,20,210]);
translate ([1333,1000,600]) cube ([20,20,210]);
translate ([1666,1000,600]) cube ([20,20,110]);
translate ([1020,1000,620]) rotate([0,-151,0])cube ([380,20,20]);
translate ([1000,1000,600]) rotate([0,-28,0])cube ([390,20,20]);
translate ([680,1000,630]) rotate([0,-167,0])cube ([340,20,20]);
translate ([1350,1000,613]) rotate([0,-14,0])cube ([340,20,20]);


//4º cercha
translate([0,1500,0]) cube ([20,20,600]);
translate ([2000,1500,0]) cube ([20,20,600]);
translate ([0,1500,600]) cube ([2020,20,20]);
translate ([1000,1500,600]) cube ([20,20,300]);
translate ([0,1500,600]) rotate([0,-16,0])cube ([1055,20,20]);
translate ([2020,1500,620]) rotate([0,-164,0])cube ([1055,20,20]);
translate ([333,1500,600]) cube ([20,20,110]);
translate ([666,1500,600]) cube ([20,20,210]);
translate ([1333,1500,600]) cube ([20,20,210]);
translate ([1666,1500,600]) cube ([20,20,110]);
translate ([1020,1500,620]) rotate([0,-151,0])cube ([380,20,20]);
translate ([1000,1500,600]) rotate([0,-28,0])cube ([390,20,20]);
translate ([680,1500,630]) rotate([0,-167,0])cube ([340,20,20]);
translate ([1350,1500,613]) rotate([0,-14,0])cube ([340,20,20]);


//5º cercha
translate([0,2000,0]) cube ([20,20,600]);
translate ([2000,2000,0]) cube ([20,20,600]);
translate ([0,2000,600]) cube ([2020,20,20]);
translate ([1000,2000,600]) cube ([20,20,300]);
translate ([0,2000,600]) rotate([0,-16,0])cube ([1055,20,20]);
translate ([2020,2000,620]) rotate([0,-164,0])cube ([1055,20,20]);
translate ([333,2000,600]) cube ([20,20,110]);
translate ([666,2000,600]) cube ([20,20,210]);
translate ([1333,2000,600]) cube ([20,20,210]);
translate ([1666,2000,600]) cube ([20,20,110]);
translate ([1020,2000,620]) rotate([0,-151,0])cube ([380,20,20]);
translate ([1000,2000,600]) rotate([0,-28,0])cube ([390,20,20]);
translate ([680,2000,630]) rotate([0,-167,0])cube ([340,20,20]);
translate ([1350,2000,613]) rotate([0,-14,0])cube ([340,20,20]);


//6º cercha
translate([0,2500,0]) cube ([20,20,600]);
translate ([2000,2500,0]) cube ([20,20,600]);
translate ([0,2500,600]) cube ([2020,20,20]);
translate ([1000,2500,600]) cube ([20,20,300]);
translate ([0,2500,600]) rotate([0,-16,0])cube ([1055,20,20]);
translate ([2020,2500,620]) rotate([0,-164,0])cube ([1055,20,20]);
translate ([333,2500,600]) cube ([20,20,110]);
translate ([666,2500,600]) cube ([20,20,210]);
translate ([1333,2500,600]) cube ([20,20,210]);
translate ([1666,2500,600]) cube ([20,20,110]);
translate ([1020,2500,620]) rotate([0,-151,0])cube ([380,20,20]);
translate ([1000,2500,600]) rotate([0,-28,0])cube ([390,20,20]);
translate ([680,2500,630]) rotate([0,-167,0])cube ([340,20,20]);
translate ([1350,2500,613]) rotate([0,-14,0])cube ([340,20,20]);


    Ahora tenemos que dibujar las vigas de arriostramiento de los pórticos con los comandos:

//Vigas de arriostramiento
translate([0,0,600]) cube([20,2500,20]);
translate([2000,0,600]) cube([20,2500,20]);


    Ahora tenemos que dibujar las zapatas sobre las que se apoyan los pilares. Comenzamos por la parte izquierda de la nave con los siguientes comandos:

//Zapatas izquierda
translate([-50,-50,-60]) cube([120,120,60]);
translate([-50,450,-60]) cube([120,120,60]);
translate([-50,950,-60]) cube([120,120,60]);
translate([-50,1450,-60]) cube([120,120,60]);
translate([-50,1950,-60]) cube([120,120,60]);
translate([-50,2450,-60]) cube([120,120,60]);


//Zapatas derecha
translate([1950,-50,-60]) cube([120,120,60]);
translate([1950,450,-60]) cube([120,120,60]);
translate([1950,950,-60]) cube([120,120,60]);
translate([1950,1450,-60]) cube([120,120,60]);
translate([1950,1950,-60]) cube([120,120,60]);
translate([1950,2450,-60]) cube([120,120,60]);


    Continuamos con las vigas de atados de las zapatas de la parte izquierda:

//Vigas de atado de zapatas izquierda
translate([0,0,-30]) cube([30,500,30]);
translate([0,500,-30]) cube([30,500,30]);
translate([0,1000,-30]) cube([30,500,30]);
translate([0,1500,-30]) cube([30,500,30]);
translate([0,2000,-30]) cube([30,500,30]);


//Vigas de atado de zapatas derecha
translate([2000,0,-30]) cube([30,500,30]);
translate([2000,500,-30]) cube([30,500,30]);
translate([2000,1000,-30]) cube([30,500,30]);
translate([2000,1500,-30]) cube([30,500,30]);
translate([2000,2000,-30]) cube([30,500,30]);


    Ahora tenemos que dibujar los pilares del pórtico frontal con sus zapatas y sus vigas de atado:

//Pilares pórtico frontal
translate ([666,0,0]) cube ([20,20,600]);
translate ([1333,0,0]) cube ([20,20,600]);
//Zapatas pilares pórtico frontales
translate([615,-50,-60]) cube([120,120,60]);
translate([1280,-50,-60]) cube([120,120,60]);
//Vigas de atado zapatas frontales
translate([0,0,-30]) cube([660,30,30]);
translate([660,0,-30]) cube([660,30,30]);
translate([1330,0,-30]) cube([660,30,30]);


    Hacemos lo mismo con el pórtico trasero:

//Pilares traseros
translate ([666,2500,0]) cube ([20,20,600]);
translate ([1333,2500,0]) cube ([20,20,600]);
//Zapatas pilares traseros
translate([615,2450,-60]) cube([120,120,60]);
translate([1280,2450,-60]) cube([120,120,60]);
//Vigas de atado traseras
translate([0,2500,-30]) cube([660,30,30]);
translate([660,2500,-30]) cube([660,30,30]);
translate([1330,2500,-30]) cube([660,30,30]);


    Ahora tenemos que dibujar las placas de asiento de los pilares sobre las zapatas. Comenzamos por la del primer pilar de la izquierda y lo vemos en detalle:

//Placas de asiento
translate([-15,-15,0]) cube([50,50,3]);
translate([-15,485,0]) cube([50,50,3]);
translate([-15,985,0]) cube([50,50,3]);
translate([-15,1485,0]) cube([50,50,3]);
translate([-15,1985,0]) cube([50,50,3]);
translate([-15,2485,0]) cube([50,50,3]);
translate([650,2485,0]) cube([50,50,3]);
translate([1317,2485,0]) cube([50,50,3]);
translate([1985,2485,0]) cube([50,50,3]);
translate([1985,1985,0]) cube([50,50,3]);
translate([1985,1485,0]) cube([50,50,3]);
translate([1985,985,0]) cube([50,50,3]);
translate([1985,485,0]) cube([50,50,3]);
translate([1985,-15,0]) cube([50,50,3]);
translate([1317,-15,0]) cube([50,50,3]);
translate([650,-15,0]) cube([50,50,3]);


    El ejercicio continua dibujando el resto de las placas de asiento y sus correspondientes rigidizadores. También tenemos que añadir las correas, un forjado a 4 metros de altura para oficinas y sus escaleras.


PARAMETRIZACIÓN Y OPTIMIZACIÓN DEL CÓDIGO

    Este ejemplo utiliza demasiadas líneas de código. Para reducir el código vamos a parametrizar los valores de la geometría de la nave, lo cual nos permitirá aumentar o reducir la luz o longitud de la cercha, de los pilares, el ángulo de inclinación del cordón superior, el número de pórticos, etc.
    Este programa es una maravilla ya que con pocas líneas de código podemos generar objetos tridimensionales de gran realismo y poder verlos desde cualquier posición, girando o aumentando el punto de vista de una forma sencilla con un solo movimiento del ratón o el teclado.
    OpenSCAD es un programa especialmente diseñado para programadores y diseñadores en 3D. Si a esto sumamos la pasión por el diseño de estructuras metálicas, de madera o de hormigón, esto nos permitirá hacer vistosos diseños en 3D de grandes y originales estructuras, que luego pueden ser calculadas en programas especializados de cálculo y diseño de estructuras como CYPE.
    Vamos a generar una nave industrial utilizando código parametrizado u reducido para ver como obtenemos el mismo resultado que en el caso anterior con muchas menos líneas de código. Utilizaremos las siguientes variables para usarlas como parámetros de los comandos de OpenSCAD:

a=150;                                     // Ancho perfil
b=150;                                     // Largo perfil
h=7000;                                   // Altura de pilares
luz=24000;                              // Luz del pórtico
nv=6;                                       // Número de vanos
av=1100;                                 // Ancho de la celosía
alfa=10;                                  // Ángulo cordón superior
lcs=(luz/2+a/3)/cos(alfa);       // Longitud cordón superior
lmc=(luz/2)*sin(alfa);            // Longitud montante central
lv=luz/nv;                               // Longitud de cada vano
hv=lv/cos(alfa)*sin(alfa);      // Avance vertical de cada cordón
np=6;                                      // Número de pórticos
sp=5000;                                // Separación entre pórticos
lgt=np*sp;                             // Longitud total de la nave

    La modificación de alguno de estos parámetros hace que la nave se redibuje y tome la nueva forma según los valores introducidos. El siguiente código optimizado nos permitirá dibujar cada uno de los pórticos utilizando el mismo código para todas las cerchas o celosías. Para ello utilizamos la función "for":

for (i=[0:sp:lgt]) {
  translate([0,i,0]) cube([a,b,h+av]); //pilar izquierdo
  translate([luz,i,0]) cube([a,b,h+av]); //pilar derecho
  translate([0,i,h]) cube([luz+a,a,b]); //Cordón inferior
  translate([luz/2,i,h+a/2]) cube([a,b,lmc+av-a/4]); //Montante central
  translate([a/4,i,h+av-a/4]) rotate ([0,-alfa,0]) cube([lcs,a,b]); //Cordón superior izquierda
  translate([luz/2+a/2,i,h+av+lmc]) rotate ([0,alfa,0]) cube([lcs,a,b]); //Cordón superior derecha
  translate([luz/nv,i,h]) rotate ([0,0,0]) cube([a,b,av+hv]); //Primer montante izquierda
  translate([luz/nv*2,i,h]) rotate ([0,0,0]) cube([a,b,av+2*hv]); //segundo montante izquierda
  translate([luz/nv*4,i,h]) rotate ([0,0,0]) cube([a,b,av+2*hv]); //Primer montante derecha
  translate([luz/nv*5,i,h]) rotate ([0,0,0]) cube([a,b,av+hv]); //Segundo montante derecha
  ld1=sqrt(av ^ 2+lv ^ 2); //longitud de la diagonal
  ad1=atan((lv+a)/(av-a)); //angulo de la diagonal
  if (av>200) {    
    translate([luz/nv+a/2,i,h+a/4]) rotate ([0,-ad1,0]) cube([a,b,ld1]); //primera diagonal izquierda
   }
  ld2=sqrt(lv ^ 2+(av+hv-a/2) ^ 2); //longitud de la diagonal
  ad2=atan((lv+a)/(av+hv-a/2)); //angulo de la diagonal
  translate([luz/nv*2+a/2,i,h+a/2]) rotate ([0,-ad2,0]) cube([a,b,ld2]); //segunda diagonal izquierda
  ld3=sqrt(lv ^ 2+(av+2*hv-a/2) ^ 2); //longitud de la diagonal
  ad3=atan((lv+a/2)/(av+2*hv-a/2)); //angulo de la diagonal
  translate([luz/2+a/4,i,h+a/2]) rotate ([0,-ad3,0]) cube([a,b,ld3]); //tercera diagonal izquierda
  translate([luz/2,i,h+a]) rotate ([0,ad3,0]) cube([a,b,ld3]); //primera diagonal derecha
  translate([luz/nv*4,i,h+a]) rotate ([0,ad2,0]) cube([a,b,ld2]); //segunda diagonal derecha
  if (av>200) { 
    translate([luz/nv*5,i,h+a]) rotate ([0,ad1,0]) cube([a,b,ld1]); //tercera diagonal derecha
  }
}

    El resultado obtenido es una nave con celosía tipo Prat y 7 pórticos:


    Podemos ocultar el editor, las líneas de comando y las botoneras, para mostrar el diseño obtenido a pantalla completa, o también exportar a una imagen, a pdf o a formatos compatibles con impresoras 3D, como stl, 3mf, amf, etc.

    Modificamos los valores de algunos parámetros para obtener una cercha sin ancho lateral. Modificamos la longitud de la celosía a 30 m, la altura de pilares a 8 m y el ancho de los perfiles tubulares cuadrados a 20x20 cm. Parametrizamos también la separación entre pórticos, obteniendo el siguiente resultado:

a=200; //ancho perfil
b=200; //largo perfil
h=8000; //altura de pilares
luz=30000; //Luz del pórtico
nv=6; // Número de vanos
av=100; //ancho de la celosía
alfa=15; //ángulo cordón superior
lcs=(luz/2+a/3)/cos(alfa); //longitud cordón superior
lmc=(luz/2)*sin(alfa); //longitud montante central
lv=luz/nv; //longitud de cada vano
hv=lv/cos(alfa)*sin(alfa); //avance vertical de cada cordón
np=6; //número de pórticos
sp=6000; // Separación entre pórticos en mm
lgt=np*sp; //longitud total de la nave



    Ahora tenemos que añadir las vigas de arriostramiento entre pórticos. Mediante el siguiente código obtenemos el resultado de la figura:

//Vigas de arriostramiento
translate([0,0,h]) cube([a,lgt,b]);
translate([luz,0,h]) cube([a,lgt,b]);
if (av>200) {    
 translate([0,0,h+av]) cube([a,lgt,b]);
 translate([luz,0,h+av]) cube([a,lgt,b]);
 for (k=[1:2:2*np]) {
  translate([0,k*(sp/2),h]) cube([a,b,av]);
  translate([luz,k*(sp/2),h]) cube([a,b,av]);
  fi=atan((sp/2)/(av-a/2)); // Ángulo diagonales laterales
  ldl=sqrt(av ^ 2+(sp/2) ^ 2); //Longitud diagonal lateral
  translate([luz,k*(sp/2),h+a]) rotate ([-fi,0,0]) cube([a,b,ldl]); //2ª Diagonal lateral derecha
  translate([luz,k*(sp/2),h+a/2]) rotate ([130-fi,0,0]) cube([a,b,ldl-a]); //1ª Diagonal lateral derecha
  translate([0,k*(sp/2),h+a/2]) rotate ([130-fi,0,0]) cube([a,b,ldl-a]); //1ª Diagonal lateral izquierda   
  translate([0,k*(sp/2),h+a]) rotate ([-fi,0,0]) cube([a,b,ldl]); //2ª Diagonal lateral izquierda   
  }   
 }


    Vamos a dibujar ahora las zapatas de ambos lados de pilares mediante el código mostrado. Para ello parametrizamos el ancho, largo y profundidad de las zapatas, que serán todas iguales en este diseño:

//Zapatas

az=1600; //Ancho de zapata
lz=1600; //Largo de zapata
alz=1000; //Alto de zapata
for (n=[1:sp:lgt+sp]) {
 translate([-az/2,n-lz/2,-alz]) cube([az,lz,alz]);
 translate([luz-az/2,n-lz/2,-alz]) cube([az,lz,alz]);   
}


    A continuación dibujamos las vigas de atado de zapatas:

//Vigas de atado de zapatas
ava=400; //Ancho vigas de atado
lva=400; //Alto vigas de atado
for (n=[1:sp:lgt]) {
  translate([-ava/2,n,-ava]) cube([ava,sp,lva]);
  translate([luz-ava/2,n,-ava]) cube([ava,sp,lva]);
}