Detach script with c ++

Detach script with c ++

anycganycgJ8A6A
Advocate Advocate
4,029 Views
44 Replies
Message 1 of 45

Detach script with c ++

anycganycgJ8A6A
Advocate
Advocate

hi

Nice to meet you

I have a problem

I have a 5000 object

That is attached..

I would like to detach with elements

I tested many detahel script

But all is failed or max freezz problem

So i found this link

 

C++ detach script

 

https://forums.cgsociety.org/t/c-detach-by-elements/1707338

 

If i use c++ , can i detach my objects

 

I dont know c++

 

Uf that is possible , can you help that ?

0 Likes
Accepted solutions (1)
4,030 Views
44 Replies
Replies (44)
Message 2 of 45

denisT.MaxDoctor
Advisor
Advisor

Since I am the actual author of this code, it will probably be easier for me to answer you.
If you don't know c++, then this code won't help you. It's impossible to just take it and somehow execute it in 3DS MAX.
Only the MaxScript solution will suit you and nothing else. If you couldn't find a working script, it doesn't mean that it doesn't exist. You just haven't come across any good ones.

 

The easiest way to get a working solution is to post an example of a max scene (MAX 2020 version), and clearly tell which object and how should be detached by element...

 

Actually, there are two technical problems here (not one):
1. find all the necessary elements
2. detach them

 

So, we need to take a look first

0 Likes
Message 3 of 45

anycganycgJ8A6A
Advocate
Advocate
really thank you for reply

https://drive.google.com/file/d/1eJQo2kvwSnBHH94Z6d2WtJbIgfebCic7/view?usp=sharing
that is attached object
i am sorry
pls can you detach test ?
i would like to know detach speed with c++ script
my pupose is element detach.
thank you again ~
0 Likes
Message 4 of 45

denisT.MaxDoctor
Advisor
Advisor

It should be noted that the task is not easy for c++ either.
Just so you know, your example does not have 5000 elements as you said, but 50000(!)... and that's a big difference.
So far, I can't solve this problem with a pure maxscript, but it's a challenge for me, and I'm interested in solving this problem anyway

0 Likes
Message 5 of 45

anycganycgJ8A6A
Advocate
Advocate
Really really thank you for your effort
I wish you can do that ~
At any way thank you
0 Likes
Message 6 of 45

denisT.MaxDoctor
Advisor
Advisor

@anycganycgJ8A6A wrote:

pls can you detach test ?
i would like to know detach speed 

how fast does it have to be to make you happy? 😉

 

0 Likes
Message 7 of 45

anycganycgJ8A6A
Advocate
Advocate
Thank you for your kindness
As fast as possbile.
5 seond is very happy
10 second is very happy also
Really Sorry for rude request :

0 Likes
Message 8 of 45

denisT.MaxDoctor
Advisor
Advisor

@anycganycgJ8A6A wrote:
As fast as possbile.
5 seond is very happy
10 second is very happy also

Ha ha ha... you're naive. While we can talk about 3-5 minutes

0 Likes
Message 9 of 45

anycganycgJ8A6A
Advocate
Advocate
i adore you
I always think of your word as the word of God
Even if I become a stone, I will wait for your answer
0 Likes
Message 10 of 45

denisT.MaxDoctor
Advisor
Advisor

I'm just wondering... why attach all the objects to one mesh first and then detach them piece by piece again?

It turns out 50,000 objects ... it is simply impossible to work with such a number!

 

you imagine detaching all in 3-5 seconds...
let's do a simple experiment, just try to create 50,000 comparable by size box objects:

(
	delete objects
	
	t0 = timestamp()
	h0 = heapfree

	bb = for k=1 to 50000 collect
	(
		b = box lengthsegs:2 widthsegs:2 heightsegs:2 pos:(random -[1000,1000,1000] [1000,1000,1000])
		converttomesh b
	)
	
	format "count:% time:% heap:%\n" bb.count (timestamp() - t0) (h0 - heapfree)
)

 

how long does it take on your machine?

0 Likes
Message 11 of 45

