Draw grid on top of model on each face

Could you please assist?

How do I get the size of each face?
And where do I mention the face to where my grid of rectangles should go?

You can get the size of a container, using THREE.Box3() and its methos .setFromObject(), something like this:

var container = _some_object_;

var size = new THREE.Vector3();
var box = new THREE.Box3().setFromObject(container); // AABB
box.getSize(size); // here you'll have dimensions of your container in the 'size' variable
1 Like

Thanks. I have tested your piece of code and I am able to get the size of the model.

Could you please also assist how to draw grid of rectangles on all sides of the object?

Anyone can shed some light on how to create a rectangle (by code) over the model object on the required area of the given side?

Look at this stuff.

http://discourse.threejs.hofk.de/3DGridOfLines/3DGridOfLines.html
http://discourse.threejs.hofk.de/GridBoxGeometry/GridBoxGeometry.html
The links to discourse.threejs. org are above in the source code

Grid Collection

But I’m not sure it’ll help you.

I just copied the code from GridoxGeometry and almost done. Sure it helped me. Many Thanks.

Github code repository is https://github.com/fayeeg/ThreeJSContainer
Note: This is Angular Project.

The problem is that I am unable to position the grid matching the position of the container object.

image

The grid can be positioned arbitrarily.

	// grid3.position.set( 1, 2, 1 )

20181129-1802-18712

I have simplified the example and moved the grid downwards.

grid3.position.y = -1.5; // raise or lower the grid !

20181129-1801-23968

The simplified version is added to the example collection. (under the original version ) http://discourse.threejs.hofk.de/

<!DOCTYPE html>
<!-- Simplified from
	https://discourse.threejs.org/t/gridboxgeometry/1420
	https://jsfiddle.net/prisoner849/8hqy99jj/ 
-->
<head>
	<meta charset="utf-8" />   
	<title> GridBox </title>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">    
</head>
<body> </body>
<script src="../js/three.min.88.js"></script>
<script src="../js/OrbitControls.js"></script>
<script>

//  Simplified from @ author prisoner849

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-3, 2, 1).setLength(20);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x808080);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.DirectionalLight(0xffffff, .5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, .5));

var boxGeometry = new THREE.BoxBufferGeometry(10, 3, 3, 10, 5, 4);

var gridGeometry = GridBoxGeometry(boxGeometry, false);

var grid = new THREE.LineSegments(gridGeometry, new THREE.LineBasicMaterial({ color: "aqua"}));

// ............ new:
	var boxGeometry3 = new THREE.BoxBufferGeometry(10, 3, 3, 10, 5, 4);
	var box3 = new THREE.Mesh(boxGeometry3, new THREE.MeshStandardMaterial({ color: 0xff0000 })); 
	box3.position.z = 3;
	scene.add(box3);
	var gridGeometry3 = GridBoxGeometry(boxGeometry3, true);
	var grid3 = new THREE.LineSegments(gridGeometry3, grid.material.clone());
	grid3.position.z = 3;
	
	//grid3.position.set( 1, 2, 1 )

	grid3.position.y = -1.5;  // raise or lower the grid !
	
	scene.add(grid3);
// ...............

render();

