Announcement

Collapse
No announcement yet.

3dsMax .MAT file editing

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 3dsMax .MAT file editing

    So, imagine buying a pack of models from say Vizpark, and you want to use their pre made Forestpack pro library, adding them to your own.
    You then see that each pre-sets materials are looking for maps in the wrong places (some network drive where they were made).
    The pre-set files all read a supplemental .mat file (one for each flavour of renderer).

    How would one go around editing the mat file's paths fast and efficiently?
    Loading the mat file into the editor never adds them to the scene, so any pathing tools never register them missing. The materials all need to be assigned to some node before showing up. Then they get their paths edited (using Collin Senner's relink Bitmaps script), then one has to manually overwrite the mat file entry you updated (all) in the loaded lib, and then finally save and overwrite the .mat file. This is quite some task as you might understand.

    Does anyone have a better way or any fancy tools to do this?
    Tried opening the mat file in Notepad+, but its obviously binary or encrypted and not readable.

    Halp me
    Signing out,
    Christian

  • #2
    I would love to know. I have the same issue with all of these Forest Pack Pro libraries from HQ Plants, VizPark etc. It's tedious in the extreme having to repath every time I load things in. I've recently taken to merging forest objects in, with their hidden geom files, from completed projects, so I can get a head-start and avoid repathing. I just wish that Forest had an option when you are loading stuff in to specify the map path for it all. It should be easy I would think. Maybe I will request it...
    Alex York
    Founder of Atelier York - Bespoke Architectural Visualisation
    www.atelieryork.co.uk

    Comment


    • #3
      If you don't mind getting your hands dirty with a tiny bit of maxscript then I can share a tool I wrote to fix our matlibs when our IT dept changes our server names etc.
      Dan Brew

      Comment


      • #4
        Well I don't mind per se, though I might not know what I'm doing depending on what you have in store.
        You are saying you have a tool (.ms) that solves this in bulk?
        Signing out,
        Christian

        Comment


        • #5
          Originally posted by trixian View Post
          You are saying you have a tool (.ms) that solves this in bulk?
          Yes, basically.
          Code:
          (
          	clearListener()
          	
          	if (matLibFP = getOpenFileName caption:"Select material library" filename:(getDir #matlib + @"\") types:"Material libraries(*.mat)") != undefined do
          	(
          		local matLib = loadMaterialLibrary matLibFP
          		for mat in currentMaterialLibrary do
          		(
          			maps = getClassInstances bitmapTex target:mat
          			for map in maps do
          			(
          				local sLength = 9 -- This is the Third. Change this number to match the number of characters between the " " in the line below. I have 9 because \\oldpath is 9 characters long
          				if substring map.filename 1 sLength as name == @"\\oldpath" as name do --this is the first line you have to edit. Replace \\oldpath with the characters you want to replace
          				(
          					map.filename = replace map.filename 1 sLength @"\\newpath" -- This is the second. Replace \\newpath with the characters you want to insert.
          					print map.filename
          				)
          			)
          		)
          	fileSaveMatLib quiet:true
          	)
          )
          First choose 'new script' from the maxscript menu and paste the above into the new script area.

          There are only 3 lines you need to edit. I have written the instructions as comments on each line.

          Make a copy of the .mat file you want to change then run the script. A load file box should open and you can then load the .mat file.
          Last edited by DanielBrew; 08-04-2015, 03:48 AM.
          Dan Brew

          Comment


          • #6
            Hi.
            Just curious. In the one line you define the old path (\\sever1\magicplace\etc\), then underneath you define the new path (\\server2\newlib\pron\etc\).
            One would think this was enough to do a standard search replace, but you then need to define how many characters you will be replacing from the original path?
            Can one not just tell the script to count the characters in the path dynamically? in my case this would vary from material to material, and I arrived at 119 characters this first test, by counting manually
            (is there a easier way to get the count?)
            I'm taking a wild guess as to why you need this sLength defined, as the complete path contains the map name and suffix as well, so you can strip only the path?

            Anyway, it did not work, as each separate material in this lib has a unique set of path characters (the maps were obviously loaded from different places originally, one for each plant type), so this script would only work on a matlib file containing only one material, or at least materials with the same path to all the maps.

            As it stands, I actually do want to point to a single location on the network for all these materials in the matlib file, but since the original paths are of varying length, the script just makes invalid paths now.

            Or am I missunderstanding this
            Signing out,
            Christian

            Comment


            • #7
              Hi,

              Sorry if that looked a bit complicated. I've added a UI to the script so there's no need to edit anything now!

              It looks at the filepath of every bitmap in the material library and if it finds the text in the 'find' textbox it replaces it with the text in the 'replace' textbox.

              For example, if your old file path is \\server1\texturemaps\wood\Oak.jpg and your new path is \\newserver\maps\wood\Oak.jpg write server1\texturemaps in the find textbox and newserver\maps in the replace textbox. Then hit the replace button.

              As before, make a copy of the .mat file you want to work on.

              Code:
              clearListener()
              try destroyDialog updateMatLibs; catch()
              
              rollout updateMatLibs "Update MatLibs" width:300 height:125
              (
              	fn setMatLib = 
              	(
              		if (matLibFP = getOpenFileName caption:"Select material library" filename:(getDir #matlib + @"\") types:"Material libraries(*.mat)") != undefined do
              		(
              			matLib = loadMaterialLibrary matLibFP
              		)
              	)
              	
              	fn replaceString =
              	(
              		if updateMatLibs._findText.text !="" and updateMatLibs._replaceText.text !="" do
              		(
              			for mat in currentMaterialLibrary do
              			(
              				maps = getClassInstances bitmapTex target:mat
              				for map in maps do
              				(
              					if (local sPos = findString ((map.filename as name) as string) updateMatLibs._findText.text) != undefined do
              					(
              						print sPos
              						local sLength = updateMatLibs._findText.text.count
              						map.filename = replace map.filename sPos sLength updateMatLibs._replaceText.text
              						print map.filename
              					)
              				)
              			)
              			fileSaveMatLib quiet:true
              		)
              	)
              	
              	button _matLibBtn "Load Mat. Lib." pos:[55,15] width:205 height:20 toolTip:"Set material library"
              	edittext _findText "Find:"pos:[28,40] width:232 fieldWidth:32 readOnly:false
              	edittext _replaceText "Replace:"pos:[10,65] width:250 fieldWidth:32 readOnly:false
              	button _replaceBtn "Replace" pos:[55,90] width:205 height:20 toolTip:"Set material library"
              	
              	on _matLibBtn pressed do setMatLib()
              	on _replaceBtn pressed do replaceString()
              )
              createDialog updateMatLibs style:#(#style_toolwindow,#style_sysmenu)
              Dan Brew

              Comment


              • #8
                Sorry I'd already started writing the post above before your reply. It doesn't solve your problem but it's quite easy to fix.
                Dan Brew

                Comment


                • #9
                  Great, thanks.

                  Got help from my colleague who is a tad more code-savvy than me, and modified it to actually be slightly more "dumb", so now it renames the paths on all materials in the matlib to one target location, as this is what we need mostly for these material types.
                  Code:
                  clearListener()try destroyDialog updateMatLibs; catch()
                  
                  
                  rollout updateMatLibs "Update MatLibs" width:300 height:125
                      
                  (
                  
                  
                      fn setMatLib = 
                      (
                          if (matLibFP = getOpenFileName caption:"Select material library" filename:(getDir #matlib + @"\") types:"Material libraries(*.mat)") != undefined do
                          (
                              matLib = loadMaterialLibrary matLibFP
                          )
                      )
                  
                  
                  
                  
                      fn replaceString =
                      (
                          if updateMatLibs.DirectoryPath.text !="" do
                          (
                              for mat in currentMaterialLibrary do
                              (
                                  maps = getClassInstances bitmapTex target:mat
                                  for map in maps do
                                  (
                                      
                                      local tempName = updateMatLibs.DirectoryPath.text + "\\" + (filenameFromPath (map.filename))
                                      map.filename = tempName
                                          
                                      --print tempName
                                          
                                  )
                              )
                          fileSaveMatLib quiet:true
                          )
                      )
                  
                  
                      button _matLibBtn "Load Mat. Lib." pos:[55,15] width:205 height:20 toolTip:"Set material library"
                      edittext DirectoryPath "Replace:"pos:[10,65] width:250 fieldWidth:32 readOnly:false
                      button _replaceBtn "Replace" pos:[55,90] width:205 height:20 toolTip:"Set material library"
                      
                      on _matLibBtn pressed do setMatLib()
                      on _replaceBtn pressed do replaceString()
                  )
                  
                  
                  createDialog updateMatLibs style:#(#style_toolwindow,#style_sysmenu)
                  Signing out,
                  Christian

                  Comment


                  • #10
                    OK, I've done something similar.

                    You can now choose to replace the entire path by checking the check button and there is a choose directory button at the end of the replace textbox so you don't need to type the folder path.

                    Code:
                    clearListener()
                    try destroyDialog updateMatLibs; catch()
                    
                    rollout updateMatLibs "Update MatLibs" width:300 height:150
                    (
                    	fn changeOutFolder =
                    	(
                    		updateMatLibs._replaceText.text = (getSavePath  caption:"Choose new path folder..." initialDir:(mapPaths.get 1))
                    	)
                    	
                    	fn updateUI =
                    	(
                    		updateMatLibs._findText.enabled = not updateMatLibs._replaceAll.state
                    		updateMatLibs._editPathBtn.enabled = updateMatLibs._replaceAll.state
                    	)
                    	
                    	fn setMatLib = 
                    	(
                    		if (matLibFP = getOpenFileName caption:"Select material library" filename:(getDir #matlib + @"\") types:"Material libraries(*.mat)") != undefined do
                    		(
                    			matLib = loadMaterialLibrary matLibFP
                    		)
                    	)
                    	
                    	fn replaceString =
                    	(
                    		if (updateMatLibs._findText.text !="" or updateMatLibs._replaceAll.state == true) and updateMatLibs._replaceText.text !="" do
                    		(
                    			for mat in currentMaterialLibrary do
                    			(
                    				maps = getClassInstances bitmapTex target:mat
                    				for map in maps do
                    				(
                    					case updateMatLibs._replaceAll.state of
                    					(
                    						false:(
                    							if (local sPos = findString ((map.filename as name) as string) updateMatLibs._findText.text) != undefined do
                    							(
                    								print sPos
                    								local sLength = updateMatLibs._findText.text.count
                    								map.filename = replace map.filename sPos sLength updateMatLibs._replaceText.text
                    								print map.filename
                    							)
                    						)
                    						true:(
                    							local fname = pathConfig.stripPathToLeaf map.filename
                    							if isDirectoryWriteable updateMatLibs._replaceText.text do map.filename = updateMatLibs._replaceText.text +@"\" + fname
                    						)
                    					)
                    				)
                    			)
                    			fileSaveMatLib quiet:true
                    		)
                    	)
                    	
                    	button _matLibBtn "Load Mat. Lib." pos:[55,15] width:205 height:20 toolTip:"Set material library"
                    	checkbox _replaceAll "Replace entire path" checked:false pos:[55,40]
                    	edittext _findText "Find:"pos:[28,65] width:232 fieldWidth:32 readOnly:false
                    	edittext _replaceText "Replace:"pos:[10,90] width:250 fieldWidth:32 readOnly:false
                    	button _editPathBtn "..." pos:[265,89] width:25 height:20
                    	button _replaceBtn "Replace" pos:[55,115] width:205 height:20 toolTip:"Set material library"
                    	
                    	on updateMatLibs open do updateUI()
                    	on _replaceAll changed state do updateUI()
                    	on _matLibBtn pressed do setMatLib()
                    	on _replaceBtn pressed do replaceString()
                    	on _editPathBtn pressed do changeOutFolder()
                    )
                    createDialog updateMatLibs style:#(#style_toolwindow,#style_sysmenu)
                    Dan Brew

                    Comment


                    • #11
                      I emailed iToosoft about this and they have mentioned that they have added my feature request to their list and will consider it for future builds. They also mentioned that they are rebuilding the whole FPP Library from scratch more or less, which is good news.
                      Alex York
                      Founder of Atelier York - Bespoke Architectural Visualisation
                      www.atelieryork.co.uk

                      Comment

                      Working...
                      X