SoBaseKit(3)

๐Ÿ“ฆ version 2.5.0, in fedora 43, fedora 44

๐ŸŽ€ SoBaseKit(3) ๐ŸŽ€

okay bestie, sit down, hydrate, because this is the Library Functions Manual page for SoBaseKit(3) and it is a whole saga. it's split into 6 parts and this is part 1 โ€” we are not even close to done, so don't go anywhere ๐ŸŒธ


๐Ÿ’– NAME ๐Ÿ’–

SoBaseKit โ€” the SoBaseKit class is the toplevel superclass for nodekits.


๐ŸŒˆ SYNOPSIS ๐ŸŒˆ

#include <Inventor/nodekits/SoBaseKit.h>

Inherits SoNode.

Inherited by SoAppearanceKit, SoCameraKit, SoInteractionKit, SoLightKit, SoSceneKit, and SoSeparatorKit.

lowkey this is the blueprint era of the whole nodekit situation. everything else is a remix ๐Ÿ’…

๐Ÿซถ Public Member Functions ๐Ÿซถ

the main character lineup, no cap:

virtual SoType getTypeId (void) const
SoBaseKit (void)
virtual const SoNodekitCatalog * getNodekitCatalog (void) const
virtual SoNode * getPart (const SbName &partname, SbBool makeifneeded)
SbString getPartString (const SoBase *part)
virtual SoNodeKitPath * createPathToPart (const SbName &partname, SbBool makeifneeded, const SoPath *pathtoextend=NULL)
virtual SbBool setPart (const SbName &partname, SoNode *from)
SbBool set (const char *namevaluepairliststring)
SbBool set (const char *partnamestring, const char *parameterstring)
virtual void doAction (SoAction *action)
virtual void callback (SoCallbackAction *action)
virtual void GLRender (SoGLRenderAction *action)
virtual void getBoundingBox (SoGetBoundingBoxAction *action)
virtual void getMatrix (SoGetMatrixAction *action)
virtual void handleEvent (SoHandleEventAction *action)
virtual void rayPick (SoRayPickAction *action)
virtual void search (SoSearchAction *action)
virtual void write (SoWriteAction *action)
virtual void getPrimitiveCount (SoGetPrimitiveCountAction *action)
virtual SoChildList * getChildren (void) const
void printDiagram (void)
void printSubDiagram (const SbName &rootname, int level)
void printTable (void)
virtual void addWriteReference (SoOutput *out, SbBool isfromfield=0)
SbBool forceChildDrivenWriteRefs (SoOutput *out)

๐Ÿฆ‹ Public Member Functions inherited from SoNode ๐Ÿฆ‹

the legacy it carries around, honestly iconic:

void setOverride (const SbBool state)
SbBool isOverride (void) const
void setNodeType (const NodeType type)
NodeType getNodeType (void) const
virtual SoNode * copy (SbBool copyconnections=0) const
virtual SbBool affectsState (void) const
virtual void GLRenderBelowPath (SoGLRenderAction *action)
virtual void GLRenderInPath (SoGLRenderAction *action)
virtual void GLRenderOffPath (SoGLRenderAction *action)
virtual void pick (SoPickAction *action)
virtual void audioRender (SoAudioRenderAction *action)
virtual void grabEventsSetup (void)
virtual void grabEventsCleanup (void)
virtual void startNotify (void)
virtual void notify (SoNotList *l)
uint32_t getNodeId (void) const
virtual void writeInstance (SoOutput *out)
virtual SoFieldContainer * copyThroughConnection (void) const

โœจ Public Member Functions inherited from SoFieldContainer โœจ

void setToDefaults (void)
SbBool hasDefaultValues (void) const
SbBool fieldsAreEqual (const SoFieldContainer *container) const
void copyFieldValues (const SoFieldContainer *container, SbBool copyconnections=0)
SbBool set (const char *const fielddata)
void get (SbString &fielddata)
virtual int getFields (SoFieldList &l) const
virtual int getAllFields (SoFieldList &l) const
virtual SoField * getField (const SbName &name) const
virtual SoField * getEventIn (const SbName &name) const
virtual SoField * getEventOut (const SbName &name) const
SbBool getFieldName (const SoField *const field, SbName &name) const
SbBool enableNotify (const SbBool flag)
SbBool isNotifyEnabled (void) const
SbBool set (const char *fielddata, SoInput *in)
void get (SbString &fielddata, SoOutput *out)
virtual SbBool validateNewFieldValue (SoField *field, void *newval)
SbBool getIsBuiltIn (void) const
void setUserData (void *userdata) const
void * getUserData (void) const

๐Ÿ’œ Public Member Functions inherited from SoBase ๐Ÿ’œ

the ancestors that started it all, fr fr:

void ref (void) const
void unref (void) const
void unrefNoDelete (void) const
int32_t getRefCount (void) const
void touch (void)
SbBool isOfType (SoType type) const
virtual SbName getName (void) const
virtual void setName (const SbName &newname)
void addAuditor (void *const auditor, const SoNotRec::Type type)
void removeAuditor (void *const auditor, const SoNotRec::Type type)
const SoAuditorList & getAuditors (void) const
SbBool shouldWrite (void)
void assertAlive (void) const

๐Ÿ‘‘ Static Public Member Functions ๐Ÿ‘‘

the class-level girlies (they don't need an instance, they're just that girl):

static SoType getClassTypeId (void)
static void initClass (void)
static const SoNodekitCatalog * getClassNodekitCatalog (void)
static SbBool isSearchingChildren (void)
static void setSearchingChildren (const SbBool newval)
static SoNode * typeCheck (const SbName &partname, const SoType &parttype, SoNode *node)

๐Ÿงš Static Public Member Functions inherited from SoNode ๐Ÿงš

static uint32_t getCompatibilityTypes (const SoType &nodetype)
static SoType getClassTypeId (void)
static SoNode * getByName (const SbName &name)
static int getByName (const SbName &name, SoNodeList &l)
static void initClass (void)
static void initClasses (void)
static uint32_t getNextNodeId (void)
static int getActionMethodIndex (const SoType type)
static void getBoundingBoxS (SoAction *action, SoNode *node)
static void GLRenderS (SoAction *action, SoNode *node)
static void callbackS (SoAction *action, SoNode *node)
static void getMatrixS (SoAction *action, SoNode *node)
static void handleEventS (SoAction *action, SoNode *node)
static void pickS (SoAction *action, SoNode *node)
static void rayPickS (SoAction *action, SoNode *node)
static void searchS (SoAction *action, SoNode *node)
static void writeS (SoAction *action, SoNode *node)
static void audioRenderS (SoAction *action, SoNode *node)
static void getPrimitiveCountS (SoAction *action, SoNode *node)

๐Ÿ“ Static Public Member Functions inherited from SoFieldContainer ๐Ÿ“

static void initClass (void)
static SoType getClassTypeId (void)
static void initCopyDict (void)
static void addCopy (const SoFieldContainer *orig, const SoFieldContainer *copy)
static SoFieldContainer * checkCopy (const SoFieldContainer *orig)
static SoFieldContainer * findCopy (const SoFieldContainer *orig, const SbBool copyconnections)
static void copyDone (void)

๐ŸŒธ Static Public Member Functions inherited from SoBase ๐ŸŒธ

static void initClass (void)
static SoType getClassTypeId (void)
static void addName (SoBase *const base, const char *const name)
static void removeName (SoBase *const base, const char *const name)
static void incrementCurrentWriteCounter (void)
static void decrementCurrentWriteCounter (void)
static SoBase * getNamedBase (const SbName &name, SoType type)
static int getNamedBases (const SbName &name, SoBaseList &baselist, SoType type)
static SbBool read (SoInput *in, SoBase *&base, SoType expectedtype)
static void setInstancePrefix (const SbString &c)
static void setTraceRefs (SbBool trace)
static SbBool getTraceRefs (void)
static SbBool connectRoute (SoInput *in, const SbName &fromnodename, const SbName &fromfieldname, const SbName &tonodename, const SbName &tofieldname)
static SbBool readRoute (SoInput *in)

๐Ÿ”’ Protected Member Functions ๐Ÿ”’

the private besties โ€” you only get to hang if you're a subclass:

