private static bool?CheckPadsForFreeMask(IODBLayer SMLayer, IODBObject checkingPad)
        {
            if (checkingPad.Type == IObjectType.Pad)
            {
                bool foundFreeArea = false;
                //check is it free on mask layer?

                #region without cmps
                foreach (IODBObject maskObjects in SMLayer.GetAllObjectInRectangle(checkingPad.GetBoundsD()))
                {
                    if (maskObjects.Bounds.Contains(checkingPad.Bounds))                                                                             //bounds included in mask object?
                    {
                        if (!maskObjects.DoesIntersect(checkingPad) || maskObjects.GetPolygonOutline().isEqualsTol(checkingPad.GetPolygonOutline())) //no intersection?
                        {
                            if (maskObjects.Type == IObjectType.Surface)
                            {
                                //surface is special with holes and convex or concave elements -> one more test
                                if (maskObjects.IsPointOfSecondObjectIncluded(checkingPad))
                                {
                                    foundFreeArea = true;
                                    break;
                                }
                            }
                            else
                            {
                                //mask object should be free!
                                foundFreeArea = true;
                                break;
                            }
                        }
                    }
                }
                #endregion

                return(foundFreeArea);
            }
            return(null);
        }
        void MarkMaskOverPadsOnPaste(IODBLayer MaskLayer, IODBLayer PasteLayer, IStep step)
        {
            if (PasteLayer == null || MaskLayer == null)
            {
                return;
            }

            List <IObject> AllMaskPads = MaskLayer.GetAllLayerObjects();

            //look for all pads if there is a paaste element inside?
            foreach (IODBObject maybePad in AllMaskPads)
            {
                if (maybePad.Type != IObjectType.Pad)
                {
                    continue;
                }
                {
                    //check for paste elements
                    List <IObject> relevantPastePads = PasteLayer.GetAllObjectInRectangle(maybePad.Bounds);

                    foreach (IODBObject pasteObj in relevantPastePads)
                    {
                        bool doesIntersect = maybePad.DoesIntersect(pasteObj);
                        if (!doesIntersect && maybePad.IsPointOfSecondObjectIncluded(pasteObj))
                        {
                            continue;     //paste complete in mask
                        }
                        if (!doesIntersect && !pasteObj.IsPointOfSecondObjectIncluded(maybePad))
                        {
                            continue;
                        }

                        maybePad.ObjectColor = MarkerColor;
                        break;
                    }
                }
            }
        }
        private static bool CheckPadsForFreeMask(IODBLayer SMLayer, IODBLayer SignalLayer, ICMPLayer compLayer)
        {
            bool foundFreeArea = true;

            #region with cmp check
            foreach (ICMPObject comp in compLayer.GetAllLayerObjects())
            {
                foreach (IPin pin in comp.GetPinList()) //check each pin for free signal pad
                {
                    bool foundForThisPin = false;
                    #region one pin
                    foreach (IODBObject checkingPad in SignalLayer.GetAllObjectInRectangle(pin.GetBounds(comp)))
                    {
                        if (checkingPad.Type != IObjectType.Pad)
                        {
                            continue;
                        }

                        foreach (IODBObject maskObjects in SMLayer.GetAllObjectInRectangle(pin.GetBounds(comp)))
                        {
                            if (maskObjects.Bounds.Contains(checkingPad.Bounds))                                                                             //bounds included in mask object?
                            {
                                if (!maskObjects.DoesIntersect(checkingPad) || maskObjects.GetPolygonOutline().isEqualsTol(checkingPad.GetPolygonOutline())) //no intersection?
                                {
                                    if (maskObjects.Type == IObjectType.Surface)
                                    {
                                        //surface is special with holes and convex or concave elements -> one more test
                                        if (maskObjects.IsPointOfSecondObjectIncluded(checkingPad))
                                        {
                                            foundForThisPin = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        //mask object should be free!
                                        foundForThisPin = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (foundForThisPin)
                        {
                            break;
                        }
                    }
                    #endregion
                    if (!foundForThisPin) //add color to find issue on layer
                    {
                        foreach (IODBObject checkingPad in SignalLayer.GetAllObjectInRectangle(pin.GetBounds(comp)))
                        {
                            if (checkingPad.Type != IObjectType.Pad)
                            {
                                continue;
                            }
                            checkingPad.ObjectColorTemporary(Color.DarkBlue);
                        }
                    }

                    if (!foundForThisPin)
                    {
                        foundFreeArea = false;
                    }
                }
            }
            #endregion
            return(foundFreeArea);
        }
        public void Execute(IPCBIWindow parent)
        {
            //example to check first solder paste with first solder mask distances.
            double maxDist = 2; //mils

            wdlg = new PCB_Investigator.PCBIWindows.PCBIWorkingDialog();
            wdlg.SetAnimationStatus(false);
            wdlg.SetStatusPercent(0);
            wdlg.SetStatusText("Working");
            wdlg.CanCancel(true);


            IMatrix matrix = parent.GetMatrix();
            IStep   step   = parent.GetCurrentStep();

            wdlg.ShowWorkingDlgAsThread();

            List <string> layerNames = step.GetAllLayerNames();
            double        value      = 0;
            double        valueStep  = ((100.0 / layerNames.Count));

            Dictionary <IODBObject.DistanceResultClass, IODBObject> DistanceList = new Dictionary <IODBObject.DistanceResultClass, IODBObject>();
            IODBLayer SMTLayer = null;
            IODBLayer SPLayer  = null;

            foreach (string layername in step.GetAllLayerNames())
            {
                wdlg.SetStatusText("Working on " + layername + "...");
                value += valueStep;
                wdlg.SetStatusPercent((int)(value));

                if (matrix.GetMatrixLayerType(layername) == MatrixLayerType.Solder_paste && SPLayer == null) //find top solderpaste
                {
                    SPLayer = (IODBLayer)step.GetLayer(layername);
                }
                else if (matrix.GetMatrixLayerType(layername) == MatrixLayerType.Solder_mask && SMTLayer == null) //find top mask layer
                {
                    SMTLayer = (IODBLayer)step.GetLayer(layername);
                }

                if (SMTLayer != null && SPLayer != null)
                {
                    foreach (IODBObject IODBO1 in SPLayer.GetAllLayerObjects())
                    {
                        RectangleD boundsToInflate = IODBO1.GetBoundsD();
                        boundsToInflate.Inflate(maxDist, maxDist);
                        foreach (IODBObject IODBO2 in SMTLayer.GetAllObjectInRectangle(boundsToInflate))
                        {
                            IODBObject.DistanceResultClass distance = IODBO1.DistanceTo(IODBO2);
                            if (distance.Distance >= 0)
                            {
                                DistanceList.Add(distance, IODBO2);
                                IODBO2.ObjectColorTemporary(Color.DarkRed);
                            }
                        }
                    }
                    break;
                }
            }
            wdlg.Dispose();
            if (DistanceList.Count > 0) //write result to excel
            {
                StringBuilder sb = new StringBuilder();

                var     excelType = Type.GetTypeFromProgID("Excel.Application");
                dynamic excel     = Activator.CreateInstance(excelType);
                excel.Visible = true;
                excel.Workbooks.Add();

                foreach (IODBObject.DistanceResultClass distanceResult in DistanceList.Keys)
                {
                    sb.Append("\t" + DistanceList[distanceResult].PcbNetNumber + "\t" + distanceResult.From + "\t" + distanceResult.To + "\t" + distanceResult.Distance + Environment.NewLine);
                }

                string     LVText       = "Distances\tNet Number\tMask Layer\tSolder Paste\tValue" + Environment.NewLine + sb.ToString();
                string     LVCsv        = sb.ToString();
                DataObject LVDataObject = new DataObject();
                LVDataObject.SetData(DataFormats.Text, true, LVText);
                LVDataObject.SetData(DataFormats.CommaSeparatedValue, true, LVCsv);
                Clipboard.SetDataObject(LVDataObject, true);

                excel.ActiveSheet.Paste();

                //release the object
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
            }
            else
            {
                MessageBox.Show("No Results found...\n Please check Layers for Paste- or Mask layers!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        void CreateForOneSide(bool top, IStep step, IFilter filter, string PackageName, List <string> DrillLayers)
        {
            ICMPLayer compLayer = step.GetCMPLayer(top);

            if (compLayer == null)
            {
                return;
            }

            IODBLayer newLayer = filter.CreateEmptyODBLayer("testpoint_locations_" + (top ? "top" : "bot"), step.Name);

            if (newLayer == null)
            {
                return;
            }

            List <IODBLayer> allDrillLayers = new List <IODBLayer>();

            foreach (string drillName in DrillLayers)
            {
                allDrillLayers.Add((IODBLayer)step.GetLayer(drillName));
            }

            int shapeIndex           = IFilter.AddToolDefinitionRound(newLayer, 75);
            int shapeIndexConnection = IFilter.AddToolDefinitionRound(newLayer, 1);

            foreach (ICMPObject cmp in compLayer.GetAllLayerObjects())
            {
                if (!cmp.UsedPackageName.Contains(PackageName))
                {
                    continue;
                }

                IODBObject     markerPad = filter.CreatePad(newLayer);
                IPadSpecificsD pad       = (IPadSpecificsD)markerPad.GetSpecificsD();

                pad.Location   = new PCBI.MathUtils.PointD(cmp.Position);
                pad.ShapeIndex = shapeIndex;

                markerPad.SetSpecifics(pad);
                markerPad.ObjectColor = Color.Green;
                markerPad.SetAttribute("Steel needle <BST> (Testpoint)");
                bool special = false;
                foreach (IODBLayer drillLayer in allDrillLayers)
                {
                    #region check drills
                    foreach (IODBObject drill in drillLayer.GetAllObjectsOnPosition(cmp.Position))
                    {
                        Dictionary <PCBI.FeatureAttributeEnum, string> attribs = drill.GetAttributesDictionary();

                        if (attribs.ContainsKey(PCBI.FeatureAttributeEnum.drill))
                        {
                            if (attribs[PCBI.FeatureAttributeEnum.drill].ToUpperInvariant() == "VIA")
                            {
                                markerPad.ObjectColor = Color.Blue;
                                markerPad.SetAttribute("Pyramid <H> (Via)");
                                special = true;
                                break;
                            }
                        }
                    }
                    if (special)
                    {
                        break;
                    }
                    #endregion
                }
                if (!special)
                {
                    //check for component pin
                    foreach (ICMPObject comp in compLayer.GetAllObjectsOnPosition(cmp.Position))
                    {
                        if (comp == cmp)
                        {
                            continue;              //testpunkt selbst wird ignoriert
                        }
                        foreach (IPin pin in comp.GetPinList())
                        {
                            PCBI.MathUtils.IPolyClass cmpPoly = pin.GetPolygonOutline(comp);
                            if (cmpPoly.PointInPolygon(pad.Location))
                            {
                                markerPad.ObjectColor = Color.Red;
                                markerPad.SetAttribute("Serrated <C>"); //hier evtl noch überprüfen ob pin bzw. body drüber liegt?
                                special = true;                         //oder Serrated with overlapping plastic <CS>
                                break;
                            }
                        }
                        if (special)
                        {
                            break;
                        }
                    }
                }
            }
            foreach (ICMPObject cmp in compLayer.GetAllLayerObjects()) //neue schleife da erst alle pads plaziert werden sollen!
            {
                if (!cmp.UsedPackageName.Contains(PackageName))
                {
                    continue;
                }

                IODBObject      textForPad = filter.CreateText(newLayer);
                ITextSpecificsD text       = (ITextSpecificsD)textForPad.GetSpecificsD();

                text.Text        = cmp.Ref.Remove(0, 2); //Annahme das alle mit TP beginnen
                text.TextSize    = new SizeF(25, 50);
                text.Location    = new PCBI.MathUtils.PointD(cmp.Position.X + 50, cmp.Position.Y - 10);
                text.WidthFactor = 0.6;
                textForPad.SetSpecifics(text);
                textForPad.ObjectColor = Color.DarkGray;

                //text location should not be intersecting!
                List <IObject> otherObjectsOnSameLocation = newLayer.GetAllObjectInRectangle(textForPad.GetBoundsD());
                int            offset     = 50;
                bool           horChecked = false;
                while (otherObjectsOnSameLocation.Count > 1)
                {
                    //move text
                    if (horChecked)
                    {
                        text.Location = new PCBI.MathUtils.PointD(cmp.Position.X, cmp.Position.Y + offset);
                    }
                    else
                    {
                        text.Location = new PCBI.MathUtils.PointD(cmp.Position.X - offset - textForPad.GetBoundsD().Width, cmp.Position.Y - 10);
                    }
                    offset    += 50;
                    horChecked = true;
                    textForPad.SetSpecifics(text);
                    otherObjectsOnSameLocation = newLayer.GetAllObjectInRectangle(textForPad.GetBoundsD());
                }

                IODBObject      connectionLine = filter.CreateLine(newLayer);
                ILineSpecificsD line           = (ILineSpecificsD)connectionLine.GetSpecificsD();

                line.ShapeIndex = shapeIndexConnection;
                line.Start      = new PCBI.MathUtils.PointD(cmp.Position);
                line.End        = new PCBI.MathUtils.PointD(text.Location.X, text.Location.Y + 25);
                connectionLine.SetSpecifics(line);
                connectionLine.ObjectColor = Color.LightGray;
            }
        }