hmm é um utilidade de oito metros .
Se você fez algum desenvolvimento de jogo em 3D, impressão 3D ou outras coisas dessas coisas, provavelmente quis converter uma imagem em escala de cinza em uma malha 3D. A maneira ingênua é bem simples, mas gera enormes malhas com milhões de triângulos. Depois de invadir várias soluções ao longo dos anos, finalmente decidi que precisava escrever uma boa ferramenta para esse fim.
hmm é uma implementação moderna de um bom algoritmo da aproximação poligonal rápida de 1995 de terrenos e campos de altura por Garland e Heckbert. As malhas produzidas pelo hmm satisfazem a condição de Delaunay e podem satisfazer um erro máximo especificado ou número máximo de triângulos ou vértices. Também é muito rápido.
brew install glm # on macOS
sudo apt-get install libglm-dev # on Ubuntu / Debian
git clone https://github.com/fogleman/hmm.git
cd hmm
make
make install heightmap meshing utility
usage: hmm --zscale=float [options] ... infile outfile.stl
options:
-z, --zscale z scale relative to x & y (float)
-x, --zexagg z exaggeration (float [=1])
-e, --error maximum triangulation error (float [=0.001])
-t, --triangles maximum number of triangles (int [=0])
-p, --points maximum number of vertices (int [=0])
-b, --base solid base height (float [=0])
--level auto level input to full grayscale range
--invert invert heightmap
--blur gaussian blur sigma (int [=0])
--gamma gamma curve exponent (float [=0])
--border-size border size in pixels (int [=0])
--border-height border z height (float [=1])
--normal-map path to write normal map png (string [=])
--shade-path path to write hillshade png (string [=])
--shade-alt hillshade light altitude (float [=45])
--shade-az hillshade light azimuth (float [=0])
-q, --quiet suppress console output
-?, --help print this message
hmm suporta uma variedade de formatos de arquivo, como PNG, JPG, etc. para a entrada de altura de entrada. A saída é sempre um arquivo STL binário. O único outro parâmetro necessário é -z , que especifica quanto para dimensionar o eixo z na malha de saída.
$ hmm input.png output.stl -z ZSCALEVocê também pode fornecer um erro máximo permitido, número de triângulos ou número de vértices. (Se vários são especificados, o primeiro alcançado é usado.)
$ hmm input.png output.stl -z 100 -e 0.001 -t 1000000Clique na imagem abaixo para ver exemplos de vários argumentos da linha de comando. Você pode experimentar estes exemplos com este HightMap: Gale.png.
O parâmetro -z necessário define a distância entre um pixel totalmente preto e um pixel totalmente branco no eixo Z vertical, com unidades iguais a uma largura ou altura de pixel. Por exemplo, se cada pixel no HightMap representasse uma área quadrada de 1x1 metros, e a faixa vertical do mapa da altura foi de 100 metros, então -z 100 deve ser usada.
O parâmetro -x é simplesmente um multiplicador extra na parte superior da escala Z fornecida. É fornecido como uma conveniência, para que você não precise fazer multiplicação em sua cabeça apenas para exagerar, por exemplo, 2x, pois as escalas z são frequentemente derivadas de dados do mundo real e podem ter valores estranhos como 142.2378.
O parâmetro -e define o erro máximo permitido na malha de saída, como uma porcentagem da altura total da malha. Por exemplo, se -e 0.01 for usado, nenhum pixel terá um erro de mais de 1% da distância entre um pixel totalmente preto e um pixel totalmente branco. Isso significa que, para uma imagem de entrada de 8 bits, um erro de e = 1 / 256 ~= 0.0039 garantirá que nenhum pixel tenha um erro maior que uma unidade de escala de cinza completa. (Ainda pode ser desejável usar um valor mais baixo, como 0.5 / 256 )
Quando a opção -b é usada para criar uma malha sólida, ela define a altura da base antes que a parte mais baixa do altura apareça, como uma porcentagem da altura do altura do altura. Por exemplo, se -z 100 -b 0.5 fossem utilizados, a malha final seria de cerca de 150 unidades de altura (se existir um pixel totalmente branco na entrada).
Uma borda pode ser adicionada à malha com os sinalizadores --border-size e --border-height . O mapa da altura será acolchoado por pixels border-size antes de triangular. O valor Z (pré-escalado) da borda pode ser definido com border-height que padrão é 1.
Um desfoque gaussiano pode ser aplicado com a bandeira --blur . Isso é particularmente útil para imagens barulhentas.
O mapa da altura pode ser invertido com o sinalizador --invert . Isso é útil para litofanos.
O mapa da altura pode ser de nível automático com a bandeira --level . Isso esticará os valores de escala de cinza para usar toda a faixa preta => branca.
Uma curva gama pode ser aplicada ao altitude com a bandeira --gamma . Isso aplica x = x ^ gamma a cada pixel, onde x está em [0, 1].
Um mapa normal de resolução total pode ser gerado com o argumento --normal-map . Isso salvará um mapa normal como um PNG RGB no caminho especificado. Isso é útil para renderizar solavancos e detalhes de maior resolução, usando uma malha de triângulo de menor resolução.
Uma imagem em escala de cinza pode ser gerada com o argumento --shade-path . A altitude e o azimute da fonte de luz podem ser alterados com os argumentos --shade-alt e --shade-az , que são inadimplentes para 45 graus em altitude e 0 graus do norte (para cima).
O desempenho depende muito da quantidade de detalhes no HightMap, mas aqui estão alguns números para um exemplo de mapa de altura de uma área de 40x40 quilômetros centrada no Monte Everest. Várias resoluções em altura e erros máximos permitidos são mostrados. Times calculados em um MacBook Pro 2018 13 (MacBook Pro (2,7 GHz Intel Core i7).
| Tamanho / erro da imagem | e = 0,01 | e = 0,001 | e = 0,0005 | e = 0,0001 |
|---|---|---|---|---|
| 9490 x 9490 px (90,0 MP) | 6.535 | 13.102 | 19.394 | 58.949 |
| 4745 x 4745 px (22,5 MP) | 1.867 | 4.903 | 8.886 | 33.327 |
| 2373 x 2373 px (5,6 MP) | 0,559 | 2.353 | 4.930 | 14.243 |
| 1187 x 1187 px (1,4 MP) | 0,168 | 1.021 | 1.961 | 3.709 |
| Tamanho / erro da imagem | e = 0,01 | e = 0,001 | e = 0,0005 | e = 0,0001 |
|---|---|---|---|---|
| 9490 x 9490 px (90,0 MP) | 33.869 | 1.084.972 | 2.467.831 | 14.488.022 |
| 4745 x 4745 px (22,5 MP) | 33.148 | 1.032.263 | 2.323.772 | 11.719.491 |
| 2373 x 2373 px (5,6 MP) | 31.724 | 935.787 | 1.979.227 | 6.561.070 |
| 1187 x 1187 px (1,4 MP) | 27.275 | 629.352 | 1.160.079 | 2.347.713 |