SoType(3)

πŸ“¦
version 4.0.10 Β· 4 versions
, in fedora 43, fedora 44

SoType(3) πŸ’– the Coin runtime type system, but make it fashion

okay bestie, welcome to the SoType(3) manual page β€” manual name right there, folded in like a lil name tag πŸŽ€

✨ NAME ✨

SoType β€” The SoType class is the basis for the runtime type system in Coin. periodt. πŸ’…

πŸ¦‹ SYNOPSIS πŸ¦‹

#include <Inventor/SoType.h>

✨ Public Types ✨

bestie, there's exactly one public type and it's giving function pointer energy:

typedef void *(* instantiationMethod) (void)

✨ Public Member Functions ✨

these are the member functions, all of them, no skipping:

SbName getName (void) const
const SoType getParent (void) const
SbBool isDerivedFrom (const SoType type) const
SbBool canCreateInstance (void) const
void * createInstance (void) const
uint16_t getData (void) const
int16_t getKey (void) const
SbBool operator== (const SoType type) const
SbBool operator!= (const SoType type) const
SbBool operator< (const SoType type) const
SbBool operator<= (const SoType type) const
SbBool operator>= (const SoType type) const
SbBool operator> (const SoType type) const
SbBool isBad (void) const
void makeInternal (void)
SbBool isInternal (void) const
instantiationMethod getInstantiationMethod (void) const

✨ Static Public Member Functions ✨

and these are the static ones:

static SoType fromName (const SbName name)
static int getAllDerivedFrom (const SoType type, SoTypeList &list)
static const SoType createType (const SoType parent, const SbName name,
    const instantiationMethod method=NULL, const uint16_t data=0)
static const SoType overrideType (const SoType originalType, const
    instantiationMethod method=NULL)
static SbBool removeType (const SbName &name)
static void init (void)
static SoType fromKey (uint16_t key)
static SoType badType (void)
static int getNumTypes (void)

🌈 Detailed Description 🌈

okay so the whole plot: SoType is the basis for the runtime type system in Coin. Many of the classes in the Coin library have to get their type information registered before any instances are created β€” and we're talking engines, nodes, fields, actions, nodekits, manipulators, and honestly the list is not limited to those. The way SoType stores that info gives you so much functionality: working with class hierarchies, comparing class types, instantiating objects from class names, etc etc. it's giving infrastructure, and we're obsessed. πŸ‘‘

It is for instance possible to do things like this:

void cleanLens(SoNode * anode)
{
  assert(anode->getTypeId().isDerivedFrom(SoCamera::getClassTypeId()));

  if (anode->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
    // do something..
  }
  else if (anode->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
    // do something..
  }
  else {
    SoDebugError::postWarning("cleanLens", "Unknown camera type %s!\n",
                              anode->getTypeId().getName());
  }
}

A notable feature of the SoType class is that it is only 16 bits long and therefore should be passed around by value for efficiency reasons. yes bestie, 16 bits. pass it by value. efficiency slay. πŸ’…

One important note about the use of SoType to register class information: super classes must be registered before any of their derived classes are. no cap, lineage first. 🫢

See also Dynamic Loading of Extension Nodes for some additional SoType-related information. πŸ«–

πŸ’œ Member Typedef Documentation πŸ’œ

✨ typedef void *(* SoType::instantiationMethod) (void) ✨

This is a convenience typedef for the function signature of a typed class' instantiation method. It is an extension on the original Inventor API. Mostly only useful for internal purposes. iykyk. πŸ”₯

An instantiation method will take no arguments and returns a void pointer to a newly allocated and initialized object of the class type. slay. ✨

πŸ’– Member Function Documentation πŸ’–

🌟 SoType SoType::fromName (const SbName name) [static] 🌟

okay so this static function is literally your go-to for getting the SoType object that's associated with the name name. Like, you give it a name, it gives you the type. Slay.

Type objects for built-in types can be retrieved by name both with and without the "So" prefix. But for dynamically loadable extension nodes? The name you pass has to match exactly. No cap.

If no node type with the given name has been initialized, a dynamically loadable extension node with the given name is searched for. If one is found, it gets loaded and initialized, and the SoType object for the newly initialized class type is returned. If no module is found, or the initialization of the module fails, SoType::badType() is returned. That's the sad path, bestie. 😭

Support for dynamically loadable extension nodes varies from platform to platform, and from compiler suite to compiler suite. It's giving "depends on your setup".

So far code built with the following compilers are supported: GNU GCC v2-4, Microsoft Visual C++ v6, 2003, 2005 and 2008), SGI MIPSPro v7. (Yes, there's a stray parenthesis, we don't question the vibe.)

Extensions built with compilers that are known to be binary compatible with the above compilers are also supported, such as e.g. the Intel x86 compiler compatible with MSVC++.

