¿Qué es STL?
STL — Stereolithography (también retroacrónimo de Standard Triangle Language o Standard Tessellation Language) — es el formato de archivo 3D más utilizado para la impresión 3D. Desarrollado por 3D Systems en 1987 para las primeras máquinas de estereolitografía comerciales, STL describe un modelo 3D como una malla de facetas triangulares, cada una definida por tres vértices y un vector normal de superficie.
La sencillez de STL es tanto su fortaleza como su limitación: almacena geometría pura sin información de color, textura, material, ensamblaje o unidades. Todo el software de corte para impresión 3D (PrusaSlicer, Cura, Bambu Studio, Chitubox) admite STL como su formato de entrada principal.
ASCII vs STL Binario
Los archivos STL vienen en dos variantes que difieren considerablemente en tamaño:
STL ASCII
El STL ASCII es legible por humanos pero verboso. Un solo triángulo ocupa seis líneas de texto:
solid cubo
facet normal 0.0 0.0 -1.0
outer loop
vertex 0.0 0.0 0.0
vertex 1.0 0.0 0.0
vertex 1.0 1.0 0.0
endloop
endfacet
...
endsolid cubo
STL Binario
El STL binario es mucho más compacto: 80 bytes de cabecera, luego un entero sin signo de 4 bytes para el recuento de triángulos, seguido de 50 bytes por triángulo (12 bytes de normal + 36 bytes para tres vértices + 2 bytes de atributo):
[80 bytes: cadena de cabecera ASCII]
[4 bytes: uint32 número de triángulos]
Para cada triángulo:
[12 bytes: float32[3] normal]
[12 bytes: float32[3] vértice 1]
[12 bytes: float32[3] vértice 2]
[12 bytes: float32[3] vértice 3]
[2 bytes: uint16 recuento de bytes de atributo — usualmente 0]
Una malla de 1.000 triángulos ocupa unos 5 KB en STL binario frente a ~100 KB en STL ASCII.
Trabajar con STL en Python
numpy-stl: Procesamiento Rápido
pip install numpy-stl
from stl import mesh
def analizar_stl(ruta: str) -> dict:
"""Carga un archivo STL y calcula estadísticas de geometría."""
m = mesh.Mesh.from_file(ruta)
volumen, cdg, inercia = m.get_mass_properties()
minimos = m.vectors.min(axis=(0, 1))
maximos = m.vectors.max(axis=(0, 1))
dimensiones = maximos - minimos
return {
'triangulos': len(m.vectors),
'volumen_mm3': abs(volumen),
'caja_delimitadora': {
'x': float(dimensiones[0]),
'y': float(dimensiones[1]),
'z': float(dimensiones[2]),
},
}
print(analizar_stl('pieza.stl'))
Crear un Archivo STL Programáticamente
import numpy as np
from stl import mesh
def crear_cubo_stl(tamanio: float, ruta_salida: str) -> None:
"""Crea un cubo simple como archivo STL."""
vertices = __import__('numpy').array([
[0,0,0],[tamanio,0,0],[tamanio,tamanio,0],[0,tamanio,0],
[0,0,tamanio],[tamanio,0,tamanio],[tamanio,tamanio,tamanio],[0,tamanio,tamanio],
])
caras = __import__('numpy').array([
[0,1,2],[0,2,3],[4,5,6],[4,6,7],
[0,1,5],[0,5,4],[2,3,7],[2,7,6],
[0,3,7],[0,7,4],[1,2,6],[1,6,5],
])
cubo = mesh.Mesh(__import__('numpy').zeros(caras.shape[0], dtype=mesh.Mesh.dtype))
for i, cara in enumerate(caras):
for j in range(3):
cubo.vectors[i][j] = vertices[cara[j]]
cubo.save(ruta_salida)
print(f"Cubo STL guardado: {ruta_salida}")
crear_cubo_stl(tamanio=20.0, ruta_salida='cubo_20mm.stl')
trimesh: Operaciones Avanzadas de Malla
pip install trimesh
import trimesh
def verificar_malla(ruta: str) -> dict:
"""Carga STL, verifica estado manifold y calcula propiedades."""
modelo = trimesh.load(ruta)
problemas = []
if not modelo.is_watertight:
problemas.append("No es hermético: la malla tiene agujeros")
if not modelo.is_winding_consistent:
problemas.append("Enrollado inconsistente: algunas normales pueden estar invertidas")
if modelo.volume < 0:
problemas.append("Volumen negativo: normales apuntan hacia adentro")
if problemas:
trimesh.repair.fill_holes(modelo)
trimesh.repair.fix_normals(modelo)
return {
'listo_para_imprimir': len(problemas) == 0,
'problemas': problemas,
'triangulos': len(modelo.faces),
'volumen_mm3': abs(modelo.volume),
}
resultado = verificar_malla('modelo.stl')
for p in resultado['problemas']:
print(f" ⚠ {p}")
# Exportar a otros formatos
modelo = trimesh.load('modelo.stl')
modelo.export('modelo.obj')
modelo.export('modelo.ply')
El Requisito Manifold para la Impresión 3D
Para que una impresora 3D corte un STL correctamente, la malla debe ser hermética (manifold): cada arista debe ser compartida exactamente por dos triángulos, no debe haber agujeros en la superficie, y las normales deben apuntar todas hacia afuera de forma consistente.
Problemas comunes de malla:
| Problema | Síntoma | Solución |
|---|---|---|
| Límites abiertos (agujeros) | El cortador reporta "aristas no-manifold" | Rellenar agujeros en Meshmixer, MeshLab o trimesh |
| Normales invertidas | El cortador muestra superficies interiores | Recalcular normales en Blender o trimesh |
| Vértices duplicados | Inflación en estadísticas de malla | Fusionar vértices por distancia |
| Autointersecciones | Artefactos en el corte | Reparación booleana en Meshmixer o Blender |
Convertir STL a Otros Formatos
# STL a OBJ con Python trimesh
python3 -c "import trimesh; trimesh.load('modelo.stl').export('modelo.obj')"
# STL a PLY
python3 -c "import trimesh; trimesh.load('modelo.stl').export('modelo.ply')"
STL a 3MF (Formato Rico para Impresión 3D)
3MF (3D Manufacturing Format) es el sustituto moderno de STL: admite color, materiales, múltiples objetos y unidades.
import trimesh
modelo = trimesh.load('modelo.stl')
escena = trimesh.scene.Scene({'modelo': modelo})
escena.export('modelo.3mf')
Software de Corte para Impresión 3D
El flujo de trabajo desde STL hasta el objeto impreso implica un cortador (slicer):
- Cargar STL → colocar en la plataforma de impresión virtual
- Configurar parámetros: altura de capa, % de relleno, soportes, adhesión a la cama
- Cortar → generar G-code (instrucciones de trayectoria para la impresora)
- Enviar G-code a la impresora
Cortadores populares y sus características STL:
- PrusaSlicer — gratuito, código abierto, excelentes herramientas de reparación
- Bambu Studio — optimizado para impresoras Bambu Lab, corte rápido
- Ultimaker Cura — gratuito, amplio soporte de impresoras, plugins
- Chitubox — impresoras de resina (SLA/MSLA)
Guía de Tamaño de Archivo y Número de Triángulos
| Complejidad del objeto | Recuento típico de triángulos | Tamaño STL binario |
|---|---|---|
| Pieza mecánica simple | 500–5.000 | 25–250 KB |
| Figurilla detallada | 50.000–500.000 | 2,5–25 MB |
| Escaneo de alta detalle | 1M–10M | 50–500 MB |
| Objeto práctico imprimible | 5.000–100.000 | 250 KB–5 MB |
Conversiones relacionadas
Conversiones frecuentes del catálogo: