Draw grid on top of model on each face

I am a beginner in ThreeJS. I have spent quite a number of hours to figure out my requirements hence as a last venue I am here.

I am loading a 3D Shipping Container model using OBJLoader. I have added OrbitControls to rotate the camera.

My next task is to draw a grid on the required side of the model for the given number of cells and then highlight/shade particular cell with a given color. The grid has to be fit within the length & height of the object side.

Please do give me guidelines/steps on how to achieve the above.

Any code samples would be great. I have gone through almost all of the ThreeJS Samples but none suits my requirement.

Hi!
Any explanatory pictures of the desired result?
Also, it would be great to provide a live code example (jsfiddle, codepen etc.).

I am doing this ThreeJS project in Angular 7 hence not sure whether I can put it in CodePen or JSFiddle.
If required I can host this app in public URL.

Desired Result:

User will be supplying the coordinates of the affected area in the container and the same should be highlighted as demonstrated in this image. It is also possible to highlight half of the cell in a row.
If any side is not affected then the grid lines can be turned of on that side.

image

The below is what I have done so far. You can see all // commented lines. I genuinely attempted to achieve the above desired result.


import { Component, OnInit, ElementRef, ViewChild, HostListener, AfterViewInit } from '@angular/core';
import * as OrbitControls from 'three-orbitcontrols';
import * as THREE from 'three';
import { MTLLoader, OBJLoader } from 'three-obj-mtl-loader';
import * as TWEEN from '@tweenjs/tween.js';
import { Color } from 'three';
import { TouchSequence } from 'selenium-webdriver';

@Component({
  selector: 'app-myfirstscene',
  templateUrl: './myfirstscene.component.html',
  styleUrls: ['./myfirstscene.component.css']
})

export class MyfirstsceneComponent implements OnInit, AfterViewInit {
  private container: HTMLElement;
  @ViewChild('container') elementRef: ElementRef;

  private scene: THREE.Scene;
  private camera: THREE.PerspectiveCamera;
  private renderer: THREE.WebGLRenderer;
  public controls: OrbitControls;
  private mtlLoader: MTLLoader;
  private loader: OBJLoader;
  public objects = [];
  public objectMaterials = THREE.Material;
  public container_object: THREE.Object3D;

  DURATION = 100;
  DEFAULT_CAMERA_POSITION = 800;
  DEFAULT_CONTAINER_SIZE = 40;
  CONSTANT_DISTANCE = 250;
  MAX_DISTANCE = 1350;
  MIN_DISTANCE = 650;
  minWheel = 0;
  maxWheel = 70;
  SCALE_RATIO = {
    z: 0.949,
    x: {
      size20: 1.02,
      size40: 1.89,
    }
  };


  FACE_MASKS = {
    FRONT: 0x01,
    BACK: 0x02,
    LEFT: 0x04,
    RIGHT: 0x08,
    TOP: 0x10,
    BOTTOM: 0x12
  };

  constructor() { }

  ngOnInit() {
    this.container = this.elementRef.nativeElement;
    this.init();
    this.animate();
    // this.show_container_side(this.FACE_MASKS.FRONT);
    this.show_container_side(this.FACE_MASKS.FRONT);
  }

  ngAfterViewInit() {

  }

  init() {
    const screen = {
      width: 800,
      height: 600
    },
      view = {
        angle: 45,
        aspect: screen.width / screen.height,
        near: 0.1,
        far: 1000
      };


    this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 2000);
    this.camera.position.x = 1000;
    // this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
    // // this.camera.position.z = 250;
    // // this.camera.position.x = -1000;
    // // this.camera.position.z = 1000;
    // this.camera.position.x = -1000;

    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color('#EEEEEE');
    const ambientLight = new THREE.AmbientLight(0xcccccc, 0.4);
    // this.scene.add( ambientLight );
    const pointLight = new THREE.PointLight(0xffffff, 0.8);
    this.camera.add(pointLight);
    this.scene.add(this.camera);


    this.renderer = new THREE.WebGLRenderer({ alpha: true });
    this.mtlLoader = new MTLLoader();
    this.loader = new OBJLoader();
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    this.renderer.setClearColor(0xEEEEEE);

    // new THREE.MTLLoader()
    // .setPath("model/")
    // .load("apple-watch.mtl", function(materials) {
    //   materials.preload();

    //   new THREE.OBJLoader()
    //     .setMaterials(materials)
    //     .setPath("model/")
    //     .load(
    //       "latest-watch.obj",
    //       function(object) {
    //         object3d = object;
    //         scene.add(object3d);



    this.container.appendChild(this.renderer.domElement);

