pmodel (lx_pmodel.hpp)

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


Contents

Mesh Operation Item

Item Type

The procedural modeling system works by evaluating a series of mesh operations, on a target mesh, to result in a final modified mesh. To integrate a mesh operation interface into the procedural modeling system, the mesh operations need to be associated with an item, that can be managed by the user. The mesh operation item performs this duty. It contains a MeshOpObj channel which stores the mesh operation, and is evaluated by the procedural modeling system, to perform an edit to the mesh.

Mesh Operation items all derive from a common type. This type is extremely basic and has no transforms or position in 3D space. There are four default channels on every Mesh Operation Item, defining things like selection type and the enable state.

(1) SDK: LXsITYPE_MESHOP, etc. defines
 #define LXsITYPE_MESHOP                 "meshoperation"
 #define LXsICHAN_MESHOP_ENABLE          "enable"
 #define LXsICHAN_MESHOP_OBJ             "meshOpObj"
 #define LXsICHAN_MESHOP_SELTYPE         "selectionType"
 #define LXsICHAN_MESHOP_USEXFRM         "useWorldXfrm"

The custom creation command allows a custom command to be fired to handle the creation of the mesh operation item. This is useful if additional setup is required, that is unique to a specific mesh operation item.

(2) SDK: LXsPKG_MESHOP_CREATECMD define
 #define LXsPKG_MESHOP_CREATECMD         "meshop.create"

Adding this tag to a mesh operation, selection operation or tool operation items specifies that the item does not require the transform of the mesh being modified. This can improve performance in certain cases, as the operation will not be reevaluated when the mesh transform changes. The tag can have any value.

(3) SDK: LXsPMODEL_NOTRANSFORM define
 #define LXsPMODEL_NOTRANSFORM           "pmodel.noXfrm"

Automatic Conversion

The steps to manually implement a Mesh Operation item can be quite complex. Because of this, a simpler method is provided, allowing ILxMeshOperation interfaces to be automatically converted into Mesh Operation items. This is only useful for simple mesh operations, that simply take a mesh, modify it and return a modified mesh, using nothing more than a few simple attributes.

Applying the following server tag to an ILxMeshOperation interface, will automatically create a mesh operation item and a modifier, writing the mesh operation server into a channel, so that it can be evaluated as part of the procedural system. The Mesh Operation server being converted, should also implement an Attributes interface. The attributes will be automatically converted into channels on the newly created item. The value of this tag doesn't matter, as the presence of the server tag is enough to automatically create a mesh operation item.

(4) SDK: LXsMESHOP_PMODEL define
 #define LXsMESHOP_PMODEL                "pmodel.meshop"

Manual Implementation

For more complex mesh operations, it is suggested that a Mesh Operation Item be implemented manually. This will allow full control over the channels on the Mesh Operation item, as well as allowing more complex channel data types, and also Mesh Operations that depend on other items in the scene.

To implement a Mesh Operation manually, a package should be created with a superType of LXsITYPE_MESHOP. This will automatically provide it with a Mesh graph input, and the standard set of channels, common to all Mesh Operation item types. A modifier should read the various input channels required to evaluate the Mesh Operation, it should spawn an ILxMeshOperation interface, and store it in the LXsICHAN_MESHOP_OBJ channel on the Mesh Operation item.

Tool Operation Item

Tool Operation Items allow traditional modeling tools that perform an edit to a mesh, to integrate into the procedural system as items. Tool Handles implemented on a Tool Model interface, will automatically be displayed when an item of this type is selected, and sub-tools such as snapping, symmetry and the workplane, can be used to directly modify a tools behavior.

Item Type

Tool Operation items all derive from a common type, which it itself a sub-type of the Mesh Operation item type.

(5) SDK: LXsITYPE_TOOLOP define
 #define LXsITYPE_TOOLOP                 "tooloperation"

The "tool" graph is automatically added to any tool operation item that performs an "actor" task. It is used to connect non-actor tools into the actor tool to create a mini-toolpipe. This mini tool pipe is evaluated, allowing the behavior of an actor tool to be modified.

(6) SDK: LXsGRAPH_TOOL define
 #define LXsGRAPH_TOOL                   "tool"

Automatic Conversion

There are a number of similarities between procedural mesh operations and traditional tools that operate on meshes. Rather than implementing a tool for one context and a mesh operation for another context, it is often desirable to implement functionality once and use in both contexts. As we have a large library of existing tools, converting a tool to work with the procedural modeling system needs to be quick and painless.

Adding the following server tag to an ILxTool server, will automatically convert the tool into a Tool Operation Item, that can be integrated directly into the procedural modeling system. The value of this tag doesn't matter, as the presence of the server tag is enough to convert the tool to work with the procedural modeling system.

