Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Maxscript worked in 2023 but fails in 2024

10 REPLIES 10
Reply
Message 1 of 11
hockey1237
941 Views, 10 Replies

Maxscript worked in 2023 but fails in 2024

I have a custom script that modifies an object's normals in order to make it behave like a retroreflective material. The script worked fine in Max 2023, but ever since updating to Max 2024 it hasn't worked. I've ruled out any network or folder permissions issues. I've also tried it on multiple systems with the same results.  Any help would be much appreciated!

 

Here is the script:

 

plugin simpleMeshMod Retroreflector
    name:"Retroreflector"
    classID:#(0x6ce99f6f, 0x315dd71d)
	usePBValidity:off

(
    local compilerParams = 
    (
        compilerParams = dotNetObject "System.CodeDom.Compiler.CompilerParameters" #(
            getDir #maxRoot + "\\bin\\assemblies\\Autodesk.Max.Wrappers.dll",
            getDir #maxRoot + "\\Autodesk.Max.dll"
        )
        compilerParams.CompilerOptions = "/optimize+"
        compilerParams.GenerateInMemory = true
        compilerParams
    )

    local compilerResults = (dotNetObject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource compilerParams #("
        using System;
        using Autodesk.Max;
        using System.Runtime.InteropServices;
        using Wrappers = Autodesk.Max.Wrappers;

        class MeshNormals {
            public static void SetNormalsConvergencePt(IntPtr mesh_pointer, IntPtr point3_pointer) {
                var mesh = (IMesh)Wrappers.CustomMarshalerMesh.GetInstance(string.Empty).MarshalNativeToManaged(mesh_pointer);
                var pt = (IPoint3)Wrappers.CustomMarshalerPoint3.GetInstance(string.Empty).MarshalNativeToManaged(point3_pointer);
		
                if (mesh.SpecifiedNormals == null)
                    mesh.SpecifyNormals();
    
                using (var normals = mesh.SpecifiedNormals) {
                    normals.SetParent(mesh);
                
                    if (mesh.GetFlag((uint)mesh.NormalsBuilt) == 0)
                        normals.CheckNormals();

                    for (int face = 0; face < mesh.NumFaces; face++) {
                        for (int faceCorner = 0; faceCorner < 3; faceCorner++) {
                            var vtxPos = mesh.Verts[(int)mesh.Faces[face].V[faceCorner]];
                            normals.SetNormal(face, faceCorner, pt.Subtract(vtxPos));
                        }
                    }
                }
            }
        }"
    )
    local meshNormals = compilerResults.CompiledAssembly.CreateInstance "MeshNormals"

    parameters main rollout:params ( centerObj type:#node useNodeTmValidity:on useNodeOsValidity:on ui:pbCenterObj; _dummy type:#maxObjectTab tabSizeVariable:on)
    rollout params "Parameters" ( pickButton pbCenterObj "Pick Object" autoDisplay:on; )

    on modifyMesh do if isValidNode centerObj do
        meshNormals.SetNormalsConvergencePt mesh (centerObj.pos * inverse owningNode.objectTransform)
    
    on postDisplay obj do
    (
        if classof obj == Editable_Poly do
        (
            deleteModifier obj (obj.numModifiers)
            local ca = obj.custAttributes["A Simple Normal Modifier"]
            if ca != undefined do
            (
                obj.custAttributes.delete ca
            )
        )
    )
	
	on attachedToNode node do if isValidNode node do
        append this._dummy (NodeTransformMonitor node:node)
	
)

 

 

When I try to run it in 2024 I get this error (file paths modified for security):


-- Error occurred in anonymous codeblock; filename: C:\Users\...\Maxscripts\Retroreflector.ms; position: 2071; line: 48
-- MAXScript Scripted plugin local init Exception:
-- Runtime error: .NET runtime exception: Could not load file or assembly 'file:///C:\Users\...\AppData\Local\Temp\bijqyraz.dll' or one of its dependencies. The system cannot find the file specified.
-- MAXScript callstack:
-- thread data: threadID:77924

Tags (2)
10 REPLIES 10
Message 2 of 11

Editing someone else's script is unethical and not a good practice; it's better to try to contact the author.

Message 3 of 11

I appreciate you looking out for authors, but this is my script. I am not a programer but pieced it together with help from ChatGPT and Reddit while trying to learn maxscript. I never did REALLY learn it though, so now I'm having no luck troubleshooting the issues in Max 2024. ChatGPT just goes in circles. Reddit hasn't been able to help yet. None of my research has turned up anything.

All of my testing suggests something in Max changed between versions that's causing the problem. The script works in 2023 on multiple systems, but throws the same error in 2024 on multiple systems. So I'm hoping someone here can help me pinpoint what's causing the problem.

Message 4 of 11
A012255
in reply to: hockey1237


@hockey1237 wrote:

pieced it together with help from ChatGPT and Reddit while trying to learn maxscript.


I rather suggest you start reading the 3dsmax scripting manual first and go through the examples, as we all did..

Message 5 of 11

