¿Qué hace image-to-figure?
Objetivo
A partir de una imagen de personaje (una ilustración, una hoja de concepto o una foto de una figura) producir una figura 3D texturizada que coincida con el personaje desde todos los lados: un archivo maestro de Blender, un GLB limpio, renders de revisión comparados con las vistas de rotación y un video turntable. El propietario aprueba el gasto y juzga el resultado; tú diriges las etapas y detectas problemas antes de que cuesten dinero.
No está incluido: rigging y animación, personajes para los que el propietario no tiene derechos de uso, y modelado manual del personaje en Blender.
Listo cuando
views/view_front.png,view_left.png,view_back.png,view_right.pngexisten, todos del mismo tamaño, deimg2fig cropcon código de salida 0.- Has comparado las cuatro vistas con la imagen de referencia y entre sí, e informado por escrito: cada accesorio está en el lado correcto del cuerpo en cada vista, no aparece nada que no esté en la referencia (presta especial atención a la vista trasera, bolsillos, cinturones y adornos para el cabello), y la pose y la línea de suelo coinciden entre las vistas. Cualquier diferencia se corrigió con
img2fig edity la hoja se recortó de nuevo antes de la etapa de modelo. models/<provider>/model.glbexiste deimg2fig model --execute.img2fig prepsalió con 0, suorientationno esambiguous(o confirmaste que el render frontal mira hacia la cámara),prep.dimensions_units[2]está dentro de 0.01 de 2.9, yprep.faces_outestá en o por debajo de--faces(para entrada triangulada como GLBs de proveedores).- Has mirado
renders/compare.jpg(vistas de entrada arriba, renders debajo) yrenders/face.png, e informado por vista qué coincide y qué no. turntable/turntable.mp4existe (img2fig turntable, salida 0) si el propietario quería un video.img2fig spendmuestra un total dentro de lo aprobado por el propietario.
Reglas de gasto
- Los comandos que llaman a una API de pago (
lookdev,turnaround,edit,model) solo imprimen un plan y una estimación a menos que se dé--execute. Muestra la estimación del plan al propietario y obtén una autorización, ya sea por llamada o como un presupuesto que establezcan; luego pasa ese presupuesto como--budget(o estableceIMG2FIG_BUDGET_USD; sin ninguno, el límite es $5). El presupuesto se verifica contra el libro de contabilidad del directorio de trabajo (spend.json, resumido porimg2fig spend) antes de cada llamada de pago, y la llamada se rechaza (salida 3) si superaría el límite. Las llamadas fallidas se registran con su estimación, ya que algunas fallan después de que el proveedor las ha facturado. img2fig estimate --stages lookdev,turnaround,edit,modelcotiza una ejecución completa. Orden de magnitud típico: menos de $0.30 por llamada de imagen, $0.60 por modelo Tripo, alrededor de $4 para un bake-off de cuatro proveedores. Las estimaciones son elevadas;cost_from_usage_usden las llamadas de imagen es la cifra basada en tokens.- Un bake-off (
--provider all) cuesta alrededor de siete ejecuciones de Tripo. Hazlo solo cuando el propietario lo solicite o Tripo falle claramente con este personaje.
Flujo de trabajo
img2fig doctor # ¿claves presentes? ¿Blender, ffmpeg encontrados?
img2fig lookdev --ref character.png --description "..." # plan; añade --execute después de la aprobación
img2fig turnaround --ref character.png --description "..." # usa la última imagen de look-dev
img2fig crop # views/view_{front,left,back,right}.png
img2fig edit --fix "Vista trasera: quitar la cola redonda debajo del lazo; falda lisa allí." # solo si es necesario
img2fig crop # recortar de nuevo: toma la hoja o edición más reciente
img2fig model # Tripo, plan; --execute después de la aprobación
img2fig prep # orientar, normalizar, decimar, gradar, renders, compare.jpg
img2fig turntable # turntable/turntable.mp4
Todos los comandos comparten --workdir DIR (por defecto $IMG2FIG_WORKDIR o ./figure_work); las entradas por defecto son el archivo más reciente de la etapa anterior en ese directorio. Cada comando imprime un objeto JSON en stdout; lee ok, las rutas, warning/warnings, next, y en caso de fallo error.type, error.message y error.detail (código de estado HTTP y cuerpo del proveedor, código de salida de Blender o ffmpeg y cola de stderr, ruta del registro).
Códigos de salida: 0 ok (incluyendo ejecuciones en seco), 1 error del proveedor, 2 error de uso, 3 presupuesto excedido, 4 falta clave/binario/paquete, 5 fallo de Blender o ffmpeg, 6 fallo en verificación de resultado (la hoja no se dividió en las vistas esperadas), 7 error interno.
Escribir --description
Enumera lo que la figura debe mantener, indicando los lados desde el punto de vista del personaje y del espectador entre corchetes: "clip para el cabello de trébol verde en su lado IZQUIERDO (derecha del espectador en la vista frontal)". Describe lo que la imagen de referencia realmente muestra, no lo que pretendías generar: los modelos de imagen a veces mueven un accesorio al otro lado, y la referencia es la que gana.
Opciones de preparación que importan
--rot auto(por defecto) renderiza el modelo con sombreado plano a 0/90/180/270 grados y compara cada uno conview_front.png. Si el resultado es ambiguo, recurre a la orientación conocida del proveedor (conocida solo para Tripo; de lo contrario, la salida indica que se verifique el render frontal). Pasa--rot DEGpara sobrescribir.--grade matte(por defecto),light(atuendos pálidos: los blancos se mantienen limpios),dark(oscurece la tela oscura),none.--keep-gloss 0.3mantiene la rugosidad y metalicidad originales en partes que eran brillantes en la fuente.--blush=X,Z(repetible) pinta un rubor de mejilla suave en un punto dado en fracciones de figura; obtén X,Z midiendo la mejilla enrenders/front.pngy ejecutandoimg2fig point --x PX --y PY. Escribe valores negativos con=(--blush=-0.08,0.6), de lo contrario argparse los lee como opciones.--faces(por defecto 350000) limita el número de caras; las texturas normal y de color mantienen el detalle fino.
Errores conocidos (todos observados)
- El modelo de imagen inventa detalles, y el modelo 3D los construye. Una vez, un turnaround ganó una cola de pompón en la espalda y una insignia en los bolsillos de la chaqueta que el personaje nunca tuvo; el modelo 3D reprodujo ambos fielmente. Soluciona esto en la etapa de imagen (
editcon un--fixpor problema, luegocropymodelde nuevo). No parchees la malla. Una primera edición puede dejar otra invención diferente (la insignia se convirtió en una decoración con forma de cupcake), así que compara de nuevo después de cada edición. - Los detalles pequeños se difuminan. Cada vista de una hoja de 3840x2160 solo tiene unos 1000 px de ancho, por lo que la cara de un peluche o los dedos salen suaves en el modelo. No hay una hoja más grande disponible; juzga el render de la cara e informa al propietario en lugar de prometer detalles pequeños nítidos.
- Los proveedores no se ponen de acuerdo en la orientación. Los GLB de Tripo miran hacia +X después de importar (necesitan -90 grados). La verificación automática lo maneja; aun así, mira el render frontal.
- Un acabado completamente mate elimina las partes de cristal y brillo. Usa
--keep-glosso--grade nonecuando el personaje tenga partes de cristal, metal o charol. - Los personajes procedurales hechos a mano no alcanzan la calidad de figura. Un personaje modelado de primitivas en Blender no pudo conseguir el cabello orgánico correctamente; el modelo de imagen a 3D sí lo hizo. No recurras al modelado procedural para formas orgánicas.
- AgX vs Standard. Los renders usan AgX por defecto: los reflejos no se recortan, pero los materiales pálidos y blancos se vuelven grisáceos y menos saturados, por lo que los acabados elevan la saturación.
--view-transform standardcoincide más de cerca con los colores de referencia pero recorta las áreas brillantes. La verificación de orientación renderiza con Standard para que los colores se comparen de manera justa. - sRGB vs lineal en Blender. Leer colores de píxeles de un PNG dentro de Blender (
Image.pixels) devolvió valores sRGB codificados, no lineales. Decodifica antes de usarlos como colores lineales si extiendes los scripts de Blender.
Recursos y límites
- Las claves provienen solo de variables de entorno:
OPENAI_API_KEY(etapas de imagen) yFAL_KEY(etapa de modelo). Nunca las imprimas ni las escribas en archivos. - Blender como binario externo (probado en 5.2; se espera que funcione 4.2 o más reciente) (
blenderen PATH oIMG2FIG_BLENDER); ffmpeg para el turntable. - El directorio de trabajo contiene imágenes, modelos y renders generados del personaje del propietario. No publiques, subas ni confirmes a menos que el propietario lo solicite; trata los personajes que el propietario ha licenciado de otra persona como privados.
- Los prompts están en
src/image_to_figure/prompts.py;--prompt-filereemplaza una plantilla para una llamada.
Impresión 3D
img2fig print convierte un modelo (por defecto figure/figure_clean.glb; cualquier GLB, STL, OBJ o PLY con --model; con --up auto, GLB/glTF/OBJ se leen como Y-up y STL/PLY como Z-up) en un sólido listo para imprimir. Necesita el extra print (uv pip install -e '.[print]'); instalar también pymeshlab (GPL, no una dependencia) añade un recuento explícito de auto-intersecciones al informe.
img2fig print --height 100 --base pedestal # sólido, FDM o resina
img2fig print --height 130 --base pedestal # FDM con partes delgadas: imprime más grande en lugar de engrosar
img2fig print --height 100 --base pedestal --hollow 2.0 # resina: pared de 2 mm, agujero(s) de drenaje
img2fig print --model raw_tripo.glb --rot -90 --height 80 # un GLB Tripo crudo mira hacia +X
Listo cuando: el comando sale con 0 y checks.printable es verdadero (hermético, una 2-variedad válida por manifold3d, volumen positivo); checks.parts es 1 a menos que las partes sueltas se mantuvieran a propósito; checks.self_intersecting_faces es 0 cuando se midió; output.height_mm es igual a --height más cualquier pedestal dentro de un vóxel; has mirado print/figure_section.png (paredes, cavidad y agujeros de drenaje) y los renders figure_preview_*.png, e informado cada entrada en warnings, en particular partes delgadas (checks.wall_thickness: thin_part_volume_fraction, largest_thin_parts con sus posiciones en mm; relief_volume_fraction es detalle superficial fino, informado pero nunca engrosado) y qué hacer al respecto. Si se usó --thicken, comparaste los renders de vista previa con una ejecución sin engrosar y no viste nuevos bultos en la cara, cabello o accesorios; sin Blender (sin vistas previas), verifica que thicken.added_mm3 sea del mismo orden que wall_thickness_before.thin_part_volume_mm3 (los bultos aparecen como volumen añadido mucho más allá) y mira la imagen de sección.
Cómo funciona: la superficie se voxeliza (vóxel por defecto = altura / 500), los espacios se sellan con el cierre morfológico más pequeño que encierra un interior (hasta 8 vóxeles; el paso voxelize informa gap_closing_voxels) y el interior se rellena, por lo que los bordes abiertos, las capas superpuestas y las auto-intersecciones desaparecen; un campo de distancia con signo realiza entonces el corte de base, pedestal, ahuecado y agujeros de drenaje; marching cubes, suavizado Taubin y manifold3d producen la malla final. Los detalles más pequeños que aproximadamente un vóxel se pierden, y las partes más cercanas que el espacio de cierre se fusionan.
Opciones: --min-wall (por defecto 1.0 mm; resina puede ir más bajo, FDM normalmente quiere 1.2 o más) establece qué cuenta como delgado; --thicken (desactivado por defecto) engrosa las partes delgadas hasta ese grosor, ver más abajo; --fragments merge|remove|keep con --merge-gap (por defecto 2 mm) decide las partes flotantes: en modo merge las partes dentro del espacio se unen con un puente y las más lejanas se mantienen e informan, nunca se eliminan silenciosamente; las migas menores de 1 mm3 siempre se eliminan; --base flat|pedestal|none; --hollow WALL con --drain-hole perfora un agujero por cavidad desde abajo (los bolsillos menores de 20 mm3 permanecen sólidos); --color escribe un PLY con color de vértice desde la textura del modelo para servicios de color completo. Los STL y 3MF son de un solo color.
Partes delgadas. El informe separa las partes delgadas (láminas, aletas, hebras, cintas y cordones que sobresalen más de --min-wall de un cuerpo más grueso, con ambas superficies cercanas) del relieve superficial (líneas en relieve, bordes de hebras, puntos pequeños y bordes convexos en un cuerpo grueso). Para FDM, prefiere imprimir más grande: cada parte delgada escala con la figura (una cinta de 0.9 mm a 100 mm es 1.17 mm a 130 mm), nada se remodela, y el manejo de paredes delgadas del laminador (paredes Arachne, "detectar paredes delgadas") imprime la mayoría de lo que queda; una fracción de un porcentaje del volumen bajo la pared es normal y está bien. Usa --thicken cuando el tamaño esté fijo y algunas partes delgadas deban imprimirse sólidas (un lazo de cinta, un mechón, un cordón colgante, un borde de falda): engrosa solo las partes delgadas, cada una hasta aproximadamente --min-wall, y desafila sus puntas; el relieve nunca se engrosa. Cuando quedan partes delgadas después de --thicken, la advertencia lo dice y sugiere imprimir más grande o ajustes del laminador, no otra ejecución. Bordes de la definición: el relieve que se eleva más de --min-wall del cuerpo (una cresta alta y estrecha, una hebra en relieve profunda) cuenta como parte delgada y se desafila; una red delgada corta que abarca un espacio entre dos partes gruesas (hasta aproximadamente dos veces --min-wall de ancho) se informa como relieve, y un laminador puede dejarla caer y dejar un agujero, así que verifica las redes en la vista previa del laminador. El crecimiento va en todas direcciones, por lo que --thicken también alarga ligeramente las puntas y puede fusionar partes delgadas que están más cerca que --min-wall.
Observado durante su construcción: el campo de distancia binario deja terrazas visibles a menos que el resultado se suavice (Taubin, --smooth, por defecto 10 iteraciones, mantiene el volumen); proyectar vértices de nuevo sobre la superficie fuente en su lugar dobló láminas delgadas y fue descartado. El suavizado y la simplificación de malla pueden introducir auto-intersecciones en regiones delgadas; el comando prueba menos suavizado y tolerancias más estrictas hasta que la verificación quede limpia e informa en qué se decidió (paso smooth_and_simplify). El ahuecado debe dejar sólidos los bolsillos que no se pueden drenar, de lo contrario se convierten en vacíos sellados. En una figura real de imagen a 3D, dos piezas simétricas de 120 mm3 fueron modeladas como capas separadas a 1.3 mm del cuerpo; una versión temprana las eliminó porque estaban justo más allá de un espacio de fusión de 1 mm, por lo que ahora las partes distantes se mantienen e informan en su lugar. En una figura real de 100 mm con --min-wall 1.2, un --thicken temprano cubrió la cara, el cabello, los lazos y un accesorio de peluche con pequeños bultos redondos: trató todo lo que una bola de 1.2 mm no podía alcanzar como delgado, incluido el relieve superficial como bordes de hebras, pestañas en relieve y puntos, y creció cada uno de esos en 0.6 mm en cada lado (5.5% más de volumen). Sin engrosar, los renders se veían...