SOBASE(3iv)

πŸŽ€ SoBase β€” bestie, this is literally the blueprint πŸ’…

okay so first things first: this page is SoBase(3IV), and it's the whole entire origin story. Sit down, hydrate, let's get into it. πŸ¦‹


✨ NAME ✨

SoBase β€” the base class for all nodes, paths, and engines. she's the mother of everybody, no cap. πŸ‘‘


🌸 INHERITS FROM 🌸

SoBase β€” yeah bestie she inherits from herself, she's built different, she's the top of the tree, there's nobody above her. main character energy fr fr. 🫢


✨ SYNOPSIS ✨

first you gotta pull her in:

#include <Inventor/misc/SoBase.h>

then, the methods from class SoBase, verbatim, because I do not play with code:

void                ref()
void                unref() const
void                unrefNoDelete() const
void                touch()
static SoType       getClassTypeId()
virtual SoType      getTypeId() const
SbBool              isOfType(SoType type) const
virtual void        setName(const SbName &name)
virtual SbName      getName() const

πŸ’– DESCRIPTION πŸ’–

okay so. SoBase is the abstract base class for Inventor node, path, and engine classes. abstract means you don't go make one of her directly, you inherit from her. she handles three things and she handles them flawlessly:

  • reference counting
  • notification
  • naming

that's the whole vibe check. periodt. ✨


πŸ’… METHODS πŸ’…

ref(), unref() const, unrefNoDelete() const β€” the reference count trio πŸ‘‘

void                ref()
void                unref() const
void                unrefNoDelete() const

so these add and remove a reference to an instance. the tea is: you should reference an instance whenever it's gonna be used outside the routine where it was initialized. (a classic example? keeping a pointer to the root of a graph. that's the one everybody does.) πŸ“

whenever the reference count for an instance gets decremented all the way down to 0, the instance is automatically destroyed by the database β€” unless you used unrefNoDelete() to unref it instead. sneak peek at the escape hatch, we'll get there.

and it's not just you doing this manually, bestie, the system does it for you:

  • the reference count of a node is automatically incremented when the node is added as a child of another node, or when a path points to the node.
  • likewise, it's automatically decremented when the node is removed as a child, or when a path that points to the node is changed or destroyed.

unrefNoDelete() is the one you call when you wanna decrement the reference count but not delete the instance even if that brings the count to zero. lowkey the most useful thing ever for returning an object to a zero-reference-count state β€” like how it was when it was created by new. iconic behavior honestly. πŸ’œ

⚠️ okay warning time: if you plain unref() and the count hits 0, that thing is gone. deleted. ghosted. if you weren't done with it, that's on you bestie. use unrefNoDelete() if you want it to survive. 😭

touch() β€” the "hey, I changed!" button πŸ“’

void                touch()

marks an instance as modified, simulating a change to it. this will notify auditors (parent nodes, connected engines, and so on) of a change to this object, and cause attached sensors to be triggered. it's giving "not me subtly updating everything downstream". πŸ”₯

static SoType getClassTypeId() β€” the class's ID card πŸͺͺ

static SoType       getClassTypeId()

returns the type identifier for this class. (the class, not the instance. keep up bestie. πŸ’…)

virtual SoType getTypeId() const β€” the instance's ID card πŸͺͺ

virtual SoType      getTypeId() const

returns the type identifier for a specific instance.

SbBool isOfType(SoType type) const β€” the vibe check βœ…

SbBool              isOfType(SoType type) const

returns TRUE if this object is of the type specified in type or is derived from that type. otherwise it returns FALSE. for example:

nodePtr->isOfType(SoGroup::getClassTypeId())

returns TRUE if nodePtr is an instance of SoGroup or one of its subclasses. so basically: "are you one of us, or descended from one of us?" and that's the whole test. 🌈

virtual void setName(const SbName &name) β€” naming your child πŸŽ€

virtual void        setName(const SbName &name)

sets the name of an instance. object names are preserved when objects are written to or read from files, which is so good of them honestly.

now the rules, and there are rules, bestie, listen up, because a name that breaks these gets fixed for you:

object names must not begin with a digit, and must not contain:

  • spaces or control characters
  • single or double quote characters
  • backslashes
  • curly braces
  • the plus character

the isBaseNameChar() and isBaseNameStartChar() methods of SbName can be used to validate names input by users β€” so if you're taking a name from a human, run it through those first. 🫢

and here's what happens when a name is bad: this method will replace any bad characters in the name with underscore characters, and will print out an error message if the application is using the Inventor debugging library. so it's not a crash, it's a glow-down. πŸ’€

virtual SbName getName() const β€” what's your name, gorgeous? ✨

virtual SbName      getName() const

returns the name of an instance. if the instance has not been named, an empty SbName is returned. and objects that are named can be looked up using the getByName() methods of SoNode, SoEngine, or SoPath. that's how you find them again later. iykyk. πŸ”


πŸ¦‹ SEE ALSO πŸ¦‹

  • SoFieldContainer
  • SoNode
  • SoPath
  • SoEngine
  • SoDB

and that's the whole page, bestie!! this was SoBase(3IV)() β€” yes, the manual name and the version are literally both SoBase(3IV)(), and there's no date on this one, so consider this your cute little sign-off instead. go forth and reference-count responsibly. πŸ’–βœ¨πŸŽ€