Skip to content

Editor - broken LDRAW support and missing PDB support #26279

@GitHubDragonFly

Description

@GitHubDragonFly

Description

Using online editor to load LDRAW file ends in error (both Firefox and Chrome browsers on Windows).

The 1st code below is actually what works for loading LDRAW files, with additional .DAT and .L3B formats + using @gkjohnson repository + removed undefined parameter from the loader.parse function call.

The 2nd code shows what works if PDB format is to be considered for inclusion, which is mainly the code extracted from the webgl_loader_pdb.html example.

I can submit a PR if this code is acceptable.

Reproduction steps

  1. Use either Firefox or Chrome browser and go to https://threejs.org/editor/
  2. Try to load any LDRAW file

Code

			case 'dat':
			case 'l3b':
			case 'ldr':
			case 'mpd':

			{

				reader.addEventListener( 'load', async function ( event ) {

					const { LDrawLoader } = await import( 'three/addons/loaders/LDrawLoader.js' );

					const loader = new LDrawLoader();

					// The path to preload color definitions from.
					await loader.preloadMaterials( 'https://raw.githubusercontent.com/gkjohnson/ldraw-parts-library/master/colors/ldcfgalt.ldr' );
					// The path to load parts from the LDraw parts library from.
					loader.setPartsLibraryPath( 'https://raw.githubusercontent.com/gkjohnson/ldraw-parts-library/master/complete/ldraw/' );
					loader.setPath( '../../examples/models/ldraw/officialLibrary/' );

					loader.parse( event.target.result, function ( group ) {

						group.name = filename;
						// Convert from LDraw coordinates: rotate 180 degrees around OX
						group.rotation.x = Math.PI;

						// Scale and add model groups to the scene
						group.scale.multiplyScalar( 0.1 );

						editor.execute( new AddObjectCommand( editor, group ) );

					} );

				}, false );
				reader.readAsText( file );

				break;

			}
			case 'pdb':

			{

				reader.addEventListener( 'load', async function ( event ) {

					const atomGeometry = new THREE.IcosahedronGeometry( 1, 2 );
					const bondGeometry = new THREE.BoxGeometry( 1, 1, 1 );
					let position = new THREE.Vector3();
					let offset = new THREE.Vector3();
					let start = new THREE.Vector3();
					let end = new THREE.Vector3();
					let color = new THREE.Color();

					let root = new THREE.Group();
					root.name = filename;

					let atoms = [];
					let bonds = [];
			
					const contents = event.target.result;

					const { PDBLoader } = await import( '../../examples/jsm/loaders/PDBLoader.js' );

					let pdb = new PDBLoader().parse( contents );

					// Get atom related data
					let geometryAtoms = pdb.geometryAtoms;
					// Get the data of the bond between atoms
					let geometryBonds = pdb.geometryBonds;
					// Get data of atomic text
					let json = pdb.json;

					// Center the model
					geometryAtoms.computeBoundingBox();
					geometryAtoms.boundingBox.getCenter( offset ).negate();
					geometryAtoms.translate( offset.x, offset.y, offset.z );
					geometryBonds.translate( offset.x, offset.y, offset.z );

					// Add atoms to the model group
					let positions = geometryAtoms.getAttribute( 'position' );
					let colors = geometryAtoms.getAttribute( 'color' );

					for ( var i = 0; i < positions.count; i ++ ) {

						position.x = positions.getX( i );
						position.y = positions.getY( i );
						position.z = positions.getZ( i );

						color.r = colors.getX( i );
						color.g = colors.getY( i );
						color.b = colors.getZ( i );

						let object = new THREE.Mesh( atomGeometry, new THREE.MeshStandardMaterial( { color: color } ) );
						object[ 'name' ] = 'atom_' + i;

						object.position.copy( position );
						object.position.multiplyScalar( 75 );
						object.scale.multiplyScalar( 25 );

						// Add atomic text to the atom's userData
						let atom = json.atoms[ i ];
						object.userData[ 'Element' ] = atom[ 4 ];

						atoms.push( object );
						root.add( object );

					}

					// Add bonds between atoms to the model group
					positions = geometryBonds.getAttribute( 'position' );

					for ( var i = 0; i < positions.count; i += 2 ) {

						start.x = positions.getX( i );
						start.y = positions.getY( i );
						start.z = positions.getZ( i );

						end.x = positions.getX( i + 1 );
						end.y = positions.getY( i + 1 );
						end.z = positions.getZ( i + 1 );

						start.multiplyScalar( 75 );
						end.multiplyScalar( 75 );

						let object = new THREE.Mesh( bondGeometry, new THREE.MeshStandardMaterial( { color: 0xFFFFFF } ) );
						object[ 'name' ] = 'bond_' + parseInt( i / 2 );

						object.position.copy( start );
						object.position.lerp( end, 0.5 );
						object.scale.set( 5, 5, start.distanceTo( end ) );
						object.lookAt( end );

						bonds.push( object );
						root.add( object );
					}

					// Scale and add model groups to the scene
					root.scale.multiplyScalar( 0.05 );

					editor.execute( new AddObjectCommand( editor, root ) );

				}, false );
				reader.readAsText( file );

				break;

			}

Live example

Screenshots

No response

Version

r153

Device

Desktop

Browser

Chrome, Firefox

OS

Windows

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions