wedge

In many digital twin projects, floor modeling is involved. Due to the variety of structures in the modeling of floors, if all modelers do manual modeling, the workload will be relatively large. The structure of the floor itself can be abstracted into objects that can be constructed through paths (similar to the pipelines and roads mentioned in the previous article), which is convenient for us to generate room floors through code.

Wall geometry object PathCubeGeometry

The floor is generally divided into two parts: wall and floor. First, let's look at the wall object. Based on threejs, extend a geometry object PathCubeGeometry. The object constructs the geometry of a wall through a Path3D path. The geometry can be divided into several surface groups such as start, end, top, bottom, outside, inside, etc., so that it is convenient to set different inner and outer surfaces, as well as the top surface, etc. The effect of the texture map. The main code is as follows:

 this.vert = vert;
    this.rawUV = rawUV;
    this.pathU = pathU;

    this.indices =  []
    this.vertices = [];
    this.uvs = [],
    this.normals = [];

    this.generateSideWall(vert,inner,outer,innerTop, outerTop, true,closed);
    this.generateSideWall(vert,inner,outer,innerTop, outerTop, false,closed);


    this.generateTopBottom(vert,inner,outer,innerTop,outerTop,true,closed);
    this.generateTopBottom(vert,inner,outer,innerTop,outerTop,false,closed);

    if(!closed) {
        this.generateAZSide(vert,inner,outer,innerTop,outerTop,true);
        this.generateAZSide(vert,inner,outer,innerTop,outerTop,false);
    }

Through PathCubeGeometry, we can easily build walls, such as the following sample code:

 const materials = [m1, m2, m3, m3, m3, m3];
const points = json.outerWall.path;
const p0 = points[0];
const path = new Path3D();
const scale = 20;
path.moveTo(p0.x * scale, p0.y * scale, p0.z * scale);
for (let i = 1; i < points.length; i++) {
let p = points[i];
    path.lineTo(p.x * scale, p.y * scale, p.z * scale);
}
path.closePath();
cosnt patCube = new PathCubeGeometry(path, 10, 50, 32, 500);
const mesh = new dt.Mesh(patCube, materials);

First construct a path through Path3D (the path is derived from a series of incoming points), then construct a combined object PathCubeGeometry through the path, and finally generate an entity, the effect is shown in the following figure:

image.png

doors and windows

It is not difficult to construct doors and windows, and they can generally be generated by means of cubes and maps. For example, the following code can generate a double door:

 function createDoor(pos) {
  var cube = new CubeGeometry(200, 400, 5);
  var material = createMaterial(graph, {
    color: 0xffffff,
    flatShading: true,
    map: "./images/glass-wall6.png",
    transparent: true,
  });

  material.map.repeat.set(0.5, 1);
  var leftDoor = new Mesh(cube, material);
  leftDoor.position.copy(pos.clone().sub(new Vec3(100)));
  leftDoor.attr("type", "left_door");
  leftDoor._type = "left_door";
  dataModel.add(leftDoor);

  var rightDoor = new Mesh(cube, material);
  rightDoor.position.copy(pos.clone().add(new Vec3(100)));
  rightDoor._type = "right_door";
  dataModel.add(rightDoor);
}

The effect of the created door is shown in the following figure:

image.png

The idea of creating single doors and windows is the same. But the difficulty is where the doors and windows are located, and the wall itself needs to be dug. Digging a hole requires the use of the BSP function.

BSP digging holes

The BSP operation can perform the operation of intersection union and difference set on the model. To dig a hole in a wall, you can do a subtraction operation on the geometry of the wall, such as subtracting a cube, which creates a square hole in the wall.
On THREEJS, there is an open source BSP package, THREEBSP.

The code looks like this:

 var csg = new CSG().setFromGeometry(patCube);
var csg2 = new CSG().setFromGeometry(cubeGeometry);
var csg3 = new CSG().setFromGeometry(cubeGeometry2);
csg.subtractOperand(csg2);
csg.subtractOperand(csg3);
var geometry = csg.toGeometry();
var mesh = new Mesh(geometry, materials);

The final result is shown in the figure below:

image.png

After placing the created doors and windows in the corresponding digging positions, the effect is as follows:

image.png

Create the floor

In threejs, the geometry of the floor can be created through ExtrudeGeometry, and then the material of the floor can be specified, which can create a floor object. The code is as follows:

 var path = new ShapePath();
  var texture = graph.loadTexture("./images/floor.jpg", {
    wrapT: RepeatWrapping,
    wrapS: RepeatWrapping,
  });
  texture.repeat.set(1 / 400, 1 / 400);
  texture.anisotropy = 16;

  let m1 = new BasicMaterial({
    map: texture,
    color: 0xffffff,
    toneMapped: false,
  });
  const simpleShapes = path.toShapes(true);

  var geometry = new ExtrudeGeometry(simpleShapes, {
    depth: 1,
    bevelEnabled: false,
    vertical: true,
  });
  var mesh = new Mesh(geometry, [m1, m1]);
  dataModel.add(mesh);

The final effect looks like this:

image.png

Epilogue

This article introduces the function of generating floors through code, which uses PathCubeGeometry, ExtrudeGeometry, and BSP related technologies. Among them, PathCubeGeometry needs to be built by itself, which will be difficult later; ExtrudeGeometry is an object that exists in threejs itself, and BSP can also find open source packages. use.

If you have good ideas, you are also welcome to communicate with me. Follow the official account "ITMan Biao Shu", you can add the author's WeChat to communicate, and receive more valuable articles in time.


netcy
204 声望120 粉丝

欢迎对canvas、webgl、图形学感兴趣的读者订阅专栏。