Loading...
Logo
Processing Forum

I got the following error when running a code in Processing 2.0b8 in Mac OS, whereas the same code runs with no problem in Processing 2.0b8 in Windows7 ...

Help is appreciated!


Replies(14)

It's very strange indeed! Just make sure that methods displayPt() & displayVec() don't add more 
nor remove  any elements already stored in cells while inside that loop!

Thanks!

However, I assume it's caused by Processing 2.0b8 as no such problem in Processing 2.0b6 for the same code ...


It isn't a good idea to show textual information in an image: no way to manipulate the text, and I find the error message hard to read.

Anyway, GoToLoop is right: in general, this error is shown when you try and change (add / remove items) the collection on which you iterate during the loop.
Not sure why it changes with the version of Processing. Do they use the same version of Java?
I think it might be caused by "changing an arraylist while interating it":
https://forum.processing.org/topic/arraylist-confusion-changing-the-variables-of-an-extracted-object-with-get

to solve it (or at least it works):
1. assume the arraylist being iterated in draw() is A
2. assume there's a function F to create a new arraylist by reading from external data source when certain key is pressed
3. within function F create a temporary arraylist B to store the data, and then assign it to A

not sure if I hit the "G spot" of this problem ...
Yeah, this is kind of what PhiLho and GoToLoop already mentioned a week ago. Since you never posted your full code, it's hard to pinpoint the specific problem and solution. In general solutions to this problem are to use an iterator or go over the ArrayList backwards...
Copy code
  1. for (int i=cells.size()-1; i>=0; i--) {
  2.   Cell c = cells.get(i);
  3.   //etc.
  4. }

Your proposed solution may be a good one for your situation (whatever works). It's hard to tell, because we are missing most of the relevant information.

Hi, amnon and all, apologize for not sharing the problematic code!

This is what I want to viz when reading from a csv file with point data (hit F key to load a new csv file).


Two example .csv files are shared via:
https://www.dropbox.com/s/gs305umujum2l8n/oakshaya_metropolis_3by3_e.csv
https://www.dropbox.com/s/eejee2kcbs8bnjo/oalexis_3by3_e.csv

The problematic and the "corrected" two sets of code are shown below.

I'm using the "enhanced for loop" rather than the backward iterator method. Anyway, pls kind advise!

