MCP 3D Printer Server

by DMontgomery40
Verified
function WebGLAttributes( gl ) { const buffers = new WeakMap(); function createBuffer( attribute, bufferType ) { const array = attribute.array; const usage = attribute.usage; const size = array.byteLength; const buffer = gl.createBuffer(); gl.bindBuffer( bufferType, buffer ); gl.bufferData( bufferType, array, usage ); attribute.onUploadCallback(); let type; if ( array instanceof Float32Array ) { type = gl.FLOAT; } else if ( array instanceof Uint16Array ) { if ( attribute.isFloat16BufferAttribute ) { type = gl.HALF_FLOAT; } else { type = gl.UNSIGNED_SHORT; } } else if ( array instanceof Int16Array ) { type = gl.SHORT; } else if ( array instanceof Uint32Array ) { type = gl.UNSIGNED_INT; } else if ( array instanceof Int32Array ) { type = gl.INT; } else if ( array instanceof Int8Array ) { type = gl.BYTE; } else if ( array instanceof Uint8Array ) { type = gl.UNSIGNED_BYTE; } else if ( array instanceof Uint8ClampedArray ) { type = gl.UNSIGNED_BYTE; } else { throw new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array ); } return { buffer: buffer, type: type, bytesPerElement: array.BYTES_PER_ELEMENT, version: attribute.version, size: size }; } function updateBuffer( buffer, attribute, bufferType ) { const array = attribute.array; const updateRanges = attribute.updateRanges; gl.bindBuffer( bufferType, buffer ); if ( updateRanges.length === 0 ) { // Not using update ranges gl.bufferSubData( bufferType, 0, array ); } else { // Before applying update ranges, we merge any adjacent / overlapping // ranges to reduce load on `gl.bufferSubData`. Empirically, this has led // to performance improvements for applications which make heavy use of // update ranges. Likely due to GPU command overhead. // // Note that to reduce garbage collection between frames, we merge the // update ranges in-place. This is safe because this method will clear the // update ranges once updated. updateRanges.sort( ( a, b ) => a.start - b.start ); // To merge the update ranges in-place, we work from left to right in the // existing updateRanges array, merging ranges. This may result in a final // array which is smaller than the original. This index tracks the last // index representing a merged range, any data after this index can be // trimmed once the merge algorithm is completed. let mergeIndex = 0; for ( let i = 1; i < updateRanges.length; i ++ ) { const previousRange = updateRanges[ mergeIndex ]; const range = updateRanges[ i ]; // We add one here to merge adjacent ranges. This is safe because ranges // operate over positive integers. if ( range.start <= previousRange.start + previousRange.count + 1 ) { previousRange.count = Math.max( previousRange.count, range.start + range.count - previousRange.start ); } else { ++ mergeIndex; updateRanges[ mergeIndex ] = range; } } // Trim the array to only contain the merged ranges. updateRanges.length = mergeIndex + 1; for ( let i = 0, l = updateRanges.length; i < l; i ++ ) { const range = updateRanges[ i ]; gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT, array, range.start, range.count ); } attribute.clearUpdateRanges(); } attribute.onUploadCallback(); } // function get( attribute ) { if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; return buffers.get( attribute ); } function remove( attribute ) { if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; const data = buffers.get( attribute ); if ( data ) { gl.deleteBuffer( data.buffer ); buffers.delete( attribute ); } } function update( attribute, bufferType ) { if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; if ( attribute.isGLBufferAttribute ) { const cached = buffers.get( attribute ); if ( ! cached || cached.version < attribute.version ) { buffers.set( attribute, { buffer: attribute.buffer, type: attribute.type, bytesPerElement: attribute.elementSize, version: attribute.version } ); } return; } const data = buffers.get( attribute ); if ( data === undefined ) { buffers.set( attribute, createBuffer( attribute, bufferType ) ); } else if ( data.version < attribute.version ) { if ( data.size !== attribute.array.byteLength ) { throw new Error( 'THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.' ); } updateBuffer( data.buffer, attribute, bufferType ); data.version = attribute.version; } } return { get: get, remove: remove, update: update }; } export { WebGLAttributes };