Class design with tightly bound iterator

J

Jim Langston

I am working on a class design to contain the indices of triangle lists for
body parts. This is for 3d modeling. As as start I have:

class PartTriangles
{
public:
PartTriangels( const std::string& Name ): Name( Name ) {}
private:
std::string Name;
std::set<size_t> Triangles;
std::vector<PartTriangles> Connections;
};

which may (probably will) change and a lot of things added. Anyway... the
reason I am designing this class is I need to keep a list of the indices for
a model for each body part so I can animate them, meaning I need to get some
type of list of what triangles are in, for instance, the right leg. My
thought was that this ... three type list... would start with the torso
"torso". Whoulc would have in it's vector 5 connections, head, right
bicept, left bicept, right upper leg, left upper leg. So in this way every
triangle would be list listed somewhere to contain the entire body, but only
once. Now, the situation is, I need to be able to get a list of things that
are in, say, the right leg, which would contain the upper leg, lower leg and
foot. So interators came to mind. So this is what I am planning on
developing:

someinteratortype it = MyBody("right upper leg");
It should be fairly easy for PartTriangles to return an iterator pointing to
it's std::set for the beginning of the upper leg. However, it would not
actually be in the instance of MyBody, which would have the set for Torso,
but in MyBody's vector of PartTriangles where the name is "right upper leg".
Also is the complication of .end() There are 5 end()'s, one for head, one
for right hand pinky (if I go as far as fingers), left hand pinkie, right
foot, etc..

In addition, looking at an implementation of a custom iterator, it's
increment is simply:
custom_iterator& operator++()
{
// preincrement
++m_Ptr;
return (*this);
}
custom_iterator operator++(int)
{
// postincrement
custom_iterator _Tmp = *this;
++*this;
return (_Tmp);
}

m_Ptr is
_Ty *m_Ptr;
in a template.

It seems to me that my iterator would have to store more information than a
single pointer especially for increment. Consider the case where I am
iteratiing over the right upper leg and get to the end of PartTriangle's
set, I would then want an increment to step into Connection's into it's
entries sets, etc... Of course, after it went through the first set, it may
have to back out to do the next part of the vector, looking like I have some
type of recursion taking place.

Anyone have familiarity with these types of iterators, or am I trying to
make an iterator do something it's not designed for?

I'm open to any and all suggestions.
 
B

Barry

Jim said:
someinteratortype it = MyBody("right upper leg");
It should be fairly easy for PartTriangles to return an iterator pointing to
it's std::set for the beginning of the upper leg. However, it would not
actually be in the instance of MyBody, which would have the set for Torso,
but in MyBody's vector of PartTriangles where the name is "right upper leg".
Also is the complication of .end() There are 5 end()'s, one for head, one
for right hand pinky (if I go as far as fingers), left hand pinkie, right
foot, etc..
Well, to iterate YourBody is so hard.

I happened to see an STL-like tree implementation,
it has
in_begin(), in_end()
post_being(), post_end()
....
in pair by the traverse method.

So why not doing so here.

As my conceptual idea, I would say why not buy strategy pattern.

begin(Strategy1()), end(Strategy1())
 
J

Jim Langston

Barry said:
Well, to iterate YourBody is so hard.

I happened to see an STL-like tree implementation,
it has
in_begin(), in_end()
post_being(), post_end()
...
in pair by the traverse method.

So why not doing so here.

.... "in pair by the traverse method..." I'm not familiar with that term,
I'll try to look it up.

But, yes, it is a form of tree.
As my conceptual idea, I would say why not buy strategy pattern.

begin(Strategy1()), end(Strategy1())

Looking at the strategy design, it seems to be a form of polymorphic funcion
calls. I don't see how that will help me, unless there is some other form
of strategy pattern I'm missing.
 
B

Barry

Jim said:
... "in pair by the traverse method..." I'm not familiar with that term,
I'll try to look it up.

Forgive my English,
it like post_order, in_order, pre_order
But, yes, it is a form of tree.


Looking at the strategy design, it seems to be a form of polymorphic funcion
calls. I don't see how that will help me, unless there is some other form
of strategy pattern I'm missing.
Here, I think Design Pattern is just way of communication,
like iterator in STL can also be designed without any virtual functions.
But Strategy here, how to? No experience here, just an idea.
 
J

Jim Langston

Barry said:
Forgive my English,
it like post_order, in_order, pre_order

Hmm.. I looked up the transversal pattern and it seems to be something I'm
doing in another tree type class to serialize it.

void CSkill::Write( std::eek:stream& os, const std::string& Prefix, const bool
AllowZero, const bool UseExpand ) const
{
if ( Name_.length() > 0 && ( Value_ > 0 || AllowZero || ! Expand_ ||
Active_ ) )
os << Prefix << Name_ << "," << Value_ << "," << jml::BoolToStr(
Active_ ) << "," << jml::BoolToStr( Activated_ ) <<
"," << jml::BoolToStr( Expand_ ) << std::endl;
// Only write skills if using expand and expanded, or we're not using
expand
if ( ! UseExpand || ( UseExpand && Expand_ ) )
{
for ( std::map< std::string, CSkill >::const_iterator it =
Skills_.begin(); it != Skills_.end(); ++it )
{
(*it).second.Write( os, ( Name_.length() > 0 ? Prefix + Name_ +
"|" : "" ), AllowZero, UseExpand );
}
}
}

It looks a little more complicated than it is with all the switches I'm
checking, but basically it's traversing the tree. I don't see how this
really helps me though.
 
J

Jim Langston

Jim Langston said:
Hmm.. I looked up the transversal pattern and it seems to be something I'm
doing in another tree type class to serialize it.

void CSkill::Write( std::eek:stream& os, const std::string& Prefix, const
bool AllowZero, const bool UseExpand ) const
{
if ( Name_.length() > 0 && ( Value_ > 0 || AllowZero || ! Expand_ ||
Active_ ) )
os << Prefix << Name_ << "," << Value_ << "," << jml::BoolToStr(
Active_ ) << "," << jml::BoolToStr( Activated_ ) <<
"," << jml::BoolToStr( Expand_ ) << std::endl;
// Only write skills if using expand and expanded, or we're not using
expand
if ( ! UseExpand || ( UseExpand && Expand_ ) )
{
for ( std::map< std::string, CSkill >::const_iterator it =
Skills_.begin(); it != Skills_.end(); ++it )
{
(*it).second.Write( os, ( Name_.length() > 0 ? Prefix + Name_ +
"|" : "" ), AllowZero, UseExpand );
}
}
}

It looks a little more complicated than it is with all the switches I'm
checking, but basically it's traversing the tree. I don't see how this
really helps me though.

Well, I think the way I'm going to do is pass into a reference to a std::set
and build the set using traversal, then iterate over the set.
Unfortunately, this means I'm going to have to copy each index instead of
using an iterator to it, but I can't think of any other way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top