1. Here's the original problematic code showing the "ConcurrentModificationException" error:
Copy code
  1. // viz CFD simulation data
  2. // coded by Ji Zhang
  3. // http://episode-hopezh.blogspot.sg
  4. // Apr 2013
  5. //===================================================================

  6. import processing.opengl.*;
  7. import peasy.*;
  8. PeasyCam cam;
  9. import org.gicentre.utils.colour.*; // color scheme library
  10. ArrayList<Cell> cells = new ArrayList();
  11. boolean displayPt  = true;
  12. boolean displayVec = true;
  13. boolean displayValue = false;
  14. boolean showText = true;
  15. boolean showColor = true;
  16. float vecScale = 1;
  17. int numCells;
  18. String csvFilePathAndName_str = "";

  19. //===================================================================
  20. void setup(){
  21.   size(1000,800,OPENGL);
  22.   smooth(8);
  23.  
  24.   //use the following to avoid pt been shown in fixed size
  25.   hint(ENABLE_STROKE_PERSPECTIVE);
  26.  
  27.   // ---------------------------------------------------------
  28.   // setup perspective parm 
  29.   float fov  = PI/3.0;  // field of view
  30.   float nearClip = 1;
  31.   float farClip = 100000;
  32.   float aspect = float(width)/float(height);
  33.   perspective(fov, aspect, nearClip, farClip);
  34.   cam = new PeasyCam(this, 200); // the smaller the var, the close the distance to the object
  35. }

  36. //===================================================================
  37. void draw(){
  38.   background(0,0,30);

  39.   assignPtColor(cells);
  40.  
  41.   for(Cell c:cells){
  42.     if (displayPt == true){
  43.       c.displayPt();
  44.     }
  45.   }
  46.  
  47.   //_____print information on screen
  48.   if(showText == true){
  49.     pushMatrix();
  50.     hint(DISABLE_DEPTH_TEST);
  51.    
  52.     camera();
  53.     noLights();
  54.    
  55.     // 2D code
  56.     noStroke();
  57.     fill(255,80);
  58.     rect(0,0, width,50);
  59.     rect(0,height-110, width,110);
  60.    
  61.     textSize(15);
  62.     fill(0,255,0);
  63.     text("data file : " + csvFilePathAndName_str, 15,15);
  64.     text("num of cells : " + numCells, 15,30);
  65.     text("vec scale : " + nfc(vecScale,1), 15,45);
  66.     text("[f] choose csv file" , 15,height-90);
  67.     text("[p] show/hide point" , 15,height-75);
  68.     text("[c] B&W or color", 15,height-60);

  69.     if (cells.size() != 0) {
  70.       // color scheme __________________________________________________
  71.       // define a Kelvin color scale
  72.       ColourTable cTable = new ColourTable();
  73.       cTable.addContinuousColourRule(0,   0,   0,   255);  // pure Blue (Value,Red,Grn,Blu)
  74.       cTable.addContinuousColourRule(0.4, 206, 255, 255);  // Pale blue
  75.       cTable.addContinuousColourRule(0.6, 238, 255, 163);  // Yellow-green.
  76.       cTable.addContinuousColourRule(0.7, 255, 255, 0);  // Yellow.
  77.       cTable.addContinuousColourRule(0.8, 240, 165, 0);  // Orange.
  78.       cTable.addContinuousColourRule(1,   255, 0,   0);  // pure Red. 
  79.      
  80.       //_____get min and max speed from the current csv file
  81.       float speedMin = 0, speedMax = 0;
  82.       for(Cell c:cells){
  83.         float speed = c.speed;
  84.         if(speed <= speedMin){
  85.           speedMin = speed;
  86.         } else if (speed > speedMax){
  87.           speedMax = speed;
  88.         }
  89.       }
  90.      
  91.       // draw color legend
  92.       int numBand = 20;
  93.       int bandHeight = 20;
  94.       int bandWidth = 10;

  95.       for (int i=0; i<numBand; i++){
  96.         color c = cTable.findColour(map(i, numBand-1,0, 0,1));
  97.         noStroke();
  98.         fill(c);
  99.         rect(width-bandWidth*(numBand-i)-10, height-bandHeight-10, bandWidth,bandHeight);
  100.       }
  101.      
  102.       textSize(15);
  103.       fill(0,255,0);
  104.       text(nfc(speedMax,2) + "m/s", width-bandWidth*numBand-50, height-bandHeight-10);
  105.       text(0, width-10, height-bandHeight-10);
  106.     }
  107.        
  108.     hint(ENABLE_DEPTH_TEST);
  109.     popMatrix();
  110.   }
  111. }

  112. class Cell{
  113.   //_____variables
  114.   int id;
  115.   PVector location = new PVector();
  116.   PVector velocity = new PVector();
  117.   float speed;
  118.   float speed_min;
  119.   float speed_max;
  120.   color ptColor;
  121.   float ptSize = 1;
  122.  
  123.   //==============================================
  124.   void displayPt(){
  125.     if(showColor==true){
  126.       stroke(ptColor);
  127.     } else {stroke(255);}
  128.     strokeWeight(ptSize);
  129.     point(location.x, location.y, location.z);
  130.   }
  131. }

  132. void loadCFD(File selection){
  133.  
  134.   if (selection == null) {
  135.     println("Window was closed or the user hit cancel."); // Do nothing.
  136.   } else {
  137.     csvFilePathAndName_str = selection.getAbsolutePath(); //get csv file path and name
  138.    
  139.     Table t = loadTable(csvFilePathAndName_str); //create a Table object to store csv file data
  140.    
  141.     numCells = t.getRowCount() - 6; //exclude the top 6 rows
  142.        
  143.     cells = new ArrayList();

  144.     //____create cell objects
  145.     for(int i=0; i<numCells; i++){
  146.       Cell c = new Cell();
  147.       cells.add(c);
  148.      
  149.       c.id = i;
  150.      
  151.       c.location.x = -t.getFloat(i+6, 0); // x of the poping start point
  152.       c.location.y = -t.getFloat(i+6, 2); // get y position from the "Z" colume in csv
  153.       c.location.z = t.getFloat(i+6, 1);  // get z position from the "Y" colume in csv
  154.      
  155.       c.velocity.x = -t.getFloat(i+6, 5); // get x velocity component
  156.       c.velocity.y = -t.getFloat(i+6, 7); // get y velocity component from the "Z" colume in csv
  157.       c.velocity.z = t.getFloat(i+6, 6);  // get z velocity component from the "Y" colume in csv
  158.      
  159.       c.speed = t.getFloat(i+6, 4); // get speed(velcocity magnitude)   
  160.     }
  161.   }
  162. }

  163. ///////////////////////////////////////////////////////////
  164. void assignPtColor(ArrayList<Cell> cells){// note the ArrayList<Cell> part!!!
  165.   float speedMin = 0, speedMax = 0;

  166.   //_____get min and max speed from the current csv file
  167.   for(Cell c:cells){
  168.     float speed = c.speed;
  169.     if(speed <= speedMin){
  170.       speedMin = speed;
  171.     } else if (speed > speedMax){
  172.       speedMax = speed;
  173.     }
  174.   }
  175.  
  176.   //_____define a Kelvin color scale2
  177.   ColourTable cTable = new ColourTable();
  178.   cTable.addContinuousColourRule(0,   0,   0,   255);  // pure Blue (Value,Red,Grn,Blu)
  179.   cTable.addContinuousColourRule(0.4, 206, 255, 255);  // Pale blue
  180.   cTable.addContinuousColourRule(0.6, 238, 255, 163);  // Yellow-green.
  181.   cTable.addContinuousColourRule(0.7, 255, 255, 0);    // Yellow.
  182.   cTable.addContinuousColourRule(0.8, 240, 165, 0);    // Orange.
  183.   cTable.addContinuousColourRule(1,   255, 0,   0);    // pure Red.
  184.  
  185.   //_____assign color to pt by its speed mapped to overall speedMin & speedMax
  186.   for(Cell c:cells){
  187.     c.ptColor = cTable.findColour(map(c.speed, speedMin, speedMax, 0, 1));
  188.   } 
  189. }

  190. void keyPressed(){
  191.   if ( key == 'f' ) {
  192.     selectInput("select a new .csv file", "loadCFD");       
  193.   }
  194.   if ( key == 'p' ) {
  195.     displayPt = (displayPt == true) ? (false):(true);
  196.   } 
  197.   if ( key == '=' ) {
  198.     vecScale += 0.2;
  199.   } 
  200.   if ( key == '-' ) {
  201.     vecScale -= 0.2;
  202.   }
  203.   if ( key == 'h' ) {
  204.     showText = (showText == true) ? (false):(true);
  205.   }
  206.   if ( key == 'c' ) {
  207.     showColor = (showColor == true) ? (false):(true);
  208.   }
  209. }

