Пример #1
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Performs the plot Isolation Object actions required based on the current context
        /// </summary>
        /// <param name="isoPlotBuilder">A GCode Builder object</param>
        /// <param name="stateMachine">the gerber plot state machine</param>
        /// <param name="errorString">the error string we return on fail</param>
        /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
        /// <returns>an enum value indicating what next action to take</returns>
        public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
        {
            // one would think that turning off the contouring would be all that was necessary. However
            // contours are complex object and sometime we have to finish off the object usually this
            // means fill the existing contour object .
            if ((stateMachine.ContourDrawingModeEnabled == true) && (stateMachine.ComplexObjectList_DCode.Count != 0))
            {
                // process the complex object by drawing in the background

                // Get the bounding box
                Rectangle boundingRect = stateMachine.GetBoundingRectangleFromComplexObjectList_DCode();
                // get a list of builderIDs in the complex object list
                List <int> builderIDList = stateMachine.GetListOfIsoPlotBuilderIDsFromComplexObjectList_DCode();
                if (builderIDList.Count > 0)
                {
                    if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
                    {
                        // Normal Dark polarity. Just fill it in with a backgroundpixel
                        isoPlotBuilder.BackgroundFillGSRegionComplex(builderIDList, builderIDList[0], boundingRect.X, boundingRect.Y, boundingRect.X + boundingRect.Width, boundingRect.Y + boundingRect.Height, -1);
                    }
                    else if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_ERASE)
                    {
                        // we have reverse polarity. The object we just drew must be cleaned out and everything underneath it removed
                        isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, IsoPlotObject.DEFAULT_ISOPLOTOBJECT_ID, boundingRect.X, boundingRect.Y, boundingRect.X + boundingRect.Width, boundingRect.Y + boundingRect.Height, -1);
                    }
                }
            }
            // reset, we have processed the complex list
            stateMachine.ComplexObjectList_DCode = new List <GerberLine_DCode>();
            // disable contour drawing mode
            stateMachine.ContourDrawingModeEnabled = false;
            return(GerberLine.PlotActionEnum.PlotAction_Continue);
        }
Пример #2
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// If we draw a line with an aperture it will not always have linear ends
        /// for example if the aperture is a circle it will have half circle ends. Each
        /// line that is drawn calls this to make it look right visually
        /// </summary>
        /// <param name="graphicsObj">a graphics object to draw on</param>
        /// <param name="workingBrush">a brush to draw with</param>
        /// <param name="workingPen">the pen used for the line, we get the width from this</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="x2">the second x value</param>
        /// <param name="y2">the second y value</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <returns>z success, nz fail</returns>
        public void FixupLineEndpointsForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int x2, int y2, int radius, int xyComp)
        {
            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            if (ADCodeAperture == null)
            {
                return;
            }
            try
            {
                ADCodeAperture.FixupLineEndpointsForGCodePlot(isoPlotBuilder, stateMachine, x1, y1, x2, y2, radius, xyComp);
            }
            catch (Exception ex)
            {
                // rethrow with line number
                throw new Exception("Line Number:" + LineNumber.ToString() + ", " + ex.Message);
            }
        }
Пример #3
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// If we draw a line with an aperture it will not always have linear ends
        /// for example if the aperture is a circle it will have half circle ends. Each
        /// line that is drawn calls this to make it look right visually
        /// </summary>
        /// <param name="graphicsObj">a graphics object to draw on</param>
        /// <param name="workingBrush">a brush to draw with</param>
        /// <param name="workingPen">the pen used for the line, we get the width from this</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="x2">the second x value</param>
        /// <param name="y2">the second y value</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <returns>z success, nz fail</returns>
        public override void FixupLineEndpointsForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int x2, int y2, int radius, int xyComp)
        {
            IsoPlotUsageTagFlagEnum usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE;

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            // set the usage mode
            if (stateMachine.GerberFileLayerPolarity == GerberLayerPolarityEnum.CLEAR)
            {
                usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE;
            }
            else
            {
                usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE;
            }

            int xComp = (int)Math.Round(((xAxisDimension * stateMachine.IsoPlotPointsPerAppUnit)));
            int yComp = (int)Math.Round(((yAxisDimension * stateMachine.IsoPlotPointsPerAppUnit) / 2));

            isoPlotBuilder.DrawGSLineOutLine(usageMode, x1, y1 - yComp - xyComp, x1, y1 + yComp + xyComp, xComp + (2 * xyComp), stateMachine.BackgroundFillModeAccordingToPolarity);
            isoPlotBuilder.DrawGSLineOutLine(usageMode, x2, y2 - yComp - xyComp, x2, y2 + yComp + xyComp, xComp + (2 * xyComp), stateMachine.BackgroundFillModeAccordingToPolarity);
            return;
        }
Пример #4
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// If we draw a line with an aperture it will not always have linear ends
        /// for example if the aperture is a circle it will have half circle ends. Each
        /// line that is drawn calls this to make it look right visually
        /// </summary>
        /// <param name="graphicsObj">a graphics object to draw on</param>
        /// <param name="workingBrush">a brush to draw with</param>
        /// <param name="workingPen">the pen used for the line, we get the width from this</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="x2">the second x value</param>
        /// <param name="y2">the second y value</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <returns>z success, nz fail</returns>
        public override void FixupLineEndpointsForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int x2, int y2, int radius, int xyComp)
        {
            IsoPlotUsageTagFlagEnum usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE;

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            // set the usage mode
            if (stateMachine.GerberFileLayerPolarity == GerberLayerPolarityEnum.CLEAR)
            {
                usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE;
            }
            else
            {
                usageMode = IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE;
            }
            // fix up the two end points
            isoPlotBuilder.DrawGSCircle(usageMode, x1, y1, radius, stateMachine.BackgroundFillModeAccordingToPolarity, stateMachine.WantClockWise);
            isoPlotBuilder.DrawGSCircle(usageMode, x2, y2, radius, stateMachine.BackgroundFillModeAccordingToPolarity, stateMachine.WantClockWise);
            return;
        }
Пример #5
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash an aperture for a Circle on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <returns>z success, nz fail</returns>
        public override void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            List <int> macroBuilderIDs = new List <int>();

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            // get the macro AM code object for this aperture
            GerberLine_AMCode workingMacro = GetMacroObject(stateMachine);

            if (workingMacro == null)
            {
                throw new Exception("No macro definition found for name " + MacroName);
            }

            //// we run through our primitive list in order and and draw for GCode
            foreach (GerberMacroPrimitive_Base primObj in workingMacro.MacroPrimitives)
            {
                int builderID = primObj.FlashMacroPrimitiveForGCodePlot(this.VariableArray, macroBuilderIDs, isoPlotBuilder, stateMachine, x1, y1, xyComp);
                if (builderID <= 0)
                {
                    continue;
                }
                macroBuilderIDs.Add(builderID);
            }
        }
