Open Inventor Release 2024.1.1
 
Loading...
Searching...
No Matches
SoBaseKit.h
1/*=======================================================================
2 * Copyright 1991-1996, Silicon Graphics, Inc.
3 * ALL RIGHTS RESERVED
4 *
5 * UNPUBLISHED -- Rights reserved under the copyright laws of the United
6 * States. Use of a copyright notice is precautionary only and does not
7 * imply publication or disclosure.
8 *
9 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
10 * Use, duplication or disclosure by the Government is subject to restrictions
11 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
12 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
13 * in similar or successor clauses in the FAR, or the DOD or NASA FAR
14 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
15 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
16 *
17 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
18 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
19 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
20 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
21 * GRAPHICS, INC.
22**=======================================================================*/
23/*=======================================================================
24** Author : Paul Isaacs (MMM yyyy)
25** Modified by : Thad Beier (MMM yyyy)
26**=======================================================================*/
27/*=======================================================================
28 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
29 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
30 *** ***
31 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
32 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
33 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
34 *** ***
35 *** RESTRICTED RIGHTS LEGEND ***
36 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
37 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
38 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
39 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
40 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
41 *** ***
42 *** COPYRIGHT (C) 1996-2020 BY FEI S.A.S, ***
43 *** BORDEAUX, FRANCE ***
44 *** ALL RIGHTS RESERVED ***
45**=======================================================================*/
46/*=======================================================================
47** Modified by : VSG (MMM YYYY)
48**=======================================================================*/
49
50
51#ifndef _SO_BASE_KIT_
52#define _SO_BASE_KIT_
53
54#include <Inventor/misc/SoChildList.h>
55#include <Inventor/fields/SoFieldData.h>
56#include <Inventor/nodes/SoNode.h>
57#include <Inventor/fields/SoSFName.h>
58#include <Inventor/fields/SoSFBool.h>
59#include <Inventor/nodes/SoNode.h>
60#include <Inventor/nodekits/SoNodekitParts.h>
61#include <Inventor/nodekits/SoSubKit.h>
62#include <Inventor/SoNodeKitPath.h>
63#include <Inventor/SbViewportRegion.h>
64
65class SoSeparator;
66class SbBox3f;
67class SbDict;
68class SoGroup;
69
71// Class: SoBaseKit --
72//
73// This is the base class for all node kits.
74//
75// NOTE TO DEVELOPERS:
76// For info about the structure of SoBaseKit:
77// [1] compile: /usr/share/src/Inventor/samples/ivNodeKitStructure
78// [2] type: ivNodeKitStructure SoBaseKit.
79// [3] The program prints a diagram of the scene graph and a table with
80// information about each part.
81//
82// It contains only 'this' and a callbackList beneath it.
83// It's catalog is made to describe the following structure:
84//
85// this
86// |
87// "callbackList"
88//
90
302class SoBaseKit : public SoNode, public SoGetView {
303
304 // Instead of calling SO_KIT_HEADER(className) here,
305 // which is the norm for all nodekits, explicitly write the contents
306 // of that macro, so as to expose the base class virtual function
307 // getNodekitCatalog for the C-api...
308 //
309 SO_NODE_HEADER(SoBaseKit);
310
311public:
316
317 private:
318 /* design of this class */
319 static SoNodekitCatalog *nodekitCatalog;
320 /* parent design */
321 static const SoNodekitCatalog **parentNodekitCatalogPtr;
322
323 public:
328
335 /* Returns an SoNodekitCatalog for the node */
336 virtual const SoNodekitCatalog *getNodekitCatalog() const;
337 // ...end of contents of SO_KIT_HEADER
338
339 private:
340 static const SoNodekitCatalog **getClassNodekitCatalogPtr();
341
342 // Define fields for the new parts of the kit...
343 SO_KIT_CATALOG_ENTRY_HEADER(callbackList);
344
345 public:
346
351
392 virtual SoNode *getPart( const SbName &partName, SbBool makeIfNeeded );
393
413 template<typename PartType>
414 PartType* getPart( const SbName& partName )
415 {
416 SoNode* part = getPart( partName, TRUE );
417 #if defined(_DEBUG)
418 part = typeCheck<PartType>( partName, part );
419 #endif
420 return static_cast<PartType*>(part);
421 }
422
442 template<typename PartType>
443 PartType* checkPart( const SbName& partName )
444 {
445 SoNode* part = getPart( partName, FALSE );
446 #if defined(_DEBUG)
447 part = typeCheck<PartType>( partName, part );
448 #endif
449 return static_cast<PartType*>(part);
450 }
451
458
459
470 virtual SoNodeKitPath *createPathToPart( const SbName &partName,
471 SbBool makeIfNeeded, const SoPath *pathToExtend = NULL );
472
496 virtual SbBool setPart( const SbName &partName, SoNode *newPart );
497
515 SoNONUNICODE SbBool set(char *nameValuePairListString);
516
532 SbBool set( const SbString& nameValuePairListString);
533
552 SoNONUNICODE SbBool set(const char *partNameString, const char *parameterString);
553
570 SbBool set( const SbString& partNameString, const SbString& parameterString);
571
576 static void setSearchingChildren( SbBool newVal );
577
582 static SbBool isSearchingChildren() { return searchingChildren; }
583
584 private:
585
592 inline virtual SbBool isBoundingBoxIgnoring() const
593 { return boundingBoxIgnoring.getValue(); }
594
595 virtual void doAction( SoAction *action );
596 // These functions implement all actions for nodekits.
597 virtual void callback( SoCallbackAction *action );
598 virtual void GLRender( SoGLRenderAction *action );
599 virtual void getBoundingBox( SoGetBoundingBoxAction *action );
600 virtual void getMatrix(SoGetMatrixAction *action );
601 virtual void handleEvent( SoHandleEventAction *action );
602 virtual void rayPick( SoRayPickAction *action );
603 virtual void search( SoSearchAction *action );
604 virtual void write( SoWriteAction *action );
605 virtual void getPrimitiveCount (SoGetPrimitiveCountAction *action);
606
607 private:
608 static void initClass();
609 static void exitClass();
610
611 // Convenient method to remove warning (conversion from const char* to char*)
612 // in set("...", "...");
613 // So set(const char*, const char*) replaces set(char*, char*) and
614 // set(char*, char*) becomes deprecated/internal
615 SbBool set(char *partNameString, char *parameterString)
616 { return set((const char*)partNameString, (const char*)parameterString); };
617
618 // Returns pointer to children
619 virtual SoChildList *getChildren() const;
620
621 static SoNode *typeCheck( const SbName &partName, const SoType &partType,
622 SoNode *node );
623
625 template<typename PartType>
626 static SoNode* typeCheck( const SbName& partName, SoNode* node )
627 {
628 return typeCheck( partName, PartType::getClassTypeId(), node );
629 }
630
631 void printDiagram();
632 void printSubDiagram( const SbName &rootName, int level );
633 void printTable();
634
635 // Overrides the default method to use countMyFields() instead of
636 // the regular SoFieldData writing mechanism.
637 virtual void addWriteReference(SoOutput *out,
638 SbBool isFromField = FALSE);
639
641 friend class SoNodekitParts;
642 friend class SoV1BaseKit;
643
644 // This returns TRUE if the nodekit intends to write out.
645 // [a] call shouldWrite(). If TRUE, trivial return.
646 // [b] If the kit thinks it shouldn't write, it first does a recursive
647 // call to its children. If any children must write, then so must
648 // the kit.
649 // [c] If kit has changed its mind because of [b], then add a writeRef.
650 //
651 // [d] If kit should not write, it will delete the fieldDataForWriting,
652 // since there will no writing pass applied to take care of this.
653 SbBool forceChildDrivenWriteRefs( SoOutput *out );
654
655 // enable/disable callbacks.
656 static void enableNotification(SbBool);
657 static SbBool isEnabledNotification();
658
659 virtual SbBool setAnyPart( const SbName &partName, SoNode *from, SbBool anyPart = TRUE );
660
661 SoNode *internalGetAnyPart( const SbName &partName, SbBool makeIfNeeded,
662 SbBool leafCheck = FALSE, SbBool publicCheck = FALSE );
663
664 // Internal child management following inheritance of classes.
665 virtual void internalRemoveChild( int index ) { removeChild(index); }
666 virtual void internalRemoveChild( SoNode *child ) { removeChild(findChild(child)); }
667 virtual void internalRemoveAllChildren() { removeAllChildren(); }
668 virtual void internalAddChild( SoNode *child ) { addChild(child); }
669 virtual int internalFindChild( const SoNode *child ) const { return findChild(child); }
670 virtual void internalInsertChild( SoNode *child, int newChildIndex ) { insertChild(child, newChildIndex); }
671 virtual SoNode *internalGetChild( int index) const { return getChild(index); }
672 virtual void internalReplaceChild( int index, SoNode *newChild) { replaceChild(index, newChild); }
673 virtual void internalReplaceChild( SoNode *oldChild, SoNode *newChild) { replaceChild(oldChild,newChild); }
674
675 // Redefines this to add this node and all part nodes to the dictionary
676 virtual SoNode * addToCopyDict() const;
677
678 // Copies the contents of the given nodekit into this instance
679 virtual void copyContents(const SoFieldContainer *fromFC,
680 SbBool copyConnections);
681
682 private:
683
684 SoChildList *children;
685
686 // Returns the containerNode within the SoNodeKitListPart given
687 // by listName.
688 SoGroup *getContainerNode( const SbName &listName,
689 SbBool makeIfNeeded = TRUE );
690
695 virtual SoNode *getAnyPart( const SbName &partName, SbBool makeIfNeeded,
696 SbBool leafCheck = FALSE, SbBool publicCheck = FALSE );
697
717 template<typename PartType>
718 PartType* getAnyPart( const SbName& partName )
719 {
720 SoNode* part = getAnyPart( partName, TRUE, FALSE, FALSE );
721 #if defined(_DEBUG)
722 part = typeCheck<PartType>( partName, part );
723 #endif
724 return static_cast<PartType*>(part);
725 }
726
746 template<typename PartType>
747 PartType* checkAnyPart( const SbName& partName )
748 {
749 SoNode* part = getAnyPart( partName, FALSE, FALSE, FALSE );
750 #if defined(_DEBUG)
751 part = typeCheck<PartType>( partName, part );
752 #endif
753 return static_cast<PartType*>(part);
754 }
755
756 virtual SoNodeKitPath *createPathToAnyPart(const SbName &partName,
757 SbBool makeIfNeeded,
758 SbBool leafCheck = FALSE, SbBool publicCheck = FALSE,
759 const SoPath *pathToExtend = NULL );
760
761 // parts list.
762 SoNodekitParts *nodekitPartsList;
763
764 // called during construction to create parts list
765 void createNodekitPartsList();
766 // called during construction to create any parts that are created by
767 // default (such as the cube in the SoCubeKit)
768 virtual void createDefaultParts();
769
770 // Return the node's partsList
771 const SoNodekitParts *getNodekitPartsList() const
772 { return nodekitPartsList; };
773
774 // Prints an Error when there's trouble building a catalog.
775 void catalogError();
776
777 // detach/attach any sensors, callbacks, and/or field connections.
778 // Called by: start/end of SoBaseKit::readInstance
779 // and on new copy by: start/end of SoBaseKit::copyContents.
780 // Classes that redefine must call setUpConnections(TRUE,TRUE)
781 // at the end of constructor to add their own connections to the ones already
782 // connected by the base classes.
783 // The doItAlways flag can force the method to do the work.
784 // But if (doItAlways == FALSE && onOff == connectionsSetUp), then
785 // the method will return immediately without doing anything.
786 // Returns the state of the node when this was called.
787 virtual SbBool setUpConnections( SbBool onOff, SbBool doItAlways = FALSE );
788 SbBool connectionsSetUp;
789
790 // Reads in from file. Takes care of setting parts and stuff.
791 virtual SbBool readInstance(SoInput *in, unsigned short flags);
792
793 // This is called during countMyFields() method. It calls setDefault()
794 // on those fields we do not wish to write out. setDefault does not change
795 // the field value, but it sets a flag indicating that the field should
796 // not get written by this node.
797 // Fields that we do not write are [a] parts that are NULL and are defined
798 // in the catalog to be NULL by default. [b] non-leaf parts for which
799 // isNodeFieldValuesImportant() is FALSE.
800 // [c] leaf parts that are empty groups, empty separators,
801 // [d] leaf parts that are empty lists (but they must have group or
802 // separator container nodes.
803 virtual void setDefaultOnNonWritingFields();
804
805 // This is called during addWriteReference() to write the fields.
806 // It sometimes treats fields for parts of the nodekit in a special way.
807 // Under normal circumstances, they write like other fields.
808 // The special case is when a part-field has a non-NULL value, but has
809 // also been set to default, indicating that we would rather not write it.
810 // If the part is a regular node, we give it a field-connection style
811 // write ref. So it only writes if some other instances of the node forces
812 // a write.
813 // If the part is a nodekit, then we additionally write ref the fields of
814 // the nodekit, using this same method.
815 // Later, in the WRITE stage, the kit-part will be written if at least
816 // one of its fields or ancestor parts has shouldWrite() ==TRUE.
817 // This way, if a nodekit part or any of its ancestors has non-NULL fields,
818 // it will later be forced to write, even though it has been set to default.
819 // Example:
820 // Parent draggers attempt not to write out child draggers.
821 // But the parentDragger must at least traverse the childDragger to see
822 // if any of the part geometry has been changed from its default. Such
823 // changes must be written to file.
824 void countMyFields(SoOutput *out);
825
826 virtual ~SoBaseKit();
827
828 static SbBool m_enableBaseKitNotification;
829
830private:
831
832 // end basekit writing.
833 void endWrite( SoOutput* out );
834
835private:
836 void skipWhiteSpace(char *&string);
837
838 // Returns FALSE if every field has either [a] hasDefaultValue() == TRUE or
839 // [b] isDefault() == TRUE
840 SbBool isNodeFieldValuesImportant( SoNode *n );
841
842 // This creates a copy of fieldData with a few changes that make
843 // it write out 'prettier'
844 void createFieldDataForWriting();
845
846 // Used to store field data during writing. Need this because a temporary
847 // version of fieldData is made that differs from the real thing.
848 SoFieldData *fieldDataForWriting;
849
850 // This list contains pointers to fields whose default
851 // flag has been changed so they won't write out.
852
853 SbPList savedList;
854
855 // Called by the readInstance routine...
856 SbBool readMyFields(SoInput *in, SoFieldData *&unknownFieldData );
857
858 // Called by write() after the (virtual) setDefaultOnNonWritingNodes()
859 // method. This method looks at the part fields which have isDefault()
860 // set to TRUE. This method will setDefault(FALSE) on any part fields
861 // that MUST write.
862 // This happens when the part-field is for a part whose parent
863 // is going to write out anyway. Therefore, it will appear in file as
864 // a node within this kit, so we better write out the part field to
865 // explain where the node belongs in the kit.
866 void undoSetDefaultOnFieldsThatMustWrite();
867
868 // Only nodekits themselves can access the private children.
869 int getNumChildren() const { return (children->getLength()); }
870 void removeChild( int index );
871 void removeChild( SoNode *child ) { removeChild(findChild(child)); }
872 void removeAllChildren();
873 void addChild( SoNode *child );
874 int findChild( const SoNode *child ) const;
875 void insertChild( SoNode *child, int newChildIndex );
876 SoNode *getChild( int index) const { return (*children)[index]; }
877 void replaceChild( int index, SoNode *newChild);
878 void replaceChild( SoNode *oldChild, SoNode *newChild)
879 { replaceChild(findChild(oldChild),newChild); }
880
881 static SbBool searchingChildren;
882};
883
884// Macro for getting at parts without doing type casting yourself:
885// for example, the code:
886// xf = (SoTransform *) myKit->getPart("transform",
887// SoTransform::getClassTypeId(), TRUE);
888// becomes:
889// xf = SO_GET_PART( myKit, "transform", SoTransform );
890//
891// The macro SO_CHECK_PART will not build the part if it is not already in the
892// kit, since it sends 'FALSE' as the 'makeIfNeeded' argument.
893//
894// CAUTION: These macros will not work in the C-api, and nothing will be
895// gained from making them. So, don't make them.
896
897
898#if defined(_DEBUG)
899#define SO_GET_PART( kitContainingPart, partName, partClassName ) \
900 ((partClassName *) SoBaseKit::typeCheck( partName, \
901 partClassName::getClassTypeId(), \
902 kitContainingPart->getPart( partName, TRUE )))
903
904#define SO_CHECK_PART( kitContainingPart, partName, partClassName ) \
905 ((partClassName *) SoBaseKit::typeCheck( partName, \
906 partClassName::getClassTypeId(), \
907 kitContainingPart->getPart( partName, FALSE )))
908
909#define SO_GET_ANY_PART( kitContainingPart, partName, partClassName ) \
910 ((partClassName *) SoBaseKit::typeCheck( partName, \
911 partClassName::getClassTypeId(), \
912 kitContainingPart->getAnyPart( partName, TRUE, FALSE, FALSE )))
913
914#define SO_CHECK_ANY_PART( kitContainingPart, partName, partClassName ) \
915 ((partClassName *) SoBaseKit::typeCheck( partName, \
916 partClassName::getClassTypeId(), \
917 kitContainingPart->getAnyPart( partName, FALSE, FALSE, FALSE )))
918#else
919
920#define SO_GET_PART( kitContainingPart, partName, partClassName ) \
921 ((partClassName *) kitContainingPart->getPart( partName, TRUE ))
922#define SO_CHECK_PART( kitContainingPart, partName, partClassName ) \
923 ((partClassName *) kitContainingPart->getPart( partName, FALSE ))
924#define SO_GET_ANY_PART( kitContainingPart, partName, partClassName ) \
925 ((partClassName *) kitContainingPart->getAnyPart( partName, TRUE, \
926 FALSE, FALSE ))
927#define SO_CHECK_ANY_PART( kitContainingPart, partName, partClassName ) \
928 ((partClassName *) kitContainingPart->getAnyPart( partName, FALSE, \
929 FALSE, FALSE ))
930#endif
931
932#endif /* _SO_BASE_KIT_ */
933
3D box class.
Definition SbBox.h:649
Character string stored in a hash table.
Definition SbName.h:162
List of generic (void *) pointers.
Definition SbPList.h:77
Class for smart character strings.
Definition SbString.h:202
Abstract base class for all actions.
Definition SoAction.h:132
Base class for all nodes, paths, and engines.
Definition SoBase.h:111
Base class for all node kits.
Definition SoBaseKit.h:302
virtual SoNode * getPart(const SbName &partName, SbBool makeIfNeeded)
Searches the nodekit catalog (and those of all nested nodekits) for the part named partName.
friend class SoNodekitParts
Definition SoBaseKit.h:641
static void setSearchingChildren(SbBool newVal)
Sets if nodekit children are searched during SoSearchAction traversal.
PartType * checkPart(const SbName &partName)
Like getPart(const SbName&,SbBool) but casts the returned part to the specified type and sets the mak...
Definition SoBaseKit.h:443
friend class SoNodekitCatalogEntry
Definition SoBaseKit.h:640
virtual const SoNodekitCatalog * getNodekitCatalog() const
Returns the SoNodekitCatalog for this instance of SoBaseKit.
SoSFBool boundingBoxIgnoring
Whether to ignore this node during bounding box traversal.
Definition SoBaseKit.h:315
friend class SoV1BaseKit
Definition SoBaseKit.h:642
SoNONUNICODE SbBool set(char *nameValuePairListString)
This function allows field values of parts (nodes) to be set in several different parts simultaneousl...
SoBaseKit()
Constructor.
SbBool set(const SbString &nameValuePairListString)
This function allows field values of parts (nodes) to be set in several different parts simultaneousl...
SbBool set(const SbString &partNameString, const SbString &parameterString)
This function allows field values of parts (nodes) to be set.
virtual SbBool setPart(const SbName &partName, SoNode *newPart)
Inserts the given node (not a copy) as the new part specified by partName.
virtual SoNodeKitPath * createPathToPart(const SbName &partName, SbBool makeIfNeeded, const SoPath *pathToExtend=NULL)
Returns a path that begins at this nodekit and ends at partName.
SbString getPartString(const SoBase *part)
Given a node or a path to a node, checks if the part exists in the nodekit, in a nested nodekit,...
PartType * getPart(const SbName &partName)
Like getPart(const SbName&,SbBool) but casts the returned part to the specified type and sets the mak...
Definition SoBaseKit.h:414
static const SoNodekitCatalog * getClassNodekitCatalog()
Returns the SoNodekitCatalog for the class SoBaseKit.
static SbBool isSearchingChildren()
Returns TRUE if nodekit children are searched during SoSearchAction traversal.
Definition SoBaseKit.h:582
SoNONUNICODE SbBool set(const char *partNameString, const char *parameterString)
This function allows field values of parts (nodes) to be set.
Performs a generic traversal of a scene graph or path.
Abstract base class for objects that contain fields.
Renders a scene graph using Open Inventor's Render Engine.
Computes bounding box of a scene.
Computes transformation matrix for a subgraph.
<a href="IconLegend.html"><img src="extTGS.gif" alt="VSG extension" border="0"></a> Counts number of...
Class to access a MeshViz view.
Base class for all group nodes.
Definition SoGroup.h:122
Allows nodes in a graph to receive input events.
Used to read Open Inventor data files.
Definition SoInput.h:363
Abstract base class for all database nodes.
Definition SoNode.h:145
friend class SoChildList
Definition SoNode.h:473
Path that points to a list of hierarchical nodekits.
Nodekit catalog class.
Used to write Open Inventor data files.
Definition SoOutput.h:186
Path that points to a list of hierarchical nodes.
Definition SoPath.h:187
Intersects objects with a ray cast into scene.
Field containing a single Boolean value.
Definition SoSFBool.h:79
SbBool getValue() const
Returns this field's value.
Definition SoSFBool.h:82
Searches for nodes in a scene graph.
Group node that saves and restores traversal state.
Stores runtime type information.
Definition SoType.h:98
Writes a scene graph to a file.
int SbBool
Boolean type.
Definition SbBase.h:87