mesh (lx_mesh.hpp)

From The Foundry MODO SDK wiki
(Redirected from ILxEdge (index))
Jump to: navigation, search
There are security restrictions on this page


Contents

Mesh Service

The mesh service provides high-level mesh system access. These methods are provided as general services that could be useful on any mesh.

(1) SDK: LXa_MESHSERVICE, etc. defines
 #define LXa_MESHSERVICE "meshservice"
 #define LXu_MESHSERVICE "82B739EC-F92E-4CC9-A5FB-584A866D5897"

(2) SDK: MeshService::ScriptQuery
         LXxMETHOD(  LxResult,
 ScriptQuery) (
         LXtObjectID              self,
         void                   **ppvObj);

Mark Modes

Mark modes are collections of bits of two types: the ones required to be set and ones required to be clear. To be specific, this is not simply turning a bit on or off; a bit can be required to be set or can be required to be clear based on the mark mode. The mesh service allows mark mode masks to be created and read via strings. The mode which matches anything (and changes nothing) is always just zero.

(3) SDK: Types
 typedef unsigned int    LXtMarkMode;
 #define LXiMARK_ANY     ((LXtMarkMode) 0)
 
 #define LXsMARK_HIDE    "hide"
 #define LXsMARK_HALO    "halo"
 #define LXsMARK_LOCK    "lock"
 #define LXsMARK_SELECT  "select"
 #define LXsMARK_USER_0  "user0"
 #define LXsMARK_USER_1  "user1"
 #define LXsMARK_USER_2  "user2"
 #define LXsMARK_USER_3  "user3"
 #define LXsMARK_USER_4  "user4"
 #define LXsMARK_USER_5  "user5"
 #define LXsMARK_USER_6  "user6"
 #define LXsMARK_USER_7  "user7"

This method allows multiple mode bits to be marked as "must be set" or "must be cleared". The two arguments take a space-delimited list of modes to set or clear, failing with LXe_NOTFOUND if the mode is unknown. Either argument can be NULL.

(4) SDK: MeshService::ModeCompose
         LXxMETHOD(  LxResult,
 ModeCompose) (
         LXtObjectID              self,
         const char              *set,
         const char              *clear,
         LXtMarkMode             *mode);

(5) SDK: ModeCompose Example
 // Get a mark mode which requires the "select" bit to be set
 rc = meshService[0]->ModeCompose (meshService, "select", NULL, &mode);
 
 // Require "user1" to be set and both "hide" and "lock" to be clear
 rc = meshService[0]->ModeCompose (meshService, "user1",  "hide lock", &mode);

The user class has a couple of methods to get modes that just set and clear.

(6) SDK: CLxUser_MeshService::SetMode method
         LXtMarkMode
 SetMode (
         const char              *set)
 {
         LXtMarkMode              mode;
 
         ModeCompose (set, 0, &mode);
         return mode;
 }
 
         LXtMarkMode
 ClearMode (
         const char              *clr)
 {
         LXtMarkMode              mode;
 
         ModeCompose (0, clr, &mode);
         return mode;
 }

Vertex Map Types

Vertex map types have names and codes which can be translated with these functions.

(7) SDK: MeshService::VMapLookupType, etc.
         LXxMETHOD(  LxResult,
 VMapLookupType) (
         LXtObjectID              self,
         const char              *name,
         LXtID4                  *type);
 
         LXxMETHOD(  LxResult,
 VMapLookupName) (
         LXtObjectID              self,
         LXtID4                   type,
         const char             **name);

It can also be useful to find the features of a vertex map type without requiring an actual instance. These functions are equivalent to the same-named functions in the mesh map interface.

(8) SDK: MeshService::VMapDimension, etc.
         LXxMETHOD(  LxResult,
 VMapDimension) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned int            *dimension);
 
         LXxMETHOD(  LxResult,
 VMapIsEdgeMap) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LxResult,
 VMapIsContinuous) (
         LXtObjectID              self,
         LXtID4                   type);
 
         LXxMETHOD(  LxResult,
 VMapZeroDefault) (
         LXtObjectID              self,
         LXtID4                   type);

Client Meshes

Clients can create their own private mesh objects, not affiliated with any item.

(9) SDK: MeshService::CreateMesh
         LXxMETHOD(  LxResult,
 CreateMesh) (
         LXtObjectID              self,
         void                   **ppvObj);

(10) SDK: CLxUser_MeshService::NewMesh method
         bool
 NewMesh (
         CLxLoc_Mesh             &mesh)
 {
         return CreateMesh (mesh);
 }

This converts a private mesh to a static mesh.

(11) SDK: MeshService::ConvertMesh
         LXxMETHOD(  LxResult,
 ConvertMesh) (
         LXtObjectID              self,
         LXtObjectID              triGroupObj,
         LXtObjectID              meshObj);

Some of the tool packets still use the obsolete LXtMeshID type. These functions allow you to convert between mesh IDs and mesh objects. These functions should be used carefully since they're not very safe. That's why the LXtMeshID was retired in the first place.

(12) SDK: MeshService::MeshFromMeshID, etc.
         LXxMETHOD(  LxResult,
 MeshFromMeshID) (
         LXtObjectID              self,
         LXtMeshID                meshID,
         void                   **ppvObj);
 
         LXxMETHOD(  LXtMeshID,
 MeshToMeshID) (
         LXtObjectID              self,
         LXtObjectID              mesh);

Defined here and in lxmeshOLD, protected because of gcc whining.

(13) SDK: Types
 #ifndef   LX_DEF_LXTMESHID
   #define LX_DEF_LXTMESHID
   typedef struct st_Mesh *      LXtMeshID;
 #endif

Empty mesh service Python user class.

(14) PY: empty Service.Mesh user class
 pass

This converts any surface to a static mesh.

(15) SDK: MeshService::SurfaceToTriGroup
         LXxMETHOD(  LxResult,
 SurfaceToTriGroup) (
         LXtObjectID              self,
         LXtObjectID              triGroupObj,
         LXtObjectID              surfObj);

This converts a static mesh to an editable mesh.

(16) SDK: MeshService::MeshFromTriGroup
         LXxMETHOD(  LxResult,
 MeshFromTriGroup) (
         LXtObjectID              self,
         LXtObjectID              meshObj,
         LXtObjectID              triGroupObj);

Static meshes can be rigidly transformed.

(17) SDK: MeshService::TriGroupTransform
         LXxMETHOD(  LxResult,
 TriGroupTransform) (
         LXtObjectID              self,
         LXtObjectID              triGroupObj,
         LXtMatrix4               xfrm);

Polygon Edit Services

Creates a ILxPolygonSlice object which slices polygons.

(18) SDK: MeshService::CreateSlice
         LXxMETHOD(  LxResult,
 CreateSlice) (
         LXtObjectID              self,
         void                   **ppvObj);

Creates a ILxSolidDrill object which slices polygons.

(19) SDK: MeshService::CreateSolidDrill
         LXxMETHOD(  LxResult,
 CreateSolidDrill) (
         LXtObjectID              self,
         void                   **ppvObj);

(20) SDK: CLxUser_MeshService::NewSolidDrill method
         bool
 NewSolidDrill (
         CLxLoc_SolidDrill       &drill)
 {
         return CreateSolidDrill (drill);
 }

Nexus 10

This returns LXe_TRUE if the specified mesh item is procedural and LXe_FALSE if it isn't.

(21) SDK: MeshService::IsMeshProcedural
         LXxMETHOD(  LxResult,
 IsMeshProcedural) (
         LXtObjectID              self,
         LXtObjectID              item);

Returns an Item object that a mesh belongs to. For private meshes, the function fails.

(22) SDK: MeshService::ItemFromMesh
         LXxMETHOD(  LxResult,
 ItemFromMesh) (
         LXtObjectID              self,
         LXtObjectID              mesh,
         void                   **ppvObj);

(23) SDK: CLxUser_MeshService::GetMeshItem method
         bool
 GetMeshItem (
         ILxUnknownID             mesh,
         CLxLoc_Item             &item)
 {
         LXtObjectID              obj = NULL;
 
         if (LXx_FAIL (ItemFromMesh (mesh, &obj)))
                 return false;
 
         return item.take (obj);
 }

Returns a curve group for the provided mesh, allowing the polygonal curves to be enumerated and evaluated.

(24) SDK: MeshService::CurveGroupFromMesh
         LXxMETHOD(  LxResult,
 CurveGroupFromMesh) (
         LXtObjectID               self,
         LXtObjectID               mesh,
         const LXtMatrix4          xfrm,
         void                    **ppvObj);

Returns a mesh from a surface interface.

(25) SDK: MeshService::MeshFromSurface
         LXxMETHOD(  LxResult,
 MeshFromSurface) (
         LXtObjectID              self,
         LXtObjectID              meshObj,
         LXtObjectID              surfItem,
         LXtObjectID              surfObj);

Returns a surface from a mesh. In the majority of cases, the mesh item can be evaluated directly for a surface. However if you have a private mesh, this function can be used.

(26) SDK: MeshService::SurfaceFromMesh
         LXxMETHOD(  LxResult,
 SurfaceFromMesh) (
         LXtObjectID              self,
         LXtObjectID              mesh,
         LXtObjectID              meshItem,
         void                    **ppvObj);

Mesh Interface

The the ILxMesh object is the core interface for manipulating meshes. It is also responsible for spawning accessors, which provide access to the points, polygons, edges, and maps within the mesh. Multiple independent accessors can be spawned for each mesh.

(27) SDK: LXa_MESH, etc. defines
 #define LXa_MESH        "mesh3"
 #define LXu_MESH        "8C7F1CF3-8CE8-4395-9324-A16DD63B4AFE"
 
 #define LXsTYPE_MESH    "mesh"

Points, polygons, edges and maps are referenced by these types. These are not COM objects, but are simply identifiers for specific elements which are then accessed through the accessors.

(28) SDK: LXtPointID, etc. typedefs (types)
 typedef struct st_MeshVertex *    LXtPointID;
 typedef struct st_MeshPolygon *   LXtPolygonID;
 typedef struct st_MeshEdge *      LXtEdgeID;
 typedef struct st_MeshVertexMap * LXtMeshMapID;

Element Counts

These methods return the number of elements of their type in the mesh.

