00001 #ifndef CURVE_H
00002 #define CURVE_H
00003
00004 #include <vector>
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <fstream>
00008 #include <list>
00009
00010 #include "Part.h"
00011
00016 template <class DataType, int dim>
00017 class Curve : public Part<DataType,dim>, public Segment<DataType,dim> {
00018 public:
00019 typedef Part<DataType,dim> PartType;
00020 typedef Connection ConBase;
00021 typedef Segment<DataType,dim> SegType;
00022 typedef Facet<DataType> FacetType;
00023
00024 Curve() {
00025 centroid(0) = 0.; centroid(1) = 0.; centroid(2) = 0.;
00026 Clength = DataType(0.);
00027 }
00028 ~Curve() {}
00029
00030 virtual void read(const int type, std::string file) {
00031
00032 ( mklog() << "\nREADING "<<file<<" type = "<<type<<" dim = "<<dim<<std::endl).flush();
00033 switch(type) {
00034 case PartType::pointList: {
00035 DataType vtmp;
00036 #ifdef CURVE_DEBUG_ON
00037 ( mklog() << "filetype = pointList\n").flush();
00038 #endif
00039 int i=0;
00040 std::string tmp;
00041
00042 std::ifstream infile;
00043 infile.open(file.c_str(), std::ifstream::in);
00044 if (!infile.is_open()) {
00045 ( mklog() <<std::system("pwd")<< "\n\n\n\t\t\tCurve read() CANNOT OPEN " << file << "\n\n\n").flush();
00046 std::cerr <<std::system("pwd")<< "\n\n\n\t\t\tCurve read() CANNOT OPEN " << file << "\n\n\n";
00047 exit (-1);
00048 }
00049
00050 infile >> tmp;
00051 infile >> tmp;
00052 setName(tmp);
00053
00054 infile >> tmp; infile >> tmp; infile >> tmp;
00055
00056 while (infile.good()) {
00057
00058 if (!infile.good()) break;
00059
00060 PType p(0.);
00061 infile >> vtmp; p(0) = vtmp;
00062 if (!infile.good()) break;
00063 infile >> vtmp; p(1) = vtmp;
00064
00065 if (dim == 3) { infile >> vtmp; p(2) = vtmp; }
00066 AddPoint(p);
00067
00068 i++;
00069 }
00070
00071 #ifdef CURVE_DEBUG_ON
00072 ( mklog() << "GetNthPoint(0) =" << GetNthPoint(0)
00073 << " GetNthPoint(i-1) =" << GetNthPoint(i-1) << std::endl
00074 << " norm_2(GetNthPoint(0)-GetNthPoint(i-1) ) ="
00075 << norm_2(GetNthPoint(0)-GetNthPoint(i-1) ) << std::endl).flush();
00076 #endif
00077 if ( norm_2(GetNthPoint(0)-GetNthPoint(i-1) ) < TOL ) {
00078 setClosure(1);
00079 }
00080 else
00081 {
00082 setClosure(0);
00083 }
00084
00085 makeConnections();
00086 makeUnique();
00087 measure();
00088
00089 infile.close();
00090
00091 break;
00092 }
00093 case PartType::VTK_curve: {
00094
00095 break;
00096 }
00097 case PartType::Brep2D: {
00098
00099 break;
00100 }
00101 case PartType::VTK_PL: {
00102
00103 break;
00104 }
00105 case PartType::Brep3D: {
00106
00107 break;
00108 }
00109 case PartType::STL: {
00110
00111 break;
00112 }
00113 }
00114 }
00115
00116 virtual void measure() {
00117 Clength = DataType(0.);
00118 centroid(0) = DataType(0.); centroid(1) = DataType(0.);
00119 if (dim == 3) centroid(2) = DataType(0.);
00120 for (register int i = 0; i < GetNumCons(); i++ ) {
00121 connectivity[i].setLength( norm_2(cPoints[connectivity[i].getNthCon(1)]
00122 - cPoints[connectivity[i].getNthCon(0)]) );
00123 connectivity[i].setCentroid( DataType(0.5)*(cPoints[connectivity[i].getNthCon(0)]
00124 + cPoints[connectivity[i].getNthCon(1)] ) );
00125 Clength += connectivity[i].Length();
00126 centroid += ( cPoints[connectivity[i].getNthCon(0)] + cPoints[connectivity[i].getNthCon(1)] )*connectivity[i].Length();
00127 }
00128 centroid *= DataType(0.5)/Clength;
00129 #ifdef CURVE_DEBUG_ON
00130 ( mklog() << Name() << " length=" << Clength << " centroid=" << Centroid() << std::endl).flush();
00131 #endif
00132 }
00133
00134 virtual DataType Length() const { return Clength; }
00135 virtual DataType Area() const { return 0; }
00136 virtual DataType Volume() const { return 0; }
00137 virtual void setLength(DataType val) { Clength = val; }
00138 virtual void setArea(DataType val) {}
00139 virtual void setVolume(DataType val) {}
00140
00141 virtual void output(int type, DataType time, FILE * fout) {}
00142 virtual void output(int type, DataType time, std::string file) {
00143
00144
00145 ( mklog() << "Output "<<file<<" type = "<<type<<" dim = "<<3<<std::endl).flush();
00146 switch(type) {
00147 case PartType::pointList: {
00148 FILE * fout;
00149 fout = fopen (file.c_str(),"w");
00150 if (fout == NULL) { std::cerr<<file<<" could not be opened.\n"; return; }
00151 ( mklog() << "Writing pointList\n").flush();
00152 #ifdef CURVE_DEBUG_ON
00153 printf("%s is open\n\n",file.c_str());
00154 #endif
00155 for (register int j = 0; j < GetNumConnections(); j ++) {
00156 fprintf(fout,"%8.5e %8.5e\n",GetNthPoint( GetNthSegment(j)->getNthCon(0) )(0),GetNthPoint( GetNthSegment(j)->getNthCon(0) )(1) );
00157 #ifdef CURVE_DEBUG_ON
00158 printf("GetNthSegment(%d) : %d\t%d\n",j,GetNthSegment(j)->getNthCon(0),GetNthSegment(j)->getNthCon(1) );
00159 printf("GetNthPoint(%d) : { (%8.5e,%8.5e) , (%8.5e,%8.5e) }\n",j,
00160 GetNthPoint(GetNthSegment(j)->getNthCon(0))(0),GetNthPoint(GetNthSegment(j)->getNthCon(0))(1),
00161 GetNthPoint(GetNthSegment(j)->getNthCon(1))(0),GetNthPoint(GetNthSegment(j)->getNthCon(1))(1) );
00162 #endif
00163
00164 }
00165 fprintf(fout,"%8.5e %8.5e\n",GetNthPoint( GetNthSegment(GetNumConnections()-1)->getNthCon(1) )(0),
00166 GetNthPoint( GetNthSegment(GetNumConnections()-1)->getNthCon(1) )(1) );
00167
00168 fclose (fout);
00169 #ifdef CURVE_DEBUG_ON
00170 printf("%s is closed\n\n",file.c_str());
00171 #endif
00172 break;
00173 }
00174 case PartType::VTK_curve: {
00175 FILE * fout;
00176 fout = fopen (file.c_str(),"w");
00177 if (fout == NULL) { std::cerr<<file<<" could not be opened.\n"; return; }
00178 #ifdef CURVE_DEBUG_ON
00179 ( mklog() << "outSurfacesVTK_Curve\n").flush();
00180 #endif
00181 fprintf(fout,"#%s\n",Name().c_str());
00182 for (register int j = 0; j < GetNumConnections(); j ++) {
00183 fprintf(fout,"%8.5e %8.5e\n",GetNthPoint( GetNthSegment(j)->getNthCon(0) )(0),GetNthPoint( GetNthSegment(j)->getNthCon(0) )(1) );
00184 #ifdef CURVE_DEBUG_ON
00185 printf("GetNthSegment(%d) : %d\t%d\n",j,GetNthSegment(j)->getNthCon(0),GetNthSegment(j)->getNthCon(1) );
00186 printf("GetNthPoint(%d) : { (%8.5e,%8.5e) , (%8.5e,%8.5e) }\n",j,
00187 GetNthPoint(GetNthSegment(j)->getNthCon(0))(0),GetNthPoint(GetNthSegment(j)->getNthCon(0))(1),
00188 GetNthPoint(GetNthSegment(j)->getNthCon(1))(0),GetNthPoint(GetNthSegment(j)->getNthCon(1))(1) );
00189 #endif
00190 }
00191 fprintf(fout,"%8.5e %8.5e\n",GetNthPoint( GetNthSegment(GetNumConnections()-1)->getNthCon(1) )(0),
00192 GetNthPoint( GetNthSegment(GetNumConnections()-1)->getNthCon(1) )(1) );
00193
00194 fclose (fout);
00195
00196 break;
00197 }
00198 case PartType::Brep2D: {
00199 FILE * fout;
00200 fout = fopen (file.c_str(),"w");
00201 if (fout == NULL) { std::cerr<<file<<" could not be opened.\n"; return; }
00202
00203 ( mklog() << "Writing Brep2D\n").flush();
00204 fprintf(fout,"2 1\n%d\n",GetNumPoints() );
00205 for (register int j=0; j < GetNumPoints(); j ++) {
00206 fprintf(fout,"%8.5e %8.5e\n",GetNthPoint(j)(0),GetNthPoint(j)(1) );
00207 }
00208
00209 fprintf(fout,"%d\n",GetNumConnections() );
00210 for (register int j = 0; j < GetNumConnections(); j++) {
00211 fprintf(fout,"%d\t%d\n",GetNthSegment(j)->getNthCon(0),GetNthSegment(j)->getNthCon(1) );
00212 }
00213
00214 fclose (fout);
00215
00216 break;
00217 }
00218 case PartType::VTK_PL: {
00219
00220 ( mklog() << "outSurfacesVTK_PL\n").flush();
00221
00222 FILE * fout;
00223 fout = fopen (file.c_str(),"w");
00224 if (fout == NULL) { std::cerr<<file<<" could not be opened.\n"; return; }
00225
00226 fprintf(fout,"# vtk DataFile Version 2.0\n3DCurves\nASCII\nDATASET UNSTRUCTURED_GRID\nFIELD FieldData 1\nTIME 1 1 float\n0.00000E+00\n");
00227 fprintf(fout,"POINTS %d float\n",GetNumPoints());
00228
00229 for (register int j=0; j < GetNumPoints(); j ++) {
00230 fprintf(fout,"%8.5e %8.5e %8.5e\n",GetNthPoint(j)(0),GetNthPoint(j)(1),GetNthPoint(j)(2) );
00231 }
00232
00233 fprintf(fout,"CELLS %d %d\n",1,GetNumConnections()+2 );
00234
00235 if (closure() == 1) fprintf(fout,"%d ",GetNumPoints()+1);
00236 else fprintf(fout,"%d ",GetNumPoints());
00237 for (register int j = 0; j < GetNumConnections(); j ++) {
00238 fprintf(fout,"%d ",GetNthSegment(j)->getNthCon(0) );
00239 }
00240 fprintf(fout,"%d ",GetNthSegment(GetNumConnections()-1)->getNthCon(1) );
00241
00242 fprintf(fout,"\nCELL_TYPES %d\n",GetNumConnections());
00243 for (register int i=0; i < GetNumConnections(); i++) {
00244 fprintf(fout,"3\n");
00245 }
00246 fprintf(fout,"CELL_DATA %d\n",GetNumConnections());
00247 fprintf(fout,"FIELD Data 1\ntest 1 %d double\n",1);
00248 for (register int i=0; i < 1; i++) {
00249 fprintf(fout,"0.0\n");
00250 }
00251 fclose (fout);
00252
00253 break;
00254 }
00255 case PartType::Brep3D: {
00256
00257 break;
00258 }
00259 case PartType::STL: {
00260
00261 break;
00262 }
00263 }
00264
00265
00266 }
00267
00268 virtual std::string Name() const { return name; }
00269 virtual void setName(std::string val) { name = val; }
00270
00271 virtual bool closure() const { return closed; }
00272 virtual void setClosure(bool val) { closed = val; }
00273
00274 virtual PType Centroid() const { return centroid; }
00275 virtual void setCentroid(PType val) { centroid = val; }
00276
00277 virtual PType operator [] (int i) const {
00278 return cPoints[i];
00279 }
00280
00281 virtual void AddPoint( PType v) {
00282 cPoints.push_back(v);
00283 }
00284
00285 virtual int GetNumPoints() const {
00286 return ((int) cPoints.size());
00287 }
00288
00289 virtual PType GetNthPoint(int n) const {
00290 return (cPoints[n]);
00291 }
00292
00293 virtual PType GetNthPoint_org(int n) const {
00294 return (cPoints_org[n]);
00295 }
00296
00297 virtual PType* GetNthPointA(int n) {
00298 return &(cPoints[n]);
00299 }
00300
00301 virtual PType * GetNthPointAddress(int n) {
00302 return &(cPoints[n]);
00303 }
00304
00305 virtual PType * GetNthVelocityAddress(int n) {
00306 return &(velocities_loc[n]);
00307 }
00308
00309 virtual std::vector<PType>& GetCPoints() {
00310 return cPoints;
00311 }
00312
00313 virtual std::vector<PType>& GetCPoints_org() {
00314 return cPoints_org;
00315 }
00316
00317 virtual std::vector<PType>& GetVelocities() {
00318 return velocities_loc;
00319 }
00320
00321 virtual int GetNumCons() {
00322 return ((int) connectivity.size());
00323 }
00324
00325 virtual int GetConnectivity() { return 2; }
00326 virtual void AddConnection(SegType v) {
00327 connectivity.push_back(v);
00328 }
00329 virtual void AddConnection(FacetType v) {}
00330 virtual int GetNumConnections() const { return connectivity.size(); }
00331 virtual ConBase * GetNthConnection(int n) const { return (ConBase*) &connectivity[n]; }
00332 virtual const SegType * GetNthSegment(int n) const { return &connectivity[n]; }
00333 virtual const FacetType * GetNthFacet(int n) const { return (FacetType *) 0; }
00334
00335 virtual void setNthCon(int i, int val) {}
00336 virtual int getNthCon(int i) const { return -1; }
00337
00338 virtual PType Normal() const {return (PType) 0.; }
00339 virtual void setNormal(PType val) {}
00340
00341 virtual void makeConnections() {
00342
00343 for (register int i = 0; i < GetNumPoints()-1; i++ ) {
00344 SegType c;
00345 #ifdef CURVE_DEBUG_ON
00346 printf("new Segment # %d created {%d,%d}\n",i,c.cPid[0],c.cPid[1]);
00347 #endif
00348 c.setNthCon(0,i);
00349 c.setNthCon(1,i+1);
00350 #ifdef CURVE_DEBUG_ON
00351 printf(" Segment # %d set {%d,%d}\n",i,c.cPid[0],c.cPid[1]);
00352 #endif
00353 AddConnection(c);
00354 #ifdef CURVE_DEBUG_ON
00355 printf(" connectivity # %d set {%d,%d}\n",i,connectivity[i].getNthCon(0),connectivity[i].getNthCon(1) );
00356 #endif
00357 }
00358 }
00359
00360 virtual void makeUnique() {
00361 ( mklog() << "UNIQUE POINTS\n GetNumPoints()="<<GetNumPoints()).flush();
00362 std::list<PType> CPointList;
00363 std::list<PType>::iterator it1, it2;
00364 std::copy (cPoints.begin (), cPoints.end (), std::back_inserter (CPointList));
00365 PType me(0.); PType other(0.);
00366 int rmcount = 0, j=0, kk=0;
00367
00368 for ( register int k = 0; k < (GetNumPoints()/2); k++) {
00369 me = GetNthPoint(k);
00370
00371 kk = k+1;
00372 it2 = CPointList.begin();
00373 advance (it2,(kk));
00374 j=kk;
00375 while ( it2 != CPointList.end() ) {
00376 other = *it2;
00377 if (norm_2(me-other) < TOL ) {
00378 for ( register int f = 0; f < GetNumConnections(); f++) {
00379 if (GetNthSegment(f)->getNthCon(0) == j || GetNthSegment(f)->getNthCon(1) == j) {
00380 if (GetNthSegment(f)->getNthCon(0) == j) {
00381 connectivity[f].cPid[0] = k;
00382 }
00383 if (GetNthSegment(f)->getNthCon(1) == j) {
00384 connectivity[f].cPid[1] = k;
00385 }
00386 if (GetNthSegment(f)->getNthCon(2) == j) {
00387 connectivity[f].cPid[2] = k;
00388 }
00389 }
00390 }
00391 #ifdef CURVE_DEBUG_ON
00392 printf("end search of SEGMENTS\n");
00393 printf(" ______removing cPoint[%d] CPointList.size()=%lu\n",j,CPointList.size());
00394 std::cout << " about to remove it2 " << *it2 << std::endl;
00395 #endif
00396 if (j == int(CPointList.size())-1) {
00397 CPointList.erase(it2);
00398 --it2;
00399 }
00400 else {
00401 it2 = CPointList.erase(it2);
00402 }
00403 rmcount++;
00404 if ( j == int(CPointList.size()) ) break;
00405
00406 for ( register int ff = 0; ff < GetNumConnections(); ff++) {
00407 if (GetNthSegment(ff)->getNthCon(0) > j || GetNthSegment(ff)->getNthCon(1) > j) {
00408 if (GetNthSegment(ff)->getNthCon(0) > j) {
00409 connectivity[ff].cPid[0]--;
00410 }
00411 if (GetNthSegment(ff)->getNthCon(1) > j) {
00412 connectivity[ff].cPid[1]--;
00413 }
00414 if (GetNthSegment(ff)->getNthCon(2) > j) {
00415 connectivity[ff].cPid[2]--;
00416 }
00417 }
00418 }
00419 }
00420 if (it2 == --CPointList.end()) {
00421 break;
00422 }
00423 if (it2 != CPointList.end()) {
00424 ++it2;
00425 j++;
00426 }
00427 }
00428 if (k==int(CPointList.size())-1 ) {
00429 break;
00430 }
00431 }
00432
00433 ( mklog() << "Removed "<<rmcount<<" redundant points. GetNumPoints()="<<GetNumPoints()<<std::endl).flush();
00434
00435 cPoints.clear();
00436 std::copy (CPointList.begin (), CPointList.end (), std::back_inserter (cPoints));
00437 cPoints_org.clear();
00438 std::copy (CPointList.begin (), CPointList.end (), std::back_inserter (cPoints_org));
00439
00440 }
00441
00442 virtual void updatePart(DataType dt,DataType time) {
00443
00444 }
00445
00446 virtual void deformPart(PType conPoint,DataType dt,DataType time) {
00447
00448 }
00449
00450 virtual void deformPart(DataType dt,DataType time) {
00451
00452 }
00453
00454 virtual void resetPart() {
00455 #ifdef CURVE_DEBUG_ON
00456 printf("%s->resetPart()\tRESETING cPOINTS\n",Name().c_str());
00457 #endif
00458 cPoints.clear();
00459 std::copy (cPoints_org.begin (), cPoints_org.end (), std::back_inserter (cPoints));
00460 }
00461
00462 virtual PType setNthCPoint(int n) { return (cPoints[n]); }
00463 virtual void setDeformation(bool val) {
00464 PartType::deformable = val;
00465 }
00466 virtual bool GetDeformation() const { return PartType::deformable; }
00467 virtual FacetType * EditNthFacet(int n) { return (FacetType *) 0; }
00468 virtual SegType * EditNthSegment(int n) { return &connectivity[n]; }
00469
00470 virtual void Restart(std::ifstream& ifs, int& pos, double& t, double& dt) {
00471 #ifdef CHECKRESTART_DEBUG_ON
00472 ( mklog() << "\nRestarting CURVE " << name << std::endl).flush();
00473 #endif
00474 ifs.seekg(pos);
00475 ifs.read((char*)&num_cPoints_org,sizeof(int));
00476 ifs.read((char*)&num_cPoints,sizeof(int));
00477 ifs.read((char*)&num_connections,sizeof(int));
00478 ifs.read((char*)&num_velocities,sizeof(int));
00479 #ifdef CHECKRESTART_DEBUG_ON
00480 ( mklog() << " num_cPoints_org " << num_cPoints_org << " num_cPoints " << num_cPoints
00481 << " num_connections " << num_connections << " num_velocities " << num_velocities << std::endl).flush();
00482 #endif
00483 for (register int i=0; i < num_cPoints_org; i++) {
00484 ifs.read((char*)&cPoints_org[i](0),sizeof(DataType));
00485 ifs.read((char*)&cPoints_org[i](1),sizeof(DataType));
00486 ifs.read((char*)&cPoints_org[i](2),sizeof(DataType));
00487 }
00488 for (register int i=0; i < num_cPoints; i++) {\
00489 ifs.read((char*)&cPoints[i](0),sizeof(DataType));
00490 ifs.read((char*)&cPoints[i](1),sizeof(DataType));
00491 ifs.read((char*)&cPoints[i](2),sizeof(DataType));
00492 }
00493 for (register int i=0; i < num_connections; i++) {
00494 ifs.read((char*)&(connectivity[i].cPid[0]),sizeof(int));
00495 ifs.read((char*)&(connectivity[i].cPid[1]),sizeof(int));
00496 }
00497 for (register int i=0; i < num_velocities; i++) {
00498 ifs.read((char*)&velocities_loc[i](0),sizeof(DataType));
00499 ifs.read((char*)&velocities_loc[i](1),sizeof(DataType));
00500 ifs.read((char*)&velocities_loc[i](2),sizeof(DataType));
00501 }
00502 pos = ifs.tellg();
00503
00504 }
00505
00506 virtual void Checkpointing(std::ofstream& ofs) {
00507 #ifdef CHECKRESTART_DEBUG_ON
00508 ( mklog() << "\nCHECKPOINTING Curve " << Name() << std::endl).flush();
00509 #endif
00510
00511 num_cPoints_org=cPoints_org.size();
00512 num_cPoints=cPoints.size();
00513 num_connections=connectivity.size();
00514 num_velocities=velocities_loc.size();
00515 #ifdef CHECKRESTART_DEBUG_ON
00516 ( mklog() << " num_cPoints_org " << num_cPoints_org << " num_cPoints " << num_cPoints
00517 << " num_connections " << num_connections << " num_velocities " << num_velocities << std::endl).flush();
00518 #endif
00519 ofs.write((char*)&num_cPoints_org,sizeof(int));
00520 ofs.write((char*)&num_cPoints,sizeof(int));
00521 ofs.write((char*)&num_connections,sizeof(int));
00522 ofs.write((char*)&num_velocities,sizeof(int));
00523 for (register int i=0; i < num_cPoints_org; i++) {
00524 ofs.write((char*)&cPoints_org[i](0),sizeof(DataType));
00525 ofs.write((char*)&cPoints_org[i](1),sizeof(DataType));
00526 ofs.write((char*)&cPoints_org[i](2),sizeof(DataType));
00527 }
00528 for (register int i=0; i < num_cPoints; i++) {
00529 ofs.write((char*)&cPoints[i](0),sizeof(DataType));
00530 ofs.write((char*)&cPoints[i](1),sizeof(DataType));
00531 ofs.write((char*)&cPoints[i](2),sizeof(DataType));
00532 }
00533 for (register int i=0; i < num_connections; i++) {
00534 ofs.write((char*)&(connectivity[i].cPid[0]),sizeof(int));
00535 ofs.write((char*)&(connectivity[i].cPid[1]),sizeof(int));
00536 }
00537 for (register int i=0; i < num_velocities; i++) {\
00538 ofs.write((char*)&velocities_loc[i](0),sizeof(DataType));
00539 ofs.write((char*)&velocities_loc[i](1),sizeof(DataType));
00540 ofs.write((char*)&velocities_loc[i](2),sizeof(DataType));
00541 }
00542
00543 }
00544
00545 virtual void pressureForce(multi_index_type* cons, DataType* press, DataType scale ) {
00546 ( mklog() << "pressureForce() Curve " << PartType::Name() << std::endl).flush();
00547 }
00548
00549 virtual void logLoad( std::ofstream& ofs, DataType time_, int step ) {
00550
00551 }
00552
00553 protected:
00554 DataType Clength;
00555 std::string name;
00556 bool closed;
00557 PType centroid;
00558 std::vector<PType> cPoints_org;
00559 std::vector<PType> cPoints;
00560 std::vector<SegType> connectivity;
00561 std::vector<PType> velocities_loc;
00562 int num_cPoints_org, num_cPoints, num_connections, num_velocities;
00563 };
00564
00565 #endif // CURVE_H