foreword
Pipe displays are common in 3D scenes. Such as the display of underground pipe networks, fruits in buildings, HVAC pipes, etc.
There are two main ways to build pipelines:
- Modeling through modeling tools such as 3DMax C4D Blender.
- From the path data, the program generates a three-dimensional pipeline.
If you need to generate pipelines dynamically through data, you can only use the second way to generate.
How the pipeline is generated
In THREE, pipelines can be generated through TubeGeometry.
TubeGeometry extrudes a tube along a 3D spline. Paths can be defined by specifying vertices. The following parameters can be entered when creating a TubeGeometry pipe geometry:
- path (required) This property uses a THREE.SplineCurve object to specify the path the pipeline follows
- segments This attribute specifies the number of segments of the pipeline. The longer the path, the more segments should be specified. The default value is 64.
- radius This property specifies the radius of the pipe, the default value is 1
- radiusSegments No This attribute specifies the number of segments of the pipe section, the more the number of segments, the smoother the pipe looks, the default value is 8
- closed
- This property is used to set whether the pipeline ends the connection, the default value is false
for example:
const points = [{
x: 0,
y: 0,
z: 0
},
{
x: 100,
y: 0,
z: 0
},
{
x: 100,
y: 0,
z: 200
},
];
const path = createPath(points);
const pipeGeometry = new THREE.TubeGeometry(path, 256, radius, 64);
const pipeMaterial = new THREE.MeshPhongMaterial({
color
});
const pipe = new THREE.Mesh(pipeGeometry, pipeMaterial);
The effect is as follows:
Optimization of TubeGeometry
TubeGeometry creates the geometry of the tube by specifying a path and the number of segments. The segments of TubeGeometry are evenly distributed, which causes a problem. If the path is long and complex, the number of segments needs to be large to ensure the accuracy of the geometry. However, the lines are mostly straight, with only a few curved lines. If there is a straight pipeline, in fact, you only need to take the starting point and introduction point of the path to describe the path completely. Only the curved pipeline needs to divide the path into many ends, and take the data of each segment point separately. In order to better complete the description of the curve. If the average segmentation method is adopted, there will inevitably be many segments falling on the straight line, which will lead to waste of resources. At the same time, the number of segments is required to be high, and the created geometric data will be relatively large and bloated, which will affect the loading of the program, rendering efficiency, video memory, etc. . For example, the following series of points all form two straight lines:
const points = [{
x: 0,
y: 0,
z: 0
},
{
x: 100,
y: 0,
z: 0
},
{
x: 100,
y: 0,
z: 200
},
];
When the number of segments is 4:
new THREE.TubeGeometry(path, 4, radius, 64);
The result is the following:
Originally two straight lines have become three straight lines, because the number of shards is not enough:
Increase the number of segments:
new THREE.TubeGeometry(path, 256, radius, 64);
The effect is as follows:
In order to draw a path composed of two straight lines, 256 segments are required, and the number of vertices can be imagined.
So we can have an optimization idea. For the straight part of the path, we don't need to segment, we only need to go to the starting point and the end point, and the number of segments is only allocated to the part of the curve. Such a segmentation method can be applied with the most reasonable number of segments. Based on this, we transformed a new class: PathTubeGeometry.
The transformed class draws the above two straight lines without the number of shards (the number of shards is 1), as follows:
new PathTubeGeometry(path, 1, radius, 64);
Great saving of resources.
corner elbow
Where two straight lines are connected, the aesthetics of the pipeline can be increased by adding a little rounded corner effect. The following code can automatically generate a path with elbows according to the existing path.
function getRoundCornerPath(oldPath, radius, path = new Path3D()) {
let points = oldPath.points;
points = removeDup(points);
let p0 = points[0];
path.moveTo(p0);
for (let i = 1; i < points.length - 1; i++) {
let pre = points[i - 1],
p = points[i],
next = points[i + 1];
let sub1 = p.clone().sub(pre).setLength(radius),
sub2 = next.clone().sub(p).setLength(radius);
let v1 = p.clone().sub(sub1),
v2 = p.clone().add(sub2);
path.lineTo(v1);
path.curveTo(p.x, p.y, p.z, v2.x, v2.y, v2.z);
}
let pl = points[points.length - 1];
path.lineTo(pl);
return path;
}
Epilogue
Follow the official account "ITMan Biao Shu", you can add the author's WeChat to communicate, and receive more valuable articles in time.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。