private void ExitApp(object sender, EventArgs e) { if (this.StartTest_button.Text == "Start") { StartTest(null, null); } Thread.Sleep(2000); IO_ThreadStop = false; AcquireImageStop = false; Thread.Sleep(2000); HOperatorSet.CloseFramegrabber(hv_AcqHandle); //关闭相机 ho_Image.Dispose(); //释放对象 IO_Thread.Abort(); AcquireImage.Abort(); HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle); HOperatorSet.ClearShapeModel(hv_ModelID); #if (NormalTest) MotionObject.CloseMotionCard(); #endif System.Environment.Exit(0); }
/// <summary> /// IO线程函数 /// </summary> private void IO_ThreadFunction() { IO_ThreadStop = false; while (!IO_ThreadStop) { #if (NormalTest) ProductSignal = MotionObject.ReadInputPortByPort(1); #endif } }
private void StartTest(object sender, EventArgs e) { if (this.StartTest_button.Text == "Start") { #if (NormalTest) ushort axis = 0; double start = 1000; double speed = 4000; double stop = 2000; double acc = 10000; double dec = 10000; ushort Direct = 0; MotionObject.ContinuationMove(axis, start, speed, stop, acc, dec, Direct); #endif this.StartTest_button.Text = "Stop"; this.StartTest_button.ForeColor = Color.White; this.StartTest_button.BackColor = Color.Blue; AcquireImageStop = false; if (AcquireImage.ThreadState == System.Threading.ThreadState.Unstarted) { AcquireImage.IsBackground = true; AcquireImage.Priority = ThreadPriority.Normal; AcquireImage.Start(); } if ((AcquireImage.ThreadState == System.Threading.ThreadState.Stopped) || (AcquireImage.ThreadState == System.Threading.ThreadState.Aborted)) { AcquireImage = new Thread(new ThreadStart(AcquireImageFunction)); AcquireImage.IsBackground = true; AcquireImage.Priority = ThreadPriority.Normal; AcquireImage.Start(); } string strLogToScreen = "开始采集图像\n"; UpdateLogMessage(strLogToScreen); //CounterTMT.AppEvents.Instance.OnUpdateScreenRun(strLogToScreen); } else if (this.StartTest_button.Text == "Stop") { #if (NormalTest) ushort axis = 0; MotionObject.ImmediatelyStop(axis); #endif this.StartTest_button.Text = "Start"; this.StartTest_button.ForeColor = Color.White; this.StartTest_button.BackColor = Color.Blue; AcquireImageStop = true; string strLogToScreen = "停止采集图像\n"; UpdateLogMessage(strLogToScreen); //CounterTMT.AppEvents.Instance.OnUpdateScreenRun(strLogToScreen); } }
/// <summary> /// load function 相机打开 打开一次即可 窗体打开时候加载图像 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Halcon_me_Load(object sender, EventArgs e) { HOperatorSet.SetSystem("width", ImageWidth); HOperatorSet.SetSystem("height", ImageHeight); HOperatorSet.SetSystem("use_window_thread", "true"); //IO线程 IO_Thread = new Thread(new ThreadStart(IO_ThreadFunction)); IO_Thread.IsBackground = true; IO_Thread.Priority = ThreadPriority.Normal; IO_Thread.Start(); //图像采集线程 AcquireImage = new Thread(new ThreadStart(AcquireImageFunction)); CreateGraphicInteractionWindow(ref GraphInteractiveObect, ref VideoWindow_hWindowControl, ImageWidth, ImageHeight); LoadInnerCameraParameter(null, null); LoadOuterCameraParameter(null, null); // 相机打开 打开一次即可 窗体打开时候加载图像 HOperatorSet.GenEmptyObj(out ho_Image);// //Image Acquisition 02: Code generated by Image Acquisition 02 HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false", "default", "[0]", 0, -1, out hv_AcqHandle); HOperatorSet.GrabImageStart(hv_AcqHandle, -1); HOperatorSet.DispObj(ho_Image, GraphInteractiveObect.halconWindow.HalconWindow); if (File.Exists(Directory.GetCurrentDirectory() + @"\ini\Templete.shm")) { HOperatorSet.ReadShapeModel(Directory.GetCurrentDirectory() + @"\ini\Templete.shm", out hv_ModelID); } if (File.Exists(Directory.GetCurrentDirectory() + @"\ini\MetrologyHandle.mtr")) { HOperatorSet.ReadMetrologyModel(Directory.GetCurrentDirectory() + @"\ini\MetrologyHandle.mtr", out hv_MetrologyHandle); } LoadHalconEnginee(); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; #if (NormalTest) MotionObject.InitMotionCard(); #endif }
/// <summary> /// 現在のモーションオブジェクトのタイプから,オブジェクトのインスタンスを作成して返します. /// </summary> public MotionObject GetEmptyObject() { if (ObjectType == null) { throw new InvalidOperationException("cannot create MotionObject of null Type"); } if (_emptyObject == null) { lock (this) { _emptyObject = (MotionObject)Activator.CreateInstance(ObjectType); return((MotionObject)_emptyObject.Clone()); } } return((MotionObject)_emptyObject.Clone()); }
public IList <MotionObject> EditObject(IList <MotionObjectInfo> targetInfoList, IList <ProcParam <MotionProcEnv> > args, ReadOnlyMotionFrame frame, bool previewMode) { List <MotionObject> ret = new List <MotionObject>(); foreach (MotionObjectInfo info in targetInfoList) { MotionObject created = null; LineObject line = frame[info] as LineObject; if (line != null) { created = new LineObject(line.Position, new Microsoft.DirectX.Vector3(line.Edge.X, 0, line.Edge.Z)); } ret.Add(created); } return(ret); }
/// <summary> /// フレームにオブジェクトを追加します /// </summary> /// <param name="id">追加するオブジェクトのID</param> /// <param name="object">オブジェクトの状態</param> public void SetObject(uint id, MotionObject @object) { lock (this) { if (@object == null) { this.RemoveObject(id); } else { MotionObjectInfo info = this.Parent.GetObjectInfoById(id); if ([email protected](info.ObjectType)) { throw new ArgumentException(string.Format("cannot assign '{0}' to frame as '{1}'", @object.GetType(), info.ObjectType)); } _objectList[id] = @object; } } }
/// <summary> /// 指定された方がモーションオブジェクトのタイプであるかを検証し,検証に失敗すれば例外をスローします. /// </summary> /// <param name="motionObjectType"></param> public static void IsMotionObjectTypeOrThrow(Type motionObjectType) { if (motionObjectType == null) { throw new ArgumentNullException("motionObjectType", "'motionObjectType' cannot be null"); } if (!motionObjectType.IsSubclassOf(typeof(MotionObject))) { throw new ArgumentException(string.Format("{0} is not subclass of MotionObject", motionObjectType)); } if (motionObjectType.IsAbstract) { throw new ArgumentException(string.Format("{0} is Abstract Type", motionObjectType)); } if (motionObjectType.GetConstructor(System.Type.EmptyTypes) == null) { throw new ArgumentException(string.Format("{0} does not have constructor with no parameter", motionObjectType)); } MotionObject @object = (MotionObject)Activator.CreateInstance(motionObjectType); Object clone = @object.Clone(); if (clone.GetType() != motionObjectType) { throw new ArgumentException(string.Format("{0}.Clone() returns not {0} but {1}", motionObjectType, clone.GetType())); } MemoryStream stream = new MemoryStream(); try { using (BinaryWriter writer = new BinaryWriter(stream)) { @object.WriteBinary(writer); } } catch (Exception ex) { throw new ArgumentException(string.Format("{0} failed to WriteBinary with default data", motionObjectType), ex); } stream = new MemoryStream(stream.ToArray()); try { using (BinaryReader reader = new BinaryReader(stream)) { ((MotionObject)clone).ReadBinary(reader); } } catch (Exception ex) { throw new ArgumentException(string.Format("{0} failed to WriteBinary and ReadBinary with default data", motionObjectType), ex); } }
/// <summary> /// フレームにオブジェクトを追加します /// </summary> /// <param name="info">追加するオブジェクトの情報</param> /// <param name="object">オブジェクトの状態</param> public void SetObject(IReadableMotionObjectInfo info, MotionObject @object) { lock (this) { //if(info.Parent != this.Parent) // throw new ArgumentException("Parent mismatch"); if (@object == null) { RemoveObject(info.Id); } else { if ([email protected](info.ObjectType)) { throw new ArgumentException(string.Format("cannot assign '{0}' to frame as '{1}'", @object.GetType(), info.ObjectType)); } _objectList[info.Id] = @object; } } }
/// <summary> /// フレームデータをバイナリ形式から取得します /// </summary> /// <param name="reader"></param> /// <param name="parent"></param> /// <returns></returns> public static MotionFrame DeserializeBinary(BinaryReader reader, MotionDataSet parent) { decimal time = reader.ReadDecimal(); int count = reader.ReadInt32(); MotionFrame ret = new MotionFrame(parent, time, count); for (int i = 0; i < count; i++) { uint id = reader.ReadUInt32(); MotionObjectInfo info = parent.GetObjectInfoById(id); if (info == null) { throw new InvalidDataException(string.Format("unexpected id:{0} in frame at:{1}", id, time)); } MotionObject @object = info.GetEmptyObject(); @object.ReadBinary(reader); ret[info] = @object; } return(ret); }
public IList <MotionObject> EditObject(IList <MotionObjectInfo> targetInfoList, IList <ProcParam <MotionProcEnv> > args, ReadOnlyMotionFrame frame, bool previewMode) { NumberParameter x = args[0] as NumberParameter; NumberParameter y = args[1] as NumberParameter; NumberParameter z = args[2] as NumberParameter; List <MotionObject> ret = new List <MotionObject>(); foreach (MotionObjectInfo info in targetInfoList) { MotionObject obj = frame[info]; if (obj == null) { ret.Add(null); } else { ret.Add(obj.CloneOffsetObject(new Microsoft.DirectX.Vector3((float)x.Value, (float)y.Value, (float)z.Value))); } } return(ret); }
/// <summary> /// IDを指定してオブジェクトを取得します. /// </summary> /// <param name="id"></param> /// <returns></returns> public MotionObject GetObject(uint id) { MotionObject tmp = _frame.GetObject(id); return(tmp == null ? null : (MotionObject)tmp.Clone()); }
/// <summary> /// IDを指定してオブジェクトを取得します. /// </summary> /// <param name="id"></param> /// <returns></returns> public MotionObject this[uint id] { get { MotionObject tmp = _frame.GetObject(id); return(tmp == null ? null : (MotionObject)tmp.Clone()); } }
/// <summary> /// 图像采集线程函数 /// </summary> private void AcquireImageFunction() { AcquireImageStop = false; while (!AcquireImageStop) { if (chkTest.Checked) { try { ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1); HOperatorSet.DispObj(ho_Image, GraphInteractiveObect.halconWindow.HalconWindow); } catch (HalconException halExp) { string strLogToScreen = halExp.ToString(); UpdateLogMessage(strLogToScreen); } } //2.对抓取的图像进行校正 else if (this.CalirationImage_checkBox1.Checked) { ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1); TempImage = CalibrationImage(ho_Image); HOperatorSet.DispObj(TempImage, GraphInteractiveObect.halconWindow.HalconWindow); //3.视觉定位 if (this.ProductLocation_checkBox.Checked) { //3.视觉定位 ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1); SearchObject(hv_ModelID, TempImage); HOperatorSet.DispObj(TempImage, GraphInteractiveObect.halconWindow.HalconWindow); } //4.调用算法进行测试 if (ProductSignal == 1 && (!TestState)) { ho_Image.Dispose(); HOperatorSet.GrabImageAsync(out ho_Image, hv_AcqHandle, -1); TestState = true; ProductSignal = 0; //4.调用算法进行测试 //HTuple hv_TempleteRow = double.Parse(this.ModelRow_textBox.Text); //HTuple hv_TempleteColumn = double.Parse(this.ModelColumn_textBox.Text); //HTuple hv_TempleteAngle = double.Parse(this.ModelAngle_textBox.Text); HTuple hv_TempleteRow = double.Parse(this.txtRow.Text); HTuple hv_TempleteColumn = double.Parse(this.txtCol.Text); HTuple hv_TempleteAngle = double.Parse(this.txtAngle.Text); HObject ho_MeasureRegion; HOperatorSet.GenEmptyObj(out ho_MeasureRegion); HTuple Distance = null; HTuple MeasureDown = double.Parse(this.txtLow.Text); HTuple MeasureTop = double.Parse(this.txtUpper.Text); string Result = MeasureAlgorithm(TempImage, MeasureDown, MeasureTop, hv_MetrologyHandle, hv_TempleteRow, hv_TempleteColumn, hv_TempleteAngle, out Distance, out ho_MeasureRegion); HOperatorSet.SetColor(GraphInteractiveObect.halconWindow.HalconWindow, "red"); HOperatorSet.SetDraw(GraphInteractiveObect.halconWindow.HalconWindow, "margin"); HOperatorSet.DispObj(TempImage, GraphInteractiveObect.halconWindow.HalconWindow); HOperatorSet.DispObj(ho_MeasureRegion, GraphInteractiveObect.halconWindow.HalconWindow); if (Result == "PASS") { this.DisplayResult_label.Text = "合格"; this.DisplayResult_label.ForeColor = Color.Green; this.Distance_textBox.Text = Distance.ToString(); this.Distance_textBox2.Text = Distance.ToString(); this.Distance_label.Text = Distance.ToString(); #if (NormalTest) MotionObject.WriteOutputByPort(4, 1); #endif } if (Result == "NG") { this.DisplayResult_label.Text = "不合格"; this.DisplayResult_label.ForeColor = Color.Red; this.Distance_textBox.Text = Distance.ToString(); this.Distance_textBox2.Text = Distance.ToString(); this.Distance_label.Text = Distance.ToString(); #if (NormalTest) MotionObject.WriteOutputByPort(2, 1); //吹气 MotionObject.WriteOutputByPort(3, 1); //NG指示灯 #endif } ho_MeasureRegion.Dispose(); TestState = false; } } } }
/// <summary> /// オブジェクト情報を指定してオブジェクトを取得します /// </summary> /// <param name="info"></param> /// <returns></returns> public MotionObject GetObject(IReadableMotionObjectInfo info) { MotionObject tmp = _frame.GetObject(info); return(tmp == null ? null : (MotionObject)tmp.Clone()); }
// Process Scene config file line private void process_config_line(String line) { if (string.IsNullOrEmpty(line)) { return; } string[] items = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); //Split(' '); if (items.Length == 0) { return; } // Create a queue of the items Queue <string> item_queue = new Queue <string>(items); string cmd = item_queue.Dequeue(); if (cmd.Length == 0) { return; // No length } if (cmd[0] == '#' || cmd == "##") { return; // Comment } // Parse Commands if (cmd == "display_x") { viewport_width = Util.get_int(item_queue); Util.alert(MODULE + "Display_x: " + viewport_width); viewport_changed = true; Width = viewport_width; } else if (cmd == "display_y") { viewport_height = Util.get_int(item_queue); Util.alert(MODULE + "Display_y: " + viewport_height); viewport_changed = true; Height = viewport_height; } else if (cmd == "display_sync") { v_sync = Util.get_int(item_queue); Util.alert(MODULE + "V_sync: " + v_sync); viewport_changed = true; VSync = v_sync > 0 ? VSyncMode.On : VSyncMode.Off; } else if (cmd == "background") { if (items.Length < 4) { Util.alert("Background command expects 4 parameters "+ items.Length); return; } Color4 color = Util.get_color(item_queue); renderer.set_background(color); } else // Parse Commands if (cmd == "camera") { if (items.Length < 4) { Util.alert("Camera command expects 4 parameters "+ items.Length); return; } Util.alert(MODULE + "Loading Camera " + items[1]); renderer.set_camera_pos(Util.get_vector(item_queue)); } else if (cmd == "lightsrc") { LightSrc l = new LightSrc(); if (!l.load_from_config(item_queue)) { renderer.add_light_src(l); } } else if (cmd == "texture") { Texture t = new Texture(); if (!t.load_from_config(item_queue)) { renderer.add_texture(t); } } else if (cmd == "material") { Material m = new Material(); if (!m.load_from_config(item_queue)) { renderer.add_material(m); } } else if (cmd == "geometry") { Geometry g = new Geometry(); if (!g.load_from_config(item_queue)) { renderer.add_geometry(g); } } else // Parse Commands if (cmd == "model") { MotionObject m = new MotionObject(); if (!m.load_from_model_config(item_queue)) { objects.Add(m); } } else { Util.error(MODULE + "Unknown config command: " + cmd); } }
// Draw object and all child objects, recursive private void draw_object(ref Matrix4 root_model, MotionObject o, List <MotionObject> objects) { // Need to save the root model matrix because we multiply by local model matrix // This root_model will be modified locally by the model matrix and passed down as modified to child objects // Todo, figure out how to make clone correctly Matrix4 oldModelMatrix = root_model.ClearScale(); //model_matrix_stack.Push(modelMatrix); Matrix4 object_model_matrix = o.get_matrix(); // Copy current model matrix to shader Matrix4.Mult(ref object_model_matrix, ref root_model, out root_model); // Compute scaled model matrix. Need to do this so we don't chain the scale to children Matrix4 scaled = Matrix4.Identity; Matrix4 scale_mat = Matrix4.CreateScale(o.get_scale().X, o.get_scale().Y, o.get_scale().Z); Matrix4.Mult(ref scale_mat, ref root_model, out scaled); GL.UniformMatrix4(shader.uModelMatrix, false, ref scaled); // Copmute normal natrix (inverse transpose of upper left 3x3 of model matrix) Matrix3 normal_matrix = Matrix3.Invert(Matrix3.Transpose(new Matrix3(root_model))); shader.set_uniform(shader.uNormalMatrix, normal_matrix); // Set drawing parameters shader.set_uniform(shader.uTestMode, test_mode); // Test scrolling //shader.set_uniform(shader.uTxOffset, count * 0.001f); //if (o.get_name() == "skull" || o.get_name() == "jaw") shader.set_uniform(shader.uTyOffset, -count * 0.001f); // Set matrial uniforms int material_idx = o.get_material(); if (material_idx >= 0) { materials[material_idx].set_uniforms(shader); } // Override object color if it is a light if (o.get_light_enabled()) { shader.set_uniform(shader.uObjectColor, o.get_light_color()); } // Draw the mesh int geometry_idx = o.get_geometry(); if (geometry_idx >= 0) { geometry[geometry_idx].draw(); } // Draw children List <int> list = o.get_child_list(); for (int i = 0; i < list.Count; i++) { int idx = list[i]; draw_object(ref root_model, objects[idx], objects); } // Restore previous so next is draw with correct starting model matrix root_model = oldModelMatrix; }
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(); } }
/// <summary> /// 各メニューを構築します /// </summary> public void InitializeMenus() { _menuAllItems = new List <OperationMenuItem>(); // 作成メニュー _createMenuItem = new ToolStripMenuItem("Create"); _createMenuItem.DropDownOpening += onMenuOpening; // 作成されるオブジェクトごとにメニューを分けるので,作成されるオブジェクトを列挙 HashSet <Type> motionObjectTypes = new HashSet <Type>(); bool otherTypeExists = false; foreach (IMotionOperationCreateObject ope in _dataSet.GetOperationCreateObject()) { Type t = ope.CreatedType; if (t != null && t.IsSubclassOf(typeof(MotionObject))) { motionObjectTypes.Add(t); } else { otherTypeExists = true; } } // 作成されるオブジェクトごとのメニューを作成 Dictionary <Type, ToolStripMenuItem> typeMenus = new Dictionary <Type, ToolStripMenuItem>(); foreach (Type type in motionObjectTypes) { MotionObjectInfo testInfo = new MotionObjectInfo(type); MotionObject testObj = testInfo.GetEmptyObject(); ToolStripMenuItem item = new ToolStripMenuItem(type.Name, testObj.GetIcon() ?? global::MotionDataHandler.Properties.Resources.question); typeMenus[type] = item; } ToolStripMenuItem otherTypeMenu = new ToolStripMenuItem("General"); // 処理ごとにメニューを作成 foreach (bool isEditWrapper in new bool[] { false, true }) { if (isEditWrapper) { foreach (Type t in motionObjectTypes) { typeMenus[t].DropDownItems.Add(new ToolStripSeparator()); } if (otherTypeExists) { otherTypeMenu.DropDownItems.Add(new ToolStripSeparator()); } } foreach (IMotionOperationCreateObject ope in _dataSet.GetOperationCreateObject()) { if ((ope is MotionOperationEditToCreateWrapper) != isEditWrapper) { continue; } Type t = ope.CreatedType; ToolStripMenuItem item = new ToolStripMenuItem(ope.GetTitle()); try { Bitmap icon = ope.IconBitmap; if (icon != null) { item.Image = icon; } } catch (NotImplementedException) { } IMotionOperationCreateObject opeForLabmda = ope; item.Click += new EventHandler((sender, e) => { DialogMotionOperation dialog = new DialogMotionOperation(ScriptConsole.Singleton, opeForLabmda); dialog.ShowDialog(); }); _menuAllItems.Add(new OperationMenuItem(ope, item)); if (motionObjectTypes.Contains(t)) { typeMenus[t].DropDownItems.Add(item); } else { otherTypeMenu.DropDownItems.Add(item); } } } foreach (Type t in motionObjectTypes.OrderBy(t => t.Name)) { _createMenuItem.DropDownItems.Add(typeMenus[t]); } if (otherTypeExists) { _createMenuItem.DropDownItems.Add(otherTypeMenu); } if (_createMenuItem.DropDownItems.Count == 0) { _createMenuItem = null; } // その他 _editMenuItem = new ToolStripMenuItem(); _outputMenuItem = new ToolStripMenuItem(); _generalMenuItem = new ToolStripMenuItem(); List <MenuAutoGenerator> genList = new List <MenuAutoGenerator>(); genList.Add(new MenuAutoGenerator("Edit", _editMenuItem, () => _dataSet.GetOperationEditObject().Select(ope => (IMotionOperationBase)ope).ToList())); genList.Add(new MenuAutoGenerator("Output", _outputMenuItem, () => _dataSet.GetOperationOutputSequence().Select(ope => (IMotionOperationBase)ope).ToList())); genList.Add(new MenuAutoGenerator("General", _generalMenuItem, () => _dataSet.GetOperationGeneral().Select(ope => (IMotionOperationBase)ope).ToList())); foreach (MenuAutoGenerator gen in genList) { gen.OutputMenu.Text = gen.DefaultName; gen.OutputMenu.DropDownOpening += onMenuOpening; foreach (IMotionOperationBase ope in gen.OperationGenerator()) { ToolStripMenuItem item = new ToolStripMenuItem(ope.GetTitle()); try { Bitmap icon = ope.IconBitmap; if (icon != null) { item.Image = icon; } } catch (NotImplementedException) { } IMotionOperationBase opeForLabmda = ope; item.Click += new EventHandler((sender, e) => { DialogMotionOperation dialog = new DialogMotionOperation(ScriptConsole.Singleton, opeForLabmda); dialog.ShowDialog(); }); _menuAllItems.Add(new OperationMenuItem(ope, item)); gen.OutputMenu.DropDownItems.Add(item); } } if (_editMenuItem.DropDownItems.Count == 0) { _editMenuItem = null; } if (_outputMenuItem.DropDownItems.Count == 0) { _outputMenuItem = null; } if (_generalMenuItem.DropDownItems.Count == 0) { _generalMenuItem = null; } }