MaxScript Tools

I made a Universe creator, playing a Goddess.

Here is the result of my work:



and I am glad to share my code!
P.S. There is an other code further... for export/import and save/load scene in a .txt file.

/**Genese of the world**/
/**Goddess: Sonia**/
-----------------------------------------------------------------------------------------------------------------
/**Day 1**/
/**Initializing the sun**/

--Sun Default Variables Definitions
if sunQty == undefined then sunQty = 1
if sunRadius == undefined then sunRadius = 7.0f
if sunColor == undefined then sunColor = color 255 255 00
if sunLighting == undefined then sunLighting = false
-----------------------------------------------------------------------------------------------------------------
/**Day 2**/
/**Initializing the planets**/

--Planets Default Variables Definitions
if planetsQty == undefined then planetsQty = 9
if planetsMinRadius == undefined then planetsMinRadius = 2.5f
if planetsMAXRadius == undefined then planetsMAXRadius = 10.0f
if planetsMAXRange == undefined then planetsMAXRange = 100.0f
if planetsMinRange == undefined then planetsMinRange = (sunRadius + planetsMAXRadius)
-----------------------------------------------------------------------------------------------------------------   
/**Day 3**/
/**Initializing the asteroids belt**/

--Asteroids Default Variables Definitions
if asteroidsQty == undefined then asteroidsQty = 300
--if asteroidsRandomShapes == undefined then asteroidsRandomShapes = sphere()
if asteroidsMinBeltRangeFromSun == undefined then asteroidsMinBeltRangeFromSun = 75.0f
if asteroidsMAXBeltRangeFromSun == undefined then asteroidsMAXBeltRangeFromSun = 80.0f
if asteroidsMinRandomRadius == undefined then asteroidsMinRandomRadius = 1.0f
if asteroidsMAXRandomRadius == undefined then asteroidsMAXRandomRadius = 3.0f
if asteroidsColor == undefined then asteroidsColor = color 127 127 127
-----------------------------------------------------------------------------------------------------------------
/**Day 4**/
/**Creating presentation interface**/
global universe