2. Here's the modified code with the temp ArrayList added in the function reading new data file (line 147 & 167)
Copy code
  1. // viz CFD simulation data
  2. // coded by Ji Zhang
  3. // http://episode-hopezh.blogspot.sg
  4. // Apr 2013

  5. import processing.opengl.*;
  6. import peasy.*;
  7. PeasyCam cam;
  8. import org.gicentre.utils.colour.*; // color scheme library
  9. ArrayList<Cell> cells = new ArrayList();
  10. boolean displayPt  = true;
  11. boolean displayVec = true;
  12. boolean displayValue = false;
  13. boolean showText = true;
  14. boolean showColor = true;
  15. float vecScale = 1;
  16. int numCells;
  17. String csvFilePathAndName_str = "";

  18. void setup(){
  19.   size(1000,800,OPENGL);
  20.   smooth(8);
  21.  
  22.   //use the following to avoid pt been shown in fixed size
  23.   hint(ENABLE_STROKE_PERSPECTIVE);
  24.  
  25.   // setup perspective parm 
  26.   float fov  = PI/3.0;  // field of view
  27.   float nearClip = 1;
  28.   float farClip = 100000;
  29.   float aspect = float(width)/float(height);
  30.   perspective(fov, aspect, nearClip, farClip);
  31.   cam = new PeasyCam(this, 200); // the smaller the var, the close the distance to the object
  32.  
  33. }

  34. void draw(){
  35.   background(0,0,30);

  36.   assignPtColor(cells);
  37.  
  38.   for(Cell c:cells){
  39.     if (displayPt == true){
  40.       c.displayPt();
  41.     }
  42.   }
  43.  
  44.   //_____print information on screen
  45.   if(showText == true){
  46.     pushMatrix();
  47.     hint(DISABLE_DEPTH_TEST);
  48.    
  49.     camera();
  50.     noLights();
  51.    
  52.     // 2D code
  53.     noStroke();
  54.     fill(255,80);
  55.     rect(0,0, width,50);
  56.     rect(0,height-110, width,110);
  57.    
  58.     textSize(15);
  59.     fill(0,255,0);
  60.     text("data file : " + csvFilePathAndName_str, 15,15);
  61.     text("num of cells : " + numCells, 15,30);
  62.     text("vec scale : " + nfc(vecScale,1), 15,45);
  63.     text("[f] choose csv file" , 15,height-90);
  64.     text("[p] show/hide point" , 15,height-75);
  65.     text("[c] B&W or color", 15,height-60);

  66.     if (cells.size() != 0) {
  67.       // color scheme __________________________________________________
  68.       // define a Kelvin color scale
  69.       ColourTable cTable = new ColourTable();
  70.       cTable.addContinuousColourRule(0,   0,   0,   255);  // pure Blue (Value,Red,Grn,Blu)
  71.       cTable.addContinuousColourRule(0.4, 206, 255, 255);  // Pale blue
  72.       cTable.addContinuousColourRule(0.6, 238, 255, 163);  // Yellow-green.
  73.       cTable.addContinuousColourRule(0.7, 255, 255, 0);  // Yellow.
  74.       cTable.addContinuousColourRule(0.8, 240, 165, 0);  // Orange.
  75.       cTable.addContinuousColourRule(1,   255, 0,   0);  // pure Red. 
  76.      
  77.       //_____get min and max speed from the current csv file
  78.       float speedMin = 0, speedMax = 0;
  79.       for(Cell c:cells){
  80.         float speed = c.speed;
  81.         if(speed <= speedMin){
  82.           speedMin = speed;
  83.         } else if (speed > speedMax){
  84.           speedMax = speed;
  85.         }
  86.       }
  87.      
  88.       // draw color legend
  89.       int numBand = 20;
  90.       int bandHeight = 20;
  91.       int bandWidth = 10;
  92.       for (int i=0; i<numBand; i++){
  93.         color c = cTable.findColour(map(i, numBand-1,0, 0,1));
  94.         noStroke();
  95.         fill(c);
  96.         rect(width-bandWidth*(numBand-i)-10, height-bandHeight-10, bandWidth,bandHeight);
  97.       }
  98.      
  99.       textSize(15);
  100.       fill(0,255,0);
  101.       text(nfc(speedMax,2) + "m/s", width-bandWidth*numBand-50, height-bandHeight-10);
  102.       text(0, width-10, height-bandHeight-10);
  103.     }
  104.        
  105.     hint(ENABLE_DEPTH_TEST);
  106.     popMatrix();
  107.   } 
  108. }

  109. class Cell{
  110.   //_____variables
  111.   int id;
  112.   PVector location = new PVector();
  113.   PVector velocity = new PVector();
  114.   float speed;
  115.   float speed_min;
  116.   float speed_max;
  117.   color ptColor;
  118.   float ptSize = 1;
  119.  
  120.   //==============================================
  121.   void displayPt(){
  122.     if(showColor==true){
  123.       stroke(ptColor);
  124.     } else {stroke(255);}
  125.     strokeWeight(ptSize);
  126.     point(location.x, location.y, location.z);
  127.   }
  128. }

  129. void loadCFD(File selection){
  130.  
  131.   if (selection == null) {
  132.     println("Window was closed or the user hit cancel."); // Do nothing.
  133.   } else {
  134.     csvFilePathAndName_str = selection.getAbsolutePath(); //get csv file path and name
  135.    
  136.     Table t = loadTable(csvFilePathAndName_str); //create a Table object to store csv file data
  137.    
  138.     numCells = t.getRowCount() - 6; //exclude the top 6 rows
  139.        
  140.     ArrayList<Cell> tempCells = new ArrayList();

  141.     //____create cell objects
  142.     for(int i=0; i<numCells; i++){
  143.       Cell c = new Cell();
  144.       tempCells.add(c);
  145.      
  146.       c.id = i;
  147.      
  148.       c.location.x = -t.getFloat(i+6, 0); // x of the poping start point
  149.       c.location.y = -t.getFloat(i+6, 2); // get y position from the "Z" colume in csv
  150.       c.location.z = t.getFloat(i+6, 1);  // get z position from the "Y" colume in csv
  151.      
  152.       c.velocity.x = -t.getFloat(i+6, 5); // get x velocity component
  153.       c.velocity.y = -t.getFloat(i+6, 7); // get y velocity component from the "Z" colume in csv
  154.       c.velocity.z = t.getFloat(i+6, 6);  // get z velocity component from the "Y" colume in csv
  155.      
  156.       c.speed = t.getFloat(i+6, 4); // get speed(velcocity magnitude)   
  157.     }
  158.    
  159.     cells = tempCells;
  160.   }
  161. }

  162. ///////////////////////////////////////////////////////////
  163. void assignPtColor(ArrayList<Cell> cells){// note the ArrayList<Cell> part!!!
  164.   float speedMin = 0, speedMax = 0;
  165.   //_____get min and max speed from the current csv file
  166.   for(Cell c:cells){
  167.     float speed = c.speed;
  168.     if(speed <= speedMin){
  169.       speedMin = speed;
  170.     } else if (speed > speedMax){
  171.       speedMax = speed;
  172.     }
  173.   }
  174.  
  175.   //_____define a Kelvin color scale2
  176.   ColourTable cTable = new ColourTable();
  177.   cTable.addContinuousColourRule(0,   0,   0,   255);  // pure Blue (Value,Red,Grn,Blu)
  178.   cTable.addContinuousColourRule(0.4, 206, 255, 255);  // Pale blue
  179.   cTable.addContinuousColourRule(0.6, 238, 255, 163);  // Yellow-green.
  180.   cTable.addContinuousColourRule(0.7, 255, 255, 0);    // Yellow.
  181.   cTable.addContinuousColourRule(0.8, 240, 165, 0);    // Orange.
  182.   cTable.addContinuousColourRule(1,   255, 0,   0);    // pure Red.
  183.  
  184.   //_____assign color to pt by its speed mapped to overall speedMin & speedMax
  185.   for(Cell c:cells){
  186.     c.ptColor = cTable.findColour(map(c.speed, speedMin, speedMax, 0, 1));
  187.   } 
  188.  
  189. }
  190. void keyPressed(){
  191.  
  192.   if ( key == 'f' ) {
  193.     selectInput("select a new .csv file", "loadCFD");       
  194.   }
  195.   if ( key == 'p' ) {
  196.     displayPt = (displayPt == true) ? (false):(true);
  197.   }
  198.   if ( key == '=' ) {
  199.     vecScale += 0.2;
  200.   }
  201.  
  202.   if ( key == '-' ) {
  203.     vecScale -= 0.2;
  204.   }
  205.  
  206.   if ( key == 'h' ) {
  207.     showText = (showText == true) ? (false):(true);
  208.   }
  209.   if ( key == 'c' ) {
  210.     showColor = (showColor == true) ? (false):(true);
  211.   }
  212.   
  213. }

From looking at your code the problem becomes clearer. I think there is the ArrayList that is used in draw(). And when a key is pressed another thread is running to open a csv file and replace the contents of the ArrayList. As everybody including yourself already pointed out, this is the problem of changing an ArrayList while going over it.

I think your solution is allright, but I wonder if it is 100% safe. By using a temp ArrayList, you are at least making sure that the number of times and the total time of changes to the ArrayList is limited to the line 167 (cells = tempCells;). Not sure, but it seems this could still happen at the same time the ArrayList is being used in draw(). Perhaps an even safer method would be to make the incoming temp ArrayList global and use a boolean newList that's set to true when the new ArrayList is loaded. Then at the top of draw() -before using the ArrayList- you can check the boolean and if it's true aka a new ArrayList is there, then you can do the replace and set the boolean to false again. That would be sync-safe, because the change happens from inside draw().

Thanks, Amnon!

I adjusted the code according to your suggestion:
13: make the temp ArrayList to store newly loaded data a global one
14: create a boolean to record if new data is loaded or not
45-48: if new data is loaded, pass temp-ArrayList to THE ArrayList to be used in draw(), and set the boolean to false
96: clear the temp-ArrayList every time new data is to be read
134: set the newDataLoaded boolean as true after finishing reading data from a new csv file

