Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 137 additions & 85 deletions src/components/CanvasGeometry.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,138 @@
import * as THREE from 'three'
THREE.Cache.enabled = true;
import { Canvas } from '@react-three/fiber';
import { Center, OrbitControls, Environment } from '@react-three/drei'
// import * as zarr from 'zarrita'
import { variables, GetArray } from '@/components/ZarrLoaderLRU'
import { useEffect, useState } from 'react';
// import { useEffect, useState } from 'react';
import { Leva, useControls } from 'leva'
import { lightTheme } from '@/utils/levaTheme'
import { ArrayToTexture, DefaultCube } from './TextureMakers';
import { DataCube, PointCloud } from './PlotObjects';

console.log(DataCube)

const storeURL = "https://s3.bgc-jena.mpg.de:9000/esdl-esdc-v3.0.2/esdc-16d-2.5deg-46x72x1440-3.0.2.zarr"

export function CanvasGeometry() {
const { variable, plotter } = useControls({
variable: {
value: "Default",
options: variables,
label:"Select Variable"
},
plotter: {
value:"volume",
options:["volume","point-cloud"],
label:"Select Plot Style"
}
})
const [texture, setTexture] = useState<THREE.DataTexture | THREE.Data3DTexture | null>(null)
const [_shape, setShape] = useState<THREE.Vector3>(new THREE.Vector3(2, 2, 2))
// because, volTexture is expected to be a THREE.Vector3
useEffect(() => {
if (variable != "Default") {
//Need to add a check somewhere here to swap to 2D or 3D based on shape. Probably export two variables from GetArray
GetArray(storeURL, variable).then((result) => {
// result now contains: { data: TypedArray, shape: number[], dtype: string }
const [texture, _shape] = ArrayToTexture({
data: result.data,
shape: result.shape
})
console.log(_shape)
if (texture instanceof THREE.DataTexture || texture instanceof THREE.Data3DTexture) {
setTexture(texture)
} else {
console.error("Invalid texture type returned from ArrayToTexture");
setTexture(null);
}
const shapeRatio = result.shape[1] / result.shape[2] * 2;
setShape(new THREE.Vector3(2, shapeRatio, 2));
})
}
else{
const texture = DefaultCube();
setTexture(texture)
setShape(new THREE.Vector3(2, 2, 2))
}
}, [variable])

return (
<>
<div className='canvas'>
<Canvas shadows camera={{ position: [4.5, 2, 4.5], fov: 50 }}
frameloop="demand"
>
{plotter == "volume" && <DataCube volTexture={texture} shape={_shape}/>}
{plotter == "point-cloud" && <PointCloud texture={texture} />}
<Center top position={[-1, 0, 1]}>
{/* <mesh rotation={[0, Math.PI / 4, 0]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color="indianred" />
</mesh> */}
</Center>
<OrbitControls minPolarAngle={0} maxPolarAngle={Math.PI / 2} enablePan={false}/>
<Environment preset="city" />
</Canvas>
</div>
{/* This drop down is temp just to show the consolidating of variables */}

<Leva theme={lightTheme} />
</>
)
}

import * as THREE from 'three'
THREE.Cache.enabled = true;
import { Canvas } from '@react-three/fiber';
import { Center, OrbitControls, Environment, Html } from '@react-three/drei'
// import * as zarr from 'zarrita'
import { variables, GetArray } from '@/components/ZarrLoaderLRU'
import { useEffect, useState } from 'react';
// import { useEffect, useState } from 'react';
import { Leva, useControls } from 'leva'
import { lightTheme } from '@/utils/levaTheme'
import { ArrayToTexture, DefaultCube } from './TextureMakers';
import { DataCube, PointCloud, UVCube } from './PlotObjects';
import { TimeSeries } from './TimeSeries';

console.log(DataCube)

const storeURL = "https://s3.bgc-jena.mpg.de:9000/esdl-esdc-v3.0.2/esdc-16d-2.5deg-46x72x1440-3.0.2.zarr"

interface TimeSeriesLocs{
uv:THREE.Vector2;
normal:THREE.Vector3
}


export function CanvasGeometry() {
const { variable, plotter } = useControls({
variable: {
value: "Default",
options: variables,
label:"Select Variable"
},
plotter: {
value:"volume",
options:["volume","point-cloud"],
label:"Select Plot Style"
}
})
const [texture, setTexture] = useState<THREE.DataTexture | THREE.Data3DTexture | null>(null)
const [shape, setShape] = useState<THREE.Vector3 | THREE.Vector3>(new THREE.Vector3(2, 2, 2))
const [timeSeriesLocs,setTimeSeriesLocs] = useState<TimeSeriesLocs>({uv:new THREE.Vector2(.5,.5), normal:new THREE.Vector3(0,0,1)})
const [valueScales,setValueScales] = useState({maxVal:1,minVal:-1})
const [showTimeSeries,setShowTimeSeries] = useState<boolean>(false)

useEffect(() => {
if (variable != "Default") {
//Need to add a check somewhere here to swap to 2D or 3D based on shape. Probably export two variables from GetArray
GetArray(storeURL, variable).then((result) => {
// result now contains: { data: TypedArray, shape: number[], dtype: string }
const [texture, shape, scaling] = ArrayToTexture({
data: result.data,
shape: result.shape
})
console.log(shape)
if (texture instanceof THREE.DataTexture || texture instanceof THREE.Data3DTexture) {
setTexture(texture)
} else {
console.error("Invalid texture type returned from ArrayToTexture");
setTexture(null);
}
// norrow down type before using it!
if (
typeof scaling === 'object' &&
'maxVal' in scaling &&
'minVal' in scaling
) {
setValueScales(scaling as { maxVal: number; minVal: number });
}
const shapeRatio = result.shape[1] / result.shape[2] * 2;
setShape(new THREE.Vector3(2, shapeRatio, 2));
})
}
else{
const texture = DefaultCube();
// again need to check type before using it
if (texture instanceof THREE.Data3DTexture || texture instanceof THREE.DataTexture) {
setTexture(texture);
}
setShape(new THREE.Vector3(2, 2, 2))
}
}, [variable])

return (
<>

<div className='canvas'>
<Canvas shadows
frameloop="demand"
>

<Center top position={[-1, 0, 1]}/>
{plotter == "volume" && <>
<DataCube volTexture={texture} shape={shape}/>
<mesh onClick={() => setShowTimeSeries(true)}>
<UVCube shape={shape} setTimeSeriesLocs={setTimeSeriesLocs}/>
</mesh>

</>}
{plotter == "point-cloud" && <PointCloud texture={texture} />}

<OrbitControls minPolarAngle={0} maxPolarAngle={Math.PI / 2} enablePan={false}/>
<Environment preset="city" />
{showTimeSeries && <>

<TimeSeries timeSeriesLocs={timeSeriesLocs} DSInfo={{variable:variable, storePath:storeURL}} scaling={valueScales}/>
<Html
fullscreen
style={{
pointerEvents: 'none', // Prevents capturing mouse events
}}
>
<button style={{
position: 'absolute',
bottom: '100px',
right: '100px',
padding: '8px 16px',
backgroundColor: '#3498db',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
pointerEvents: 'auto'

}}
onClick={()=>setShowTimeSeries(false)}
>
Hide Time Series
</button>
</Html>

</>}
</Canvas>
</div>
<Leva theme={lightTheme} />
</>
)
}

export default CanvasGeometry
Loading
Loading