/// <summary> /// Chamfers the specified corner (experimental code). /// </summary> /// <param name="p"> /// The corner point. /// </param> /// <param name="d"> /// The chamfer distance. /// </param> /// <param name="eps"> /// The corner search limit distance. /// </param> /// <param name="chamferPoints"> /// If this parameter is provided, the collection will be filled with the generated chamfer points. /// </param> public void ChamferCorner(Point3D p, double d, double eps = 1e-6, IList<Point3D> chamferPoints = null) { this.NoSharedVertices(); this.normals = null; this.textureCoordinates = null; var cornerNormal = this.FindCornerNormal(p, eps); var newCornerPoint = p - (cornerNormal * (float)d); int index0 = this.positions.Count; this.positions.Add(newCornerPoint); var plane = new Plane3D(newCornerPoint, cornerNormal); int ntri = this.triangleIndices.Count; for (int i = 0; i < ntri; i += 3) { int i0 = i; int i1 = i + 1; int i2 = i + 2; var p0 = this.positions[this.triangleIndices[i0]]; var p1 = this.positions[this.triangleIndices[i1]]; var p2 = this.positions[this.triangleIndices[i2]]; var d0 = (p - p0).LengthSquared(); var d1 = (p - p1).LengthSquared(); var d2 = (p - p2).LengthSquared(); var mind = Math.Min(d0, Math.Min(d1, d2)); if (mind > eps) { continue; } if (d1 < eps) { i0 = i + 1; i1 = i + 2; i2 = i; } if (d2 < eps) { i0 = i + 2; i1 = i; i2 = i + 1; } p0 = this.positions[this.triangleIndices[i0]]; p1 = this.positions[this.triangleIndices[i1]]; p2 = this.positions[this.triangleIndices[i2]]; // p0 is the corner vertex (at index i0) // find the intersections between the chamfer plane and the two edges connected to the corner var line1 = new Ray(p0, p1 - p0); var line2 = new Ray(p0, p2 - p0); Point3D p01, p02; if (!plane.Intersects(ref line1, out p01)) { continue; } if (!plane.Intersects(ref line2, out p02)) { continue; } if (chamferPoints != null) { // add the chamfered points if (!chamferPoints.Contains(p01)) { chamferPoints.Add(p01); } if (!chamferPoints.Contains(p02)) { chamferPoints.Add(p02); } } int i01 = i0; // change the original triangle to use the first chamfer point this.positions[this.triangleIndices[i01]] = p01; int i02 = this.positions.Count; this.positions.Add(p02); // add a new triangle for the other chamfer point this.triangleIndices.Add(i01); this.triangleIndices.Add(i2); this.triangleIndices.Add(i02); // add a triangle connecting the chamfer points and the new corner point this.triangleIndices.Add(index0); this.triangleIndices.Add(i01); this.triangleIndices.Add(i02); } this.NoSharedVertices(); }