X-Git-Url: http://gitweb.hugovil.com/?a=blobdiff_plain;f=scripts%2Faltium%2Fpcb-assembly-drawings.pas;fp=scripts%2Faltium%2Fpcb-assembly-drawings.pas;h=b5b3a45b4b8a811fa2c9be8039b69462054ada6f;hb=d2cace985fa8e2bbe86940fb7921d3b4afd829e1;hp=0000000000000000000000000000000000000000;hpb=0dc7006d16de56921ead4a834a444f9cfa0a09a4;p=eda-utils.git diff --git a/scripts/altium/pcb-assembly-drawings.pas b/scripts/altium/pcb-assembly-drawings.pas new file mode 100644 index 0000000..b5b3a45 --- /dev/null +++ b/scripts/altium/pcb-assembly-drawings.pas @@ -0,0 +1,262 @@ +// Création des dessins d'assemblage sur les couches mécaniques 10 (TOP) et 11 (BOT) +// +// TODO: +// Afficher le nombre de composants total et celui qui est présentement traité (1/200) +// Gérer les composants avec des orientations non multiples de 90 deg. + +Const + MY_REF_SIZE_MILS = 30; + MY_REF_WIDTH_MILS = 3; + + // La grosseur du texte en fonction de la taille du composant, jusqu´à cette limite. + TEXT_SIZE_MAX_MILS = 100; + + // Ratio de la longueur du texte du refdes par rapport à la longueur maximale permise par les dimensions du composant. + RATIO_MAXLEN_REFDES = 0.85; + + // Ratio de la hauteur du texte du refdes par rapport à la hauteur maximale permise par les dimensions du composant. + RATIO_MAXHEIGHT_REFDES = 0.65; + + // Ajustement empirique. + AJUSTEMENT_CENTRAGE = 0.90; + + TOP_ASSEMBLY_LAYER = eMechanical10; + BOT_ASSEMBLY_LAYER = eMechanical11; + +Procedure PCB_GenerateAssemblyDrawings; +Var + Board : IPCB_Board; + Comp : IPCB_Component; + Iterator : IPCB_BoardIterator; + + strlen, : Integer; + StrWidth : TCoord; + StrHeight : TCoord; + OffsetX : TCoord; + OffsetY : TCoord; + MidX, MidY : Integer; + MaxLen : Integer; + MaxHeight : Integer; + TempSize : Integer; + + IsCircle : Boolean; + + DestLayer : TLayer; + TextObj : IPCB_Text; + + // Pour sauvegarder les valeurs du composant original. + OldCommentOn : Boolean; + OldCompRotation : Integer; + OldCompNameRotation : Integer; + + // Attributs du nouveau composant sur la couche d'assemblage + NewRotation : Integer; + NewSize : Integer; + +Begin + Pcbserver.PreProcess; + + Board := PCBServer.GetCurrentPCBBoard; + If Not Assigned(Board) Then + Begin + ShowMessage('The Current Document is not a Protel PCB Document.'); + Exit; + End; + + // Efface les 2 couches d'assemblage + ClearAssemblyLayer(Board, TOP_ASSEMBLY_LAYER); + ClearAssemblyLayer(Board, BOT_ASSEMBLY_LAYER); + + // Setup Board iterator + Iterator := Board.BoardIterator_Create; + Iterator.AddFilter_ObjectSet(MkSet(eComponentObject)); + //Iterator.AddFilter_LayerSet(MkSet(eBottomLayer)); + Iterator.AddFilter_LayerSet(AllLayers); + Iterator.AddFilter_Method(eProcessAll); + + Comp := Iterator.FirstPCBObject; + While (Comp <> Nil) Do + Begin + IsCircle := False; + + // Check if Component Name property exists before extracting the text + If Comp.Name = Nil Then Exit; + + // On ne modifie pas le numéro du PCB, qui est la référence du logo de compagnie + If CompareString(Comp.Pattern, 'LOGOCOMPANY', 7) Then + Begin + Comp := Iterator.NextPCBObject; + Continue; + End; + + If CompareString(UpperCase(Comp.Pattern), 'MIRE', 4) Then + Begin + Comp := Iterator.NextPCBObject; + Continue; + End; + + If CompareString(UpperCase(Comp.Pattern), 'CRACK', 5) Then + Begin + Comp := Iterator.NextPCBObject; + Continue; + End; + + // On n´affiche pas les fiducials + If CompareString(UpperCase(Comp.Pattern), 'FIDG', 4) Then + Begin + Comp := Iterator.NextPCBObject; + Continue; + End; + + // On n´affiche pas la légende des couches + If CompareString(UpperCase(Comp.Pattern), 'LAYERS', 6) Then + Begin + Comp := Iterator.NextPCBObject; + Continue; + End; + + // Modify the component + PCBServer.SendMessageToRobots(Comp.I_ObjectAddress, c_Broadcast, PCBM_BeginModify , c_NoEventData); + + // Sauvegarde valeurs originales + OldCommentOn := Comp.CommentOn; + OldCompRotation := Comp.Rotation; + OldCompNameRotation := Comp.Name.Rotation; + + // Sauf pour les MH + if CompareString(Comp.Name.Text, 'MH', 2) Then + IsCircle := True; + if CompareString(Comp.Name.Text, 'TP', 2) Then + IsCircle := True; + + If IsCircle Then + Comp.Rotation := 0; + + // Et on désactive temporairement les commentaires + Comp.CommentOn := False; + + // On fait une rotation de la référence selon l'orientation du composant + Case Comp.Rotation of + 0, 180, 360 : Comp.Name.Rotation := 0; + 90, 270 : Comp.Name.Rotation := 90; + End; + + If Comp.Layer = eBottomLayer Then + Begin + Case Comp.Name.Rotation of + 90 : Comp.Name.Rotation := 270; + End; + End; + + FetchComponentMidPoints(Comp, MidX, MidY, MaxLen, MaxHeight); + + // string length * character_width <= MaxLen + // character_width = 2/3 * Size en mil. + // Ex: Si le size est de 30 mils, la largeur est environ de 20 mils. + // -> Size = MaxLen / strlen * 3/2 + strlen := Length(Comp.Name.Text); + + // Calcul de la grosseur de la référence selon la longueur disponible (bonding box). + TempSize := CoordToMils(MaxLen * RATIO_MAXLEN_REFDES) / strlen * 0.9; + if TempSize > TEXT_SIZE_MAX_MILS Then + TempSize := TEXT_SIZE_MAX_MILS; + + // Ajustement selon la hauteur disponible (bonding box). + If TempSize > (CoordToMils(MaxHeight) * RATIO_MAXHEIGHT_REFDES) Then + TempSize := CoordToMils(MaxHeight) * RATIO_MAXHEIGHT_REFDES; + + // Adjust size according to available space + NewSize := MilsToCoord(TempSize); + StrWidth := strlen * NewSize; + StrHeight:= NewSize; + + If Comp.Layer = eTopLayer Then + Begin + DestLayer := TOP_ASSEMBLY_LAYER; + Case Comp.Name.Rotation of + 0 : + Begin + OffsetX := -StrWidth / 2; + OffsetY := -StrHeight / 2; + End; + 90 : + Begin + OffsetX := StrHeight / 2; + OffsetY := -StrWidth / 2; + End; + End; + End; + If Comp.Layer = eBottomLayer Then + Begin + DestLayer := BOT_ASSEMBLY_LAYER; + Case Comp.Name.Rotation of + 0 : + Begin + OffsetX := StrWidth / 2; + OffsetY := -StrHeight / 2; + End; + 270 : + Begin + OffsetX := -StrHeight / 2; + OffsetY := -StrWidth / 2; + End; + End; + End; + + // Ajustement empirique... + Case Comp.Name.Rotation of + 0 : OffsetX := OffsetX * AJUSTEMENT_CENTRAGE; + 90 : OffsetY := OffsetY * AJUSTEMENT_CENTRAGE; + 270 : OffsetY := OffsetY * AJUSTEMENT_CENTRAGE; + End; + + // Sauvegarde nouvelles valeurs pour nouveau composant sur couche d'assemblage + NewRotation := Comp.Name.Rotation; + + // Restauration valeurs originales + Comp.CommentOn := OldCommentOn; + Comp.Rotation := OldCompRotation; + Comp.Name.Rotation := OldCompNameRotation; + + PCBServer.SendMessageToRobots(Comp.I_ObjectAddress, c_Broadcast, PCBM_EndModify , c_NoEventData); + + If IsCircle Then + // Crée un cercle représentant le composant + CreateBondingcircle(Board, DestLayer, MidX, MidY, MaxLen / 2) + Else + // Crée une boite représentant le composant + CreateBondingBox(Board, DestLayer); + + //Create a first text object non True Type font. + TextObj := PCBServer.PCBObjectFactory(eTextObject, eNoDimension, eCreate_Default); + + // notify that the pcb object is going to be modified + PCBServer.SendMessageToRobots(TextObj.I_ObjectAddress ,c_Broadcast, PCBM_BeginModify , c_NoEventData); + + TextObj.Layer := DestLayer; + TextObj.XLocation := MidX + OffsetX; + TextObj.YLocation := MidY + OffsetY; + TextObj.Rotation := NewRotation; + TextObj.Text := Comp.Name.Text; + TextObj.Size := NewSize; + TextObj.Width := MilsToCoord(MY_REF_WIDTH_MILS); + TextObj.UseTTFonts := False; + TextObj.Italic := False; + TextObj.Bold := False; + TextObj.FontName := 'Default'; + If Comp.Layer = eBottomLayer Then + TextObj.MirrorFlag := True; + + Board.AddPCBObject(TextObj); + + // notify that the pcb object has been modified + PCBServer.SendMessageToRobots(TextObj.I_ObjectAddress, c_Broadcast, PCBM_EndModify , c_NoEventData); + + Comp := Iterator.NextPCBObject; + End; + + Board.BoardIterator_Destroy(Iterator); + + Pcbserver.PostProcess; + Client.SendMessage('PCB:Zoom', 'Action=Redraw', 255, Client.CurrentView); +End;