00001 /*======================================================================= 00002 * Copyright 1991-1996, Silicon Graphics, Inc. 00003 * ALL RIGHTS RESERVED 00004 * 00005 * UNPUBLISHED -- Rights reserved under the copyright laws of the United 00006 * States. Use of a copyright notice is precautionary only and does not 00007 * imply publication or disclosure. 00008 * 00009 * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: 00010 * Use, duplication or disclosure by the Government is subject to restrictions 00011 * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights 00012 * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or 00013 * in similar or successor clauses in the FAR, or the DOD or NASA FAR 00014 * Supplement. Contractor/manufacturer is Silicon Graphics, Inc., 00015 * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. 00016 * 00017 * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY 00018 * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, 00019 * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY 00020 * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON 00021 * GRAPHICS, INC. 00022 **=======================================================================*/ 00023 /*======================================================================= 00024 ** Author : Paul Isaacs (MMM yyyy) 00025 ** Modified by : Paul S. Strauss (MMM yyyy) 00026 **=======================================================================*/ 00027 /*======================================================================= 00028 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), *** 00029 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. *** 00030 *** *** 00031 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS *** 00032 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR *** 00033 *** WRITTEN AUTHORIZATION OF FEI S.A.S. *** 00034 *** *** 00035 *** RESTRICTED RIGHTS LEGEND *** 00036 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS *** 00037 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN *** 00038 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT *** 00039 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN *** 00040 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. *** 00041 *** *** 00042 *** COPYRIGHT (C) 1996-2020 BY FEI S.A.S, *** 00043 *** BORDEAUX, FRANCE *** 00044 *** ALL RIGHTS RESERVED *** 00045 **=======================================================================*/ 00046 /*======================================================================= 00047 ** Modified by : VSG (MMM YYYY) 00048 **=======================================================================*/ 00049 00050 00051 // There is a cycle of include files between SoBaseKit.h and SoSubKit.h 00052 // SoBaseKit.h must be included before _SO_SUB_KIT_ is defined. Otherwise, 00053 // SoBaseKit.h will not compile. 00054 #include <Inventor/nodekits/SoBaseKit.h> 00055 00056 #ifndef _SO_SUB_KIT_ 00057 #define _SO_SUB_KIT_ 00058 00059 00060 #include <Inventor/nodes/SoNode.h> 00061 #include <Inventor/fields/SoSFNode.h> 00062 #include <Inventor/nodekits/SoNodekitCatalog.h> 00063 #include <Inventor/nodekits/SoNodeKitListPart.h> 00064 00066 // 00067 // Macros to be called within the class definition header for a SoBaseKit 00068 // subclass: 00069 // 00070 00072 // 00073 // This defines a catalog describing the arrangement 00074 // of the subgraph for instances of this class 00075 // 00076 00077 #define SO__KIT_CATALOG_HEADER(className) \ 00078 private: \ 00079 /* design of this class */ \ 00080 static SoNodekitCatalog *nodekitCatalog; \ 00081 /* parent design */ \ 00082 static const SoNodekitCatalog **parentNodekitCatalogPtr; \ 00083 public: \ 00084 \ 00085 static const SoNodekitCatalog *getClassNodekitCatalog(); \ 00086 \ 00087 virtual const SoNodekitCatalog *getNodekitCatalog() const; \ 00088 private: \ 00089 static const SoNodekitCatalog **getClassNodekitCatalogPtr() 00090 00091 #define SO_KIT_HEADER(className) \ 00092 SO_NODE_HEADER(className); \ 00093 SO__KIT_CATALOG_HEADER(className) 00094 00095 #define SO_KIT_ABSTRACT_HEADER(className) \ 00096 SO_NODE_ABSTRACT_HEADER(className); \ 00097 SO__KIT_CATALOG_HEADER(className) 00098 00099 00101 // 00102 // This defines an SoSFNode field for the catalog part given. 00103 // The field will always be a (protected) node-pointer field. 00104 // It will keep track of which (hidden) child is which part. 00105 // 00106 00107 #define SO_KIT_CATALOG_ENTRY_HEADER(partName) \ 00108 private: \ 00109 SoSFNode partName 00110 00111 00113 // 00114 // Macros to be called within the source file for a node subclass: 00115 // 00116 00118 // 00119 // This declares the static variables defined in SO__KIT_CATALOG_HEADER. 00120 // 00121 00122 #define SO__KIT_CATALOG_VARS(className) \ 00123 SoNodekitCatalog *className::nodekitCatalog = NULL; \ 00124 const SoNodekitCatalog **className::parentNodekitCatalogPtr = NULL 00125 00127 // 00128 // This implements the methods defined in SO__KIT_CATALOG_HEADER. 00129 // 00130 00131 #define SO__KIT_CATALOG_METHODS(className) \ 00132 const SoNodekitCatalog * \ 00133 className::getNodekitCatalog() const \ 00134 { \ 00135 return nodekitCatalog; \ 00136 } \ 00137 \ 00138 const SoNodekitCatalog * \ 00139 className::getClassNodekitCatalog() \ 00140 { \ 00141 return nodekitCatalog; \ 00142 } \ 00143 \ 00144 const SoNodekitCatalog ** \ 00145 className::getClassNodekitCatalogPtr() \ 00146 { \ 00147 return (const SoNodekitCatalog **)&nodekitCatalog; \ 00148 } 00149 00150 00152 // 00153 // These include all the definitions required 00154 // at file scope 00155 // 00156 00157 #define SO_KIT_SOURCE(className) \ 00158 SO_NODE_SOURCE(className) \ 00159 SO__KIT_CATALOG_VARS(className); \ 00160 SO__KIT_CATALOG_METHODS(className) 00161 00162 #define SO_KIT_ABSTRACT_SOURCE(className) \ 00163 SO_NODE_ABSTRACT_SOURCE(className); \ 00164 SO__KIT_CATALOG_VARS(className); \ 00165 SO__KIT_CATALOG_METHODS(className) 00166 00168 // 00169 // Internal initialization macros 00170 // 00171 #define SO__KIT_INIT_CLASS(className,classPrintName,parentClass) \ 00172 SO__NODE_INIT_CLASS(className,classPrintName,parentClass); \ 00173 parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr() 00174 00175 #define SO__KIT_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) \ 00176 SO__NODE_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass); \ 00177 parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr() 00178 00179 #define SO__KIT_EXIT_CLASS(className) \ 00180 SO__NODE_EXIT_CLASS(className); \ 00181 delete nodekitCatalog; nodekitCatalog = NULL; 00182 00184 // 00185 // This calls SO_NODE_INIT_CLASS to initialize the type 00186 // identifier variables defined in SO_KIT_HEADER. 00187 // It should be called from within initClass(). 00188 // The parentClass argument should be the class that this 00189 // subclass is derived from. 00190 // The parentNodekitCatalogPtr is also initialized here. 00191 // 00192 00193 #define SO_KIT_INIT_CLASS(className,parentClass,parentPrintClass) \ 00194 SO_NODE_INIT_CLASS(className,parentClass,parentPrintClass); \ 00195 parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr() 00196 00197 #define SO_KIT_INIT_ABSTRACT_CLASS(className,parentClass,parentPrintClass) \ 00198 SO_NODE_INIT_ABSTRACT_CLASS(className,parentClass,parentPrintClass); \ 00199 parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr() 00200 00202 // 00203 // This is an internal macro. 00204 // It initializes the SoNodekitCatalog structure defined in 00205 // SO__KIT_CATALOG_HEADER. This macro is automatically called as 00206 // part of SO_KIT_CONSTRUCTOR 00207 // 00208 // This and other macros rely on static member variable "firstInstance" 00209 // from SoSubNode.h 00210 // 00211 00212 #define SO__KIT_INHERIT_CATALOG(className) \ 00213 /* get a copy of the catalog from the base class */ \ 00214 if (firstInstance) \ 00215 { \ 00216 if (parentNodekitCatalogPtr == NULL) /* only true in SoBaseKit */ \ 00217 nodekitCatalog = new SoNodekitCatalog; \ 00218 else \ 00219 nodekitCatalog = (*parentNodekitCatalogPtr)->clone(SoType::fromName(SO__QUOTE(className))); \ 00220 } 00221 00223 // 00224 // These are here to complete the set of subclassing macros for nodekits. 00225 // They are just stubs to call the SO_NODE equivalents, really. 00226 00227 #define SO_KIT_CONSTRUCTOR(className) \ 00228 SO_NODE_CONSTRUCTOR(className); \ 00229 SO__KIT_INHERIT_CATALOG(className) 00230 00231 #define SO_KIT_IS_FIRST_INSTANCE() \ 00232 SO_NODE_IS_FIRST_INSTANCE() 00233 00234 #define SO_KIT_ADD_FIELD(fieldName,defValue) \ 00235 SO_NODE_ADD_FIELD(fieldName,defValue) 00236 00237 #define SO_KIT_DEFINE_ENUM_VALUE(enumType,enumValue) \ 00238 SO_NODE_DEFINE_ENUM_VALUE(enumType,enumValue) 00239 00240 #define SO_KIT_SET_MF_ENUM_TYPE(fieldName, enumType) \ 00241 SO_NODE_SET_MF_ENUM_TYPE(fieldName, enumType) 00242 00243 #define SO_KIT_SET_SF_ENUM_TYPE(fieldName, enumType) \ 00244 SO_NODE_SET_SF_ENUM_TYPE(fieldName, enumType) 00245 00247 // 00248 // This adds the info for a single new part to the SoNodekitCatalog. 00249 // The parameters are as follows: 00250 // 00251 // partName: the name used to refer to this part in nodekitCatalog 00252 // NOTE: do not make an entry for 'this'. 00253 // 'this' is implicitly the top of the tree when 00254 // building the catalog. 00255 // partClassName: the class of node to which this part belongs. 00256 // 00257 // nullByDefault: If TRUE, the part is not created during the constructor. 00258 // (which is the usual case.) 00259 // If FALSE, then it will be automatically created by the 00260 // constructor during the call to the 00261 // macro SO_KIT_INIT_INSTANCE() 00262 // 00263 // parentName: the partName of the parent of this part within 00264 // the nodekitCatalog 00265 // NOTE: if this node is to be a direct descendant of 00266 // 'this', then parentName should be given as "this" 00267 // 00268 // rightName: the partName of the right sibling of this part 00269 // within the nodekitCatalog. 00270 // NOTE: if this part is to be the rightmost child, then 00271 // the rightName should be given as "" (the empty string). 00272 // 00273 // isPublicPart: can a user receive a pointer to this part through 00274 // getPart? If a part is not a leaf, this property is 00275 // irrelevant (non-leaf parts are always private ). But if 00276 // it is a leaf, the user's access can be stopped through 00277 // this field. 00278 // 00279 // For example, 00280 // 00281 // SO_KIT_ADD_CATALOG_ENTRY(material,SoMaterial,TRUE,this,, TRUE); 00282 // 00283 // adds to the catalog a part named 'material.' This part will be an 00284 // SoMaterial node that is NOT created by default. It will be a direct 00285 // child of the nodekit part 'this.' It will be installed as the 00286 // rightmost child below 'this'. 00287 // Since it is public, a user will be able to receive a pointer to this 00288 // part by calling getPart(). 00289 // 00290 // Another example: 00291 // if we are making a catalog for a class SoBirdKit, and we have already 00292 // created the class SoWingKit, then the following macros: 00293 // SO_KIT_ADD_CATALOG_ENTRY(mainSep,SoSeparator,TRUE,this,, FALSE); 00294 // SO_KIT_ADD_CATALOG_ENTRY(rightW,SoWingKit,TRUE,mainSep,, TRUE); 00295 // SO_KIT_ADD_CATALOG_ENTRY(leftW,SoWingKit,TRUE,mainSep,rightWing, TRUE); 00296 // describe a catalog with this structure: 00297 // 00298 // this 00299 // | 00300 // mainSep 00301 // | 00302 // ------------- 00303 // | | 00304 // leftW rightW 00305 00306 #define SO_KIT_ADD_CATALOG_ENTRY(partName, partClassName, nullByDefault, parentName, rightName, isPublicPart) \ 00307 SO_KIT_ADD_FIELD(partName,(NULL)); \ 00308 if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \ 00309 SoType::fromName(SO__QUOTE(partClassName)), \ 00310 SoType::fromName(SO__QUOTE(partClassName)), nullByDefault,\ 00311 SO__QUOTE(parentName), \ 00312 SO__QUOTE(rightName), FALSE, SoType::badType(), \ 00313 SoType::badType(), isPublicPart )) \ 00314 catalogError() 00315 00316 00318 // 00319 // This adds the info for a new part to the SoNodekitCatalog. 00320 // 'partName' may be of an abstract node type. 00321 // 00322 // The parameters are as follows: 00323 // 00324 // partName: same as SO_KIT_ADD_CATALOG_ENTRY 00325 // partClassName: same as SO_KIT_ADD_CATALOG_ENTRY, except that 00326 // abstract node classes are acceptable. 00327 // 00328 // defaultPartClassName: If the nodekit is asked to construct this part, 00329 // using getPart, then the 'defaultPartClassName' will 00330 // specify what type of node to build. 00331 // This may NOT be an abstract class. 00332 // This MUST be a subclass of 'partClassName' 00333 // 00334 // nullByDefault: same as SO_KIT_ADD_CATALOG_ENTRY 00335 // parentName: same as SO_KIT_ADD_CATALOG_ENTRY 00336 // rightName: same as SO_KIT_ADD_CATALOG_ENTRY 00337 // isPublicPart: same as SO_KIT_ADD_CATALOG_ENTRY 00338 // 00339 // For example, 00340 // 00341 // SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(light,SoLight, SoDirectionalLight, 00342 // TRUE, this,, TRUE); 00343 // 00344 // makes a part node refered to as "light". 00345 // When calling setPart, any node that is a subclass of light can be 00346 // used (e.g., SoDirectionalLight, SoSpotLight, SoPointLight ) 00347 // However, if the user asks for the node and it has not been created yet, 00348 // (this happens, for example, in the case where there is currently 00349 // no 'light' and the user calls 00350 // SO_GET_PART( myKit, "light", SoLight ), 00351 // then an SoDirectionalLight will be created and returned. 00352 // 00353 00354 #define SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(partName, partClassName, \ 00355 defaultPartClassName, nullByDefault, parentName, \ 00356 rightName, isPublicPart ) \ 00357 SO_KIT_ADD_FIELD(partName,(NULL)); \ 00358 if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \ 00359 SoType::fromName(SO__QUOTE(partClassName)), \ 00360 SoType::fromName(SO__QUOTE(defaultPartClassName)), nullByDefault,\ 00361 SO__QUOTE(parentName), SO__QUOTE(rightName), FALSE, \ 00362 SoType::badType(), SoType::badType(), isPublicPart )) \ 00363 catalogError() 00364 00366 // 00367 // This adds the info for a new part to the SoNodekitCatalog. 00368 // 'partName' refers to a part that is a LIST. 00369 // 00370 // Any list in a nodekit will automatically be a node of type SoNodeKitListPart. 00371 // These nodes act like subclasses of group but enforce type checking when 00372 // you add children to them. 00373 // 00374 // The parameters you specify will determine 00375 // [a] what kind of group node holds the children (SoGroup, SoSeparator, 00376 // SoSwitch, etc). 00377 // [b] what single class of node will be allowable as children in the list. 00378 // 00379 // Subsequent calls to SO_KIT_ADD_LIST_ITEM_TYPE allow you to add other classes 00380 // of nodes that will be allowable children for the list. 00381 // 00382 // The parameters are as follows: 00383 // 00384 // partName: Same as in SO_KIT_ADD_CATALOG_ENTRY 00385 // listContainerClassName: 00386 // What class will be used to hold the children in the list? 00387 // NOTE: since this is going to have children, it MUST 00388 // be a subclass of SoGroup, such as SoSeparator 00389 // or SoSwitch. 00390 // nullByDefault:same as SO_KIT_ADD_CATALOG_ENTRY 00391 // parentName: Same as in SO_KIT_ADD_CATALOG_ENTRY 00392 // rightName: Same as in SO_KIT_ADD_CATALOG_ENTRY 00393 // 00394 // listItemClassName: The name of the class of node that may appear in 00395 // the list. Any node class is legal here. 00396 // isPublicPart: Same as in SO_KIT_ADD_CATALOG_ENTRY 00397 // 00398 // For example, 00399 // 00400 // SO_KIT_ADD_CATALOG_LIST_ENTRY(subCubes,SoSeparator,TRUE,this,,SoCube, TRUE ); 00401 // 00402 // makes a list that may contain only SoCubes. An SoSeparator will be used to 00403 // contain this list of cubes. 00404 00405 #define SO_KIT_ADD_CATALOG_LIST_ENTRY(partName, listContainerClassName,nullByDefault, parentName, rightName, listItemClassName, isPublicPart ) \ 00406 SO_KIT_ADD_FIELD(partName,(NULL)); \ 00407 if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \ 00408 SoNodeKitListPart::getClassTypeId(), \ 00409 SoNodeKitListPart::getClassTypeId(), nullByDefault, \ 00410 SO__QUOTE(parentName), SO__QUOTE(rightName), TRUE, \ 00411 SoType::fromName(SO__QUOTE(listContainerClassName)), \ 00412 SoType::fromName(SO__QUOTE(listItemClassName)), isPublicPart)) \ 00413 catalogError() 00414 00416 // 00417 // Assuming that the part 'partName' was already put in the nodekit catalog, 00418 // using the macro SO_KIT_ADD_CATALOG_LIST_ENTRY(...) 00419 // this macro will add 'newListItemClassName' to its listItemTypes. 00420 // 00421 // This means that nodes of type 'newListItemClassName' will be permitted 00422 // in the list, as well as any other parts that are already permitted. 00423 // 00424 // Example: 00425 // The macro: 00426 // SO_KIT_ADD_CATALOG_LIST_ENTRY(myList, SoSeparator, TRUE, 00427 // myListParent, , SoCube, TRUE ) 00428 // creates a list called "myList" that accepts cubes. 00429 // calling: 00430 // myKit->addChild( "myList", myCube ); 00431 // will work just fine, but: 00432 // myKit->addChild( "myList", mySphere ); 00433 // will produce an error. 00434 // If, however, a subsequent call is made to: 00435 // SO_KIT_ADD_LIST_ITEM_TYPE( myList, SoSphere ); 00436 // then both calls to addChild will be acceptable 00437 // 00438 // partName: Name of the part to add the listItemType to 00439 // newListItemClassName: Name of the class to add to partName's listItemTypes 00440 00441 #define SO_KIT_ADD_LIST_ITEM_TYPE(partName, newListItemClassName ) \ 00442 if (firstInstance) nodekitCatalog->addListItemType(SO__QUOTE(partName), \ 00443 SoType::fromName(SO__QUOTE(newListItemClassName)) ) 00444 00446 // 00447 // This changes the class of a part in the nodekit catalog. 00448 // Both the newPartClassname and the newDefaultPartClassName must be given. 00449 // 00450 // Used when creating catalogs for subclasses of other nodekits. 00451 // 00452 // The parameters are as follows: 00453 // 00454 // partName: Same as SO_KIT_ADD_CATALOG_ENTRY 00455 // 00456 // newPartClassName: The name of the new node class describing this part. 00457 // 00458 // newDefaultPartClassName: 00459 // The new defaultPartClassName. If asked to build a 00460 // new node for this part, a node of type 00461 // newDefaultPartClassName will be built. 00462 // For example, 00463 // 00464 // The part "shape" is entered in the nodekit catalog as a part for 00465 // the SoShapeKit using the following macro call in the constructor: 00466 // 00467 // SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(shape, SoShape, SoCube, FALSE, 00468 // shapeSeparator, , TRUE ); 00469 // 00470 // If we created a subclass of SoShape, SoVertexShapeKit, 00471 // then the following command might be used in the SoVertexShapeKit constructor: 00472 // 00473 // SO_KIT_CHANGE_ENTRY_TYPE( shape, SoVertexShape, SoFaceSet ); 00474 // 00475 // This would allow any subclass of SoVertexShape to be inserted as the part 00476 // "shape." If the SoVertexShapeKit were asked to build the part "shape", it 00477 // would create it as an SoFaceSet, the default (and non-abstract) type. 00478 // 00479 // Continuing further, the class SoFaceSetKit, subclassed from SoVertexShapeKit, 00480 // might contain this command in its constructor: 00481 // 00482 // SO_KIT_CHANGE_ENTRY_TYPE(shape,SoFaceSet, SoFaceSet ); 00483 // 00484 // This class would allow one and only one type of node for "shape", 00485 // and that is the type SoFaceSet. 00486 00487 #define SO_KIT_CHANGE_ENTRY_TYPE(partName, newPartClassName, \ 00488 newDefaultPartClassName) \ 00489 if (firstInstance) nodekitCatalog->narrowTypes(SO__QUOTE(partName), \ 00490 SoType::fromName(SO__QUOTE(newPartClassName)), \ 00491 SoType::fromName(SO__QUOTE(newDefaultPartClassName))) 00492 00494 // 00495 // This changes whether or not a part is NULL by default. 00496 // If TRUE, the part is NULL by default. 00497 // If FALSE, the part is always created during the constructor for the 00498 // nodekit that uses this catalog. In this case, construction occurs 00499 // during the call to SO_KIT_INIT_INSTANCE(). 00500 // 00501 #define SO_KIT_CHANGE_NULL_BY_DEFAULT(partName, newNullByDefault) \ 00502 if (firstInstance) nodekitCatalog->setNullByDefault(SO__QUOTE(partName), \ 00503 newNullByDefault) 00504 00506 // 00507 // This must be called within the constructor of every class of nodekit. 00508 // It should be called immediately after the catalog is defined. 00509 // 00510 // It does 2 things: 00511 // [1] created the nodekitPartsList, which keeps track of which parts 00512 // have been created. 00513 // [2] creates all parts that must be created by default (such as the 00514 // cube in SoCubeKit) as specified by the nullByDefault parameter 00515 // in the nodekit catalog 00516 // 00517 #define SO_KIT_INIT_INSTANCE() \ 00518 createNodekitPartsList(); \ 00519 createDefaultParts() 00520 00521 00522 #endif /* _SO_SUB_KIT_ */ 00523 00524 00525