GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TrackContainer.cxx
Go to the documentation of this file.
1 /*=========================================================================
2  Authors: The GoFigure Dev. Team.
3  at Megason Lab, Systems biology, Harvard Medical school, 2009-11
4 
5  Copyright (c) 2009-11, President and Fellows of Harvard College.
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  Redistributions of source code must retain the above copyright notice,
12  this list of conditions and the following disclaimer.
13  Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16  Neither the name of the President and Fellows of Harvard College
17  nor the names of its contributors may be used to endorse or promote
18  products derived from this software without specific prior written
19  permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 =========================================================================*/
34 
35 #include "TrackContainer.h"
36 
37 #include "vtkActor.h"
38 
39 // reconstruct the polydata
40 #include "vtkPointData.h"
41 #include "vtkPolyLine.h"
42 #include "vtkCellArray.h"
43 
44 // tubes and glyph
45 #include "vtkGlyph3D.h"
46 #include "vtkSphereSource.h"
47 #include "vtkTubeFilter.h"
48 #include "vtkAppendPolyData.h"
49 
50 // division polydata
51 #include "vtkLine.h"
52 
53 // to convert coordinates
54 #include "vtkViewImage2D.h"
55 
56 #include "vtkLookupTable.h"
57 
58 #include "vtkStringArray.h"
59 
60 #include <limits>
61 
62 #include <QDebug>
63 
64 //-------------------------------------------------------------------------
67  Superclass(iParent, iView)
68 {
69  m_TimeInterval = 0;
70  m_ActiveTrackScalars.append("Original");
71  m_ActiveDivisionScalars.append("Original");
72 }
73 
74 //-------------------------------------------------------------------------
75 
76 //-------------------------------------------------------------------------
79 {
80  MultiIndexContainerType::iterator it = m_Container.begin();
81 
82  while ( it != m_Container.end() )
83  {
84  it->ReleaseData();
85  ++it;
86  }
87 }
88 
89 //-------------------------------------------------------------------------
90 
91 //-------------------------------------------------------------------------
92 bool
94 DeleteElement(const unsigned int & iId)
95 {
97  it = m_Container.get< TraceID >().find(iId);
98 
99  return DeleteElement(it);
100 }
101 
102 //-------------------------------------------------------------------------
103 
104 //-------------------------------------------------------------------------
105 bool
108 {
109  assert ( iIter != m_Container.get< TraceID >().end() );
110  assert ( this->m_ImageView );
111 
112  if ( iIter->ActorXY )
113  {
114  this->m_ImageView->RemoveActor(0, iIter->ActorXY);
115  }
116  if ( iIter->ActorXZ )
117  {
118  this->m_ImageView->RemoveActor(1, iIter->ActorXZ);
119  }
120  if ( iIter->ActorYZ )
121  {
122  this->m_ImageView->RemoveActor(2, iIter->ActorYZ);
123  }
124  if ( iIter->ActorXYZ )
125  {
126  this->m_ImageView->RemoveActor(3, iIter->ActorXYZ);
127  }
128 
129  iIter->ReleaseData();
130 
131  m_Container.get< TraceID >().erase(iIter);
133 
134  return true;
135 }
136 
137 //-------------------------------------------------------------------------
138 
139 //-------------------------------------------------------------------------
140 std::list< unsigned int >
143 {
144  assert ( this->m_ImageView );
145 
147 
148  boost::tuples::tie(it0, it1) =
149  m_Container.get< Highlighted >().equal_range(true);
150 
151  std::list< unsigned int > oList;
152 
153  while ( it0 != it1 )
154  {
155  oList.push_back(it0->TraceID);
156 
157  if ( it0->ActorXY )
158  {
159  this->m_ImageView->RemoveActor(0, it0->ActorXY);
160  }
161  if ( it0->ActorXZ )
162  {
163  this->m_ImageView->RemoveActor(1, it0->ActorXZ);
164  }
165  if ( it0->ActorYZ )
166  {
167  this->m_ImageView->RemoveActor(2, it0->ActorYZ);
168  }
169  if ( it0->ActorXYZ )
170  {
171  this->m_ImageView->RemoveActor(3, it0->ActorXYZ);
172  }
173 
174  it0->ReleaseData();
175 
176  it_t = it0;
177  ++it0;
178 
179  m_Container.get< Highlighted >().erase(it_t);
180  }
181 
183 
184  return oList;
185 }
186 //-------------------------------------------------------------------------
187 
188 //-------------------------------------------------------------------------
189 bool
192 {
193  if ( iTrackStructure.PointsMap.empty() )
194  {
195  qDebug() << "No points in the map, reset nodes";
196 
197  iTrackStructure.ResetNodes();
198 
199  return false;
200  }
201 
202  // read map and fill points
203  vtkSmartPointer< vtkPoints > newPoints = vtkSmartPointer< vtkPoints >::New();
204  vtkSmartPointer< vtkIntArray > newArray = vtkSmartPointer< vtkIntArray >::New();
205  newArray->SetNumberOfComponents(1);
206  newArray->SetName("TemporalInformation");
207 
208  // Create a line from points
209  vtkSmartPointer< vtkPolyLine > polyLine = vtkSmartPointer< vtkPolyLine >::New();
210  polyLine->GetPointIds()->SetNumberOfIds( iTrackStructure.PointsMap.size() );
211 
212  std::map< unsigned int, double * >::const_iterator it =
213  iTrackStructure.PointsMap.begin();
214 
215  vtkIdType i = 0;
216 
217  while ( it != iTrackStructure.PointsMap.end() )
218  {
219  newArray->InsertNextValue(it->first);
220  newPoints->InsertNextPoint(it->second);
221 
222  polyLine->GetPointIds()->SetId(i, i);
223 
224  ++i;
225  ++it;
226  }
227 
228  //Create a cell array to store the lines in and add the lines to it
229  vtkSmartPointer< vtkCellArray > cells =
230  vtkSmartPointer< vtkCellArray >::New();
231  cells->InsertNextCell(polyLine);
232 
233  //Create a polydata to store everything in
234  vtkSmartPointer< vtkPolyData > polyData = vtkSmartPointer< vtkPolyData >::New();
235 
236  //add the points to the dataset
237  polyData->SetPoints(newPoints);
238  //add the lines to the dataset
239  polyData->SetLines(cells);
240  //add the temporal information
241  polyData->GetPointData()->AddArray(newArray);
242 
243  vtkSmartPointer< vtkDoubleArray > speedArray =
244  vtkSmartPointer< vtkDoubleArray >::New();
245  speedArray->SetNumberOfComponents(1);
246  speedArray->SetName("SpeedInformation");
247  polyData->GetPointData()->AddArray(speedArray);
248 
249  vtkSmartPointer<vtkIntArray> trackIDArray = vtkSmartPointer<vtkIntArray>::New();
250  trackIDArray->SetNumberOfComponents(1);
251  trackIDArray->SetNumberOfValues(1);
252  trackIDArray->SetName("TRACK");
253  trackIDArray->SetValue(0,iTrackStructure.TraceID);
254 
255  polyData->GetFieldData()->AddArray(trackIDArray);
256 
257  iTrackStructure.Nodes->DeepCopy(polyData);
258  //update speed information
259  iTrackStructure.ComputeAttributes();
260 
261  iTrackStructure.Nodes->GetPointData()->SetActiveScalars(NULL);
262 
263  return true;
264 }
265 //-------------------------------------------------------------------------
266 
267 //-------------------------------------------------------------------------
268 void
270 ImportTrackInCurrentElement(std::map<unsigned int, double*>& iMeshes)
271 {
272  std::map< unsigned int, double * >::iterator beginMesh = iMeshes.begin();
273  std::map< unsigned int, double * >::iterator endMesh = iMeshes.end();
274 
275  while ( beginMesh != endMesh )
276  {
277  this->m_CurrentElement.InsertElement(beginMesh->first,
278  beginMesh->second);
279  ++beginMesh;
280  }
281 
282  this->m_CurrentElement.Visible = true;
283 
284  this->m_CurrentElement.Nodes = vtkPolyData::New();
285 
287 
289 }
290 
291 //-------------------------------------------------------------------------
292 
293 //-------------------------------------------------------------------------
294 void
297 {
298  assert( this->m_ImageView );
299 
300  //Create new actors (new address)
301  vtkProperty *trace_property = vtkProperty::New();
302  double r = iStructure.rgba[0];
303  double g = iStructure.rgba[1];
304  double b = iStructure.rgba[2];
305  double a = iStructure.rgba[3];
306 
307  trace_property->SetColor(r,
308  g,
309  b);
310  trace_property->SetOpacity(a);
311 
312  // Add contour
313  std::vector< vtkActor * > trackActors =
314  m_ImageView->AddContour(iStructure.Nodes, trace_property);
315 
316  //has actor being created?
317  assert(trackActors[0]);
318 
319  // add actors address to structure
320  iStructure.ActorXY = trackActors[0];
321  iStructure.ActorXZ = trackActors[1];
322  iStructure.ActorYZ = trackActors[2];
323  iStructure.ActorXYZ = trackActors[3];
324 
325  this->m_ImageView->AddActor(3, trackActors[3]);
326 
327  trace_property->Delete();
328 }
329 //-------------------------------------------------------------------------
330 
331 //-------------------------------------------------------------------------
332 void
335 {
336  if(iStructure.Nodes->GetNumberOfPoints() < 2 )
337  {
338  // clean actor
339  this->m_ImageView->RemoveActor(0, iStructure.TreeNode.ActorXY);
340  this->m_ImageView->RemoveActor(1, iStructure.TreeNode.ActorXZ);
341  this->m_ImageView->RemoveActor(2, iStructure.TreeNode.ActorYZ);
342  this->m_ImageView->RemoveActor(3, iStructure.TreeNode.ActorXYZ);
343  }
344 }
345 //-------------------------------------------------------------------------
346 
347 //-------------------------------------------------------------------------
350 UpdatePointsForATrack(const unsigned int& iTrackID,
351  std::list< double * >& iListCenterBoundingBoxes)
352 {
353  assert( iTrackID != 0 );
354 
355  assert ( this->m_ImageView );
356 
357  // get pointer to the track
359  = m_Container.get< TraceID >().find(iTrackID);
360  TrackStructure* mother;
361 
362  if ( motherIt != m_Container.get< TraceID >().end() )
363  {
364 
365  /*
366  * \note Nicolas- const_cast is OK to modify polydata in the container since
367  we don't sort on it but better avoid it
368  */
369  mother = const_cast<TrackStructure*>(&(*motherIt));
370  RecomputeMap(mother, iListCenterBoundingBoxes);
371 
372  // if the element has no polydata create a new address for the polydata
373  if ( ! mother->Nodes )
374  {
375  //Create new polydata (new address)
376  mother->Nodes = vtkPolyData::New();
377  }
378 
379  // update the polydata (which represents the current track)
380  UpdateTrackStructurePolyData( *mother );
381 
382  // if element has no actors, create it
383  if ( ! mother->ActorXY )
384  {
385  // add actors in the visualization with given property
386  CreateTrackActors( *mother );
387  return mother;
388  }
389 
390  UpdateTrackActors( *mother );
391  }
392  else
393  {
394  mother = new TrackStructure;
395  }
396 
397  return mother;
398 }
399 //-------------------------------------------------------------------------
400 
401 //-------------------------------------------------------------------------
402 void
404 RecomputeMap(TrackStructure* iStructure, std::list< double * >& iPoints)
405 {
406 
407  // empty current element map
408  PointsMapConstIterator begin = iStructure->PointsMap.begin();
409  PointsMapConstIterator end = iStructure->PointsMap.end();
410 
411  while ( begin != end )
412  {
413  // free memory
414  delete[] begin->second;
415  ++begin;
416  }
417 
418  iStructure->PointsMap.clear();
419 
420  // add points to the map
421  std::list< double * >::iterator beginList = iPoints.begin();
422  std::list< double * >::iterator endList = iPoints.end();
423 
424  while ( beginList != endList )
425  {
426  int xyzBB[3] = {
427  static_cast< int >( ( *beginList )[0] ),
428  static_cast< int >( ( *beginList )[1] ),
429  static_cast< int >( ( *beginList )[2] )
430  };
431 
432  unsigned int time = static_cast< unsigned int >( ( *beginList )[3] );
433 
434  // convert xyz coordinates
435  double *xyz = m_ImageView->GetImageViewer(0)
437 
438  bool insertElement = iStructure->InsertElement(time, xyz);
439 
440  (void) insertElement;
441 
442  assert ( insertElement );
443 
444  ++beginList;
445  }
446 }
447 
448 //-------------------------------------------------------------------------
449 
450 //-------------------------------------------------------------------------
451 void
454  const Qt::CheckState & iCheck)
455 {
456 
458  iCheck);
459 }
460 
461 //-------------------------------------------------------------------------
462 
463 //-------------------------------------------------------------------------
464 void
467  const Qt::CheckState & iCheck)
468 {
470 }
471 //-------------------------------------------------------------------------
472 
473 //-------------------------------------------------------------------------
474 void
476 ChangeColorCode(const QString& iColorCode)
477 {
478  m_ActiveTrackScalars = iColorCode;
479 
480  if ( m_ActiveTrackScalars.compare("Original") )
481  {
482  // get range for the tracks
483  double *range = setTrackNodeScalars(iColorCode);
484 
485  // associated LUT
486  vtkSmartPointer< vtkLookupTable > LUT = vtkSmartPointer< vtkLookupTable >::New();
487  LUT->SetTableRange(range);
488  LUT->SetNumberOfTableValues(1024);
489  LUT->SetHueRange(0, 0.7);
490  LUT->SetSaturationRange(1, 1);
491  LUT->SetValueRange(1, 1);
492  LUT->Build();
493 
494  SetScalarRangeForAllElements(range[0], range[1]);
496 
497  delete[] range;
498  }
499  else
500  {
502  }
503 }
504 //-------------------------------------------------------------------------
505 
506 //-------------------------------------------------------------------------
507 void
510 {
512  m_ActiveDivisionScalars.append(iColorCode);
513 
514  if ( m_ActiveDivisionScalars.compare("Original") )
515  {
516  // get range for the division
517  double *range = setDivisionNodeScalars(iColorCode);
518 
519  // associated LUT
520  vtkSmartPointer< vtkLookupTable > LUT =
521  vtkSmartPointer< vtkLookupTable >::New();
522  LUT->SetTableRange(range);
523  LUT->SetNumberOfTableValues(1024);
524  LUT->SetHueRange(0, 0.7);
525  LUT->SetSaturationRange(1, 1);
526  LUT->SetValueRange(1, 1);
527  LUT->Build();
528 
529  SetScalarRangeForAllDivisions(range[0], range[1]);
531  }
532  else
533  {
535  }
536 
537  assert ( m_ImageView );
539 }
540 //-------------------------------------------------------------------------
541 
542 //-------------------------------------------------------------------------
543 void
545 SetScalarRangeForAllDivisions(const double& iMin, const double& iMax)
546 {
548  it = m_Container.get< TraceID >().begin();
549 
550  while ( it != m_Container.get< TraceID >().end() )
551  {
552  if ( !it->IsLeaf() )
553  {
554  it->TreeNode.SetScalarRange(iMin, iMax);
555  }
556  ++it;
557  }
558 }
559 //-------------------------------------------------------------------------
560 
561 //-------------------------------------------------------------------------
562 void
564 SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut)
565 {
567  it = m_Container.get< TraceID >().begin();
568 
569  while ( it != m_Container.get< TraceID >().end() )
570  {
571  if ( !it->IsLeaf() )
572  {
573  it->TreeNode.SetLookupTable(iLut);
574  }
575  ++it;
576  }
577 }
578 //-------------------------------------------------------------------------
579 
580 //-------------------------------------------------------------------------
581 void
584 {
586  it = m_Container.get< TraceID >().begin();
587 
588  while ( it != m_Container.get< TraceID >().end() )
589  {
590  if ( !it->IsLeaf() )
591  {
592  it->TreeNode.RenderWithOriginalColors();
593  }
594  ++it;
595  }
596 }
597 
598 //-------------------------------------------------------------------------
599 
600 //-------------------------------------------------------------------------
601 double *
603 setTrackNodeScalars(const QString& iArrayName)
604 {
605  double *range = new double[2];
606 
607  range[0] = std::numeric_limits< double >::max();
608  range[1] = std::numeric_limits< double >::min();
609 
611  it = m_Container.get< TraceID >().begin();
612 
613  while ( it != m_Container.get< TraceID >().end() )
614  {
615  // does the track have a polydata
616  if ( it->Nodes )
617  {
618  // convert qstring to const char*
619  double *realTime =
620  it->Nodes->GetPointData()->GetArray(
621  iArrayName.toLocal8Bit().data())->GetRange();
622  range[0] = std::min(range[0], realTime[0]);
623  range[1] = std::max(range[1], realTime[1]);
624 
625  //set active scalar
626  // convert qstring to const char*
627  it->Nodes->GetPointData()->SetActiveScalars(
628  iArrayName.toLocal8Bit().data());
629  }
630  ++it;
631  }
632 
633  return range;
634 }
635 
636 //-------------------------------------------------------------------------
637 
638 //-------------------------------------------------------------------------
639 double *
641 setDivisionNodeScalars(const QString& iArrayName)
642 {
643  double *range = new double[2];
644 
645  range[0] = std::numeric_limits< double >::max();
646  range[1] = std::numeric_limits< double >::min();
647 
649  it = m_Container.get< TraceID >().begin();
650 
651  while ( it != m_Container.get< TraceID >().end() )
652  {
653  // does the division have a polydata
654  if ( !it->IsLeaf() )
655  {
656  // convert qstring to const char*
657  double *realTime =
658  it->TreeNode.Nodes->GetPointData()->GetArray(
659  iArrayName.toLocal8Bit().data())->GetRange();
660  range[0] = std::min(range[0], realTime[0]);
661  range[1] = std::max(range[1], realTime[1]);
662 
663  //set active scalar
664  // convert qstring to const char*
665  it->TreeNode.Nodes->GetPointData()->SetActiveScalars(
666  iArrayName.toLocal8Bit().data());
667  }
668 
669  ++it;
670  }
671 
672  return range;
673 }
674 
675 //-------------------------------------------------------------------------
676 
677 //-------------------------------------------------------------------------
678 void
680 setTimeInterval(const int& iTimeInterval)
681 {
682  m_TimeInterval = iTimeInterval;
683 }
684 
685 //-------------------------------------------------------------------------
686 
687 //-------------------------------------------------------------------------
688 int
691 {
692  return m_TimeInterval;
693 }
694 
695 //-------------------------------------------------------------------------
696 
697 //-------------------------------------------------------------------------
698 void
700 UpdateTracksRepresentation(const double& iRadius,
701  const double& iRadius2,
702  const double& iWidth )
703 {
704  MultiIndexContainerType::iterator it = m_Container.begin();
705  bool IsThereNonNullRadius = ( iRadius > 0 || iRadius2 > 0 );
706 
707  while ( it != m_Container.end() )
708  {
709  // restore original polydata
710  bool pointsInPolydata = UpdateTrackStructurePolyData( ( *it ) );
711 
712  // add glyphs if necessary
713  if( pointsInPolydata )
714  {
715  if ( IsThereNonNullRadius )
716  {
717  it->UpdateTracksRepresentation(iRadius, iRadius2);
718  }
719  else
720  {
721  it->UpdateLineWidth( iWidth );
722  }
723  }
724  ++it;
725  }
726 
727  // update color since active scalar is set to NULL in
728  // UpdateTrackStructurePolyData
730 
731  assert ( this->m_ImageView );
732 
734 }
735 
736 //-------------------------------------------------------------------------
737 
738 //-------------------------------------------------------------------------
739 double*
740 TrackContainer::GetBorderOfTheTrack( const unsigned int& iTrackID,
741  const BorderType& iBorder)
742 {
744  it = m_Container.get< TraceID >().find(iTrackID);
745 
746  if( it != m_Container.get< TraceID >().end() )
747  {
748  vtkPolyData* nodes = it->Nodes;
749 
750  if( nodes )
751  {
752  vtkPoints* points = nodes->GetPoints();
753 
754  if( points )
755  {
756  if(!iBorder)
757  {
758  return points->GetPoint(0);
759  }
760  else
761  {
762  vtkIdType nbOfPoints = points->GetNumberOfPoints();
763  return points->GetPoint(nbOfPoints-1);
764  }
765  }
766  }
767  }
768 
769  return NULL;
770 }
771 //-------------------------------------------------------------------------
772 
773 //-------------------------------------------------------------------------
774 void
776 SetListOfDivisions( std::list<unsigned int>& iListOfDivisions)
777 {
778  // Create list iterator
779  std::list<unsigned int>::iterator it = iListOfDivisions.begin();
780 
781  while( it != iListOfDivisions.end() )
782  {
783  // get ids
784  unsigned int mother = *it;
785  ++it;
786  unsigned int daughter1 = *it;
787  ++it;
788  unsigned int daughter2 = *it;
789  ++it;
790  // create connections and actor for the division of interest
791  AddDivision(mother, daughter1, daughter2, false);
792  }
793 }
794 //-------------------------------------------------------------------------
795 
796 //-------------------------------------------------------------------------
797 void
799 AddDivision( const unsigned int& iMotherID, const unsigned int& iDaughter1ID,
800  const unsigned int& iDaughter2ID, const bool& iVisible)
801 {
802  // get address of the structures of interest
803  //------------------------------
805  = m_Container.get< TraceID >().find(iMotherID);
806 
807  if( motherIt != m_Container.get< TraceID >().end() )
808  {
810  = m_Container.get< TraceID >().find(iDaughter1ID);
811 
812  if( daughter1It != m_Container.get< TraceID >().end() )
813  {
815  = m_Container.get< TraceID >().find(iDaughter2ID);
816 
817  if( daughter2It != m_Container.get< TraceID >().end() )
818  {
819  // create connections
820  //------------------------------
821  // motherID->D1
822  // ->D2
823  //------------------------------
824  TrackStructure* mother = const_cast<TrackStructure*>(&(*motherIt));
825  mother->TreeNode.m_Child.push_back(
826  const_cast<TrackStructure*>(&(*daughter1It)));
827  mother->TreeNode.m_Child.push_back(
828  const_cast<TrackStructure*>(&(*daughter2It)));
829 
830  // Create Polydata
831  CreateDivisionPolydata(iMotherID);
832 
833  // Create Actor
834  /*
835  \todo Nicolas - should do it through a modify
836  */
837  std::vector< vtkActor * > actors =
838  CreateDivisionActor(mother->TreeNode.Nodes, iVisible);
839  mother->TreeNode.ActorXY = actors[0];
840  mother->TreeNode.ActorXZ = actors[1];
841  mother->TreeNode.ActorYZ = actors[2];
842  mother->TreeNode.ActorXYZ = actors[3];
843  mother->TreeNode.Visible = iVisible;
844 
845  //------------------------------
846  // D1->motherID
847  // D2->motherID
848  //------------------------------
849  /*
850  \todo Nicolas - should do it through a modify
851  */
852  TrackStructure* d1 = const_cast<TrackStructure*>(&(*daughter1It));
853  d1->TreeNode.m_Mother = const_cast<TrackStructure*>(&(*motherIt));
854 
855  TrackStructure* d2 = const_cast<TrackStructure*>(&(*daughter2It));
856  d2->TreeNode.m_Mother = const_cast<TrackStructure*>(&(*motherIt));
857 
859  }
860  }
861  }
862 }
863 //-------------------------------------------------------------------------
864 void
866 CreateDivisionPolydata(const unsigned int& iMother)
867 {
869  = m_Container.get< TraceID >().find(iMother);
870 
871  if( motherIt != m_Container.get< TraceID >().end() )
872  {
873  // Arnaud: what about if any of the parameter is NULL?
874  // Arnaud: what about if one daughter is in the field of view,
875  // and not the other one?
876  // Nicolas: dont deal with any of that yet
877 
878  // Get points of interest:
879  // Mother: last point
880  // D1 & D2: first point
881  double* mother = this->GetBorderOfTheTrack(iMother, LAST);
882 
883  if( !mother )
884  {
885  std::cout << "iMother : " << iMother << std::endl;
886  return;
887  }
888 
889  double* daughter1 = this->GetBorderOfTheTrack(
890  motherIt->TreeNode.m_Child[0]->TraceID, FIRST);
891 
892  if( !daughter1 )
893  {
894  std::cout << "iMother : " << iMother << std::endl;
895  std::cout << "daughter1: " << motherIt->TreeNode.m_Child[0]->TraceID << std::endl;
896  return;
897  }
898 
899  double* daughter2 = this->GetBorderOfTheTrack(
900  motherIt->TreeNode.m_Child[1]->TraceID, FIRST);
901 
902  if( !daughter2 )
903  {
904  std::cout << "iMother : " << iMother << std::endl;
905  std::cout << "daughter2: " << motherIt->TreeNode.m_Child[1]->TraceID << std::endl;
906  return;
907  }
908 
909  //setup points (geometry)
910  vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
911  points->InsertNextPoint ( daughter1[0], daughter1[1], daughter1[2] );
912  points->InsertNextPoint ( mother[0], mother[1], mother[2] );
913  points->InsertNextPoint ( daughter2[0], daughter2[1], daughter2[2] );
914 
915  // create the lines
916  vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
917  for(int i=0; i<2; ++i)
918  {
919  //Create the first line (between Origin and P0)
920  vtkSmartPointer<vtkLine> line =
921  vtkSmartPointer<vtkLine>::New();
922  line->GetPointIds()->SetId(0,i);
923  line->GetPointIds()->SetId(1,i+1);
924  lines->InsertNextCell(line);
925  }
926 
927  // create polydata
928  vtkSmartPointer<vtkPolyData> division = vtkSmartPointer<vtkPolyData>::New();
929  division->SetPoints(points);
930  division->SetLines(lines);
931  /*
932  * \todo Nicolas: we might want to extend it to more parameters: color, ...
933  * and to the meshes->efficiency of show/hide, picking, boxwidget, ...!
934  */
935  // add track ID to the polydata so we can get it from the actor later on
936  vtkSmartPointer<vtkIntArray> trackIDArray = vtkSmartPointer<vtkIntArray>::New();
937  trackIDArray->SetNumberOfComponents(1);
938  trackIDArray->SetNumberOfValues(1);
939  trackIDArray->SetName("DIVISION");
940  trackIDArray->SetValue(0,iMother);
941 
942  division->GetFieldData()->AddArray(trackIDArray);
943 
944  // update structure
945 
946  m_Container.get< TraceID >().modify( motherIt , create_node_division(division) );
947  }
948 }
949 //-------------------------------------------------------------------------
950 
951 //-------------------------------------------------------------------------
952 std::vector<vtkActor* >
954 CreateDivisionActor(vtkPolyData* iPolyData, const bool& iVisible)
955 {
956  /*
957  * \todo Nicolas: to be enhanced
958  */
959  vtkSmartPointer<vtkProperty> trace_property =
960  vtkSmartPointer<vtkProperty>::New();
961  double r = 1.0;
962  double g = 1.0;
963  double b = 1.0;
964  double a = 1.0;
965 
966  trace_property->SetColor(r,
967  g,
968  b);
969  trace_property->SetOpacity(a);
970 
971  std::vector< vtkActor * > divisionActors =
972  this->m_ImageView->AddContour( iPolyData, trace_property );
973 
974  /*
975  \todo Nicolas- clear all that. Should be requiered or should be consistent at least
976  */
977  // add it to visu??
978  if( iVisible )
979  {
980  // add to 3d
981  this->m_ImageView->AddActor(3, divisionActors[3]);
982  }
983  else
984  {
985  // remove from 2d
986  this->m_ImageView->RemoveActor(0, divisionActors[0]);
987  this->m_ImageView->RemoveActor(1, divisionActors[1]);
988  this->m_ImageView->RemoveActor(2, divisionActors[2]);
989  }
990 
991  return divisionActors;
992 }
993 //-------------------------------------------------------------------------
994 
995 //-------------------------------------------------------------------------
996 void
998 HighlightCollection(const unsigned int& iRootTrackID, const bool& iHilighted)
999 {
1001  = m_Container.get< TraceID >().find(iRootTrackID);
1002 
1003  if( motherIt != m_Container.get< TraceID >().end() )
1004  {
1005  UpdateCollectionHighlighted(motherIt, iHilighted);
1006 
1008  }
1009 }
1010 //-------------------------------------------------------------------------
1011 
1012 //-------------------------------------------------------------------------
1013 void
1015 ShowCollection(const unsigned int& iRootTrackID, const bool& iVisible)
1016 {
1018  = m_Container.get< TraceID >().find(iRootTrackID);
1019 
1020  if( motherIt != m_Container.get< TraceID >().end() )
1021  {
1022  UpdateCollectionVisibility(motherIt, iVisible);
1023 
1025  }
1026 }
1027 //-------------------------------------------------------------------------
1028 
1029 //-------------------------------------------------------------------------
1030 void
1033  const bool& iVisible)
1034 {
1035  if( !it->IsLeaf() )
1036  {
1037  ModifyDivisionVisibility(it, iVisible);
1038  }
1039 
1040  std::vector<TrackStructure*>::const_iterator itDivision =
1041  it->TreeNode.m_Child.begin();
1042 
1043  while(itDivision != it->TreeNode.m_Child.end())
1044  {
1045  // find the iterator
1047  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1048 
1049  if( childIt != m_Container.get< TraceID >().end() )
1050  {
1051  UpdateCollectionVisibility(childIt,iVisible);
1052  }
1053  ++itDivision;
1054  }
1055 }
1056 //-------------------------------------------------------------------------
1057 //-------------------------------------------------------------------------
1058 void
1060 DeleteCollection(unsigned int iRootTrackID)
1061 {
1063  = m_Container.get< TraceID >().find(iRootTrackID);
1064 
1065  if( motherIt != m_Container.get< TraceID >().end() )
1066  {
1067  UpdateCollectionDelete(motherIt);
1068 
1070  }
1071 }
1072 //-------------------------------------------------------------------------
1073 
1074 //-------------------------------------------------------------------------
1075 void
1078 {
1079  std::vector<TrackStructure*>::const_iterator itDivision =
1080  it->TreeNode.m_Child.begin();
1081 
1082  while(itDivision != it->TreeNode.m_Child.end())
1083  {
1084  // find the iterator
1086  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1087 
1088  if( childIt != m_Container.get< TraceID >().end() )
1089  {
1090  UpdateCollectionDelete(childIt);
1091  }
1092  ++itDivision;
1093  }
1094 
1095  if( !it->IsLeaf() )
1096  {
1097  DeleteADivision(it->TraceID);
1098  }
1099 }
1100 //-------------------------------------------------------------------------
1101 
1102 //-------------------------------------------------------------------------
1103 void
1106  const bool& iHighlighted)
1107 {
1108  if( !it->IsLeaf() )
1109  {
1110  ModifyDivisionHighlight(it, iHighlighted);
1111  }
1112 
1113  std::vector<TrackStructure*>::const_iterator itDivision =
1114  it->TreeNode.m_Child.begin();
1115 
1116  while(itDivision != it->TreeNode.m_Child.end())
1117  {
1118  // find the iterator
1120  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1121 
1122  if( childIt != m_Container.get< TraceID >().end() )
1123  {
1124  UpdateCollectionHighlighted(childIt,iHighlighted);
1125  }
1126  ++itDivision;
1127  }
1128 }
1129 //-------------------------------------------------------------------------
1130 
1131 //-------------------------------------------------------------------------
1132 int
1135  const bool& iVisible)
1136 {
1137  m_Container.get< TraceID >().modify( it , change_visible_division(iVisible) );
1138 
1139  typedef void ( QGoImageView3D::*ImageViewMember )(const int &, vtkActor *);
1140  ImageViewMember f;
1141 
1142  if ( iVisible )
1143  {
1145  }
1146  else
1147  {
1149  }
1150 
1151  assert( m_ImageView );
1152  ( m_ImageView->*f )(0, it->TreeNode.ActorXY);
1153  ( m_ImageView->*f )(1, it->TreeNode.ActorXZ);
1154  ( m_ImageView->*f )(2, it->TreeNode.ActorYZ);
1155  ( m_ImageView->*f )(3, it->TreeNode.ActorXYZ);
1156 
1157  return 1;
1158 }
1159 //-------------------------------------------------------------------------
1160 
1161 //-------------------------------------------------------------------------
1162 int
1165  const bool& iHighlight )
1166 {
1167  vtkProperty* temp_property = vtkProperty::New();
1168  if (!iHighlight)
1169  {
1170  temp_property->SetColor(it->TreeNode.rgba[0],
1171  it->TreeNode.rgba[1],
1172  it->TreeNode.rgba[2]);
1173  temp_property->SetOpacity(it->TreeNode.rgba[3]);
1174  temp_property->SetLineWidth(this->m_IntersectionLineWidth);
1175  }
1176  else
1177  {
1178  temp_property->DeepCopy(this->m_HighlightedProperty);
1179  }
1180 
1181  m_Container.get< TraceID >().modify(
1182  it, change_highlighted_division(temp_property, iHighlight));
1183 
1184  temp_property->Delete();
1185 
1186  return 1;
1187 }
1188 //-------------------------------------------------------------------------
1189 
1190 //-------------------------------------------------------------------------
1191 void
1193 DeleteADivision( const unsigned int& iMotherID)
1194 {
1195  // find iterator
1197  = m_Container.get< TraceID >().find(iMotherID);
1198 
1199  if(motherIt!= m_Container.get< TraceID >().end())
1200  {
1201  TrackStructure* mother = const_cast<TrackStructure*>(&(*motherIt));
1202 
1203  // Delete the actor
1204  // remove actor from visu and delete them
1205  this->m_ImageView->RemoveActor(0, mother->TreeNode.ActorXY);
1206  this->m_ImageView->RemoveActor(1, mother->TreeNode.ActorXZ);
1207  this->m_ImageView->RemoveActor(2, mother->TreeNode.ActorYZ);
1208  this->m_ImageView->RemoveActor(3, mother->TreeNode.ActorXYZ);
1209  mother->TreeNode.ReleaseData();
1210 
1211  // Reset pointers
1212  // child (to do first)
1213  /*
1214  \todo Nicolas - do a loop
1215  */
1216  mother->TreeNode.m_Child[0]->TreeNode.m_Mother = NULL;
1217  mother->TreeNode.m_Child[1]->TreeNode.m_Mother = NULL;
1218 
1219  // mother
1220  mother->TreeNode.m_Child.resize(0);
1221  }
1222 }
1223 //-------------------------------------------------------------------------
1224 
1225 //-------------------------------------------------------------------------
1226 std::list<unsigned int>
1228 GetSubLineage( const unsigned int& iTrackID )
1229 {
1230  std::list<unsigned int> listOfIDs;
1231 
1232  // find the iterator
1234  = m_Container.get< TraceID >().find(iTrackID);
1235 
1236  if( motherIt != m_Container.get< TraceID >().end() )
1237  {
1238  UpdateSubLineage(motherIt, listOfIDs);
1239  }
1240 
1241  return listOfIDs;
1242 }
1243 //-------------------------------------------------------------------------
1244 
1245 //-------------------------------------------------------------------------
1246 void
1249  std::list<unsigned int>& iList)
1250 {
1251  iList.push_back( it->TraceID );
1252 
1253  std::vector<TrackStructure*>::const_iterator itDivision =
1254  it->TreeNode.m_Child.begin();
1255 
1256  while(itDivision != it->TreeNode.m_Child.end())
1257  {
1258  // find the iterator
1260  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1261  if( childIt != m_Container.get< TraceID >().end() )
1262  {
1263  UpdateSubLineage(childIt,iList);
1264  }
1265  ++itDivision;
1266  }
1267 }
1268 //-------------------------------------------------------------------------
1269 
1270 //-------------------------------------------------------------------------
1271 void
1273 UpdateCollectionHighlighting(const unsigned int& iTraceId)
1274 {
1276  = m_Container.get< TraceID >().find(iTraceId);
1277 
1278  if(motherIt!=m_Container.get<TraceID>().end())
1279  {
1280  GetRootIterator( motherIt );
1281 
1282  bool highlight = !motherIt->TreeNode.Highlighted;
1283 
1284  UpdateCollectionHighlighted(motherIt, highlight);
1285 
1287 
1288  // send signal to lineage container
1289  emit UpdateLineageHighlightingFromTrackRootID( motherIt->TraceID );
1290  }
1291 }
1292 //-------------------------------------------------------------------------
1293 
1294 //-------------------------------------------------------------------------
1295 void
1298 {
1299  if( iMotherIterator->IsRoot() )
1300  {
1301  return;
1302  }
1303 
1304  iMotherIterator
1305  = m_Container.get< TraceID >().find( iMotherIterator->TreeNode.m_Mother->TraceID );
1306  GetRootIterator( iMotherIterator );
1307 }
1308 //-------------------------------------------------------------------------
1309 
1310 //-------------------------------------------------------------------------
1313 UpdateDivisionsForALineage(unsigned int iTrackIDRoot, double* color)
1314 {
1316  = m_Container.get< TraceID >().find(iTrackIDRoot);
1317  GoFigureLineageAttributes Attributes;
1318  if(motherIt!=m_Container.get<TraceID>().end())
1319  {
1320  UpdateDivisionScalar(motherIt, 0); // 0=depth of the root
1321  Attributes = this->GetLineageAttributes(iTrackIDRoot);
1322  UpdateDivisionColor(motherIt, color);
1324  }
1325 
1326  return Attributes;
1327 }
1328 //-------------------------------------------------------------------------
1329 
1330 //-------------------------------------------------------------------------
1333 UpdateCollectionScalars(const unsigned int& iTrackID)
1334 {
1336  = m_Container.get< TraceID >().find(iTrackID);
1337  GoFigureLineageAttributes oAttributes;
1338  if( motherIt != m_Container.get< TraceID >().end() )
1339  {
1340  UpdateDivisionScalar(motherIt, 0);
1341  oAttributes = this->GetLineageAttributes(iTrackID);
1342  // 0=depth of the root
1343  }
1344  return oAttributes;
1345 }
1346 //-------------------------------------------------------------------------
1347 
1348 //-------------------------------------------------------------------------
1349 void
1352  const unsigned int& iDepth)
1353 {
1354  if(!it->IsLeaf())
1355  {
1356  //add array
1357  vtkSmartPointer< vtkIntArray > depthArray =
1358  vtkSmartPointer< vtkIntArray >::New();
1359  depthArray->SetNumberOfComponents(1);
1360  depthArray->SetName("DepthInformation");
1361  depthArray->InsertNextValue(iDepth);
1362  depthArray->InsertNextValue(iDepth);
1363  depthArray->InsertNextValue(iDepth);
1364  m_Container.get< TraceID >().modify( it , add_array_division(depthArray) );
1365  }
1366 
1367  std::vector<TrackStructure*>::const_iterator itDivision =
1368  it->TreeNode.m_Child.begin();
1369 
1370  while(itDivision != it->TreeNode.m_Child.end())
1371  {
1372  // find the iterator
1374  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1375  if( childIt != m_Container.get< TraceID >().end() )
1376  {
1377  unsigned int depth = iDepth+1;
1378  UpdateDivisionScalar(childIt,depth);
1379  }
1380  ++itDivision;
1381  }
1382 }
1383 //-------------------------------------------------------------------------
1384 
1385 //-------------------------------------------------------------------------
1386 void
1388 UpdateCollectionColors(const unsigned int& iTrackID, const double* color)
1389 {
1391  = m_Container.get< TraceID >().find(iTrackID);
1392 
1393  if(motherIt != m_Container.get< TraceID >().end())
1394  {
1395  UpdateDivisionColor(motherIt, color);
1396 
1398  }
1399 }
1400 //-------------------------------------------------------------------------
1401 
1402 //-------------------------------------------------------------------------
1403 void
1406  const double* iColor)
1407 {
1408  if(!it->IsLeaf())
1409  {
1410  m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) );
1411  m_Container.get< TraceID >().modify( it , change_actor_color_division(iColor) );
1412  }
1413 
1414  std::vector<TrackStructure*>::const_iterator itDivision =
1415  it->TreeNode.m_Child.begin();
1416 
1417  while(itDivision != it->TreeNode.m_Child.end())
1418  {
1419  // find the iterator
1421  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1422  if( childIt != m_Container.get< TraceID >().end() )
1423  {
1424  UpdateDivisionColor(childIt,iColor);
1425  }
1426  ++itDivision;
1427  }
1428 }
1429 //-------------------------------------------------------------------------
1430 
1431 //-------------------------------------------------------------------------
1432 void
1434 UpdateCollectionColorsData(const unsigned int& iTrackID, const double* color)
1435 {
1437  = m_Container.get< TraceID >().find(iTrackID);
1438 
1439  if( motherIt != m_Container.get< TraceID >().end() )
1440  {
1441  UpdateDivisionColorData(motherIt, color);
1442 
1444  }
1445 }
1446 //-------------------------------------------------------------------------
1447 
1448 //-------------------------------------------------------------------------
1449 void
1452  const double* iColor)
1453 {
1454  if(!it->IsLeaf())
1455  {
1456  m_Container.get< TraceID >().modify( it , change_data_color_division(iColor) );
1457  }
1458 
1459  std::vector<TrackStructure*>::const_iterator itDivision =
1460  it->TreeNode.m_Child.begin();
1461 
1462  while(itDivision != it->TreeNode.m_Child.end())
1463  {
1464  // find the iterator
1466  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1467  if( childIt != m_Container.get< TraceID >().end() )
1468  {
1469  UpdateDivisionColorData(childIt,iColor);
1470  }
1471  ++itDivision;
1472  }
1473 }
1474 //-------------------------------------------------------------------------
1475 
1476 //-------------------------------------------------------------------------
1477 unsigned int
1479 GetCollectionMaxDepth(const unsigned int& iTrackRootID)
1480 {
1482  = m_Container.get< TraceID >().find(iTrackRootID);
1483 
1484  if( motherIt != m_Container.get< TraceID >().end() )
1485  {
1486  unsigned int depth = 0;
1487  UpdateCollectionMaxDepth(motherIt, 0, depth); //0: root depth
1488 
1489  return depth;
1490  }
1491  else
1492  {
1493  return 0;
1494  }
1495 }
1496 //-------------------------------------------------------------------------
1497 
1498 //-------------------------------------------------------------------------
1499 void
1502  const unsigned int& iDivisionDepth,
1503  unsigned int& iLineageDepth)
1504 {
1505  if( it->IsLeaf() )
1506  {
1507  if( iDivisionDepth > iLineageDepth )
1508  {
1509  iLineageDepth = iDivisionDepth;
1510  }
1511  }
1512  std::vector<TrackStructure*>::const_iterator itDivision =
1513  it->TreeNode.m_Child.begin();
1514 
1515  while(itDivision != it->TreeNode.m_Child.end())
1516  {
1517  // find the iterator
1519  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1520  if( childIt != m_Container.get< TraceID >().end() )
1521  {
1522  unsigned int depth = iDivisionDepth+1;
1523  UpdateCollectionMaxDepth(childIt,depth,iLineageDepth);
1524  }
1525  ++itDivision;
1526  }
1527 }
1528 //-------------------------------------------------------------------------
1529 
1530 //-------------------------------------------------------------------------
1531 unsigned int
1533 GetCollectionMinDepth(const unsigned int& iTrackRootID)
1534 {
1536  = m_Container.get< TraceID >().find(iTrackRootID);
1537 
1538  if( motherIt != m_Container.get< TraceID >().end() )
1539  {
1540  unsigned int depth = std::numeric_limits<unsigned int>::max();
1541  UpdateCollectionMinDepth(motherIt, 0, depth); //0: root depth
1542 
1543  return depth;
1544  }
1545  else
1546  {
1547  return 0;
1548  }
1549 }
1550 //-------------------------------------------------------------------------
1551 
1552 //-------------------------------------------------------------------------
1553 void
1556  const unsigned int& iDivisionDepth,
1557  unsigned int& iLineageDepth)
1558 {
1559  if( it->IsLeaf() )
1560  {
1561  if( iDivisionDepth < iLineageDepth )
1562  {
1563  iLineageDepth = iDivisionDepth;
1564  }
1565  }
1566 
1567  std::vector<TrackStructure*>::const_iterator itDivision =
1568  it->TreeNode.m_Child.begin();
1569 
1570  while(itDivision != it->TreeNode.m_Child.end())
1571  {
1572  // find the iterator
1574  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1575  if( childIt != m_Container.get< TraceID >().end() )
1576  {
1577  unsigned int depth = iDivisionDepth+1;
1578  UpdateCollectionMinDepth(childIt,depth,iLineageDepth);
1579  }
1580  ++itDivision;
1581  }
1582 }
1583 //-------------------------------------------------------------------------
1584 
1585 //-------------------------------------------------------------------------
1586 unsigned int
1588 GetCollectionNumberOfDivisions(const unsigned int& iTrackRootID)
1589 {
1591  = m_Container.get< TraceID >().find(iTrackRootID);
1592 
1593  if( motherIt != m_Container.get< TraceID >().end() )
1594  {
1595  unsigned int numberOfDivisions = 0;
1596  UpdateCollectionNumberOfDivisions(motherIt,numberOfDivisions);
1597 
1598  return numberOfDivisions;
1599  }
1600  else
1601  {
1602  return 0;
1603  }
1604 }
1605 //-------------------------------------------------------------------------
1606 
1607 //-------------------------------------------------------------------------
1608 void
1611  unsigned int& iNumberOfDivisions)
1612 {
1613  if(!it->IsLeaf())
1614  {
1615  ++iNumberOfDivisions;
1616  }
1617 
1618  std::vector<TrackStructure*>::const_iterator itDivision =
1619  it->TreeNode.m_Child.begin();
1620 
1621  while(itDivision != it->TreeNode.m_Child.end())
1622  {
1623  // find the iterator
1625  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1626  if( childIt != m_Container.get< TraceID >().end() )
1627  {
1628  UpdateCollectionNumberOfDivisions(childIt,iNumberOfDivisions);
1629  }
1630  ++itDivision;
1631  }
1632 }
1633 //-------------------------------------------------------------------------
1634 
1635 //-------------------------------------------------------------------------
1636 unsigned int
1638 GetCollectionNumberOfLeaves(const unsigned int& iTrackRootID)
1639 {
1641  = m_Container.get< TraceID >().find(iTrackRootID);
1642 
1643  if(motherIt != m_Container.get< TraceID >().end())
1644  {
1645  unsigned int numberOfLeaves = 1;
1646  UpdateCollectionNumberOfDivisions(motherIt,numberOfLeaves);
1647 
1648  return numberOfLeaves;
1649  }
1650  else
1651  {
1652  return 0;
1653  }
1654 }
1655 //-------------------------------------------------------------------------
1656 
1657 //-------------------------------------------------------------------------
1660 GetLineageAttributes(unsigned int iTrackRootID)
1661 {
1662  //check if possible to iterate on the tree only once
1663  GoFigureLineageAttributes LineageAttributes;
1664 
1665  LineageAttributes.MaxDepth = this->GetCollectionMaxDepth(iTrackRootID);
1666  LineageAttributes.MinDepth = this->GetCollectionMinDepth(iTrackRootID);
1667  LineageAttributes.NumberOfDivisions = this->GetCollectionNumberOfDivisions(iTrackRootID);
1668  LineageAttributes.NumberOfLeaves = this->GetCollectionNumberOfLeaves( iTrackRootID);
1669 
1670  return LineageAttributes;
1671 }
1672 //-------------------------------------------------------------------------
1673 
1674 //-------------------------------------------------------------------------
1675 void
1678  unsigned int& iNumberOfLeaves)
1679 {
1680  if(it->IsLeaf())
1681  {
1682  ++iNumberOfLeaves;
1683  }
1684 
1685  std::vector<TrackStructure*>::const_iterator itDivision =
1686  it->TreeNode.m_Child.begin();
1687 
1688  while(itDivision != it->TreeNode.m_Child.end())
1689  {
1690  // find the iterator
1692  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1693  if( childIt != m_Container.get< TraceID >().end() )
1694  {
1695  UpdateCollectionNumberOfLeaves(childIt,iNumberOfLeaves);
1696  }
1697  ++itDivision;
1698  }
1699 }
1700 //-------------------------------------------------------------------------
1701 
1702 //-------------------------------------------------------------------------
1703 vtkMutableDirectedGraph*
1705 ExportLineage(const unsigned int& iTrackID)
1706 {
1708  = m_Container.get< TraceID >().find(iTrackID);
1709 
1710  // graph to be exported
1711  vtkMutableDirectedGraph* graph = vtkMutableDirectedGraph::New();
1712  unsigned int pedigree = graph->AddVertex();
1713 
1714  // arrays we want to export
1715  vtkDoubleArray* id = vtkDoubleArray::New();
1716  id->SetName("Track ID");
1717 
1718  // arrays we want to export
1719  vtkDoubleArray* depth = vtkDoubleArray::New();
1720  depth->SetName("Lineage Depth");
1721 
1722  vtkStringArray* cellType = vtkStringArray::New();
1723  depth->SetName("Cell Type");
1724 
1725  UpdateLineage(motherIt,
1726  graph,
1727  pedigree,
1728  0, // mother vtkIDtype
1729  0,depth,// depth information
1730  id); // id info
1731 
1732  graph->GetVertexData()->AddArray(id);
1733  graph->GetVertexData()->AddArray(depth);
1734 
1735  // delete array
1736  id->Delete();
1737  depth->Delete();
1738  cellType->Delete();
1739 
1740  return graph;
1741 }
1742 //-------------------------------------------------------------------------
1743 
1744 //-------------------------------------------------------------------------
1745 void
1748  vtkMutableDirectedGraph* iGraph, unsigned int iPedrigree,
1749  vtkIdType mother, unsigned int iDepth,
1750  vtkDoubleArray* iDepthArray, vtkDoubleArray* iIDArray)
1751 {
1752  // Update mother ID
1753  vtkIdType motherPedigree = iPedrigree;
1754 
1755  //add info
1756  iIDArray->InsertValue(iPedrigree, it->TraceID);
1757  // add info
1758  iDepthArray->InsertValue(iPedrigree, iDepth);
1759 
1760  if( it->IsLeaf() )
1761  {
1762  return;
1763  }
1764 
1765  std::vector<TrackStructure*>::const_iterator itDivision =
1766  it->TreeNode.m_Child.begin();
1767 
1768  while(itDivision != it->TreeNode.m_Child.end())
1769  {
1770  // find the iterator
1772  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1773  // add edge
1774  iPedrigree = iGraph->AddChild(motherPedigree);
1775  //go through tree
1776  UpdateLineage(childIt,iGraph, iPedrigree, motherPedigree, iDepth+1, iDepthArray,iIDArray);
1777  ++itDivision;
1778  }
1779 }
1780 //-------------------------------------------------------------------------
1781 
1782 //-------------------------------------------------------------------------
1783 void
1785 SetCollectionColorCode(const std::string& iColumnName,
1786  const std::map< unsigned int, std::string >& iValues)
1787 {
1788  typedef std::map< unsigned int, std::string > MapType;
1789  typedef MapType::const_iterator MapConstIterator;
1790 
1791  std::map< std::string, double > stringmap;
1792 
1793  if ( iColumnName.empty() || iValues.empty() )
1794  {
1796  assert ( m_ImageView );
1798  return;
1799  }
1800 
1801  MapConstIterator it = iValues.begin();
1802 
1803  double temp = 0.;
1804  try
1805  {
1806  temp = boost::lexical_cast< double >(it->second);
1807  }
1808  catch(boost::bad_lexical_cast &)
1809  {
1810  if ( stringmap.empty() )
1811  {
1812  stringmap[it->second] = 0.;
1813  }
1814  else
1815  {
1816  std::map< std::string, double >::iterator m_it = stringmap.find(it->second);
1817 
1818  if ( m_it != stringmap.end() )
1819  {
1820  temp = m_it->second;
1821  }
1822  else
1823  {
1824  std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin();
1825  temp = r_it->second;
1826  temp += 1.0;
1827  }
1828  }
1829  }
1830 
1831  double min_value = temp;
1832  double max_value = temp;
1833 
1834  while ( it != iValues.end() )
1835  {
1836 
1838  trace_it = this->m_Container.get< TraceID >().find(it->first);
1839 
1840  // convert value
1841  // Here let's make sure you are not passing crazy values!
1842  try
1843  {
1844  temp = boost::lexical_cast< double >(it->second);
1845  }
1846  catch(boost::bad_lexical_cast &)
1847  {
1848  // stringmap is not empty and has at least one elements
1849  std::map< std::string, double >::iterator m_it = stringmap.find(it->second);
1850 
1851  if ( m_it != stringmap.end() )
1852  {
1853  temp = m_it->second;
1854  }
1855  else
1856  {
1857  std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin();
1858  temp = r_it->second;
1859  temp += 1.0;
1860  }
1861  }
1862 
1863  UpdateDivisionScalarData(trace_it, it->second, temp, min_value, max_value);
1864  ++it;
1865  }
1866 
1867  SetScalarRangeForAllDivisions(min_value, max_value);
1868 
1869  assert ( m_ImageView );
1871 }
1872 //-------------------------------------------------------------------------
1873 
1874 //-------------------------------------------------------------------------
1875 void
1878  const std::string& iColumnName, const double& iValue,
1879  double& iMin, double& iMax)
1880 {
1881 
1882  if( !it->IsLeaf() )
1883  {
1884  if ( iValue > iMax )
1885  {
1886  iMax = iValue;
1887  }
1888  if ( iValue < iMin )
1889  {
1890  iMin = iValue;
1891  }
1892 
1893  it->TreeNode.SetScalarData(iColumnName, iValue);
1894  }
1895 
1896  std::vector<TrackStructure*>::const_iterator itDivision =
1897  it->TreeNode.m_Child.begin();
1898 
1899  while( itDivision != it->TreeNode.m_Child.end())
1900  {
1901  // find the iterator
1903  = m_Container.get< TraceID >().find((*itDivision)->TraceID);
1904  if( childIt != m_Container.get< TraceID >().end() )
1905  {
1906  UpdateDivisionScalarData(childIt, iColumnName, iValue, iMin, iMax);
1907  }
1908  ++itDivision;
1909  }
1910 }
1911 //-------------------------------------------------------------------------
1912 
1913 //-------------------------------------------------------------------------
1914 void
1916 SetDivisionRandomColor(const std::string & iColumnName,
1917  const std::map< unsigned int, std::string > & iValues)
1918 {
1919  typedef std::map< unsigned int, std::string > MapType;
1920  typedef MapType::const_iterator MapConstIterator;
1921 
1922  std::map< std::string, double > stringmap;
1923 
1924  if ( iColumnName.empty() || iValues.empty() )
1925  {
1927  return;
1928  }
1929 
1930  MapConstIterator it = iValues.begin();
1931 
1932  double temp = 0.;
1933  try
1934  {
1935  temp = boost::lexical_cast< double >(it->second);
1936  }
1937  catch(boost::bad_lexical_cast &)
1938  {
1939  if ( stringmap.empty() )
1940  {
1941  stringmap[it->second] = 0.;
1942  }
1943  else
1944  {
1945  std::map< std::string, double >::iterator m_it = stringmap.find(it->second);
1946 
1947  if ( m_it != stringmap.end() )
1948  {
1949  temp = m_it->second;
1950  }
1951  else
1952  {
1953  std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin();
1954  temp = r_it->second;
1955  temp += 1.0;
1956  }
1957  }
1958  }
1959 
1960  unsigned int val = static_cast< unsigned int >(temp);
1961  unsigned int modulo = val % 30;
1962 
1963  temp = static_cast< double >(modulo);
1964 
1965  double min_value = temp;
1966  double max_value = temp;
1967 
1968  using boost::multi_index:: get;
1969 
1970  while ( it != iValues.end() )
1971  {
1973  trace_it = this->m_Container.get< TraceID >().find(it->first);
1974 
1975  if ( trace_it != this->m_Container.get< TraceID >().end() )
1976  {
1977  if ( trace_it->TreeNode.Nodes ) //make sure the trace has points !!!
1978  {
1979  // Here let's make sure you are not passing crazy values!
1980  try
1981  {
1982  temp = boost::lexical_cast< double >(it->second);
1983  }
1984  catch(boost::bad_lexical_cast &)
1985  {
1986  // stringmap is not empty and has at least one element
1987  std::map< std::string, double >::iterator m_it = stringmap.find(it->second);
1988 
1989  if ( m_it != stringmap.end() )
1990  {
1991  temp = m_it->second;
1992  }
1993  else
1994  {
1995  std::map< std::string, double >::reverse_iterator r_it = stringmap.rbegin();
1996  temp = r_it->second;
1997  temp += 1.0;
1998  }
1999  }
2000 
2001  val = static_cast< unsigned int >(temp);
2002  modulo = val % 30;
2003 
2004  temp = static_cast< double >(modulo);
2005 
2006  UpdateDivisionScalarData(trace_it, it->second, temp, min_value, max_value);
2007  }
2008  } //end make sure the trace has points !!!
2009  ++it;
2010  }
2011 
2012  SetScalarRangeForAllDivisions(min_value, max_value);
2013 
2014  assert ( m_ImageView );
2016 }
2017 //-------------------------------------------------------------------------
2018 
2019 //-------------------------------------------------------------------------
2020 void
2022 AddVolume(const unsigned int& iTrackID, const double& iVolume)
2023 {
2025  trace_it = this->m_Container.get< TraceID >().find(iTrackID);
2026 
2027  if ( trace_it != m_Container.get< TraceID >().end() )
2028  {
2029  m_Container.get< TraceID >().modify( trace_it , add_volume(iVolume) );
2030  }
2031 }
2032 //-------------------------------------------------------------------------
QString & append(QChar ch)
double * setTrackNodeScalars(const QString &iArrayName)
Changes the scalars to be displayed and return the new range.
unsigned int GetCollectionNumberOfLeaves(const unsigned int &iTrackRootID)
virtual double * GetWorldCoordinatesFromImageCoordinates(int indices[3])
Convert an indices coordinate point (image coordinates) into a world coordinate point.
Add an array to a division with an unary function. Useful for the color coding.
virtual ~TrackContainer()
Destructor.
void UpdateRenderWindows()
Update only the visualization.
void CreateTrackActors(TrackStructure &iStructure)
Create new actors for the current polydata and update and visualize the current actors.
GoFigureTrackAttributes ComputeAttributes() const
QString m_ActiveTrackScalars
void UpdateCollectionHighlighted(MultiIndexContainerTraceIDIterator &it, const bool &iHighlighted)
int ModifyDivisionHighlight(MultiIndexContainerTraceIDIterator &it, const bool &iHighlight)
MultiIndexContainerType::template index< TraceID >::type::iterator MultiIndexContainerTraceIDIterator
void SetCollectionColorCode(const std::string &iColumnName, const std::map< unsigned int, std::string > &iValues)
MultiIndexContainerType m_Container
Trace Contaienr.
virtual void UpdateElementHighlightingWithGivenTraceIDsBase(const QStringList &iList, const Qt::CheckState &iCheck)
Change elements highlighting property given a list of TraceIDs and the new status.
void HighlightCollection(const unsigned int &iRootTrackID, const bool &iHighlighted)
vtkActor * ActorXYZ
void SetScalarRangeForAllElements(const double &iMin, const double &iMax)
Set the scalar range.
void UpdateDivisionColorData(MultiIndexContainerTraceIDIterator &iMotherIterator, const double *iColor)
std::vector< vtkActor * > AddContour(vtkPolyData *iDataset, vtkProperty *iProperty=NULL)
Add contour with given property into the visualization.
vtkMutableDirectedGraph * ExportLineage(const unsigned int &iTrackID)
void SetLookupTableForAllDivisionsColorCoding(const vtkLookupTable *iLut)
int ModifyDivisionVisibility(MultiIndexContainerTraceIDIterator &it, const bool &iVisibility)
void setTimeInterval(const int &iTimeInterval)
void UpdateCollectionMaxDepth(MultiIndexContainerTraceIDIterator &it, const unsigned int &iDivisionDepth, unsigned int &iLineageDepth)
void ResetNodes() const
void DeleteADivision(const unsigned int &iMotherID)
void clear()
vtkViewImage2D * GetImageViewer(const int &iId)
Create a polydata for a division with an unary function. Useful for the color coding.
Change the visibility of a division with an unary function.
void DeleteCollection(unsigned int)
unsigned int GetCollectionNumberOfDivisions(const unsigned int &iTrackRootID)
void SetScalarRangeForAllDivisions(const double &iMin, const double &iMax)
MultiIndexContainerType::template index< Highlighted >::type::iterator MultiIndexContainerHighlightedIterator
void ChangeColorCode(const QString &iColorCode)
Color code the track by an array.
TreeNodeStructure< Self > TreeNode
void UpdateLineageHighlightingFromTrackRootID(unsigned int)
class for the visualization of 3D Image represented by one vtkImageData*.
unsigned int GetCollectionMinDepth(const unsigned int &iTrackRootID)
GoFigureLineageAttributes GetLineageAttributes(unsigned int iTrackRootID)
unsigned int GetCollectionMaxDepth(const unsigned int &iTrackRootID)
void UpdateCollectionColors(const unsigned int &iTrackID, const double *color)
virtual void RemoveActor(const int &iId, vtkActor *iActor)
Change the highlight of a division with an unary function.
PointsMapType PointsMap
void UpdateSubLineage(MultiIndexContainerTraceIDIterator it, std::list< unsigned int > &iList)
void ImportTrackInCurrentElement(std::map< unsigned int, double * > &iMeshes)
Update the current element map then polydata.
Structure which represent a track, and used for interaction between Visualization and TableWidget...
bool UpdateTrackStructurePolyData(const TrackStructure &iTrackStructure)
Update the TrackStructure polydata according to the current map.
void UpdateLineage(MultiIndexContainerTraceIDIterator &it, vtkMutableDirectedGraph *iGraph, unsigned int iPedrigree, vtkIdType mother, unsigned int iDepth, vtkDoubleArray *iDepthArray, vtkDoubleArray *iIDArray)
QString m_ActiveDivisionScalars
double * GetBorderOfTheTrack(const unsigned int &iTrackID, const BorderType &iBorder)
void ChangeDivisionsColorCode(const QString &iColorCode)
Color code the lineage by an array.
void UpdateCollectionMinDepth(MultiIndexContainerTraceIDIterator &it, const unsigned int &iDivisionDepth, unsigned int &iLineageDepth)
virtual void UpdateElementVisibilityWithGivenTraceIDsBase(const QStringList &iList, const Qt::CheckState &iCheck)
Change elements visibility property given a list of TraceIDs and the new status.
TrackContainer(QObject *iParent, QGoImageView3D *iView)
Constructor.
TrackType::PointsMapConstIterator PointsMapConstIterator
unsigned int TraceID
bool InsertElement(const unsigned int &iTime, double *iPoint)
Insert a point at the current time point.
QByteArray toLocal8Bit() const
vtkActor * ActorYZ
vtkPolyData * Nodes
void UpdateTracksRepresentation(const double &iRadius, const double &iRadius2, const double &iWidth)
void SetListOfDivisions(std::list< unsigned int > &iListOfDivisions)
std::list< unsigned int > GetSubLineage(const unsigned int &iTrackID)
virtual void AddActor(const int &iId, vtkActor *iActor)
GoFigureLineageAttributes UpdateDivisionsForALineage(unsigned int iTrackIDRoot, double *color)
update the color and the divisions scalars of an all lineage which has iTrackIDRoot as track root ...
void RecomputeMap(TrackStructure *iStructure, std::list< double * > &iPoints)
Recompute a polydata from a list of point (coordinates) for the current element. If the current eleme...
void UpdateCollectionDelete(MultiIndexContainerTraceIDIterator &it)
void UpdateCollectionColorsData(const unsigned int &iTrackID, const double *color)
vtkActor * ActorXY
QGoImageView3D * m_ImageView
Link to the visualization.
void UpdateDivisionColor(MultiIndexContainerTraceIDIterator &iMotherIterator, const double *iColor)
void UpdateDivisionScalarData(MultiIndexContainerTraceIDIterator &it, const std::string &iColumnName, const double &iValue, double &iMin, double &iMax)
MultiIndexContainerElementType m_CurrentElement
Current Element of the trace type.
void UpdateTrackActors(TrackStructure &iStructure)
void UpdateDivisionScalar(MultiIndexContainerTraceIDIterator &iMotherIterator, const unsigned int &iDepth)
void RenderAllDivisionsWithOriginalColors()
void ShowCollection(const unsigned int &, const bool &)
std::vector< vtkActor * > CreateDivisionActor(vtkPolyData *iPolyData, const bool &iVisible=true)
void UpdateCollectionNumberOfLeaves(MultiIndexContainerTraceIDIterator &it, unsigned int &iNumberOfLeaves)
vtkActor * ActorXZ
void SetDivisionRandomColor(const std::string &iColumnName, const std::map< unsigned int, std::string > &iValues)
TrackStructure * UpdatePointsForATrack(const unsigned int &iTrackID, std::list< double * > &iListCenterBoundingBoxes)
get the element with iTrackID into the current element, remove it from the container, recalculate the points from the iListCenterBoundingBox and emit a signal for the current element to be saved into the database
void CreateDivisionPolydata(const unsigned int &iMother)
char * data()
void UpdateCollectionNumberOfDivisions(MultiIndexContainerTraceIDIterator &it, unsigned int &iNumberOfDivisions)
void AddDivision(const unsigned int &iMotherID, const unsigned int &iDaughter1ID, const unsigned int &iDaughter2ID, const bool &iVisible=true)
void AddVolume(const unsigned int &iTrackID, const double &iVolume)
GoFigureLineageAttributes UpdateCollectionScalars(const unsigned int &iTrackID)
double * setDivisionNodeScalars(const QString &iArrayName)
Changes the divisions scalars to be displayed and return the new range.
void SetLookupTableForColorCoding(vtkLookupTable *iLut)
Apply the given lookup table to all traces in the container.
double rgba[4]
std::list< unsigned int > DeleteAllHighlightedElements()
Delete all highlighted elements.
void UpdateCollectionHighlighting(const unsigned int &iTraceId)
void UpdateCollectionVisibility(MultiIndexContainerTraceIDIterator &it, const bool &iVisibility)
virtual void UpdateElementVisibilityWithGivenTraceIDs(const QStringList &iList, const Qt::CheckState &iCheck)
Change elements visibility property given a list of TraceIDs and the new status.
int compare(const QString &other) const
void RenderAllElementsWithOriginalColors()
Render with original colors.
void GetRootIterator(MultiIndexContainerTraceIDIterator &iMotherIterator)
virtual void UpdateElementHighlightingWithGivenTraceIDs(const QStringList &iList, const Qt::CheckState &iCheck)
Change elements highlighting property given a list of TraceIDs and the new status.
bool DeleteElement(const unsigned int &iId)
Remove the element which TraceId = iId.