Castle Game Engine: X3DNodes: Class TX3DNode

# Class TX3DNode
Description | Hierarchy | Fields | Methods | Properties
## Unit X3DNodes ## Declaration `type TX3DNode = class(TX3DFileItem, IX3DNode)` ## Description X3D node. Every VRML/X3D node class descends from this. ## Hierarchy TPersistent TNonRefCountedInterfacedPersistent TX3DFileItem TX3DNode ## Overview ### Fields
| `VRML1ChildrenAllowed: boolean;`
| `VRML1ChildrenParsingAllowed: boolean;`
### Methods
| `function DeepCopyCore(CopyState: TX3DNodeDeepCopyState): TX3DNode; virtual;`
| `function DeepCopyCreate(CopyState: TX3DNodeDeepCopyState): TX3DNode; virtual;`
| `class function VRML1ChildrenSaveToStream: boolean; virtual;`
| `procedure DirectEnumerateActive( Func: TEnumerateChildrenFunction); virtual;`
| `procedure DirectEnumerateActiveForTraverse( Func: TEnumerateChildrenFunction; StateStack: TX3DGraphTraverseStateStack); virtual;`
| `procedure DirectEnumerateAll( Func: TEnumerateChildrenFunction);`
| `procedure DirectEnumerate( Func: TEnumerateChildrenFunction; OnlyActive: boolean);`
| `procedure BeforeTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
| `procedure MiddleTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
| `procedure AfterTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
| `function ParseNodeBodyElement(Lexer: TX3DLexer; Reader: TX3DReaderNames; const APositionInParent: Integer): boolean; virtual;`
| `procedure ParseAfter(Reader: TX3DReaderNames); virtual;`
| `procedure CreateNode; virtual;`
| `function FieldOrEvent(const Name: string): TX3DFieldOrEvent;`
| `function AnyEvent(const Name: string): TX3DEvent;`
| `function VRML1ChildrenCount: integer;`
| `procedure VRML1ChildAdd(Index: Integer; child: TX3DNode); overload;`
| `procedure VRML1ChildAdd(child: TX3DNode); overload;`
| `procedure VRML1ChildRemove(i: integer);`
| `procedure VRML1ChildrenClear;`
| `function VRML1ChildExtract(I: Integer): TX3DNode;`
| `function VRML1ParentsCount: integer;`
| `function ParentFieldsCount: Integer;`
| `procedure FreeRemovingFromAllParents;`
| `procedure FreeIfUnused;`
| `procedure KeepExistingBegin;`
| `procedure KeepExistingEnd;`
| `function PathFromBaseUrl(const RelativePath: string): string;`
| `procedure Parse(Lexer: TX3DLexer; Reader: TX3DReaderNames); virtual;`
| `procedure ParseXML(Element: TDOMElement; Reader: TX3DReaderNames);`
| `constructor Create(const ANodeName: string = ''; const ABaseUrl: string = ''); virtual;`
| `destructor Destroy; override;`
| `function NodeTypeName: string; virtual;`
| `class function ClassNodeTypeName: string; virtual;`
| `procedure Traverse( NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc);`
| `procedure TraverseInternal(StateStack: TX3DGraphTraverseStateStack; NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc; ParentInfo: PTraversingInfo);`
| `procedure TraverseIntoChildren(StateStack: TX3DGraphTraverseStateStack; NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc; ParentInfo: PTraversingInfo);`
| `procedure EnumerateNodes( proc: TX3DNodeProc; OnlyActive: boolean); overload;`
| `procedure EnumerateNodes(nodeClass: TX3DNodeClass; proc: TX3DNodeProc; OnlyActive: boolean); overload;`
| `procedure EnumerateNodes(nodeClass: TX3DNodeClass; const SeekNodeName: string; proc: TX3DNodeProc; OnlyActive: boolean); overload;`
| `function TryFindNodeByName(FindClass: TX3DNodeClass; const FindName: string; OnlyActive: boolean): TX3DNode;`
| `function FindNodeByName(FindClass: TX3DNodeClass; const FindName: string; OnlyActive: boolean): TX3DNode;`
| `function TryFindNode(FindClass: TX3DNodeClass; OnlyActive: boolean): TX3DNode;`
| `function FindNode(FindClass: TX3DNodeClass; OnlyActive: boolean): TX3DNode;`
| `function TryFindNodeState( NodeClass: TX3DNodeClass; out Node: TX3DNode; out State: TX3DGraphTraverseState): boolean;`
| `function TryFindNodeTransform( NodeClass: TX3DNodeClass; out Node: TX3DNode; out Transform: TMatrix4Single; out TransformScale: Single): boolean;`
| `function TryFindParentByName(const FindName: string): TX3DNode;`
| `function FindParentByName(const FindName: string): TX3DNode;`
| `function HasParent(Node: TX3DNode): boolean;`
| `function TryFindDirectParentByName(const FindName: string): TX3DNode;`
| `function IsNodePresent(Node: TX3DNode; OnlyActive: boolean): boolean;`
| `function NodesCount(NodeClass: TX3DNodeClass; CountOnlyActiveNodes: boolean): integer;`
| `procedure SaveToStream(Writer: TX3DWriter); override;`
| `class function VRML1StateNode(out StateNode: TVRML1StateNode): boolean;`
| `class function ForVRMLVersion(const Version: TX3DVersion): boolean; virtual;`
| `function EnumerateReplaceChildren( Func: TEnumerateReplaceNodesFunction): Cardinal;`
| `function RemoveChildrenWithMatchingName( const Wildcard: string; IgnoreCase: Boolean): Cardinal;`
| `function DeepCopy: TX3DNode;`
| `class function URNMatching(const URN: string): boolean; virtual;`
| `procedure PostAddInterfaceDeclaration(IDecl: TX3DInterfaceDeclaration); virtual;`
| `procedure AddCustomField(Field: TX3DField; const Exposed: boolean = false);`
| `function NiceName: string;`
### Properties
| `property CDataField: TMFString read FCDataField write FCDataField;`
| `property Fields: TX3DFieldList read FFields;`
| `property Events: TX3DEventList read FEvents;`
| `property VRML1Children [i:integer]: TX3DNode read GetVRML1Child write SetVRML1Child;`
| `property VRML1Parents [i:integer]: TX3DNode read GetVRML1Parent;`
| `property ParentFields[Index:Integer]: TX3DField read GetParentFieldsItem;`
| `property ParentFieldsNode[Index:Integer]: TX3DNode read GetParentFieldsNodeItem;`
| `property KeepExisting: Cardinal read FKeepExisting write FKeepExisting;`
| `property NodeName: string read fNodeName write FNodeName;`
| `property BaseUrl: string read FBaseUrl write FBaseUrl;`
| `property WWWBasePath: string read FBaseUrl write FBaseUrl; deprecated;`
| `property Prototypes: TX3DPrototypeBaseList read FPrototypes;`
| `property Routes: TX3DRouteList read FRoutes;`
| `property ImportsList: TX3DFileItemList read FImportsList;`
| `property ExportsList: TX3DFileItemList read FExportsList;`
| `property PrototypeInstance: boolean read FPrototypeInstance;`
| `property PrototypeInstanceSourceNode: TX3DPrototypeNode read FPrototypeInstanceSourceNode;`
| `property PrototypeInstanceHelpers: TX3DNode read FPrototypeInstanceHelpers;`
| `property DefaultContainerField: string read FDefaultContainerField write FDefaultContainerField;`
| `property HasInterfaceDeclarations: TX3DAccessTypes read FHasInterfaceDeclarations write SetHasInterfaceDeclarations default [];`
| `property InterfaceDeclarations: TX3DInterfaceDeclarationList read FInterfaceDeclarations;`
| `property DestructionNotifications: TNodeDestructionNotificationList read FDestructionNotifications;`
| `property Scene: TX3DEventsEngine read FScene write FScene;`
| `property ShapeTrees: TObject read FShapeTrees write FShapeTrees;`
## Description ### Fields
| `VRML1ChildrenAllowed: boolean;`
Are VRML 1.0 children allowed. This condition is checked in VRML1ChildAdd, so it's strictly impossible to add a node that is not allowed. Note that in some special cases `VRML1ChildrenAllowed` and VRML1ChildrenParsingAllowed values may be changed during object lifetime. Currently, this may concern TX3DUnknownNode. Default `False`.
| `VRML1ChildrenParsingAllowed: boolean;`
VRML 1.0 children allowed to be added during parsing. This is used only by *Inline nodes for now, that do not allow reading children during parsing but may get new children in memory. So their `VRML1ChildrenParsingAllowed` must be empty, but VRML1ChildrenAllowed must allow all. When VRML1ChildrenAllowed is `False` then `VRML1ChildrenParsingAllowed` should also be `False`. Default `False`.
### Methods
| `function DeepCopyCore(CopyState: TX3DNodeDeepCopyState): TX3DNode; virtual;`
Does actual DeepCopy work. You can override this to copy some more properties for descendants.
| `function DeepCopyCreate(CopyState: TX3DNodeDeepCopyState): TX3DNode; virtual;`
This should be a mere call to constructor of your own class. In TX3DNode, this simply calls default virtual constructor, which is Ok for all normal nodes. But we have some special nodes, like TX3DPrototypeNode or TX3DUnknownNode, that simply cannot be created by default constructor. They need to override this.
| `class function VRML1ChildrenSaveToStream: boolean; virtual;`
Should SaveToStream save our VRML1Children. In this class default implementation returns `True`, this is what you will want in 99% of cases. It's useful to set this to false if you use VRML1Children internally, e.g. *Inline nodes.
| `procedure DirectEnumerateActive( Func: TEnumerateChildrenFunction); virtual;`
Enumerate all active child nodes of given node. "Active nodes" are the ones affecting current VRML graph look or collisions, e.g. from Switch node only one child will be enumerated. See Traverse for more precise definition. "Direct" means that this enumerates only direct descendants, i.e. this is not recursive. See methods like Traverse or EnumerateNodes if you want recursive behavior. This can enumerate both VRML1Children nodes nodes within TSFNode and TMFNode fields. Default implementation in this class returns all Children nodes of VRML 1.0. If you need to remove some children for VRML 1.0 (e.g. for Switch or LOD nodes) or add some children for VRML 2.0 you have to override this. You're not required to call inherited when overriding this.
| `procedure DirectEnumerateActiveForTraverse( Func: TEnumerateChildrenFunction; StateStack: TX3DGraphTraverseStateStack); virtual;`
Enumerate all active child nodes of given node, and may additionally modify StateStack. It's used by Traverse. Default implementation in this class simply calls DirectEnumerateActive, ignoring StateStack, and this is suitable for 99% of nodes. However, for some special nodes (only Collision node for now), they have to modify state during traversing into various children, and then they can override this.
| `procedure DirectEnumerateAll( Func: TEnumerateChildrenFunction);`
Simply enumerate all direct descendant nodes. That is, all children in VRML 1.0 style and all nodes in SFNode and MFNode fields. This includes prototype stuff, if this node is expanded from prototype: PrototypeInstanceSourceNode and PrototypeInstanceHelpers.
| `procedure DirectEnumerate( Func: TEnumerateChildrenFunction; OnlyActive: boolean);`
This enumerates direct descendant nodes of this node. This is equivalent to DirectEnumerateActive or DirectEnumerateAll, depending on value of OnlyActive param.
| `procedure BeforeTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
Override these methods to determine what happens when given node is traversed during Traverse call. The main use of this is to operate on TX3DGraphTraverseStateStack. Remember to always call inherited when overriding. In `BeforeTraverse` and MiddleTraverse you should call inherited at the beginning, in AfterTraverse inherited should be called at the end. Besides changing StateStack.Top fields, you can do push/pop on the stack. Remember that if you do StateStack.Push in `BeforeTraverse`, and then you must call StateStack.Pop in AfterTraverse.
| `procedure MiddleTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
| `procedure AfterTraverse(StateStack: TX3DGraphTraverseStateStack); virtual;`
| `function ParseNodeBodyElement(Lexer: TX3DLexer; Reader: TX3DReaderNames; const APositionInParent: Integer): boolean; virtual;`
Parse VRML node body element. Usually, this is a field. May also be VRML 1.0 style child node. May also be VRML 2.0 Script node interface declaration, etc. — see VRML 2.0 grammar spec. This should be overriden to parse special features within particular nodes. While generally VRML is very clean and there's no need to override this, there's one use for this currently: Since we handle a couple of VRML flavors (at least Inventor, VRML 1.0 and VRML 97), sometimes the same node has different fields to express the same things in various VRML flavors. So it may be useful to parse a field and copy it's value into other fields. Example: TShapeHintsNode_1 in Inventor parses "hints" field, and copies it's value to other fields as appropriate. "hints" field is not exposed in TShapeHintsNode_1 interface, so everything is clean in the interface, and under the hood TShapeHintsNode_1 can "magically" handle "hints" field for Inventor. When overriding, always check inherited result first, and exit if inherited handled successfully. Otherwise either read your stuff and return `True` (Lexer should advance to the position of next "nodeBodyElement"). Or return `False` without changing Lexer position.
| `procedure ParseAfter(Reader: TX3DReaderNames); virtual;`
Called at the end of parsing (in both classic and XML encoding).
| `procedure CreateNode; virtual;`
| `function FieldOrEvent(const Name: string): TX3DFieldOrEvent;`
Search by name for given field or event (exposed by some field or not). `Nil` if not found.
| `function AnyEvent(const Name: string): TX3DEvent;`
Search by name for given event (exposed by some field or not). `Nil` if not found.
| `function VRML1ChildrenCount: integer;`
| `procedure VRML1ChildAdd(Index: Integer; child: TX3DNode); overload;`
Add a VRML 1.0 child node at given position. Index (position) must be in [0..VRML1ChildrenCount]. Items at and above Index position are moved to the right, to insert new child at Index position.
| `procedure VRML1ChildAdd(child: TX3DNode); overload;`
Add a VRML 1.0 child node at the end of VRML1Children list.
| `procedure VRML1ChildRemove(i: integer);`
| `procedure VRML1ChildrenClear;`
| `function VRML1ChildExtract(I: Integer): TX3DNode;`
Remove a VRML 1.0 children at index I and return it (do not free it). Compare this with VRML1Remove, that removes children I and frees it if it's no longer used by anything. This removes children I, appropriately adjusting all parent / children links, but even if a node is unused after removing, it is not freed. It's always returned.
| `function VRML1ParentsCount: integer;`
| `function ParentFieldsCount: Integer;`
| `procedure FreeRemovingFromAllParents;`
Free this object (if it's not `Nil`) also removing it from all parent nodes and fields. By design, normal destructor (Destroy called by Free) doesn't care about removing references to this object from it's parents. That's because it's the parents that usually initialize freeing of their children, and they free child when it's reference count is 0. So this freeing method is special in this regard. Use this if you really want to remove all node occurrences from the middle of VRML hierarchy.
| `procedure FreeIfUnused;`
Free this node if it is not referenced by any parent fields or nodes. Takes into account that node may have VRML 1.0 parent nodes and VRML 2.0 / X3D parent fields (SFNode or MFNode). This is a safe way of removing a node that may, but doesn't have to, be part of some VRML/X3D graph. The idea is that if a node is a part of some graph, we don't need to do anything (since you should have a reference to the entine graph somewhere anyway), otherwise node is considered unused and freed. Analogous to standard TObject.Free, this also works when called on a `Nil` value (does nothing in this case). For safety, it's advised to set reference to `Nil` after calling `FreeIfUnused`. You can use FreeIfUnusedAndNil utility for this (that employs a trick to `Nil` the visible reference even before freeing, which is even safer). This is analogous to standard FreeAndNil.
| `procedure KeepExistingBegin;`
| `procedure KeepExistingEnd;`
| `function PathFromBaseUrl(const RelativePath: string): string;`
Returns an absolute path, assuming that RelativePath is relative path from BaseUrl or that RelativePath is already absolute.
| `procedure Parse(Lexer: TX3DLexer; Reader: TX3DReaderNames); virtual;`
Parse node. This should set values of your fields, VRML 1.0 Children list, BaseUrl. In special cases like TX3DUnknownNode this may actually initialize whole Fields list (by VRML 1.0 "fields" extensibility feature).
| `procedure ParseXML(Element: TDOMElement; Reader: TX3DReaderNames);`
Parse node body, i.e. mainly node's fields.
| `constructor Create(const ANodeName: string = ''; const ABaseUrl: string = ''); virtual;`
Constructor. Initializes various properties: NodeName, BaseUrl are initialized directly from given parameters. The Fields, Events lists are filled in every descendant, to have all the fields/events defined by the specification. DefaultContainerField, and other node-specific stuff, is filled in descendants. This is actually implemented in CreateNode, that is called at the end of this constructor.
| `destructor Destroy; override;`
| `function NodeTypeName: string; virtual;`
Node type name in VRML/X3D. Never empty. Constant for the class lifetime (even for special TX3DUnknownNode and TX3DPrototypeNode, where this is calculated at runtime). Note that VRML/X3D is generally case-sensitive, so this property is too. In TX3DNode, this returns ClassNodeTypeName, which is suitable for most nodes. See ClassNodeTypeName.
| `class function ClassNodeTypeName: string; virtual;`
Node type name in VRML/X3D, for this class. Normal VRML/X3D node classes should override this to return something non-empty, and then NodeTypeName automatically will return the same value. Empty for classes that don't have a hardcoded VRML/X3D node name, like a special TX3DUnknownNode. Such special classes should override then NodeTypeName to return actual non-empty name there. You usually should call NodeTypeName. The only use of this method is that it works on classes (it's "class function"), without needing at actual instance.
| `procedure Traverse( NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc);`
Traverse all the nodes of VRML graph that are active. An "active" part of the VRML graph are the nodes that actually change what the VRML file represents, in terms of geometry, collision detection etc. For example, the Switch node has only one child usually active. Nodes that merely influence the active graph by some events and routes do not have to be active (these nodes may change what the VRML file actually represents, but only by changing other nodes). For all nodes of NodeClass TraversingFunc will be called. Traverse not only enumerates these nodes, it also collects all state (transformation, etc — see TX3DGraphTraverseState) that affects how given node should be presented. Also, TraversingInfo is passed to each TraversingFunc call. This allows you to investigate, during TraversingFunc call, the parents hierarchy (you can't use VRML1Parents / ParentFields of the current node, since a node may have many parents). Traverse calls are naturally recursive, and so the stack of TraversingInfo structures is naturally build and destroyed by recursive calls. For the root node (the one where you called Traverse without specifying initial TraversingInfo), ParentInfo is simply `Nil`. The scheme of how Traverse works:
      BeforeTraverse;

      TraverseIntoChildren := true;
      if Self is NodeClass then TraversingFunc (Self, State, TraverseIntoChildren);

      MiddleTraverse;

      if TraverseIntoChildren is still true then
        for all children returned by DirectEnumerateActive
          call their Traverse(State);

      AfterTraverse;

      Add Self to State.LastNodes (for VRML 1.0 state nodes, see
        TraverseStateLastNodesClasses);
Note: setting TraverseIntoChildren to false means that some part of the tree is explicitly omitted from traversing. Use this only if you know what you're doing, as for some nodes they actually affect their parents too (for example, chilren within VRML 1.0 Group affect other nodes too; global lights within VRML >= 2.0 affect all nodes; and so on...). Usually, you will use this only for separator-like nodes (for VRML >= 2.0, all Group, Transform, Switch etc. act like separators), and only when you will somehow traverse into these nodes anyway. We guarantee that AfterTraverse will be called if BeforeTraverse was called and finished (that is, AfterTraverse is called in the `finally..end`). During traversing, you can only modify the children (direct or not) nodes of the current node.
| `procedure TraverseInternal(StateStack: TX3DGraphTraverseStateStack; NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc; ParentInfo: PTraversingInfo);`
Like Traverse, but it takes explicit starting state stack and starting ParentInfo. Not generally useful, use only for special purposes.
| `procedure TraverseIntoChildren(StateStack: TX3DGraphTraverseStateStack; NodeClass: TX3DNodeClass; TraversingFunc: TTraversingFunc; ParentInfo: PTraversingInfo);`
Like Traverse, but only enters children. This does the job of Traverse normally omitted if your Traverse callback returns `TraverseIntoChildren` = `False`. Using this method, you can traverse into children explicitly from your callback.
| `procedure EnumerateNodes( proc: TX3DNodeProc; OnlyActive: boolean); overload;`
Enumerate all our children of some class. Recursively. Enumerates also this instance (Self), if it satisfies the NodeClass and SeekNodeName conditions. This enumerates both VRML 1.0 children (VRML1Children) as well as VRML >= 2.0 (including X3D) children (nodes in TSFNode and TMFNode fields). If OnlyActive then it will enumerate only active parts of the graph ("active" as defined by Traverse), so it will work as a simpler version of Traverse (simpler, because it doesn't track any state). If not OnlyActive then it will simply enumerate all nodes. This will include then also prototype helpers, if this node was expanded from prototype: see PrototypeInstanceSourceNode and PrototypeInstanceHelpers. If you give SeekNodeName parameter, we'll only look for nodes with NodeName = SeekNodeName. When SeekNodeName = '' it, consistently, looks for unnamed nodes (where NodeName = ''). Enumerates children only after enumerating Self. So you can modify children before enumerating them in the Proc callback. You can only modify your children in the Proc callback.
| `procedure EnumerateNodes(nodeClass: TX3DNodeClass; proc: TX3DNodeProc; OnlyActive: boolean); overload;`
| `procedure EnumerateNodes(nodeClass: TX3DNodeClass; const SeekNodeName: string; proc: TX3DNodeProc; OnlyActive: boolean); overload;`
| `function TryFindNodeByName(FindClass: TX3DNodeClass; const FindName: string; OnlyActive: boolean): TX3DNode;`
`TryFindNodeByName` and TryFindNode seek for a node with given class (and node name, in case of `TryFindNodeByName`). If OnlyActive then they seek among only active nodes ("active" as defined by Traverse), otherwise all nodes. These functions are quite like EnumerateNodes, except they stop at the first occurrence and return it. `TryFindNodeByName` and TryFindNode return `Nil` if such node is not found. FindNodeByName and FindNode raise exception EX3DNotFound in this case. ###### Exceptions raised EX3DNotFound FindNodeByName and FindNode raise this exception when node is not found.
| `function FindNodeByName(FindClass: TX3DNodeClass; const FindName: string; OnlyActive: boolean): TX3DNode;`
| `function TryFindNode(FindClass: TX3DNodeClass; OnlyActive: boolean): TX3DNode;`
| `function FindNode(FindClass: TX3DNodeClass; OnlyActive: boolean): TX3DNode;`
| `function TryFindNodeState( NodeClass: TX3DNodeClass; out Node: TX3DNode; out State: TX3DGraphTraverseState): boolean;`
Find the first node with given class (NodeClass), return it's state or just transformation. Similar to Traverse, but stops as soon as the given node is found. Returns `False` when not found ("out" parametrs Node, State and Transform are undefined then).
| `function TryFindNodeTransform( NodeClass: TX3DNodeClass; out Node: TX3DNode; out Transform: TMatrix4Single; out TransformScale: Single): boolean;`
| `function TryFindParentByName(const FindName: string): TX3DNode;`
Seeks Self and parent nodes (from VRML1Parents and ParentFields, recursively) for given node name. In other words, this is similar to TryNodeByName or NodeByName, but it goes "upward" in graph hierarchy. Note that this never restricts itself only to "active" graph part ("active" as defined by Traverse) because you really can't detect what is the "active" part of the graph when going upward. ###### Exceptions raised EX3DNotFound FindParentByName raises this exception when node is not found.
| `function FindParentByName(const FindName: string): TX3DNode;`
| `function HasParent(Node: TX3DNode): boolean;`
Looks for a given Node in parents (and self), recursively. Similar to TryFindParentByName. Returns `True` only if found.
| `function TryFindDirectParentByName(const FindName: string): TX3DNode;`
Search immediate parents of this node for a node with given FindName. Returns `Nil` if not found.
| `function IsNodePresent(Node: TX3DNode; OnlyActive: boolean): boolean;`
Looks for a given node in our children (direct and not, including self). If OnlyActive, then only active parts are searched ("active" as defined by Traverse).
| `function NodesCount(NodeClass: TX3DNodeClass; CountOnlyActiveNodes: boolean): integer;`
Count the occurrences of given node class in our children. For example, you can pass NodeClass = TAbstractLightNode to count the light sources in the scene. If CountOnlyActiveNodes, then only active parts are searched ("active" as defined by Traverse). This traverses both VRML 1.0 children nodes and VRML 2.0 nodes inside SFNode and MFNode fields.
| `procedure SaveToStream(Writer: TX3DWriter); override;`
Save node to a stream. Saves everything, including node name, node type, and node contents.
| `class function VRML1StateNode(out StateNode: TVRML1StateNode): boolean;`
Do the nodes of (exactly) this class should be included in VRML 1.0 state (see TX3DGraphTraverseState.LastNodes).
| `class function ForVRMLVersion(const Version: TX3DVersion): boolean; virtual;`
Some nodes are present only in specific VRML/X3D version. This functions decides it. For example some nodes can only work in VRML < 2.0, some others only in VRML >= 2.0. There are even some pairs of nodes: for example TConeNode_1 works with VRML < 2.0, TConeNode works with VRML >= 2.0. NodesManager will use this. Default implementation of this function returns always `True`. Generally, I don't try to set this too aggresively — in other words, for all cases when it's sensible, I allow nodes to be used in every VRML/X3D version, even when official specification doesn't. This means that when reading VRML 1.0 files actually a large part of VRML 2.0 is allowed too, and also while reading VRML 2.0 many constructs from VRML 1.0 (officially no longer present in VRML 2.0) are allowed too. I'm trying to support what I call a "sum of VRML 1.0 and 2.0". In practice I only use this function when various VRML/X3D versions specify the same node name but With different fields. For example Cone and Cylinder have slightly different fields, due to the fact that VRML 2.0 resigned from using TSFBitMask fields. With different behavior. For example definitions of Sphere for VRML 1.0 and 2.0 are practically equal. However, the behavior from where to take texture and material info is different — in VRML 1.0 we take last Texture2, Material etc. nodes, while in VRML 2.0 we look in parent Shape's "appearance" field. So once again two different Sphere classes are needed.
| `function EnumerateReplaceChildren( Func: TEnumerateReplaceNodesFunction): Cardinal;`
Enumerates all children nodes (recursively), allowing you to decide for each node to replace or remove it. So this is something like EnumerateNodes, except that it allows you to remove the nodes. It always enumerates all nodes, not only active (e.g. it enumerates all Switch node children, not only the chosen one). Note that (unlike regular EnumerateNodes) this doesn't report Self to Func !. Which is natural, since this may remove nodes by normal VRML1ChildRemove calls, so it needs to know ParentNode of the removed node. For each node Func will be called, with ParentNode and Node set. If you change the Node to something else, then the old node will be removed and new Node inserted in the same place. If new Node is `Nil`, then only the old node will be removed. Nodes are traversed in depth-first search. Node is first reported to Func, and then (if it's not replaced) we descend into this Node. ###### Returns The number of removed (and possibly replaced) nodes.
| `function RemoveChildrenWithMatchingName( const Wildcard: string; IgnoreCase: Boolean): Cardinal;`
Removes all children (and their children, recursively) with node names matchig Wildcard. You can use * and ? special chars in the Wildcard. ###### Returns The number of removed nodes.
| `function DeepCopy: TX3DNode;`
Create a deep copy of this node and all it's children. New copy is completely independent from original, having all children nodes (in both VRML 1.0 sense (Children) and VRML >= 2.0 (inside SFNode and MFNode fields)) also duplicated. New copy has protypes, routes, interface declarations and generally everything established like in the original, using copied nodes. Doesn't copy things which are dependent on container hierarchy. (So copying them would be more dangerous than useful.) This means: DestructionNotifications, Scene, VRML1Parents, ParentFields. VRML1Parents and ParentFields will be set for children anyway (to appropriate copies). Caller owns this newly created copy — as returned by this method, it's not linked anywhere.
| `class function URNMatching(const URN: string): boolean; virtual;`
Should we use this node when URN is required by EXTERNPROTO ? Implementors note: in this class, this returns `False`. You can use constants like URNVRML97Nodes and URNKambiNodes to help implementing this.
| `procedure PostAddInterfaceDeclaration(IDecl: TX3DInterfaceDeclaration); virtual;`
This will be always called by VRML parsers after adding new item to our InterfaceDeclarations. In this class, this simply adds IDecl.FieldOrEvent to our normal fields/events by IDecl.AddFieldOrEvent. You may override this in subclasses to react in some special way to new fields/events, for example Script node may register here to receive notification when input event is received.
| `procedure AddCustomField(Field: TX3DField; const Exposed: boolean = false);`
Add to node InterfaceDeclarations given field. Sets the field's exposed to given Exposed parameter, for comfort. This should only be used with nodes having HasInterfaceDeclarations = `True`, like Script or ComposedShader.
| `function NiceName: string;`
Nice and concise node description for user. Shows node type and name.
### Properties
| `property CDataField: TMFString read FCDataField write FCDataField;`
The field where CDATA section from XML is added. Used when loading X3D in XML encoding: XML elements may contain CDATA sections, that are added to "url" field. See X3D XML encoding specification about "Encapsulating Script node code" [http://www.web3d.org/x3d/specifications/ISO-IEC-19776-1.2-X3DEncodings-XML/Part01/concepts.html#EncapsulatingScriptNodeCode]. We also allow this for shader nodes (sensible (follows the intention of the spec) and compatible with InstantReality). When not assigned, then CDATA section for this node is not allowed. This should be set in descendants constructor.
| `property Fields: TX3DFieldList read FFields;`
Node fields. For normal nodes, all Fields are created and added to Fields list in constructor. Fields default values are set, and of course current field values are set to these defaults. Later, we only modify these fields current values (e.g. when parsing). However, there are special node classes that set their Fields differently. TX3DPrototypeNode has their fields set according to it's VRML 2.0 prototype. TX3DUnknownNode may have it's fields set by VRML 1.0 "fields" feature (so it's Fields are initialized by parsing it). Nodes with HasInterfaceDeclarations have some Fields and Events added when reading node. All fields on this list are owned by this object.
| `property Events: TX3DEventList read FEvents;`
Explicit events (that is, not exposed by some field) of this node. For exposed events, see each field's property ExposedEvents.
| `property VRML1Children [i:integer]: TX3DNode read GetVRML1Child write SetVRML1Child;`
VRML 1.0 children nodes. These are nodes directly specified inside a VRML 1.0 node, they don't belong to any node field. (In VRML 1.0, there was no SFNode / MFNode fields.) In VRML 2.0, this is always empty. VRML 1.0 nodes may have any number of children. The children nodes refer back to it's parent nodes in VRML1Parents list. When travelling over VRML/X3D graph, remember that cycles are possible, because of DEF/USE. Obviously, they possible when travelling along the VRML1Parents list. We currently assume that there are no cycles when we treat the graph as directed, but it may change one day (some VRML/X3D models create real cycles). Adding/removing stuff from the `VRML1Children` list keeps track of how many times a node is used. If the child node has no parents, it will be freed. Actually, nodes can be children of both nodes (VRML 1.0 style, then `VRML1Children` and VRML1Parents is used) or fields (TMFNode or TSFNode, in VRML 2.0 style; then ParentFields is used). So the node is freed only when it's not referenced by any node and not referenced by any field. Generally, it's the parent that takes care of reference-counting and freeing the children, not the other way around. Note that given node instance may be a children of a single node multiple times, through DEF/USE mechanism. The order of children is important and preserved. (On the other hand, the order of VRML1Parents is not important, as that list is mostly for reference-counting.) You can replace one children with another like ``VRML1Children`[I] := NewChildren;`. This works like a shortcut for `VRML1ChildRemove(I); VRML1ChildAdd(I, NewChildren);`. But 1. it's more efficient; 2. it's safer — if Children[I] is already equal to NewChildren, it does nothing.
| `property VRML1Parents [i:integer]: TX3DNode read GetVRML1Parent;`
VRML 1.0 parent nodes. `VRML1Parents` is a reverse of VRML1Children — it lists all the nodes where we are on VRML1Children list.
| `property ParentFields[Index:Integer]: TX3DField read GetParentFieldsItem;`
This lists all SFNode and MFNode fields where this node is referenced. This is somewhat analogous for VRML1Parents, but for VRML 2.0. ParentFieldsNode is just for your comfort, it returns always appropriate field's ParentNode property value (i.e. `(ParentField[Index] as TSFNode).ParentNode` or `(ParentField[Index] as TMFNode).ParentNode`).
| `property ParentFieldsNode[Index:Integer]: TX3DNode read GetParentFieldsNodeItem;`
| `property KeepExisting: Cardinal read FKeepExisting write FKeepExisting;`
Increase `KeepExisting` property value to disable automatic freeing of the node when unused. This may be useful in cases when you remove the node from VRML graph hierarchy, but you want to keep a valid reference to it anyway (for example, maybe you'll free it later by hand or add it somewhere else). Simple methods KeepExistingBegin and KeepExistingEnd simply increase / decrease `KeepExisting` value by 1. This is the most usual usage.
| `property NodeName: string read fNodeName write FNodeName;`
Name of this node. When saving/loading, this comes from VRML/X3D "DEF" construct. Empty value means that the name is not defined. Do not change it during loading / saving or searching.
| `property BaseUrl: string read FBaseUrl write FBaseUrl;`
Base URL for all URLs inside our fields. Used everywhere as a base for relative URLs, to handle fields that refer to external files like textures, other 3D models (ImageTexture, Inline nodes, many others). It must be an absolute URL. Currently, it doesn't have to contain a protocol, and is then interpreted as a path on local filesystem (just like it had file:// prefix). Still, it must be an absolute path. This is set in constructor, and eventually adjusted by various parsing routines. This way we could, if only we would like to, resolve nodes like Inline or ImageTexture immediately after parsing them.
| `property WWWBasePath: string read FBaseUrl write FBaseUrl; deprecated;`
Warning: this symbol is deprecated. Old deprecated name for BaseUrl.
| `property Prototypes: TX3DPrototypeBaseList read FPrototypes;`
| `property Routes: TX3DRouteList read FRoutes;`
| `property ImportsList: TX3DFileItemList read FImportsList;`
| `property ExportsList: TX3DFileItemList read FExportsList;`
| `property PrototypeInstance: boolean read FPrototypeInstance;`
`PrototypeInstance` = `True` indicates that this node was created from a non-external prototype instantiation. Then PrototypeInstanceSourceNode is non-nil and indicates parsed prototype node (and PrototypeInstanceSourceNode.Prototype gives you even a link to the actual prototype specification). PrototypeInstanceSourceNode is used for events: any ROUTEs specified outside of prototype and leading to/from instantiated prototype should actually lead to PrototypeInstanceSourceNode events (not to events of Self). Reason: prototype events may be different than actual expanded node events, and ROUTEs want to lead to prototype events. This is implemented when expanding prototype (TX3DPrototypeNode.Instantiate) and when linking ROUTE (TX3DRoute.SetSource, TX3DRoute.SetDestination). PrototypeInstanceHelpers may be `Nil` if empty, or may contain a list of other nodes duplicated along with the main prototype node. From VRML spec:
            Any other nodes and accompanying scene graphs
            are not part of the transformation hierarchy, but may be referenced
            by ROUTE statements or Script nodes in the prototype definition.
Note that for TX3DPrototypeNode (within PrototypeInstanceSourceNode) these have a little different meaning: they describe the nested prototype, if any, that was used to create this node. This may happen if the node was expanded from one prototype within another. (Usually, you shouldn't be concerned about this; see TX3DPrototypeNode.Instantiate implementation comments for gory details about this.)
| `property PrototypeInstanceSourceNode: TX3DPrototypeNode read FPrototypeInstanceSourceNode;`
| `property PrototypeInstanceHelpers: TX3DNode read FPrototypeInstanceHelpers;`
| `property DefaultContainerField: string read FDefaultContainerField write FDefaultContainerField;`
Default value of "containerField" attribute for this node in X3D XML encoding.
| `property HasInterfaceDeclarations: TX3DAccessTypes read FHasInterfaceDeclarations write SetHasInterfaceDeclarations default [];`
For some special VRML / X3D nodes (like Script, ComposedShader) that allow the definition of additional fields/events within. In X3D specification this is marked like
      # And any number of:
      fieldType [in]     fieldName
      fieldType [in,out] fieldName    initialValue
      fieldType [out]    fieldName
      fieldType []       fieldName    initialValue
If `HasInterfaceDeclarations` is not [], then InterfaceDeclarations will be non-nil and parser (classic VRML parser in this unit, X3D XML reader too) will read this from VRML files. Moreover, for each interface declaration, also appropriate field/event will be added to the list of Fields or Events, so fields/events created by interface declarations will function just like other standard fields everywhere.
| `property InterfaceDeclarations: TX3DInterfaceDeclarationList read FInterfaceDeclarations;`
| `property DestructionNotifications: TNodeDestructionNotificationList read FDestructionNotifications;`
Functions registered here will be called when this TX3DNode descendant will be destroyed.
| `property Scene: TX3DEventsEngine read FScene write FScene;`
Scene that will be notified about changes to this node. This is necessary to allow the scene to properly process VRML/X3D events, and also to react properly to any other changes to the nodes (like when you change some field directly by ObjectPascal code, e.g. by TX3DField.Send). May be `Nil` if none. A given TX3DNode may be renderable only by a single renderer. This means it can be placed only within one TCastleScene or one TCastlePrecalculatedAnimation (nothing else gives you a renderer). A given TX3DNode may be placed inside many TCastleSceneCore instances (including TCastleScene). But if more than one scene is used, then all the scenes must be static (TCastleSceneCore.ProcessEvents = false and TCastleSceneCore.Static = true). Static scenes are ones that never change, that is never have any TCastleSceneCore.ChangedField called. This means that events processing is disabled, and also other dynamic scene changes from code are disallowed. These two rules are both at action when you think about a node inside many TCastleScene instances. In this case, all such scene instances must be created with the same renderer (hence the need for TCastleScene.CreateCustomRenderer) and all must be static. This is actually exactly how TCastlePrecalculatedAnimation works: it internally creates a single renderer and a series of TCastleScene instances.
| `property ShapeTrees: TObject read FShapeTrees write FShapeTrees;`
Managed and used by TCastleSceneCore to keep TShapeTreesList for every ITransformNode.
Generated by PasDoc 0.13.0 on 2015-06-15 04:43:14