private void bgwRender_DoWork(object sender, DoWorkEventArgs e) { TimeController timeController = _timeController; MotionDataSet dataSet = _dataSet; if (dataSet == null || timeController == null) { Bitmap infoImage = new Bitmap(_width, _height); using (Graphics gfx = Graphics.FromImage(infoImage)) { gfx.Clear(Color.DimGray); gfx.DrawString("Error...", this.Font, Brushes.LightGray, new PointF()); } setPictureImage(pictGraph, infoImage); return; } RangeSet <int> existAll = null; // 選択されたオブジェクトが被欠損なインデックス List <int> clipIndices = new List <int>(); // グラフ上の各x座標のインデックスの範囲 Collection <MotionObjectInfo> infoList; // メッセージを表示 setText(labelInfo, "データ欠損情報"); infoList = dataSet.GetSelectedObjectInfoList(); if (infoList.Count == 0) { Bitmap infoImage = new Bitmap(_width, _height); using (Graphics gfx = Graphics.FromImage(infoImage)) { gfx.Clear(Color.DimGray); gfx.DrawString("選択オブジェクトなし", this.Font, Brushes.Ivory, new PointF()); } setPictureImage(pictGraph, infoImage); return; } else { Bitmap infoImage = new Bitmap(_width, _height); using (Graphics gfx = Graphics.FromImage(infoImage)) { gfx.Clear(Color.DimGray); gfx.DrawString("読み込み中...", this.Font, Brushes.LightGray, new PointF()); } setPictureImageImmediate(pictGraph, infoImage); } // 選択された全オブジェクトの非欠損のandを取る foreach (var info in infoList) { if (bgwRender.CancellationPending) { e.Cancel = true; return; } if (existAll == null) { existAll = getExistenceList(info.Id); } else { existAll = existAll.GetIntersect(getExistenceList(info.Id)); } } // 各x座標に対応する時間に対応するフレームのインデックスを求める // clipIndices[0] から (clipIndices[1] - 1)には,[x=0に対応する時刻]から[x=1に対応する時刻の直前]までに含まれるインデックスが入るようにする for (int x = 0; x <= _width; x++) { decimal time = positionToTime(x); int index = dataSet.GetFrameIndexAt(time); // ちょうどtimeの値がフレームの時間と一緒のときだけ特別対応 Motion.MotionFrame frame = dataSet.GetFrameByIndex(index); if (frame == null || frame.Time != time) { index++; // 取得されたインデックスは,今回のループのx座標に対応する時間範囲に入らない } clipIndices.Add(index); } lock (_lockAccessGraphImage) { // グラフの作成 _graphImage = new Bitmap(_width, _height); using (Graphics gfx = Graphics.FromImage(_graphImage)) { gfx.Clear(Color.Black); for (int x = 0; x < _width; x++) { // 今回のx座標に対応するフレームインデックスの範囲 int clipCount = clipIndices[x + 1] - clipIndices[x]; RangeSet <int> .Range clipRange = new RangeSet <int> .Range(clipIndices[x], clipIndices[x + 1]); // 今回の範囲の被欠損情報を取得 RangeSet <int> existClipped = existAll.GetClipped(clipRange); int existCount = existClipped.Total(); Pen pen = Pens.LightGreen; if (existCount == clipCount) { pen = Pens.YellowGreen; } if (existCount > 0) { gfx.DrawLine(pen, new Point(x, _height - 1), new Point(x, _height - 1 - _height * existCount / clipCount)); } } // 選択範囲の欠損割合の計算 decimal selectBegin = timeController.VisibleBeginTime; decimal selectEnd = timeController.VisibleEndTime; int selectBeginIndex = dataSet.GetFrameIndexAt(selectBegin); int selectEndIndex = dataSet.GetFrameIndexAt(selectEnd); MotionFrame selectBeginFrame = dataSet.GetFrameByIndex(selectBeginIndex); MotionFrame selectEndFrame = dataSet.GetFrameByIndex(selectEndIndex); if (selectBeginFrame == null || selectBeginFrame.Time != selectBegin) { selectBeginIndex++; // clipIndicesを求めるときと同じ処理 } if (selectEndFrame == null || selectEndFrame.Time != selectEnd) { selectEndIndex++; } RangeSet <int> whole = existAll.GetClipped(new RangeSet <int> .Range(selectBeginIndex, selectEndIndex)); int selectClipCount = selectEndIndex - selectBeginIndex; int selectExistCount = whole.Total(); int missingCount = selectClipCount - selectExistCount; double percentage = selectClipCount == 0 ? 0 : (100.0 - 100.0 * selectExistCount / selectClipCount); setText(labelInfo, string.Format("欠落フレーム数: {0} (選択フレーム数 {1}, {2}% 欠損) ({3} オブジェクト)", missingCount, selectClipCount, Math.Round(percentage, 2), infoList.Count)); } } }
private void addPhaseSpace(PhaseSpaceDataReader reader) { WaitForForm waitForm = new WaitForForm(ctrl => { try { Dictionary <int, uint> index2id = new Dictionary <int, uint>(); int count = 1; int index = 0; PhaseSpaceFrame prevInFrame = new PhaseSpaceFrame(); bool first = true; Action <PhaseSpaceFrame, int> import = (inFrame, endIndex) => { for (; index < endIndex && index < _dataSet.FrameLength; index++) { MotionFrame frame = _dataSet.GetFrameByIndex(index); if (frame == null) { continue; } for (int i = 0; i < inFrame.Markers.Length; i++) { uint id; if (!index2id.TryGetValue(i, out id)) { MotionObjectInfo newInfo = new MotionObjectInfo(typeof(PointObject)); newInfo.Name = PathEx.CombineName("unnamed", (i + 1).ToString()); _dataSet.AddObject(newInfo); id = index2id[i] = newInfo.Id; } if (inFrame.Markers[i].Condition > 0) { frame[id] = new PointObject(new Vector3(inFrame.Markers[i].X, inFrame.Markers[i].Y, inFrame.Markers[i].Z)); } } } }; while (!reader.EndOfStream) { PhaseSpaceFrame inFrame = reader.ReadFrame(); int inIndex = _dataSet.GetFrameIndexAt(inFrame.Time); MotionFrame tmp = _dataSet.GetFrameByIndex(inIndex); if (tmp == null || tmp.Time == inFrame.Time) { inIndex++; } if (first) { first = false; } else { import(prevInFrame, inIndex); } prevInFrame = inFrame; ctrl.ReportProgress(99 - 990000 / (count + 10000), string.Format("Load Frame Data: {0} ({1} sec)", count, inFrame.Time.ToString("0.00"))); count++; } if (!first) { import(prevInFrame, _dataSet.FrameLength); } ctrl.ReportProgress(100, string.Format("Done")); ctrl.DialogResult = DialogResult.OK; } catch (Exception) { _dataSet.ClearObject(); _dataSet.ClearFrame(); _dataSet.DoObjectInfoSetChanged(); _dataSet.DoFrameListChanged(); throw; } }); if (waitForm.ShowDialog() == DialogResult.OK) { _dataSet.DoObjectInfoSetChanged(); _dataSet.DoFrameListChanged(); } }