@@ -46,6 +46,7 @@ VolumeSampler::VolumeSampler() :
4646 m_neg_mask(false ),
4747 m_crop_origin(0.0 ),
4848 m_crop_size(0.0 ),
49+ m_use_clipbox(false ),
4950 m_filter(0 ),
5051 m_filter_size(0.0 ),
5152 m_border(0 )
@@ -101,9 +102,14 @@ void VolumeSampler::SetNegMask(bool bval)
101102 m_neg_mask = bval;
102103}
103104
104- void VolumeSampler::SetClipRotation ( const fluo::Quaternion &q )
105+ void VolumeSampler::SetUseClipbox ( bool bval )
105106{
106- m_q_cl = q;
107+ m_use_clipbox = bval;
108+ }
109+
110+ void VolumeSampler::SetRotation (const fluo::Quaternion &q)
111+ {
112+ m_q = q;
107113}
108114
109115void VolumeSampler::SetCenter (const fluo::Point &p)
@@ -162,7 +168,13 @@ void VolumeSampler::Resize(SampDataType type, bool replace)
162168 if (m_size_out.any_le_zero () || m_fix_size)
163169 m_size_out = m_size_in;
164170 // check rotation & translation
165- bool rot = !m_q_cl.IsIdentity ();
171+ auto & cb = input->GetClippingBox ();
172+ fluo::Quaternion q_rot;
173+ if (m_use_clipbox)
174+ q_rot = cb.GetRotation ();
175+ else
176+ q_rot = m_q;
177+ bool rot = !q_rot.IsIdentity ();
166178 bool trans = m_trans != fluo::Vector ();
167179 fluo::Vector size = m_size_out - fluo::Vector (0.5 );
168180 fluo::Vector size_in = m_size_in - fluo::Vector (0.5 );
@@ -175,15 +187,16 @@ void VolumeSampler::Resize(SampDataType type, bool replace)
175187 if (!m_fix_size && rot &&
176188 m_size_out.all_non_zero ())
177189 {
178- rotate_scale (size_in, spc_in, size, spc );
179- m_size_out = size + fluo::Vector ( 0.5 ) ;
190+ size = cb. GetPlaneSizeIndex ( );
191+ m_size_out = size;
180192 m_size_out.normalize_at_least_one ();
193+ size -= fluo::Vector (0.5 );
194+ spc = cb.GetPlaneSizeWorld () / cb.GetPlaneSizeIndex ();
181195 }
182196
183197 // recalculate range
184- auto & cb = input->GetClippingBox ();
185- m_crop_origin = cb.GetBBoxIndex ().Min ();
186- m_crop_size = cb.GetBBoxIndex ().diagonal ();
198+ m_crop_origin = cb.GetClipsUnit ().Min () * m_size_out;
199+ m_crop_size = cb.GetClipSizeIndex ();
187200 }
188201 else
189202 {
@@ -197,7 +210,6 @@ void VolumeSampler::Resize(SampDataType type, bool replace)
197210 ncenter = fluo::Vector (0.5 );
198211 else
199212 ncenter = fluo::Vector (m_center) / m_size_out;
200- fluo::Quaternion q_cl = m_q_cl;
201213 bool neg = m_neg_mask && (type == SDT_Mask || type == SDT_Label);
202214 if (neg)
203215 {
@@ -246,7 +258,7 @@ void VolumeSampler::Resize(SampDataType type, bool replace)
246258 vec -= ncenter;// center
247259 vec *= spcsize;// scale
248260 fluo::Quaternion qvec (vec);
249- qvec = (-q_cl ) * qvec * (q_cl );// rotate
261+ qvec = (-q_rot ) * qvec * (q_rot );// rotate
250262 vec = qvec.GetVector ();
251263 vec /= spcsize_in;// normalize
252264 vec += ncenter;// translate
@@ -493,100 +505,6 @@ std::pair<fluo::Point, fluo::Vector> VolumeSampler::xyz2ijkt(const fluo::Point&
493505 return { ijk, t };
494506}
495507
496- int VolumeSampler::rotate_scale (fluo::Vector &vsize_in, fluo::Vector &vspc_in,
497- fluo::Vector &vsize, fluo::Vector &vspc)
498- {
499- fluo::Vector rsf = vsize / vsize_in;// rescale factor
500- std::vector<fluo::Quaternion> qs;
501- std::vector<fluo::Vector> vs;
502- std::vector<fluo::Vector> vs2;
503- qs.push_back (fluo::Quaternion (1 , 0 , 0 , 0 ));
504- qs.push_back (fluo::Quaternion (0 , 1 , 0 , 0 ));
505- qs.push_back (fluo::Quaternion (0 , 0 , 1 , 0 ));
506- fluo::Vector vec_in = vsize_in * vspc_in;
507- for (auto &q : qs)
508- {
509- q = (-m_q_cl) * q * (m_q_cl);
510- vs.push_back (q.GetVector () * vec_in);
511- vs2.push_back (q.GetVector () * vspc_in);
512- }
513- fluo::Vector rv;
514- int i = 0 ;
515- for (auto &v : vs)
516- if (i < 3 ) rv[i++] = v.length ();
517- i = 0 ;
518- for (auto &v : vs2)
519- if (i < 3 ) vspc[i++] = v.length ();
520- if (vspc.x () == 0.0 ||
521- vspc.y () == 0.0 ||
522- vspc.z () == 0.0 )
523- return 0 ;// invalid
524- // rescale spcs to maintain sample size
525- consv_volume (vspc, vspc_in);
526- if (m_crop)
527- {
528- vspc /= rsf;
529- vsize = rv / vspc;
530- }
531- else
532- {
533- vsize = rv * rsf / vspc;
534- }
535- return 1 ;
536- }
537-
538- int VolumeSampler::consv_volume (fluo::Vector &vec, fluo::Vector &vec_in)
539- {
540- double vol = vec.volume ();
541- double vol_in = vec_in.volume ();
542- if (vol == 0.0 || vol_in == 0.0 )
543- return 0 ;
544- // conserve volume
545- if (std::abs (vol - vol_in) >
546- fluo::Epsilon (3 ) * vec_in[vec_in.max ()])
547- {
548- // diff array
549- double dif[9 ] = {
550- vec[0 ] - vec_in[0 ], vec[0 ] - vec_in[1 ], vec[0 ] - vec_in[2 ],
551- vec[1 ] - vec_in[0 ], vec[1 ] - vec_in[1 ], vec[1 ] - vec_in[2 ],
552- vec[2 ] - vec_in[0 ], vec[2 ] - vec_in[1 ], vec[2 ] - vec_in[2 ] };
553- int ind_min;
554- double val_min, val;
555- for (int i = 0 ; i < 9 ; ++i)
556- {
557- val = std::abs (dif[i]);
558- if (i == 0 )
559- {
560- val_min = val;
561- ind_min = i;
562- }
563- else
564- {
565- if (val < val_min)
566- {
567- val_min = val;
568- ind_min = i;
569- }
570- }
571- }
572- int ind = ind_min / 3 ;
573- int ind_in = ind_min % 3 ;
574- // align min dif
575- double f = std::sqrt (vol_in*vec[ind]/vol/vec_in[ind_in]);
576- vec[ind] = vec_in[ind_in];
577- // the remaining 2
578- for (int i = 0 ; i < 3 ; ++i)
579- {
580- if (i == ind)
581- continue ;
582- vec[i] *= f;
583- }
584-
585- return 1 ;
586- }
587- return 0 ;
588- }
589-
590508double VolumeSampler::SampleNearestNeighbor (const fluo::Point& coord)
591509{
592510 auto ijk = xyz2ijk (coord);
0 commit comments