select (lx_select.hpp)

From The Foundry MODO SDK wiki
Jump to: navigation, search
There are security restrictions on this page


Selection

The types of entities that can be selected are determined by the extensible ILxSelectionType interface. Individual selections themselves are defined as opaque packets which are allocated and managed by the selection system. For extracting specific information about the selection, the selection type can provide an alternate packet translation interface.

(1) SDK: Declarations
 #define LXu_SELECTIONTYPE       "6f0E612B-4462-43B5-84D3-A6FCA7C8EF94"
 #define LXa_SELECTIONTYPE       "SelectionType"

A selection type is defined by a few methods:

Size
This returns the packet size in bytes. The selection system itself will handle memory management. In general the packet should be as small as possible.
Flags
The flags give information about the selection type. If UNDOABLE is set then the selection will be managed as part of the undoable model state.

(2) SDK: Declarations

MessageTable
This returns the name of the message table for the selection type. The message table will be used to find user messages for the selection type.
Compare
This method compares two packets and returns a ranking using the same sign logic as strcmp(). This is used to sort packets and to search on packets.
SubType
This returns the subtype of the packet. For selections that can contain heterogenous elements this should be non-zero, while for selections where all the elements are the same this should be zero.

(3) SDK: ILxSelectionType interface
         LXxMETHOD(  unsigned int,
 Size) (
         LXtObjectID              self);
 
         LXxMETHOD(  unsigned int,
 Flags) (
         LXtObjectID              self);
 
         LXxMETHOD(  const char *,
 MessageTable) (
         LXtObjectID              self);
 
         LXxMETHOD(  int,
 Compare) (
         LXtObjectID              self,
         void                    *pkey,
         void                    *pelt);
 
         LXxMETHOD(  unsigned int,
 SubType) (
         LXtObjectID              self,
         void                    *pkt);

User methods allow the selection type wrapper to be initialized given the name or type code for a selection type.

(4) User Class: SelectionType method
         bool
 fromType (
         const char              *name)
 {
         CLxLoc_SelectionService  svc;
         LXtObjectID              obj;
         LxResult                 rc;
 
         rc = svc.Allocate (name, &obj);
         if (LXx_FAIL (rc))
                 return false;
 
         return take (obj);
 }
 
         bool
 fromType (
         LXtID4                   type)
 {
         CLxLoc_SelectionService  svc;
 
         return fromType (svc.LookupName (type));
 }

Empty SelectionType Python user class.

(5) PY: SelectionType method
 pass

Selection Events

The ILxSelectionListener interface allows SDK clients to listen to the global selection events. These are just methods that the client defines that we will call to signal change events.

(6) SDK: ILxSelectionListener interface
         LXxMETHOD(  void,
 Current) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  void,
 Add) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned int             subtType);
 
         LXxMETHOD(  void,
 Remove) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned int             subtType);
 
         LXxMETHOD(  void,
 Time) (
         LXtObjectID              self,
         double                   time);
 
         LXxMETHOD(  void,
 TimeRange) (
         LXtObjectID              self,
         LXtID4                   type);

(7) SDK: Declarations
 #define LXu_SELECTIONLISTENER   "32E1B478-F2F6-41A8-9D79-14919B793AFE"
 #define LXa_SELECTIONLISTENER   "selectionListener"

Empty SelectionListener Python user class.

(8) PY: SelectionListener method
 pass

Global Interfaces

The selection system is wrapped by a selection service interface for reading and altering the selection state. The ILxSelectionService interface has the obligatory SQ method, and some basic methods to read the current state of the selection by type.

(9) SDK: ILxSelectionService interface
         LXxMETHOD(  LxResult,
 ScriptQuery) (
         LXtObjectID              self,
         void                   **ppvObj);
 
         LXxMETHOD(  int,
 Count) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  void *,
 ByIndex) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned int             idx);
 
         LXxMETHOD(  void *,
 Recent) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LxResult,
 Test) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);

Clients can also enumerate packets in sequence, which may be more efficient than accessing them by index for loops that want to hit everything. ScanLoop() gets all elements of the given type, while ScanLoopCurrent() gets only those that match the current subtypes.

(10) SDK: Types
 typedef void *           LXtScanInfoID;

(11) SDK: ILxSelectionService interface
         LXxMETHOD(  LXtScanInfoID,
 ScanLoop) (
         LXtObjectID              self,
         LXtScanInfoID            scan,
         LXtID4                   type,
         void                   **packet);
 
         LXxMETHOD(  LXtScanInfoID,
 ScanLoopCurrent) (
         LXtObjectID              self,
         LXtScanInfoID            scan,
         LXtID4                   type,
         void                   **packet);

Editing the selection can be done selecting or deselecting, removing packets from all selections, and manipulating the batch state.

(12) SDK: ILxSelectionService interface
         LXxMETHOD(  LxResult,
 Select) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);
 
         LXxMETHOD(  LxResult,
 Deselect) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);
 
         LXxMETHOD(  LxResult,
 Remove) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);
 
         LXxMETHOD(  LxResult,
 Toggle) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);
 
         LXxMETHOD(  LxResult,
 Drop) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LxResult,
 StartBatch) (
         LXtObjectID              self);
 
         LXxMETHOD(  LxResult,
 EndBatch) (
         LXtObjectID              self);
 
         LXxMETHOD(  LxResult,
 AbortBatch) (
         LXtObjectID              self);