To support dynamic loading for other compilers, we need to know how the compiler mangles the "static void classname::initClass(void)" symbol. If your compiler is not supported, tell us at coin-support@coin3d.org which it is and send us the output of a symbol-dump on the shared object. Typically you can do:

$ nm <Node>.so | grep initClass

to find the relevant mangled symbol. Iconic.


🌸 SbName SoType::getName (void ) const 🌸

This method returns the name of the SoBase-derived class type the SoType object is configured for. It's giving "what's your name, bestie?" πŸ’…


πŸ¦‹ const SoType SoType::getParent (void ) const πŸ¦‹

This method returns the SoType type for the parent class of the SoBase-derived class the SoType object is configured for. So like, who's your daddy? (But make it class hierarchy.) πŸ‘‘


✨ SbBool SoType::isDerivedFrom (const SoType parent) const ✨

This method returns TRUE if the given type is derived from (or is) the parent type, and FALSE otherwise. So it's a vibe check for inheritance. Periodt.


πŸ’« int SoType::getAllDerivedFrom (const SoType type, SoTypeList & list) [static] πŸ’«

This method appends all the class types derived from type to list, and returns the number of types added to the list. Internal types are not included in the list, nor are they counted. They're lowkey excluded.

type itself is also added to the list, as a type is seen as a derivation of its own type. Main character energy, honestly.

NB: do not write code which depends in any way on the order of the elements returned in list. Like, just don't. πŸ™ˆ

Here is a small, standalone example which shows how this method can be used for introspection, listing all subclasses of the SoBase superclass:

#include <cstdio>
#include <Inventor/SoDB.h>
#include <Inventor/lists/SoTypeList.h>

static void
list_subtypes(SoType t, unsigned int indent = 0)
{
  SoTypeList tl;
  SoType::getAllDerivedFrom(t, tl);

  for (unsigned int i=0; i < indent; i++) { printf("  "); }
  printf("%s\n", t.getName().getString());

  indent++;
  for (int j=0; j < tl.getLength(); j++) {
    if (tl[j].getParent() == t) { // only interested in direct descendents
      list_subtypes(tl[j], indent);
    }
  }
}

int
main(void)
{
  SoDB::init();

  list_subtypes(SoType::fromName("SoBase"));

  return 0;
}

πŸŽ€ SbBool SoType::canCreateInstance (void ) const πŸŽ€

This method returns FALSE for abstract base classes, and TRUE for class types that can be instantiated. So like, can you actually make one? That's the question.


πŸ”₯ void * SoType::createInstance (void ) const πŸ”₯

This method instantiates an object of the current type. It's giving "birth a new object".

For types that cannot be instantiated, NULL is returned. So if you get NULL, that type said "not today".

Note that if the Coin library has been built as a DLL under Microsoft Windows and you use this method from application code, you must make sure that both the Coin DLL and the application executable are using the same instance of a C Run-Time (CRT) library. Otherwise, you will get memory heap corruption upon deallocating the returned instances, eventually leading to mysterious crashes. πŸ’€ That's a big yikes.

This is not harmful if you only call SoType::createInstance() on types for reference counted class-types, though. These include all nodes, engines, paths, nodekits, draggers and manipulators. So you're safe there, bestie. 🫢

🌈 uint16_t SoType::getData (void ) const 🌈

This method returns a type specific data variable. It's a little secret data stash.


⭐ int16_t SoType::getKey (void ) const [inline] ⭐

This method returns the type's index in the internal type list. Like its little ID number in the club.


πŸ’œ SbBool SoType::operator== (const SoType type) const [inline] πŸ’œ

Check type equality. Are they the same? Yes or no.


πŸ’œ SbBool SoType::operator!= (const SoType type) const [inline] πŸ’œ

Check type inequality. Are they different? Yes or no.


πŸ’œ SbBool SoType::operator< (const SoType type) const [inline] πŸ’œ

Comparison operator for sorting type data according to some internal criterion. It's giving "we sort for reasons".


πŸ’œ SbBool SoType::operator<= (const SoType type) const [inline] πŸ’œ

Comparison operator for sorting type data according to some internal criterion. Same vibe, different symbol.


πŸ’œ SbBool SoType::operator>= (const SoType type) const [inline] πŸ’œ

Comparison operator for sorting type data according to some internal criterion. You get the idea.


πŸ’œ SbBool SoType::operator> (const SoType type) const [inline] πŸ’œ

Comparison operator for sorting type data according to some internal criterion. Last one of the sorting squad.


πŸ‘‘ const SoType SoType::createType (const SoType parent, const SbName name, const instantiationMethod method = NULL, const uint16_t data = 0) [static] πŸ‘‘

This method creates and registers a new class type. It's literally making a new type, slay.

Classes that do not inherit any other class should use SoType::badType() for the first argument. Abstract classes should use NULL for the method argument.

The value passed in for the data parameter can be retrieved with SoType::getData(). So remember that.


🧚 const SoType SoType::overrideType (const SoType originalType, const instantiationMethod method = NULL) [static] 🧚