Пример #6
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     // This is just a circular interpolation
     stateMachine.GerberFileInterpolationMode = GerberInterpolationModeEnum.INTERPOLATIONMODE_CIRCULAR;
     stateMachine.GerberFileInterpolationCircularDirectionMode = GerberInterpolationCircularDirectionModeEnum.DIRECTIONMODE_COUNTERCLOCKWISE;
     return(GerberLine.PlotActionEnum.PlotAction_Continue);
 }
Пример #7
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Performs the plot Isolation Object actions required based on the current context
        /// </summary>
        /// <param name="isoPlotBuilder">A GCode Builder object</param>
        /// <param name="stateMachine">the gerber plot state machine</param>
        /// <param name="errorString">the error string we return on fail</param>
        /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
        /// <returns>an enum value indicating what next action to take</returns>
        public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
        {
            if (isoPlotBuilder == null)
            {
                errorValue  = 998;
                errorString = "PerformPlotIsoStep1Action (G54) isoPlotBuilder == null";
                return(GerberLine.PlotActionEnum.PlotAction_FailWithError);
            }
            if (stateMachine == null)
            {
                errorValue  = 999;
                errorString = "PerformPlotIsoStep1Action (G54) stateMachine == null";
                return(GerberLine.PlotActionEnum.PlotAction_FailWithError);
            }

            return(GerberLine.PlotActionEnum.PlotAction_Continue);
        }
Пример #8
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash an aperture for a Circle on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <returns>z success, nz fail</returns>
        public override void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            int workingOuterDiameter = int.MinValue;

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            // figure out the diameter
            workingOuterDiameter = (int)Math.Round((outerDiameter * stateMachine.IsoPlotPointsPerAppUnit));
            // now do the flash
            PerformCircularApertureFlashWithHole(isoPlotBuilder, stateMachine, x1, y1, xyComp, workingOuterDiameter, HoleDiameter);
        }
Пример #9
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Flash the aperture
 /// </summary>
 /// <param name="isoPlotBuilder">the builder opbject</param>
 /// <param name="stateMachine">the statemachine</param>
 /// <param name="xyComp">the xy compensation factor</param>
 /// <param name="x1">the first x value</param>
 /// <param name="y1">the first y value</param>
 /// <returns>z success, nz fail</returns>
 public void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
 {
     if (ADCodeAperture == null)
     {
         return;
     }
     try
     {
         // macros need to reset
         ADCodeAperture.ResetForFlash();
         // flash it
         ADCodeAperture.FlashApertureForGCodePlot(isoPlotBuilder, stateMachine, x1, y1, xyComp);
     }
     catch (Exception ex)
     {
         // rethrow with line number
         throw new Exception("Line Number:" + LineNumber.ToString() + ", " + ex.Message);
     }
 }
Пример #10
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     // This is just a linear interpolation
     stateMachine.GerberFileInterpolationMode = GerberInterpolationModeEnum.INTERPOLATIONMODE_LINEAR;
     return(GerberLine.PlotActionEnum.PlotAction_Continue);
 }
Пример #11
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// If we draw a line with an aperture it will not always have linear ends
 /// for example if the aperture is a circle it will have half circle ends. Each
 /// line that is drawn calls this to make it look right visually
 /// </summary>
 /// <param name="graphicsObj">a graphics object to draw on</param>
 /// <param name="workingBrush">a brush to draw with</param>
 /// <param name="workingPen">the pen used for the line, we get the width from this</param>
 /// <param name="x1">the first x value</param>
 /// <param name="y1">the first y value</param>
 /// <param name="x2">the second x value</param>
 /// <param name="y2">the second y value</param>
 /// <param name="xyComp">the xy compensation factor</param>
 /// <returns>z success, nz fail</returns>
 public override void FixupLineEndpointsForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int x2, int y2, int radius, int xyComp)
 {
     throw new Exception("Not available in this aperture type");
 }
Пример #12
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Perform a circular aperture flash. This is a static call so other things can call it
        /// if they need to do so.
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <returns>z success, nz fail</returns>
        public static void PerformCircularApertureFlashWithHole(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp, int workingOuterDiameter, float holeDia)
        {
            int hDia;
            int holeRadius       = 0;
            int builderID        = 0;
            int holeBuilderObjID = 0;

            if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
            {
                // draw the circle
                builderID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1, y1, ((workingOuterDiameter + xyComp) / 2), GSFillModeEnum.FillMode_BACKGROUND, stateMachine.WantClockWise);
                // do we need to do a hole?
                if (holeDia > 0)
                {
                    // yes we do
                    hDia       = (int)Math.Round((holeDia * stateMachine.IsoPlotPointsPerAppUnit));
                    holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_BACKGROUND, stateMachine.WantClockWise);

                        // There is more going on here than is immediately obvious
                        // we want the inside of the hole to not be filled with isocells from the holeBuilderObjID
                        // we could just have not filled it and only placed edge isocells
                        // but this causes complications on the erase. It is better to fill it then remove the outer
                        // object then remove the background only pixels of the holeBuilderObjID. This makes sure we
                        // get all of the outer objects isocells rather than relying on hitting the edge to
                        // figure out where to start.

                        // remove everything belonging to the outer circle from the circle we just drew, this
                        // leaves anything else which might be in there in there
                        isoPlotBuilder.EraseABuilderIDFromRegionUsingABuilderID(holeBuilderObjID, builderID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);

                        // remove all background only pixels belonging to the hole circle leaving just the edge pixels
                        isoPlotBuilder.EraseBackgroundOnlyIsoCellsByBuilderID(holeBuilderObjID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);
                    }
                }
            }
            else if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_ERASE)
            {
                // we have to decide whether we are drawing a hole or not. In Clear Polarity holes do not come in as solid DARK spot like you
                // think they would. Instead they just "do nothing" on the area the contents below them remain there and there is no fill or erase

                if (holeDia > 0)
                {
                    // we are dealing with a erase flash with a hole

                    // draw the circle, we use invert edges here so we draw the circle only if it is on some other background, use no fill. We will erase between it and the hole later
                    int outerRadius = (workingOuterDiameter + xyComp) / 2;
                    builderID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1, outerRadius, GSFillModeEnum.FillMode_NONE, stateMachine.WantClockWise);

                    // now do the hole we use invert edges so anything we draw over a background will get drawn, there is no fill
                    hDia       = (int)Math.Round((holeDia * stateMachine.IsoPlotPointsPerAppUnit));
                    holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole using no fill. Whatever is in there is in there
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_NONE, stateMachine.WantClockWise);
                    }

                    // now erase between the outer and inner circles
                    // we are dealing with a simple erase flash, no hole
                    List <int> builderIDList = new List <int>();
                    builderIDList.Add(builderID);
                    builderIDList.Add(holeBuilderObjID);
                    isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, IsoPlotObject.DEFAULT_ISOPLOTOBJECT_ID, x1 - outerRadius - 1, y1 - outerRadius - 1, x1 + outerRadius + 1, y1 + outerRadius + 1, -1);
                }
                else
                {
                    // draw the circle, we use invert edges here so we draw only if it is on some other background, we still erase everything under it though
                    int outerRadius = (workingOuterDiameter + xyComp) / 2;
                    builderID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1, outerRadius, GSFillModeEnum.FillMode_ERASE, stateMachine.WantClockWise);
                }
            }

            return;
        }
