public void SetPicture(MtpData.MtpPicture picture) { this.activePicture = picture; }
public void DrawMtpPictureIntoCanvas( Canvas canvas, MtpData.MtpPicture pic, bool drawHandlePoints = true, bool drawBoundingBoxes = true) { // clear access if (canvas == null || pic == null) { return; } canvas.Children.Clear(); // prepare options correctly this.VisuOptions?.Prepare(); // for some tests, we need randomness #if _only_testing var rnd = new Random(); #endif // first, set up the canvas if (true) { if (pic.TotalSize.Width < 1 || pic.TotalSize.Height < 1) { return; } canvas.Width = pic.TotalSize.Width; canvas.Height = pic.TotalSize.Height; if (this.VisuOptions?.BackgroundBrush != null) { canvas.Background = this.VisuOptions.BackgroundBrush; scrollViewerVisu.Background = this.VisuOptions.BackgroundBrush; } } // assume, that the elements below are in a list foreach (var obj in pic.Objects) { // the check described in VDI2658 rely on RefBaseSystemUnitPath if (obj == null || obj.Name == null) { continue; } // // Pipe, FunctionLine, MeasurementLine // if (obj is MtpData.MtpConnectionObject conn) { // make appropriate poly line var l = new Polyline(); l.Stroke = Brushes.Black; l.StrokeThickness = 1; l.Points = conn.points; // line style SetLineStyle(l, obj.ObjClass); // draw l.Tag = conn; canvas.Children.Add(l); } // // VisualObject // if (obj is MtpData.MtpVisualObject vo) { // debug? if (obj.Name == "V001") { ; } // search var symbol = vo?.visObj?.Symbol; if (symbol?.SymbolData == null) { // make missing bounding box if (drawBoundingBoxes && vo.x.HasValue && vo.y.HasValue && vo.width.HasValue && vo.height.HasValue) { // box DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, ConstructRect(Brushes.Red, 2.0)); // label? var labeltb = UIElementHelper.CreateStickyLabel(this.LabelFontSettings, "" + vo.Name); UIElementHelper.DrawToCanvasAtPositionAligned(canvas, vo.x.Value + vo.width.Value / 2, vo.y.Value + vo.height.Value / 2, UIElementHelper.DrawToCanvasAlignment.Centered, labeltb); } continue; } // make a NEW content object to display & manipulate var contentObject = symbol.SymbolData as Canvas; if (contentObject == null) { continue; } contentObject = UIElementHelper.cloneElement(contentObject) as Canvas; // delete not necessary artifacts in the XAML UIElementHelper.FindNozzlesViaTags(contentObject, "Nozzle", extractShapes: true); UIElementHelper.FindNozzlesViaTags(contentObject, "Label", extractShapes: true); // same logic for potential dynamic instance var dynInstanceVO = vo.dynInstance?.CreateVisualObject(vo.width.Value, vo.height.Value); // // how to draw content? // if (dynInstanceVO != null) { // draw an dynamic instance object // make bounding box Rect if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, ConstructRect(Brushes.Violet, 1.0)); } // draw it var vb = ConstructViewboxVO(dynInstanceVO, 0.0 /* vo.rotation.Value */); vb.Stretch = Stretch.Uniform; vb.Tag = vo; DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, vb); } if (vo.dynInstance == null || vo.dynInstance.DrawSymbolAsWell) { if (vo.visObj != null && contentObject != null) { // how to draw based on valid vis obj information if (vo.visObj.Placement == MtpSymbol.SymbolPlaceType.FitNozzles && vo.nozzlePoints.Count > 0 && symbol.NozzlePos != null && symbol.NozzlePos.Length > 0) { // magnetically snap in // COG of "surrounding" nozzles, and distance var npArr = vo.nozzlePoints.ToArray(); var npCOG = UIElementHelper.ComputeCOG(npArr); var npRadius = UIElementHelper.ComputeRadiusForCenterPointer(npArr, npCOG.Value); // COG of content nozzles, and distance var contentCOG = UIElementHelper.ComputeCOG(symbol.NozzlePos); var contentRadius = UIElementHelper.ComputeRadiusForCenterPointer( symbol.NozzlePos, contentCOG.Value); // compute the delta between visual object's mid an its nozzle COG var contentCogToMid = new Point( contentCOG.Value.X - contentObject.Width / 2.0, contentCOG.Value.Y - contentObject.Height / 2.0); if (npArr == null || npCOG == null || npRadius == null || contentCOG == null || contentRadius == null) { continue; } // based on the radius and COG information, construct a start vector // FIX: radius could be 0! var start = new UIElementHelper.Transformation2D( (contentRadius.Value < 0.01) ? 1.0 : npRadius.Value / contentRadius.Value, vo.rotation.Value, npCOG.Value.X, npCOG.Value.Y ); // disturb it? #if _only_testing #pragma warning disable 162 // ReSharper disable once HeuristicUnreachableCode { // ReSharper disable once HeuristicUnreachableCode start.Rot += -15.0 + 30.0 * rnd.NextDouble(); start.Scale *= 0.8 + 0.4 * rnd.NextDouble(); start.OfsX += -5.0 + 10.0 * rnd.NextDouble(); start.OfsY += -5.0 + 10.0 * rnd.NextDouble(); } #pragma warning restore 162 #endif // improve it var better = UIElementHelper.FindBestFitForFieldOfPoints( symbol.NozzlePos, npArr, start, 0.3, 30.0, 10.0, 10, 3); if (better != null) { start = better; } // draw it UIElementHelper.ApplyMultiLabel(contentObject, new[] { new Tuple <string, string>("%TAG%", "" + vo.Name) }); if (obj.Name == "P001") { } var shape = ConstructDirectVO(contentObject, 1.0 * start.Scale, 1.0 * start.Rot, contentCOG.Value); shape.Width *= start.Scale; shape.Height *= start.Scale; var sr = new Rect( start.OfsX - shape.Width / 2, start.OfsY - shape.Height / 2, shape.Width, shape.Height); if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, sr.X, sr.Y, sr.Width, sr.Height, ConstructRect(Brushes.Blue, 1.0)); } // Correct position for drawing the shape for some IRRATIONAL offset and the delta // between shape's mid and the COG of the nozzles sr.Location = new Point( sr.X - 2.0 - contentCogToMid.X * start.Scale, sr.Y - 2.0 - contentCogToMid.Y * start.Scale); // for debugging? //// DrawHandlePoint(canvas, sr.X, sr.Y, drawHandlePoints); // draw shape.Tag = vo; shape.BorderThickness = new Thickness(2); shape.BorderBrush = Brushes.Orange; DrawToCanvasAtPositionSize(canvas, sr.X, sr.Y, sr.Width, sr.Height, shape); // register in dynInstance? if (vo.dynInstance != null) { vo.dynInstance.SymbolElement = shape; vo.dynInstance.RedrawSymbol(); } // draw the label at mid of bounding box var labeltb = UIElementHelper.CreateStickyLabel(this.LabelFontSettings, "" + vo.Name); labeltb.Tag = vo; UIElementHelper.DrawToCanvasAtPositionAligned(canvas, vo.x.Value + vo.width.Value / 2, vo.y.Value + vo.height.Value / 2, UIElementHelper.TranslateRotToAlignemnt(start.Rot), labeltb); } else if (vo.visObj.Placement == MtpSymbol.SymbolPlaceType.StretchToBoundingBox) { // make bounding box Rect if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, ConstructRect(Brushes.Blue, 1.0)); } // draw it UIElementHelper.ApplyMultiLabel(contentObject, new[] { new Tuple <string, string>("%TAG%", "" + vo.Name) }); var vb = ConstructViewboxVO(contentObject, vo.rotation.Value); vb.Tag = vo; DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, vb); } else { // right now, impossible! } } else { // make missing part Rect if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, vo.x.Value, vo.y.Value, vo.width.Value, vo.height.Value, ConstructRect(Brushes.Red, 2.0)); } } } // handle in the mid DrawHandlePoint(canvas, vo.x.Value + vo.width.Value / 2, vo.y.Value + vo.height.Value / 2, drawHandlePoints); } // // Topology Object // if (obj is MtpData.MtpTopologyObject to) { // draw source / sink? if (to.ObjClass >= 301 && to.ObjClass <= 302 && to.x != null && to.y != null) { // get visual object var contentObject = ConstructContentObject(to.visObj); UIElementHelper.ApplyMultiLabel(contentObject, new[] { new Tuple <string, string>("%TAG%", "" + to.Name) }); if (to.visObj != null && contentObject != null) { // determine XY // Note: still not knowing, if to use nozzle or measurement Nullable <Point> targetPos = null; if (to.nozzlePoints != null && to.nozzlePoints.Count > 0 && to.nozzlePoints[0].X > 0.001 && to.nozzlePoints[0].Y > 0.001) { targetPos = to.nozzlePoints[0]; } if (to.measurementPoints != null && to.measurementPoints.Count > 0 && to.measurementPoints[0].X > 0.001 && to.measurementPoints[0].Y > 0.001) { targetPos = to.measurementPoints[0]; } if (targetPos == null) { targetPos = new Point(to.x.Value, to.y.Value); } // draw nozzle based if (to.visObj.Placement == MtpSymbol.SymbolPlaceType.FitNozzles && to.visObj.Symbol?.NozzlePos != null && to.visObj.Symbol?.NozzlePos.Length > 0) { // draw centered to nozzle pos in fixed size var vb = ConstructViewboxVO(contentObject, rotation: 0.0); vb.Height = 40; vb.Width = 40; vb.Stretch = Stretch.UniformToFill; vb.Tag = to; UIElementHelper.DrawToCanvasAtPositionAligned(canvas, targetPos.Value.X, targetPos.Value.Y, UIElementHelper.DrawToCanvasAlignment.Centered, vb); // make bounding box Rect if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, targetPos.Value.X - vb.Width / 2, targetPos.Value.Y - vb.Height / 2, vb.Width, vb.Height, ConstructRect(Brushes.Blue, 1.0)); } // draw a nice label var labelPos = UIElementHelper.RescalePointsByRatioOfFEs(contentObject, vb, to.visObj.Symbol?.LabelPos); // draw the label var pos = new Point(targetPos.Value.X, targetPos.Value.Y); var li = (int)to.visObj.LabelAlignment; if (li >= 0 && labelPos != null && li < labelPos.Length) { pos = pos + (Vector)labelPos[li]; } var labeltb = UIElementHelper.CreateStickyLabel(this.LabelFontSettings, "" + to.Name); labeltb.Tag = to; UIElementHelper.DrawToCanvasAtPositionAligned(canvas, pos.X, pos.Y, to.visObj.LabelAlignment, labeltb); } else { // draw square-sized symbol in fixed size over (x/y) var size = 50; // make bounding box Rect if (drawBoundingBoxes) { DrawToCanvasAtPositionSize(canvas, // ReSharper disable PossibleLossOfFraction to.x.Value - size / 2, to.y.Value - size / 2, size, size, ConstructRect(Brushes.DarkOrange, 1.0)); } // all helpers are NULL-invariant var vb = ConstructViewboxVO(contentObject, rotation: 0.0); vb.Tag = to; DrawToCanvasAtPositionSize(canvas, to.x.Value - size / 2, to.y.Value - size / 2, size, size, vb); } // handle DrawHandlePoint(canvas, targetPos.Value.X, targetPos.Value.Y, drawHandlePoints); } } } } }