function GridBoxGeometry(geometry, independent) {

	if (!(geometry instanceof THREE.BoxBufferGeometry)) {
	console.log("GridBoxGeometry: the parameter 'geometry' has to be of the type THREE.BoxBufferGeometry");
	return geometry;
	}
	independent = independent !== undefined ? independent : false;
	
	let newGeometry = new THREE.BoxBufferGeometry();
	let position = geometry.attributes.position;
	newGeometry.attributes.position = independent === false ? position : position.clone();
	
	let segmentsX = geometry.parameters.widthSegments || 1;
	let segmentsY = geometry.parameters.heightSegments || 1;
	let segmentsZ = geometry.parameters.depthSegments || 1;
	
	let startIndex = 0;
	let indexSide1 = indexSide(segmentsZ, segmentsY, startIndex);
	startIndex += (segmentsZ + 1) * (segmentsY + 1);
	let indexSide2 = indexSide(segmentsZ, segmentsY, startIndex);
	startIndex += (segmentsZ + 1) * (segmentsY + 1);
	let indexSide3 = indexSide(segmentsX, segmentsZ, startIndex);
	startIndex += (segmentsX + 1) * (segmentsZ + 1);
	let indexSide4 = indexSide(segmentsX, segmentsZ, startIndex);
	startIndex += (segmentsX + 1) * (segmentsZ + 1);
	let indexSide5 = indexSide(segmentsX, segmentsY, startIndex);
	startIndex += (segmentsX + 1) * (segmentsY + 1);
	let indexSide6 = indexSide(segmentsX, segmentsY, startIndex);
	
	let fullIndices = [];
	fullIndices = fullIndices.concat(indexSide1);
	fullIndices = fullIndices.concat(indexSide2);
	fullIndices = fullIndices.concat(indexSide3);
	fullIndices = fullIndices.concat(indexSide4);
	fullIndices = fullIndices.concat(indexSide5);
	fullIndices = fullIndices.concat(indexSide6);
	
	newGeometry.setIndex(fullIndices);
	
	function indexSide(x, y, shift) {
		let indices = [];
		for (let i = 0; i < y + 1; i++) {
			let index11 = 0;
			let index12 = 0;
			for (let j = 0; j < x; j++) {
			index11 = (x + 1) * i + j;
			index12 = index11 + 1;
			let index21 = index11;
			let index22 = index11 + (x + 1);
			indices.push(shift + index11, shift + index12);
			if (index22 < ((x + 1) * (y + 1) - 1)) {
				indices.push(shift + index21, shift + index22);
			}
			}
			if ((index12 + x + 1) <= ((x + 1) * (y + 1) - 1)) {
			indices.push(shift + index12, shift + index12 + x + 1);
			}
		}
		return indices;
	}
	return newGeometry;
};

