/// <summary> /// 合并小三角形为大三角形 /// </summary> public void MergeNeighbors() { int faceNum = weak_faceFs.Count; for (int i = 0; i < faceNum; i++) { for (int j = 0; j < faceNum; j++) { if (i == j) { continue; } FaceF fa = weak_faceFs[i]; FaceF fb = weak_faceFs[j]; if (fa.SameFace(fb) || !fa.SamePlane(fb)) { continue; } if (FaceF.TryConfirmNeighbor(fa, fb, out int faC, out int fbC)) { fa.Vertices[faC] = fb.Vertices[(fbC + 2) % 3]; fb.SetParent(fa); // 根节点是 fa } } } }
public void SetParent(FaceF parent) { if (IsRoot()) { root = parent.Root; } else { Root.SetParent(parent); } }
public bool SameFace(FaceF another) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (!SameVector(Vertices[i], another.Vertices[j])) { return(false); } } } return(true); }
private bool disposedValue = false; // 要检测冗余调用 protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: 释放托管状态(托管对象)。 weak_vertices.Dispose(); weak_vertices = null; ObjectPool <FaceF> .Recycle(this); } // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。 // TODO: 将大型字段设置为 null。 root = null; disposedValue = true; } }
/// <summary> /// 确定两个面是否可以合并 /// </summary> /// <param name="fa"></param> /// <param name="fb"></param> /// <param name="faCommon">共同点的下标 i,另一个下标为 (i+2)%3</param> /// <param name="fbCommon">共同点的下标 j,另一个下标为 (j+1)%3</param> /// <returns></returns> public static bool TryConfirmNeighbor(FaceF fa, FaceF fb, out int faCommon, out int fbCommon) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (SameVector(fa.Vertices[i], fb.Vertices[j]) && SameVector(fa.Vertices[(i + 2) % 3], fb.Vertices[(j + 1) % 3]) && V3Collinear(fa.Vertices[(i + 1) % 3], fa.Vertices[i], fb.Vertices[(j + 2) % 3])) { faCommon = i; fbCommon = j; return(true); } } } faCommon = -1; fbCommon = -1; return(false); }
public static bool FaceClearOf(FaceF fa, FaceF fb, float epsilon = float.Epsilon) { Vector3 getMin(IList <Vector3> vs) { return(new Vector3(Mathf.Min(vs[0].x, vs[1].x, vs[2].x), Mathf.Min(vs[0].y, vs[1].y, vs[2].y), Mathf.Min(vs[0].z, vs[1].z, vs[2].z))); } Vector3 getMax(IList <Vector3> vs) { return(new Vector3(Mathf.Max(vs[0].x, vs[1].x, vs[2].x), Mathf.Max(vs[0].y, vs[1].y, vs[2].y), Mathf.Max(vs[0].z, vs[1].z, vs[2].z))); } Vector3 faMin = getMin(fa.Vertices); Vector3 faMax = getMax(fa.Vertices); Vector3 fbMin = getMin(fb.Vertices); Vector3 fbMax = getMax(fb.weak_vertices); return(faMin.x > fbMax.x + epsilon || faMax.x < fbMin.x - epsilon || faMin.y > fbMax.y + epsilon || faMax.y < fbMin.y - epsilon || faMin.z > fbMax.z + epsilon || faMax.z < fbMin.z - epsilon); }
public bool SamePlane(FaceF another) { return(SameVector(PlaneNormal, another.PlaneNormal) && Mathf.Abs(DisOrigin2plane - another.DisOrigin2plane) < TOL); }