00001
00002
00003
00004
00005
00006
00007
00008 #include "vtk.hh"
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <math.h>
00012 #include <windows.h>
00013
00014 #define UNIT 32768L
00015 #define DESELECTED 0
00016 #define SELECTED 1
00017 #define INEDITOR 6
00018
00019 #ifdef __cplusplus
00020 extern "C" {
00021 #endif
00022
00023 #include "struct.h"
00024 #include "dstruct.h"
00025
00026 #ifdef __cplusplus
00027 }
00028 #endif
00029
00030 #include "decimate.h"
00031
00032 static long ColourToLong(unsigned char *c);
00033
00034 static void LongToColour(long id, unsigned char *c);
00035
00036 class SfxReader : public vtkPolySource
00037 {
00038 public:
00039 SfxReader();
00040 ~SfxReader();
00041 char *GetClassName() {return "SfxReader";};
00042 int GetNumberOfVertices(void);
00043 int GetNumberOfEdge(void);
00044 int GetNumberOfFaces(void);
00045
00046 protected:
00047 void Execute();
00048 int Nv,Nf,Ne;
00049 };
00050
00051 class SfxBaseWriter : public vtkObject
00052 {
00053 public:
00054 SfxBaseWriter();
00055 virtual void Write();
00056 void Update();
00057
00058 protected:
00059 vtkDataSet *Input;
00060 virtual void WriteData() = 0;
00061 };
00062
00063 class SfxWriter : public SfxBaseWriter
00064 {
00065 public:
00066 SfxWriter();
00067 ~SfxWriter();
00068 char *GetClassName() {return "SfxWriter";};
00069 void SetInput(vtkPolyData *input);
00070 void SetInput(vtkPolyData &input) {this->SetInput(&input);};
00071 vtkPolyData *GetInput() {return (vtkPolyData *)this->Input;};
00072 int GetNumberOfVertices(void);
00073 int GetNumberOfEdge(void);
00074 int GetNumberOfFaces(void);
00075 void EraseOldStructure(long );
00076 void OffsetStructure(long , long , long , long );
00077
00078 protected:
00079 int Nv,Ne,Nf;
00080 void WriteData();
00081 void InsertInVertexList(long , long , long );
00082 void BuildEdges(long );
00083 };
00084
00085 static HWND hParent;
00086 static HINSTANCE hThisInstance;
00087
00088 static BOOL CALLBACK SimplifyDlgProc(HWND hwnd, UINT msg,
00089 WPARAM wparam, LPARAM lparam);
00090
00091 #if __WATCOMC__
00092 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00093 #else
00094 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00095 #endif
00096 switch (dwReason) {
00097 case DLL_PROCESS_ATTACH: {
00098 hThisInstance=(HINSTANCE)hDLL;
00099 if(hDLL == NULL)MessageBeep(MB_OK);
00100 break;
00101 }
00102 case DLL_PROCESS_DETACH:
00103 break;
00104 }
00105 return TRUE;
00106 }
00107
00108
00109 extern "C" BOOL _Xmodeler
00110 (HWND parent_window,HWND info_window,X__STRUCTURE *lpevi){
00111 HCURSOR hSave;
00112 static struct bp {
00113 double TargetReduction;
00114 long MaximumIterations,MaximumSubIterations;
00115 double InitialError,ErrorIncrement,
00116 AspectRatio,InitialFeatureAngle;
00117 } d;
00118 lpEVI=lpevi;
00119 hParent=parent_window;
00120 d.TargetReduction=0.9;
00121 d.MaximumIterations=10;
00122 d.MaximumSubIterations=2;
00123 d.InitialError=0.0000;
00124 d.ErrorIncrement=0.002;
00125 d.AspectRatio=20.0;
00126 d.InitialFeatureAngle=60.0;
00127 if(DialogBoxParam(hThisInstance,MAKEINTRESOURCE(DLG_SIM),hParent,
00128 (DLGPROC)SimplifyDlgProc,(LPARAM)&d) == FALSE)return FALSE;
00129 hSave=SetCursor(LoadCursor(NULL,IDC_WAIT));
00130 {
00131 char message[256];
00132 int Nv1,Nf1,Nv2,Nf2;
00133 SfxReader sfxinput;
00134 SfxWriter sfxoutput;
00135 vtkDecimate deci;
00136 sfxinput.Update();
00137 Nv1=sfxinput.GetNumberOfVertices();
00138 Nf1=sfxinput.GetNumberOfFaces();
00139 deci.SetInput(sfxinput.GetOutput());
00140 deci.SetTargetReduction((float)d.TargetReduction);
00141 deci.SetMaximumIterations(d.MaximumIterations);
00142 deci.SetMaximumSubIterations(d.MaximumSubIterations);
00143 deci.SetInitialError((float)d.InitialError);
00144 deci.SetErrorIncrement((float)d.ErrorIncrement);
00145 deci.SetAspectRatio((float)d.AspectRatio);
00146 deci.SetInitialFeatureAngle((float)d.InitialFeatureAngle);
00147 sfxoutput.SetInput(deci.GetOutput());
00148 sfxoutput.Write();
00149 Nv2=sfxoutput.GetNumberOfVertices();
00150 Nf2=sfxoutput.GetNumberOfFaces();
00151 sprintf(message,"Decimated %ld Vertices %ld Faces\n to %ld Vertices %ld Faces",
00152 Nv1,Nf1,Nv2,Nf2);
00153 MessageBox(parent_window,message,"Decimate",MB_OK);
00154 }
00155 SetCursor(hSave);
00156 return TRUE;
00157 }
00158
00159 static BOOL CALLBACK SimplifyDlgProc(HWND hwnd, UINT msg,
00160 WPARAM wparam, LPARAM lparam){
00161 BOOL err;
00162 double f;
00163 int i;
00164 static struct bp {
00165 double TargetReduction;
00166 long MaximumIterations,MaximumSubIterations;
00167 double InitialError,ErrorIncrement,
00168 AspectRatio,InitialFeatureAngle;
00169 } *dp;
00170 char str[32];
00171 switch( msg ) {
00172 case WM_INITDIALOG:
00173 dp=(struct bp *)lparam;
00174 SetDlgItemInt(hwnd,DLG_SIM_MAXIMUMITERATIONS,dp->MaximumIterations,FALSE);
00175 SetDlgItemInt(hwnd,DLG_SIM_MAXIMUMSUBITERATIONS,dp->MaximumSubIterations,FALSE);
00176 sprintf(str,"%.1lf",dp->TargetReduction*100.0);
00177 SetDlgItemText(hwnd,DLG_SIM_TARGETREDUCTION,(LPCTSTR)str);
00178 sprintf(str,"%.4lf",dp->InitialError);
00179 SetDlgItemText(hwnd,DLG_SIM_INITIALERROR,(LPCTSTR)str);
00180 sprintf(str,"%.4lf",dp->ErrorIncrement);
00181 SetDlgItemText(hwnd,DLG_SIM_ERRORINCREMENT,(LPCTSTR)str);
00182 sprintf(str,"%.2lf",dp->AspectRatio);
00183 SetDlgItemText(hwnd,DLG_SIM_ASPECTRATIO,(LPCTSTR)str);
00184 sprintf(str,"%.2lf",dp->InitialFeatureAngle);
00185 SetDlgItemText(hwnd,DLG_SIM_INITIALFEATUREANGLE,(LPCTSTR)str);
00186 CentreDlgOnS(hwnd);
00187 return (TRUE);
00188 case WM_COMMAND:
00189 switch(LOWORD(wparam)){
00190 case IDCANCEL:
00191 EndDialog(hwnd,FALSE);
00192 return(TRUE);
00193 case IDOK:
00194 if(GetDlgItemText(hwnd,DLG_SIM_TARGETREDUCTION,str,10) == 0){
00195 EndDialog(hwnd,FALSE); return TRUE;
00196 }
00197 dp->TargetReduction=atof(str)/100.0;
00198 if(GetDlgItemText(hwnd,DLG_SIM_INITIALERROR,str,10) == 0){
00199 EndDialog(hwnd,FALSE); return TRUE;
00200 }
00201 dp->InitialError=atof(str);
00202 if(GetDlgItemText(hwnd,DLG_SIM_ERRORINCREMENT,str,10) == 0){
00203 EndDialog(hwnd,FALSE); return TRUE;
00204 }
00205 dp->ErrorIncrement=atof(str);
00206 if(GetDlgItemText(hwnd,DLG_SIM_ASPECTRATIO,str,10) == 0){
00207 EndDialog(hwnd,FALSE); return TRUE;
00208 }
00209 dp->AspectRatio=atof(str);
00210 if(GetDlgItemText(hwnd,DLG_SIM_INITIALFEATUREANGLE,str,10) == 0){
00211 EndDialog(hwnd,FALSE); return TRUE;
00212 }
00213 dp->InitialFeatureAngle=atof(str);
00214 i=GetDlgItemInt(hwnd,DLG_SIM_MAXIMUMITERATIONS,&err,FALSE);
00215 if(err)dp->MaximumIterations=i;
00216 i=GetDlgItemInt(hwnd,DLG_SIM_MAXIMUMSUBITERATIONS,&err,FALSE);
00217 if(err)dp->MaximumSubIterations=i;
00218 EndDialog(hwnd,TRUE);
00219 return(TRUE);
00220 default:
00221 break;
00222 }
00223 break;
00224 default: break;
00225 }
00226 return(FALSE);
00227 }
00228
00229 long ColourToLong(unsigned char *c){
00230 return ((long)(c[0]) << 16) | ((long)(c[1]) << 8) | ((long)c[2]);
00231 }
00232
00233 void LongToColour(long id, unsigned char *c){
00234 c[0] = (unsigned char)((id >> 16) & 0xff);
00235 c[1] = (unsigned char)((id >> 8) & 0xff);
00236 c[2] = (unsigned char)((id ) & 0xff);
00237 }
00238
00239 SfxReader::SfxReader()
00240 {
00241 Nv=Ne=Nf=0;
00242 }
00243
00244 SfxReader::~SfxReader()
00245 {
00246 }
00247
00248 int SfxReader::GetNumberOfVertices(void){return (int)this->Nv;}
00249 int SfxReader::GetNumberOfEdge(void){return (int)this->Ne;}
00250 int SfxReader::GetNumberOfFaces(void){return (int)this->Nf;}
00251
00252 void SfxReader::Execute()
00253 {
00254 face *fp;
00255 float x[3];
00256 int i,pts[3],count;
00257 vtkFloatPoints *newPoints;
00258 vtkCellArray *newTris;
00259 vtkPolyData *output = this->GetOutput();
00260 vtkUserDefined *vdata;
00261 if(NvertSelect == 0)return;
00262 newPoints = new vtkFloatPoints(NvertSelect);
00263 vdata = new vtkUserDefined(NvertSelect);
00264
00265
00266 for(i=0,count=0;i<Nface;i++){
00267 fp=(MainFp+i);
00268 if((MainVp+fp->V[0])->status == SELECTED &&
00269 (MainVp+fp->V[1])->status == SELECTED &&
00270 (MainVp+fp->V[2])->status == SELECTED){
00271 (MainVp+fp->V[0])->id=ColourToLong(fp->color);
00272 (MainVp+fp->V[1])->id=ColourToLong(fp->color);
00273 (MainVp+fp->V[2])->id=ColourToLong(fp->color);
00274 }
00275 }
00276 for(count=0,i=0;i<Nvert;i++){
00277 if((MainVp+i)->status == SELECTED){
00278 x[0] = (float)((MainVp+i)->xyz[0])/((float)UNIT);
00279 x[1] = (float)((MainVp+i)->xyz[1])/((float)UNIT);
00280 x[2] = (float)((MainVp+i)->xyz[2])/((float)UNIT);
00281
00282 vdata->InsertNextUserDefined((void *)((MainVp+i)->id));
00283 (MainVp+i)->id=count++;
00284 newPoints->InsertNextPoint(x);
00285 this->Nv++;
00286 }
00287 }
00288 for(i=0,count=0;i<Nface;i++){
00289 fp=(MainFp+i);
00290 if((MainVp+fp->V[0])->status == SELECTED &&
00291 (MainVp+fp->V[1])->status == SELECTED &&
00292 (MainVp+fp->V[2])->status == SELECTED)count++;
00293 }
00294 newTris = new vtkCellArray;
00295 newTris->Allocate(count);
00296 for(i=0;i<Nface;i++){
00297 fp=(MainFp+i);
00298 if((MainVp+fp->V[0])->status == SELECTED &&
00299 (MainVp+fp->V[1])->status == SELECTED &&
00300 (MainVp+fp->V[2])->status == SELECTED){
00301 pts[0] = (int)((MainVp+fp->V[0])->id);
00302 pts[1] = (int)((MainVp+fp->V[1])->id);
00303 pts[2] = (int)((MainVp+fp->V[2])->id);
00304 newTris->InsertNextCell(3,pts);
00305 this->Nf++;
00306 }
00307 }
00308 output->SetPoints(newPoints);
00309 newPoints->Delete();
00310 output->SetPolys(newTris);
00311 newTris->Delete();
00312 output->GetPointData()->SetUserDefined(vdata);
00313 vdata->Delete();
00314 output->Squeeze();
00315 }
00316
00317 SfxBaseWriter::SfxBaseWriter()
00318 {
00319 this->Input = NULL;
00320 }
00321
00322 void SfxBaseWriter::Write()
00323 {
00324 if ( !this->Input ) {
00325 return;
00326 }
00327 this->Input->Update();
00328 this->WriteData();
00329 this->Input->ReleaseData();
00330 }
00331
00332 void SfxBaseWriter::Update()
00333 {
00334 this->Write();
00335 }
00336
00337 SfxWriter::SfxWriter()
00338 {
00339 Nv=0; Ne=0; Nf=0;
00340 }
00341
00342 SfxWriter::~SfxWriter()
00343 {
00344 }
00345
00346 int SfxWriter::GetNumberOfVertices(void){return (int)this->Nv;}
00347 int SfxWriter::GetNumberOfEdge(void){return (int)this->Ne;}
00348 int SfxWriter::GetNumberOfFaces(void){return (int)this->Nf;}
00349
00350 void SfxWriter::SetInput(vtkPolyData *input)
00351 {
00352 if ( this->Input != input )
00353 {
00354 this->Input = (vtkDataSet *) input;
00355 this->Modified();
00356 }
00357 }
00358
00359 void SfxWriter::WriteData()
00360 {
00361 vtkPoints *pts;
00362 vtkCellArray *polys;
00363 vtkPolyData *input=(vtkPolyData *)this->Input;
00364
00365 if ( (pts = input->GetPoints()) == NULL ||
00366 (polys = input->GetPolys()) == NULL ){
00367 return;
00368 }
00369 vertex *Vp;
00370 face *Fp;
00371 float p[3];
00372 int i,npts,npolys;
00373 long BaseVert;
00374 BaseVert=Nvert;
00375 npts=input->GetNumberOfPoints();
00376 npolys=input->GetNumberOfPolys();
00377 this->Nv=npts;
00378 this->Nf=npolys;
00379 if(npts > 0){
00380 if(!UpdateVertexHeap(Nvert+npts))return;
00381 for(i=0;i<npts;i++){
00382 pts->GetPoint(i,p);
00383 CreateVertex();
00384 Vp=(MainVp+Nvert-1);
00385 Vp->id=0;
00386 Vp->sp=NULL;
00387 Vp->xyz[0]=(long)(p[0]*(float)UNIT);
00388 Vp->xyz[1]=(long)(p[1]*(float)UNIT);
00389 Vp->xyz[2]=(long)(p[2]*(float)UNIT);
00390 }
00391 }
00392 if(npolys > 0){
00393 int *indx;
00394 if(!UpdateFaceHeap(Nface+npolys))return;
00395 vtkPointData *pd=input->GetPointData();
00396 vtkUserDefined *data=pd->GetUserDefined();
00397 int ns=data->GetNumberOfUserDefined();
00398 for (polys->InitTraversal(); polys->GetNextCell(npts,indx); ){
00399 CreateFace(BaseVert+(long)indx[0],
00400 BaseVert+(long)indx[1],
00401 BaseVert+(long)indx[2]);
00402
00403
00404 long c = (long)data->GetUserDefined(indx[0]);
00405
00406 unsigned char fc[3];
00407 LongToColour(c,fc);
00408 for(i=0;i<3;i++)(MainFp+Nface-1)->color[i]=fc[i];
00409
00410 this->InsertInVertexList(BaseVert,indx[0],indx[1]);
00411 this->InsertInVertexList(BaseVert,indx[1],indx[2]);
00412 this->InsertInVertexList(BaseVert,indx[2],indx[0]);
00413 }
00414 this->BuildEdges(BaseVert);
00415 }
00416
00417
00418 this->EraseOldStructure(BaseVert);
00419 }
00420
00421
00422
00423
00424
00425 void SfxWriter::InsertInVertexList(long base, long Vj, long Vi){
00426 vertex *vj,*vi;
00427 long *list,i,j;
00428 vj=(MainVp+base+Vj);
00429 vi=(MainVp+base+Vi);
00430 list = (long *)vi->sp;
00431 if(vi->id > 0)for(i=0;i<vi->id;i++)if(list[i] == Vj)return;
00432 list = (long *)vj->sp;
00433 if(vj->id > 0)for(j=0;j<vj->id;j++)if(list[j] == Vi)return;
00434 if(vi->id == 0){
00435 if((list = (long *)X__Malloc((vi->id + 1)*sizeof(long))) == NULL){
00436 return;
00437 }
00438 vi->sp=(struct Designer_SKELETON_tag *)list;
00439 }
00440 else{
00441 list = (long *)vi->sp;
00442 if((list = (long *)X__Realloc(list,(vi->id + 1)*sizeof(long))) == NULL){
00443 return;
00444 }
00445 vi->sp=(struct Designer_SKELETON_tag *)list;
00446 }
00447 list[vi->id] = base+Vj;
00448 (vi->id)++;
00449 }
00450
00451 void SfxWriter::BuildEdges(long base){
00452 long n,j,i,*list;
00453 vertex *vp;
00454 vp=(MainVp+base);
00455 for(j=base;j<Nvert;j++){
00456 if(vp->id != 0 && vp->sp != NULL){
00457 if(!UpdateEdgeHeap(Nedge+vp->id))return;
00458 list = (long *)vp->sp;
00459 for(i=0;i<vp->id;i++)CreateEdge(j,list[i]);
00460 X__Free(vp->sp); vp->sp=NULL; vp->id=0;
00461 }
00462 vp++;
00463 }
00464 }
00465
00466 void SfxWriter::EraseOldStructure(long base){
00467 long c;
00468 vertex *vp;
00469 vp=(MainVp+base); for(c=base;c<Nvert;c++){
00470 if(vp->status == SELECTED){
00471 vp->status=INEDITOR; NvertSelect--; NvertDeselect++;
00472 }
00473 vp++;
00474 }
00475 EraseVertex(1);
00476 vp=MainVp; for(c=0;c<Nvert;c++){
00477 if(vp->status == INEDITOR){
00478 vp->status=SELECTED; NvertSelect++; NvertDeselect--;
00479 }
00480 vp++;
00481 }
00482 }
00483
00484 void SfxWriter::OffsetStructure(long base, long dx, long dy, long dz){
00485 long c;
00486 vertex *vp;
00487 vp=(MainVp+base); for(c=base;c<Nvert;c++){
00488 vp->xyz[0] += dx;
00489 vp->xyz[1] += dy;
00490 vp->xyz[2] += dz;
00491 vp++;
00492 }
00493 }