Add Altium Delphi scripts
[eda-utils.git] / scripts / altium / functions.pas
diff --git a/scripts/altium/functions.pas b/scripts/altium/functions.pas
new file mode 100644 (file)
index 0000000..c72dbfd
--- /dev/null
@@ -0,0 +1,180 @@
+Const
+    MY_BOX_WIDTH_MILS = 4;
+    MY_CIRCLE_WIDTH_MILS = 4;
+
+    MY_REF_SIZE_MILS  = 30;
+    MY_REF_WIDTH_MILS = 4;
+
+Var
+    MinX, MinY, MaxX, MaxY : Integer;
+
+Procedure RemoveSpaces(Var Str : AnsiString);
+Var
+    SpacePos : Integer;
+Begin
+    Repeat
+        SpacePos := Pos(' ', Str);
+        If SpacePos <> 0 Then
+            Delete(Str, SpacePos, 1);
+    Until SpacePos = 0;
+End;
+
+Function IsNumber(AChar : Char) : Boolean;
+Begin
+    Result := ('0' <= AChar) And (AChar <= '9');
+End;
+
+Function IsLetter(AChar : Char) : Boolean;
+Begin
+    Result := ('a' <= AChar) And (AChar <= 'Z');
+End;
+
+Function CompareString(a, b : AnsiString; len : Integer) : Boolean;
+Var
+    a1, b1 : AnsiString;
+Begin
+    Result := False;
+
+    a1 := Copy(a, 1, len);
+    b1 := Copy(b, 1, len);
+
+    Result := a1 = b1;
+End;
+
+
+Procedure ClearAssemblyLayer(Board : IPCB_Board; Layer :  TLayer);
+Var
+    Comp      : IPCB_Component;
+    Iterator  : IPCB_BoardIterator;
+Begin
+    // Setup Board iterator 
+    Iterator        := Board.BoardIterator_Create; 
+    Iterator.AddFilter_ObjectSet(AllObjects); 
+    Iterator.AddFilter_LayerSet(MkSet(Layer));
+    Iterator.AddFilter_Method(eProcessAll);
+    
+    Comp := Iterator.FirstPCBObject;
+    While (Comp <> Nil) Do
+    Begin
+        Board.RemovePCBObject(Comp);
+
+        Comp := Iterator.NextPCBObject;
+    End;
+    
+    Board.BoardIterator_Destroy(Iterator);
+End;
+
+
+Procedure TrackAdd(Board : IPCB_Board; Layer : TLayer; x1, y1, x2, y2 : Integer);
+Var
+    Track : IPCB_Track;
+Begin
+    // Create a Track object.
+    Track := PCBServer.PCBObjectFactory(eTrackObject, eNoDimension, eCreate_Default);
+
+    Track.X1       := x1;
+    Track.Y1       := y1;
+    Track.X2       := x2;
+    Track.Y2       := y2;
+    Track.Layer    := Layer;
+    Track.Width    := MilsToCoord(MY_BOX_WIDTH_MILS);
+    Board.AddPCBObject(Track);
+End;
+
+
+Procedure CreateBondingBox(Board : IPCB_Board; Layer : TLayer);
+Begin
+    TrackAdd(Board, Layer, MinX, MinY, MaxX, MinY);
+    TrackAdd(Board, Layer, MaxX, MinY, MaxX, MaxY);
+    TrackAdd(Board, Layer, MaxX, MaxY, MinX, MaxY);
+    TrackAdd(Board, Layer, MinX, MaxY, MinX, MinY);
+End;
+
+
+Procedure CreateBondingCircle(Board : IPCB_Board; Layer : TLayer; x, y, r : Integer);
+Var
+    Arc : IPCB_Arc;
+Begin
+    Arc := PCBServer.PCBObjectFactory(eArcObject, eNoDimension, eCreate_Default);
+    Arc.XCenter    := x;
+    Arc.YCenter    := y;
+    Arc.Radius     := r;
+    Arc.LineWidth  := MilsToCoord(MY_CIRCLE_WIDTH_MILS);
+    Arc.StartAngle := 0;
+    Arc.EndAngle   := 360;
+    Arc.Layer      := Layer;
+    Board.AddPCBObject(Arc);
+End;
+
+
+Procedure ProcessObjectsOfAComponent(Const P : IPCB_Primitive);
+Var
+    R : TCoordRect;
+Begin
+    // check for comment / name objects
+    If P.ObjectId <> eTextObject Then
+    Begin
+        R := P.BoundingRectangle;
+
+        If R.left   < MinX Then MinX := R.left;
+        If R.bottom < MinY Then MinY := R.bottom;
+        If R.right  > MaxX Then MaxX := R.right;
+        If R.top    > MaxY Then MaxY := R.top;
+    End;
+End;
+
+Procedure FetchComponentMidPoints(Comp : IPCB_Component; out MidX, MidY, MaxLen, MaxHeight);
+Var
+    GroupIterator : IPCB_GroupIterator;
+    GroupHandle   : IPCB_Primitive;
+Begin
+    // setting extreme constants...
+    MinX :=  2147483647;
+    MinY :=  2147483647;
+    MaxX := -2147483647;
+    MaxY := -2147483647;
+
+    GroupIterator := Comp.GroupIterator_Create;
+    GroupIterator.AddFilter_ObjectSet(AllObjects);
+    GroupHandle   := GroupIterator.FirstPCBObject;
+    While GroupHandle <> Nil Do
+    Begin
+        ProcessObjectsOfAComponent(GroupHandle);
+        GroupHandle := GroupIterator.NextPCBObject;
+    End;
+    Comp.GroupIterator_Destroy(GroupIterator);
+
+    MidX := (MinX + MaxX) / 2;
+    MidY := (MinY + MaxY) / 2;
+    
+    Case Comp.Name.Rotation of
+        0   : MaxLen := MaxX - MinX;
+        90  : MaxLen := MaxY - MinY;
+        270 : MaxLen := MaxY - MinY;
+    End;
+    
+    Case Comp.Name.Rotation of
+        0   : MaxHeight := MaxY - MinY;
+        90  : MaxHeight := MaxX - MinX;
+        270 : MaxHeight := MaxX - MinX;
+    End;
+End;
+
+Procedure ResizeRefDes(Comp : IPCB_Component);
+Begin
+   // Check if Component Name property exists before extracting the text
+   If Comp.Name = Nil Then Exit;
+
+   // Modify the component
+   PCBServer.SendMessageToRobots(Comp.I_ObjectAddress, c_Broadcast, PCBM_BeginModify , c_NoEventData);
+
+   Comp.Name.Size  := MilsToCoord(MY_REF_SIZE_MILS);;
+   Comp.Name.Width := MilsToCoord(MY_REF_WIDTH_MILS);
+   Comp.Name.UseTTFonts := False; 
+   Comp.Name.Italic := False; 
+   Comp.Name.Bold := False; 
+   Comp.Name.FontName := 'Default';
+
+   PCBServer.SendMessageToRobots(Comp.I_ObjectAddress, c_Broadcast, PCBM_EndModify , c_NoEventData);
+End;
+