private void CopyAllViasToNewLayer(IPCBIWindow parent, string layerName, string newLayerName)
        {
            IStep curStep = parent.GetCurrentStep();

            if (curStep == null)
            {
                MessageBox.Show("No Job loaded, please load a job before start this script!", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                return;
            }
            ILayer relevantLayer = curStep.GetLayer(layerName);
            ILayer NewLayer      = curStep.GetLayer(newLayerName);

            if (NewLayer == null || relevantLayer == null || !(NewLayer is IODBLayer))
            {
                MessageBox.Show("Check Layers, something is wrong!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            List <IODBObject> ViaList = new List <IODBObject>();

            //check all elements for via attribute
            foreach (IObject obj in relevantLayer.GetAllLayerObjects())
            {
                if (obj is IODBObject)
                {
                    if (((IODBObject)obj).Type == IObjectType.Pad)
                    {
                        Dictionary <PCBI.FeatureAttributeEnum, string> attributesOfPad = ((IODBObject)obj).GetAttributesDictionary();

                        if (attributesOfPad.ContainsKey(PCBI.FeatureAttributeEnum.pad_usage))
                        {
                            if (attributesOfPad[PCBI.FeatureAttributeEnum.pad_usage] == "via")
                            {
                                ViaList.Add((IODBObject)obj);
                            }
                        }
                    }
                }
            }
            IFilter filter = new IFilter(parent); //to create copies on new layer

            //add vias to new layer
            foreach (IODBObject viaPad in ViaList)
            {
                IPadSpecificsD padInfo = (IPadSpecificsD)viaPad.GetSpecificsD();

                int toolNr = IFilter.AddToolDefinitionRound((IODBLayer)NewLayer, (float)padInfo.Diameter, -1);

                IODBObject newViaPad = filter.CreatePad((IODBLayer)NewLayer);

                newViaPad.SetSpecifics(padInfo, toolNr);
                newViaPad.SetAttribute("pad_usage=via");
            }
        }
        public void Execute(IPCBIWindow parent)
        {
            IFilter filter = new IFilter(parent);

            IStep curStep = parent.GetCurrentStep();

            if (curStep == null)
            {
                return;
            }

            List <IODBObject> selectedElements = curStep.GetSelectedElements();

            //create list with all selected elements to make a new symbol of it
            List <IObjectSpecificsD> newSymbolSpecs = new List <IObjectSpecificsD>();
            string relLayerName = "";

            PCBI.MathUtils.RectangleD bounds = new PCBI.MathUtils.RectangleD();
            int indexOfLastElement           = 1;

            foreach (IODBObject obj in selectedElements)
            {
                newSymbolSpecs.Add(obj.GetSpecificsD());
                relLayerName = obj.GetParentLayerName();
                if (bounds == RectangleD.Empty)
                {
                    bounds = obj.GetBoundsD();
                }
                else
                {
                    bounds = PCBI.MathUtils.RectangleD.Union(bounds, obj.GetBoundsD());
                }
                indexOfLastElement = obj.GetIndexOnLayer();
            }

            IODBLayer relLayer = (IODBLayer)curStep.GetLayer(relLayerName);

            if (relLayer == null)
            {
                return;
            }

            //create new symbol for pads, the name must be unique. We try it with the index of one of the elements.
            int nr = IFilter.AddToolDefinitionSpecial(relLayer, parent, "testsymbol3" + indexOfLastElement, newSymbolSpecs, -bounds.GetMidPoint().X, -bounds.GetMidPoint().Y);

            if (nr < 0)
            {
                //no new symbol was created, maybe name is already existing
                return;
            }

            //delete old elements
            IAutomation.SuppressUserNotifications = false; //otherwise the delete action will be blocked
            parent.UIAction.Execute(ID_ActionItem.ID_DELETE);

            IODBObject pad = filter.CreatePad(relLayer);

            IPadSpecificsD padSpec = (IPadSpecificsD)pad.GetSpecificsD();

            padSpec.Location = bounds.GetMidPoint();
            pad.SetSpecifics(padSpec, nr);
            pad.SetAttribute("new symbol attribute");

            pad.Select(true);

            parent.UpdateView();
        }
        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;
            }
        }
        internal static bool CutRectangle(IPolyClass rectanglePoly, IODBLayer layer, IODBLayer NewlayerToAddElements, IFilter filter, IPCBIWindow parentPCBI)
        {
            if (layer == null)
            {
                return(false);               //no layer
            }
            if (NewlayerToAddElements == null)
            {
                return(false);                               //no layer for new elements
            }
            //use bounds to get relevant objects
            //cut intersecting objects

            //helper for Symbols
            Dictionary <int, int> symbolUsed = new Dictionary <int, int>();
            //Performance
            RectangleD relevantRectangle = rectanglePoly.GetBounds();

            foreach (IODBObject obj in layer.GetAllLayerObjects())
            {
                if (relevantRectangle.IntersectsWith(obj.GetBoundsD()))
                {
                    #region cut elements
                    //cutting
                    IPolyClass polygon = obj.GetPolygonOutline();

                    IPolyClass cuttingPolygon;
                    if (rectanglePoly.GetBounds().Contains(polygon.GetBounds()))
                    {
                        cuttingPolygon = polygon;
                    }
                    else
                    {
                        cuttingPolygon = polygon.Intersect(rectanglePoly);
                    }

                    if (cuttingPolygon.GetEdgeCount() == 0)
                    {
                        continue;                                     //bounds cutting but not of any interest
                    }
                    List <ISurfaceSpecificsD> subPolygons = cuttingPolygon.SplitInIsleAndHoles(parentPCBI, NewlayerToAddElements);

                    foreach (ISurfaceSpecificsD subPolygon in subPolygons) //create part surfaces
                    {
                        IODBObject surface = filter.CreatePolygon(NewlayerToAddElements);
                        subPolygon.Positive = obj.Positive;

                        surface.SetSpecifics(subPolygon);
                        Dictionary <string, string> attributes = obj.GetAttributesDictionaryStringKeys();
                        foreach (string attribute in attributes.Keys)
                        {
                            surface.SetAttribute(attributes[attribute], attribute); //copy attributes
                        }
                    }
                    #endregion
                }
                else
                {
                    //not relevant -> ignore
                }
            }

            return(true); //finish
        }