REPLACE VIS WITH hcomp/koef
REPLACE X WITH dat[1]/koef
REPLACE Y WITH dat[2]/koef
gabar[1]:=SHIR*koef
gabar[2]:=DLIN*koef
IF compon[nn,3]=0
compon[nn,3]=Vis*koef
ENDIF
ELSE
EXIT
ENDIF
ENDIF
ENDDO
ROT(X*koef,Y*koef,gabar[1],gabar[2],nn)
RETURN gabar
//****************************************************
FUNCTION ROT(a,b,shc,dlc,L)//функция учитывающая поворот элемента относительно оси и производящая соответствующий пересчет его координат
IF compon[L,6]=0 //учет поворота элемента
IF compon[L,2]='bot'
compon[L,4]=compon[L,4]+shc-a
compon[L,5]=compon[L,5]-b
ELSE
compon[L,4]=compon[L,4]+a
compon[L,5]=compon[L,5]-b
ENDIF
compon[L,7]=shc
compon[L,8]=dlc
ELSEIF compon[L,6]=1
IF compon[L,2]='bot'
compon[L,4]=compon[L,4]+b
compon[L,5]=compon[L,5]-a
ELSE
compon[L,4]=compon[L,4]+b
compon[L,5]=compon[L,5]+a-shc
ENDIF
compon[L,7]=dlc
compon[L,8]=shc
ELSEIF compon[L,6]=2
IF compon[L,2]='bot'
compon[L,4]=compon[L,4]+a
compon[L,5]=compon[L,5]+b-dlc
ELSE
compon[L,4]=compon[L,4]-a+shc
compon[L,5]=compon[L,5]+b-dlc
ENDIF
compon[L,7]=shc
compon[L,8]=dlc
ELSEIF compon[L,6]=3
IF compon[L,2]='bot'
compon[L,4]=compon[L,4]-b+dlc
compon[L,5]=compon[L,5]+a-shc
ELSE
compon[L,4]=compon[L,4]-b+dlc
compon[L,5]=compon[L,5]-a
ENDIF
compon[L,7]=dlc
compon[L,8]=shc
ENDIF
RETURN
//****************************************************
//Функция которая последовательно считывает pdf- файл кусками по 65000 байт (т.е. после анализа 1-го куска в 65000 байт считывается следующий и т.д.
FUNCTION READF() //чтение куска файла 65000 с текущей позиции
PRIVATE bait:=CHR(10),seek,contr,sost:=' ',buf
bufer=SPACE(65001)
contr:=FREAD(desc,@bufer,65000)
IF contr<65000
sost='end'
IF lastseek<65000
PROCENT()
ENDIF
ELSE
sost='noend'
buf=RIGHT(bufer,1000)
seek=64000+RAT(bait,buf)
bufer:=LEFT(bufer,seek)
lastseek:=FSEEK(desc,-(65000-seek),1)
PROCENT()
ENDIF
RETURN sost
//****************************************************
//Функция построчно анализирующая pdf- файл и берущая из него по определенным критериям названия и координаиы элементов
FUNCTION SEAR()
PRIVATE filesost,c1,c2,c3,c4,namecomp,ends:=0
@ 5,0 SAY 'Анализ файла:'
SETPOS(8,0)
FOR contin:=1 TO 2 //пойск контура платы
contin=2
filesost=READF() //загрузить первые 65000 pdf- файла
IF AT('COMP_DEF ',bufer)<>0
ends=1
ENDIF
c0=AT('{ANNOTATE',bufer)
IF c0<>0
bufer:=LTRIM(RIGHT(bufer,LEN(bufer)-(c0+5)))
FOR kol=1 TO 2 //поиск между ANNOTATE и COMP_DEF
kol=2
c0=AT('[Ly "KONTUR"]',bufer)
IF c0<>0
bufer:=LTRIM(RIGHT(bufer,LEN(bufer)-(c0+5)))
FOR kol1=1 TO 2
kol1=2
c0:=AT('{R ',bufer)
ver:=AT('[Ly "',bufer)
IF ver=0
ver:=66000
ENDIF
IF c0=0
IF AT('COMP_DEF ',bufer)<>0
ends=1
ELSEIF AT('Ly "',bufer)<>0
ends=1
ELSE
IF filesost<>'end'
filesost=READF()
kol1=1
ENDIF
ENDIF
ELSEIF c0>ver
ends=1
ELSE
kont=ALLTRIM(STROKA(c0+3))
ends=1
verkont=1 //переменная наличия контура
DISPOUT('Найден контур платы','b/gb')
koll:=SKONT(kont)
FOR kk:=1 TO LEN(koll)
AADD(kontur,({nil}))
kontur[kk]=koll[kk]
NEXT
ENDIF
NEXT
ELSE
c1=AT('{COMP_DEF ',bufer)
IF c1<>0
ends=1
ELSEIF ends=1
ends=1
ELSE
IF filesost<>'end'
filesost=READF()
kol=1
ENDIF
ENDIF
ENDIF
NEXT
ENDIF
IF filesost='end'
IF AT('{COMP_DEF ',bufer)=0
ends=1
ENDIF
ELSEIF ends=0
contin=1
ENDIF
NEXT
IF verkont=0
DISPOUT('Контур платы не обнаружен','r/gb')
ENDIF
private endc2,contin,powtor,slovo
namecomp:='not found'
c1=AT('{COMP_DEF ',bufer)
IF c1<>0 //поиск имени prt в bufer
slovo:=STROKA(c1)
namecomp=ALLTRIM(SUBSTR(slovo,11,15))
bufer:=LTRIM(RIGHT(bufer,LEN(bufer)-(c1+11)))
ENDIF
FOR contin:=1 TO 2
IF SHELK()=1
FINDCOMP()
ENDIF
c1=AT('{COMP_DEF ',bufer)
IF c1<>0 //поиск имени prt в оставшемся buferе
slovo=STROKA(c1)
namecomp=ALLTRIM(SUBSTR(slovo,11,15))
bufer:=LTRIM(RIGHT(bufer,LEN(bufer)-(c1+10)))
contin=1
ELSE
IF filesost<>'end'
filesost=READF()
contin=1
ELSE
contin=2
ENDIF
ENDIF
NEXT
PROCENT()
setpos(maxrow(),20)
dispout('OK. Анализ файла завершен.','g+/gb')
inkey(3)
tmz:=INSERTCOMP()
RETURN tmz
//****************************************************
FUNCTION STROKA(nomer) //выдел.подстроки из переменной //bufer,с указанной позиции (nomer)
PRIVATE txt,pos //до конца строки (символа CHR10)
txt:=RIGHT(bufer,LEN(bufer)+1-nomer)
pos=AT(CHR(10),txt)
txt=ALLTRIM(LEFT(txt,pos-2))
RETURN txt
//****************************************************
FUNCTION PROCENT() //функция построения процентной линии
PRIVATE laststr,laststolb
laststr:=ROW()
laststolb:=COL()
pnow=pnow+1
oldcol:=SETCOLOR()
IF pnow=1
str:=5
stolb:=15
parts:=ROUND(filelen/65000,0)
IF parts<2
parts=parts+1
ENDIF
procen:=ROUND(90/parts,0)
znak:=ROUND(45/parts,0)
stcolor:=setcolor('R+/gb')
mstolb:=stolb+49
WHILE stolb<mstolb
SETPOS(str,stolb)
??'|'
stolb=stolb+5
ENDDO
SETPOS(str,mstolb)
??'|'
stolb=15
setcolor(stcolor)
ENDIF
IF pnow=parts
znak:=60-stolb
ENDIF
IF pnow-1=parts
znak:=5
filelen=65000
pnow=0
ENDIF
SETPOS(str,stolb)
FOR k:=1 TO znak
IF stolb>65
EXIT
ENDIF
SETCOLOR('b/gb')
??'-'
stolb=stolb+1
SETPOS(4,57)
SETCOLOR('B/gb')
??((stolb-15)*2)
??'% '
SETPOS(str,stolb)
NEXT
SETPOS(laststr,laststolb)
SETCOLOR(oldcol)
RETURN
//****************************************************
FUNCTION SKONT(st0) //выделение координат контура (если он //обнаружен)
PRIVATE rez[0]
nom:=0
FOR k=1 to 2
p1:=AT(' ',st0)
IF p1=0
p1=AT('}',st0)
k=2
ELSE
k=1
ENDIF
nom:=nom+1
AADD(rez,({nil}))
rez[nom]=SUBSTR(st0,0,p1-1)
rez[nom]=(VAL(rez[nom])*koef)
st0=ALLTRIM(SUBSTR(st0,p1,60))
NEXT
RETURN rez
//****************************************************
FUNCTION SHELK(max) //проверка компонента на слой шелкографии
false:=0
FOR proo:=1 TO 2
proo=2
n1:=AT ('[Ly "SLK',bufer)
n2=AT('{I '+namecomp,bufer)
n3=AT('COMP_DEF ',bufer)
IF n3=0
n3=65500
ENDIF
IF n2=0
n2=n3
ENDIF
IF n1<>0
IF n1<n2
false:=1
ELSE
false:=0
ENDIF
ENDIF
IF n1=0
IF n2=65500
IF filesost<>'end'
filesost=READF()
proo=1
ENDIF
ENDIF
ENDIF
NEXT
RETURN false
//****************************************************
FUNCTION FINDCOMP() // поиск компонента с именем 'namecomp'
FOR kol:=1 TO 2
kol=2
c2=AT('{I ',bufer) //поиск {I 'имя prt'
c1=AT('{COMP_DEF ',bufer)
IF c2<>0 .AND. c1<>0 .AND. c2>c1
c2=0
ENDIF
IF c2<>0
kol=1 //после конца процедуры повторить поиск с тем-//же именем
nomcomp=nomcomp+1
?'Количство элементов на плате:',ALLTRIM(STR(nomcomp)),' '
setpos(row()-1,Col())
AADD(compon,{NIL,NIL,NIL,0,0,NIL,0,0,NIL}) //увеличение массива на один элемент
slovo:=STROKA(c2)
st0:=ALLTRIM(slovo)
st1:=AT('.',st0)
compon[nomcomp,1]=ALLTRIM(SUBSTR(st0,4,st1-4)) //выделение названия компонента
st1:=RAT(' ',slovo)
compon[nomcomp,9]:=(SUBSTR(st0,st1+1,30)) compon[nomcomp,6]:=0
compon[nomcomp,3]:=0
compon[nomcomp,2]='top'
bufer:=LTRIM(RIGHT(bufer,LEN(bufer)-(c2+3))) //отброс передней части буфера
FOR powtor:=1 TO 2
powtor=2
c2=AT('{I ',bufer) //определ.поз.следующ.компон.
c3=AT('{Ps "B"',bufer)
c4=AT('{Pl ',bufer)
c1=AT('{COMP_DEF ',bufer) //определ.след.названия
IF c1=0
c1=66000
ENDIF
c5=AT('{Ro' ,bufer)
c6=AT('{At H ' ,bufer)
IF c2<>0 .AND. c1<>0 .AND. c2<c1
endc2=c2
ELSEIF c1<>0 //определения конца области
endc2=c1 //поиска в пределах текущего
ELSE //компонента
endc2=65001
ENDIF
IF c3<>0 //определ.стороны
IF c3<endc2 //компон. в пределах текущего {I
compon[nomcomp,2]='bot'
ENDIF
ENDIF
IF c5<>0 //определ.стороны
IF c5<endc2 //компон. в пределах текущего {I
rot:=STROKA(c5)
compon[nomcomp,6]=VAL(SUBSTR(rot,5,20))
ENDIF
ENDIF
IF c6<>0 //определ.стороны
IF c6<endc2 //компон. в пределах текущего {I
rot:=STROKA(c6+6)
compon[nomcomp,3]=koef*VAL(ALLTRIM(rot))
ENDIF
ENDIF
IF c4<>0 опр.атриб.комп,если он расположен
IF c4<endc2 не дальше следующего {I-го)
slovo:=STROKA(c4)
compon[nomcomp,4]=ALLTRIM(SUBSTR(slovo,5,15))
ENDIF
ELSE
IF endc2=65001 если атриб. в данном буфере
IF filesost<>'end' не наидены и до конца буфера
filesost=READF() не встречается {I ,{COMP_DEF, тогда
powtor=1 подгрузить след. буфер и искать
ELSE в нем
powtor=2 если буфер последний то
идти дальше
ENDIF
ENDIF
ENDIF
NEXT
ENDIF
NEXT повторный поиск комп. в оставш. буфере с тем-же именем
RETURN
//****************************************************
FUNCTION POISK(name) поиск данных о новом элементе
PRIVATE razmx:={},razmy:={},st_org:=' ',st_razm:=' ',x:=0,y:=0,tp
CLS
fclose(desc)
pnow=0
setpos(0,0)
??'Поиск данных на элемент ',name,'...'
str=4
stolb=15
desc:=FOPEN('PDF\'+alltrim(name)+'.pdf')
IF FERROR()<>0
??'не найдены'
IF ASCAN(errfile,name+'.pdf')=0
AADD(errfile,name+'.pdf')
ENDIF
fclose(desc)
RETURN 'no'
ENDIF
FOR cont:=1 to 2
cont=2
IF READF()='end'
cont=2
ELSE
cont=1
ENDIF
c1=AT('{Org ',bufer)
IF c1<>0
st_org:=STROKA(c1+5)+'}'
ENDIF
c1=AT('{At H ',bufer)
IF c1<>0
tm1:=(STROKA(c1+6)+'}')
ttt:=SKONT(tm1)
hcomp:=ttt[1]
ENDIF
POISKRAZM(@x,@y)
NEXT
PROCENT()
st_org:=SKONT(st_org) координаты org
ASORT(razmx)
ASORT(razmy)
IF len(razmx)<1
razmx:={0}
ENDIF
IF len(razmy)<1
razmy:={0}
ENDIF
gabar[1]=ABS(razmx[LEN(razmx)]-razmx[1])
gabar[2]=ABS(razmy[LEN(razmy)]-razmy[1])
st_org[1]:=razmx[LEN(razmx)]-st_org[1]
st_org[2]:=st_org[2]-razmy[1]
??'найдены'
fclose(desc)
PROCENT()
RETURN st_org возвращает коорд. точки привязки
FUNCTION POISKRAZM(x,y)
private mpoisk:={{65000,'L'},{65000,'R'},{65000,'C'}}
mpoisk[1,1]=AT('{L ',bufer) поиск на графическом слое линий(L),прямо-
угольников(R),кругов(C)
mpoisk[2,1]=AT('{R ',bufer)
mpoisk[3,1]=AT('{C ',bufer)
cc:=0
For pk:=1 to len(mpoisk)
IF mpoisk[pk,1]=0
mpoisk[pk,1]=65000
ENDIF
Next
ASORT(mpoisk,,,{|px,py| px[1]<py[1]}) выбор графического элемента,ближайшего к началу файла
cc:=mpoisk[1,1]
IF cc<>65000 .AND. mpoisk[1,2]<>'C'
st_razm:=ALLTRIM(STROKA(cc+3))+'}'
bufer:=SUBSTR(bufer,cc+3,65000)
mas:=SKONT(st_razm)
FOR k:=1 TO LEN(mas)-1 STEP 2 выборка координат по Х
x=x+1
AADD(razmx,0)
razmx[x]:=mas[k]
IF LEN(razmx)>20
ASORT(razmx)
min1:=razmx[1]
max2:=razmx[LEN(razmx)]
razmx={min1,max2}
x=2
ENDIF
NEXT
FOR k:=2 TO LEN(mas) STEP 2 выборка координат по Y
y=y+1
AADD(razmy,0)
razmy[y]:=mas[k]
IF LEN(razmy)>20
ASORT(razmy)
min1:=razmy[1]
max2:=razmy[LEN(razmy)]
razmy={min1,max2}
y=2
ENDIF
NEXT
POISKRAZM(@x,@y)
ELSEIF cc<>65000 .AND. mpoisk[1,2]='C'
st_razm:=ALLTRIM(STROKA(cc+3))+'}'
bufer:=SUBSTR(bufer,cc+3,65000)
mas:=SKONT(st_razm)
IF len(mas)=3
st_tmp:=SKONT(st_org) координаты org
AADD(razmx,st_tmp[1]+(mas[1]+mas[3]/2))
AADD(razmy,st_tmp[2]+(mas[2]+mas[3]/2))
AADD(razmx,st_tmp[1]+mas[1]-mas[3]/2)
AADD(razmy,st_tmp[2]+mas[2]-mas[3]/2)
ENDIF
POISKRAZM(@x,@y)
ENDIF
RETURN
//****************************************************
5.Файл specif.prg содержит в себе текст подпрограммы, создающей перечень всех элементов, содержащихся на анализируемой плате, в виде стандартного dbf файла с именем xxxxx.dbf, где ххххх — имя pfd файла PCAD-а.
//***************************************************************
FUNCTION CreatSpec()
PRIVATE struct1 [4,4],nom, ns1:='name',ns2:='oboz',ns3:='kol',ns4:='con'
struct1[1,1]=ns1
struct1[1,2]="C"
struct1[1,3]=20
struct1[1,4]=0
struct1[2,1]=ns2
struct1[2,2]="C"
struct1[2,3]=25
struct1[2,4]=0
struct1[3,1]=ns3
struct1[3,2]="C"
struct1[3,3]=6
struct1[3,4]=0
struct1[4,1]=ns4
struct1[4,2]="C"
struct1[4,3]=10
struct1[4,4]=0
public nameper:=''
nameper:=alltrim(left(fname,at('.',fname)-1))+'.dbf'
DBCREATE(nameper,struct1) //
USE
//***************************************************************
append blank
FOR naz=1 to len(snaz)
REPLACE &ns1 WITH snaz[naz,1]
nzap:=recno()