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