
- •Введение
- •1.1 Краткий обзор современных методов проектирования бис.
- •1.2 Маршрут проектирования бис на основе бмк.
- •2.1 Постановка задачи размещения элементов матричных бис. Критерии размещения.
- •2.2 Основные алгоритмы начального размещения элементов бис.
- •2.3 Итерационные алгоритмы оптимизации размещения элементов бис на бмк.
- •3.1 Обоснование выбора алгоритма размещения и оптимизации размещения элементов на бмк.
- •3.2 Описание используемого алгоритма размещения и оптимизации размещения элементов на бмк.
- •5.1 Общие положения.
- •5.4 Расчет дополнительных капитальных вложений.
- •5.5 Данные для расчета.
- •6.1 Особенности работы с компьютером.
- •6.2 Болезни связанные с работой на компьютере.
- •6.3.2 Учет требований охраны труда при организации трудового процесса.
- •6.3.3 Планировка рабочего места.
- •6.3.4 Рабочая поза.
- •6.3.5 Требования к органам управления.
- •6.5 Воздействие излучения.
- •6.6 Основные выводы.
- •7.1 Технологический маршрут изготовления кмоп-ячейки бмк тц-5500.
- •Литература
Литература
-
Ю. М. Ильин, Т. Л. Короткова, Г. Д. Костина. Методические указания к курсовой работе и дипломному проектированию по расчету экономической эффективности от внедрения АСУТП и САПР. - М. : МИЭТ, 1987.
-
РМ Система автоматизированного проектирования изделий электронной техники. Методика определения экономической эффективности.
-
Методика расчета экономической эффективности программных средств вычислительной техники. - М. 1989.
-
Методика (основные положения) определения экономической эффективности использования в народном хозяйстве новой техники, изобретений и рационализаторских предложений. - М. 1987.
-
Г. Г. Казеннов, Е. В. Сердобинцев. Автоматизация проектирования БИС. Проектирование топологии матричных БИС. - М. : Высшая школа, 1990.
-
М. Ватанабэ и др. . Проектирование СБИС. - М. : Мир, 1988.
-
Л. А. Константинова, Н. М. Ларионов, В. М. Писеев. Методы и средства обеспечения безопасности технологических процессов на предприятиях электронной промышленности. - Учебное пособие по курсу “Охрана труда и окружающей среды”.
-
Под ред. Шилина А. С.. Охрана труда в машиностроении.
-
В. И. Каракеян, Л. А. Константинова, В. М. Писеев. Лабораторный практикум по курсу “Производственная и экологическая безопасность в микроэлектронике”.
П Р И Л О Ж Е Н И Я.
Приложение I: блок автоматического размещения и оптимизации.
//----------------------------------------------------------------------------
// СОДЕРЖАНИЕ:
// Функции доразмещения и оптимизации ячеек класса ZRazmWindow.
// ПРОГРАММИСТ:
// Кутепов Д.В.
//----------------------------------------------------------------------------
#include <owl\owlpch.h>
#include <classlib\stacks.h>
#include <math.h>
#include "razm.rh"
#include "global\global.h"
#include "global\nstbmk.h"
#include "global\nstyach.h"
#include "global\framemon.h"
#include "topolog\optrazm.h"
#include "topolog\razmwin.h"
#include "razm.h"
#include "statedlg.h"
#include "poleupr.h"
#include "polerazm.h"
#include "listfr.h"
//#define _OTLAD1
//#define _OTLAD2
//#define _OTLAD3
//----------------------------------------------------------------------------
void ZRazmWindow::CmDorazm() {
BOOL ok = TRUE;
if (!IsOkZapasPriv('v')) ok = FALSE;
if (!IsOkZapasPriv('z')) ok = FALSE;
if (!ok) return;
StateOptim = new ZStateOptimDialog(this);
StateOptim->Execute();
delete StateOptim;
StateOptim = 0;
}
void ZRazmWindow::Dorazm() {
CmKeyEsc();
AvtoRazmFr();
}
// Производит автоматическое размещение и оптимизацию фрагмента
void
ZRazmWindow::AvtoRazmFr()
{
float procent;
unsigned long BestSumma, PromSumma;
BOOL FlagRazmZ;
int KolNoRazm, KolNewNoRazm;
ZPsh *RodObj,*Obj,*Obj2;
ZPriv *RPr,*OldPriv;
TIStackAsList<ZPsh> RabStack;
TIArrayAsVector<ZPriv> *RabListXY,*RabListYX;
TIArrayAsVector<ZPsh> SpHranPsh(20, 0, 5);
TIArrayAsVector<ZPsh> SpHranPerifYach(10, 0, 5);
TIListImp<ZPriv> SpHranPriv;
TIListImp<ZPriv> SpHranPerifPriv;
const ZOptRazm& optRazm = *GlobalData->GetOptRazm();
// Формируем список ячеек для размещения: все неразмещенные ячейки в
// незафиксированных подфрагментах текущего фрагмента.
RabStack.OwnsElements(0);
SpHranPsh.OwnsElements(0);
SpHranPerifYach.OwnsElements(0);
RabStack.Push(PtrTekFr);
while (!RabStack.IsEmpty()) {
RodObj = RabStack.Pop();
if (!RodObj->IsFixed) {
for (int i=0; i < RodObj->SostavPsh->GetItemsInContainer(); i++) {
Obj = (*RodObj->SostavPsh)[i];
if (Obj->IsYach()) {
if (!Obj->PrivYach) {
ZNstYach nstYach(Obj->Name);
switch (nstYach.typ) {
case 'v': SpHranPsh.Add(Obj); break;
case 'z': SpHranPerifYach.Add(Obj); break;
default: PROG_LOV;
}
Obj->InMassiv=TRUE;
}
} else RabStack.Push(Obj);
}
}
}
# ifdef _OTLAD1
{
PrMsg("OTLAD1: Список ячеек типа 'v' для размещения.\n");
for (int i=0; i < SpHranPsh.GetItemsInContainer(); i++) {
PrMsg("i=%3d Name=%6s id=%s%s\n", i, SpHranPsh[i]->Name,
SpHranPsh[i]->IdGrup, SpHranPsh[i]->IdPsh);
}
PrMsg("OTLAD1: Список ячеек типа 'z' для размещения.\n");
for (i=0; i < SpHranPerifYach.GetItemsInContainer(); i++) {
PrMsg("i=%3d Name=%6s id=%s%s\n", i, SpHranPerifYach[i]->Name,
SpHranPerifYach[i]->IdGrup, SpHranPerifYach[i]->IdPsh);
}
}
# endif
// Проверяем, что связанные с данным фрагментом периферийные ячейки размещены.
TIArrayAsVectorIterator<ZPsh> itt(SpHranPsh);
FlagRazmZ=TRUE;
while (itt!=0 && FlagRazmZ){
Obj=itt++;
for (int kont=0; kont < Obj->KolKontPsh; kont++) {
TIListIteratorImp<ZPsh> iter2(*(Obj->SpIncidYach[kont]));
while (iter2!=0){
Obj2=iter2++;
ZNstYach nstYach(Obj2->Name);
if (nstYach.typ=='z' && Obj2->PrivYach==NULL) FlagRazmZ=FALSE;
}
}
}
BOOL flagContinue = TRUE;
if (!FlagRazmZ) {
char msg[512];
wsprintf(msg, GetModule()->LoadString(IDS_NO_ALL_PERIF_RAZM).c_str(), PtrTekFr->Name);
if (MessageBox(msg, GetModule()->GetName(), MB_YESNO | MB_ICONQUESTION) != IDYES) {
flagContinue = FALSE;
StateOptim->Destroy();
} else {
PoleRazm->UpdateWindow();
StateOptim->UpdateWindow();
StateOptim->SetFocus();
}
}
if (!flagContinue) return;
// Формируем список привязок для размещения и оптимизации:
// запланированная свободная область под фрагменты плюс область уже стоящих
// незафиксированных ячеек в незафиксированных фрагментах.
RabStack.Push(PtrTekFr);
while (!RabStack.IsEmpty()) {
RodObj = RabStack.Pop();
TIListIteratorImp<ZPriv> iter(*(RodObj->SostavPriv));
while (iter) {
RPr = iter++;
if (!RPr->Yach) {
switch (RPr->Typ) {
case 'v': SpHranPriv.Add(RPr); break;
case 'z': SpHranPerifPriv.Add(RPr); break;
default: PROG_LOV;
}
}
}
for (int i=0; i < RodObj->SostavPsh->GetItemsInContainer(); i++) {
Obj = (*RodObj->SostavPsh)[i];
if (Obj->IsYach()) {
if (Obj->PrivYach && !Obj->IsFixed && !RodObj->IsFixed) {
ZNstYach nstYach(Obj->Name, &TPoint(Obj->PrivYach->XPriv, Obj->PrivYach->YPriv));
for (int j=0; j< nstYach.kol_pokr_toch_priv; j++) {
RPr = PoleRazm->FindPrivKoord(nstYach.pokr_toch_priv[j].x, nstYach.pokr_toch_priv[j].y);
if (!RPr) PROG_LOV;
switch (RPr->Typ) {
case 'v': SpHranPriv.Add(RPr); break;
case 'z': SpHranPerifPriv.Add(RPr); break;
default: PROG_LOV;
}
}
}
} else RabStack.Push(Obj);
}
}
MaxX = 0;
MaxY = 0;
MinX = GlobalData->GetNstBMK()->gabarit_x_bmk;
MinY = GlobalData->GetNstBMK()->gabarit_y_bmk;
TIListIteratorImp<ZPriv> iter(SpHranPriv);
while (iter!=0) {
RPr=iter++;
if (RPr->XPriv > MaxX) MaxX = RPr->XPriv;
if (RPr->YPriv > MaxY) MaxY = RPr->YPriv;
if (RPr->XPriv < MinX) MinX = RPr->XPriv;
if (RPr->YPriv < MinY) MinY = RPr->YPriv;
}
RabListXY = new TIArrayAsVector<ZPriv>(20,0,5);
RabListYX = new TIArrayAsVector<ZPriv>(20,0,5);
TIListIteratorImp<ZPriv> rit2(SpHranPriv);
while (rit2) {
RPr = rit2++;
RabListXY->Add(RPr);
RabListYX->Add(RPr);
}
UporadSpXY(RabListXY, TRUE);
UporadSpXY(RabListYX, FALSE);
// Доразмещение периферийных ячеек фрагмента.
int tekSum, bestSum;
ZPriv* bestPriv;
if (SpHranPerifYach.GetItemsInContainer() >0) StateOptim->State->SetText("Размещение Z-яч.");
for (int i=0; i< SpHranPerifYach.GetItemsInContainer(); i++) {
Obj = SpHranPerifYach[i];
bestSum = INT_MAX;
bestPriv = 0;
TIListIteratorImp<ZPriv> iter(SpHranPerifPriv);
while (iter) {
RPr = iter++;
if (!RPr->Yach) {
tekSum = SummaDln(Obj, RPr, FALSE);
if (tekSum < bestSum) {
bestSum = tekSum;
bestPriv = RPr;
}
}
}
if (!bestPriv) PROG_LOV;
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
PoleRazm->RazmYach(DC, Obj, bestPriv, ZPsh::NoFixed);
}
// Оптимизация периферийных ячеек фрагмента.
GetSpYachOptim(SpHranPerifYach, 'z');
OptimizePerif(SpHranPerifYach, SpHranPerifPriv);
//
// Первоначальное размещение ячеек.
//
OldPriv = NULL;
KolNoRazm = 0;
if (SpHranPsh.GetItemsInContainer() > 0) {
StateOptim->State->SetText("Размещение.");
SortirSpiska(&SpHranPsh);
for (int i=0; i<SpHranPsh.GetItemsInContainer(); i++){
Obj=SpHranPsh[i];
PrivOdnojYach(&SpHranPriv, Obj, FALSE, OldPriv, RabListXY, RabListYX);
if (Obj->PrivYach!=NULL){
OldPriv = Obj->PrivYach;
Obj->BestPriv=Obj->PrivYach;
}
else KolNoRazm++;
if (PtrTekFr->KolYach >0) {
procent = ((float)PtrTekFr->KolRazmYach/ PtrTekFr->KolYach)*100;
SetTextState(StateOptim->ProcentRazm, procent);
}
}
}
TIArrayAsVectorIterator<ZPsh> iterr(SpHranPerifYach);
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
Obj->BestPriv=Obj->PrivYach;
}
//
// Оптимизация первоначального размещения.
//
GetSpYachOptim(SpHranPsh, 'v');
OldPriv = NULL;
BestSumma = ShowSummaSv(&SpHranPsh);
TIArrayAsVectorIterator<ZPsh> itr(SpHranPsh);
BOOL FlagFirst = TRUE;
for (unsigned long yy=1; yy <= optRazm.KolCiklOptim(); yy++){
SetTextState(StateOptim->TekKolOpt1, 0UL);
SetTextState(StateOptim->TekKolOpt2, 0UL);
SetTextState(StateOptim->TekKolOpt3, 0UL);
if (optRazm.IsOptimRerazm) {
StateOptim->State->SetText("Оптимизация 1.");
for (unsigned long y1=1; y1 <= optRazm.KolIterRerazm(); y1++){
// Снимаем все размещенные ячейки.
itr.Restart();
while (itr!=0){
Obj=itr++;
RPr=Obj->PrivYach;
if (RPr!=NULL){
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
Obj->OldPrivYach=RPr;
}
}
// После(!) снятия ячеек сортируем список ячеек для оптимизации.
if (FlagFirst){
FlagFirst=FALSE;
SortirSpiska(&SpHranPsh);
}
// Выполняем оптимизацию.
KolNewNoRazm = 0;
for (int i=0; i<SpHranPsh.GetItemsInContainer(); i++){
Obj=SpHranPsh[i];
PrivOdnojYach(&SpHranPriv,Obj,FALSE,OldPriv, RabListXY,RabListYX);
if (Obj->PrivYach!=NULL) OldPriv = Obj->PrivYach;
else KolNewNoRazm++;
procent=100.0* (i+1)/ SpHranPsh.GetItemsInContainer();
SetTextState(StateOptim->ProcentOptim, procent);
}
OptimizePerif(SpHranPerifYach, SpHranPerifPriv);
// Запоминаем лучшее размещение.
PromSumma= ShowSummaSv(&SpHranPsh);
if ((KolNewNoRazm < KolNoRazm) || (KolNewNoRazm == KolNoRazm && PromSumma < BestSumma)) {
KolNoRazm = KolNewNoRazm;
BestSumma = PromSumma;
itr.Restart();
while (itr!=0){
Obj=itr++;
Obj->BestPriv=Obj->PrivYach;
}
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
Obj->BestPriv=Obj->PrivYach;
}
}
SetTextState(StateOptim->TekKolOpt1, y1);
}
}
if (optRazm.IsOptimLocalMove){
StateOptim->State->SetText("Оптимизация 2.");
for (unsigned long y1=1; y1 <= optRazm.KolIterLocalMove(); y1++){
int i=0;
KolNewNoRazm = 0;
itr.Restart();
while (itr!=0){
Obj=itr++;
i++;
RPr=Obj->PrivYach;
if (RPr!=NULL){
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
Obj->OldPrivYach=Obj->PrivYach;
PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
PrivOdnojYach(&SpHranPriv,Obj,FALSE,OldPriv,RabListXY,RabListYX);
if (Obj->PrivYach!=NULL) OldPriv = Obj->PrivYach;
else KolNewNoRazm++;
}
procent=100.0* i/ SpHranPsh.GetItemsInContainer();
SetTextState(StateOptim->ProcentOptim, procent);
}
OptimizePerif(SpHranPerifYach, SpHranPerifPriv);
// Запоминаем лучшее размещение.
PromSumma= ShowSummaSv(&SpHranPsh);
if ((KolNewNoRazm < KolNoRazm) || (KolNewNoRazm == KolNoRazm && PromSumma < BestSumma)) {
KolNoRazm = KolNewNoRazm;
BestSumma = PromSumma;
itr.Restart();
while (itr!=0){
Obj=itr++;
Obj->BestPriv=Obj->PrivYach;
}
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
Obj->BestPriv=Obj->PrivYach;
}
}
SetTextState(StateOptim->TekKolOpt2, y1);
}
}
if (optRazm.IsOptimSilAlgor){
StateOptim->State->SetText("Оптимизация 3.");
for (unsigned long y1=1; y1 <= optRazm.KolIterSilAlgor(); y1++){
Optimize3(&SpHranPsh, &SpHranPriv);
OptimizePerif(SpHranPerifYach, SpHranPerifPriv);
// Запоминаем лучшее размещение.
PromSumma= ShowSummaSv(&SpHranPsh);
if (PromSumma < BestSumma){
BestSumma = PromSumma;
itr.Restart();
while (itr!=0){
Obj=itr++;
Obj->BestPriv=Obj->PrivYach;
}
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
Obj->BestPriv=Obj->PrivYach;
}
}
SetTextState(StateOptim->TekKolOpt3, y1);
}
}
SetTextState(StateOptim->TekKolCikl, yy);
} // yy
RabListXY->Flush(TShouldDelete::NoDelete);
RabListYX->Flush(TShouldDelete::NoDelete);
delete RabListXY;
delete RabListYX;
// Формируем окончательное размещение.
if (SpHranPsh.GetItemsInContainer() > 0){
TIArrayAsVectorIterator<ZPsh> itp(SpHranPsh);
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
while (itp!=0){
Obj=itp++;
if (Obj->PrivYach !=NULL) PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
Obj->NomMassiv=0;
Obj->KolSvias=0;
}
itp.Restart();
while (itp!=0){
Obj=itp++;
if (Obj->BestPriv!=NULL) PoleRazm->RazmYach(DC, Obj, Obj->BestPriv, ZPsh::NoFixed);
}
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
if (Obj->PrivYach !=NULL) PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
Obj->NomMassiv=0;
Obj->KolSvias=0;
}
iterr.Restart();
while (iterr!=0){
Obj=iterr++;
if (Obj->BestPriv!=NULL) PoleRazm->RazmYach(DC, Obj, Obj->BestPriv, ZPsh::NoFixed);
Obj->BestPriv =0;
}
ShowSummaSv(&SpHranPsh);
itp.Restart();
while (itp!=0){
Obj=itp++;
Obj->InMassiv=FALSE;
Obj->BestPriv =0;
Obj->OldPrivYach =0;
}
}
PoleUpr->PaintSpYach();
PoleUpr->PaintSpFr();
StateOptim->State->SetText("Процесс завершен.");
}
// Формирует список ячеек для оптимизации: все незафиксированные ячейки
// в незафиксированных фрагментах.
void ZRazmWindow::GetSpYachOptim(TIArrayAsVector<ZPsh>& spYach, int typYach)
{
TIStackAsList<ZPsh> rabStack;
ZPsh *rodObj, *obj;
rabStack.OwnsElements(0);
spYach.Flush();
rabStack.Push(PtrTekFr);
while (!rabStack.IsEmpty()) {
rodObj = rabStack.Pop();
if (!rodObj->IsFixed) {
for (int i=0; i < rodObj->SostavPsh->GetItemsInContainer(); i++) {
obj = (*rodObj->SostavPsh)[i];
if (obj->IsYach()) {
if (obj->PrivYach && !obj->IsFixed && obj->PrivYach->Typ==typYach) {
spYach.Add(obj);
obj->BestPriv = obj->PrivYach;
obj->OldPrivYach = obj->PrivYach;
obj->InMassiv = TRUE;
}
} else rabStack.Push(obj);
}
}
}
# ifdef _OTLAD2
{
PrMsg("OTLAD2: Список ячеек типа '%c' для оптимизации.\n", typYach);
for (int i=0; i < spYach.GetItemsInContainer(); i++) {
PrMsg("i=%3d Name=%6s id=%s%s\n", i, spYach[i]->Name, spYach[i]->IdGrup, spYach[i]->IdPsh);
}
}
# endif
}
// Возвращает сумму длин для ячейки SelYach в точке APriv
// ( FlagAllSum=TRUE если вычисляется сумма длин связей нескольких
// связанных друг с другом ячеек).
long ZRazmWindow::SummaDln(ZPsh *SelYach, ZPriv* APriv, BOOL FlagAllSum)
{
struct YACH_CEP { // Ячейка, подключенная к цепи.
int NomPriv; // Номер привязки ячейки.
BOOL FlagSoed; // Флаг соединения ячейки.
};
struct CENTR_PRIV { // Координаты центра привязки.
ZPriv* Priv; // Привязка ячейки.
float Koef; // Коэффициент учета предыдущего размещения.
int x; // Координата Х.
int y; // Координата У.
};
// Коэффициент учета предыдущего размещения (от 0 до 1, лучше 0.4-0.6).
float koefPredRazm = 0.4;
YACH_CEP* YachCep;
CENTR_PRIV* Centr;
int KolRazmYachCep,KolSoedYachCep,NomSoed,NomNeSoed,Rasst,MinRasst;
int kont,kol,kol1,i,j,nom,KolPriv,PrivSoed,PrivNeSoed,InMassiv;
long DlSvyaz=0;
ZPriv *ptr1,*ptr2,*RPrYach;
ZPsh* obj;
kol=kol1=0;
for (kont=0; kont<SelYach->KolKontPsh; kont++) {
kol=max(kol, SelYach->SpIncidYach[kont]->GetItemsInContainer());
kol1+=SelYach->SpIncidYach[kont]->GetItemsInContainer();
}
SelYach->KolSvias=kol1;
kol++; kol1++;
YachCep = new YACH_CEP[kol];
Centr = new CENTR_PRIV[kol1];
Centr[0].Priv=APriv;
Centr[0].x = (APriv->Rect.left+APriv->Rect.right) /2;
Centr[0].y = (APriv->Rect.top +APriv->Rect.bottom)/2;
Centr[0].Koef =1;
KolPriv = 1;
for (kont=0; kont<SelYach->KolKontPsh; kont++) {
YachCep[0].NomPriv =0;
YachCep[0].FlagSoed=TRUE;
KolRazmYachCep=1;
InMassiv=1;
TIListIteratorImp<ZPsh> iter(*(SelYach->SpIncidYach[kont]));
while (iter!=0) {
obj=iter++;
if (obj->PrivYach!=NULL || obj->OldPrivYach!=NULL) {
nom=-1;
if (obj->PrivYach!=NULL) RPrYach=obj->PrivYach;
else RPrYach=obj->OldPrivYach;
for (i=0; i<KolPriv; i++) {
if (Centr[i].Priv==RPrYach) {
nom=i; break;
}
}
if (obj->InMassiv==TRUE) InMassiv++;
if (nom==-1) {
Centr[KolPriv].Priv=RPrYach;
Centr[KolPriv].x=(RPrYach->Rect.left+RPrYach->Rect.right)/2;
Centr[KolPriv].y=(RPrYach->Rect.top+RPrYach->Rect.bottom)/2;
if (obj->PrivYach!=NULL) Centr[KolPriv].Koef= 1;
else Centr[KolPriv].Koef= koefPredRazm;
nom=KolPriv;
KolPriv++;
}
YachCep[KolRazmYachCep ].NomPriv=nom;
YachCep[KolRazmYachCep++].FlagSoed=FALSE;
}
}
KolSoedYachCep=1;
while (KolSoedYachCep< KolRazmYachCep) {
NomSoed=NomNeSoed=-1;
MinRasst=30000;
for (i=0; i<KolRazmYachCep; i++) {
if (!YachCep[i].FlagSoed) continue;
for (j=0; j<KolRazmYachCep; j++) {
if (YachCep[j].FlagSoed) continue;
ptr1=Centr[YachCep[i].NomPriv].Priv;
ptr2=Centr[YachCep[j].NomPriv].Priv;
Rasst=Centr[YachCep[i].NomPriv].Koef*
Centr[YachCep[j].NomPriv].Koef* (abs(ptr1->XPriv-ptr2->XPriv)+
abs(ptr1->YPriv-ptr2->YPriv));
if (Rasst<MinRasst) {
MinRasst=Rasst;
NomSoed =i;
NomNeSoed=j;
}
}
}
if (NomSoed!=-1 && NomNeSoed!=-1) {
PrivSoed =YachCep[NomSoed ].NomPriv;
PrivNeSoed=YachCep[NomNeSoed].NomPriv;
Centr[PrivSoed ].x+=2;
Centr[PrivSoed ].y+=2;
Centr[PrivNeSoed].x+=2;
Centr[PrivNeSoed].y+=2;
YachCep[NomNeSoed].FlagSoed=TRUE;
if (!FlagAllSum)
DlSvyaz+=ceil(Centr[PrivSoed].Koef*Centr[PrivNeSoed].Koef* (abs((Centr[PrivSoed ].Priv)->XPriv-(Centr[PrivNeSoed].Priv)->XPriv)+
abs((Centr[PrivSoed ].Priv)->YPriv-(Centr[PrivNeSoed].Priv)->YPriv)));
else
DlSvyaz+=ceil((Centr[PrivSoed].Koef*Centr[PrivNeSoed].Koef* (abs((Centr[PrivSoed ].Priv)->XPriv-(Centr[PrivNeSoed].Priv)->XPriv)+
abs((Centr[PrivSoed ].Priv)->YPriv-(Centr[PrivNeSoed].Priv)->YPriv)))/ InMassiv);
KolSoedYachCep++;
}
}
}
delete[] YachCep;
delete[] Centr;
return DlSvyaz;
}
static BOOL SravnKoordPriv(ZPriv* priv1, ZPriv* priv2, BOOL PrizXY) {
if (PrizXY)
return priv1->XPriv > priv2->XPriv || (priv1->XPriv == priv2->XPriv && priv1->YPriv > priv2->YPriv);
else
return priv1->YPriv > priv2->YPriv || (priv1->YPriv == priv2->YPriv && priv1->XPriv > priv2->XPriv);
}
// Сортирует список привязок по XY или YX (по возрастанию координат).
// PrizXY=TRUE если сортировка по XY.
void
ZRazmWindow::UporadSpXY(TIArrayAsVector<ZPriv>* arrayPriv, BOOL PrizXY)
{
ZPriv* tmp;
int is, js, zazor;
for (zazor = arrayPriv->GetItemsInContainer()/2; zazor >0; zazor /=2) {
for (is=zazor; is< arrayPriv->GetItemsInContainer(); is++) {
for (js = is - zazor; js >= 0 && SravnKoordPriv((*arrayPriv)[js], (*arrayPriv)[js+zazor], PrizXY); js -= zazor) {
tmp = (*arrayPriv)[js];
(*arrayPriv)[js] = (*arrayPriv)[js+zazor];
(*arrayPriv)[js+zazor] = tmp;
}
}
}
# ifdef _OTLAD3
{
PrMsg("OTLAD3: Список упорядоченных привязок, PrizXY = %d.\n", PrizXY);
for (int i=0; i< arrayPriv->GetItemsInContainer(); i++) {
PrMsg("i=%4d x=%5d y=%5d\n", i, (*arrayPriv)[i]->XPriv,(*arrayPriv)[i]->YPriv);
}
}
# endif
}
// Проверяет, что под фрагмент выделено достаточно привязок заданного типа.
BOOL
ZRazmWindow::IsOkZapasPriv(int typePriv)
{
TIStackAsList<ZPsh> RabStack;
ZPsh *RodObj, *Obj;
ZPriv *tmpPriv;
int kolPrivSvob=0, kolPrivNeobhod=0;
RabStack.OwnsElements(0);
RabStack.Push(PtrTekFr);
while (!RabStack.IsEmpty()) {
RodObj = RabStack.Pop();
TIListIteratorImp<ZPriv> iter(*(RodObj->SostavPriv));
while (iter) {
tmpPriv = iter++;
if (!tmpPriv->Yach && tmpPriv->Typ == typePriv) kolPrivSvob++;
}
for (int i=0; i < RodObj->SostavPsh->GetItemsInContainer(); i++) {
Obj = (*RodObj->SostavPsh)[i];
if (Obj->IsYach()) {
if (!Obj->PrivYach) {
switch (typePriv) {
case 'v':
kolPrivNeobhod += Obj->KolVFakt; break;
case 'z':
kolPrivNeobhod += Obj->KolZFakt; break;
default: PROG_LOV;
}
}
} else RabStack.Push(Obj);
}
}
BOOL ok = TRUE;
if (kolPrivNeobhod > kolPrivSvob) {
ok = FALSE;
char msg[512];
wsprintf(msg, GetModule()->LoadString(IDS_UNDER_FR_SMALL_PRIV).c_str(),PtrTekFr->Name,
kolPrivNeobhod - kolPrivSvob, toupper(typePriv));
MessageBox(msg, GetModule()->GetName(), MB_OK | MB_ICONSTOP);
}
return ok;
}
// Расчет силы связности с областью А для всех элементов списка.
int
ZRazmWindow::MSilaF(TIArrayAsVector<ZPsh> *ASp)
{
int A,kol=0;
ZPsh *obj,*obj2;
float SilaF;
int xxx=0;
TIArrayAsVectorIterator<ZPsh> iter(*ASp);
while (iter!=0) {
obj=iter++;
if (!obj->NomMassiv) {
kol;
SilaF=0;
xxx++;
for (int kont=0; kont < obj->KolKontPsh; kont++) {
A=0;
TIListIteratorImp<ZPsh> iter2(*(obj->SpIncidYach[kont]));
iter2.Restart();
kol=obj->SpIncidYach[kont]->GetItemsInContainer();
for (int daff=0; daff< kol; daff++) {
obj2=iter2++;
if (obj2->NomMassiv==1 || obj2->PrivYach!=0) A++;
}
if (A>0) {
if (kol-A) SilaF+= 1/(kol-A)*(obj->KolVFakt);
else SilaF+= 2* obj->KolVFakt;
}
}
obj->SilaF=SilaF;
}
}
return xxx;
}
// Возвращает элемент с максимальной связностью с областью А.
ZPsh*
ZRazmWindow::MaxSila(TIArrayAsVector<ZPsh> *ASp,ZPsh *RodPshPred)
{
ZPsh *RabFr,*obj;
RabFr=NULL;
float MSila=-1000;
TIArrayAsVectorIterator<ZPsh> iter(*ASp);
iter.Restart();
while (iter!=0) {
obj=iter++;
if (!obj->NomMassiv) {
if ((MSila < obj->SilaF) || (MSila==obj->SilaF && obj->PtrRoditPsh==RodPshPred)) {
RabFr=obj;
MSila=obj->SilaF;
}
}
}
return RabFr;
}
// Устанавливает порядок размещения ячеек.
void
ZRazmWindow::SortirSpiska(TIArrayAsVector<ZPsh> *BazArray)
{
ZPsh *Obj1,*RodPsh;
TIArrayAsVector<ZPsh> *RabAr;
RabAr = new TIArrayAsVector<ZPsh>(20,0,5);
Obj1=(*BazArray)[0];
RodPsh = PtrTekFr;
while (Obj1!=NULL) {
MSilaF(BazArray);
Obj1=MaxSila(BazArray,RodPsh);
if (Obj1!=NULL){
Obj1->NomMassiv=1;
RabAr->Add(Obj1);
RodPsh=Obj1->PtrRoditPsh;
}
}
BazArray->Flush(TShouldDelete::NoDelete);
TIArrayAsVectorIterator<ZPsh> iter(*RabAr);
while (iter!=0) {
Obj1=iter++;
Obj1->NomMassiv=0;
BazArray->Add(Obj1);
}
RabAr->Flush(TShouldDelete::NoDelete);
delete RabAr;
}
// Выполняет привязку одной ячейки.
void
ZRazmWindow::PrivOdnojYach(TIListImp<ZPriv> *BazList, ZPsh *Yach, BOOL Zamesch, ZPriv *OldPriv,
TIArrayAsVector<ZPriv> *RabListXY, TIArrayAsVector<ZPriv> *RabListYX)
{
if (Yach->PrivYach) return;
ZPriv *RPr2,*RPr3,*RPr;
int minsum = 30000;
int SummaDl,Ogran;
int NomInArr;
BOOL FlagModified,FlModBlok;
if (Zamesch) Ogran=2;
else Ogran=1;
if (OldPriv!=NULL) RPr = OldPriv;
else {
RPr = (*RabListXY)[0];
OldPriv=RPr;
}
FlagModified=TRUE;
while (FlagModified) {
FlagModified=FALSE;
RPr2=RPr;
FlModBlok=TRUE;
while (FlModBlok){ // X++ Y++
FlModBlok = FALSE;
NomInArr=RabListXY->Find(RPr2);
if (NomInArr< RabListXY->GetItemsInContainer()-1) {
RPr3=(*RabListXY)[NomInArr+1];
if (RPr2->XPriv != RPr3->XPriv) {
NomInArr=RabListYX->Find(RPr2);
if (NomInArr< RabListYX->GetItemsInContainer()-1)
RPr3=(*RabListYX)[NomInArr+1];
else RPr3=NULL;
}
if (RPr3!=NULL){
SummaDl=SummaDln(Yach,RPr3,FALSE);
if (SummaDl<minsum) {
FlModBlok = TRUE;
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr3->XPriv,RPr3->YPriv, RPr3, BazList)){
minsum=SummaDl;
RPr=RPr3;
FlagModified=TRUE;
}
RPr2=RPr3;
}
}
}
}
RPr2=RPr;
FlModBlok=TRUE;
while (FlModBlok){ // Y++ X--
FlModBlok = FALSE;
NomInArr=RabListYX->Find(RPr2);
if (NomInArr< RabListYX->GetItemsInContainer()-1) {
RPr3=(*RabListYX)[NomInArr+1];
if (RPr2->YPriv != RPr3->YPriv) {
NomInArr=RabListXY->Find(RPr2);
if (NomInArr>0) RPr3=(*RabListXY)[NomInArr-1];
else RPr3=NULL;
}
if (RPr3!=NULL){
SummaDl=SummaDln(Yach,RPr3,FALSE);
if (SummaDl<minsum) {
FlModBlok = TRUE;
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr3->XPriv,RPr3->YPriv, RPr3, BazList)){
minsum=SummaDl;
RPr=RPr3;
FlagModified=TRUE;
}
RPr2=RPr3;
}
}
}
}
RPr2=RPr;
FlModBlok=TRUE;
while (FlModBlok){ // X-- Y--
FlModBlok = FALSE;
NomInArr=RabListXY->Find(RPr2);
if (NomInArr>0) {
RPr3=(*RabListXY)[NomInArr-1];
if (RPr2->XPriv != RPr3->XPriv) {
NomInArr=RabListYX->Find(RPr2);
if (NomInArr>0) RPr3=(*RabListYX)[NomInArr-1];
else RPr3=NULL;
}
if (RPr3!=NULL){
SummaDl=SummaDln(Yach,RPr3,FALSE);
if (SummaDl<minsum) {
FlModBlok = TRUE;
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr3->XPriv,RPr3->YPriv, RPr3, BazList)){
minsum=SummaDl;
RPr=RPr3;
FlagModified=TRUE;
}
RPr2=RPr3;
}
}
}
}
RPr2=RPr;
FlModBlok=TRUE;
while (FlModBlok){ // Y-- X++
FlModBlok = FALSE;
NomInArr=RabListYX->Find(RPr2);
if (NomInArr>0) {
RPr3=(*RabListYX)[NomInArr-1];
if (RPr2->YPriv != RPr3->YPriv) {
NomInArr=RabListXY->Find(RPr2);
if (NomInArr< RabListXY->GetItemsInContainer()-1)
RPr3=(*RabListXY)[NomInArr+1];
else RPr3=NULL;
}
if (RPr3!=NULL){
SummaDl=SummaDln(Yach,RPr3,FALSE);
if (SummaDl<minsum) {
FlModBlok = TRUE;
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr3->XPriv,RPr3->YPriv, RPr3, BazList)){
minsum=SummaDl;
RPr=RPr3;
FlagModified=TRUE;
}
RPr2=RPr3;
}
}
}
}
} // FlagModified
int x, y;
int dx, dy;
GetDxDyPriv(dx, dy);
int Delta=1, maxDelta=3;
RPr3=NULL;
if (ProvNalosh(Yach,RPr)>=Ogran) {
minsum=30000;
BOOL FlEnd = FALSE;
while ((RPr3==NULL && !FlEnd) || Delta <= maxDelta){
for (x= RPr->XPriv - Delta*dx; x<= RPr->XPriv + Delta*dx; x+=dx){
RPr2=PoleRazm->FindPrivKoord(x, RPr->YPriv - Delta*dy);
if (RPr2!=NULL){
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr2->XPriv,RPr2->YPriv, Rpr2,BazList)){
if (ProvNalosh(Yach,RPr2)<Ogran) {
SummaDl=SummaDln(Yach,RPr2,FALSE);
if (SummaDl<minsum) {
minsum=SummaDl;
RPr3=RPr2;
}
}
}
}
}
for (x= RPr->XPriv - Delta*dx; x<= RPr->XPriv + Delta*dx; x+=dx){
RPr2=PoleRazm->FindPrivKoord(x, RPr->YPriv + Delta*dy);
if (RPr2!=NULL){
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr2->XPriv,RPr2->YPriv, RPr2, BazList)){
if (ProvNalosh(Yach,RPr2)<Ogran) {
SummaDl=SummaDln(Yach,RPr2,FALSE);
if (SummaDl<minsum) {
minsum=SummaDl;
RPr3=RPr2;
}
}
}
}
}
for (y= RPr->YPriv - (Delta-1)*dy; y<= RPr->YPriv + (Delta-1)*dy; y+=dy){
RPr2=PoleRazm->FindPrivKoord(RPr->XPriv - Delta*dx, y);
if (RPr2!=NULL){
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr2->XPriv, RPr2->YPriv, RPr2, BazList)){
if (ProvNalosh(Yach,RPr2)<Ogran) {
SummaDl=SummaDln(Yach,RPr2,FALSE);
if (SummaDl<minsum) {
minsum=SummaDl;
RPr3=RPr2;
}
}
}
}
}
for (y= RPr->YPriv - (Delta-1)*dy; y<= RPr->YPriv + (Delta-1)*dy; y+=dy){
RPr2=PoleRazm->FindPrivKoord(RPr->XPriv + Delta*dx, y);
if (RPr2!=NULL){
if (!PoleRazm->ErrorAvtPrivYach(Yach, RPr2->XPriv,RPr2->YPriv, RPr2, BazList)){
if (ProvNalosh(Yach,RPr2)<Ogran) {
SummaDl=SummaDln(Yach,RPr2,FALSE);
if (SummaDl<minsum) {
minsum=SummaDl;
RPr3=RPr2;
}
}
}
}
}
Delta++;
if (RPr->XPriv - Delta*dx < MinX && RPr->XPriv + Delta*dx > MaxX &&
RPr->YPriv - Delta*dy < MinY && RPr->YPriv + Delta*dy > MaxY)
FlEnd = TRUE;
} // while
if (RPr3!=NULL) RPr=RPr3;
else RPr=NULL;
} // ProvNalosh
if (RPr!=NULL) {
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
PoleRazm->RazmYach(DC, Yach, RPr, ZPsh::NoFixed);
Yach->OldPrivYach=NULL;
}
}
// Проверка наложения ячеек.
int
ZRazmWindow::ProvNalosh(ZPsh *PrPsh,ZPriv *PrPriv)
{
int situation=0;
ZPriv *RabPriv;
ZNstYach nstYach(PrPsh->Name, &TPoint(PrPriv->XPriv, PrPriv->YPriv));
for (int i=0; i< nstYach.kol_pokr_toch_priv; i++) {
RabPriv = PoleRazm->FindPrivKoord(nstYach.pokr_toch_priv[i].x, nstYach.pokr_toch_priv[i].y);
if (RabPriv!=NULL) {
if (RabPriv->Yach!=NULL) situation=2;
}
else situation=3;
}
return situation;
}
ZPriv*
ZRazmWindow::Mediana(ZPsh *Obj)
{
struct RectObl {
int XMin;
int YMin;
int XMax;
int YMax;
};
int kol,Xcp,Ycp,N;
ZPriv *RPr,*RabPriv;
ZPsh *PromObj;
RectObl Oblast;
RPr=NULL;
kol=Obj->KolKontPsh;
Xcp=0;
Ycp=0;
N=0;
for (int i=0;i<kol;i++){
Oblast.XMax= 0;
Oblast.YMax= 0;
Oblast.XMin= GlobalData->GetNstBMK()->gabarit_x_bmk;
Oblast.YMin= GlobalData->GetNstBMK()->gabarit_y_bmk;
TIListIteratorImp<ZPsh> irr(*(Obj->SpIncidYach[i]));
while (irr!=0){
PromObj=irr++;
if (PromObj->PrivYach!=NULL) RabPriv=PromObj->PrivYach;
else RabPriv=PromObj->OldPrivYach;
if (RabPriv!=NULL){
if (Oblast.XMax< RabPriv->XPriv) Oblast.XMax= RabPriv->XPriv;
if (Oblast.YMax< RabPriv->YPriv) Oblast.YMax= RabPriv->YPriv;
if (Oblast.XMin> RabPriv->XPriv) Oblast.XMin= RabPriv->XPriv;
if (Oblast.YMin> RabPriv->YPriv) Oblast.YMin= RabPriv->YPriv;
}
}
if (Oblast.XMax>=Oblast.XMin) {
Xcp+=Oblast.XMax+Oblast.XMin;
Ycp+=Oblast.YMax+Oblast.YMin;
N+=2;
}
}
if (N!=0){
Xcp= ceil(Xcp/N);
Ycp= ceil(Ycp/N);
RPr= PoleRazm->FindNearPriv(Xcp, Ycp);
}
return RPr;
}
// Оптимизация N3.
void
ZRazmWindow::Optimize3(TIArrayAsVector<ZPsh> *RabAr, TIListImp<ZPriv> *RabList)
{
ZPsh *Obj,*OkPsh;
int iii,InCont;
float procent;
ZPriv *HranPriv,*OkPriv;
TIArrayAsVectorIterator<ZPsh> itr(*RabAr);
iii=0;
InCont=RabAr->GetItemsInContainer();
while (itr!=0){
Obj=itr++;
iii++;
OkPsh=Obmen(Obj,RabList);
if (OkPsh!=NULL) {
if (OkPsh==Obj) OkPriv=OkPsh->OldPrivYach;
else OkPriv=OkPsh->OldPrivYach;
}
else OkPriv=NULL;
if (OkPriv!=NULL){
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
HranPriv=Obj->PrivYach;
PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
if (OkPsh!=NULL && OkPsh!=Obj){
PoleRazm->DeleteRazmYach(DC,OkPsh->PrivYach,FALSE);
PoleRazm->RazmYach(DC, OkPsh, HranPriv, ZPsh::NoFixed);
}
PoleRazm->RazmYach(DC, Obj, OkPriv, ZPsh::NoFixed);
}
procent=100.0*iii/InCont;
SetTextState(StateOptim->ProcentOptim, procent);
}
}
ZPsh*
ZRazmWindow::Obmen(ZPsh *First,TIListImp<ZPriv> *RabList)
{
ZPsh *HranPsh,*OkPsh;
int Nalosh,OldSum,NewSum,DopSum,MinSum;
ZPriv *RPr,*RPriv,*NachPriv,*OkPriv,*FirstPriv;
OkPriv=NULL;
OkPsh=NULL;
MinSum=30000;
int dx, dy;
GetDxDyPriv(dx, dy);
if (First->PrivYach!=NULL){
RPriv=Mediana(First);
FirstPriv=First->PrivYach;
OldSum=SummaDln(First,FirstPriv,FALSE);
if (RPriv!=NULL){
for (int i=RPriv->XPriv - dx; i<= RPriv->XPriv + dx; i+=dx){
for (int j=RPriv->YPriv - dy; j<= RPriv->YPriv + dy; j+=dy){
RPr=PoleRazm->FindPrivKoord(i,j);
if (RPr!=NULL){
// Поднимаем 1 ячейку с 1 привязки
RazmOrDelPsh(First,FirstPriv,FALSE);
Nalosh=ProvNalosh(First,RPr);
if (Nalosh==2){
if (RPr->Yach!=NULL){
NachPriv= PoleRazm->GetNachPriv(RPr);
HranPsh=NachPriv->Yach;
DopSum=SummaDln(HranPsh,NachPriv,FALSE);
// Поднимаем 2 ячейку со 2 привязки
RazmOrDelPsh(HranPsh,NachPriv,FALSE);
if (ProvNalosh(First,RPr)==0 && !PoleRazm->ErrorAvtPrivYach(First,RPr->XPriv, RPr->YPriv, RPr, RabList)){
//Опускаем 1 на 2
RazmOrDelPsh(First,RPr,TRUE);
if (ProvNalosh(HranPsh,FirstPriv)==0 && !PoleRazm->ErrorAvtPrivYach(HranPsh, FirstPriv->XPriv,
FirstPriv->YPriv, FirstPriv, RabList)){
NewSum= SummaDln(HranPsh,FirstPriv,FALSE)+SummaDln(First,RPr,FALSE);
if (OldSum+DopSum>NewSum && MinSum>NewSum) {
MinSum=NewSum;
OkPriv=RPr;
OkPsh=HranPsh;
}
}
//Поднимаем 1 с 2
RazmOrDelPsh(First,RPr,FALSE);
}
//Опускаем 2 на 2
RazmOrDelPsh(HranPsh,NachPriv,TRUE);
}
}
else {
if (!(PoleRazm->ErrorAvtPrivYach(First, RPr->XPriv,RPr->YPriv, RPr, RabList)) &&
SummaDln(First,RPr,FALSE)< OldSum) {
OkPriv=RPr;
OkPsh=NULL;
MinSum=0;
}
}
//Опускаем 1 на 1
RazmOrDelPsh(First,FirstPriv,TRUE);
}
} // for j
} // for i
}
}
if (OkPriv!=NULL){
if (OkPsh==NULL) OkPsh=First;
OkPsh->OldPrivYach=OkPriv;
}
return OkPsh;
}
void
ZRazmWindow::RazmOrDelPsh(ZPsh *RabPsh,ZPriv *RabPriv,BOOL FlRazm)
{
ZPriv *tmpPriv;
if (FlRazm==TRUE){
RabPriv->Yach=RabPsh;
RabPsh->PrivYach=RabPriv;
RabPriv->FlagNachYach=TRUE;
ZNstYach nstYach(RabPsh->Name, &TPoint(RabPriv->XPriv, RabPriv->YPriv));
for (int i=1; i< nstYach.kol_pokr_toch_priv; i++) {
tmpPriv = PoleRazm->FindPrivKoord(nstYach.pokr_toch_priv[i].x,nstYach.pokr_toch_priv[i].y);
if (!tmpPriv) PROG_LOV;
tmpPriv->Yach=RabPsh;
}
}
else {
RabPriv->Yach=NULL;
RabPsh->PrivYach=NULL;
RabPriv->FlagNachYach=FALSE;
ZNstYach nstYach(RabPsh->Name, &TPoint(RabPriv->XPriv, RabPriv->YPriv));
for (int i=1; i< nstYach.kol_pokr_toch_priv; i++) {
tmpPriv = PoleRazm->FindPrivKoord(nstYach.pokr_toch_priv[i].x, nstYach.pokr_toch_priv[i].y);
if (!tmpPriv) PROG_LOV;
tmpPriv->Yach=NULL;
}
}
}
void
ZRazmWindow::OptimizePerif(TIArrayAsVector<ZPsh>& SpHranPsh, TIListImp<ZPriv>& SpHranPriv)
{
ZPsh *Obj,*Obj2;
ZPriv *HranPriv1,*RabPriv;
int Sum1_1,Sum2_2,Sum1_2,Sum2_1,Delta,DeltaOld;
TIArrayAsVectorIterator<ZPsh> it1(SpHranPsh);
TIListIteratorImp<ZPriv> it2(SpHranPriv);
StateOptim->State->SetText("Оптимизация Z-яч.");
for (int i=0;i<3;i++){
it1.Restart();
while (it1!=0){
Obj=it1++;
DeltaOld=0;
Sum1_1=SummaDln(Obj,Obj->PrivYach,FALSE);
it2.Restart();
while (it2!=0){
RabPriv=it2++;
if (RabPriv->Yach==NULL){
Sum1_2=SummaDln(Obj,RabPriv,FALSE);
Delta=Sum1_1-Sum1_2;
if (Delta > DeltaOld){
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
PoleRazm->DeleteRazmYach(DC,Obj->PrivYach,FALSE);
PoleRazm->RazmYach(DC,Obj, RabPriv, ZPsh::NoFixed);
DeltaOld=Delta;
}
}
else {
if (RabPriv!=Obj->PrivYach){
Obj2=RabPriv->Yach;
Sum2_2=SummaDln(Obj2,RabPriv,FALSE);
Sum1_2=SummaDln(Obj,RabPriv,FALSE);
Sum2_1=SummaDln(Obj2,Obj->PrivYach,FALSE);
Delta=Sum1_1+Sum2_2-Sum1_2-Sum2_1;
if (Delta > DeltaOld){
TDC& DC = PoleRazm->SetDC(TClientDC(*PoleRazm));
HranPriv1=Obj->PrivYach;
PoleRazm->DeleteRazmYach(DC,HranPriv1,FALSE);
PoleRazm->DeleteRazmYach(DC,RabPriv,FALSE);
PoleRazm->RazmYach(DC, Obj, RabPriv, ZPsh::NoFixed);
PoleRazm->RazmYach(DC, Obj2, HranPriv1, ZPsh::NoFixed);
DeltaOld=Delta;
}
}
}
}
}
}
it1.Restart();
while (it1){
Obj=it1++;
Obj->InMassiv=FALSE;
}
}
void
ZRazmWindow::CmColorRaskras()
{
if (MessageBox(GetModule()->LoadString(IDS_SETUP_COLOR_PSH).c_str(),
GetModule()->GetName(), MB_YESNO | MB_ICONQUESTION) != IDYES)
return;
const kolColors = 36;
const COLORREF colors[] = {
RGB( 0, 255, 0), // LtGreen
RGB( 0, 0, 255), // LtBlue
RGB(255, 0, 0), // LtRed
RGB(255, 0, 255), // LtMagenta
RGB( 0, 255, 255), // LtCyan
RGB(192, 192, 192), // LtGray
RGB(128, 128, 128), // Gray
RGB(255, 128, 128),
RGB(255, 128, 0),
RGB(128, 64, 0),
RGB(128, 128, 0),
RGB(128, 255, 0),
RGB( 0, 128, 0),
RGB(128, 128, 64),
RGB( 0, 255, 128),
RGB(192, 220, 192),
RGB( 0, 128, 128),
RGB( 0, 128, 64),
RGB(128, 255, 255),
RGB( 64, 128, 128),
RGB( 0, 128, 255),
RGB(164, 200, 240),
RGB(128, 128, 255),
RGB(255, 128, 192),
RGB(128, 0, 128),
RGB(255, 128, 255),
RGB(255, 0, 128),
RGB(128, 0, 255),
RGB(128, 0, 0),
RGB(128, 64, 64),
RGB( 0, 64, 64),
RGB( 0, 64, 128),
RGB( 0, 0, 128),
RGB(128, 0, 64),
RGB( 64, 0, 64),
RGB( 64, 0, 128)
};
int indexColor=0;
for (int i=0; i < PtrTekFr->SostavPsh->GetItemsInContainer(); i++) {
ZPsh* Obj = (*PtrTekFr->SostavPsh)[i];
if (!Obj->IsYach()) {
SetColorPsh(Obj, colors[indexColor], "Bk");
indexColor++;
if (indexColor==kolColors) indexColor=0;
}
}
}
unsigned long
ZRazmWindow::ShowSummaSv(TIArrayAsVector<ZPsh> *SpHranPsh)
{
unsigned long ObschDl = GetSummaSv(SpHranPsh);
SetTextState(StateOptim->KriterOptim, ObschDl);
return ObschDl;
}
unsigned long
ZRazmWindow::GetSummaSv(TIArrayAsVector<ZPsh> *SpHranPsh)
{
ZPsh *Obj;
unsigned long ObschDl;
ObschDl=0;
TIArrayAsVectorIterator<ZPsh> iir(*SpHranPsh);
while (iir!=0) {
Obj=iir++;
if (Obj->PrivYach!=NULL) {
ObschDl+=SummaDln(Obj, Obj->PrivYach, TRUE);
}
}
return ObschDl;
}
void
ZRazmWindow::SetTextState(TStatic* item, unsigned long value)
{
char buf[20];
item->SetText(ultoa(value, buf, 10));
}
void
ZRazmWindow::SetTextState(TStatic* item, float value)
{
char buf[20];
sprintf(buf, "%.1f %%", value);
item->SetText(buf);
}
// Определяет расстояние между соседними точками привязки внутри поля БМК.
void
ZRazmWindow::GetDxDyPriv(int& dx, int& dy)
{
const ZNstBMK& bmk = *GlobalData->GetNstBMK();
DOP_PRIV_YACH *priv1, *priv2;
dx =0;
dy =0;
for (int i=0; i< bmk.dop_priv_yach->GetItemsInContainer()-1 && (!dx || !dy); i++) {
priv1 = (*bmk.dop_priv_yach)[i];
priv2 = (*bmk.dop_priv_yach)[i+1];
if (!priv1->perif && !priv2->perif) {
if (!dx) dx = abs(priv1->x - priv2->x);
if (!dy) dy = abs(priv1->y - priv2->y);
}
}
if (!dx || !dy) PROG_LOV;
}
void
ZRazmWindow::CmFixYach()
{
FixYach(TRUE);
}
void
ZRazmWindow::CmUnfixYach()
{
FixYach(FALSE);
}
void
ZRazmWindow::CmFixFr()
{
FixFr(TRUE);
}
void
ZRazmWindow::CmUnfixFr()
{
FixFr(FALSE);
}
void
ZRazmWindow::CmSelFixYach()
{
SelFixYach(TRUE);
}
void
ZRazmWindow::CmSelNofixYach()
{
SelFixYach(FALSE);
}
// Закрепляет или открепляет размещение выделенных ячеек.
void
ZRazmWindow::FixYach(BOOL fix)
{
char msg[512]; ZPsh *obj;
TIListIteratorImp<ZPsh> iter(*PoleRazm->SpSelYach);
while (iter!=0) {
obj=iter++;
obj->IsFixed = fix;
}
ZFrameMonitor* frame = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), ZFrameMonitor);
if (!frame) PROG_LOV;
wsprintf(msg, GetModule()->LoadString((fix) ? IDS_FIX_YACH : IDS_UNFIX_YACH).c_str(),
PoleRazm->SpSelYach->GetItemsInContainer());
frame->SetTextSLine(msg);
if (PoleRazm->SpSelYach->GetItemsInContainer()) Modif = TRUE;
}
// Закрепляет или открепляет выделенный фрагмент.
// Статус ячеек фрагмента при этом не изменяется!
void
ZRazmWindow::FixFr(BOOL fix)
{
TIStackAsList<ZPsh> StackFr;
ZPsh *RodObj, *Obj;
ZPsh* PtrSelFr = GetPtrSelFr();
if (!PtrSelFr) return;
StackFr.OwnsElements(0);
StackFr.Push(PtrSelFr);
while (!StackFr.IsEmpty()) {
RodObj = StackFr.Pop();
RodObj->IsFixed = fix;
for (int i=0; i<RodObj->SostavPsh->GetItemsInContainer(); i++) {
Obj = (*(RodObj->SostavPsh))[i];
if (!Obj->IsYach()) StackFr.Push(Obj);
}
}
PoleUpr->PaintSpFr();
Modif = TRUE;
char msg[512];
int ids = (fix) ? IDS_FIX_FR : IDS_UNFIX_FR;
wsprintf(msg, GetModule()->LoadString(ids).c_str(), PtrSelFr->Name);
MessageBox(msg, GetModule()->GetName(), MB_OK | MB_ICONINFORMATION);
}
// Выделяет все фиксированные или нефиксированные ячейки текущего фрагмента.
// Текущий режим выбора ячеек (YACH, FR или RECT) не изменяется!
void
ZRazmWindow::SelFixYach(BOOL fixYach)
{
// Для блокировки возможности перемещения и удаления отдельных ячеек.
TypOper = OPR_SELECT;
TIStackAsList<ZPsh> StackFr;
ZPsh *RodObj, *Obj;
StackFr.OwnsElements(0);
StackFr.Push(PtrTekFr);
int kolSel = 0;
while (!StackFr.IsEmpty()) {
RodObj = StackFr.Pop();
for (int i=0; i<RodObj->SostavPsh->GetItemsInContainer(); i++) {
Obj=(*(RodObj->SostavPsh))[i];
if (Obj->IsYach()) {
if (Obj->PrivYach && Obj->IsFixed == fixYach) {
if (Obj->PrivYach->Select || PoleRazm->SelectYach(Obj->PrivYach, TRUE, TRUE)) kolSel++;
}
} else StackFr.Push(Obj);
}
}
char msg[512];
int ids = (fixYach) ? IDS_KOL_SEL_FIX_YACH : IDS_KOL_SEL_NOFIX_YACH;
wsprintf(msg, GetModule()->LoadString(ids).c_str(), PtrTekFr->Name, kolSel);
ZFrameMonitor* frame = TYPESAFE_DOWNCAST(GetApplication()->GetMainWindow(), ZFrameMonitor);
if (!frame) PROG_LOV;
frame->SetTextSLine(msg);
}
Приложение II: Схема TIMER
Приложение III: Технология изготовления КМОП-ячейки.