Is there a way to plot or copy paste mask openings only for populated components (i.e. components that do not carry the attribute 'do not populate') automatically?
Can you reference any pre-existing SKILL code that can be modified for this purpose?
The only time I was asked to do this the simplest solution was to save the design, then detete the component symbols with the 'do not populate' attribute, then generate the paste mask artworks & then reopen the design to undo the deletion
I believe the only SKILL way is to delete the paste mask from the padstacks.
Find all affected padstacks (from components which are not populated)
Create for each padstack a new one with axlDBCreatePadStack(), but without the pastemask
Replace the padstacks with axlReplacePadstack() for all not populated components.
I see. Unfortunately, my skills in SKILL coding are not very advanced. Can you please refer to a SKILL code written for a similar purpose?
Can I just copy the existing padstacks and delete the pastemask from it via SKILL, instead of creating new ones for every pad type which might be quite elaborative?
That's a good and easy solution. But probably not so well suited for a board with 4000+ components and different population versions...
I assume/hope that you have only a few padstacks in your 4000+ components PCB design?
The idea is that you create a set of alternative padstacks of which the paste mask is removed. Then you simply replace the individual padstacks per refdes in the design.
So something like this. Please take this as-is and change it for your own needs.
;axlDBCloak('_RemovePasteMask(list("C100" "U100")) '(shape ignoreFixed))defun( _RemovePasteMask (l_refdes) let( ((success 0) (fail 0) (skipped 0) pcre1 comp_dbID ps_newName ps_dbID bbox figureSize1 new_layer pad_list x y) pcre1 = pcreCompile(".*-NO_PASTE" 1) ;need to create 2 new mask layers where we will move the original padstack pastemask to. axlPadUserMaskLayers('create "NOPASTE_TOP") axlPadUserMaskLayers('create "NOPASTE_BOTTOM") foreach(refdes l_refdes if(comp_dbID = axlDBFindByName('refdes refdes) ;get component instance. (not symbol or comp/symbdef) then foreach(pin comp_dbID->pins ;only process SMD pins unless(pin->isthrough ps_newName = pin->definition->name ;Check if padstack name is already changed. If not then create and change padstack if(pcreMatchp(pcre1 ps_newName) then skipped++ else sprintf(ps_newName "%s-NO_PASTE" ps_newName) ;check if padstack can be loaded, otherwise create one unless(ps_dbID= axlLoadPadstack(ps_newName) pad_list = nil foreach(pad pin->definition->pads figureSize = list( caadr(pad->bBox)-caar(pad->bBox) cadadr(pad->bBox)-cadar(pad->bBox)) new_layer = case(pad->layer ("PIN/PASTEMASK_TOP" "NOPASTE_TOP" ) ("PIN/PASTEMASK_BOTTOM" "NOPASTE_BOTTOM" ) (t cadr(parseString(pad->layer "/"))) ) unless(pad->figureName=="NULL" push(make_axlPadStackPad( ?layer new_layer ?type concat(pad->type) ?flash pad->flash ?figure if(pad->figureName == "SHAPE", pad->name ,pad->figureName) ?figureSize figureSize ?offset pad->offset ) pad_list) ) ) ps_dbID= axlDBCreatePadStack(ps_newName nil reverse(pad_list) nil) axlDBRefreshId(nil) ) if(ps_dbID then if(car(axlReplacePadstack(pin ps_dbID)) then success++ else fail++ ) else axlMsgPut('("Component %s: Could not change %s into %s." 3) refdes pin->definition->name ps_newName) ) ) ) ) axlDBRefreshId(comp_dbID) else axlMsgPut( '("Refdes %s not found" 3) refdes) ) ) when(plusp(success) axlMsgPut( "%d padstacks replaced successful" success)) when(plusp(fail) axlMsgPut( "Failed to replace %d padstacks" fail)) when(plusp(skipped) axlMsgPut( "%d padstacks already replaced" skipped))));defun