/*jshint esversion: 6 */
	import * as THREE from 'three';
	// import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
	import {FontLoader} from 'three/addons/loaders/FontLoader.js';
	import {TextGeometry} from 'three/addons/geometries/TextGeometry.js';

	// rack
	export function rack(text, width=800, height=2500, depth=800, color=0xf0f0f0) {
		const rackObject = new THREE.Object3D();

		const materialBase = new THREE.MeshLambertMaterial({color: 0x0000d0});
		let group, textMesh, textGeo, materials;
		let size = 60;
		let textheight = 10;
		let pos = [];
		let rot = [];
		const hover = 30;
		const curveSegments = 8;
		let font;
		function insertText(isize, ipos, irot) {
			group = new THREE.Group();
			group.position.y = 100;
			rackObject.add( group );
			size = isize;
			pos = ipos;
			rot = irot;
			loadFont();
		}
		function loadFont() {
			const loader = new FontLoader();
			// https://threejs.org/examples/fonts/droid_sans_bold.typeface.json
			loader.load( './fonts/droid_sans_bold.typeface.json', function ( response ) {
				font = response;
				refreshText();
			} );
		}
		function createText() {
			textGeo = new TextGeometry(text, {font: font, size: size, height: textheight, curveSegments: curveSegments});
			textGeo.computeBoundingBox();
			const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x);
			textMesh = new THREE.Mesh(textGeo, materialBase);
			textMesh.position.x = pos[0];
			textMesh.position.y = pos[1];
			textMesh.position.z = pos[2];
			textMesh.rotation.x = rot[0];
			textMesh.rotation.y = rot[1];
			textMesh.rotation.z = rot[2];
			group.add( textMesh );
			const group2 = group.clone();
			group2.rotateY(Math.PI);
			group2.position.set(width, 90, depth-100);
			rackObject.add(group2);	
			
		}
		function refreshText() {
			group.remove( textMesh );
			if ( ! text ) return;
			createText();
		}
		insertText(50, [width+10, height-170, depth-150], [0, Math.PI / 2, 0]);

		const tag = new THREE.MeshLambertMaterial({color: 0xfbe928});
		//front yellow tag
		const Ftag = new THREE.BoxGeometry(2, 90, depth-100);
		const Ftagmesh = new THREE.Mesh(Ftag, tag);
		Ftagmesh.position.set(-10, height-50, depth/2-5);
		rackObject.add(Ftagmesh);		
		//Rear yellow tag
		const Rtag = new THREE.BoxGeometry(2, 90, depth-100);
		const Rtagmesh = new THREE.Mesh(Rtag, tag);
		Rtagmesh.position.set(width+10, height-50, depth/2-5);
		rackObject.add(Rtagmesh);				

		const rackmaterial = new THREE.MeshLambertMaterial({color: color});
		const rackgeometry = new THREE.BoxGeometry(width, height, depth);
		const rackmesh = new THREE.Mesh(rackgeometry, rackmaterial);
		rackmesh.position.set(width/2, height/2, depth/2);
		rackObject.add(rackmesh);
		return rackObject;
	}
	// transparent wall
	export function wall(param) {
		const length=3000;
		const material = new THREE.MeshBasicMaterial({color: 0xff8080, transparent: true, opacity: 0.2, side: THREE.DoubleSide,});
		const geometry = new THREE.CylinderGeometry(10 /*radiusTop*/, 10 /*radiusBottom*/, length /*height*/, 4 /*radialSegments*/, 2 /*heightSegments*/, false /*openEnded*/,0 /*thetaStart*/, Math.PI * 2 /*thetaLength*/);
		const chamberMesh = new THREE.Mesh(geometry, material);
		chamberMesh.rotateX(Math.PI * 0.5);
		chamberMesh.scale.setZ(100);
		chamberMesh.rotatedX = true;
		return chamberMesh;
	}
	// label
	export function label(param) {
		let size = 700;
		const label = new THREE.Object3D();
		const text=param.name, height=-50;
		const length = param && param.labelReverse && param.labelReverse[1]? param.labelReverse[1]: -3000;
		const depth = param && param.labelReverse && param.labelReverse[2]? param.labelReverse[2]: -3000;
		const materialBase = new THREE.MeshLambertMaterial({color: 0xff0000});
		const objLabel = new THREE.Object3D();
		let group, textMesh, textGeo, materials;
		let textheight = 50;
		let pos = [];
		let rot = [];
		const hover = 30;
		const curveSegments = 8;
		let font;
		function insertText(isize, ipos, irot) {
			group = new THREE.Group();
			objLabel.add( group );
			size = isize;
			pos = ipos;
			rot = irot;
			loadFont();
		}
		function loadFont() {
			const loader = new FontLoader();
			// https://threejs.org/examples/fonts/droid_sans_bold.typeface.json
			loader.load( './fonts/droid_sans_bold.typeface.json', function ( response ) {
				font = response;
				refreshText();
			} );
		}
		function createText() {
			textGeo = new TextGeometry(text, {font: font, size: size, height: textheight, curveSegments: curveSegments});
			textGeo.computeBoundingBox();
			const centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
			textMesh = new THREE.Mesh( textGeo, materialBase );
			textMesh.position.x = pos[0];
			textMesh.position.y = pos[1];
			textMesh.position.z = pos[2];
			textMesh.rotation.x = rot[0];
			textMesh.rotation.y = rot[1];
			textMesh.rotation.z = rot[2];
			group.add( textMesh );
			
		}
		function refreshText() {
			group.remove( textMesh );
			if ( ! text ) return;
			createText();
		}
		insertText(size, [length, height, depth], [Math.PI*0.5, Math.PI, 0]);

		return objLabel;
	}
	export function rack2fast(param) {return rack(param.name, 800, 2000, 600);}
	export function rdfast(param) {return rack(param.name, 800, 2500, 600,0x0060f0);}
	export function rvfast(param) {return rack(param.name, 800, 2500, 800, 0x0060f0);}
	export function ridfast(param) {return rack(param.name, 800, 2500, 600, 0x0060f0);}
	export function rpsfast(param) {return rack(param.name, 800, 2500, 600,0x0060f0);}
	export function rcfast(param) {return rack(param.name, 800, 2500, 600,0x0060f0);}
	export function fugfast(param) {return rack(param.name, 1000, 2000, 1000);}
	export function rllrffast(param) {return rack(param.name, 800, 1200, 600);}
	export function rar1fast(param) {return rack(param.name, 800, 2000, 800);}
	export function rar2fast(param) {return rack(param.name, 800, 2000, 800);}
	export function camodfast(param) {return rack(param.name, 1200, 2000, 1500);}
	export function klystronxfast(param) {return rack(param.name, 1000, 2000, 800, 'darkred');}

	export function klystronfast(param) {
		const text=param.name, myscale=0.625;
		const width=1500, height=1500, depth=1500;
		const ModK = new THREE.Object3D();
		const ModContainer = new THREE.Object3D();
		const materialBase = new THREE.MeshLambertMaterial({color: 0xff0000});
		const klystron = new THREE.Object3D();
		let group, textMesh, textGeo, materials;
		let size = 60;
		let textheight = 10;
		let pos = [];
		let rot = [];
		const hover = 30;
		const curveSegments = 8;
		let font;
		function insertText(isize, ipos, irot) {
			group = new THREE.Group();
			group.position.y = 100;
			klystron.add( group );
			size = isize;
			pos = ipos;
			rot = irot;
			loadFont();
		}
		function loadFont() {
			const loader = new FontLoader();
			// https://threejs.org/examples/fonts/droid_sans_bold.typeface.json
			loader.load( './fonts/droid_sans_bold.typeface.json', function ( response ) {
				font = response;
				refreshText();
			} );
		}
		materials = [
			new THREE.MeshPhongMaterial( { color: 0x333333, flatShading: true } ), // front
			new THREE.MeshPhongMaterial( { color: 0x333333 } ) // side
		];
		function createText() {
			textGeo = new TextGeometry(text.replace('TKLY_KG','K').replace('.01',''), {font: font, size: size, height: textheight, curveSegments: curveSegments});
			textGeo.computeBoundingBox();
			const centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
			textMesh = new THREE.Mesh( textGeo, materials );
			textMesh.position.x = pos[0];
			textMesh.position.y = pos[1];
			textMesh.position.z = pos[2];
			textMesh.rotation.x = rot[0];
			textMesh.rotation.y = rot[1];
			textMesh.rotation.z = rot[2];
			group.add( textMesh );
		}
		function refreshText() {
			group.remove( textMesh );
			if ( ! text ) return;
			createText();
		}
		insertText(75, [950,680,560], [0, Math.PI / 2, 0]);
		
		const basegeometry = new THREE.BoxGeometry(width, height, depth);
		const d1mesh = new THREE.Mesh(basegeometry, materialBase);
		ModContainer.add(d1mesh);

		// cover
		const d2geometry = new THREE.BoxGeometry(width+100, 100, depth+100);
		const dmaterial2= new THREE.MeshLambertMaterial({color: 0xf0f0f0});
		const d2mesh = new THREE.Mesh(d2geometry, dmaterial2);
		d2mesh.position.set(0, 800, 0);		
		ModContainer.add(d2mesh);	
		
		const materialGreyDark= new THREE.MeshLambertMaterial({color: 0x9d9d9d});
		
		// big cylinder
		const d4geometry = new THREE.CylinderGeometry(400, 400, 1200, 50);
		const d4mesh = new THREE.Mesh(d4geometry, materialGreyDark);
		d4mesh.rotateX(Math.PI * 1);
		d4mesh.rotateY(Math.PI * 1);
		d4mesh.rotateZ(Math.PI * 1);
		d4mesh.position.set(0, 970 , 300);			
		ModContainer.add(d4mesh);	

		// small cylinder
		const d5geometry = new THREE.CylinderGeometry(200, 200, 1200, 50);
		const d5mesh = new THREE.Mesh(d5geometry, materialGreyDark);
		d5mesh.rotateX(Math.PI * 1);
		d5mesh.rotateY(Math.PI * 1);
		d5mesh.rotateZ(Math.PI * 1);
		d5mesh.position.set(0, 1670 , 300);			
		ModContainer.add(d5mesh);	
		
		// high cover
		const d6geometry = new THREE.CylinderGeometry(220, 220, 90, 50);
		const d6mesh = new THREE.Mesh(d6geometry, materialGreyDark);
		d6mesh.rotateX(Math.PI * 1);
		d6mesh.rotateY(Math.PI * 1);
		d6mesh.rotateZ(Math.PI * 1);
		d6mesh.position.set(0, 2300 , 300);			
		ModContainer.add(d6mesh);	
		
		// right arm
		const Bracciodx = new THREE.BoxGeometry( 600, 100, 200 );
		const d7mesh = new THREE.Mesh(Bracciodx, materialBase);
		d7mesh.rotateX(Math.PI * 1);
		d7mesh.rotateY(Math.PI * 1.25);
		d7mesh.rotateZ(Math.PI * 1);		
		d7mesh.position.set(300, 1300 , 600);			
		ModContainer.add(d7mesh);	

		// left arm
		const Bracciosx = new THREE.BoxGeometry( 600, 100, 200 );
		const d8mesh = new THREE.Mesh(Bracciosx, materialBase);
		d8mesh.rotateX(Math.PI * 1);
		d8mesh.rotateY(Math.PI * 1.75);
		d8mesh.rotateZ(Math.PI * 1);		
		d8mesh.position.set(300, 1300 , 0);			
		ModContainer.add(d8mesh);	

		// right arm continue
		const PBracciodx = new THREE.BoxGeometry( 600, 100, 190 );
		const d9mesh = new THREE.Mesh(PBracciodx, materialBase);
		d9mesh.rotateX(Math.PI * 1);
		d9mesh.rotateY(Math.PI * 1);
		d9mesh.rotateZ(Math.PI * 1);		
		d9mesh.position.set(743, 1300 , 790);			
		ModContainer.add(d9mesh);			
		
		//prolung braccia sx
		const PBracciosx = new THREE.BoxGeometry( 600, 100, 190 );
		const d10mesh = new THREE.Mesh(PBracciosx, materialBase);
		d10mesh.rotateX(Math.PI * 1);
		d10mesh.rotateY(Math.PI * 1);
		d10mesh.rotateZ(Math.PI * 1);		
		d10mesh.position.set(743, 1300 , -190);			
		ModContainer.add(d10mesh);	
		

		//targhetta
		const targhetta = new THREE.BoxGeometry( 10, 300, 300 );
		const d14mesh = new THREE.Mesh(targhetta, dmaterial2);
		d14mesh.position.set(-750, 550 , 0);
		ModContainer.add(d14mesh);	
		

		ModContainer.rotateY(Math.PI);
		ModContainer.scale.set(myscale, myscale, myscale);
		ModContainer.position.set(width*myscale/2, height*myscale/2, depth*myscale/2);
		klystron.add(ModContainer);
		return klystron;
	}

	// rpsb rack
	export function rpsb(param) {
		const width=1000, height=2100, depth=1000;
		const rpsb = new THREE.Object3D();
		const rpsb_rackObject = new THREE.Object3D();

		const materialBase = new THREE.MeshLambertMaterial({color: 0x0000d0});
		const text = param.name;
		let group, textMesh, textGeo, materials;
		let size = 60;
		let textheight = 10;
		let pos = [];
		let rot = [];
		const hover = 30;
		const curveSegments = 8;
		let font;
		function insertText(isize, ipos, irot) {
			group = new THREE.Group();
			group.position.y = 100;
			rpsb.add( group );
			size = isize;
			pos = ipos;
			rot = irot;
			loadFont();
		}
		function loadFont() {
			const loader = new FontLoader();
			// https://threejs.org/examples/fonts/droid_sans_bold.typeface.json
			loader.load( './fonts/droid_sans_bold.typeface.json', function ( response ) {
				font = response;
				refreshText();
			} );
		}
		function createText() {
			textGeo = new TextGeometry(text, {font: font, size: size, height: textheight, curveSegments: curveSegments});
			textGeo.computeBoundingBox();
			const centerOffset = -0.5 * (textGeo.boundingBox.max.x - textGeo.boundingBox.min.x);
			textMesh = new THREE.Mesh(textGeo, materialBase);
			textMesh.position.x = pos[0];
			textMesh.position.y = pos[1];
			textMesh.position.z = pos[2];
			textMesh.rotation.x = rot[0];
			textMesh.rotation.y = rot[1];
			textMesh.rotation.z = rot[2];
			group.add( textMesh );
			const group2 = group.clone();
			group2.rotateY(Math.PI);
			group2.position.set(790, 90, -850);
			rpsb.add(group2);				
		}
		function refreshText() {
			group.remove( textMesh );
			if ( ! text ) return;
			createText();
		}
		insertText(50, [900, 1725, -180], [0, Math.PI / 2, 0]);				
		
		const greenmaterial = new THREE.MeshLambertMaterial({color: 0x00ac76});
		const target = new THREE.MeshLambertMaterial({color: 0xfbe928});
		
		//rack
		const geometry = new THREE.BoxGeometry(width, height, depth);
		const rackmesh = new THREE.Mesh(geometry, greenmaterial);
		rackmesh.position.set( 0, 0 , 0);
		rpsb_rackObject.add(rackmesh);				
	
		//front yellow target
		const Ftarget = new THREE.BoxGeometry(2, 90, 600);
		const Ftargetmesh = new THREE.Mesh(Ftarget, target);
		Ftargetmesh.position.set( -504, 800 , 0);
		rpsb_rackObject.add(Ftargetmesh);		
		//Rear yellow target
		const Rtarget = new THREE.BoxGeometry(2, 90, 600);
		const Rtargetmesh = new THREE.Mesh(Rtarget, target);
		Rtargetmesh.position.set( 504, 800 , 0);
		rpsb_rackObject.add(Rtargetmesh);		
		
		rpsb_rackObject.rotateY(Math.PI);
		rpsb_rackObject.position.set(400, 1050, -400);
		rpsb.add(rpsb_rackObject);		
		
		
		rpsb_rackObject.position.set(400, 1050, -400);
		rpsb.add(rpsb_rackObject);	
		return rpsb;
	}

	// cavity for linac
	export function cavitylinac(param) {
		const length = param.length? param.length: 1200;
		const cavitylinacMaster = new THREE.Object3D();
		const dmaterial = new THREE.MeshLambertMaterial({color: 0xf0f0f0});
		const d1geometry = new THREE.CylinderGeometry(75, 75, length, 25);
		const d1mesh = new THREE.Mesh(d1geometry, dmaterial);
		d1mesh.position.set(0, length/2+350, 0);
		cavitylinacMaster.add(d1mesh);				
		cavitylinacMaster.rotateX(Math.PI * 0.5);
		cavitylinacMaster.rotatedX = true;
		return cavitylinacMaster;
	}

	// flsc
	export function flscfast(param) {
		const length=700;
		const flscSR = new THREE.Object3D();
		const flscContiner = new THREE.Object3D();
		const materialGrey = new THREE.MeshLambertMaterial({color: 0xf0f0f0});
		
		
		const d1geometry = new THREE.CylinderGeometry(25, 25, 500, 15);
		const d1mesh = new THREE.Mesh(d1geometry, materialGrey);
		flscContiner.add(d1mesh);				
		flscContiner.rotateX(Math.PI * 1);
		
		// zigrinatura
		const d4geometry = new THREE.CylinderGeometry(70, 70, 160, 20);
		const textureLoader = new THREE.TextureLoader();
		const texture = textureLoader.load('./components/flsc_texture.png');	
		texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
		texture.repeat.set(5, 40);		
		const material = new THREE.MeshBasicMaterial({ map: texture });		
		const d4mesh = new THREE.Mesh(d4geometry, material);
		d4mesh.rotateX(Math.PI * 1);
		d4mesh.rotateY(Math.PI * 1);
		d4mesh.rotateZ(Math.PI * 1);
		d4mesh.position.set(0, 80 , 0);			
		flscContiner.add(d4mesh);		
		
		// cil3
		const dmateria6 = new THREE.MeshLambertMaterial({color: 0x000000});
		const d6geometry = new THREE.CylinderGeometry(50, 50, 60, 15);
		const d6mesh = new THREE.Mesh(d6geometry, dmateria6);
		d6mesh.rotateX(Math.PI * 1);
		d6mesh.rotateY(Math.PI * 1);
		d6mesh.rotateZ(Math.PI * 1);
		d6mesh.position.set(0, -30 , 0);			
		flscContiner.add(d6mesh);		
		
		// box gray
		const d7geometry = new THREE.BoxGeometry(100, 100, 100);
		const dmaterial7= new THREE.MeshLambertMaterial({color: 0x405040});
		const d7mesh = new THREE.Mesh(d7geometry, dmaterial7);
		d7mesh.position.set(0, -110, 0);		
		flscContiner.add(d7mesh);				
				
		// box orange
		const d9geometry = new THREE.BoxGeometry(100, 120, 100);
		const dmaterial9= new THREE.MeshLambertMaterial({color: 0xffA500});
		const d9mesh = new THREE.Mesh(d9geometry, dmaterial9);
		d9mesh.position.set(0, -220, 0);		
		flscContiner.add(d9mesh);	

		flscContiner.position.set(0, 280, 0);
		flscSR.add(flscContiner);
		flscSR.rotateY(Math.PI * -0.5);
		return flscSR;
	}

	// fug PS
	export function fug(param) {
		const width=800, height=1700, depth=600;
		const fug = new THREE.Object3D();
		const fugObject = new THREE.Object3D();
		
		const materialGreyDark= new THREE.MeshLambertMaterial({color: 0x9d9d9d});
		const materialVeryGreyDark= new THREE.MeshLambertMaterial({color: 0x242424});
		const silvermaterial = new THREE.MeshLambertMaterial({color: 0xf0f0f0});
		const basematerial = new THREE.MeshLambertMaterial({color: 0xc4b2a8});
		
		//right rack
		const lrgeometry = new THREE.BoxGeometry(width, height, depth);
		const lrmesh = new THREE.Mesh(lrgeometry, silvermaterial);
		lrmesh.position.set(0 , 0 , -100);
		fugObject.add(lrmesh);
		
		
		//left rack
		const rrgeometry = new THREE.BoxGeometry(width, height, depth);
		const rrmesh = new THREE.Mesh(rrgeometry, silvermaterial);
		rrmesh.position.set( 0, 0 , -710);
		fugObject.add(rrmesh);		
		
		//basefug
		const basegeometry = new THREE.BoxGeometry(width+250, height-800, depth+600);
		const basemesh = new THREE.Mesh(basegeometry, silvermaterial);
		basemesh.position.set( -130, -1320 , -400);
		fugObject.add(basemesh);			
		
		//edge lle		
		const llegeometry = new THREE.BoxGeometry(50, 1700, 50);
		const llemesh = new THREE.Mesh(llegeometry, materialGreyDark);
		llemesh.position.set( -425, 0 , -985);
		fugObject.add(llemesh);
		
		//edge lre		
		const lregeometry = new THREE.BoxGeometry(50, 1700, 50);
		const lremesh = new THREE.Mesh(lregeometry, materialGreyDark);
		lremesh.position.set( -425, 0 , -430);
		fugObject.add(lremesh);		

		//edge rle		
		const rlegeometry = new THREE.BoxGeometry(50, 1700, 50);
		const rlemesh = new THREE.Mesh(rlegeometry, materialGreyDark);
		rlemesh.position.set( -425, 0 , -370);
		fugObject.add(rlemesh);	
		
		//edge rre		
		const rregeometry = new THREE.BoxGeometry(50, 1700, 50);
		const rremesh = new THREE.Mesh(rregeometry, materialGreyDark);
		rremesh.position.set( -425, 0 , 175);
		fugObject.add(rremesh);		
		
		//edge lue		
		const luegeometry = new THREE.BoxGeometry(50, 50, 505);
		const luemesh = new THREE.Mesh(luegeometry, materialGreyDark);
		luemesh.position.set( -425, 825 , -707);
		fugObject.add(luemesh);		

		//edge lde		
		const ldegeometry = new THREE.BoxGeometry(50, 50, 505);
		const ldemesh = new THREE.Mesh(ldegeometry, materialGreyDark);
		ldemesh.position.set( -425, -830 , -707);
		fugObject.add(ldemesh);				

		//edge rue		
		const ruegeometry = new THREE.BoxGeometry(50, 50, 505);
		const ruemesh = new THREE.Mesh(ruegeometry, materialGreyDark);
		ruemesh.position.set( -425, 825 , -100);
		fugObject.add(ruemesh);			
		
		//edge rde		
		const rdegeometry = new THREE.BoxGeometry(50, 50, 505);
		const rdemesh = new THREE.Mesh(rdegeometry, materialGreyDark);
		rdemesh.position.set( -425, -825 , -100);
		fugObject.add(rdemesh);	
				
		//base1 left and texture
   		const drawer1geometry = new THREE.BoxGeometry(10, 1600, 500);
		const textureLoader = new THREE.TextureLoader();
		const texture = textureLoader.load('./components/fug1screenfoto.jpg');
		texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
		texture.repeat.set(1, 1);
		const material = new THREE.MeshBasicMaterial({ map: texture });
		const gridgeometrymesh = new THREE.Mesh(drawer1geometry, material);
		gridgeometrymesh.rotateX(Math.PI * 1);
		gridgeometrymesh.rotateY(Math.PI * 1);
		gridgeometrymesh.rotateZ(Math.PI * 1);
		gridgeometrymesh.position.set( -400, 0 , -707);
		fugObject.add(gridgeometrymesh);		
		
		//base2 right and texture
   		const drawer2geometry = new THREE.BoxGeometry(10, 1600, 500);
		const textureLoader2 = new THREE.TextureLoader();
		const texture2 = textureLoader2.load('./components/fug2screenfoto.jpg');
		texture2.wrapS = texture2.wrapT = THREE.RepeatWrapping;
		texture2.repeat.set(1, 1);
		const material2 = new THREE.MeshBasicMaterial({ map: texture2 });
		const gridgeometry2mesh = new THREE.Mesh(drawer2geometry, material2);
		gridgeometry2mesh.rotateX(Math.PI * 1);
		gridgeometry2mesh.rotateY(Math.PI * 1);
		gridgeometry2mesh.rotateZ(Math.PI * 1);
		gridgeometry2mesh.position.set( -400, 0 , -100);
		fugObject.add(gridgeometry2mesh);	
		
		//base3 FUG write and texture
   		const drawer0geometry = new THREE.BoxGeometry(1, 900, 1200);
		const textureLoader0 = new THREE.TextureLoader();
		const texture0 = textureLoader0.load('./components/fug0screenfoto.jpg');
		texture0.wrapS = texture0.wrapT = THREE.RepeatWrapping;
		texture0.repeat.set(1, 1);
		const material0 = new THREE.MeshBasicMaterial({ map: texture0 });
		const gridgeometry0mesh = new THREE.Mesh(drawer0geometry, material0);
		gridgeometry0mesh.rotateX(Math.PI * 1);
		gridgeometry0mesh.rotateY(Math.PI * 1);
		gridgeometry0mesh.rotateZ(Math.PI * 1);
		gridgeometry0mesh.position.set( -655, -1320 , -400);
		fugObject.add(gridgeometry0mesh);			

		fugObject.rotateY(Math.PI);
		fugObject.position.set(400, 1750, 400);
		fug.add(fugObject);
		return fug;
	}

	export function gun(param) {
		const sphereRadius=200, sphereFactor=0.8;
		const cavityObject = new THREE.Object3D();
		const cavitymaterial = new THREE.MeshLambertMaterial({color: 0xb0b0b0});
		const cavitygeometry = new THREE.SphereGeometry(sphereRadius, 32, 32);
		const cavitymesh = new THREE.Mesh(cavitygeometry, cavitymaterial);
		cavitymesh.scale.setZ(sphereFactor);
		cavityObject.add(cavitymesh);
		/*const rfGeometry = new THREE.CylinderGeometry(cylinderRadius, cylinderRadius,  cylinderHeight, 20, 2, false, 0, Math.PI * 2);
		const rfMesh = new THREE.Mesh(rfGeometry, cavitymaterial);
		// rfMesh.rotateX(Math.PI * 0.5);
		rfMesh.position.set(0, sphereRadius, 0);
		cavityObject.add(rfMesh);*/
		return cavityObject;
	}

	// corrector fermi
	export function correctorfermi(param) {
		const length=400;
		const CorrectorContiner = new THREE.Object3D();
		const CorrectorMaster = new THREE.Object3D();
		
		// coil settings
		const loader = new THREE.TextureLoader();
		const texture = loader.load('./components/coil_texture_fermi.png');
		const textureTop = texture.clone();
		const textureSide = texture.clone();
		texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
		texture.repeat.set(2, 20);
		textureTop.center.set(0.5, 0.5);
		textureTop.rotation = THREE.MathUtils.degToRad(90);
		textureSide.offset.set(0, 0.8);
		const dmaterial = new THREE.MeshLambertMaterial({map: texture});
		const face = new THREE.MeshBasicMaterial({map: texture});
		const faceTop = new THREE.MeshBasicMaterial({map: textureTop});
		const faceSide = new THREE.MeshBasicMaterial({map: textureSide});
		const materials = [face,face,faceTop,faceSide,faceSide,faceSide];
		const d1geometry = new THREE.CylinderGeometry(500, 500, length, 4 /*radialSegments*/, 2 /*heightSegments*/, true /*openEnded*/,0 /*thetaStart*/, Math.PI * 2 /*thetaLength*/);
		const d1mesh = new THREE.Mesh(d1geometry, materials);
		d1mesh.position.set(0, 0, 0);
		d1mesh.rotateX(Math.PI * 1.25);
		d1mesh.rotateY(Math.PI * 1);
		d1mesh.rotateZ(Math.PI * 1.5);	
		CorrectorMaster.add(d1mesh);	

		//spessore esterno plastica bianca
		const redmaterialp = new THREE.MeshLambertMaterial({color: 0xeD2D2D2, side:THREE.DoubleSide});
		const geometry_1p = new THREE.CylinderGeometry(501 /*radiusTop*/, 501 /*radiusBottom*/, 90 /*height*/, 4 /*radialSegments*/, 2 /*heightSegments*/, true /*openEnded*/,0 /*thetaStart*/, Math.PI * 2 /*thetaLength*/);
		const dmesh_1p = new THREE.Mesh(geometry_1p, redmaterialp);
		dmesh_1p.position.set(0, 0, 0);
		dmesh_1p.rotateX(Math.PI * 1.25);
		dmesh_1p.rotateY(Math.PI * 1);
		dmesh_1p.rotateZ(Math.PI * 1.5);	
		CorrectorMaster.add(dmesh_1p); 
		
		//spessore alto centro
		const redmaterial_5 = new THREE.MeshLambertMaterial({color: 0xeD2D2D2});
		const geometry_1_5 = new THREE.BoxGeometry(length, 150, 700);
		const dmesh_1_5 = new THREE.Mesh(geometry_1_5, redmaterial_5);
		dmesh_1_5.position.set(0, 277, 0);
		CorrectorMaster.add(dmesh_1_5);
		
		//spessore basso
		const dmesh_2 = new THREE.Mesh(geometry_1_5, redmaterial_5);
		dmesh_2.position.set(0, -277, 0);
		CorrectorMaster.add(dmesh_2);
		
		//spessore destro
		const geometry_3 = new THREE.BoxGeometry(length, 600, 150);
		const dmesh_3 = new THREE.Mesh(geometry_3, redmaterial_5);
		dmesh_3.position.set(0, 0, -275);
		CorrectorMaster.add(dmesh_3);	
		
		//spessore sinistro
		const dmesh_4 = new THREE.Mesh(geometry_3, redmaterial_5);
		dmesh_4.position.set(0, 0, 275);
		CorrectorMaster.add(dmesh_4);	
		
		//cubo al centro
		const loader_2 = new THREE.TextureLoader();
		const texture_2 = loader.load('./components/coil_texture_fermi.png');
		texture_2.wrapS = texture_2.wrapT = THREE.RepeatWrapping;
		texture_2.repeat.set(20, 20);
		const textureTop_2 = texture.clone();
		const textureSide_2 = texture.clone();
		const dmaterial_2 = new THREE.MeshLambertMaterial({map: texture_2});
		const geometry_2 = new THREE.BoxGeometry(390, 390, 390);
		const dmesh_5 = new THREE.Mesh(geometry_2, dmaterial_2);
		dmesh_5.position.set(0, 0, 0);		
		CorrectorMaster.add(dmesh_5);
		
		//spessore interno plastica bianca
		const redmaterial_6 = new THREE.MeshLambertMaterial({color: 0xeD2D2D2, side:THREE.DoubleSide});
		const geometry_6 = new THREE.CylinderGeometry(280 /*radiusTop*/, 280 /*radiusBottom*/, 90 /*height*/, 4 /*radialSegments*/, 2 /*heightSegments*/, true /*openEnded*/,0 /*thetaStart*/, Math.PI * 2 /*thetaLength*/);
		const dmesh_6 = new THREE.Mesh(geometry_6, redmaterial_6);
		dmesh_6.position.set(0, 0, 0);
		dmesh_6.rotateX(Math.PI * 1);
		dmesh_6.rotateY(Math.PI * 1.25);
		dmesh_6.rotateZ(Math.PI * 1);	
		CorrectorMaster.add(dmesh_6); 
				
		CorrectorMaster.position.set(0, 0, 0);
		CorrectorContiner.add(CorrectorMaster);
		CorrectorContiner.rotateY(Math.PI * 1);
		CorrectorContiner.scale.setX(0.25);
		CorrectorContiner.scale.setY(0.125);
		CorrectorContiner.scale.setZ(0.25);
		
		return CorrectorContiner;
	}


	// BPM (beam position monitor)
	export function bpm(param) {
		const width=300, height=300, depth=50, transverse=100;
		const bpmObject = new THREE.Object3D();
		const bpmmaterial = new THREE.MeshLambertMaterial({color: 0x8000ff});
		const bpmgeometryh = new THREE.BoxGeometry(width, transverse, depth);
		const bpmmeshh = new THREE.Mesh(bpmgeometryh, bpmmaterial);
		bpmObject.add(bpmmeshh);
		const bpmgeometryv = new THREE.BoxGeometry(transverse, height, depth);
		const bpmmeshv = new THREE.Mesh(bpmgeometryv, bpmmaterial);
		bpmObject.add(bpmmeshv);
		return bpmObject;
	}


	// Quadrupole 
	export function quadrupolefermi(param) {
		const length=200;
		const quadrupoleMaster = new THREE.Object3D();
		const dmaterial = new THREE.MeshLambertMaterial({color: 0xe05040});
		const d1geometry = new THREE.BoxGeometry(550, 500, length);
		const d1mesh = new THREE.Mesh(d1geometry, dmaterial);
		quadrupoleMaster.add(d1mesh);				
		return quadrupoleMaster;
	}

	// PLC
	export function plc(width=500, height=300, depth=600) {
		const plcObject = new THREE.Object3D();
		const cardsObject = new THREE.Object3D();
		const mirrorObject = new THREE.Object3D();
		
	
		const greenmaterial = new THREE.MeshLambertMaterial({color: 0x00ff11});
		const greenDarkmaterial = new THREE.MeshLambertMaterial({color: 0x0b5e11});
		const graymaterial = new THREE.MeshLambertMaterial({color: 0x575757});
		const graymaterial2 = new THREE.MeshLambertMaterial({color: 0x7d7d7d});
		const silvermaterial = new THREE.MeshLambertMaterial({color: 0xa6a6a6});
		const blackmaterial = new THREE.MeshLambertMaterial({color: 0x000000});

		
		// base
		const basegeometry = new THREE.BoxGeometry(500, 300, 600);
		const basegeometrymesh = new THREE.Mesh(basegeometry, silvermaterial);
		basegeometrymesh.position.set( 0, 0 ,0);
		plcObject.add(basegeometrymesh);	
		
		// card
		const cardgeometry = new THREE.BoxGeometry(502, 270, 250);
		const cardgeometrymesh = new THREE.Mesh(cardgeometry, blackmaterial);
		cardgeometrymesh.position.set( 0, 0 , -100);
		cardsObject.add(cardgeometrymesh);
		
		//led1
		const led1green = new THREE.BoxGeometry(504, 20, 20);
		const led1greenmesh = new THREE.Mesh(led1green, greenmaterial);
		led1greenmesh.position.set( 0, 120 , -200);
		cardsObject.add(led1greenmesh);		
		//led2
		const led2green = new THREE.BoxGeometry(504, 20, 20);
		const led2greenmesh = new THREE.Mesh(led2green, greenmaterial);
		led2greenmesh.position.set( 0, 90 , -200);
		cardsObject.add(led2greenmesh);
		//led3
		const led3green = new THREE.BoxGeometry(504, 20, 20);
		const led3greenmesh = new THREE.Mesh(led3green, greenmaterial);
		led3greenmesh.position.set( 0, 60 , -200);
		cardsObject.add(led3greenmesh);
		//led4
		const led4green = new THREE.BoxGeometry(504, 20, 20);
		const led4greenmesh = new THREE.Mesh(led4green, greenmaterial);
		led4greenmesh.position.set( 0, 30 , -200);
		cardsObject.add(led4greenmesh);
		//led5
		const led5green = new THREE.BoxGeometry(504, 20, 20);
		const led5greenmesh = new THREE.Mesh(led5green, greenDarkmaterial);
		led5greenmesh.position.set( 0, 0 , -200);
		cardsObject.add(led5greenmesh);			
		//led6
		const led6green = new THREE.BoxGeometry(504, 20, 20);
		const led6greenmesh = new THREE.Mesh(led6green, greenDarkmaterial);
		led6greenmesh.position.set( 0, -30 , -200);
		cardsObject.add(led6greenmesh);
		//led7
		const led7green = new THREE.BoxGeometry(504, 20, 20);
		const led7greenmesh = new THREE.Mesh(led7green, greenDarkmaterial);
		led7greenmesh.position.set( 0, -60 , -200);
		cardsObject.add(led7greenmesh);		
		//led8
		const led8green = new THREE.BoxGeometry(504, 20, 20);
		const led8greenmesh = new THREE.Mesh(led8green, greenDarkmaterial);
		led8greenmesh.position.set( 0, -90 , -200);
		cardsObject.add(led8greenmesh);
		//led9
		const led9green = new THREE.BoxGeometry(504, 20, 20);
		const led9greenmesh = new THREE.Mesh(led9green, greenDarkmaterial);
		led9greenmesh.position.set( 0, -120 , -200);
		cardsObject.add(led9greenmesh);		
		

		
		// baseScreen
		const baseScreengeometry = new THREE.BoxGeometry(502, 270, 200);
		const baseScreengeometrymesh = new THREE.Mesh(baseScreengeometry, blackmaterial);
		baseScreengeometrymesh.position.set( 0, 0 , 120);
		plcObject.add(baseScreengeometrymesh);	
		
		// 1livel
		const livel1geometry = new THREE.BoxGeometry(550, 150, 150);
		const livel1geometrymesh = new THREE.Mesh(livel1geometry, graymaterial);
		livel1geometrymesh.position.set( 0, 0 , 120);
		plcObject.add(livel1geometrymesh);
		
		
		
		plcObject.add(cardsObject);
		
	
		
		return plcObject;
	}


	// Bending Dipole
	export function dipolefermi(length=500) {
		const dipoleContainer = new THREE.Object3D();
		const dipoleMaster = new THREE.Object3D();

		//texture
		const loader = new THREE.TextureLoader();
		const texture = loader.load('./components/dipole.png');
		const textureTop = texture.clone();
		const textureSide = texture.clone();
		textureTop.center.set(0.5, 0.5);
		textureTop.rotation = THREE.MathUtils.degToRad(90);
		textureSide.offset.set(0, 0.8);
		const dmaterial = new THREE.MeshLambertMaterial({map: texture});
		const face = new THREE.MeshBasicMaterial({map: texture});
		const faceTop = new THREE.MeshBasicMaterial({map: textureTop});
		const faceSide = new THREE.MeshBasicMaterial({map: textureSide});
		const materials = [face,face,faceTop,faceSide,faceSide,faceSide];
		const d1geometry = new THREE.BoxGeometry(550, 400, length);
		const d1mesh = new THREE.Mesh(d1geometry, materials);
		d1mesh.position.set(-100, 100, 0);
		dipoleMaster.add(d1mesh);	

		//Coil
		const dipoleCoil = new THREE.Object3D();
		const coilmaterial = new THREE.MeshLambertMaterial({color: 0xc08000});
		const d4geometry = new THREE.BoxGeometry(100, 100, length);
		const d4mesh = new THREE.Mesh(d4geometry, coilmaterial);
		d4mesh.position.set(-200, 0, 0);
		dipoleCoil.add(d4mesh);
		const d2geometry = new THREE.CylinderGeometry(150 /*radiusTop*/, 150 /*radiusBottom*/, 100 /*height*/, 20 /*radialSegments*/, 2 /*heightSegments*/, false /*openEnded*/,Math.PI * 1.5 /*thetaStart*/, Math.PI * 1 /*thetaLength*/);
		const d2mesh = new THREE.Mesh(d2geometry, coilmaterial);
		d2mesh.position.set(-100, 0, length/2);
		dipoleCoil.add(d2mesh);
		const d3geometry = new THREE.CylinderGeometry(150 /*radiusTop*/, 150 /*radiusBottom*/, 100 /*height*/, 20 /*radialSegments*/, 2 /*heightSegments*/, false /*openEnded*/,Math.PI * 0.5 /*thetaStart*/, Math.PI * 1 /*thetaLength*/);
		const d3mesh = new THREE.Mesh(d3geometry, coilmaterial);
		d3mesh.position.set(-100, 0, -length/2);
		dipoleCoil.add(d3mesh);
		dipoleCoil.position.set(0, 0, 0);
		dipoleMaster.add(dipoleCoil);
		const dipoleCoil2 = dipoleCoil.clone();
		dipoleCoil2.position.set(0, 200, 0);
		dipoleMaster.add(dipoleCoil2);

		dipoleMaster.position.set(200, 0, 0);
		dipoleContainer.add(dipoleMaster);

		return dipoleContainer;
	}
	// Current Monitor	
	export function cm(param) {
		const cmContiner = new THREE.Object3D();
		const cmObject = new THREE.Object3D();
		
		//cylinder mid
		const cylgeometry = new THREE.CylinderGeometry(115, 115, 30, 20);
		const cylmaterial = new THREE.MeshLambertMaterial({color: 0x00d0ff});
		const cylmesh = new THREE.Mesh(cylgeometry, cylmaterial);
		cylmesh.rotateX(Math.PI * 1);
		cylmesh.rotateY(Math.PI * 1.0);
		cylmesh.rotateZ(Math.PI * 1.5);
		cylmesh.position.set(0, 0 , 0);			
		cmObject.add(cylmesh);			
		
		//cylinder center
		const cyl2geometry = new THREE.CylinderGeometry(75, 75, 31, 20);
		const cyl2material = new THREE.MeshLambertMaterial({color: 0x2d2b70});
		const cyl2mesh = new THREE.Mesh(cyl2geometry, cyl2material);
		cyl2mesh.rotateX(Math.PI * 1);
		cyl2mesh.rotateY(Math.PI * 1.0);
		cyl2mesh.rotateZ(Math.PI * 1.5);
		cyl2mesh.position.set(0, 0 , 0);			
		cmObject.add(cyl2mesh);			
		
			
		cmObject.scale.setX(1);
		cmObject.scale.setY(1);
		cmObject.scale.setZ(1);
		cmObject.position.set(0, 0, 0);
		cmContiner.add(cmObject);
		cmContiner.rotateY(Math.PI * -0.5);		
		
		
		return cmContiner;
	}
	// undulator
	export function undulator(param) {
		const length=1000;
		const undulatorMaster = new THREE.Object3D();
		const chamberMaterial = new THREE.MeshLambertMaterial({color: 0xc0c0c0});
		const loader = new THREE.TextureLoader();
		const texture = loader.load('./components/undulator.png');
		const textureTop = texture.clone();
		const textureSide = texture.clone();
		textureTop.wrapS = textureTop.wrapT = THREE.RepeatWrapping;
		textureTop.repeat.set(30, 1);
		textureSide.offset.set(0.95, 0.95);
		const face = new THREE.MeshBasicMaterial({map: texture});
		const faceTop = new THREE.MeshBasicMaterial({map: textureTop});
		const faceSide = new THREE.MeshBasicMaterial({map: textureSide});
		const materials = [faceTop,faceTop,chamberMaterial,chamberMaterial,chamberMaterial,chamberMaterial];
		const ugeometry = new THREE.BoxGeometry(400, 400, length);
		const umesh = new THREE.Mesh(ugeometry, materials);
		undulatorMaster.add(umesh);				
		const qedges = new THREE.EdgesGeometry(ugeometry);
		const lineMaterial = new THREE.LineBasicMaterial({color: 0x000000});
		lineMaterial.linewidth = 4;
		const qline = new THREE.LineSegments(qedges, lineMaterial);
		undulatorMaster.add(qline);
		return undulatorMaster;
	}

	// Beam Loss Monitor
	export function blm(length=100, dcolor='white', width=100) {
		const cMaster = new THREE.Object3D();
		const d1geometry = new THREE.BoxGeometry(length, width, width);
		const material = new THREE.MeshLambertMaterial({color: dcolor});
		const d1mesh = new THREE.Mesh(d1geometry, material);
		d1mesh.position.set(-length/2, 0, 0);
		cMaster.add(d1mesh);
		return cMaster;
	}
	function blmColor(val) {
		if (document.location.search.indexOf('demo')>-1) {
			if (val < 0) return 'white';
			else if (val < 1) return 'yellow';
			else if (val < 2) return 'orange';
			else if (val < 3) return 'red';
			else return 'violet';
		}
		if (val < 20) return 'white';
		else if (val < 50) return 'yellow';
		else if (val < 100) return 'orange';
		else if (val < 200) return 'red';
		else return 'violet';
	}
	export function blmUpdate(c, val, direction, width=100, histogramFactor=50) {
		if (typeof val !== 'number') val = 0; else val = Math.abs(val);
		const blm = c.children[0];
		blm.material.dispose();
		blm.material = new THREE.MeshLambertMaterial({color: blmColor(val)});
		blm.geometry.dispose();
		blm.geometry = new THREE.BoxGeometry(width+val*histogramFactor, width, width);
		blm.position.set(direction*(width+val*histogramFactor)/2, 0, 0);
		blm.geometry.computeVertexNormals();
		blm.geometry.normalsNeedUpdate = true;
		blm.geometry.verticesNeedUpdate = true;
		blm.geometry.dynamic = true;
	}
	// bst
	export function bstfast(param) {
		const bstObject = new THREE.Object3D();
		const bstContiner = new THREE.Object3D();
		
		const materialGrey = new THREE.MeshLambertMaterial({color: 0xc0c0c0});
		
		
		const d1geometry = new THREE.CylinderGeometry(25, 25, 200, 25);
		const d1mesh = new THREE.Mesh(d1geometry, materialGrey);
		d1mesh.position.set(0, 190, 0);
		bstObject.add(d1mesh);				
		bstObject.rotateX(Math.PI * 1);
			
		// circ base
		const d2geometry = new THREE.CylinderGeometry(50, 50, 80, 15);
		const d2mesh = new THREE.Mesh(d2geometry, materialGrey);
		d2mesh.position.set(0, 290, 0);
		d2mesh.rotateX(Math.PI * 1);
		d2mesh.rotateY(Math.PI * 1);
		d2mesh.rotateZ(Math.PI * 1.5);		
		bstObject.add(d2mesh);
		
		// z
		const d4geometry = new THREE.CylinderGeometry(40, 40, 120, 15);
		const d4mesh = new THREE.Mesh(d4geometry, materialGrey);
		d4mesh.rotateX(Math.PI * 1);
		d4mesh.rotateY(Math.PI * 1);
		d4mesh.rotateZ(Math.PI * 1);
		d4mesh.position.set(0, 120 , 0);			
		bstObject.add(d4mesh);		
		
		// cil Med
		const d6geometry = new THREE.CylinderGeometry(70, 70, 120, 15);
		const d6mesh = new THREE.Mesh(d6geometry, materialGrey);
		d6mesh.rotateX(Math.PI * 1);
		d6mesh.rotateY(Math.PI * 1);
		d6mesh.rotateZ(Math.PI * 1);
		d6mesh.position.set(0, 0 , 0);			
		bstObject.add(d6mesh);	
		
		// cil low
		const d7geometry = new THREE.CylinderGeometry(50, 50, 120, 15);
		const d7mesh = new THREE.Mesh(d7geometry, materialGrey);
		d7mesh.rotateX(Math.PI * 1);
		d7mesh.rotateY(Math.PI * 1);
		d7mesh.rotateZ(Math.PI * 1);
		d7mesh.position.set(0, -100 , 0);			
		bstObject.add(d7mesh);			
		
				
		bstObject.position.set(0, 280, 0);
		bstContiner.add(bstObject);
		bstContiner.rotateY(Math.PI * -0.5);
		return bstContiner;
	}
	export function bstUpdate(c, color) {
		const vlv = c.children[0].children;
		for (let i=0; i<vlv.length; i++) {
			if (vlv[i].colorable) {
				vlv[i].material.dispose();
				vlv[i].material = new THREE.MeshLambertMaterial({color: color});
			}
		}
	}
	// valve
	export function vlv(param) {
		const vlvContiner = new THREE.Object3D();
		const vlvObject = new THREE.Object3D();
		const blackboxmaterial = new THREE.MeshLambertMaterial({color: 0x636363});
		//cylinder
		const cylgeometry = new THREE.CylinderGeometry(25, 25, 100, 15);
		const cylmaterial = new THREE.MeshLambertMaterial({color: 0xc7c7c7});
		const cylmesh = new THREE.Mesh(cylgeometry, cylmaterial);
		cylmesh.rotateX(Math.PI * 1);
		cylmesh.rotateY(Math.PI * 1.0);
		cylmesh.rotateZ(Math.PI * 1.5);
		cylmesh.position.set(0, 0 , 0);			
		vlvObject.add(cylmesh);			
		
		// base1
		const vlvgeometry = new THREE.BoxGeometry(30, 160, 60 );
		const vlvmaterial = new THREE.MeshLambertMaterial({color: 0xc7c7c7});		
		const vlv1mesh = new THREE.Mesh(vlvgeometry, vlvmaterial);
		vlv1mesh.position.set(0, 50, 0);
		vlv1mesh.colorable = true;
		vlvObject.add(vlv1mesh);		
		
		// hat1
		const hatmaterial = new THREE.MeshLambertMaterial({color: 0xc7c7c7});
		const hatgeometry = new THREE.BoxGeometry(50, 20, 100 );
		const hatmesh = new THREE.Mesh(hatgeometry, hatmaterial);
		hatmesh.colorable = true;
		hatmesh.position.set(0, 120, 0);
		vlvObject.add(hatmesh);	
		
		
		//TRIANGLE1
		const trianglegeometry = new THREE.CylinderGeometry(18, 18, 32, 3);
		const trianglegeometrymesh = new THREE.Mesh(trianglegeometry, blackboxmaterial);
		trianglegeometrymesh.rotateX(Math.PI * 0);
		trianglegeometrymesh.rotateY(Math.PI * 0);
		trianglegeometrymesh.rotateZ(Math.PI * 0.5);		
		trianglegeometrymesh.position.set(0, 60 , -17);		
		vlvObject.add(trianglegeometrymesh);	
		
		//TRIANGLE2
		const trianglegeometry2 = new THREE.CylinderGeometry(18, 18, 32, 3);
		const triangle2geometrymesh = new THREE.Mesh(trianglegeometry2, blackboxmaterial);
		triangle2geometrymesh.rotateX(Math.PI * 0);
		triangle2geometrymesh.rotateY(Math.PI * 1);
		triangle2geometrymesh.rotateZ(Math.PI * 0.5);		
		triangle2geometrymesh.position.set(0, 60 ,17);		
		vlvObject.add(triangle2geometrymesh);		
		
		vlvObject.position.set(0, 0, 0);
		vlvObject.rotateY(Math.PI * -0.5);
		vlvContiner.add(vlvObject);

		return vlvContiner;
	}
	export function vlvUpdate(c, color) {
		const vlv = c.children[0].children;
		for (let i=0; i<vlv.length; i++) {
			if (vlv[i].colorable) {
				vlv[i].material.dispose();
				vlv[i].material = new THREE.MeshLambertMaterial({color: color});
			}
		}
	}