00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "CellBoundaryTrackerPlugin.h"
00024
00025 #include <CompuCell3D/Simulator.h>
00026 #include <CompuCell3D/Potts3D/Potts3D.h>
00027 #include <CompuCell3D/Field3D/AdjacentNeighbor.h>
00028 #include <CompuCell3D/plugins/Volume/VolumePlugin.h>
00029 #include <CompuCell3D/plugins/Volume/VolumeEnergy.h>
00030
00031 using namespace CompuCell3D;
00032
00033 #include <XMLCereal/XMLPullParser.h>
00034 #include <XMLCereal/XMLSerializer.h>
00035
00036 #include <iostream>
00037 #include <cmath>
00038 using namespace std;
00039
00040 CellBoundaryTrackerPlugin::CellBoundaryTrackerPlugin() :
00041 cellFieldG(0),
00042 periodicX(false),
00043 periodicY(false),
00044 periodicZ(false)
00045 {}
00046
00047 CellBoundaryTrackerPlugin::~CellBoundaryTrackerPlugin() {
00048
00049 }
00050
00051 void CellBoundaryTrackerPlugin::init(Simulator *_simulator) {
00052
00053 cout<<"INITIALIZING CELL BOUNDARYTRACKER PLUGIN"<<endl;
00054 simulator=_simulator;
00055 Potts3D *potts = simulator->getPotts();
00056 cellFieldG = potts->getCellFieldG();
00057
00058
00060 BasicClassAccessorBase * cellBTAPtr=&cellBoundaryTrackerAccessor;
00064 potts->getCellFactoryGroupPtr()->registerClass(cellBTAPtr);
00065
00066
00067
00068
00069
00070 potts->registerCellGChangeWatcher(this);
00071
00072 fieldDim=cellFieldG->getDim();
00073
00074 adjNeighbor = AdjacentNeighbor(fieldDim);
00075 if(potts->getBoundaryXName()=="Periodic"){
00076 adjNeighbor.setPeriodicX();
00077 periodicX=true;
00078 }
00079 if(potts->getBoundaryYName()=="Periodic"){
00080 adjNeighbor.setPeriodicY();
00081 periodicY=true;
00082 }
00083 if(potts->getBoundaryZName()=="Periodic"){
00084 adjNeighbor.setPeriodicZ();
00085 periodicZ=true;
00086 }
00087
00088
00089
00090 maxIndex=adjNeighbor.getField3DIndex().getMaxIndex();
00091
00092
00093 }
00094
00096
00097 void CellBoundaryTrackerPlugin::field3DChange(const Point3D &pt, CellG *newCell,
00098 CellG *oldCell) {
00099
00100
00101
00102
00103
00104
00105
00106
00107 if(newCell==oldCell){
00108 return;
00109 }
00110
00111
00112 vector<Point3D> const & adjNeighborOffsetsVec_inn=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
00113 unsigned int neighborSize=adjNeighborOffsetsVec_inn.size();
00114
00115 const vector<Point3D> & adjFace2FaceNeighborOffsetsVec_inn=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
00116 unsigned int face2FaceNeighborSize=adjFace2FaceNeighborOffsetsVec_inn.size();
00117
00118
00119
00120
00121 const Field3DIndex & field3DIndex=adjNeighbor.getField3DIndex();
00122
00123 long currentPtIndex=0;
00124 long adjNeighborIndex=0;
00125 long adjFace2FaceNeighborIndex=0;
00126
00127 CellG * currentCellPtr=0;
00128 CellG * adjCellPtr=0;
00129
00130 unsigned int token = 0;
00131 double distance;
00132 int oldDiff = 0;
00133 int newDiff = 0;
00134 Point3D n;
00135 Point3D ptAdj;
00136 CellG *nCell=0;
00137
00138
00139
00140
00141 set<BoundaryData> * oldCellBoundarySetPtr=0;
00142 set<BoundaryData> * newCellBoundarySetPtr=0;
00143 set<BoundaryData>::iterator BdSitr;
00144 set<BoundaryData>::iterator BdSitrN;
00145 set<BoundaryData>::iterator InsSitr;
00146 pair<set<BoundaryData>::iterator,bool> InsSitrOKPair;
00147
00148 set<NeighborSurfaceData> * oldCellNeighborSurfaceDataSetPtr=0;
00149 set<NeighborSurfaceData> * newCellNeighborSurfaceDataSetPtr=0;
00150 pair<set<NeighborSurfaceData>::iterator,bool > set_NSD_itr_OK_Pair;
00151 set<NeighborSurfaceData>::iterator set_NSD_itr;
00152
00153
00154 if(newCell){
00155 newCellBoundarySetPtr= & cellBoundaryTrackerAccessor.get(newCell->extraAttribPtr)->boundary;
00156 newCellNeighborSurfaceDataSetPtr = &cellBoundaryTrackerAccessor.get(newCell->extraAttribPtr)->cellNeighbors;
00157 }
00158
00159 if(oldCell){
00160 oldCellBoundarySetPtr= & cellBoundaryTrackerAccessor.get(oldCell->extraAttribPtr)->boundary;
00161 oldCellNeighborSurfaceDataSetPtr = &cellBoundaryTrackerAccessor.get(oldCell->extraAttribPtr)->cellNeighbors;
00162 }
00163
00164
00165 currentPtIndex=field3DIndex.index(pt);
00166 currentCellPtr=cellFieldG->getByIndex(currentPtIndex);
00167
00168
00169
00170
00171
00172
00173 if(oldCell){
00175
00176
00177
00178
00179 BdSitr=oldCellBoundarySetPtr->find(BoundaryData(currentPtIndex));
00180
00181 if(BdSitr!=oldCellBoundarySetPtr->end()){
00182
00183
00184 oldCellBoundarySetPtr->erase(BdSitr);
00185
00187
00188
00189
00190
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 for(int i = 0 ; i < neighborSize ; ++i){
00202 ptAdj=pt;
00203 ptAdj+=adjNeighborOffsetsVec_inn[i];
00204
00205 adjNeighborIndex=field3DIndex.index(ptAdj);
00206
00207
00208
00209 if(cellFieldG->isValid(ptAdj)){
00210
00211
00212 adjCellPtr=cellFieldG->get(ptAdj);
00213
00214
00215 if(adjCellPtr==oldCell){
00216
00217 BdSitr=oldCellBoundarySetPtr->find(BoundaryData(adjNeighborIndex));
00218 if(BdSitr!=oldCellBoundarySetPtr->end()){
00219 BdSitr->incrementNumberOfForeignNeighbors(*BdSitr);
00220 }else{
00221 oldCellBoundarySetPtr->insert(BoundaryData(adjNeighborIndex,1));
00222 }
00223
00224
00225 }
00226
00227 }
00228 }
00229
00230
00232 long temp_index;
00233 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
00234 ptAdj=pt;
00235 ptAdj+=adjFace2FaceNeighborOffsetsVec_inn[i];
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 if(cellFieldG->isValid(ptAdj)){
00251
00252
00253 adjCellPtr=cellFieldG->get(ptAdj);
00254
00255 if( adjCellPtr != oldCell ){
00256
00257
00258 set_NSD_itr = oldCellNeighborSurfaceDataSetPtr->find(NeighborSurfaceData(adjCellPtr));
00259 if( set_NSD_itr != oldCellNeighborSurfaceDataSetPtr->end() ){
00260 set_NSD_itr->decrementCommonSurfaceArea(*set_NSD_itr);
00261 if(set_NSD_itr->OKToRemove())
00262 oldCellNeighborSurfaceDataSetPtr->erase(set_NSD_itr);
00263
00264 }else{
00265 cerr<<"Could not find cell address in the boundary - set of cellNeighbors is corrupted. Exiting ..."<<endl;
00266 exit(0);
00267 }
00268
00269
00270 if(adjCellPtr){
00271 set<NeighborSurfaceData> &set_NSD_ref = cellBoundaryTrackerAccessor.get(adjCellPtr->extraAttribPtr)->cellNeighbors;
00272 set<NeighborSurfaceData>::iterator sitr;
00273 sitr=set_NSD_ref.find(oldCell);
00274 if(sitr!=set_NSD_ref.end()){
00275 sitr->decrementCommonSurfaceArea(*sitr);
00276 if(sitr->OKToRemove())
00277 set_NSD_ref.erase(sitr);
00278
00279 }
00280 }
00281 }
00282 }
00283
00284
00285 }
00286 }
00287
00288 if(newCell){
00289
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 BdSitrN=newCellBoundarySetPtr->find(BoundaryData(currentPtIndex));
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 InsSitrOKPair=(newCellBoundarySetPtr->insert(BoundaryData(currentPtIndex,0)));
00314
00315
00316 InsSitr=InsSitrOKPair.first;
00317
00318 for(int i = 0 ; i < neighborSize ; ++i){
00319
00320 ptAdj=pt;
00321 ptAdj+=adjNeighborOffsetsVec_inn[i];
00322
00323 adjNeighborIndex=field3DIndex.index(ptAdj);
00324
00325 if(cellFieldG->isValid(ptAdj)){
00326
00327
00328 adjCellPtr=cellFieldG->get(ptAdj);
00329
00330 if(adjCellPtr == newCell){
00331 BdSitrN = newCellBoundarySetPtr->find(BoundaryData(adjNeighborIndex));
00332 if(BdSitrN != newCellBoundarySetPtr->end() ) {
00333 BdSitrN->decrementNumberOfForeignNeighbors(*BdSitrN);
00334 if(BdSitrN->OKToRemove()){
00335 newCellBoundarySetPtr->erase(BdSitrN);
00336
00337 }
00338 }
00339
00340 }else{
00341 InsSitr->incrementNumberOfForeignNeighbors(*InsSitr);
00342 }
00343
00344 }else{
00345
00346
00349
00350 InsSitr->incrementNumberOfForeignNeighbors(*InsSitr);
00351 }
00352
00353
00354 }
00355 if(InsSitr->numberOfForeignNeighbors==0){
00356 newCellBoundarySetPtr->erase(InsSitr);
00357 }
00358
00360 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
00361 ptAdj=pt;
00362 ptAdj+=adjFace2FaceNeighborOffsetsVec_inn[i];
00363 adjFace2FaceNeighborIndex=field3DIndex.index(ptAdj);
00364
00365
00366
00367
00368 if(cellFieldG->isValid(ptAdj)){
00369
00370
00371 adjCellPtr=cellFieldG->get(ptAdj);
00372
00373 if( adjCellPtr != newCell ){
00374
00375 set_NSD_itr_OK_Pair=newCellNeighborSurfaceDataSetPtr->insert(NeighborSurfaceData(adjCellPtr));
00376
00377
00378 set_NSD_itr=set_NSD_itr_OK_Pair.first;
00379 set_NSD_itr->incrementCommonSurfaceArea(*set_NSD_itr);
00380
00381 if(adjCellPtr){
00382 set<NeighborSurfaceData> &set_NSD_ref = cellBoundaryTrackerAccessor.get(adjCellPtr->extraAttribPtr)->cellNeighbors;
00383 pair<set<NeighborSurfaceData>::iterator,bool> sitr_OK_pair=set_NSD_ref.insert(newCell);
00384 set<NeighborSurfaceData>::iterator sitr=sitr_OK_pair.first;
00385 sitr->incrementCommonSurfaceArea(*sitr);
00386 }
00387
00388 }
00389
00390 }
00391
00392
00393 }
00394 }
00395
00396
00397 if(!oldCell){
00398
00399
00401 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
00402 ptAdj=pt;
00403 ptAdj+=adjFace2FaceNeighborOffsetsVec_inn[i];
00404
00405 adjFace2FaceNeighborIndex = field3DIndex.index(ptAdj);
00406
00407
00408
00409
00410
00411 if(cellFieldG->isValid(ptAdj)){
00412
00413
00414 adjCellPtr=cellFieldG->get(ptAdj);
00415
00416 if( adjCellPtr != oldCell && !(ptAdj == pt)){
00417
00418 if(adjCellPtr){
00419 set<NeighborSurfaceData> &set_NSD_ref = cellBoundaryTrackerAccessor.get(adjCellPtr->extraAttribPtr)->cellNeighbors;
00420 set<NeighborSurfaceData>::iterator sitr;
00421 sitr=set_NSD_ref.find(oldCell);
00422 if(sitr!=set_NSD_ref.end()){
00423 sitr->decrementCommonSurfaceArea(*sitr);
00424 if(sitr->OKToRemove()){
00425 set_NSD_ref.erase(sitr);
00426
00427
00428 }
00429
00430 }
00431 }
00432 }
00433 }
00434
00435
00436 }
00437
00438
00439 }
00440
00441 if(!newCell){
00442
00443
00444 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
00445 ptAdj=pt;
00446 ptAdj+=adjFace2FaceNeighborOffsetsVec_inn[i];
00447
00448
00449
00450
00451
00452 if(cellFieldG->isValid(ptAdj)){
00453
00454
00455
00456 adjCellPtr=cellFieldG->get(ptAdj);
00457
00458 if( adjCellPtr != newCell ){
00459
00460 if(adjCellPtr){
00461 set<NeighborSurfaceData> &set_NSD_ref = cellBoundaryTrackerAccessor.get(adjCellPtr->extraAttribPtr)->cellNeighbors;
00462 pair<set<NeighborSurfaceData>::iterator,bool> sitr_OK_pair=set_NSD_ref.insert(newCell);
00463 set<NeighborSurfaceData>::iterator sitr=sitr_OK_pair.first;
00464 sitr->incrementCommonSurfaceArea(*sitr);
00465 }
00466
00467 }
00468
00469 }
00470
00471
00472 }
00473
00474 }
00475
00476
00477
00478
00479
00480
00481
00483
00484
00485 ++changeCounter;
00486 int interval;
00487 if(changeCounter>1){
00488 interval=100000;
00489 }else{
00490 interval=100000;
00491 }
00492 if(!(changeCounter % interval)){
00493 cerr<<"OLD CELL ADR: "<<oldCell<<" NEW CELL ADR: "<<newCell<<endl;
00494 cerr<<"ChangeCounter:"<<changeCounter<<endl;
00495 testLatticeSanityFull();
00496
00497 }
00498
00499
00500
00501 }
00502
00504
00505 void CellBoundaryTrackerPlugin::initializeBoundaries(){
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 }
00652
00653
00656
00657 void CellBoundaryTrackerPlugin::testLatticeSanity(){
00658
00659 set<CellG *> set_of_visited_cells;
00660
00661 Dim3D fieldDim=cellFieldG->getDim();
00662
00663
00664
00665
00666 const Field3DIndex & field3DIndex=adjNeighbor.getField3DIndex();
00667 Point3D pt(0,0,0);
00668 Point3D ptAdj;
00669 Point3D ptBoundary;
00670
00671
00672
00673
00674
00675
00676
00677
00678 long currentPtIndex=0;
00679 long adjNeighborIndex=0;
00680 long adjFace2FaceNeighborIndex=0;
00681
00682
00683
00685
00686
00687 CellG * currentCellPtr;
00688 CellG * adjCellPtr;
00689 int localNeighborCounter=0;
00690 int localCommonSurfaceArea=0;
00691 set<BoundaryData>::iterator bdsitr;
00692 set<NeighborSurfaceData>::iterator nsdsitr;
00693
00694 bool isInBoundary=false;
00695 bool inInNeighborSurfaceData=false;
00696
00697 for(int z=0 ; z < fieldDim.z ; ++z)
00698 for(int y=0 ; y < fieldDim.y ; ++y)
00699 for(int x=0 ; x < fieldDim.x ; ++x){
00700
00701 pt.x=x;
00702 pt.y=y;
00703 pt.z=z;
00704
00705 currentPtIndex=field3DIndex.index(pt);
00706
00707 currentCellPtr=cellFieldG->get(pt);
00708
00709 const vector<Point3D> & adjNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
00710 int neighborSize=adjNeighborOffsetsVec.size();
00711
00712 const vector<Point3D> & adjFace2FaceNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
00713 int face2FaceNeighborSize=adjFace2FaceNeighborOffsetsVec.size();
00714
00715
00716
00717 if(!currentCellPtr)
00718 continue;
00719
00721 set<BoundaryData> & set_ref=cellBoundaryTrackerAccessor.get(currentCellPtr->extraAttribPtr)->boundary;
00722
00723
00724
00725
00727 localNeighborCounter=0;
00728 isInBoundary=false;
00729
00731 for(int i = 0 ; i < neighborSize ; ++i){
00732 ptAdj=pt;
00733 ptAdj+=adjNeighborOffsetsVec[i];
00734 adjNeighborIndex=field3DIndex.index(ptAdj);
00735
00736
00737
00738 if(cellFieldG->isValid(ptAdj)){
00739
00740
00741
00742
00743 adjCellPtr=cellFieldG->get(ptAdj);
00744
00745 if( adjCellPtr != currentCellPtr ){
00746 ++localNeighborCounter;
00748 isInBoundary=true;
00749 }
00750
00751 }
00752 }
00753
00754
00756 localCommonSurfaceArea=0;
00757 inInNeighborSurfaceData=false;
00758
00759 set<NeighborSurfaceData> & set_NSD_ref=cellBoundaryTrackerAccessor.get(currentCellPtr->extraAttribPtr)->cellNeighbors;
00760
00761 if(set_of_visited_cells.find(currentCellPtr)!=set_of_visited_cells.end()){
00762 continue;
00763 }else
00764 {
00765 set_of_visited_cells.insert(currentCellPtr);
00766 long indexBoundary;
00767
00768 set<NeighborSurfaceData> set_NSD_local;
00769 pair<set<NeighborSurfaceData>::iterator,bool > set_NSD_itr_OK_Pair;
00770 set<NeighborSurfaceData>::iterator set_NSD_itr;
00771
00772 for(set<BoundaryData>::iterator sitr = set_ref.begin() ; sitr !=set_ref.end() ; ++sitr){
00773
00774 indexBoundary=sitr->pixelIndex;
00775 ptBoundary=field3DIndex.index2Point(indexBoundary);
00777 const vector<Point3D> & adjFace2FaceNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(ptBoundary);
00778 int face2FaceNeighborSize=adjFace2FaceNeighborOffsetsVec.size();
00779
00780 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
00781 ptAdj=ptBoundary;
00782 ptAdj+=adjFace2FaceNeighborOffsetsVec[i];
00783 adjFace2FaceNeighborIndex=field3DIndex.index(ptAdj);
00784
00785
00786
00787
00788 if(cellFieldG->isValid(ptAdj)){
00789
00790
00791 adjCellPtr=cellFieldG->get(ptAdj);
00792
00793 if( adjCellPtr != currentCellPtr ){
00794
00795 set_NSD_itr_OK_Pair=set_NSD_local.insert(NeighborSurfaceData(adjCellPtr));
00796 set_NSD_itr=set_NSD_itr_OK_Pair.first;
00797 set_NSD_itr->incrementCommonSurfaceArea(*set_NSD_itr);
00798
00799
00800 }
00801
00802 }
00803
00804 }
00805
00806
00807 }
00808
00810
00811 if(set_NSD_local.size()!=set_NSD_ref.size()){
00812 cerr<<"Sets have different sizes - orig:"<<set_NSD_ref.size()<<" local:"<<set_NSD_local.size()<<
00813 " . Exining..."<<endl;
00814 exit(0);
00815
00816 }
00817
00818
00819
00820 set<NeighborSurfaceData>::iterator sitr_local=set_NSD_local.begin();
00821 for(set<NeighborSurfaceData>::iterator sitr=set_NSD_ref.begin() ; sitr!=set_NSD_ref.end() ; ++sitr ){
00822
00823
00824 if(sitr_local->neighborAddress!=sitr->neighborAddress){
00825 cerr<<"Neighbor addresses - orig: "<<sitr->neighborAddress<<" local:"<<sitr_local->neighborAddress<<
00826 " do not match. Exiting "<<endl;
00827 exit(0);
00828 }
00829 if(sitr_local->commonSurfaceArea!=sitr->commonSurfaceArea){
00830 cerr<<"Neighbor commonSurfaceArea - orig: "<<sitr->commonSurfaceArea<<" local:"<<sitr_local->commonSurfaceArea<<
00831 " do not match. Exiting "<<endl;
00832 exit(0);
00833 }
00835
00836 ++sitr_local;
00837 }
00838
00839
00840
00841 }
00842
00845 if(isInBoundary){
00846 bdsitr=set_ref.find(BoundaryData(currentPtIndex) );
00847
00848 if(bdsitr==set_ref.end()){
00849 cerr<<"Requested pixel:"<<currentPtIndex<< " was not found in the boundary set. Boundary corrupted. Exiting..."<<endl;
00850 cerr<<"Tried address "<<currentCellPtr<<endl;
00851 exit(0);
00852 }else if(bdsitr->numberOfForeignNeighbors!=localNeighborCounter){
00853 cerr<<"Different Number of foreign neighbors - orig="<<bdsitr->numberOfForeignNeighbors
00854 <<" instant init="<<localNeighborCounter<<endl;
00855 cerr<<"Tried address "<<currentCellPtr<<endl;
00856 exit(0);
00857 }else if((bdsitr->numberOfForeignNeighbors) > 26){
00858 cerr<<"Number of fN's is "<<bdsitr->numberOfForeignNeighbors<<" but allowed value is 26 "<<endl;
00859 exit(0);
00860
00861 }else{
00862
00863
00864
00865 }
00866 }
00867
00868
00869
00870
00871
00872 }
00873
00874 cerr<<"LATTICE IS SANE!!!!!"<<endl;
00875
00876 }
00877
00878
00880 double distance(double x1,double y1,double z1,double x2,double y2,double z2){
00881 return sqrt (
00882 (x1-x2)*(x1-x2)+
00883 (y1-y2)*(y1-y2)+
00884 (z1-z2)*(z1-z2)
00885 );
00886 }
00887
00889 void CellBoundaryTrackerPlugin::readXML(XMLPullParser &in) {
00890
00891 }
00892
00893 void CellBoundaryTrackerPlugin::writeXML(XMLSerializer &out) {
00894
00895 }
00896
00897
00899
00900 void CellBoundaryTrackerPlugin::testLatticeSanityFull(){
00901
00902 set<CellG *> set_of_visited_cells;
00903
00904 Dim3D fieldDim=cellFieldG->getDim();
00905
00906
00907
00908
00909 const Field3DIndex & field3DIndex=adjNeighbor.getField3DIndex();
00910 Point3D pt(0,0,0);
00911 Point3D ptAdj;
00912 Point3D ptBoundary;
00913
00914
00915
00916
00917
00918
00919
00920
00921 long currentPtIndex=0;
00922 long adjNeighborIndex=0;
00923 long adjFace2FaceNeighborIndex=0;
00924
00925
00926
00928
00929
00930 CellG * currentCellPtr;
00931 CellG * adjCellPtr;
00932 int localNeighborCounter=0;
00933 int localCommonSurfaceArea=0;
00934 set<BoundaryData>::iterator bdsitr;
00935 set<NeighborSurfaceData>::iterator nsdsitr;
00936
00937 bool isInBoundary=false;
00938 bool inInNeighborSurfaceData=false;
00939
00940 map<CellG*,set<BoundaryData> > mapCellBoundaryData;
00941 map<CellG*,set<BoundaryData> >::iterator mitr;
00942
00944 for(int z=0 ; z < fieldDim.z ; ++z)
00945 for(int y=0 ; y < fieldDim.y ; ++y)
00946 for(int x=0 ; x < fieldDim.x ; ++x){
00947 pt.x=x;
00948 pt.y=y;
00949 pt.z=z;
00950 currentPtIndex=field3DIndex.index(pt);
00951
00952 currentCellPtr=cellFieldG->get(pt);
00953 if(!currentCellPtr)
00954 continue;
00955
00956
00957
00958 if(isBoundaryPixel(pt)){
00959 mitr=mapCellBoundaryData.find(currentCellPtr);
00960
00961 if(mitr != mapCellBoundaryData.end() ){
00962 mitr->second.insert(BoundaryData(currentPtIndex));
00963 }else{
00964 set<BoundaryData> tmpSet;
00965 tmpSet.insert(BoundaryData(currentPtIndex));
00966 mapCellBoundaryData.insert(make_pair(currentCellPtr,tmpSet));
00967 }
00968 }
00969
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 for(int z=0 ; z < fieldDim.z ; ++z)
01011 for(int y=0 ; y < fieldDim.y ; ++y)
01012 for(int x=0 ; x < fieldDim.x ; ++x){
01013
01014 pt.x=x;
01015 pt.y=y;
01016 pt.z=z;
01017
01018 currentPtIndex=field3DIndex.index(pt);
01019
01020 currentCellPtr=cellFieldG->get(pt);
01021
01022 const vector<Point3D> & adjNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
01023 int neighborSize=adjNeighborOffsetsVec.size();
01024
01025 const vector<Point3D> & adjFace2FaceNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
01026 int face2FaceNeighborSize=adjFace2FaceNeighborOffsetsVec.size();
01027
01028
01029
01030 if(!currentCellPtr)
01031 continue;
01032
01034 set<BoundaryData> & set_ref=cellBoundaryTrackerAccessor.get(currentCellPtr->extraAttribPtr)->boundary;
01035
01036
01037
01038
01040 localNeighborCounter=0;
01041 isInBoundary=false;
01042
01044 for(int i = 0 ; i < neighborSize ; ++i){
01045 ptAdj=pt;
01046 ptAdj+=adjNeighborOffsetsVec[i];
01047 adjNeighborIndex=field3DIndex.index(ptAdj);
01048
01049
01050
01051 if(cellFieldG->isValid(ptAdj)){
01052
01053
01054
01055
01056 adjCellPtr=cellFieldG->get(ptAdj);
01057
01058 if( adjCellPtr != currentCellPtr ){
01059 ++localNeighborCounter;
01061 isInBoundary=true;
01062 }
01063
01064 }else{
01065
01066 ++localNeighborCounter;
01068 isInBoundary=true;
01069
01070
01071 }
01072 }
01073
01074
01076 localCommonSurfaceArea=0;
01077 inInNeighborSurfaceData=false;
01078
01079 set<NeighborSurfaceData> & set_NSD_ref=cellBoundaryTrackerAccessor.get(currentCellPtr->extraAttribPtr)->cellNeighbors;
01080
01081 if(set_of_visited_cells.find(currentCellPtr)!=set_of_visited_cells.end()){
01082 continue;
01083 }else
01084 {
01085 set_of_visited_cells.insert(currentCellPtr);
01086 long indexBoundary;
01087
01088 set<NeighborSurfaceData> set_NSD_local;
01089 pair<set<NeighborSurfaceData>::iterator,bool > set_NSD_itr_OK_Pair;
01090 set<NeighborSurfaceData>::iterator set_NSD_itr;
01091
01092 for(set<BoundaryData>::iterator sitr = set_ref.begin() ; sitr !=set_ref.end() ; ++sitr){
01093
01094 indexBoundary=sitr->pixelIndex;
01095 ptBoundary=field3DIndex.index2Point(indexBoundary);
01097 const vector<Point3D> & adjFace2FaceNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(ptBoundary);
01098 int face2FaceNeighborSize=adjFace2FaceNeighborOffsetsVec.size();
01099
01100 for(int i = 0 ; i < face2FaceNeighborSize ; ++i){
01101 ptAdj=ptBoundary;
01102 ptAdj+=adjFace2FaceNeighborOffsetsVec[i];
01103 adjFace2FaceNeighborIndex=field3DIndex.index(ptAdj);
01104
01105
01106
01107
01108 if(cellFieldG->isValid(ptAdj)){
01109
01110
01111 adjCellPtr=cellFieldG->get(ptAdj);
01112
01113 if( adjCellPtr != currentCellPtr ){
01114
01115 set_NSD_itr_OK_Pair=set_NSD_local.insert(NeighborSurfaceData(adjCellPtr));
01116 set_NSD_itr=set_NSD_itr_OK_Pair.first;
01117 set_NSD_itr->incrementCommonSurfaceArea(*set_NSD_itr);
01118
01119
01120 }
01121
01122 }
01123
01124 }
01125
01126
01127 }
01128
01130
01131 if(set_NSD_local.size()!=set_NSD_ref.size()){
01132 cerr<<"Sets have different sizes - orig:"<<set_NSD_ref.size()<<" local:"<<set_NSD_local.size()<<
01133 " . Exining..."<<endl;
01134 exit(0);
01135
01136 }
01137
01138
01139
01140 set<NeighborSurfaceData>::iterator sitr_local=set_NSD_local.begin();
01141 for(set<NeighborSurfaceData>::iterator sitr=set_NSD_ref.begin() ; sitr!=set_NSD_ref.end() ; ++sitr ){
01142
01143
01144 if(sitr_local->neighborAddress!=sitr->neighborAddress){
01145 cerr<<"Neighbor addresses - orig: "<<sitr->neighborAddress<<" local:"<<sitr_local->neighborAddress<<
01146 " do not match. Exiting "<<endl;
01147 exit(0);
01148 }
01149 if(sitr_local->commonSurfaceArea!=sitr->commonSurfaceArea){
01150 cerr<<"Neighbor commonSurfaceArea - orig: "<<sitr->commonSurfaceArea<<" local:"<<sitr_local->commonSurfaceArea<<
01151 " do not match. Exiting "<<endl;
01152 exit(0);
01153 }
01155
01156 ++sitr_local;
01157 }
01158
01159
01160
01161 }
01162
01165 if(isInBoundary){
01166 bdsitr=set_ref.find(BoundaryData(currentPtIndex) );
01167
01168 if(bdsitr==set_ref.end()){
01169 cerr<<"Requested pixel:"<<currentPtIndex<< " was not found in the boundary set. Boundary corrupted. Exiting..."<<endl;
01170 cerr<<"Tried address "<<currentCellPtr<<endl;
01171 exit(0);
01172 }else if(bdsitr->numberOfForeignNeighbors!=localNeighborCounter){
01173 cerr<<"Different Number of foreign neighbors - orig="<<bdsitr->numberOfForeignNeighbors
01174 <<" instant init="<<localNeighborCounter<<endl;
01175 cerr<<"Tried address "<<currentCellPtr<<endl;
01176 exit(0);
01177 }else if((bdsitr->numberOfForeignNeighbors) > 26){
01178 cerr<<"Number of fN's is "<<bdsitr->numberOfForeignNeighbors<<" but allowed value is 26 "<<endl;
01179 exit(0);
01180
01181 }else{
01182
01183
01184
01185 }
01186 }
01187
01188
01189
01190
01191
01192 }
01193
01194 cerr<<"LATTICE IS SANE!!!!!"<<endl;
01195
01196 }
01197
01199 bool CellBoundaryTrackerPlugin::isBoundaryPixel(Point3D pt){
01200
01201 const vector<Point3D> & adjNeighborOffsetsVec=adjNeighbor.getAdjFace2FaceNeighborOffsetVec(pt);
01202 CellG * currentCellPtr=cellFieldG->get(pt);;
01203 CellG * adjCellPtr;
01204
01205
01206 Point3D ptAdj;
01207 for (int i = 0 ; i < adjNeighborOffsetsVec.size() ; ++i){
01208 ptAdj=pt;
01209 ptAdj+=adjNeighborOffsetsVec[i];
01210
01211
01212 if(cellFieldG->isValid(ptAdj)){
01213 adjCellPtr=cellFieldG->get(ptAdj);
01214
01215 if( adjCellPtr != currentCellPtr ){
01216
01217
01218 return true;
01219 }
01220 }else{
01221
01222
01223 return true;
01224 if(isTouchingLatticeBoundary(pt,ptAdj))
01225 return true;
01226 else
01227 continue;
01228
01229 }
01230 }
01231
01232 return false;
01233 }
01236 bool CellBoundaryTrackerPlugin::isTouchingLatticeBoundary(Point3D pt,Point3D ptAdj){
01237
01238
01239 ptAdj-=pt;
01240
01241
01242 if(ptAdj.x!=0 && periodicX){
01243
01244 return false;
01245 }else if(ptAdj.x!=0 && !periodicX){
01246
01247 return true;
01248
01249 }
01250
01251
01252 if(ptAdj.y!=0 && periodicY){
01253
01254 return false;
01255 }else if(ptAdj.y!=0 && !periodicY){
01256
01257 return true;
01258
01259 }
01260
01261 if(ptAdj.z!=0 && periodicZ){
01262
01263 return false;
01264 }else if(ptAdj.z!=0 && !periodicZ){
01265
01266 return true;
01267
01268 }
01269
01270 }