From what I can see from the code, you want to set the object's normals so that they all face a specific point. In terms of Reflection the idea is clear, but it will change the entire lighting of the object. For me this is a very questionable decision. I would solve the problem at the shader level, not at the geometry level.

Message 6 of 11

 

 

 

plugin simpleMeshMod LookAtNormals
    name:"LookAtNormals"
    classID:#(0x2A882515, 0x744F49CB)
(
	fn create_IMeshNormalsAssembly =
	(
		local source = @"
			using System;
			using System.Runtime.InteropServices;
			using Autodesk.Max;
			using Wrappers = Autodesk.Max.Wrappers;

			class IMeshNormals 
			{
				public static void SetNormalsConvergencePt(IntPtr mesh_pointer, IntPtr point3_pointer) 
				{
					var mesh = (IMesh)Wrappers.CustomMarshalerMesh.GetInstance(string.Empty).MarshalNativeToManaged(mesh_pointer);
					var pivot = (IPoint3)Wrappers.CustomMarshalerPoint3.GetInstance(string.Empty).MarshalNativeToManaged(point3_pointer);
			
					if (mesh.SpecifiedNormals == null) mesh.SpecifyNormals();
		
					using (var normals = mesh.SpecifiedNormals) 
					{
						normals.SetParent(mesh);
					
						if (mesh.GetFlag((uint)mesh.NormalsBuilt) == 0) normals.CheckNormals();

						for (int face = 0; face < mesh.NumFaces; face++) 
						{
							for (int faceCorner = 0; faceCorner < 3; faceCorner++) 
							{
								var vtxPos = mesh.Verts[(int)mesh.Faces[face].V[faceCorner]];
								var vtxNorm = pivot.Subtract(vtxPos).FNormalize;
								normals.SetNormal(face, faceCorner, vtxNorm);
							}
						}
					}
				}
			}"	

		local csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

		compilerParams.ReferencedAssemblies.AddRange #("System.dll", getDir #assemblies + @"\Autodesk.Max.Wrappers.dll", getDir #maxRoot + @"\Autodesk.Max.dll")

		compilerParams.GenerateInMemory = true
		local compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
		
		if (compilerResults.Errors.Count > 0) then
		(
			errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %\n" err.ErrorNumber err.Line err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%\n" errs
			undefined
		)
		else
		(
			local _assembly = compilerResults.CompiledAssembly
			_assembly.CreateInstance "IMeshNormals"
		)
	)	
	
	local _IMeshNormals = create_IMeshNormalsAssembly()
	
    parameters main rollout:params 
	( 
		target type:#node useNodeTmValidity:on ui:ui_target
		object type:#maxobject readonly:on
	)
    rollout params "Parameters" 
	(
		pickButton ui_target "Pick Object" autoDisplay:on
	)

    on modifyMesh do if isValidNode target do
	(
        _IMeshNormals.SetNormalsConvergencePt mesh (target.pos * inverse owningNode.objectTransform)
    )
	on attachedToNode node do if isValidNode node do 
	(
		object = NodeTransformMonitor node:node
	)
	on update do
	(
		if isValidNode owningNode do object = NodeTransformMonitor node:owningNode
	)
)


/* TEST SCENE: *************************

delete objects
gc()

t = teapot name:"OBJECT" wirecolor:orange
p = point name:"TARGET" wirecolor:green
addmodifier t (LookAtNormals target:p)

****************************************/

 

 

 

 

 

Message 7 of 11
freedom1k
in reply to: A012255

Gotta Love ChatGPT!

Message 8 of 11


@freedom1k wrote:

Gotta Love ChatGPT!


be safe

Message 9 of 11
freedom1k
in reply to: hockey1237

Any reason why half the Script is Commented out?

commentedOUT.jpg

Message 10 of 11

it's not commented.

Message 11 of 11
hockey1237
in reply to: hockey1237

So some projects came up that forced me to put this on the backburner, but I'm jumping back in this week. After some digging, the issue I'm having appears to be the result of Max changing from .NET 4 to .NET 6 in 2024, which the original script is not compatible with. I did some testing, some research, worked with my IT team, and upgraded to the latest version of ChatGPT and came up with the below, which required downloading a few DLLs and has some debugging efforts built in (username swapped out because, the internet):

 

plugin simpleMeshMod Retroreflector24
    name:"Retroreflector24"
    classID:#(0x6ce99f6f, 0x315dd71e)
    usePBValidity:off

