[{"data":1,"prerenderedAt":2589},["ShallowReactive",2],{"navigation-docsTs":3,"lib-picker-navigation":139,"docsTs-\u002Fts\u002Fmodules\u002Fcsg":435,"docsTs-\u002Fts\u002Fmodules\u002Fcsg-surround":2584},[4],{"title":5,"path":6,"stem":7,"children":8,"page":27},"Ts","\u002Fts","ts",[9,28,91,98,120],{"title":10,"path":11,"stem":12,"children":13,"icon":27},"Getting Started","\u002Fts\u002Fgetting-started","ts\u002F1.getting-started\u002F1.index",[14,17,22],{"title":15,"path":11,"stem":12,"icon":16},"Introduction","i-lucide-house",{"title":18,"path":19,"stem":20,"icon":21},"Installation","\u002Fts\u002Fgetting-started\u002Finstallation","ts\u002F1.getting-started\u002F2.installation","i-lucide-download",{"title":23,"path":24,"stem":25,"icon":26},"Live Examples","\u002Fts\u002Fgetting-started\u002Flive-examples","ts\u002F1.getting-started\u002F3.live-examples","i-lucide-play",false,{"title":29,"path":30,"stem":31,"children":32,"icon":27},"Modules","\u002Fts\u002Fmodules","ts\u002F2.modules\u002F00.index",[33,36,41,46,51,56,61,66,71,76,81,86],{"title":34,"path":30,"stem":31,"icon":35},"Overview","i-lucide-library",{"title":37,"path":38,"stem":39,"icon":40},"Core","\u002Fts\u002Fmodules\u002Fcore","ts\u002F2.modules\u002F01.core","i-lucide-atom",{"title":42,"path":43,"stem":44,"icon":45},"Spatial","\u002Fts\u002Fmodules\u002Fspatial","ts\u002F2.modules\u002F02.spatial","i-lucide-scale-3d",{"title":47,"path":48,"stem":49,"icon":50},"Topology","\u002Fts\u002Fmodules\u002Ftopology","ts\u002F2.modules\u002F03.topology","i-lucide-git-graph",{"title":52,"path":53,"stem":54,"icon":55},"Geometry","\u002Fts\u002Fmodules\u002Fgeometry","ts\u002F2.modules\u002F04.geometry","i-lucide-ruler",{"title":57,"path":58,"stem":59,"icon":60},"Remesh","\u002Fts\u002Fmodules\u002Fremesh","ts\u002F2.modules\u002F05.remesh","i-lucide-triangle",{"title":62,"path":63,"stem":64,"icon":65},"Intersect","\u002Fts\u002Fmodules\u002Fintersect","ts\u002F2.modules\u002F06.intersect","i-lucide-squares-intersect",{"title":67,"path":68,"stem":69,"icon":70},"Cut","\u002Fts\u002Fmodules\u002Fcut","ts\u002F2.modules\u002F07.cut","i-lucide-scissors",{"title":72,"path":73,"stem":74,"icon":75},"CSG","\u002Fts\u002Fmodules\u002Fcsg","ts\u002F2.modules\u002F08.csg","i-lucide-shapes",{"title":77,"path":78,"stem":79,"icon":80},"Clean","\u002Fts\u002Fmodules\u002Fclean","ts\u002F2.modules\u002F09.clean","i-lucide-sparkles",{"title":82,"path":83,"stem":84,"icon":85},"Reindex","\u002Fts\u002Fmodules\u002Freindex","ts\u002F2.modules\u002F10.reidx","i-lucide-shuffle",{"title":87,"path":88,"stem":89,"icon":90},"I\u002FO","\u002Fts\u002Fmodules\u002Fio","ts\u002F2.modules\u002F11.io","i-lucide-file-input",{"title":92,"path":93,"stem":94,"children":95,"icon":27},"Benchmarks","\u002Fts\u002Fbenchmarks","ts\u002F3.benchmarks\u002F1.index",[96],{"title":34,"path":93,"stem":94,"icon":97},"i-lucide-chart-bar-stacked",{"title":99,"path":100,"stem":101,"children":102,"icon":27},"Examples","\u002Fts\u002Fexamples","ts\u002F4.examples\u002F0.index",[103,105,110,115],{"title":34,"path":100,"stem":101,"icon":104},"i-lucide-book-open",{"title":106,"path":107,"stem":108,"icon":109},"Core Functionality","\u002Fts\u002Fexamples\u002Fcore-functionality","ts\u002F4.examples\u002F2.core-functionality","i-lucide-code",{"title":111,"path":112,"stem":113,"icon":114},"Alignment","\u002Fts\u002Fexamples\u002Falignment","ts\u002F4.examples\u002F3.alignment","i-lucide-move-3d",{"title":116,"path":117,"stem":118,"icon":119},"Raycast Rendering","\u002Fts\u002Fexamples\u002Fraycast-render","ts\u002F4.examples\u002F4.raycast-render","i-lucide-image",{"title":121,"icon":27,"path":122,"stem":123,"children":124,"page":27},"About","\u002Fts\u002Fabout","ts\u002F5.about",[125,129,134],{"title":126,"path":127,"stem":128,"icon":104},"Research","\u002Fts\u002Fabout\u002Fresearch","ts\u002F5.about\u002F1.research",{"title":130,"path":131,"stem":132,"icon":133},"Contributing","\u002Fts\u002Fabout\u002Fcontributing","ts\u002F5.about\u002F2.contributing","i-lucide-heart-handshake",{"title":135,"path":136,"stem":137,"icon":138},"License","\u002Fts\u002Fabout\u002Flicense","ts\u002F5.about\u002F3.license","i-lucide-file-text",{"cpp":140,"py":286,"ts":399},[141],{"title":142,"path":143,"stem":144,"children":145,"page":27},"Cpp","\u002Fcpp","cpp",[146,157,195,221,244,273],{"title":10,"path":147,"stem":148,"children":149,"icon":27},"\u002Fcpp\u002Fgetting-started","cpp\u002F1.getting-started\u002F1.index",[150,151,154],{"title":15,"path":147,"stem":148,"icon":16},{"title":18,"path":152,"stem":153,"icon":21},"\u002Fcpp\u002Fgetting-started\u002Finstallation","cpp\u002F1.getting-started\u002F2.installation",{"title":23,"path":155,"stem":156,"icon":26},"\u002Fcpp\u002Fgetting-started\u002Flive-examples","cpp\u002F1.getting-started\u002F3.live-examples",{"title":29,"path":158,"stem":159,"children":160,"icon":27},"\u002Fcpp\u002Fmodules","cpp\u002F2.modules\u002F00.index",[161,162,165,168,171,174,177,180,183,186,189,192],{"title":34,"path":158,"stem":159,"icon":35},{"title":37,"path":163,"stem":164,"icon":40},"\u002Fcpp\u002Fmodules\u002Fcore","cpp\u002F2.modules\u002F01.core",{"title":42,"path":166,"stem":167,"icon":45},"\u002Fcpp\u002Fmodules\u002Fspatial","cpp\u002F2.modules\u002F02.spatial",{"title":47,"path":169,"stem":170,"icon":50},"\u002Fcpp\u002Fmodules\u002Ftopology","cpp\u002F2.modules\u002F03.topology",{"title":52,"path":172,"stem":173,"icon":55},"\u002Fcpp\u002Fmodules\u002Fgeometry","cpp\u002F2.modules\u002F04.geometry",{"title":57,"path":175,"stem":176,"icon":60},"\u002Fcpp\u002Fmodules\u002Fremesh","cpp\u002F2.modules\u002F05.remesh",{"title":62,"path":178,"stem":179,"icon":65},"\u002Fcpp\u002Fmodules\u002Fintersect","cpp\u002F2.modules\u002F06.intersect",{"title":67,"path":181,"stem":182,"icon":70},"\u002Fcpp\u002Fmodules\u002Fcut","cpp\u002F2.modules\u002F07.cut",{"title":72,"path":184,"stem":185,"icon":75},"\u002Fcpp\u002Fmodules\u002Fcsg","cpp\u002F2.modules\u002F08.csg",{"title":77,"path":187,"stem":188,"icon":80},"\u002Fcpp\u002Fmodules\u002Fclean","cpp\u002F2.modules\u002F09.clean",{"title":82,"path":190,"stem":191,"icon":85},"\u002Fcpp\u002Fmodules\u002Freindex","cpp\u002F2.modules\u002F10.reidx",{"title":87,"path":193,"stem":194,"icon":90},"\u002Fcpp\u002Fmodules\u002Fio","cpp\u002F2.modules\u002F11.io",{"title":92,"path":196,"stem":197,"children":198,"icon":27},"\u002Fcpp\u002Fbenchmarks","cpp\u002F3.benchmarks\u002F1.index",[199,200,203,206,209,212,215,218],{"title":34,"path":196,"stem":197,"icon":97},{"title":42,"path":201,"stem":202,"icon":45},"\u002Fcpp\u002Fbenchmarks\u002Fspatial","cpp\u002F3.benchmarks\u002F2.spatial",{"title":47,"path":204,"stem":205,"icon":50},"\u002Fcpp\u002Fbenchmarks\u002Ftopology","cpp\u002F3.benchmarks\u002F3.topology",{"title":52,"path":207,"stem":208,"icon":55},"\u002Fcpp\u002Fbenchmarks\u002Fgeometry","cpp\u002F3.benchmarks\u002F4.geometry",{"title":57,"path":210,"stem":211,"icon":60},"\u002Fcpp\u002Fbenchmarks\u002Fremesh","cpp\u002F3.benchmarks\u002F5.remesh",{"title":62,"path":213,"stem":214,"icon":65},"\u002Fcpp\u002Fbenchmarks\u002Fintersect","cpp\u002F3.benchmarks\u002F6.intersect",{"title":67,"path":216,"stem":217,"icon":70},"\u002Fcpp\u002Fbenchmarks\u002Fcut","cpp\u002F3.benchmarks\u002F7.cut",{"title":87,"path":219,"stem":220,"icon":90},"\u002Fcpp\u002Fbenchmarks\u002Fio","cpp\u002F3.benchmarks\u002F8.io",{"title":222,"path":223,"stem":224,"children":225,"icon":27},"VTK","\u002Fcpp\u002Fvtk","cpp\u002F4.vtk\u002F1.index",[226,228,231,236,241],{"title":34,"path":223,"stem":224,"icon":227},"i-lucide-layers",{"title":37,"path":229,"stem":230,"icon":40},"\u002Fcpp\u002Fvtk\u002Fcore","cpp\u002F4.vtk\u002F2.core",{"title":232,"path":233,"stem":234,"icon":235},"Functions","\u002Fcpp\u002Fvtk\u002Ffunctions","cpp\u002F4.vtk\u002F3.functions","i-lucide-function-square",{"title":237,"path":238,"stem":239,"icon":240},"Filters","\u002Fcpp\u002Fvtk\u002Ffilters","cpp\u002F4.vtk\u002F4.filters","i-lucide-filter",{"title":99,"path":242,"stem":243,"icon":26},"\u002Fcpp\u002Fvtk\u002Fexamples","cpp\u002F4.vtk\u002F5.examples",{"title":99,"path":245,"stem":246,"children":247,"icon":27},"\u002Fcpp\u002Fexamples","cpp\u002F5.examples\u002F0.index",[248,249,254,259,264,268],{"title":34,"path":245,"stem":246,"icon":104},{"title":250,"path":251,"stem":252,"icon":253},"Geometry Walkthrough","\u002Fcpp\u002Fexamples\u002Fmesh-assembly","cpp\u002F5.examples\u002F1.mesh-assembly","i-lucide-box",{"title":255,"path":256,"stem":257,"icon":258},"Point Cloud Alignment","\u002Fcpp\u002Fexamples\u002Falignment","cpp\u002F5.examples\u002F2.alignment","i-lucide-move",{"title":260,"path":261,"stem":262,"icon":263},"Booleans and Domains from One Build","\u002Fcpp\u002Fexamples\u002Farrangements","cpp\u002F5.examples\u002F3.arrangements","i-lucide-layers-3",{"title":265,"path":266,"stem":267,"icon":227},"VTK Integration","\u002Fcpp\u002Fexamples\u002Fvtk","cpp\u002F5.examples\u002F4.vtk",{"title":269,"path":270,"stem":271,"icon":272},"Coming from Other Libraries","\u002Fcpp\u002Fexamples\u002Flibrary-comparisons","cpp\u002F5.examples\u002F5.library-comparisons","i-lucide-git-compare",{"title":121,"path":274,"stem":275,"children":276,"page":27},"\u002Fcpp\u002Fabout","cpp\u002F6.about",[277,280,283],{"title":126,"path":278,"stem":279,"icon":104},"\u002Fcpp\u002Fabout\u002Fresearch","cpp\u002F6.about\u002F1.research",{"title":130,"path":281,"stem":282,"icon":133},"\u002Fcpp\u002Fabout\u002Fcontributing","cpp\u002F6.about\u002F2.contributing",{"title":135,"path":284,"stem":285,"icon":138},"\u002Fcpp\u002Fabout\u002Flicense","cpp\u002F6.about\u002F3.license",[287],{"title":288,"path":289,"stem":290,"children":291,"page":27},"Py","\u002Fpy","py",[292,303,341,346,367,386],{"title":10,"path":293,"stem":294,"children":295,"icon":27},"\u002Fpy\u002Fgetting-started","py\u002F1.getting-started\u002F1.index",[296,297,300],{"title":15,"path":293,"stem":294,"icon":16},{"title":18,"path":298,"stem":299,"icon":21},"\u002Fpy\u002Fgetting-started\u002Finstallation","py\u002F1.getting-started\u002F2.installation",{"title":23,"path":301,"stem":302,"icon":26},"\u002Fpy\u002Fgetting-started\u002Flive-examples","py\u002F1.getting-started\u002F3.live-examples",{"title":29,"path":304,"stem":305,"children":306,"icon":27},"\u002Fpy\u002Fmodules","py\u002F2.modules\u002F00.index",[307,308,311,314,317,320,323,326,329,332,335,338],{"title":34,"path":304,"stem":305,"icon":35},{"title":37,"path":309,"stem":310,"icon":40},"\u002Fpy\u002Fmodules\u002Fcore","py\u002F2.modules\u002F01.core",{"title":42,"path":312,"stem":313,"icon":45},"\u002Fpy\u002Fmodules\u002Fspatial","py\u002F2.modules\u002F02.spatial",{"title":47,"path":315,"stem":316,"icon":50},"\u002Fpy\u002Fmodules\u002Ftopology","py\u002F2.modules\u002F03.topology",{"title":52,"path":318,"stem":319,"icon":55},"\u002Fpy\u002Fmodules\u002Fgeometry","py\u002F2.modules\u002F04.geometry",{"title":57,"path":321,"stem":322,"icon":60},"\u002Fpy\u002Fmodules\u002Fremesh","py\u002F2.modules\u002F05.remesh",{"title":62,"path":324,"stem":325,"icon":65},"\u002Fpy\u002Fmodules\u002Fintersect","py\u002F2.modules\u002F06.intersect",{"title":67,"path":327,"stem":328,"icon":70},"\u002Fpy\u002Fmodules\u002Fcut","py\u002F2.modules\u002F07.cut",{"title":72,"path":330,"stem":331,"icon":75},"\u002Fpy\u002Fmodules\u002Fcsg","py\u002F2.modules\u002F08.csg",{"title":77,"path":333,"stem":334,"icon":80},"\u002Fpy\u002Fmodules\u002Fclean","py\u002F2.modules\u002F09.clean",{"title":82,"path":336,"stem":337,"icon":85},"\u002Fpy\u002Fmodules\u002Freindex","py\u002F2.modules\u002F10.reidx",{"title":87,"path":339,"stem":340,"icon":90},"\u002Fpy\u002Fmodules\u002Fio","py\u002F2.modules\u002F11.io",{"title":92,"path":342,"stem":343,"children":344,"icon":27},"\u002Fpy\u002Fbenchmarks","py\u002F3.benchmarks\u002F1.index",[345],{"title":34,"path":342,"stem":343,"icon":97},{"title":347,"path":348,"stem":349,"children":350,"icon":27},"Blender","\u002Fpy\u002Fblender","py\u002F4.blender\u002F1.index",[351,353,358,362],{"title":34,"path":348,"stem":349,"icon":352},"i-vscode-icons:file-type-blender",{"title":354,"path":355,"stem":356,"icon":357},"Convert","\u002Fpy\u002Fblender\u002Fconvert","py\u002F4.blender\u002F2.convert","i-lucide-repeat",{"title":359,"path":360,"stem":361,"icon":227},"Scene","\u002Fpy\u002Fblender\u002Fscene","py\u002F4.blender\u002F3.scene",{"title":363,"path":364,"stem":365,"icon":366},"Plugin Architecture","\u002Fpy\u002Fblender\u002Fplugin","py\u002F4.blender\u002F4.plugin","i-lucide-puzzle",{"title":99,"path":368,"stem":369,"children":370,"icon":27},"\u002Fpy\u002Fexamples","py\u002F5.examples\u002F0.index",[371,372,375,378,382],{"title":34,"path":368,"stem":369,"icon":104},{"title":106,"path":373,"stem":374,"icon":109},"\u002Fpy\u002Fexamples\u002Fcore-functionality","py\u002F5.examples\u002F2.core-functionality",{"title":260,"path":376,"stem":377,"icon":263},"\u002Fpy\u002Fexamples\u002Farrangements","py\u002F5.examples\u002F3.arrangements",{"title":265,"path":379,"stem":380,"icon":381},"\u002Fpy\u002Fexamples\u002Fvtk-integration","py\u002F5.examples\u002F4.vtk-integration","i-lucide-grid-2x2",{"title":116,"path":383,"stem":384,"icon":385},"\u002Fpy\u002Fexamples\u002Fraycast-rendering","py\u002F5.examples\u002F5.raycast-rendering","i-lucide-scan-line",{"title":121,"path":387,"stem":388,"children":389,"page":27},"\u002Fpy\u002Fabout","py\u002F6.about",[390,393,396],{"title":126,"path":391,"stem":392,"icon":104},"\u002Fpy\u002Fabout\u002Fresearch","py\u002F6.about\u002F1.research",{"title":130,"path":394,"stem":395,"icon":133},"\u002Fpy\u002Fabout\u002Fcontributing","py\u002F6.about\u002F2.contributing",{"title":135,"path":397,"stem":398,"icon":138},"\u002Fpy\u002Fabout\u002Flicense","py\u002F6.about\u002F3.license",[400],{"title":5,"path":6,"stem":7,"children":401,"page":27},[402,407,421,424,430],{"title":10,"path":11,"stem":12,"children":403,"icon":27},[404,405,406],{"title":15,"path":11,"stem":12,"icon":16},{"title":18,"path":19,"stem":20,"icon":21},{"title":23,"path":24,"stem":25,"icon":26},{"title":29,"path":30,"stem":31,"children":408,"icon":27},[409,410,411,412,413,414,415,416,417,418,419,420],{"title":34,"path":30,"stem":31,"icon":35},{"title":37,"path":38,"stem":39,"icon":40},{"title":42,"path":43,"stem":44,"icon":45},{"title":47,"path":48,"stem":49,"icon":50},{"title":52,"path":53,"stem":54,"icon":55},{"title":57,"path":58,"stem":59,"icon":60},{"title":62,"path":63,"stem":64,"icon":65},{"title":67,"path":68,"stem":69,"icon":70},{"title":72,"path":73,"stem":74,"icon":75},{"title":77,"path":78,"stem":79,"icon":80},{"title":82,"path":83,"stem":84,"icon":85},{"title":87,"path":88,"stem":89,"icon":90},{"title":92,"path":93,"stem":94,"children":422,"icon":27},[423],{"title":34,"path":93,"stem":94,"icon":97},{"title":99,"path":100,"stem":101,"children":425,"icon":27},[426,427,428,429],{"title":34,"path":100,"stem":101,"icon":104},{"title":106,"path":107,"stem":108,"icon":109},{"title":111,"path":112,"stem":113,"icon":114},{"title":116,"path":117,"stem":118,"icon":119},{"title":121,"icon":27,"path":122,"stem":123,"children":431,"page":27},[432,433,434],{"title":126,"path":127,"stem":128,"icon":104},{"title":130,"path":131,"stem":132,"icon":133},{"title":135,"path":136,"stem":137,"icon":138},{"id":436,"title":72,"body":437,"description":2577,"extension":2578,"links":2579,"meta":2580,"navigation":2581,"path":73,"seo":2582,"stem":74,"__hash__":2583},"docsTs\u002Fts\u002F2.modules\u002F08.csg.md",{"type":438,"value":439,"toc":2557},"minimark",[440,449,453,498,680,686,690,701,776,783,924,928,1101,1112,1115,1168,1173,1179,1197,1201,1211,1215,1268,1279,1283,1372,1376,1517,1527,1531,1565,1572,1694,1702,1713,1756,1759,1929,1934,2081,2092,2096,2125,2129,2132,2173,2176,2183,2331,2335,2363,2367,2550,2553],[441,442,443,444,448],"p",{},"The CSG module builds an arrangement of N meshes ",[445,446,447],"strong",{},"once"," and evaluates any boolean expression over them — no chaining of pairwise booleans, no recomputation between queries.",[450,451,34],"h2",{"id":452},"overview",[454,455,456,472],"ul",{},[457,458,459,462,463,467,468,471],"li",{},[445,460,461],{},"Build"," — ",[464,465,466],"code",{},"tf.csgGraph([...])"," computes the arrangement and its domain classification. This is where the heavy work happens; ",[464,469,470],{},"tf.async.csgGraph"," runs it off the main thread.",[457,473,474,477,478],{},[445,475,476],{},"Query"," — every call after that is cheap and reuses the same build:\n",[454,479,480,486,492],{},[457,481,482,485],{},[464,483,484],{},"graph.mesh(expr)"," — the boolean result mesh for any expression",[457,487,488,491],{},[464,489,490],{},"graph.domains()"," — every kept volumetric domain as its own watertight mesh",[457,493,494,497],{},[464,495,496],{},"graph.intersectionCurves()"," — the seam polylines where surfaces cross",[499,500,505],"pre",{"className":501,"code":502,"language":503,"meta":504,"style":504},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const graph = tf.csgGraph([meshA, meshB, meshC]);\n\nconst diff = graph.mesh(tf.op(0).sub(tf.op(1)));   \u002F\u002F boolean difference\nconst { meshes, ids } = graph.domains();            \u002F\u002F volumetric decomposition\n\ngraph.delete();                                     \u002F\u002F explicit lifetime, like Mesh\n","typescript","",[464,506,507,551,558,620,657,662],{"__ignoreMap":504},[508,509,512,516,520,524,527,530,534,537,540,543,545,548],"span",{"class":510,"line":511},"line",1,[508,513,515],{"class":514},"spNyl","const",[508,517,519],{"class":518},"sTEyZ"," graph ",[508,521,523],{"class":522},"sMK4o","=",[508,525,526],{"class":518}," tf",[508,528,529],{"class":522},".",[508,531,533],{"class":532},"s2Zo4","csgGraph",[508,535,536],{"class":518},"([meshA",[508,538,539],{"class":522},",",[508,541,542],{"class":518}," meshB",[508,544,539],{"class":522},[508,546,547],{"class":518}," meshC])",[508,549,550],{"class":522},";\n",[508,552,554],{"class":510,"line":553},2,[508,555,557],{"emptyLinePlaceholder":556},true,"\n",[508,559,561,563,566,568,571,573,576,579,581,584,587,591,594,596,599,601,603,605,607,610,613,616],{"class":510,"line":560},3,[508,562,515],{"class":514},[508,564,565],{"class":518}," diff ",[508,567,523],{"class":522},[508,569,570],{"class":518}," graph",[508,572,529],{"class":522},[508,574,575],{"class":532},"mesh",[508,577,578],{"class":518},"(tf",[508,580,529],{"class":522},[508,582,583],{"class":532},"op",[508,585,586],{"class":518},"(",[508,588,590],{"class":589},"sbssI","0",[508,592,593],{"class":518},")",[508,595,529],{"class":522},[508,597,598],{"class":532},"sub",[508,600,578],{"class":518},[508,602,529],{"class":522},[508,604,583],{"class":532},[508,606,586],{"class":518},[508,608,609],{"class":589},"1",[508,611,612],{"class":518},")))",[508,614,615],{"class":522},";",[508,617,619],{"class":618},"sHwdD","   \u002F\u002F boolean difference\n",[508,621,623,625,628,631,633,636,639,642,644,646,649,652,654],{"class":510,"line":622},4,[508,624,515],{"class":514},[508,626,627],{"class":522}," {",[508,629,630],{"class":518}," meshes",[508,632,539],{"class":522},[508,634,635],{"class":518}," ids ",[508,637,638],{"class":522},"}",[508,640,641],{"class":522}," =",[508,643,570],{"class":518},[508,645,529],{"class":522},[508,647,648],{"class":532},"domains",[508,650,651],{"class":518},"()",[508,653,615],{"class":522},[508,655,656],{"class":618},"            \u002F\u002F volumetric decomposition\n",[508,658,660],{"class":510,"line":659},5,[508,661,557],{"emptyLinePlaceholder":556},[508,663,665,668,670,673,675,677],{"class":510,"line":664},6,[508,666,667],{"class":518},"graph",[508,669,529],{"class":522},[508,671,672],{"class":532},"delete",[508,674,651],{"class":518},[508,676,615],{"class":522},[508,678,679],{"class":618},"                                     \u002F\u002F explicit lifetime, like Mesh\n",[441,681,682,683,529],{},"A sequence of operations costs ",[445,684,685],{},"one arrangement, not one per operation",[450,687,689],{"id":688},"building-expressions","Building Expressions",[441,691,692,693,696,697,700],{},"Expressions are built from ",[464,694,695],{},"tf.op(i)"," leaves — ",[464,698,699],{},"i"," is the operand's index in the mesh array — combined with builder methods:",[702,703,704,717],"table",{},[705,706,707],"thead",{},[708,709,710,714],"tr",{},[711,712,713],"th",{},"Builder",[711,715,716],{},"Meaning",[718,719,720,734,747,764],"tbody",{},[708,721,722,728],{},[723,724,725],"td",{},[464,726,727],{},"a.or(b)",[723,729,730,731],{},"union — inside ",[445,732,733],{},"any",[708,735,736,741],{},[723,737,738],{},[464,739,740],{},"a.and(b)",[723,742,743,744],{},"intersection — inside ",[445,745,746],{},"every",[708,748,749,754],{},[723,750,751],{},[464,752,753],{},"a.sub(b)",[723,755,756,757,760,761],{},"difference — inside ",[464,758,759],{},"a",", outside ",[464,762,763],{},"b",[708,765,766,771],{},[723,767,768],{},[464,769,770],{},"a.not()",[723,772,773,774],{},"complement — outside ",[464,775,759],{},[441,777,778,779,782],{},"Plain integers auto-promote as arguments: ",[464,780,781],{},"tf.op(0).sub(1)"," works.",[499,784,786],{"className":501,"code":785,"language":503,"meta":504,"style":504},"const carved = tf.op(0).sub(tf.op(1).or(2));\nconst shared = tf.op(0).and(1).and(2);\nconst outside = tf.op(0).or(1).not();\n",[464,787,788,840,884],{"__ignoreMap":504},[508,789,790,792,795,797,799,801,803,805,807,809,811,813,815,817,819,821,823,825,827,830,832,835,838],{"class":510,"line":511},[508,791,515],{"class":514},[508,793,794],{"class":518}," carved ",[508,796,523],{"class":522},[508,798,526],{"class":518},[508,800,529],{"class":522},[508,802,583],{"class":532},[508,804,586],{"class":518},[508,806,590],{"class":589},[508,808,593],{"class":518},[508,810,529],{"class":522},[508,812,598],{"class":532},[508,814,578],{"class":518},[508,816,529],{"class":522},[508,818,583],{"class":532},[508,820,586],{"class":518},[508,822,609],{"class":589},[508,824,593],{"class":518},[508,826,529],{"class":522},[508,828,829],{"class":532},"or",[508,831,586],{"class":518},[508,833,834],{"class":589},"2",[508,836,837],{"class":518},"))",[508,839,550],{"class":522},[508,841,842,844,847,849,851,853,855,857,859,861,863,866,868,870,872,874,876,878,880,882],{"class":510,"line":553},[508,843,515],{"class":514},[508,845,846],{"class":518}," shared ",[508,848,523],{"class":522},[508,850,526],{"class":518},[508,852,529],{"class":522},[508,854,583],{"class":532},[508,856,586],{"class":518},[508,858,590],{"class":589},[508,860,593],{"class":518},[508,862,529],{"class":522},[508,864,865],{"class":532},"and",[508,867,586],{"class":518},[508,869,609],{"class":589},[508,871,593],{"class":518},[508,873,529],{"class":522},[508,875,865],{"class":532},[508,877,586],{"class":518},[508,879,834],{"class":589},[508,881,593],{"class":518},[508,883,550],{"class":522},[508,885,886,888,891,893,895,897,899,901,903,905,907,909,911,913,915,917,920,922],{"class":510,"line":560},[508,887,515],{"class":514},[508,889,890],{"class":518}," outside ",[508,892,523],{"class":522},[508,894,526],{"class":518},[508,896,529],{"class":522},[508,898,583],{"class":532},[508,900,586],{"class":518},[508,902,590],{"class":589},[508,904,593],{"class":518},[508,906,529],{"class":522},[508,908,829],{"class":532},[508,910,586],{"class":518},[508,912,609],{"class":589},[508,914,593],{"class":518},[508,916,529],{"class":522},[508,918,919],{"class":532},"not",[508,921,651],{"class":518},[508,923,550],{"class":522},[450,925,927],{"id":926},"building-the-graph","Building the Graph",[499,929,931],{"className":501,"code":930,"language":503,"meta":504,"style":504},"const graph = tf.csgGraph(meshes, {\n  sheets: [2],                 \u002F\u002F optional: operands declared as open sheets\n  mode: \"primitives\",          \u002F\u002F intersection mode (\"sos\" or \"primitives\")\n  tolerance: 0,                \u002F\u002F predicate tolerance band (0 = exact)\n  triangulation: \"cdt\",        \u002F\u002F cut-surface triangulation (see below)\n});\n\n\u002F\u002F or off the main thread:\nconst graph = await tf.async.csgGraph(meshes, { triangulation: \"refinedCdt\" });\n",[464,932,933,955,977,999,1014,1033,1041,1046,1052],{"__ignoreMap":504},[508,934,935,937,939,941,943,945,947,950,952],{"class":510,"line":511},[508,936,515],{"class":514},[508,938,519],{"class":518},[508,940,523],{"class":522},[508,942,526],{"class":518},[508,944,529],{"class":522},[508,946,533],{"class":532},[508,948,949],{"class":518},"(meshes",[508,951,539],{"class":522},[508,953,954],{"class":522}," {\n",[508,956,957,961,964,967,969,972,974],{"class":510,"line":553},[508,958,960],{"class":959},"swJcz","  sheets",[508,962,963],{"class":522},":",[508,965,966],{"class":518}," [",[508,968,834],{"class":589},[508,970,971],{"class":518},"]",[508,973,539],{"class":522},[508,975,976],{"class":618},"                 \u002F\u002F optional: operands declared as open sheets\n",[508,978,979,982,984,987,991,994,996],{"class":510,"line":560},[508,980,981],{"class":959},"  mode",[508,983,963],{"class":522},[508,985,986],{"class":522}," \"",[508,988,990],{"class":989},"sfazB","primitives",[508,992,993],{"class":522},"\"",[508,995,539],{"class":522},[508,997,998],{"class":618},"          \u002F\u002F intersection mode (\"sos\" or \"primitives\")\n",[508,1000,1001,1004,1006,1009,1011],{"class":510,"line":622},[508,1002,1003],{"class":959},"  tolerance",[508,1005,963],{"class":522},[508,1007,1008],{"class":589}," 0",[508,1010,539],{"class":522},[508,1012,1013],{"class":618},"                \u002F\u002F predicate tolerance band (0 = exact)\n",[508,1015,1016,1019,1021,1023,1026,1028,1030],{"class":510,"line":659},[508,1017,1018],{"class":959},"  triangulation",[508,1020,963],{"class":522},[508,1022,986],{"class":522},[508,1024,1025],{"class":989},"cdt",[508,1027,993],{"class":522},[508,1029,539],{"class":522},[508,1031,1032],{"class":618},"        \u002F\u002F cut-surface triangulation (see below)\n",[508,1034,1035,1037,1039],{"class":510,"line":664},[508,1036,638],{"class":522},[508,1038,593],{"class":518},[508,1040,550],{"class":522},[508,1042,1044],{"class":510,"line":1043},7,[508,1045,557],{"emptyLinePlaceholder":556},[508,1047,1049],{"class":510,"line":1048},8,[508,1050,1051],{"class":618},"\u002F\u002F or off the main thread:\n",[508,1053,1055,1057,1059,1061,1065,1067,1069,1072,1074,1076,1078,1080,1082,1085,1087,1089,1092,1094,1097,1099],{"class":510,"line":1054},9,[508,1056,515],{"class":514},[508,1058,519],{"class":518},[508,1060,523],{"class":522},[508,1062,1064],{"class":1063},"s7zQu"," await",[508,1066,526],{"class":518},[508,1068,529],{"class":522},[508,1070,1071],{"class":518},"async",[508,1073,529],{"class":522},[508,1075,533],{"class":532},[508,1077,949],{"class":518},[508,1079,539],{"class":522},[508,1081,627],{"class":522},[508,1083,1084],{"class":959}," triangulation",[508,1086,963],{"class":522},[508,1088,986],{"class":522},[508,1090,1091],{"class":989},"refinedCdt",[508,1093,993],{"class":522},[508,1095,1096],{"class":522}," }",[508,1098,593],{"class":518},[508,1100,550],{"class":522},[441,1102,1103,1104,1107,1108,1111],{},"All meshes must share the dtype (",[464,1105,1106],{},"float32","\u002F",[464,1109,1110],{},"float64","). Structures already built on the meshes (tree, topology) are reused, not rebuilt.",[441,1113,1114],{},"Everything passed at construction is remembered on the graph:",[499,1116,1118],{"className":501,"code":1117,"language":503,"meta":504,"style":504},"graph.forms            \u002F\u002F the input Mesh array, as passed\ngraph.sheets           \u002F\u002F sheet indices, as passed\ngraph.config           \u002F\u002F { mode, tolerance, resolveCrossings, triangulation }\ngraph.createdPoints    \u002F\u002F NDArray [K, 3] of created points, input dtype\n",[464,1119,1120,1132,1144,1156],{"__ignoreMap":504},[508,1121,1122,1124,1126,1129],{"class":510,"line":511},[508,1123,667],{"class":518},[508,1125,529],{"class":522},[508,1127,1128],{"class":518},"forms            ",[508,1130,1131],{"class":618},"\u002F\u002F the input Mesh array, as passed\n",[508,1133,1134,1136,1138,1141],{"class":510,"line":553},[508,1135,667],{"class":518},[508,1137,529],{"class":522},[508,1139,1140],{"class":518},"sheets           ",[508,1142,1143],{"class":618},"\u002F\u002F sheet indices, as passed\n",[508,1145,1146,1148,1150,1153],{"class":510,"line":560},[508,1147,667],{"class":518},[508,1149,529],{"class":522},[508,1151,1152],{"class":518},"config           ",[508,1154,1155],{"class":618},"\u002F\u002F { mode, tolerance, resolveCrossings, triangulation }\n",[508,1157,1158,1160,1162,1165],{"class":510,"line":622},[508,1159,667],{"class":518},[508,1161,529],{"class":522},[508,1163,1164],{"class":518},"createdPoints    ",[508,1166,1167],{"class":618},"\u002F\u002F NDArray [K, 3] of created points, input dtype\n",[1169,1170,1172],"h3",{"id":1171},"cut-surface-triangulation","Cut-Surface Triangulation",[441,1174,1175,1178],{},[464,1176,1177],{},"triangulation"," selects how cut faces are triangulated:",[454,1180,1181,1187],{},[457,1182,1183,1186],{},[464,1184,1185],{},"\"cdt\""," (default) — plain constrained Delaunay per cut loop.",[457,1188,1189,1192,1193,1196],{},[464,1190,1191],{},"\"refinedCdt\""," — quality refinement of the cut surface (Ruppert circumcenter insertion). Boundary splits are negotiated globally, so shared loop boundaries stay ",[445,1194,1195],{},"watertight by construction","; refined outputs carry more created points.",[1169,1198,1200],{"id":1199},"sheets","Sheets",[441,1202,1203,1204,1206,1207,1210],{},"An operand listed in ",[464,1205,1199],{}," is treated as an ",[445,1208,1209],{},"oriented open surface"," that cuts volumes through the same boolean algebra without enclosing one — a terrain horizon splitting a block, for example.",[450,1212,1214],{"id":1213},"boolean-meshes","Boolean Meshes",[499,1216,1218],{"className":501,"code":1217,"language":503,"meta":504,"style":504},"const result = graph.mesh(tf.op(0).sub(tf.op(1)));   \u002F\u002F Mesh\n",[464,1219,1220],{"__ignoreMap":504},[508,1221,1222,1224,1227,1229,1231,1233,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253,1255,1257,1259,1261,1263,1265],{"class":510,"line":511},[508,1223,515],{"class":514},[508,1225,1226],{"class":518}," result ",[508,1228,523],{"class":522},[508,1230,570],{"class":518},[508,1232,529],{"class":522},[508,1234,575],{"class":532},[508,1236,578],{"class":518},[508,1238,529],{"class":522},[508,1240,583],{"class":532},[508,1242,586],{"class":518},[508,1244,590],{"class":589},[508,1246,593],{"class":518},[508,1248,529],{"class":522},[508,1250,598],{"class":532},[508,1252,578],{"class":518},[508,1254,529],{"class":522},[508,1256,583],{"class":532},[508,1258,586],{"class":518},[508,1260,609],{"class":589},[508,1262,612],{"class":518},[508,1264,615],{"class":522},[508,1266,1267],{"class":618},"   \u002F\u002F Mesh\n",[441,1269,1270,1271,1274,1275,1278],{},"With no expression, ",[464,1272,1273],{},"graph.mesh()"," returns the ",[445,1276,1277],{},"full arrangement mesh"," — every input face, cut at intersections, each surface emitted once.",[1169,1280,1282],{"id":1281},"face-provenance","Face Provenance",[499,1284,1286],{"className":501,"code":1285,"language":503,"meta":504,"style":504},"const { mesh, tagLabels, faceLabels } =\n  graph.mesh(tf.op(0).or(1), { returnSourceIds: true });\n\u002F\u002F tagLabels[f]  -> which input mesh face f came from\n\u002F\u002F faceLabels[f] -> the original face id within it\n",[464,1287,1288,1312,1362,1367],{"__ignoreMap":504},[508,1289,1290,1292,1294,1297,1299,1302,1304,1307,1309],{"class":510,"line":511},[508,1291,515],{"class":514},[508,1293,627],{"class":522},[508,1295,1296],{"class":518}," mesh",[508,1298,539],{"class":522},[508,1300,1301],{"class":518}," tagLabels",[508,1303,539],{"class":522},[508,1305,1306],{"class":518}," faceLabels ",[508,1308,638],{"class":522},[508,1310,1311],{"class":522}," =\n",[508,1313,1314,1317,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1350,1352,1356,1358,1360],{"class":510,"line":553},[508,1315,1316],{"class":518},"  graph",[508,1318,529],{"class":522},[508,1320,575],{"class":532},[508,1322,578],{"class":518},[508,1324,529],{"class":522},[508,1326,583],{"class":532},[508,1328,586],{"class":518},[508,1330,590],{"class":589},[508,1332,593],{"class":518},[508,1334,529],{"class":522},[508,1336,829],{"class":532},[508,1338,586],{"class":518},[508,1340,609],{"class":589},[508,1342,593],{"class":518},[508,1344,539],{"class":522},[508,1346,627],{"class":522},[508,1348,1349],{"class":959}," returnSourceIds",[508,1351,963],{"class":522},[508,1353,1355],{"class":1354},"sfNiH"," true",[508,1357,1096],{"class":522},[508,1359,593],{"class":518},[508,1361,550],{"class":522},[508,1363,1364],{"class":510,"line":560},[508,1365,1366],{"class":618},"\u002F\u002F tagLabels[f]  -> which input mesh face f came from\n",[508,1368,1369],{"class":510,"line":622},[508,1370,1371],{"class":618},"\u002F\u002F faceLabels[f] -> the original face id within it\n",[1169,1373,1375],{"id":1374},"index-maps","Index Maps",[499,1377,1379],{"className":501,"code":1378,"language":503,"meta":504,"style":504},"const im = graph.mesh(tf.op(0).sub(1), { returnIndexMap: true });\nim.pointTagLabels;   \u002F\u002F output point -> input mesh (created -> nTags)\nim.pointLabels;      \u002F\u002F output point -> input point id\nim.faceTagLabels;    \u002F\u002F output face  -> input mesh\nim.faceLabels;       \u002F\u002F output face  -> original face id\nim.pointFOffsets;    \u002F\u002F forward map blocks: offsets[tag] slices pointFData\nim.pointFData;\n",[464,1380,1381,1435,1450,1464,1478,1492,1506],{"__ignoreMap":504},[508,1382,1383,1385,1388,1390,1392,1394,1396,1398,1400,1402,1404,1406,1408,1410,1412,1414,1416,1418,1420,1422,1425,1427,1429,1431,1433],{"class":510,"line":511},[508,1384,515],{"class":514},[508,1386,1387],{"class":518}," im ",[508,1389,523],{"class":522},[508,1391,570],{"class":518},[508,1393,529],{"class":522},[508,1395,575],{"class":532},[508,1397,578],{"class":518},[508,1399,529],{"class":522},[508,1401,583],{"class":532},[508,1403,586],{"class":518},[508,1405,590],{"class":589},[508,1407,593],{"class":518},[508,1409,529],{"class":522},[508,1411,598],{"class":532},[508,1413,586],{"class":518},[508,1415,609],{"class":589},[508,1417,593],{"class":518},[508,1419,539],{"class":522},[508,1421,627],{"class":522},[508,1423,1424],{"class":959}," returnIndexMap",[508,1426,963],{"class":522},[508,1428,1355],{"class":1354},[508,1430,1096],{"class":522},[508,1432,593],{"class":518},[508,1434,550],{"class":522},[508,1436,1437,1440,1442,1445,1447],{"class":510,"line":553},[508,1438,1439],{"class":518},"im",[508,1441,529],{"class":522},[508,1443,1444],{"class":518},"pointTagLabels",[508,1446,615],{"class":522},[508,1448,1449],{"class":618},"   \u002F\u002F output point -> input mesh (created -> nTags)\n",[508,1451,1452,1454,1456,1459,1461],{"class":510,"line":560},[508,1453,1439],{"class":518},[508,1455,529],{"class":522},[508,1457,1458],{"class":518},"pointLabels",[508,1460,615],{"class":522},[508,1462,1463],{"class":618},"      \u002F\u002F output point -> input point id\n",[508,1465,1466,1468,1470,1473,1475],{"class":510,"line":622},[508,1467,1439],{"class":518},[508,1469,529],{"class":522},[508,1471,1472],{"class":518},"faceTagLabels",[508,1474,615],{"class":522},[508,1476,1477],{"class":618},"    \u002F\u002F output face  -> input mesh\n",[508,1479,1480,1482,1484,1487,1489],{"class":510,"line":659},[508,1481,1439],{"class":518},[508,1483,529],{"class":522},[508,1485,1486],{"class":518},"faceLabels",[508,1488,615],{"class":522},[508,1490,1491],{"class":618},"       \u002F\u002F output face  -> original face id\n",[508,1493,1494,1496,1498,1501,1503],{"class":510,"line":664},[508,1495,1439],{"class":518},[508,1497,529],{"class":522},[508,1499,1500],{"class":518},"pointFOffsets",[508,1502,615],{"class":522},[508,1504,1505],{"class":618},"    \u002F\u002F forward map blocks: offsets[tag] slices pointFData\n",[508,1507,1508,1510,1512,1515],{"class":510,"line":1043},[508,1509,1439],{"class":518},[508,1511,529],{"class":522},[508,1513,1514],{"class":518},"pointFData",[508,1516,550],{"class":522},[441,1518,1519,1522,1523,1526],{},[464,1520,1521],{},"returnSourceIds"," and ",[464,1524,1525],{},"returnIndexMap"," are exclusive; the index map already carries the face labels. The index-map form requires an expression.",[450,1528,1530],{"id":1529},"domain-decomposition","Domain Decomposition",[499,1532,1534],{"className":501,"code":1533,"language":503,"meta":504,"style":504},"const { meshes, ids } = graph.domains();   \u002F\u002F one watertight Mesh per domain\n",[464,1535,1536],{"__ignoreMap":504},[508,1537,1538,1540,1542,1544,1546,1548,1550,1552,1554,1556,1558,1560,1562],{"class":510,"line":511},[508,1539,515],{"class":514},[508,1541,627],{"class":522},[508,1543,630],{"class":518},[508,1545,539],{"class":522},[508,1547,635],{"class":518},[508,1549,638],{"class":522},[508,1551,641],{"class":522},[508,1553,570],{"class":518},[508,1555,529],{"class":522},[508,1557,648],{"class":532},[508,1559,651],{"class":518},[508,1561,615],{"class":522},[508,1563,1564],{"class":618},"   \u002F\u002F one watertight Mesh per domain\n",[441,1566,1567,1568,1571],{},"The expression is optional and the options can take its place — no ",[464,1569,1570],{},"null"," placeholder needed:",[499,1573,1575],{"className":501,"code":1574,"language":503,"meta":504,"style":504},"graph.domains();                                     \u002F\u002F every kept domain\ngraph.domains(tf.op(0).and(1));                      \u002F\u002F inside the selection\ngraph.domains({ returnSourceIds: true });            \u002F\u002F options only\ngraph.domains(tf.op(0), { returnIndexMap: true });   \u002F\u002F both\n",[464,1576,1577,1592,1627,1655],{"__ignoreMap":504},[508,1578,1579,1581,1583,1585,1587,1589],{"class":510,"line":511},[508,1580,667],{"class":518},[508,1582,529],{"class":522},[508,1584,648],{"class":532},[508,1586,651],{"class":518},[508,1588,615],{"class":522},[508,1590,1591],{"class":618},"                                     \u002F\u002F every kept domain\n",[508,1593,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620,1622,1624],{"class":510,"line":553},[508,1595,667],{"class":518},[508,1597,529],{"class":522},[508,1599,648],{"class":532},[508,1601,578],{"class":518},[508,1603,529],{"class":522},[508,1605,583],{"class":532},[508,1607,586],{"class":518},[508,1609,590],{"class":589},[508,1611,593],{"class":518},[508,1613,529],{"class":522},[508,1615,865],{"class":532},[508,1617,586],{"class":518},[508,1619,609],{"class":589},[508,1621,837],{"class":518},[508,1623,615],{"class":522},[508,1625,1626],{"class":618},"                      \u002F\u002F inside the selection\n",[508,1628,1629,1631,1633,1635,1637,1640,1642,1644,1646,1648,1650,1652],{"class":510,"line":560},[508,1630,667],{"class":518},[508,1632,529],{"class":522},[508,1634,648],{"class":532},[508,1636,586],{"class":518},[508,1638,1639],{"class":522},"{",[508,1641,1349],{"class":959},[508,1643,963],{"class":522},[508,1645,1355],{"class":1354},[508,1647,1096],{"class":522},[508,1649,593],{"class":518},[508,1651,615],{"class":522},[508,1653,1654],{"class":618},"            \u002F\u002F options only\n",[508,1656,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683,1685,1687,1689,1691],{"class":510,"line":622},[508,1658,667],{"class":518},[508,1660,529],{"class":522},[508,1662,648],{"class":532},[508,1664,578],{"class":518},[508,1666,529],{"class":522},[508,1668,583],{"class":532},[508,1670,586],{"class":518},[508,1672,590],{"class":589},[508,1674,593],{"class":518},[508,1676,539],{"class":522},[508,1678,627],{"class":522},[508,1680,1424],{"class":959},[508,1682,963],{"class":522},[508,1684,1355],{"class":1354},[508,1686,1096],{"class":522},[508,1688,593],{"class":518},[508,1690,615],{"class":522},[508,1692,1693],{"class":618},"   \u002F\u002F both\n",[441,1695,1696,1697,1701],{},"The same selection can be made by hand from one full extraction — see ",[759,1698,1700],{"href":1699},"#cell-classification","Cell Classification"," below; ids are stable across queries on one graph, so the two routes agree cell for cell.",[441,1703,1704,1705,1708,1709,1712],{},"Options: ",[464,1706,1707],{},"excludeOuterShell"," drops the unbounded outside domain; ",[464,1710,1711],{},"ignoreOpenFragments"," fuses open fragments (fins, damage) instead of letting them partition volumes. Both default on.",[441,1714,1715,1717,1718,1107,1721,1724,1725,1107,1728,1731,1732,1735,1736,1738,1739,1741,1742,1724,1745,1724,1748,1751,1752,1755],{},[464,1716,1521],{}," adds per-cell face-provenance blocks (",[464,1719,1720],{},"tagOffsets",[464,1722,1723],{},"tagData",", ",[464,1726,1727],{},"faceOffsets",[464,1729,1730],{},"faceData",") parallel to ",[464,1733,1734],{},"meshes","; ",[464,1737,1525],{}," adds per-cell face ",[445,1740,865],{}," point maps plus the sentinels (",[464,1743,1744],{},"nTags",[464,1746,1747],{},"nOutputPoints",[464,1749,1750],{},"nOriginalPoints",") and the ",[464,1753,1754],{},"inclusion"," matrix.",[1169,1757,1700],{"id":1758},"cell-classification",[499,1760,1762],{"className":501,"code":1761,"language":503,"meta":504,"style":504},"const im = graph.domains({ returnIndexMap: true });\n\nconst inc = im.inclusion;      \u002F\u002F [nCells, nTags] boolean NDArray, row-major\nconst d = inc.data;\nconst onlyA = im.meshes.filter((_, k) =>\n  d[k * im.nTags + 0] && !d[k * im.nTags + 1]);   \u002F\u002F inside A, outside B\n",[464,1763,1764,1794,1798,1819,1838,1876],{"__ignoreMap":504},[508,1765,1766,1768,1770,1772,1774,1776,1778,1780,1782,1784,1786,1788,1790,1792],{"class":510,"line":511},[508,1767,515],{"class":514},[508,1769,1387],{"class":518},[508,1771,523],{"class":522},[508,1773,570],{"class":518},[508,1775,529],{"class":522},[508,1777,648],{"class":532},[508,1779,586],{"class":518},[508,1781,1639],{"class":522},[508,1783,1424],{"class":959},[508,1785,963],{"class":522},[508,1787,1355],{"class":1354},[508,1789,1096],{"class":522},[508,1791,593],{"class":518},[508,1793,550],{"class":522},[508,1795,1796],{"class":510,"line":553},[508,1797,557],{"emptyLinePlaceholder":556},[508,1799,1800,1802,1805,1807,1810,1812,1814,1816],{"class":510,"line":560},[508,1801,515],{"class":514},[508,1803,1804],{"class":518}," inc ",[508,1806,523],{"class":522},[508,1808,1809],{"class":518}," im",[508,1811,529],{"class":522},[508,1813,1754],{"class":518},[508,1815,615],{"class":522},[508,1817,1818],{"class":618},"      \u002F\u002F [nCells, nTags] boolean NDArray, row-major\n",[508,1820,1821,1823,1826,1828,1831,1833,1836],{"class":510,"line":622},[508,1822,515],{"class":514},[508,1824,1825],{"class":518}," d ",[508,1827,523],{"class":522},[508,1829,1830],{"class":518}," inc",[508,1832,529],{"class":522},[508,1834,1835],{"class":518},"data",[508,1837,550],{"class":522},[508,1839,1840,1842,1845,1847,1849,1851,1853,1855,1858,1860,1862,1866,1868,1871,1873],{"class":510,"line":659},[508,1841,515],{"class":514},[508,1843,1844],{"class":518}," onlyA ",[508,1846,523],{"class":522},[508,1848,1809],{"class":518},[508,1850,529],{"class":522},[508,1852,1734],{"class":518},[508,1854,529],{"class":522},[508,1856,1857],{"class":532},"filter",[508,1859,586],{"class":518},[508,1861,586],{"class":522},[508,1863,1865],{"class":1864},"sHdIc","_",[508,1867,539],{"class":522},[508,1869,1870],{"class":1864}," k",[508,1872,593],{"class":522},[508,1874,1875],{"class":514}," =>\n",[508,1877,1878,1881,1884,1886,1888,1891,1894,1896,1899,1902,1905,1908,1910,1912,1914,1916,1918,1921,1924,1926],{"class":510,"line":664},[508,1879,1880],{"class":518},"  d[k ",[508,1882,1883],{"class":522},"*",[508,1885,1809],{"class":518},[508,1887,529],{"class":522},[508,1889,1890],{"class":518},"nTags ",[508,1892,1893],{"class":522},"+",[508,1895,1008],{"class":589},[508,1897,1898],{"class":518},"] ",[508,1900,1901],{"class":522},"&&",[508,1903,1904],{"class":522}," !",[508,1906,1907],{"class":518},"d[k ",[508,1909,1883],{"class":522},[508,1911,1809],{"class":518},[508,1913,529],{"class":522},[508,1915,1890],{"class":518},[508,1917,1893],{"class":522},[508,1919,1920],{"class":589}," 1",[508,1922,1923],{"class":518},"])",[508,1925,615],{"class":522},[508,1927,1928],{"class":618},"   \u002F\u002F inside A, outside B\n",[441,1930,1931,1933],{},[464,1932,1754],{}," classifies every cell against every operand, so one extraction\nanswers every selection — a mask picks the same cells the equivalent\nexpression query would return. A sheet operand's column means \"behind the\nsheet's normal\".",[499,1935,1937],{"className":501,"code":1936,"language":503,"meta":504,"style":504},"const all = graph.domains({ excludeOuterShell: false, returnIndexMap: true });\nconst outer = all.meshes.filter((_, k) =>          \u002F\u002F the outer-shell cells\n  !all.inclusion.data.slice(k * all.nTags, (k + 1) * all.nTags).some(Boolean));\n",[464,1938,1939,1980,2018],{"__ignoreMap":504},[508,1940,1941,1943,1946,1948,1950,1952,1954,1956,1958,1961,1963,1966,1968,1970,1972,1974,1976,1978],{"class":510,"line":511},[508,1942,515],{"class":514},[508,1944,1945],{"class":518}," all ",[508,1947,523],{"class":522},[508,1949,570],{"class":518},[508,1951,529],{"class":522},[508,1953,648],{"class":532},[508,1955,586],{"class":518},[508,1957,1639],{"class":522},[508,1959,1960],{"class":959}," excludeOuterShell",[508,1962,963],{"class":522},[508,1964,1965],{"class":1354}," false",[508,1967,539],{"class":522},[508,1969,1424],{"class":959},[508,1971,963],{"class":522},[508,1973,1355],{"class":1354},[508,1975,1096],{"class":522},[508,1977,593],{"class":518},[508,1979,550],{"class":522},[508,1981,1982,1984,1987,1989,1992,1994,1996,1998,2000,2002,2004,2006,2008,2010,2012,2015],{"class":510,"line":553},[508,1983,515],{"class":514},[508,1985,1986],{"class":518}," outer ",[508,1988,523],{"class":522},[508,1990,1991],{"class":518}," all",[508,1993,529],{"class":522},[508,1995,1734],{"class":518},[508,1997,529],{"class":522},[508,1999,1857],{"class":532},[508,2001,586],{"class":518},[508,2003,586],{"class":522},[508,2005,1865],{"class":1864},[508,2007,539],{"class":522},[508,2009,1870],{"class":1864},[508,2011,593],{"class":522},[508,2013,2014],{"class":514}," =>",[508,2016,2017],{"class":618},"          \u002F\u002F the outer-shell cells\n",[508,2019,2020,2023,2026,2028,2030,2032,2034,2036,2039,2042,2044,2046,2048,2050,2052,2055,2057,2059,2062,2064,2066,2068,2071,2073,2076,2079],{"class":510,"line":560},[508,2021,2022],{"class":522},"  !",[508,2024,2025],{"class":518},"all",[508,2027,529],{"class":522},[508,2029,1754],{"class":518},[508,2031,529],{"class":522},[508,2033,1835],{"class":518},[508,2035,529],{"class":522},[508,2037,2038],{"class":532},"slice",[508,2040,2041],{"class":518},"(k ",[508,2043,1883],{"class":522},[508,2045,1991],{"class":518},[508,2047,529],{"class":522},[508,2049,1744],{"class":518},[508,2051,539],{"class":522},[508,2053,2054],{"class":518}," (k ",[508,2056,1893],{"class":522},[508,2058,1920],{"class":589},[508,2060,2061],{"class":518},") ",[508,2063,1883],{"class":522},[508,2065,1991],{"class":518},[508,2067,529],{"class":522},[508,2069,2070],{"class":518},"nTags)",[508,2072,529],{"class":522},[508,2074,2075],{"class":532},"some",[508,2077,2078],{"class":518},"(Boolean))",[508,2080,550],{"class":522},[441,2082,2083,2084,2087,2088,2091],{},"The ",[445,2085,2086],{},"outer shell"," is the space inside no operand — the unbounded outside,\nplus any void enclosed by nothing. Its cells are exactly the all-false rows,\nand there can be several: disjoint operand clusters each bound their own\npatch of the outside. ",[464,2089,2090],{},"excludeOuterShell: true"," (the default) drops\nprecisely these rows.",[1169,2093,2095],{"id":2094},"sheets-and-open-fragments","Sheets and Open Fragments",[441,2097,2098,2099,2101,2102,2105,2106,2109,2110,2113,2114,2117,2118,2121,2122,2124],{},"For a sheet, ",[464,2100,1711],{}," governs whether its ",[445,2103,2104],{},"dangling"," part — fragments that seal nothing, like a knife's rim poking past the solids — partitions space. With the default (",[464,2107,2108],{},"True","), only the sealed portion of the sheet cuts; the outside stays whole, and with ",[464,2111,2112],{},"excludeOuterShell: false"," it returns as one closed inverted cell. With ",[464,2115,2116],{},"False",", the dangling part separates too: the outside splits into a front and a behind half, each an ",[445,2119,2120],{},"open"," inverted mesh — and the behind half carries the sheet bit, so ",[464,2123,1707],{}," (which drops all-false rows) keeps it. Sheet bits are half-space indicators for bounded and unbounded regions alike: behind the normal is \"inside\", everywhere.",[450,2126,2128],{"id":2127},"intersection-curves","Intersection Curves",[441,2130,2131],{},"The seam network of the arrangement — the polylines where surfaces of different operands cross (coincident walls excluded):",[499,2133,2135],{"className":501,"code":2134,"language":503,"meta":504,"style":504},"const curves = graph.intersectionCurves();   \u002F\u002F Curves, input dtype\ncurves.delete();\n",[464,2136,2137,2160],{"__ignoreMap":504},[508,2138,2139,2141,2144,2146,2148,2150,2153,2155,2157],{"class":510,"line":511},[508,2140,515],{"class":514},[508,2142,2143],{"class":518}," curves ",[508,2145,523],{"class":522},[508,2147,570],{"class":518},[508,2149,529],{"class":522},[508,2151,2152],{"class":532},"intersectionCurves",[508,2154,651],{"class":518},[508,2156,615],{"class":522},[508,2158,2159],{"class":618},"   \u002F\u002F Curves, input dtype\n",[508,2161,2162,2165,2167,2169,2171],{"class":510,"line":553},[508,2163,2164],{"class":518},"curves",[508,2166,529],{"class":522},[508,2168,672],{"class":532},[508,2170,651],{"class":518},[508,2172,550],{"class":522},[450,2174,2175],{"id":1071},"Async",[441,2177,2178,2179,2182],{},"Every query has an async twin under ",[464,2180,2181],{},"tf.async",", running on the worker pool:",[499,2184,2186],{"className":501,"code":2185,"language":503,"meta":504,"style":504},"const graph = await tf.async.csgGraph(meshes);\nconst diff  = await tf.async.csgMesh(graph, tf.op(0).sub(1));\nconst doms  = await tf.async.csgDomains(graph, { returnSourceIds: true });\nconst seams = await tf.async.csgIntersectionCurves(graph);\n",[464,2187,2188,2213,2264,2304],{"__ignoreMap":504},[508,2189,2190,2192,2194,2196,2198,2200,2202,2204,2206,2208,2211],{"class":510,"line":511},[508,2191,515],{"class":514},[508,2193,519],{"class":518},[508,2195,523],{"class":522},[508,2197,1064],{"class":1063},[508,2199,526],{"class":518},[508,2201,529],{"class":522},[508,2203,1071],{"class":518},[508,2205,529],{"class":522},[508,2207,533],{"class":532},[508,2209,2210],{"class":518},"(meshes)",[508,2212,550],{"class":522},[508,2214,2215,2217,2220,2222,2224,2226,2228,2230,2232,2235,2238,2240,2242,2244,2246,2248,2250,2252,2254,2256,2258,2260,2262],{"class":510,"line":553},[508,2216,515],{"class":514},[508,2218,2219],{"class":518}," diff  ",[508,2221,523],{"class":522},[508,2223,1064],{"class":1063},[508,2225,526],{"class":518},[508,2227,529],{"class":522},[508,2229,1071],{"class":518},[508,2231,529],{"class":522},[508,2233,2234],{"class":532},"csgMesh",[508,2236,2237],{"class":518},"(graph",[508,2239,539],{"class":522},[508,2241,526],{"class":518},[508,2243,529],{"class":522},[508,2245,583],{"class":532},[508,2247,586],{"class":518},[508,2249,590],{"class":589},[508,2251,593],{"class":518},[508,2253,529],{"class":522},[508,2255,598],{"class":532},[508,2257,586],{"class":518},[508,2259,609],{"class":589},[508,2261,837],{"class":518},[508,2263,550],{"class":522},[508,2265,2266,2268,2271,2273,2275,2277,2279,2281,2283,2286,2288,2290,2292,2294,2296,2298,2300,2302],{"class":510,"line":560},[508,2267,515],{"class":514},[508,2269,2270],{"class":518}," doms  ",[508,2272,523],{"class":522},[508,2274,1064],{"class":1063},[508,2276,526],{"class":518},[508,2278,529],{"class":522},[508,2280,1071],{"class":518},[508,2282,529],{"class":522},[508,2284,2285],{"class":532},"csgDomains",[508,2287,2237],{"class":518},[508,2289,539],{"class":522},[508,2291,627],{"class":522},[508,2293,1349],{"class":959},[508,2295,963],{"class":522},[508,2297,1355],{"class":1354},[508,2299,1096],{"class":522},[508,2301,593],{"class":518},[508,2303,550],{"class":522},[508,2305,2306,2308,2311,2313,2315,2317,2319,2321,2323,2326,2329],{"class":510,"line":622},[508,2307,515],{"class":514},[508,2309,2310],{"class":518}," seams ",[508,2312,523],{"class":522},[508,2314,1064],{"class":1063},[508,2316,526],{"class":518},[508,2318,529],{"class":522},[508,2320,1071],{"class":518},[508,2322,529],{"class":522},[508,2324,2325],{"class":532},"csgIntersectionCurves",[508,2327,2328],{"class":518},"(graph)",[508,2330,550],{"class":522},[450,2332,2334],{"id":2333},"memory","Memory",[441,2336,2337,2340,2341,2344,2345,2348,2349,2352,2353,2356,2357,2360,2361,529],{},[464,2338,2339],{},"CsgGraph"," follows the same lifetime rules as ",[464,2342,2343],{},"Mesh",": call ",[464,2346,2347],{},".delete()"," when done (or use ",[464,2350,2351],{},"using"," \u002F ",[464,2354,2355],{},"[Symbol.dispose]","); a ",[464,2358,2359],{},"FinalizationRegistry"," backstop releases leaked handles. Meshes returned by queries are independent and need their own ",[464,2362,2347],{},[450,2364,2366],{"id":2365},"many-operations-one-graph","Many Operations, One Graph",[499,2368,2370],{"className":501,"code":2369,"language":503,"meta":504,"style":504},"const graph = await tf.async.csgGraph([a, b, c]);\n\nconst union = graph.mesh(tf.op(0).or(1).or(2));\nconst carved = graph.mesh(tf.op(0).sub(1).sub(2));\nconst { meshes, ids } = graph.domains();\n\ngraph.delete();\n",[464,2371,2372,2407,2411,2460,2508,2534,2538],{"__ignoreMap":504},[508,2373,2374,2376,2378,2380,2382,2384,2386,2388,2390,2392,2395,2397,2400,2402,2405],{"class":510,"line":511},[508,2375,515],{"class":514},[508,2377,519],{"class":518},[508,2379,523],{"class":522},[508,2381,1064],{"class":1063},[508,2383,526],{"class":518},[508,2385,529],{"class":522},[508,2387,1071],{"class":518},[508,2389,529],{"class":522},[508,2391,533],{"class":532},[508,2393,2394],{"class":518},"([a",[508,2396,539],{"class":522},[508,2398,2399],{"class":518}," b",[508,2401,539],{"class":522},[508,2403,2404],{"class":518}," c])",[508,2406,550],{"class":522},[508,2408,2409],{"class":510,"line":553},[508,2410,557],{"emptyLinePlaceholder":556},[508,2412,2413,2415,2418,2420,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446,2448,2450,2452,2454,2456,2458],{"class":510,"line":560},[508,2414,515],{"class":514},[508,2416,2417],{"class":518}," union ",[508,2419,523],{"class":522},[508,2421,570],{"class":518},[508,2423,529],{"class":522},[508,2425,575],{"class":532},[508,2427,578],{"class":518},[508,2429,529],{"class":522},[508,2431,583],{"class":532},[508,2433,586],{"class":518},[508,2435,590],{"class":589},[508,2437,593],{"class":518},[508,2439,529],{"class":522},[508,2441,829],{"class":532},[508,2443,586],{"class":518},[508,2445,609],{"class":589},[508,2447,593],{"class":518},[508,2449,529],{"class":522},[508,2451,829],{"class":532},[508,2453,586],{"class":518},[508,2455,834],{"class":589},[508,2457,837],{"class":518},[508,2459,550],{"class":522},[508,2461,2462,2464,2466,2468,2470,2472,2474,2476,2478,2480,2482,2484,2486,2488,2490,2492,2494,2496,2498,2500,2502,2504,2506],{"class":510,"line":622},[508,2463,515],{"class":514},[508,2465,794],{"class":518},[508,2467,523],{"class":522},[508,2469,570],{"class":518},[508,2471,529],{"class":522},[508,2473,575],{"class":532},[508,2475,578],{"class":518},[508,2477,529],{"class":522},[508,2479,583],{"class":532},[508,2481,586],{"class":518},[508,2483,590],{"class":589},[508,2485,593],{"class":518},[508,2487,529],{"class":522},[508,2489,598],{"class":532},[508,2491,586],{"class":518},[508,2493,609],{"class":589},[508,2495,593],{"class":518},[508,2497,529],{"class":522},[508,2499,598],{"class":532},[508,2501,586],{"class":518},[508,2503,834],{"class":589},[508,2505,837],{"class":518},[508,2507,550],{"class":522},[508,2509,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530,2532],{"class":510,"line":659},[508,2511,515],{"class":514},[508,2513,627],{"class":522},[508,2515,630],{"class":518},[508,2517,539],{"class":522},[508,2519,635],{"class":518},[508,2521,638],{"class":522},[508,2523,641],{"class":522},[508,2525,570],{"class":518},[508,2527,529],{"class":522},[508,2529,648],{"class":532},[508,2531,651],{"class":518},[508,2533,550],{"class":522},[508,2535,2536],{"class":510,"line":664},[508,2537,557],{"emptyLinePlaceholder":556},[508,2539,2540,2542,2544,2546,2548],{"class":510,"line":1043},[508,2541,667],{"class":518},[508,2543,529],{"class":522},[508,2545,672],{"class":532},[508,2547,651],{"class":518},[508,2549,550],{"class":522},[441,2551,2552],{},"Three results, one arrangement build. This is the pattern for interactive workflows: build on load (async), query per user action.",[2554,2555,2556],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":504,"searchDepth":511,"depth":553,"links":2558},[2559,2560,2561,2565,2569,2573,2574,2575,2576],{"id":452,"depth":553,"text":34},{"id":688,"depth":553,"text":689},{"id":926,"depth":553,"text":927,"children":2562},[2563,2564],{"id":1171,"depth":560,"text":1172},{"id":1199,"depth":560,"text":1200},{"id":1213,"depth":553,"text":1214,"children":2566},[2567,2568],{"id":1281,"depth":560,"text":1282},{"id":1374,"depth":560,"text":1375},{"id":1529,"depth":553,"text":1530,"children":2570},[2571,2572],{"id":1758,"depth":560,"text":1700},{"id":2094,"depth":560,"text":2095},{"id":2127,"depth":553,"text":2128},{"id":1071,"depth":553,"text":2175},{"id":2333,"depth":553,"text":2334},{"id":2365,"depth":553,"text":2366},"N-form boolean expressions over one arrangement, built once.","md",null,{},{"icon":75},{"title":72,"description":2577},"thNkX30cS5I1qhIQOwqD9gsXaQQLqg_jj_AI0qfpeFI",[2585,2587],{"title":67,"path":68,"stem":69,"description":2586,"icon":70,"children":-1},"Exact mesh arrangements, booleans, and curve embedding.",{"title":77,"path":78,"stem":79,"description":2588,"icon":80,"children":-1},"Remove duplicates, degenerates, and unreferenced elements.",1783858068128]