Notifications
Clear all

[Closed] Scope problem with struct – Section Updater Tool

Hello.
While modeling, it’s often very useful to be able to see section of modeled part.
3ds max’s Section objects doesn’t update automatically.

I am writing a simple tool, that forces updating all Section Objects in the scene, triggered by changing geometry of picked object.

Tool works, but I am having some errors on the first run. I can’t seem to grasp the scope of variables in maxscript struct-based tools. On the second run everything work’s as intended.

How to fix this?

Code here:

struct pgsects(
	sections = #(),
	
	fn findSections = (PGSections.sections = for s in shapes where (classof  s == section) collect s ),
	
	fn sectionsUpdate = ( 
		pgsects.findSections()
		
		for sect in PGSections.sections do (
			sect.transform = (rotateZmatrix 0.001) * sect.transform
		)
	),

	fn deleteHandlers = ( deleteAllChangeHandlers id:#PGtopoChange ),

	fn geoFilter obj = ( superclassof obj == GeometryClass ),
	
	fn run = (
		try (destroyDialog PGSectionsDial) catch()
		
		rollout PGSectionsDial "Sections Auto Update" width:200
		(
			label l "Keep this dialog open\n for realtime updates" height:30 multiline:true
			pickButton topoBtn "<< Pick geometry... >>" filter:geoFilter width:180 height:25
			
			on topoBtn picked obj do (
				topoBtn.text = obj.name
				
				pgsects.deleteHandlers()
				when geometry obj changes id:#PGtopoChange do pgsects.sectionsUpdate()
			)
			
			on PGSectionsDial close do pgsects.deleteHandlers()
		)
		
		createDialog PGSectionsDial
	)
	
)

PGSections = pgsects()
PGSections.run()

Video showing problem here:

3 Replies

look at this post first: tool in struct example

Your mistake is that you are using a reference to an instance of the structure inside this structure definition. This is not correct.
Following the example posted above, you should solve your problem. If not, we will be glad to any questions.

(if you fix your code, please post a working version for other people who may encounter similar problems)

1 Reply
(@polytools3d)
Joined: 2 years ago

Posts: 0

In this particular case, I see no reason to go over a more complex structure development.

Shouldn’t it be enough to declare ‘PGSections’ either as local or global before the struct declaration?

Try enclosing the whole script in parenthesis and add this line before the struct declaration and see if it works.

(
	local PGSections
	
	struct pgsects
	(...)
)

I followed @PolyTools3D advice and it worked!
I don’t get it though. Why did that solve scope problem? Why didn’t struct have access to PGSections instance in my original post?

Working code here:

(
	local PGSections

	struct pgsects(
		sections = #(),
		
		fn findSections = (PGSections.sections = for s in shapes where (classof  s == section) collect s ),
		
		fn sectionsUpdate = ( 
			pgsects.findSections()
			
			for sect in PGSections.sections do (
				sect.transform = (rotateZmatrix 0.001) * sect.transform
			)
		),

		fn deleteHandlers = ( deleteAllChangeHandlers id:#PGtopoChange ),

		fn geoFilter obj = ( superclassof obj == GeometryClass ),
		
		fn run = (
			try (destroyDialog PGSectionsDial) catch()
			
			rollout PGSectionsDial "Sections Auto Update" width:200
			(
				label l "Keep this dialog open\n for realtime updates" height:30 multiline:true
				pickButton topoBtn "<< Pick geometry... >>" filter:geoFilter width:180 height:25
				
				on topoBtn picked obj do (
					topoBtn.text = obj.name
					
					pgsects.deleteHandlers()
					when geometry obj changes id:#PGtopoChange do pgsects.sectionsUpdate()
				)
				
				on PGSectionsDial close do pgsects.deleteHandlers()
			)
			
			createDialog PGSectionsDial
		)
		
	)

	PGSections = pgsects()
	PGSections.run()
)

Newest version possible always available here: