How to create special pads

Some formats including elements how are not included in ODB++, for this you can create special pads. For existing elements its very easy to add them e.g.:

int index1 = IFilter.AddToolDefinitionRound(layer, 10, 0);
int index2 = IFilter.AddToolDefinitionRect(layer, 20, 1, 20, 50, true);
int index3 = IFilter.AddToolDefinitionDonut(layer, 50, 25, 2);
int index4 = IFilter.AddToolDefinitionOct(layer, 40, 40, 40, 5, 3);

Then add your element and use the correct shape index from your definition:

IPadSpecifics padInfos = new IPadSpecifics();
padInfos.Location = new PointF(400, 400);
padInfos.Positiv = (true);
pad.SetSpecifics(padInfos, index1);

For ODB++ Features it is possible to create them form strings, in the same way like reading it from an ODB++ feature file:

/// <summary>
/// Creates an pad from an ODB++ String, please check specification for details.
/// </summary>
/// <param name="pcbiFilter">The creation object with reference to PCB-Investigator.</param>
/// <param name="parentLayer">The layer to add the new object.</param>
/// <param name="location">Where should the pad located?</param>
/// <param name="ODBString">The ODB++ specificated element.</param>
/// <param name="symbolType">To fill the property correct.</param>
/// <returns>The shape index for later using.</returns>
internal int CreatePadFromString(IFilter pcbiFilter, IODBLayer parentLayer, PointF location, string ODBString, PCBI.Symbol_Type symbolType)
{
IODBObject pad = pcbiFilter.CreatePad(parentLayer);//create a new pad object
IPadSpecifics specPad = (IPadSpecifics)pad.GetSpecifics();
specPad.Location = location;
specPad.ShapeIndex = IFilter.AddToolFromODBString(parentLayer, ODBString, -1);
 
specPad.Positiv = true;
specPad.Type = symbolType; //for pads are many different symbols reasonable, special symbols can have all outlines you wan't (see there).
pad.SetSpecifics(specPad, specPad.ShapeIndex); //activate the new setting.
 
return specPad.ShapeIndex; //maybe you want save the ShapeIndex in your own list.
}

But for new elements its a little bit more work to do, first the CreateSpecialPad method:

/// <summary>
/// This only a specific example, you have to change some parts of it.
/// You can use the returned shape index to set the outline for more pads.
/// </summary>
internal static int CreateSpecialPad(IFilter pcbiFilter, IODBLayer parentLayer, PointF Location, List<ExampleSurface.Grf_Object> OutlineOfSpecialPad)
{
IODBObject t = pcbiFilter.CreateOutlinePolygon(); //the t is only a temporary object to create a specifics!
ISurfaceSpecifics outline = (ISurfaceSpecifics)t.GetSpecifics(); //put all outline elements in this object
IODBObject padODB = null; //this is the object in pcb-investigator.
IPadSpecifics specPad = null; //to set the specifics us this.
 
#region example set outline
bool started = false;
foreach (IFilterDemoApp.ExampleSurface.Grf_Object obj in OutlineOfSpecialPad) //you need a list of objects from your own class, here we hace Grf_Objects with Grf_Arc and Grf_Line
{
if (obj is IFilterDemoApp.ExampleSurface.Grf_Line) //special class for Lines
{
#region line
IFilterDemoApp.ExampleSurface.Grf_Line line = (IFilterDemoApp.ExampleSurface.Grf_Line)obj;

if (!started)
{
started = true;
outline.StartPolygon(false, line.Start);
}
outline.AddLine(line.Start, line.End); //add the line to the outline of the special pad.
#endregion
}
else if (obj is IFilterDemoApp.ExampleSurface.Grf_Arc) //special class for Arcs
{
#region arc
IFilterDemoApp.ExampleSurface.Grf_Arc arc = (IFilterDemoApp.ExampleSurface.Grf_Arc)obj;

if (!started)
{
started = true;
outline.StartPolygon(false, arc.Start);
}
 
outline.AddArc(arc.Start, arc.End, arc.Center, arc.Clockwise);
#endregion
}
#endregion
}
#endregion
 
outline.EndPolygon();
RectangleF bounds = outline.GetBounds();
 
if (padODB == null)
padODB = pcbiFilter.CreatePad(parentLayer);
if (specPad == null)
specPad = (IPadSpecifics)padODB.GetSpecifics();
 
//maybe you save a counter, or use this:
Dictionary<int, PCBI.Automation.IFilter.ToolDefinition> symbolList = pcbiFilter.GetUsedSymbolList(parentLayer);
 
//The name should be descipe the outline or typenumber or the name in your specifics.
specPad.ShapeIndex = pcbiFilter.AddToolDefinitionSpecial(parentLayer, "special_" + "name of pad", outline, outline.GetBounds().Width, symbolList.Count + 1);
 
specPad.Positiv = true;
specPad.Type = PCBI.Symbol_Type.special;
specPad.Location.X = Location.X;
specPad.Location.Y = Location.Y;
 
padODB.SetSpecifics(specPad, specPad.ShapeIndex);
 
return specPad.ShapeIndex;
}
 
internal class ExampleSurface
{
 
internal class Grf_Object
{ }
/// <summary>
/// The Line is a simple element with Start and End Points.
/// </summary>

internal class Grf_Line : Grf_Object
{
internal PointF Start;
internal PointF End;
}
/// <summary>
/// The Arc has more information for Center and direction of the arc.
/// </summary>

internal class Grf_Arc : Grf_Object
{
internal PointF Start;
internal PointF End;
internal PointF Center;
internal bool Clockwise = true

Here is the example code in C Sharp and VB: