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));
                }
            }
        }
Exemple #2
0
        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();
            }
        }