Meshes¶
How do I get a CLxUser_Mesh from a mesh item?¶
There are two meshes you can get. If you want the base mesh – the mesh that the user edits – then you need to use the form of GetChannels which specifies the action layer, and use LXs_ACTIONLAYER_EDIT. This allows you to read the mesh channel from the action directly:
C++
unsigned index;
CLxUser_Scene scene;
CLxUser_ChannelRead rchan;
CLxUser_Mesh umesh;
if (LXx_OK(item.ChannelLookup (LXsICHAN_MESH_MESH, &index))) {
item.GetContext (scene);
scene.GetChannels (rchan, LXs_ACTIONLAYER_EDIT); // this version is crucial here!!!
if (rchan.Object (itm, index, umesh))
np = umesh.NPoints ();
}
Python
item = lxu.object.Item() # given
scene = item.Context()
rchan = scene.Channels(lx.symbol.s_ACTIONLAYER_EDIT, 0.0)
index = item.ChannelLookup(lx.symbol.sICHAN_MESH_MESH)
meshChanVal = rchan.ValueObj(item, index)
umesh = lxu.object.Mesh(meshChanVal)
np = umesh.PointCount()
If you want to access the mesh after deformation, then you want to read from the evaluated mesh channel. This is done by specifying the time at which you want to evaluate. You can then read the channel as a MeshFilter Interface which can be evaluated:
C++
unsigned index;
CLxUser_Scene scene;
CLxUser_ChannelRead rchan;
CLxUser_MeshFilter mfilt;
CLxUser_Mesh umesh;
if (LXx_OK(item.ChannelLookup (LXsICHAN_MESH_MESH, &index))) {
scene.from (item);
scene.GetChannels (rchan, 0.0); // read the deformed mesh at time zero
if (rchan.Object (itm, index, mfilt)) {
if (mfilt.GetMesh (umesh))
np = umesh.NPoints ();
}
}
Python
item = lxu.object.Item() # given
scene = item.Context()
rchan = scene.Channels(None, 0.0)
index = item.ChannelLookup(lx.symbol.sICHAN_MESH_MESH)
meshChanVal = rchan.ValueObj(item, index)
mfilt = lxu.object.MeshFilter(meshChanVal)
umesh = mfilt.Generate()
np = umesh.PointCount()
Note that the channel is a Mesh Object in one case and a EvaluationStack Object in the other. You have to know the source of your ChannelRead Object to know which one you will get. Alternately you could query for the different interface types to probe the object as runtime.
The MeshFilter is also what you get from a modifier. You’d specify the mesh channel as an input and store its attribute index. During evaluation you’d read the channel as a MeshFilter:
C++
CLxUser_MeshFilter mfilt;
CLxUser_Mesh mesh;
if (m_attr.ObjectRO (i_mesh, mfilt)) {
if (mfilt.GetMesh (mesh))
np = mesh.NPoints ();
}
How do I get the bounding box of a mesh with the Python API?¶
There are a couple of ways to do this, assuming you have the mesh as an item object, one is by using the “Surface” interface:
Python
chan_eval = scene.Channels(None, 0.0)
surfItem = lxu.object.SurfaceItem(item)
surf = surfItem.GetSurface(chan_eval, 0)
bbox = surf.GetBBox()
Or alternatively you can cast the mesh item as a Mesh object and query it’s BoundingBox:
Python
chan_read = scene.Channels(lx.symbol.s_ACTIONLAYER_EDIT, lx.service.Selection().GetTime())
mesh_chan = chan_read.ValueObj(mesh, mesh.ChannelLookup(lx.symbol.sICHAN_MESH_MESH))
mesh_obj = lx.object.Mesh(mesh_chan)
bbox = mesh_obj.BoundingBox(lx.symbol.iMARK_ANY)
A mesh object can be retrieved via a layer scan or mesh channel - what method is preferred?¶
The preferred way of editing a mesh is by using a layer scan. The mesh channel object does not internally store deltas and thus does not support undoing edits. The mesh channel object is rather useful to evaluate a deformed mesh at an arbitrary time from animation.
How do I get the primary mesh layer item?¶
The best way to get the primary mesh layer item is using the layer service. This will allocate a layer scan for the primary layer, and then lookup the mesh item.
Python
lyr_svc = lx.service.Layer ()
scan = lx.object.LayerScan (lyr_svc.ScanAllocate (lx.symbol.f_LAYERSCAN_PRIMARY))
if scan.Count () > 0:
item = scan.MeshItem (0)
scan.Apply ()