3434#include < Core/Datatypes/Legacy/Field/VField.h>
3535#include < Core/Datatypes/Legacy/Field/VMesh.h>
3636
37- #include < algorithm>
38-
3937using namespace SCIRun ;
38+ using namespace SCIRun ::Core;
4039using namespace SCIRun ::Core::Geometry;
4140using namespace SCIRun ::Core::Algorithms;
4241using namespace SCIRun ::Core::Algorithms::Fields;
@@ -56,8 +55,8 @@ GenerateStreamLinesAlgo::GenerateStreamLinesAlgo()
5655 addParameter (Parameters::StreamlineStepSize, 0.01 );
5756 addParameter (Parameters::StreamlineTolerance, 0.0001 );
5857 addParameter (Parameters::StreamlineMaxSteps, 100 );
59- addParameter (Parameters::StreamlineDirection, 1 );
60- addParameter (Parameters::StreamlineValue, 1 );
58+ add_option (Parameters::StreamlineDirection, " Both " , " Negative|Both|Positive " );
59+ add_option (Parameters::StreamlineValue, " Seed index " , " Seed value|Seed index|Integration index|Integration step|Distance from seed|Streamline length " );
6160 addParameter (Parameters::RemoveColinearPoints, true );
6261 add_option (Parameters::StreamlineMethod, " CellWalk" , " AdamsBashforth|Heun|RungeKutta|RungeKuttaFehlberg|CellWalk" );
6362 // Estimate step size and tolerance automatically based on average edge length
@@ -93,19 +92,75 @@ void CleanupStreamLinePoints(const std::vector<Point> &input, std::vector<Point>
9392 }
9493}
9594
95+ bool directionIncludesNegative (int dir)
96+ {
97+ return dir <= 1 ;
98+ }
99+
100+ bool directionIncludesPositive (int dir)
101+ {
102+ return dir >= 1 ;
103+ }
104+
105+ bool directionIsBoth (int dir)
106+ {
107+ return 1 == dir;
108+ }
109+
110+ int convertDirectionOption (const std::string& dir)
111+ {
112+ if (dir == " Negative" )
113+ return 0 ;
114+ else if (dir == " Both" )
115+ return 1 ;
116+ else // Positive
117+ return 2 ;
118+ }
119+
120+ IntegrationMethod convertMethod (const std::string& option)
121+ {
122+ int method = 0 ;
123+ if (option == " AdamsBashforth" ) method = 0 ;
124+ else if (option == " Heun" ) method = 2 ;
125+ else if (option == " RungeKutta" ) method = 3 ;
126+ else if (option == " RungeKuttaFehlberg" ) method = 4 ;
127+ else if (option == " CellWalk" ) method = 5 ;
128+ else
129+ BOOST_THROW_EXCEPTION (AlgorithmInputException () << ErrorMessage (" Unknown streamline method selected" ));
130+ return IntegrationMethod (method);
131+ }
132+
133+ StreamlineValue convertValue (const std::string& option)
134+ {
135+ // "Seed value|Seed index|Integration index|Integration step|Distance from seed|Streamline length"
136+ if (option == " Seed value" )
137+ return SeedValue;
138+ if (option == " Seed index" )
139+ return SeedIndex;
140+ if (option == " Integration index" )
141+ return IntegrationIndex;
142+ if (option == " Integration step" )
143+ return IntegrationStep;
144+ if (option == " Distance from seed" )
145+ return DistanceFromSeed;
146+ if (option == " Streamline length" )
147+ return StreamlineLength;
148+
149+ BOOST_THROW_EXCEPTION (AlgorithmInputException () << ErrorMessage (" Unknown streamline value selected" ));
150+ }
96151
97152
98153class GenerateStreamLinesAlgoP {
99154
100155 public:
101156 GenerateStreamLinesAlgoP () :
102- tolerance_ (0 ), step_size_(0 ), max_steps_(0 ), direction_(0 ), value_(0 ), remove_colinear_pts_(false ),
103- method_ (0 ), seed_field_(0 ), seed_mesh_(0 ), field_(0 ), mesh_(0 ), ofield_(0 ), omesh_(0 ), algo_(0 ), success_(false )
104- {}
157+ tolerance_ (0 ), step_size_(0 ), max_steps_(0 ), direction_(0 ), value_(SeedIndex ), remove_colinear_pts_(false ),
158+ method_ (AdamsBashforth ), seed_field_(0 ), seed_mesh_(0 ), field_(0 ), mesh_(0 ), ofield_(0 ), omesh_(0 ), algo_(0 ), success_(false )
159+ {}
105160
106161 bool run (const AlgorithmBase* algo, FieldHandle input,
107162 FieldHandle seeds, FieldHandle& output,
108- int method);
163+ IntegrationMethod method);
109164
110165 private:
111166 void runImpl ();
@@ -114,9 +169,9 @@ class GenerateStreamLinesAlgoP {
114169 double step_size_;
115170 int max_steps_;
116171 int direction_;
117- int value_;
172+ StreamlineValue value_;
118173 bool remove_colinear_pts_;
119- int method_;
174+ IntegrationMethod method_;
120175
121176 VField* seed_field_;
122177 VMesh* seed_mesh_;
@@ -157,20 +212,21 @@ GenerateStreamLinesAlgoP::runImpl()
157212 seed_mesh_->get_point (BI.seed_ , idx);
158213
159214 // Is the seed point inside the field?
160- if (!field_->interpolate (test, BI.seed_ )) continue ;
215+ if (!field_->interpolate (test, BI.seed_ ))
216+ continue ;
161217
162218 BI.nodes_ .clear ();
163219 BI.nodes_ .push_back (BI.seed_ );
164220
165221 int cc = 0 ;
166222
167223 // Find the negative streamlines.
168- if ( direction_ <= 1 )
224+ if ( directionIncludesNegative ( direction_) )
169225 {
170226 BI.step_size_ = -step_size_; // initial step size
171227 BI.integrate ( method_ );
172228
173- if ( direction_ == 1 )
229+ if (directionIsBoth ( direction_) )
174230 {
175231 BI.seed_ = BI.nodes_ [0 ]; // Reset the seed
176232
@@ -181,7 +237,7 @@ GenerateStreamLinesAlgoP::runImpl()
181237 }
182238
183239 // Append the positive streamlines.
184- if ( direction_ >= 1 )
240+ if ( directionIncludesPositive ( direction_) )
185241 {
186242 BI.step_size_ = step_size_; // initial step size
187243 BI.integrate ( method_ );
@@ -190,7 +246,7 @@ GenerateStreamLinesAlgoP::runImpl()
190246 double length = 0 ;
191247 Point p1;
192248
193- if ( value_ == 5 )
249+ if ( value_ == StreamlineLength )
194250 {
195251 node_iter = BI.nodes_ .begin ();
196252 if (node_iter != BI.nodes_ .end ())
@@ -221,12 +277,12 @@ GenerateStreamLinesAlgoP::runImpl()
221277
222278 ofield_->resize_values ();
223279
224- if (value_ == 0 ) ofield_->copy_value (seed_field_,idx,n1);
225- else if (value_ == 1 ) ofield_->set_value (index_type (idx),n1);
226- else if (value_ == 2 ) ofield_->set_value (abs (cc),n1);
227- else if (value_ == 3 ) ofield_->set_value (0 ,n1);
228- else if (value_ == 4 ) ofield_->set_value (0 ,n1);
229- else if (value_ == 5 ) ofield_->set_value (length,n1);
280+ if (value_ == SeedValue ) ofield_->copy_value (seed_field_, idx, n1);
281+ else if (value_ == SeedIndex ) ofield_->set_value (index_type (idx), n1);
282+ else if (value_ == IntegrationIndex ) ofield_->set_value (abs (cc), n1);
283+ else if (value_ == IntegrationStep ) ofield_->set_value (0 , n1);
284+ else if (value_ == DistanceFromSeed ) ofield_->set_value (0 , n1);
285+ else if (value_ == StreamlineLength ) ofield_->set_value (length, n1);
230286
231287 ++node_iter;
232288 cc++;
@@ -236,20 +292,20 @@ GenerateStreamLinesAlgoP::runImpl()
236292 n2 = omesh_->add_point (*node_iter);
237293 ofield_->resize_fdata ();
238294
239- if (value_ == 0 ) ofield_->copy_value (seed_field_,idx,n2);
240- else if (value_ == 1 ) ofield_->set_value (index_type (idx),n2);
241- else if (value_ == 2 ) ofield_->set_value (abs (cc),n2);
242- else if (value_ == 3 )
295+ if (value_ == SeedValue ) ofield_->copy_value (seed_field_, idx, n2);
296+ else if (value_ == SeedIndex ) ofield_->set_value (index_type (idx), n2);
297+ else if (value_ == IntegrationIndex ) ofield_->set_value (abs (cc), n2);
298+ else if (value_ == IntegrationStep )
243299 {
244300 length = Vector ( *node_iter-p1 ).length ();
245301 ofield_->set_value (length,n2);
246302 }
247- else if (value_ == 4 )
303+ else if (value_ == DistanceFromSeed )
248304 {
249305 length += Vector ( *node_iter-p1 ).length ();
250306 ofield_->set_value (length,n2);
251307 }
252- else if (value_ == 5 )
308+ else if (value_ == StreamlineLength )
253309 {
254310 ofield_->set_value (length,n2);
255311 }
@@ -305,7 +361,7 @@ GenerateStreamLinesAlgoP::run(const AlgorithmBase* algo,
305361 FieldHandle input,
306362 FieldHandle seeds,
307363 FieldHandle& output,
308- int method)
364+ IntegrationMethod method)
309365{
310366 seed_field_ = seeds->vfield ();
311367 seed_mesh_ = seeds->vmesh ();
@@ -318,8 +374,8 @@ GenerateStreamLinesAlgoP::run(const AlgorithmBase* algo,
318374 tolerance_ = algo->get (Parameters::StreamlineTolerance).toDouble ();
319375 step_size_ = algo->get (Parameters::StreamlineStepSize).toDouble ();
320376 max_steps_ = algo->get (Parameters::StreamlineMaxSteps).toInt ();
321- direction_ = algo->get (Parameters::StreamlineDirection). toInt ( );
322- value_ = algo->get (Parameters::StreamlineValue). toInt ( );
377+ direction_ = convertDirectionOption ( algo->get_option (Parameters::StreamlineDirection));
378+ value_ = convertValue ( algo->get_option (Parameters::StreamlineValue));
323379 remove_colinear_pts_ = algo->get (Parameters::RemoveColinearPoints).toBool ();
324380 method_ = method;
325381
@@ -339,7 +395,7 @@ class GenerateStreamLinesAccAlgo {
339395
340396 public:
341397 GenerateStreamLinesAccAlgo () :
342- max_steps_ (0 ), direction_(0 ), value_(0 ), remove_colinear_pts_(false ),
398+ max_steps_ (0 ), direction_(0 ), value_(SeedIndex ), remove_colinear_pts_(false ),
343399 seed_field_ (0 ), seed_mesh_(0 ), field_(0 ), mesh_(0 ), ofield_(0 ),
344400 omesh_ (0 ), success_(false )
345401 {}
@@ -351,7 +407,7 @@ class GenerateStreamLinesAccAlgo {
351407 private:
352408 int max_steps_;
353409 int direction_;
354- int value_;
410+ StreamlineValue value_;
355411 bool remove_colinear_pts_;
356412
357413 VField* seed_field_;
@@ -383,8 +439,8 @@ GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo,
383439 omesh_ = output->vmesh ();
384440
385441 max_steps_ = algo->get (Parameters::StreamlineMaxSteps).toInt ();
386- direction_ = algo->get (Parameters::StreamlineDirection). toInt ( );
387- value_ = algo->get (Parameters::StreamlineValue). toInt ( );
442+ direction_ = convertDirectionOption ( algo->get_option (Parameters::StreamlineDirection));
443+ value_ = convertValue ( algo->get_option (Parameters::StreamlineValue));
388444 remove_colinear_pts_ = algo->get (Parameters::RemoveColinearPoints).toBool ();
389445
390446 Point seed;
@@ -405,18 +461,19 @@ GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo,
405461 seed_mesh_->get_center (seed, idx);
406462
407463 // Is the seed point inside the field?
408- if (!(mesh_->locate (elem, seed))) continue ;
464+ if (!(mesh_->locate (elem, seed)))
465+ continue ;
409466 nodes.clear ();
410467 nodes.push_back (seed);
411468
412469 int cc = 0 ;
413470
414471 // Find the negative streamlines.
415- if ( direction_ <= 1 )
472+ if ( directionIncludesNegative ( direction_) )
416473 {
417474 find_nodes (nodes, seed, true );
418475
419- if ( direction_ == 1 )
476+ if (directionIsBoth ( direction_) )
420477 {
421478 std::reverse (nodes.begin (), nodes.end ());
422479 cc = nodes.size ();
@@ -425,15 +482,15 @@ GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo,
425482 }
426483
427484 // Append the positive streamlines.
428- if ( direction_ >= 1 )
485+ if ( directionIncludesPositive ( direction_) )
429486 {
430487 find_nodes (nodes, seed, false );
431488 }
432489
433490 double length = 0 ;
434491 Point p1;
435492
436- if ( value_ == 5 )
493+ if ( value_ == StreamlineLength )
437494 {
438495 node_iter = nodes.begin ();
439496 if (node_iter != nodes.end ())
@@ -464,12 +521,12 @@ GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo,
464521
465522 ofield_->resize_values ();
466523
467- if (value_ == 0 ) ofield_->copy_value (field_,idx,n1);
468- else if ( value_ == 1 ) ofield_->set_value (( int ) index_type (idx),n1);
469- else if (value_ == 2 ) ofield_->set_value (abs (cc),n1);
470- else if (value_ == 3 ) ofield_->set_value (0 ,n1);
471- else if (value_ == 4 ) ofield_->set_value (0 ,n1);
472- else if (value_ == 5 ) ofield_->set_value (length,n1);
524+ if (value_ == SeedValue ) ofield_->copy_value (field_, idx, n1);
525+ else if ( value_ == SeedIndex ) ofield_->set_value (static_cast < int > (idx), n1);
526+ else if (value_ == IntegrationIndex ) ofield_->set_value (abs (cc), n1);
527+ else if (value_ == IntegrationStep ) ofield_->set_value (0 , n1);
528+ else if (value_ == DistanceFromSeed ) ofield_->set_value (0 , n1);
529+ else if (value_ == StreamlineLength ) ofield_->set_value (length, n1);
473530 ++node_iter;
474531
475532 cc++;
@@ -479,20 +536,20 @@ GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo,
479536 n2 = omesh_->add_point (*node_iter);
480537 ofield_->resize_values ();
481538
482- if (value_ == 0 ) ofield_->copy_value (field_,idx,n2);
483- else if ( value_ == 1 ) ofield_->set_value (( int ) index_type (idx),n2);
484- else if (value_ == 2 ) ofield_->set_value (abs (cc),n2);
485- else if (value_ == 3 )
539+ if (value_ == SeedValue ) ofield_->copy_value (field_, idx, n2);
540+ else if ( value_ == SeedIndex ) ofield_->set_value (static_cast < int > (idx), n2);
541+ else if (value_ == IntegrationIndex ) ofield_->set_value (abs (cc), n2);
542+ else if (value_ == IntegrationStep )
486543 {
487544 length = Vector ( *node_iter-p1 ).length ();
488545 ofield_->set_value (length,n2);
489546 }
490- else if (value_ == 4 )
547+ else if (value_ == DistanceFromSeed )
491548 {
492549 length += Vector ( *node_iter-p1 ).length ();
493550 ofield_->set_value (length,n2);
494551 }
495- else if (value_ == 5 )
552+ else if (value_ == StreamlineLength )
496553 {
497554 ofield_->set_value (length,n2);
498555 }
@@ -666,21 +723,12 @@ bool GenerateStreamLinesAlgo::runImpl(FieldHandle input, FieldHandle seeds, Fiel
666723 return (false );
667724 }
668725
669- const std::string smethod = get_option (Parameters::StreamlineMethod);
670- int method;
671- if (smethod == " AdamsBashforth" ) method = 0 ;
672- if (smethod == " Heun" ) method = 2 ;
673- if (smethod == " RungeKutta" ) method = 3 ;
674- if (smethod == " RungeKuttaFehlberg" ) method = 4 ;
675- if (smethod == " CellWalk" ) method = 5 ;
726+ auto method = detail::convertMethod (get_option (Parameters::StreamlineMethod));
676727
677- if (method == 5 )
728+ if (method == CellWalk && ifield-> basis_order () != 0 )
678729 {
679- if (ifield->basis_order () != 0 )
680- {
681- error (" The Cell Walk method only works for cell centered Vector Fields." );
682- return (false );
683- }
730+ error (" The Cell Walk method only works for cell centered Vector Fields." );
731+ return (false );
684732 }
685733
686734 FieldInformation fi (input);
0 commit comments