(7) SDK: LXsTOOL_PMODEL define
 #define LXsTOOL_PMODEL                  "pmodel.toolop"

Whilst the addition of the server tag makes it simple to convert an existing tool to work with the procedural modeling system, more work is often needed to the tool itself, to ensure it works correctly in an evaluated context. The tool should implement a GetOp function that spawns and returns a Tool Operation interface.

Some considerations also need to be made to the evaluation of the tool operation. The general rule is that when evaluated procedurally, a tool should not rely on any global state, or values that aren't provided by either tool attributes or tool packets. It should not attempt any operation that requires an undo context or attempt to execute commands. With some thought and design, it should be possible to convert most tools that operate on meshes, to work in a procedural context, without altering the functionality of the tool itself.

On automatically generated tool operation items, the tool object will be stored in the following channel.

(8) SDK: LXsICHAN_TOOL_OBJ define
 #define LXsICHAN_TOOL_OBJ               "toolObj"

Manual Implementation

Whilst it's often desirable to automatically generate a Tool Operation item from an existing tool, it is also possible to manually implement Tool Operation items that can be integrated into the procedural system. This is useful for writing tool operation items that provide more complexity than is usually supported through the tool system.

To create a Tool Operation Item from scratch. A package should be created, with a SuperType of LXsITYPE_TOOLOP. This will provide it with the standard set of channels, common to all Tool Operation items.

A Modifier, associated with the Tool Operation Item, should read any channels it requires to evaluate the tool. It should spawn an ILxTool interface and write it into a channel on the package of the type LXsTYPE_OBJREF. The channel name used for storing the tool, should be defined on the server tags using the following tag.

(9) SDK: LXsPKG_TOOL_CHANNEL define
 #define LXsPKG_TOOL_CHANNEL             "tool.channel"

Two other server tags should also be added to the package. One defines the task of the tool, and should be of the type LXs_TASK and the other defines the order of evaluation and should be LXs_ORD. In the majority of cases, these values should be identical to the values returned by the tool.

(10) SDK: LXsPKG_TOOL_TASK, etc. defines
 #define LXsPKG_TOOL_TASK                "tool.task"
 #define LXsPKG_TOOL_ORDER               "tool.order"

Mesh Element Groups

Mesh Operations and Tool Operations can optionally implement an ILxMeshElementGroup interface. This interface is used to get named groups of elements that have been modified, or created by the procedural operation. These can then be used to define new selections later in the stack, allowing the user to easily access elements from an earlier operation.

The returned groups should have a descriptive name that is easily understandable to the user, and is clear how it relates to the operation. For example, a curve extrude operation may return two groups; one named "End Caps" and another named "Sides".

(11) SDK: LXu_MESHELEMENTGROUP, etc. defines
 #define LXu_MESHELEMENTGROUP            "4773EA40-C2D6-4B55-800C-59FF6E9730B7"
 #define LXa_MESHELEMENTGROUP            "meshelementgroup"

This method is expected to return the number of element groups.

(12) SDK: MeshElementGroup::GroupCount
         LXxMETHOD( LxResult,
 GroupCount) (
         LXtObjectID              self,
         unsigned int            *count);

This method should return the name of an element group by index.

(13) SDK: MeshElementGroup::GroupName
         LXxMETHOD( LxResult,
 GroupName) (
         LXtObjectID               self,
         unsigned int              index,
         const char              **name);

This method should return the username of an element group by index. Ideally, this would be a translatable entry in a message table.

(14) SDK: MeshElementGroup::GroupUserName
         LXxMETHOD( LxResult,
 GroupUserName) (
         LXtObjectID               self,
         unsigned int              index,
         const char              **username);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given point exists in the group. The group to test is given by index.

(15) SDK: MeshElementGroup::TestPoint
         LXxMETHOD( LxResult,
 TestPoint) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPointID               point);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given edge exists in the group. The group to test is given by index.

(16) SDK: MeshElementGroup::TestEdge
         LXxMETHOD( LxResult,
 TestEdge) (
         LXtObjectID              self,
         unsigned int             index,
         LXtEdgeID                edge);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given polygon exists in the group. The group to test is given by index.

(17) SDK: MeshElementGroup::TestPolygon
         LXxMETHOD( LxResult,
 TestPolygon) (
         LXtObjectID              self,
         unsigned int             index,
         LXtPolygonID             polygon);

(18) SDK: empty MeshElementGroup User Class

Empty Mesh Element Group Python user class.

(19) PY: empty MeshElementGroup user class
 pass

Selection