Пример #13
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flashes the rectangular aperture at a point
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <returns>z success, nz fail</returns>
        public override void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            int holeBuilderObjID = 0;
            int hDia;

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            int xComp = (int)Math.Round(((XAxisDimension * stateMachine.IsoPlotPointsPerAppUnit)));
            int yComp = (int)Math.Round(((YAxisDimension * stateMachine.IsoPlotPointsPerAppUnit) / 2));

            if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
            {
                // corrected, courtesy of MaikF
                int builderID = isoPlotBuilder.DrawGSLineOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1, y1 - yComp - xyComp / 2, x1, y1 + yComp + xyComp / 2, xComp + (1 * xyComp), stateMachine.BackgroundFillModeAccordingToPolarity);
                // do we need to do a hole?
                if (HoleDiameter > 0)
                {
                    // yes we do
                    hDia = (int)Math.Round((HoleDiameter * stateMachine.IsoPlotPointsPerAppUnit));
                    int holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_BACKGROUND, stateMachine.WantClockWise);

                        // There is more going on here than is immediately obvious
                        // we want the inside of the hole to not be filled with isocells from the holeBuilderObjID
                        // we could just have not filled it and only placed edge isocells
                        // but this causes complications on the erase. It is better to fill it then remove the outer
                        // object then remove the background only pixels of the holeBuilderObjID. This makes sure we
                        // get all of the outer objects isocells rather than relying on hitting the edge to
                        // figure out where to start.

                        // remove everything belonging to the outer circle from the circle we just drew, this
                        // leaves anything else which might be in there in there
                        isoPlotBuilder.EraseABuilderIDFromRegionUsingABuilderID(holeBuilderObjID, builderID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);

                        // remove all background only pixels belonging to the hole circle leaving just the edge pixels
                        isoPlotBuilder.EraseBackgroundOnlyIsoCellsByBuilderID(holeBuilderObjID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);
                    }
                }
            } // bottom of if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
            else if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_ERASE)
            {
                // we have to decide whether we are drawing a hole or not. In Clear Polarity holes do not come in as solid DARK spot like you
                // think they would. Instead they just "do nothing" on the area the contents below them remain there and there is no fill or erase

                if (HoleDiameter > 0)
                {
                    // we are dealing with a erase flash with a transparent hole

                    // draw the rectangle, we use invert edges here so we draw the circle only if it is on some other background, use no fill. We will erase between it and the hole later
                    int builderID = isoPlotBuilder.DrawGSLineOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1 - yComp - xyComp / 2, x1, y1 + yComp + xyComp / 2, xComp + (1 * xyComp), GSFillModeEnum.FillMode_NONE);

                    // now do the hole we use invert edges so anything we draw over a background will get drawn, there is no fill
                    hDia = (int)Math.Round((HoleDiameter * stateMachine.IsoPlotPointsPerAppUnit));
                    int holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole using no fill. Whatever is in there is in there
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_NONE, stateMachine.WantClockWise);
                    }
                    // now erase between the outer and inner circles
                    // we are dealing with a simple erase flash, no hole
                    List <int> builderIDList = new List <int>();
                    builderIDList.Add(builderID);
                    builderIDList.Add(holeBuilderObjID);
                    MiscGraphicsUtils.GetWideLineEndPoints(x1, y1 - yComp - xyComp / 2, x1, y1 + yComp + xyComp / 2, xComp + (1 * xyComp), out Point ptLL, out Point ptUL, out Point ptUR, out Point ptLR);
                    // now erase the background
                    isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, IsoPlotObject.DEFAULT_ISOPLOTOBJECT_ID, ptLL.X, ptLL.Y, ptUR.X, ptUR.Y, -1);
                }
                else
                {
                    // draw the rectangle, we use invert edges here so we draw only if it is on some other background, we still erase everything under it though
                    int builderID = isoPlotBuilder.DrawGSLineOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1 - yComp - xyComp / 2, x1, y1 + yComp + xyComp / 2, xComp + (1 * xyComp), GSFillModeEnum.FillMode_ERASE);
                }
            }
        }
Пример #14
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     // enable contour drawing mode
     stateMachine.ContourDrawingModeEnabled = true;
     return(GerberLine.PlotActionEnum.PlotAction_Continue);
 }
Пример #15
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// If we draw a line with an aperture it will not always have linear ends
 /// for example if the aperture is a circle it will have half circle ends. Each
 /// line that is drawn calls this to make it look right visually
 /// </summary>
 /// <param name="isoPlotBuilder">the builder opbject</param>
 /// <param name="stateMachine">the statemachine</param>
 /// <param name="xyComp">the xy compensation factor</param>
 /// <param name="x1">the first x value</param>
 /// <param name="y1">the first y value</param>
 /// <returns>z success, nz fail</returns>
 public abstract void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp);
Пример #16
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Flash a macro primitive for a Circle on a GCode Plot
 /// </summary>
 /// <param name="isoPlotBuilder">the builder opbject</param>
 /// <param name="stateMachine">the statemachine</param>
 /// <param name="xyComp">the xy compensation factor</param>
 /// <param name="macroBuilderIDs">a list of builder IDs which have drawn in POSITIVE on this macro</param>
 /// <param name="x1">the first x value</param>
 /// <param name="y1">the first y value</param>
 /// <param name="varArray">the array to get the numbered variables from</param>
 /// <returns>z success, nz fail</returns>
 public abstract int FlashMacroPrimitiveForGCodePlot(GerberMacroVariableArray varArray, List <int> macroBuilderIDs, IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp);
