Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
KUTEPOV / DIPL.DOC
Скачиваний:
40
Добавлен:
16.04.2013
Размер:
2.87 Mб
Скачать

Литература

  1. Ю. М. Ильин, Т. Л. Короткова, Г. Д. Костина. Методические указания к курсовой работе и дипломному проектированию по расчету экономической эффективности от внедрения АСУТП и САПР. - М. : МИЭТ, 1987.

  2. РМ Система автоматизированного проектирования изделий электронной техники. Методика определения экономической эффективности.

  3. Методика расчета экономической эффективности программных средств вычислительной техники. - М. 1989.

  4. Методика (основные положения) определения экономической эффективности использования в народном хозяйстве новой техники, изобретений и рационализаторских предложений. - М. 1987.

  5. Г. Г. Казеннов, Е. В. Сердобинцев. Автоматизация проектирования БИС. Проектирование топологии матричных БИС. - М. : Высшая школа, 1990.

  6. М. Ватанабэ и др. . Проектирование СБИС. - М. : Мир, 1988.

  7. Л. А. Константинова, Н. М. Ларионов, В. М. Писеев. Методы и средства обеспечения безопасности технологических процессов на предприятиях электронной промышленности. - Учебное пособие по курсу “Охрана труда и окружающей среды”.

  8. Под ред. Шилина А. С.. Охрана труда в машиностроении.

  9. В. И. Каракеян, Л. А. Константинова, В. М. Писеев. Лабораторный практикум по курсу “Производственная и экологическая безопасность в микроэлектронике”.

П Р И Л О Ж Е Н И Я.

Приложение 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: Технология изготовления КМОП-ячейки.

111