rollout universe "UniverseGenerator" width:400 height:520
(
    --Sun Generator interface
    pickbutton btn2 "Sun Generator" pos:[10,10] width:380 height:20
    GroupBox grp1 "Sun properties" pos:[10,40] width:380 height:60
    spinner spn1 "Radius" pos:[35,65] width:100 height:16 range:[5,50,7] type:#float
    colorPicker cp1 "Sun color" pos:[150,65] width:125 height:20 color:(color 255 255 0)
    checkbox chk2 "Sun Shining" pos:[290,65] width:75 height:25
    --Planets generator interface
    pickbutton btn3 "Planets Generator" pos:[10,110] width:380 height:20
    GroupBox grp3 "Planets properties" pos:[10,140] width:380 height:90
    spinner spn2 "Number of planets" pos:[60,165] width:120 height:16 range:[0,25,9] type:#integer
    spinner spn3 "Maximum radius" pos:[230,165] width:120 height:16 range:[5,10,3] type:#float
    spinner spn4 "Minimum radius" pos:[230,190] width:120 height:16 range:[1,20,10] type:#float
    spinner spn5 "Max range position" pos:[60,190] width:120 height:16 range:[50,500,100] type:#float
    --Asteroids generator interface
    pickbutton btn4 "Asteroids Generator" pos:[10,240] width:380 height:20
    GroupBox grp4 "Asteroids properties" pos:[10,270] width:380 height:180
    spinner spn6 "Quantity" pos:[50,290] width:80 height:16 range:[0,1000,300] type:#integer
    GroupBox grp5 "Shapes" pos:[30,320] width:340 height:85
    colorPicker cp2 "AsteroidsColor" pos:[45,350] width:160 height:30 color:(color 127 127 127)
    spinner spn8 "Min range from sun" pos:[80,420] width:120 height:16 range:[0,100,75] type:#float
    spinner spn9 "Max range" pos:[250,420] width:120 height:16 range:[20,150,80] type:#float
    spinner spn106 "Min radius" pos:[165,290] width:80 height:16 range:[1,3,1] type:#float
    spinner spn107 "Max radius" pos:[280,290] width:80 height:16 range:[3,5,3] type:#float
    --Important buttons
    button btn5 "Create the Universe!!!" pos:[10,465] width:145 height:20
    button btn6 " Reset" pos:[160,465] width:120 height:20
    button btn7 "Close" pos:[290,465] width:95 height:20
    --loading bar
    progressBar pb3 "Loading" pos:[10,495] width:380 height:13 color:(color 255 127.5 0)
   
   
    /**Day 5**/
    /**Creating the utility of all that beauty**/

    on spn1 changed val do
    (
        --if the value of the spinner 1 changes, the sun's radius will change as well
        (
            --put value of spinner1 in sunRadius variable used to draw the sun
            sunRadius = spn1.value
        )
    )
    on cp1 changed col do
    (
        --if the color picker changes, apply the color to the sun's sphere
        (
            --put color numbers into sunColor variable
            sunColor = cp1.color
            --apply the color chosen to the sphere
            try sun.wirecolor = sunColor catch()
        )
    )
    on chk2 changed state do
    (
        sunLighting = true
        --incrementer un int
    )
    on spn2 changed val do
    (
        --gets the spinner value to become planet quantity
        planetsQty = spn2.value
    )
    on spn3 changed val do
    (
        --gets the spinner value to become planet maximum possible radius
        planetsMAXradius = spn3.value
    )
    on spn4 changed val do
    (
        --gets the spinner value to become planet minimum possible radius
        planetsMinRadius = spn4.value
    )
    on spn5 changed val do
    (
        --gets the spinner value to become planet maximum distance from the sun
        planetsMAXRange = spn5.value
    )
    on spn6 changed val do
    (
        --gets the spinner value to become asteroids quantity
        asteroidsQty = spn6.value
    )
    on cp2 changed col do
    (
        --gets the color picker color to become asteroids color
        asteroidsColor = cp2.color
        --try obj.wirecolor = asteroidsColor catch()   
    )
    on spn8 changed val do
    (
        --gets the spinner value to become asteroids minimum distance from the sun
        asteroidsMinBeltRangeFromSun = spn8.value
    )
    on spn9 changed val do
    (
        --gets the spinner value to become asteroids maximum distance from the sun
        asteroidsMAXBeltRangeFromSun = spn9.value
    )
    on spn106 changed val do
    (
        --gets the spinner value to become the minimum radius for the asteroids
        asteroidsMinRandomRadius = spn106.value
    )
    on spn107 changed val do
    (
        --gets the spinner value to become the maximum radius for the asteroids
        asteroidsMAXRandomRadius = spn107.value
    )
    on btn5 pressed do
    (
        --Creates the universe according to values got from the user's choice or default values
        sun = sphere()
        sun.radius = sunRadius
        sun.wirecolor = sunColor
        sun.pos = [0, 0, 0]
        if sunLighting == true then
        (
            addModifier sun (normalModifier flip:on)
            sunShining = Omnilight()
            sunShining.pos = [0,0,0]
        )
        --Si int mod 2 = 0, apply modifier
        --else flip anyway...
        --LIGHTING--
       
        for j = 1 to planetsQty do
        (
            planetOrbit = Circle()
            planetOrbit.radius = (random planetsMinRange planetsMAXRange)
            planetOrbit.pos = [0, 0, 0]
            posXY = random 0.0 360.0
            randomPosX = cos posXY                --each planet will be located in the perfect circle around the sun X between -100 and 100
            randomPosY = sin posXY                --each planet will be located in the perfect circle around the sun Y between -100 and 100
            allSameLevelZ = 0                        --each planet will be located in the perfect circle around the sun, not a sphere so... 0!
            obj = sphere pos:[randomPosX * planetOrbit.radius, randomPosY * planetOrbit.radius, allSameLevelZ]    --placing planets in the Milky Way
           
            randomPlanetRadius = (random planetsMinRadius planetsMAXRadius)
            obj.radius = randomPlanetRadius
        )
       
        --asteroidsBelt = donut()
        --asteroidsBelt.pos = [0, 0, 0]
        --asteroidsBelt.radius1 = asteroidsMinBeltRangeFromSun
        --asteroidsBelt.radius2 = asteroidsMAXBeltRangeFromSun
        /*asteroidsBeltMAX = Circle()
        asteroidsBeltMAX.pos = [0, 0, 0]
        asteroidsBeltMAX.radius = asteroidsMAXBeltRangeFromSun*/
        asteroidsBeltHeight = (asteroidsMAXBeltRangeFromSun - asteroidsMinBeltRangeFromSun)
       
        for i = 1 to asteroidsQty do
        (
            pb3.value = ((i / (asteroidsQty + planetsQty) as float) * 100)
            posXY = random 0.0 360.0
            posZ = (random -asteroidsBeltHeight asteroidsBeltHeight)
            randomPosX = cos posXY
            randomPosY = sin posXY
            randomRange = (random asteroidsMinBeltRangeFromSun asteroidsMAXBeltRangeFromSun)
            obj = sphere pos:[randomPosX * randomRange, randomPosY * randomRange, posZ]
           
            randomAsteroidRadius = (random asteroidsMinRandomRadius asteroidsMAXRandomRadius)
            obj.radius = randomAsteroidRadius
            obj.wirecolor = asteroidsColor
            addModifier obj (noiseModifier fractal:true roughness:(random 0.40 0.70) seed:(random 6 8) scale:(random 130.0 160.0) iterations:(random 4 6 ) strength:[5,5,5])
               
        )
   
    )
    on btn7 pressed do
    (
        destroyDialog universe
    )
    on btn6 pressed  do
        resetMaxFile()
)
createDialog universe

