How to fix holes display in geometry

Hello, everyone! Worked on creating a hole inside the geometry of the group components.
I was faced with the fact that on some sides the holes are not scaled correctly.

How can this be fixed?

Picture of right hole scaling.
изображение

Picture of wrong hole scaling.
изображение

I’m creating rectangle through THREE.Group

//Create and render rectangle at scene.
const rectangle = new Rectangle(150, 300, 500)
scene.add(rectangle)

//Set up holes parameters for each side of rectangle
const hole = {
  holeX: 0,
  holeY: 0,
  holeRadius: 30
}


rectangle.children.forEach(child => {
  createHole(child, hole)
})

For creating holes I used this functions

/*
* Creates hole in 3D-component through ShapeGeometry.
* @param component:Object3D object where need to create hole.
* @param holePamaters:Object containing parameters of creating hole such as radius and x, y position at geometry.
*/function createHole(component, holeParameters) {
  //Forming new geo
  const shape = new Shape().copy(component.getShape())
  const path = createHoleVertices(component, holeParameters)
  shape.holes.push(path)
  
  //Delete old geo and setting up new one.
  const oldGeo = component.geometry 
  component.geometry = new ShapeGeometry(shape)
  oldGeo.dispose()
}

/*
* Creates Path of hole vertices.
* @param component:Object3D object where need to create hole.
* @param holePamaters:Object containing parameters of creating hole such as radius and x, y position at geometry.
* @return Path of hole.
*/function createHoleVertices(component, holeParameters) {
  let {holeX, holeY, holeRadius} = holeParameters
  
  //Normalizing hole parameters due to planes origin size is (width: 1, height: 1).
  const {x, y} = component.getParentScale()
  holeX = holeX / x
  holeY = holeY / y
  return new Path().absellipse(holeX, holeY, holeRadius / x, holeRadius / y, 0, 2 * Math.PI) 
 }

Here is codepen for demonstration: https://codepen.io/DYDOI-NSK/pen/ZEPvyde?editors=0010

Actually, it is just the opposite. They are scaled correctly as coded in the source. The culprit is this command:

this.scale.set(width, height, depth)

Initially each side is a square, when it is scaled nonuniformly, the square is stretched into a rectangle, and the circular hole is stretched into an ellipse. To resolve this create, each side as it is, without using this.scale.set . If you use it, use it only with the same scaling factors, e.g. this.scale.set(2,2,2).

Thanks for the answer. Unfortunately, I need to set not same scaling factor on rectangle. Is there any others ways to normalize hole display?

If you absolutely need to use different scale factors, then you should shrink some of the holes, so that after stretching they become circles. Another alternative is to use CSG to punch the holes after creating the shape.

BTW, I still think you can go without scaling. Of course, I do not know the context of your project, so I might be wrong. Here is a demo without scaling:

What do you mean “without scaling”? Is it to create sides of rectangle only by initial width and height?

Yes. Instead of create(-0.5,0.5) → scale(3), you can just create(-1.5,1.5).

https://codepen.io/boytchev/full/RwdxxrO

2 Likes

An interesting box.

2024-01-29 17.38.17

The geometry can also be created in a similar way to
RoundedRectangle + Squircle
and
Round-edged box flat

Here there are circles inside and not at the corners.

1 Like

Thanks for answer! But this is not matchable for my case. I’ll think for different approach :smiley:

A modified material can be an option, where you compute coordinate’s length and check it against the desired hole radius.

1 Like

Thanks for the answer! I’m not try to do this way. Can you please provide demo or code example for achiving that result?

Here you are: Edit fiddle - JSFiddle - Code Playground

2 Likes