Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exporting to 3DM format with three.js #579

Open
GitHubDragonFly opened this issue Jan 15, 2024 · 5 comments
Open

Exporting to 3DM format with three.js #579

GitHubDragonFly opened this issue Jan 15, 2024 · 5 comments
Assignees
Labels

Comments

@GitHubDragonFly
Copy link

I bothered creating a custom 3DMExporter that, in my opinion, does a decent job exporting meshes and points to 3dm format.

My question would be related to accessing rhino's material.textures array, which does not seem to exist but is included in the 3DMLoader.js code.

With the following code I can get all the necessary texture information, including base64 image strings, that can be used by the 3DM Loader, but cannot figure a way of passing it to rhino object to be written into the resulting file:

		// convert scene to JSON
		let json = JSON.stringify( scene.toJSON() );

		// parse metadata, geometries, materials, images, textures and object:
		let result = JSON.parse( json );

The above code can be seen in the link I provided to my exporter's code, which also shows a structure of the result variable for better understanding.

Just looking for any help I could get to try and improve the exporter by exporting textures together with the model.

@GitHubDragonFly
Copy link
Author

Here is an example code that I am trying to make work and include in the exporter:

						rhino_material = new Module.Material();
						rhino_material.default();

						// this textures array does get created and stores images
						// but will not be included in the final output file

						rhino_material.textures = [];

						const texture_names = {};

						function add_texture( map, map_type ) {

							for ( const texture of result.textures ) {

								if ( texture.uuid === map && ! texture_names[ texture.name ] ) {

									texture_names[ texture.name ] = texture.name;

									let tex = texture;

									tex.type = map_type;

									if ( texture.wrap !== undefined ) {

										tex.wrapU = texture.wrap[ 0 ] === 1000 ? 0 : 1;
										tex.wrapV = texture.wrap[ 1 ] === 1000 ? 0 : 1;

									}

									if ( texture.image ) {

										for ( const image of result.images ) {

											if ( image.uuid === texture.image ) {

												tex.image = image.url;

											}

										}

									}

									rhino_material.textures.push( tex );

								}

							}

						}

						if ( material.type === 'MeshStandardMaterial' || material.type === 'MeshPhysicalMaterial' ) {

							if ( material.map ) add_texture( material.map, 'PBR_BaseColor' );
							if ( material.aoMap ) add_texture( material.aoMap, 'PBR_AmbientOcclusion' );
							if ( material.alphaMap ) add_texture( material.alphaMap, 'PBR_Alpha' );
							if ( material.emissiveMap ) add_texture( material.emissiveMap, 'PBR_Emission' );
							if ( material.anisotropyMap ) add_texture( material.anisotropyMap, 'PBR_Anisotropic' );
							if ( material.clearcoatMap ) add_texture( material.clearcoatMap, 'PBR_Clearcoat' );
							if ( material.clearcoatNormalMap ) add_texture( material.clearcoatNormalMap, 'PBR_ClearcoatBump' );
							if ( material.clearcoatRoughnessMap ) add_texture( material.clearcoatRoughnessMap, 'PBR_ClearcoatRoughness' );
							if ( material.displacementMap ) add_texture( material.displacementMap, 'PBR_Displacement' );
							if ( material.metalnessMap ) add_texture( material.metalnessMap, 'PBR_Metallic' );
							if ( material.roughnessMap ) add_texture( material.roughnessMap, 'PBR_Roughness' );
							if ( material.sheenColorMap ) add_texture( material.sheenColorMap, 'PBR_Sheen' );
							if ( material.specularColorMap ) add_texture( material.specularColorMap, 'PBR_Specular' );
							if ( material.transmissionMap ) add_texture( material.transmissionMap, 'Opacity' );
							if ( material.thicknessMap ) add_texture( material.thicknessMap, 'PBR_Subsurface' );

						} else {

							if ( material.map ) add_texture( material.map, 'Diffuse' );
							if ( material.alphaMap ) add_texture( material.alphaMap, 'Transparency' );
							if ( material.bumpMap ) add_texture( material.bumpMap, 'Bump' );
							if ( material.envMap ) add_texture( material.envMap, 'Emap' );

						}

@fraguada
Copy link
Member

Hello! Thanks for sharing your exporter efforts. This is something that has been on my list to do, but have not yet come around to doing it.

I will take a look at your exporter implementation, but first I'd like to know what might be going wrong? I have a few ideas of some limitations, including adding embedded files (texture maps) into the 3dm. I am not sure we have exposed all of this properly in rhino3dm.js.

@fraguada fraguada self-assigned this Jan 15, 2024
@fraguada fraguada added the js label Jan 15, 2024
@GitHubDragonFly
Copy link
Author

@fraguada thank you for responding.

Below you can see a screenshot of the browser console which shows the rhino material object and its properties.

The textures property is not available in the prototype of the object but is attached to the object as a property after my code is processed. Once this rhino material is added to the rhino object (File3dm) then it looks like that this textures property is just discarded.

This screenshot represents an attempt to export the Damaged Helmet example model.

Console - Rhino Material

@GitHubDragonFly
Copy link
Author

@fraguada this is just an off topic FYI related to 3DM Loader available in the three.js repository. This is in case if you were the one to create it.

It contains typos for clearCoat properties (which should all be lowercase) and does not seem to be treating all the colors in the same way (dividing by 255.0).

On my end, I have included a modified version of 3DM Loader so you can check it if necessary.

I might also be wrong about some modifications.

@GitHubDragonFly
Copy link
Author

@fraguada just as an FYI, eventually I figured out how to include textures and additional physical material properties by using user strings.

This is all a custom workaround but appears to be highly functional with three.js library, at least on my end.

You can close this issue at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants