public ScriptVariable Call(IList <ScriptVariable> args, ScriptConsole console)
        {
            _progress.Initialize(0, "Initializing...");
            if (args == null)
            {
                throw new ArgumentNullException("args", "args cannot be null");
            }
            if (args.Count < 1)
            {
                args = new List <ScriptVariable> {
                    null
                }
            }
            ;
            if (args[0] == null)
            {
                args[0] = new ListVariable();
            }
            IList <ScriptVariable> objectNamesVar = args[0].ToList();

            if (objectNamesVar.Any(n => n.IsNull()))
            {
                throw new ArgumentException(global::MotionDataHandler.Properties.Settings.Default.Msg_ObjectNameCannotBeNull, "args");
            }
            List <string>           objectNames = objectNamesVar.Select(n => n.ToString()).ToList();
            MotionDataSet           dataSet     = console.MotionDataSet;
            MotionProcEnv           env2        = new MotionProcEnv(console);
            List <MotionObjectInfo> infoList    = new List <MotionObjectInfo>();

            foreach (string objectName in objectNames)
            {
                MotionObjectInfo info = dataSet.GetObjectInfoByName(objectName);
                if (info == null)
                {
                    throw new ArgumentException(global::MotionDataHandler.Properties.Settings.Default.Msg_ObjectNotFound + ": " + objectName, "args");
                }
                infoList.Add(info);
            }
            foreach (MotionObjectInfo info in infoList)
            {
                if (!_operation.FilterSelection(info))
                {
                    throw new ArgumentException(global::MotionDataHandler.Properties.Settings.Default.Msg_InvalidTargetObjectSpecified + ": " + info.Name, "args");
                }
            }
            string errorMessage = "";

            if (!_operation.ValidateSelection(infoList, ref errorMessage))
            {
                if (errorMessage == null)
                {
                    errorMessage = "";
                }
                throw new ArgumentException(global::MotionDataHandler.Properties.Settings.Default.Msg_ImproperObjectSelection + ": " + errorMessage, "args");
            }

            IList <ProcParam <MotionProcEnv> > parameters = _operation.GetParameters() ?? new ProcParam <MotionProcEnv> [0];

            if (args.Count != parameters.Count + 1)
            {
                throw new ArgumentException(string.Format(global::MotionDataHandler.Properties.Settings.Default.Msg_NumberOfArgumentsRequired, parameters.Count + 1));
            }
            for (int i = 0; i < parameters.Count; i++)
            {
                if (!parameters[i].FromScriptVariable(env2, args[i + 1], ref errorMessage))
                {
                    throw new ArgumentException(string.Format(global::MotionDataHandler.Properties.Settings.Default.Msg_InvalidNthArgument + ": {1}", i + 1, errorMessage ?? ""), "args");
                }
            }
            if (!_operation.ValidateArguments(parameters, ref errorMessage))
            {
                throw new ArgumentException(string.Format(global::MotionDataHandler.Properties.Settings.Default.Msg_InvalidArgument + ": {0}", errorMessage ?? ""), "args");
            }
            IMotionOperationGeneral general = _operation as IMotionOperationGeneral;

            if (general != null)
            {
                _progress.Initialize(0, "Operation");
                general.Operate(infoList, parameters, dataSet, _progress);
                return(new ListVariable(infoList.Select(info => new StringVariable(info.Name))));
            }
            IMotionOperationEditObject edit = _operation as IMotionOperationEditObject;

            if (edit != null)
            {
                _progress.Initialize(dataSet.FrameLength, "Edit Object");
                foreach (MotionFrame frame in dataSet.EnumerateFrame())
                {
                    IList <MotionObject> results = edit.EditObject(infoList, parameters, new ReadOnlyMotionFrame(frame), false);
                    int count = Math.Min(results.Count, infoList.Count);
                    for (int i = 0; i < count; i++)
                    {
                        frame[infoList[i]] = results[i];
                    }
                    _progress.CurrentValue++;
                }
                dataSet.DoFrameListChanged();
                return(new ListVariable(infoList.Select(info => new StringVariable(info.Name))));
            }
            IMotionOperationOutputSequence output = _operation as IMotionOperationOutputSequence;

            if (output != null)
            {
                _progress.Initialize(0, "Output");
                IList <Sequence.SequenceData> sequences = output.OutputSequence(infoList, parameters, dataSet.EnumerateFrame().Select(frame => new ReadOnlyMotionFrame(frame)), _progress);
                foreach (Sequence.SequenceData sequence in sequences)
                {
                    console.SequenceController.AddSequence(sequence);
                }
                return(new ListVariable(sequences.Select(s => new StringVariable(s.Title))));
            }
            IMotionOperationCreateObject create = _operation as IMotionOperationCreateObject;

            if (create != null)
            {
                _progress.Initialize(dataSet.FrameLength, "Create Object");
                IList <MotionObjectInfo> newInfoList = create.GetNewObjectInfoList(infoList, parameters);
                MotionFrame firstFrame = dataSet.GetFrameByIndex(0);
                if (firstFrame != null)
                {
                    IList <MotionObject> newObjects = create.CreateObjects(infoList, parameters, new ReadOnlyMotionFrame(firstFrame), false) ?? new MotionObject[0];
                    if (newObjects.Count != newInfoList.Count)
                    {
                        throw new InvalidOperationException(global::MotionDataHandler.Properties.Settings.Default.Msg_CreateObjectLengthMismatch);
                    }
                }
                foreach (MotionObjectInfo newInfo in newInfoList)
                {
                    dataSet.AddObject(newInfo);
                }
                foreach (MotionFrame frame in dataSet.EnumerateFrame())
                {
                    IList <MotionObject> newObjects = create.CreateObjects(infoList, parameters, new ReadOnlyMotionFrame(frame), false) ?? new MotionObject[0];
                    int count = Math.Min(newObjects.Count, newInfoList.Count);
                    for (int i = 0; i < count; i++)
                    {
                        frame[newInfoList[i]] = newObjects[i];
                    }
                    _progress.CurrentValue++;
                }
                dataSet.DoObjectInfoSetChanged();
                dataSet.DoFrameListChanged();
                return(new ListVariable(newInfoList.Select(info => new StringVariable(info.Name))));
            }
            return(null);
        }
        public void Operate(IList <MotionObjectInfo> selectedInfoList, IList <ProcParam <MotionProcEnv> > args, MotionDataSet dataSet, ProgressInformation progressInfo)
        {
            SingleSelectParameter mode   = args[0] as SingleSelectParameter;
            NumberParameter       limit2 = args[1] as NumberParameter;
            bool addMode = mode.Value == 1;
            int  limit   = (int)limit2.Value;

            progressInfo.Initialize(selectedInfoList.Count, "Interpolate");
            foreach (var info in selectedInfoList)
            {
                // 欠落範囲の集合
                RangeSet <int> missings = new RangeSet <int>();

                bool exist = true;
                int  begin = 0;
                // 最初のフレームからかけている部分,最後のかけている部分は無視
                for (int i = 0; i < dataSet.FrameLength; i++)
                {
                    if (dataSet.GetFrameByIndex(i)[info] == null)
                    {
                        if (exist)
                        {
                            begin = i;
                            exist = false;
                        }
                    }
                    else
                    {
                        if (!exist)
                        {
                            if (begin != 0)
                            {
                                missings.Add(new RangeSet <int> .Range(begin, i));
                                exist = true;
                            }
                        }
                    }
                }
                // 別オブジェクトにするとき用に入力オブジェクトと出力オブジェクトを分ける
                MotionObjectInfo addInfo = info;
                if (addMode)
                {
                    // 別オブジェクトにするオプション
                    addInfo      = new MotionObjectInfo(info.ObjectType, info);
                    addInfo.Name = PathEx.GiveName("interpolate", info.Name);
                    dataSet.AddObject(addInfo);
                }
                // 線形補間
                foreach (var range in missings)
                {
                    if (limit == 0 || range.End - range.Start <= limit)
                    {
                        int          pre       = range.Start - 1;
                        int          post      = range.End;
                        MotionFrame  preFrame  = dataSet.GetFrameByIndex(pre);
                        MotionFrame  postFrame = dataSet.GetFrameByIndex(post);
                        MotionObject preObject = preFrame[info];
                        if (preObject != null)
                        {
                            for (int index = range.Start; index < range.End; index++)
                            {
                                float       interpolater = (float)(index - pre) / (post - pre);
                                MotionFrame frame        = dataSet.GetFrameByIndex(index);
                                frame[addInfo] = preObject.InterpolateLinear(postFrame[info], interpolater);
                            }
                        }
                    }
                }
                progressInfo.CurrentValue++;
            }

            dataSet.DoFrameListChanged();
            if (addMode)
            {
                dataSet.DoObjectInfoSetChanged();
            }
        }
        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 #4
