Development of Fashion CAD Systemfashiontech.snu.ac.kr/note/fashioncad/12-Custom Classes.pdf ·...
Transcript of Development of Fashion CAD Systemfashiontech.snu.ac.kr/note/fashioncad/12-Custom Classes.pdf ·...
Sungmin Kim
SEOUL NATIONAL UNIVERSITY
Development of Fashion CAD System
12. Custom Classes
Introduction Topics Using Custom Classes
Spline Curve 사용하기
– TBSpline Class
DXF (Drawing Exchange Format) 로 저장하기
– TDXFWriter Class
Equation Solver 사용하기
– TEquationSolver Class
» 인체 치수를 이용한 패턴 디자인에의 응용
2
Spline Curve TBSpline Class 의 활용 Spline Curve
Bezier 보다 계산이 복잡하나 각각의 조정점이 전체 형상에 영향을 적게 미침
지정한 점을 지나도록 interpolate 할 수 있음
– Poly Bezier Curve 로 그리기도 구현 가능
3
Spline Curve TBSpline Class 의 활용 Project 에 필요한 파일을 추가
CustomClass.lib
ptLine Class 정의 수정
4
...#include "TBSpline.h"
class ptLine{public :
...
TBSpline *Spline;void FormSpline(ptPoint**);
...};#endif
ptLine::ptLine(int p1,int p2){...
Spline=0;}
ptLine::ptLine(int p1,int p2,int p3,int p4){...
Spline=0;}
ptLine::ptLine(ptLine &L){...Spline=0;}
ptLine::~ptLine(){if (Spline) delete Spline;Spline=0;}
Spline Curve TBSpline Class 의 활용 FormSpline 함수의 구성
Spline 에 사용될 점의 갯수를 지정
– SetPointNum 함수
각 점의 좌표를 입력
– SetPoint 함수
Interpolate 함수로 Spline 을 구성
– Interpolate 함수
5
void ptLine::FormSpline(ptPoint **P){Spline=new TBSpline;Spline->SetPointNum(4);int i;for(i=0;i<4;i++){
Spline->SetPoint(i,P[Point[i]]->x,P[Point[i]]->y);}
Spline->Interpolate();}
Spline Curve TBSpline Class 의 활용 ptGarment Class 수정
AddLine 함수에 Spline 을 구성하는 코드를 추가
6
void ptGarment::AddLine(int p1,int p2,int p3,int p4){Line=(ptLine**)realloc(Line,sizeof(ptLine*)*(LineNum+1));Line[LineNum]=new ptLine(p1,p2,p3,p4);Line[LineNum]->FormSpline(Point);LineNum++;}
Spline Curve TBSpline Class 의 활용 ptGarment Class 수정
ptLine 클래스의 Draw 함수 수정
7
CV->PolyBezier(pt,3);
...if (Spline){
Spline->Draw(C,NC);}
...
DXF Writer DXF 파일로 저장하기 DXF (Drawing Exchange Format)
AutoCAD의 개발사인 AutoDesk에서 만든 규격
서로 다른 CAD 시스템 간 데이터 교환에 널리 이용됨
의복 전용 AAMA-DXF 표준 규격도 존재 (American Apparel Manufacturers Association)
8
DXF Writer TDXFWriter Class의 활용 YUKA CAD 와 호환 가능한 구조
한 패턴이 하나의 Block 을 구성
한 패턴은 하나의 재단선으로 구성됨
– 직선-Spline 모두를 엮어서 하나의 polyline 으로 변환하기
– Spline 을 Polyline 으로 바꾸는 것이 문제
» TBSpline 클래스 활용
9
DXF Writer TDXFWriter Class의 활용 TMainForm 에 메뉴 추가
SaveDialog를 복사/붙이기 하여 SaveDXF dialog box 를 생성
– Filter, Title 등을 수정
프로젝트에는 TDXFWriter.cpp 유닛을 추가
10
DXF Writer TDXFWriter Class의 활용 Menu Handler 작성
11
void __fastcall TMainForm::SaveasDXF1Click(TObject *Sender){TChildForm *C=(TChildForm*)ActiveMDIChild;if (C){
SaveDXF->FileName="";if (SaveDXF->Execute()){
C->Garment->SaveAsDXF(SaveDXF->FileName);}
}}
DXF Writer TDXFWriter Class의 활용 조건 설정
패턴이 없으면 안됨
패턴은 반드시 한개의 외곽선 (Line)을 가져야 함
12
void ptGarment::SaveAsDXF(AnsiString N){if (!PatternNum){
MessageBox(Handle,"No pattern has been defined","Caution",MB_ICONEXCLAMATION|MB_OK);return;}
int i;for(i=0;i<PatternNum;i++){
if (!Pattern[i]->Line->Count){MessageBox(Handle,"Some patterns don't have a cut line","Caution",MB_ICONEXCLAMATION|MB_OK);return;}
}}
DXF Writer TDXFWriter Class의 활용 Section 구조
Pattern section
– 하나의 block 이 하나의 패턴 geometry 를 정의
Information section
– 각각의 패턴을 등록
13
void ptGarment::SaveAsDXF(AnsiString N){...
TDXFWriter *D=new TDXFWriter;D->OpenFile(N);D->OpenPatternSection();for(i=0;i<PatternNum;i++){
D->BeginPattern(Pattern[i]->Name);SaveAsPolyline(D,Pattern[i]);D->EndPattern();}
D->EndPatternSection();D->OpenInfoSection();for(i=0;i<PatternNum;i++){
D->InsertPattern(Pattern[i]->Name);}
D->EndInfoSection();D->CloseFile();delete D;}
Pattern
Pattern
...
Pattern Name
Pattern Name
...
PatternSection
InfoSection
DXF Writer TDXFWriter Class의 활용 SaveAsPolyline 함수의 작성
14
void ptGarment::SaveAsPolyline(TDXFWriter *D,ptPattern *P){int i,j;int num=0;ptIntegerList *I=P->Line;for(i=0;i<I->Count;i++){
ptLine *L=Line[I->Number[i]];if (L->PointNum==2){ // straight line
num+=1;}
else{L->Spline->GetUniformPointLength(10.0f);num+=L->Spline->UniformPointNum;}
}float *x=new float[num+100];float *y=new float[num+100];num=0;for(i=0;i<I->Count;i++){
ptLine *L=Line[I->Number[i]];if (L->PointNum==2){
x[num]=Point[L->Point[0]]->x;y[num]=Point[L->Point[0]]->y;num++;}
else{
L->Spline->GetUniformPointLength(10.0f);int n=L->Spline->UniformPointNum;for(j=0;j<n-1;j++){
TPoint2D p=L->Spline->UniformPoint[j].As2D();x[num]=p.x;y[num]=p.y;num++;}
}}
x[num]=x[0];y[num]=y[0];num++;D->WritePolyline(num,x,y);delete []x;delete []y;}
DXF Writer TDXFWriter Class의 활용
15
DXF Writer TDXFWriter Class의 활용 https://a360.autodesk.com/viewer
16
Equation Solver Equation Solver 의 활용 TEquationSolver 유닛을 프로젝트에 추가
변수 이름, 값을 입력
– a=100
– b=200
변수를 포함한 수식의 값을 계산
– a+b*3
– c+a/2
인체 치수를 이용한 패턴 제도에 활용
– 인체 치수를 입력 받아서 변수에 할당
– 점을 정의할 때 단순한 숫자가 아니라 변수를 이용한 수식으로 정의
– 변수 값을 바꾸면 패턴이 변경되도록
17
+
Equation Solver Equation Solver 의 활용 TEquationSolver
핵심은 Reverse Polish Notation (RPN, 역폴란드법) 을 이용한 식의 계산
18
5 + ((1 + 2) × 4) − 3 5 1 2 + 4 × + 3 −
5
1
2
StackFILO (First in Last Out)
Equation Solver Equation Solver 의 활용 변수 관리 UI 작성
TChildForm에 메뉴 추가
TVariableDialog.cpp Form 추가
19
TStringGrid
DefaultColWidth=150DefaultRowHeight=20FixedCols=1FixedRows=0Name=LISTOptions:goEditing=trueRowCount=1ScrollBars=ssVertical
NAME VALUE
Equation Solver Equation Solver 의 활용 변수 관리 UI 작성
ptGarment Class 에 변수 관리 기능 추가
20
...#include "TEquationSolver.h"
class ptGarment{public :
...
int ObjectType;int ViewPoint,ViewHull;
TEquationSolver *Solver;
...
ptGarment::ptGarment(){...
Solver=new TEquationSolver;}
ptGarment::~ptGarment(){...
delete Solver; Clear 할 때도 변수는 지우지 않음Solver=0;Clear();}
Equation Solver Equation Solver 의 활용 Edit-Variables Event Handler 작성
21
TVariableDialog *V=VariableDialog;TEquationSolver *S=Garment->Solver;
V->LIST->RowCount=S->VariableNum;V->LIST->Cells[0][0]="";V->LIST->Cells[1][0]="";int i;for(i=0;i<S->VariableNum;i++){
V->LIST->Cells[0][i]=AnsiString(S->Variable[i].Name);V->LIST->Cells[1][i]=AnsiString(S->Variable[i].Value);}
V->ShowModal();if (V->Result){
S->ClearVariable();for(i=0;i<V->LIST->RowCount;i++){
if (V->LIST->Cells[0][i]!=""){S->AddVariable(V->LIST->Cells[0][i],V->LIST->Cells[1][i].ToDouble());}
}Garment->Regenerate();FormPaint(this);}
Equation Solver Equation Solver 의 활용 Variable Dialog 의 Event Handler
Add / Delete
22
void __fastcall TVariableDialog::Button1Click(TObject *Sender){if (NAME->Text!="" && VALUE->Text!=""){
int i;for(i=0;i<LIST->RowCount;i++){
if (LIST->Cells[0][i]==NAME->Text) return;}
if (LIST->Cells[0][0]!="") LIST->RowCount++;LIST->Cells[0][LIST->RowCount-1]=NAME->Text;LIST->Cells[1][LIST->RowCount-1]=VALUE->Text;}
}
void __fastcall TVariableDialog::Button2Click(TObject *Sender){int r=LIST->Row;if (r!=-1 && LIST->Cells[0][r]!=""){
int i;for(i=r;i<LIST->RowCount-1;i++){
LIST->Cells[0][i]=LIST->Cells[0][i+1];LIST->Cells[1][i]=LIST->Cells[1][i+1];}
if (LIST->RowCount==1){LIST->Cells[0][0]="";LIST->Cells[1][0]="";}
else LIST->RowCount--;}
}
Equation Solver Equation Solver 의 활용 Variable Dialog 의 Event Handler
Ok / Cancel
23
void __fastcall TVariableDialog::Button3Click(TObject *Sender){Result=1;Close();}
void __fastcall TVariableDialog::Button4Click(TObject *Sender){Result=0;Close();}
Equation Solver Equation Solver 의 활용 ptGarment Class 에서 변수를 저장하도록 수정
24
void ptGarment::SaveToFileBinary(AnsiString N){TNewFileStream *F=new TNewFileStream(N,fmCreate);F->WriteInt(1); // Version,20160624F->WriteInt(StepNum);int i;for(i=0;i<StepNum;i++){
Step[i]->SaveToFileBinary(F);}
F->WriteInt(Solver->VariableNum);for(i=0;i<Solver->VariableNum;i++){
F->WriteString(Solver->Variable[i].Name);F->WriteFloat(Solver->Variable[i].Value);}
delete F;}
void ptGarment::LoadFromFileBinary(AnsiString N){TNewFileStream *F=new TNewFileStream(N,fmOpenRead);int Version=F->ReadInt();StepNum=F->ReadInt();Step=(ptDesignStep**)calloc(StepNum,sizeof(ptDesignStep*));int i;for(i=0;i<StepNum;i++){
Step[i]=new ptDesignStep;Step[i]->LoadFromFileBinary(F);}
int n=F->ReadInt();for(i=0;i<n;i++){
AnsiString S=F->ReadString();float f=F->ReadFloat();Solver->AddVariable(S,f);}
delete F;Regenerate();}
Equation Solver Equation Solver 의 활용 점의 정의에 변수를 활용하기
좌표 대신 식을 입력하게 하기
– 입력창 및 코드 수정
25
void __fastcall TChildForm::AddXY1Click(TObject *Sender){...Garment->AddPoint(PointXYDialog->X->Text,PointXYDialog->Y->Text);...}
void __fastcall TChildForm::MovePoint1Click(TObject *Sender){...Garment->AddPointMove(PointXYDialog->X->Text,PointXYDialog->Y->Text);...}
void __fastcall TChildForm::AddDividePoint1Click(TObject *Sender){...Garment->AddPointDivide(DividePointDialog->M->Text,DividePointDialog->N->Text);...}
Equation Solver Equation Solver 의 활용 ptDesignStep 의 수정
x, y 값을 float 값이 아닌 AnsiString 으로 받을 수 있도록 변수를 추가
26
ptDesignStep.h
AnsiString XEqn,YEqn;
void SetXEquation(AnsiString S) {XEqn=S;}void SetYEquation(AnsiString S) {YEqn=S;}AnsiString GetXEquation() {return XEqn;}AnsiString GetYEquation() {return YEqn;}
ptDesignStep::ptDesignStep(){...XEqn=YEqn="";}
void ptDesignStep::SaveToFileBinary(TNewFileStream *F){...F->WriteString(XEqn);F->WriteString(YEqn);}
void ptDesignStep::LoadFromFileBinary(TNewFileStream *F){...XEqn=F->ReadString();YEqn=F->ReadString();}
Equation Solver Equation Solver 의 활용 ptGarment 클래스의 수정
27
void ptGarment::AddPoint(AnsiString X,AnsiString Y){ptDesignStep *S=AddStep(stAddPointXY);S->SetXEquation(X);S->SetYEquation(Y);float x,y;Solver->Evaluate(X,x);Solver->Evaluate(Y,y);AddPoint(x,y,StepNum-1);}
void ptGarment::AddPointMove(AnsiString X,AnsiString Y){int i;for(i=0;i<SelNum;i++){
if (Sel[i]->Type==0){ptDesignStep *S=AddStep(stAddPointMove);S->AddIntParam(Sel[i]->Num);S->SetXEquation(X);S->SetYEquation(Y);float x,y;Solver->Evaluate(X,x);Solver->Evaluate(Y,y);AddPoint(Point[Sel[i]->Num]->x+x,Point[Sel[i]->Num]->y+y,StepNum-1);}
}}
Equation Solver Equation Solver 의 활용 ptGarment 클래스의 수정
28
void ptGarment::AddPointDivide(AnsiString M,AnsiString N){ptDesignStep *S=AddStep(stAddPointDiv);S->AddIntParam(Sel[0]->Num);S->AddIntParam(Sel[1]->Num);S->SetXEquation(M);S->SetYEquation(N);float x,y,m,n;Solver->Evaluate(M,m);Solver->Evaluate(N,n);x=(m*Point[Sel[1]->Num]->x+n*Point[Sel[0]->Num]->x)/(m+n);y=(m*Point[Sel[1]->Num]->y+n*Point[Sel[0]->Num]->y)/(m+n);AddPoint(x,y,StepNum-1);}
Equation Solver Equation Solver 의 활용 ptGarment 클래스의 수정
Regenerate 함수의 수정
29
...switch(S->Type){
case stAddPointXY:Solver->Evaluate(S->GetXEquation(),x);Solver->Evaluate(S->GetYEquation(),y);AddPoint(x,y,i);break;
case stAddPointMove:Solver->Evaluate(S->GetXEquation(),x);Solver->Evaluate(S->GetYEquation(),y);AddPoint(Point[S->GetIntParam(0)]->x+x,Point[S->GetIntParam(0)]->y+y,i);break;
case stAddPointDiv:Solver->Evaluate(S->GetXEquation(),m);Solver->Evaluate(S->GetYEquation(),n);x=(m*Point[S->GetIntParam(1)]->x+n*Point[S->GetIntParam(0)]->x)/(m+n);y=(m*Point[S->GetIntParam(1)]->y+n*Point[S->GetIntParam(0)]->y)/(m+n);AddPoint(x,y,i);break;
...
Equation Solver Equation Solver 의 활용 Point-Edit Property Event Handler 수정
30
void __fastcall TChildForm::EditProperty2Click(TObject *Sender){float x,y;if (Garment->OnePoint()){
ptDesignStep *S=Garment->PointStep();switch(S->Type){
case stAddPointXY:PointXYDialog->Caption="Set Coordinate";PointXYDialog->X->Text=S->GetXEquation();PointXYDialog->Y->Text=S->GetYEquation();PointXYDialog->ShowModal();if (PointXYDialog->Result==1){
S->SetXEquation(PointXYDialog->X->Text);S->SetYEquation(PointXYDialog->Y->Text);}
break;case stAddPointMove:PointXYDialog->Caption="Set Displacement";PointXYDialog->X->Text=S->GetXEquation();PointXYDialog->Y->Text=S->GetYEquation();PointXYDialog->ShowModal();if (PointXYDialog->Result==1){
S->SetXEquation(PointXYDialog->X->Text);S->SetYEquation(PointXYDialog->Y->Text);}
break;
case stAddPointDiv:DividePointDialog->M->Text=S->GetXEquation();DividePointDialog->N->Text=S->GetYEquation();DividePointDialog->ShowModal();if (DividePointDialog->Result){
S->SetXEquation(DividePointDialog->M->Text);S->SetYEquation(DividePointDialog->N->Text);}
break;}
Garment->Regenerate();FormPaint(this);}
}