Trying to intersect 2 objects but have an error

Hi, I’m trying to make an intersect between two objects: a cube and a triangle. however, when trying cubeCSG.intersect(pyramidCSG) the error “Cannot read properties of undefined (reading ‘array’)” appears. If you create a cone instead of a triangle, you can make the intersection without any problems. How can this be fixed? Preferably, please write the code…

Here is my code:

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { CSG } from 'three-csg-ts';

let camera: THREE.PerspectiveCamera,
  scene: THREE.Scene,
  renderer: THREE.WebGLRenderer;

init();
animate();

function init() {
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    10000
  );
  const controls = new OrbitControls(camera, renderer.domElement);
  camera.position.set(0, 20, 10);
  controls.update();

  const rectWidth = 5;
  const rectHeight = 2;
  const maxDistance = 8;

  const box = new THREE.Mesh(
    new THREE.BoxGeometry(2, 2, 2),
    new THREE.MeshNormalMaterial({ wireframe: true })
  );

  scene.add(box);

  // Create the vertices of the triangle
  const vertices = new Float32Array([
    0, 1, 0, // Vertex A
    -1, -1, -1, // Vertex B
    1, -1, 0, // Vertex C
    0, -1, 1 // Vertex D 
  ]);

  // Create indexes to define the faces of the triangle
  const indices = new Uint32Array([0, 1, 2, 0, 2, 3, 0, 3, 1, 1, 3, 2]);

  // Create a buffer geometry
  const geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
  geometry.setIndex(new THREE.BufferAttribute(indices, 1));

  // Create the material
  const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });

  // Create a mesh
  const triangle = new THREE.Mesh(geometry, material);

  // Add a triangle to the scene
  scene.add(triangle);


  // Convert objects to CSG
  const cubeCSG = CSG.fromMesh(box);
  const pyramidCSG = CSG.fromMesh(triangle);

  // Perform the subtraction operation
  const intersect = cubeCSG.intersect(pyramidCSG);

  // Convert the result back to Three.js Mesh
  const resultMesh = CSG.toMesh(intersect, box.matrix);
  resultMesh.material = new THREE.MeshNormalMaterial({ wireframe: false });

  scene.add(resultMesh);

}

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

Change your triangles buffer geometry code to

    // Create a buffer geometry
    const geometry = new THREE.BufferGeometry()
    geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
    geometry.setIndex(new THREE.BufferAttribute(indices, 1))
    geometry.scale(1.5, 1.5, 1.5)
    geometry.computeVertexNormals()

The scale is just so you can see it, otherwise it’s cut completely inside the cube,
then computeVertexNormals()

1 Like

Yes, thanks, I repeated your code, it works the same as in the screenshot. However, I don’t need to cut a triangle out of a cube, but find the intersection of two figures, and draw the resulting figure (the result should be the same triangle)

I replaced my method with intersect with subtract, now the final model looks like a triangle, as I need (if I return geometry.scale(1, 1, 1) to it). But now I don’t understand why 1 line of code “geometry.computeVertexNormals()” changes the logic of the methods. If I understand correctly, intersect should find the intersection of shapes and return the value of the intersection, and subtract should cut one shape from another. Now it works the other way around…

don’t add the box and triangle to the scene, otherwise it hides the resultMesh

or position the result mesh somewhere else.

Also experiment swapping the indices order

const indices = new Uint32Array([2, 1, 0, 3, 2, 0, 1, 3, 0, 2, 3, 1])