public void EnterFoldingMode(Vertex pickedVertex, Face nearestFace) { this.cloverController = CloverController.GetInstance(); // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为baseFace this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace); if (this.group == null) { System.Windows.MessageBox.Show("找不到Groups"); return; } this.pickedVertex = pickedVertex; this.baseFace = nearestFace; foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < baseFace.Layer) baseFace = face; } // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组 foreach (Face face in group.GetFaceList()) { if (face.Layer >= baseFace.Layer) this.facesAboveBase.Add(face); else this.facesBelowBase.Add(face); } // 保存pickedVertex的原始位置 originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z); }
public List<Face> EnterTuckingMode(Vertex pickedVertex, Face nearestFace) { this.cloverController = CloverController.GetInstance(); //cloverController.ShadowSystem.CheckUndoTree(); // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为floorFace,最上面的那个面作为ceilingFace this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace); this.pickedVertex = pickedVertex; this.floorFace = this.ceilingFace = nearestFace; // 是正向还是反向 Vector3D currNormal = group.Normal * cloverController.RenderController.Entity.Transform.Value; Double judge = Vector3D.DotProduct(currNormal, new Vector3D(0, 0, 1)); isPositive = judge < 0 ? false : true; if (isPositive) { foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < floorFace.Layer) floorFace = face; if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > ceilingFace.Layer) ceilingFace = face; } // 将同Group的面分为在floor和ceiling之间和在floor和ceiling之外两组 foreach (Face face in group.GetFaceList()) { if (face.Layer >= floorFace.Layer && face.Layer <= ceilingFace.Layer) this.facesInHouse.Add(face); else this.facesNotInHouse.Add(face); } } else { foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > floorFace.Layer) floorFace = face; if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < ceilingFace.Layer) ceilingFace = face; } // 将同Group的面分为在floor和ceiling之间和在floor和ceiling之外两组 foreach (Face face in group.GetFaceList()) { if (face.Layer <= floorFace.Layer && face.Layer >= ceilingFace.Layer) this.facesInHouse.Add(face); else this.facesNotInHouse.Add(face); } } // 保存pickedVertex的原始位置 originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z); return facesInHouse; }
public List<Face> EnterFoldingMode(Vertex pickedVertex, Face nearestFace) { this.cloverController = CloverController.GetInstance(); //cloverController.ShadowSystem.CheckUndoTree(); // 寻找同group面中拥有pickedVertex的面中最下面的那个面作为baseFace this.group = cloverController.FaceGroupLookupTable.GetGroup(nearestFace); this.pickedVertex = pickedVertex; this.baseFace = nearestFace; // 是正向还是反向 Vector3D currNormal = group.Normal * cloverController.RenderController.Entity.Transform.Value; Double judge = Vector3D.DotProduct(currNormal, new Vector3D(0, 0, 1)); isPositive = judge < 0 ? false : true; if (isPositive) { foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer < baseFace.Layer) baseFace = face; } // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组 foreach (Face face in group.GetFaceList()) { if (face.Layer >= baseFace.Layer) this.facesAboveBase.Add(face); else this.facesBelowBase.Add(face); } } else { foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face) && face.Layer > baseFace.Layer) baseFace = face; } // 将同Group的面分为在base面之上(含baseFace)和base面之下的两组 foreach (Face face in group.GetFaceList()) { if (face.Layer <= baseFace.Layer) this.facesAboveBase.Add(face); else this.facesBelowBase.Add(face); } } // 保存pickedVertex的原始位置 originPoint = new Point3D(pickedVertex.X, pickedVertex.Y, pickedVertex.Z); return facesAboveBase; }
/// <summary> /// 寻找所有要折叠(旋转)的面,放在beBlendedFaces中。 /// </summary> void FindBeBlendedFaces() { // 寻找所有与nearestFace同一group的Face group = CloverController.GetInstance().FaceGroupLookupTable.GetGroup(nearestFace); checkMask += 4; if (group == null) System.Windows.MessageBox.Show("这怎么可能?一个face居然不在group中!--Blending"); // 找到所有拥有pickedVertex的Face faceContainVertex = new List<Face>(); checkMask += 8; foreach (Face face in group.GetFaceList()) { if (CloverTreeHelper.IsVertexInFace(pickedVertex, face)) faceContainVertex.Add(face); } // 找到所有拥有pickedVertex中layer最“低”的那个面 // 这里需要加一个正负法线方向的判断 Todo Face baseFace = faceContainVertex[0]; foreach (Face face in faceContainVertex) { if (face.Layer < baseFace.Layer) baseFace = face; } // group中所有layer高于baseFace的面即为beBlendedFaces beBlendedFaces = new List<Face>(); checkMask += 16; foreach (Face face in group.GetFaceList()) { if (face.Layer >= baseFace.Layer) beBlendedFaces.Add(face); } }
/// <summary> /// 在bend前调用 /// </summary> /// <param name="faces">要bend的所有面</param> /// <param name="angle">bend的角度,角度</param> public bool BeforeBending(List<Face> faces) { if ( faces == null ) { return false; } if ( faces.Count == 0) { return false; } if (bendingParticipateGroup != null) { return false; } // 建立bending的临时组 bendingParticipateGroup = new FaceGroup( faces[ 0 ] ); for ( int i = 1; i < faces.Count; i++ ) { bendingParticipateGroup.AddFace( faces[ i ] ); } bendingParticipateGroup.SortFace(); bendingParticipateGroup.Normal = bendingParticipateGroup.GetFaceList()[ 0 ].Normal; if ( CloverMath.IsTwoVectorTheSameDir( bendingParticipateGroup.Normal, GetGroup( bendingParticipateGroup.GetFaceList()[ 0 ] ).Normal, true ) ) { IsBasicBendedFaceTheSameNormalWithItsGroup = true; } for ( int i = 0; i < faces.Count; i++ ) { RemoveFace( faces[ i ] ); } UpdateGroup(); // 判断折叠样式 return true; }
/// <summary> /// 更新整个组的面 /// </summary> /// <param name="group"></param> public void Update(FaceGroup group, Boolean autoUpdate = true) { foreach (Face face in group.GetFaceList()) { faceMeshMap[face].Geometry = NewMesh(face, autoUpdate); } }
/// <summary> /// 使纸张按组的法线方向散开 /// </summary> /// <param name="group"></param> public void DisperseLayer(FaceGroup group) { if (group == null || group.GetFaceList().Count == 0) return; List<Face> faceList = group.GetFaceList(); // 重置同组所有面的渲染点坐标 foreach (Face face in faceList) { foreach (Vertex v in face.Vertices) { v.RenderPoint = new Point3D(v.X, v.Y, v.Z); } } // 从中间向两头逼近的算法 // 旭瑜你的group里面face的layer不能保证间距均为1 // 补丁by kid int lastLayer = faceList[0].Layer; for (int i = 1; i < faceList.Count; i++) { if (faceList[i].Layer == faceList[i - 1].Layer) continue; faceList[i].Layer = ++lastLayer; } int step = 1; int baseval = step; Double pivot = (faceList[faceList.Count - 1].Layer - faceList[0].Layer) / 2.0; int up = 0, down = 0; if (faceList.Count > 1) for (int i = 0; i <= faceList.Count; i++) if (faceList[i].Layer < pivot && faceList[i + 1].Layer > pivot) { down = i; up = i + 1; break; } while (true) { Vector3D offsetVec = group.Normal * (baseval); while (up < faceList.Count) { foreach (Vertex v in faceList[up].Vertices) v.RenderPoint = v.GetPoint3D() + offsetVec; if (up + 1 == faceList.Count || faceList[up].Layer != faceList[up + 1].Layer) break; up++; } up++; while (down > -1) { foreach (Vertex v in faceList[down].Vertices) v.RenderPoint = v.GetPoint3D() - offsetVec; if (down - 1 == -1 || faceList[down].Layer != faceList[down - 1].Layer) break; down--; } down--; baseval += step; if (up >= faceList.Count && down <= -1) break; } //// sb算法 //int step = 6; //Vector3D offsetVec = group.Normal * step; //foreach (Face f in faceList) //{ // foreach (Vertex v in f.Vertices) // { // v.RenderPoint += f.Layer * offsetVec; // } //} //// 以当前总层数作为依据,指定offset值 //int step = 6; ////int step = 1; //// 从faceList的两头向中间逼近,逐层计算偏移量 //Dictionary<Vertex, int> historyOffset = new Dictionary<Vertex, int>();// 这蛋疼的玩意记录了每个点的历史偏移量。一个顶点不可以两次偏向同一方向 //int bottom = 0; //int top = faceList.Count - 1; //int offset = (faceList[top].Layer - faceList[bottom].Layer) * step; //while (top >= bottom) //{ // Vector3D offVec = group.Normal * -offset; // while (true) // { // foreach (Vertex v in faceList[bottom].Vertices) // { // v.RenderPoint += offVec; // //if (!historyOffset.ContainsKey(v)) // //{ // // v.RenderPoint += offVec; // // historyOffset[v] = -offset; // //} // //else // //{ // // if (historyOffset[v] == 0) // // { // // v.RenderPoint += offVec; // // historyOffset[v] = -offset; // // } // // else if (historyOffset[v] + offset == 0) // // { // // v.RenderPoint += offVec; // // historyOffset[v] = 0; // // } // //} // } // bottom++; // if (bottom + 1 > top || faceList[bottom].Layer != faceList[bottom + 1].Layer) // break; // } // offVec *= -1; // while (true) // { // foreach (Vertex v in faceList[top].Vertices) // { // v.RenderPoint += offVec; // //if (!historyOffset.ContainsKey(v)) // //{ // // v.RenderPoint += offVec; // // historyOffset[v] = offset; // //} // //else // //{ // // if (historyOffset[v] == 0) // // { // // v.RenderPoint += offVec; // // historyOffset[v] = offset; // // } // // else if (historyOffset[v] - offset == 0) // // { // // v.RenderPoint += offVec; // // historyOffset[v] = 0; // // } // //} // } // top--; // if (top - 1 < bottom || faceList[top].Layer != faceList[top - 1].Layer) // break; // } // offset -= step; //} }