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> /// 退出Blending模式 /// </summary> public void ExitBlendingMode() { pickedVertex = null; nearestFace = null; foldLine = null; group = null; beBlendedFaces = null; faceContainVertex = null; checkMask = 0; // 更新组 CloverController.GetInstance().FaceGroupLookupTable.UpdateTableAfterBending(11); // 反重叠 RenderController.GetInstance().AntiOverlap(); }
/// <summary> /// 判断一个面是否在一个组中 /// </summary> /// <param name="face"></param> /// <param name="group"></param> /// <returns></returns> public static Boolean IsFaceInGroup(Face face, FaceGroup group) { // 等待杨旭瑜写完group,。。。 // todo return false; }
/// <summary> /// 返回一个组的基面,用以计算其他面的渲染偏差量 /// </summary> /// <param name="group"></param> public static Face FindBaseFace(FaceGroup group) { //todo return null; }
/// <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); } }
bool AddGroup( FaceGroup fg ) { foreach ( FaceGroup fgin in faceGroupList ) { // 判断组里面是否已经有了这样的组 if ( CloverMath.IsTwoVectorTheSameDir( fg.Normal, fgin.Normal ) ) { return false; } } faceGroupList.Add( fg ); return true; }
/// <summary> /// 往lookuptable中加入face,会自动匹配加入group中或新增group。 /// 否则强制新建一个group /// </summary> /// <param name="f"></param> void AddFace( Face f ) { foreach ( FaceGroup fg in faceGroupList ) { if ( fg.HasFace( f ) ) { return; } if ( fg.IsMatch( f ) ) { fg.AddFace( f ); return; } } FaceGroup newfgt = new FaceGroup( f ); faceGroupList.Add( newfgt ); }
/// <summary> /// 在foldup后更lookuptable /// </summary> /// <param name="participatedGroup">参与折叠的面</param> /// <param name="movedFaceGroup">所有移动的面</param> /// <param name="fixedFaceGroup">所有不动的面</param> /// <param name="IsFacingUser">是否组的法线面向用户</param> /// <returns></returns> public bool UpdateTableAfterFoldUp( List<Face> participatedFaces, List<Face> movedFaces, List<Face> fixedFaces, bool IsFacingUser = true ) { if (movedFaces.Count == 0) return false; RemoveRedundantFaceGroup(); FaceGroup participatedGroup = GetGroup( participatedFaces[ 0 ] ); FaceGroup movedFaceGroup = new FaceGroup( movedFaces[ 0 ] ); FaceGroup fixedFaceGroup = new FaceGroup( fixedFaces[ 0 ] ); foreach ( Face f in movedFaces ) { if ( !movedFaceGroup.HasFace( f ) ) { movedFaceGroup.AddFace( f ); } } foreach ( Face f in fixedFaces ) { if ( !fixedFaceGroup.HasFace( f ) ) { fixedFaceGroup.AddFace( f ); } } foreach ( Face fp in participatedGroup.GetFaceList() ) { if ( fp.LeftChild == null && fp.RightChild == null ) { if ( !movedFaceGroup.HasFace( fp ) && !fixedFaceGroup.HasFace( fp ) ) { fixedFaceGroup.AddFace( fp ); } } } fixedFaceGroup.SortFace(); fixedFaceGroup.Normal = participatedGroup.Normal; return participatedGroup.UpdateGroupAfterFoldUp( participatedGroup, movedFaceGroup, fixedFaceGroup, IsFacingUser ); }
/// <summary> /// bend后调用来更新lookuptable /// </summary> /// <returns></returns> public bool UpdateTableAfterBending(double angle, bool IsFacingUser = true) { BendTpye bendtype; if ( Math.Abs( angle ) < 0.00001 ) // 适应误差 { bendtype = BendTpye.BlendZero; } else if ( Math.Abs( angle ) <= 180 && Math.Abs( angle ) >= 179.999999999999 )// 适应误差 { bendtype = BendTpye.BlendSemiCycle; } else { bendtype = BendTpye.BlendNormally; } if (bendtype == BendTpye.BlendZero) { return true; } FaceGroup participateGroup = null; // bend半周即180度 if (bendtype == BendTpye.BlendSemiCycle) { // 找到相关的组 foreach (FaceGroup fg in faceGroupList) { if ( CloverMath.IsTwoVectorTheSameDir(fg.Normal, bendingParticipateGroup.Normal)) { if (participateGroup == null) { participateGroup = fg; } else if ( participateGroup != fg) { return false;// 一次只可能有一个组参与 } } } faceGroupList.Remove( participateGroup ); bendingParticipateGroup.RevertFaces(); foreach (Face f in bendingParticipateGroup.GetFaceList()) { participateGroup.RemoveFace( f ); } participateGroup.SortFace(); bendingParticipateGroup.SortFace(); // 判断用户的方向: if ( IsFacingUser ) // 组的正面面向用户 { // 逆序从上贴合 int layer = 0; int lastlayer = 0; layer = participateGroup.GetTopLayer() + 1; // 根据是否覆盖来调整layer的值 for ( int i = participateGroup.GetFaceList().Count - 1; i >= 0; i-- ) { if ( !CloverMath.IsIntersectionOfTwoFaceOnOnePlane( bendingParticipateGroup.GetFaceList()[ bendingParticipateGroup.GetFaceList().Count - 1 ], participateGroup.GetFaceList()[ i ] ) ) { layer--; } else if ( i == participateGroup.GetFaceList().Count - 1 ) { break; } } lastlayer = bendingParticipateGroup.GetTopLayer(); for ( int i = bendingParticipateGroup.GetFaceList().Count - 1; i >= 0; i-- ) { if ( bendingParticipateGroup.GetFaceList()[ i ].Layer == lastlayer) { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } else { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; layer++; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } participateGroup.AddFace( bendingParticipateGroup.GetFaceList()[ i ] ); } } else // 组背向用户 { int layer = 0; int lastlayer = 0; layer = participateGroup.GetBottomLayer() + 1; for ( int i = 0; i < participateGroup.GetFaceList().Count; i++ ) { if ( !CloverMath.IsIntersectionOfTwoFaceOnOnePlane( bendingParticipateGroup.GetFaceList()[ 0 ], participateGroup.GetFaceList()[ i ] ) ) { layer++; } else if (i == 0) { break; } } lastlayer = bendingParticipateGroup.GetBottomLayer(); for ( int i = 0; i < bendingParticipateGroup.GetFaceList().Count; i++ ) { if ( bendingParticipateGroup.GetFaceList()[ i ].Layer == lastlayer ) { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } else { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; layer--; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } participateGroup.AddFace( bendingParticipateGroup.GetFaceList()[ i ] ); } } faceGroupList.Add( participateGroup ); } // 非180度的折叠 if (bendtype == BendTpye.BlendNormally) { if ( !IsBasicBendedFaceTheSameNormalWithItsGroup ) // 新组与原来的组排序方向不同,里面的面的顺序必须倒置 { bendingParticipateGroup.RevertFaces(); } // 更新参与bend的新组的法线 bendingParticipateGroup.Normal = bendingParticipateGroup.GetFaceList()[0].Normal; // 寻找是否会和某个组重合 foreach (FaceGroup fg in faceGroupList) { if ( CloverMath.IsTwoVectorTheSameDir( fg.Normal, bendingParticipateGroup.Normal )) { if ( fg == bendingParticipateGroup) { continue; } if ( participateGroup == null ) { participateGroup = fg; } else if ( participateGroup != fg ) { return false; } } } if (participateGroup == null) { FaceGroup newgroup = (FaceGroup)bendingParticipateGroup.Clone(); AddGroup( newgroup ); bendtype = BendTpye.BlendZero; bendingParticipateGroup = null; return true; // 很幸运,没有什么组跟你重合 } // 有和某个组巧妙地重合: // 判断自己组的排序方向和对方是不是一样的 if ( !CloverMath.IsTwoVectorTheSameDir( participateGroup.Normal, bendingParticipateGroup.Normal, true ) ) { bendingParticipateGroup.RevertFaces(); } if ( IsFacingUser )// 用户面向对方的组 { // 从上贴合 int layer = 0; int lastlayer = 0; // 根据是否覆盖来调整layer的值 for ( int i = participateGroup.GetFaceList().Count - 1; i >= 0; i-- ) { if ( !CloverMath.IsIntersectionOfTwoFaceOnOnePlane( bendingParticipateGroup.GetFaceList()[ bendingParticipateGroup.GetFaceList().Count - 1 ], participateGroup.GetFaceList()[ i ] ) ) { layer--; } else if ( i == participateGroup.GetFaceList().Count - 1 ) { break; } } layer = bendingParticipateGroup.GetTopLayer() + 1; lastlayer = bendingParticipateGroup.GetBottomLayer(); for ( int i = 0; i < bendingParticipateGroup.Count; i++ ) { if ( bendingParticipateGroup.GetFaceList()[ i ].Layer == lastlayer) { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } else { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; layer++; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } participateGroup.AddFace( bendingParticipateGroup.GetFaceList()[ i ] ); } } else { // 从下贴合 int layer = 0; int lastlayer = 0; layer = participateGroup.GetBottomLayer(); layer--; for ( int i = 0; i < participateGroup.GetFaceList().Count; i++ ) { if ( !CloverMath.IsIntersectionOfTwoFaceOnOnePlane( bendingParticipateGroup.GetFaceList()[ 0 ], participateGroup.GetFaceList()[ i ] ) ) { layer++; } else if (i == 0) { break; } } lastlayer = participateGroup.GetTopLayer(); for ( int i = bendingParticipateGroup.GetFaceList().Count - 1; i >= 0; i-- ) { if (bendingParticipateGroup.GetFaceList()[ i ].Layer == lastlayer) { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } else { lastlayer = bendingParticipateGroup.GetFaceList()[ i ].Layer; layer--; bendingParticipateGroup.GetFaceList()[ i ].Layer = layer; } participateGroup.AddFace( bendingParticipateGroup.GetFaceList()[ i ] ); } } faceGroupList.Add( participateGroup ); } bendtype = BendTpye.BlendZero; bendingParticipateGroup = null; return true; }
/// <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="f"></param> public FaceGroupLookupTable( Face f ) { FaceGroup g = new FaceGroup( f ); faceGroupList.Add( g ); }
/// <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; //} }