import { Accessor , Document , Logger , Transform , TypedArray } from '@gltf-transform/core' ; import { createTransform } from './utils' ; const NAME = 'unweld' ; /** Options for the  unweld function.  export interface UnweldOptions { } const UNWELD_DEFAULTS = { } ; /**
 * De-index  Primitive s, disconnecting any shared vertices. This operation will generally
 * increase the number of vertices in a mesh, but may be helpful for some geometry operations or
 * for creating hard edges.
 *
 * No options are currently implemented for this function.
  export function unweld ( _options = UNWELD_DEFAULTS ) { const options = { ... UNWELD_DEFAULTS , ... _options } as Required < UnweldOptions > ; return createTransform ( NAME , ( doc ) : void => { const logger = doc . getLogger ( ) ; const visited = new Map < Accessor , Map < Accessor , Accessor > > ( ) ; for ( const mesh of doc . getRoot ( ) . listMeshes ( ) ) { for ( const prim of mesh . listPrimitives ( ) ) { const indices = prim . getIndices ( ) ; if ( ! indices ) continue ; for ( const srcAttribute of prim . listAttributes ( ) ) { prim . swap ( srcAttribute , unweldAttribute ( srcAttribute , indices , logger , visited ) ) ; if ( srcAttribute . listParents ( ) . length === 1 ) srcAttribute . dispose ( ) ; } for ( const target of prim . listTargets ( ) ) { for ( const srcAttribute of target . listAttributes ( ) ) { target . swap ( srcAttribute , unweldAttribute ( srcAttribute , indices , logger , visited ) ) ; if ( srcAttribute . listParents ( ) . length === 1 ) srcAttribute . dispose ( ) ; } } prim . setIndices ( null ) ; if ( indices . listParents ( ) . length === 1 ) indices . dispose ( ) ; } } logger . debug ( `${ NAME }: Complete.` ) ; } ) ; } function unweldAttribute ( srcAttribute , indices , logger , visited ) { if ( visited . has ( srcAttribute ) && visited . get ( srcAttribute ) ! . has ( indices ) ) { logger . debug ( `${ NAME }: Cache hit for reused attribute, "${ srcAttribute . getName ( ) }".` ) ; return visited . get ( srcAttribute ) ! . get ( indices ) ! ; } const dstAttribute = srcAttribute . clone ( ) ; const ArrayCtor = srcAttribute . getArray ( ) ! . constructor as new ( len ) => TypedArray ; dstAttribute . setArray ( new ArrayCtor ( indices . getCount ( ) * srcAttribute . getElementSize ( ) ) ) ; const el = [ ] ; for ( let i = 0 ; i < indices . getCount ( ) ; i ++ ) { dstAttribute . setElement ( i , srcAttribute . getElement ( indices . getScalar ( i ) , el ) ) ; } if ( ! visited . has ( srcAttribute ) ) visited . set ( srcAttribute , new Map ( ) ) ; visited . get ( srcAttribute ) ! . set ( indices , dstAttribute ) ; return dstAttribute ; }