However, the "ConcurrentModification" error will pop out the 2nd time a new csv file is loaded.

Appreciate if you can kindly help to point out where the code goes wrong!

Copy code
  1. /*----------------------------------------------------
  2. //  viz CFD simulation data
  3. //  coded by Ji Zhang
  4. //  http://episode-hopezh.blogspot.sg
  5. //  Apr 2013
  6. ----------------------------------------------------*/
  7. import processing.opengl.*;
  8. import peasy.*;
  9. PeasyCam cam;
  10. import org.gicentre.utils.colour.*; // color scheme library
  11. ArrayList<Cell> cells = new ArrayList(); //current arraylist to be used in draw()
  12. ArrayList<Cell> cellsTemp = new ArrayList(); //temp arraylist to store newly loaded data
  13. boolean newDataLoaded = false;
  14. boolean displayPt  = true;
  15. boolean showColor = true;
  16. float vecScale = 1;
  17. int numCells;
  18. String csvFilePathAndName_str = "";

  19. ////////////////////////////////////////////////////////////////
  20. void setup(){
  21.   size(1000,800,OPENGL);
  22.   smooth(8);
  23.  
  24.   //use the following to avoid pt been shown in fixed size
  25.   hint(ENABLE_STROKE_PERSPECTIVE);
  26.  
  27.   //_____setup perspective parm
  28.   float fov  = PI/3.0;  // field of view
  29.   float nearClip = 1;
  30.   float farClip = 100000;
  31.   float aspect = float(width)/float(height);
  32.   perspective(fov, aspect, nearClip, farClip);
  33.   cam = new PeasyCam(this, 200); // the smaller the var, the close the distance to the object
  34. }

  35. ////////////////////////////////////////////////////////////////
  36. void draw(){
  37.   background(0);
  38.   if (newDataLoaded == true){
  39.     cells = cellsTemp;
  40.     newDataLoaded = false;
  41.   }
  42.   assignPtColor(cells);
  43.  
  44.   for(Cell c:cells){
  45.     if (displayPt == true){
  46.       c.displayPt();
  47.     }
  48.   }
  49. }

  50. class Cell{
  51.   //_____variables
  52.   int id;
  53.   PVector location = new PVector();
  54.   PVector velocity = new PVector();
  55.   float speed;
  56.   float speed_min;
  57.   float speed_max;
  58.   color ptColor;
  59.   float ptSize = 1;
  60.  
  61.   //==============================================
  62.   void displayPt(){
  63.     if(showColor==true){
  64.       stroke(ptColor);
  65.     } else {stroke(255);}
  66.     strokeWeight(ptSize);
  67.     point(location.x, location.y, location.z);
  68.   }
  69. }

  70. /*----------------------------------------------------
  71. load CFD results .csv file and
  72. assign each row of data to a cell object
  73. ----------------------------------------------------*/
  74. void loadCFD(File selection){
  75.  
  76.   if (selection == null) {
  77.     println("Window was closed or the user hit cancel."); // Do nothing.
  78.   } else {
  79.     csvFilePathAndName_str = selection.getAbsolutePath(); //get csv file path and name
  80.   
  81.     Table t = loadTable(csvFilePathAndName_str); //create a Table object to store csv file data
  82.   
  83.     numCells = t.getRowCount() - 6; //exclude the top 6 rows
  84.       
  85.     cellsTemp.clear(); //clear and initiate a new array list of cells for the current set of data
  86.   
  87.     float speedMin = 0, speedMax = 0; //initialize overall min and max speed values
  88.   
  89.     //____create cell objects
  90.     for(int i=0; i<numCells; i++){
  91.       Cell c = new Cell();
  92.       cellsTemp.add(c);
  93.     
  94.       c.id = i;
  95.     
  96.       c.location.x = -t.getFloat(i+6, 0); // x of the poping start point
  97.       c.location.y = -t.getFloat(i+6, 2); // get y position from the "Z" colume in csv
  98.       c.location.z = t.getFloat(i+6, 1);  // get z position from the "Y" colume in csv
  99.     
  100.       c.velocity.x = -t.getFloat(i+6, 5); // get x velocity component
  101.       c.velocity.y = -t.getFloat(i+6, 7); // get y velocity component from the "Z" colume in csv
  102.       c.velocity.z = t.getFloat(i+6, 6);  // get z velocity component from the "Y" colume in csv
  103.     
  104.       c.speed = t.getFloat(i+6, 4); // get speed(velcocity magnitude)
  105.     
  106.       // compare current pt speed with min and max speed and replace them if qualified
  107.       if(c.speed <= speedMin){
  108.         speedMin = c.speed;
  109.       } else if (c.speed > speedMax){
  110.         speedMax = c.speed;
  111.       }  
  112.     }
  113.   
  114.     //_____assign overall min and max speed to each pt
  115.     for(Cell c:cellsTemp){
  116.       c.speed_min = speedMin;
  117.       c.speed_max = speedMax;
  118.     }
  119.  
  120.     // !!! pass the temp ArrayList "cellsTemp" to "cells" which is to be iterated in draw()
  121.     //cells = cellsTemp;
  122.   
  123.     newDataLoaded = true;
  124.   }
  125. }

  126. /*----------------------------------------------------
  127. assign color to pt based on their speed
  128. as mapped to min to max speeds of the current data set
  129. ----------------------------------------------------*/
  130. void assignPtColor(ArrayList<Cell> cells){// !!! note the "ArrayList<Cell>" part
  131.  
  132.   //_____define a Kelvin color scale2
  133.   ColourTable cTable = new ColourTable();
  134.   cTable.addContinuousColourRule(0,   0,   0,   255);  // pure Blue (Value,Red,Grn,Blu)
  135.   cTable.addContinuousColourRule(0.4, 206, 255, 255);  // Pale blue
  136.   cTable.addContinuousColourRule(0.6, 238, 255, 163);  // Yellow-green.
  137.   cTable.addContinuousColourRule(0.7, 255, 255, 0);    // Yellow.
  138.   cTable.addContinuousColourRule(0.8, 240, 165, 0);    // Orange.
  139.   cTable.addContinuousColourRule(1,   255, 0,   0);    // pure Red.
  140.  
  141.   //_____assign color to pt by its speed mapped to overall speedMin & speedMax
  142.   for(Cell c:cells){
  143.     c.ptColor = cTable.findColour(map(c.speed, c.speed_min, c.speed_max, 0, 1));
  144.   }
  145.  
  146. }

  147. void keyPressed(){
  148.   if ( key == 'f' ) {
  149.     selectInput("select a new .csv file", "loadCFD");
  150.   }
  151. }