/**Day 6**/
/**Synthesis and debug**/


/*Synthèse*/
/**
This I won't share!
*/


/**Day 7**/
/**Resting time for the goddess!! and probably admiring the beauty of the universe with a glass of wine!!!**/
  
/*********************************************************/
Export/Import & Save/Load

--Declaring arrays
global arrayNodePRSInfos = #()
mAllGeometryName = #()
mAllGeometry = #()
mAllLightsName = #()
mAllLights = #()

--Nodes information structure
struct NodePrsInfo
(
    mNode,
    mName,
    mPosition,
    mRotation,
    mScale
)

--Filling the objects arrays
for geo in geometry do
(
    append mAllGeometry(geo)
    append mAllGeometryName(geo.name)
)

for luz in lights where classof != Targetobject do
(
    append mAllLights(luz)
    append mAllLightsName(luz.name)
)

--The DestroyDialog RolloutCreator is executed and any errors that occur are trapped and the ok is executed.
try DestroyDialog RolloutCreator catch ok
   
--Creating the rollout with RolloutCreator
RC = RolloutCreator "SaveLoadImportExport" "Files utilities"
RC.Begin()

--GroupBox to show the possible selections
RC.AddControl #groupBox #grp_selectionOptions "Select the objects to save" ParamStr: "pos:[5,10] width:340 height:400"
RC.AddControl #groupBox #grp_transformInfos "Select the geometry parameters to save" ParamStr: "pos:[30,190] width:280 height:110"

--Creating a multilist of geometry in the scene
RC.AddControl #multilistbox #ml_geometryList "Geometry" ParamStr: "items: mAllGeometryName pos:[30,30] width:130 height:10"
RC.AddHandler #ml_geometryList #selected paramStr:"val" CodeStr:("
    tempArray = #()
    clearSelection()
   
    for selected = 1 to ml_geometryList.selection.Count do
    (
        if ml_geometryList.selection[selected] do
        (
            append tempArray(mAllGeometry[selected])
        )
    )
    Select tempArray
")
--Creating a multilist of lights in the scene
RC.AddControl #multilistbox #ml_lightsList "Lights" ParamStr: "items: mAllLightsName pos:[180,30] width:130 height:10"
RC.AddHandler #ml_lightsList #selected paramStr:"val2" CodeStr:("
    tempArray2 = #()
    clearSelection()
   
    for selected = 1 to ml_lightsList.selection.Count do
    (
        if ml_lightsList.selection[selected] do
        (
            append tempArray2(mAllLights[selected])
        )
    )
    Select tempArray2
")

--CheckedBox to select the parameters of the transform we want to save or load
RC.AddControl #checkbox #chk_position "Position" ParamStr: "pos:[80,205] width:100 height:30"
RC.AddControl #checkbox #chk_rotation "Rotation" ParamStr: "pos:[80,235] width:100 height:30"
RC.AddControl #checkbox #chk_scale "Scale" ParamStr: "pos:[80,265] width:100 height:30"

