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