(29) SDK: Mesh::PointCount, etc.
         LXxMETHOD(  LxResult,
 PointCount) (
         LXtObjectID              self,
         unsigned int            *count);
 
         LXxMETHOD(  LxResult,
 PolygonCount) (
         LXtObjectID              self,
         unsigned int            *count);
 
         LXxMETHOD(  LxResult,
 EdgeCount) (
         LXtObjectID              self,
         unsigned int            *count);
 
         LXxMETHOD(  LxResult,
 MapCount) (
         LXtObjectID              self,
         unsigned int            *count);

User class variants gets the counts directly, with minimal checking.

(30) SDK: CLxUser_Mesh::NPoints method
         int
 NPoints () const
 {
         unsigned         count;
 
         if (LXx_OK (PointCount (&count)))
                 return count;
         return -1;
 }
 
         int
 NPolygons () const
 {
         unsigned         count;
 
         if (LXx_OK (PolygonCount (&count)))
                 return count;
         return -1;
 }
 
         int
 NEdges () const
 {
         unsigned         count;
 
         if (LXx_OK (EdgeCount (&count)))
                 return count;
         return -1;
 }
 
         int
 NMaps () const
 {
         unsigned         count;
 
         if (LXx_OK (MapCount (&count)))
                 return count;
         return -1;
 }

Empty Mesh Python user class.

(31) PY: empty Mesh user class
 pass

Mesh Properties

This method returns the bounding box of the mesh.

(32) SDK: Mesh::BoundingBox
         LXxMETHOD(  LxResult,
 BoundingBox) (
         LXtObjectID              self,
         LXtMarkMode              pick,
         LXtBBox                 *bbox);

This method returns the maximum number of polygons shared by any point in the mesh.

(33) SDK: Mesh::MaxPointPolygons
         LXxMETHOD(  LxResult,
 MaxPointPolygons) (
         LXtObjectID              self,
         LXtMarkMode              pick,
         unsigned int            *count);

This method returns the maximum size of any polygon marked in the mesh.

(34) SDK: Mesh::MaxPolygonSize
         LXxMETHOD(  LxResult,
 MaxPolygonSize) (
         LXtObjectID              self,
         LXtMarkMode              pick,
         unsigned int            *count);

Sets the the value of the specified tag that will be applied to any newly created polys.

(35) SDK: Mesh::PolyTagSetDefault
         LXxMETHOD(  LxResult,
 PolyTagSetDefault) (
         LXtObjectID              self,
         LXtID4                   type,
         const char              *tag);

Allocating Accessors

Most data about a mesh is obtained through the accessors. These methods return new accessors, which must be released by the client when no longer needed. Multiple accessors can exist at the same time for the same mesh without conflicting. Accessors can be used to walk the list of elements in a mesh or to obtain specific information about a particular element.

These methods create and return the various accessors. Each one is unique to the caller can so can be used in parallel with others obtained from these methods.

(36) SDK: Mesh::PointAccessor, etc.
         LXxMETHOD(  LxResult,
 PointAccessor) (
         LXtObjectID              self,
         void                   **ppvObj);
 
         LXxMETHOD(  LxResult,
 PolygonAccessor) (
         LXtObjectID              self,
         void                   **ppvObj);
 
         LXxMETHOD(  LxResult,
 EdgeAccessor) (
         LXtObjectID              self,
         void                   **ppvObj);
 
         LXxMETHOD(  LxResult,
 MeshMapAccessor) (
         LXtObjectID              self,
         void                   **ppvObj);

(37) SDK: Declarations
 

User class methods allocate directly into the user classes for the accessors.

(38) SDK: CLxUser_Mesh::GetPoints method
         bool
 GetPoints (
         CLxLoc_Point            &acc)
 {
         return PointAccessor (acc);
 }
 
         bool
 GetPolygons (
         CLxLoc_Polygon          &acc)
 {
         return PolygonAccessor (acc);
 }
 
         bool
 GetEdges (
         CLxLoc_Edge             &acc)
 {
         return EdgeAccessor (acc);
 }
 
         bool
 GetMaps (
         CLxLoc_MeshMap          &acc)
 {
         return MeshMapAccessor (acc);
 }

If a mesh is accessed for write, any edits made have to be signalled back to the mesh.

(39) SDK: Mesh::SetMeshEdits
         LXxMETHOD(  LxResult,
 SetMeshEdits) (
         LXtObjectID              self,
         unsigned int             edits);

(40) SDK: LXf_MESHEDIT_POSITION, etc. defines

Polygon Type Attributes

Polygon types can have overall settings that affect all the polygons of that type in the mesh.

Set and get SUBD subdivision level for the mesh.

(41) SDK: Mesh::SUBDGetLevel
         LXxMETHOD(  LxResult,
 SUBDGetLevel) (
         LXtObjectID              self,
         int                     *n);

(42) SDK: Mesh::SUBDSetLevel
         LXxMETHOD(  LxResult,
 SUBDSetLevel) (
         LXtObjectID              self,
         int                      n);

Set and get SUBD UV interpolation flag.

(43) SDK: Mesh::SUBDGetLinearUV
         LXxMETHOD(  LxResult,
 SUBDGetLinearUV) (
         LXtObjectID              self,
         int                     *isLinear);

(44) SDK: Mesh::SUBDSetLinearUV
         LXxMETHOD(  LxResult,
 SUBDSetLinearUV) (
         LXtObjectID              self,
         int                      isLinear);

Set and get PSUB boundary rules. They are mapped to "smooth", "crease all" and "crease edges" in definitions of prman.

(45) SDK: LXiPSUB_BOUND_SMOOTH, etc. defines

(46) SDK: Mesh::PSUBGetBoundRule
         LXxMETHOD(  LxResult,
 PSUBGetBoundRule) (
         LXtObjectID              self,
         int                     *bound);

(47) SDK: Mesh::PSUBSetBoundRule
         LXxMETHOD(  LxResult,
 PSUBSetBoundRule) (
         LXtObjectID              self,
         int                      bound);

601 Methods

Give a mesh interface and another mesh object, this returns true if they refer to the same actual mesh.

(48) SDK: Mesh::TestSameMesh
         LXxMETHOD(  LxResult,
 TestSameMesh) (
         LXtObjectID              self,
         LXtObjectID              other);

(49) SDK: CLxUser_Mesh::IsSame method
         bool
 IsSame (
         ILxUnknownID             other)
 {
         return (TestSameMesh (other) == LXe_TRUE);
 }

These methods separate contents of a PICK ptag into component selection sets, presenting a list of the distinct selection sets, rather than the large and redundant list of all distinct PICK poly tag values.

(50) SDK: Mesh::PTagCount
         LXxMETHOD(  unsigned,
 PTagCount) (
         LXtObjectID              self,
         LXtID4                   type);

(51) SDK: Mesh::PTagByIndex
         LXxMETHOD(  LxResult,
 PTagByIndex) (
         LXtObjectID              self,
         LXtID4                   type,
         unsigned                 index,
         const char              **tag);

Catmull-Clark Methods

Set and get PSUB subdivision level for the mesh.

(52) SDK: Mesh::PSUBGetLevel
         LXxMETHOD(  LxResult,
 PSUBGetLevel) (
         LXtObjectID              self,
         int                     *n);

(53) SDK: Mesh::PSUBSetLevel
         LXxMETHOD(  LxResult,
 PSUBSetLevel) (
         LXtObjectID              self,
         int                      n);

Set and get PSUB subdivision level for the mesh.

(54) SDK: Mesh::PSUBGetCurrentLevel
         LXxMETHOD(  LxResult,
 PSUBGetCurrentLevel) (
         LXtObjectID              self,
         int                     *n);

(55) SDK: Mesh::PSUBSetCurrentLevel
         LXxMETHOD(  LxResult,
 PSUBSetCurrentLevel) (
         LXtObjectID              self,
         int                      n);

(56) SDK: Mesh::PSUBSetSubdivObj
         LXxMETHOD(  LxResult,
 PSUBSetSubdivObj) (
         LXtObjectID              self,
         LXtObjectID              subObj);

(57) SDK: Mesh::ChangeEvent
         LXxMETHOD(  LxResult,
 ChangeEvent) (
         LXtObjectID              self,
         unsigned                 event);

Multi-Resolution layers

Multi-Resolution layers are new displacement data for 901. Displpacement vectors in layers are composited based on the opacity ratio.

This method returns number of multi-resolution layer.

(58) SDK: Mesh::PSUBDispNumLayer
         LXxMETHOD(  LxResult,
 PSUBDispNumLayer) (
         LXtObjectID              self,
         int                     *num);

This method returns name of multi-resolution layer for given layer index.

(59) SDK: Mesh::PSUBDispLayerName
         LXxMETHOD(  const char *,
 PSUBDispLayerName) (
         LXtObjectID              self,
         int                      index);

This method look up multi-resolution layer by layer name and set the index and retruns OK if it is found.

(60) SDK: Mesh::PSUBDispLayerLookupByName
         LXxMETHOD(  LxResult,
 PSUBDispLayerLookupByName) (
         LXtObjectID              self,
         const char              *name,
         int                     *index);

This method returns the current selected multi-resolution layer. index.

(61) SDK: Mesh::PSUBDispLayerCurrent
         LXxMETHOD(  LxResult,
 PSUBDispLayerCurrent) (
         LXtObjectID              self,
         int                     *index);

This method returns the enable state of multi-resolution layer for given layer index.

(62) SDK: Mesh::PSUBDispLayerEnable
         LXxMETHOD(  LxResult,
 PSUBDispLayerEnable) (
         LXtObjectID              self,
         int                      index,
         int                     *enable);

This method returns the opacity of multi-resolution layer for given layer index.

(63) SDK: Mesh::PSUBDispLayerOpacity
         LXxMETHOD(  LxResult,
 PSUBDispLayerOpacity) (
         LXtObjectID              self,
         int                      index,
         double                  *opacity);

This method set the opacity of multi-resolution layer for given layer index. This is not undoable action.

(64) SDK: Mesh::PSUBDispLayerSetOpacity
         LXxMETHOD(  LxResult,
 PSUBDispLayerSetOpacity) (
         LXtObjectID              self,
         int                      index,
         double                   opacity);

Nexus 10

If multiple operations need to be batched together, this function will start and end a mesh edit batch on the specified mesh.

(65) SDK: Mesh::BeginEditBatch, etc.
         LXxMETHOD( LxResult,
 BeginEditBatch) (
         LXtObjectID              self);
 
         LXxMETHOD( LxResult,
 EndEditBatch) (
         LXtObjectID              self);

This merges the provided mesh with the current mesh, copying all the data from other. The flags argument controls which elements are copied from the source mesh to the target mesh.

