Source: utilities/drawDimensionsLineBoundingBox.js

import { Project } from '../project.js'
//import { View } from '../view/view.js'

import {
    Vector3,
	Group,
	PointsMaterial,
	Points,
	BufferGeometry,
	CanvasTexture,
	LineBasicMaterial,
	Line,
	Line3,
	Color,
	SRGBColorSpace

} from '../../node_modules/three/build/three.module.js';

import { LineMaterial } from '../../node_modules/three/examples/jsm/lines/LineMaterial.js';
import { Line2 } from '../../node_modules/three/examples/jsm/lines/Line2.js';

//Not in 155! need newer version
//import { Line2NodeMaterial, LineDashedNodeMaterial, LineBasicNodeMaterial, color } from '../../node_modules/three/examples/jsm/nodes/Nodes.js';

import { LineGeometry } from '../../node_modules/three/examples/jsm/lines/LineGeometry.js';

import { Wireframe } from '../../node_modules/three/examples/jsm/lines/Wireframe.js';
import { WireframeGeometry2 } from '../../node_modules/three/examples/jsm/lines/WireframeGeometry2.js';




import { CSS2DObject } from '../../node_modules/three/examples/jsm/renderers/CSS2DRenderer.js';
import { CSS3DObject } from '../../node_modules/three/examples/jsm/renderers/CSS3DRenderer.js';

import { Marker } from '../view/marker.js';


/**
 * @param {Array} points -- array with vectors
 * @param {Number} offset 
 * @param {String} side 
 */
  

//console.log( dimLayer )

function drawDimensionsLineBoundingBox( points, offset, side ){

	const dimLayer = Project.layerMap.dimLines

	//SET OFFSET
	switch(side){
		case "left": 
			var offsetVector = new Vector3( -offset, -0.01, 0 )
			break;
		case "back": 
			var offsetVector = new Vector3( 0, -0.01, -offset )
			break;
		case "right": 
			var offsetVector = new Vector3( offset, -0.01, 0 )
			break;
		case "front": 
			var offsetVector = new Vector3( 0, -0.01, offset )
			break;
		case "height": 
			var offsetVector = new Vector3( -offset, -0.01, -offset )
			break;
	}

	//set points from objects
	var geoPoints = []
	//geoPoints.push( points[0].start )

	for( var i=0; i< points.length; i++ ){
		geoPoints.push( points[i].start )
		geoPoints.push( points[i].end )
	}

	//console.log("geoPoints", geoPoints)


	var dimGroup = new Group();
	dimGroup.name = "dimLine"
	//dimGroup.layers.set( dimLayer )	//<- layers per groep werkt niet! Werkt alleen als je het direct op het object zet dat je wil uitzetten!


	var geometry = new BufferGeometry().setFromPoints( geoPoints );

	var size = 0.03;

	var canvas = document.createElement( 'canvas' );
		canvas.width = 128;
		canvas.height = 128;

	var context = canvas.getContext( '2d' );
		context.arc( 64, 64, 64, 0, 2 * Math.PI );
		context.fillStyle = "#000000";
		context.fill();

	var texture = new CanvasTexture( canvas );

	var pointMaterial = new PointsMaterial( { 
		size: size, 
		map: texture, 
		transparent: false, 
		alphaTest: 0.5 
	} );

	var dimPoints = new Points( geometry, pointMaterial ) ;

	const positions = [];
	geoPoints.forEach( point => positions.push( point.x, point.y, point.z ) );

	const testLine = createLine2(positions)
	//const testLine = createWireframeGeoLine(geometry)

	//dimGroup.add(testLine)

	//LINES
	var material = new LineBasicMaterial({   //LineMaterial({ // lineMaterial needs lineGeo see example engine_events in components
		color: 0x000000,
		linewidth: 1, 
	});
	var dimLine = new Line( geometry, material );
	

	dimLine.layers.set( dimLayer )	
	dimPoints.layers.set( dimLayer )

	dimGroup.add( dimLine );
	dimGroup.add( dimPoints );
	//dimGroup.visible = false;
	

	//MARKERS & POSITIONS

	const center = new Vector3();
	
	for( var i=0; i< points.length; i++ ){
		var line = new Line3( points[i].start, points[i].end )

		const lengthCm = Math.round( line.distance() * 100 )
		//console.log( "length in cm", lengthCm)
		const lengthInches = Math.round( ( line.distance() * 100 ) / 2.54 )
		//console.log( "length in inches", lengthInches)

		//CSS DIV
		var div = document.createElement( 'div' );
		div.className = 'label';
		div.textContent = `${lengthCm} cm` //` \u00A0\u00A0|\u00A0\u00A0 ${lengthInches}"` ; // hiernog de waarde van de lengte invullen
		div.style.marginTop = '-1em';

		//MARKERS
		var label = new CSS2DObject( div );
		label.name = "dimLabel"
		label.visible = false;
		label.position.copy(  line.getCenter( center) ) 

		//var markerPosition = line.getCenter( center)
		//const marker = new Marker({ position: markerPosition, HTMLElement:div, view: view});

		label.layers.set( dimLayer ) //<- werkt ook niet met layers!
		
		dimGroup.add( label )
		//dimGroup.add( marker )
		//configuration.add( dimGroup )
	
	}

	dimGroup.position.add( offsetVector ) // addthe dimensions to the 
	
	return dimGroup;

}

function createGLLine( geo ){
	const matLineBasic = new THREE.LineBasicMaterial( { vertexColors: true } );
	line = new Line( geo, matLineBasic );
	line.computeLineDistances();
	return line
}


//https://github.com/mrdoob/three.js/pull/16912


function createLine2(positions){

	const colors = [];
	const color = new Color();
	color.setHSL( 0.25, 1.0, 0.5, SRGBColorSpace );
	colors.push( color.r, color.g, color.b );

	const buffer = new Float32Array( positions )
	const geometry = new LineGeometry();
	geometry.setPositions(buffer)
	geometry.setColors( colors );

	const matLine = new LineMaterial( {

		color: 0xffffff,
		worldUnits: false,
		linewidth: 1, // in world units with size attenuation, pixels otherwise
		vertexColors: true,
		dashed: false,
		alphaToCoverage: true,

	} );
	
	const line = new Line2( geometry, matLine );
	line.computeLineDistances();
	line.scale.set( 1, 1, 1 );

	return line;

}


function createSegmentsLine(geo){
	const matLineBasic = new THREE.LineBasicMaterial( { color: 0x4080ff } );
	wireframe1 = new THREE.LineSegments( geo, matLineBasic );
	wireframe1.computeLineDistances();
}



function createWireframeGeoLine(geo){

	const geometry = new WireframeGeometry2(geo);

	const matLine = new LineMaterial( {

		color: 0x4080ff,
		linewidth: 5, // in pixels
		dashed: false

	});

	const wireframeLine = new Wireframe( geometry, matLine );

	return wireframeLine
}




function updateLabels( renderer, camera, objects  ) {


	for ( var i = 0; i < objects.length; i++){

		var labels = []

		//for each object check foro labels
		objects[i].traverse( ( child ) =>{
			if( child instanceof CSS2DObject ){
				labels.push( child )
			}
		})


		for ( var j = 0; j < labels.length; j++){
			const meshDistance = camera.position.distanceTo( objects[i].position );
			const labelDistance = camera.position.distanceTo( labels[j].position );
			let labelBehindObject = labelDistance > meshDistance;
			labels[j].element.style.opacity = labelBehindObject ? 0.25 : 1;
		}
	}

}

export{ drawDimensionsLineBoundingBox }