Skip to content

Commit

Permalink
extrudeLinear implementation (#10)
Browse files Browse the repository at this point in the history
* get extrudeLinear working

* fix formatting
  • Loading branch information
seveibar authored Jul 9, 2024
1 parent 99d0f20 commit 17bc761
Show file tree
Hide file tree
Showing 12 changed files with 275 additions and 106 deletions.
3 changes: 2 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"noExplicitAny": "off"
},
"complexity": {
"noForEach": "off"
"noForEach": "warn",
"noBannedTypes": "warn"
},
"style": {
"noNonNullAssertion": "off",
Expand Down
21 changes: 21 additions & 0 deletions examples/extrude-linear.fixture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JsCadFixture } from "../lib/components/jscad-fixture"
import { ExtrudeLinear } from "../lib/jscad-fns"
import { Polygon } from "../lib/jscad-fns/polygon"

export default () => (
<JsCadFixture>
<ExtrudeLinear height={2}>
<Polygon
points={[
[-2, -1],
[2, -1],
[2.5, 2],
[1, 1],
[0, 2],
[-1, 1],
[-2, 2],
]}
/>
</ExtrudeLinear>
</JsCadFixture>
)
4 changes: 0 additions & 4 deletions lib/components/jscad-fixture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ export function JsCadFixture({
const root = createJSCADRoot(jscadGeoms)
root.render(children)

// Here, you would typically use the container to render the 3D shape
// For this example, we'll just log the result
console.log("JSCad objects:", jscadGeoms)

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
Expand Down
2 changes: 0 additions & 2 deletions lib/convert-csg-to-three-geom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import {
} from "three"

export default function convertCSGToThreeGeom(csg): BufferGeometry {
console.log("csg", csg)

if (csg.polygons) {
// 3D shape
const vertices = []
Expand Down
230 changes: 157 additions & 73 deletions lib/create-host-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,162 @@ import type {
RoundedCylinderProps,
SphereProps,
TorusProps,
PolygonProps,
ExtrudeLinearProps,
} from "./jscad-fns"
import type { JSCADModule, JSCADPrimitive } from "./jscad-primitives"
import type { PolygonProps } from "./jscad-fns/polygon"

const ex = {
sides: [
[
[-2, 2],
[-2, -1],
],
[
[-2, -1],
[2, -1],
],
[
[2, -1],
[2.5, 2],
],
[
[2.5, 2],
[1, 1],
],
[
[1, 1],
[0, 2],
],
[
[0, 2],
[-1, 1],
],
[
[-1, 1],
[-2, 2],
],
],
transforms: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
}

export function createHostConfig(jscad: JSCADModule) {
const createInstance = (
type: string | Function,
props: any,
rootContainerInstance: any,
hostContext: any,
internalInstanceHandle: any,
) => {
const renderChildren = (children: any) => {
if (Array.isArray(children)) {
// TODO union all children together
throw new Error("Unioning multiple children is not yet supported")
}
if (children) {
// Single child
return createInstance(
children.type,
children.props,
[],
hostContext,
internalInstanceHandle,
)
}
return null
}

if (typeof type === "function") {
const element = type(props)
return createInstance(
element.type,
element.props,
rootContainerInstance,
hostContext,
internalInstanceHandle,
)
}

switch (type) {
case "cube":
return jscad.primitives.cube({ size: (props as CubeProps).size })

Check failure on line 90 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Cannot find name 'CubeProps'.
case "sphere":
return jscad.primitives.sphere({
radius: (props as SphereProps).radius,
segments: (props as SphereProps).segments,
})
case "cuboid":
return jscad.primitives.cuboid({
size: (props as CuboidProps).size,
})
case "roundedCuboid":
return jscad.primitives.roundedCuboid({
size: (props as RoundedCuboidProps).size,
roundRadius: (props as RoundedCuboidProps).roundRadius,
})
case "geodesicSphere":
return jscad.primitives.geodesicSphere({
radius: (props as GeodesicSphereProps).radius,
frequency: (props as GeodesicSphereProps).frequency,
})
case "ellipsoid":
return jscad.primitives.ellipsoid({
radius: (props as EllipsoidProps).radius,
})
case "cylinder":
return jscad.primitives.cylinder({
radius: (props as CylinderProps).radius,
height: (props as CylinderProps).height,
startRadius: (props as CylinderProps).startRadius,

Check failure on line 118 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Property 'startRadius' does not exist on type 'CylinderProps'.
endRadius: (props as CylinderProps).endRadius,

Check failure on line 119 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Property 'endRadius' does not exist on type 'CylinderProps'. Did you mean 'radius'?
})
case "roundedCylinder":
return jscad.primitives.roundedCylinder({
radius: (props as RoundedCylinderProps).radius,
height: (props as RoundedCylinderProps).height,
roundRadius: (props as RoundedCylinderProps).roundRadius,
})
case "cylinderElliptic":
return jscad.primitives.cylinderElliptic({
radius: (props as CylinderEllipticProps).radius,

Check failure on line 129 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Property 'radius' does not exist on type 'CylinderEllipticProps'.
height: (props as CylinderEllipticProps).height,
startRadius: (props as CylinderEllipticProps).startRadius,
endRadius: (props as CylinderEllipticProps).endRadius,
startAngle: (props as CylinderEllipticProps).startAngle,
endAngle: (props as CylinderEllipticProps).endAngle,
})
case "torus":
return jscad.primitives.torus({
radius: (props as TorusProps).radius,

Check failure on line 138 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Property 'radius' does not exist on type 'TorusProps'.
tube: (props as TorusProps).tube,

Check failure on line 139 in lib/create-host-config.ts

View workflow job for this annotation

GitHub Actions / type-check

Property 'tube' does not exist on type 'TorusProps'.
})
case "jscadPolygon":
return jscad.primitives.polygon({
points: (props as PolygonProps).points,
})
// biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation>
case "extrudeLinear": {
const { children, ...extrudeProps } = props as ExtrudeLinearProps

const childrenGeometry = renderChildren(children)

const extrudedGeometry = jscad.extrusions.extrudeLinear(
{
height: extrudeProps.height,
// twistAngle: extrudeProps.twistAngle,
// twistSteps: extrudeProps.twistSteps,
},
childrenGeometry,
)

return extrudedGeometry
}

default:
throw new Error(`Unknown element type: ${type}`)
}
}

const hostConfig: ReactReconciler.HostConfig<
string, // Type
Props, // Props
Expand All @@ -34,89 +185,22 @@ export function createHostConfig(jscad: JSCADModule) {
supportsPersistence: false,
supportsHydration: false,

createInstance(
type: string,
props: Props,
rootContainerInstance: any,
hostContext: any,
internalInstanceHandle: any,
) {
switch (type) {
case "cube":
return jscad.primitives.cube({ size: (props as CubeProps).size })
case "sphere":
return jscad.primitives.sphere({
radius: (props as SphereProps).radius,
segments: (props as SphereProps).segments,
})
case "cuboid":
return jscad.primitives.cuboid({
size: (props as CuboidProps).size,
})
case "roundedCuboid":
return jscad.primitives.roundedCuboid({
size: (props as RoundedCuboidProps).size,
roundRadius: (props as RoundedCuboidProps).roundRadius,
})
case "geodesicSphere":
return jscad.primitives.geodesicSphere({
radius: (props as GeodesicSphereProps).radius,
frequency: (props as GeodesicSphereProps).frequency,
})
case "ellipsoid":
return jscad.primitives.ellipsoid({
radius: (props as EllipsoidProps).radius,
})
case "cylinder":
return jscad.primitives.cylinder({
radius: (props as CylinderProps).radius,
height: (props as CylinderProps).height,
startRadius: (props as CylinderProps).startRadius,
endRadius: (props as CylinderProps).endRadius,
})
case "roundedCylinder":
return jscad.primitives.roundedCylinder({
radius: (props as RoundedCylinderProps).radius,
height: (props as RoundedCylinderProps).height,
roundRadius: (props as RoundedCylinderProps).roundRadius,
})
case "cylinderElliptic":
return jscad.primitives.cylinderElliptic({
radius: (props as CylinderEllipticProps).radius,
height: (props as CylinderEllipticProps).height,
startRadius: (props as CylinderEllipticProps).startRadius,
endRadius: (props as CylinderEllipticProps).endRadius,
startAngle: (props as CylinderEllipticProps).startAngle,
endAngle: (props as CylinderEllipticProps).endAngle,
})
case "torus":
return jscad.primitives.torus({
radius: (props as TorusProps).radius,
tube: (props as TorusProps).tube,
})
case "jscadpolygon":
return jscad.primitives.polygon({
points: (props as PolygonProps).points,
})
default:
throw new Error(`Unknown element type: ${type}`)
}
},
createInstance: createInstance,

createTextInstance() {
throw new Error("Text elements are not supported in JSCAD")
},

appendInitialChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
return parentInstance
},

appendChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.union(parentInstance, child) as JSCADPrimitive
return parentInstance
},

removeChild(parentInstance: JSCADPrimitive, child: JSCADPrimitive) {
return jscad.booleans.subtract(parentInstance, child) as JSCADPrimitive
return parentInstance
},

appendChildToContainer(container: JSCADPrimitive[], child: JSCADPrimitive) {
Expand All @@ -143,7 +227,7 @@ export function createHostConfig(jscad: JSCADModule) {
newProps: Props,
) {
// Re-create the instance with new props
return this.createInstance(type, newProps, instance, {}, null)
return createInstance(type, newProps, instance, {}, null)
},

finalizeInitialChildren() {
Expand Down
20 changes: 20 additions & 0 deletions lib/intrinsic-jsx.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type * as FN from "./jscad-fns"

declare global {
namespace JSX {
interface IntrinsicElements {
extrudeLinear: FN.ExtrudeLinearProps
cube: FN.CubeProps
sphere: FN.SphereProps
cuboid: FN.CuboidProps
roundedCuboid: FN.RoundedCuboidProps
geodesicSphere: FN.GeodesicSphereProps
ellipsoid: FN.EllipsoidProps
cylinder: FN.CylinderProps
roundedCylinder: FN.RoundedCylinderProps
cylinderElliptic: FN.CylinderEllipticProps
torus: FN.TorusProps
jscadPolygon: FN.PolygonProps
}
}
}
23 changes: 23 additions & 0 deletions lib/jscad-fns/extrude-linear.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type ExtrudeLinearProps = {
height: number
twistAngle?: number
twistSteps?: number
children: any
}

export function ExtrudeLinear({
height,
twistAngle,
twistSteps,
children,
}: ExtrudeLinearProps) {
return (
<extrudeLinear
height={height}
twistAngle={twistAngle}
twistSteps={twistSteps}
>
{children}
</extrudeLinear>
)
}
2 changes: 2 additions & 0 deletions lib/jscad-fns/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from "./cylinder"
export * from "./rounded-cylinder"
export * from "./cylinder-elliptic"
export * from "./torus"
export * from "./polygon"
export * from "./extrude-linear"
2 changes: 1 addition & 1 deletion lib/jscad-fns/polygon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ export type PolygonProps = {
}

export function Polygon({ points }: PolygonProps) {
return <jscadpolygon points={points} />
return <jscadPolygon points={points} />
}
Loading

0 comments on commit 17bc761

Please sign in to comment.