How to replace pads with surfaces


Some special pads cause problems, when trying to export them to Gerber or other formats. An easy way out is removing and replacing them with surfaces (polygons).
You can use this code to change other elements too.
 
The basis was a script from PCB-Investigator scripting engine, you can copy the execute method in a script and use it directly without creating a plug-in.
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PCBI.Automation;
using PCBI.MathUtils;
 
namespace example
{
  public class ReplacePadBySurface
  {
    public void Execute(IPCBIWindow parent)
    {
      //replace all pads by surfaces
      try
      {
        IStep step = parent.GetCurrentStep();
 
        if (step == null) return;
 
        IFilter objectCreator = new IFilter(parent);
 
        foreach (string layerName in step.GetAllLayerNames()) //check all layer
        {
          ILayer gerberLayer = step.GetLayer(layerName);
 
          if (gerberLayer == null) continue;
 
          if (gerberLayer is ICMPLayer) continue; //should not be for gerberlayers
          if (gerberLayer is IPictureLayer) continue; //should not be for gerberlayers
 
          //gerber layers always contain IODBObjects
          foreach (IODBObject obj in gerberLayer.GetAllLayerObjects())
          {
            if (obj.Type == IObjectType.Pad) //we replace pads by surfaces
            {
              List<IObjectSpecificsD> outlineelements = obj.GetOutlineD();
 
              IODBObject surf = objectCreator.CreatePolygon((IODBLayer)gerberLayer); //new surface with pad outline
 
              ISurfaceSpecificsD surfSpec = (ISurfaceSpecificsD)surf.GetSpecificsD();
 
              bool first = true;
              foreach (IObjectSpecificsD objSpec in outlineelements) //set each element to the surface
              {
                if (objSpec is IArcSpecificsD)
                {
                  IArcSpecificsD arcS = (IArcSpecificsD)objSpec;
                  if (first)
                  {
                    surfSpec.StartPolygon(false, arcS.Start); //important to start the surface correct
                    first = false;
                  }
 
                  surfSpec.AddArc(arcS.Start, arcS.End, arcS.Center, arcS.ClockWise);
                }
                else if (objSpec is ILineSpecificsD)
                {
                  ILineSpecificsD lineS = (ILineSpecificsD)objSpec;
                  if (first)
                  {
                    surfSpec.StartPolygon(false, lineS.Start);
                    first = false;
                  }
 
                  surfSpec.AddLine(lineS.Start, lineS.End);
                }
              }
              surfSpec.EndPolygon(); //we have to close sub polygons
              surf.SetSpecifics(surfSpec); //add the information to PCB-Investigator
 
              if (!obj.ReplaceItemBy(surf)) //replace pad by surface
                Console.WriteLine("Could not replace item!");
            }
          }
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine("Error! " + ex.ToString());
 
      }
      parent.UpdateView(); //to show the replaced elements
    }
 
  }
}