function render( ) {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
</script> 
</html>

Thanks for the hint. I have got my results with the below changes in my code.

this.container_object = object;

    const size = new THREE.Vector3();
    const box = new THREE.Box3().setFromObject(object); // AABB
    box.getSize(size);

    const geometry = new THREE.BoxBufferGeometry(size.x + 10, size.y + 10, size.z + 10, 5, 5, 5);

    const gridGeometry = this.GridBoxGeometry(geometry, true);
    const grid = new THREE.LineSegments(gridGeometry, new THREE.LineBasicMaterial({
      color: 'aqua'
    }));


    grid.position.y = 130;
    group.add(grid);

Thanks don’t go to me, but to @prisoner849 for this helpful gridbox (and many other great solutions on discourse: Collection of examples from discourse.threejs.org).

I only assisted a little.

1 Like

Thank you @prisoner849 for your amazing contribution to ThreeJS.

@hofk your little assistance is a big step for people like me.

1 Like

@Mohamed_Fayeeg
You’re welcome :beers:
I like it when people think and find solutions themselves, having just a starting idea :slight_smile:

1 Like

I am sorry I am not one of them. I am just utilizing ThreeJS for just a tiny functionality within a very large enterprise system - meaning to say I am neither a computer graphics guy nor a math expert. I regret ignoring my geometry lessons during my school.

I spent 2 days to fill a cell with a color by a logic like this ( pseudo code)

highlight(side, row, col, ‘aqua’)

side is - LEFT, RIGHT, TOP, BOTTOM, FRONT, BACK

eg. highlight(RIGHT, 2, 3, ‘aqua’);

Many examples I have gone through but I am missing the math.

If you can guide me with a methodology/pseudo code/logic then I can attempt to follow.

You probably mean the cells highlighted in yellow in your first picture?

Should only these cells be visible?

Yes each box within the grid is a cell.
No - I can pass the index number as the parameter to select the specific cell on a particular face of the grid.

If you have the coordinates of the cells, you can easily place a frame or a transparent rectangle there.

20181202-1146-18130

The code for rectangle and frame is something like this:

<!DOCTYPE html>
<head>
	<title> cell </title>
	<meta charset="utf-8">
</head>
<body>
	<div id="container"></div>			
</body>
<script src="../js/three.min.98.js"></script>
<script src="../js/OrbitControls.js"></script>
<script src="../js/THREEx.WindowResize.js"></script>

<script>
'use strict'
var container, camera, scene, renderer, geometryMesh, geometryLines, materialMesh, materialLines, mesh, lines;

init();
animate();
//--------

function init() {

	container = document.getElementById( 'container' );

	camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.1, 20 );
  	camera.position.y = 2;
	camera.position.z = 10;

	scene = new THREE.Scene();

	renderer = new THREE.WebGLRenderer( { antialias: false } );
	
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.setClearColor( 0x777777, 1 );	

	container.appendChild( renderer.domElement );
	var controls = new THREE.OrbitControls( camera, renderer.domElement );
	THREEx.WindowResize( renderer, camera );
	
	materialMesh = new THREE.MeshBasicMaterial( { color: 0xffff00, transparent: true, opacity: 0.05, side: THREE.DoubleSide, } );
	materialLines = new THREE.LineBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide, } );

	geometryMesh = new THREE.BufferGeometry();
	
	var verticesMesh = new Float32Array( [
	// first triangle
	   -1, -1, 0,
	    1, -1, 0,
	    1,  1, 0,
	 // second triangle
	    1,  1, 0,
	   -1,  1, 0,
	   -1, -1, 0
		
	] );
	
	geometryMesh.addAttribute( 'position', new THREE.BufferAttribute( verticesMesh, 3 ) );
	
	geometryLines = new THREE.BufferGeometry();
	
	var verticesLines = new Float32Array( [
	
		// four lines
	   -1, -1, 0,
	    1, -1, 0,
		
	    1, -1, 0,
	    1,  1, 0,
		
	    1,  1, 0,
	    -1, 1, 0,
			
	   -1,  1, 0,
	   -1, -1, 0,
		
	] );
		
	geometryLines.addAttribute( 'position', new THREE.BufferAttribute( verticesLines, 3 ) );
	
	mesh = new THREE.Mesh( geometryMesh, materialMesh );
	lines =  new THREE.LineSegments( geometryLines, materialLines )
	
	scene.add( mesh );
	scene.add( lines );
}

function animate() {

	requestAnimationFrame( animate );
	renderer.render( scene, camera );

}

</script>
</html>

You can also use a real frame.


see also http://discourse.threejs.hofk.de/ProfiledContourGeometry/ProfiledContourGeometry.html

This is a good start for me. I have tested the above given code.The frame is appearing on only side.
Could you please advise how to show the frame on the required side of the gridboxgeometry? ( have six sides )

You have a 3D design:

var verticesLines = new Float32Array( [
    	
    // four lines
       //   x  y   z
    	   -1, -1, 0,
    	    1, -1, 0,
    		
    	    1, -1, 0,
    	    1,  1, 0,
    		
    	    1,  1, 0,
    	    -1, 1, 0,
    			
    	   -1,  1, 0,
    	   -1, -1, 0,
    		
    	] );

Look what happens:

  1. Take a fix number for z ( e.g. -3 then +3)
  2. Add a fix number to all numbers x ( then y)
  3. Swap the complete columns.

(Possibly you first change the column x with z - and look)

try it

On request.
Another basic help.20181210-0916-11694

Based on the instructions above and another simple way.


<!DOCTYPE html>

<head>
  <title> GridBoxCells </title>
  <meta charset="utf-8" />
  <style>
	body {
	overflow: hidden;
	margin: 0;
	}
  </style>
</head>

<body>
</body>

<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script>

'use strict';

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(-0.5, 0.75, 1).setLength(20);
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xb0b0b0);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var axesHelper = new THREE.AxesHelper( 12 );
scene.add( axesHelper );