0
        bool openEyeSight(string fileName)
        {
            if (fileName == null)
            {
                if (dialogLoadEyeSight.ShowDialog() != DialogResult.OK)
                {
                    return(false);
                }
                // すべて開く
                return(dialogLoadEyeSight.FileNames.All(path => openEyeSight(path)));
            }
            WaitForForm waitForm = new WaitForForm(ctrl => {
                lock (_dataSet) {
                    try {
                        ctrl.OperationTitle      = fileName;
                        MotionObjectInfo newInfo = new MotionObjectInfo(typeof(LineObject));
                        newInfo.Name             = Path.GetFileNameWithoutExtension(fileName);
                        _dataSet.AddObject(newInfo);
                        using (CSVReader reader = new CSVReader(fileName)) {
                            int index = 0;
                            while (!reader.EndOfStream)
                            {
                                if (index < 0 || index >= _dataSet.FrameLength)
                                {
                                    break;
                                }
                                MotionFrame frame = _dataSet.GetFrameByIndex(index);
                                int progress      = 0;
                                if (_dataSet.FrameLength > 0)
                                {
                                    progress = Math.Min(99, 100 * index / _dataSet.FrameLength);
                                }
                                ctrl.ReportProgress(progress, "Loading...: " + index.ToString());

                                string[] values = reader.ReadValues();
                                if (values == null)
                                {
                                    break;
                                }

                                if (values.Length >= 8)
                                {
                                    float[] floats = new float[8];
                                    bool failure   = false;
                                    for (int i = 0; !failure && i < 8; i++)
                                    {
                                        if (!float.TryParse(values[i], out floats[i]))
                                        {
                                            failure = true;
                                        }
                                    }
                                    if (!failure)
                                    {
                                        if (floats[0] > 0 && floats[4] > 0)
                                        {
                                            Vector3 end = new Vector3(floats[1], floats[2], floats[3]);
                                            Vector3 dir = new Vector3(floats[5], floats[6], floats[7]);
                                            dir.Normalize();
                                            frame[newInfo] = new LineObject(end, dir * 1000);
                                        }
                                    }
                                }
                                index++;
                            }
                        }
                    } catch (Exception ex) {
                        ErrorLogger.Tell(ex, "読み込みに失敗しました");
                    } finally {
                        _dataSet.DoObjectInfoSetChanged();
                        _dataSet.DoFrameListChanged();
                    }
                }
            });

            if (waitForm.ShowDialog() == DialogResult.OK)
            {
                return(true);
            }
            return(false);
        }