Digital 3D Anthropometry 7. Data Analysis Sungmin Kim SEOUL NATIONAL UNIVERSITY Body 기본정보표시 Introduction 스케일조절하기 단면형상추출 단면정보관리 3D 단면형상표시 2
기본정보표시및스케일조절 UI 및핸들러구성 void fastcall TMainForm::BeginNewProject1Click(TObject *Sender) LOADBODY->FileName=""; if (LOADBODY->Execute()) SetInformation(); TListBox INFO TEdit SCALE void fastcall TMainForm::LoadProject1Click(TObject *Sender) LOADPROJECT->FileName=""; if (LOADPROJECT->Execute()) SetInformation(); void fastcall TMainForm::SetInformation() if (Body) Body->GetInformation(INFO); 3 기본정보표시 void TBodyData::GetInformation(TListBox *L) Model->GetSize(); L->Items->Clear(); L->Items->Add("Width = "+AnsiString((int)(Model->Mx-Model->mx))); L->Items->Add("Height = "+AnsiString((int)(Model->My-Model->my))); L->Items->Add("Depth = "+AnsiString((int)(Model->Mz-Model->mz))); 스케일변경 void fastcall TMainForm::Button5Click(TObject *Sender) if (Body) Body->Scale(SCALE->Text.ToDouble()); SetInformation(); void TBodyData::Scale(float r) Model->Scale(r); 4
단면위치표시하기 class TBodyData bool TModel3D float ; ShowPlane; *Plane; PlaneHeight; TCheckBox SHOWPLANE TEdit HEIGHT TBodyData::TBodyData() Plane=new TModel3D; Plane->FormPlane(1000,1000,1,1,0,255,0); Plane->Opaque=0; PlaneHeight=0; TBodyData::~TBodyData() delete Plane; Plane=0; 5 단면위치를표시하기 void fastcall TMainForm::Redraw() if (GL) GL->BeginDraw(GetDC(RIGHT->Handle)); GL->DrawAxis(1000); if (Body) Body->ShowPlane=SHOWPLANE->Checked; Body->Draw(GL); GL->EndDraw(GetDC(RIGHT->Handle)); void TBodyData::Draw(TOpenGL *GL) if (Model) Model->ViewFace=ViewFace; Model->Opaque=Opaque; GL->Draw(Model); if (ShowPlane) GL->Draw(Plane,0,PlaneHeight,0); // offset 6
단면위치표시하기 void TOpenGL::Draw(TModel3D *M) Draw(M,0,0,0); void TOpenGL::Draw(TModel3D *M,float x,float y,float z) if (M->ViewFace) glvertex3f(p[e].x+x,p[e].y+y,p[e].z+z); glend(); else glvertex3f(p[e].x+z,p[e].y+y,p[e].z+z); glend(); 7 단면위치표시하기 Set Plane 버튼의핸들러작성 Up/Down 버튼을만들어서더편리하게할수도있음 (Homework) void fastcall TMainForm::Button6Click(TObject *Sender) if (Body) Body->PlaneHeight=HEIGHT->Text.ToDouble(); 8
주어진위치에서단면을추출하기 삼각형요소와단면의교점들을모두찾기 단면을리스트로관리하기 SHOWSECTION S_NAME S_LIST 9 단면형상을저장할 TBodySection 클래스설계 #include class TBodySection public: ; "TPoint3D.h" TBodySection(); ~TBodySection(); AnsiString int TPoint3D Name; PointNum; *Point; TBodySection::TBodySection() Name=""; PointNum=0; Point=0; TBodySection::~TBodySection() if (Point) delete[]point; Point=0; PointNum=0; 10
Get 버튼의이벤트핸들러구성 void fastcall TMainForm::Button7Click(TObject *Sender) if (Body) AnsiString N=S_NAME->Text; if (N=="") return; if (Body->FindSection(N)!=-1) Application->MessageBox("Section already exists","caution",mb_iconexclamation MB_OK); return; Body->AddSection(N,Body->PlaneHeight); S_LIST->Items->Add(N); void fastcall TMainForm::SetInformation() if (Body) Body->GetInformation(INFO); S_LIST->Items->Clear(); for(i=0;i<body->sectionnum;i++) S_LIST->Items->Add(Body->Section[i]->Name); 11 TBodyData 클래스수정 #include class TBodyData public: "TBodySection.h" TBodyData::TBodyData() SectionNum=0; Section=0; ; bool int TBodySection int void ShowSection; SectionNum; **Section; FindSection(AnsiString N); AddSection(AnsiString N,float y); TBodyData::~TBodyData() if (Section) for(i=0;i<sectionnum;i++) delete Section[i]; free(section); Section=0; SectionNum=0; 12
FindSection 함수 이름으로 Section 을검색 해당하는 Section 이없으면 -1 을리턴 int TBodyData::FindSection(AnsiString N) for(i=0;i<sectionnum;i++) if (Section[i]->Name==N) return i; return -1; // not found 13 단면과모델의교차점갯수세기 void TBodyData::AddSection(AnsiString N,float y) TPoint3D O,NM,p1,p2; O.Set(0,y,0); NM.Set(0,1,0); int i,j,k,num=0; float d; int *is=new int[model->elemnum*3]; // 교차하는점의갯수를계산 for(i=0;i<model->elemnum;i++) for(j=0;j<3;j++) k=(j==2)? 0 : j+1; p1=model->node[model->elem[i*3+j]]-o; p2=model->node[model->elem[i*3+k]]-o; d=(p1*nm)*(p2*nm); if (d<=0) is[i*3+j]=1; num++; else is[i+j]=0; 14
Section 을추가하기 TBodySection* TBodyData::AddSection(AnsiString N) Section=(TBodySection**)realloc(Section,sizeof(TBodySection*)*(SectionNum+1)); Section[SectionNum]=new TBodySection; Section[SectionNum]->Name=N; return Section[SectionNum++]; Section 삭제하기 Delete 버튼핸들러구현 void fastcall TMainForm::Button8Click(TObject *Sender) if (Body) int n=s_list->itemindex; if (n!=-1) Body->DeleteSection(n); SetInformation(); 15 Section 삭제하기 void TBodyData::DeleteSection(int s) delete Section[s]; for(i=s;i<sectionnum-1;i++) Section[i]=Section[i+1]; SectionNum--; if (!SectionNum) free(section); Section=0; else Section=(TBodySection**)realloc(Section,sizeof(TBodySection*)*SectionNum); 16
교차점을찾아 Section 에추가하기 void TBodyData::AddSection(AnsiString N,float y) TBodySection *S=AddSection(N); S->Point=new TPoint3D[num]; for(i=0;i<model->elemnum;i++) for(j=0;j<3;j++) k=(j==2)? 0 : j+1; if (is[i*3+j]) // 교차한다면 p1=model->node[model->elem[i*3+j]]-o; p2=model->node[model->elem[i*3+k]]-o; S->Point[S->PointNum++]=GetIntersection(NM,p1,p2)+O; delete []is; 17 교차점찾기 TPoint3D TBodyData::GetIntersection(TPoint3D &V,TPoint3D &A,TPoint3D &B) TPoint3D D=A.Direction(B); if (!(V*D)) if (A.Length()<B.Length()) return A; else return B; float k=-(v*a)/(v*d); TPoint3D R; R=D*k+A; return R; float TPoint3D::Length() return sqrt(x*x+y*y+z*z); 18
교차점 3D 표시하기 void fastcall TMainForm::Redraw() if (GL) GL->BeginDraw(GetDC(RIGHT->Handle)); GL->DrawAxis(1000); if (Body) Body->ShowPlane=SHOWPLANE->Checked; Body->ShowSection=SHOWSECTION->Checked; Body->Draw(GL); GL->EndDraw(GetDC(RIGHT->Handle)); 19 교차점 3D 표시하기 void TBodyData::Draw(TOpenGL *GL) if (Model) Model->ViewFace=ViewFace; Model->Opaque=Opaque; GL->Draw(Model); if (ShowPlane) GL->Draw(Plane,0,PlaneHeight,0); // offset if (ShowSection) for(i=0;i<sectionnum;i++) GL->DrawPoints(Section[i]->PointNum,Section[i]->Point,3,255,0,0); 20
교차점 3D 표시하기 DrawPoints 함수정의 void TOpenGL::DrawPoints(int num,tpoint3d *p,int s,float r,float g,float b) gldisable(gl_lighting); glcolor3f(r,g,b); glpointsize(s); glbegin(gl_points); for(i=0;i<num;i++) glvertex3f(p[i].x,p[i].y,p[i].z); glend(); glenable(gl_lighting); 21 TOpenGL 에점그리는함수정의 void fastcall TMainForm::SHOWPLANEClick(TObject *Sender) void fastcall TMainForm::SHOWSECTIONClick(TObject *Sender) 22