Open Inventor Release 2024.2.1
 
Loading...
Searching...
No Matches
SoField.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 S. Strauss (MMM yyyy)
25** Modified by : Nick Thompson (MMM yyyy)
26** Modified by : Gavin Bell (MMM yyyy)
27**=======================================================================*/
28/*=======================================================================
29 *** THE CONTENT OF THIS WORK IS PROPRIETARY TO FEI S.A.S, (FEI S.A.S.), ***
30 *** AND IS DISTRIBUTED UNDER A LICENSE AGREEMENT. ***
31 *** ***
32 *** REPRODUCTION, DISCLOSURE, OR USE, IN WHOLE OR IN PART, OTHER THAN AS ***
33 *** SPECIFIED IN THE LICENSE ARE NOT TO BE UNDERTAKEN EXCEPT WITH PRIOR ***
34 *** WRITTEN AUTHORIZATION OF FEI S.A.S. ***
35 *** ***
36 *** RESTRICTED RIGHTS LEGEND ***
37 *** USE, DUPLICATION, OR DISCLOSURE BY THE GOVERNMENT OF THE CONTENT OF THIS ***
38 *** WORK OR RELATED DOCUMENTATION IS SUBJECT TO RESTRICTIONS AS SET FORTH IN ***
39 *** SUBPARAGRAPH (C)(1) OF THE COMMERCIAL COMPUTER SOFTWARE RESTRICTED RIGHT ***
40 *** CLAUSE AT FAR 52.227-19 OR SUBPARAGRAPH (C)(1)(II) OF THE RIGHTS IN ***
41 *** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 52.227-7013. ***
42 *** ***
43 *** COPYRIGHT (C) 1996-2021 BY FEI S.A.S, ***
44 *** BORDEAUX, FRANCE ***
45 *** ALL RIGHTS RESERVED ***
46**=======================================================================*/
47/*=======================================================================
48** Modified by : VSG (MMM YYYY)
49**=======================================================================*/
50
51
52#ifndef _SO_FIELD_
53#define _SO_FIELD_
54
55#include <Inventor/SbString.h>
56#include <Inventor/SoTypedObject.h>
57#include <Inventor/misc/SoNotification.h>
58#include <Inventor/misc/SoAuditorList.h>
59#include <Inventor/threads/SbThreadMutex.h>
60#include <Inventor/threads/SbThreadLocalStorage.h>
61#include <Inventor/sensors/SoDataSensor.h>
62#include <Inventor/misc/SoMemoryObject.h>
63
64class SoEngineOutput;
65class SoVRMLInterpOutput;
66struct SoFieldConnectionInfo;
68struct SoFieldAuditorInfo;
69class SoFieldConverter;
70class SoFieldList;
71class SoInput;
72class SoMemoryObject;
73class SoNotList;
74class SoOutput;
75class SoFieldSensor;
76
77#ifndef HIDDEN_FROM_DOC
78// If the field is connected or there are any FieldSensors attached to
79// this field, flags.hasAuditors will be TRUE, and this structure is
80// used to contain the extra information needed. Done this way to
81// save space in the common case.
85struct SoFieldAuditorInfo {
86 SoFieldAuditorInfo()
87 : container(NULL)
88 { connection.field=NULL; }
89
90 SoFieldContainer *container;
91
92 // List of auditors: objects to pass notification to.
93 SoAuditorList auditors;
94 // The "connection" field points to either an engine output,
95 // a VRMLInterpolator output, or
96 // another field:
97 union {
98 SoEngineOutput *engineOutput;
99 SoField *field;
100 SoVRMLInterpOutput *interpOutput;
101 } connection;
102};
103
104// If the field has a connections from other fields, there is a
105// SoFieldConnectionInfo structure for each connection and the index
106// of the last connection that touched this field is in the variable
107// lastTouched. The variable numConnected containes the number of connections
108// to this field. If multiple connections are allowed, this is also the
109// next connection index.
113struct SoFieldConnectionInfo {
114 // The "connection" field points to either an engine output,
115 // a VRMLInterpolator output, or
116 // another field:
117 void* indexToField;
118 union {
119 SoEngineOutput *engineOutput;
120 SoField *field;
121 SoVRMLInterpOutput *interpOutput;
122 } connection;
123 struct {
124 unsigned int converted : 1; // Connection required converter
125 unsigned int fromEngine : 1; // Connection is from engine
126 unsigned int fromVRMLInterp : 1; // Connection is from
127 // VRMLInterpolator
128 } flags;
129};
130#endif // HIDDEN_FROM_DOC
131
133//
134// Class: SoField
135//
136// Base class for all kinds of fields. SoField maintains the state
137// (ignored, modified, default, ...) of the field.
138//
140
234class SoField: public SoTypedObject {
235
236 public:
237
238 // Destructor
239#ifndef HIDDEN_FROM_DOC
240 virtual ~SoField();
241#endif // HIDDEN_FROM_DOC
242
262 SbBool isIgnored() const { return flags.ignored; }
263
271 SbBool isDefault() const { return flags.hasDefault; }
272
277
293
299 { return flags.connectionEnabled; }
300
309
318
327
335
343
351
356 void disconnect(SoEngineOutput *engineOutput);
357
362 void disconnect(SoField *field);
363
368 void disconnect(SoVRMLInterpOutput *interpOutput);
369
374 {
375 if (indexToConnectInfo)
376 return indexToConnectInfo->getLength();
377 return 0;
378 }
379
384
390
394 SbBool isConnected() const { return flags.connected; }
395
400
405
410
411 // Returns the engine or field the output field is connected to.
412 // Returns FALSE if there is no connection of the appropriate type.
413
420
426 SbBool getConnectedField(SoField *&writingField) const;
427
433
440
462
473 SoNONUNICODE SbBool set(const char *valueString);
474
483 SbBool set( const SbString& valueString );
484
485
490 void get(SbString &valueString);
491
495 virtual size_t getValueSize() const { return 0; }
496
504 virtual void touch();
505
510 int operator ==(const SoField &f) const
511 { return isSame(f); }
516 int operator !=(const SoField &f) const
517 { return ! isSame(f); }
518
519 SoEXTENDER private:
520 // Constuctor:
521 SoField();
522
523 private:
524 static void initClass();
525 static void exitClass();
526
527 SB_THREAD_TLS_HEADER();
528
529 // Initialize ALL Inventor node classes
530 static void initClasses();
531 static void exitClasses();
532
533 // Sets value of field from the Inventor data file format
534 // information in the value string. Returns TRUE if successful,
535 // FALSE otherwise. This is used in SoVRMLPROTOInstance to set the
536 // fields value that is an SFNode. It is necessary for the SoInput created to
537 // know that this is a VRML2 file so it will know a PROTO if it it is the
538 // default field
539 SbBool setVRML(const char *valueString);
540
541
542 // Sets default flag
543 void setDefault(SbBool def) { flags.hasDefault = def; }
544
545 // Initiates or propagates notification through container
546 virtual void startNotify();
547 virtual void notify(SoNotList *list);
548
549 // Sets the containing node. This also calls enableNotify(TRUE)
550 // and setDefault(TRUE).
551 void setContainer(SoFieldContainer *cont);
552
553 // Returns TRUE if the field really needs to be written out.
554 // Fields with default values that aren't ignored and
555 // aren't connected to anything will return FALSE.
556 SbBool shouldWrite() const;
557
558 // Adds/removes an auditor to/from list
559 void addAuditor(void *auditor, SoNotRec::Type type);
560 void removeAuditor(void *auditor, SoNotRec::Type type);
561
562 // Indicates whether notification will propagate as the result of
563 // setting the field value. Engines turn this off when writing
564 // results into fields, since notification has already propagated.
565 SbBool enableNotify(SbBool flag);
566 SbBool isNotifyEnabled() const
567 { return flags.notifyEnabled; }
568
569 // Indicates to a field that a change has been made involving a
570 // connection from it (as source) to another field. Passed the
571 // number of things being connected to the field; the number will
572 // be negative when things are disconnected.
573 // The default method does nothing.
574 virtual void connectionStatusChanged(int numConnections);
575
576 // If this returns TRUE, it means we're in the middle of doing a
577 // setValue()+valueChanged() and values from an upstream
578 // connection shouldn't write into this field.
579 SbBool isReadOnly() const { return flags.readOnly; }
580
581 // Returns TRUE if the given field is of the same type and has the
582 // same value(s) as this. Subclasses must define this as well as
583 // an == operator.
584 virtual SbBool isSame(const SoField &f) const = 0;
585
586 // Copies the value from one field to another, assuming same subclass
587 virtual void copyFrom(const SoField &f) = 0;
588
589 // After a field value has been copied using copyFrom(),
590 // this is called to allow fields to update the copy. This is used
591 // by node, engine, and path fields to make sure instances are
592 // handled properly. The default implementation does nothing.
593 virtual void fixCopy(SbBool copyConnections);
594
595 // This returns TRUE if this field contains a reference to a node
596 // or engine that is copied during a copy operation (i.e., it is
597 // "inside"). The default method just checks if the field is
598 // connected to such a node or engine. Subclasses may contain
599 // other tests, such as those that contain pointers to nodes or
600 // engines.
601 virtual SbBool referencesCopy() const;
602
603 // Copies connection from one field to another. Assumes fields are
604 // the same subclass and that this field is connected.
605 void copyConnection(const SoField *fromField);
606
607 // Reads value of field (with given name) from file as defined by
608 // SoInput. This does the work common to all fields, then calls
609 // other read methods to do the rest.
610 virtual SbBool read(SoInput *in, const SbName &name);
611
612 // Writes field (with given name) to file as defined by SoOutput
613 virtual void write(SoOutput *out, const SbName &name) const;
614
615 // Counts write-references on field to prepare for writing
616 virtual void countWriteRefs(SoOutput *out) const;
617
618 // Evaluates the field from whatever it's connected to. If
619 // there's no connection or we don't need to evaluate, this does
620 // nothing. This has to be const because it's used by getValue
621 // methods.
622 void evaluate() const
623 { if (flags.dirty) evaluateConnection(); }
624
625 // This is used to set the fieldType member of the flags structure
626 void setFieldType( int flagValue)
627 { flags.fieldType = flagValue; };
628
629 // This is used to get the fieldType member of the flags structure
630 int getFieldType() const
631 { return flags.fieldType; };
632
633 // Get the dirty flag so that the actions know to evaluate the events
634 SbBool getDirty() const
635 { return flags.dirty; };
636
637 void setDirty(SbBool value)
638 { flags.dirty = value; };
639
640 // Get the userDataIsUsed flag
641 SbBool getUserDataIsUsed() const
642 { return flags.userDataIsUsed; };
643
644 void setUserDataIsUsed(SbBool value)
645 { flags.userDataIsUsed = value; };
646
647 // Get the sameValueNotificationEnabled flag
648 SbBool getSameValueNotificationEnabled() const
649 { return flags.sameValueNotificationEnabled; };
650
651 // Connects the field to the given output of an engine or to
652 // another field. Returns FALSE if the connection could not be made.
653 SbBool connectFrom(SoEngineOutput *engineOutput, SbBool notDefault);
654
655 SbBool connectFrom(SoField *field, SbBool notDefault);
656
657 // Connects the field to the given output of an VRMLInterpolator.
658 // Returns FALSE if the connection could not be ade.
659 SbBool connectFrom(SoVRMLInterpOutput *interpOutput, SbBool notDefault);
660
661 // Connects the field to the given output of an engine or to
662 // another field. Returns FALSE if the connection could not be made.
663 SbBool connectFrom(SoEngineOutput *engineOutput,
664 SbBool notDefault, SbBool append);
665
666 SbBool connectFrom(SoField *field, SbBool notDefault, SbBool append);
667
668 // Connects the field to the given output of an VRMLInterpolator.
669 // Returns FALSE if the connection could not be made.
671 SbBool notDefault, SbBool append);
672
673 // Changed to support FanIn for VRML2 but used by Inventor also.
674
675 // Appends the field to the given output of an engine or to
676 // another field. Returns FALSE if the connection could not be made.
677 // An overloaded function to allow the appendConnection to not do
678 // the notify if setting up a ROUTE-TO connection.
680 SbBool notDefault);
681
682 SbBool appendConnection(SoField *field, SbBool notDefault);
683
684 // Connects the field to the given output of an VRMLInterpolator.
685 // Returns FALSE if the connection could not be made.
686 // An overloaded function to allow the appendConnection to not do
687 // the notify if setting up a ROUTE-TO connection.
689 SbBool notDefault);
690
691 // Set callback function or lambda called on the field value change
692 void setOnValueChangedCallback( const std::function<void( SoField* current )>& value );
693
694 virtual bool isEnabledMemObj() { return false; }
695 virtual SoMemoryObject* getMemObj() { return NULL; }
696 virtual void setMemObj( SoMemoryObject* ) { }
697
698
699 enum FieldType
700 {
701 HIDDEN_FIELD = 0,
702 EVENTIN_FIELD = 1,
703 EVENTOUT_FIELD = 2,
704 FIELD_EVENTIN_FIELD = 3,
705 INTERNAL_FIELD = 4,
706 EXPOSED_FIELD = 5,
707 PRIVATE_FIELD = 6,
708 UNSUPPORTED_FIELD = 7
709 };
710
711 private:
712 // Called by an instance to indicate that a value has changed. If
713 // resetDefault is TRUE, this turns off default flag. Initiates
714 // notification, if necessary.
715 void valueChangedBasic(SbBool resetDefault = TRUE);
716
717 // Evaluates the field or engine the field is connected to,
718 // storing the result in the field. This is const because it is
719 // called by evaluate().
720 virtual void evaluateConnection() const;
721
722 // Reads value(s) of field
723 virtual SbBool readValue(SoInput *in) = 0;
724
725 // Reads connection.
726 virtual SbBool readConnection(SoInput *in);
727
728 // Writes value(s) of field
729 virtual void writeValue(SoOutput *out) const = 0;
730
731 // Writes field connection
732 virtual void writeConnection(SoOutput *out) const;
733
734 // These are used by SoField::get()/SoMField::get1()
735 // to hold the returned field string
736 static SbThreadMutex s_classMutex;
737 struct MTstruct
738 {
739 char *fieldBuf;
740 size_t fieldBufSize;
741 };
742 // This is used to reallocate the string buffer used by SoField::get()
743 static void *reallocFieldBuf(void *ptr, size_t newSize);
744
745 // Number of values (0 by default for SoSField)
746 // only used by SoMField but here for memory padding reasons.
747 int num;
748
749 private:
750 static SoType classTypeId;
751 // set if by default notification is triggered when doing SoSFField::setValue() with same value than previous.
752 // this is controlled with OIV_ENABLE_SAMEVALUE_NOTIFICATION envvar. Default is TRUE.
753 static bool s_defaultSameValueNotificationEnabled;
754
755
756 // The "flags" field contains several bit flags:
757 struct Flags {
758 unsigned int hasDefault : 1; // Field is set to default value
759 unsigned int ignored : 1; // Field value is to be ignored
760 unsigned int connected : 1; // Field connected from something
761 unsigned int converted : 1; // Connection required converter
762 unsigned int fromEngine : 1; // Connection is from engine
763 unsigned int connectionEnabled : 1; // Connection is enabled
764 unsigned int notifyEnabled : 1; // Notification is enabled
765 unsigned int hasAuditors : 1; // Connected, or FieldSensor
766 unsigned int isEngineModifying : 1; // Engine evaluating
767 unsigned int readOnly : 1; // Must not write into this field
768 unsigned int dirty : 1; // Field was notified and needs evaluation
769 unsigned int fromVRMLInterp : 1; // Connection is from VRMLInterpolator
770 unsigned int fieldType : 3; // Specifies field type for VRML2 nodes.
771 unsigned int userDataIsUsed : 1; // 1 if user data array is used and if enableDeleteValues has never been called (only used by SoMField).
772 unsigned int sameValueNotificationEnabled : 1; // 1 if doing a setValue() with same value than previous generate a notification (only used by SoSField)
773 // 0 = hidden field 0 0 0
774 // 1 = eventIn 0 0 1
775 // 2 = eventOut 0 1 0
776 // 3 = field and eventIn 0 1 1
777 // 4 = internal field 0 0 1
778 // 5 = exposedField 1 0 1
779 // 6 = private field 1 1 0 // Useful for IvTune, fields which are not displayed
780 };
781 Flags flags;
782
783 // If no other auditors, the container for this field is stored
784 // directly here. If the field has other auditors (flags.hasAuditors)
785 // then the connection information and the container are
786 // stored in an opaque SoFieldAuditorInfo structure. This is
787 // done to save space in the common case.
788 union {
789
791
792 SoFieldAuditorInfo *auditorInfo;
793 };
794
795 SbPList *indexToConnectInfo;
796
797 // Creates auditorInfo structure, if necessary:
798 void createAuditorInfo();
799
800 // Creates connectionInfo strucuture, if necessary:
801 SoFieldConnectionInfo* createConnectionInfo(void* fromWhere);
802
803 // return index of the connection info that have the indexToField member equal to fromWhere
804 // -1 if not found
805 int findConnectionInfo(void* fromWhere) const ;
806
807 // Creates a converter engine to convert from the given field
808 // type to the type of this field. Returns NULL on error.
809 SoFieldConverter *createConverter(const SoType &fromFieldType) const;
810
811 // Really disconnects field from whatever it's connected to
812 void reallyDisconnect();
813
814 // Returns pointer to field converter, if fields was connected
815 // through one
816 SoFieldConverter *getConverter() const;
817
818 // Looks up what field connection is from (container and field/output name)
819 void getConnectionInfo(SoFieldContainer *&, SbName &) const;
820
821 // Callback for field sync
822 std::function<void( SoField* current )> m_onValueChanged;
823 SoFieldSensor * m_onValueChangedFieldSensor;
824
825 friend class SoEngineOutput;
826 friend class SoVRMLInterpOutput;
827};
828
829// for compatibility we include also this 2 headers
830// that were previously implemented here
831#include <Inventor/fields/SoSField.h>
832#include <Inventor/fields/SoMField.h>
833
834#endif /* _SO_FIELD_ */
835
836
Character string stored in a hash table.
Definition SbName.h:162
List of generic (void *) pointers.
Definition SbPList.h:77
int getLength() const
Returns number of pointers in list.
Definition SbPList.h:125
Class for smart character strings.
Definition SbString.h:202
<a href="IconLegend.html"><img src="extTGS.gif" alt="VSG extension" border="0"></a> Portable mutex c...
Class for all engine outputs.
Definition SoEngine.h:279
Abstract base class for objects that contain fields.
Base class for all fields.
Definition SoField.h:234
SoNONUNICODE SbBool set(const char *valueString)
Sets the field to the given value, which is an ASCII string in the Open Inventor file format.
SbBool connectFrom(SoEngineOutput *engineOutput)
Connects this field from an engine output.
SbBool isDefault() const
Gets the state of default flag of the field.
Definition SoField.h:271
void disconnect(SoVRMLInterpOutput *interpOutput)
Disconnect the field from the requested interpOutput.
SbBool appendConnection(SoVRMLInterpOutput *interpOutput)
Appends this field to the list of connections from another interpOutput.
int operator==(const SoField &f) const
Return TRUE if this field is of the same type and has the same value as f.
Definition SoField.h:510
SbBool isConnected() const
Returns TRUE if the field is connected to anything.
Definition SoField.h:394
friend class SoVRMLInterpOutput
Definition SoField.h:826
void disconnect(SoField *field)
Disconnect the field from the requested field.
SbBool set(const SbString &valueString)
Sets the field to the given value, which is an ASCII string in the Open Inventor file format.
void disconnect()
Disconnect the field from whatever it was connected to.
SbBool isConnectionEnabled() const
Returns FALSE if connections to this field are disabled.
Definition SoField.h:298
SoFieldAuditorInfo * auditorInfo
Definition SoField.h:792
SbBool getConnectedField(SoField *&writingField) const
Returns TRUE if this field is being written into by another field, and returns the field it is connec...
virtual size_t getValueSize() const
Gets the size of the value.
Definition SoField.h:495
SbBool isIgnored() const
Gets the ignore flag for this field.
Definition SoField.h:262
SoFieldContainer * container
Definition SoField.h:790
virtual void touch()
Simulates a change to the field, causing attached sensors to fire, connected fields and engines to be...
int getConnections(SoFieldList &list)
Returns a list of the connections to this field.
SbBool appendConnection(SoField *field)
Appends this field to the list of connections from another field.
void enableConnection(SbBool flag)
Field connections may be enabled and disabled.
void disconnect(SoEngineOutput *engineOutput)
Disconnect the field from the requested engineOutput.
SbBool connectFrom(SoField *field)
Connects this field to another field.
SbBool isConnectedFromEngine() const
Returns TRUE if the field is connected to an engine's output.
SbBool isConnectedFromField() const
Returns TRUE if the field is connected to another field.
static SoType getClassTypeId()
Return the type identifier for this field class.
SbBool connectFrom(SoVRMLInterpOutput *interpOutput)
Connects this field from an interpOutput.
void setIgnored(SbBool ig)
Sets the ignore flag for this field.
int getForwardConnections(SoFieldList &list) const
Adds references to all of the fields that this field is writing into (either fields in nodes,...
void get(SbString &valueString)
Returns the value of the field in the Open Inventor file format, even if the field has its default va...
SbBool isConnectedFromVRMLInterp() const
Returns TRUE if the field is connected to a VRML interpOutput.
int operator!=(const SoField &f) const
Return FALSE if this field is of the same type and has the same value as f.
Definition SoField.h:516
int getNumConnections() const
Returns the number of connections to this field.
Definition SoField.h:373
SbBool getConnectedEngine(SoEngineOutput *&engineOutput) const
Returns TRUE if this field is being written into by an engine, and returns the engine output it is co...
SbBool getConnectedVRMLInterp(SoVRMLInterpOutput *&interpOutput) const
Returns the VRMLInterpolator output field is connected to.
SoFieldContainer * getContainer() const
Returns the object that contains this field.
SbBool appendConnection(SoEngineOutput *engineOutput)
Appends this field to the list of connections from another engineOutput.
Maintains a list of pointers to fields.
Definition SoFieldList.h:72
Sensor class that can be attached to Open Inventor fields.
Used to read Open Inventor data files.
Definition SoInput.h:363
<a href="IconLegend.html"><img src="extTGS.gif" alt="VSG extension" border="0"></a> Handle memory bu...
Used to write Open Inventor data files.
Definition SoOutput.h:186
Stores runtime type information.
Definition SoType.h:98
Base class for object storing runtime type information.
int SbBool
Boolean type.
Definition SbBase.h:87