    // group
    const group = new THREE.Group();
    this.scene.add( group );

    // this.mtlLoader
    //   .setPath('assets/models/')
    //   .load('container.mtl', (mtls) => {
    //   mtls.preload();
    //   this.loader
    //     .setPath('assets/models/')
    //     .setMaterials(mtls)
    //     .load('ContainerOBJ', (object) => {

    //       object.traverse(function (child) {
    //         if (child instanceof THREE.Mesh) {
    //           // child.material.map = texture;
    //           child.castShadow = true;
    //           child.receiveShadow = true;

    //           // child.material.color.setHex(0xd3d3ba);
    //         }
    //       });
    //       // object.lookAt(0, 1000, -1);
    //       // object.position.z = - 95;
    //       // object.position.set( 0, 1000, -1 );
    //       this.scene.add(object);
    //       object.scale.z = 0.949;
    //       object.scale.x = 1;
    //       console.log('object loaded');
    //       this.container_object = object;
    //       console.log(this.container_object);
    //     }
    //     );


    this.loader
      .setPath('assets/models/')
      .load('ContainerOBJ.obj', (object) => {


        // geometry.computeBoundingBox();
        // var bb = geometry.boundingBox;
        // var object3DWidth = bb.max.x - bb.min.x;
        // var object3DHeight = bb.max.y - bb.min.y;
        // var object3DDepth = bb.max.z - bb.min.z;
        // box helper to see the extend of the volume
        // object.computeBoundingBox();
        // const bb = object.boundingBox;
        // const object3DWidth = bb.max.x - bb.min.x;
        // const object3DHeight = bb.max.y - bb.min.y;
        // const object3DDepth = bb.max.z - bb.min.z;

        // console.log('bounding box');
        // console.log(bb);

        // const vct = new THREE.Vector3();
        // const boxsize = new THREE.Box3().setFromObject(object);
        // const size = new THREE.Box3().setFromObject(object).getSize(vct);
        // const geometry = new THREE.BoxBufferGeometry(size.x, size.y, size.z);
        // const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        // const cube = new THREE.Mesh(geometry, material);
        // cube.visible = false;
        // const box = new THREE.BoxHelper(cube);
        // this.scene.add(box);
        // box.applyMatrix(object.matrix);
        // this.scene.add(cube);


        // new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
        //  const cubeMaterials =
        // [
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ),  // RIGHT
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ),  // LEFT
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ),  // TOP
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ),  // BOTTOM
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} ),  // FRONT
        //    new THREE.LineBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} )   // BACK

        // ];

        // const cubeMaterials =
        // [
        //   new THREE.MeshBasicMaterial({new THREE.BoxBufferGeometry(16, 16), side: THREE.DoubleSide }),  //RIGHT
        //   // new THREE.MeshBasicMaterial({new THREE.TextureLoader().load(''), side: THREE.DoubleSide}),  //LEFT
        //   // new THREE.MeshBasicMaterial({new THREE.TextureLoader().load(''), side: THREE.DoubleSide}),  //TOP
        //   // new THREE.MeshBasicMaterial({new THREE.TextureLoader().load(''), side: THREE.DoubleSide}),  //BOTTOM
        //   // new THREE.MeshBasicMaterial({new THREE.TextureLoader().load(''), side: THREE.DoubleSide}),  //FRONT
        //   // new THREE.MeshBasicMaterial({new THREE.TextureLoader().load(''), side: THREE.DoubleSide})   //BACK

        // ];


        // const material = new THREE.MeshFaceMaterial( cubeMaterials );
        object.traverse(function (child) {
          if (child instanceof THREE.Mesh) {
            // child.material = material;
            child.castShadow = true;
            child.receiveShadow = true;
          }
        });
        // object.position.z = - 95;
        // object.position.set( 0, 1000, -1 );

        // this.scene.add(object);
        group.add(object);
        object.scale.z = 0.949;
        object.scale.x = 1;
        console.log('object loaded');
        this.container_object = object;
        // object.material.wireframe = true;

        const gridHelper = new THREE.GridHelper( 200, 10, 0x000000, 0x000000 );
        group.add( gridHelper );

        
        // const wireframe = new THREE.WireframeHelper( object, 0x00ff00 );
        // this.scene.add( wireframe );


        // const grid = new THREE.GridHelper( 200 , 16 );
        // this.scene.add( grid );
        // grid.geometry.rotateX( Math.PI / 2 );

        // const vector = new THREE.Vector3( 1, 1, 1 );
        // grid.lookAt( vector );



        // const gridHelper = new THREE.GridHelper(50, 10); // 500 is grid size, 20 is grid step
        // // gridHelper.position = new THREE.Vector3(0, 1000, 0);
        // // gridHelper.rotation = new THREE.Euler(0, 0, 0);
        // this.scene.add(gridHelper);
        // const gridHelper2 = gridHelper.clone();
        // gridHelper2.rotation = new THREE.Euler(Math.PI / 2, 0, 0);
        // this.scene.add(gridHelper2);
        // const gridHelper3 = gridHelper.clone();
        // // gridHelper3.rotation = new THREE.Euler(Math.PI / 2, 0, Math.PI / 2);
        // this.scene.add(gridHelper3);



        //           const geometry = new THREE.BoxBufferGeometry(-100, 0, -100, 0 );
        // const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
        // const plane = new THREE.Mesh( geometry, material );
        // this.scene.add( plane );
        // plane.position.setX(-250);
        // plane.position.setY(0);

        // const mesh = new THREE.Mesh( geometry, material );
        // this.scene.add( mesh );


        // const geo = new THREE.EdgesGeometry( mesh.geometry ); // or WireframeGeometry
        // const mat = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
        // const wireframe = new THREE.LineSegments( geo, mat );
        // mesh.add( wireframe );




        // // create a blue LineBasicMaterial
        // const material = new THREE.LineBasicMaterial({ color: 0x0000ff });
        // const geometry = new THREE.Geometry();
        // geometry.vertices.push(new THREE.Vector3(0, 0, 0));
        // geometry.vertices.push(new THREE.Vector3(0, 10, 0));
        // geometry.vertices.push(new THREE.Vector3(10, 0, 0));

        // const line = new THREE.Line(geometry, material);


        // this.scene.add( line );

        // const geom = new THREE.Geometry();
        // const v1 = new THREE.Vector3(0, 0, 0);
        // const v2 = new THREE.Vector3(0, 100, 0);
        // const v3 = new THREE.Vector3(0, 100, 0);

        // geom.vertices.push(v1);
        // geom.vertices.push(v2);
        // geom.vertices.push(v3);

        // geom.faces.push(new THREE.Face3(0, 1, 2));

        // const objectMesh = new THREE.Mesh(geom, new THREE.MeshNormalMaterial());
        // objectMesh.rotation.x = Math.PI / 2;
        // this.scene.add(objectMesh);



        // this.render();
        // this.show_container_side(this.FACE_MASKS.BACK);

      });
    console.log('init completed rendered');
    this.addControls();
    this.createMesh();
  }

  render() {
    this.renderer.render(this.scene, this.camera);
  }
  // render() {
  //   const self: MyfirstsceneComponent = this;

  //   requestAnimationFrame(this.render.bind(self));
  //   self.renderer.render(self.scene, self.camera);
  //   self.animate();
  //   // this.show_container_side(this.FACE_MASKS.FRONT);
  //   // (function render() {
  //   //   requestAnimationFrame(this.render.bind(this));
  //   //   self.renderer.render(self.scene, self.camera);
  //   //   self.animate();
  //   // }());
  // }

  public addControls() {
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    // this.controls.rotateSpeed = 1.0;
    // this.controls.zoomSpeed = 1.2;
    this.controls.enableDamping = true;
    this.controls.dampingFactor = 0.25;
    this.controls.enableZoom = true;

    this.controls.enablePan = false;
    this.controls.addEventListener('change', this.render.bind(this));
    console.log('addControls');

  }


  @HostListener('document:keypress', ['$event'])
  public onKeyPress(event: KeyboardEvent) {
    console.log('onKeyPress: ' + event.key);
  }
  @HostListener('document:mousedown', ['$event'])
  public onMouseDown(event: MouseEvent) {
    console.log('onMouseDown');
    event.preventDefault();

    // // Example of mesh selection/pick:
    // const raycaster = new THREE.Raycaster();
    // const mouse = new THREE.Vector3();
    // mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
    // mouse.y = - (event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
    // raycaster.setFromCamera(mouse, this.camera);

    // const obj: THREE.Object3D[] = [];
    // this.findAllObjects(obj, this.scene);
    // const intersects = raycaster.intersectObjects(obj);
    // // const colorArray = intersects[0].object.geometry.attributes.color.array,
    // const faceIndices = ['a', 'b', 'c', 'd'];
    // const face = intersects[0].face;
    // const numberOfSides = (face instanceof THREE.Face3) ? 3 : 4;
    // console.log('Number of sides' + numberOfSides);
    // // assign color to each vertex of current face
    // for (let j = 0; j < numberOfSides; j++) {
    //   const vertexIndex = face[faceIndices[j]];
    //   // initialize color variable
    //   const clr = new THREE.Color(0xffffff);
    //   clr.setRGB(Math.random(), 0, 0);
    //   face.vertexColors[j] = clr;
    // }

    // // const color = new THREE.Color( 0xffffff );
    // // color.setRGB( Math.random(), 0, 0 );

    // // face.vertexColors[0] = color;
    // // colorArray[face.a] = 1;
    // // colorArray[face.a + 1] = 0;
    // // colorArray[face.a + 2] = 0;
    // // colorArray[face.b] = 1;
    // // colorArray[face.b + 1] = 0;
    // // colorArray[face.b + 2] = 0;
    // // colorArray[face.c] = 1;
    // // colorArray[face.c + 1] = 0;
    // // colorArray[face.c + 2] = 0;
    // // intersects[0].object.geometry.attributes.color.needsUpdate = true;

    // console.log('Scene has ' + obj.length + ' objects');
    // console.log(intersects.length + ' intersected objects found');
    // intersects.forEach((i) => {
    //   console.log(i.object); // do what you want to do with object
    // });
    // this.show_container_side(this.FACE_MASKS.BOTTOM);
  }

  private findAllObjects(pred: THREE.Object3D[], parent: THREE.Object3D) {
    // NOTE: Better to keep separate array of selected objects
    if (parent.children.length > 0) {
      parent.children.forEach((i) => {
        pred.push(i);
        this.findAllObjects(pred, i);
      });
    }
  }

  public onMouseUp(event: MouseEvent) {
    console.log('onMouseUp');
  }



  animate() {
    TWEEN.update();
    requestAnimationFrame(this.animate.bind(this));
    this.controls.update();
    this.render();

  }

  createMesh() {
    const geometry = new THREE.BoxBufferGeometry(1, 1, 1);
    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

    const cubeA = new THREE.Mesh(geometry, material);
    cubeA.position.set(100, 100, 0);

    const cubeB = new THREE.Mesh(geometry, material);
    cubeB.position.set(-100, -100, 0);

    // create a group and add the two cubes
    // These cubes can now be rotated / scaled etc as a group
    const group = new THREE.Group();
    group.add(cubeA);
    group.add(cubeB);

    this.scene.add(group);
  }

  show_container_side(side) {
    // document.getElementById('dismiss-button').style.display = 'block';
    const face_vector = { x: 0, y: 0, z: 0 };
    switch (side) {
      case this.FACE_MASKS.LEFT:
        face_vector.z = 1;
        break;
      case this.FACE_MASKS.RIGHT:
        face_vector.z = -1;
        break;
      case this.FACE_MASKS.BACK:
        face_vector.x = -1;
        break;
      case this.FACE_MASKS.FRONT:
        face_vector.x = 1;
        break;
      case this.FACE_MASKS.TOP:
        face_vector.y = 1;
        break;
      case this.FACE_MASKS.BOTTOM:
        face_vector.y = -1;
        break;
    }
    const selected_side_vector = face_vector;
    console.log('selected side of the vector' + face_vector + ' side ' + side);
    const current_pos = { x: this.controls.object.position.x, y: this.controls.object.position.y, z: this.controls.object.position.z };
    const target_pos = {
      x: face_vector.x * this.DEFAULT_CAMERA_POSITION, y: face_vector.y * this.DEFAULT_CAMERA_POSITION,
      z: face_vector.z * this.DEFAULT_CAMERA_POSITION
    };
    const tween = this.get_rotation_tween(current_pos, target_pos, this.DURATION);
    // this.controls.disableAutoRotate();

    if (this.controls.AutoRotate) {
      this.controls.autoRotate = false;
    }
    tween.start();

    // const event = new CustomEvent('show_option_panel', {detail: side} );
    // (document)[0].dispatchEvent( event );
    console.log('showing ' + side);

  }

  get_rotation_tween(current, target, duration_time) {
    console.log('get_rotation_tween');

    const tween = new TWEEN.Tween(current).to(target, duration_time);
    tween.easing(TWEEN.Easing.Quartic.Out);
    tween.onUpdate(() => {
      // this.controls.update();
      this.controls.object.position.set(current.x, current.y, current.z);
      // this.controls.object.position.set(0, 1000, 1000);
      // this.controls.object.position.set(target.x, target.y, target.z);
      // this.container_object.lookAt(targe)
      // console.log(this.controls);
      console.log('current');
      console.log(current);
      console.log('target');
      console.log(target);
    });
    return tween;
  }

}

You can cover your container with a grid of rectangles of lines, each rectangle is a separated THREE.Line() object, for example. Then you simply change the color of the material of a rectangle.

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 )

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 )