# Draw grid on top of model on each face

**URL:** <https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156>\
**Category:** Questions\
**Tags:** geometry\
**Created:** [November 28, 2018, 11:26am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156 "2018-11-28T11:26:46Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 28, 2018, 11:26am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/1 "2018-11-28T11:26:46Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 28, 2018, 12:01pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/2 "2018-11-28T12:01:24Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 28, 2018, 1:38pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/3 "2018-11-28T13:38:15Z")

</div>

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](https://cdck-file-uploads-canada1.s3.dualstack.ca-central-1.amazonaws.com/flex035/uploads/threejs/original/2X/c/cce7e63e84901e73a568d4b2c6ba968dd5b4ffea.png)

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

* * *

```auto
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;
  }

}

```

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 28, 2018, 1:56pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/4 "2018-11-28T13:56:32Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 28, 2018, 2:10pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/5 "2018-11-28T14:10:31Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 28, 2018, 2:38pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/6 "2018-11-28T14:38:46Z")

</div>

> [@Mohamed\_Fayeeg](#):
>
> How do I get the size of each face?

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

```javascript
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

```

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 28, 2018, 3:49pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/7 "2018-11-28T15:49:37Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 29, 2018, 8:30am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/8 "2018-11-29T08:30:46Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [November 29, 2018, 9:51am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/9 "2018-11-29T09:51:44Z")

</div>

> [@Mohamed\_Fayeeg](#):
>
> 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/3DGridOfLines/3DGridOfLines.html)  
[http://discourse.threejs.hofk.de/GridBoxGeometry/GridBoxGeometry.html](http://discourse.threejs.hofk.de/GridBoxGeometry/GridBoxGeometry.html)  
_The links to discourse.threejs. org are above in the source code_

[Grid Collection](https://discourse.threejs.org/t/grid-collection/1893)

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

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 29, 2018, 2:11pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/10 "2018-11-29T14:11:13Z")

</div>

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](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](https://cdck-file-uploads-canada1.s3.dualstack.ca-central-1.amazonaws.com/flex035/uploads/threejs/original/2X/6/69a23f95270d25ead35c3912744ce5ed65b05411.png)

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [November 29, 2018, 5:06pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/11 "2018-11-29T17:06:36Z")

</div>

> [@Mohamed\_Fayeeg](#):
>
> The problem is that I am unable to position the grid matching the position of the container object.

The grid can be positioned arbitrarily.

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

```

 ![20181129-1802-18712](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/8/889bd65c0f4096b09465619b8cf054eaa734a7b1.png)

I have simplified the example and moved the grid downwards.

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

![20181129-1801-23968](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/f/f55252b9de18249a8648f27fc123995145d92979.png)

_The simplified version is added to the example collection. (under the original version )_ [http://discourse.threejs.hofk.de/](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>

```

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 30, 2018, 1:40am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/12 "2018-11-30T01:40:17Z")

</div>

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);

```

* * *

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [November 30, 2018, 8:09am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/13 "2018-11-30T08:09:31Z")

</div>

> [@Mohamed\_Fayeeg](#):
>
> Thanks for the hint.

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](https://discourse.threejs.org/t/collection-of-examples-from-discourse-threejs-org/4315)).

_I only assisted a little._

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [November 30, 2018, 10:09am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/14 "2018-11-30T10:09:38Z")

</div>

Thank you @prisoner849 for your amazing contribution to ThreeJS.

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

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [November 30, 2018, 7:15pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/15 "2018-11-30T19:15:32Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [December 1, 2018, 4:29pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/16 "2018-12-01T16:29:27Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [December 1, 2018, 4:37pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/17 "2018-12-01T16:37:39Z")

</div>

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

Should only these cells be visible?

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [December 1, 2018, 10:57pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/18 "2018-12-01T22:57:38Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![hofk](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/hofk/32/44944_2.png) [@hofk](https://discourse.threejs.org/u/hofk)\
**Post date:** [December 2, 2018, 10:48am UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/19 "2018-12-02T10:48:03Z")

</div>

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

![20181202-1146-18130](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/2X/8/8cbdbda89f3e5cc8a2162df4059d46e2b7dcd5fc.png)

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.

> [@ProfiledContourGeometry](https://discourse.threejs.org/t/profiledcontourgeometry/2330):
>
> Evolving of that [post](https://discourse.threejs.org/t/simple-rectangular-geometry-extrusion-anyone/743/14) [ProfiledContourGeometry3] The function has four parameters: THREE.Shape() for a profile; array of THREE.Vector2() for a contour; a boolean value for closing the contour (default is true); a boolean value for open ends (default is false). It calculates an angle between two edges of contour and then consiquently applies three matrices of shear/shift, rotation and translation to the points of the profile at each point of contour. The solution is still rough and raw, an…

see also [http://discourse.threejs.hofk.de/ProfiledContourGeometry/ProfiledContourGeometry.html](http://discourse.threejs.hofk.de/ProfiledContourGeometry/ProfiledContourGeometry.html)

---

<div class="post-metadata">

**Author:** ![Mohamed\_Fayeeg](https://avatars.discourse-cdn.com/v4/letter/m/a87d85/32.png) [@Mohamed\_Fayeeg](https://discourse.threejs.org/u/Mohamed_Fayeeg)\
**Post date:** [December 2, 2018, 4:58pm UTC](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156/20 "2018-12-02T16:58:48Z")

</div>

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 )

[Next page](https://discourse.threejs.org/t/draw-grid-on-top-of-model-on-each-face/5156.md?page=2)