Пример #17
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash a macro primitive for a CLine on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="macroBuilderIDs">a list of builder IDs which have drawn in POSITIVE on this macro</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="varArray">the array to get the numbered variables from</param>
        /// <returns>z success, nz fail</returns>
        public override int FlashMacroPrimitiveForGCodePlot(GerberMacroVariableArray varArray, List <int> macroBuilderIDs, IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            // now do the flash
            int builderID = 0;

            if (isoPlotBuilder == null)
            {
                return(-1);
            }
            if (stateMachine == null)
            {
                return(-1);
            }
            if (macroBuilderIDs == null)
            {
                return(-1);
            }

            // figure out width and height
            float workingWidth             = GetWidth(varArray);
            int   lineWidthInScreenCoords  = (int)Math.Round(workingWidth * stateMachine.IsoPlotPointsPerAppUnit);
            float workingHeight            = GetLineLength(varArray);
            int   lineHeightInScreenCoords = (int)Math.Round(workingHeight * stateMachine.IsoPlotPointsPerAppUnit);

            //DebugMessage("efc_X=" + effectiveCenter_X.ToString() + ", " + "efc_Y=" + effectiveCenter_Y.ToString());

            // figure out the xyComp in plot coords, it comes in as screen coords here
            // we need it to feed into the rotation calculations
            float xyCompInPlotCoords = ((float)xyComp) / stateMachine.IsoPlotPointsPerAppUnit;

            xyCompInPlotCoords /= 2;

            // draw the line outline, is the polarity on?
            if (GetApertureIsOn(varArray) == false)
            {
                // we will need the center point coords
                PointF centerPoint = GetCenterPoint(varArray);
                int    primCenterPointInScreenCoords_X = (int)(centerPoint.X * stateMachine.IsoPlotPointsPerAppUnit);
                int    primCenterPointInScreenCoords_Y = (int)(centerPoint.Y * stateMachine.IsoPlotPointsPerAppUnit);

                int effectiveCenter_X = x1 + primCenterPointInScreenCoords_X;
                int effectiveCenter_Y = y1 + primCenterPointInScreenCoords_Y;

                // get the center points
                PointF centerPointLeft  = this.GetLeftCenterCoord(varArray, xyCompInPlotCoords, true);
                PointF centerPointRight = this.GetRightCenterCoord(varArray, xyCompInPlotCoords, true);
                // convert them to screen coords
                int leftCenterPointInScreenCoords_X  = (int)(centerPointLeft.X * stateMachine.IsoPlotPointsPerAppUnit);
                int leftCenterPointInScreenCoords_Y  = (int)(centerPointLeft.Y * stateMachine.IsoPlotPointsPerAppUnit);
                int rightCenterPointInScreenCoords_X = (int)(centerPointRight.X * stateMachine.IsoPlotPointsPerAppUnit);
                int rightCenterPointInScreenCoords_Y = (int)(centerPointRight.Y * stateMachine.IsoPlotPointsPerAppUnit);
                // now calc the effective draw points
                int effectiveLeftCenterPoint_X  = x1 + leftCenterPointInScreenCoords_X;
                int effectiveLeftCenterPoint_Y  = y1 + leftCenterPointInScreenCoords_Y;
                int effectiveRightCenterPoint_X = x1 + rightCenterPointInScreenCoords_X;
                int effectiveRightCenterPoint_Y = y1 + rightCenterPointInScreenCoords_Y;

                // adjust the line height for the XY comp, the width was compensated earlier
                int lineHeightInScreenCoordsXYCompensated = lineHeightInScreenCoords - (xyComp);

                // clear polarity
                builderID = isoPlotBuilder.DrawGSLineOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, effectiveLeftCenterPoint_X, effectiveLeftCenterPoint_Y, effectiveRightCenterPoint_X, effectiveRightCenterPoint_Y, lineHeightInScreenCoordsXYCompensated, stateMachine.BackgroundFillModeAccordingToPolarity);

                // get the bounding box of this primitive
                RectangleF primBoundingBox = GetMacroPrimitiveBoundingBox(varArray);
                // convert to screen values, this is still the primitive bounding rect though
                RectangleF primBoundingBoxInScreenCoords = MiscGraphicsUtils.ConvertRectFToScreenCoordinates(primBoundingBox, stateMachine);
                // the bounding box is relative to the center coords we adjust to absolute
                int newX0 = (int)(effectiveCenter_X - (primBoundingBoxInScreenCoords.Width / 2));
                int newY0 = (int)(effectiveCenter_Y - (primBoundingBoxInScreenCoords.Height / 2));
                int newX1 = (int)(newX0 + primBoundingBoxInScreenCoords.Width);
                int newY1 = (int)(newY0 + primBoundingBoxInScreenCoords.Height);

                // now remove everything belonging to the macro at this point which is under our transparent flash
                isoPlotBuilder.EraseBuilderIDListFromRegionUsingABuilderIDHoriz(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1, -1);

                // now remove the transparent flash INVERT_EDGE if it is not on something belonging to the macro. This prevents us
                // cutting through non macro material.
                isoPlotBuilder.EraseBuilderIDIfNotOnCellWithIDsInList(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1);

                // we do NOT return the builder ID here only the ones which draw in positive get returned
                return(0);
            }
            else
            {
                // get the center points
                PointF centerPointLeft  = this.GetLeftCenterCoord(varArray, xyCompInPlotCoords, false);
                PointF centerPointRight = this.GetRightCenterCoord(varArray, xyCompInPlotCoords, false);
                // convert them to screen coords
                int leftCenterPointInScreenCoords_X  = (int)(centerPointLeft.X * stateMachine.IsoPlotPointsPerAppUnit);
                int leftCenterPointInScreenCoords_Y  = (int)(centerPointLeft.Y * stateMachine.IsoPlotPointsPerAppUnit);
                int rightCenterPointInScreenCoords_X = (int)(centerPointRight.X * stateMachine.IsoPlotPointsPerAppUnit);
                int rightCenterPointInScreenCoords_Y = (int)(centerPointRight.Y * stateMachine.IsoPlotPointsPerAppUnit);
                // now calc the effective draw points
                int effectiveLeftCenterPoint_X  = x1 + leftCenterPointInScreenCoords_X;
                int effectiveLeftCenterPoint_Y  = y1 + leftCenterPointInScreenCoords_Y;
                int effectiveRightCenterPoint_X = x1 + rightCenterPointInScreenCoords_X;
                int effectiveRightCenterPoint_Y = y1 + rightCenterPointInScreenCoords_Y;

                // adjust the line height for the XY comp, the width was compensated earlier
                int lineHeightInScreenCoordsXYCompensated = lineHeightInScreenCoords + (xyComp);

                // dark polarity
                builderID = isoPlotBuilder.DrawGSLineOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, effectiveLeftCenterPoint_X, effectiveLeftCenterPoint_Y, effectiveRightCenterPoint_X, effectiveRightCenterPoint_Y, lineHeightInScreenCoordsXYCompensated, stateMachine.BackgroundFillModeAccordingToPolarity);
                return(builderID);
            }
        }
