O que image-to-figure faz?
Objetivo
A partir de uma imagem de personagem (uma ilustração, uma folha de conceito ou uma foto de uma figura) produzir uma figura 3D texturizada que corresponda ao personagem de todos os lados: um arquivo mestre do Blender, um GLB limpo, renders de revisão comparados com as vistas de virada e um vídeo turntable. O proprietário aprova os gastos e julga o visual; você conduz as etapas e detecta problemas antes que eles custem dinheiro.
Fora do escopo: rigging e animação, personagens sobre os quais o proprietário não possui direitos de uso e modelagem manual do personagem no Blender.
Concluído quando
views/view_front.png,view_left.png,view_back.png,view_right.pngexistem, todos do mesmo tamanho, provenientes deimg2fig cropcom código de saída 0.- Você comparou as quatro vistas com a imagem de referência e entre si, e relatou por escrito: cada acessório está no lado correto do corpo em cada vista, nada aparece que não esteja na referência (olhe com mais atenção para a vista traseira, bolsos, cintos e enfeites de cabelo), e a pose e a linha do chão correspondem entre as vistas. Qualquer diferença foi corrigida com
img2fig edite a folha foi recortada novamente antes da etapa do modelo. models/<provider>/model.glbexiste proveniente deimg2fig model --execute.img2fig prepterminou com código 0, suaorientationnão éambiguous(ou você confirmou que o render frontal está de frente para a câmera),prep.dimensions_units[2]está dentro de 0,01 de 2,9 eprep.faces_outestá igual ou abaixo de--faces(para entrada triangulada, como GLBs de provedores).- Você olhou para
renders/compare.jpg(vistas de entrada em cima, renders abaixo) erenders/face.png, e relatou por vista o que corresponde e o que não corresponde. turntable/turntable.mp4existe (img2fig turntable, código 0) se o proprietário desejou um vídeo.img2fig spendmostra um total dentro do que o proprietário aprovou.
Regras de gastos
- Comandos que chamam uma API paga (
lookdev,turnaround,edit,model) apenas exibem um plano e uma estimativa, a menos que--executeseja fornecido. Mostre a estimativa do plano ao proprietário e obtenha autorização, seja por chamada ou como um orçamento que ele definir; então passe esse orçamento como--budget(ou definaIMG2FIG_BUDGET_USD; sem nenhum dos dois, o limite é $5). O orçamento é verificado no ledger do diretório de trabalho (spend.json, resumido porimg2fig spend) antes de cada chamada paga, e a chamada é recusada (código de saída 3) se ultrapassar o limite. Chamadas com falha são registradas pelo valor da estimativa, pois algumas falham após o provedor ter cobrado. img2fig estimate --stages lookdev,turnaround,edit,modelprecifica uma execução completa. Ordem de grandeza típica: menos de $0,30 por chamada de imagem, $0,60 por modelo Tripo, cerca de $4 para um bake-off com quatro provedores. As estimativas erram para cima;cost_from_usage_usdem chamadas de imagem é o valor baseado em tokens.- Um bake-off (
--provider all) custa cerca de sete execuções do Tripo. Faça isso apenas quando o proprietário solicitar ou o Tripo falhar claramente neste personagem.
Fluxo de trabalho
img2fig doctor # chaves presentes? Blender, ffmpeg encontrados?
img2fig lookdev --ref character.png --description "..." # plano; adicione --execute após aprovação
img2fig turnaround --ref character.png --description "..." # usa a imagem look-dev mais recente
img2fig crop # views/view_{front,left,back,right}.png
img2fig edit --fix "Vista traseira: remover o rabo redondo sob o laço; saia lisa ali." # apenas se necessário
img2fig crop # recortar novamente: pega a folha ou edição mais recente
img2fig model # Tripo, plano; --execute após aprovação
img2fig prep # orientar, normalizar, decimar, graduar, renders, compare.jpg
img2fig turntable # turntable/turntable.mp4
Todos os comandos compartilham --workdir DIR (padrão $IMG2FIG_WORKDIR ou ./figure_work); as entradas padrão são o arquivo mais recente do estágio anterior nesse diretório. Cada comando imprime um objeto JSON no stdout; leia ok, os caminhos, warning/warnings, next e, em caso de falha, error.type, error.message e error.detail (status HTTP e corpo do provedor, código de saída e final do stderr do Blender ou ffmpeg, caminho do log).
Códigos de saída: 0 ok (incluindo dry runs), 1 erro do provedor, 2 erro de uso, 3 orçamento excedido, 4 chave/binário/pacote ausente, 5 falha do Blender ou ffmpeg, 6 falha em uma verificação de resultado (a folha não foi dividida nas vistas esperadas), 7 bug interno.
Escrevendo --description
Liste o que a figura deve manter, com os lados indicados do ponto de vista do personagem e do visualizador entre colchetes: "clipe de cabelo de trevo verde no lado ESQUERDO dela (direita do visualizador na vista frontal)". Descreva o que a imagem de referência realmente mostra, não o que você pretendia gerar: modelos de imagem às vezes movem um acessório para o outro lado, e a referência vence.
Opções de preparação que importam
--rot auto(padrão) renderiza o modelo com sombreamento plano a 0/90/180/270 graus e compara cada um comview_front.png. Se o resultado for ambíguo, ele usa a orientação conhecida do provedor (conhecida apenas para o Tripo; caso contrário, a saída diz para verificar o render frontal). Passe--rot DEGpara substituir.--grade matte(padrão),light(roupas claras: brancos permanecem limpos),dark(escurece tecidos escuros),none.--keep-gloss 0.3mantém a rugosidade e metal original em partes que eram brilhantes na origem.--blush=X,Z(repetível) pinta um blush suave na bochecha em um ponto dado em frações da figura; obtenha X,Z medindo a bochecha emrenders/front.pnge executandoimg2fig point --x PX --y PY. Escreva valores negativos com=(--blush=-0,08,0,6), caso contrário o argparse os lê como opções.--faces(padrão 350000) limita a contagem de faces; as texturas normal e de cor mantêm detalhes finos.
Armadilhas conhecidas (todas observadas)
- O modelo de imagem inventa detalhes, e o modelo 3D os constrói. Uma virada de vista uma vez ganhou uma cauda de pompom nas costas e um distintivo nos bolsos da jaqueta que o personagem nunca teve; o modelo 3D reproduziu ambos fielmente. Corrija isso no estágio de imagem (
editcom um--fixpor problema, depoiscropemodelnovamente). Não conserte a malha. Uma primeira edição pode deixar uma invenção diferente para trás (o distintivo se tornou uma decoração em forma de cupcake), então compare novamente após cada edição. - Pequenos detalhes ficam borrados. Cada vista de uma folha de 3840x2160 tem apenas cerca de 1000 px de largura, então o rosto de um brinquedo de pelúcia ou os dedos saem suaves no modelo. Uma folha maior não está disponível; julgue o render do rosto e informe ao proprietário em vez de prometer pequenos detalhes nítidos.
- Provedores discordam sobre a orientação. Os GLBs do Tripo enfrentam +X após a importação (precisa de -90 graus). A verificação automática lida com isso; ainda assim, olhe para o render frontal.
- Uma graduação totalmente fosca (matte) mata partes de cristal e brilho. Use
--keep-glossou--grade nonequando o personagem tiver partes de cristal, metal ou patente. - Personagens processuais construídos à mão não atingem qualidade de figura. Um personagem modelado a partir de primitivas no Blender não conseguia acertar o cabelo orgânico; o modelo imagem-para-3D conseguiu. Não recorra à modelagem processual para formas orgânicas.
- AgX vs Standard. Os renders usam AgX por padrão: realces não estouram, mas materiais pálidos e brancos ficam acinzentados e menos saturados, e é por isso que as graduações aumentam a saturação.
--view-transform standardcorresponde mais de perto às cores de referência, mas estoura áreas claras. A verificação de orientação renderiza com Standard para que as cores sejam comparadas de forma justa. - sRGB vs linear no Blender. Ler cores de pixel de um PNG dentro do Blender (
Image.pixels) retornou valores sRGB codificados, não lineares. Decodifique antes de usá-los como cores lineares se você estender os scripts do Blender.
Recursos e limites
- As chaves vêm apenas de variáveis de ambiente:
OPENAI_API_KEY(estágios de imagem) eFAL_KEY(estágio de modelo). Nunca as imprima nem as escreva em arquivos. - Blender como binário externo (testado no 5.2; espera-se que o 4.2 ou mais recente funcione) (
blenderno PATH ouIMG2FIG_BLENDER); ffmpeg para o turntable. - O diretório de trabalho contém imagens geradas, modelos e renders do personagem do proprietário. Não publique, carregue ou faça commit deles a menos que o proprietário peça; trate personagens que o proprietário licenciou de outra pessoa como privados.
- Os prompts estão em
src/image_to_figure/prompts.py;--prompt-filesubstitui um modelo para uma chamada.
Impressão 3D
img2fig print transforma um modelo (padrão figure/figure_clean.glb; qualquer GLB, STL, OBJ ou PLY com --model; com --up auto, GLB/glTF/OBJ são lidos como Y-up e STL/PLY como Z-up) em um sólido pronto para impressão. Precisa do extra print (uv pip install -e '.[print]'); instalar pymeshlab também (GPL, não uma dependência) adiciona uma contagem explícita de autointersecção ao relatório.
img2fig print --height 100 --base pedestal # sólido, FDM ou resina
img2fig print --height 130 --base pedestal # FDM com partes finas: imprimir maior em vez de engrossar
img2fig print --height 100 --base pedestal --hollow 2.0 # resina: parede de 2 mm, furo(s) de drenagem
img2fig print --model raw_tripo.glb --rot -90 --height 80 # um GLB Tripo bruto enfrenta +X
Concluído quando: o comando termina com código 0 e checks.printable é verdadeiro (estanque, uma 2-variedade válida pelo manifold3d, volume positivo); checks.parts é 1 a menos que partes soltas tenham sido mantidas intencionalmente; checks.self_intersecting_faces é 0 quando foi medido; output.height_mm é igual a --height mais qualquer pedestal dentro de um voxel; você olhou para print/figure_section.png (paredes, cavidade e furos de drenagem) e os renders figure_preview_*.png, e relatou cada entrada em warnings, em particular partes finas (checks.wall_thickness: thin_part_volume_fraction, largest_thin_parts com suas posições em mm; relief_volume_fraction é detalhe de superfície fino, relatado mas nunca engrossado) e o que fazer sobre elas. Se --thicken foi usado, você comparou os renders de pré-visualização com uma execução sem espessamento e não viu novos relevos no rosto, cabelo ou acessórios; sem Blender (sem pré-visualizações), verifique que thicken.added_mm3 é da mesma ordem que wall_thickness_before.thin_part_volume_mm3 (os relevos aparecem como volume adicionado muito além disso) e olhe para a imagem da seção.
Como funciona: a superfície é voxelizada (voxel padrão = altura / 500), lacunas são seladas com o menor fechamento morfológico que envolve um interior (até 8 voxels; a etapa voxelize relata gap_closing_voxels) e o interior é preenchido, então bordas abertas, cascas sobrepostas e autointersecções desaparecem; um campo de distância com sinal então realiza o corte da base, pedestal, hollowing e furos de drenagem; marching cubes, suavização Taubin e manifold3d produzem a malha final. Detalhes menores que cerca de um voxel são perdidos, e partes mais próximas que a lacuna de fechamento se fundem.
Opções: --min-wall (padrão 1,0 mm; resina pode ir mais baixo, FDM geralmente quer 1,2 ou mais) define o que conta como fino; --thicken (desligado por padrão) engrossa partes finas até essa espessura, veja abaixo; --fragments merge|remove|keep com --merge-gap (padrão 2 mm) decide partes flutuantes: no modo merge, partes dentro da lacuna são anexadas com uma ponte e as mais distantes são mantidas e relatadas, nunca descartadas silenciosamente; migalhas abaixo de 1 mm3 são sempre removidas; --base flat|pedestal|none; --hollow WALL com --drain-hole perfura um furo por cavidade a partir de baixo (bolsos abaixo de 20 mm3 permanecem sólidos); --color escreve um PLY com cores de vértice a partir da textura do modelo para serviços coloridos. Os STL e 3MF são de cor única.
Partes finas. O relatório separa partes finas (folhas, aletas, fios, fitas e cordões que se projetam mais que --min-wall de um corpo mais grosso, com ambas as superfícies próximas) de relevo de superfície (linhas em relevo, bordas de fios, pequenos pontos e bordas convexas em um corpo grosso). Para FDM, prefira imprimir maior: cada parte fina escala com a figura (uma fita de 0,9 mm a 100 mm é 1,17 mm a 130 mm), nada é remodelado, e o tratamento de paredes finas do slicer (paredes Arachne, "detectar paredes finas") imprime a maior parte do que resta; uma fração de um por cento do volume abaixo da parede é normal e aceitável. Use --thicken quando o tamanho for fixo e algumas partes finas devem imprimir sólidas (um laço de fita, um ahoge, um cordão pendurado, uma bainha de saia): ele engrossa apenas partes finas, cada uma até cerca de --min-wall, e achata suas pontas; o relevo nunca é engrossado. Quando partes finas permanecem após --thicken, o aviso diz isso e sugere imprimir maior ou configurações do slicer, não outra execução. Bordas da definição: relevo que se eleva mais que --min-wall do corpo (uma crista alta e estreita, um fio em relevo profundo) conta como parte fina e fica cego; uma teia fina e curta atravessando uma lacuna entre duas partes grossas (até cerca de duas vezes --min-wall de largura) é relatada como relevo, e um slicer pode descartá-la e deixar um furo, então verifique as teias na pré-visualização do slicer. O crescimento vai em todas as direções, então --thicken também alonga as pontas ligeiramente e pode fundir partes finas que estão mais próximas que --min-wall.
Observado durante a construção: o campo de distância binária deixa terraços visíveis a menos que o resultado seja suavizado (Taubin, --smooth, padrão 10 iterações, mantém volume); projetar vértices de volta na superfície de origem, em vez disso, dobrou folhas finas e foi descartado. A suavização e simplificação de malha podem ambas introduzir autointersecções em regiões finas; o comando tenta menos suavização e tolerâncias mais apertadas até que a verificação esteja limpa e relata no que se estabeleceu (smooth_and_simplify step). Hollowing deve deixar bolsos não drenáveis sólidos, caso contrário eles se tornam vazios selados. Em uma figura real de imagem-para-3D, duas peças simétricas de 120 mm3 foram modeladas como cascas separadas a 1,3 mm do corpo; uma versão inicial as removeu porque estavam logo além de uma lacuna de fusão de 1 mm, e é por isso que partes distantes agora são mantidas e relatadas. Em uma figura real de 100 mm com --min-wall 1,2, um --thicken inicial cobriu o rosto, cabelo, laços e um acessório de pelúcia em pequenos relevos redondos: ele tratou tudo que uma bola de 1,2 mm não conseguia alcançar como fino, incluindo relevo raso, como bordas de fios, cílios em relevo e pontos, e engrossou cada um desses em 0,6 mm em cada lado (5,5% mais volume). Sem espessamento, o mesmo...