anycganycgJ8A6A
Advocate
Advocate
really thank you for reply again
first of all, i tested
count:50000 time:17770 heap:49620672L

Please understand my poor English skills

Here's why it's made with one mesh:

I often get attached large objects from clients.
So I have to separate for mapping.

So this time
I have a curiosity that I want to solve

My curiosity won't stop
0 Likes
Message 12 of 45

anycganycgJ8A6A
Advocate
Advocate
second : count:50000 time:11445 heap:49893368L
third : count:50000 time:11601 heap:49891960L


denist , i have a question
without opening max program , Is it impossible to run a script from the command line?

0 Likes
Message 13 of 45

denisT.MaxDoctor
Advisor
Advisor

 


@anycganycgJ8A6A wrote:
I often get attached large objects from clients.
So I have to separate for mapping. 


In this case, you do not need to detach all the parts. Detach only those you need to work on at the moment and reattach them when the job is done.
It also makes sense to specifically do the mapping for only certain parts, and copy the mapping from them to the same or similar ones. This will save you a lot of time.

0 Likes
Message 14 of 45

denisT.MaxDoctor
Advisor
Advisor

@anycganycgJ8A6A wrote:
without opening max program , Is it impossible to run a script from the command line?


in general, consider that it is impossible. Expect MAX must be opened to run tools...

 

The "hidden UI" option (launching MAX without a UI) is designed and used almost exclusively for rendering purposes. Running MAX with command line is not an area in which my expert opinion means something. Surely there are more experienced people in this topic

0 Likes
Message 15 of 45

anycganycgJ8A6A
Advocate
Advocate
Really Thank you for good advice
I have many style in my work

1. Detach all , and replace that
2. Other complex attached scene , extract model

Etc...

Files from clients have a lot of different styles.
I felt it was convenient to work after just detaching the whole thing.
0 Likes
Message 16 of 45

denisT.MaxDoctor
Advisor
Advisor

try this:

try(destroydialog TakeApartRol) catch()
rollout TakeApartRol "Take Apart" width:191
(
	fn getAllMeshElements node faces: detach:on pb: ni: gi: ti: mi: gc_count:0 =
	(
		prefix = node.name + "_"
		
		local tmesh = snapshotasmesh node
		--local amesh = copy tmesh
		local num_groups = 0
		local num_elements = 0
		local elements = #()
		local _detachfaces = meshop.detachfaces
		local _deletefaces = meshop.deletefaces
		
		local t0 = timestamp()
			
		local numverts = tmesh.numverts
		local numfaces = tmesh.numfaces

		local allfaces = #{1..numfaces}
		local verts = for v = 1 to numverts collect #()
		
		for j in allfaces do
		(
			f = getface tmesh j
			for k = 1 to 3 do append verts[f[k]] j
		)
		
		out = false
		local element = #()
		
		if faces == unsupplied do faces = allfaces
		
		for i in faces while not keyboard.escPressed do
		(
			element = #(i)
			for j in element where faces[j] do
			(
				faces[j] = false
				f = getface tmesh j
				for k = 1 to 3 where verts[f[k]] != undefined do
				(
					join element verts[f[k]]
					verts[f[k]] = undefined
				)
			)
			
			if detach then
			(
				join elements element
			)
			else
			(
				append elements (element as bitarray)
			)
			num_elements += 1
			if pb != undefined do pb.value = mod (num_elements/10.0) 100
			if ni != undefined do ni.text = num_elements as string
			if gc_count and (mod num_elements gc_count == 0 or i == numfaces) do 
			(
				--gc light:on
				if detach do
				(
					m = _detachfaces tmesh elements delete:false asmesh:true
					name = uniquename prefix
					n = editable_mesh name:name parent:node
					n.mesh = m
					
					elements = #()
				)
				num_groups += 1
				if gi != undefined do gi.text = num_groups as string
				if ti != undefined do ti.text = ((timestamp() - t0) / 1000) as string
				local val = int (100.0 * heapFree / heapSize + 0.5)
				if mi != undefined do mi.text = val as string
				windows.processPostedMessages()
			)
			
			out = true
		)
		num_elements
		elements
	)	
	
	label facetype_lb "Face Targets: " align:#right offset:[0,4] across:2
	radiobuttons facetype_rb labels:#("All", "Selected") columns:1 align:#left offset:[0,3]
	label bycount_lb "Group By Count: " align:#right offset:[0,4] across:2
	radiobuttons bycount_rb labels:#("1", "10", "100", "1000", "10000") default:1 columns:1 align:#left offset:[0,3]

	checkbox detach_ch "Detach" align:#left offset:[0,0] --across:2

	button mxs_detach_bt "MXS Process" width:172 align:#left offset:[-4,2] 
	progressbar progress_pb color:orange width:172 height:10 align:#center offset:[0,0]
	
	group "Statistics: "
	(
		label number_lb "All Elements" align:#left offset:[8,0] across:3
		label info_01 "0" align:#right offset:[40,0]
		label data_01 "" width:20 align:#right offset:[8,0]
		label groups_lb "Groups By Count" align:#left offset:[8,0] across:3
		label info_02 "0" align:#right offset:[40,0]
		label data_02 "" width:20 align:#right offset:[8,0]
		label time_lb "Time" align:#left offset:[8,0] across:3
		label info_03 "0" align:#right offset:[40,0]
		label data_03 "s" width:20 align:#right offset:[8,0]
		label heap_lb "Memory" align:#left offset:[8,0] across:3
		label info_04 "0" align:#right offset:[40,0]
		label data_04 "%" width:20 align:#right offset:[8,0]
	)
	group "Settings and Debug: "
	(
		checkbox debugh_ch "Debug" align:#left offset:[0,4] across:2
		checkbox gclight_ch " GC Light" align:#left offset:[20,4]
		button gc_bt "Garbage Collection" width:172 align:#left offset:[-4,2] 
	)
		
	fn memoryDisplay = 
	(
		local val = 100.0*heapFree/heapSize + 0.5
		info_04.text = (int val) as string
	)
	on gc_bt pressed do 
	(
		gc light:gclight_ch.state
		memoryDisplay()
		completeRedraw()
	)
	
	local num
	local t0, t1
	local h0, h1
		
	on mxs_detach_bt pressed do undo "Detach" off, with redraw off
	(
		node = selection[1]
		if iskindof node GeometryClass do
		(
			gc light:on
			memoryDisplay()
			
			t0 = timestamp()
			h0 = heapfree
			
			mesh = gettempmesh node
			faces = if facetype_rb.state == 1 then #{1..mesh.numfaces} else (mesh.selectedfaces as bitarray)
			
			count = #(1,10,100,1000,10000)[bycount_rb.state]
			
			global _ee = GetAllMeshElements node faces:faces detach:detach_ch.state \
				pb:progress_pb ni:info_01 gi:info_02 ti:info_03 mi:info_04 gc_count:count
			
			t1 = timestamp()
			h1 = heapfree
			
			format "count:% time:% heap:%\n" _ee.count (t1 - t0) (h0 - h1)
		)
	)

	on TakeApartRol open do
	(
		gc light:on
		memoryDisplay()
	)
)
createdialog TakeApartRol
Message 17 of 45

denisT.MaxDoctor
Advisor
Advisor

you have a pretty fast machine, so the script might not be too slow for you

0 Likes
Message 18 of 45

anycganycgJ8A6A
Advocate
Advocate
I fell asleep and woke up .
You gave me something big like Santa Claus.
thank you thank you thank you
I'll test it tomorrow after I get some sleep.
thank you so much.
0 Likes
Message 19 of 45

Serejah
Advocate
Advocate
Removing frequent stats updates and unrolling 1..3 loops made it noticebly faster from 5.856sec to 4.176sec. But I'm not sure if it depends on a test scene. I used a few dozens of teapots collapsed together.
0 Likes
Message 20 of 45

denisT.MaxDoctor
Advisor
Advisor

I'm pretty sure you're right... there are a few traces, mostly for debugging and analysis, and they should be removed in the final version.

0 Likes