Metadata
aliases: [Rendering traingle meshes is TikZ]
shorthands: {}
created: 2022-07-08 14:28:41
modified: 2022-07-08 14:38:19
In TikZ, we can draw triangle meshes from files that contain the mesh data
What's good about this method is that this results in a vector image, unlike in the case of plotly, but is much less flexible.
The source code for this figure is in LaTeX:
\begin{tikzpicture}
% the view can be set in the following line, it is hard to set it just right and the result might need some cropping anyway
\begin{axis}[axis equal,axis line style={draw=none}, tick style={draw=none},draw=none,axis lines=none,view={180}{50},rotate=180]
% indices.dat contains:
% # each row makes up one facet; it
% # consists of 0-based indices into
% # the vertex array
% 0 1 2 % triangle of vertices #0,#1 and #2
% 0 3 1 % triangle of vertices #0,#3 and #1
% 3 4 1
% 5 6 7
% 6 8 7
% 8 9 7
% 8 10 9
% ...
% while vertices.dat contains
% 105.577 -19.7332 2.85249 % vertex #0
% 88.9233 -21.1254 13.0359 % vertex #1
% 89.2104 -22.1547 1.46467 % vertex #2
% 105.577 -17.2161 12.146
% 105.577 -10.6054 18.7567
% 105.577 7.98161 18.7567
% 105.577 14.5923 12.146
% ...
\addplot3[patch,
patch table=
{figures/teapot/indices.dat}]
file
{figures/teapot/vertices.dat};
\end{axis}
\end{tikzpicture}
The format of the .dat files is described in the comments of the code snippet. We also need to import both tikz and pgfplots into
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
.dat filesThe described .dat files are not part of a standard, so we need to create them manually. I wrote a JavaScript program for this, which takes JSON, which was exported from MeshLab.
The source code for this small program is here, to be run in Node:
// Load the JSON file (specifying the extension is optional)
// The JSON must be exported from MeshLab
const mesh = require("./teapot_mesh");
const vertices = mesh.vertices[0].values;
const indices = mesh.connectivity[0].indices;
// Filesystem module in Node.js
const fs = require("fs");
let vcontent = "";
for (let i = 0; i < vertices.length; i += 3) {
vcontent += `<mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="9.903ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 4377 1000" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="MJX-1731-TEX-I-1D463" d="M173 380Q173 405 154 405Q130 405 104 376T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Q21 294 29 316T53 368T97 419T160 441Q202 441 225 417T249 361Q249 344 246 335Q246 329 231 291T200 202T182 113Q182 86 187 69Q200 26 250 26Q287 26 319 60T369 139T398 222T409 277Q409 300 401 317T383 343T365 361T357 383Q357 405 376 424T417 443Q436 443 451 425T467 367Q467 340 455 284T418 159T347 40T241 -11Q177 -11 139 22Q102 54 102 117Q102 148 110 181T151 298Q173 362 173 380Z"></path><path id="MJX-1731-TEX-I-1D452" d="M39 168Q39 225 58 272T107 350T174 402T244 433T307 442H310Q355 442 388 420T421 355Q421 265 310 237Q261 224 176 223Q139 223 138 221Q138 219 132 186T125 128Q125 81 146 54T209 26T302 45T394 111Q403 121 406 121Q410 121 419 112T429 98T420 82T390 55T344 24T281 -1T205 -11Q126 -11 83 42T39 168ZM373 353Q367 405 305 405Q272 405 244 391T199 357T170 316T154 280T149 261Q149 260 169 260Q282 260 327 284T373 353Z"></path><path id="MJX-1731-TEX-I-1D45F" d="M21 287Q22 290 23 295T28 317T38 348T53 381T73 411T99 433T132 442Q161 442 183 430T214 408T225 388Q227 382 228 382T236 389Q284 441 347 441H350Q398 441 422 400Q430 381 430 363Q430 333 417 315T391 292T366 288Q346 288 334 299T322 328Q322 376 378 392Q356 405 342 405Q286 405 239 331Q229 315 224 298T190 165Q156 25 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 114 189T154 366Q154 405 128 405Q107 405 92 377T68 316T57 280Q55 278 41 278H27Q21 284 21 287Z"></path><path id="MJX-1731-TEX-I-1D461" d="M26 385Q19 392 19 395Q19 399 22 411T27 425Q29 430 36 430T87 431H140L159 511Q162 522 166 540T173 566T179 586T187 603T197 615T211 624T229 626Q247 625 254 615T261 596Q261 589 252 549T232 470L222 433Q222 431 272 431H323Q330 424 330 420Q330 398 317 385H210L174 240Q135 80 135 68Q135 26 162 26Q197 26 230 60T283 144Q285 150 288 151T303 153H307Q322 153 322 145Q322 142 319 133Q314 117 301 95T267 48T216 6T155 -11Q125 -11 98 4T59 56Q57 64 57 83V101L92 241Q127 382 128 383Q128 385 77 385H26Z"></path><path id="MJX-1731-TEX-I-1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path><path id="MJX-1731-TEX-I-1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path><path id="MJX-1731-TEX-I-1D460" d="M131 289Q131 321 147 354T203 415T300 442Q362 442 390 415T419 355Q419 323 402 308T364 292Q351 292 340 300T328 326Q328 342 337 354T354 372T367 378Q368 378 368 379Q368 382 361 388T336 399T297 405Q249 405 227 379T204 326Q204 301 223 291T278 274T330 259Q396 230 396 163Q396 135 385 107T352 51T289 7T195 -10Q118 -10 86 19T53 87Q53 126 74 143T118 160Q133 160 146 151T160 120Q160 94 142 76T111 58Q109 57 108 57T107 55Q108 52 115 47T146 34T201 27Q237 27 263 38T301 66T318 97T323 122Q323 150 302 164T254 181T195 196T148 231Q131 256 131 289Z"></path><path id="MJX-1731-TEX-N-5B" d="M118 -250V750H255V710H158V-210H255V-250H118Z"></path><path id="MJX-1731-TEX-N-5D" d="M22 710V750H159V-250H22V-210H119V710H22Z"></path></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><use data-c="1D463" xlink:href="#MJX-1731-TEX-I-1D463"></use></g><g data-mml-node="mi" transform="translate(485,0)"><use data-c="1D452" xlink:href="#MJX-1731-TEX-I-1D452"></use></g><g data-mml-node="mi" transform="translate(951,0)"><use data-c="1D45F" xlink:href="#MJX-1731-TEX-I-1D45F"></use></g><g data-mml-node="mi" transform="translate(1402,0)"><use data-c="1D461" xlink:href="#MJX-1731-TEX-I-1D461"></use></g><g data-mml-node="mi" transform="translate(1763,0)"><use data-c="1D456" xlink:href="#MJX-1731-TEX-I-1D456"></use></g><g data-mml-node="mi" transform="translate(2108,0)"><use data-c="1D450" xlink:href="#MJX-1731-TEX-I-1D450"></use></g><g data-mml-node="mi" transform="translate(2541,0)"><use data-c="1D452" xlink:href="#MJX-1731-TEX-I-1D452"></use></g><g data-mml-node="mi" transform="translate(3007,0)"><use data-c="1D460" xlink:href="#MJX-1731-TEX-I-1D460"></use></g><g data-mml-node="mo" transform="translate(3476,0)"><use data-c="5B" xlink:href="#MJX-1731-TEX-N-5B"></use></g><g data-mml-node="mi" transform="translate(3754,0)"><use data-c="1D456" xlink:href="#MJX-1731-TEX-I-1D456"></use></g><g data-mml-node="mo" transform="translate(4099,0)"><use data-c="5D" xlink:href="#MJX-1731-TEX-N-5D"></use></g></g></g></g></svg></mjx-container>{vertices[i + 1]} <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.452ex;" xmlns="http://www.w3.org/2000/svg" width="52.941ex" height="2.149ex" role="img" focusable="false" viewBox="0 -750 23400 950" xmlns:xlink="http://www.w3.org/1999/xlink"><defs></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="merror" data-mjx-error="Extra close brace or missing open brace"><rect data-background="true" width="23400" height="950" y="-200"></rect><g data-mml-node="mtext" style="font-family: serif;"><text data-variant="-explicitFont" transform="scale(1,-1)" font-size="884px">Extra close brace or missing open brace</text></g></g></g></g></svg></mjx-container>{indices[i]} <mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.566ex;" xmlns="http://www.w3.org/2000/svg" width="13.125ex" height="2.262ex" role="img" focusable="false" viewBox="0 -750 5801.4 1000" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="MJX-1733-TEX-I-1D456" d="M184 600Q184 624 203 642T247 661Q265 661 277 649T290 619Q290 596 270 577T226 557Q211 557 198 567T184 600ZM21 287Q21 295 30 318T54 369T98 420T158 442Q197 442 223 419T250 357Q250 340 236 301T196 196T154 83Q149 61 149 51Q149 26 166 26Q175 26 185 29T208 43T235 78T260 137Q263 149 265 151T282 153Q302 153 302 143Q302 135 293 112T268 61T223 11T161 -11Q129 -11 102 10T74 74Q74 91 79 106T122 220Q160 321 166 341T173 380Q173 404 156 404H154Q124 404 99 371T61 287Q60 286 59 284T58 281T56 279T53 278T49 278T41 278H27Q21 284 21 287Z"></path><path id="MJX-1733-TEX-I-1D45B" d="M21 287Q22 293 24 303T36 341T56 388T89 425T135 442Q171 442 195 424T225 390T231 369Q231 367 232 367L243 378Q304 442 382 442Q436 442 469 415T503 336T465 179T427 52Q427 26 444 26Q450 26 453 27Q482 32 505 65T540 145Q542 153 560 153Q580 153 580 145Q580 144 576 130Q568 101 554 73T508 17T439 -10Q392 -10 371 17T350 73Q350 92 386 193T423 345Q423 404 379 404H374Q288 404 229 303L222 291L189 157Q156 26 151 16Q138 -11 108 -11Q95 -11 87 -5T76 7T74 17Q74 30 112 180T152 343Q153 348 153 366Q153 405 129 405Q91 405 66 305Q60 285 60 284Q58 278 41 278H27Q21 284 21 287Z"></path><path id="MJX-1733-TEX-I-1D451" d="M366 683Q367 683 438 688T511 694Q523 694 523 686Q523 679 450 384T375 83T374 68Q374 26 402 26Q411 27 422 35Q443 55 463 131Q469 151 473 152Q475 153 483 153H487H491Q506 153 506 145Q506 140 503 129Q490 79 473 48T445 8T417 -8Q409 -10 393 -10Q359 -10 336 5T306 36L300 51Q299 52 296 50Q294 48 292 46Q233 -10 172 -10Q117 -10 75 30T33 157Q33 205 53 255T101 341Q148 398 195 420T280 442Q336 442 364 400Q369 394 369 396Q370 400 396 505T424 616Q424 629 417 632T378 637H357Q351 643 351 645T353 664Q358 683 366 683ZM352 326Q329 405 277 405Q242 405 210 374T160 293Q131 214 119 129Q119 126 119 118T118 106Q118 61 136 44T179 26Q233 26 290 98L298 109L352 326Z"></path><path id="MJX-1733-TEX-I-1D450" d="M34 159Q34 268 120 355T306 442Q362 442 394 418T427 355Q427 326 408 306T360 285Q341 285 330 295T319 325T330 359T352 380T366 386H367Q367 388 361 392T340 400T306 404Q276 404 249 390Q228 381 206 359Q162 315 142 235T121 119Q121 73 147 50Q169 26 205 26H209Q321 26 394 111Q403 121 406 121Q410 121 419 112T429 98T420 83T391 55T346 25T282 0T202 -11Q127 -11 81 37T34 159Z"></path><path id="MJX-1733-TEX-I-1D452" d="M39 168Q39 225 58 272T107 350T174 402T244 433T307 442H310Q355 442 388 420T421 355Q421 265 310 237Q261 224 176 223Q139 223 138 221Q138 219 132 186T125 128Q125 81 146 54T209 26T302 45T394 111Q403 121 406 121Q410 121 419 112T429 98T420 82T390 55T344 24T281 -1T205 -11Q126 -11 83 42T39 168ZM373 353Q367 405 305 405Q272 405 244 391T199 357T170 316T154 280T149 261Q149 260 169 260Q282 260 327 284T373 353Z"></path><path id="MJX-1733-TEX-I-1D460" d="M131 289Q131 321 147 354T203 415T300 442Q362 442 390 415T419 355Q419 323 402 308T364 292Q351 292 340 300T328 326Q328 342 337 354T354 372T367 378Q368 378 368 379Q368 382 361 388T336 399T297 405Q249 405 227 379T204 326Q204 301 223 291T278 274T330 259Q396 230 396 163Q396 135 385 107T352 51T289 7T195 -10Q118 -10 86 19T53 87Q53 126 74 143T118 160Q133 160 146 151T160 120Q160 94 142 76T111 58Q109 57 108 57T107 55Q108 52 115 47T146 34T201 27Q237 27 263 38T301 66T318 97T323 122Q323 150 302 164T254 181T195 196T148 231Q131 256 131 289Z"></path><path id="MJX-1733-TEX-N-5B" d="M118 -250V750H255V710H158V-210H255V-250H118Z"></path><path id="MJX-1733-TEX-N-2B" d="M56 237T56 250T70 270H369V420L370 570Q380 583 389 583Q402 583 409 568V270H707Q722 262 722 250T707 230H409V-68Q401 -82 391 -82H389H387Q375 -82 369 -68V230H70Q56 237 56 250Z"></path><path id="MJX-1733-TEX-N-31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path><path id="MJX-1733-TEX-N-5D" d="M22 710V750H159V-250H22V-210H119V710H22Z"></path></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="TeXAtom" data-mjx-texclass="ORD"><g data-mml-node="mi"><use data-c="1D456" xlink:href="#MJX-1733-TEX-I-1D456"></use></g><g data-mml-node="mi" transform="translate(345,0)"><use data-c="1D45B" xlink:href="#MJX-1733-TEX-I-1D45B"></use></g><g data-mml-node="mi" transform="translate(945,0)"><use data-c="1D451" xlink:href="#MJX-1733-TEX-I-1D451"></use></g><g data-mml-node="mi" transform="translate(1465,0)"><use data-c="1D456" xlink:href="#MJX-1733-TEX-I-1D456"></use></g><g data-mml-node="mi" transform="translate(1810,0)"><use data-c="1D450" xlink:href="#MJX-1733-TEX-I-1D450"></use></g><g data-mml-node="mi" transform="translate(2243,0)"><use data-c="1D452" xlink:href="#MJX-1733-TEX-I-1D452"></use></g><g data-mml-node="mi" transform="translate(2709,0)"><use data-c="1D460" xlink:href="#MJX-1733-TEX-I-1D460"></use></g><g data-mml-node="mo" transform="translate(3178,0)"><use data-c="5B" xlink:href="#MJX-1733-TEX-N-5B"></use></g><g data-mml-node="mi" transform="translate(3456,0)"><use data-c="1D456" xlink:href="#MJX-1733-TEX-I-1D456"></use></g><g data-mml-node="mo" transform="translate(4023.2,0)"><use data-c="2B" xlink:href="#MJX-1733-TEX-N-2B"></use></g><g data-mml-node="mn" transform="translate(5023.4,0)"><use data-c="31" xlink:href="#MJX-1733-TEX-N-31"></use></g><g data-mml-node="mo" transform="translate(5523.4,0)"><use data-c="5D" xlink:href="#MJX-1733-TEX-N-5D"></use></g></g></g></g></svg></mjx-container>{indices[i + 2]}\n`;
}
fs.writeFile('indices.dat', icontent, err => {
if (err) {
console.error(err);
}
// file written successfully
});