Пример #18
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash a macro primitive for a Circle on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="macroBuilderIDs">a list of builder IDs which have drawn in POSITIVE on this macro</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="varArray">the array to get the numbered variables from</param>
        /// <returns>z success, nz fail</returns>
        public override int FlashMacroPrimitiveForGCodePlot(GerberMacroVariableArray varArray, List <int> macroBuilderIDs, IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            // now do the flash
            int builderID = 0;

            if (isoPlotBuilder == null)
            {
                return(-1);
            }
            if (stateMachine == null)
            {
                return(-1);
            }
            if (macroBuilderIDs == null)
            {
                return(-1);
            }

            // get the VertexPointArray converted and rotated
            PointF[] tmpPointArray = GetPointArrayAsPointFArray(varArray);
            // collect the vertexPoints we operate on here
            PointF[] vertexPoints = new PointF[vertexPointArray.Length];

            // loop through the tmpPointArray
            for (int i = 0; i < tmpPointArray.Length; i++)
            {
                //DebugMessage("rawPoint=" + tmpPointArray[i].ToString());

                // we will need them as screen coords
                float primPointInScreenCoords_X = tmpPointArray[i].X * stateMachine.IsoPlotPointsPerAppUnit;
                float primPointInScreenCoords_Y = tmpPointArray[i].Y * stateMachine.IsoPlotPointsPerAppUnit;

                // we can calc the effective draw point of the current primitive, we do it out here to make this obvious
                float effectiveDrawPoint_X = x1 + primPointInScreenCoords_X;
                float effectiveDrawPoint_Y = y1 + primPointInScreenCoords_Y;

                // create a new point and stuff it in the array
                vertexPoints[i] = new PointF(effectiveDrawPoint_X, effectiveDrawPoint_Y);
                //DebugMessage("  vertexPoint=" + vertexPoints[i].ToString());
            }

            if (GetApertureIsOn(varArray) == true)
            {
                // draw the circle

                builderID = isoPlotBuilder.DrawGSOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, vertexPoints, stateMachine.BackgroundFillModeAccordingToPolarity);
                // return this, the caller keeps track of these
                return(builderID);
            }
            else
            {
                // draw the circle, we use invert edges here so we draw the circle only if it is on some other background, use no fill. We will erase between it and the hole later
                builderID = isoPlotBuilder.DrawGSOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, vertexPoints, GSFillModeEnum.FillMode_NONE);

                // now we have to remove every builderID in the macro in every isoCell under the above object. This is not fast.
                // We know which ones might be there because we have a list

                // we will need the center point coords
                int primCenterPointInScreenCoords_X = (int)(GetXCenterCoord(varArray) * stateMachine.IsoPlotPointsPerAppUnit);
                int primCenterPointInScreenCoords_Y = (int)(GetYCenterCoord(varArray) * stateMachine.IsoPlotPointsPerAppUnit);

                int effectiveCenter_X = x1 + primCenterPointInScreenCoords_X;
                int effectiveCenter_Y = y1 + primCenterPointInScreenCoords_Y;

                // get the bounding box of this primitive
                RectangleF primBoundingBox = GetMacroPrimitiveBoundingBox(varArray);
                // convert to screen values, this is still the primitive bounding rect though
                RectangleF primBoundingBoxInScreenCoords = MiscGraphicsUtils.ConvertRectFToScreenCoordinates(primBoundingBox, stateMachine);
                // the bounding box is relative to the center coords we adjust to absolute
                int newX0 = (int)(effectiveCenter_X - (primBoundingBoxInScreenCoords.Width / 2));
                int newY0 = (int)(effectiveCenter_Y - (primBoundingBoxInScreenCoords.Height / 2));
                int newX1 = (int)(newX0 + primBoundingBoxInScreenCoords.Width);
                int newY1 = (int)(newY0 + primBoundingBoxInScreenCoords.Height);

                // now remove everything belonging to the macro at this point which is under our transparent flash
                isoPlotBuilder.EraseBuilderIDListFromRegionUsingABuilderIDHoriz(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1, -1);

                // now remove the transparent flash INVERT_EDGE if it is not on something belonging to the macro. This prevents us
                // cutting through non macro material.
                isoPlotBuilder.EraseBuilderIDIfNotOnCellWithIDsInList(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1);

                // we do NOT return the builder ID here only the ones which draw in positive get returned
                return(0);
            }
        }
