Skip to main content

Selection

Selectors, the lists the user picks faces, edges and other items into in the 3D view, and what the user has selected in the model: for apps that let the user pick.

Types​

Selector​

type Selector<T> = {
customSelect?: CustomSelect;
customUnSelect?: CustomSelect;
hoveredItem: SelectedItem<T> | null;
isSelectable: SelectionFilter;
items: SelectedItem<T>[];
maxLen: number;
};

A selector: a list that items are picked into, such as the edges of a fillet, with a filter for what it takes.

Plugins and inputs create one with createSelector of a drawing's api.selection, and activate it while the user picks. The 3D view of @buerli.io/react adds what the user clicks to the active selector, if its filter takes it.

Example​

import { DrawingID, getDrawing, LineGeometry, lineFilter, SelectionFilter } from '@buerli.io/core'
import { useDrawing } from '@buerli.io/react'
import { useEffect } from 'react'

// Lets the user pick two straight edges in the 3D view (BuerliGeometry with `selection`), and shows their lengths
function LinePicker({ drawingId }: { drawingId: DrawingID }) {
useEffect(() => {
const { api } = getDrawing(drawingId)
// An active selector for at most two lines; the cleanup removes it
return api.selection.createSelector('lines', lineFilter as SelectionFilter, true, [], 2)
}, [drawingId])

const items = useDrawing(drawingId, drawing => drawing.selection.refs['lines']?.items) ?? []
const lines = items.map(item => item.data as LineGeometry)
return <p>{lines.map(line => line.start.distanceTo(line.end).toFixed(1)).join(' and ') || 'Pick two edges'}</p>
}

Type Parameters​

Type ParameterDefault typeDescription
T extends SeletedItemData<any>anyThe data of the items.

Properties​

PropertyModifierTypeDescription
customSelect?readonlyCustomSelectTakes over from select: it is then up to it to set the items, with setItems.
customUnSelect?readonlyCustomSelectTakes over from unselect and unselectAll: it is then up to it to set the items, with setItems.
hoveredItemreadonlySelectedItem<T> | nullThe item under the pointer, or null.
isSelectablereadonlySelectionFilterWhether the selector takes an item.
itemsreadonlySelectedItem<T>[]The items picked so far.
maxLenreadonlynumberHow many items the selector holds at most; -1 for any number.

SelectedItem​

type SelectedItem<T> = {
data: T;
id: any;
label?: any;
removeCondition?: (d) => boolean;
scope: SelectionScope;
};

An item in a selector: an element of the geometry, or anything else a selector picks.

Items are told apart by id and scope. createGraphicItem makes the item of a geometry element.

Example​

import { getDrawing, SelectedItem } from '@buerli.io/core'

// A feature of the tree as an item of a scope of its own; it leaves the selector when the feature is deleted
const item: SelectedItem<{ objectId: number }> = {
id: `feature|${featureId}`,
scope: 'Features',
data: { objectId: featureId },
label: 'FT',
removeCondition: drawing => drawing.structure.tree[featureId] === undefined,
}
getDrawing(drawingId).api.selection.select(item, 'features')

Type Parameters​

Type ParameterDefault typeDescription
T extends SeletedItemData<any>anyThe item's data.

Properties​

PropertyModifierTypeDescription
datareadonlyTThe item's data; for an element of the geometry, the element (ProductElement).
idreadonlyanyTells the item apart in its scope; for an element of the geometry, <productId>|<graphicId>|<type>.
label?readonlyanyA short text the Selection element of @buerli.io/react shows for the item, such as LI for a line.
removeCondition?readonly(d) => booleanCalled each time the drawing changes; when it returns true, the item is removed from the selector. For example, d => d.structure.tree[id] === undefined when the object is deleted.
scopereadonlySelectionScopeWhat kind of item it is.

InteractionInfo​

type InteractionInfo<T> = {
containerId?: ObjectID;
graphicId?: GraphicID;
objectId: ObjectID;
objectPath?: ObjectID[];
prodRefId?: ObjectID | null;
uniqueIdent: string;
userData?: T;
};

An object of the structure tree or an element of its geometry, as the user selects or hovers it.

It is what interaction of a drawing holds (DrawingState). An object of the tree has objectId and the product it is in; an element of the geometry also has the solid (containerId) and the element (graphicId). createInfo makes one, with its uniqueIdent.

Example​

import { DrawingID } from '@buerli.io/core'
import { useDrawing } from '@buerli.io/react'

// The names of the objects the user has selected in the model
function Selected({ drawingId }: { drawingId: DrawingID }) {
const names = useDrawing(drawingId, drawing =>
drawing.interaction.selected?.map(info => drawing.structure.tree[info.objectId]?.name).join(', '),
)
return <p>Selected: {names || 'nothing'}</p>
}

Type Parameters​

Type ParameterDefault type
Tany

Properties​

PropertyTypeDescription
containerId?ObjectIDFor an element of the geometry: the container (solid) it is in, as in geometry.cache and graphic.containers.
graphicId?GraphicIDFor an element of the geometry: the face, edge or point in the container.
objectIdObjectIDThe object of the tree: a feature, a solid, a part or an instance. For an element of the geometry, the solid it belongs to.
objectPath?ObjectID[]The object's full path of ids in the tree, starting at AllObjects. It is optional, but should be filled if possible: it gives the object's whole transformation.
prodRefId?ObjectID | nullThe product or instance the object is in, which places it in the model.
uniqueIdentstringTells items apart: made of prodRefId, objectId, containerId and graphicId.
userData?TWhatever the app wants to keep with the item.

SelectionFilter​

type SelectionFilter<T> = (scope, data) => boolean;

