Hooks
What a drawing is being worked on as, and whether the engine is busy, for components of the app's own.
Hooks
useEditMode()
function useEditMode(drawingId): EditMode;
Returns what the drawing is being worked on as: a part, an assembly, or neither; and renders again when it changes.
It is EditMode.Part where the current product is a part, or where the drawing's root is one; EditMode.Assembly where the current product is an assembly. The ModelTree shows a part's features or an assembly's nodes by it.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
Example
import type { DrawingID } from '@buerli.io/core'
import { Constraints, EditMode, Solids, useEditMode } from '@buerli.io/react-cad'
// the lower pane of a sidebar of the app's own: a part's bodies, an assembly's constraints
function LowerPane({ drawingId }: { drawingId: DrawingID }) {
const mode = useEditMode(drawingId)
if (mode === EditMode.Part) return <Solids drawingId={drawingId} />
if (mode === EditMode.Assembly) return <Constraints drawingId={drawingId} />
return <p>Open a part or an assembly.</p>
}
useHasPending()
function useHasPending(drawingId): boolean;
Returns whether the drawing has commands the engine has not answered yet, and renders again when that changes.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
boolean
true while one or more commands are pending.
Example
import { useBuerliCadFacade } from '@buerli.io/react'
import { useHasPending } from '@buerli.io/react-cad'
// a button that builds a box, and waits while the engine is busy
function AddBox({ partId }: { partId: number }) {
const { api, drawingId } = useBuerliCadFacade('bracket')
const busy = useHasPending(drawingId)
return (
<button disabled={busy} onClick={() => api.v1.part.box({ id: partId, width: 20, length: 20, height: 20 })}>
{busy ? 'Working…' : 'Add a box'}
</button>
)
}
useIsLoading()
function useIsLoading(drawingId): boolean;
Returns whether the drawing is loading a model (a pending command whose name has .load in it), and renders again
when that changes.
Drawing covers the stage with its loading screen while it is.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
boolean
true while a load is pending.
Example
import type { DrawingID } from '@buerli.io/core'
import { useIsLoading } from '@buerli.io/react-cad'
// what the app shows over its stage while a model is loaded
function LoadingVeil({ drawingId }: { drawingId: DrawingID }) {
const loading = useIsLoading(drawingId)
return loading ? <div className="veil">Loading the model…</div> : null
}
useIsSketchActive()
function useIsSketchActive(drawingId): boolean;
Returns whether the drawing's active feature is a sketch, that is, whether its sketch is being edited; and renders again when that changes.
The stage turns to paper while it is, and the canvas interaction of an app leaves the sketch's own to the sketcher. sketchUtils.isSketchActive asks the same outside of a component.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
boolean
Example
import { OrbitControls } from '@react-three/drei'
import type { DrawingID } from '@buerli.io/core'
import { useIsSketchActive } from '@buerli.io/react-cad'
// in the canvas: while a sketch is edited, the view does not turn away from its plane
function Controls({ drawingId }: { drawingId: DrawingID }) {
const sketching = useIsSketchActive(drawingId)
return <OrbitControls makeDefault enableRotate={!sketching} />
}
useVisibleSolids()
function useVisibleSolids(drawingId): number[];
Returns the bodies (solids and sheets) of the current product, and renders again when they change.
For an assembly they are the bodies of the parts in the current instance, each once; for a part, the part's own.
The curves of a composite curve are left out. The ids are the bodies' graphic containers, as
drawing.geometry.cache and the scene's meshes (userData.containerId) have them. The Solids list
shows them.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
number[]
Example
import { useDrawing } from '@buerli.io/react'
import type { DrawingID } from '@buerli.io/core'
import { useVisibleSolids } from '@buerli.io/react-cad'
// a list of the bodies of the current product, by their names
function Bodies({ drawingId }: { drawingId: DrawingID }) {
const solids = useVisibleSolids(drawingId)
const names = useDrawing(drawingId, (d) =>
solids.map((id) => d.structure.tree[d.graphic.containers[id]?.owner]?.name).join(', '),
)
return <p>{solids.length} bodies: {names}</p>
}
Types
EditMode
What the drawing is being worked on as: a part, an assembly, or nothing yet (useEditMode).
Enumeration Members
| Enumeration Member | Value | Description |
|---|---|---|
Assembly | 2 | An assembly: its instances are put together. |
None | 0 | Neither: the drawing has no current product yet. |
Part | 1 | A part: its features are built. |
Advanced
Most apps do not need these directly: types they meet through the exports above, and what is there for special cases or for building on buerli itself.
useAllObjects()
function useAllObjects(drawingId): number;
Returns the id of the drawing's AllObjects container, which holds every part and assembly of the drawing; and
renders again when the root changes.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
Returns
number
Its id, or 0 while the drawing has none.
Example
import { ScgClassType } from '@buerli.io/classcad'
import { useDrawing } from '@buerli.io/react'
import type { DrawingID } from '@buerli.io/core'
import { useAllObjects } from '@buerli.io/react-cad'
// the names of the drawing's parts, as the Products panel lists them
function PartNames({ drawingId }: { drawingId: DrawingID }) {
const allObjects = useAllObjects(drawingId)
const names = useDrawing(drawingId, (d) => {
const tree = d.structure.tree
const parts = tree[allObjects]?.children?.find((id) => tree[id]?.class === ScgClassType.CCPartContainer)
return parts ? tree[parts].children?.map((id) => tree[id].name).join(', ') : ''
})
return <p>Parts: {names}</p>
}
useOperationSequence()
function useOperationSequence(drawingId, partId): number | null;
Returns the id of a part's operation sequence (CC_OperationSequence), the list its features are in; and renders
again when the part's children change.
The sequence's children are the references to the part's features, in the order they are built.
Parameters
| Parameter | Type | Description |
|---|---|---|
drawingId | DrawingID | The drawing. |
partId | number | The part. |
Returns
number | null
The sequence's id, or null where the part has none.
Example
import { useDrawing } from '@buerli.io/react'
import type { DrawingID, ObjectID } from '@buerli.io/core'
import { useOperationSequence } from '@buerli.io/react-cad'
// how many features a part has
function FeatureCount({ drawingId, partId }: { drawingId: DrawingID; partId: ObjectID }) {
const sequence = useOperationSequence(drawingId, partId)
const count = useDrawing(drawingId, (d) => (sequence ? d.structure.tree[sequence]?.children?.length : 0)) ?? 0
return <span>{count} features</span>
}