Oh, right. What if you change lines 40-43 in the draw() loop to this:
Copy code
  1.  if (newDataLoaded){
  2.     cells = new ArrayList<Cell>(cellsTemp);
  3.     cellsTemp.clear();
  4.     newDataLoaded = false;
  5.  }
See if that works all right. Otherwise a possible alternative method might be to have two global ArrayLists A and B and pingpong between them:
  • When A is in use in the main draw(), load to B, then toggle main draw() to use B (and then clear A).
  • When B is in use in the main draw(), load to A, then toggle main draw() to use A (and then clear B).

Thank you very much, Amnon!

Your suggestion about line 40-43 solves the problem.

I'll try the two-global-ArrayList method later.

Big thanks, again!






This project is coming along nicely. Looking very good.
Hello all,

I think I have a same problem or closer, but I don't understand your solution.

In my case, I have no problem to display in the setup() with the method  : for (Pixel p : listPixelRaw )
but in the draw() I receive "ConcurrentModificationException" with this one but not with the :
for ( int i = 0 ; i < listPixelRaw.size() ; i++) {
    Pixel p = (Pixel) listPixelRaw.get(i) ;

If you have an idea...

Thx

Stan
Copy code
  1. PImage img ;
    String pathImg ;

    //ANALYZE PICTURE
    //size analyze pixel
    int pixelAnalyzeSize = 3; // pour la grille de mon cahier tester vec 40

    boolean choiceImageToAnalyze = false ;
    boolean security ;
    java.awt.Insets insets; // use for the border of window (top and right)


    void setup()
    {
      colorMode(HSB,360,100,100) ;
      //to make the window can be resizable when you open a picture
      frame.pack(); 
      insets = frame.getInsets(); // use for the border of window (top and right)
     
      if( !choiceImageToAnalyze ) {
        size(220,200) ;
        fill(0,0,0) ;
        text("tape “o” and choice an image", 15,40) ;
       
      } else {
        img = loadImage(pathImg) ;
        PVector newSizeSketch = new PVector (img.width, img.height ) ;
        setSize((int)newSizeSketch.x, (int)newSizeSketch.y) ;
        PVector newSizeWindow = new PVector ( Math.max( newSizeSketch.x, MIN_WINDOW_WIDTH)  + insets.left + insets.right,
                                              Math.max( newSizeSketch.y, MIN_WINDOW_HEIGHT) + insets.top  + insets.bottom) ;
        frame.setSize((int)newSizeWindow.x, (int)newSizeWindow.y);
        colorAnalyzeSetup(pixelAnalyzeSize) ;
        recordPixelRaw(pixelAnalyzeSize, img, false) ;
        //println(listPixelRaw.size() );
      }
     
     
      //ok in setup, not in the draw
      //displayPixelNewWay() ;
    }


    void draw()
    {
      //cannot use this way, because I receive this message ConcurrentModificationException and not in the setup ??????
      displayPixelNewWay() ;
      
       // Must use this way but it's not really good
       //displayPixelOldWay() ;
    }

    //DISPLAY VOID
    //new way
    void displayPixelNewWay()
    {
      for (Pixel p : listPixelRaw ) {
        stroke(p.c) ;
        strokeWeight(5) ;
        point(p.pos.x, p.pos.y) ;
      }
    }
    //old way
    void displayPixelOldWay()
    {
      for ( int i = 0 ; i < listPixelRaw.size() ; i++) {
        Pixel p = (Pixel) listPixelRaw.get(i) ;
        stroke(p.c) ;
        strokeWeight(5) ;
        point(p.pos.x, p.pos.y) ;
      }
    }


    //OPEN IMAGE
    void keyPressed() {
      if ( key == 'o' ) {
        selectInput("Choisissez une belle image", "choiceImg");
      }
    }
    void choiceImg(File selection) {
      if (selection == null) {
        println("aucun fichier selectionné");
      } else {
        pathImg  = selection.getAbsolutePath() ;
        choiceImageToAnalyze =true ;
        //println("chemin " + pathImg);
        setup() ;
      }
    }


    //CLASS
    class Pixel
    {
      color c ;
      PVector pos ;
     
      Pixel(PVector pos, color c)
      {
        this.pos = pos ;
        this.c = c ;
      }
    }



    //ANALYZE
    ArrayList<Pixel> listPixelRaw = new ArrayList<Pixel>() ;
    // Number of columns and rows in our system
    int cols, rows;

    //SETUP
    void colorAnalyzeSetup(int pixSize)
    {
      //grid analyze
      cols = img.width / pixSize;
      rows = img.height / pixSize;
    }

    //RECORD

    //DRAW
    int stepAnalyzeImg ;
    int whereIsPixel ;
    //RAW RECORD without timer
    void recordPixelRaw(int cellSize, PImage imgRecord, boolean mirror)
    {
      imgRecord.loadPixels() ;
      //start analyze
      for (int i = 0; i < cols; i++) {
        for (int j = 0; j < rows; j++) {
         
          int x = i*cellSize;
          int y = j*cellSize;
          //check if there is mirror effect or not
          if(!mirror) whereIsPixel =  y*img.width +x; else whereIsPixel = (imgRecord.width - x - 1) + y*imgRecord.width; // Reversing x to mirror the image
          //analyze the color of the pixel in the HSB mode
          float h = hue       (imgRecord.pixels[whereIsPixel]);
          float s = saturation(imgRecord.pixels[whereIsPixel]);
          float b = brightness(imgRecord.pixels[whereIsPixel]);
          // Make a new color and position
          color c = color(h, s, b);
          PVector pos = new PVector(x+cellSize/2, y+cellSize/2 ) ;
          //add position and color of the pixel in the list
          listPixelRaw.add(new Pixel(pos, c)) ;
        }
      }
    }



First, instead of awakening a month old thread, you should have made your own thread and, if needed, referenced this one.

I hadn't the error on the first image I loaded (a small one), I had it with a larger image. I think it is a problem with the fact that the image selector uses a separate thread: you try to work on the image before it is completely loaded.

Beside, you should not call setup()! Processing callback functions like setup(), draw() or keyPressed() shouldn't be called, it is Processing that call them.
Isolate your code in a function you created and call it from setup(), while leaving the size() call in it.
And it would avoid the logic around choiceImageToAnalyze.

Thanks a lot PhiLho, the sketch work perfectly now.
I had a securuty like your suggest, and don't call the setup() again...I put all the stuff in the draw.
 And sorry next time I open a new post. but I had thought it's a good idea to continue on same post.

I give the new code for information

++
Copy code
  1. PImage img ;
    String pathImg ;

    //ANALYZE PICTURE
    //size analyze pixel
    int pixelAnalyzeSize = 3; // pour la grille de mon cahier tester vec 40

    // boolean choiceImageToAnalyze = false ;
    java.awt.Insets insets; // use for the border of window (top and right)


    void setup()
    {
      colorMode(HSB,360,100,100) ;
      //to make the window can be resizable when you open a picture
      frame.pack(); 
      insets = frame.getInsets(); // use for the border of window (top and right)
     
      size(220,200) ;
      fill(0,0,0) ;
      text("tape “o” and choice an image", 15,40) ;
    }


    void draw()
    {
      //change the size of displaying if you load a new image or a new image
      updateSizeDisplay() ;
      //Analyze
      colorAnalyzeSetting(pixelAnalyzeSize) ;
      recordPixelRaw(pixelAnalyzeSize, img, false) ;
     
      displayPixelNewWay() ;
      
    }

    //DISPLAY VOID
    //new way
    void displayPixelNewWay()
    {
      for (Pixel p : listPixelRaw ) {
        stroke(p.c) ;
        strokeWeight(5) ;
        point(p.pos.x, p.pos.y) ;
      }
    }


    //change the size of the displaying
    void updateSizeDisplay()
    {
      if (img != null ) {
        PVector newSizeSketch = new PVector (img.width, img.height ) ;
        setSize((int)newSizeSketch.x, (int)newSizeSketch.y) ;
        PVector newSizeWindow = new PVector ( Math.max( newSizeSketch.x, MIN_WINDOW_WIDTH)  + insets.left + insets.right,
                                              Math.max( newSizeSketch.y, MIN_WINDOW_HEIGHT) + insets.top  + insets.bottom) ;
        frame.setSize((int)newSizeWindow.x, (int)newSizeWindow.y);
      }
    }


    //OPEN IMAGE
    void keyPressed() {
      if ( key == 'o' ) {
        selectInput("Choisissez une belle image", "choiceImg");
      }
    }
    void choiceImg(File selection) {
      if (selection == null) {
        println("aucun fichier selectionné");
      } else {
        pathImg  = selection.getAbsolutePath() ;
        img = loadImage(pathImg) ;
        analyzeDone = false ;
      }
    }


    //ANALYZE
    ArrayList<Pixel> listPixelRaw = new ArrayList<Pixel>() ;
    // Number of columns and rows in our system
    int cols, rows;

    //SETTING
    void colorAnalyzeSetting(int pixSize)
    {
      if (img != null ) {
        println("Je suis là !") ;
        cols = img.width / pixSize;
        rows = img.height / pixSize;
      }
    }

    //RECORD

    //DRAW
    int stepAnalyzeImg ;
    int whereIsPixel ;
    boolean analyzeDone ;
    //RAW RECORD without timer
    void recordPixelRaw(int cellSize, PImage imgRecord, boolean mirror)
    {
      if (img != null && !analyzeDone  ) {
        imgRecord.loadPixels() ;
        //start analyze
        for (int i = 0; i < cols; i++) {
          for (int j = 0; j < rows; j++) {
         
            int x = i*cellSize;
            int y = j*cellSize;
            //check if there is mirror effect or not
            if(!mirror) whereIsPixel =  y*img.width +x; else whereIsPixel = (imgRecord.width - x - 1) + y*imgRecord.width; // Reversing x to mirror the image
            //analyze the color of the pixel in the HSB mode
            float h = hue       (imgRecord.pixels[whereIsPixel]);
            float s = saturation(imgRecord.pixels[whereIsPixel]);
            float b = brightness(imgRecord.pixels[whereIsPixel]);
            // Make a new color and position
            color c = color(h, s, b);
            PVector pos = new PVector(x+cellSize/2, y+cellSize/2 ) ;
            //add position and color of the pixel in the list
            listPixelRaw.add(new Pixel(pos, c)) ;
          }
        }
        analyzeDone = true ;
      } else {
        println("Hey Man, where is your picture ?") ;
      }
    }


    //CLASS
    class Pixel
    {
      color c ;
      PVector pos ;
     
      Pixel(PVector pos, color c)
      {
        this.pos = pos ;
        this.c = c ;
      }
    }