virtual const SoFieldData * getFieldData (void) const
virtual ~SoBaseKit ()
virtual SoNode * addToCopyDict (void) const
virtual void copyContents (const SoFieldContainer *fromfc, SbBool copyconnections)
SoGroup * getContainerNode (const SbName &listname, SbBool makeifneeded=1)
virtual SoNode * getAnyPart (const SbName &partname, SbBool makeifneeded, SbBool leafcheck=0, SbBool publiccheck=0)
virtual SoNodeKitPath * createPathToAnyPart (const SbName &partname, SbBool makeifneeded, SbBool leafcheck=0, SbBool publiccheck=0, const SoPath *pathtoextend=NULL)
virtual SbBool setAnyPart (const SbName &partname, SoNode *from, SbBool anypart=1)
void createNodekitPartsList (void)
void createFieldList (void)
virtual void createDefaultParts (void)
const SoNodekitParts * getNodekitPartsList (void) const
const SbList< SoSFNode * > & getCatalogInstances (void) const
void catalogError (void)
virtual SbBool setUpConnections (SbBool onoff, SbBool doitalways=0)
virtual SbBool readInstance (SoInput *in, unsigned short flags)
virtual void setDefaultOnNonWritingFields (void)
void countMyFields (SoOutput *out)
virtual SbBool setPart (const int partNum, SoNode *node)

๐Ÿš Protected Member Functions inherited from SoNode ๐Ÿš

SoNode (void)
virtual ~SoNode ()

๐Ÿš Protected Member Functions inherited from SoFieldContainer ๐Ÿš

SoFieldContainer (void)
~SoFieldContainer ()

๐Ÿš Protected Member Functions inherited from SoBase ๐Ÿš

SoBase (void)
virtual ~SoBase ()
virtual void destroy (void)
SbBool hasMultipleWriteRefs (void) const
SbBool writeHeader (SoOutput *out, SbBool isgroup, SbBool isengine) const
void writeFooter (SoOutput *out) const
virtual const char * getFileFormatName (void) const

๐Ÿงต Static Protected Member Functions ๐Ÿงต

static const SoFieldData ** getFieldDataPtr (void)
static const SoNodekitCatalog ** getClassNodekitCatalogPtr (void)

๐Ÿงต Static Protected Member Functions inherited from SoNode ๐Ÿงต

static const SoFieldData ** getFieldDataPtr (void)
static void setNextActionMethodIndex (int index)
static int getNextActionMethodIndex (void)
static void incNextActionMethodIndex (void)
static void setCompatibilityTypes (const SoType &nodetype, const uint32_t bitmask)

๐Ÿงต Static Protected Member Functions inherited from SoBase ๐Ÿงต

static uint32_t getCurrentWriteCounter (void)
static void staticDataLock (void)
static void staticDataUnlock (void)

๐ŸŽ€ Protected Attributes ๐ŸŽ€

the vibes the class keeps to itself:

SoSFNode callbackList
SoChildList * children
SbBool connectionsSetUp

๐ŸŽ€ Protected Attributes inherited from SoNode ๐ŸŽ€

uint32_t uniqueId

๐ŸŽ€ Protected Attributes inherited from SoFieldContainer ๐ŸŽ€

SbBool isBuiltIn

๐Ÿ’Œ Friends ๐Ÿ’Œ

these two get the all-access pass:

class SoInteractionKit
class SoBaseKitP

๐Ÿ“ฆ Additional Inherited Members ๐Ÿ“ฆ

๐Ÿท๏ธ Public Types inherited from SoNode

enum NodeType { INVENTOR = 0x0000, VRML1 = 0x0001, VRML2 = 0x0002, INVENTOR_1 = 0x0004, INVENTOR_2_0 = 0x0008, INVENTOR_2_1 = 0x0010, INVENTOR_2_5 = 0x0020, INVENTOR_2_6 = 0x0040, COIN_1_0 = 0x0080, COIN_2_0 = 0x0100, EXTENSION = 0x0200, COIN_2_2 = 0x0400, COIN_2_3 = 0x0800, COIN_2_4 = 0x1000, INVENTOR_5_0 = 0x2000, COIN_2_5 = 0x4000 }

๐Ÿท๏ธ Protected Types inherited from SoBase

enum BaseFlags { IS_ENGINE = 0x01, IS_GROUP = 0x02 }

๐Ÿท๏ธ Static Protected Attributes inherited from SoNode

static uint32_t nextUniqueId = 0
static int nextActionMethodIndex = 0

๐Ÿ’œ Detailed Description ๐Ÿ’œ

The SoBaseKit class is the toplevel superclass for nodekits.

bestie that's the whole plot summary and honestly? it's giving everything is built on this. โœจ

๐ŸŒธ and that's part 1 of 6 โ€” hold that thought, we are so not done yet ๐ŸŒธ

Okay bestie, real talk: a node kit is literally just a collection of nodes and other node kits โ€” and from here on out, any node kit that's part of some other node kit is just gonna get called a node or a part (go peep the catalog and parts lore for the full โœจsituationโœจ) โ€” all organized in a way that's actually convenient to use. A node kit inherits SoNode, so you can drop it into a scenegraph exactly like any other node. No special treatment, no drama. ๐Ÿ’…

The whole organizing sitch โ€” the nodes and node kits of some node kit โ€” happens through catalogs. A node kit's catalog describes the nodes that are allowed to be members of the node kit. Those members are called parts. So yeah, a node kit has a catalog describing the parts it's offering up to you. ๐ŸŽ€

Every part in the catalog comes with a little bundle of values that say something about the part itself and about the role it plays in the scenegraph. Those values are, and I'm listing them all because you deserve the full picture:

Name

The name of the part.

Type

The part's node type.

Default Type

If the part's type is an abstract superclass, this value will hold the default subclass used by this part.

Created by Default?

Holds TRUE if the part should be instantiated when the node kit is instantiated, otherwise the part is kept empty until it is set by some of the means applicable.

Parent Name

The name of the part that is this part's parent.

Right Sibling

The name of the part that is the part immediately to the right of this part in the node kit scenegraph.

Is it a List?

Holds TRUE if the part is a list, otherwise it is FALSE. See SoNodeKitListPart for more info on node kit lists.

List Cointainer Type

The type of group node used to hold the items if the part is a list.

List Element Type

The types of nodes that is allowed to be held by this part if the part is a list.

Is It Public?

Holds TRUE if the part should be publically available, otherwise it holds FALSE.


Now here's the part that's lowkey genius: node kits use lazy instantiation when they create their parts. Meaning the nodes making up the parts of the node kit only get created when they're actually needed. If "Created by Default?" holds TRUE, the part gets created right when the node kit itself is instantiated. If not? Parts get created when they're requested through SoBaseKit::getPart() or the SO_GET_PART() macro, or created with SoBaseKit::set(). And plot twist โ€” if a part is set with SoBaseKit::setPart() or the SO_SET_PART() macro, any previously uncreated parts above the set part in the hierarchy get created automatically. Slay. โœจ

The advantages of using node kits to represent a scenegraph are, like, so many:

  • Since a node kit collects nodes into a single unit, it becomes an extra abstraction layer for the application programmer. Such a layer can represent a model of a human being as one unit where subunits as arms, legs, textures, etc are contained within. Thus we can instantiate a model of a human by creating an instance of the node kit, instead of having to create a possibly large amount of nodes needed for such a model.
  • A part of the node kit doesn't have one spesific setup. A shape part can e.g. be swapped with any other shape, since they are of the same type. If the node kit of a human has a part called "head" which is of type SoShape, it might default to a sphere. But if the programmer thinks that a cube might fit better, one can set the "head" part to a cube instead, or maybe a face set representing a complex model of a head.
  • Node kits can have as simple or as complex catalogs as needed. The nodes included in the node kit can, if needed, represent the whole range of Inventor features. One part can as easily be of a node kit type, making it possible to create hierarchys of node kits. Having a node kit of a human, it might be feasible to have sub node kits describing the different body parts.
  • Node kits are an efficient way of creating scenegraphs. If some part of it isn't needed at the moment of node kit instantiation, they aren't created. Thus parts are only created when needed, either by the application or some other part.
  • The application code becomes smaller and easier to read, as the node kits provides simple routines for creating and setting parts.
  • New node kits can be created through subclassing to obtain simple setups of scenegraphs best fitted to the application.

Using a node kit is genuinely so straightforward. Below follows a code example showing some simple SoShapeKit usage. ๐Ÿฆ‹

#include <Inventor/Qt/SoQt.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/nodekits/SoShapeKit.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoCube.h>

int
main(int argc, char ** argv)
{
  QWidget * window = SoQt::init(argv[0]);

  SoQtExaminerViewer * viewer = new SoQtExaminerViewer(window);

  // Instantiating a shape kit, by default creating a simple sphere.
  SoShapeKit * shapekit = new SoShapeKit;
  // Swapping the sphere with a cube.
  shapekit->setPart("shape", new SoCube);
  // Setting the cube to be rendered in the color red. The shape kit
  // has a SoAppearanceKit as one of it's parts. The "material" part
  // used to set the color of the shape, really belongs the
  // appearance kit. If the SoShapeKit::set() is used, it will
  // check if some of its sub kits has a part with the name given,
  // and delegate the setting to the correct kit.
  shapekit->set("material", "diffuseColor 1 0 0");

  SoSeparator * newroot = new SoSeparator;
  newroot->ref();

  newroot->addChild(shapekit);

  viewer->setSceneGraph(newroot);

  viewer->show();
  SoQt::show(window);

  SoQt::mainLoop();
  delete viewer;

  newroot->unref();
  return 0;
}