(66) SDK: LXf_MESHMERGE_PTAG, etc. defines

(67) SDK: Mesh::Merge
         LXxMETHOD(  LxResult,
 Merge) (
         LXtObjectID              self,
         LXtObjectID              other,
         unsigned int             flags);

This removes all data in the current mesh.

(68) SDK: Mesh::Clear
         LXxMETHOD(  LxResult,
 Clear) (
         LXtObjectID              self);

Nexus 11

Often, it can be useful to track multiple changes to a mesh within a particular time period. The TrackChanges function returns an ILxMeshTracker interface. The MeshTracker will collect a series of changes to a base mesh, along with a list of modified points and polygons. Multiple trackers can be created per mesh, each with their own lifetime, independent of the mesh.

(69) SDK: Mesh::TrackChanges
         LXxMETHOD (  LxResult,
 TrackChanges) (
         LXtObjectID               self,
         void                    **ppvObj);

Accessors

Common Accessor Methods

Each of the accessors have similar methods for walking their respective lists of elements, spawning new copies of the accessor, etc.

This method creates a new instance of the accessor. The initial state is the same as the original accessor, but it is completely independent and can be separately manipulated. This is useful if you want to keep this element's information around while you continue to manipulate the original accessor.

(70) Common Accessor Methods
         LXxMETHOD(  LxResult,
 Spawn) (
         LXtObjectID              self,
         void                   **ppvObj);

(71) SDK: Declarations
 

This method can be used to test an element's mark bits against a mark mode, returning LXe_TRUE if they match and LXe_FALSE if they don't.

(72) Common Geometry Accessor Methods
         LXxMETHOD(  LxResult,
 TestMarks) (
         LXtObjectID              self,
         LXtMarkMode              mode);

This method can be used to change the marks on an element. Bits set in the mode will be set, and bits clear in the mode will be cleared. All other bits will be unchanged. This does not require the mesh to be editable.

(73) Common Geometry Accessor Methods
         LXxMETHOD(  LxResult,
 SetMarks) (
         LXtObjectID              self,
         LXtMarkMode              set);

These are common user class methods that are common to the different enumerators. We have a constructor that can take a mesh user object and spawn the right type of accessor. Alternately we can set the interface from a raw mesh object. User class duplicate method makes a copy of this accessor using Spawn() into the user class of the same type.

(74) Common $$ User Methods
 CLxUser_$$ (
         CLxLoc_Mesh             &mesh)
 {
         _init ();
         fromMesh (mesh);
 }
 
         bool
 fromMesh (
         CLxLoc_Mesh             &mesh)
 {
         LXtObjectID              acc;
 
         clear ();
         if (mesh.test () && LXx_OK (mesh.$$Accessor (&acc)))
                 return take (acc);
 
         return false;
 }
 
         bool
 fromMeshObj (
         ILxUnknownID             obj)
 {
         CLxLoc_Mesh              mesh (obj);
         LXtObjectID              acc;
 
         clear ();
         if (mesh.test () && LXx_OK (mesh.$$Accessor (&acc)))
                 return take (acc);
 
         return false;
 }
 
         bool
 duplicate (
         CLxLoc_$$               &acc)
 {
         LXtObjectID              obj;
 
         acc.clear ();
         if (LXx_FAIL (Spawn (&obj)))
                 return false;
 
         return acc.take (obj);
 }

The C++ version of the test method returns a native boolean.

(75) Common Marking User Methods
         bool
 Test (
         LXtMarkMode              mode)
 {
         return (TestMarks (mode) == LXe_TRUE);
 }

Enumeration

The fastest method of traversing the mesh is an enumeration. The mode selects which subset of elements to traverse. The visitor will be called with the accessor set to each successive element. The optional monitor allows the caller to track the progress of the enumeration.

If the visitor returns an error code, the enumeration will be aborted and that code will be returned directly from Enumerate().

For example, the return code LXe_FALSE can be returned by the visitor to exit early.

Note that the monitor will itself return LXe_ABORT should the user manually abort the operation by clicking the abort button.

(76) Common Accessor Methods
         LXxMETHOD(  LxResult,
 Enumerate) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         LXtObjectID              visitor,
         LXtObjectID              monitor);

C++ Enumeration is done by the user passing in a visitor. We create a generic visitor as a COM object on the stack and pass that to the real enumeration method. Our generic visitor will then call the user's real abstract visitor's Evaluate() method. The LxResult is returned because the enumeration can terminate on different error codes from the user.

(77) Common Enumerator User Methods
         LxResult
 Enum (
         CLxImpl_AbstractVisitor *visitor,
         LXtMarkMode              mode = LXiMARK_ANY,
         ILxUnknownID             mon  = 0)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
         return Enumerate (mode, gv, mon);
 }

Point Accessor

The ILxPoint is a combination of an accessor for specific points, as well as providing a mechanism to walk the mesh's point list.

(78) SDK: LXa_POINT, etc. defines
 #define LXa_POINT       "point"
 #define LXu_POINT       "37B477FE-ED3C-4EDC-A4A8-9BB24F58A4E6"

As mentioned previously, all accessors share common interface methods for walking their respective lists.

