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