Need help with a implementing expansion functionality using three js

I was trying to do expansion of a instance mesh on screen using user input in three js but can’t find the method to do even expansion that increased the thickness of the material. if i move the vertex positions and give a new mesh the new mesh is not like expansion but like elongation.

For vertex expansion shader, you have to move the vertices outward along their vertex normal… and it only works well if the vertex normals are smooth, not like face normals…

You got any screenshots of where you’re at so far?

I just move the position and normals along their direction upto the user defined value but the polygon is disassembling.

You may need to make a copy of geometry, merge it’s vertices with buffergeometryutils.mergevertices, then geometry.computevertexnormals()

Then run you normal expansion on that.

1 Like

still the expansion just moves the planes along the normal. Is there any library for this expansion?

are you doing the expansion to render outlines?

no trying to expand the mesh instance on user input. trying to achieved that.

@SRIDHAR.M since I don’t really understand what you are trying to achieve, but IF and only IF this expansion functionality would be equivalent to scaling the mesh up or down then could the following possibly help:

  whatever_mesh.scale.multiplyScalar( adjusted_user_input_value );
1 Like

Oof yea I might have been overthinking OPs task. :smiley:

I need to simulate the expansion of for example a hollow cylinder mesh in Three.js. Specifically, I want to achieve the following effect:

  • The outer surface of the cylinder expands outward by 5 mm.
  • The inner surface of the cylinder contracts inward by 5 mm, maintaining the hollow structure.

This kind of expansion where each vertex moves. Scaling will elongate it in all directions right?

2 Likes

As @manthrax said, you need to merge the vertices, generate new normals, and then use those to push/pull your original vertices.
Some more advanced logic will be needed if you want to keep the same angles between faces.

Imagine new BoxGeometry(1,1,1,2,2,2) if you move the middle vertex by 1 it’s going to move perpendicular to the face. when you move the edge vertex by 1 its going to go at 45 degrees. So you actually get it at 0.707 from the face (two faces). Not sure how to address this off the top of my head.

1 Like

… and to piggyback off of what dubois said, sometimes you also need to remove the existing uv and vertex normals, for the merging to work.

So the full flow might be something like:

let g = mesh.geometry;
g.deleteAttribute('uv');
g.deleteAttribute('normal');
mesh.geometry = BufferGeometryUtils.mergeVertices(g);

No sadly it didn’t work. This resulted in elongation and also smoothing of the mesh but not thickness increase or expansion.

Can you show some images?



The image is original stl file got form GrabCAD website and second is after applying expansion as i understood from the discussion above.

This seems to be a mesh that is not perfectly in shape with the original model.

How would you expect it to look though? It’s either going to become disconnected, or stretched / morphed a little, if you expect it to grow in all axes at the same time.

I am trying to get a uniform expansion this code below as per the discussion in this forum expanded the geometry of the 3d object but it expanded only in 2 planes y and x not in the z plane for certain 3d models.

  setSolidExtension(newValue);

    if (selectedMesh) {
      const geometry = selectedMesh[0].geometry;

      geometry.computeBoundingBox();

      const test = geometry.boundingBox.clone();

      const test1 = new Vector3();

      test.getSize(test1);

      geometry.deleteAttribute("uv");
      geometry.deleteAttribute("normal");

      const mergedGeometry = BufferGeometryUtils.mergeVertices(geometry);

      selectedMesh[0].geometry = mergedGeometry;
      
      mergedGeometry.computeVertexNormals();

      const thickness = parseFloat(newValue);
      if (isNaN(thickness)) {
        console.error("Invalid thickness value");
        return;
      }

      const positionAttribute = mergedGeometry.attributes.position;
      const normalAttribute = mergedGeometry.attributes.normal;

      const positions = positionAttribute.array;
      const normals = normalAttribute.array;

      for (let i = 0; i < positions.length; i += 3) {
        // const normalLength = Math.sqrt(
        //   normals[i] * normals[i] +
        //     normals[i + 1] * normals[i + 1] +
        //     normals[i + 2] * normals[i + 2]
        // );

        // normalAttribute.setXYZ(
        //   i,
        //   normals[i] / normalLength,
        //   normals[i + 1] / normalLength,
        //   normals[i + 2] / normalLength
        // );
        positions[i] += normals[i] * thickness;
        positions[i + 1] += normals[i + 1] * thickness;
        positions[i + 2] += normals[i + 2] * thickness * 2;
      }

      positionAttribute.needsUpdate = true;

      mergedGeometry.computeBoundingBox();

      const finalBoundingBox = mergedGeometry.boundingBox.clone();
      const finalSize = new Vector3();
      finalBoundingBox.getSize(finalSize);
      console.log(
        `After Expansion - Length: ${finalSize.x}, Width: ${finalSize.y}, Height: ${finalSize.z}`
      );