public LotEditorItemMarker CreateGeometry() { LotEditorItemMarker marker = new LotEditorItemMarker(this); Model3DCollection coll = new Model3DCollection(); TruncatedConeVisual3D cone = new TruncatedConeVisual3D(); cone.Height = 2.5; cone.BaseRadius = 0; cone.TopRadius = 1; cone.Material = MaterialHelper.CreateMaterial(Brushes.Red, new SolidColorBrush(Color.FromScRgb(1f, 0.2f, 0.0f, 0f))); marker.ManipulatorModel = cone.Model; marker.Transform = new MatrixTransform3D(this.Transform.GetAsMatrix3D()); ModelRepresentation = marker; BillboardTextVisual3D billboard = new BillboardTextVisual3D(); billboard.Text = Index.ToString(); billboard.Background = Brushes.White; billboard.Transform = new TranslateTransform3D(0, 0, 5); marker.Children.Add(billboard); return(marker); }
public ChickenData( GameObjectId id, Point3D position, double beakAngle, ModelVisual3D visual, MatrixTransform3D transform, BillboardTextVisual3D billboardVisual) : base(id, position, transform) { #region Argument Check if (visual == null) { throw new ArgumentNullException("visual"); } if (billboardVisual == null) { throw new ArgumentNullException("billboardVisual"); } #endregion this.BeakAngle = beakAngle; this.Visual = visual; this.BillboardVisual = billboardVisual; }
internal void add3DText(Point3D point, string text) { BillboardTextVisual3D txt = new BillboardTextVisual3D(); point.Y = point.Y + 5; txt.Position = point; txt.FontSize = 12; txt.Text = text; txt.Height = 25; this.Children.Add(txt); _text.Add(point, txt); }
private void View1_MouseDown(object sender, MouseButtonEventArgs e) { var viewport = (HelixViewport3D)sender; var firstHit = viewport.Viewport.FindHits(e.GetPosition(viewport)).FirstOrDefault(); if (firstHit != null) { if (firstHit.Visual is BillboardTextVisual3D) { BillboardTextVisual3D t = (BillboardTextVisual3D)firstHit.Visual; dgvCalc.CurrentItem = lstHeadLossCalcs.FirstOrDefault(x => x.ElementId == Convert.ToInt32(t.Text.ToString())); } } }
/// <summary> /// Initializes a new instance of the <see cref="BillboardTextVisualizationObject"/> class. /// </summary> public BillboardTextVisualizationObject() { this.billboard = new BillboardTextVisual3D() { BorderBrush = new SolidColorBrush(this.BillboardBorderColor), Background = new SolidColorBrush(this.BillboardBackgroundColor) { Opacity = this.BillboardOpacity * 0.01, }, Foreground = new SolidColorBrush(this.BillboardForegroundColor), Padding = new System.Windows.Thickness(this.BillboardPadding), }; this.UpdateVisibility(); }
private void InitializeVisualData(GamePresentation presentation) { ClearData(); foreach (var chicken in presentation.Chickens) { var material = chicken.Team == GameTeam.Light ? LightTeamUnitMaterial : DarkTeamUnitMaterial; var currentPosition = chicken.GetCurrentPosition(); var matrix = GetChickenTransformMatrix(chicken); var transform = new MatrixTransform3D(matrix); var position = ConvertEnginePosition(currentPosition.Position); var chickenVisual = new ModelVisual3D { Content = new GeometryModel3D(_chickenGeometry, material) { Transform = transform } }; var billboardVisual = new BillboardTextVisual3D { Text = "(ID)", FontWeight = FontWeights.ExtraBold, FontSize = 9, Foreground = new SolidColorBrush( chicken.Team == GameTeam.Light ? LightTeamCaptionColor : DarkTeamCaptionColor), Background = new SolidColorBrush(Colors.Gray.WithAlpha(128)), BorderBrush = new SolidColorBrush(Colors.Red.WithAlpha(128)), BorderThickness = new Thickness(1) }; var data = new ChickenData( chicken.UniqueId, position, currentPosition.Angle.DegreeValue, chickenVisual, transform, billboardVisual); _chickenDatas.Add(data.Id, data); _chickenVisualToData.Add(chickenVisual, data); this.BoardVisual.Children.Add(chickenVisual); this.BoardVisual.Children.Add(billboardVisual); } }
/// <summary>Creates the plot elements.</summary> /// <remarks>Changes to the bounding box and other parameters will not take effect until this method is called.</remarks> public void CreateElements() { double lineThickness = 500 / 1000; labelOffset = lineThickness * 50; minDistanceSquared = MinDistance * MinDistance; if (EnableMarker)//Elements.HasFlag(EElements.Marker { marker = new TruncatedConeVisual3D(); marker.Height = labelOffset; marker.BaseRadius = 0.0; marker.TopRadius = labelOffset / 5; marker.TopCap = true; marker.Origin = new Point3D(0.0, 0.0, 0.0); marker.Normal = new Vector3D(-1.0, -1.0, 1.0); marker.Fill = MarkerBrush; parentViewport.Children.Add(marker); coords = new BillboardTextVisual3D(); coordinateFormat = string.Format("{{0:F{0}}}, {{1:F{0}}}, {{2:F{0}}}", DecimalPlaces, DecimalPlaces, DecimalPlaces); // "{0:F2}, {1:F2}, {2:F2}" coords.Text = string.Format(coordinateFormat, 0.0, 0.0, 0.0); coords.Foreground = MarkerBrush; coords.Position = new Point3D(-labelOffset, -labelOffset, labelOffset); parentViewport.Children.Add(coords); } else { marker = null; coords = null; } if (trace != null) { foreach (LinesVisual3D p in trace) { parentViewport.Children.Add(p); } if (trace.Count > 0) { path = trace[trace.Count - 1]; } } }
public void Draw() { //3D Drawing BillboardTextVisual3D txt1; LinesVisual3D linesVisual; PointsVisual3D pointsVisual; Point3DCollection pts = new Point3DCollection(); View1.Children.Clear(); foreach (HeadLossCalc i in lstHeadLossCalcs) { Point3D p1 = new Point3D(i.Node1.X, i.Node1.Y, i.Node1.Z); pts.Add(p1); Point3D p2 = new Point3D(i.Node2.X, i.Node2.Y, i.Node2.Z); pts.Add(p2); txt1 = new BillboardTextVisual3D(); txt1.Text = i.ElementId.ToString(); txt1.Position = new Point3D((i.Node1.X + i.Node2.X) / 2, (i.Node1.Y + i.Node2.Y) / 2, (i.Node1.Z + i.Node2.Z) / 2); View1.Children.Add(txt1); } GridLinesVisual3D grid = new GridLinesVisual3D(); grid.Length = 50000; grid.Width = 50000; grid.MajorDistance = 10000; grid.MinorDistance = 1000; grid.Visible = true; grid.Thickness = 10; View1.Children.Add(grid); pointsVisual = new PointsVisual3D { Color = Colors.Red, Size = 4 }; pointsVisual.Points = pts; View1.Children.Add(pointsVisual); linesVisual = new LinesVisual3D { Color = Colors.Blue }; linesVisual.Points = pts; linesVisual.Thickness = 2; View1.Children.Add(linesVisual); View1.ZoomExtents(10); }
/// <summary> /// Adds the StartElements for one Axis of the Coordinate System. /// </summary> /// <param name="direction">The Direction of the Axis.</param> /// <param name="brush">The Brush defines the Color of the Arrow and Label.</param> /// <param name="position">Position of the Axis Label.</param> /// <param name="text">The Axis Label Text.</param> private void AddAxisInfo(Vector3D direction, Brush brush, Point3D position, string text) { var asix = new ArrowVisual3D() { Direction = direction, HeadLength = 2, Diameter = 0.05, Fill = brush }; _startElements.Add(new Visual3DViewModel(null, asix, $"{text} - Axis")); var axisLabel = new BillboardTextVisual3D() { Position = position, Text = text, Foreground = brush, FontSize = 18 }; _startElements.Add(new Visual3DViewModel(null, axisLabel, text)); }
public void UpdateDebugLabels() { if (!IsDebugEnabled) { return; } double n = Math.Pow(2, TileZoom); double inverseZoom = 18 - tileZoom; double newTileX = TileX * Math.Pow(2, inverseZoom); double newTileY = tileY * Math.Pow(2, inverseZoom); double NormalizedX = (scale.NormalizeX(newTileX) + scale.NormalizeX(TileService.xTileOffset)); double NormalizedY = (scale.NormalizeY(newTileY) + scale.NormalizeY(TileService.yTileOffset)); double osmTileXPreFloor = NormalizedX * n; double osmTileYPreFloor = NormalizedY * n; int osmTileX = (int)Math.Floor(osmTileXPreFloor); int osmTileY = (int)Math.Floor(osmTileYPreFloor); //Clear any previous this.Children.Clear(); //Generate a unique tile color Random r = new Random(Guid.NewGuid().GetHashCode()); Color color = Color.FromArgb(100, (byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255)); //Create a small border for tile double borderSize = Width * 0.05; // 5% RectangleVisual3D LeftEdge = new RectangleVisual3D(); RectangleVisual3D RightEdge = new RectangleVisual3D(); RectangleVisual3D TopEdge = new RectangleVisual3D(); RectangleVisual3D BottomEdge = new RectangleVisual3D(); double offset = Width / 2; //LeftEdge LeftEdge.Origin = new Point3D(borderSize / 2 - offset, Width / 2 - offset, 0.1); LeftEdge.Width = Width; LeftEdge.Length = borderSize; LeftEdge.Fill = new SolidColorBrush(color); //Right Edge RightEdge.Origin = new Point3D(Width - borderSize / 2 - offset, Width / 2 - offset, 0.1); RightEdge.Length = borderSize; RightEdge.Width = Width; RightEdge.Fill = new SolidColorBrush(color); //TopEdge TopEdge.Origin = new Point3D(Width / 2 - offset, borderSize / 2 - offset, 0.1); TopEdge.Width = borderSize; TopEdge.Length = Width; TopEdge.Fill = new SolidColorBrush(color); //BottomEdge BottomEdge.Origin = new Point3D(Width / 2 - offset, Width - borderSize / 2 - offset, 0.1); BottomEdge.Width = borderSize; BottomEdge.Length = Width; BottomEdge.Fill = new SolidColorBrush(color); //Create text billboard for x / y values BillboardTextVisual3D tilenumBilboard = new BillboardTextVisual3D(); tilenumBilboard.Position = new Point3D(0, 0, 8 + inverseZoom * 4); tilenumBilboard.Background = Brushes.LightSalmon; tilenumBilboard.Text = $"TXY: {TileX}/{TileY} NTXY: {newTileX}/{newTileY} \n OSMTXY: {osmTileXPreFloor}/{osmTileYPreFloor} \n OSMFTXY: {osmTileX - 1}/{osmTileY}"; Children.Add(LeftEdge); Children.Add(RightEdge); Children.Add(TopEdge); Children.Add(BottomEdge); Children.Add(tilenumBilboard); }
private void AddBody(ulong trackingId) { List <SphereVisual3D> joints = new List <SphereVisual3D>(); List <bool> jointsTracked = new List <bool>(); for (int i = 0; i < Body.JointCount; i++) { var bodyPart = new SphereVisual3D() { ThetaDiv = SphereDiv, PhiDiv = SphereDiv, }; joints.Add(bodyPart); jointsTracked.Add(true); this.Children.Add(bodyPart); } this.bodyJoints.Add(trackingId, joints); this.bodyJointsTracked.Add(trackingId, jointsTracked); var bones = new Dictionary <Tuple <JointType, JointType>, PipeVisual3D> { { Tuple.Create(JointType.HandTipLeft, JointType.HandLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ThumbLeft, JointType.HandLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.HandLeft, JointType.WristLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.WristLeft, JointType.ElbowLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ElbowLeft, JointType.ShoulderLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ShoulderLeft, JointType.SpineShoulder), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.HandTipRight, JointType.HandRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ThumbRight, JointType.HandRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.HandRight, JointType.WristRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.WristRight, JointType.ElbowRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ElbowRight, JointType.ShoulderRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.ShoulderRight, JointType.SpineShoulder), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.Head, JointType.Neck), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.Neck, JointType.SpineShoulder), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.SpineShoulder, JointType.SpineBase), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.SpineBase, JointType.HipRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.HipRight, JointType.KneeRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.KneeRight, JointType.AnkleRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.AnkleRight, JointType.FootRight), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.SpineBase, JointType.HipLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.HipLeft, JointType.KneeLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.KneeLeft, JointType.AnkleLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, { Tuple.Create(JointType.AnkleLeft, JointType.FootLeft), new PipeVisual3D() { ThetaDiv = PipeDiv } }, }; var bonesTracked = new Dictionary <Tuple <JointType, JointType>, bool> { { Tuple.Create(JointType.HandTipLeft, JointType.HandLeft), true }, { Tuple.Create(JointType.ThumbLeft, JointType.HandLeft), true }, { Tuple.Create(JointType.HandLeft, JointType.WristLeft), true }, { Tuple.Create(JointType.WristLeft, JointType.ElbowLeft), true }, { Tuple.Create(JointType.ElbowLeft, JointType.ShoulderLeft), true }, { Tuple.Create(JointType.ShoulderLeft, JointType.SpineShoulder), true }, { Tuple.Create(JointType.HandTipRight, JointType.HandRight), true }, { Tuple.Create(JointType.ThumbRight, JointType.HandRight), true }, { Tuple.Create(JointType.HandRight, JointType.WristRight), true }, { Tuple.Create(JointType.WristRight, JointType.ElbowRight), true }, { Tuple.Create(JointType.ElbowRight, JointType.ShoulderRight), true }, { Tuple.Create(JointType.ShoulderRight, JointType.SpineShoulder), true }, { Tuple.Create(JointType.Head, JointType.Neck), true }, { Tuple.Create(JointType.Neck, JointType.SpineShoulder), true }, { Tuple.Create(JointType.SpineShoulder, JointType.SpineBase), true }, { Tuple.Create(JointType.SpineBase, JointType.HipRight), true }, { Tuple.Create(JointType.HipRight, JointType.KneeRight), true }, { Tuple.Create(JointType.KneeRight, JointType.AnkleRight), true }, { Tuple.Create(JointType.AnkleRight, JointType.FootRight), true }, { Tuple.Create(JointType.SpineBase, JointType.HipLeft), true }, { Tuple.Create(JointType.HipLeft, JointType.KneeLeft), true }, { Tuple.Create(JointType.KneeLeft, JointType.AnkleLeft), true }, { Tuple.Create(JointType.AnkleLeft, JointType.FootLeft), true }, }; foreach (var b in bones) { this.Children.Add(b.Value); } this.bodyBones.Add(trackingId, bones); this.bodyBonesTracked.Add(trackingId, bonesTracked); // add the billboard var billboard = new BillboardTextVisual3D() { // Background = new SolidColorBrush(Color.FromArgb(255, 70, 85, 198)), Background = Brushes.Gray, Foreground = new SolidColorBrush(Colors.White), Padding = new System.Windows.Thickness(5), Text = $"Kinect Id: {this.numBodies++}", }; this.trackingIdBillboards.Add(trackingId, billboard); this.Children.Add(billboard); this.UpdateProperties(); }
/// <summary>Creates the plot elements.</summary> /// <remarks>Changes to the bounding box and other parameters will not take effect until this method is called.</remarks> public void CreateElements() { Children.Clear(); Children.Add(new DefaultLights()); string[] labels = AxisLabels.Split(','); if (labels.Length < 3) { labels = new string[] { "X", "Y", "Z" } } ; double bbSize = Math.Max(Math.Max(BoundingBox.SizeX, BoundingBox.SizeY), BoundingBox.SizeZ); double lineThickness = bbSize / 1000; double arrowOffset = lineThickness * 30; labelOffset = lineThickness * 50; minDistanceSquared = MinDistance * MinDistance; if (Elements.HasFlag(EElements.Grid)) { var grid = new GridLinesVisual3D(); grid.Center = new Point3D(BoundingBox.X + 0.5 * BoundingBox.SizeX, BoundingBox.Y + 0.5 * BoundingBox.SizeY, BoundingBox.Z); grid.Length = BoundingBox.SizeX; grid.Width = BoundingBox.SizeY; grid.MinorDistance = TickSize; grid.MajorDistance = bbSize; grid.Thickness = lineThickness; grid.Fill = AxisBrush; Children.Add(grid); } if (Elements.HasFlag(EElements.Axes)) { var arrow = new ArrowVisual3D(); arrow.Point2 = new Point3D((BoundingBox.X + BoundingBox.SizeX) + arrowOffset, 0.0, 0.0); arrow.Diameter = lineThickness * 5; arrow.Fill = AxisBrush; Children.Add(arrow); var label = new BillboardTextVisual3D(); label.Text = labels[0]; label.FontWeight = FontWeights.Bold; label.Foreground = AxisBrush; label.Position = new Point3D((BoundingBox.X + BoundingBox.SizeX) + labelOffset, 0.0, 0.0); Children.Add(label); arrow = new ArrowVisual3D(); arrow.Point2 = new Point3D(0.0, (BoundingBox.Y + BoundingBox.SizeY) + arrowOffset, 0.0); arrow.Diameter = lineThickness * 5; arrow.Fill = AxisBrush; Children.Add(arrow); label = new BillboardTextVisual3D(); label.Text = labels[1]; label.FontWeight = FontWeights.Bold; label.Foreground = AxisBrush; label.Position = new Point3D(0.0, (BoundingBox.Y + BoundingBox.SizeY) + labelOffset, 0.0); Children.Add(label); if (BoundingBox.SizeZ > 0) { arrow = new ArrowVisual3D(); arrow.Point2 = new Point3D(0.0, 0.0, (BoundingBox.Z + BoundingBox.SizeZ) + arrowOffset); arrow.Diameter = lineThickness * 5; arrow.Fill = AxisBrush; Children.Add(arrow); label = new BillboardTextVisual3D(); label.Text = labels[2]; label.FontWeight = FontWeights.Bold; label.Foreground = AxisBrush; label.Position = new Point3D(0.0, 0.0, (BoundingBox.Z + BoundingBox.SizeZ) + labelOffset); Children.Add(label); } } if (Elements.HasFlag(EElements.BoundingBox) && BoundingBox.SizeZ > 0) { var box = new BoundingBoxWireFrameVisual3D(); box.BoundingBox = BoundingBox; box.Thickness = 1; box.Color = AxisBrush.Color; Children.Add(box); } if (Elements.HasFlag(EElements.Marker)) { marker = new TruncatedConeVisual3D(); marker.Height = labelOffset; marker.BaseRadius = 0.0; marker.TopRadius = labelOffset / 5; marker.TopCap = true; marker.Origin = new Point3D(0.0, 0.0, 0.0); marker.Normal = new Vector3D(-1.0, -1.0, 1.0); marker.Fill = MarkerBrush; Children.Add(marker); coords = new BillboardTextVisual3D(); coordinateFormat = string.Format("{{0:F6}}, {{1:F6}}, {{2:F6}}", DecimalPlaces, DecimalPlaces, DecimalPlaces); // "{0:F2}, {1:F2}, {2:F2}" coords.Text = string.Format(coordinateFormat, 0.0, 0.0, 0.0); coords.Foreground = MarkerBrush; coords.Position = new Point3D(-labelOffset, -labelOffset, labelOffset); Children.Add(coords); } else { marker = null; coords = null; } if (trace != null) { foreach (LinesVisual3D p in trace) { Children.Add(p); } path = trace[trace.Count - 1]; } }
private void RenderBoard(LagoVista.EaglePCB.Models.PCB board, LagoVista.EaglePCB.Models.PCBProject project, bool resetZoomAndView = true) { var linePoints = new Point3DCollection(); var modelGroup = new Model3DGroup(); var copperMaterial = MaterialHelper.CreateMaterial(Color.FromRgb(0xb8, 0x73, 0x33)); var redMaterial = MaterialHelper.CreateMaterial(Colors.Red); var greenMaterial = MaterialHelper.CreateMaterial(Colors.Green); var blueMaterial = MaterialHelper.CreateMaterial(Colors.Blue); var blackMaterial = MaterialHelper.CreateMaterial(Colors.Black); var grayMaterial = MaterialHelper.CreateMaterial(Colors.DarkGray); var scrapX = project == null ? 0 : project.ScrapSides; var scrapY = project == null ? 0 : project.ScrapTopBottom; var boardThickness = project == null ? 1.60 : project.StockThickness; if (_topWiresVisible) { foreach (var wireSection in board.TopWires.GroupBy(wre => wre.Width)) { var width = wireSection.First().Width; foreach (var wire in wireSection) { var topWireMeshBuilder = new MeshBuilder(false, false); var boxRect = new Rect3D(wire.Rect.X1 - (width / 2), wire.Rect.Y1, -0.1, width, wire.Rect.Length, 0.2); topWireMeshBuilder.AddBox(boxRect); topWireMeshBuilder.AddCylinder(new Point3D(wire.Rect.X1, wire.Rect.Y1, -0.1), new Point3D(wire.Rect.X1, wire.Rect.Y1, .1), width / 2, 50, true, true); var boxModel = new GeometryModel3D() { Geometry = topWireMeshBuilder.ToMesh(true), Material = copperMaterial }; boxModel.Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), wire.Rect.Angle), new Point3D(wire.Rect.X1, wire.Rect.Y1, 0)); modelGroup.Children.Add(boxModel); } } } if (_bottomWiresVisible) { foreach (var wireSection in board.BottomWires.GroupBy(wre => wre.Width)) { var width = wireSection.First().Width; foreach (var wire in wireSection) { var topWireMeshBuilder = new MeshBuilder(false, false); var boxRect = new Rect3D(wire.Rect.X1 - (width / 2), wire.Rect.Y1, -0.105, width, wire.Rect.Length, 0.2); topWireMeshBuilder.AddBox(boxRect); topWireMeshBuilder.AddCylinder(new Point3D(wire.Rect.X1, wire.Rect.Y1, -0.105), new Point3D(wire.Rect.X1, wire.Rect.Y1, .095), width / 2, 50, true, true); var boxModel = new GeometryModel3D() { Geometry = topWireMeshBuilder.ToMesh(true), Material = grayMaterial }; boxModel.Transform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), wire.Rect.Angle), new Point3D(wire.Rect.X1, wire.Rect.Y1, 0)); modelGroup.Children.Add(boxModel); } } } foreach (var element in board.Components) { foreach (var pad in element.SMDPads) { var padMeshBuilder = new MeshBuilder(false, false); padMeshBuilder.AddBox(new Rect3D(pad.OriginX - (pad.DX / 2), pad.OriginY - (pad.DY / 2), -0.1, (pad.DX), (pad.DY), 0.2)); var box = new GeometryModel3D() { Geometry = padMeshBuilder.ToMesh(true), Material = element.Layer == 1 ? copperMaterial : grayMaterial }; var transformGroup = new Transform3DGroup(); transformGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), element.RotateAngle))); transformGroup.Children.Add(new TranslateTransform3D(new Vector3D(element.X.Value, element.Y.Value, element.Layer == 1 ? 0 : 0.05))); box.Transform = transformGroup; modelGroup.Children.Add(box); } foreach (var pad in element.Pads) { var padCopperMeshBuilder = new MeshBuilder(false, false); padCopperMeshBuilder.AddCylinder(new Point3D(pad.X, pad.Y, 0), new Point3D(pad.X, pad.Y, 0.1), pad.DrillDiameter * 0.75); var padCopper = new GeometryModel3D() { Geometry = padCopperMeshBuilder.ToMesh(true), Material = copperMaterial }; modelGroup.Children.Add(padCopper); var padDrillMeshBuilder = new MeshBuilder(false, false); padDrillMeshBuilder.AddCylinder(new Point3D(pad.X, pad.Y, 0), new Point3D(pad.X, pad.Y, 0.101), pad.DrillDiameter / 2); var padDrill = new GeometryModel3D() { Geometry = padDrillMeshBuilder.ToMesh(true), Material = blackMaterial }; modelGroup.Children.Add(padDrill); } if (_pcbVisible) { var billBoard = new BillboardTextVisual3D() { Foreground = Brushes.White, Text = element.Name, Position = new Point3D(element.X.Value + scrapX, element.Y.Value + scrapY, 4), FontSize = 14 }; viewport.Children.Add(billBoard); } } foreach (var via in board.Vias) { var padCopperMeshBuilder = new MeshBuilder(false, false); padCopperMeshBuilder.AddCylinder(new Point3D(via.X, via.Y, 0), new Point3D(via.X, via.Y, 0.1), (via.DrillDiameter)); var padCopper = new GeometryModel3D() { Geometry = padCopperMeshBuilder.ToMesh(true), Material = copperMaterial }; modelGroup.Children.Add(padCopper); var padDrillMeshBuilder = new MeshBuilder(false, false); padDrillMeshBuilder.AddCylinder(new Point3D(via.X, via.Y, 0), new Point3D(via.X, via.Y, 0.11), via.DrillDiameter / 2); var padDrill = new GeometryModel3D() { Geometry = padDrillMeshBuilder.ToMesh(true), Material = blackMaterial }; modelGroup.Children.Add(padDrill); } if (_pcbVisible) { foreach (var circle in board.Holes) { var circleMeshBuilder = new MeshBuilder(false, false); circleMeshBuilder.AddCylinder(new Point3D(circle.X, circle.Y, 0), new Point3D(circle.X, circle.Y, 0.01), circle.Drill / 2); modelGroup.Children.Add(new GeometryModel3D() { Geometry = circleMeshBuilder.ToMesh(true), Material = blackMaterial }); } #region Hold your nose to discover why irregular boards don't render as expected... /* gonna cheat here in next chunk of code...need to make progress, assume all corners are * either square or round. If rounded, same radius...WILL revisit this at some point, KDW 2/24/2017 * FWIW - feel so dirty doing this, but need to move on :*( * very happy to accept a PR to fix this! Proper mechanism is to create a polygon and likely subdivide the curve into smaller polygon edges * more work than it's worth right now....sorry again :( */ //TODO: Render proper edge of board. var boardEdgeMeshBuilder = new MeshBuilder(false, false); var cornerWires = board.Layers.Where(layer => layer.Number == 20).FirstOrDefault().Wires.Where(wire => wire.Curve.HasValue == true); var radius = cornerWires.Any() ? Math.Abs(cornerWires.First().Rect.X1 - cornerWires.First().Rect.X2) : 0; if (radius == 0) { boardEdgeMeshBuilder.AddBox(new Point3D(board.Width / 2, board.Height / 2, -boardThickness / 2), board.Width, board.Height, boardThickness); } else { boardEdgeMeshBuilder.AddBox(new Point3D(board.Width / 2, board.Height / 2, -boardThickness / 2), board.Width - (radius * 2), board.Height - (radius * 2), boardThickness); boardEdgeMeshBuilder.AddBox(new Point3D(board.Width / 2, radius / 2, -boardThickness / 2), board.Width - (radius * 2), radius, boardThickness); boardEdgeMeshBuilder.AddBox(new Point3D(board.Width / 2, board.Height - radius / 2, -boardThickness / 2), board.Width - (radius * 2), radius, boardThickness); boardEdgeMeshBuilder.AddBox(new Point3D(radius / 2, board.Height / 2, -boardThickness / 2), radius, board.Height - (radius * 2), boardThickness); boardEdgeMeshBuilder.AddBox(new Point3D(board.Width - radius / 2, board.Height / 2, -boardThickness / 2), radius, board.Height - (radius * 2), boardThickness); boardEdgeMeshBuilder.AddCylinder(new Point3D(radius, radius, -boardThickness), new Point3D(radius, radius, 0), radius, 50, true, true); boardEdgeMeshBuilder.AddCylinder(new Point3D(radius, board.Height - radius, -boardThickness), new Point3D(radius, board.Height - radius, 0), radius, 50, true, true); boardEdgeMeshBuilder.AddCylinder(new Point3D(board.Width - radius, radius, -boardThickness), new Point3D(board.Width - radius, radius, 0), radius, 50, true, true); boardEdgeMeshBuilder.AddCylinder(new Point3D(board.Width - radius, board.Height - radius, -boardThickness), new Point3D(board.Width - radius, board.Height - radius, 0), radius, 50, true, true); } modelGroup.Children.Add(new GeometryModel3D() { Geometry = boardEdgeMeshBuilder.ToMesh(true), Material = greenMaterial }); #endregion } PCBLayer.Content = modelGroup; PCBLayer.Transform = new TranslateTransform3D(scrapX, scrapY, 0); if (project != null) { var stockGroup = new Model3DGroup(); var circleMeshBuilder = new MeshBuilder(false, false); var holdDownDrills = project.GetHoldDownDrills(board); foreach (var drl in holdDownDrills) { circleMeshBuilder.AddCylinder(new Point3D(drl.X, drl.Y, -boardThickness), new Point3D(drl.X, drl.Y, 0.01), project.HoldDownDiameter / 2); } stockGroup.Children.Add(new GeometryModel3D() { Geometry = circleMeshBuilder.ToMesh(true), Material = blackMaterial }); if (_stockVisible) { var stockMeshBuilder = new MeshBuilder(false, false); stockMeshBuilder.AddBox(new Point3D(project.StockWidth / 2, project.StockHeight / 2, -boardThickness / 2), project.StockWidth, project.StockHeight, boardThickness - 0.05); stockGroup.Children.Add(new GeometryModel3D() { Geometry = stockMeshBuilder.ToMesh(true), Material = copperMaterial }); } StockLayer.Content = stockGroup; } else { StockLayer.Content = null; } if (resetZoomAndView) { RefreshExtents(); } }
/// <summary> /// This function contains all the "business logic" for constructing a SurfacePlot 3D. /// </summary> /// <returns>A Model3DGroup containing all the component models (mesh, surface definition, grid objects, etc).</returns> private Model3DGroup CreateModel() { var newModelGroup = new Model3DGroup(); double lineThickness = 0.01; double axesOffset = 0.05; // Get relevant constaints from the DataPoints object int sizeX = DataPoints.GetUpperBound(0) + 1; int sizeY = DataPoints.GetUpperBound(1) + 1; // Determine the x, y, and z ranges of the DataPoints collection int minX = int.MaxValue; int maxX = int.MinValue; int minY = int.MaxValue; int maxY = int.MinValue; double minZ = double.MaxValue; double maxZ = double.MinValue; double minColorValue = double.MaxValue; double maxColorValue = double.MinValue; for (int i = 0; i < sizeX; i++) { for (int j = 0; j < sizeY; j++) { int x = (int)DataPoints[i, j].X; int y = (int)DataPoints[i, j].Y; double z = DataPoints[i, j].Z; maxX = Math.Max(maxX, x); maxY = Math.Max(maxY, y); maxZ = Math.Max(maxZ, z); minX = Math.Min(minX, x); minY = Math.Min(minY, y); minZ = Math.Min(minZ, z); if (ColorValues != null) { maxColorValue = Math.Max(maxColorValue, ColorValues[i, j]); minColorValue = Math.Min(minColorValue, ColorValues[i, j]); } } } /* TEMP */ int numberOfXAxisTicks = sizeX - 1; //Updated by Guppy, was 10 int numberOfYAxisTicks = sizeY - 1; //Updated by Guppy, was 10 int numberOfZAxisTicks = 5; double XAxisInterval = 1; //Updated by Guppy, was (maxX - minX) / numberOfXAxisTicks; double YAxisInterval = 1; //Updated by Guppy, was (maxY - minY) / numberOfYAxisTicks; double ZAxisInterval = (maxZ - minZ) / numberOfZAxisTicks; /* /TEMP */ // Set color value to 0 at texture coordinate 0.5, with an even spread in either direction if (Math.Abs(minColorValue) < Math.Abs(maxColorValue)) { minColorValue = -maxColorValue; } else { maxColorValue = -minColorValue; } // Set the texture coordinates by either z-value or ColorValue var textureCoordinates = new Point[sizeX, sizeY]; for (int i = 0; i < sizeX; i++) { for (int j = 0; j < sizeY; j++) { double tc; if (ColorValues != null) { tc = (ColorValues[i, j] - minColorValue) / (maxColorValue - minColorValue); } else { tc = (DataPoints[i, j].Z - minZ) / (maxZ - minZ); } textureCoordinates[i, j] = new Point(tc, tc); } } // Build the surface model (i.e. the coloured surface model) MeshBuilder surfaceModelBuilder = new MeshBuilder(); surfaceModelBuilder.AddRectangularMesh(DataPoints, textureCoordinates); GeometryModel3D surfaceModel = new GeometryModel3D(surfaceModelBuilder.ToMesh(), MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0)); surfaceModel.BackMaterial = surfaceModel.Material; // Instantiate MeshBuilder objects for the Grid and SurfaceMeshLines meshes MeshBuilder surfaceMeshLinesBuilder = new MeshBuilder(); MeshBuilder gridBuilder = new MeshBuilder(); // Build the axes labels model (i.e. the object that holds the axes labels and ticks) ModelVisual3D axesLabelsModel = new ModelVisual3D(); // Add surface mesh lines which denote intervals along the x-axis for (int i = 0; i < sizeX; i++) { var surfacePath = new List <Point3D>(); for (int j = 0; j < sizeY; j++) { surfacePath.Add(DataPoints[i, j]); } surfaceMeshLinesBuilder.AddTube(surfacePath, lineThickness, 9, false); // Axes labels BillboardTextVisual3D label = new BillboardTextVisual3D(); label.Text = string.Format("{0}", i); label.Position = new Point3D(i, minY - axesOffset, minZ - axesOffset); axesLabelsModel.Children.Add(label); } // Add surface mesh lines which denote intervals along the y-axis for (int j = 0; j < sizeY; j++) { var surfacePath = new List <Point3D>(); for (int i = 0; i < sizeX; i++) { surfacePath.Add(DataPoints[i, j]); } surfaceMeshLinesBuilder.AddTube(surfacePath, lineThickness, 9, false); // Axes labels BillboardTextVisual3D label = new BillboardTextVisual3D(); label.Text = string.Format("{0}", j); label.Position = new Point3D(minX - axesOffset, j, minZ - axesOffset); axesLabelsModel.Children.Add(label); } // Loop through z intervals - for the grid, and Z axes ticks for (double z = minZ; z <= maxZ + 0.0001; z += ZAxisInterval) { // Grid lines var path = new List <Point3D>(); path.Add(new Point3D(minX, maxY, z)); path.Add(new Point3D(maxX, maxY, z)); path.Add(new Point3D(maxX, minY, z)); gridBuilder.AddTube(path, lineThickness, 9, false); // Axes labels BillboardTextVisual3D label = new BillboardTextVisual3D(); label.Text = string.Format("{0:F2}", z); label.Position = new Point3D(minX - axesOffset, maxY + axesOffset, z); axesLabelsModel.Children.Add(label); } // Add axes labels BillboardTextVisual3D xLabel = new BillboardTextVisual3D(); xLabel.Text = "X Axis"; xLabel.Position = new Point3D((maxX - minX) / 2, minY - 3 * axesOffset, minZ - 5 * axesOffset); axesLabelsModel.Children.Add(xLabel); BillboardTextVisual3D yLabel = new BillboardTextVisual3D(); yLabel.Text = "Y Axis"; yLabel.Position = new Point3D(minX - 3 * axesOffset, (maxY - minY) / 2, minZ - 5 * axesOffset); axesLabelsModel.Children.Add(yLabel); BillboardTextVisual3D zLabel = new BillboardTextVisual3D(); zLabel.Text = "Z Axis"; zLabel.Position = new Point3D(minX - 5 * axesOffset, maxY + 5 * axesOffset, 0); // Note: trying to find the midpoint of minZ, maxZ doesn't work when minZ = -0.5 and maxZ = 0.5... axesLabelsModel.Children.Add(zLabel); // Create models from MeshBuilders GeometryModel3D surfaceMeshLinesModel = new GeometryModel3D(surfaceMeshLinesBuilder.ToMesh(), Materials.Black); GeometryModel3D gridModel = new GeometryModel3D(gridBuilder.ToMesh(), Materials.Black); // Update model group this.Children.Add(axesLabelsModel); newModelGroup.Children.Add(surfaceModel); newModelGroup.Children.Add(surfaceMeshLinesModel); newModelGroup.Children.Add(gridModel); //ScaleTransform3D surfaceTransform = new ScaleTransform3D(1, 1, 2, 0, 0, 0); //newModelGroup.Transform = surfaceTransform; return(newModelGroup); }