var light = new THREE.DirectionalLight(0xffffff, .5);
light.position.setScalar(10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, .5));

var boxGeometry = new THREE.BoxBufferGeometry(10, 3, 3, 10, 2, 2);  // 10, 3, 3 box dimensions
boxGeometry.attributes.positionStart = boxGeometry.attributes.position.clone();
var gridGeometry = GridBoxGeometry(boxGeometry, false);

var position = boxGeometry.attributes.position;
var positionStart = boxGeometry.attributes.positionStart;

var box0 = new THREE.Mesh(boxGeometry, new THREE.MeshStandardMaterial({ color: 0x999999, transparent: true, opacity: 0.8 }));
var x0 = 5; 
var y0 = 3;
var z0 = 4;
box0.position.set( x0, y0, z0 ); // center of box
scene.add( box0 );
var grid0 = new THREE.LineSegments(gridGeometry, new THREE.LineBasicMaterial({ color: "aqua" }));
grid0.position.set( x0, y0, z0 );
scene.add( grid0 );

var	materialLines  = new THREE.LineBasicMaterial( { color: 0xff00ff, side: THREE.DoubleSide } );
var	materialLines0 = new THREE.LineBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
var	materialLines1 = new THREE.LineBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide } );

var geometryLines0 = new THREE.BufferGeometry();
var verticesLines0 = new Float32Array( [
// to boxGeometry from THREE.BoxBufferGeometry(  10, 3, 3,   10, 2, 2 ); - a container 10, 3, 3  - I think in meters 

// one side of the cell has a length of 1, the other 3 / 2  = 1.5 -->  0.5  , 0.75
		// four lines
	//	     x             y               z 
	   x0+2.5 + (-0.5), y0+0.75 -0.75, z0 + 1.5 + 0.04, // z: +1.5 --> half of depth
	   x0+2.5 + 0.5   , y0+0.75 -0.75, z0 + 1.5 + 0.04,
						  
	   x0+2.5 + 0.5   , y0+0.75 -0.75, z0 + 1.5 + 0.04,
	   x0+2.5 + 0.5   , y0+0.75 +0.75, z0 + 1.5 + 0.04,
						  
	   x0+2.5 + 0.5,    y0+0.75 +0.75, z0 + 1.5 + 0.04,
	   x0+2.5 + (-0.5), y0+0.75 +0.75, z0 + 1.5 + 0.04,
						  
	   x0+2.5 + (-0.5), y0+0.75 +0.75, z0 + 1.5 + 0.04,
	   x0+2.5 + (-0.5), y0+0.75 -0.75, z0 + 1.5 + 0.04,
		
	] );
		
	geometryLines0.addAttribute( 'position', new THREE.BufferAttribute( verticesLines0, 3 ) );

	var lines0 =  new THREE.LineSegments( geometryLines0, materialLines0 )
	scene.add( lines0 );

//......................... another simple solution ..........................................................

var box1 = box0.clone();

box1.position.set( -5, 3, -5 );
scene.add( box1 );
var grid1 = grid0.clone();
grid1.position.set( -5, 3, -5 );
scene.add( grid1 );

var geometryLines1 = new THREE.BufferGeometry();

