Notifications
Clear all

[Closed] another – Unknown system exception

Hi,

So I get – Unknown system exception << on my script. This is really weird because the error does not appear every time, just sometimes. So this gives me no idea whats wrong.

The code itself is ok. It looks like max has issues with deleting objects…

Here is a simplified code (sorry for the language, I hope you dont mind)

try(destroyDialog WTF)catch()
rollout WTF "" (
	global ThisIsIt
	
	fn makeObj = (
		sphere radius:10 name:"SuperOwesomeObject"
	)
	
	button _doIt "press the F button" 
	
	on _doIt pressed do (
		for obj in geometry do (
			if obj.name == "SuperOwesomeObject" do delete obj
		)
		makeObj()
	)
)createDialog WTF

P.S. Im using max2016. But I just tested the script in max2017 and it gave me completely different feedback, this is the error I got:

-- MAXScript Rollout Handler Exception:
-- Known system exception
-- ########################################################################
-- Address: 0x0; nCode: 0x00000000C0000005
-- Desc: EXCEPTION_ACCESS_VIOLATION The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
--       Write of Address: 0x0000000100000000
-- ########################################################################
-- MAXScript callstack:
--	thread data: threadID:3708
--	------------------------------------------------------
--	[stack level: 0]
--	In _doIt.pressed(); filename: ; position: 291; line: 14
--	member of: Rollout:WTF
--		Locals:
--		Externals:
--			owner: Rollout:WTF
--			WTF: Rollout:WTF
--			makeObj: makeObj()
--	------------------------------------------------------
--	[stack level: 1]
--	called from top-level
-- ########################################################################
-- C++ callstack:
-- ((module-name not available)): (filename not available): (function-name not available)
-- (MAXScrpt): (filename not available): ObjectSet::find_first
-- (MAXScrpt): (filename not available): ObjectSet::find_first
-- (MAXScrpt): (filename not available): ObjectSet::map
-- (MAXScrpt): (filename not available): clear_error_source_data
-- (MAXScrpt): (filename not available): Primitive::apply
-- (MAXScrpt): (filename not available): CodeTree::eval
-- (MAXScrpt): (filename not available): Primitive::apply
-- (MAXScrpt): (filename not available): CodeTree::eval
-- (MAXScrpt): (filename not available): Generic::apply
-- (MAXScrpt): (filename not available): SourceFileWrapper::apply
-- (MAXScrpt): (filename not available): RolloutControl::call_event_handler
-- (MAXScrpt): (filename not available): RolloutControl::get_wrapped_event_handler
-- (MAXScrpt): (filename not available): InitMacroScriptDir
-- (MAXScrpt): (filename not available): InitMacroScriptDir
-- (USER32): (filename not available): DispatchMessageW
-- (USER32): (filename not available): DispatchMessageW
-- (USER32): (filename not available): GetMenuItemInfoW
-- (ntdll): (filename not available): KiUserCallbackDispatcher
-- (USER32): (filename not available): InvalidateRect
-- (USER32): (filename not available): SendMessageW
-- (USER32): (filename not available): SendMessageW
-- (core): (filename not available): GetICustButton
-- (core): (filename not available): CustomControl::WindowProc
-- (core): (filename not available): AncestorIsCUIToolbarWindow
-- (USER32): (filename not available): DispatchMessageW
-- (USER32): (filename not available): DispatchMessageW
-- (USER32): (filename not available): IsDialogMessageW
-- (3dsmax): (filename not available): XMLAnimTreeEntry::GetType
-- ((module-name not available)): (filename not available): (function-name not available)
-- ((module-name not available)): (filename not available): (function-name not available)
-- ((module-name not available)): (filename not available): (function-name not available)
-- ((module-name not available)): (filename not available): (function-name not available)
-- ########################################################################

P.P.S. This happens only with rollout

16 Replies

Try:

for obj in geometry [B]as array[/B] do
 lo1

More efficient:

delete (for obj in geometry where obj.name == "SuperOwesomeObject" collect obj)

Thanks guys, both work great

If you are looking for performance then the following code may perform much better in general situations. Just try them and see what fits better for your needs.

Additionally, you can so a case insensitive search with this method, and if you don’t need Undo, you can turn it off when deleting the nodes.