(79) SDK: ILxPoint interface
 ''[[#C70|Common Accessor Methods]]''
 ''[[#C72|Common Geometry Accessor Methods]]''

(80) User Class: Point method
 ''[[#C74|Common Point User Methods]]''
 ''[[#C75|Common Marking User Methods]]''
 ''[[#C77|Common Enumerator User Methods]]''

Selecting a Point to Access

This method sets the accessor to the given point. Only points that are known to be in the mesh should be passed to this method.

(81) SDK: Point::Select
         LXxMETHOD(  LxResult,
 Select) (
         LXtObjectID              self,
         LXtPointID               point);

A point can be selected by its index in the mesh.

(82) SDK: Point::SelectByIndex
         LXxMETHOD(  LxResult,
 SelectByIndex) (
         LXtObjectID              self,
         unsigned int             index);

A point can also be selected by its index within a polygon.

(83) SDK: Point::SelectPolygonVertex
         LXxMETHOD(  LxResult,
 SelectPolygonVertex) (
         LXtObjectID              self,
         LXtPolygonID             polygon,
         unsigned int             index);

Point Properties

This methods returns the ID of the curent point or null if none.

(84) SDK: Point::ID
         LXxMETHOD( LXtPointID,
 ID) (
         LXtObjectID              self);

This methods returns the index of the curent point.

(85) SDK: Point::Index
         LXxMETHOD( LxResult,
 Index) (
         LXtObjectID              self,
         unsigned int            *index);

This returns the position of the point.

(86) SDK: Point::Pos

This method returns the geometric normal of this point for the given polygon. This is the average of the connected polyon normals if the polygon is null.

(87) SDK: Point::Normal
         LXxMETHOD(  LxResult,
 Normal) (
         LXtObjectID              self,
         LXtPolygonID             pol,
         LXtVector                normal);

This returns the value of the current point in the given map. This returns LXe_FALSE for points with no value set in the map.

(88) SDK: Point::MapValue
         LXxMETHOD(  LxResult,
 MapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         float                   *value);

This method is the same as MapValue(), except that if the point is not in the map it will return zero for maps that allow that.

(89) SDK: Point::MapEvaluate
         LXxMETHOD(  LxResult,
 MapEvaluate) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         float                   *value);

These methods return the number of polygons sharing this point as a vertex, and get the polygon ID for a specific index.

(90) SDK: Point::PolygonCount, etc.
         LXxMETHOD(  LxResult,
 PolygonCount) (
         LXtObjectID              self,
         unsigned int            *count);
 
         LXxMETHOD(  LxResult,
 PolygonByIndex) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPolygonID            *polygonID);

Edit Operations

This creates a new point in the mesh. It sets the current point to the new point.

(91) SDK: Point::New
         LXxMETHOD(  LxResult,
 New) (
         LXtObjectID              self,
         const LXtVector          pos,
         LXtPointID              *pointID);

This creates a new point in the mesh duplicating the current point. If this point has already been copied this function returns the same pointer.

(92) SDK: Point::Copy
         LXxMETHOD(  LxResult,
 Copy) (
         LXtObjectID              self,
         LXtPointID              *pointID);

This removes a point from the mesh. Any polygons that use this point should already have been altered to remove the point from their vertex list. Maps are automatically updated to reflect the removed point.

(93) SDK: Point::Remove
         LXxMETHOD(  LxResult,
 Remove) (
         LXtObjectID              self);

This sets a point's position.

(94) SDK: Point::SetPos
         LXxMETHOD(  LxResult,
 SetPos) (
         LXtObjectID              self,
         const LXtVector          pos);

This sets the value for the point in the given map.

(95) SDK: Point::SetMapValue
         LXxMETHOD(  LxResult,
 SetMapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         const float             *value);

This removes any value for the point in the given map.

(96) SDK: Point::ClearMapValue
         LXxMETHOD(  LxResult,
 ClearMapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map);

Patch Operations

The corner control point for a vertex can also be accessed. This is the location of the actual intersection of the patch mesh.

(97) SDK: Point::Corner
         LXxMETHOD(  LxResult,
 Corner) (
         LXtObjectID              self,
         LXtFVector               pos);

Interconnection

These methods return the number of points connecting this point as a point, and get the point ID for a specific index.

(98) SDK: Point::PointCount
         LXxMETHOD(  LxResult,
 PointCount) (
         LXtObjectID              self,
         unsigned int            *count);

(99) SDK: Point::PointByIndex
         LXxMETHOD(  LxResult,
 PointByIndex) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPointID              *pointID);

These methods return the number of edges connecting this point as a point, and get the edge ID for a specific index.

(100) SDK: Point::EdgeCount
         LXxMETHOD(  LxResult,
 EdgeCount) (
         LXtObjectID              self,
         unsigned int            *count);

(101) SDK: Point::EdgeByIndex
         LXxMETHOD(  LxResult,
 EdgeByIndex) (
         LXtObjectID              self,
         unsigned int             index,
         LXtEdgeID               *edgeID);

Symmetry

This sets the symmetric point corresponding to the current point when the symmetry mode is enabled. This returns LXe_OK when the symmetric point is found, otherwise it returns LXe_FAILED. When the current point is on the symmetry center plane, it returns LXe_FAILED.

(102) SDK: Point::Symmetry
         LXxMETHOD(  LxResult,
 Symmetry) (
         LXtObjectID              self,
         LXtPointID              *pointID);

This returns LXe_TRUE if the symmetry state is enabled and the current point is on the symmetry center plane, otherwise it returns LXe_FALSE.

(103) SDK: Point::OnSymmetryCenter
         LXxMETHOD(  LxResult,
 OnSymmetryCenter) (
         LXtObjectID              self);

Empty Point Python user class.

(104) PY: empty Point user class
 pass

Polygon Accessor

The ILxPolygon is used to obtain information about specific polygons, as well as allowing the list of polygons to be walked.

(105) SDK: LXa_POLYGON, etc. defines
 #define LXa_POLYGON     "polygon2"
 #define LXu_POLYGON     "DD64141D-DC92-4348-B45B-F73FC64F1E52"

As mentioned previously, all accessors share common interface methods for walking their respective lists.

(106) SDK: ILxPolygon interface
 ''[[#C70|Common Accessor Methods]]''
 ''[[#C72|Common Geometry Accessor Methods]]''

(107) User Class: Polygon method
 ''[[#C74|Common Polygon User Methods]]''
 ''[[#C75|Common Marking User Methods]]''
 ''[[#C77|Common Enumerator User Methods]]''

Selecting a Polygon to Access

This method sets the accessor to the given polygon.

(108) SDK: Polygon::Select
         LXxMETHOD(  LxResult,
 Select) (
         LXtObjectID              self,
         LXtPolygonID             polygon);

(109) SDK: Polygon::SelectByIndex
         LXxMETHOD(  LxResult,
 SelectByIndex) (
         LXtObjectID              self,
         unsigned int             index);

Polygon Properties

This method returns the ID of the current polygon.

(110) SDK: Polygon::ID
         LXxMETHOD( LXtPolygonID,
 ID) (
         LXtObjectID              self);

This methods returns the index of the curent polygon.

(111) SDK: Polygon::Index
         LXxMETHOD( LxResult,
 Index) (
         LXtObjectID              self,
         int                     *index);

This returns the type of the polygon.

(112) SDK: Polygon::Type
         LXxMETHOD(  LxResult,
 Type) (
         LXtObjectID              self,
         LXtID4                  *type);

These return the number of vertices in the polygon, and get the point ID's by index.

(113) SDK: Polygon::VertexCount, etc.
         LXxMETHOD(  LxResult,
 VertexCount) (
         LXtObjectID              self,
         unsigned int            *count);
 
         LXxMETHOD(  LxResult,
 VertexByIndex) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPointID              *point);

There are two special polygon flags, which are used by curves. The first method returns LXe_TRUE if the first point on is an extended control point, while the second returns true if the last point is a control point. If the polygon is not a curve, this method fails.

(114) SDK: Polygon::FirstIsControlEndpoint, etc.
         LXxMETHOD(  LxResult,
 FirstIsControlEndpoint) (
         LXtObjectID              self);
 
         LXxMETHOD(  LxResult,
 LastIsControlEndpoint) (
         LXtObjectID              self);

This method returns the geometric normal of this polygon. This fails if there is no normal or the polygon has only one or two points. The normal is the same as the normal for the triangle containing the first point.

(115) SDK: Polygon::Normal
         LXxMETHOD(  LxResult,
 Normal) (
         LXtObjectID              self,
         LXtVector                normal);

This method gets the map value of a specific point in this polygon given a map. It returns LXe_FALSE if the specific is unmapped.

(116) SDK: Polygon::MapValue
         LXxMETHOD(  LxResult,
 MapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         LXtPointID               point,
         float                   *value);

Evaluating the map first tries to find a discontinuous value specific to this polygon. If there is none it falls back on the continuous value for the point itself. Failing that it may return zero for a map that allows that.

(117) SDK: Polygon::MapEvaluate
         LXxMETHOD(  LxResult,
 MapEvaluate) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         LXtPointID               point,
         float                   *value);

This function returns the approximate surface area of the current polygon.

(118) SDK: Polygon::Area
         LXxMETHOD(  LxResult,
 Area) (
         LXtObjectID              self,
         double                  *area);

Editing Operations

This method creates a new polygon of the given type from a prepared list of point IDs. If 'rev' is true, the point list will be used in reverse.

(119) SDK: Polygon::New
         LXxMETHOD(  LxResult,
 New) (
         LXtObjectID              self,
         LXtID4                   type,
         const LXtPointID        *vertices,
         unsigned int             numVert,
         unsigned int             rev,
         LXtPolygonID            *polygonID);

This method is the same as New(), but it copies the tags from the current polygon which is used as a prototype. Type can also be zero to copy the polygon type from the prototype.

(120) SDK: Polygon::NewProto
         LXxMETHOD(  LxResult,
 NewProto) (
         LXtObjectID              self,
         LXtID4                   type,
         const LXtPointID        *vertices,
         unsigned int             numVert,
         unsigned int             rev,
         LXtPolygonID            *polygonID);

This removes a polygon from the mesh.

(121) SDK: Polygon::Remove
         LXxMETHOD(  LxResult,
 Remove) (
         LXtObjectID              self);

These set if the first or last endpoints of a curve are control points, failing if this is not a curve-type polygon.

(122) SDK: Polygon::SetFirstIsControlEndpoint, etc.
         LXxMETHOD(  LxResult,
 SetFirstIsControlEndpoint) (
         LXtObjectID              self,
         int                      state);
 
         LXxMETHOD(  LxResult,
 SetLastIsControlEndpoint) (
         LXtObjectID              self,
         int                      state);

This method allows the vertex list of a polygon to be changed.

(123) SDK: Polygon::SetVertexList
         LXxMETHOD(  LxResult,
 SetVertexList) (
         LXtObjectID              self,
         const LXtPointID        *vertices,
         unsigned int             numVert,
         unsigned int             rev);

This sets the value in the given point map for a point/polygon pair. The number of elements in the 'value' array should match the dimension of the map.

(124) SDK: Polygon::SetMapValue
         LXxMETHOD(  LxResult,
 SetMapValue) (
         LXtObjectID              self,
         LXtPointID               point,
         LXtMeshMapID             map,
         const float             *value);

This removes any value for the point/polygon pair in the given map.

(125) SDK: Polygon::ClearMapValue
         LXxMETHOD(  LxResult,
 ClearMapValue) (
         LXtObjectID              self,
         LXtPointID               point,
         LXtMeshMapID             map);

A polygon has 16 bits for its point count, so it can have a large but limited number of vertices. Zero is never really valid but is nonetheless possible.

(126) SDK: LXi_POLY_MAXVERT define
 #define LXi_POLY_MAXVERT         65535

Create from Contour

Polygons can also be created from a contour. A contour defines a path that can consist of multiple closed loops with reversed loops inside that act as holes. this call starts a contour.

(127) SDK: Polygon::StartContour
         LXxMETHOD(  LxResult,
 StartContour) (
         LXtObjectID              self);

This call adds an edge to the contour. Edges must form a set of closed loops.

(128) SDK: Polygon::AddContourEdge
         LXxMETHOD(  LxResult,
 AddContourEdge) (
         LXtObjectID              self,
         LXtPointID               startPt,
         LXtPointID               endPt);

When all the contour edges are added, this adds a set of polygons describing the same surface as the closed contour. Since multiple polygons may be added this only returns the new polygon ID if there was only one. Multiple polygons must be inferred some other way.

(129) SDK: Polygon::GenerateContour
         LXxMETHOD(  LxResult,
 GenerateContour) (
         LXtObjectID              self,
         LXtID4                   type,
         LXtPolygonID            *polygonID);

This is the same but uses the current polygon as prototype for all the new polygons to be created from the contour.

(130) SDK: Polygon::GenerateContourProto
         LXxMETHOD(  LxResult,
 GenerateContourProto) (
         LXtObjectID              self,
         LXtPolygonID            *polygonID);

Raycasting Polygons

This method traces a ray with a given start position and direction (normalized). If the ray intersects a polygon it sets the current polygon, sets the distance to the hit point and the surface normal, and returns LXe_TRUE. It returns LXe_FALSE if there are no polygons in the path of the ray.

(131) SDK: Polygon::IntersectRay
         LXxMETHOD(  LxResult,
 IntersectRay) (
         LXtObjectID              self,
         const LXtVector          pos,
         const LXtVector          dir,
         LXtVector                hitNorm,
         double                  *hitDist);

This method finds the closest polygon from the given position. If it finds a polygon, it sets the current polygon, the hit position, the distance to the hit position and the surface normal, and returns LXe_TRUE. It returns LXe_FALSE if there are no polygons. If 'maxDist' is set, the method finds polygons in the radius given by 'maxDist' from the given position.

(132) SDK: Polygon::Closest
         LXxMETHOD(  LxResult,
 Closest) (
         LXtObjectID              self,
         double                   maxDist,
         const LXtVector          pos,
         LXtVector                hitPos,
         LXtVector                hitNorm,
         double                  *hitDist);

Polygon Properties

This returns the index of the point on the polygon. It return -1 if the given point is not belong to the polygon.

(133) SDK: Polygon::PointIndex
         LXxMETHOD( LxResult,
 PointIndex) (
         LXtObjectID              self,
         LXtPointID               pointID,
         unsigned int            *index);

This returns the index of the edge on the polygon. It return -1 if the given edge is not belong to the polygon.

(134) SDK: Polygon::EdgeIndex
         LXxMETHOD( LxResult,
 EdgeIndex) (
         LXtObjectID              self,
         LXtEdgeID                edgeID,
         unsigned int            *index);

Returns the edge that is shared by both edges.

(135) SDK: Polygon::SharedEdge
         LXxMETHOD( LxResult,
 SharedEdge) (
         LXtObjectID              self,
         LXtPolygonID             polygonID,
         LXtEdgeID               *edgeID);

This returns LXe_TRUE if the polygon is on border or the polygon type is not surface.

(136) SDK: Polygon::IsBorder
         LXxMETHOD( LxResult,
 IsBorder) (
         LXtObjectID              self);

Find a representative position for a polygon. This returns a position that is on the interior or the polygon but not on an edge.

(137) SDK: Polygon::RepresentativePosition
         LXxMETHOD( LxResult,
 RepresentativePosition) (
         LXtObjectID              self,
         LXtVector                pos);

Find a representative position for point list. This returns an index that is on the interior or the point list but not on an edge.

(138) SDK: Polygon::GoodPoint
         LXxMETHOD( LxResult,
 GoodPoint) (
         LXtObjectID              self,
         const LXtPointID        *points,
         unsigned int             nPoints,
         unsigned int            *index);

Triangulation

These functions provide a way to triagulate surface type polygons.

'GenerateTriangles' generates triangle lists and it returns the number of triangle to 'count'. If the current polygon is not a surface type, it returns FAILED.

(139) SDK: Polygon::GenerateTriangles
         LXxMETHOD( LxResult,
 GenerateTriangles) (
         LXtObjectID              self,
         unsigned int            *count);

This function returns three points consist of the triangle given by the index. 'GenerateTriangles' must be called to generate triangle list before calling this function.

(140) SDK: Polygon::TriangleByIndex
         LXxMETHOD( LxResult,
 TriangleByIndex) (
         LXtObjectID              self,
         unsigned                 index,
         LXtPointID              *point0,
         LXtPointID              *point1,
         LXtPointID              *point2);

This clears the internal triangle list.

(141) SDK: Polygon::ClearTriangles
         LXxMETHOD( LxResult,
 ClearTriangles) (
         LXtObjectID              self);

Box and Ray Enumeration

Enumerate polygons using test conditions. The mode selects which subset of elements to traverse. The visitor will be called with the accessor set to each successive element.

This function enumerates the polygons conatined in the given bounding box.

(142) SDK: Polygon::EnumerateBBox
         LXxMETHOD(  LxResult,
 EnumerateBBox) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         LXtObjectID              visitor,
         const LXtVector          min,
         const LXtVector          max);

This function enumerates the polygons along the ray given by its origin and direction vectors.

(143) SDK: Polygon::EnumerateRay
         LXxMETHOD(  LxResult,
 EnumerateRay) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         LXtObjectID              visitor,
         const LXtVector          org,
         const LXtVector          ray);

This function enumerates the polygons along the line given by its origin and direction vectors.

(144) SDK: Polygon::EnumerateLine
         LXxMETHOD(  LxResult,
 EnumerateLine) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         LXtObjectID              visitor,
         const LXtVector          org,
         const LXtVector          dir);

Curve Fill polygon

Create curve fill polygon from continuous linear type polygons.

(145) SDK: Polygon::NewCurveFill
         LXxMETHOD(  LxResult,
 NewCurveFill) (
         LXtObjectID              self,
         const LXtPolygonID      *polygons,
         unsigned int             numPols,
         LXtPolygonID            *polygonID);

Symmetry

This sets the symmetric point corresponding to the current polygon when the symmetry mode is enabled. This returns LXe_OK when the symmetric polygon is found, otherwise it returns LXe_FAILED.

(146) SDK: Polygon::Symmetry
         LXxMETHOD(  LxResult,
 Symmetry) (
         LXtObjectID              self,
         LXtPolygonID            *polygonID);

Empty Polygon Python user class.

(147) PY: empty Polygon user class
 pass

UV Lookup

This returns surface point, normal, DPDU and DPDV for a given UV position on the polygon. The normal and the DPDU/DPDV can be null, if not interested in those values.

(148) SDK: Polygon::UVLookup
         LXxMETHOD( LxResult,
 UVLookup) (
         LXtObjectID              self,
         const char              *vMapName,
         const LXtVector2         uv,
         LXtVector                surfacePosition,
         LXtVector                surfaceNormal,
         LXtVector                surfaceDPDU,
         LXtVector                surfaceDPDV);

The quality of the UV tracking depends on this enum.

(149) SDK: LXsPQ_POLY, etc. defines
 #define LXsPQ_POLY              0
 #define LXsPQ_SUBD              1

This function enumerates the polygons that contain the given texture coordinate position.

(150) SDK: Polygon::EnumerateByUV
         LXxMETHOD(  LxResult,
 EnumerateByUV) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         const char              *vMapName,
         int                      quality,
         const LXtVector2         uv,
         LXtObjectID              visitor);

Types

The polygon type is given by a character string identifier which allows for extensible polygon types. A "face" polygon is just the facet defined by the vertices. A "curve" polygon is a Modeler-style spline curve.

(151) SDK: LXsPTYP_FACE, etc. defines
 #define LXsPTYP_FACE            "face"
 #define LXsPTYP_CURVE           "curve"
 #define LXsPTYP_BEZIER          "bezier"
 #define LXsPTYP_SUBD            "subdiv"
 #define LXsPTYP_SPCH            "spatch"
 #define LXsPTYP_TEXT            "text"
 #define LXsPTYP_PSUB            "psubdiv"
 #define LXsPTYP_LINE            "line"
 #define LXsPTYP_CRVFIL          "curveFill"
 #define LXsPTYP_BSPLINE         "BSpline"

The second method is as a numeric ID code which is much faster when the type is known. There are ways to look up the one from the other.

(152) SDK: LXiPTYP_FACE, etc. defines
 #define LXiPTYP_FACE            LXxID4('F','A','C','E')
 #define LXiPTYP_CURVE           LXxID4('C','U','R','V')
 #define LXiPTYP_BEZIER          LXxID4('B','E','Z','R')
 #define LXiPTYP_SUBD            LXxID4('S','U','B','D')
 #define LXiPTYP_SPCH            LXxID4('S','P','C','H')
 #define LXiPTYP_TEXT            LXxID4('T','E','X','T')
 #define LXiPTYP_PSUB            LXxID4('P','S','U','B')
 #define LXiPTYP_LINE            LXxID4('L','I','N','E')
 #define LXiPTYP_CRVFIL          LXxID4('C','F','I','L')
 #define LXiPTYP_BSPLINE         LXxID4('B','S','P','L')
 #define LXiPTYP_BEZR            LXiPTYP_BEZIER
 #define LXiPTYP_CURV            LXiPTYP_CURVE
 #define LXiPTYP_BSPL            LXiPTYP_BSPLINE

New methods for Modo 11

This function enumerates all the polygons with a given surface bin.

(153) SDK: Polygon::EnumerateBin
         LXxMETHOD(  LxResult,
 EnumerateBin) (
         LXtObjectID              self,
         LXtMarkMode              mode,
         LXtObjectID              visitor,
         LXtObjectID              bin);

Polygon Tags

Polygons have tags which can be accessed using the ILxStringTag interface on the polygon accessor.

Polygon tag types can be arbitrary, so clients and even plugins are free to invent any type with any meaning they need for a specific application. However, having some predefined common types makes some of the basic applications more obvious.

MATR The material name for a polygon is stored in a tag of this type. If the polygon has no material, some suitable default should be used.
PART This tag is the name of the abstract element to which this polygon belongs. It is used primarily for selection during modeling.
PICK This tag indicates the selection sets that this polygon belongs to. The name of the sets are separated by semicolons, for example if a polygon belongs to A and B its pick tag will be: "A;B"

These three polygon tags are for text polygon type.

FONT This tag indicates the font name for this text polygon.
TEXT This tag includes the text string for this text polygon.
JUST This tag indicates the justification for this text polygon.The first character takes 'T'(Top), 'M'(Middle) and 'B'(Bottom). The second character takes 'L'(Left), 'C'(Center), and 'R'(Right). For example, 'BL' indicates the justification is bottom-left.
(154) SDK: LXi_POLYTAG_MATERIAL, etc. defines
 #define LXi_POLYTAG_MATERIAL            LXxID4('M','A','T','R')
 #define LXi_POLYTAG_PART                LXxID4('P','A','R','T')
 #define LXi_POLYTAG_SMOOTHING_GROUP     LXxID4('S','M','G','P')
 #define LXi_POLYTAG_PICK                LXxID4('P','I','C','K')
 #define LXi_POLYTAG_FONT                LXxID4('F','O','N','T')
 #define LXi_POLYTAG_TEXT                LXxID4('T','E','X','T')
 #define LXi_POLYTAG_JUST                LXxID4('J','U','S','T')
 
 #define LXi_PTAG_MATR           LXxID4('M','A','T','R')
 #define LXi_PTAG_PART           LXxID4('P','A','R','T')
 #define LXi_PTAG_PICK           LXxID4('P','I','C','K')
 #define LXi_PTAG_FONT           LXxID4('F','O','N','T')
 #define LXi_PTAG_TEXT           LXxID4('T','E','X','T')
 #define LXi_PTAG_JUST           LXxID4('J','U','S','T')

Edge Accessor

The ILxEdge is used to obtain information about specific edges, as well as allowing the list of edges to be walked.

(155) SDK: LXa_EDGE, etc. defines
 #define LXa_EDGE        "edge"
 #define LXu_EDGE        "19A44432-E2CF-4BCF-9EA6-D696E7A0F16E"

As mentioned previously, all accessors share common interface methods for walking their respective lists.

(156) SDK: ILxEdge interface
 ''[[#C70|Common Accessor Methods]]''
 ''[[#C72|Common Geometry Accessor Methods]]''

(157) User Class: Edge method
 ''[[#C74|Common Edge User Methods]]''
 ''[[#C75|Common Marking User Methods]]''
 ''[[#C77|Common Enumerator User Methods]]''

This method sets the accessor to the given edge. Edge IDs are somewhat dynamic based on the points and polygons in the mesh, so an old edge ID should not be assumed valid if the mesh has been edited.

(158) SDK: Edge::Select
         LXxMETHOD(  LxResult,
 Select) (
         LXtObjectID              self,
         LXtEdgeID                edge);

This selects the edge by its endpoints.

(159) SDK: Edge::SelectEndpoints
         LXxMETHOD(  LxResult,
 SelectEndpoints) (
         LXtObjectID              self,
         LXtPointID               v0,
         LXtPointID               v1);

These methods returns the current edge ID.

(160) SDK: Edge::ID
         LXxMETHOD(  LXtEdgeID,
 ID) (
         LXtObjectID              self);

Edge Properties

This method returns the points that make up the edge. Either argument can be NULL if you only want one or the other.

(161) SDK: Edge::Endpoints
         LXxMETHOD(  LxResult,
 Endpoints) (
         LXtObjectID              self,
         LXtPointID              *point0,
         LXtPointID              *point1);

This method returns the value of the edge in the map provided, returning LXe_FALSE if the edge is unmapped.

(162) SDK: Edge::MapValue
         LXxMETHOD(  LxResult,
 MapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         float                   *value);

(163) SDK: Edge::MapEvaluate
         LXxMETHOD(  LxResult,
 MapEvaluate) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         float                   *value);

Editing Operations

This sets the edge's value in the given point map.

(164) SDK: Edge::SetMapValue
         LXxMETHOD(  LxResult,
 SetMapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map,
         const float             *value);

This removes any value for the edge pair in the given map.

(165) SDK: Edge::ClearMapValue
         LXxMETHOD(  LxResult,
 ClearMapValue) (
         LXtObjectID              self,
         LXtMeshMapID             map);

Edge Properties

These methods return the number of polygons sharing this edge.

(166) SDK: Edge::PolygonCount
         LXxMETHOD(  LxResult,
 PolygonCount) (
         LXtObjectID              self,
         unsigned int            *count);

This returns the polygon given by its index.

(167) SDK: Edge::PolygonByIndex
         LXxMETHOD(  LxResult,
 PolygonByIndex) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPolygonID            *polygonID);

This returns a polygon that is visible and surface. It also return the index of the polygon in the polygon list of the edge.

(168) SDK: Edge::RepresentativePolygon
         LXxMETHOD(  LxResult,
 RepresentativePolygon) (
         LXtObjectID              self,
         LXtPolygonID            *polygonID,
         unsigned int            *index);

This returns a shared polygon between two edges.

(169) SDK: Edge::SharedPolygon
         LXxMETHOD(  LxResult,
 SharedPolygon) (
         LXtObjectID              self,
         LXtEdgeID                edgeID,
         LXtPolygonID            *polygonID);

This returns LXe_TRUE if the edge is on border and it is belong to one polygon.

(170) SDK: Edge::IsBorder
         LXxMETHOD(  LxResult,
 IsBorder) (
         LXtObjectID              self);

Symmetry

This sets the symmetric point corresponding to the current edge when the symmetry mode is enabled. This returns LXe_OK when the symmetric edge is found, otherwise it returns LXe_FAILED. When the current edge is on the symmetry center plane, it returns LXe_FAILED.

(171) SDK: Edge::Symmetry
         LXxMETHOD(  LxResult,
 Symmetry) (
         LXtObjectID              self,
         LXtEdgeID               *edgeID);

This returns LXe_TRUE if the symmetry state is enabled and the current edge is on the symmetry center plane, otherwise it returns LXe_FALSE.

(172) SDK: Edge::OnSymmetryCenter
         LXxMETHOD(  LxResult,
 OnSymmetryCenter) (
         LXtObjectID              self);

Nexus 10

This methods returns the index of the curent edge.

(173) SDK: Edge::Index
         LXxMETHOD( LxResult,
 Index) (
         LXtObjectID              self,
         unsigned int            *index);

An edge can be selected by it's index. As edges don't have a deterministic index, this is calculated by iterating through the mesh polygon's edges and returning the index of the first occurance.

(174) SDK: Edge::SelectByIndex
         LXxMETHOD(  LxResult,
 SelectByIndex) (
          LXtObjectID             self,
          unsigned int            index);

Empty Edge Python user class.

(175) PY: empty Edge user class
 pass

Map Accessor

The ILxMeshMap is used to obtain information about specific point maps, as well as allowing the list of maps to be walked.

(176) SDK: LXa_MESHMAP, etc. defines
 #define LXa_MESHMAP     "meshmap"
 #define LXu_MESHMAP     "2AEBA454-2AC4-4F1E-B892-7A16F7601030"

As mentioned previously, all accessors share common interface methods for walking their respective lists.

(177) SDK: ILxMeshMap interface
 ''[[#C70|Common Accessor Methods]]''

(178) User Class: MeshMap method
 ''[[#C74|Common MeshMap User Methods]]''
 ''[[#C77|Common Enumerator User Methods]]''

This method sets the accessor to the given point map.

(179) SDK: MeshMap::Select
         LXxMETHOD(  LxResult,
 Select) (
         LXtObjectID              self,
         LXtMeshMapID             map);

This can be used to select a map by type and name.

(180) SDK: MeshMap::SelectByName
         LXxMETHOD(  LxResult,
 SelectByName) (
         LXtObjectID              self,
         LXtID4                   type,
         const char              *name);

Maps can also be filtered by type which affects their enumeration. Passing a type of zero clears the filter.

(181) SDK: MeshMap::FilterByType
         LXxMETHOD( LxResult,
 FilterByType) (
         LXtObjectID              self,
         LXtID4                   type);

Map Properties

This method returns the ID of the current map.

(182) SDK: MeshMap::ID
         LXxMETHOD( LXtMeshMapID,
 ID) (
         LXtObjectID              self);

These return the map's name and type.

(183) SDK: MeshMap::Name
         LXxMETHOD( LxResult,
 Name) (
         LXtObjectID              self,
         const char             **name);

(184) SDK: MeshMap::Type
         LXxMETHOD( LxResult,
 Type) (
         LXtObjectID              self,
         LXtID4                  *type);

This method returns the dimension of the current map.

(185) SDK: MeshMap::Dimension
         LXxMETHOD(  LxResult,
 Dimension) (
         LXtObjectID              self,
         unsigned int            *dimension);

This returns LXe_TRUE if this is an edge map.

(186) SDK: MeshMap::IsEdgeMap
         LXxMETHOD(  LxResult,
 IsEdgeMap) (
         LXtObjectID              self);

This returns LXe_TRUE if it is a continuous (vs. a discontinuous) map.

(187) SDK: MeshMap::IsContinuous
         LXxMETHOD(  LxResult,
 IsContinuous) (
         LXtObjectID              self);

This returns LXe_TRUE if the default value of elements not in the map should be zero.

(188) SDK: MeshMap::ZeroDefault
         LXxMETHOD(  LxResult,
 ZeroDefault) (
         LXtObjectID              self);

Editing Operations

(189) SDK: MeshMap::New
         LXxMETHOD(  LxResult,
 New) (
         LXtObjectID              self,
         LXtID4                   type,
         const char              *name,
         LXtMeshMapID            *mapID);

(190) SDK: MeshMap::Remove
         LXxMETHOD(  LxResult,
 Remove) (
         LXtObjectID              self);

(191) SDK: MeshMap::Clear
         LXxMETHOD(  LxResult,
 Clear) (
         LXtObjectID              self);

Map Traversal

It's possible for the client to enumerate just the elements that are members of the map. This function enumerates continuous values, calling the visitor with the point accessor set to each point.

(192) SDK: MeshMap::EnumerateContinuous
         LXxMETHOD(  LxResult,
 EnumerateContinuous) (
         LXtObjectID              self,
         LXtObjectID              visitor,
         LXtObjectID              point);

Discontinuous values are the same but require a point and a polygon.

(193) SDK: MeshMap::EnumerateDiscontinuous
         LXxMETHOD(  LxResult,
 EnumerateDiscontinuous) (
         LXtObjectID              self,
         LXtObjectID              visitor,
         LXtObjectID              point,
         LXtObjectID              poly);

Likewise edge map can also be enumerated with an associated edge accessor.

(194) SDK: MeshMap::EnumerateEdges
         LXxMETHOD(  LxResult,
 EnumerateEdges) (
         LXtObjectID              self,
         LXtObjectID              visitor,
         LXtObjectID              edge);

Nexus 901 SP3

This sets the map's name

(195) SDK: MeshMap::SetName
         LXxMETHOD( LxResult,
 SetName) (
         LXtObjectID              self,
         const char              *name);

Enumerates UV seam edges.

(196) SDK: MeshMap::EnumerateUVSeamEdges
         LXxMETHOD(  LxResult,
 EnumerateUVSeamEdges) (
         LXtObjectID              self,
         LXtObjectID              visitor,
         LXtObjectID              edge,
         LXtObjectID              poly);

Returns with the opposite edge. Call only from the Evaluate of a the EnumerateUVSeamEdges()!

(197) SDK: MeshMap::UVSeamOppositeEdge
         LXxMETHOD(  LxResult,
 UVSeamOppositeEdge) (
         LXtObjectID              self,
         LXtEdgeID                originalEdge,
         LXtPolygonID             originalPoly,
         LXtPolygonID            *opppositePoly,
         int                     *isReverse
 );

User methods all have the same name but different arguments. They also wrap the native C++ visitor in a layer of chocolatey COM goodness.

(198) SDK: CLxUser_MeshMap::EnumContents method
         LxResult
 EnumContents (
         CLxImpl_AbstractVisitor *visitor,
         CLxLoc_Point            &point)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
         return EnumerateContinuous (gv, point);
 }
 
         LxResult
 EnumContents (
         CLxImpl_AbstractVisitor *visitor,
         CLxLoc_Point            &point,
         CLxLoc_Polygon          &poly)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
         return EnumerateDiscontinuous (gv, point, poly);
 }
 
         LxResult
 EnumContents (
         CLxImpl_AbstractVisitor *visitor,
         CLxLoc_Edge             &edge)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
         return EnumerateEdges (gv, edge);
 }

Empty MeshMap Python user class.

(199) PY: empty MeshMap user class
 pass

Map Types

Map types can be arbitrary, so clients and even plugins are free to invent any type with any meaning they need for a specific application. However, having some predefined common types makes some of the basic applications more obvious. The dimension of the map is given in parenthesis.

OPOS(3) Object-space position vectors. This is a required singleton map and must be defined for all points. If the map is undefined then the point has no base location in object space.
MORF(3) Morph target displacement vectors. The position of a point in the morph target is the base position of the point plus the offset stored in the map. Unassigned points have an implicit displacement of zero.
SPOT(3) Morph target position vectors. The position of a point in the morph target is given by an absolute vector in the map. Unassigned points have their position given by the base position.
NORM(3) Surface normals. These can be continuous at each point for smooth meshes or discontinuous for angular shapes.
TXUV(2) Texture coordinates with an implicit range of 0.0 to 1.0. Values outside that range are folded back into the unit range when used. Unassigned points have no coordinates and no texturing is done for them.
WGHT(1) General point weights. Although these can have any value, they should map into the nominal range of 0.0 to 1.0, or -1.0 to 1.0. Typically unassigned points are treated as if they have a weight of zero, so the zero value should be considered the default. These weights can also have any meaning, and may be applied to modulate shading, deformation or animation.
PICK(0) Point selection sets. Since they have dimension zero, there is no actual data associated with the points. If the point has a value in the map that indicates membership in the selection set.
EPCK(0) Edge selection sets. Since they have dimension zero, there is no actual data associated with the edges. If the edge has a value in the map that indicates membership in the selection set.
RGB (3) Point color information, stored as red, green and blue in the range of 0.0 to 1.0.
RGBA(4) Point color with transparency, stored as red, green, blue and alpha.
SUBV(1) SubPatch point weights in the range of -1.0 to 1.0. Unassigned points have the default zero weight.
VECT(3) Vector expressed in the local space defined by the normal and the base vector.
TBASIS(6) Tangent and bitangent (binormal) packed together forming a tangent basis with the normal vector, usualy used for deforming mesh (ie. rigged character) normal mapping for real-time 3D engines.
INDX(1) Integer index to specify 1D profile to vertex.
(200) SDK: LXi_VMAP_OBJECTPOS, etc. defines
 #define LXi_VMAP_OBJECTPOS      LXxID4('O','P','O','S')
 #define LXi_VMAP_MORPH          LXxID4('M','O','R','F')
 #define LXi_VMAP_SPOT           LXxID4('S','P','O','T')
 #define LXi_VMAP_NORMAL         LXxID4('N','O','R','M')
 #define LXi_VMAP_TEXTUREUV      LXxID4('T','X','U','V')
 #define LXi_VMAP_WEIGHT         LXxID4('W','G','H','T')
 #define LXi_VMAP_PICK           LXxID4('P','I','C','K')
 #define LXi_VMAP_EPCK           LXxID4('E','P','C','K')
 #define LXi_VMAP_RGB            LXxID4('R','G','B',' ')
 #define LXi_VMAP_RGBA           LXxID4('R','G','B','A')
 #define LXi_VMAP_SUBDIV         LXxID4('S','U','B','V')
 #define LXi_VMAP_VECTOR         LXxID4('V','E','C','T')
 #define LXi_VMAP_TBASIS         LXxID4('T','B','A','S')
 #define LXi_VMAP_BSPLINE        LXxID4('B','S','P','L')

Sometimes it's nice to have maps that are linked to specific items, especially for weights. This is done by setting a special prefix on the map name that is recognized as belonging to an item. The rest of the name is the internal item ident.

(201) SDK: LXsVMAP_ITEMPREFIX define
 #define LXsVMAP_ITEMPREFIX      "__item_"

Mesh Listener

A mesh listener can be attached to a mesh to be informed of changes.

NOTE: Needs to be fleshed out!

(202) SDK: MeshListener::Destroy
         LXxMETHOD( void,
 Destroy) (
         LXtObjectID              self);

This is called for mesh edit changes with event codes defined as LXf_MESHEDIT.

(203) SDK: MeshListener::Changes
         LXxMETHOD( void,
 Changes) (
         LXtObjectID              self,
         unsigned                 event);

(204) SDK: LXu_MESHLISTENER define
 #define LXu_MESHLISTENER        "9373A003-BEBC-44D4-ADEB-36862F0AFC38"

Mesh Tracker

Often, it can be useful to track multiple changes to a mesh within a particular time period. The MeshTracker interface will record a series of mesh changes, and maintain a list of modified points and polygons. The list of changes can be queried, enumerated and cleared at any point. This provides a efficient way to be kept informed of multiple changes, without reacting to every mesh change event.

The Start function starts tracking mesh changes. If this tracker is already running, this function does nothing. The tracker can be started and stopped multiple times, however, it will only record changes when it's active.

(205) SDK: MeshTracker::Start
         LXxMETHOD(  LxResult,
 Start) (
         LXtObjectID              self);

The Stop function stops tracking mesh changes. If this tracker is already stopped, this function does nothing. The tracker can be started and stopped multiple times, however, it will only record changes when it's active.

(206) SDK: MeshTracker::Stop
         LXxMETHOD(  LxResult,
 Stop) (
         LXtObjectID              self);

This returns if the mesh tracker is active or not. The function will return either LXe_TRUE or LXe_FALSE.

(207) SDK: MeshTracker::Active
         LXxMETHOD(  LxResult,
 Active) (
         LXtObjectID              self);

After the changes have been queried and enumerated by the client, the list of changes should be cleared. The Reset function will clear the list of changes, ready to start tracking new change events.

(208) SDK: MeshTracker::Reset
         LXxMETHOD(  LxResult,
 Reset) (
         LXtObjectID              self);

This function returns a flag describing the edits that have been performed on the mesh. The flag will be a combination of the LXf_MESHEDIT flags.

(209) SDK: MeshTracker::Changes
         LXxMETHOD(  LxResult,
 Changes) (
         LXtObjectID              self,
         unsigned int            *edit);

Returns the ILxMesh object that the tracker is watching. If the mesh no longer exists, the function will return a failure code.

(210) SDK: MeshTracker::Mesh
         LXxMETHOD(  LxResult,
 Mesh) (
         LXtObjectID               self,
         void                    **ppvObj);

This function allows the modified points on the mesh to be enumerated. A change flag argument will be used as a mask for enumeration, for example if the LXf_ELTEDIT_POINT_POS flag is provided, only points that have had their position modified will be enumerated. A change flag of 0 will enumerate all points.

(211) SDK: MeshTracker::EnumeratePoints
         LXxMETHOD(  LxResult,
 EnumeratePoints) (
         LXtObjectID              self,
         unsigned int             change,
         LXtObjectID              visitor,
         LXtObjectID              point);

This function allows the modified polygons on the mesh to be enumerated. A change flag argument will be used as a mask for enumeration, for example if the LXf_ELTEDIT_POLTAGS flag is provided, only polygons that have had their tags modified will be enumerated. A change flag of 0 will enumerate all polygons.

(212) SDK: MeshTracker::EnumeratePolygons
         LXxMETHOD(  LxResult,
 EnumeratePolygons) (
         LXtObjectID              self,
         unsigned int             change,
         LXtObjectID              visitor,
         LXtObjectID              poly);

(213) SDK: CLxUser_MeshTracker::EnumPoints method
         LxResult
 EnumPoints (
         unsigned int             change,
         CLxImpl_AbstractVisitor *visitor,
         CLxLoc_Point            &point)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
 
         return EnumeratePoints (change, gv, point);
 }
 
         LxResult
 EnumPolygons (
         unsigned int             change,
         CLxImpl_AbstractVisitor *visitor,
         CLxLoc_Polygon          &poly)
 {
         CLxInst_OneVisitor<CLxGenericVisitor>  gv;
 
         gv.loc.vis = visitor;
 
         return EnumeratePolygons (change, gv, poly);
 }

Adding Changes

The MeshTracker can also be used by clients to register individual changes to specific elements. Changes are passed using the LXf_ELTEDIT flags. These describe a single operation that has been performed to an element.

ADD An element has been added to the mesh.
DELETE An element has been removed from the mesh.
POINT_POS The position of a point has changed.
VMAP_VAL The value of a vertex map for a point or polygon has changed.
POLY_VLIST The vertex list for a polygon has been modified.
POLY_TAGS The tags assigned to a polygon have changed.
POLY_TYPE The type of the polygon has changed.
(214) SDK: LXf_ELTEDIT_ADD, etc. defines

The SetChange function is used to describe the overall change performed by the filter. It should be one of the LXf_MESHEDIT flags.

(215) SDK: MeshTracker::SetChange
         LXxMETHOD(  LxResult,
 SetChange) (
         LXtObjectID              self,
         unsigned int             change);

The AddPoint function is used to store a point that has been edited. An edit flag allows the type of change to be recorded. The flag should be one of the LXf_ELTEDIT flags.

(216) SDK: MeshTracker::AddPoint
         LXxMETHOD(  LxResult,
 AddPoint) (
         LXtObjectID              self,
         LXtPointID               point,
         unsigned int             change);

The AddPolygon function is used to store a polygon that has been edited. An edit flag allows the type of change to be recorded. The flag should be one of the LXf_ELTEDIT flags.

(217) SDK: MeshTracker::AddPolygon
         LXxMETHOD(  LxResult,
 AddPolygon) (
         LXtObjectID              self,
         LXtPolygonID             poly,
         unsigned int             change);

Clients can provide a combination of change flags to filter the tracker to tracker matching change types. For example, if the client only cares about position changes, they can specify LXf_ELTEDIT_POINT_POS. Other kinds of changes may be tracked, but this can provide a performance improvement if clients are going to ignore certain change types. By default, all types of changes will be tracked.

(218) SDK: MeshTracker::SetFilter
         LXxMETHOD(  LxResult,
 SetFilter) (
         LXtObjectID              self,
         unsigned int             filter);

The filter state can also be queried.

(219) SDK: MeshTracker::Filter
         LXxMETHOD(  LxResult,
 Filter) (
         LXtObjectID              self,
         unsigned int            *filter);

Empty MeshTracker Python user class.

(220) PY: empty MeshTracker user class
 pass

(221) SDK: LXu_MESHTRACKER define
 #define LXu_MESHTRACKER         "8FAD284F-C289-40AB-97D2-63932385BAB6"

Mesh Operation

A mesh operation is a container for a modeling operating on a target mesh. It is a simple interface that takes a writeable mesh, and modifies the mesh in any way that it wants. This could be as simple as simply offsetting geometry positions, or it could be more complex, such as creating new geometry or editing mesh properties.

(222) SDK: LXu_MESHOPERATION, etc. defines
 #define LXu_MESHOPERATION               "71D124CB-8D2A-4E5A-814D-3921D9986D3A"
 #define LXa_MESHOPERATION               "meshoperation2"

The Evaluate function is used to perform the main evaluation. It is given an editable mesh, which should be edited in place, to perform the modeling operation. A selection mark mode and selection type is provided, to limit the operation to a particular subset of components.

(223) SDK: MeshOperation::Evaluate
         LXxMETHOD( LxResult,
 Evaluate) (
         LXtObjectID              self,
         LXtObjectID              mesh,
         LXtID4                   type,
         LXtMarkMode              mode);

When a mesh operation creates new geometry, it can be inefficient to recreate the geometry for every evaluation. This set of optional functions allow the previous evaluation result to be used as a starting point for the current evaluation. For example, a bevel tool may use the initial evaluation to create the beveled polygons, and any further evaluation calls may simply offset the position of the beveled geometry.

The Compare function is used to compare one mesh operation with another. The old mesh operation is passed to the new mesh operation and the attributes should be compared, to see if they are compatible. If the function returns DIFFERENT, then the operation will be discarded and evaluated from scratch. If the function returns COMPATIBLE, then the previous result will be used as a starting point for the next evaluation. If the function returns IDENTICAL, then re-evaluation of the mesh operation will be skipped altogether, and the previous result will be used, as is.

(224) SDK: LXiMESHOP_DIFFERENT, etc. defines

(225) SDK: MeshOperation::Compare
         LXxMETHOD( int,
 Compare) (
         LXtObjectID              self,
         LXtObjectID              other);

If the previous mesh operation is compatible, then Convert will be called to transfer variables and user data from the old mesh operation to the new mesh operation. The function will be passed the old operation and any variables should be transferred.

(226) SDK: MeshOperation::Convert
         LXxMETHOD( LxResult,
 Convert) (
         LXtObjectID              self,
         LXtObjectID              other);

The ReEvaluate function is called to perform a fast update to a previous mesh. The mesh from the previous evaluation result is passed to the function, and the mesh operation is expected to simply update the mesh in place.

(227) SDK: MeshOperation::ReEvaluate
         LXxMETHOD( LxResult,
 ReEvaluate) (
         LXtObjectID              self,
         LXtObjectID              mesh,
         LXtID4                   type);

The SetTransform function is used to provide the Mesh Operation with a transform matrix to use for evaluation.

(228) SDK: MeshOperation::SetTransform
         LXxMETHOD( LxResult,
 SetTransform) (
         LXtObjectID              self,
         const LXtMatrix4         matrix);

The Blend function is used to map elements generated by one mesh operation to elements generated by another. A second mesh operation is provided with alternate settings, along with an ILxMeshBlend object, which can be used for marking two corresponding elements as equivalent.

(229) SDK: MeshOperation::Blend
         LXxMETHOD( LxResult,
 Blend) (
         LXtObjectID              self,
         LXtObjectID              other,
         LXtObjectID              blend);

The Clone function is expected to return a clone of this mesh operation and it's internal state. A target item is provided to use as a key, allowing the mesh operation to return an existing cloned mesh operation, if one has already been created for this target item.

(230) SDK: MeshOperation::Clone
         LXxMETHOD( LxResult,
 Clone) (
         LXtObjectID               self,
         LXtObjectID               target,
         void                    **ppvObj);

(231) SDK: empty MeshOperation User Class

Empty Mesh Operation Python user class.

(232) PY: empty MeshOperation user class
 pass

Mesh Filters

Mesh filters are added to evaluation stacks in order to perform mesh operations during evaluation. They can also be read during evaluation to get deforming meshes.

The Type() method returns the type of filter, given by one of the codes below. These select which operational method is called and how its results are interpreted.

(233) SDK: MeshFilter::Type
         LXxMETHOD(  unsigned,
 Type) (
         LXtObjectID              self);

(234) SDK: LXiFILT_MODIFY, etc. defines
 #define LXiFILT_MODIFY          1
 #define LXiFILT_GENERATE        2
 #define LXiFILT_SOURCE          3

If the type of filter is MODIFY, then the Evaluate() method is used to transform a mesh. A writable mesh is passed as input and should be modified in placed based on the settings of the filter. An ILxMeshTracker object is provided, allowing it to return a list of modified elements.

(235) SDK: MeshFilter::Evaluate
         LXxMETHOD(  LxResult,
 Evaluate) (
         LXtObjectID              self,
         LXtObjectID              mesh,
         LXtObjectID              tracker);

For GENERATE and SOURCE type filters the Generate() function is called and it returns a new mesh to replace the input mesh. For GENERATE filters the mesh is instanced while with SOURCE filters the result is used directly.

(236) SDK: MeshFilter::Generate
         LXxMETHOD(  LxResult,
 Generate) (
         LXtObjectID              self,
         void                   **ppvObj);

(237) SDK: LXu_MESHFILTER define
 #define LXu_MESHFILTER  "9AA6236A-CF0F-4E72-B8F3-20BBC5532B61"

(238) SDK: CLxUser_MeshFilter::GetMesh method
         bool
 GetMesh (
         CLxLoc_Mesh             &mesh)
 {
         return Generate (mesh);
 }

Empty MeshFilter Python user class.

(239) PY: empty MeshFilter user class
 pass

ILxMeshFilterBBox

The bounding box interface only computes the mesh bounding box.

(240) SDK: MeshFilterBBox::Evaluate
         LXxMETHOD(  LxResult,
 Evaluate) (
         LXtObjectID              self,
         LXtBBox                 *box);

(241) SDK: LXu_MESHFILTERBBOX define
 #define LXu_MESHFILTERBBOX      "FBD83166-4B50-42A0-8C91-C36D3BB76904"

(242) SDK: empty MeshFilterBBox User Class

Empty MeshFilterBBox Python user class.

(243) PY: empty MeshFilterBBox user class
 pass

Mesh Filter Ident

The ident interface returns a mesh in the mesh stack that has a matching ident. The ident is usually defined as the item ident of the Mesh Operation or Deformer that generated the filter in the mesh stack. If no mesh can be found with the provided ident, the function will return LXe_NOTFOUND.

An BASE identifier will return the non-editable base mesh. And obviously top will return the topmost mesh in the stack.

(244) SDK: LXs_MESHFILTER_BASE, etc. defines
 #define LXs_MESHFILTER_BASE     "__base__"
 #define LXs_MESHFILTER_TOP      "__top__"

(245) SDK: MeshFilterIdent::Generate
         LXxMETHOD(  LxResult,
 Generate) (
         LXtObjectID              self,
         const char              *ident,
         void                   **ppvObj);

(246) SDK: LXu_MESHFILTERIDENT define
 #define LXu_MESHFILTERIDENT     "68713DE3-45D8-4722-BC43-D03EF4964AB8"

(247) SDK: CLxUser_MeshFilterIdent::GetMesh method
         bool
 GetMesh (
         std::string              ident,
         CLxLoc_Mesh             &mesh)
 {
         if (ident.length () > 0)
                 return Generate (ident.c_str (), mesh);
 
         return false;
 }

Empty MeshFilterIdent Python user class.

(248) PY: empty MeshFilterIdent user class
 pass

Mesh Filter Blend

The MeshFilterBlend interface allows the result of one mesh filter to be blended with another.

The Generate method is provided with a second mesh filter storing alternate state for the mesh filter. The function is expected to return an ILxMeshBlend object that maps elements generated by one filter to elements generated by another.

(249) SDK: MeshFilterBlend::Generate
         LXxMETHOD(  LxResult,
 Generate) (
         LXtObjectID              self,
         LXtObjectID              other,
         void                   **ppvObj);

The Evaluate method is provided with a second mesh filter storing alternate state for the mesh filter, as well as an ILxMeshBlend object. The function is expected to populate the ILxMeshBlend object, mapping elements generated by one filter to elements generated by another.

(250) SDK: MeshFilterBlend::Evaluate
         LXxMETHOD(  LxResult,
 Evaluate) (
         LXtObjectID              self,
         LXtObjectID              other,
         LXtObjectID              blend);

(251) SDK: LXu_MESHFILTERBLEND define
 #define LXu_MESHFILTERBLEND     "590F4482-3EDE-47DB-A260-651B687D2B1E"

(252) SDK: empty MeshFilterBlend User Class

Empty MeshFilterBlend Python user class.

(253) PY: empty MeshFilterBlend user class
 pass

Mesh Blend

It can be useful to be able to compare the result of one mesh stack with the result of another. The MeshBlend object provides methods for finding equivalent elements on two mesh stack results, as well as a blending the topology of one mesh stack, into the positions of another.

The BlendMesh method returns a new mesh that contains the source mesh stack topology, in the positions of the target mesh stack. The t argument determines how the mesh is blended, with a value of 0.0 representing the original source mesh positions, and a value of 1.0 representing the target mesh positions.

(254) SDK: MeshBlend::BlendMesh
         LXxMETHOD(  LxResult,
 BlendMesh) (
         LXtObjectID              self,
         double                   t,
         void                   **ppvObj);

The SourceMesh method returns the source mesh.

(255) SDK: MeshBlend::SourceMesh
         LXxMETHOD(  LxResult,
 SourceMesh) (
         LXtObjectID              self,
         void                   **ppvObj);

The TargetMesh method returns the target mesh.

(256) SDK: MeshBlend::TargetMesh
         LXxMETHOD(  LxResult,
 TargetMesh) (
         LXtObjectID              self,
         void                   **ppvObj);

Provided with a point on the source mesh, the GetPoint method will return the equivalent point on the target mesh.

(257) SDK: MeshBlend::GetPoint
         LXxMETHOD(  LxResult,
 GetPoint) (
         LXtObjectID              self,
         LXtPointID               source,
         LXtPointID              *target);

Provided with a polygon on the source mesh, the GetPolygon method will return the equivalent polygon on the target mesh.

(258) SDK: MeshBlend::GetPolygon
         LXxMETHOD(  LxResult,
 GetPolygon) (
         LXtObjectID              self,
         LXtPolygonID             source,
         LXtPolygonID            *target);

Equivalent points can be updated by providing a point on the source mesh, and a point on the target mesh. If the list of equivalent elements cannot be edited, NOACCESS will be returned.

(259) SDK: MeshBlend::SetPoint
         LXxMETHOD(  LxResult,
 SetPoint) (
         LXtObjectID              self,
         LXtPointID               source,
         LXtPointID               target);

Equivalent polygons can be updated by providing a polygon on the source mesh, and a polygon on the target mesh. If the list of equivalent elements cannot be edited, NOACCESS will be returned.

(260) SDK: MeshBlend::SetPolygon
         LXxMETHOD(  LxResult,
 SetPolygon) (
         LXtObjectID              self,
         LXtPolygonID             source,
         LXtPolygonID             target);

Points can be enumerated by providing a source point accessor, a target point accessor and a visitor. For each source point, the accessor for the source and target will be set, and the visitor will be called.

(261) SDK: MeshBlend::EnumeratePoints
         LXxMETHOD(  LxResult,
 EnumeratePoints) (
         LXtObjectID              self,
         LXtObjectID              source,
         LXtObjectID              target,
         LXtObjectID              visitor);

Polygons can be enumerated by providing a source polygon accessor, a target polygon accessor and a visitor. For each source polygon, the accessor for the source and target will be set, and the visitor will be called.

(262) SDK: MeshBlend::EnumeratePolygons
         LXxMETHOD(  LxResult,
 EnumeratePolygons) (
         LXtObjectID              self,
         LXtObjectID              source,
         LXtObjectID              target,
         LXtObjectID              visitor);

(263) SDK: LXu_MESHBLEND define
 #define LXu_MESHBLEND           "E4690A09-96B9-40CB-B264-AB900BF1D989"

(264) SDK: empty MeshBlend User Class

Empty MeshBlend Python user class.

(265) PY: empty MeshBlend user class
 pass