These methods allow clients to look up name-type associations and to allocate our own instances of the packet interface.

(13) SDK: ILxSelectionService interface
         LXxMETHOD(  const char *,
 LookupName) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LXtID4,
 LookupType) (
         LXtObjectID              self,
         const char              *name);
 
         LXxMETHOD( LxResult,
 Allocate) (
         LXtObjectID              self,
         const char              *name,
         void                   **ppvObj);

These methods allow clients to read and set the current time.

(14) SDK: ILxSelectionService interface
         LXxMETHOD(  double,
 GetTime) (
         LXtObjectID              self);
 
         LXxMETHOD(  LxResult,
 SetTime) (
         LXtObjectID              self,
         double                   time);

This is like Drop() but doesn't change the current selection mode.

(15) SDK: ILxSelectionService interface
         LXxMETHOD(  LxResult,
 Clear) (
         LXtObjectID              self,
         LXtID4                   type);

This is similar to Test(), but returns the actual selection state for the element. State can have one or more of the LXf_SELECTION_* bits set, or be LXf_SELECTION_NONE.

(16) SDK: ILxSelectionService interface
         LXxMETHOD(  int,
 State) (
         LXtObjectID              self,
         LXtID4                   type,
         void                    *packet);

LXf_SELECTION_NONE
Element is not selected, nor recently selected.
LXf_SELECTION_PRIMARY
First element for its selection type.
LXf_SELECTION_SECONDARY
Present in the selection, but not as the primary element.
LXf_SELECTION_LAST
Last element of its selection type.
LXf_SELECTION_CURRENT
Present in the current selection at any location.
LXf_SELECTION_HISTORY
Not found in the active selection but still existing in the cache of recently deselected elements.

(17) SDK: Declarations
 #define LXf_SELECTION_NONE              0x00
 #define LXf_SELECTION_PRIMARY           0x01
 #define LXf_SELECTION_SECONDARY         0x02
 #define LXf_SELECTION_LAST              0x04
 #define LXf_SELECTION_CURRENT           0x08
 #define LXf_SELECTION_HISTORY           0x10

This returns the most recent selection type -- the one the user acted on last. If 'types' is non-null, it will be an array of types terminated with zero, and the type returned will be one of the ones in the list.

(18) SDK: ILxSelectionService interface
         LXxMETHOD(  LXtID4,
 CurrentType) (
         LXtObjectID              self,
         const LXtID4            *types);

Nicer ways to get a selection type implementation in C++.

(19) User Service Class: SelectionService method
         bool
 GetImplementation (
         const char              *name,
         CLxLoc_SelectionType    &sel)
 {
         LXtObjectID               obj;
         LxResult                  rc;
 
         rc = Allocate (name, &obj);
         if (LXx_FAIL (rc))
                 return false;
 
         return sel.take (obj);
 }
 
         bool
 GetImplementation (
         LXtID4                   type,
         CLxLoc_SelectionType    &sel)
 {
         const char              *name;
 
         name = LookupName (type);
         if (!name)
                 return false;
 
         return GetImplementation (name, sel);
 }

This returns the list of current subtypes into the client's array. If the number of current subtypes is laarger than the length of the buffer then SHORTBUFFER is returned.

(20) SDK: ILxSelectionService interface
         LXxMETHOD(  LxResult,
 CurrentSubTypes) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned                *sub,
         unsigned                 len,
         unsigned                *num);

User class gives a nice wrapper method for getting the array.

(21) User Service Class: SelectionService method
         LxResult
 GetSubtypeList (
         LXtID4                   type,
         std::vector<unsigned>   &subTypes)
 {
         LxResult                 rc;
         unsigned                *buf;
         unsigned                 i, n;
         size_t                   len;
 
         subTypes.clear ();
         len = 128;
         while (1)
         {
                 buf = new unsigned [len];
 
                 rc = CurrentSubTypes (type, buf, static_cast<unsigned>(len), &n);
                 if (rc != LXe_SHORTBUFFER)
                         break;
 
                 delete[] buf;
                 len *= 2;
         }
 
         if (LXx_OK (rc))
                 for (i = 0; i < n; i++)
                         subTypes.push_back (buf[i]);
 
         delete[] buf;
         return rc;
 }

Empty selection service Python user class.

(22) PY: SelectionService method
 pass

This service has the same GUID as the old SelectionStack interface. They have the same second and third methods, which are all that were ever used in plug-ins, so we should be good for backwards compatibility.

(23) SDK: Declarations
 #define LXu_SELECTIONSERVICE    "6AEF6F27-046F-4C04-90E0-994D742851E7"
 #define LXa_SELECTIONSERVICE    "selectionservice"

This is a legacy service global that implements a subset of the monolithic service. Since we used it in the old wrappers we need to allow queries to succeed.

(24) SDK: ILxSelectionPacket1Service interface
         LXxMETHOD(  LxResult,
 ScriptQuery) (
         LXtObjectID              self,
         void                   **ppvObj);
 
         LXxMETHOD(  const char *,
 LookupName) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LXtID4,
 LookupType) (
         LXtObjectID              self,
         const char              *name);
 
         LXxMETHOD( LxResult,
 Allocate) (
         LXtObjectID              self,
         const char              *name,
         void                   **ppvObj);

(25) SDK: Declarations
 #define LXu_SELECTIONPACKET1SERVICE     "58D8DEAD-3B0C-41FB-AC1E-B17A36521D44"