[Insight-developers] ImageToImageFilter: dimension reductionproblem

Wilson Chang wmcst6+@pitt.edu
Mon, 29 Apr 2002 16:56:27 -0400


I think that we will run into the same problem even if we use pointers or
smart pointers to the RegionCopier because the pointers still have to have
the ImageRegionCopier type associated with them.  Therefore, the
ExtractImageFilterRegionCopier pointer will get cast to a ImageRegionCopier
pointer, and we have the same problem all over again.   we might have to go
with the less optimal solution you suggested.

wilson

----- Original Message -----
From: "Miller, James V (Research)" <millerjv@crd.ge.com>
To: "'Wilson Chang'" <wmcst6@pitt.edu>; "Insight-developers (E-mail)"
<Insight-developers@public.kitware.com>
Sent: Monday, April 29, 2002 10:10 AM
Subject: RE: [Insight-developers] ImageToImageFilter: dimension
reductionproblem


> Wilson,
>
> I am guessing the problem here is that the function object ivar
m_RegionCopier
> is held as an instance of an ImageRegionCopier as opposed to a "reference
> to" or a "pointer to" an ImageRegionCopier.  So the SetRegionCopier()
method
> is casting your subclass back to the baseclass and copying it into the
baseclass
> type.  It must be loosing the virtual function table.
>
> I tried to model the RegionCopier after STL.  Specifically, the
priority_queue
> class (snippet below) has an ivar of type std::less<> but allows the value
of
> this function object to be overridden at constructor time. Truthfully, I
am surprised that this works
> in STL.  I would have thought that passing in a subclass to
> std::less<> would still end up calling std::less<>::operator() and not the
> subclass's version.  Perhaps the only reason STL allows you to override
this
> function object at constructor time is to allow you to use a function
object
> which is a subclass of less that carries around additional information but
> still uses std::less<>::operator() for the call operator. If STL does
allow
> you to reroute the function object's call operator by passing in a
subclass
> of std::less at constructor time, then the difference between STL and the
RegionCopier
> is that STL calls the function object's copy constructor where we are
calling
> the RegionCopier's operator=().
>
> Unless someone has another idea, I would suggest making the RegionCopier
ivar
> a pointer (smart pointer?) to a RegionCopier.
>
> A less optimal solution be to change line 137 of ImageToImageFilter.txx
from
>
> m_RegionCopier(inputRegion, this->GetOutput()->GetRequestedRegion());
>
> to
>
> this->CallRegionCopier(inputRegion,
this->GetOutput()->GetRequestedRegion());
>
> where CallRegionCopier() is a virual method in ImageToImageFilter which
has the
> original line 137 of ImageToImageFilter.txx as its implementation.
ExtractImageFilter
> would override the CallRegionCopier() method and use an
ExtractImageFilterDetail
> instead of the standard region copier. This is the "less optimal" solution
because
> the ExtractImageFilter ends up with two ivars for the RegionCopier.  It
could
> get confusing as to which ivar is used when...
>
> (By the by, I think your class should be called
ExtractImageFilterRegionCopier
> and not ExtractImageFilterDetail (as shown in your code snippets)).
>
>
>
> // TEMPLATE CLASS priority_queue
> template<class _Ty, class _C = vector<_Ty>,
> class _Pr = less<_C::value_type> >
> class priority_queue {
> public:
> typedef _C::allocator_type allocator_type;
> typedef _C::value_type value_type;
> typedef _C::size_type size_type;
> explicit priority_queue(const _Pr& _X = _Pr(),
> const allocator_type& _Al = allocator_type())
> : c(_Al), comp(_X) {}
> typedef const value_type *_It;
> priority_queue(_It _F, _It _L, const _Pr& _X = _Pr(),
> const allocator_type& _Al = allocator_type())
> : c(_Al), comp(_X)
> {for (; _F != _L; ++_F)
> push(*_F); }
> allocator_type get_allocator() const
> {return (c.get_allocator()); }
> bool empty() const
> {return (c.empty()); }
> size_type size() const
> {return (c.size()); }
> value_type& top()
> {return (c.front()); }
> const value_type& top() const
> {return (c.front()); }
> void push(const value_type& _X)
> {c.push_back(_X);
> push_heap(c.begin(), c.end(), comp); }
> void pop()
> {pop_heap(c.begin(), c.end(), comp);
> c.pop_back(); }
> protected:
> _C c;
> _Pr comp;
> };
>
>
> -----Original Message-----
> From: Wilson Chang [mailto:wmcst6+@pitt.edu]
> Sent: Friday, April 26, 2002 4:18 PM
> To: Insight-developers (E-mail)
> Subject: Re: [Insight-developers] ImageToImageFilter: dimension
> reductionproblem
>
>
> Within the ImageToImageFilterDetail namespace, I have been trying to make
a
> class called ExtractImageRegionCopier that derives from ImageRegionCopier:
>
>   template <unsigned int D1, unsigned int D2>
>   class ITK_EXPORT ExtractImageFilterDetail: public ImageRegionCopier<D1,
> D2>
>   {
>
>   public:
>     void operator() (ImageRegion<D1> &destRegion,
>                      const ImageRegion<D2> &srcRegion) const
>     {
>       std::cout<<"ExtractImageFilterDetail call"<<std::endl;
>       ExtractImageCopyRegion<D1, D2>(BinaryUnsignedIntDispatch<D1,
> D2>::ComparisonType(),
>                          destRegion, srcRegion);
>     }
>   };
>
> In the ExtractImageFilter class:
>
>   typedef
>
ImageToImageFilterDetail::ExtractImageFilterDetail<InputImageDimension,
>                      OutputImageDimension> ExtractImageFilterDetailType;
>
> and in ExtractImageFilter's constructor:
>
> this->SetRegionCopier(m_ExtractImageRegionCopier);
>
> But for some reason, all of the to "CopyRegion()" are getting routed to
the
> parent class ImageRegionCopier and not the child class
> ExtractImageRegionCopier.
> Ideas?
> Does this have somethign to do with the fact that the "SetRegionCopier"
call
> expects a type of ImageRegionCopier, and not a child class?
>
> wilson
>
>
>
> _______________________________________________
> Insight-developers mailing list
> Insight-developers@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-developers
>