The above code snippet will produce a viewer with a side view to the scene shown below:

Notice that the code needed for creating this simple shape using a shape kit, amounts to this:

SoShapeKit * shapekit = new SoShapeKit;

shapekit->setPart("shape", new SoCube);
shapekit->set("material", "diffuseColor 1 0 0");

..while doing it without shape kits amounts to this:

SoSeparator * root = new SoSeparator;
SoMaterial * material = new SoMaterial;
material->diffuseColor.setValue(1,0,0);
root->addChild(material);
root->addChild(new SoCube);

..so even for this miniscule mock-up example, you save on code verbosity and complexity. Fr fr, the difference is giving efficiency. ๐Ÿ‘‘


For extending the Coin library with your own classes, we strongly recommend that you make yourself acquainted with the excellent ยซThe Inventor Toolmakerยป book (ISBN 0-201-62493-1), which describes the tasks involved in detail. This book was written by the original SGI Inventor designers and explains many of the underlying design ideas, aswell as having lots of hands-on examples on how to extend the Coin toolkit in ways that are true to the fundamental design ideas. (ยซThe Inventor Toolmakerยป is also available at SGI's online library, at no cost. See Download The Inventor Toolmaker.) Reading the sourcecode of the built-in classes in Coin should also provide very helpful.


Following is a complete example of a node kit extension. The node kit is a kit which automatically scales a shape so it will be the same size in screen-pixels, no matter which distance it is from the camera. This is useful for marker graphics. The shape defaults to a cube, but can be set by the programmer to any shape or scene sub-graph.

The header file:

// Copyright (C) 1998-2007 by Systems in Motion. All rights reserved.

#ifndef COIN_SHAPESCALE_H
#define COIN_SHAPESCALE_H
#include <Inventor/nodekits/SoSubKit.h>
#include <Inventor/nodekits/SoBaseKit.h>
#include <Inventor/fields/SoSFFloat.h>

class SbViewport;
class SoState;
class SbColor;
class SbVec2s;

class ShapeScale : public SoBaseKit {
  typedef SoBaseKit inherited;

  SO_KIT_HEADER(ShapeScale);

  SO_KIT_CATALOG_ENTRY_HEADER(topSeparator);
  SO_KIT_CATALOG_ENTRY_HEADER(scale);
  SO_KIT_CATALOG_ENTRY_HEADER(shape);

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

  SoSFFloat active;
  SoSFFloat projectedSize;

 protected:
  virtual void GLRender(SoGLRenderAction * action);
  virtual ~ShapeScale();
};

#endif // ! SHAPESCALE_H

The source code for the example:

// Copyright (C) 1998-2007 by Systems in Motion. All rights reserved.

//  The ShapeScale class is used for scaling a shape based on
//  projected size.
//
//  This nodekit can be inserted in your scene graph to add for
//  instance 3D markers that will be of a constant projected size.
//
//  The marker shape is stored in the "shape" part. Any kind of node
//  can be used, even group nodes with several shapes, but the
//  marker shape should be approximately of unit size, and with a
//  center position in (0, 0, 0).

//  SoSFFloat ShapeScale::active
//  Turns the scaling on/off. Default value is TRUE.

//  SoSFFloat ShapeScale::projectedSize
//  The requested projected size of the shape. Default value is 5.0.

#include "ShapeScale.h"

#include <Inventor/actions/SoGLRenderAction.h>
#include <Inventor/nodes/SoShape.h>
#include <Inventor/nodes/SoScale.h>
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/elements/SoViewVolumeElement.h>
#include <Inventor/elements/SoViewportRegionElement.h>
#include <Inventor/elements/SoModelMatrixElement.h>

SO_KIT_SOURCE(ShapeScale);

//  Constructor.
ShapeScale::ShapeScale(void)
{
  SO_KIT_CONSTRUCTOR(ShapeScale);

  SO_KIT_ADD_FIELD(active, (TRUE));
  SO_KIT_ADD_FIELD(projectedSize, (5.0f));

  SO_KIT_ADD_CATALOG_ENTRY(topSeparator, SoSeparator, FALSE, this, \x0, FALSE);
  SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(shape, SoNode, SoCube, TRUE, topSeparator, \x0, TRUE);
  SO_KIT_ADD_CATALOG_ENTRY(scale, SoScale, FALSE, topSeparator, shape, FALSE);

  SO_KIT_INIT_INSTANCE();
}

// Destructor.
ShapeScale::~ShapeScale()
{
}

// Initializes this class. Call before using it.

void
ShapeScale::initClass(void)
{
  SO_KIT_INIT_CLASS(ShapeScale, SoBaseKit, "BaseKit");
}

static void
update_scale(SoScale * scale, const SbVec3f & v)
{
  // only write to field when scaling has changed.
  if (scale->scaleFactor.getValue() != v) {
    scale->scaleFactor = v;
  }
}

// Overridden to (re)initialize scaling before rendering marker.
void
ShapeScale::GLRender(SoGLRenderAction * action)
{
  SoState * state = action->getState();

...and here's the rest of that GLRender() snippet, bestie โ€” watch it go from "is the scale part even there" to "boom, world-space math":

         SoScale * scale = (SoScale*) this->getAnyPart(SbName("scale"), TRUE);
         if (!this->active.getValue()) {
           update_scale(scale, SbVec3f(1.0f, 1.0f, 1.0f));
         }
         else {
           const SbViewportRegion & vp = SoViewportRegionElement::get(state);
           const SbViewVolume & vv = SoViewVolumeElement::get(state);
           SbVec3f center(0.0f, 0.0f, 0.0f);
           float nsize = this->projectedSize.getValue() / float(vp.getViewportSizePixels()[1]);
           SoModelMatrixElement::get(state).multVecMatrix(center, center); // transform to WCS
           float scalefactor = vv.getWorldToScreenScale(center, nsize);
           update_scale(scale, SbVec3f(scalefactor, scalefactor, scalefactor));
         }
         inherited::GLRender(action);
       }

And a whole entire working example of how you'd actually use this node kit in the wild โ€” copy it, love it, run it:

       // Copyright (C) 1998-2007 by Systems in Motion. All rights reserved.

       #include <Inventor/Qt/SoQt.h>
       #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
       #include <Inventor/SoInput.h>
       #include <Inventor/SoOutput.h>
       #include <Inventor/SoPickedPoint.h>
       #include <Inventor/actions/SoRayPickAction.h>
       #include <Inventor/events/SoMouseButtonEvent.h>
       #include <Inventor/nodes/SoBaseColor.h>
       #include <Inventor/nodes/SoCube.h>
       #include <Inventor/nodes/SoEventCallback.h>
       #include <Inventor/nodes/SoSeparator.h>
       #include <Inventor/nodes/SoSwitch.h>
       #include <Inventor/nodes/SoTranslation.h>
       #include <assert.h>
       #include <stdlib.h>
       #include <time.h>

       #include "ShapeScale.h"

       // Returns random value between 0.0f and 1.0f.
       static float
       normalized_rand(void)
       {
         return float(rand())/float(RAND_MAX);
       }

       static SoSeparator *
       construct_new_marker(const SbVec3f & v)
       {
         SoSeparator * markerroot = new SoSeparator;

         SoTranslation * t = new SoTranslation;
         t->translation = v;
         markerroot->addChild(t);

         ShapeScale * kit = new ShapeScale;
         kit->active = TRUE;
         kit->projectedSize = 5.0f;

         // create the marker
         SoSeparator * markersep = new SoSeparator;

         SoBaseColor * mat = new SoBaseColor;
         mat->rgb.setValue(normalized_rand(), normalized_rand(), normalized_rand());
         markersep->addChild(mat);

         // marker shape should be unit size, with center in (0.0f, 0.0f, 0.0f)
         SoCube * cube = new SoCube;
         cube->width = 1.0f;
         cube->height = 1.0f;
         cube->depth = 1.0f;

         markersep->addChild(cube);
         kit->setPart("shape", markersep);
         markerroot->addChild(kit);

         return markerroot;
       }

       static void
       event_cb(void * ud, SoEventCallback * n)
       {
         const SoMouseButtonEvent * mbe = (SoMouseButtonEvent *)n->getEvent();

         if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 &&
           mbe->getState() == SoButtonEvent::DOWN) {

           SoQtExaminerViewer * viewer = (SoQtExaminerViewer *)ud;

           SoRayPickAction rp(viewer->getViewportRegion());
           rp.setPoint(mbe->getPosition());
           rp.apply(viewer->getSceneManager()->getSceneGraph());

           SoPickedPoint * point = rp.getPickedPoint();
           if (point == NULL) {
             (void)fprintf(stderr, "\n** miss! **\n\n");
             return;
           }

           n->setHandled();

           const SoPath * p = rp.getCurPath();

           for (int i = 0; i < p->getLength(); i++) {
             SoNode * n = p->getNodeFromTail(i);
             if (n->isOfType(SoGroup::getClassTypeId())) {
               SoGroup * g = (SoGroup *)n;
               g->addChild(construct_new_marker(point->getPoint()));
               break;
             }
           }
         }
       }

       void
       show_instructions(void)
       {
         (void)fprintf(stdout,
           "\nThis example program demonstrates the use of the ShapeScale nodekit.\n"
           "\nQuick instructions:\n\n"
           "  * place the marker by clicking on a shape with the left mouse button\n"
           "  * hit ESC to toggle back and forth to view mode\n"
           "  * zoom back and forth to see how the markers stay the same size\n\n");
       }

       int
       main(int argc, char ** argv)
       {
         if (argc != 2) {
           (void) fprintf(stderr,"\nSpecify an Inventor file as argument.\n");
           return -1;
         }

         QWidget * window = SoQt::init(argv[0]);
         ShapeScale::initClass(); // init our extension nodekit

         SoQtExaminerViewer * ex1 = new SoQtExaminerViewer(window);

         SoInput input;
         SbBool ok = input.openFile(argv[1]);
         if (!ok) {
           (void) fprintf(stderr, "Unable to open file: %s\n", argv[1]);
           return -1;
         }

         SoSeparator * root = SoDB::readAll(&input);

         if (root == NULL) {
           (void) fprintf(stderr, "Unable to read file: %s\n", argv[1]);
           return -1;
         }

         show_instructions();

         SoSeparator * newroot = new SoSeparator;
         newroot->ref();

         newroot->addChild(root);

         // create event callback and marker nodes
         SoSeparator * sep = new SoSeparator;
         newroot->addChild(sep);

         SoEventCallback * ecb = new SoEventCallback;
         ecb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), event_cb, ex1);
         sep->addChild(ecb);

         ex1->setSceneGraph(newroot);
         ex1->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
         ex1->setViewing(FALSE);

         ex1->show();
         SoQt::show(window);

         SoQt::mainLoop();
         delete ex1;

         newroot->unref();
         return 0;
       }

