public void SegPostProcess() { DebugMethod.slicerUniformAll = new List <List <SlicerRecordUniform> >(); DebugMethod.slicerAll = new List <List <SlicerRecord> >(); bodypart[] bdparr = (bodypart[])Enum.GetValues(typeof(bodypart)); List <SlicerRecord>[] bodySlicerGroup = new List <SlicerRecord> [(int)bodypart.PartCount]; for (int i = 0; i < (int)bodypart.PartCount; i++) { List <SlicerRecord> slicerSeq; bodypart bdt = bdparr[i]; CreateSlicerSequence(bdt, interval, out slicerSeq); bodySlicerGroup[i] = slicerSeq; } AddtionCreateSlicer(bodySlicerGroup); for (int i = 0; i < (int)bodypart.PartCount; i++) { List <SlicerRecord> slicerSeq = bodySlicerGroup[i]; int n = (int)bodypart.Torso == i ? 20 : // 密集 30 10 10 18 (int)bodypart.Arm_0 == i ? 10 : (int)bodypart.Arm_1 == i ? 10 : 18; bodypart bdt = bdparr[i]; List <SlicerRecordUniform> radialSlicer = RadialSlicerCut(slicerSeq, n); // TrickForSegment.PostEliminateChestGap(radialSlicer, bdparr[i]); // display foreach (SlicerRecordUniform sru in radialSlicer) { sru.lable = i; } DebugMethod.slicerUniformAll.Add(radialSlicer); //DebugMethod.slicerAll.Add(slicerSeq); WriteToSlicFile(radialSlicer, bdt); } }
// 把这个当作主要的处理函数 public void CreateSlicerSequence(bodypart bdt, double interval, out List <SlicerRecord> slicerSeq) { slicerSeq = new List <SlicerRecord>(); if (bdt == bodypart.Arm_0 || bdt == bodypart.Arm_1) { CreateArmSlicerSequence(bdt, interval, slicerSeq); return; } List <int> skeletonSeq = partSkelSeq[(int)bdt]; #region compute interval: output pSkeLen double pSkeLen = 0.0; for (int i = 0; i < skeletonSeq.Count - 1; i++) { pSkeLen += (skeRcd.nodePosList[skeletonSeq[i + 1]] - skeRcd.nodePosList[skeletonSeq[i]]).Length(); } interval = pSkeLen / (Math.Floor(pSkeLen / interval)) + interval / 200; #endregion Vector3d nodeNV; Vector3d nodepos; Plane nodePlane; double globalPos = 0.0; // 整个骨架序列线段中的位置 double skeLineAddup = 0.0; // 单个骨架线中的位置 int skeLineIndex = 0; // 骨架序列索引 // start point nodeNV = skeRcd.nodePosList[skeletonSeq[1]] - skeRcd.nodePosList[skeletonSeq[0]]; nodePlane = new Plane(skeRcd.nodePosList[skeletonSeq[0]], nodeNV); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); globalPos += interval; skeLineAddup = (skeRcd.nodePosList[skeletonSeq[1]] - skeRcd.nodePosList[skeletonSeq[0]]).Length(); // medial points // 总的不超过整个seq do { int currStartIndex = skeletonSeq[skeLineIndex]; int currEndIndex = skeletonSeq[skeLineIndex + 1]; double currLineLen = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Length(); for (; skeLineAddup < globalPos;) { skeLineIndex++; currStartIndex = skeletonSeq[skeLineIndex]; currEndIndex = skeletonSeq[skeLineIndex + 1]; currLineLen = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Length(); skeLineAddup += currLineLen; }// 循环停止的结果:skeLineAddup>=globalPos skeLineIndex指向超过globalpos的那个线段 nodepos = (1 - (skeLineAddup - globalPos) / currLineLen) * (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]) + skeRcd.nodePosList[currStartIndex]; nodeNV = skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]; nodePlane = new Plane(nodepos, nodeNV); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); globalPos += interval; } while (globalPos < pSkeLen); //end point nodeNV = skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 1]] - skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 2]]; nodePlane = new Plane(skeRcd.nodePosList[skeletonSeq.Last()], nodeNV); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); SlicerSeqPruning(ref slicerSeq, bdt); }
void drawbody(bodypart bp) { if (bp == bodypart.l_eyes) textBox3.Text = "x"; else if (bp == bodypart.r_eyes) textBox4.Text = "x"; else if (bp == bodypart.body) textBox5.Text = "x"; else if (bp == bodypart.l_leg) textBox6.Text = "x"; else if (bp == bodypart.r_leg) textBox7.Text = "x"; }
/// <summary> /// 与 createsequence函数搭配使用,因此在s上不需要进行分割 /// </summary> /// <param name="s"></param> /// <param name="bdt"></param> private void SlicerSeqPruning(ref List <SlicerRecord> s, bodypart bdt) { switch (bdt) { case bodypart.Head: /* HeadSeqPrune(ref s);*/ break; case bodypart.Torso: { int ct; TorsoSeqPrune(s, out ct); TrickForSegment.chest = new Plane(s[ct].skeletonNodepos, s[ct].slicerNormal); TrickForSegment.navel = new Plane(s.Last().skeletonNodepos, s.Last().slicerNormal); break; } case bodypart.Arm_0: ArmSeqPrune(ref s); break; case bodypart.Arm_1: ArmSeqPrune(ref s); break; case bodypart.Leg_0: LegSeqPrune(ref s); break; case bodypart.Leg_1: LegSeqPrune(ref s); break; } }
/// <summary> /// 这个函数是用来对手臂上的分片进行特殊处理的,是CreateSlicerSequence的分支,后面还需要对躯干与手臂进行交叉 /// </summary> /// <param name="bdt"></param> /// <param name="interval"></param> /// <param name="slicerSeq"></param> private void CreateArmSlicerSequence(bodypart bdt, double interval, List <SlicerRecord> slicerSeq) { List <int> skeletonSeq = partSkelSeq[(int)bdt]; int foreArmIndex = skeletonSeq.Count / 8 - 1; Vector3d torso2ArmDir = skeRcd.nodePosList[skeletonSeq[foreArmIndex]] - skeRcd.nodePosList[skeletonSeq[0]]; // 得到初始的法向量 Vector3d armEndDir = skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 1]] - skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 2]]; // 得到末端的法向量 #region get the length of skeleton and compute two intervals of relative slicer sknode. double pSkeLen = 0.0; for (int i = 0; i < skeletonSeq.Count - 1; i++) { pSkeLen += (skeRcd.nodePosList[skeletonSeq[i + 1]] - skeRcd.nodePosList[skeletonSeq[i]]).Length(); } interval = pSkeLen / (Math.Floor(pSkeLen / interval)) + interval / 200; double oxterInterval = interval / 5; // 寻找腋窝的interval 细化 #endregion //Vector3d nodeNV; Vector3d nodepos; Plane nodePlane; List <KeyValuePair <int, int> > skeEndIndex = new List <KeyValuePair <int, int> >(); // 因为起点的slicer并不需要所以直接舍弃 double globalPos = oxterInterval; // 整个骨架序列线段中的位置 double skeLineAddup = 0.0; // 单个骨架线中的位置 int skeLineIndex = 0; // 骨架序列索引 do { int currStartIndex = 0; int currEndIndex = 1; double currLineLen = (skeRcd.nodePosList[1] - skeRcd.nodePosList[0]).Length(); for (; skeLineAddup < globalPos; skeLineIndex++) { currStartIndex = skeletonSeq[skeLineIndex]; currEndIndex = skeletonSeq[skeLineIndex + 1]; currLineLen = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Length(); skeLineAddup += currLineLen; }// 循环停止的结果:skeLineAddup>=globalPos skeLineIndex指向超过globalpos的那个线段 if (skeEndIndex.Count == 0 || currEndIndex != skeEndIndex.Last().Key) { skeEndIndex.Add(new KeyValuePair <int, int>(currEndIndex, skeLineIndex - 1)); nodepos = (1 - (skeLineAddup - globalPos) / currLineLen) * (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]) + skeRcd.nodePosList[currStartIndex]; //nodeNV = skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]; 这里注释了 nodePlane = new Plane(nodepos, torso2ArmDir); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); } globalPos += oxterInterval; } while (globalPos < pSkeLen); // find oxter slicer Diff2rdPrune(slicerSeq, out int outstart); // outstart 就是腋窝的index // 进行手臂的分片生成 SlicerRecord temp = slicerSeq[outstart]; slicerSeq.Clear(); slicerSeq.Add(temp); double armLength = 0.0; for (int i = skeEndIndex[outstart].Value; i < skeletonSeq.Count - 1; i++) { armLength += (skeRcd.nodePosList[skeletonSeq[i + 1]] - skeRcd.nodePosList[skeletonSeq[i]]).Length(); } double foreArmLength = armLength / 3 * 2; interval = armLength / (Math.Floor(armLength / interval)) + interval / 200; Vector3d nodeNV; globalPos = interval; // 整个骨架序列线段中的位置 skeLineAddup = 0.0; // 单个骨架线中的位置 skeLineIndex = skeEndIndex[outstart].Value; // 骨架序列索引 do { int currStartIndex = skeletonSeq[skeLineIndex]; int currEndIndex = skeletonSeq[skeLineIndex + 1]; double currLineLen = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Length(); for (; skeLineAddup < globalPos; skeLineIndex++) { currStartIndex = skeletonSeq[skeLineIndex]; currEndIndex = skeletonSeq[skeLineIndex + 1]; currLineLen = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Length(); skeLineAddup += currLineLen; }// 循环停止的结果:skeLineAddup>=globalPos skeLineIndex指向超过globalpos的那个线段 nodepos = (1 - (skeLineAddup - globalPos) / currLineLen) * (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]) + skeRcd.nodePosList[currStartIndex]; if (skeLineAddup < foreArmLength) { nodeNV = (skeLineAddup * (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]) + (foreArmLength - skeLineAddup) * torso2ArmDir) / (foreArmLength); //这里注释了 } else { nodeNV = (skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Normalize(); } nodePlane = new Plane(nodepos, nodeNV); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); globalPos += interval * (1 / nodeNV.Normalize().Dot((skeRcd.nodePosList[currEndIndex] - skeRcd.nodePosList[currStartIndex]).Normalize())); } while (globalPos < armLength); // final cut slicer nodeNV = skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 1]] - skeRcd.nodePosList[skeletonSeq[skeletonSeq.Count - 2]]; nodePlane = new Plane(skeRcd.nodePosList[skeletonSeq.Last()], nodeNV); slicerSeq.Add(new SlicerRecord(segMesh, nodePlane)); }
public void WriteToSlicFile(List <SlicerRecordUniform> osl, bodypart bdt) { string currPath = "W:\\Release\\ResultHexa\\"; switch (bdt) { case bodypart.Arm_0: { List <SlicerRecordUniform> osl1; List <SlicerRecordUniform> osl2; LimbMidDivision(osl, out osl1, out osl2); WriteToSlicFile_single(osl1, currPath + "LeftupperArm.txt"); WriteToSlicFile_single(osl2, currPath + "LeftlowerArm.txt"); break; } case bodypart.Arm_1: { List <SlicerRecordUniform> osl1; List <SlicerRecordUniform> osl2; LimbMidDivision(osl, out osl1, out osl2); WriteToSlicFile_single(osl1, currPath + "RightupperArm.txt"); WriteToSlicFile_single(osl2, currPath + "RightlowerArm.txt"); break; } case bodypart.Leg_0: { List <SlicerRecordUniform> osl1; List <SlicerRecordUniform> osl2; LimbMidDivision(osl, out osl1, out osl2); WriteToSlicFile_single(osl1, currPath + "LeftupperLeg.txt"); WriteToSlicFile_single(osl2, currPath + "LeftlowerLeg.txt"); break; } case bodypart.Leg_1: { List <SlicerRecordUniform> osl1; List <SlicerRecordUniform> osl2; LimbMidDivision(osl, out osl1, out osl2); WriteToSlicFile_single(osl1, currPath + "RightupperLeg.txt"); WriteToSlicFile_single(osl2, currPath + "RightlowerLeg.txt"); break; } case bodypart.Head: { osl.Reverse(); for (int i = 0; i < osl.Count; i++) { osl[i].pointInfoList.Reverse(); } WriteToSlicFile_single(osl, currPath + "Head.txt"); break; } case bodypart.Torso: { WriteToSlicFile_single(osl, currPath + "Torso.txt"); break; } } }