(
    fn compileAndLoadAssembly =
    (
        try
        (
            -- Define the references to required DLLs
            local references = #(
                getDir #maxRoot + "\\bin\\assemblies\\Autodesk.Max.Wrappers.dll",
                getDir #maxRoot + "\\Autodesk.Max.dll",
                "C:\\Users\\[Username]\\DLLs\\Microsoft.CodeAnalysis.dll",
                "C:\\Users\\[Username]\\DLLs\\Microsoft.CodeAnalysis.CSharp.dll",
                "C:\\Users\\[Username]\\DLLs\\System.Collections.Immutable.dll",
                "C:\\Users\\[Username]\\DLLs\\System.Reflection.Metadata.dll"
            )

            -- Print paths to ensure they are correct
            for ref in references do
            (
                print ("Reference path: " + ref)
            )

            -- Define the C# code
            local csharpCode = "
                using System;
                using Autodesk.Max;
                using System.Runtime.InteropServices;
                using Wrappers = Autodesk.Max.Wrappers;

                public class MeshNormals {
                    public static void SetNormalsConvergencePt(IntPtr mesh_pointer, IntPtr point3_pointer) {
                        var mesh = (IMesh)Wrappers.CustomMarshalerMesh.GetInstance(string.Empty).MarshalNativeToManaged(mesh_pointer);
                        var pt = (IPoint3)Wrappers.CustomMarshalerPoint3.GetInstance(string.Empty).MarshalNativeToManaged(mesh_pointer);

                        if (mesh.SpecifiedNormals == null)
                            mesh.SpecifyNormals();

                        using (var normals = mesh.SpecifiedNormals) {
                            normals.SetParent(mesh);

                            if (mesh.GetFlag((uint)mesh.NormalsBuilt) == 0)
                                normals.CheckNormals();

                            for (int face = 0; face < mesh.NumFaces; face++) {
                                for (int faceCorner = 0; faceCorner < 3; faceCorner++) {
                                    var vtxPos = mesh.Verts[(int)mesh.Faces[face].V[faceCorner]];
                                    normals.SetNormal(face, faceCorner, pt.Subtract(vtxPos));
                                }
                            }
                        }
                    }
                }
            "

            -- Create the SyntaxTree and Compilation objects
            print "Creating SyntaxTree..."
            local syntaxTree = (dotNetClass "Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree").ParseText csharpCode
            print "Creating References..."
            local referencesArray = for ref in references collect (dotNetClass "Microsoft.CodeAnalysis.MetadataReference").CreateFromFile ref
            print "Creating Compilation..."
            local compilation = (dotNetClass "Microsoft.CodeAnalysis.CSharp.CSharpCompilation").Create "MeshNormalsAssembly"
            compilation = compilation.WithOptions ((dotNetClass "Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions").Create (dotNetClass "Microsoft.CodeAnalysis.OutputKind").DynamicallyLinkedLibrary)
            compilation = compilation.AddReferences referencesArray
            compilation = compilation.AddSyntaxTrees #(syntaxTree)

            -- Emit the compiled assembly to a temporary file
            print "Emitting Assembly..."
            local tempDllPath = getDir #temp + "\\MeshNormals.dll"
            local emitResult = compilation.Emit tempDllPath

            if not emitResult.Success then
            (
                for diag in emitResult.Diagnostics do
                (
                    format "Diagnostic: %\n" (diag.ToString())
                )
                throw "Compilation failed. See diagnostics for details."
            )

            -- Load the emitted assembly and create an instance of MeshNormals
            print "Loading Assembly..."
            local assembly = (dotNetClass "System.Reflection.Assembly").LoadFrom tempDllPath
            local meshNormals = assembly.CreateInstance "MeshNormals"
            print "Assembly Loaded Successfully"
            
            return meshNormals
        )
        catch e
        (
            if isKindOf e dotNetObject then
            (
                format "Error: %\n" (e.ToString())
                format "Exception Type: %\n" (e.GetType()).ToString()
                format "Exception Message: %\n" e.Message
                format "Exception Stack Trace: %\n" e.StackTrace
            )
            else
            (
                format "Error: %\n" (e as string)
            )
            return undefined
        )
    )

    -- Compile and load the assembly
    print "Compiling and Loading Assembly..."
    local meshNormals = compileAndLoadAssembly()

    -- Check if the assembly was loaded successfully
    if meshNormals == undefined then
    (
        format "Failed to load the compiled assembly.\n"
        return
    )

    -- Define the parameters and rollout
    parameters main rollout:params ( 
        centerObj type:#node useNodeTmValidity:on useNodeOsValidity:on ui:pbCenterObj;
        _dummy type:#maxObjectTab tabSizeVariable:on
    )
    rollout params "Parameters" ( 
        pickButton pbCenterObj "Pick Object" autoDisplay:on;
    )

    -- Modify the mesh normals to converge at the specified point
    on modifyMesh do if isValidNode centerObj do
        if meshNormals != undefined do
            meshNormals.SetNormalsConvergencePt mesh (centerObj.pos * inverse owningNode.objectTransform)
    
    -- Clean up after display
    on postDisplay obj do
    (
        if classof obj == Editable_Poly do
        (
            deleteModifier obj (obj.numModifiers)
            local ca = obj.custAttributes["A Simple Normal Modifier"]
            if ca != undefined do
            (
                obj.custAttributes.delete ca
            )
        )
    )

    -- Track node transformation
    on attachedToNode node do if isValidNode node do
        append this._dummy (NodeTransformMonitor node:node)
)

 

 

I'm not back to going in circles troubleshooting the issue, getting this error with the current code:


-- Error occurred in anonymous codeblock; filename: C:\Users\JSwanson\DLLs\Retroreflector-2024.ms; position: 4916; line: 110
-- Syntax error: at name, expected Plugin clause:
-- In line: print "

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report