nodes = getnodebyname "SuperOwesomeObject" exact:true ignoreCase:false all:true
nodes = for j in nodes where superclassof j == geometryclass collect j
delete nodes

Another thing to consider, if only you will be creating/deleting these nodes, you could store them in a local array and just delete those when needed. That would be a more efficient and elegant solution.

i think the quickest way and shortest code:

delete $SuperOwesomeObject
3 Replies
(@polytools3d)
Joined: 10 months ago

Posts: 0

Not if there are Helpers, Lights, etc. with the same name.
Not if there are more than 1 node with the same name.
Not if there are no nodes with that name.

At least it should be:

try (delete $SuperOwesomeObject*) catch()

Which would also fail with nodes that are not Geometry with that name.

If these nodes will only be created by this tool, I would store them in a variable, safer and cleaner.
But I have not idea how this tool will work, so it is not possible to give a good advice.

(@denist)
Joined: 10 months ago

Posts: 0
(
	delete objects
	for k=1 to 10000 do box name:#SuperOwesomeObject
	gc()
	(
		t = timestamp()
		h = heapfree

		nodes
		for k=1 to 1000 do 
		(
			nodes = (getnodebyname "SuperOwesomeObject" exact:true ignoreCase:false all:true)
			nodes = for node in nodes where iskindof node geometryclass collect node
		)
		format "% => time:% heap:%
" nodes.count (timestamp() - t) (h - heapfree)
	)
	(
		t = timestamp()
		h = heapfree

		nodes
		for k=1 to 1000 do nodes = ([B]$geometry...SuperOwesomeObject[/B])
		format "% => time:% heap:%
" nodes.count (timestamp() - t) (h - heapfree)
	)
)

not many people know well the path value syntax.

if anyone is interested i can explain why this difference is so big

(@polytools3d)
Joined: 10 months ago

Posts: 0

Including me.

I am interested

sure the right code works. but do you understand why your code does not?

1 Reply
(@juzwa)
Joined: 10 months ago

Posts: 0

Actually I do not understand what is the difference between

for obj in geometry

and

for obj in geometry as array do

I mean yeah, the second goes through array, and the first one… Im not sure.

every new node’s name the system registers after definition, and puts in some sort of dictionary. this dictionary later is used to find new unique name for example. (it’s called in documentation Fast Node Name Lookup)

so searching by hash value is much faster than a string comparison.

but this dictionary can take name with some limitations only. it makes some names “the same” no matter than they look different… and it’s not just about case sensitivity.

for example:

delete objects
p1 = point name:"a b"
p2 = point name:"a_b"

($...'a_b').count
($...'a b').count

that’s why getNodeByName method has an optional key argument exact

1 Reply
(@polytools3d)
Joined: 10 months ago

Posts: 0

Isn’t the convertion to array what makes the difference?

(
	delete objects
	gc()
	a = undefined
	it = 100
	for j = 1 to 10000 do plane lengthsegs:1 widthsegs:1 name:"test"
	
	-- ARRAYS ---------------------------------------------
	st=timestamp()
	for j = 1 to it do a = ($geometry...TEST) as array	-- Not Case Sensitive ?
	format "time:% count:%
" (timestamp()-st) a.count

	st=timestamp()
	for j = 1 to it do a = geometry as array
	format "time:% count:%
" (timestamp()-st) a.count
	
	st=timestamp()
	for j = 1 to it do a = getnodebyname "test" all:true
	format "time:% count:%
" (timestamp()-st) a.count
	-------------------------------------------------------
	
	st=timestamp()
	for j = 1 to it do a = $geometry...TEST
	format "time:% count:%
" (timestamp()-st) a.count

	st=timestamp()
	for j = 1 to it do a = geometry
	format "time:% count:%
" (timestamp()-st) a.count
)

time:1159 count:10000
time:747 count:10000
time:947 count:10000
time:0 count:10000 – Not converted
time:0 count:10000 – Not converted

When there is no convertion to array, the value to cast is minimal.
Also, how do you make the path syntax case sensitive?

hmm… maybe me and Bobo only (still an active members of this community) can remember what was originally…

the ‘dictionary’ is not case sensitive. more… it ignores (substitutes) some “characters’.
many old built-in methods takes it in account. but not all…

so. DON’T name things “alternatively”!

Page 1 / 2