00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include "charm++.h"
00013 #include "patch.h"
00014
00015 static void abort(const char *why) {
00016 fprintf(stderr,"Fatal error reading patch: %s\n",why);
00017 exit(1);
00018 }
00019
00020 class patchReader {
00021 const char *fName;
00022 FILE *f;
00023 int lineCount;
00024 char line[1024];
00025 int curChar;
00026
00027 void abort(const char *why) {
00028 CkError("Fatal error reading patch description: %s\n",why);
00029 CkError(" while parsing line %d of file '%s'.\n",lineCount,fName);
00030 CkExit();
00031 }
00032 public:
00033 patchReader(const char *fileName) {
00034 lineCount=0; fName=fileName;
00035 f=fopen(fileName,"r");
00036 if (f==NULL) {
00037 CkError("Couldn't open patch file '%s'!\n",fileName);
00038 CkExit();
00039 }
00040 nextLine();
00041 }
00042 ~patchReader() {fclose(f);}
00043
00044
00045 int nextLine(void) {
00046 while (NULL!=fgets(line,1024,f)) {
00047 curChar=0;
00048 lineCount++;
00049 if (line[0]=='#' || line[0]=='!') continue;
00050 strtok(line,"!#");
00051 if (line[0]==0 || line[0]=='\n') continue;
00052 return 1;
00053 }
00054 return 0;
00055 }
00056
00057
00058 int nextInt(void) {
00059 int ret=0,offset=0;
00060 if (sscanf(&line[curChar],"%d%n",&ret,&offset)<1)
00061 abort("couldn't parse int");
00062 curChar+=offset;
00063 return ret;
00064 }
00065
00066 double nextDouble(void) {
00067 double ret=0.0;
00068 int offset=0;
00069 if (sscanf(&line[curChar],"%lg%n",&ret,&offset)<1)
00070 abort("couldn't parse double");
00071 curChar+=offset;
00072 return ret;
00073 }
00074
00075 blockDim nextDim(void) {
00076 blockDim ret;
00077 for (int axis=0;axis<3;axis++)
00078 ret[axis]=nextInt();
00079 return ret;
00080 }
00081
00082 blockSpan nextSpan(void) {
00083 blockSpan ret;
00084 for (int axis=0;axis<3;axis++) {
00085 ret.start[axis]=nextInt();
00086 ret.end[axis]=nextInt();
00087 }
00088 return ret;
00089 }
00090 };
00091
00092
00093 block::block(const char *filePrefix,int blockNo)
00094 {
00095 char fName[1024];
00096
00097
00098 sprintf(fName,"%s%05d.bblk",filePrefix,blockNo);
00099 {
00100 patchReader f(fName);
00101 double version=f.nextDouble(); f.nextLine();
00102 if (version>=2.0) abort("Incompatible block version!\n");
00103 int blockNo=f.nextInt(); dim=f.nextDim(); f.nextLine();
00104 int nFaces=f.nextInt(); nPatches=f.nextInt(); f.nextLine();
00105 typedef patch *patchPtr;
00106 patches=new patchPtr[nPatches];
00107 int curPatch=0;
00108 for (int fc=0;fc<nFaces;fc++)
00109 {
00110 int nP=f.nextInt();f.nextLine();
00111 for (int pc=0;pc<nP;pc++)
00112 {
00113 int type=f.nextInt();
00114 blockSpan span=f.nextSpan();
00115 f.nextLine();
00116 patch *p;
00117 if (type==-1) {
00118 int destBlock=f.nextInt();
00119 int destPatch=f.nextInt();
00120 int orient[3];
00121 for (int axis=0;axis<3;axis++)
00122 orient[axis]=f.nextInt();
00123 f.nextLine();
00124 p=new internalBCpatch(destBlock,destPatch,orient, span);
00125 }
00126 else
00127 p=new externalBCpatch(span,type);
00128 patches[curPatch++]=p;
00129 }
00130 }
00131 if (curPatch!=nPatches) abort("Didn't define all patches!");
00132 }
00133
00134
00135 sprintf(fName,"%s%05d.mblk",filePrefix,blockNo);
00136 FILE *fm=fopen(fName,"r");
00137 if (fm==NULL) abort("Can't open .mblk file!");
00138 int sizes;
00139 if (3!=fscanf(fm,"%d%d%d",&sizes,&sizes,&sizes)) abort("Can't parse .mblk file's header");
00140 locs=new vector3d[dim.getSize()];
00141 blockLoc i;
00142 BLOCKSPAN_FOR(i,blockSpan(blockLoc(0,0,0),dim)) {
00143 double x,y,z;
00144 if (3!=fscanf(fm,"%lf%lf%lf",&x,&y,&z)) abort("Can't parse .mblk file's location");
00145 locs[dim[i]]=vector3d(x,y,z);
00146 }
00147 fclose(fm);
00148 }
00149
00150 block::~block() {
00151 delete[] locs;
00152 for (int p=0;p<nPatches;p++)
00153 delete patches[p];
00154 delete[] patches;
00155 }
00156
00157 orientation::orientation(const int *codedOrient)
00158 {
00159 for (int axis=0;axis<3;axis++) {
00160 int code=codedOrient[axis];
00161 flip[axis]=(code<0);
00162 if (flip[axis]) code=-code;
00163 s2d[axis]=code-1;
00164 }
00165 }
00166
00167 patch::patch(const blockSpan &span_)
00168 :span(span_)
00169 {
00170 flatAxis=span.getFlatAxis();
00171 isLow=(span.start[flatAxis]==0);
00172 }
00173
00174
00175 blockSpan patch::getExtents(const extrudeMethod &m,bool forVoxel,int dir)
00176 {
00177
00178 blockLoc s=span.start;
00179 blockLoc e=span.end;
00180
00181
00182 int w=m.toWidth*dir;
00183 if (isLow) w=-w;
00184 if (w<0) s[flatAxis]+=w;
00185 else e[flatAxis]+=w;
00186
00187
00188 if (w<0) w=-w;
00189 if (m.withCorners) {
00190 for (int axis=0;axis<3;axis++)
00191 if (axis!=flatAxis) {
00192 s[axis]-=w;
00193 e[axis]+=w;
00194 }
00195 }
00196
00197
00198 if (forVoxel) {
00199 e=e-blockLoc(1,1,1);
00200 } else {
00201 if (isLow) e[flatAxis]--;
00202 else s[flatAxis]++;
00203 }
00204 return blockSpan(s,e);
00205 }
00206
00207