--Saving rotation, position and/or scale of the selected objects
RC.AddControl #button #btn_save "Save geometry OR lights selected" ParamStr: "pos:[30,310] width:280 height:35"
RC.AddHandler #btn_save #pressed CodeStr:("
    arrayNodePRSInfos =
    for obj in selection collect
    (
        newArrayNodePRSInfos = NodePRSInfo()
        newArrayNodePRSInfos.mNode = obj
        newArrayNodePRSInfos.mName = obj.name
       
        if isProperty obj #position then
        (
            newArrayNodePRSInfos.mPosition = obj.position
        )
        if isProperty obj #rotation then
        (
            newArrayNodePRSInfos.mRotation = obj.rotation
        )
        if isProperty obj #scale then
        (
            newArrayNodePRSInfos.mScale = obj.scale
        )
       
        newArrayNodePRSInfos
    )
")

--Loading rotation, position and/or scale of the selected objects
RC.AddControl #button #btn_load "Load geometry OR lights selected" ParamStr: "pos:[30,360] width:280 height:35"
RC.AddHandler #btn_load #pressed CodeStr:("
    for savedNodePRSInfo in arrayNodePRSInfos do
    (
        obj = GetNodeByName savedNodePRSInfo.mName
        if isValidNode obj and obj.IsSelected then
        (
            if chk_position.checked then
            (
                if IsProperty obj #position and savedNodePRSInfo.mPosition != undefined then
                (
                    obj.position = savedNodePRSInfo.mPosition
                )
            )
            if chk_rotation.checked then
            (
                if IsProperty obj #rotation and savedNodePRSInfo.mRotation != undefined then
                (   
                    positionBackup = undefined
                    if isProperty obj #position then
                    (
                        positionBackup = obj.position
                    )
                    obj.rotation = savedNodePRSInfo.mRotation
                )
            )
            if chk_scale.checked then
            (
                if positionBackup != undefined then
                (
                    obj.position = positionBackup
                )
            )
            if IsProperty obj #scale and savedNodePRSInfo.mScale != undefined then
            (
                obj.scale = savedNodePRSInfo.mScale
            )
        )
    )
")

--Exporting informations of all the objects in the scene at the time of pressing the button in a txt file
RC.AddControl #button #btn_export "Export scene in text file" ParamStr: "pos:[30,425] width:280 height:35"
RC.AddHandler #btn_export #pressed CodeStr:("
    savingPath = GetSaveFileName()
    if savingPath != undefined then
    (
        filePath = OpenFile savingPath mode:@w@
        arrayNodePRSInfos = for obj in objects collect
        (
            newArrayNodePRSInfos = NodePRSInfo()
            newArrayNodePRSInfos.mName = obj.name
            if IsProperty obj #position then
            (
                newArrayNodePRSInfos.mPosition = obj.position
            )
            if IsProperty obj #rotation then
            (
                newArrayNodePRSInfos.mRotation = obj.rotation
            )   
            if IsProperty obj #scale then
            (
                newArrayNodePRSInfos.mScale = obj.scale
            )
           
            newArrayNodePRSInfos
        )
        with printAllElements on
        (
            format @%@ arrayNodePRSInfos to:filePath
        )
        Close filePath
    )   
")

--Importing the scene informations we've exported in the txt file
RC.AddControl #button #btn_import "Import scene from text file" ParamStr: "pos:[30,475] width:280 height:35"
RC.AddHandler #btn_import #pressed CodeStr:("
    openingPath = GetOpenFileName()
    if openingPath != undefined then
    (
        filePath = OpenFile openingPath mode:@r@
        arrayNodePRSInfos = ReadExpr filePath
        Close filePath
   
        for savedNodePRSInfo in arrayNodePRSInfos do
        (
            obj = GetNodeByName savedNodePRSInfo.mName
            if isValidNode obj then            (
                if IsProperty obj #position and savedNodePRSInfo.mPosition != undefined then
                (
                    obj.position = savedNodePRSInfo.mPosition
                )
                if IsProperty obj #rotation and savedNodePRSInfo.mRotation != undefined then
                (   
                    positionBackup = undefined
                    if isProperty obj #position then
                    (
                        positionBackup = obj.position
                    )
                    obj.rotation = savedNodePRSInfo.mRotation
                )
                if positionBackup != undefined then
                (
                    obj.position = positionBackup
                )
                if IsProperty obj #scale and savedNodePRSInfo.mScale != undefined then
                (
                    obj.scale = savedNodePRSInfo.mScale
                )
            )
        )
    )
")

--RC.AddControl #progressBar #pb_loadImport "Progress Bar" ParamStr: "pos:[25,525] width:300 height:15 color:(color 255 0 0)"


--Turns the existing rollout definition into a floating Dialog
CreateDialog(RC.End()) width:350 height:550