GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QGoTrackEditingWidget.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-10
4 
5  Copyright (c) 2009-10, 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 "QGoTrackEditingWidget.h"
36 
37 #include "ContourMeshStructure.h"
38 
39 #include "vtkSphereSource.h"
40 
41 #include "vtkPolyDataMapper.h"
42 #include "vtkLabeledDataMapper.h"
43 
44 #include "vtkPoints.h"
45 #include "vtkPolyLine.h"
46 #include "vtkCellArray.h"
47 #include "vtkPolyData.h"
48 #include "vtkPointData.h"
49 
50 #include "vtkActor2D.h"
51 #include "vtkProperty.h"
52 
53 // visu
54 #include "vtkRenderer.h"
55 #include "vtkRenderWindow.h"
56 #include "vtkRenderWindowInteractor.h"
57 #include "vtkRendererCollection.h"
58 
59 #include "vtkViewImage3DCommand.h"
60 #include "itkMacro.h"
61 
62 #include "vtkMath.h"
63 
64 #include <limits>
65 
66 //-------------------------------------------------------------------------
68  QDialog(iParent), m_MeshContainer(imeshContainer),
69  m_MaxTrackID(0), m_NumberOfTracks(0), m_SecondClick(false)
70 {
71  this->setupUi(this);
72 
73  renderer = vtkSmartPointer< vtkRenderer >::New();
74 
76 
77  m_VtkEventQtConnector = vtkSmartPointer< vtkEventQtSlotConnect >::New();
78  m_VtkEventQtConnector->Connect(
79  reinterpret_cast< vtkObject * >( m_InteractorStyle3D ),
81  this, SLOT( updateCurrentActorSelection(vtkObject *) ) );
82 
83  m_MinimalDistance = std::numeric_limits< double >::max();
84 
85  // ADD A STATUS BAR
86  m_StatusBar = new QStatusBar;
87  this->gridLayout_2->addWidget(m_StatusBar, 1, 0, 1, 1);
88  m_StatusBar->showMessage("No track selected");
89 
90  QObject::connect ( this->buttonBox, SIGNAL( accepted() ),
91  this, SLOT( restoreTrackIDs() ) );
92 
93  QObject::connect ( this->realMeshes, SIGNAL( toggled(bool) ),
94  this, SLOT( updateMeshesActors(bool) ) );
95 }
96 
97 //-------------------------------------------------------------------------
98 
99 //-------------------------------------------------------------------------
102 {
103  m_InteractorStyle3D->Delete();
104 
106  while ( it != m_Line2MeshID.end() )
107  {
108  renderer->RemoveActor(it->first);
109  it->first->Delete();
110  ++it;
111  }
112 }
113 
114 //-------------------------------------------------------------------------
115 
116 //-------------------------------------------------------------------------
117 vtkActor *
118 QGoTrackEditingWidget::createPolylineActor(double *iCenter1, double *iCenter2,
119  const double *iColor1, const double *iColor2)
120 {
121  // Might be useful at some point
122  (void)iColor1;
123  (void)iColor2;
124  //create a vtkPoints object and storevtkRenderWindow the points in it
125  vtkSmartPointer< vtkPoints > points = vtkSmartPointer< vtkPoints >::New();
126  points->InsertNextPoint(iCenter1);
127  points->InsertNextPoint(iCenter2);
128 
129  vtkSmartPointer< vtkPolyLine > polyLine = vtkSmartPointer< vtkPolyLine >::New();
130  polyLine->GetPointIds()->SetNumberOfIds(2);
131  polyLine->GetPointIds()->SetId(0, 0);
132  polyLine->GetPointIds()->SetId(1, 1);
133 
134  //Create a cell array to store the lines in and add the lines to it
135  vtkSmartPointer< vtkCellArray > cells = vtkSmartPointer< vtkCellArray >::New();
136  cells->InsertNextCell(polyLine);
137 
138  //Create a polydata to store everything in
139  vtkSmartPointer< vtkPolyData > polyData = vtkSmartPointer< vtkPolyData >::New();
140 
141  //add the points to the dataset
142  polyData->SetPoints(points);
143 
144  //add the lines to the dataset
145  polyData->SetLines(cells);
146 
147  //setup actor and mapper
148  vtkSmartPointer< vtkPolyDataMapper > mapper =
149  vtkSmartPointer< vtkPolyDataMapper >::New();
150  mapper->SetInput(polyData);
151 
152  vtkActor *actor = vtkActor::New();
153  actor->SetMapper(mapper);
154 
155  return actor;
156 }
157 
158 //-------------------------------------------------------------------------
159 
160 //-------------------------------------------------------------------------
161 void
163 {
165  static_cast< vtkInteractorStyleImage3D * >( caller );
166 
167  m_CurrentActor = vtkActor::
168  SafeDownCast( t->GetCurrentProp() );
169 
170  // if we click on the background
171  if ( !m_CurrentActor )
172  {
173  return;
174  }
175 
176  LineActor2MeshIDIterator polyToMeshID =
178 
179  if ( polyToMeshID != m_Line2MeshID.end() )
180  {
181  if ( m_CurrentActor->GetProperty()->GetOpacity() == 1 )
182  {
183  //Update track IDs - CUT
185  }
186  }
187  /*else
188  {
189  MeshContainer::MultiIndexContainerTraceIDIterator iter;
190  vtkIntArray* testArray =
191  static_cast<vtkIntArray*>(m_CurrentActor->GetMapper()->GetInput()
192  ->GetPointData()->GetArray("MESH"));
193  iter = m_MeshContainer->m_Container.get< TraceID >().find( testArray->GetValue(0) );
194  assert(iter != m_MeshContainer->m_Container.get< TraceID >().end() );
195  merge(iter);
196  }*/
197 }
198 
199 //-------------------------------------------------------------------------
200 
201 //-------------------------------------------------------------------------
202 void
204 {
205  if ( m_SecondClick )
206  {
207  mergeTrack(m_FirstMeshID, iBegin->TraceID);
208  }
209  else
210  {
211  m_FirstMeshID = iBegin->TraceID;
213  m_StatusBar->showMessage("Select another mesh to merge tracks");
214  }
216 }
217 
218 //-------------------------------------------------------------------------
219 
220 //-------------------------------------------------------------------------
221 void
223 {
225 
226  c_it = m_MeshContainer->m_Container.get< CollectionID >().begin();
227  unsigned int collection = std::numeric_limits< unsigned int >::max();
228 
229  c_end = m_MeshContainer->m_Container.get< CollectionID >().end();
230  unsigned int current_track = 0;
231 
232  while ( c_it != c_end )
233  {
234  unsigned int temp_collection = c_it->CollectionID;
235  unsigned int traceID = c_it->TraceID;
236  ++c_it;
237 
238  if ( temp_collection != collection )
239  {
240  collection = temp_collection;
241  current_track = m_NumberOfTracks;
242 
243  TrackInformation track(collection, UPDATED_TRACK);
244  m_TrackMapping[current_track] = track;
245 
247  }
248 
249  if ( temp_collection > m_MaxTrackID )
250  {
251  m_MaxTrackID = temp_collection;
252  }
253 
254  modifyMeshCollectionID(traceID, current_track);
255  }
256 }
257 
258 //-------------------------------------------------------------------------
259 
260 //-------------------------------------------------------------------------
261 void
263 {
265 
267 
269 
270  this->updateMeshesActors( false );
271 
273 
275 }
276 
277 //-------------------------------------------------------------------------
278 
279 //-------------------------------------------------------------------------
280 void
282 {
283  // Create the actors
284  for ( unsigned int i = 0; i < m_NumberOfTracks; ++i )
285  {
287 
288  boost::tuples::tie(it0, it1) =
289  m_MeshContainer->m_Container.get< CollectionID >().equal_range(i);
290 
291  while ( it0 != it1 )
292  {
293  ContourMeshStructure tempStructure(*it0);
294 
295  // Get the polydata
296  vtkPolyData *nodes = tempStructure.Nodes;
297  double * rgba = tempStructure.rgba;
298 
299  // add trace info in the polydata
300  vtkSmartPointer<vtkIntArray> trackIDArray = vtkSmartPointer<vtkIntArray>::New();
301  trackIDArray->SetNumberOfComponents(1);
302  trackIDArray->SetNumberOfValues(1);
303  trackIDArray->SetName("MESH");
304  trackIDArray->SetValue(0,tempStructure.TraceID);
305 
306  nodes->GetPointData()->AddArray(trackIDArray);
307 
308  //setup actor and mapper
309  vtkSmartPointer< vtkPolyDataMapper > mapper =
310  vtkSmartPointer< vtkPolyDataMapper >::New();
311  mapper->SetInput(nodes);
312 
313  vtkActor *actor = vtkActor::New();
314  actor->SetMapper(mapper);
315  actor->GetProperty()->SetColor(rgba);
316  tempStructure.ActorXY = actor; // real mesh
317  // generate sphere based on the minimal distance between 2 points in a
318  // track
319  // actors are invisible
320  vtkActor *sphereActor = computeSphere(tempStructure.TraceID,
321  actor->GetCenter(), m_MinimalDistance / 3);
322  tempStructure.ActorXZ = sphereActor;
323 
324  // Add actor to visu
325  renderer->AddActor(actor);
326  renderer->AddActor(sphereActor);
327 
328  m_MeshContainer->m_Container.get< CollectionID >().replace(it0, tempStructure);
329 
330  ++it0;
331  }
332  }
333 }
334 
335 //-------------------------------------------------------------------------
336 
337 //-------------------------------------------------------------------------
338 void
340 {
341  vtkSmartPointer< vtkDoubleArray > randomScalars =
342  vtkSmartPointer< vtkDoubleArray >::New();
343  randomScalars->SetNumberOfComponents(1);
344  randomScalars->SetName("TimePoint");
345 
346  vtkSmartPointer< vtkPoints > pts = vtkSmartPointer< vtkPoints >::New();
347 
348  // Create the actors
349  for ( unsigned int i = 0; i < m_NumberOfTracks; ++i )
350  {
352 
353  boost::tuples::tie(it0, it1) =
354  m_MeshContainer->m_Container.get< CollectionID >().equal_range(i);
355 
356  while ( it0 != it1 )
357  {
358  // Get the polydata
359  vtkPolyData *nodes = it0->Nodes;
360  unsigned int time = it0->TCoord;
361 
362  randomScalars->InsertNextTuple1(time);
363  pts->InsertNextPoint( nodes->GetCenter() );
364 
365  ++it0;
366  }
367  }
368 
369  vtkSmartPointer< vtkPolyData > labelData = vtkSmartPointer< vtkPolyData >::New();
370  labelData->GetPointData()->SetScalars(randomScalars);
371  labelData->SetPoints(pts);
372 
373  // The labeled data mapper will place labels at the points
374  vtkSmartPointer< vtkLabeledDataMapper > labelMapper =
375  vtkSmartPointer< vtkLabeledDataMapper >::New();
376  labelMapper->SetFieldDataName("TimePoint");
377  labelMapper->SetInput(labelData);
378  labelMapper->SetLabelModeToLabelScalars();
379  labelMapper->SetLabelFormat("%6.0f");
380 
381  vtkSmartPointer< vtkActor2D > isolabels =
382  vtkSmartPointer< vtkActor2D >::New();
383  isolabels->SetMapper(labelMapper);
384 
385  renderer->AddActor(isolabels);
386 }
387 
388 //-------------------------------------------------------------------------
389 
390 //-------------------------------------------------------------------------
391 void
393 {
394  LineActor2MeshIDIterator it = m_Line2MeshID.find(iActor);
395 
396  // Find the mesh ID
397  if ( it != m_Line2MeshID.end() )
398  {
400  it0 = m_MeshContainer->m_Container.get< TraceID >().find(it->second);
401 
402  unsigned int collectionID = it0->CollectionID;
403  unsigned int tLimit = it0->TCoord;
404 
406  boost::tuples::tie(it2, it3) =
407  m_MeshContainer->m_Container.get< CollectionID >().equal_range(collectionID);
408 
409  while ( it2 != it3 )
410  {
411  unsigned int time = it2->TCoord;
412  unsigned int traceID = it2->TraceID;
413  ++it2;
414  // change track ID if we are before the mesh
415  if ( time < tLimit )
416  {
418 
419  TrackInformation track(0, NEW_TRACK);
421  }
422  }
424 
426  {
428  }
429  // update visu
432  }
433  m_StatusBar->showMessage("Track splitted");
434 }
435 
436 //-------------------------------------------------------------------------
437 
438 //-------------------------------------------------------------------------
439 void
441 {
443 
444  while ( it != m_Line2MeshID.end() )
445  {
446  renderer->RemoveActor(it->first);
447  it->first->Delete();
448  ++it;
449  }
450  m_Line2MeshID.clear();
451 }
452 
453 //-------------------------------------------------------------------------
454 
455 //-------------------------------------------------------------------------
456 void
458 {
459  std::map< unsigned int, unsigned int > m_Time2MeshID;
460  // For each track, create the actors
461  for ( unsigned int i = 0; i < m_NumberOfTracks; ++i )
462  {
463  m_Time2MeshID.clear();
464 
466  boost::tuples::tie(it0, it1) =
467  m_MeshContainer->m_Container.get< CollectionID >().equal_range(i);
468 
469  while ( it0 != it1 )
470  {
471  m_Time2MeshID[it0->TCoord] = ( it0->TraceID );
472  ++it0;
473  }
474 
475  // Go through map to create polylines
476  std::map< unsigned int, unsigned int >::iterator polyLIt = m_Time2MeshID.begin();
477  if ( polyLIt != m_Time2MeshID.end() )
478  {
479  vtkActor *firstActor = ( m_MeshContainer->GetActorGivenTraceID(polyLIt->second) )[0];
480  vtkActor *secondActor = NULL;
481  ++polyLIt;
482 
483  while ( polyLIt != m_Time2MeshID.end() )
484  {
485  secondActor = ( m_MeshContainer->GetActorGivenTraceID(polyLIt->second) )[0];
486  vtkActor *polyLine = createPolylineActor( firstActor->GetCenter(),
487  secondActor->GetCenter() );
488 
490  double color[3] = { 1, 1, 1 };
491  polyLine->GetProperty()->SetColor(color);
492  // Add actor to visu
493  renderer->AddActor(polyLine);
494 
495  // key is actor
496  m_Line2MeshID[polyLine] = polyLIt->second;
497 
498  firstActor = secondActor;
499  ++polyLIt;
500  }
501  }
502  else
503  {
504  std::cout << "List is empty" << std::endl;
505  }
506  }
507 }
508 
509 //-------------------------------------------------------------------------
510 
511 //-------------------------------------------------------------------------
512 void
514 {
515  TrackMapping::iterator it = m_TrackMapping.begin();
516 
517  unsigned int collection = 0;
518 
519  m_ListOfNewTrack.clear();
520  m_ListOfUpdatedTracks.clear();
521  m_ListOfDeletedTracks.clear();
522 
523  while ( it != m_TrackMapping.end() )
524  {
525  collection = it->first;
526 
527  switch ( it->second.Status )
528  {
529  case NEW_TRACK:
530  {
531  std::list< unsigned int > list_meshid = getMeshIDsInTrack(collection);
532  m_ListOfNewTrack.push_back(list_meshid);
533  break;
534  }
535 
536  case UPDATED_TRACK:
537  {
538  std::list< unsigned int > list_meshid = getMeshIDsInTrack(collection);
539  m_ListOfUpdatedTracks[it->second.RealID] = list_meshid;
540  break;
541  }
542 
543  case DELETED_TRACK:
544  {
545  // if real ID > 0
546  if ( it->second.RealID )
547  {
548  m_ListOfDeletedTracks.push_back(it->second.RealID);
549  }
550  break;
551  }
552  }
553  ++it;
554  }
555 }
556 
557 //-------------------------------------------------------------------------
558 
559 //-------------------------------------------------------------------------
560 std::list< unsigned int >
562 {
563  std::list< unsigned int > list_meshid;
564 
566 
567  boost::tuples::tie(it0, it1) =
568  m_MeshContainer->m_Container.get< CollectionID >().equal_range(iCollection);
569 
570  while ( it0 != it1 )
571  {
572  list_meshid.push_back(it0->TraceID);
573  ++it0;
574  }
575  return list_meshid;
576 }
577 
578 //-------------------------------------------------------------------------
579 
580 //-------------------------------------------------------------------------
581 std::list< std::list< unsigned int > >
583 {
584  return this->m_ListOfNewTrack;
585 }
586 
587 //-------------------------------------------------------------------------
588 
589 //-------------------------------------------------------------------------
590 std::map< unsigned int, std::list< unsigned int > >
592 {
593  return this->m_ListOfUpdatedTracks;
594 }
595 
596 //-------------------------------------------------------------------------
597 
598 //-------------------------------------------------------------------------
599 std::list< unsigned int >
601 {
602  return this->m_ListOfDeletedTracks;
603 }
604 
605 //-------------------------------------------------------------------------
606 
607 //-------------------------------------------------------------------------
608 bool
609 QGoTrackEditingWidget::mergeTrack(const unsigned int & iFirstMesh, const unsigned int & iSecondMesh)
610 {
611  unsigned int FirstCollectionID = 0;
612  unsigned int SecondCollectionID = 0;
613 
614  try
615  {
616  FirstCollectionID = m_MeshContainer->GetCollectionIDOfGivenTraceID(iFirstMesh);
617  }
618  catch ( const itk::ExceptionObject & e )
619  {
620  std::cout << "caught an exception: " << std::endl;
621  e.Print(std::cout);
622  return false;
623  }
624 
625  try
626  {
627  SecondCollectionID = m_MeshContainer->GetCollectionIDOfGivenTraceID(iSecondMesh);
628  }
629  catch ( const itk::ExceptionObject & e )
630  {
631  std::cout << "caught an exception: " << std::endl;
632  e.Print(std::cout);
633  return false;
634  }
635 
636  if ( FirstCollectionID != SecondCollectionID )
637  {
638  //Check if actors are border of track
639  std::pair< std::pair< unsigned int, unsigned int >,
640  std::pair< unsigned int, unsigned int > >
641  border1 = getTrackBorders(FirstCollectionID);
642 
643  std::pair< std::pair< unsigned int, unsigned int >,
644  std::pair< unsigned int, unsigned int > >
645  border2 = getTrackBorders(SecondCollectionID);
646 
647  // Check for overlap
648  if ( ( border2.first.second <= border1.second.second )
649  && ( border1.first.second <= border2.second.second ) )
650  {
651  m_StatusBar->showMessage("Can't merge tracks: overlap");
652  return false;
653  }
654 
655  //Get Highest time to know which meshes we should update
656  unsigned int trackToUpdate = 0;
657  unsigned int trackToDelete = 0;
658  if ( border1.first.first < border2.first.first )
659  {
660  trackToDelete = FirstCollectionID;
661  trackToUpdate = SecondCollectionID;
662  }
663  else
664  {
665  trackToUpdate = FirstCollectionID;
666  trackToDelete = SecondCollectionID;
667  }
668 
669  m_TrackMapping[trackToDelete].Status = DELETED_TRACK;
670 
671  // Change the ID of the track by the other one
672  updateTracksIDs(trackToDelete, trackToUpdate);
673 
674  // update visu
677 
678  m_StatusBar->showMessage("Tracks merged");
679 
680  return true;
681  }
682 
683  m_StatusBar->showMessage("Meshes belong to same track");
684  return false;
685 }
686 
687 //-------------------------------------------------------------------------
688 
689 //-------------------------------------------------------------------------
690 std::pair< std::pair< unsigned int, unsigned int >,
691  std::pair< unsigned int, unsigned int > >
692 QGoTrackEditingWidget::getTrackBorders(const unsigned int & iCollectionID)
693 {
695 
696  boost::tuples::tie(it0, it1) =
697  m_MeshContainer->m_Container.get< CollectionID >().equal_range(iCollectionID);
698 
699  std::pair< unsigned int, unsigned int >
700  minBorder( 0, std::numeric_limits< unsigned int >::max() );
701 
702  std::pair< unsigned int, unsigned int >
703  maxBorder(0, 0);
704 
705  unsigned int time = 0;
706 
707  while ( it0 != it1 )
708  {
709  time = it0->TCoord;
710 
711  if ( minBorder.second > time )
712  {
713  minBorder.first = it0->TraceID;
714  minBorder.second = time;
715  }
716 
717  if ( maxBorder.second < time )
718  {
719  maxBorder.first = it0->TraceID;
720  maxBorder.second = time;
721  }
722  ++it0;
723  }
724 
725  return std::make_pair(minBorder, maxBorder);
726 }
727 
728 //-------------------------------------------------------------------------
729 
730 //-------------------------------------------------------------------------
731 void
732 QGoTrackEditingWidget::updateTracksIDs(const unsigned int & iIDToDelete,
733  const unsigned int & iIDToUpdate)
734 {
736 
737  boost::tuples::tie(it0, it1) =
738  m_MeshContainer->m_Container.get< CollectionID >().equal_range(iIDToDelete);
739 
740  while ( it0 != it1 )
741  {
742  unsigned int traceID = it0->TraceID;
743  ++it0;
744  modifyMeshCollectionID(traceID, iIDToUpdate);
745  }
746 }
747 
748 //-------------------------------------------------------------------------
749 
750 //-------------------------------------------------------------------------
751 void
753 {
755 
756  //setup render window, renderer, and interactor
757  this->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
758 
759  this->qvtkWidget->GetInteractor()->SetInteractorStyle(m_InteractorStyle3D);
761 
762  this->qvtkWidget->GetRenderWindow()->Render();
763 }
764 
765 //-------------------------------------------------------------------------
766 
767 //-------------------------------------------------------------------------
768 void
769 QGoTrackEditingWidget::modifyMeshCollectionID(unsigned int iMeshID, unsigned int iCollectionID)
770 {
772  it = m_MeshContainer->m_Container.get< TraceID >().find(iMeshID);
773  ContourMeshStructure tempStructure(*it);
774 
775  tempStructure.CollectionID = iCollectionID;
776  m_MeshContainer->m_Container.get< TraceID >().replace(it, tempStructure);
777 }
778 
779 //-------------------------------------------------------------------------
780 
781 //-------------------------------------------------------------------------
782 void
784 {
785  m_FirstMeshActor->GetProperty()->SetSpecular(iHighlight);
786  m_FirstMeshActor->GetProperty()->SetAmbient(iHighlight);
787  m_SecondClick = iHighlight;
788 }
789 
790 //-------------------------------------------------------------------------
791 
792 //-------------------------------------------------------------------------
793 void
795 {
796  // Go through container and update visibility
798 
799  iter = m_MeshContainer->m_Container.get< TraceID >().begin();
800  c_end = m_MeshContainer->m_Container.get< TraceID >().end();
801 
802  while ( iter != c_end )
803  {
804  iter->ActorXY->SetVisibility(iRealMeshes);
805  iter->ActorXZ->SetVisibility(!iRealMeshes);
806  ++iter;
807  }
808 
809  // update visu
810  this->qvtkWidget->update();
811 }
812 
813 //-------------------------------------------------------------------------
814 
815 //-------------------------------------------------------------------------
816 vtkActor *
817 QGoTrackEditingWidget::computeSphere(unsigned int iTraceID, double *iCenter, double iRadius)
818 {
819  // Sphere
820  vtkSmartPointer< vtkSphereSource > sphereSource =
821  vtkSmartPointer< vtkSphereSource >::New();
822  sphereSource->SetCenter(iCenter);
823  sphereSource->SetRadius(iRadius);
824  sphereSource->Update();
825 
826  // add trace ID into the polydata
827  vtkSmartPointer<vtkIntArray> trackIDArray = vtkSmartPointer<vtkIntArray>::New();
828  trackIDArray->SetNumberOfComponents(1);
829  trackIDArray->SetNumberOfValues(1);
830  trackIDArray->SetName("MESH");
831  trackIDArray->SetValue(0,iTraceID);
832 
833  sphereSource->GetOutput()->GetPointData()->AddArray(trackIDArray);
834 
835  vtkSmartPointer< vtkPolyDataMapper > sphereMapper =
836  vtkSmartPointer< vtkPolyDataMapper >::New();
837  sphereMapper->SetInput( sphereSource->GetOutput() );
838 
839  vtkActor *sphereActor = vtkActor::New();
840  sphereActor->SetMapper(sphereMapper);
841  sphereActor->SetVisibility(false);
842 
843  return sphereActor;
844 }
845 
846 //-------------------------------------------------------------------------
847 
848 //-------------------------------------------------------------------------
849 void
851 {
853 
854  it = m_MeshContainer->m_Container.get< TraceID >().begin();
855  end = m_MeshContainer->m_Container.get< TraceID >().end();
856 
857  it2 = it;
858 
859  while ( it != end )
860  {
861  it2 = it;
862  it2++;
863  while ( it2 != end )
864  {
865  double distance =
866  sqrt( vtkMath::Distance2BetweenPoints( it->Nodes->GetCenter(),
867  it2->Nodes->GetCenter() ) );
868  if ( it->TraceID != it2->TraceID )
869  {
870  m_MinimalDistance = std::min(m_MinimalDistance, distance);
871  }
872  ++it2;
873  }
874  it2 = m_MeshContainer->m_Container.get< TraceID >().begin();
875  ++it;
876  }
877 }
std::list< std::list< unsigned int > > GetListOfTracksToBeCreated()
Returns the list of tracks to be created.
void setupUi(QWidget *widget)
void removeLineActors()
Remove the polyLines actors. Usefull after a merge or a cut. An "Update" method would be more efficie...
void init()
Initialize the renderer, the rendering window, the interactor style and add the meshes, polylines and labels to the visualization.
void highlightFirstActor(bool iHighlight)
Change the apperance of the mesh depending on if we want to highlight it or not. First click on one a...
void showMessage(const QString &message, int timeout)
void computeLineActors()
Create the polyLines actors according to the current MeshContainer.
void EnablePickMode()
Start the Pick Mode.
MultiIndexContainerType::template index< TraceID >::type::iterator MultiIndexContainerTraceIDIterator
void restoreTrackIDs()
Restore the track IDs to theirs original values (ie before entering the widget). Creates a TracksToBe...
void accepted()
MultiIndexContainerType m_Container
Trace Contaienr.
std::list< std::list< unsigned int > > m_ListOfNewTrack
vtkActor * createPolylineActor(double *iCenter1, double *iCenter2, const double *iColor1=NULL, const double *iColor2=NULL)
Create a line between 2 points.
unsigned int GetCollectionIDOfGivenTraceID(unsigned int iTraceID)
Get the CollectionID given a TraceID.
void reassignTrackIDs()
Reassing real track IDs to temporary ones for convenience.
void computeLabelActor()
Create label actors to see the temporal information of each mesh. It is very useful for the merge...
static vtkInteractorStyleImage3D * New()
Convenient method to access the constructor.
void addWidget(QWidget *widget, int stretch)
vtkSmartPointer< vtkRenderer > renderer
std::vector< vtkActor * > GetActorGivenTraceID(unsigned int iTraceID)
std::map< unsigned int, std::list< unsigned int > > GetListOfTracksToBeUpdated()
Returns the list of tracks to be updated.
vtkActor * computeSphere(unsigned int iTraceID, double *iCenter, double radius)
std::list< unsigned int > GetListOfTracksToBeDeleted()
Returns the list of tracks to be deleted.
void updateTracksIDs(const unsigned int &iIDToDelete, const unsigned int &iIDToUpdate)
Update track IDs after a merge -The mesh has to be a border of its own track.
QGoTrackEditingWidget(MeshContainer *imeshContainer=NULL, QWidget *parent=0)
void merge(MeshContainer::MultiIndexContainerTraceIDIterator iBegin)
std::list< unsigned int > getMeshIDsInTrack(unsigned int iCollection)
Get the list of the mesh IDs which belong to the given track.
vtkInteractorStyleImage3D * m_InteractorStyle3D
void modifyMeshCollectionID(unsigned int iMeshID, unsigned int iCollectionID)
Modify the mesh collection to the chosen track ID.
std::list< unsigned int > m_ListOfDeletedTracks
unsigned int TraceID
vtkPolyData * Nodes
void cutTrack(vtkActor *iActor)
Cut a track at the current actor. The actor represents a polyline between 2 meshes.
void updateCurrentActorSelection(vtkObject *caller)
Defines behavior when we pick an actor in the visualization.
std::map< vtkActor *, unsigned int > m_Line2MeshID
vtkActor * ActorXY
void computeMeshActors()
Get and display the meshes actors.
Wraps a boost::multi_index_container of ContourMeshStructure. This class is specialized for the means...
Definition: MeshContainer.h:46
unsigned int CollectionID
Structure which represent a contour or a mesh, and used for interaction between Visualization and Tab...
QWidget * find(WId id)
MultiIndexContainerType::template index< CollectionID >::type::iterator MultiIndexContainerCollectionIDIterator
vtkActor * ActorXZ
void initializeVisualization()
Reassigns track IDs and add the meshes, polylines and labels actors to the visualization.
std::pair< std::pair< unsigned int, unsigned int >, std::pair< unsigned int, unsigned int > > getTrackBorders(const unsigned int &iCollectionID)
Get the borders of the given track.
vtkProp * GetCurrentProp()
Return the actor which is pointed by the cursor.
Define the interactor behavior withing a vtkImage3D. 4 modes (Default, Zoom, Pan and Pick) ...
vtkSmartPointer< vtkEventQtSlotConnect > m_VtkEventQtConnector
std::map< unsigned int, std::list< unsigned int > > m_ListOfUpdatedTracks
bool mergeTrack(const unsigned int &iFirstMesh, const unsigned int &iSecondMesh)
Merge 2 tracks, given 2 mesh IDs. Requierements for a successful merge: -Each mesh must belong to dif...
double rgba[4]
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
std::map< vtkActor *, unsigned int >::iterator LineActor2MeshIDIterator