Here is an OpenFlight script that should get you started. It can be customized (see the "parameters" section near the top of the script). Making GUIs for Scripts is not trivial so for now, just change the values near the top of the script to customize it. Of course you could make a C/C++ plugin complete with a custom GUI but we'll leave that for another day.
The trick in this script is figuring out the "scale center". This will depend on the kind of geometry you want to run through this. You can choose (also in the "parameters" section):
import random # these are "enums" for how the center of the scale is calculated CENTERBOTTOM = 0 # scale about the center bottom of the object CENTER = 1 # scale about the center of the object ORIGIN = 2 # scale about the origin # these are the "parameters" of the script. # change them here and then run the script MinScale = 0.5 # the minimum value to scale MaxScale = 2.0 # the maximum value to scale # the scale will be random between MinScale and MaxScale UniformScale = True # True makes X,Y and Z scale values the same, False lets X,Y and Z scale be all different ScaleCenter = CENTERBOTTOM # the center of the scale (chosen from list aboe) # this is all for "Undo/Redo" class undoData(): def __init__(self): self.undoList = [] self.readyForUndo = True class undoScaleXform(): def __init__(self, xform, node): self.xform = xform self.node = node def undo(self): mgDetach(self.xform) def redo(self): mgAppend(self.node, self.xform) def cleanup(self): mgDelete(self.xform) def RedoFunc (db, undoData): for i in undoData.undoList: i.redo() undoData.readyForUndo = True mgEditorAddUndoForRedo (UndoFunc, UndoCleanupFunc, undoData) def UndoFunc (db, undoData): for i in undoData.undoList: i.undo() undoData.readyForUndo = False mgEditorAddRedo (RedoFunc, UndoCleanupFunc, undoData) def UndoCleanupFunc (db, reason, undoData): if (undoData.readyForUndo == False): for i in undoData.undoList: i.cleanup() class randomScaleData(): def __init__(self, db): self.undoData = undoData () def appendUndo(self, xform, node): undoOne = undoScaleXform (xform, node) self.undoData.undoList.append (undoOne) def RandomValueBetween(v1, v2): """Return a random value between v1 and v2.""" amount = random.random() # between 0 and 1 oneMinusAmount = 1.0 - amount r = (v1 * oneMinusAmount) + (v2 * amount) return r def GetScaleCenter(node): """Calculate scale center for a node.""" c = mgMakeCoord3d(0.0, 0.0, 0.0) b, box = mgGetBounds(node) if (b) : if (ScaleCenter == CENTERBOTTOM): c = mgBoxGetCenterBottom(box) elif (ScaleCenter == CENTER): c = mgBoxGetCenter(box) elif (ScaleCenter == ORIGIN): c = mgMakeCoord3d(0.0, 0.0, 0.0) return c def ApplyRandomScale(node, min, max): """Create a scale transform with random values and attach to node.""" xform = mgNewRec(fltXmScale) scaleX = RandomValueBetween(MinScale, MaxScale) if (UniformScale == True): scaleY = scaleX scaleZ = scaleX else: scaleY = RandomValueBetween(MinScale, MaxScale) scaleZ = RandomValueBetween(MinScale, MaxScale) center = GetScaleCenter(node) mgSetCoord3d(xform, fltXmScaleCenter, center.x, center.y, center.z) mgSetAttList(xform, fltXmScaleX, scaleX, fltXmScaleY, scaleY, fltXmScaleZ, scaleZ) mgAppend(node, xform) return xform def RandomScale(): toolName = "Random Scale" editorContext = mgNewEditorContext (toolName) if (not editorContext): mgSendMessage (MMSG_ERROR, "Failed creating Editor Context") return mgSendMessage (MMSG_STATUS, "Editor Context Created"); db = mgEditorGetDbRec (editorContext) geometry = mgGetSelectList (db) num = mgGetRecListCount (geometry) if (num == 0): mgSendMessage (MMSG_ERROR, "Nothing Selected") return data = randomScaleData (db) for i in range (0, num): rec,matrix = mgGetNextRecInList (geometry) xform = ApplyRandomScale(rec, MinScale, MaxScale) data.appendUndo(xform, rec) mgEditorAddUndo (editorContext, toolName, UndoFunc, UndoCleanupFunc, data.undoData) RandomScale()
Jburrows