home *** CD-ROM | disk | FTP | other *** search
/ 3D World 120 / 3DW_120.iso / pc / DiscContents / tutorials / scripting / Data / Scripting / Script / ReplaceSelected_Annotations.ls < prev    next >
Encoding:
Text File  |  2009-06-18  |  10.0 KB  |  271 lines

  1. /* @warnings is good for alerting the artist to potential problems within the
  2.    script. @version sets the minimum version of Lscript to use. Finally, @name
  3.    is the name of the plugin which will appear in Lightwave's plugin manager. */
  4.  
  5. @warnings
  6. @version 2.3
  7. @name ReplaceSelected
  8.  
  9. /* We set the type of script to a generic class script. */
  10. generic
  11. {
  12.  
  13. /* We define the (global) variables that we want the whole script to have access
  14.    to. If we did not use global variables, portions of the script would not be
  15.    able to read and set values. In addition, we use ôrecallö to retrieve values
  16.    from previous script executions. Recall's parameters are: the variable you
  17.    would like to recall, followed by the default value of the variable. The
  18.    default value is only important for the initial execution, after which the
  19.    script will use the recalled value. */
  20.  
  21.     replaceType = recall("replaceType", 1);             
  22.     replaceList = recall("replaceList", "");
  23.     replaceMethod = recall("replaceMethod", 1);
  24.     replaceObject = recall("replaceObject", "");
  25.     vColor = recall("vColor", 1);
  26.  
  27. /* We create an array of the currently selected meshes in the scene that will be
  28.    replaced and initialize the variables. */
  29.  
  30.   objSelection =  Scene().getSelect(MESH);             
  31.   objectListSize = 0;
  32.   objectList;
  33.  
  34. /* This If statement will only continue if the objSelection array is not empty.*/
  35.  
  36.   if(objSelection)
  37.   {
  38.  
  39. /* Now we create a dialog to allow the artist to interact with the script. Then we
  40.    create control variables that will allow us to retrieve the values from the
  41.    dialog. The necessary controls for our script are: the path to the object list,
  42.    path to a specific object, an option to choose between the list, object, or
  43.    nulls, an option for either sequential or random, and finally we make an option
  44.    to change the color of the objects. */
  45.   
  46.       reqbegin("ReplaceSelected");
  47.       c0 = ctlfilename("Replacement List", replaceList, 70, true);
  48.       c1 = ctlfilename("Replacement Object", replaceObject, 70, true);
  49.       c2 = ctlchoice("Replace With",replaceType,@"List","Object","Null"@);
  50.       c3 = ctlchoice("Replace Method",replaceMethod,@"Sequential","Random"@);
  51.       c4 = ctlpopup("Color",vColor,@"- No Change -","Black","Dark Blue","Dark
  52.       Green","Dark Cyan","Dark Red","Purple","Brown","Grey","Blue","Green","Cyan
  53.       ","Red","Magenta","Orange","White"@);
  54.  
  55. /* The ctlactive command will be useful to decrease confusion, because it will
  56.    only enable the controls that match the criteria the artist selects. */
  57.   
  58.       ctlactive(c2, "isList", c0);
  59.       ctlactive(c2, "isList", c3);
  60.       ctlactive(c2, "isObject", c1);
  61.  
  62. /* The following statement tells the script to halt if the user cancels the
  63.    dialog. */
  64.  
  65.       return if !reqpost();
  66.  
  67. /* Now we retrieve our  variables from the dialog and set our variables to these
  68.    new values. */
  69.                      
  70.       replaceList = getvalue(c0);
  71.       replaceType = getvalue(c2);
  72.       replaceMethod = getvalue(c3);
  73.       vColor = getvalue(c4);
  74.       replaceObject = getvalue(c1);
  75.  
  76. /* The store command works in tandem with the recall command by saving all of
  77.    the data inputted for future executions. */
  78.  
  79.       store("replaceList", replaceList);
  80.       store("replaceType", replaceType);
  81.       store("replaceMethod", replaceMethod);
  82.       store("vColor", vColor);
  83.       store("replaceObject", replaceObject);
  84.  
  85. /* Now we end the dialog. */
  86.  
  87.       reqend();                                  
  88.  
  89. /* This If statement will ensure that we have the replacement list option
  90.    selected and also that the replacement list path is not blank. Next it will
  91.    try to read the list line by line and store the information as variable ôfö.
  92.    If the file cannot be found, our script will throw an error and halt the
  93.    script from proceeding. The following If statement will check to make sure
  94.    that there is indeed at least one line of text in the replacement list before
  95.     proceeding. */
  96.  
  97.     if(replaceType == 1 && replaceList != "")
  98.     {
  99.  
  100. /* One caveat of Lightwave, is that when it reads files it reads the last line
  101.    of text as nil. This would pose a problem in our script because the last
  102.    object in the list would never be used. The following statement corrects this
  103.    problem by detecting whether Lightwave can read the last line properly. If
  104.    it has trouble, it appends the list with an empty line. If it does not
  105.    detect a problem, it will just continue on. */
  106.     
  107.       f = File(replaceList,"r") || error("Cannot open file: ",replaceList,"");
  108.       f.line(f.linecount());
  109.       if(!f.read())
  110.       {
  111.           f.reopen("a");
  112.           f.nl();
  113.       }
  114.       f.close();
  115.  
  116.       f = File(replaceList,"r") || error("Cannot open file: ",replaceList,"");
  117.       if(f.linecount() > 1)
  118.       { 
  119.       
  120. /* The while loop will continue as long as the current line is not the end of
  121.    the file. The loop will read each line and check to see if it contains ô.lwoö
  122.    (a Lightwave object file). If it does, it will store it to an array that we
  123.    will use for the replacing object(s).*/
  124.    
  125.         while(!f.eof())
  126.         {
  127.           curLine = f.read();
  128.           if(curLine.contains(".lwo"))
  129.           {
  130.             objectListSize++;
  131.             objectList[objectListSize] = curLine;             
  132.           }
  133.           if(!curLine.contains(".lwo") && curLine != nil)
  134.           {
  135.  
  136. /* If the user has entered something other than a blank line or an object file,
  137.    they will be warned. */
  138.  
  139.             warn("At least one file in the list is not a .LWO file. File ignored.");
  140.           }
  141.         }
  142.       }
  143.       else
  144.       {
  145.  
  146. /* If there are no lines in the text file we throw an error. */
  147.   
  148.         error("Problem reading file: No files detected.");
  149.       }
  150.     }
  151.  
  152. /* Below we have an If statement which determines the type of replacement. Since
  153.    the code is relatively similar to cycle through all of the objects based on
  154.    their object IDÆs, we will continue to the more specialized parts.
  155.  
  156.    For the sequential list we use a counter to keep track of the items we have
  157.    to choose from. Next we check to make certain that as we replace objects we
  158.    increment our counter to keep track of the item we are replacing with. If we
  159.    reach the end of the list, we set the counter back to the first object in the
  160.     list and continue processing. */
  161.  
  162.       if(replaceType == 1)
  163.       {
  164.         seqObject = 1;
  165.         for(i = 1; i <= size(objSelection); i++)
  166.         {
  167.           SelectItem(objSelection[i].id);
  168.           if(replaceMethod == 1)
  169.           {
  170.             if(seqObject > size(objectList))
  171.             {
  172.               seqObject = 1;
  173.             }        
  174.             ReplaceWithObject(objectList[seqObject]);
  175.             seqObject++;
  176.           }
  177.           else
  178.           {
  179. /* We use the random command to choose a random number between the minimum value
  180.    (in this case we set it to 1) and our maximum (size of our object list). We
  181.    can then take this random number and plug it back into our objectList array
  182.    to retrieve a random object from the list.*/
  183.             randObj = random(1, size(objectList));
  184.             ReplaceWithObject(objectList[randObj]);
  185.           }
  186.           message(i,size(objSelection));
  187.         }
  188.       }
  189. /* For replacing a specific object our code gets even more straightforward. We
  190.    simply tell Lightwave what object (path) we want to replace the current
  191.    object with. */
  192.       if(replaceType == 2)
  193.       {
  194.         for(i = 1; i <= size(objSelection); i++)
  195.         {
  196.           SelectItem(objSelection[i].id);
  197.           ReplaceWithObject(replaceObject);
  198.           message(i,size(objSelection));
  199.         }
  200.       }
  201. /* This is the null replacement portion of the script. We utilize the
  202.    ReplaceWithNull command (using ôNullö for the name) to replace the objects. */
  203.       if(replaceType == 3)
  204.       {
  205.         for(i = 1; i <= size(objSelection); i++)
  206.         {
  207.           SelectItem(objSelection[i].id);
  208.           ReplaceWithNull("Null");
  209.           message(i,size(objSelection));
  210.         }
  211.       }
  212.       for(i=1; i <= size(objSelection); i++)
  213.       {
  214. /* If the artist chooses to recolor the meshes, this is where we apply those
  215.    colors. We convert vColor to an integer and subtract by 2 to match
  216.    LightwaveÆs color order. Then we essentially turn it back into a string and
  217.    combine it with the Lightwave command sequence ItemColor. Since ItemColor is
  218.    not a native Lscript command we have to combine all of the parameters of the
  219.    command together and then feed that string into CommandInput. This allows us
  220.    to use command sequences inside of Lscript.*/
  221.         if(vColor != 1)
  222.         {
  223.           vC = integer(vColor) - 2;
  224.           color = "ItemColor " + vC;
  225.           CommandInput(color);
  226.         }
  227. /* Here we add the other items back to the selection. */
  228.         AddToSelection(objSelection[i].id);
  229.       }
  230.     }
  231.   if(!objSelection)
  232.   {
  233. /* If there are no selected meshes in the scene, alert the artist and stop the
  234.    script from proceeding. */
  235.     error("Please select a mesh item and then run the script again.");
  236.   }
  237. }
  238.  
  239.  
  240. /* Below are UDF's (User Defined Functions) which process the code independently
  241. from the main portion of the script. These will minimize our code by placing
  242. repetitive code in a UDF and simply calling it when we need it. We send the
  243. value from the dialog to check if the List choice is selected. If so, it will
  244. return a true value enabling the proper controls, otherwise it will disable the
  245. controls. */
  246.  
  247. isList: value
  248. {
  249.   if(value == 1)
  250.     return 1;
  251.   else
  252.     return 0;
  253. }
  254.  
  255. isObject: value
  256. {
  257.   if(value == 2)
  258.     return 1;
  259.   else
  260.     return 0;
  261. }
  262.  
  263. /* Here our custom UDF is used for displaying feedback to the user. This
  264.    function will display the progress of the script at the bottom of the screen
  265.    in the status bar. */
  266.  
  267. message: value, selectionsize
  268. {
  269.   statmessage = string(value) + " of " + string(selectionsize) + " replaced.";
  270.   StatusMsg(statmessage);
  271. }