import { Five } from '@realsee/five'
const five: Five = {} as any
// - five
import { Sculpt } from '@realsee/dnalogel'
const sculpt = new Sculpt(five)
// - sculpt
const item = sculpt.getItemById('1')!
// - itemOverview
Sculpt (/ skʌlpt / vt. to carve; n. sculpture) is a 3D editor built on top of @realsee/five, used to draw and edit 3D objects within a Five SDK scene.
Demo
Open the official Sculpt demo.
Quick Start
Initialization
Initialize via Five SDK plugins:
import { SculptPlugin } from '@realsee/dnalogel'
import { Five } from '@realsee/five'
import type { FivePlugin } from '@realsee/five'
const fivePlugins: [FivePlugin<any, any>, string, any][] = [
[SculptPlugin, 'sculpt', {}]
]
// Load the Five plugin
const five = new Five({
plugins: fivePlugins
})You can also initialize it yourself:
// @include: main-five
// ---cut---
import { Sculpt } from '@realsee/dnalogel'
const sculpt = new Sculpt(five) // five is a Five instance; theme is optionalLoading Data
There are two ways to add objects to a sculpt scene. The first is to load existing data via the sculpt.load(data) method. List item data structure: data
// @include: main
// ---cut---
const data = {
items: [
{
id: '1',
type: 'Point',
point: [0, 0, 0]
},
{
id: '2',
type: 'Polyline',
points: [[0, 0, 0], [1, 1, 1]]
}
]
}
// Draw a point and a line in the scene
sculpt.load(data)Creating Objects
The other way to add objects to a sculpt scene is to create them via the sculpt.createXXXX() methods.
Draw a Box
// @include: main
// ---cut---
sculpt.createBox()Draw a red Box with a green border
// @include: main
// ---cut---
sculpt.createBox({ color: 0xff0000, opacity: 0.8, lineColor: 0x00ff00, lineWidth: 2 })Draw a red line segment
// @include: main
// ---cut---
sculpt.createLine({ lineColor: 0xff0000 })Draw a line segment with a distance label
// @include: main
// ---cut---
sculpt.createLine({ lengthEnable: true })Draw a line segment with a tip
// @include: main
// ---cut---
sculpt.createLine({ tip: 'Line segment' })Draw a line segment locked to the horizontal plane
// @include: main
// ---cut---
sculpt.createLine({ limit: 'xoz' })Draw a rectangle locked to a vertical plane, drawn by its diagonal
// @include: main
// ---cut---
sculpt.createRectangle({ limit: 'y', drawMethod: 'diagonal' })More flexible drawing and editing
// @include: main
// ---cut---
import { Util } from '@realsee/dnalogel'
const { PointSelector } = Util
const { BoxMesh, BoxMeshEditor, createBox } = Util.sculpt
// Create a boxMesh
const boxMesh = new BoxMesh({ lineColor: 0xff0000 })
five.scene.add(boxMesh)
// Initialize the editor as needed
const editor = new BoxMeshEditor(boxMesh)
// Create a selector
const pointSelector = new PointSelector(five)
createBox(boxMesh, pointSelector).then(() => {
console.log('Drawing complete')
// Enable editing as needed
editor.enable()
})Enabling Editing
Editing is enabled by default. You can disable the default behavior by passing an argument when loading data:
// @include: main
const data = {
items: [
{
id: '1',
type: 'Point',
point: [0, 0, 0]
},
{
id: '2',
type: 'Polyline',
points: [[0, 0, 0], [1, 1, 1]]
}
]
}
// ---cut---
sculpt.load(data, { defaultAction: false })Click to start editing
// @include: main
// ---cut---
sculpt.on('click', (e, item) => {
// Select on click (with a highlight effect)
item.select({ only: true })
// Enable editing after the click
item.editor.enable()
// Triggered when the object is moved/rotated/scaled
item.editor.hooks.on('objectUpdate', () => {
console.log('new Data: ', item.data)
})
})Click to show the delete button
// @include: main
// ---cut---
sculpt.on('click', (e, item) => {
const point = e instanceof TouchEvent ? e.touches[0] : e
if (!point) return
const { clientX: x, clientY: y } = point
item.showDeleteButton(x, y)
})Sculpt API
Glossary
Item
The instance of an object. Every object in sculpt is an Item. API
Currently supported Item kinds: ItemType
Theme
At initialization you can set the default style for each type of object.
// @include: main-five
// ---cut---
import { Sculpt } from '@realsee/dnalogel'
/**
* - color: fill color
* - opacity: opacity
* - lineColor: border line color
* - lineWidth: line width
* - lineOpacity: border line opacity
* - occlusionVisibility: whether to render occluded portions in a semi-transparent way
* - occlusionMode: occlusion mode
*/
const theme = {
point: { color: 0xffffff },
line: { lineColor: 0xffffff, lineWidth: 1 },
polyline: { lineColor: 0x0000ff, lineWidth: 2 },
polygon: { color: 0xffffff, lineColor: 0x000000, lineWidth: 2, lineOpacity: 0.8 },
prism: { color: 0xffffff, lineColor: 0x000000, lineWidth: 2, lineOpacity: 1 },
rectangle: { color: 0xffffff, lineColor: 0x000000, opacity: 0.5 },
circle: { color: 0xffffff, lineColor: 0x000000, occlusionVisibility: false },
cylinder: { color: 0xffffff, lineColor: 0x000000, occlusionMode: 'translucence' },
box: { color: 0xffffff, lineColor: 0x000000 },
} as const
const sculpt = new Sculpt(five, theme)sculpt.data
// @include: main
// ---cut---
const data = sculpt.dataGets the full Item data for the current scene.
sculpt.items
Return value: Item[]
Gets all Item instances in the current scene.
sculpt.load(data)
Loads data and renders it into the scene.
sculpt.createXXXX()
Starts drawing an object on screen. Drawing is completed through mouse clicks, dragging, keyboard shortcuts (esc), and similar interactions.
Supported functions:
// @include: main
// ---cut---
sculpt.createPoint() // draw a point
sculpt.createLine() // draw a line segment
sculpt.createPolyline() // draw a polyline
sculpt.createPolygon() // draw a polygon
sculpt.createRectangle() // draw a rectangle
sculpt.createCircle() // draw a circle
sculpt.createPrism() // draw a prism
sculpt.createBox() // draw a Box/cuboid
sculpt.createCylinder() // draw a cylindersculpt.getItemById(id)
Gets an Item instance by id.
// @include: main-sculpt
// ---cut---
const item = sculpt.getItemById('1')sculpt.clear()
Clears all objects from the scene.
// @include: main
// ---cut---
sculpt.clear()Item API
item.type
Return value: ItemType
Returns the type of the current Item.
item.data
Returns the data of the current Item.
item.setData()
Sets the data of the current Item. Parameter data structure: data
item.create()
// @include: main
// ---cut---
item.create()Starts drawing the Item through mouse, keyboard, and other interactions.
item.stopCreating()
// @include: main
// ---cut---
item.stopCreating()Exits creation of the current Item, equivalent to the esc shortcut. If the current Item has not finished drawing, it will be deleted.
item.delete()
// @include: main
// ---cut---
item.delete()Deletes the current Item.
item.on(event)
// @include: main
// ---cut---
// @noErrors
item.on('')
// ^|
import type * as THREE from 'three'
type EventName = keyof FiveDomEventMap
type PreventFiveEvent = boolean
// ---cut---
interface FiveDomEvent {
type: EventName
target: THREE.Object3D
origDomEvent?: Event
raycaster: THREE.Raycaster
intersects?: THREE.Intersection[]
stopPropagation: () => void
}
interface FiveDomEventMap {
/**
* @description click event
* @return {PreventFiveEvent} return false to allow Five's tap event to fire; default: true
*/
click: (event: FiveDomEvent) => PreventFiveEvent | void
/**
* @description double-click event
*/
dblclick: (event: FiveDomEvent) => void
/**
* @description mouse down event
*/
mousedown: (event: FiveDomEvent) => void
/**
* @description mouse up event
*/
mouseup: (event: FiveDomEvent) => void
/**
* @description mouse enter event
*/
hover: (event: FiveDomEvent) => void
/**
* @description mouse leave event
*/
unHover: (event: FiveDomEvent) => void
/**
* @description: drag start
*/
dragstart: (event: FiveDomEvent) => void
/**
* @description: dragging
*/
drag: (event: FiveDomEvent) => void
/**
* @description: drag end
*/
dragend: (event: FiveDomEvent) => void
}Reference
ItemType
type ItemType =
| 'Point' // point
| 'Line' // line segment
| 'Polyline' // line segment / polyline
| 'Polygon' // polygon
| 'Rectangle' // rectangle
| 'Circle' // circle
| 'Prism' // prism
| 'Box' // Box/cuboid
| 'Cylinder' // cylinderdata
Hover over the corresponding data to view its type.
// import type { SculptData } from "@realsee/dnalogel"
// ---cut---
import type { SculptData } from "@realsee/dnalogel"
/**
* point: coordinates of a point in 3D space
*/
type PointData = SculptData.PointData
/**
* points: the set of point coordinates of the polyline
*/
type PolylineData = SculptData.PolylineData
/**
* points: the set of vertex coordinates of the polygon
*/
type PolygonData = SculptData.PolygonData
/**
* points: the set of the four vertex coordinates of the rectangle
*/
type RectangleData = SculptData.RectangleData
/**
* center: coordinates of the circle's center
* normal: the circle's normal vector
* radius: the circle's radius
*/
type CircleData = SculptData.CircleData
/**
* points: the set of bottom-face vertex coordinates of the prism
* heightPoint: coordinates of the top-face point corresponding to the first point of the bottom face
*/
type PrismData = SculptData.PrismData
/**
* points: the set of bottom-face vertex coordinates of the box
* heightPoint: coordinates of the top-face point corresponding to the first point of the bottom face
*/
type BoxData = SculptData.BoxData
/**
* bottomCenter: coordinates of the cylinder's bottom-face center
* topCenter: coordinates of the cylinder's top-face center
* radius: the cylinder's radius
*/
type CylinderData = SculptData.CylinderData