MCP 3D Printer Server

by DMontgomery40
Verified
import InputNode from '../core/InputNode.js'; import { nodeObject, addMethodChaining } from '../tsl/TSLCore.js'; import { varying } from '../core/VaryingNode.js'; import { InterleavedBufferAttribute } from '../../core/InterleavedBufferAttribute.js'; import { InterleavedBuffer } from '../../core/InterleavedBuffer.js'; import { StaticDrawUsage, DynamicDrawUsage } from '../../constants.js'; /** @module BufferAttributeNode **/ /** * In earlier `three.js` versions it was only possible to define attribute data * on geometry level. With `BufferAttributeNode`, it is also possible to do this * on the node level. * ```js * const geometry = new THREE.PlaneGeometry(); * const positionAttribute = geometry.getAttribute( 'position' ); * * const colors = []; * for ( let i = 0; i < position.count; i ++ ) { * colors.push( 1, 0, 0 ); * } * * material.colorNode = bufferAttribute( new THREE.Float32BufferAttribute( colors, 3 ) ); * ``` * This new approach is especially interesting when geometry data are generated via * compute shaders. The below line converts a storage buffer into an attribute node. * ```js * material.positionNode = positionBuffer.toAttribute(); * ``` * @augments InputNode */ class BufferAttributeNode extends InputNode { static get type() { return 'BufferAttributeNode'; } /** * Constructs a new buffer attribute node. * * @param {BufferAttribute|InterleavedBuffer|TypedArray} value - The attribute data. * @param {String?} [bufferType=null] - The buffer type (e.g. `'vec3'`). * @param {Number} [bufferStride=0] - The buffer stride. * @param {Number} [bufferOffset=0] - The buffer offset. */ constructor( value, bufferType = null, bufferStride = 0, bufferOffset = 0 ) { super( value, bufferType ); /** * This flag can be used for type testing. * * @type {Boolean} * @readonly * @default true */ this.isBufferNode = true; /** * The buffer type (e.g. `'vec3'`). * * @type {String} * @default null */ this.bufferType = bufferType; /** * The buffer stride. * * @type {Number} * @default 0 */ this.bufferStride = bufferStride; /** * The buffer offset. * * @type {Number} * @default 0 */ this.bufferOffset = bufferOffset; /** * The usage property. Set this to `THREE.DynamicDrawUsage` via `.setUsage()`, * if you are planning to update the attribute data per frame. * * @type {Number} * @default StaticDrawUsage */ this.usage = StaticDrawUsage; /** * Whether the attribute is instanced or not. * * @type {Boolean} * @default false */ this.instanced = false; /** * A reference to the buffer attribute. * * @type {BufferAttribute?} * @default null */ this.attribute = null; /** * `BufferAttributeNode` sets this property to `true` by default. * * @type {Boolean} * @default true */ this.global = true; if ( value && value.isBufferAttribute === true ) { this.attribute = value; this.usage = value.usage; this.instanced = value.isInstancedBufferAttribute; } } /** * This method is overwritten since the attribute data might be shared * and thus the hash should be shared as well. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The hash. */ getHash( builder ) { if ( this.bufferStride === 0 && this.bufferOffset === 0 ) { let bufferData = builder.globalCache.getData( this.value ); if ( bufferData === undefined ) { bufferData = { node: this }; builder.globalCache.setData( this.value, bufferData ); } return bufferData.node.uuid; } return this.uuid; } /** * This method is overwritten since the node type is inferred from * the buffer attribute. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The node type. */ getNodeType( builder ) { if ( this.bufferType === null ) { this.bufferType = builder.getTypeFromAttribute( this.attribute ); } return this.bufferType; } /** * Depending on which value was passed to the node, `setup()` behaves * differently. If no instance of `BufferAttribute` was passed, the method * creates an internal attribute and configures it respectively. * * @param {NodeBuilder} builder - The current node builder. */ setup( builder ) { if ( this.attribute !== null ) return; const type = this.getNodeType( builder ); const array = this.value; const itemSize = builder.getTypeLength( type ); const stride = this.bufferStride || itemSize; const offset = this.bufferOffset; const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer( array, stride ); const bufferAttribute = new InterleavedBufferAttribute( buffer, itemSize, offset ); buffer.setUsage( this.usage ); this.attribute = bufferAttribute; this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute } /** * Generates the code snippet of the buffer attribute node. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The generated code snippet. */ generate( builder ) { const nodeType = this.getNodeType( builder ); const nodeAttribute = builder.getBufferAttributeFromNode( this, nodeType ); const propertyName = builder.getPropertyName( nodeAttribute ); let output = null; if ( builder.shaderStage === 'vertex' || builder.shaderStage === 'compute' ) { this.name = propertyName; output = propertyName; } else { const nodeVarying = varying( this ); output = nodeVarying.build( builder, nodeType ); } return output; } /** * Overwrites the default implementation to return a fixed value `'bufferAttribute'`. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The input type. */ getInputType( /*builder*/ ) { return 'bufferAttribute'; } /** * Sets the `usage` property to the given value. * * @param {Number} value - The usage to set. * @return {BufferAttributeNode} A reference to this node. */ setUsage( value ) { this.usage = value; if ( this.attribute && this.attribute.isBufferAttribute === true ) { this.attribute.usage = value; } return this; } /** * Sets the `instanced` property to the given value. * * @param {Boolean} value - The value to set. * @return {BufferAttributeNode} A reference to this node. */ setInstanced( value ) { this.instanced = value; return this; } } export default BufferAttributeNode; /** * TSL function for creating a buffer attribute node. * * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`). * @param {Number} [stride=0] - The buffer stride. * @param {Number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ export const bufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => nodeObject( new BufferAttributeNode( array, type, stride, offset ) ); /** * TSL function for creating a buffer attribute node but with dynamic draw usage. * Use this function if attribute data are updated per frame. * * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`). * @param {Number} [stride=0] - The buffer stride. * @param {Number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ export const dynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setUsage( DynamicDrawUsage ); /** * TSL function for creating a buffer attribute node but with enabled instancing * * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`). * @param {Number} [stride=0] - The buffer stride. * @param {Number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ export const instancedBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => bufferAttribute( array, type, stride, offset ).setInstanced( true ); /** * TSL function for creating a buffer attribute node but with dynamic draw usage and enabled instancing * * @function * @param {BufferAttribute|InterleavedBuffer|TypedArray} array - The attribute data. * @param {String?} [type=null] - The buffer type (e.g. `'vec3'`). * @param {Number} [stride=0] - The buffer stride. * @param {Number} [offset=0] - The buffer offset. * @returns {BufferAttributeNode} */ export const instancedDynamicBufferAttribute = ( array, type = null, stride = 0, offset = 0 ) => dynamicBufferAttribute( array, type, stride, offset ).setInstanced( true ); addMethodChaining( 'toAttribute', ( bufferNode ) => bufferAttribute( bufferNode.value ) );