A crucial component of the procedural system is selection, as the user needs a way to specify which elements on a mesh will be operated on by a procedural mesh operation. The user should have the ability to combine multiple selections, and easily modify existing selections to perform operations such as type conversions.

Selection Operation Item Type

The selection operation item provides a selection to the procedural system. It encapsulates channels that can be evaluated to determine the current selection state. This item will be evaluated prior to a procedural edit to determine which elements should be operated on.

Selection Operation items all derive from a common type. This type is extremely basic and has no transforms or position in 3D space. The default channels define enable state, the output channel to which the ILxSelectionOperationID is written, whether the selection operation should be inverted, and the blend mode used to blend multiple selection operations together.

(20) SDK: LXsGRAPH_SELOP define
 #define LXsGRAPH_SELOP                  "selop"

(21) SDK: LXsITYPE_SELOP, etc. defines
 #define LXsITYPE_SELOP                  "selectionoperation"
 
 #define LXsICHAN_SELOP_ENABLE           "enable"
 #define LXsICHAN_SELOP_OBJ              "selopobj"
 #define LXsICHAN_SELOP_INVERT           "invert"
 #define LXsICHAN_SELOP_BLENDMODE        "blendmode"

When multiple selection operations are connected to a mesh operation, they can be blended together to create complex selections. This is similar to the concept of shading, where multiple texture layers can be blended together to create a final texture. The following blending modes are available:

OVERRIDE This blending mode (default) will override all selection operations below it in the stack. Any previous selection will be discarded, and the new selection will be used instead.
ADD This blending mode will add the new selection to the previous selection. Elements will only be treated as deselected if they are deselected by all selection operations in the stack.
SUBTRACT This blending mode will remove any elements that are selected by the selection operation from the previous selection. Deselected elements will be ignored.
MULTIPLY This blending mode will only select elements from the second selection operation that are selected by the first, essentially filtering the previous selection.
(22) SDK: LXiSELOP_BLEND_OVERRIDE, etc. defines

Selection Operations should specify the types of selection they support. Mesh Operation and Tool Operation items should also specify the type of selections they require. This combination of selection types on both the selection operation and the mesh operation, helps determine which selection operations can be used with which mesh operations.

Supported selection types are defined using the following server tag. The server is expected to provide a comma seperated list of selection types. The server can also specify that no selection is required by returning the NONE value. If no tag is provided, it will be assumed that all types are supported.

(23) SDK: LXsPMODEL_SELECTIONTYPES define
 #define LXsPMODEL_SELECTIONTYPES        "selectionoperation"

The server tag must have one of the following values. Any other value will be treated as supporting all selection types.

(24) SDK: LXsSELOP_TYPE_NONE, etc. defines
 #define LXsSELOP_TYPE_NONE              "-"
 #define LXsSELOP_TYPE_VERTEX            "VERX"
 #define LXsSELOP_TYPE_EDGE              "EDGE"
 #define LXsSELOP_TYPE_POLYGON           "POLY"

Automatic Conversion

The steps to manually implement a Selection Operation item can be quite complex. Because of this, a simpler method is provided, allowing ILxSelectionOperation interfaces to be automatically converted into Selection Operation items. This is only useful for simple selection operations, that can test the selection status of an element without any complex channel input->

Applying the following server tag to an ILxSelectionOperation interface, will automatically create a selection operation item and a modifier, writing the Selection operation server into a channel, so that it can be queried as part of the procedural system. The Selection Operation server being converted, should also implement an Attributes interface. The attributes will be automatically converted into channels on the newly created item. The value of this tag doesn't matter, as the presence of the server tag is enough to automatically create a selection operation item.

(25) SDK: LXsSELOP_PMODEL define
 #define LXsSELOP_PMODEL                 "pmodel.selectionop"

Selection Operation Interface

This interface allows the procedural modeling system to test the selection status of a given element, allowing it to mark it for use during mesh operation evaluation.

(26) SDK: LXu_SELECTIONOPERATION, etc. defines
 #define LXu_SELECTIONOPERATION          "AA86E146-36F1-44C3-B170-0107F600941D"
 #define LXa_SELECTIONOPERATION          "selectionoperation2"

This function is called before any elements are tested, to set the mesh that the elements belong to.

(27) SDK: SelectionOperation::SetMesh
         LXxMETHOD( LxResult,
 SetMesh) (
         LXtObjectID              self,
         LXtObjectID              mesh);

This function is called before any elements are tested. It provides the transform matrix for the mesh being tested. It can then be used for transforming any component position tests into world space.

(28) SDK: SelectionOperation::SetTransform
         LXxMETHOD( LxResult,
 SetTransform) (
         LXtObjectID              self,
         LXtMatrix4               xfrm);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given point should be included in the selection.