๐ŸŽ€ Constructor & Destructor Documentation ๐ŸŽ€

SoBaseKit::SoBaseKit (void )

Constructor, bestie. ๐Ÿ’…

This is the top-level superclass of all node kit and dragger classes. Its catalog structure looks like this:

CLASS SoBaseKit
-->"this"
-->   "callbackList"

(Peep SoBaseKit::printDiagram() if you wanna know how that output formatting actually works.)

And the detailed tea on the catalog parts:

CLASS SoBaseKit
PVT   "this",  SoBaseKit  ---
      "callbackList",  SoNodeKitListPart [ SoCallback, SoEventCallback ]

(Again, SoBaseKit::printTable() has the formatting lore.)

So like โ€” as you can literally see from the catalog, every single node kit can have a callback node sitting in front of all the other nodes in the kit. That's the move for catching events that should be routed to application processing. Handy fr fr. ๐Ÿซถ

References SoType::badType(), children, connectionsSetUp, and SoBaseKit().

Referenced by copyContents(), countMyFields(), createPathToAnyPart(), forceChildDrivenWriteRefs(), getAnyPart(), getClassNodekitCatalog(), getContainerNode(), getPartString(), printSubDiagram(), set(), set(), setAnyPart(), SoInteractionKit::setAnyPartAsDefault(), SoInteractionKit::setAnySurrogatePath(), and SoBaseKit().

SoBaseKit::~SoBaseKit () โ€” [protected], [virtual]

Destructor. Gotta clean up after yourself, queen. โœจ

References children.


๐Ÿ’– Member Function Documentation ๐Ÿ’–

SoType SoBaseKit::getTypeId (void ) const โ€” [virtual]

Returns the type identification of an object derived from a class inheriting SoBase. This is the whole mechanism behind run-time type checking and "downward" casting, no cap.

Usage example, because seeing it hits different:

void foo(SoNode * node)
{
  if (node->getTypeId() == SoFile::getClassTypeId()) {
    SoFile * filenode = (SoFile *)node;  // safe downward cast, knows the type
  }
  else if (node->getTypeId().isOfType(SoGroup::getClassTypeId())) {
    SoGroup * group = (SoGroup *)node;  // safe downward cast, knows the type
  }
}

Now for the app devs out there who wanna extend the library with new nodes, engines, nodekits, draggers or whatever: this method needs to be overridden in all subclasses. That's typically done as part of setting up the full type system for your extension classes, and usually you get there by using the pre-defined macros available through, like, Inventor/nodes/SoSubNode.h (that's SO_NODE_INIT_CLASS and SO_NODE_CONSTRUCTOR for node classes), Inventor/engines/SoSubEngine.h (for engine classes), and so on.

For more on writing Coin extensions, go read the class documentation of the toplevel superclasses for the various class groups. iykyk ๐Ÿ’œ

Implements SoBase.

Reimplemented in SoAppearanceKit, SoCameraKit, SoCenterballDragger, SoDirectionalLightDragger, SoDragger, SoDragPointDragger, SoHandleBoxDragger, SoInteractionKit, SoJackDragger, SoLightKit, SoPointLightDragger, SoRotateCylindricalDragger, SoRotateDiscDragger, SoRotateSphericalDragger, SoScale1Dragger, SoScale2Dragger, SoScale2UniformDragger, SoScaleUniformDragger, SoSceneKit, SoSeparatorKit, SoShapeKit, SoSpotLightDragger, SoTabBoxDragger, SoTabPlaneDragger, SoTrackballDragger, SoTransformBoxDragger, SoTransformerDragger, SoTranslate1Dragger, SoTranslate2Dragger, and SoWrapperKit.

Referenced by addToCopyDict(), printDiagram(), printSubDiagram(), and printTable().

const SoFieldData * SoBaseKit::getFieldData (void ) const โ€” [protected], [virtual]

Hands you a pointer to the class-wide field data storage object for this instance. And if there are literally no fields present? Returns NULL. That's it, that's the whole vibe. ๐ŸŒธ

Reimplemented from SoFieldContainer.

Reimplemented in SoAppearanceKit, SoCameraKit, SoCenterballDragger, SoDirectionalLightDragger, SoDragger, SoDragPointDragger, SoHandleBoxDragger, SoInteractionKit, SoJackDragger, SoLightKit, SoPointLightDragger, SoRotateCylindricalDragger, SoRotateDiscDragger, SoRotateSphericalDragger, SoScale1Dragger, SoScale2Dragger, SoScale2UniformDragger, SoScaleUniformDragger, SoSceneKit, SoSeparatorKit, SoShapeKit, SoSpotLightDragger, SoTabBoxDragger, SoTabPlaneDragger, SoTrackballDragger, SoTransformBoxDragger, SoTransformerDragger, SoTranslate1Dragger, SoTranslate2Dragger, and SoWrapperKit.

const SoNodekitCatalog * SoBaseKit::getClassNodekitCatalog (void ) โ€” [static]

Returns the nodekit catalog that defines the layout of this class' kit. The blueprint, basically. ๐Ÿฆ‹

References SoBaseKit().

const SoNodekitCatalog * SoBaseKit::getNodekitCatalog (void ) const โ€” [virtual]

Returns the nodekit catalog which defines the layout of this class' kit. (Yes, same description as the static one above โ€” that's on purpose, they're siblings.)

Reimplemented in SoAppearanceKit, SoCameraKit, SoCenterballDragger, SoDirectionalLightDragger, SoDragger, SoDragPointDragger, SoHandleBoxDragger, SoInteractionKit, SoJackDragger, SoLightKit, SoPointLightDragger, SoRotateCylindricalDragger, SoRotateDiscDragger, SoRotateSphericalDragger, SoScale1Dragger, SoScale2Dragger, SoScale2UniformDragger, SoScaleUniformDragger, SoSceneKit, SoSeparatorKit, SoShapeKit, SoSpotLightDragger, SoTabBoxDragger, SoTabPlaneDragger, SoTrackballDragger, SoTransformBoxDragger, SoTransformerDragger, SoTranslate1Dragger, SoTranslate2Dragger, and SoWrapperKit.

Referenced by countMyFields(), createDefaultParts(), createFieldList(), createPathToAnyPart(), forceChildDrivenWriteRefs(), getAnyPart(), getPartString(), printSubDiagram(), printTable(), readInstance(), SoNodekitCatalog::recursiveSearch(), setAnyPart(), SoInteractionKit::setAnySurrogatePath(), setDefaultOnNonWritingFields(), and setPart().

