00001
00002
00003 #include "Iguana/GLModels/interface/Ig3DBaseModel.h"
00004 #include "Iguana/GLModels/interface/Ig3DBaseModelEvent.h"
00005 #include "Iguana/GLModels/interface/Ig3DBaseRep.h"
00006 #include <Inventor/nodes/SoSelection.h>
00007 #include <Inventor/nodes/SoSeparator.h>
00008 #include <Inventor/actions/SoSearchAction.h>
00009 #include <Inventor/SoPath.h>
00010 #include <classlib/utils/DebugAids.h>
00011 #include <algorithm>
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 Ig3DBaseModel::Ig3DBaseModel (IgState *state)
00024 : m_state (state),
00025 m_sceneGraph (new SoSelection),
00026 m_attachPoint (0)
00027 {
00028
00029 m_sceneGraph->ref ();
00030 m_sceneGraph->setName ("IGUANA_SCENE_GRAPH_V2");
00031 Ig3DBaseRep *rep = new Ig3DBaseRep (this, 0, 0, new SoSeparator);
00032 ASSERT (m_attachPoint == rep);
00033 }
00034
00035 Ig3DBaseModel::~Ig3DBaseModel (void)
00036 { m_sceneGraph->unref (); }
00037
00039 IgState *
00040 Ig3DBaseModel::state (void) const
00041 { return m_state; }
00042
00044 void
00045 Ig3DBaseModel::listen (EventType , const Listener &listener)
00046 { m_listeners.push_back (listener); }
00047
00048 void
00049 Ig3DBaseModel::unlisten (EventType , const Listener &listener)
00050 {
00051 Listeners::iterator pos = std::find (m_listeners.begin (),
00052 m_listeners.end(),
00053 listener);
00054 ASSERT (pos != m_listeners.end ());
00055 m_listeners.erase (pos);
00056 }
00057
00058 void
00059 Ig3DBaseModel::changed (void)
00060 {
00061 Ig3DBaseModelEvent event (this);
00062 for (Listeners::iterator pos = m_listeners.begin ();
00063 pos != m_listeners.end (); ++pos)
00064 (*pos) (event);
00065 }
00066
00068 Ig3DBaseRep *
00069 Ig3DBaseModel::lookup (SoGroup *node) const
00070 { ASSERT (false); return dynamic_cast<Ig3DBaseRep *> (node); }
00071
00073 void
00074 Ig3DBaseModel::add (Ig3DBaseRep *rep)
00075 {
00076 ASSERT (rep);
00077
00078 if (! m_attachPoint)
00079 {
00080
00081 ASSERT (m_sceneGraph->getNumChildren () == 0);
00082 m_sceneGraph->addChild (m_attachPoint = rep);
00083 }
00084 else
00085 {
00086 ASSERT (m_attachPoint->findChild (rep) == -1);
00087 m_attachPoint->addChild (rep);
00088 changed ();
00089 }
00090 }
00091
00092 void
00093 Ig3DBaseModel::remove (Ig3DBaseRep *rep, bool search )
00094 {
00095 ASSERT (rep);
00096
00097
00098 int index;
00099 if ((index = m_attachPoint->findChild (rep)) != -1)
00100 m_attachPoint->removeChild (index);
00101
00102 if (search)
00103 {
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 SoSearchAction searcher;
00115 searcher.setNode (rep);
00116 searcher.apply (m_attachPoint);
00117
00118 if (searcher.getPath ())
00119 {
00120 ASSERT (searcher.getPath ()->getLength () > 1);
00121 SoNode *parent = searcher.getPath ()->getNodeFromTail (1);
00122 ASSERT (parent && parent->isOfType(SoSeparator::getClassTypeId()));
00123 SoSeparator *p = static_cast<SoSeparator *> (parent);
00124 p->removeChild (rep);
00125 }
00126 }
00127
00128 changed ();
00129 }
00130
00131 void
00132 Ig3DBaseModel::change (Ig3DBaseRep *rep)
00133 {
00134 ASSERT (rep);
00135 changed ();
00136 }
00137
00139 SoGroup *
00140 Ig3DBaseModel::sceneGraph (void) const
00141 { return m_sceneGraph; }
00142
00143 Ig3DBaseRep *
00144 Ig3DBaseModel::attachPoint (void) const
00145 { return m_attachPoint; }
00146
00148 SbString
00149 Ig3DBaseModel::encode (const std::string &name)
00150 {
00151
00152
00153
00154 static const char hexdigits [] = "0123456789abcdef";
00155 std::string result;
00156
00157 if (! SbName::isBaseNameStartChar (name [0]))
00158 {
00159 result += '_';
00160 }
00161
00162 for (std::string::size_type i = 0; i < name.size (); ++i)
00163 if (SbName::isBaseNameChar (name[i]))
00164 result.append (1, name[i]);
00165 else if (i > 0 && SbName::isBaseNameStartChar (name[i]))
00166 result.append (1, name[i]);
00167 else
00168 {
00169 # if UCHAR_MAX != 255 || CHAR_BIT != 8
00170 # error expected 8-bit characters
00171 # endif
00172 result += '_';
00173 result += 'X';
00174 result += hexdigits [((unsigned char) name[i]>>4)&0xf];
00175 result += hexdigits [(unsigned char) name[i]&0xf];
00176 }
00177
00178 return result.c_str ();
00179 }
00180
00181 std::string
00182 Ig3DBaseModel::decode (const std::string &name)
00183 {
00184
00185
00186
00187 static const char hexdigits [] = "0123456789abcdef";
00188 std::string result;
00189 const char *first;
00190 const char *second;
00191
00192 for (std::string::size_type i = 0; i < name.size (); ++i)
00193 if (name[i] != '_'
00194 || i > name.size () - 4
00195 || name[i+1] != 'X'
00196 || !(first = strchr (hexdigits, name[i+2]))
00197 || !(second = strchr (hexdigits, name[i+3])))
00198 result.append (1, name[i]);
00199 else
00200 {
00201 # if UCHAR_MAX != 255 || CHAR_BIT != 8
00202 # error expected 8-bit characters
00203 # endif
00204 unsigned int code = ((unsigned) (first - hexdigits) << 4)
00205 + ((unsigned) (second - hexdigits));
00206 ASSERT (code <= UCHAR_MAX);
00207 result += static_cast<char> (code);
00208 i += 3;
00209 }
00210
00211 return result;
00212 }
00213
00214 std::string
00215 Ig3DBaseModel::decode (const SbName &name)
00216 { return decode (std::string (name.getString ())); }