const CUT_COLORS={myocardium:10242622,vesselRed:9316900,vesselBlue:2768248,papillary:8010274,coronary:10496032,vein:3099274,leaflet:15129020};function sectionGroups(o){const f=o.chambers.userData.walls,p=o.chambers.userData.cavities,u=[];for(const t of Object.values(o.valves.userData.valves))u.push(...t.userData.leaflets);const c=t=>o.vessels.children.filter(a=>t.includes(a.name)),r=(t,a)=>a.map(d=>t[d]).filter(Boolean);return[{name:"myocardiumV",color:CUT_COLORS.myocardium,plus:r(f,["LV","RV"]),offset:0},{name:"bloodLV",color:CUT_COLORS.vesselRed,plus:r(p,["LV"]),offset:-1,blood:"LV_cavity"},{name:"bloodRV",color:CUT_COLORS.vesselBlue,plus:r(p,["RV"]),offset:-1,blood:"RV_cavity"},{name:"myocardiumA",color:CUT_COLORS.myocardium,plus:r(f,["LA","RA"]),offset:0},{name:"bloodLA",color:CUT_COLORS.vesselRed,plus:r(p,["LA"]),offset:-1,blood:"LA_cavity"},{name:"bloodRA",color:CUT_COLORS.vesselBlue,plus:r(p,["RA"]),offset:-1,blood:"RA_cavity"},{name:"capAORTA",color:CUT_COLORS.vesselRed,plus:c(["AORTA"]),offset:-1,blood:"AORTA"},{name:"capPULM",color:CUT_COLORS.vesselRed,plus:c(["PULM_VEINS"]),offset:-1,blood:"PULM_VEINS"},{name:"capPA",color:CUT_COLORS.vesselBlue,plus:c(["PA"]),offset:-1,blood:"PA"},{name:"capSVC",color:CUT_COLORS.vesselBlue,plus:c(["SVC"]),offset:-1,blood:"SVC"},{name:"capIVC",color:CUT_COLORS.vesselBlue,plus:c(["IVC"]),offset:-1,blood:"IVC"},{name:"papillary",color:CUT_COLORS.papillary,plus:o.papillary.children,offset:-2},{name:"coronaries",color:CUT_COLORS.coronary,plus:o.coronaries.children.filter(t=>!VEIN_NODES.includes(t.name)),offset:-2},{name:"veins",color:CUT_COLORS.vein,plus:o.coronaries.children.filter(t=>VEIN_NODES.includes(t.name)),offset:-2},{name:"leaflets",color:CUT_COLORS.leaflet,plus:u,offset:-3}]}function buildSectionRig(o,f){const p=sectionGroups(o.userData.parts),u=[],c=[],r=(e,l)=>new GFX.M.Basic({side:e,depthWrite:!1,depthTest:!1,colorWrite:!1,stencilWrite:!0,stencilFunc:THREE.AlwaysStencilFunc,stencilFail:l,stencilZFail:l,stencilZPass:l,clippingPlanes:[f]}),t=(e,l,R)=>{const s=THREE.IncrementWrapStencilOp,i=THREE.DecrementWrapStencilOp;(l>0?[[THREE.BackSide,s],[THREE.FrontSide,i]]:[[THREE.FrontSide,s],[THREE.BackSide,i]]).forEach(([O,g],A)=>{const n=new THREE.Mesh(e.geometry,r(O,g));n.name=`${e.name}_stencil${l>0?"":"_neg"}${A}`,n.renderOrder=R+A,n.morphTargetInfluences=e.morphTargetInfluences,n.morphTargetDictionary=e.morphTargetDictionary,n.raycast=()=>{},n.frustumCulled=!1,n.userData.stencilWriter=!0,e.add(n),u.push(n)})},a=new THREE.Group;a.name="sectionCaps",a.userData.sectionCap=!0,o.add(a),o.updateMatrixWorld(!0);const d=new THREE.Box3().setFromObject(o).applyMatrix4(o.matrixWorld.clone().invert()),v=d.getSize(new THREE.Vector3),y=d.getCenter(new THREE.Vector3),T=new THREE.PlaneGeometry(v.x*1.3+2,v.y*1.3+2);T.translate(y.x,y.y,0);let b=100;for(const e of p){const l=b;b+=10;for(const i of e.plus)t(i,1,l);for(const i of e.minus||[])t(i,-1,l+2);const R=new GFX.M.Standard({color:e.color,roughness:.85,metalness:0,side:THREE.DoubleSide,stencilWrite:!0,stencilRef:0,stencilFunc:THREE.NotEqualStencilFunc,stencilFail:THREE.ReplaceStencilOp,stencilZFail:THREE.ReplaceStencilOp,stencilZPass:THREE.ReplaceStencilOp,polygonOffset:!0,polygonOffsetFactor:e.offset,polygonOffsetUnits:e.offset}),s=new THREE.Mesh(T,R);s.name="cap_"+e.name,s.renderOrder=l+5,s.raycast=()=>{},s.receiveShadow=!1,s.userData.sectionCap=!0,s.userData.blood=e.blood||null,s.userData.capOffset=e.offset,window.GFX&&window.GFX.tsl||(s.onAfterRender=i=>i.clearStencil()),a.add(s),c.push(s)}let m=0;const w=new THREE.Vector3,S=new THREE.Vector3,E=()=>{o.updateMatrix(),w.set(0,0,-1).applyQuaternion(o.quaternion).normalize(),S.set(0,0,m).applyMatrix4(o.matrix),f.setFromNormalAndCoplanarPoint(w,S)},H=e=>{m=e,a.position.z=e,E()},V=e=>{for(const l of u)l.visible=e;a.visible=e};return V(!1),E(),{setEnabled:V,setDepth:H,update:E,writers:u,caps:c,get depth(){return m}}}Object.assign(window,{buildSectionRig});