Пример #19
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash an aperture for a OBRound on a GCode Plot
        ///
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <returns>z success, nz fail</returns>
        public override void FlashApertureForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            int   holeBuilderObjID = 0;
            int   hDia;
            bool  ellipseIsVertical    = false;
            int   workingOuterDiameter = int.MinValue;
            float majorEllipseAxis     = float.NegativeInfinity;
            float minorEllipseAxis     = float.NegativeInfinity;
            float majorEllipseAxisAdjustedForCircle = float.NegativeInfinity;
            int   x1EllipseCompensatedCenterpoint;
            int   y1EllipseCompensatedCenterpoint;
            int   x2EllipseCompensatedCenterpoint;
            int   y2EllipseCompensatedCenterpoint;
            float circle1StartDegrees = 90;
            float circle2StartDegrees = 270;
            float circle1SweepDegrees = 180;
            float circle2SweepDegrees = 180;
            int   majorEllipseAxisEndpointCompensation = 0;

            int outerBoundingBoxLL_X = 0;
            int outerBoundingBoxLL_Y = 0;
            int outerBoundingBoxUR_X = 0;
            int outerBoundingBoxUR_Y = 0;

            if (isoPlotBuilder == null)
            {
                return;
            }
            if (stateMachine == null)
            {
                return;
            }

            // NOTE: it is not possible to encode an Oval or Ellipse in GCode, you have to
            //       represent this with a line segment which has two circles at the end
            //       the total length should be equal the longest dimension. The shortest
            //       dimension will be used as the diameter of the circles.

            // NOTE: we need not deal with ellipses in here which do not have major and minor
            //       axis parallel to the X and Y axis. There is no way to represent this in
            //       Gerber code and they are usually encoded as an AM macro which is a
            //       combination of two circles and a line - just as we are doing (see above)
            //       and for exactly the same reasons.

            // find the shortest and longest dimensions. NOTE according to the spec OBRounds
            // cannot have a rotation. They are either Horizontal or Vertical
            if (xAxisDimension > yAxisDimension)
            {
                majorEllipseAxis  = xAxisDimension;
                minorEllipseAxis  = yAxisDimension;
                ellipseIsVertical = false;
            }
            else
            {
                majorEllipseAxis  = yAxisDimension;
                minorEllipseAxis  = xAxisDimension;
                ellipseIsVertical = true;
            }
            // now figure out the length of the line between the circles
            majorEllipseAxisAdjustedForCircle = majorEllipseAxis - minorEllipseAxis;
            // sanity checks
            if (majorEllipseAxisAdjustedForCircle < 0)
            {
                // what the hell? we got problems
                throw new Exception("Cannot draw ellipse adjusted axis less than zero.");
            }
            else if (majorEllipseAxisAdjustedForCircle == 0)
            {
                // special case, we must be dealing with a circle, just draw one
                workingOuterDiameter = (int)Math.Round((majorEllipseAxis * stateMachine.IsoPlotPointsPerAppUnit));
                // now do the flash
                GerberAperture_CCode.PerformCircularApertureFlashWithHole(isoPlotBuilder, stateMachine, x1, y1, xyComp, workingOuterDiameter, HoleDiameter);
                return;
            }

            // we are not dealing with a circle. We are dealing with an OBRound

            // now figure out the diameter of the endpoint circles
            workingOuterDiameter = (int)Math.Round((minorEllipseAxis * stateMachine.IsoPlotPointsPerAppUnit));
            // calc the amount we have to add/subtract on the center point to get to the
            // endpoints
            majorEllipseAxisEndpointCompensation  = (int)Math.Round(((majorEllipseAxisAdjustedForCircle * stateMachine.IsoPlotPointsPerAppUnit) / 2));
            majorEllipseAxisEndpointCompensation += (xyComp / 2);

            // compensate the endpoints, the way we do this is dependent on whether
            // the ellipse is horizontal or vertical. NOTE according to the spec OBRounds
            // cannot have a rotation. They are either Horizontal or Vertical
            if (ellipseIsVertical == false)
            {
                x1EllipseCompensatedCenterpoint = x1 - majorEllipseAxisEndpointCompensation;
                x2EllipseCompensatedCenterpoint = x1 + majorEllipseAxisEndpointCompensation;
                y1EllipseCompensatedCenterpoint = y1;
                y2EllipseCompensatedCenterpoint = y1;
                circle1StartDegrees             = 90;
                circle1SweepDegrees             = 180;
                circle2StartDegrees             = 270;
                circle2SweepDegrees             = 180;
            }
            else
            {
                x1EllipseCompensatedCenterpoint = x1;
                x2EllipseCompensatedCenterpoint = x1;
                y1EllipseCompensatedCenterpoint = y1 - majorEllipseAxisEndpointCompensation;
                y2EllipseCompensatedCenterpoint = y1 + majorEllipseAxisEndpointCompensation;
                circle1StartDegrees             = 180;
                circle1SweepDegrees             = 180;
                circle2StartDegrees             = 0;
                circle2SweepDegrees             = 180;
            }

            // calculate the endpoints of the wide line rectangle.
            MiscGraphicsUtils.GetWideLineEndPoints(x1EllipseCompensatedCenterpoint, y1EllipseCompensatedCenterpoint, x2EllipseCompensatedCenterpoint, y2EllipseCompensatedCenterpoint, (workingOuterDiameter + xyComp), out Point ptLL, out Point ptUL, out Point ptUR, out Point ptLR);
            // now set the dimensions of the bounding box
            if (ellipseIsVertical == false)
            {
                outerBoundingBoxLL_X = ptLL.X - x1EllipseCompensatedCenterpoint;
                outerBoundingBoxLL_Y = ptLL.Y;
                outerBoundingBoxUR_X = ptUR.X + x2EllipseCompensatedCenterpoint;
                outerBoundingBoxUR_Y = ptUR.Y;
            }
            else
            {
                outerBoundingBoxLL_X = ptLL.X;
                outerBoundingBoxLL_Y = ptLL.Y - y1EllipseCompensatedCenterpoint;
                outerBoundingBoxUR_X = ptUR.X;
                outerBoundingBoxUR_Y = ptUR.Y + y2EllipseCompensatedCenterpoint;
            }

            // now we draw according to the polarity

            if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
            {
                // draw the first arc
                int circle1BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1EllipseCompensatedCenterpoint, y1EllipseCompensatedCenterpoint, circle1StartDegrees, circle1SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                // draw the second arc
                int circle2BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x2EllipseCompensatedCenterpoint, y2EllipseCompensatedCenterpoint, circle2StartDegrees, circle2SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                // draw in the top line
                int line1BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, ptUL.X, ptUL.Y, ptUR.X, ptUR.Y);
                // draw in the bottom line
                int line2BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, ptLL.X, ptLL.Y, ptLR.X, ptLR.Y);

                // create a list of the builder IDs used
                List <int> builderIDList = new List <int>();
                builderIDList.Add(circle1BuilderID);
                builderIDList.Add(circle2BuilderID);
                builderIDList.Add(line1BuilderID);
                builderIDList.Add(line2BuilderID);

                // now background fill the complex object, note how we only fill with the circle1BuilderID, This will be important when filling in the hole
                isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, circle1BuilderID, outerBoundingBoxLL_X, outerBoundingBoxLL_Y, outerBoundingBoxUR_X, outerBoundingBoxUR_Y, -1);

                // do we need to do a hole?
                if (HoleDiameter > 0)
                {
                    // yes we do
                    hDia = (int)Math.Round((HoleDiameter * stateMachine.IsoPlotPointsPerAppUnit));
                    int holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_BACKGROUND, stateMachine.WantClockWise);

                        // There is more going on here than is immediately obvious
                        // we want the inside of the hole to not be filled with isocells from the holeBuilderObjID
                        // we could just have not filled it and only placed edge isocells
                        // but this causes complications on the erase. It is better to fill it then remove the outer
                        // object then remove the background only pixels of the holeBuilderObjID. This makes sure we
                        // get all of the outer objects isocells rather than relying on hitting the edge to
                        // figure out where to start.

                        // remove everything belonging to the obRoundObj we just drew, note we only filled with circle1BuilderID above so that is all we need to remove
                        isoPlotBuilder.EraseABuilderIDFromRegionUsingABuilderID(holeBuilderObjID, circle1BuilderID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);

                        // remove all background only pixels belonging to the hole circle leaving just the edge pixels
                        isoPlotBuilder.EraseBackgroundOnlyIsoCellsByBuilderID(holeBuilderObjID, x1 - holeRadius - 1, y1 - holeRadius - 1, x1 + holeRadius + 1, y1 + holeRadius + 1);
                    }
                }
            } // bottom of if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_BACKGROUND)
            else if (stateMachine.BackgroundFillModeAccordingToPolarity == GSFillModeEnum.FillMode_ERASE)
            {
                // we have to decide whether we are drawing a hole or not. In Clear Polarity holes do not come in as solid DARK spot like you
                // think they would. Instead they just "do nothing" on the area the contents below them remain there and there is no fill or erase

                if (HoleDiameter > 0)
                {
                    // we are dealing with a erase flash with a transparent hole

                    // draw the first arc
                    int circle1BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1EllipseCompensatedCenterpoint, y1EllipseCompensatedCenterpoint, circle1StartDegrees, circle1SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                    // draw the second arc
                    int circle2BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x2EllipseCompensatedCenterpoint, y2EllipseCompensatedCenterpoint, circle2StartDegrees, circle2SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                    // draw in the top line
                    int line1BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, ptUL.X, ptUL.Y, ptUR.X, ptUR.Y);
                    // draw in the bottom line
                    int line2BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, ptLL.X, ptLL.Y, ptLR.X, ptLR.Y);

                    // create a list of the builder IDs used
                    List <int> builderIDList = new List <int>();
                    builderIDList.Add(circle1BuilderID);
                    builderIDList.Add(circle2BuilderID);
                    builderIDList.Add(line1BuilderID);
                    builderIDList.Add(line2BuilderID);

                    // note that at this point we effectively have an invert edge OBRound with FillMode_NONE

                    // now do the hole we use invert edges so anything we draw over a background will get drawn, there is no fill
                    hDia = (int)Math.Round((HoleDiameter * stateMachine.IsoPlotPointsPerAppUnit));
                    int holeRadius = (hDia - xyComp) / 2;
                    if (holeRadius > 0)
                    {
                        // draw the circle for the hole using no fill. Whatever is in there is in there
                        holeBuilderObjID = isoPlotBuilder.DrawGSCircle(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1, y1, holeRadius, GSFillModeEnum.FillMode_NONE, stateMachine.WantClockWise);
                    }
                    builderIDList.Add(holeBuilderObjID);

                    // now erase between the outer and inner circles
                    isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, IsoPlotObject.DEFAULT_ISOPLOTOBJECT_ID, outerBoundingBoxLL_X, outerBoundingBoxLL_Y, outerBoundingBoxUR_X, outerBoundingBoxUR_Y, -1);
                }
                else
                {
                    // draw the obRound, we use invert edges here so we draw only if it is on some other background, we still erase everything under it though
                    // draw the first arc
                    int circle1BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x1EllipseCompensatedCenterpoint, y1EllipseCompensatedCenterpoint, circle1StartDegrees, circle1SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                    // draw the second arc
                    int circle2BuilderID = isoPlotBuilder.DrawGSContourArc(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, x2EllipseCompensatedCenterpoint, y2EllipseCompensatedCenterpoint, circle2StartDegrees, circle2SweepDegrees, ((workingOuterDiameter + xyComp) / 2), false, true, false);
                    // draw in the top line
                    int line1BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, ptUL.X, ptUL.Y, ptUR.X, ptUR.Y);
                    // draw in the bottom line
                    int line2BuilderID = isoPlotBuilder.DrawGSLineContourLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, ptLL.X, ptLL.Y, ptLR.X, ptLR.Y);

                    // create a list of the builder IDs used
                    List <int> builderIDList = new List <int>();
                    builderIDList.Add(circle1BuilderID);
                    builderIDList.Add(circle2BuilderID);
                    builderIDList.Add(line1BuilderID);
                    builderIDList.Add(line2BuilderID);

                    // now erase the background
                    isoPlotBuilder.BackgroundFillGSByBoundaryComplexVert(builderIDList, IsoPlotObject.DEFAULT_ISOPLOTOBJECT_ID, outerBoundingBoxLL_X, outerBoundingBoxLL_Y, outerBoundingBoxUR_X, outerBoundingBoxUR_Y, -1);
                }
            }


            /*
             *                  DebugMessage("");
             *                  DebugMessage("majorEllipseAxis=" + (majorEllipseAxis * stateMachine.IsoPlotPointsPerAppUnit));
             *                  DebugMessage("minorEllipseAxis =" + (minorEllipseAxis * stateMachine.IsoPlotPointsPerAppUnit).ToString());
             *                  DebugMessage("y1EllipseCompensatedCenterpoint =" + (y1EllipseCompensatedCenterpoint).ToString());
             *                  DebugMessage("y2EllipseCompensatedCenterpoint =" + (y2EllipseCompensatedCenterpoint).ToString());
             *                  DebugMessage("y2EllipseCompensatedCenterpoint-y1EllipseCompensatedCenterpoint =" + (y2EllipseCompensatedCenterpoint - y1EllipseCompensatedCenterpoint).ToString());
             *                  DebugMessage("xyComp =" + xyComp.ToString());
             *                  DebugMessage("workingOuterDiameter =" + workingOuterDiameter.ToString());
             *                  DebugMessage("");
             */
            return;
        }
