Attach transform controls error

why every time is show this error in transform controls

Uncaught TypeError: array[i].call is not a function
at TransformControls.dispatchEvent (three.module.js:262)
at TransformControls.set (TransformControls.js:201)
at TransformControls.attach (TransformControls.js:170)
at HTMLInputElement.document.getElementById.onclick (test.js:406)

What are you attaching the controls to? Could you share more details / code?

selectedobject is intersected stl file or plane

function createTransformControls() {
  if (tcontrols != undefined) tcontrols.dispose();
  tcontrols = new TransformControls(camera, renderer.domElement);
  tcontrols.addEventListener("change", renderer);
  tcontrols.addEventListener("dragging-changed", function (event) {
    controls.enabled = !event.value;
  });
  
  window.addEventListener("keypress", function (e) {
    switch (e.key) {
      case "w" || "W":
        tcontrols.setMode("translate");
        break;

      case "e" || "E":
        tcontrols.setMode("rotate");
        break;

      case "r" || "R":
        tcontrols.setMode("scale");
        break;
    }
  });
}

 let getedge = selectObject.geometry;
  let edges = new THREE.EdgesGeometry(getedge);
  let edgematerial = new THREE.LineBasicMaterial({ color: 0xffaa22 });

  edgematerial.linewidth = 5;

  if (
    getedge.type == "PlaneGeometry" ||
    getedge.type == "PlaneBufferGeometry"
  ) {
    let setborder =
      getedge.parameters.width < 5000 || getedge.parameters.height < 5000;
    if (setborder) {
      let linemesh = new THREE.LineSegments(edges, edgematerial);

      let x = selectObject.position.x;
      let y = selectObject.position.y;
      let z = selectObject.position.z;

      linemesh.position.set(x, y, z);

      let setobject = selectObject;

      group.add(setobject);
      group.add(linemesh);

      const box = new THREE.Box3();
      box.setFromObject(group);

      tcontrols.attach(object3d);
      scene.add(tcontrols);


function init() {
  CreateRenderer();
  scene = new THREE.Scene();
  CreateCamera();
  camera.position.z = 500;
  AddLightsToScene();
  createOrbitControls();
  createTransformControls();
}

Please do format the code - it is not readable in this form :pray:

@Ajay
Instead of bedsheets of code in posts, would be better to provide a link to a minimal editable working example, that demonstrates the issue.

1 Like
import * as THREE from "../three js/build/three.module.js";
import { STLLoader } from "../three js/loaders/STLLoader.js";
import { TransformControls } from "../three js/controls/TransformControls.js";
import { TrackballControls } from "../three js/controls/TrackballControls.js";

//normal variable
let camera,
  scene,
  renderer,
  tcontrols,
  controls,
  INTERSECTED = null,
  selectObject, // intersected object
  rightMenuX,
  rightMenuY;

//plane border
let compose, effectFXAA, Outline;

//declaretion of variable

let vector3 = new THREE.Vector3(),
  object3d = new THREE.Object3D(),
  group = new THREE.Group(),
  rightclick = document.getElementById("rightclick");

//raycaster for hovering
let setname,
  raycast = new THREE.Raycaster(),
  mouse = new THREE.Vector2(),
  span = document.getElementById("showname"),
  check = true;
// span = document.createElement("span");

//canvas
let canvas = document.getElementById("mysegmenter"),
  width = canvas.offsetWidth,
  height = canvas.offsetHeight;

function CreateRenderer() {
  renderer = new THREE.WebGLRenderer({
    anitialias: true,
    alpha: true,
  });
  // renderer.setPixelRatio(window.devicePixelRatio);
  // renderer.setClearColor(0xdedede);
  renderer.castShader = true;
  renderer.autoClear = true;
  canvas.appendChild(renderer.domElement);
}

function CreateCamera() {
  const left = ((width / height) * height) / 5,
    right = (-(width / height) * height) / 5,
    top = -height / 5,
    bottom = height / 5,
    near = 0.00001,
    // near = 70,
    far = 5000 * 5000;

  camera = new THREE.PerspectiveCamera(35, width / height, near, far);
  // camera = new THREE.OrthographicCamera(left, right, top, bottom, near, far);

  // camera.position.set(0, 0, 1000);
}

function AddLightsToScene() {
  const light = new THREE.DirectionalLight(0xffffff, 1),
    light2 = new THREE.DirectionalLight(0xffffff, 1);

  light.position.set(50, 50, 50);
  light2.position.set(-50, -50, -50);
  scene.add(light, light2);
}

document.getElementById("importbone").onchange = function () {
  setloadfile(this.files); //!!!!temp

  this.value = null;
};

//check to transform controls
document.getElementById("localtransform").onclick = function () {
  // if (createTransformControls(selectObject)) return;

  tcontrols.setSpace = "local";

  //Signals.spaceChanged.dispatch('local');
  // return;
};

document.getElementById("Worldtransform").onclick = function () {
  tcontrols.setSpace = "world";

  //Signals.spaceChanged.dispatch('world');
  // return;
  // if (axis == workingaxis.XAXIS) currentmesh.userData.lockX = false;
  // else if (axis == workingaxis.YAXIS) currentmesh.userData.lockY = false;
  // else currentmesh.userData.lockZ = false;
  // updatetransformcontrol(currentmesh);
};

// //set of transform controls
// function setTransformControls() {
//   let getobject = [];
//   getobject.push(selectObject);

//   const getobjectgeo = getobject[0].geometry;
//   const getobjectmaterial = getobject[0].geometry;

//   const objectmesh = new THREE.Mesh(getobjectgeo, getobjectmaterial);

//   tcontrols.attach(objectmesh);
//   scene.add(tcontrols);
// }

function setloadfile(stlfile) {
  for (let i = 0; i < stlfile.length; i++) {
    // creategeometry(stlfile[i]);
  }
  scene.add(group);
}

//////////////////////////////////////////////// stlfile loade /////////////////////////////
function creategeometry(setfile) {
  // if (!setfile.name.endsWith(".stl")) return;

  const manager = new THREE.LoadingManager();

  const stlloader = new STLLoader(manager);
  // const objectURL = URL.createObjectURL(setfile);

  stlloader.load(
    // objectURL,
    setfile,
    (geo) => {
      const material = new THREE.MeshPhongMaterial({
        color: 0xffc250,
      });

      const bgeo = new THREE.Geometry().fromBufferGeometry(geo);

      const mesh = new THREE.Mesh(bgeo, material);
      mesh.castShader = true;

      mesh.geometry.computeBoundingBox();
      mesh.updateMatrixWorld(true);

      mesh.name = setfile;

      group.add(mesh);

      const box = new THREE.Box3();
      box.setFromObject(group);
      camera.lookAt(
        box.getCenter(vector3).x,
        box.getCenter(vector3).y,
        box.getCenter(vector3).z
      );
      controls.target.set(
        box.getCenter(vector3).x,
        box.getCenter(vector3).y,
        box.getCenter(vector3).z
      );

      scene.add(group);
    },
    (xhr) => {
      // console.log(
      (xhr.loaded / xhr.total) * 100 + "% loaded";
      // );
    },
    (error) => {
      console.log(error);
    }
  );
}

//all are cotrols declared
function createOrbitControls() {
  if (undefined != controls) controls.dispose();
  controls = new TrackballControls(camera, renderer.domElement);

  controls.RotateSpeed = 5;
}

function createTransformControls() {
  if (tcontrols != undefined) tcontrols.dispose();
  tcontrols = new TransformControls(camera, renderer.domElement);
  tcontrols.addEventListener("change", renderer);
  tcontrols.addEventListener("dragging-changed", function (event) {
    controls.enabled = !event.value;
  });

  window.addEventListener("keypress", function (e) {
    switch (e.key) {
      case "w" || "W":
        tcontrols.setMode("translate");
        break;

      case "e" || "E":
        tcontrols.setMode("rotate");
        break;

      case "r" || "R":
        tcontrols.setMode("scale");
        break;
    }
  });
}

// create plane for testing and drow plane on selected 3 points
function plane() {
  const planegeo = new THREE.PlaneBufferGeometry(50, 50);
  const matarial = new THREE.MeshPhongMaterial({
    color: 0x5a32de,
    side: THREE.DoubleSide,
  });
  const plane = new THREE.Mesh(planegeo, matarial);

  plane.name = "Plane1";

  scene.add(plane);

  let meshpoint1 = new THREE.Mesh(
    new THREE.SphereGeometry(1, 40, 40),
    new THREE.MeshPhongMaterial({ color: 0x000000 })
  );

  let meshpoint2 = new THREE.Mesh(
    new THREE.SphereGeometry(1, 40, 40),
    new THREE.MeshPhongMaterial({ color: 0x000000 })
  );

  let meshpoint3 = new THREE.Mesh(
    new THREE.SphereGeometry(1, 40, 40),
    new THREE.MeshPhongMaterial({ color: 0x000000 })
  );

  meshpoint1.position.set(90, 0, 0);
  meshpoint2.position.set(0, 90, 0);
  meshpoint3.position.set(0, 0, 90);

  meshpoint1.name = meshpoint2.name = meshpoint3.name = "Point";

  scene.add(meshpoint1, meshpoint2, meshpoint3);

  let v1 = meshpoint2.position.clone().sub(meshpoint1.position.clone());
  let v2 = meshpoint3.position.clone().sub(meshpoint1.position.clone());

  vector3.crossVectors(v1, v2);
  vector3.normalize();

  let geom = new THREE.PlaneGeometry(200, 200);
  let mtrl = new THREE.MeshPhongMaterial({
    color: "black",
    opacity: 0.5,
    side: THREE.DoubleSide,
  });
  geom.lookAt(new THREE.Vector3(vector3.x, vector3.y, vector3.z));
  let msh = new THREE.Mesh(geom, mtrl);

  msh.position.set(
    meshpoint1.position.x / 3,
    meshpoint2.position.y / 3,
    meshpoint3.position.z / 3
  );

  msh.name = "Plane2";

  scene.add(msh);

  // createTransformControls(msh);

  // group.add(msh);

  // console.log((msh.material.wireframe = true));

  // let point = [];

  // let linematerial = new THREE.LineBasicMaterial({ color: 0x000000 });

  // if (msh.geometry.vertices) {
  //   point.push(msh.geometry.vertices[0]);
  //   point.push(msh.geometry.vertices[1]);
  //   point.push(msh.geometry.vertices[2]);
  //   point.push(msh.geometry.vertices[3]);
  // }

  // let linegeo = new THREE.BufferGeometry().setFromPoints(point);

  // let planeline = new THREE.Line(linegeo, linematerial);

  // scene.add(planeline);
}

//on document mouse moveing
function onDocumentMouseMove(e) {
  mouse.x = (e.clientX / renderer.domElement.width) * 2 - 1;
  mouse.y = -(e.clientY / renderer.domElement.height) * 2 + 1;

  span.style.top = e.clientY + "px";
  span.style.left = e.clientX + "px";
  span.style.display = "none";

  // let canvaswidth = canvas.offsetWidth;

  // if (canvaswidth) {
  //   span.style.left = e.clientX - 100 + "px";
  // }
}

// set name of intersected mouse and set object on variable intersected
function meshname() {
  raycast.setFromCamera(mouse, camera);

  let intersect = raycast.intersectObjects(scene.children, true);

  for (let i = 0; i < intersect.length; i++) {
    setname = intersect[i].object.name;
  }

  function showname() {
    let time;

    setTimeout(() => {
      span.style.display = "block";
    }, time - 2000);

    if (time == 6000) return;
  }

  for (let i = 0; i < intersect.length; i++) {
    if (INTERSECTED != intersect[0].object) {
      if (intersect[0].object.name) {
        let name = intersect[0].object.name;
        let setname = name.replace(/[A-Za-z.]+[/]/g, "");
        span.innerText = setname;
        // span.style.display = "block";

        showname();

        setTimeout(() => {
          span.style.display = "none";
        }, 3000);
      }
    } else {
      span.style.display = "none";
      INTERSECTED = null;
    }
    selectObject = intersect[0].object;
  }
}

function setTctl(getobj) {
  if (getobj) {
    // for (let i = 0; i < getobj.length; i++) {
    // tcontrols.attach(getobj[i]);
    tcontrols.attach(getobj);
    scene.add(tcontrols);
    // }
  }
}

//set border of selected 3D object.
document.getElementById("border").onclick = function () {
  let getedge = selectObject.geometry;
  let edges = new THREE.EdgesGeometry(getedge);
  let edgematerial = new THREE.LineBasicMaterial({ color: 0xffaa22 });

  edgematerial.linewidth = 5;

  if (
    getedge.type == "PlaneGeometry" ||
    getedge.type == "PlaneBufferGeometry"
  ) {
    let setborder =
      getedge.parameters.width < 5000 || getedge.parameters.height < 5000;
    if (setborder) {
      let linemesh = new THREE.LineSegments(edges, edgematerial);

      let x = selectObject.position.x;
      let y = selectObject.position.y;
      let z = selectObject.position.z;

      linemesh.position.set(x, y, z);

      let setobject = selectObject;

      group.add(setobject);
      group.add(linemesh);

      const box = new THREE.Box3();
      box.setFromObject(group);

      tcontrols.attach(object3d);
      scene.add(tcontrols);

      scene.add(group);
    }
  }

  rightclick.style.display = "none";
};

//object remove
document.getElementById("objectremove").onclick = function () {
  alert("working");

  rightclick.style.display = "none";
};

canvas.onpointerup = function onDocumentMouseRightClick(e) {
  if (rightclick.style.display == "none") {
    rightMenuY = rightclick.style.top = e.clientY + 5 + "px";
    rightMenuX = rightclick.style.left = e.clientX + 5 + "px";
  }
  switch (e.button) {
    case 0:
      rightclick.style.display = "none";
      break;
    case 1:
      console.log(1);
      break;
    case 2:
      rightclick.style.display = "block";
      if (rightclick.style.display == "block") {
        rightclick.style.top = rightMenuY + "px";
        rightclick.style.top = rightMenuX + "px";
        span.style.display = "none";
      }
      break;
    default:
      console.log("default");
      break;
  }
};

function init() {
  CreateRenderer();
  scene = new THREE.Scene();
  CreateCamera();
  camera.position.z = 500;
  AddLightsToScene();
  createOrbitControls();
  createTransformControls();

  // tcontrols.attach(scene.children);
  // scene.add(tcontrols);

  plane();
  creategeometry("../model/FemurLt.stl");
  creategeometry("../model/HipLt.stl");
  creategeometry("../model/ShaftLt.stl");

  canvas.addEventListener("mousemove", onDocumentMouseMove, false);
  document.addEventListener("mousemove", onDocumentMouseMove, false);

  //resize
  canvas.addEventListener("resize", () => {
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    renderer.setSize(width, height, true);
  });
}

//sizing for object
function resizetoDisplay(renderer) {
  const canvas = renderer.domElement;
  const width = canvas.clientWidth;
  const height = canvas.clientHeight;
  const needResize = canvas.width !== width || canvas.height !== height;

  if (needResize) {
    renderer.setSize(width, height, false);
  }
  return needResize;
}

function animated() {
  requestAnimationFrame(animated);

  // linemesh.position.set(vector3.x, vector3.y, vector3.z);

  if (resizetoDisplay(renderer)) {
    const canvas = renderer.domElement;
    camera.aspect = canvas.clientWidth / canvas.clientHeight;
    camera.updateProjectionMatrix();
  }

  meshname();

  camera.lookAt(scene);
  controls.update();
  render();
}

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

init();
animated();