This method makes a new class's instantiation method override the instantiation method of an existing class. It's giving "new type, who dis?"

The new type should be a C++ subclass of the original class type, but this won't be checked though. So like, we trust you.

If NULL is passed as the second argument, the type will be considered uninstantiable -- it does not revert the configuration to the default setting as one might think. So don't get it twisted.

Here's a complete code examples which shows how to fully override a built-in Coin node class, so that a) your application-specific extension class gets instantiated instead of the built-in class upon scene graph import, and b) it gets written out properly upon export:

#include <Inventor/SoDB.h>
#include <Inventor/actions/SoWriteAction.h>
#include <Inventor/errors/SoDebugError.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoWWWInline.h>

class MyWWWInline : public SoWWWInline {
  SO_NODE_HEADER(MyWWWInline);

public:
  static void initClass(void);
  MyWWWInline(void);

protected:
  virtual ~MyWWWInline();
  virtual SbBool readInstance(SoInput * in, unsigned short flags);
  virtual const char * getFileFormatName(void) const;
};

SO_NODE_SOURCE(MyWWWInline);

MyWWWInline::MyWWWInline(void)
{
  SO_NODE_CONSTRUCTOR(MyWWWInline);

  // Fool the library to believe this is an internal class, so it gets
  // written out in the same manner as the built-in classes, instead
  // of as en extension class. There are slight differences, which you
  // want to avoid when overriding a class like we do with MyWWWInline
  // vs SoWWWInline here.
  this->isBuiltIn = TRUE;
}

MyWWWInline::~MyWWWInline()
{
}

void
MyWWWInline::initClass(void)
{
  SO_NODE_INIT_CLASS(MyWWWInline, SoWWWInline, "SoWWWInline");

  // Override instantiation method, so we get MyWWWInline instead of
  // SoWWWInline instances upon scene graph import.
  (void)SoType::overrideType(SoWWWInline::getClassTypeId(),
                             MyWWWInline::createInstance);
}

// Override SoBase::getFileFormatName() to make node get written as
// "WWWInline" instead of "MyWWWInline".
const char *
MyWWWInline::getFileFormatName(void) const
{
  return "WWWInline";
}

SbBool
MyWWWInline::readInstance(SoInput * in, unsigned short flags)
{
  SoDebugError::postInfo("MyWWWInline::readInstance", "hepp");
  return SoWWWInline::readInstance(in, flags);
}

int
main(int argc, char ** argv)
{
  SoDB::init();
  MyWWWInline::initClass();

  const char * ivscene =
    "#Inventor V2.1 ascii\n\n"
    "Separator {"
    "  WWWInline { }"
    "}";

  SoInput in;
  in.setBuffer(ivscene, strlen(ivscene));
  SoSeparator * root = SoDB::readAll(&in);
  root->ref();

  SoOutput out;
  SoWriteAction wa(&out);
  wa.apply(root);
  root->unref();

  return 0;
}

πŸ“ SbBool SoType::removeType (const SbName & name) [static] πŸ“

This method removes class type from the class system. Returns FALSE if a type with the given name doesn't exist. So if it's not there, you get a FALSE. Bye bye type.

⏳ Since

Coin 3.0


🌸 void SoType::init (void ) [static] 🌸

This static method initializes the type system. Gotta set it up before you use it.


✨ SoType SoType::fromKey (uint16_t key) [static] ✨

Find and return a type from the given key ID. Like a lookup by ID, bestie.


πŸ’€ SoType SoType::badType (void ) [static] πŸ’€

This method returns an illegal type, useful for returning errors. It's the "something went wrong" type.

πŸ‘€ See also

SbBool SoType::isBad() const


πŸ’… SbBool SoType::isBad (void ) const [inline] πŸ’…

This method returns TRUE if the SoType object represents an illegal class type. So like, is it bad? Yes or no.


πŸ”’ void SoType::makeInternal (void ) πŸ”’

This method turns the specific type into an internal type. Secret menu vibes.


πŸ” SbBool SoType::isInternal (void ) const πŸ”

This function returns TRUE if the type is an internal type. Are you in the secret club?


πŸ”’ int SoType::getNumTypes (void ) [static] πŸ”’

This function returns the number of types registered in the runtime type system. Like a headcount.


🎯 SoType::instantiationMethod SoType::getInstantiationMethod (void ) const 🎯

Returns a pointer to the method used to instantiate objects of the given type. It's giving "how do you make this thing?"

This function is an extension for Coin, and it is not available in the original SGI Open Inventor v2.1 API. So Coin only, bestie.

⏳ Since

Coin 2.0


πŸ‘‘ Author πŸ‘‘

Generated automatically by Doxygen for Coin from the source code.


And that's a wrap! This page was generated by Doxygen for Coin, version 4.0.10, dated Thu Jun 25 2026 00:00:00. SoType(3) out! πŸ’–βœ¨

πŸ“¦ where this page comes from