SoNode * SoBaseKit::getPart (const SbName & partname, SbBool makeifneeded) โ€” [virtual]

Returns a pointer to the node part with partname.

โญ More coming in the next part, bestie โ€” we are not done yet.

okay so this one calls SoBaseKit::getAnyPart() with leafcheck and publiccheck both set to TRUE.

Want the full tea on how to actually use partname and makeifneeded, and what's gonna come back at you from this call? Go read the SoBaseKit::getAnyPart() docs, bestie, it's all laid out there. ๐Ÿ’–

References: getAnyPart(). Referenced by: SoDirectionalLightManip::fieldSensorCB(), SoPointLightManip::fieldSensorCB(), SoSpotLightManip::fieldSensorCB(), SoCenterballDragger::getBoundingBox(), SoCenterballDragger::getMatrix(), SoCenterballDragger::kidFinishCB(), SoCenterballDragger::kidStartCB(), SoClipPlaneManip::replaceNode(), SoDirectionalLightManip::replaceNode(), SoPointLightManip::replaceNode(), SoSpotLightManip::replaceNode(), SoTransformManip::replaceNode(), SoCenterballManip::SoCenterballManip(), SoHandleBoxManip::SoHandleBoxManip(), SoJackManip::SoJackManip(), SoTabBoxManip::SoTabBoxManip(), SoTrackballManip::SoTrackballManip(), SoTransformBoxManip::SoTransformBoxManip(), and SoTransformerManip::SoTransformerManip().

โœจ SbString SoBaseKit::getPartString(const SoBase * part) โœจ

Hands you back the full path name to a catalog part, based on that part's current item pointer. It's giving "GPS coordinates for one specific node in your kit" ๐Ÿ—บ๏ธ๐Ÿ’…

References: SbString::addIntString(), SoNodeKitListPart::findChild(), SoPath::findNode(), SoFullPath::getLength(), SoNodekitCatalog::getName(), SoPath::getNode(), getNodekitCatalog(), SbName::getString(), SoFullPath::getTail(), SoNodekitCatalog::isLeaf(), SoBase::isOfType(), SoDebugError::postWarning(), SoBase::SoBase(), SoBaseKit(), and SoNode::SoNode(). Referenced by: SoClipPlaneManip::replaceNode(), SoDirectionalLightManip::replaceNode(), SoPointLightManip::replaceNode(), SoSpotLightManip::replaceNode(), and SoTransformManip::replaceNode().

โœจ SoNodeKitPath * SoBaseKit::createPathToPart(const SbName & partname, SbBool makeifneeded, const SoPath * pathtoextend = NULL) โœจ

[virtual] โ€” she's virtual, she's iconic, she's doing the most. ๐ŸŒˆ

This just calls SoBaseKit::createPathToAnyPart() with leafcheck set to FALSE and publiccheck set to FALSE (and all the other arguments passed straight through as given to this function).

For the actual documentation, go look at SoBaseKit::createPathToAnyPart(). ๐Ÿ‘‘

References: createPathToAnyPart().

โœจ SbBool SoBaseKit::setPart(const SbName & partname, SoNode * from) โœจ

[virtual] โ€” yes bestie, another virtual one.

Sets the catalog part named by partname to the node pointer from. Swap in, swap out, slay. ๐Ÿ’…

Reimplemented in SoInteractionKit.

References: setAnyPart(), and SoNode::SoNode(). Referenced by: readInstance(), SoClipPlaneManip::replaceNode(), SoDirectionalLightManip::replaceNode(), SoPointLightManip::replaceNode(), SoSpotLightManip::replaceNode(), SoTransformManip::replaceNode(), setAnyPart(), SoInteractionKit::setAnyPartAsDefault(), SoInteractionKit::setAnySurrogatePath(), SoInteractionKit::setPart(), and SoInteractionKit::setPart().

โœจ SbBool SoBaseKit::set(const char * namevaluepairliststring) โœจ

Sets nodekit part field values, and the input string you hand her has to be formatted like this:

partname {
  fieldname fieldval
  fieldname fieldval
  [...]
}
partname {
  fieldname fieldval
  fieldname fieldval
  [...]
}
[...]

