Development of Fashion CAD System 9. Object Oriented Programming-3 Sungmin Kim SEOUL NATIONAL UNIVERSITY Introduction Topics Object Oriented Programming (OOP) 정의 복수의 pattern object 로 이루어지는 새로운 class Pattern design 과 관련된 모든 data 의 encapsulation Document-View 구조의 완성 를 이용한 User Interface 와 데이터의 insulation 2
의필요성 TChildForm 데이터구조의복잡성 Point, Line, Pattern 등단위데이터구조는모두클래스화됨 Pattern 을다루는함수들은아직 TChildForm 클래스의멤버함수 Pattern 을다루는함수들을멤버함수로가지는포괄적클래스가필요함 다수의 ptpattern object를관리하는 Garment class 가필요함 pt의정의 새로운 ptgarment.cpp 유닛으로저장 ptnewcanvas를제외한 TChildForm에존재하는모든데이터를멤버데이터로가져온다 3 생성자 / 파괴자정의 #include #include TChildForm 의생성자 / 파괴자코드를옮겨온다 class ptgarment public : ; ptgarment(); ~ptgarment(); "ptpattern.h" "ptselection.h" int PointNum; ptpoint **Point; int LineNum; ptline **Line; int PatternNum; ptpattern **Pattern; int SelNum; ptselection **Sel; int ObjectType; int ViewPoint,ViewHull; ptgarment::ptgarment() PointNum=0; Point=0; LineNum=0; Line=0; PatternNum=0; Pattern=0; SelNum=0; Sel=0; ViewPoint=ViewHull=1; ptgarment::~ptgarment() if (Point) for(i=0;i<pointnum;i++) delete Point[i]; free(point); PointNum=0; Point=0; if (Line) for(i=0;i<linenum;i++) delete Line[i]; free(line); LineNum=0; Line=0; if (Pattern) for(i=0;i<patternnum;i++) delete Pattern[i]; free(pattern); PatternNum=0; Pattern=0; if (Sel) for(i=0;i<selnum;i++) delete Sel[i]; free(sel); SelNum=0; Sel=0; 4
TChildForm 수정 모든데이터를없애고 ptgarment object 하나만남긴다 ptnewcanvas ptgarment *NewCanvas; *Garment; 생성자 / 파괴자코드에추가 fastcall TChildForm::TChildForm(TComponent* Owner,AnsiString C) : TForm(Owner) Caption=C; NewCanvas=new ptnewcanvas; Garment=new ptgarment; fastcall TChildForm::FormClose(TObject *Sender, TCloseAction &Action) delete NewCanvas; NewCanvas=0; delete Garment; Garment=0; Action=caFree; 5 Member Function의구성 TChildForm 에정의된모든함수정의를옮겨온다 Calling convention ( fastcall) 은삭제가능 class ptgarment ; int bool bool AddPoint(float x,float y); AddLine(int p1,int p2); AddLine(int p1,int p2,int p3,int p4); AddBezierCurve(ptSelection **S); AddPattern(AnsiString); AddSelection(int type,int object); FindObject(int x,int y); DrawLine(int l,tcolor C,int hull); DrawPattern(int); AllLines(); IsClosedLoop(); 6
기본 Member Function의구성 TChildForm 에정의된함수구현코드를 ptgarment.cpp 로옮긴다 UI의 Event Handler 는제외하는것에주의한다 TChildForm 을 ptgarment 로변경 UI 와의접점수정 NewCanvas, Canvas 등의변수가필요한함수수정 int FindObject(ptNewCanvas *NC,int x,int y); DrawLine(TCanvas *CV,ptNewCanvas *NC,int l,tcolor C,int hull); DrawPattern(TCanvas *C,ptNewCanvas *NC,int p); 7 기본 Member Function 의구성 UI 와의접점수정 int ptgarment::findobject(ptnewcanvas *NC,int x,int y) for(i=0;i<pointnum;i++) ptpoint P=NC->Screen(*Point[i]); for (i=0;i<linenum;i++) d=line[i]->distancetopoint(nc,point,x,y); for(i=0;i<patternnum;i++) ptpoint P=NC->Screen(Pattern[i]->Center); 8
기본 Member Function 의구성 UI 와의접점수정 ptgarment::drawline(tcanvas *CV,ptNewCanvas *NC,int l,tcolor C,int hull) Canvas 를 C NewCanvas 를 NC 로 ptgarment::drawpattern(tcanvas *C,ptNewCanvas *NC,int p) Canvas 를 C NewCanvas 를 NC 로 9 ptgarmet 클래스의멤버함수호출을포함하는코드수정 Garment-> 를추가 최대한 Garment 클래스의멤버함수로처리되도록수정하는것이핵심 fastcall TChildForm::AddXY1Click(TObject *Sender) PointXYDialog->ShowModal(); if (PointXYDialog->Result==1) Garment->AddPoint(PointXYDialog->X->Text.ToDouble(),PointXYDialog->Y->Text.ToDouble()); 10
FormPaint event handler UI와데이터의접점 Canvas 와 NewCanvas 를인자로하는 ptgarment 의 Member function 이되는것이맞음 fastcall TChildForm::FormPaint(TObject *Sender) if (Garment) Garment->Draw(Canvas,NewCanvas,ClientWidth,ClientHeight); 프로그램종료후 Garment=0 이되므로, 데이터가있는지없는지확인이필요 11 Draw Function을 Garment 의 member 함수로 ptgarment::draw(tcanvas *C,ptNewCanvas *NC,int CW,int CH) C->Pen->Color=clWhite; C->Brush->Color=clWhite; C->Rectangle(0,0,CW,CH); C->Pen->Color=clLime; C->Brush->Color=clYellow; ptpoint P; P=NC->Screen(-500,0) ; C->MoveTo(P.x,P.y); P=NC->Screen(500,0); C->LineTo(P.x,P.y); P=NC->Screen(0,-500); C->MoveTo(P.x,P.y); P=NC->Screen(0,500); C->LineTo(P.x,P.y); C->Pen->Color=clBlack; if (ViewPoint==1) for(i=0;i<pointnum;i++) P=NC->Screen(*Point[i]); C->Ellipse(P.x-3,P.y-3,P.x+3,P.y+3); for(i=0;i<linenum;i++) DrawLine(C,NC,i,Line[i]->Color,1); 12
C->Pen->Color=clBlack; for(i=0;i<patternnum;i++) DrawPattern(C,NC,i); C->Pen->Color=clRed; C->Brush->Style=bsClear; for(i=0;i<selnum;i++) if (Sel[i]->Type==0) P=NC->Screen(*Point[Sel[i]->Num]); C->Ellipse(P.x-5,P.y-5,P.x+5,P.y+5); if (Sel[i]->Type==1) DrawLine(C,NC,Sel[i]->Num,clRed,0); if (Sel[i]->Type==2) ptpoint p1=nc->screen(pattern[sel[i]->num]->mx,pattern[sel[i]->num]->my); ptpoint p2=nc->screen(pattern[sel[i]->num]->mx,pattern[sel[i]->num]->my); C->Rectangle(p1.x,p1.y,p2.x,p2.y); C->Brush->Style=bsSolid; 13 FormMouseDown event handler 를 Garment 의 member 함수로 fastcall TChildForm::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) if (Shift.Contains(ssCtrl)) Garment->SelectObject(NewCanvas,Shift,X,Y); else NewCanvas->MouseDown(Button,Shift,X,Y); ptgarment::selectobject(ptnewcanvas *C,TShiftState S,int x,int y) int o=findobject(c,x,y); if (!S.Contains(ssShift)) SelNum=0; if (Sel) free(sel); Sel=0; if (o!=-1) AddSelection(ObjectType,o); 14
MovePoint1Click event handler 를 Garment 의 member 함수로 fastcall TChildForm::MovePoint1Click(TObject *Sender) if (Garment->SelNum==0) return; PointXYDialog->ShowModal(); if (PointXYDialog->Result==1) float x=pointxydialog->x->text.todouble(); float y=pointxydialog->y->text.todouble(); Garment->AddPointMove(x,y); ptgarment::addpointmove(float x,float y) for(i=0;i<selnum;i++) if (Sel[i]->Type==0) AddPoint(Point[Sel[i]->Num]->x+x,Point[Sel[i]->Num]->y+y); 15 AddDivide1Click event handler 를 Garment 의 member 함수로 fastcall TChildForm::AddDividePoint1Click(TObject *Sender) if (!Garment->TwoPoint()) return; DividePointDialog->ShowModal(); if (DividePointDialog->Result) Garment->AddPointDivide(m,n); bool ptgarment::twopoint() if (SelNum!=2 Sel[0]->Type!=0 Sel[1]->Type!=0) Application->MessageBox("Select two points","caution",mb_iconexclamation MB_OK); return false; return true; ptgarment::addpointdivide(float m,float n) AddPoint((m*Point[Sel[1]->Num]->x+n*Point[Sel[0]->Num]->x)/(m+n),(m*Point[Sel[1]->Num]->y+n*Point[Sel[0]->Num]->y)/(m+n)); 16
Polyline1Click event handler 를 Garment 의 member 함수로 fastcall TChildForm::Polyline1Click(TObject *Sender) if (Garment->AllPoint()) Garment->AddPolyline(); bool ptgarment::allpoint() for(i=0;i<selnum;i++) if (Sel[i]->Type!=0) Application->MessageBox("Select points only","caution",mb_iconexclamation MB_OK); return false; return true; 17 ptgarment::addpolyline() if (SelNum<2) Application->MessageBox("Select more than two points","caution",mb_iconexclamation MB_OK); return; for(i=0;i<selnum-1;i++) AddLine(Sel[i]->Num,Sel[i+1]->Num); 18
BezierCurve1Click menu handler 를 Garment 의 member 함수로 fastcall TChildForm::BezierCurve1Click(TObject *Sender) if (Garment->AllPoint()) Garment->AddBezierCurve(); ptgarment::addbeziercurve() if (SelNum!=4) Application->MessageBox("Select four points","caution",mb_iconexclamation MB_OK); return; AddLine(Sel[0]->Num,Sel[1]->Num,Sel[2]->Num,Sel[3]->Num); 19 ViewPoint, ViewHull 관련코드수정 fastcall TChildForm::TogglePoint1Click(TObject *Sender) Garment->ViewPoint=1-Garment->ViewPoint; fastcall TChildForm::ToggleHull1Click(TObject *Sender) Garment->ViewHull=1-Garment->ViewHull; 20
EditProperty1Click event handler 를 Garment 의 member 함수로 fastcall TChildForm::EditProperty1Click(TObject *Sender) if (!Garment->SelNum) return; LinePropertyDialog->ShowModal(); if (LinePropertyDialog->Result) Garment->SetLineProperty(LinePropertyDialog->SHAPE->Brush->Color, LinePropertyDialog->THICKNESS->Text.ToInt(), LinePropertyDialog->STYLE->ItemIndex); ptgarment::setlineproperty(tcolor C,int T,int S) for(i=0;i<selnum;i++) if (Sel[i]->Type==1) Line[Sel[i]->Num]->Color=C; Line[Sel[i]->Num]->Thickness=T; Line[Sel[i]->Num]->Style=S; 21 fastcall TChildForm::AddMirrorPoints1Click(TObject *Sender) Garment->AddMirrorPoint(); ptgarment::addmirrorpoint() if (SelNum<2) return; if (Sel[0]->Type!=1 Line[Sel[0]->Num]->Type!=0) Application->MessageBox("Select a line first","caution",mb_iconexclamation); ptpoint a=*point[line[sel[0]->num]->point[0]]; ptpoint b=*point[line[sel[0]->num]->point[1]]; for(i=1;i<selnum;i++) ptpoint p=point[sel[i]->num]->mirrorpoint(a,b); AddPoint(p.x,p.y); 22
Define1Click menu handler 를 Garment 의 member 함수로 fastcall TChildForm::Define1Click(TObject *Sender) Garment->DefinePattern(); ptgarment::definepattern() if (!SelNum) return; if (!AllLines()) return; if (!IsClosedLoop()) return; int i,j; AddPattern("Pattern-"+AnsiString(PatternNum+1)); ptpattern *P=Pattern[PatternNum-1]; for(i=0;i<selnum;i++) if (Sel[i]->Type==1) P->Line->Add(Sel[i]->Num); for(j=0;j<line[sel[i].num]->pointnum;j++) P->Point->AddUnique(Line[Sel[i].Num]->Point[j]); P->FindCenter(Point,Line); 23 Mirror, Pattern 메뉴수정 fastcall TChildForm::Mirror1Click(TObject *Sender) Garment->MirrorPattern(); fastcall TChildForm::Flip1Click(TObject *Sender) Garment->FlipPattern(); ptgarment::mirrorpattern() for(i=0;i<selnum;i++) if (Sel[i]->Type==2) Pattern[Sel[i]->Num]->MirrorFlip(Point,Line,-1,1); ptgarment::flippattern() for(i=0;i<selnum;i++) if (Sel[i]->Type==2) Pattern[Sel[i]->Num]->MirrorFlip(Point,Line,1,-1); 24
Document-View 구조의완성 패턴디자인과관련된모든데이터를 TChildForm 과분리 포괄적클래스인 ptgarment 클래스는다른프로그램에도응용이가능 다른 framework 에도적용가능 View TMainForm TChildForm TChildForm TChildForm Document ptgarment ptpattern ptline ptpoint ptselection ptintegerlist 25