EdgesGeometry constructor
EdgesGeometry(
- BufferGeometry geometry,
- double? thresholdAngle
Implementation
EdgesGeometry(BufferGeometry geometry, double? thresholdAngle) : super() {
type = "EdgesGeometry";
parameters = {"thresholdAngle": thresholdAngle};
thresholdAngle = (thresholdAngle != null) ? thresholdAngle : 1;
//final precisionPoints = 4;
//final precision = math.pow(10, precisionPoints);
final thresholdDot = math.cos((math.pi/180) * thresholdAngle);
final indexAttr = geometry.getIndex();
final positionAttr = geometry.getAttribute(Attribute.position);
final indexCount = indexAttr != null ? indexAttr.count : positionAttr.count;
final indexArr = [0, 0, 0];
final vertKeys = ['a', 'b', 'c'];
Map hashes = {};
final edgeData = {};
List<double> vertices = [];
for (int i = 0; i < indexCount; i += 3) {
if (indexAttr != null) {
indexArr[0] = indexAttr.getX(i)!.toInt();
indexArr[1] = indexAttr.getX(i + 1)!.toInt();
indexArr[2] = indexAttr.getX(i + 2)!.toInt();
} else {
indexArr[0] = i;
indexArr[1] = i + 1;
indexArr[2] = i + 2;
}
final a = _triangle.a;
final b = _triangle.b;
final c = _triangle.c;
a.fromBuffer(positionAttr, indexArr[0]);
b.fromBuffer(positionAttr, indexArr[1]);
c.fromBuffer(positionAttr, indexArr[2]);
_triangle.getNormal(_normal);
// create hashes for the edge from the vertices
hashes[0] = "${a.x},${a.y},${a.z}";
hashes[1] = "${b.x},${b.y},${b.z}";
hashes[2] = "${c.x},${c.y},${c.z}";
// skip degenerate triangles
if (hashes[0] == hashes[1] ||
hashes[1] == hashes[2] ||
hashes[2] == hashes[0]) {
continue;
}
// iterate over every edge
for (int j = 0; j < 3; j++) {
// get the first and next vertex making up the edge
final jNext = (j + 1) % 3;
final vecHash0 = hashes[j];
final vecHash1 = hashes[jNext];
final v0 = _triangle[vertKeys[j]];
final v1 = _triangle[vertKeys[jNext]];
final hash = "${vecHash0}_$vecHash1";
final reverseHash = "${vecHash1}_$vecHash0";
if (edgeData.containsKey(reverseHash) &&
edgeData[reverseHash] != null) {
// if we found a sibling edge add it into the vertex array if
// it meets the angle threshold and delete the edge from the map.
if (_normal.dot(edgeData[reverseHash]["normal"]) <= thresholdDot) {
vertices
.addAll([v0.x.toDouble(), v0.y.toDouble(), v0.z.toDouble()]);
vertices
.addAll([v1.x.toDouble(), v1.y.toDouble(), v1.z.toDouble()]);
}
edgeData[reverseHash] = null;
} else if (!(edgeData.containsKey(hash))) {
// if we've already got an edge here then skip adding a new one
edgeData[hash] = {
"index0": indexArr[j],
"index1": indexArr[jNext],
"normal": _normal.clone(),
};
}
}
}
// iterate over all remaining, unmatched edges and add them to the vertex array
for (final key in edgeData.keys) {
if (edgeData[key] != null) {
final ed = edgeData[key];
final index0 = ed["index0"];
final index1 = ed["index1"];
_v0.fromBuffer(positionAttr, index0);
_v1.fromBuffer(positionAttr, index1);
vertices.addAll([_v0.x.toDouble(), _v0.y.toDouble(), _v0.z.toDouble()]);
vertices.addAll([_v1.x.toDouble(), _v1.y.toDouble(), _v1.z.toDouble()]);
}
}
setAttribute(Attribute.position,Float32BufferAttribute.fromList(vertices, 3, false));
}