Пример #20
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash a macro primitive for a Circle on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="macroBuilderIDs">a list of builder IDs which have drawn in POSITIVE on this macro</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="varArray">the array to get the numbered variables from</param>
        /// <returns>z success, nz fail</returns>
        public override int FlashMacroPrimitiveForGCodePlot(GerberMacroVariableArray varArray, List <int> macroBuilderIDs, IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            // now do the flash
            int builderID            = 0;
            int workingOuterDiameter = int.MinValue;

            if (isoPlotBuilder == null)
            {
                return(-1);
            }
            if (stateMachine == null)
            {
                return(-1);
            }
            if (macroBuilderIDs == null)
            {
                return(-1);
            }

            // figure out the diameter
            float workingDiameter = GetDiameter(varArray);

            workingOuterDiameter = (int)Math.Round((workingDiameter * stateMachine.IsoPlotPointsPerAppUnit));
            int   workingNumSides = (int)GetNumSides(varArray);
            float rotationAngle   = GetDegreesRotation(varArray);

            // we will need the center point coords
            int primCenterPointInScreenCoords_X = (int)(GetXCenterCoord(varArray) * stateMachine.IsoPlotPointsPerAppUnit);
            int primCenterPointInScreenCoords_Y = (int)(GetYCenterCoord(varArray) * stateMachine.IsoPlotPointsPerAppUnit);

            int effectiveCenter_X = x1 + primCenterPointInScreenCoords_X;
            int effectiveCenter_Y = y1 + primCenterPointInScreenCoords_Y;

            //DebugMessage("efc_X=" + effectiveCenter_X.ToString() + ", " + "efc_Y=" + effectiveCenter_Y.ToString());

            if (GetApertureIsOn(varArray) == true)
            {
                // draw the circle
                int radius = (workingOuterDiameter + xyComp) / 2;
                builderID = isoPlotBuilder.DrawGSPolygonOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_NORMALEDGE, effectiveCenter_X, effectiveCenter_Y, workingNumSides, workingOuterDiameter + xyComp, rotationAngle, stateMachine.BackgroundFillModeAccordingToPolarity);
                // return this, the caller keeps track of these
                return(builderID);
            }
            else
            {
                // draw the circle, we use invert edges here so we draw the circle only if it is on some other background, use no fill. We will erase between it and the hole later
                int radius = (workingOuterDiameter - xyComp) / 2;
                if (radius <= 0)
                {
                    return(-1);
                }
                builderID = isoPlotBuilder.DrawGSPolygonOutLine(IsoPlotUsageTagFlagEnum.IsoPlotUsageTagFlag_INVERTEDGE, effectiveCenter_X, effectiveCenter_Y, workingNumSides, workingOuterDiameter - xyComp, rotationAngle, GSFillModeEnum.FillMode_NONE);

                // now we have to remove every builderID in the macro in every isoCell under the above object. This is not fast.
                // We know which ones might be there because we have a list

                int newX0 = effectiveCenter_X - radius;
                int newY0 = effectiveCenter_Y - radius;
                int newX1 = effectiveCenter_X + radius;
                int newY1 = effectiveCenter_Y + radius;

                // now remove everything belonging to the macro at this point which is under our transparent flash
                isoPlotBuilder.EraseBuilderIDListFromRegionUsingABuilderIDHoriz(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1, -1);

                // now remove the transparent flash INVERT_EDGE if it is not on something belonging to the macro. This prevents us
                // cutting through non macro material.
                isoPlotBuilder.EraseBuilderIDIfNotOnCellWithIDsInList(macroBuilderIDs, builderID, newX0, newY0, newX1, newY1);

                // we do NOT return the builder ID here only the ones which draw in positive get returned
                return(0);
            }
        }