// original square side length is 2 (-1 to +1) --> *0.5 when scale to get 1
// (you could also work with -0.5, 0.5 to get side length 1 at the beginning
var verticesLines1 = new Float32Array( [
	
		// four lines
        // x   y  z
	   -1, -1, 0,
	    1, -1, 0,
		
	    1, -1, 0,
	    1,  1, 0,
		
	    1,  1, 0,
	    -1, 1, 0,
			
	   -1,  1, 0,
	   -1, -1, 0,
		
	] );
		
	geometryLines1.addAttribute( 'position', new THREE.BufferAttribute( verticesLines1, 3 ) );

	var lines =  new THREE.LineSegments( geometryLines1, materialLines )
	scene.add( lines ); //(original square in the origin of the scene) 
	
	var lines1 =  new THREE.LineSegments( geometryLines1, materialLines1 )
	box1.add( lines1 ); //(original square in the origin of the box)      // or take grid1.add( lines1 );
	
	var linesNx = lines1.clone( );
	// here you have a square with side length 1.5 --> 0.75 * 2 (original square) 
	linesNx.scale.set( 0.75, 1.5 * 0.5, 1.5  );
	linesNx.position.set( -5 - 0.04,  1.5 / 2, 1.5 / 2 );
	linesNx.rotation.set( 0, -Math.PI/ 2, 0);
  	box1.add( linesNx );	
	
	var linesPy = lines1.clone( );
	// one side of the cell has a length of 1, the other 3 / 2  = 1.5
	linesPy.scale.set( 1 * 0.5, 1.5 * 0.5, 1.5  );
	linesPy.position.set( -1.5, 1.5 + 0.04, 1.5 / 2  ); // z = ( middle of cell 0.5 ) * 3 / 2 
	linesPy.rotation.set( Math.PI/ 2, 0, 0);
  	box1.add( linesPy );
	
	var linesPz = lines1.clone( );		
	// one side of the cell has a length of 1, the other 3 / 2  = 1.5
	linesPz.scale.set( 1 * 0.5, 1.5 * 0.5, 1.5  );
	linesPz.position.set( 3.5,  1.5 / 2, 1.5 + 0.04 );
	box1.add( linesPz );
		
render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}


  function GridBoxGeometry(geometry, independent) {
   // @author prisoner849
    if (!(geometry instanceof THREE.BoxBufferGeometry)) {
      console.log("GridBoxGeometry: the parameter 'geometry' has to be of the type THREE.BoxBufferGeometry");
      return geometry;
    }
    independent = independent !== undefined ? independent : false;

    let newGeometry = new THREE.BoxBufferGeometry();
    let position = geometry.attributes.position;
    newGeometry.attributes.position = independent === false ? position : position.clone();

    let segmentsX = geometry.parameters.widthSegments || 1;
    let segmentsY = geometry.parameters.heightSegments || 1;
    let segmentsZ = geometry.parameters.depthSegments || 1;

    let startIndex = 0;
    let indexSide1 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide2 = indexSide(segmentsZ, segmentsY, startIndex);
    startIndex += (segmentsZ + 1) * (segmentsY + 1);
    let indexSide3 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide4 = indexSide(segmentsX, segmentsZ, startIndex);
    startIndex += (segmentsX + 1) * (segmentsZ + 1);
    let indexSide5 = indexSide(segmentsX, segmentsY, startIndex);
    startIndex += (segmentsX + 1) * (segmentsY + 1);
    let indexSide6 = indexSide(segmentsX, segmentsY, startIndex);

    let fullIndices = [];
    fullIndices = fullIndices.concat(indexSide1);
    fullIndices = fullIndices.concat(indexSide2);
    fullIndices = fullIndices.concat(indexSide3);
    fullIndices = fullIndices.concat(indexSide4);
    fullIndices = fullIndices.concat(indexSide5);
    fullIndices = fullIndices.concat(indexSide6);

    newGeometry.setIndex(fullIndices);

    function indexSide(x, y, shift) {
      let indices = [];
      for (let i = 0; i < y + 1; i++) {
        let index11 = 0;
        let index12 = 0;
        for (let j = 0; j < x; j++) {
          index11 = (x + 1) * i + j;
          index12 = index11 + 1;
          let index21 = index11;
          let index22 = index11 + (x + 1);
          indices.push(shift + index11, shift + index12);
          if (index22 < ((x + 1) * (y + 1) - 1)) {
            indices.push(shift + index21, shift + index22);
          }
        }
        if ((index12 + x + 1) <= ((x + 1) * (y + 1) - 1)) {
          indices.push(shift + index12, shift + index12 + x + 1);
        }
      }
      return indices;
    }
    return newGeometry;
  };

</script>

</html>

I appreciate your help. I will try at my end to implement your methods.

Good luck. :slightly_smiling_face: