Create THREE.Shape() from file or array

Hi,
Does anyone know if it is possible to create a THREE.Shape() from an external file or array?

Basically add the moveTo, lineTo, quadraticCurveTo etc to the shape() from data in an array.

Thanks

Thinking possible option is to use a csv file to a 2d array

const csv = `moveTo,0,0
moveTo,20,0
lineTo,40,0
quadraticCurveTo,60,0,60,20
lineTo,60,60
lineTo,0,60
lineTo,0,20
quadraticCurveTo,0, 0, 20, 0`;

let rows = csv.split('\n');
let lines = csv.split('\n').length;

let twodArray = rows.map(row => row.split(','));
console.log(twodArray)

for (var i = 0; i < twodArray.length; i++) {
  if(twodArray[i][0] === 'moveTo'){
    railShape.moveTo(twodArray[i][1], twodArray[i][2]);
  }else if(twodArray[i][0] === 'lineTo'){
    railShape.lineTo(twodArray[i][1], twodArray[i][2]);
  }else if(twodArray[i][0] === 'quadraticCurveTo'){
    railShape.quadraticCurveTo( twodArray[i][1],twodArray[i][2],twodArray[i][3],twodArray[i][4] );
  }
 }

You can load a suitable text file and then process the values from the array.

HTML

< input type="file" id="shapeFileLoad" style="display: none;" >

JS




const openShapeFileLoadWindow = async( ) => { await delay( 0.33 ); shapeFileLoad.click( ) }
shapeFileLoad.addEventListener( 'change', onShapeFileLoadChange );

function onShapeFileLoadChange( e ) {

    const f = shapeFileLoad.files[ 0 ];
    
    if ( f.type.match( /text.*/ ) ) {
        
        reader.readAsText( f );
         
        reader.onload =  e => { 
            
            // separate by , values into array
            array = e.target.result.match( /-?\d+(\.\d+)?/g ).map( Number ); 
             
            processLoadedShape( array );
            
        }
        
    } else {
        
        alert( "incorrect file type" );
        
    }
    
}

UPDATE:

You only need
async( ) => { await delay( 0.33 ); shapeFileLoad.click( ) }
if you call up the function on a graphic element with a key pressed at the same time. This prevents several pressed characters from appearing in the file name field.

It is easier if you call it with a button.

document.getElementById( 'importShape' ).addEventListener('pointerdown', ( ) => {
    document.getElementById( 'shapeFileLoad' ).click();
});

document.getElementById('shapeFileLoad').addEventListener('change', ( ) => {
     onShapeFileLoadChange( );
});

Very Helpful!

Thank you

Shape is a good match for SVG path command too. Its a lot more terse to read, but is a standard (its the d=“…” part). Its used internally by SVGLoader parsePathNode and supports holes if you later need that support.

Thank you :+1: