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)); } } }
public static IList <uint> OptimizePlaneOrder(IList <MotionObjectInfo> infoList, Motion.MotionFrame frame) { return(OptimizePlaneOrder(infoList, new ReadOnlyMotionFrame(frame))); }