Пример #21
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     // set the polarity to whatever we are
     stateMachine.GerberFileLayerPolarity = LayerPolarity;
     return(GerberLine.PlotActionEnum.PlotAction_Continue);
 }
Пример #22
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public virtual GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     errorValue  = 0;
     errorString = "";
     return(PlotActionEnum.PlotAction_Continue);
 }
Пример #23
0
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Flash a macro primitive for a Circle on a GCode Plot
        /// </summary>
        /// <param name="isoPlotBuilder">the builder opbject</param>
        /// <param name="stateMachine">the statemachine</param>
        /// <param name="macroBuilderIDs">a list of builder IDs which have drawn in POSITIVE on this macro</param>
        /// <param name="xyComp">the xy compensation factor</param>
        /// <param name="x1">the first x value</param>
        /// <param name="y1">the first y value</param>
        /// <param name="varArray">the array to get the numbered variables from</param>
        /// <returns>z success, nz fail</returns>
        public override int FlashMacroPrimitiveForGCodePlot(GerberMacroVariableArray varArray, List <int> macroBuilderIDs, IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int xyComp)
        {
            // note this type of (pseudo) primitive does not draw. It is essentially a variable assignment.
            float outVar = VariableOperation.ProcessVariableStringToFloat(varArray);

            // now we have it, set it
            varArray[this.VariableNumber] = new GerberMacroVariable(this.VariableNumber, outVar.ToString());

            return(0);
        }
Пример #24
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// Performs the plot Isolation Object actions required based on the current context
 /// </summary>
 /// <param name="isoPlotBuilder">A GCode Builder object</param>
 /// <param name="stateMachine">the gerber plot state machine</param>
 /// <param name="errorString">the error string we return on fail</param>
 /// <param name="errorValue">the error value we return on fail, z success, nz fail </param>
 /// <returns>an enum value indicating what next action to take</returns>
 public override GerberLine.PlotActionEnum PerformPlotIsoStep1Action(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, ref int errorValue, ref string errorString)
 {
     // This is just a circular interpolation
     stateMachine.GerberFileInterpolationCircularQuadrantMode = GerberInterpolationCircularQuadrantModeEnum.QUADRANTMODE_SINGLE;
     return(GerberLine.PlotActionEnum.PlotAction_Continue);
 }
Пример #25
0
 /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 /// <summary>
 /// If we draw a line with an aperture it will not always have linear ends
 /// for example if the aperture is a circle it will have half circle ends. Each
 /// line that is drawn calls this to make it look right visually
 /// </summary>
 /// <param name="graphicsObj">a graphics object to draw on</param>
 /// <param name="workingBrush">a brush to draw with</param>
 /// <param name="workingPen">the pen used for the line, we get the width from this</param>
 /// <param name="x1">the first x value</param>
 /// <param name="y1">the first y value</param>
 /// <param name="x2">the second x value</param>
 /// <param name="y2">the second y value</param>
 /// <param name="xyComp">the xy compensation factor</param>
 /// <returns>z success, nz fail</returns>
 public abstract void FixupLineEndpointsForGCodePlot(IsoPlotBuilder isoPlotBuilder, GerberFileStateMachine stateMachine, int x1, int y1, int x2, int y2, int radius, int xyComp);