I am working on application in which i need to find wall thickness of 3D models mainly STL files.
The application I am working is mainly used for 3D printing manufacturing. So for me it is very important to unsure that the model is printable and model thickness is within the range.
based on similar questions on mesh volume, volume of a mesh can be calculated by following equation:
volume = ((vec1 x vec2) . vec3) /6
where vec1, vec2, and vec3 are the vectors from origin to a mesh triangle, and x is cross product and . is dot product.
and for the volume of the whole mesh, that should be calculated for all triangles.
Afterwards, the area of the triangle can be calculated by the following equation:
area = || (vec2 - vec1) x (vec3 - vec1)|| /2
where vec1, vec2, and vec3 is the same as previous equation.
calculating volume and area, the height can be obtained by following equation:
height = 3*volume/area
However, I am not sure how to perform final calculation to obtain the wall thickness when I have all the heights of triangles (which are the vectors from origin perpendicular to triangles).
I have already calculated volume of model
Below is the code i used:
function volumeOfT(p1, p2, p3) {
var v321 = p3.x * p2.y * p1.z;
var v231 = p2.x * p3.y * p1.z;
var v312 = p3.x * p1.y * p2.z;
var v132 = p1.x * p3.y * p2.z;
var v213 = p2.x * p1.y * p3.z;
var v123 = p1.x * p2.y * p3.z;
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6.0;
}
function calculateVolume(mesh){
var volumes = 0.0;
var len = mesh.geometry.faces.length;
for (var i = 0; i < len; i++){
var Pi = mesh.geometry.faces[i].a;
var Qi = mesh.geometry.faces[i].b;
var Ri = mesh.geometry.faces[i].c;
var P = new THREE.Vector3(mesh.geometry.vertices[Pi].x, mesh.geometry.vertices[Pi].y, mesh.geometry.vertices[Pi].z);
var Q = new THREE.Vector3(mesh.geometry.vertices[Qi].x, mesh.geometry.vertices[Qi].y, mesh.geometry.vertices[Qi].z);
var R = new THREE.Vector3(mesh.geometry.vertices[Ri].x, mesh.geometry.vertices[Ri].y, mesh.geometry.vertices[Ri].z);
volumes += volumeOfT(P, Q, R);
}
loadedmeshVolume = Math.abs(volumes);
}
But i don’t get how you calculated area.
area = || (vec2 - vec1) x (vec3 - vec1)|| /2
Is this area of single face or whole body area?
Because i have already calculated surface area of whole body.
And the formula for height you mention
@sonali_funde1
I didn’t get the start of the process, when you want to find the thickness of a wall.
Do you want to point on it with mouse and then get the distance to the other side of the wall?
Or do you have just a model and somehow you have to know the thickness of a specific wall?
Could you provide more detailed explanation of the process?
Hi, I use the same formula as you for the volume. The formula for the area is as below based on your notation:
Area of a triangle of a mesh = || (Q - P) x (R - P) || /2
Where x is cross product of the vectors, and || is norm of the total vector, which is the same as the length of the total vector.
So when I have the volume of the tetrahedral, and the area of the triangle, I calculate the height of the tetrahedral by reversing this formula.
Volume of tetrahedral = area * height/3
Now that i have all the heights of tetrahedrals of the mesh, I don’t know how to sum up the heights to obtain wall thickness.
Hi, thank you for the questions. I merely have a stl file, loaded into three.js, and I need to know minimum wall thickness of the mesh, in order to check printability. For example, a ring has specific thickness = outerRadius - innerRadius. I need to calculate this wall thickness, for irregular geometries as well.
find the distance between two faces of model by pointing/clicking on it with mouse.
Analyse the whole model and find out whether the model is printable or not. Because 3D printing machines have limitation on wall thickness.
for example, some machines does not accept wall thickness below 6mm.
Is there any other way to find out whether STL files are printable or not?other than finding wall thickness?
Also please suggest if you have some solution for task 1.
Maybe something like this:
Set material’s property .side to THREE.Double.
Loop through faces, finding the midpoint of a face, then use a raycaster to cast a ray from the midpoint in direction of the negated normal of the face, thus you’ll get the distance to the nearest intersected face an call Math.min(minValue, distance). In the end, after finishing the loop on faces, you’ll get the shortest distance and if it’s less than 0.6, then the model is not printable.
Thanks for suggestion!!
I have reviewed your code but i got stuck in line no.61 intersects = raycaster.intersectObject(plane1);
In this you passes plane 1(which is your box geometry) as a intersecting object but in my case i loaded STL file and from that geometry i made mesh which is to be added in scene. intersects = raycaster.intersectObject(mesh);
But above line show intersects length as 0
So can you suggest me what should i pass instead of mesh?
Thanks for reply,
I used
material = new THREE.MeshPhongMaterial({ color: 0x5C98BD,side: THREE.DoubleSide });
I used side: THREE.DoubleSide beause some faces of stl files are misssing.
When i remove this from my code i get some faces open.
So close all faces i used double side
I used this only for display purpose.
I am not sure that open faces are acceptable for 3D printing or not .
But for analyzing 3D printing wall thickness of part should be consider,
that’s why i wanna find it.
loader.load("file5.stl", function (geometry1) {
geometry1.toNonIndexed();
geometry=new THREE.Geometry().fromBufferGeometry(geometry1);
//geometry.toNonIndexed();
material = new THREE.MeshPhongMaterial({ color: 0x5C98BD});
mesh = new THREE.Mesh(geometry,material);
scene.add(mesh);
objects.push(mesh);
console.log(mesh);
geometry.center();
var size =(bounding_box_x+bounding_box_z);
var divisions =7;
var gridHelper = new THREE.GridHelper( size, divisions );
gridHelper.position.x=0;
gridHelper.position.y=0-(Math.abs(bounding_box_y)/2);
gridHelper.position.z=0;
scene.add( gridHelper );
helper = new THREE.BoxHelper(mesh, 0x000000);
helper.update();
scene.add(helper);
helper.name="BoundingBox";
var minDist = 0.6;
var raycaster = new THREE.Raycaster();
var intersects = [];
//var pos = plane.geometry.attributes.position;
var positions = geometry1.attributes.position;
console.log(positions);
var ori = new THREE.Vector3();
var dir = new THREE.Vector3();
var trc = new THREE.Vector3();
var a = new THREE.Vector3(),
b = new THREE.Vector3(),
c = new THREE.Vector3(),
midPoint = new THREE.Vector3(),
tri = new THREE.Triangle();
var closest = new THREE.Vector3();
var faces = positions.count / 3;
console.log(faces);
for (let i = 0; i < faces; i++) {
a.fromBufferAttribute(positions, i * 3 + 0);
b.fromBufferAttribute(positions, i * 3 + 1);
c.fromBufferAttribute(positions, i * 3 + 2);
tri.set(a,b,c);
tri.getMidpoint(ori);
tri.getNormal(dir)
raycaster.set(ori,dir.negate());
alert(intersects.length);
intersects = raycaster.intersectObject(mesh, true);
The loader already returns a non-indexed buffer geometry, and this is the type of geometry that the algorithm intended for. So all these lines are very enigmatic for me.