Open Inventor
Release 2024.2.1
Loading...
Searching...
No Matches
SoSubKit.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 : Paul S. Strauss (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-2014 BY FEI S.A.S, ***
43
*** BORDEAUX, FRANCE ***
44
*** ALL RIGHTS RESERVED ***
45
**=======================================================================*/
46
/*=======================================================================
47
** Modified by : VSG (MMM YYYY)
48
**=======================================================================*/
49
50
51
// There is a cycle of include files between SoBaseKit.h and SoSubKit.h
52
// SoBaseKit.h must be included before _SO_SUB_KIT_ is defined. Otherwise,
53
// SoBaseKit.h will not compile.
54
#include <Inventor/nodekits/SoBaseKit.h>
55
56
#ifndef _SO_SUB_KIT_
57
#define _SO_SUB_KIT_
58
59
60
#include <Inventor/nodes/SoNode.h>
61
#include <Inventor/fields/SoSFNode.h>
62
#include <Inventor/nodekits/SoNodekitCatalog.h>
63
#include <Inventor/nodekits/SoNodeKitListPart.h>
64
66
//
67
// Macros to be called within the class definition header for a SoBaseKit
68
// subclass:
69
//
70
72
//
73
// This defines a catalog describing the arrangement
74
// of the subgraph for instances of this class
75
//
76
77
#define SO__KIT_CATALOG_HEADER(className) \
78
private: \
79
/* design of this class */
\
80
static SoNodekitCatalog *nodekitCatalog; \
81
/* parent design */
\
82
static const SoNodekitCatalog **parentNodekitCatalogPtr; \
83
public: \
84
\
85
static const SoNodekitCatalog *getClassNodekitCatalog(); \
86
\
87
virtual const SoNodekitCatalog *getNodekitCatalog() const; \
88
private: \
89
static const SoNodekitCatalog **getClassNodekitCatalogPtr()
90
91
#define SO_KIT_HEADER(className) \
92
SO_NODE_HEADER(className); \
93
SO__KIT_CATALOG_HEADER(className)
94
95
#define SO_KIT_ABSTRACT_HEADER(className) \
96
SO_NODE_ABSTRACT_HEADER(className); \
97
SO__KIT_CATALOG_HEADER(className)
98
99
101
//
102
// This defines an SoSFNode field for the catalog part given.
103
// The field will always be a (protected) node-pointer field.
104
// It will keep track of which (hidden) child is which part.
105
//
106
107
#define SO_KIT_CATALOG_ENTRY_HEADER(partName) \
108
private: \
109
SoSFNode partName
110
111
113
//
114
// Macros to be called within the source file for a node subclass:
115
//
116
118
//
119
// This declares the static variables defined in SO__KIT_CATALOG_HEADER.
120
//
121
122
#define SO__KIT_CATALOG_VARS(className) \
123
SoNodekitCatalog *className::nodekitCatalog = NULL; \
124
const SoNodekitCatalog **className::parentNodekitCatalogPtr = NULL
125
127
//
128
// This implements the methods defined in SO__KIT_CATALOG_HEADER.
129
//
130
131
#define SO__KIT_CATALOG_METHODS(className) \
132
const SoNodekitCatalog * \
133
className::getNodekitCatalog() const \
134
{ \
135
return nodekitCatalog; \
136
} \
137
\
138
const SoNodekitCatalog * \
139
className::getClassNodekitCatalog() \
140
{ \
141
return nodekitCatalog; \
142
} \
143
\
144
const SoNodekitCatalog ** \
145
className::getClassNodekitCatalogPtr() \
146
{ \
147
return (const SoNodekitCatalog **)&nodekitCatalog; \
148
}
149
150
152
//
153
// These include all the definitions required
154
// at file scope
155
//
156
157
#define SO_KIT_SOURCE(className) \
158
SO_NODE_SOURCE(className) \
159
SO__KIT_CATALOG_VARS(className); \
160
SO__KIT_CATALOG_METHODS(className)
161
162
#define SO_KIT_ABSTRACT_SOURCE(className) \
163
SO_NODE_ABSTRACT_SOURCE(className); \
164
SO__KIT_CATALOG_VARS(className); \
165
SO__KIT_CATALOG_METHODS(className)
166
168
//
169
// Internal initialization macros
170
//
171
#define SO__KIT_INIT_CLASS(className,classPrintName,parentClass) \
172
SO__NODE_INIT_CLASS(className,classPrintName,parentClass); \
173
parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr()
174
175
#define SO__KIT_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass) \
176
SO__NODE_INIT_ABSTRACT_CLASS(className,classPrintName,parentClass); \
177
parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr()
178
179
#define SO__KIT_EXIT_CLASS(className) \
180
SO__NODE_EXIT_CLASS(className); \
181
delete nodekitCatalog; nodekitCatalog = NULL;
182
184
//
185
// This calls SO_NODE_INIT_CLASS to initialize the type
186
// identifier variables defined in SO_KIT_HEADER.
187
// It should be called from within initClass().
188
// The parentClass argument should be the class that this
189
// subclass is derived from.
190
// The parentNodekitCatalogPtr is also initialized here.
191
//
192
193
#define SO_KIT_INIT_CLASS(className,parentClass,parentPrintClass) \
194
SO_NODE_INIT_CLASS(className,parentClass,parentPrintClass); \
195
parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr()
196
197
#define SO_KIT_INIT_ABSTRACT_CLASS(className,parentClass,parentPrintClass) \
198
SO_NODE_INIT_ABSTRACT_CLASS(className,parentClass,parentPrintClass); \
199
parentNodekitCatalogPtr = parentClass::getClassNodekitCatalogPtr()
200
202
//
203
// This is an internal macro.
204
// It initializes the SoNodekitCatalog structure defined in
205
// SO__KIT_CATALOG_HEADER. This macro is automatically called as
206
// part of SO_KIT_CONSTRUCTOR
207
//
208
// This and other macros rely on static member variable "firstInstance"
209
// from SoSubNode.h
210
//
211
212
#define SO__KIT_INHERIT_CATALOG(className) \
213
/* get a copy of the catalog from the base class */
\
214
if (firstInstance) \
215
{ \
216
if (parentNodekitCatalogPtr == NULL)
/* only true in SoBaseKit */
\
217
nodekitCatalog = new SoNodekitCatalog; \
218
else \
219
nodekitCatalog = (*parentNodekitCatalogPtr)->clone(SoType::fromName(SO__QUOTE(className))); \
220
}
221
223
//
224
// These are here to complete the set of subclassing macros for nodekits.
225
// They are just stubs to call the SO_NODE equivalents, really.
226
227
#define SO_KIT_CONSTRUCTOR(className) \
228
SO_NODE_CONSTRUCTOR(className); \
229
SO__KIT_INHERIT_CATALOG(className)
230
231
#define SO_KIT_IS_FIRST_INSTANCE() \
232
SO_NODE_IS_FIRST_INSTANCE()
233
234
#define SO_KIT_ADD_FIELD(fieldName,defValue) \
235
SO_NODE_ADD_FIELD(fieldName,defValue)
236
237
#define SO_KIT_DEFINE_ENUM_VALUE(enumType,enumValue) \
238
SO_NODE_DEFINE_ENUM_VALUE(enumType,enumValue)
239
240
#define SO_KIT_SET_MF_ENUM_TYPE(fieldName, enumType) \
241
SO_NODE_SET_MF_ENUM_TYPE(fieldName, enumType)
242
243
#define SO_KIT_SET_SF_ENUM_TYPE(fieldName, enumType) \
244
SO_NODE_SET_SF_ENUM_TYPE(fieldName, enumType)
245
247
//
248
// This adds the info for a single new part to the SoNodekitCatalog.
249
// The parameters are as follows:
250
//
251
// partName: the name used to refer to this part in nodekitCatalog
252
// NOTE: do not make an entry for 'this'.
253
// 'this' is implicitly the top of the tree when
254
// building the catalog.
255
// partClassName: the class of node to which this part belongs.
256
//
257
// nullByDefault: If TRUE, the part is not created during the constructor.
258
// (which is the usual case.)
259
// If FALSE, then it will be automatically created by the
260
// constructor during the call to the
261
// macro SO_KIT_INIT_INSTANCE()
262
//
263
// parentName: the partName of the parent of this part within
264
// the nodekitCatalog
265
// NOTE: if this node is to be a direct descendant of
266
// 'this', then parentName should be given as "this"
267
//
268
// rightName: the partName of the right sibling of this part
269
// within the nodekitCatalog.
270
// NOTE: if this part is to be the rightmost child, then
271
// the rightName should be given as "" (the empty string).
272
//
273
// isPublicPart: can a user receive a pointer to this part through
274
// getPart? If a part is not a leaf, this property is
275
// irrelevant (non-leaf parts are always private ). But if
276
// it is a leaf, the user's access can be stopped through
277
// this field.
278
//
279
// For example,
280
//
281
// SO_KIT_ADD_CATALOG_ENTRY(material,SoMaterial,TRUE,this,, TRUE);
282
//
283
// adds to the catalog a part named 'material.' This part will be an
284
// SoMaterial node that is NOT created by default. It will be a direct
285
// child of the nodekit part 'this.' It will be installed as the
286
// rightmost child below 'this'.
287
// Since it is public, a user will be able to receive a pointer to this
288
// part by calling getPart().
289
//
290
// Another example:
291
// if we are making a catalog for a class SoBirdKit, and we have already
292
// created the class SoWingKit, then the following macros:
293
// SO_KIT_ADD_CATALOG_ENTRY(mainSep,SoSeparator,TRUE,this,, FALSE);
294
// SO_KIT_ADD_CATALOG_ENTRY(rightW,SoWingKit,TRUE,mainSep,, TRUE);
295
// SO_KIT_ADD_CATALOG_ENTRY(leftW,SoWingKit,TRUE,mainSep,rightWing, TRUE);
296
// describe a catalog with this structure:
297
//
298
// this
299
// |
300
// mainSep
301
// |
302
// -------------
303
// | |
304
// leftW rightW
305
306
#define SO_KIT_ADD_CATALOG_ENTRY(partName, partClassName, nullByDefault, parentName, rightName, isPublicPart) \
307
SO_KIT_ADD_FIELD(partName,(NULL)); \
308
if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \
309
SoType::fromName(SO__QUOTE(partClassName)), \
310
SoType::fromName(SO__QUOTE(partClassName)), nullByDefault,\
311
SO__QUOTE(parentName), \
312
SO__QUOTE(rightName), FALSE, SoType::badType(), \
313
SoType::badType(), isPublicPart )) \
314
catalogError()
315
316
318
//
319
// This adds the info for a new part to the SoNodekitCatalog.
320
// 'partName' may be of an abstract node type.
321
//
322
// The parameters are as follows:
323
//
324
// partName: same as SO_KIT_ADD_CATALOG_ENTRY
325
// partClassName: same as SO_KIT_ADD_CATALOG_ENTRY, except that
326
// abstract node classes are acceptable.
327
//
328
// defaultPartClassName: If the nodekit is asked to construct this part,
329
// using getPart, then the 'defaultPartClassName' will
330
// specify what type of node to build.
331
// This may NOT be an abstract class.
332
// This MUST be a subclass of 'partClassName'
333
//
334
// nullByDefault: same as SO_KIT_ADD_CATALOG_ENTRY
335
// parentName: same as SO_KIT_ADD_CATALOG_ENTRY
336
// rightName: same as SO_KIT_ADD_CATALOG_ENTRY
337
// isPublicPart: same as SO_KIT_ADD_CATALOG_ENTRY
338
//
339
// For example,
340
//
341
// SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(light,SoLight, SoDirectionalLight,
342
// TRUE, this,, TRUE);
343
//
344
// makes a part node refered to as "light".
345
// When calling setPart, any node that is a subclass of light can be
346
// used (e.g., SoDirectionalLight, SoSpotLight, SoPointLight )
347
// However, if the user asks for the node and it has not been created yet,
348
// (this happens, for example, in the case where there is currently
349
// no 'light' and the user calls
350
// SO_GET_PART( myKit, "light", SoLight ),
351
// then an SoDirectionalLight will be created and returned.
352
//
353
354
#define SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(partName, partClassName, \
355
defaultPartClassName, nullByDefault, parentName, \
356
rightName, isPublicPart ) \
357
SO_KIT_ADD_FIELD(partName,(NULL)); \
358
if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \
359
SoType::fromName(SO__QUOTE(partClassName)), \
360
SoType::fromName(SO__QUOTE(defaultPartClassName)), nullByDefault,\
361
SO__QUOTE(parentName), SO__QUOTE(rightName), FALSE, \
362
SoType::badType(), SoType::badType(), isPublicPart )) \
363
catalogError()
364
366
//
367
// This adds the info for a new part to the SoNodekitCatalog.
368
// 'partName' refers to a part that is a LIST.
369
//
370
// Any list in a nodekit will automatically be a node of type SoNodeKitListPart.
371
// These nodes act like subclasses of group but enforce type checking when
372
// you add children to them.
373
//
374
// The parameters you specify will determine
375
// [a] what kind of group node holds the children (SoGroup, SoSeparator,
376
// SoSwitch, etc).
377
// [b] what single class of node will be allowable as children in the list.
378
//
379
// Subsequent calls to SO_KIT_ADD_LIST_ITEM_TYPE allow you to add other classes
380
// of nodes that will be allowable children for the list.
381
//
382
// The parameters are as follows:
383
//
384
// partName: Same as in SO_KIT_ADD_CATALOG_ENTRY
385
// listContainerClassName:
386
// What class will be used to hold the children in the list?
387
// NOTE: since this is going to have children, it MUST
388
// be a subclass of SoGroup, such as SoSeparator
389
// or SoSwitch.
390
// nullByDefault:same as SO_KIT_ADD_CATALOG_ENTRY
391
// parentName: Same as in SO_KIT_ADD_CATALOG_ENTRY
392
// rightName: Same as in SO_KIT_ADD_CATALOG_ENTRY
393
//
394
// listItemClassName: The name of the class of node that may appear in
395
// the list. Any node class is legal here.
396
// isPublicPart: Same as in SO_KIT_ADD_CATALOG_ENTRY
397
//
398
// For example,
399
//
400
// SO_KIT_ADD_CATALOG_LIST_ENTRY(subCubes,SoSeparator,TRUE,this,,SoCube, TRUE );
401
//
402
// makes a list that may contain only SoCubes. An SoSeparator will be used to
403
// contain this list of cubes.
404
405
#define SO_KIT_ADD_CATALOG_LIST_ENTRY(partName, listContainerClassName,nullByDefault, parentName, rightName, listItemClassName, isPublicPart ) \
406
SO_KIT_ADD_FIELD(partName,(NULL)); \
407
if (firstInstance && !nodekitCatalog->addEntry(SO__QUOTE(partName), \
408
SoNodeKitListPart::getClassTypeId(), \
409
SoNodeKitListPart::getClassTypeId(), nullByDefault, \
410
SO__QUOTE(parentName), SO__QUOTE(rightName), TRUE, \
411
SoType::fromName(SO__QUOTE(listContainerClassName)), \
412
SoType::fromName(SO__QUOTE(listItemClassName)), isPublicPart)) \
413
catalogError()
414
416
//
417
// Assuming that the part 'partName' was already put in the nodekit catalog,
418
// using the macro SO_KIT_ADD_CATALOG_LIST_ENTRY(...)
419
// this macro will add 'newListItemClassName' to its listItemTypes.
420
//
421
// This means that nodes of type 'newListItemClassName' will be permitted
422
// in the list, as well as any other parts that are already permitted.
423
//
424
// Example:
425
// The macro:
426
// SO_KIT_ADD_CATALOG_LIST_ENTRY(myList, SoSeparator, TRUE,
427
// myListParent, , SoCube, TRUE )
428
// creates a list called "myList" that accepts cubes.
429
// calling:
430
// myKit->addChild( "myList", myCube );
431
// will work just fine, but:
432
// myKit->addChild( "myList", mySphere );
433
// will produce an error.
434
// If, however, a subsequent call is made to:
435
// SO_KIT_ADD_LIST_ITEM_TYPE( myList, SoSphere );
436
// then both calls to addChild will be acceptable
437
//
438
// partName: Name of the part to add the listItemType to
439
// newListItemClassName: Name of the class to add to partName's listItemTypes
440
441
#define SO_KIT_ADD_LIST_ITEM_TYPE(partName, newListItemClassName ) \
442
if (firstInstance) nodekitCatalog->addListItemType(SO__QUOTE(partName), \
443
SoType::fromName(SO__QUOTE(newListItemClassName)) )
444
446
//
447
// This changes the class of a part in the nodekit catalog.
448
// Both the newPartClassname and the newDefaultPartClassName must be given.
449
//
450
// Used when creating catalogs for subclasses of other nodekits.
451
//
452
// The parameters are as follows:
453
//
454
// partName: Same as SO_KIT_ADD_CATALOG_ENTRY
455
//
456
// newPartClassName: The name of the new node class describing this part.
457
//
458
// newDefaultPartClassName:
459
// The new defaultPartClassName. If asked to build a
460
// new node for this part, a node of type
461
// newDefaultPartClassName will be built.
462
// For example,
463
//
464
// The part "shape" is entered in the nodekit catalog as a part for
465
// the SoShapeKit using the following macro call in the constructor:
466
//
467
// SO_KIT_ADD_CATALOG_ABSTRACT_ENTRY(shape, SoShape, SoCube, FALSE,
468
// shapeSeparator, , TRUE );
469
//
470
// If we created a subclass of SoShape, SoVertexShapeKit,
471
// then the following command might be used in the SoVertexShapeKit constructor:
472
//
473
// SO_KIT_CHANGE_ENTRY_TYPE( shape, SoVertexShape, SoFaceSet );
474
//
475
// This would allow any subclass of SoVertexShape to be inserted as the part
476
// "shape." If the SoVertexShapeKit were asked to build the part "shape", it
477
// would create it as an SoFaceSet, the default (and non-abstract) type.
478
//
479
// Continuing further, the class SoFaceSetKit, subclassed from SoVertexShapeKit,
480
// might contain this command in its constructor:
481
//
482
// SO_KIT_CHANGE_ENTRY_TYPE(shape,SoFaceSet, SoFaceSet );
483
//
484
// This class would allow one and only one type of node for "shape",
485
// and that is the type SoFaceSet.
486
487
#define SO_KIT_CHANGE_ENTRY_TYPE(partName, newPartClassName, \
488
newDefaultPartClassName) \
489
if (firstInstance) nodekitCatalog->narrowTypes(SO__QUOTE(partName), \
490
SoType::fromName(SO__QUOTE(newPartClassName)), \
491
SoType::fromName(SO__QUOTE(newDefaultPartClassName)))
492
494
//
495
// This changes whether or not a part is NULL by default.
496
// If TRUE, the part is NULL by default.
497
// If FALSE, the part is always created during the constructor for the
498
// nodekit that uses this catalog. In this case, construction occurs
499
// during the call to SO_KIT_INIT_INSTANCE().
500
//
501
#define SO_KIT_CHANGE_NULL_BY_DEFAULT(partName, newNullByDefault) \
502
if (firstInstance) nodekitCatalog->setNullByDefault(SO__QUOTE(partName), \
503
newNullByDefault)
504
506
//
507
// This must be called within the constructor of every class of nodekit.
508
// It should be called immediately after the catalog is defined.
509
//
510
// It does 2 things:
511
// [1] created the nodekitPartsList, which keeps track of which parts
512
// have been created.
513
// [2] creates all parts that must be created by default (such as the
514
// cube in SoCubeKit) as specified by the nullByDefault parameter
515
// in the nodekit catalog
516
//
517
#define SO_KIT_INIT_INSTANCE() \
518
createNodekitPartsList(); \
519
createDefaultParts()
520
521
522
#endif
/* _SO_SUB_KIT_ */
523
524
Inventor
nodekits
SoSubKit.h
Generated by
1.9.8