(Whitespace layout? Ignored, periodt. That's just how it always goes with Inventor format input strings. ๐Ÿ™ˆ)

Here's a whole example, changing several values of the camera part of an SoCameraKit instance:

kit->set("camera { heightAngle 0.3927  nearDistance 1.1  farDistance 999.9 }");
References: SoNodeKitListPart::getChild(), SoFieldContainer::getFieldData(), SoInput::getNumBytesRead(), SoNodeKitListPart::getNumChildren(), SbString::getString(), SoDebugError::postWarning(), SoFieldData::read(), SoInput::setBuffer(), SoBaseKit(), and SoNode::SoNode().

โœจ SbBool SoBaseKit::set(const char * partnamestring, const char * parameterstring) โœจ

This one is literally just an overload of the other SoBaseKit::set() method. The whole point? It gives you a way to set a part value while using separate input arguments for the name of the part and for the name of the field (a.k.a. parameter) settings. Two strings, one glow-up. โœจ

References: SoNodeKitListPart::getChild(), SoFieldContainer::getFieldData(), SoNodeKitListPart::getNumChildren(), SbString::getString(), SoBase::isOfType(), SoDebugError::postWarning(), SoFieldData::read(), SoInput::setBuffer(), SoBaseKit(), and SoNode::SoNode().

โœจ void SoBaseKit::doAction(SoAction * action) โœจ

[virtual] โ€” this function performs the typical operation of a node for any action. The all-rounder. The main character who can do every role. ๐ŸŽญ

Reimplemented from SoNode.

References: children, and SoAction::getPathCode(). Referenced by: callback(), getPrimitiveCount(), GLRender(), handleEvent(), rayPick(), and search().

โœจ void SoBaseKit::callback(SoCallbackAction * action) โœจ

[virtual] โ€” the action method for SoCallbackAction.

She simply updates the state according to how the node behaves for the render action, so that you, the application programmer, can use SoCallbackAction to extract information about the scene graph. Intel, bestie. ๐Ÿ”

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: doAction(). Referenced by: SoDragger::callback().

โœจ void SoBaseKit::GLRender(SoGLRenderAction * action) โœจ

[virtual] โ€” the action method for SoGLRenderAction.

This gets called during rendering traversals. Any node that influences the rendering state in any way, or that just wants to throw geometry primitives at OpenGL, overrides this method. No cap. ๐Ÿ”ฅ

Reimplemented from SoNode.

Reimplemented in SoDragger, and SoTabPlaneDragger.

References: doAction(). Referenced by: SoDragger::GLRender().

โœจ void SoBaseKit::getBoundingBox(SoGetBoundingBoxAction * action) โœจ

[virtual] โ€” the action method for SoGetBoundingBoxAction.

She calculates the bounding box and center coordinates for the node, then modifies the action's values so they encompass this node's bounding box, and shifts the center point for the scene more towards the one for this node. She's centering herself, as she should. ๐Ÿ‘‘

Nodes that influence how geometry nodes calculate their bounding box also override this method to change the relevant state variables.

Reimplemented from SoNode.

Reimplemented in SoCenterballDragger, and SoDragger.

References: children, SoGetBoundingBoxAction::getCenter(), SoAction::getPathCode(), SoGetBoundingBoxAction::isCenterSet(), SoGetBoundingBoxAction::resetCenter(), and SoGetBoundingBoxAction::setCenter(). Referenced by: SoDragger::getBoundingBox().

โœจ void SoBaseKit::getMatrix(SoGetMatrixAction * action) โœจ

[virtual] โ€” the action method for SoGetMatrixAction.

Updates the action by accumulating with the transformation matrix of this node (if it has one, ofc).

Reimplemented from SoNode.

Reimplemented in SoCenterballDragger, and SoDragger.

References: children, and SoAction::getPathCode(). Referenced by: SoDragger::getMatrix().

โœจ void SoBaseKit::handleEvent(SoHandleEventAction * action) โœจ

[virtual] โ€” the action method for SoHandleEventAction.

She inspects the event data from action, and processes it if it's something this node should actually react to. Vibe check, then react. ๐Ÿ’…

Nodes that influence the relevant state variables for how event handling is done also override this method.

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: doAction(). Referenced by: SoDragger::handleEvent().

โœจ void SoBaseKit::rayPick(SoRayPickAction * action) โœจ

[virtual] โ€” the action method for SoRayPickAction.

Checks the ray specification of the action and tests for intersection with the data of the node. Poking it with a laser to see if it pokes back. ๐Ÿ”ฆ

Nodes that influence the relevant state variables for how picking is done also override this method.

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: SoPath::containsNode(), doAction(), SoPickedPoint::getDetail(), SbPList::getLength(), SoPickedPoint::getPath(), and SoRayPickAction::getPickedPointList(). Referenced by: SoDragger::rayPick().

โœจ void SoBaseKit::search(SoSearchAction * action) โœจ

[virtual] โ€” the action method for SoSearchAction.

She compares the search criteria from the action to see if this node is a match. The searching works by matching up all the criteria set up in the SoSearchAction โ€” if even one of the requested criteria is a miss, then the search is just not deemed successful for the node. All or nothing, bestie. ๐Ÿ˜ค

See also: SoSearchAction

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: doAction(), SoSearchAction::isFound(), and SoNode::search(). Referenced by: SoDragger::search().

โœจ void SoBaseKit::write(SoWriteAction * action) โœจ

[virtual] โ€” the action method for SoWriteAction.

Writes out a node object, plus any connected nodes, engines, etc., if that's necessary. Journaling, but make it scene graph. ๐Ÿ“

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: addWriteReference(), children, SoWriteAction::getOutput(), SoOutput::getStage(), SoBase::writeFooter(), and SoBase::writeHeader(). Referenced by: SoDragger::write().

โœจ void SoBaseKit::getPrimitiveCount(SoGetPrimitiveCountAction * action) โœจ

[virtual] โ€” the action method for the SoGetPrimitiveCountAction.

She calculates the number of triangle, line segment and point primitives for the node and adds all of those to the counters of the action. Math, but cute. ๐Ÿ”ข

Nodes that influence how geometry nodes calculate their primitive count also override this method to change the relevant state variables.

Reimplemented from SoNode.

Reimplemented in SoDragger.

References: doAction(). Referenced by: SoDragger::getPrimitiveCount().

โœจ SoChildList * SoBaseKit::getChildren(void) const โœจ

[virtual] โ€” returns the list of children for this node. That's it, that's the function. ๐Ÿซถ

Reimplemented from SoNode.

References: children. Referenced by: copyContents(), and readInstance().

โœจ void SoBaseKit::printDiagram(void) โœจ

Prints out the full nodekit catalog structure. It literally just invokes SoBaseKit::printSubDiagram() on the catalog root. Super useful for debugging. ๐Ÿ›โœจ

Example output:

CLASS SoWrapperKit
-->"this"
      "callbackList"
      "topSeparator"
         "pickStyle"
         "appearance"
         "units"
         "transform"
         "texture2Transform"
         "childList"
-->      "localTransform"
-->      "contents"

Those arrows mean "hey, this entry is new in the catalog for this particular class, versus the superclass." (Except the root entry, obviously โ€” she was always there. ๐Ÿ‘‘)

Want a more detailed catalog dump? Go see SoBaseKit::printTable().

References: SoBase::getName(), getTypeId(), and printSubDiagram().

โœจ void SoBaseKit::printSubDiagram(const SbName & rootname, int level) โœจ

Prints out the nodekit catalog structure starting from rootname and going downwards through the catalog tree, with the indentation starting at level. Tree branch by tree branch, gorgeous. ๐ŸŒณ

See also: printDiagram()

References: SoType::createInstance(), SoNodekitCatalog::getName(), getNodekitCatalog(), SoNodekitCatalog::getNumEntries(), SoType::getParent(), SoNodekitCatalog::getParentName(), SoNodekitCatalog::getPartNumber(), SbName::getString(), SoNodekitCatalog::getType(), getTypeId(), printSubDiagram(), SoBase::ref(), SoBaseKit(), and SoBase::unref(). Referenced by: printDiagram(), and printSubDiagram().

โœจ void SoBaseKit::printTable(void) โœจ

Writes the complete nodekit catalog in table form. Every entry, every column, no crumbs left. ๐Ÿ“‹

Example output:

okay bestie, before we dive into the next batch of methods, here's the catalog output for SoWrapperKit โ€” and it's giving โœจhierarchical realnessโœจ:

CLASS SoWrapperKit
PVT   "this",  SoWrapperKit  ---
      "callbackList",  SoNodeKitListPart [ SoCallback, SoEventCallback ]
PVT   "topSeparator",  SoSeparator  ---
      "pickStyle",  SoPickStyle  ---
      "appearance",  SoAppearanceKit  ---
      "units",  SoUnits  ---
      "transform",  SoTransform  ---
      "texture2Transform",  SoTexture2Transform  ---
      "childList",  SoNodeKitListPart [ SoShapeKit, SoSeparatorKit ]
      "localTransform",  SoTransform  ---
      "contents",  SoSeparator  ---

PVT means it's a private entry in the catalog, then you get the part name and the part type. If the part is a list, the allowed node types for the list are in square brackets, and if not there's a triple hyphen. If the part type is abstract, the default part type will be listed last (not shown in the example output above). ๐Ÿ’…

References: SoNodekitCatalog::getDefaultType(), SbPList::getLength(), SoNodekitCatalog::getListItemTypes(), SoBase::getName(), SoNodekitCatalog::getName(), SoType::getName(), getNodekitCatalog(), SoNodekitCatalog::getNumEntries(), SbName::getString(), SoNodekitCatalog::getType(), getTypeId(), SoNodekitCatalog::isList(), and SoNodekitCatalog::isPublic().


void SoBaseKit::addWriteReference (SoOutput * out, SbBool isfromfield = 0) [virtual]

okay so this one is literally doing the most during the first write pass of a write action โ€” it's counting how many references point to this object in the scene graph. periodt. ๐Ÿ’–

Reimplemented from SoFieldContainer.

References: SoBase::addWriteReference(), countMyFields(), and SoBase::hasMultipleWriteRefs().

Referenced by: countMyFields(), and write().


SbBool SoBaseKit::forceChildDrivenWriteRefs (SoOutput * out)

Returns TRUE if the kit should write โ€” and bestie, that happens if shouldWrite() returns TRUE, or if any of the children (recursively, no cap) should write. it's giving family affair energy ๐Ÿซถ

References: SoBase::addWriteReference(), forceChildDrivenWriteRefs(), getNodekitCatalog(), SoNodekitCatalog::getPartNumber(), SoField::isDefault(), SoBase::isOfType(), SoBase::shouldWrite(), SoBaseKit(), and SoNode::SoNode().

Referenced by: countMyFields(), and forceChildDrivenWriteRefs().


SbBool SoBaseKit::isSearchingChildren (void ) [static]

Returns the value of the flag that says whether or not the kit parts get searched during SoSearchAction traversal. it's a whole vibe check for your scene graph ๐Ÿ”

See also: SoBaseKit::setSearchingChildren()

Referenced by: SoNodeKitPath::append().


void SoBaseKit::setSearchingChildren (const SbBool newval) [static]

Set whether or not the kit parts should be searched during SoSearchAction traversal. The default value is FALSE โ€” so by default, no searching, keep it lowkey. ๐Ÿ™ˆ

Referenced by: SoNodeKitPath::append().


SoNode * SoBaseKit::typeCheck (const SbName & partname, const SoType & parttype, SoNode * node) [static]

This API member is considered internal to the library, as it is not likely to be of interest to the application programmer. so like, not for you bestie, it's giving backstage pass only ๐Ÿ’…

This is a private method in the original SGI Inventor 2.1 API. Consider it obsolete -- it will be removed from Coin v3.0.

References: SoType::getName(), SbName::getString(), SoBase::getTypeId(), SoBase::isOfType(), SoDebugError::postInfo(), and SoNode::SoNode().


const SoNodekitCatalog ** SoBaseKit::getClassNodekitCatalogPtr (void ) [static], [protected]

Returns the pointer to the pointer of the nodekit catalog for this class. yes, a double pointer โ€” it's giving inception but for catalogs ๐ŸŒ€


SoNode * SoBaseKit::addToCopyDict (void ) const [protected], [virtual]

Add a copy of this node and (recursively) all children to the copy dictionary of SoFieldContainer if this has not already been done. it's the "make sure everyone's invited to the copy party" method ๐ŸŽ‰

Used internally during copy operations.

Reimplemented from SoNode.

References: SoFieldContainer::addCopy(), SoNode::addToCopyDict(), SoFieldContainer::checkCopy(), SoType::createInstance(), getTypeId(), SoBase::ref(), SoNode::SoNode(), and SoBase::unrefNoDelete().


void SoBaseKit::copyContents (const SoFieldContainer * from, SbBool copyconnections) [protected], [virtual]

Makes a deep copy of all data of from into this instance, except external scenegraph references if copyconnections is FALSE. it's giving "copy everything but the connections" energy ๐Ÿ”ฅ

This is the protected method that should be overridden by extension node / engine / dragger / whatever subclasses which needs to account for internal data that are not handled automatically.

For copying nodes from application code, you should not invoke this function directly, but rather call the SoNode::copy() function:

SoNode * mynewnode = templatenode->copy();

The same also goes for engines.

Make sure that when you override the copyContents() method in your extension class that you also make it call upwards to it's parent superclass in the inheritance hierarchy, as copyContents() in for instance SoNode and SoFieldContainer does important work. It should go something like this:

void
MyCoinExtensionNode::copyContents(const SoFieldContainer * from,
                                  SbBool copyconnections)
{
  // let parent superclasses do their thing (copy fields, copy
  // instance name, etc etc)
  SoNode::copyContents(from, copyconnections);

  // [..then copy internal data..]
}

Reimplemented from SoNode.

Reimplemented in SoInteractionKit, SoRotateCylindricalDragger, and SoRotateSphericalDragger.

References: SbList< Type >::append(), SoNode::copyContents(), getCatalogInstances(), getChildren(), SbList< Type >::getLength(), setUpConnections(), SoBaseKit(), and SoFieldContainer::SoFieldContainer().

Referenced by: SoInteractionKit::copyContents().


SoGroup * SoBaseKit::getContainerNode (const SbName & listname, SbBool makeifneeded = 1) [protected]

Returns a pointer to the group node above an SoNodeKitListPart in the catalog given by listname. it's like finding the parent group chat for a list part ๐Ÿ’ฌ

If the list part (and its container) was not yet constructed, they will be so if makeifneeded is TRUE (otherwise, NULL will be returned). so if you need it, say yes, and it shall be built โœจ

References: SoNodeKitListPart::getContainerNode(), SbName::getString(), SoBase::isOfType(), SoBaseKit(), and SoNode::SoNode().

Referenced by: SoSceneKit::getCameraNumber(), and SoSceneKit::setCameraNumber().


SoNode * SoBaseKit::getAnyPart (const SbName & partname, SbBool makeifneeded, SbBool leafcheck = 0, SbBool publiccheck = 0) [protected], [virtual]

Returns catalog part of the given partname. if the partname part is not in the nodekit's catalog, return NULL โ€” sorry bestie, not found ๐Ÿ’€

If the part is specified in the catalog, but has not yet been made, the function will either construct the part (if makeifneeded is TRUE) or just return NULL (if makeifneeded is FALSE).

If leafcheck is TRUE, a pointer to the part will only be returned if it's a leaf in the catalog (otherwise NULL is returned).

If publiccheck is TRUE, a pointer to the part will only be returned if it's a public catalog part (otherwise NULL is returned).

The partname input argument should be given as a "path" of catalog part names down to the wanted leaf part. The syntax for specifiying partname "paths" is as follows (given in Backus-Naur Form (BNF)):

BNF:

partname = singlename | compoundname
compoundname = singlename | compoundname.singlename
singlename = singlepartname | singlelistelementname
singlelistelementname = singlelistname[idx]

singlepartname is name of a part ("ordinary", nodekit or list) singlelistname is name of a part which is a list idx is an integer value

References: SoNodeKitListPart::getChild(), getNodekitCatalog(), SoNodeKitListPart::getNumChildren(), SbName::getString(), SoNodekitCatalog::isLeaf(), SoBase::isOfType(), SoNodekitCatalog::isPublic(), SoDebugError::postWarning(), SoBaseKit(), and SoNode::SoNode().

Referenced by: SoTransformerDragger::dragStart(), getPart(), SoInteractionKit::readInstance(), SoTrackballDragger::setDefaultOnNonWritingFields(), SoCenterballDragger::setUpConnections(), SoDirectionalLightDragger::setUpConnections(), SoDragPointDragger::setUpConnections(), SoJackDragger::setUpConnections(), SoPointLightDragger::setUpConnections(), SoSpotLightDragger::setUpConnections(), SoTabBoxDragger::setUpConnections(), and SoTransformBoxDragger::setUpConnections().


SoNodeKitPath * SoBaseKit::createPathToAnyPart (const SbName & partname, SbBool makeifneeded, SbBool leafcheck = 0, SbBool publiccheck = 0, const SoPath * pathtoextend = NULL) [protected], [virtual]

Return path with nested SoNodeKit instances down in the catalog hierarchy given by partname. it's giving GPS for your nodekit tree ๐Ÿ—บ๏ธ

If the trailing part has not been made and makeifneeded is TRUE, make an instance of the part type and insert into the catalog, as done in setAnyPart().

If leafcheck is TRUE, ignore non-leaf catalog node entries. If publiccheck is TRUE, ignore private catalog entries.

pathtoextend is a path through the nodekit instance catalog hierarchy, where we should pick up and continue to create the path from where pathtoextend terminates. If pathtoextend is NULL, we simply start at the "this" toplevel node.

Returns NULL on failure, for any of the possible reasons described above (part ends in non-leaf or private catalog entry, part is not syntactically valid or refers to non-existing catalog entries).

References: SoPath::append(), SoPath::containsNode(), SoPath::copy(), SbPList::find(), SoNodeKitListPart::getChild(), SoNode::getChildren(), SoNodeKitListPart::getContainerNode(), SoFullPath::getLength(), getNodekitCatalog(), SoNodeKitListPart::getNumChildren(), SbName::getString(), SoFullPath::getTail(), SoNodekitCatalog::isLeaf(), SoNodekitCatalog::isPublic(), SoFullPath::pop(), SoDebugError::postWarning(), SoBase::ref(), SoBaseKit(), SoNode::SoNode(), SoBase::unref(), and SoBase::unrefNoDelete().

Referenced by: createPathToPart(), and SoDragger::getPartToLocalMatrix().


SbBool SoBaseKit::setAnyPart (const SbName & partname, SoNode * from, SbBool anypart = 1) [protected], [virtual]

This API member is considered internal to the library, as it is not likely to be of interest to the application programmer. so like, don't worry about it unless you're deep in the source ๐Ÿ’…

References: SoNodeKitListPart::addChild(), getNodekitCatalog(), SoNodeKitListPart::getNumChildren(), SbName::getString(), SoBase::isOfType(), SoNodekitCatalog::isPublic(), SoDebugError::postWarning(), SoNodeKitListPart::replaceChild(), setPart(), SoBaseKit(), and SoNode::SoNode().

Referenced by: readInstance(), and setPart().


void SoBaseKit::createNodekitPartsList (void ) [protected]

Not part of the Coin API. it's giving legacy energy ๐Ÿ•ฐ๏ธ

It is supposed to create the SoNodekitParts class instance. Since this class can only be used by SoBaseKit (all members are private, with SoBaseKit as friend), we decided to not support this class, and solve the problem of recording which parts are created in an alternative way.


void SoBaseKit::createFieldList (void ) [protected]

Replaces the createNodekitPartsList() method. so it's the glow-up replacement โœจ

...sets up the list of SoSFNode fields with node pointers to the instances in our catalog. ๐Ÿ’– That's the whole vibe of it, bestie.

References: SoFieldContainer::getField(), SoNodekitCatalog::getName(), getNodekitCatalog(), and SoNodekitCatalog::getNumEntries().


void SoBaseKit::createDefaultParts (void ) โ€” [protected], [virtual]

okay so this API member is considered internal to the library, because it is "not likely to be of interest to the application programmer." Translation: not for you, bestie, this is housekeeping the library does on itself. ๐Ÿ™ˆ

References: getNodekitCatalog(), and SoNodekitCatalog::isNullByDefault().


const SoNodekitParts * SoBaseKit::getNodekitPartsList (void ) const โ€” [protected]

ngl this one is a little tragic. ๐Ÿ˜ญ In Open Inventor, this method returns a pointer to a private class. It will always return NULL in Coin. So likeโ€ฆ it exists, it's legal, and it gives you nothing. It's giving ghosting. ๐Ÿ’€

See also: createNodekitPartsList()


const SbList< SoSFNode * > & SoBaseKit::getCatalogInstances (void ) const โ€” [protected]

again with the internal-to-the-library energy โ€” considered internal, not likely to be of interest to the application programmer. She's backstage, not on stage. ๐ŸŽ€

Referenced by copyContents(), SoInteractionKit::setAnyPartAsDefault(), SoInteractionKit::setAnySurrogatePath(), and SoInteractionKit::setDefaultOnNonWritingFields().


void SoBaseKit::catalogError (void ) โ€” [protected]

Obsoleted from the API in Coin. That's it. That's the whole entry. She's retired, we still list her in the yearbook. ๐Ÿซถ


SbBool SoBaseKit::setUpConnections (SbBool onoff, SbBool doitalways = 0) โ€” [protected], [virtual]

This is the one that sets up all internal connections for instances of this class. โœจ

(And yes, it comes with the classic disclaimer: this method will usually not be of interest to the application programmer โ€” unless you want to extend the library with new custom nodekits or dragger classes. If that's you, the SoBaseKit class documentation has the tea. ๐Ÿ“)

Reimplemented in SoCenterballDragger, SoDirectionalLightDragger, SoDragPointDragger, SoHandleBoxDragger, SoInteractionKit, SoJackDragger, SoPointLightDragger, SoRotateCylindricalDragger, SoRotateDiscDragger, SoRotateSphericalDragger, SoScale1Dragger, SoScale2Dragger, SoScale2UniformDragger, SoScaleUniformDragger, SoSeparatorKit, SoSpotLightDragger, SoTabBoxDragger, SoTabPlaneDragger, SoTrackballDragger, SoTransformBoxDragger, SoTransformerDragger, SoTranslate1Dragger, and SoTranslate2Dragger.

References: connectionsSetUp.

Referenced by copyContents(), readInstance(), SoCenterballDragger::setUpConnections(), SoDirectionalLightDragger::setUpConnections(), SoDragPointDragger::setUpConnections(), SoHandleBoxDragger::setUpConnections(), SoInteractionKit::setUpConnections(), SoJackDragger::setUpConnections(), SoPointLightDragger::setUpConnections(), SoRotateCylindricalDragger::setUpConnections(), SoRotateDiscDragger::setUpConnections(), SoRotateSphericalDragger::setUpConnections(), SoScale1Dragger::setUpConnections(), SoScale2Dragger::setUpConnections(), SoScale2UniformDragger::setUpConnections(), SoScaleUniformDragger::setUpConnections(), SoSeparatorKit::setUpConnections(), SoSpotLightDragger::setUpConnections(), SoTabBoxDragger::setUpConnections(), SoTabPlaneDragger::setUpConnections(), SoTrackballDragger::setUpConnections(), SoTransformBoxDragger::setUpConnections(), SoTransformerDragger::setUpConnections(), SoTranslate1Dragger::setUpConnections(), and SoTranslate2Dragger::setUpConnections().


SbBool SoBaseKit::readInstance (SoInput * in, unsigned short flags) โ€” [protected], [virtual]

Mainly for internal use during file import operations, so don't stress if you've never had to call it. It reads a definition of an instance from the input stream in. The input stream state points to the start of a serialized / persistant representation of an instance of this class type. ๐Ÿ“ฅ

TRUE or FALSE comes back, depending on if the instantiation and configuration of the new object of this class type went ok or not. The import process should be robust and handle corrupted input streams by returning FALSE. No crashing out, bestie, that's not the vibe. ๐Ÿ’…

flags is used internally during binary import when reading user extension nodes, group nodes or engines.

Reimplemented from SoNode.

Reimplemented in SoInteractionKit.

References: SbList< Type >::append(), SoNodeList::append(), SoFieldContainer::enableNotify(), getChildren(), SoFieldData::getField(), SoFieldData::getFieldName(), getNodekitCatalog(), SoFieldData::getNumFields(), SoNodekitCatalog::isLeaf(), SoBase::isOfType(), SoGroup::removeAllChildren(), SoBaseList::set(), setAnyPart(), setPart(), setUpConnections(), and SoNode::SoNode().

Referenced by SoInteractionKit::readInstance().


void SoBaseKit::setDefaultOnNonWritingFields (void ) โ€” [protected], [virtual]

heads up bestie: this method is unlikely to be of interest to the application programmer who does not want to extend the library with new custom nodekits or draggers. If you are writing extensions, the SoBaseKit class documentation has the info. ๐Ÿฆ‹

This is a virtual method, and the code in it should call SoField::setDefault() with argument TRUE on part fields that should not be written upon scenegraph export operations.

This is typically done when:

  1. field value is NULL and part is NULL by default
  2. it is a leaf SoGroup or SoSeparator node with no children
  3. it is a leaf listpart with no children and an SoGroup or SoSeparator container
  4. it is a non-leaf part and it's of SoGroup type and all fields are at their default values

Subclasses should usually override this to do additional settings for new member fields. And from the subclass, do remember to call "upwards" to your superclass' setDefaultOnNonWritingFields() method. Don't skip your ancestors, that's rude. ๐Ÿ‘‘

Reimplemented in SoCenterballDragger, SoDirectionalLightDragger, SoDragger, SoDragPointDragger, SoHandleBoxDragger, SoInteractionKit, SoJackDragger, SoPointLightDragger, SoSeparatorKit, SoShapeKit, SoSpotLightDragger, SoTabBoxDragger, SoTabPlaneDragger, SoTrackballDragger, SoTransformBoxDragger, and SoTransformerDragger.

References: SoNodeKitListPart::getContainerNode(), getNodekitCatalog(), SoNodeKitListPart::getNumChildren(), SoBase::getTypeId(), SoField::isDefault(), SoNodekitCatalog::isLeaf(), SoNodekitCatalog::isNullByDefault(), SoBase::isOfType(), SoField::setDefault(), and SoNode::SoNode().

Referenced by countMyFields(), SoInteractionKit::setDefaultOnNonWritingFields(), and SoSeparatorKit::setDefaultOnNonWritingFields().


void SoBaseKit::countMyFields (SoOutput * out) โ€” [protected]

Reference count the write connections to nodes in the catalog. That's the whole job description. ๐Ÿงฎโœจ

References: addWriteReference(), countMyFields(), forceChildDrivenWriteRefs(), getNodekitCatalog(), SoNodekitCatalog::getPartNumber(), SoOutput::getStage(), SoField::isDefault(), SoBase::isOfType(), SoField::setDefault(), setDefaultOnNonWritingFields(), SoField::shouldWrite(), SoBaseKit(), SoNode::SoNode(), and SoField::write().

Referenced by addWriteReference(), and countMyFields().


SbBool SoBaseKit::setPart (const int partnum, SoNode * node) โ€” [protected], [virtual]

This one sets parts, updates nodekit scene graph, and makes sure graph is valid with respect to right siblings and parent. It's virtual so subclasses can detect when a part changes value. ๐Ÿ‘€

ngl this method is not part of the original SGI Open Inventor API โ€” it's an extension specific to Coin. ๐Ÿช™

Reimplemented in SoInteractionKit.

References: SoGroup::addChild(), SoChildList::append(), SbPList::find(), SoNode::getChildren(), SoBase::getName(), SoNodekitCatalog::getName(), SoType::getName(), getNodekitCatalog(), SoNodekitCatalog::getParentPartNumber(), SbName::getString(), SoNodekitCatalog::getType(), SoBase::getTypeId(), SoChildList::insert(), SoGroup::insertChild(), SoType::isDerivedFrom(), SoBase::isOfType(), SoDebugError::postWarning(), SoChildList::remove(), SoGroup::removeChild(), SoGroup::replaceChild(), SoChildList::set(), and SoNode::SoNode().


โœจ Member Data Documentation โœจ

SoChildList* SoBaseKit::children โ€” [protected]

This API member is considered internal to the library, as it is not likely to be of interest to the application programmer. ๐ŸŽ€

Referenced by doAction(), getBoundingBox(), getChildren(), getMatrix(), SoBaseKit(), write(), and ~SoBaseKit().

SbBool SoBaseKit::connectionsSetUp โ€” [protected]

Same deal, bestie โ€” internal to the library, not likely to be of interest to the application programmer. She's a flag and she's thriving. ๐Ÿ’–

Referenced by setUpConnections(), SoCenterballDragger::setUpConnections(), SoDirectionalLightDragger::setUpConnections(), SoDragPointDragger::setUpConnections(), SoHandleBoxDragger::setUpConnections(), SoInteractionKit::setUpConnections(), SoJackDragger::setUpConnections(), SoPointLightDragger::setUpConnections(), SoRotateCylindricalDragger::setUpConnections(), SoRotateDiscDragger::setUpConnections(), SoRotateSphericalDragger::setUpConnections(), SoScale1Dragger::setUpConnections(), SoScale2Dragger::setUpConnections(), SoScale2UniformDragger::setUpConnections(), SoScaleUniformDragger::setUpConnections(), SoSeparatorKit::setUpConnections(), SoSpotLightDragger::setUpConnections(), SoTabBoxDragger::setUpConnections(), SoTabPlaneDragger::setUpConnections(), SoTrackballDragger::setUpConnections(), SoTransformBoxDragger::setUpConnections(), SoTransformerDragger::setUpConnections(), SoTranslate1Dragger::setUpConnections(), SoTranslate2Dragger::setUpConnections(), and SoBaseKit().


๐ŸŒˆ Author ๐ŸŒˆ

Generated automatically by Doxygen for Coin from the source code. ๐Ÿค– (so if you've got beef with the wording, take it up with the robot, not me ๐Ÿ’…)


aaaand that's a wrap on SoBaseKit(3), bestie!! ๐ŸŽ‰๐Ÿ‘‘ This whole page came from Coin, and it's tagged as Version 2.5.0, dated SoBaseKit(3) โ€” so go forth, kit your nodes, and slay. periodt. ๐Ÿ’–โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from