Whether a selector takes an item: called with the item's scope and data.

For elements of the geometry, the 3D view calls it with BuerliScope and the element's GraphicType; the filters solidFilter, meshFilter, edgeFilter, … check for one kind. Combine them for more.

Type Parameters​

Type ParameterDefault type
Tany

Parameters​

ParameterType
scopeSelectionScope
dataT

Returns​

boolean

Example​

import { ScgGraphicType } from '@buerli.io/classcad'
import { BuerliScope, getDrawing, SelectionFilter } from '@buerli.io/core'

// Planar faces and straight edges
const planesAndLines: SelectionFilter = (scope, type) =>
scope === BuerliScope && (type === ScgGraphicType.PLANE || type === ScgGraphicType.LINE)

const remove = getDrawing(drawingId).api.selection.createSelector('references', planesAndLines, true)

SelectorID​

type SelectorID = string | number;

A selector's id, chosen by whoever creates the selector.

Selector has an example.

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.

arcCircleFilter()​

function arcCircleFilter(scope, data): boolean;

Takes arcs and circles, for example for a center or a radius.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


arcFilter()​

function arcFilter(scope, data): boolean;

Takes arcs of solids, not full circles.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


BuerliScope​

const BuerliScope: "ClassCAD" = 'ClassCAD';

The scope of selected items that are elements of the geometry: faces, edges, points and solids.

Such an item's data is the element (ProductElement, which has an example); createGraphicItem makes one. A SelectionFilter gets this scope with the element's GraphicType.


circleFilter()​

function circleFilter(scope, data): boolean;

Takes circles of solids.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


createGraphicItem()​

function createGraphicItem(productId, el): SelectedItem<ProductElement>;

Makes the selected item of an element of the geometry, in BuerliScope, for a selector.

Parameters​

ParameterTypeDescription
productIdnumberThe product the element is in; its transformation places the element.
elGeometryElementThe element, from a drawing's geometry.cache.

Returns​

SelectedItem<ProductElement>

The item: its data is the element with productId.

Example​

import { ScgGraphicType } from '@buerli.io/classcad'
import { createGraphicItem, getDrawing } from '@buerli.io/core'

// Select all planar faces of a part, in the active selector
const { api, geometry, structure } = getDrawing(drawingId)
const faces = (structure.tree[partId]?.solids ?? []).flatMap(id => geometry.cache[id]?.meshes ?? [])
const items = faces.filter(face => face.type === ScgGraphicType.PLANE).map(face => createGraphicItem(partId, face))
api.selection.select(items)

createInfo()​

function createInfo(data): InteractionInfo;

Makes an InteractionInfo: the given fields with the uniqueIdent they make.

Parameters​

ParameterTypeDescription
dataOmit<InteractionInfo, "uniqueIdent">The item's fields, without uniqueIdent.

Returns​

InteractionInfo

The item, for interaction.select or interaction.setSelected of a drawing's API.

Example​

import { createInfo, getDrawing } from '@buerli.io/core'

const { api, structure } = getDrawing(drawingId)
const product = structure.currentProduct
// Select a feature of the current part, as a click in the tree does, and hover a sketch
api.interaction.select(createInfo({ objectId: featureId, prodRefId: product }))
api.interaction.setHovered(createInfo({ objectId: sketchId, prodRefId: product }))

CustomSelect​

type CustomSelect = (selectorId, newItems, diff, options?) => void;

Takes over from a selector's select (or unselect): it gets the items and sets them itself, with setItems.

Called with the selector, the items it would have (newItems), the ones that change (diff: those added, or those removed), and the options of the call.

Parameters​

ParameterType
selectorIdSelectorID
newItemsSelectedItem[]
diffSelectedItem[]
options?{ [key: string]: any; }

Returns​

void

Example​

import { CustomSelect, getDrawing, meshFilter, SelectionFilter } from '@buerli.io/core'

// Faces are picked only from one product: what is picked elsewhere is left out
const onlyFrom =
(productId: number): CustomSelect =>
(selectorId, newItems) => {
const items = newItems.filter(item => item.data.productId === productId)
getDrawing(drawingId).api.selection.setItems(selectorId, items)
}

const { api } = getDrawing(drawingId)
api.selection.createSelector('faces', meshFilter as SelectionFilter, true, [], -1, onlyFrom(productId))

edgeFilter()​

function edgeFilter(scope, data): boolean;

Takes edges of solids: lines, arcs, circles and other curves.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


lineFilter()​

function lineFilter(scope, data): boolean;

Takes straight edges of solids.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


loopFilter()​

function loopFilter(scope, data): boolean;

Takes loops, the edges around a face: the 3D view takes the loop of the face that is picked.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


meshFilter()​

function meshFilter(scope, data): boolean;

Takes faces of solids: planar, cylindrical, conical, spherical and free-form faces.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


planeFilter()​

function planeFilter(scope, data): boolean;

Takes planar faces.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


pointFilter()​

function pointFilter(scope, data): boolean;

Takes points of solids: the ends of their edges.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean


SelectionScope​

type SelectionScope = string | number;

What kind of item a selected item is: BuerliScope for elements of the geometry, or a scope of its own.

Other items have scopes of their own, like the tree objects of react-cad; SelectedItem has an example.


solidFilter()​

function solidFilter(scope, data): boolean;

Takes whole solids: picking any face or edge selects its solid.

Use it as a selector's filter (SelectionFilter): Selector has an example.

Parameters​

ParameterTypeDescription
scopestringThe item's scope; only BuerliScope is taken.
dataScgGraphicTypeThe element's GraphicType.

Returns​

boolean