/// <summary> /// Adds a gerber object to the selection buffer if it lies within the selection region. /// </summary> /// <param name="selectionInfo">current selection info</param> /// <param name="image">gerber image containing the net</param> /// <param name="net">net to add to the selection info</param> public void ObjectInSelectedRegion(SelectionInformation selectionInfo, ref int i, Graphics graphics) { bool inSelect = false; GerberImage image = selectionInfo.SelectionImage; GerberNet net = image.GerberNetList[i]; float x1 = (float)selectionInfo.LowerLeftX; float y1 = (float)selectionInfo.LowerLeftY; float x2 = (float)selectionInfo.UpperRightX; float y2 = (float)selectionInfo.UpperRightY; if (selectionInfo.SelectionType == GerberSelection.PointClick) { if (net.BoundingBox != null) { if (!net.BoundingBox.Contains(new PointD(x1, y1))) { return; } if (net.ApertureState == GerberApertureState.Flash) { inSelect = net.BoundingBox.Contains(new PointD(x1, y1)); } else if (net.ApertureState == GerberApertureState.On) { switch (net.Interpolation) { case GerberInterpolation.PolygonAreaStart: inSelect = net.BoundingBox.Contains(new PointD(x1, y1)); break; case GerberInterpolation.LinearX10: case GerberInterpolation.LinearX1: case GerberInterpolation.LinearX01: case GerberInterpolation.LinearX001: using (GraphicsPath gp = new GraphicsPath()) using (Pen pen = new Pen(Color.Transparent)) { pen.Width = (float)image.ApertureArray[net.Aperture].Parameters[0]; pen.StartCap = pen.EndCap = LineCap.Round; PointF start = new PointF((float)(net.StartX), (float)(net.StartY)); PointF end = new PointF((float)(net.StopX), (float)(net.StopY)); gp.AddLine(start, end); if (gp.IsOutlineVisible(new PointF(x1, y1), pen, graphics)) { inSelect = true; } break; } case GerberInterpolation.ClockwiseCircular: case GerberInterpolation.CounterClockwiseCircular: using (GraphicsPath gp = new GraphicsPath()) using (Pen pen = new Pen(Color.Transparent)) { float centerX = (float)net.CircleSegment.CenterX; float centerY = (float)net.CircleSegment.CenterY; float width = (float)net.CircleSegment.Width; float height = (float)net.CircleSegment.Height; float startAngle = (float)net.CircleSegment.StartAngle; float sweepAngle = (float)net.CircleSegment.SweepAngle; if (image.ApertureArray[net.Aperture].ApertureType == GerberApertureType.Rectangle) { pen.StartCap = pen.EndCap = LineCap.Square; } else { pen.StartCap = pen.EndCap = LineCap.Round; } RectangleF arcRectangle = new RectangleF(centerX - (width / 2), centerY - (height / 2), width, height); pen.Width = width; gp.AddArc(arcRectangle, startAngle, sweepAngle); if (gp.IsOutlineVisible(new PointF(x1, y1), pen, graphics)) { inSelect = true; } } break; } } } } else if (selectionInfo.SelectionType == GerberSelection.DragBox) { if (net.BoundingBox != null) { double left = Math.Min(selectionInfo.LowerLeftX, selectionInfo.UpperRightX); double right = Math.Max(selectionInfo.LowerLeftX, selectionInfo.UpperRightX); double top = Math.Min(selectionInfo.LowerLeftY, selectionInfo.UpperRightY); double bottom = Math.Max(selectionInfo.LowerLeftY, selectionInfo.UpperRightY); BoundingBox box = new BoundingBox(left, bottom, right, top); if (!box.Contains(net.BoundingBox)) { return; } if (net.ApertureState == GerberApertureState.Flash) { inSelect = box.Contains(net.BoundingBox); } else if (net.ApertureState == GerberApertureState.On) { inSelect = box.Contains(net.BoundingBox); } } } if (inSelect) { selectionInfo.SelectedNetList.Add(net); selectionInfo.SelectionCount++; if (net.Interpolation == GerberInterpolation.PolygonAreaStart) // Add all the poly points. { do { i++; net = image.GerberNetList[i]; selectionInfo.SelectedNetList.Add(net); } while (net.Interpolation != GerberInterpolation.PolygonAreaEnd); } } }
/// <summary> /// Calculates the overall image bounds of the project. /// </summary> /// <param name="project">project containing file list</param> public BoundingBox GetProjectBounds(GerberProject project) { double x1 = double.MaxValue, y1 = double.MaxValue, x2 = double.MinValue, y2 = double.MinValue; GerberImageInfo imageInfo; float minX, minY, maxX, maxY; int fileCount = project.FileInfo.Count; for (int i = 0; i < fileCount; i++) { if ((project.FileInfo[i] != null) && (project.FileInfo[i].IsVisible)) { imageInfo = project.FileInfo[i].Image.ImageInfo; // Find the biggest image and use as a size reference. minX = (float)imageInfo.MinX; minY = (float)imageInfo.MinY; maxX = (float)imageInfo.MaxX; maxY = (float)imageInfo.MaxY; if (!IsNormal(minX) || !IsNormal(minY) || !IsNormal(maxX) || !IsNormal(maxY)) { continue; } // Transform the bounding box based on the user supplied transformations. using (Matrix fullMatrix = new Matrix(1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f)) { // Don't use mirroring for the scale matrix double scaleX = project.UserTransform.ScaleX; double scaleY = project.UserTransform.ScaleY; if (project.UserTransform.MirrorAroundX) { scaleY *= -1; } if (project.UserTransform.MirrorAroundY) { scaleX *= -1; } fullMatrix.Scale((float)scaleX, (float)scaleY); fullMatrix.Rotate((float)project.UserTransform.Rotation); fullMatrix.Translate((float)project.UserTransform.TranslateX, (float)project.UserTransform.TranslateY); PointF[] points = new PointF[] { new PointF(minX, minY), new PointF(maxX, maxY) }; fullMatrix.TransformPoints(points); // Compare both min and max, since a mirror transform may have made "max" smaller than "min". x1 = Math.Min(x1, points[0].X); x1 = Math.Min(x1, points[1].X); y1 = Math.Min(y1, points[0].Y); y1 = Math.Min(y1, points[1].Y); x2 = Math.Max(x2, points[0].X); x2 = Math.Max(x2, points[1].X); y2 = Math.Max(y2, points[0].Y); y2 = Math.Max(y2, points[1].Y); } } } BoundingBox boundingbox = new BoundingBox(x1, y2, x2, y1); return(boundingbox); }