1"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6713],{4550:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var i=t(797),a=t(685),s=t(4848);function o({prefill:e="",text:n="Content feeling overwhelming? Catch up by asking Philodemus."}){const{siteConfig:t}=(0,i.A)();if(!(t.customFields&&t.customFields.chatEndpoint||""))return null;return(0,s.jsxs)("aside",{className:"vc-callout",children:[(0,s.jsx)(a.A,{size:40,className:"vc-callout__avatar"}),(0,s.jsx)("p",{className:"vc-callout__text",children:n}),(0,s.jsx)("button",{type:"button",className:"vc-callout__btn",onClick:()=>{"undefined"!=typeof window&&window.dispatchEvent(new CustomEvent("vc:open-chat",{detail:{prefill:e}}))},children:"Ask Philodemus"})]})}},5537:(e,n,t)=>{t.d(n,{A:()=>y});var i=t(6540),a=t(4164),s=t(5627),o=t(6347),l=t(372),r=t(604),c=t(1861),d=t(8749);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:t}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((({props:{value:e,label:n,attributes:t,default:i}})=>({value:e,label:n,attributes:t,default:i})))}(t);return function(e){const n=(0,c.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function p({value:e,tabValues:n}){return n.some((n=>n.value===e))}function m({queryString:e=!1,groupId:n}){const t=(0,o.W6)(),a=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,r.aZ)(a),(0,i.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,s=u(e),[o,r]=(0,i.useState)((()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!p({value:e,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const t=n.find((e=>e.default))??n[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:s}))),[c,h]=m({queryString:t,groupId:a}),[g,w]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[t,a]=(0,d.Dv)(n);return[t,(0,i.useCallback)((e=>{n&&a.set(e)}),[n,a])]}({groupId:a}),x=(()=>{const e=c??g;return p({value:e,tabValues:s})?e:null})();(0,l.A)((()=>{x&&r(x)}),[x]);return{selectedValue:o,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:s}))throw new Error(`Can't select invalid tab value=${e}`);r(e),h(e),w(e)}),[h,w,s]),tabValues:s}}var w=t(9136);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=t(4848);function v({className:e,block:n,selectedValue:t,selectValue:i,tabValues:o}){const l=[],{blockElementScrollPositionUntilNextRender:r}=(0,s.a_)(),c=e=>{const n=e.currentTarget,a=l.indexOf(n),s=o[a].value;s!==t&&(r(n),i(s))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.A)("tabs",{"tabs--block":n},e),children:o.map((({value:e,label:n,attributes:i})=>(0,f.jsx)("li",{role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>{l.push(e)},onKeyDown:d,onClick:c,...i,className:(0,a.A)("tabs__item",x.tabItem,i?.className,{"tabs__item--active":t===e}),children:n??e},e)))})}function j({lazy:e,children:n,selectedValue:t}
1){const s=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=s.find((e=>e.props.value===t));return e?(0,i.cloneElement)(e,{className:(0,a.A)("margin-top--md",e.props.className)}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:s.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function b(e){const n=g(e);return(0,f.jsxs)("div",{className:(0,a.A)("tabs-container",x.tabList),children:[(0,f.jsx)(v,{...n,...e}),(0,f.jsx)(j,{...n,...e})]})}function y(e){const n=(0,w.A)();return(0,f.jsx)(b,{...e,children:h(e.children)},String(n))}},7189:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>d,default:()=>m,frontMatter:()=>c,metadata:()=>i,toc:()=>u});const i=JSON.parse('{"id":"tutorial_VC3D","title":"Virtual Unwrapping with VC3D","description":"<meta","source":"@site/docs/06_tutorial_VC3D.md","sourceDirName":".","slug":"/tutorial_VC3D","permalink":"/tutorial_VC3D","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":6,"frontMatter":{"title":"Virtual Unwrapping with VC3D"},"sidebar":"overviewSidebar","previous":{"title":"Open Problems","permalink":"/2026_open_problems"},"next":{"title":"Spiral Fitting","permalink":"/tutorial_spiral"}}');var a=t(4848),s=t(8453),o=t(4550),l=t(5537),r=t(9329);const c={title:"Virtual Unwrapping with VC3D"},d="Virtual Unwrapping with VC3D",h={},u=[{value:"Installing VC3D",id:"installing-vc3d",level:2},{value:"Launching the GUI",id:"launching-the-gui",level:2},{value:"Using VC3D",id:"using-vc3d",level:2},{value:"Viewing a scroll",id:"viewing-a-scroll",level:3},{value:"Growing surfaces",id:"growing-surfaces",level:3},{value:"Winding Annotation",id:"winding-annotation",level:2},{value:"Fibers (<em>same-winding</em>)",id:"fibers-same-winding",level:3},{value:"Manually created Point Collections (<em>relative or same-winding</em>)",id:"manually-created-point-collections-relative-or-same-winding",level:3},{value:"Same-winding using the wrap annotation tool",id:"same-winding-using-the-wrap-annotation-tool",level:3},{value:"Viewer Controls",id:"viewer-controls",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components},{Head:t}=n;return t||function(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("Head",!0),(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t,{children:[(0,a.jsx)("html",{"data-theme":"dark"}),(0,a.jsx)("meta",{name:"description",content:"Virtual Unwrapping with VC3D tutorial: install and launch the GUI, load scroll data, navigate volumes, and annotate fibers and windings."}),(0,a.jsx)("meta",{property:"og:type",content:"website"}),(0,a.jsx)("meta",{property:"og:url",content:"https://scrollprize.org"}),(0,a.jsx)("meta",{property:"og:title",content:"Vesuvius Challenge"}),(0,a.jsx)("meta",{property:"og:description",content:"Virtual Unwrapping with VC3D tutorial: install and launch the GUI, load scroll data, navigate volumes, and annotate fibers and windings."}),(0,a.jsx)("meta",{property:"og:image",content:"https://scrollprize.org/img/social/opengraph.jpg"}),(0,a.jsx)("meta",{property:"twitter:card",content:"summary_large_image"}),(0,a.jsx)("meta",{property:"twitter:url",content:"https://scrollprize.org"}),(0,a.jsx)("meta",{property:"twitter:title",content:"Vesuvius Challenge"}),(0,a.jsx)("meta",{property:"twitter:description",content:"Virtual Unwrapping with VC3D tutorial: install and launch the GUI, load scroll data, navigate volumes, and annotate fibers and windings."}),(0,a.jsx)("meta",{property:"twitter:image",content:"https://scrollprize.org/img/social/opengraph.jpg"})]}),"\n","\n",(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"virtual-unwrapping-with-vc3d",children:"Virtual Unwrapping with VC3D"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.em,{children:"Last updated: July 12, 2026"})}),"\n",(0,a.jsx)(o.A,{prefill:"Help me get started with VC3D"}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"VC3D is updated frequently. Follow along in Discord for the latest changes."})}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, you will see how to open a CT scan of a scroll in VC3D, our specialized software for virtual unwrapping, and how to segment part of the papyrus surface."}),"\n",(0,a.jsx)(n.h2,{id:"installing-vc3d",children:"Installing VC3D"}),"\n",(0,a.jsxs)(n.p,{children:["Downloads for all operating systems are available on the ",(0,a.jsx)(n.a,{href:"https://github.com/ScrollPrize/villa/releases",children:"releases page"})," of the villa repository."]}),"\n",(0,a.jsxs)(l.A,{groupId:"operating-systems",children:[(0,a.jsxs)(r.A,{value:"mac-apple-silicon",label:"Mac (Apple Silicon)",children:[(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Download the macos .dmg file from the ",(0,a.jsx)(n.a,{href:"https://github.com/ScrollPrize/villa/releases",children:"releases page"})," of the villa repository."]}),"\n",(0,a.jsxs)(n.li,{children:["Double click the .dmg file, and drag/drop it into applications (",(0,a.jsx)(n.strong,{children:"you may have to right click the dmg and click 'open'."}),")"]}),"\n"]}),(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInl
1ine:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/macos-install-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/macos-install.webm",type:"video/webm"})})})]}),(0,a.jsx)(r.A,{value:"windows",label:"Windows",children:(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Download the windows installer .zip file from the ",(0,a.jsx)(n.a,{href:"https://github.com/ScrollPrize/villa/releases",children:"releases page"})," of the villa repository."]}),"\n",(0,a.jsx)(n.li,{children:"Extract the contents of the .zip file to a folder of your choice."}),"\n",(0,a.jsx)(n.li,{children:'Double click the install file, click "show more details" and then "run anyway"'}),"\n",(0,a.jsx)(n.li,{children:"Follow the prompts, clicking yes or next where necessary"}),"\n"]})}),(0,a.jsxs)(r.A,{value:"linux",label:"Linux",children:[(0,a.jsx)(n.p,{children:"Currently, the application must be built from source on linux. There is an install script at the volume-cartographer root\n(villa/volume-cartographer/build_from_src_debian.sh) that will handle this build for you"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd villa/volume-cartographer\nchmod +x build_from_src_debian.sh\n./build_from_src_debian.sh\n"})})]}),(0,a.jsxs)(r.A,{value:"docker",label:"Docker",children:[(0,a.jsx)(n.p,{children:"Prebuilt docker containers are hosted on the GitHub container registry. To use them, run the following command:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"docker pull ghcr.io/scrollprize/villa/volume-cartographer:stable\n"})})]})]}),"\n",(0,a.jsx)(n.h2,{id:"launching-the-gui",children:"Launching the GUI"}),"\n",(0,a.jsx)(n.p,{children:"Depending on your install method or operating system, the application may be launched in different ways."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Mac:"})," Open the application from the Applications folder"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Windows:"})," Open the application from the Start menu"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Linux:"})," Navigate to the build folder and run the VC3D app. example: ",(0,a.jsx)(n.code,{children:"cd build/bin && ./VC3D"})]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"using-vc3d",children:"Using VC3D"}),"\n",(0,a.jsx)(n.h3,{id:"viewing-a-scroll",children:"Viewing a scroll"}),"\n",(0,a.jsx)(n.p,{children:"VC3D is intended as a viewer of scroll data and to assist in the virtual unwrapping of scrolls, so the fastest way to get familiar with it is to unwrap some part of a scroll. Let's start\nwith PHerc1447. This scroll (as of July 13, 2026) has no public surfaces, so let's make one. You should see the open data catalog window in the VC3D gui when you launch it, and from here\nwe can select our sample:"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.em,{children:"if the data catalog is not visible, you can reopen it"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.strong,{children:"File \u2192 Open Data Catalog\u2026"})}),"\n"]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/open_data_catalog-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/open_data_catalog.webm",type:"video/webm"})})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Select PHerc1447 and either double click or press ",(0,a.jsx)(n.strong,{children:"Open Sample"})]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After a brief wait to download any necessary data, you should see the scroll data in the xy and yz planes (the two viewers to the right) and a large blank window to the left."}),"\n",(0,a.jsx)(n.p,{children:"General navigation tips:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"You can zoom in and out in any viewer by using the mouse wheel."}),"\n",(0,a.jsxs)(n.li,{children:["Use right click to pan the view, and either ",(0,a.jsx)(n.code,{children:"ctrl+click"})," or ",(0,a.jsx)(n.code,{children:"R"})," to move the focus point. When the focus point is moved, the other planes will all align with it, so you are seeing the same location in the scroll volume from different planes/orientations."]}),"\n",(0,a.jsx)(n.li,{children:"You can rotate the yz plane either by dragging the green handle in the xy view, or by pressing the mousewheel in and dragging the mouse in the yz view"}),"\n",(0,a.jsx)(n.li,{children:"You can slice through the planes by holding shift and moving the mousewheel up or down"}),"\n",(0,a.jsxs)(n.li,{children:["You can increase the sensitivity of any navigation actions by changing the settings in ",(0,a.jsx)(n.code,{children:"Viewer Controls \u2192 Navigation"})]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"PHerc1447 has recto surface predictions available from the open data catalog, and these should pre-populate in your overlay selector. Let's take a look at this volume with the surface predictions overlaid:"}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInl
1ine:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/navigate_and_open_overlay-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/navigate_and_open_overlay.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.h3,{id:"growing-surfaces",children:"Growing surfaces"}),"\n",(0,a.jsxs)(n.p,{children:["Now that we've got all our necessary data, we can create our first segmentation. Let's find a place on the volume we would like to see unwrapped, and use ",(0,a.jsx)(n.code,{children:"ctrl+right click"})," to bring up the volume actions menu.\nFrom here, click ",(0,a.jsx)(n.code,{children:"Create Segment (GrowPatch)"}),', and a dialog box will pop up. From the volume selector, ensure that the volume containing "surface" is selected, set your growth iterations to 35, and check that\nthe output path is to the desired location (by default, this will go to your open data catalog folder in a "patches" folder for the selected volume, you do not need to change this).']}),"\n",(0,a.jsxs)(n.p,{children:['You should see another dialog box pop up, and it will show the progress of the current segmentation growth. After a brief wait, it should say "Successful". Click ',(0,a.jsx)(n.code,{children:"OK"})," and then click on ",(0,a.jsx)(n.code,{children:"Volume Package"}),", and you should see your segment.\nClick on it to show it in the flattened view on the left. You can also see how the 2D sheet surface is situated in the original CT volume in the xy and yz views -- the orange line in these views shows where they slice through the sheet you have segmented.\nA high quality segment should follow the sheets in the cross-section views, and also have the horizontal and vertical fibers clearly visible in the flattened view -- this indicates the segment is followimg the original written surface of the papyrus accurately."]}),"\n",(0,a.jsxs)(n.p,{children:["This segment, while currently small, can be used already either for ",(0,a.jsx)(n.a,{href:"tutorial5",children:"ink detection"}),", as an input to the ",(0,a.jsx)(n.a,{href:"tutorial_spiral",children:"spiral fit"}),", or for ",(0,a.jsx)(n.a,{href:"2026_open_problems#surface-prediction",children:"training data"}),". Any segment created by VC3D, regardless of how big, is in this same format."]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/grow_from_seed-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/grow_from_seed.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.p,{children:"Growth tips:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"the more iterations you have selected, the bigger the resulting segment, but the longer it will take to complete. Later iterations take longer due to the edges of the surface being longer."}),"\n",(0,a.jsx)(n.li,{children:"Try and select an area that is on the surface predictions to get better results."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["If we want to make our segment larger, we can do this easily with the built-in segmentation tools. Click on ",(0,a.jsx)(n.code,{children:"Segmentation"})," and ",(0,a.jsx)(n.code,{children:"Enable Editing"}),". You can then use either the growth button or keybinds to grow in a desired direction."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"1"})," to grow left, ",(0,a.jsx)(n.code,{children:"2"})," to grow up, ",(0,a.jsx)(n.code,{children:"3"})," to grow down, ",(0,a.jsx)(n.code,{children:"4"})," to grow right, ",(0,a.jsx)(n.code,{children:"5"})," to grow in all directions"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.code,{children:"steps"})," spinbox in the segmentation tool can be used to increase or decrease the number of steps to take in each direction (a step being roughly 20 voxels)"]}),"\n"]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/growth_directions-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/growth_directions.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.h2,{id:"winding-annotation",children:"Winding Annotation"}),"\n",(0,a.jsxs)(n.p,{children:["VC3D can be used to create winding annotations for the spiral fit (see ",(0,a.jsx)(n.a,{href:"tutorial_spiral#what-goes-in",children:"the inputs section"})," of the spiral\nfitting document for more details on how these are used). VC3D outputs these primarily as ",(0,a.jsx)(n.em,{children:"patches (segmentations)"})," or ",(0,a.jsx)(n.em,{children:"point collections"}),". See ",(0,a.jsx)(n.a,{href:"/open_problems/winding_annotations",children:"In-depth: Winding Constraints"})," for more on why these annotations matter and how they're used."]}),"\n",(0,a.jsx)(n.p,{children:"When generating data for the spiral, we can think of the inputs broadly as two types of annotations:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"same-winding annotations (fibers, patches, kolleisis, points along surface preds, etc)"}),"\n",(0,a.jsxs)(n.li,{children:["relative or different winding annotations (generally points which move outward radially ",(0,a.jsx)(n.em,{children:"across"})," sheets rather than ",(0,a.jsx)(n.em,{children:"along"})," them)"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"If you've been following along with this guide, you've already created a same-winding annotation in the form of a patch (see the previous section)."}),"\n",(0,a.jsx)(n.p,{children:'A same-winding annotation is simply some set of points which say "these points are all part of the same sheet of the scroll". Conversely, a\nrelative or different winding annotation is a set of points which say "these points are part of different sheets of the scroll, and they are this many windings apart"'}),"\n",(0,a.jsx)(n.p,{children:"These can be generated in an infinite number of ways. VC3D has built-in tools for generating a few examples of them:"}),"\n",(0,a.jsxs)(n.h3,{id:"fibers-same-winding",children:["Fibers (",(0,a.jsx)(n.em,{children:"same-winding"}),")"]}),"\n",(0,a.jsx)(n.p,{children:"A tool to manually add control points to a line annotation (which we often use to target fibers), with interpolation and extrapolation assistance via lasagna normals."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Note: lasagna normals must be present to use this tool"}),"\n"]}),"\n",(0,a.jsx)("div",{className:"mb-4",children:(0,a.jsx)("img",{src:"/img/tutorials/vc3d/fiber-pane.webp",className:"w-[75%] rounded-xl zoomable",width:"1074",height:"589",loading:"lazy",decoding:"async"})}),"\n",(0,a.jsxs)(n.p,{children:["To start a line annotation: ",(0,a.jsx)(n.strong,{children:"Ctrl + Right click"})," on your starting point in the 3D volume, then select ",(0,a.jsx)(n.strong,{children:"Line Annotation"}),". The first time, you will be prompted to load the lasagna normals."]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInl
1ine:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/start-line-annotation-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/start-line-annotation.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.p,{children:"A line annotation workspace will launch, with 4 viewers:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Top left:"})," XY plane"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Top right:"})," orthogonal plane, similar to the YZ plane"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Middle:"})," a flattened fiber view"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Bottom:"})," a flattened fiber view, orthogonal to the middle plane"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"To pan along a fiber:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Move the mouse pointer over the middle or bottom view"}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Shift + Wheel"})," while the mouse pointer is in one of the top viewers"]}),"\n"]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/fiber-annotating-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/fiber-annotating.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"To annotate:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Press ",(0,a.jsx)(n.strong,{children:"Spacebar"})," to freeze panning via the mouse pointer"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Left click"})," to add a control point"]}),"\n",(0,a.jsx)(n.li,{children:"A reoptimization takes place after each control point is added"}),"\n",(0,a.jsxs)(n.li,{children:["To delete a control point, use ",(0,a.jsx)(n.strong,{children:"Ctrl + Right click \u2192 Delete control point"})]}),"\n"]}),"\n",(0,a.jsxs)(n.h3,{id:"manually-created-point-collections-relative-or-same-winding",children:["Manually created Point Collections (",(0,a.jsx)(n.em,{children:"relative or same-winding"}),")"]}),"\n",(0,a.jsxs)(n.p,{children:["You can manually place points by enabling annotation and using ",(0,a.jsx)(n.code,{children:"shift+click"})," in any of the volume views. Using this method, you can create either a relative or same-winding annotations easily. If\nyou have a patch already loaded, these annotations can be even more influential in a later fit. You can think of them as extensions of the patch itself, and they can be used as edges in a patch graph if you\nwant to connect sparse patches."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.em,{children:"same winding"}),"\nplace points along the surface of the scroll, beginning partially inside a patch and extending outward"]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/manual_same_wind-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/manual_same_wind.webm",type:"video/webm"})})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.em,{children:"relative winding"}),"\nplace points outward radially, indicating the winding offset between points"]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInline:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/manual_rel_wind-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/manual_rel_wind.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.h3,{id:"same-winding-using-the-wrap-annotation-tool",children:"Same-winding using the wrap annotation tool"}),"\n",(0,a.jsxs)(n.p,{children:["You can use the same-wrap annotation tool to quickly create same-winding annotations along surface predictions. Each tool uses ",(0,a.jsx)(n.code,{children:"shift+click"})," (or ",(0,a.jsx)(n.code,{children:"shift+click+drag"}),' for the manual tool) to place tentative points, which\nare then "commited" to point collections with ',(0,a.jsx)(n.code,{children:"shift+e"})]}),"\n",(0,a.jsx)("div",{className:"mb-4 max-w-[760px]",children:(0,a.jsx)("video",{autoPlay:!0,playsInl
1ine:!0,loop:!0,muted:!0,className:"w-[100%] rounded-xl",poster:"/img/tutorials/vc3d/same-wrap-annotation-tool-poster.webp",children:(0,a.jsx)("source",{src:"/img/tutorials/vc3d/same-wrap-annotation-tool.webm",type:"video/webm"})})}),"\n",(0,a.jsx)(n.h2,{id:"viewer-controls",children:"Viewer Controls"}),"\n",(0,a.jsx)("div",{className:"mb-4",children:(0,a.jsx)("img",{src:"/img/tutorials/vc3d/viewer-controls.webp",className:"w-[55%] rounded-xl zoomable",width:"757",height:"646",loading:"lazy",decoding:"async"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Focus point"})," \u2014 hover the mouse in 3D; the keybinds ",(0,a.jsx)(n.strong,{children:"Ctrl + Left click"})," or ",(0,a.jsx)(n.strong,{children:"r"})," move the focus point to those coordinates"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Intersection thickness"})," \u2014 adjust segment line thickness in the 3D volume windows"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Volume window"})," \u2014 manually threshold/window the volume data"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Show axis overlays in XY view"})," \u2014 toggles visibility of the YZ axis plane adjustment tool"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"Max dis
1played resolution"})," \u2014 increase if streaming is slow"]}),"\n"]})]})}function m(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var i=t(6540);const a={},s=i.createContext(a);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(s.Provider,{value:n},e.children)}},9329:(e,n,t)=>{t.d(n,{A:()=>o});t(6540);var i=t(4164);const a={tabItem:"tabItem_Ymn6"};var s=t(4848);function o({children:e,hidden:n,className:t}){return(0,s.jsx)("div",{role:"tabpanel",className:(0,i.A)(a.tabItem,t),hidden:n,children:e})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.