-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathalign_utils.il
437 lines (414 loc) · 11.2 KB
/
align_utils.il
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
;
; $Source: align_utils.il $ $Revision: 78:ee7b9b257e1d $ $Branch$ $Rev: 78 $
; $Author: Kapustin $ $Date: 2012-01-21 23:42 +0300 $
;
; skill load "o:\\Sripts\\align\\align_utils.il"
;
; Get the point snapped to the nearest grid (if snapToGrid mode is true).
;
defun( alnGriddedPoint (point grids)
let( (xOrigin yOrigin xMajor yMajor pointX pointY)
when( (axlIsDebug) printf("alnGriddedPoint\n"))
pointX = xCoord(point)
pointY = yCoord(point)
when( (axlVersion('version) >= 15.7) ; since 15.7
if( _alnFormData->snapToGrid then
xMajor = grids->xMajor
yMajor = grids->yMajor
xOrigin = grids->xOrigin
yOrigin = grids->yOrigin
pointX = round(pointX/xMajor)*xMajor + xOrigin
pointY = round(pointY/yMajor)*yMajor + yOrigin
)
)
list(pointX pointY) ;return
)
);defun
;
; Get the current grid.
;
defun( alnGetCurrentGrid (selectedObjects)
prog( (grids isMirrored)
when( (axlVersion('version) >= 15.7) ; since 15.7
case( car(selectedObjects)->objType
( ("group" "symbol" "pin" "via") ; use etch grid
isMirrored = car(selectedObjects)->isMirrored
foreach( item _alnSelectedObjects
if( isMirrored == item->isMirrored
then isMirrored = item->isMirrored
else return(axlDBGridGet(axlConductorTopLayer())) ;both layers, use TOP
)
)
if( isMirrored
then return(axlDBGridGet(axlConductorBottomLayer())) ; mirrored, use BOT
else return(axlDBGridGet(axlConductorTopLayer())) ; non mirrores, use TOP
)
)
( "text" ;use non-etch grid
grids = axlDBGridGet("non-etch")
)
)
)
return(grids)
)
);defun
;
; Get maximum X coordinate from list of objects
;
defun( alnMaxX (lObjects)
let( (obj pointX result)
result = -1000000.0
foreach( obj lObjects
pointX = xCoord(alnGetObjectLocation(obj))
result = max(pointX result)
)
result
)
);defun
;
; Get minimum X coordinate from list of objects
;
defun( alnMinX (lObjects)
let( (obj pointX result)
result = 1000000.0
foreach( obj lObjects
pointX = xCoord(alnGetObjectLocation(obj))
result = min(pointX result)
)
result
)
);defun
;
; Get maximum Y coordinate from list of objects
;
defun( alnMaxY (lObjects)
let( (obj pointY result)
result = -1000000.0
foreach( obj lObjects
pointY = yCoord(alnGetObjectLocation(obj))
result = max(pointY result)
)
result
)
);defun
;
; Get minimum Y coordinate from list of objects
;
defun( alnMinY (lObjects)
let( (obj pointY result)
result = 1000000.0
foreach( obj lObjects
pointY = yCoord(alnGetObjectLocation(obj))
result = min(pointY result)
)
result
)
);defun
;
; Sort list of objects by X coordinate, ascending order.
;
defun( alnOrderByX (objectList)
sort( objectList 'alnComparePositionX )
);defun
defun( alnComparePositionX ( obj1 obj2 )
let( ( pt1x pt2x pt1y pt2y pt1 pt2 result)
pt1 = alnGetObjectLocation(obj1)
pt2 = alnGetObjectLocation(obj2)
pt1x = xCoord( pt1 )
pt2x = xCoord( pt2 )
if( (pt1x < pt2x)
then result = t
else
if( (pt1x == pt2x)
then
; aditionaly compare by Y
pt1y = yCoord( pt1 )
pt2y = yCoord( pt2 )
if( (pt1y < pt2y)
then result = t
else result = nil
)
else result = nil
)
)
result
) ; let
) ; defun
;
; Sort list of objects by Y coordinate, ascending order.
;
defun( alnOrderByY (objectList)
sort( objectList 'alnComparePositionY )
) ;defun
defun( alnComparePositionY ( obj1 obj2 )
let( ( pt1x pt2x pt1y pt2y pt1 pt2 result)
pt1 = alnGetObjectLocation(obj1)
pt2 = alnGetObjectLocation(obj2)
pt1y = yCoord( pt1 )
pt2y = yCoord( pt2 )
if( (pt1y < pt2y)
then result = t
else
if( (pt1y == pt2y)
then
; aditionaly compare by X
pt1x = xCoord( pt1 )
pt2x = xCoord( pt2 )
if( (pt1x < pt2x)
then result = t
else result = nil
)
else result = nil
)
)
result
) ; let
) ; defun
;
; Get object location point according to selected mode (Origin, Body Center, Pin)
;
defun( alnGetObjectLocation (object)
let( (result message)
case( _alnFormData->snapPoint
( "origin" result = axlDBAltOrigin('origin object) )
( "center" result = axlDBAltOrigin('center object) )
( "pin"
result = alnGetPinLocation(object _alnFormData->snapPinNumber)
when( !result
message = strcat("WARNING: Pin '", _alnFormData->snapPinNumber, "' not found")
if( object->refdes
then message = strcat(message, " for symbol '", object->refdes, "', got body center.")
else message = strcat(message, ", got body center.")
)
axlMsgPut(message)
result = axlDBAltOrigin('center object)
)
)
);case
result
) ; let
) ; defun+
;
; Get location for given object's pin
; Return nil if pin not found.
defun( alnGetPinLocation (object pinNumber)
let( (result number)
pinNumber = upperCase(pinNumber)
pinList = object->pins
foreach( pin pinList
number = pin->number
number = upperCase(number)
when( pinNumber == number result = pin->xy)
)
result
) ; let
) ; defun
;
; Get object boundary box.
; First trying get Dfa_Bound_Top(Bottom)
; if Dfa not present trying Place_Bound_Top(Bottom)
; if Place not present get bBox property.
;
defun( alnGetObjectBBox (object)
let( ( objectChildren child dfaLayer placeLayer result)
if(object->isMirrored
then dfaLayer = "PACKAGE GEOMETRY/DFA_BOUND_BOTTOM" placeLayer = "PACKAGE GEOMETRY/PLACE_BOUND_BOTTOM"
else dfaLayer = "PACKAGE GEOMETRY/DFA_BOUND_TOP" placeLayer = "PACKAGE GEOMETRY/PLACE_BOUND_TOP"
)
objectChildren = object->children
; only Symbols have objectChildren
if(objectChildren then
; find Dfa_Bound_ shape
foreach( child objectChildren
if((child->objType == "shape" && child->layer == dfaLayer) then
result = child->bBox
)
)
; find Place_Bound_ shape
if(!result then
foreach( child objectChildren
if((child->objType == "shape" && child->layer == placeLayer) then
result = child->bBox
)
)
)
)
if(!result then result = object->bBox)
result
) ; let
) ; defun
;
; Get objects boundary boxes.
; Return list of boxes.
;
defun( alnGetBBoxes (objectList)
let( ( object result)
foreach( object objectList
result = tconc(result alnGetObjectBBox(object))
)
car(result) ; get list from "tconc" list
) ; let
) ; defun
;
; Get minimal X boundary box coordinate for given BBoxes.
;
defun( alnGetMinBBoxX (boxList)
let( ( pointX box result)
result = 1000000.0
foreach( box boxList
pointX = xCoord(car(box))
result = min(pointX result)
)
result
) ; let
) ; defun
;
; Get maximal X boundary box coordinate for given BBoxes.
;
defun( alnGetMaxBBoxX (boxList)
let( ( pointX box result)
result = -1000000.0
foreach( box boxList
pointX = xCoord(cadr(box))
result = max(pointX result)
)
result
) ; let
) ; defun
;
; Get minimal Y boundary box coordinate for given BBoxes.
;
defun( alnGetMinBBoxY (boxList)
let( ( pointY box result)
result = 1000000.0
foreach( box boxList
pointY = yCoord(car(box))
result = min(pointY result)
)
result
) ; let
) ; defun
;
; Get maximal Y boundary box coordinate for given BBoxes.
;
defun( alnGetMaxBBoxY (boxList)
let( ( pointY box result)
result = -1000000.0
foreach( box boxList
pointY = yCoord(cadr(box))
result = max(pointY result)
)
result
) ; let
) ; defun
defun( alnRefreshIDs (objectList)
let( ( object resultList)
foreach( object objectList
resultList = tconc(resultList axlDBRefreshId(object))
)
car(resultList) ; get list from "tconc" list
) ; let
) ; defun
;
; Check for object have "Fixed" property. If it's true, remove this object from selection.
; Return list without fixed objects.
;
defun( alnCheckForFixedObjects (objectList)
let( ( x prop object resultList)
foreach( object objectList
if( axlDBIsFixed(object nil)
; remove from selection
then axlSubSelectObject(object)
; place to returned list
else resultList = tconc(resultList object)
)
)
car(resultList) ; get list from "tconc" list
) ; let
) ; defun
;
; Move object to provided distance.
; Analise useStretch and useRipup settings and respectively move/ripup connected to object CLines.
;
defun( alnMoveObject (object deltaPoint) ; object = car(_alnSelectedObjects) deltaPoint = list(10.0 -10.0) alnMoveObject(object deltaPoint)
let( (segmentsToCreate segmentsToRemove pinList pin pinXY paths isVia
path segments segment startEnd newStartEnd segmentToCreate x1 y1 x2 y2 net)
if( (car(deltaPoint) != 0.0 || cadr(deltaPoint) != 0.0) then
if( (_alnFormData->useStretch || _alnFormData->useRipup) then
;get list of pins
pinList = object->pins
if( object->objType == "via" then
isVia = t
pinList = list(object) ; hack for vias
)
; get CLines for each pin
foreach( pin pinList
pinXY = pin->xy
; get paths connected to pin
paths = axlDBGetConnect(pin nil)
; get segments for each path
foreach( path paths
segments = path->segments
; find segment which connected to pin (points are equal)
foreach( segment segments
startEnd = segment->startEnd
newStartEnd = nil
if( car(startEnd) == pinXY
then
; calculate new segment points
x1 = xCoord(car(startEnd)) + xCoord(deltaPoint)
y1 = yCoord(car(startEnd)) + yCoord(deltaPoint)
x2 = xCoord(cadr(startEnd))
y2 = yCoord(cadr(startEnd))
newStartEnd = list( x1:y1 x2:y2 )
else
if( cadr(startEnd) == pinXY
then
; calculate new segment points
x1 = xCoord(car(startEnd))
y1 = yCoord(car(startEnd))
x2 = xCoord(cadr(startEnd)) + xCoord(deltaPoint)
y2 = yCoord(cadr(startEnd)) + yCoord(deltaPoint)
newStartEnd = list( x1:y1 x2:y2 )
)
);if
if(newStartEnd then
segmentsToRemove = cons(segment segmentsToRemove)
segmentToCreate = ncons(t)
segmentToCreate->startEnd = newStartEnd
segmentToCreate->width = segment->width
segmentToCreate->layer = segment->layer
segmentToCreate->netname = (segment->net)->name
segmentsToCreate = cons(segmentToCreate segmentsToCreate)
);if(newStartEnd
);foreach( segment segments
);foreach( path paths
);foreach( pin pinList
; remove old segments
if( segmentsToRemove then
foreach(segment segmentsToRemove
axlDeleteObject(segment)
)
)
);if(_alnFormData->useStretch
;move object
axlTransformObject( object ?move deltaPoint )
when( isVia
; restore net
net = car(segmentsToCreate)->netname
when( net axlDBAssignNet(object net) )
)
; create new segments
if( (segmentsToCreate && _alnFormData->useStretch) then
foreach(segment segmentsToCreate
startEnd = segment->startEnd
width = segment->width
layer = segment->layer
netname = segment->netname
axlDBCreateLine( startEnd width layer netname nil)
)
)
);if( (car(deltaPoint)
t ;return
) ; let
) ; defun