// Helper. Removes given IGraphic from their images and adds given annotations to the images as AimGraphic private void UpdateImagesWithProperAimGraphic(List <aim_dotnet.Annotation> annotations, List <IGraphic> annotationsGraphic) { if (annotationsGraphic != null) { foreach (IGraphic graphic in annotationsGraphic) { // For now, we should be creating annotations only for the current image // Code below that reads annotations back depends on this. // Otherwise we either need to keep track of images from which we delete graphics (could be different from the images for the annotations?) // or to pass in a list of images. Debug.Assert(graphic.ParentPresentationImage == null || graphic.ParentPresentationImage == this.ImageViewer.SelectedPresentationImage); IOverlayGraphicsProvider currentOverlayGraphics = graphic.ParentPresentationImage as IOverlayGraphicsProvider; if (currentOverlayGraphics != null && currentOverlayGraphics.OverlayGraphics != null) { currentOverlayGraphics.OverlayGraphics.Remove(graphic); } } } if (annotations != null) { foreach (aim_dotnet.Annotation annotation in annotations) { AimHelpers.ReadGraphicsFromAnnotation(annotation, this.ImageViewer.SelectedPresentationImage); } } }
// Forces re-draw of displayed images if they have AIMGraphic private static void UpdateDisplayedImages(string loginName) { foreach (DesktopWindow desktopWindow in Application.DesktopWindows) { foreach (Workspace workspace in desktopWindow.Workspaces) { IImageViewer imageViewer = ImageViewerComponent.GetAsImageViewer(workspace); if (imageViewer != null) { foreach (ImageBox imageBox in imageViewer.PhysicalWorkspace.ImageBoxes) { foreach (Tile tile in imageBox.Tiles) { IOverlayGraphicsProvider graphicsProvider = tile.PresentationImage as IOverlayGraphicsProvider; if (graphicsProvider != null) { foreach (IGraphic graphic in graphicsProvider.OverlayGraphics) { AimGraphic aimGraphic = graphic as AimGraphic; if (aimGraphic != null && (string.IsNullOrEmpty(loginName) || string.Equals(loginName, aimGraphic.UserLoginName, StringComparison.InvariantCultureIgnoreCase))) { tile.PresentationImage.Draw(); break; } } } } } } } } }
protected void AddGraphic(IPresentationImage image, IControlGraphic graphic, IOverlayGraphicsProvider provider) { _undoableCommand = new DrawableUndoableCommand(image); _undoableCommand.Enqueue(new AddGraphicUndoableCommand(graphic, provider.OverlayGraphics)); _undoableCommand.Name = CreationCommandName; _undoableCommand.Execute(); }
internal static void DeleteAll(IPresentationImage image) { // if any editbox exists on the image, forcibly abort it now if (image.Tile.EditBox != null) { image.Tile.EditBox.Cancel(); } IOverlayGraphicsProvider provider = image as IOverlayGraphicsProvider; if (provider == null) { return; } DrawableUndoableCommand command = new DrawableUndoableCommand(image); foreach (IGraphic graphic in provider.OverlayGraphics) { command.Enqueue(new RemoveGraphicUndoableCommand(graphic)); } if (command.Count == 0) { return; } command.Execute(); command.Name = SR.CommandDeleteAllAnnotations; image.ImageViewer.CommandHistory.AddCommand(command); }
private static void TestCalibration(string pixelShape, bool uncalibrated, PointF pt1, PointF pt2, double calibrationValue, double expectedRowSpacing, double expectedColSpacing) { using (IPresentationImage image = GetCalibrationTestImage(pixelShape, uncalibrated)) { Trace.WriteLine(string.Format("TEST {0} image with {1} pixels", uncalibrated ? "uncalibrated" : "calibrated", pixelShape)); Trace.WriteLine(string.Format("calibrating [{0}, {1}] to {2} mm", pt1, pt2, calibrationValue)); PolylineGraphic lineGraphic; IOverlayGraphicsProvider overlayGraphicsProvider = (IOverlayGraphicsProvider)image; overlayGraphicsProvider.OverlayGraphics.Add(new VerticesControlGraphic(lineGraphic = new PolylineGraphic())); lineGraphic.CoordinateSystem = CoordinateSystem.Source; lineGraphic.Points.Add(pt1); lineGraphic.Points.Add(pt2); lineGraphic.ResetCoordinateSystem(); CalibrationTool.TestCalibration(calibrationValue, lineGraphic); IImageSopProvider imageSopProvider = (IImageSopProvider)image; Trace.WriteLine(string.Format("Pixel Spacing (Actual)/(Expected): ({0:F4}:{1:F4})/({2:F4}:{3:F4})", imageSopProvider.Frame.NormalizedPixelSpacing.Row, imageSopProvider.Frame.NormalizedPixelSpacing.Column, expectedRowSpacing, expectedColSpacing)); float percentErrorRow = Math.Abs((float)((imageSopProvider.Frame.NormalizedPixelSpacing.Row - expectedRowSpacing) / expectedRowSpacing * 100F)); float percentErrorCol = Math.Abs((float)((imageSopProvider.Frame.NormalizedPixelSpacing.Column - expectedColSpacing) / expectedColSpacing * 100F)); Trace.WriteLine(String.Format("Percent Error (Row/Column): {0:F3}%/{1:F3}%", percentErrorRow, percentErrorCol)); Assert.AreEqual(expectedColSpacing, imageSopProvider.Frame.NormalizedPixelSpacing.Column, 0.005, "Column Spacing appears to be wrong"); Assert.AreEqual(expectedRowSpacing, imageSopProvider.Frame.NormalizedPixelSpacing.Row, 0.005, "Row Spacing appears to be wrong"); Assert.IsTrue(percentErrorCol < 1.5, "Column Spacing appears to be wrong"); Assert.IsTrue(percentErrorRow < 1.5, "Row Spacing appears to be wrong"); } }
private Dictionary <String, List <AimGraphic> > GetAimUserGraphics() { Dictionary <String, List <AimGraphic> > userGraphics = new Dictionary <string, List <AimGraphic> >(); foreach (ImageBox imageBox in Context.Viewer.PhysicalWorkspace.ImageBoxes) { foreach (Tile tile in imageBox.Tiles) { IOverlayGraphicsProvider graphicsProvider = tile.PresentationImage as IOverlayGraphicsProvider; if (graphicsProvider != null) { foreach (IGraphic graphic in graphicsProvider.OverlayGraphics) { AimGraphic aimGraphic = graphic as AimGraphic; if (aimGraphic != null) { string user = aimGraphic.UserLoginName; if (!userGraphics.ContainsKey(user)) { userGraphics.Add(user, new List <AimGraphic>()); } userGraphics[user].Add(aimGraphic); } } } } } return(userGraphics); }
// Returns currently displayed annotations' colors and associated user names private static Dictionary <string, Color> GetDisplayedUsersAndMarkupColors() { Dictionary <string, Color> displayedUserColors = new Dictionary <string, Color>(); IImageViewer imageViewer = ImageViewerComponent.GetAsImageViewer(Application.ActiveDesktopWindow.ActiveWorkspace); if (imageViewer != null) { foreach (ImageBox imageBox in imageViewer.PhysicalWorkspace.ImageBoxes) { foreach (Tile tile in imageBox.Tiles) { IOverlayGraphicsProvider graphicsProvider = tile.PresentationImage as IOverlayGraphicsProvider; if (graphicsProvider != null) { foreach (IGraphic graphic in graphicsProvider.OverlayGraphics) { AimGraphic aimGraphic = graphic as AimGraphic; if (aimGraphic != null) // && String.Equals(loginName, aimGraphic.UserLoginName, StringComparison.InvariantCultureIgnoreCase)) { if (!displayedUserColors.ContainsKey(aimGraphic.UserLoginName)) { displayedUserColors[aimGraphic.UserLoginName] = aimGraphic.Color; } } } } } } } return(displayedUserColors); }
private void AnalyzeInternal() { IPresentationImage presImage = this.ImageViewer.SelectedPresentationImage; IImageGraphicProvider imageGraphicProvider = presImage as IImageGraphicProvider; GrayscaleImageGraphic imageGraphic = imageGraphicProvider.ImageGraphic as GrayscaleImageGraphic; IOverlayGraphicsProvider overlayProvider = presImage as IOverlayGraphicsProvider; CadOverlayGraphic cadOverlay = GetCadOverlayGraphic(overlayProvider); if (cadOverlay == null) { cadOverlay = new CadOverlayGraphic(imageGraphic); overlayProvider.OverlayGraphics.Add(cadOverlay); } MemorableUndoableCommand command = new MemorableUndoableCommand(cadOverlay); command.BeginState = cadOverlay.CreateMemento(); cadOverlay.Threshold = (int)this.Threshold; cadOverlay.Opacity = (int)this.Opacity; cadOverlay.Analyze(); command.EndState = cadOverlay.CreateMemento(); this.ImageViewer.CommandHistory.AddCommand(command); }
/// <summary> /// Tests the statistics calculation for consistency over a number of trial runs using the same shape. /// </summary> protected void TestRoiStatsCalculationConsistency() { const int samples = 100; const int gridSize = 4; foreach (ImageKey imageKey in Enum.GetValues(typeof(ImageKey))) { WriteLine("Testing on Image {0}", imageKey.ToString()); using (IPresentationImage image = GetImage(imageKey)) { IImageSopProvider provider = (IImageSopProvider)image; IOverlayGraphicsProvider overlayGraphicsProvider = (IOverlayGraphicsProvider)image; int rows = provider.Frame.Rows; int cols = provider.Frame.Columns; for (int r = rows / gridSize / 2; r < rows; r += rows / gridSize) { for (int c = cols / gridSize / 2; c < cols; c += cols / gridSize) { if (this.VerboseOutput) { WriteLine("Checking {0} core samples for consistent results at location {1}", samples, new PointF(c, r)); } T shapeData = CreateCoreSampleShape(new PointF(c, r), rows, cols); double expectedArea = 0, expectedMean = 0, expectedSigma = 0; for (int n = 0; n < samples; n++) { Roi userRoi = CreateRoiFromGraphic(overlayGraphicsProvider, shapeData); RoiStatistics stats = RoiStatistics.Calculate(userRoi); if (n == 0) { if (userRoi is IRoiAreaProvider) { expectedArea = ((IRoiAreaProvider)userRoi).Area; } expectedMean = stats.Mean; expectedSigma = stats.StandardDeviation; if (this.VerboseOutput) { WriteLine("First sample reported A={0:f0} \u03BC={1:f3} \u03C3={2:f3}", expectedArea, expectedMean, expectedSigma); } continue; } // very strict tolerance. performing the calculation the first time should yield the same result as the next hundred times. if (userRoi is IRoiAreaProvider) { Assert.AreEqual(expectedArea, ((IRoiAreaProvider)userRoi).Area, double.Epsilon, "Area calculation consistency fail."); } Assert.AreEqual(expectedMean, stats.Mean, double.Epsilon, "Mean calculation consistency fail."); Assert.AreEqual(expectedSigma, stats.StandardDeviation, double.Epsilon, "Stdev calculation consistency fail."); } } } } } }
protected override void OnParentPresentationImageChanged(IPresentationImage oldParentPresentationImage, IPresentationImage newParentPresentationImage) { if (oldParentPresentationImage != null) { IOverlayGraphicsProvider overlayGraphicsProvider = oldParentPresentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider != null) { overlayGraphicsProvider.OverlayGraphics.ItemChanging -= OnOverlayGraphicsItemRemoved; overlayGraphicsProvider.OverlayGraphics.ItemRemoved -= OnOverlayGraphicsItemRemoved; } } base.OnParentPresentationImageChanged(oldParentPresentationImage, newParentPresentationImage); if (newParentPresentationImage != null) { IOverlayGraphicsProvider overlayGraphicsProvider = newParentPresentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider != null) { overlayGraphicsProvider.OverlayGraphics.ItemRemoved += OnOverlayGraphicsItemRemoved; overlayGraphicsProvider.OverlayGraphics.ItemChanging += OnOverlayGraphicsItemRemoved; } } _isDirty = true; }
// makes requested Graphic object selected private void SelectAimGraphic(IPresentationImage presentationImage, string aimUid) { IOverlayGraphicsProvider imageGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (imageGraphicsProvider != null) { foreach (IGraphic graphic in imageGraphicsProvider.OverlayGraphics) { IAimGraphic aimGraphic = graphic as IAimGraphic; if (aimGraphic != null && aimGraphic.AimAnnotation.UniqueIdentifier == aimUid) { IDecoratorGraphic decoratorGraphic = aimGraphic as IDecoratorGraphic; if (decoratorGraphic != null) { presentationImage.SelectedGraphic = decoratorGraphic.DecoratedGraphic as ISelectableGraphic; presentationImage.FocussedGraphic = decoratorGraphic.DecoratedGraphic as IFocussableGraphic; if (presentationImage.SelectedGraphic != null) { presentationImage.SelectedGraphic.Selected = true; } break; } } } } }
protected override Roi CreateRoiFromGraphic(IOverlayGraphicsProvider overlayGraphics, Line shapeData) { PolylineGraphic graphic = new PolylineGraphic(); overlayGraphics.OverlayGraphics.Add(graphic); graphic.CoordinateSystem = CoordinateSystem.Source; graphic.Points.Add(shapeData.Point1); graphic.Points.Add(shapeData.Point2); graphic.ResetCoordinateSystem(); return(graphic.GetRoi()); }
private static ShowAnglesTool.ShowAnglesToolCompositeGraphic FindShowAnglesToolComposite(IPresentationImage image) { IOverlayGraphicsProvider imageOverlayGraphics = (IOverlayGraphicsProvider)image; IGraphic graphic = imageOverlayGraphics.OverlayGraphics.FirstOrDefault(IsOfType <ShowAnglesTool.ShowAnglesToolCompositeGraphic>); if (graphic is CompositeGraphic) { ((CompositeGraphic)graphic).OnDrawing(); } return((ShowAnglesTool.ShowAnglesToolCompositeGraphic)graphic); }
protected override Roi CreateRoiFromGraphic(IOverlayGraphicsProvider overlayGraphics, RectangleF shapeData) { RectanglePrimitive graphic = new RectanglePrimitive(); overlayGraphics.OverlayGraphics.Add(graphic); graphic.CoordinateSystem = CoordinateSystem.Source; graphic.TopLeft = shapeData.Location; graphic.BottomRight = shapeData.Location + shapeData.Size; graphic.ResetCoordinateSystem(); return(graphic.GetRoi()); }
private CadOverlayGraphic GetCadOverlayGraphic(IOverlayGraphicsProvider provider) { foreach (IGraphic graphic in provider.OverlayGraphics) { if (graphic is CadOverlayGraphic) { return(graphic as CadOverlayGraphic); } } return(null); }
protected override Roi CreateRoiFromGraphic(IOverlayGraphicsProvider overlayGraphics, Angle shapeData) { ProtractorGraphic graphic = new ProtractorGraphic(); overlayGraphics.OverlayGraphics.Add(graphic); graphic.CoordinateSystem = CoordinateSystem.Source; graphic.Points.Add(shapeData.Value1); graphic.Points.Add(shapeData.Value2); graphic.Points.Add(shapeData.Value3); graphic.ResetCoordinateSystem(); return(graphic.GetRoi()); }
protected override Roi CreateRoiFromGraphic(IOverlayGraphicsProvider overlayGraphics, IEnumerable <PointF> shapeData) { PolylineGraphic graphic = new PolylineGraphic(); overlayGraphics.OverlayGraphics.Add(graphic); graphic.CoordinateSystem = CoordinateSystem.Source; foreach (PointF data in shapeData) { graphic.Points.Add(data); } graphic.Points.Add(graphic.Points[0]); graphic.ResetCoordinateSystem(); return(graphic.GetRoi()); }
private void OnGraphicSelectionChanged(object sender, GraphicSelectionChangedEventArgs e) { if (e.SelectedGraphic != null) { IPresentationImage image = e.SelectedGraphic.ParentPresentationImage; IOverlayGraphicsProvider overlayGraphicsProvider = image as IOverlayGraphicsProvider; if (overlayGraphicsProvider != null) { ShowAnglesToolCompositeGraphic compositeGraphic = (ShowAnglesToolCompositeGraphic)CollectionUtils.SelectFirst(overlayGraphicsProvider.OverlayGraphics, g => g is ShowAnglesToolCompositeGraphic); if (compositeGraphic == null) { overlayGraphicsProvider.OverlayGraphics.Add(compositeGraphic = new ShowAnglesToolCompositeGraphic(this)); } compositeGraphic.Select(e.SelectedGraphic); } } }
public override bool Start(IMouseInformation mouseInformation) { // don't let the tool start if we're disabled! if (!this.Enabled) { return(false); } base.Start(mouseInformation); if (_lineGraphicBuilder != null) { return(_lineGraphicBuilder.Start(mouseInformation)); } IPresentationImage image = mouseInformation.Tile.PresentationImage; IOverlayGraphicsProvider provider = image as IOverlayGraphicsProvider; if (provider == null) { return(false); } // this memento will be consumed when the graphic builder is completed or cancelled _originalResliceToolsState = _resliceToolGroup.ToolGroupState.CreateMemento(); TranslocateGraphic(_resliceGraphic, this.SelectedPresentationImage); // The interactive graphic builders typically operate on new, pristine graphics // Since our graphic isn't new, clear the points from it! (Otherwise you'll end up with a polyline) _resliceGraphic.Points.Clear(); _lineGraphicBuilder = new InteractivePolylineGraphicBuilder(2, _resliceGraphic); _lineGraphicBuilder.GraphicComplete += OnGraphicBuilderDone; _lineGraphicBuilder.GraphicCancelled += OnGraphicBuilderCancelled; if (_lineGraphicBuilder.Start(mouseInformation)) { return(true); } this.Cancel(); return(false); }
void EventBroker_PresentationImageSelected(object sender, PresentationImageSelectedEventArgs e) { IOverlayGraphicsProvider provider = e.SelectedPresentationImage as IOverlayGraphicsProvider; CadOverlayGraphic cadOverlay = GetCadOverlayGraphic(provider); if (cadOverlay == null) { this.ThresholdEnabled = false; this.OpacityEnabled = false; } else { this.Threshold = cadOverlay.Threshold; this.Opacity = cadOverlay.Opacity; this.ThresholdEnabled = true; this.OpacityEnabled = true; } }
internal static void DeleteAll(IPresentationImage image) { IOverlayGraphicsProvider provider = image as IOverlayGraphicsProvider; if (provider == null) { return; } DrawableUndoableCommand command = new DrawableUndoableCommand(image); foreach (IGraphic graphic in provider.OverlayGraphics) { command.Enqueue(new RemoveGraphicUndoableCommand(graphic)); } command.Execute(); command.Name = SR.CommandDeleteAllAnnotations; image.ImageViewer.CommandHistory.AddCommand(command); }
private void OnImageDrawing(object sender, ImageDrawingEventArgs e) { if (e.PresentationImage != null) { IOverlayGraphicsProvider graphicsProvider = e.PresentationImage as IOverlayGraphicsProvider; if (graphicsProvider != null && graphicsProvider.OverlayGraphics != null) { AimSettings aimSettings = AimSettings.Default; foreach (IGraphic overlayGraphic in graphicsProvider.OverlayGraphics) { if (overlayGraphic is AimGraphic) { AimGraphic aimGraphic = (AimGraphic)overlayGraphic; string userName = aimGraphic.UserLoginName; aimGraphic.Visible = !_displayMarkupPerUser.ContainsKey(userName) || _displayMarkupPerUser[userName]; aimGraphic.Color = aimSettings.GetAimGraphicColorForUser(userName); } } } } }
// makes requested Graphic object selected private void SelectAimGraphic(IPresentationImage presentationImage, string aimUid) { IOverlayGraphicsProvider imageGraphicsProvider = presentationImage as IOverlayGraphicsProvider; if (imageGraphicsProvider != null) { bool isFound = false; foreach (IGraphic graphic in imageGraphicsProvider.OverlayGraphics) { IAimGraphic aimGraphic = graphic as IAimGraphic; if (aimGraphic != null && aimGraphic.AnnotationUid == aimUid) { IDecoratorGraphic decoratorGraphic = aimGraphic as IDecoratorGraphic; if (decoratorGraphic != null) { presentationImage.SelectedGraphic = decoratorGraphic.DecoratedGraphic as ISelectableGraphic; presentationImage.FocussedGraphic = decoratorGraphic.DecoratedGraphic as IFocussableGraphic; if (presentationImage.SelectedGraphic != null) { presentationImage.SelectedGraphic.Selected = true; isFound = true; } break; } } } if (!isFound) { // Unselect current selection if (presentationImage.SelectedGraphic != null) { presentationImage.SelectedGraphic.Selected = false; } presentationImage.SelectedGraphic = null; presentationImage.FocussedGraphic = null; } } }
public static bool IsImageMarkupPresent(IPresentationImage image) { IOverlayGraphicsProvider currentOverlayGraphics = image as IOverlayGraphicsProvider; if (currentOverlayGraphics != null) { foreach (IGraphic graphic in currentOverlayGraphics.OverlayGraphics) { if (graphic is RoiGraphic) { return(true); } ContextMenuControlGraphic contextMenuControlGraphic = graphic as ContextMenuControlGraphic; if (contextMenuControlGraphic != null && contextMenuControlGraphic.Subject != null) { UserCalloutGraphic userCalloutGraphic = contextMenuControlGraphic.Subject as UserCalloutGraphic; if (userCalloutGraphic != null) { return(true); } InvariantTextPrimitive invariantTextPrimitive = contextMenuControlGraphic.Subject as InvariantTextPrimitive; if (invariantTextPrimitive != null) { return(true); } UserCrosshairCalloutGraphic crosshairGraphic = contextMenuControlGraphic.Subject as UserCrosshairCalloutGraphic; if (crosshairGraphic != null) { return(true); } } } } return(false); }
private void AddPinwheelGraphic() { IPresentationImage selectedImage = base.SelectedPresentationImage; if (selectedImage == null) { return; } if (!base.IsMprImage(selectedImage)) { return; } MprDisplaySet displaySet = (MprDisplaySet)selectedImage.ParentDisplaySet; if (displaySet.Identifier == MprDisplaySetIdentifier.Oblique) { return; } IOverlayGraphicsProvider overlayProvider = selectedImage as IOverlayGraphicsProvider; IImageGraphicProvider imageGraphicProvider = selectedImage as IImageGraphicProvider; if (overlayProvider != null && imageGraphicProvider != null) { _currentPinwheelGraphic = new PinwheelGraphic(); int width = imageGraphicProvider.ImageGraphic.Columns; int height = imageGraphicProvider.ImageGraphic.Rows; overlayProvider.OverlayGraphics.Add(_currentPinwheelGraphic); _currentPinwheelGraphic.CoordinateSystem = CoordinateSystem.Source; _currentPinwheelGraphic.Rotation = GetRotationAngle(); _currentPinwheelGraphic.Draw(); } }
public override void OnDrawing() { base.OnDrawing(); if (!_isDirty) { return; } IOverlayGraphicsProvider overlayGraphicsProvider = this.ParentPresentationImage as IOverlayGraphicsProvider; if (overlayGraphicsProvider == null) { return; } IList <ShowAnglesToolGraphic> freeAngleGraphics = CollectionUtils.Cast <ShowAnglesToolGraphic>(this.Graphics); if (this.Visible && _selectedLine != null && _selectedLine.Points.Count == 2) { _selectedLine.CoordinateSystem = CoordinateSystem.Source; try { foreach (IGraphic otherLineGraphic in overlayGraphicsProvider.OverlayGraphics) { IPointsGraphic otherLine = GetLine(otherLineGraphic); if (otherLine != null && !ReferenceEquals(otherLine, _selectedLine) && otherLine.Points.Count == 2) { ShowAnglesToolGraphic showAnglesToolGraphic; if (freeAngleGraphics.Count > 0) { freeAngleGraphics.Remove(showAnglesToolGraphic = freeAngleGraphics[0]); } else { this.Graphics.Add(showAnglesToolGraphic = new ShowAnglesToolGraphic()); } showAnglesToolGraphic.CoordinateSystem = otherLine.CoordinateSystem = CoordinateSystem.Source; try { showAnglesToolGraphic.SetEndpoints(_selectedLine.Points[0], _selectedLine.Points[1], otherLine.Points[0], otherLine.Points[1]); } finally { showAnglesToolGraphic.ResetCoordinateSystem(); otherLine.ResetCoordinateSystem(); } } } } finally { _selectedLine.ResetCoordinateSystem(); } } foreach (IGraphic freeAngleGraphic in freeAngleGraphics) { this.Graphics.Remove(freeAngleGraphic); freeAngleGraphic.Dispose(); } }
protected abstract Roi CreateRoiFromGraphic(IOverlayGraphicsProvider overlayGraphics, T shapeData);
protected void AddGraphic(IPresentationImage image, IControlGraphic graphic, IOverlayGraphicsProvider provider) { _undoableCommand = new DrawableUndoableCommand(image); _undoableCommand.Enqueue(new AddGraphicUndoableCommand(graphic, provider.OverlayGraphics)); _undoableCommand.Name = CreationCommandName; _undoableCommand.Execute(); }