Undocumented and discovered LUA things of Moho

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
Fazek
Posts: 246
Joined: Thu Apr 13, 2006 1:37 pm
Location: Hungary
Contact:

Undocumented and discovered LUA things of Moho

Post by Fazek »

If you want to answer to me, do it here:
http://www.lostmarble.com/forum/viewtopic.php?t=3507

Share your discoveries of the undocumented, strange or interesting features of Moho! During my programming, I am discovering many things from the internal work of the software. I find the reason and behaviour of the bugs, to bypass them.

To use this topic:

PLEASE, KEEP THIS TOPIC CLEAN! PLEASE DON'T PUT DISCUSSIONS HERE, THIS WOULD BE A PROGRAMMERS' DATABASE. IF YOU WANT TO SHARE YOUR IDEAS HERE, CREATE A SINGLE POST AND LATER EDIT THAT ONLY. FOR ANSWERS, JUST PUT A LINK TO A DIFFERENT PLACE AT THE BEGINNING OF YOUR PART. THANK YOU.

Last modified: 12/05/2006 (Moho 5.3.1)

Points, curves and shapes:

Point-segment order in a curve:
Point(0) - (SegmentID=0) - Point(1) - (SegmenID=1) - ... Point(n) - (SegmentID=n) if the curve is closed, and has an additional point Point(n+1) if the curve is open. So curve:CountPoints() = curve:CountSegments() if the curve is closed, and CountSegments() + 1, if it's open.

The curve ID is differ from the Mesh ID for the same point, but you get the same LUA table for the same point.

There are two SetCurvature functions in Moho, one for the M_Point, and one for the M_Curve. You can assign curvature to points, but it really belongs to the curve segments. The M_Point's SetCurvature sets the curvature for all of the segments belonging to the Point, but M_Curve's version sets only for the segments of the curve.

The mesh:PrepMovePoints() function simply does the point.fTempPos= point.fPos operation for the selected points.

The curves are simplified cubic Bezier curves. You can get the position of the internal control points if you get the vector between the two neighbours of the point (at the end of an open curve, between the point and the one neighbour), normalize it, and multiply it with the point's Curvature value, then multiply it with the distance between the point and the connecting neighbour point.

Bones:

You can calculate the bone's actual positions if you use the bone.fMovedMatrix():Transform() function with LM.Vector2 (0,0) for the root (wide) end, and (bone.fLength,0) for the tip.

If you are on the frame 0, use bone.fRestMatrix() instead.

On frame 0, you get the moved bones (with red bubbles around), if your tool's ScriptName is one of the names hardcoded into Moho. LM_ManipulateBone, etc. In this case you should use the fMovedMatrix() for frame 0, too.

Layers:

You can assign any variable to a layer, since it is a LUA table. Moho keeps it even if you move the layer inside the layer tree. But you cannot save them into the document file.

The document's (MohoDoc) CountLayers() and Layer() functions gives only the top-level layers. If you want to collect all layers in the scene, you must go into GroupLayers recursively.

The Switch layers has an AnimString timeline and it can contain ANY strings in the keys, regardless of the sub-layers of the Switch. If Moho finds an unknown string, it shows the switchLayer:Layer(switchLayer:CountLayers() - 1) sub-layer, or nothing if
there are no sublayers.

The default name for frame 0 in a Switch layer is "" (empty string). If you have a sublayer with that name, Moho will show that sublayer for the empty string.

Don't forget to use the moho:LayerAsImage().. etc. typecasts for the type-specific layer functions. Be careful, because the Layer() function of the document/group layers, sometimes gives the correct layer type so maybe a bug remains hidden if you don't use it.

In the Layers window, listing from top to bottom, the layer IDs are going backwards, from the last (Layer(CountLayers() -1 ) to the first (Layer(0)). If you want to put a newLayer under the other (newLayerID= otherLayerID - 1), use the
moho:PlaceLayerBehindAnother(newLayer, otherLayer) function. If you want to put it above the other(newLayerID= otherLayerID + 1), use the following pair:

moho:PlaceLayerBehindAnother(newLayer,otherLayer)
moho:PlaceLayerBehindAnother(otherLayer,newLayer)

User interface:

The dialog windows are not getting the moho (ScriptInterface) structure. If you pass it them somehow, be careful because it is not guaranteed that the moho.document variable is valid. That's why some functions of moho crashing when you call them from a dialog window.

Don't use the LM_MeshPreview object on the tool's DoLayout() toolbar. It crashes Moho randomly if you create a new document. But if you put it into a button's pulldown menu, it seems safety.

Always create the UpdateWidgets() function of DoModal() dialogs. If you exit a modal dialog with the Cancel button, and you open a dialog without the UpdateWidgets(), Moho crashes.

Opposite to the manual, the (LM.GUI) LM_TextList widget's SetSelItem(number) function is an associative search, just like the SetSelItem(string). There is no way to position the list cursor directly. You should put a special string to the place you want, and call SetSelItem.
- - - Fazek
Post Reply