(29) SDK: SelectionOperation::TestPoint
         LXxMETHOD( LxResult,
 TestPoint) (
         LXtObjectID              self,
         LXtPointID               point);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given edge should be included in the selection.

(30) SDK: SelectionOperation::TestEdge
         LXxMETHOD( LxResult,
 TestEdge) (
         LXtObjectID              self,
         LXtEdgeID                edge);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given polygon should be included in the selection.

(31) SDK: SelectionOperation::TestPolygon
         LXxMETHOD( LxResult,
 TestPolygon) (
         LXtObjectID              self,
         LXtPolygonID             polygon);

This function is called at the start of selection evaluation. It can be used to modify a previous selection, or initialize any state needed to evaluate individual elements. The function is called with the selection type that is being evaluated, as well as a ILxSelectionState object. The ILxSelectionState object allows individual elements to be tested for selection, and elements to be added or removed from the selection. If this function returns LXe_TRUE, the selection operation has finished modifying the selection, and then TestPoint, TestEdge and TestPolygon functions will not be called, whereas if the function returns LXe_FALSE, the various test functions will be called.

(32) SDK: SelectionOperation::Evaluate
         LXxMETHOD( LxResult,
 Evaluate) (
         LXtObjectID              self,
         LXtID4                   type,
         LXtObjectID              state);

(33) SDK: empty SelectionOperation User Class

Empty Selection Operation Python user class.

(34) PY: empty SelectionOperation user class
 pass

Legacy 10.1v1 Selection Operation Interface

This selection operation interface was deprecated in 10.2v1.

(35) SDK: LXu_SELECTIONOPERATION1, etc. defines
 #define LXu_SELECTIONOPERATION1         "563E56B1-ACC9-4E3F-B3A8-E0AFE2AB5645"
 #define LXa_SELECTIONOPERATION1         "selectionoperation"

(36) SDK: SelectionOperation1::SetMesh, etc.
         LXxMETHOD( LxResult,
 SetMesh) (
         LXtObjectID              self,
         LXtObjectID              mesh);
 
         LXxMETHOD( LxResult,
 SetTransform) (
         LXtObjectID              self,
         LXtMatrix4               xfrm);
 
         LXxMETHOD( LxResult,
 TestPoint) (
         LXtObjectID              self,
         LXtPointID               point);
 
         LXxMETHOD( LxResult,
 TestEdge) (
         LXtObjectID              self,
         LXtEdgeID                edge);
 
         LXxMETHOD( LxResult,
 TestPolygon) (
         LXtObjectID              self,
         LXtPolygonID             polygon);

Selection State

This interface caches the procedural selection state. It can be used by selection operations to query the selection state, and well as modify the selection state.

(37) SDK: LXu_SELECTIONSTATE, etc. defines
 #define LXu_SELECTIONSTATE              "D1F068A3-5DFC-4587-AD63-FE1D4D0501ED"
 #define LXa_SELECTIONSTATE              "selectionstate"

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given point is selected.

(38) SDK: SelectionState::TestPoint
         LXxMETHOD( LxResult,
 TestPoint) (
         LXtObjectID              self,
         LXtPointID               point);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given edge is selected.

(39) SDK: SelectionState::TestEdge
         LXxMETHOD( LxResult,
 TestEdge) (
         LXtObjectID              self,
         LXtEdgeID                edge);

This method returns either LXe_TRUE or LXe_FALSE, indicating whether or not the given polygon is selected.

(40) SDK: SelectionState::TestPolygon
         LXxMETHOD( LxResult,
 TestPolygon) (
         LXtObjectID              self,
         LXtPolygonID             polygon);

This method is used to set a point as selected. The function should be passed either LXe_TRUE or LXe_FALSE to specify the selection state.

(41) SDK: SelectionState::SetPoint
         LXxMETHOD( LxResult,
 SetPoint) (
         LXtObjectID              self,
         LXtPointID               point,
         LxResult                 state);

This method is used to set an edge as selected. The function should be passed either LXe_TRUE or LXe_FALSE to specify the selection state.

(42) SDK: SelectionState::SetEdge
         LXxMETHOD( LxResult,
 SetEdge) (
         LXtObjectID              self,
         LXtEdgeID                edge,
         LxResult                 state);

This method is used to set a polygon as selected. The function should be passed either LXe_TRUE or LXe_FALSE to specify the selection state.

(43) SDK: SelectionState::SetPolygon
         LXxMETHOD( LxResult,
 SetPolygon) (
         LXtObjectID              self,
         LXtPolygonID             polygon,
         LxResult                 state);

(44) SDK: empty SelectionState User Class

Empty Selection State Python user class.

(45) PY: empty SelectionState user class
 pass