Break and Weld UV's on 100k tris meshes

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Display Modes
  02 February 2014
Break and Weld UV's on 100k tris meshes

Hello !

So i have those many CAD objects imported as meshes in max.
I'd like to use uv's generated by the CAD software as they are pretty good already but they also have some issues.

First, a lot of map vertices are welded together even if the vertices on the mesh aren't spatially at the same place.
I've found a way to fix this by breaking all uv vertices and reweld them.
But this action takes forever on a huge mesh (50k vertices,100k tris). Canceled after 20min just for breaking.
Do you think there would be a smarter way to do this via maxscript ?
I was thinking that, for instance, there's no need for the weld to look into a treshold as vertex are directly on top of each others.
Thanks for any hints.
__________________

 
  02 February 2014
a small sample file may help
 
  02 February 2014
Ok. I took a small part ot the mesh and duplicated to match the 100k
https://dl.dropboxusercontent.com/u...unwrap_test.obj
You can see that this duplicated part has only one uv element which is a total non sense. I don't even get how max authorize this.
Anyway, as i said, the workaround i've found is to break all points and weld them. Not really an issue for a small mesh. I guess i could split big meshes in small parts, taking care to not destroy the edited normals.
__________________

 
  02 February 2014
Originally Posted by Clanker: First, a lot of map vertices are welded together even if the vertices on the mesh aren't spatially at the same place.
I've found a way to fix this by breaking all uv vertices and reweld them.
But this action takes forever on a huge mesh (50k vertices,100k tris). Canceled after 20min just for breaking.

what do you use to break and weld back map vertices? unwrap_uvw?
using just pure mxs it shouldn't take more than ~2-3 secs for 50K verts mesh

Last edited by denisT : 02 February 2014 at 03:50 AM.
 
  02 February 2014
Yeah,this what i do, considering there's an unwrap on the object

obj = selection[1]
myUV = obj.modifiers[1] 
myUV.unwrap6.selectVerticesByNode #{1..obj.numverts} obj
myUV.breakSelected() 
myUV.setWeldThreshold 0.0001
myUV.weldSelected() 


It obviously doesn't take 3 sec D:
__________________

 
  02 February 2014
fn FakeDetach msh elementFaces = ( meshop.detachFaces msh elementFaces )	

fn ForAllElements msh theFunction =
(
	faces = msh.faces as bitarray;
	while not faces.isEmpty do
	(	
		elemfaces = meshop.getElementsUsingFace msh #((faces as array)[1]); -- this is what slows us down and also requires the gc() call or else we'll run out of memory
		theFunction msh elemfaces;
		faces = faces - elemfaces;
		gc();
	)
)	

ForAllElements $ FakeDetach


this will do what you want takes about 4mins on the sample file
 
  02 February 2014
though the quickest way to get the result is to use explode in the mesh edit geometry panel, set the angle to 180 and use to elements.
 
  02 February 2014
Ok sorry, the sample file isn't representative. Each object is watertight, made of 1 element. I cant parse elements to detach them.
I've reuploaded the obj. It's a small part, only 2,5k point, but same principle, with "corrupted" uvs.
__________________


Last edited by Clanker : 02 February 2014 at 12:58 PM.
 
  02 February 2014
The following code should break all UVW vertices. Welding them is a different thing and I am unsure of how would you accomplish that.

Looks like the source mapping, in the model you uploaded, is highly corrupted and there are many UVW vertices placed on the exact same positions, so welding all of them at once with a threshold will weld vertices that probably belong to different UVW shells.

The code can be easily adapted to work with Editable Poly and with different mapping channels.
(
    
    fn BreakAllUvwVerts obj =
    (
        if obj.modifiers.count == 0 and classof obj == editable_mesh do
        (
            m = snapshotasmesh obj
            meshop.breakVerts m #{1..m.numverts}
            
            numtverts = getnumtverts m
            
            setnumtverts obj numtverts
            buildtvfaces obj
    
            for j = 1 to numtverts do settvert obj j (gettvert m j)
            for j = 1 to m.numfaces do settvface obj j (gettvface m j)
            )
    )
    
    st = timestamp(); sh = heapfree
    BreakAllUvwVerts $
    format "time:% ram:%\n" (timestamp()-st) (sh-heapfree)
    
    )
__________________
Jorge Rodríguez
PolyTools3D
 
  02 February 2014
Originally Posted by Clanker: Yeah,this what i do, considering there's an unwrap on the object

 obj = selection[1]
 myUV = obj.modifiers[1] 
 myUV.unwrap6.selectVerticesByNode #{1..obj.numverts} obj
 myUV.breakSelected() 
 myUV.setWeldThreshold 0.0001
 myUV.weldSelected() 
 


It obviously doesn't take 3 sec D:

honestly i don't believe that this can fix the mapping.
 
  02 February 2014
Well it does, I did the sequence several times on different imports and it always worked. The "re-weld" doesn't weld points that aren't physically at the same place, fixing the 1st issue.
Then I have to re run a break on open edges to actually separate all elements.
Then i run a script to fix the texel ratio, then a bit of manual stitching
I needed it to be faster as i have hundreds of objects. In the end it's still faster than redoing the unwrap manually from scratch.

Thanks Polytools, i've already seen you using that snapshot voodoo magic. Tbh i'm not sure to get what it does, but it's fast. Do you think that welding wouldnt work as the unwrap weld ? I just need it to not weld points that arent at the same physical place.
__________________


Last edited by Clanker : 02 February 2014 at 11:15 PM.
 
  02 February 2014
@Clanker,
I am not sure of the whole process you are doing or what results you are looking for so my comment is purely related to the file you uploaded and the script you posted.

So, if I import the .OBJ file and run your script, I am not getting anything good (from my point of view). But perhaps I am missing part of the process you do, and so my comments about this are useless.

The first script I posted was to just break the UVW vertices, as I didn’t know is the welding you use in your script worked for you. Now that you mention that your script does indeed work as you need, I added the weld part to the original script. So here it is, this script should break all the UVW vertices, and then weld those which are at the same location. In short, you should get the same result as with the snippet you posted but faster.

I think there is still room for optimization, but it performs pretty well compared it with the Unwrap UVW modifier break/weld functions.

If it works for what you need I am not sure it would worth it to keep working on optimizations.

I got these results:
faces:99380 time:2839 ram:25872632L

Edit: Minor improvement in memory ussage speed.
faces:99380 time:2559 ram:19112856L
(
   	
   fn BreakAndWeldAllUvwVerts obj weld:false =
   (
   	
   	if obj.modifiers.count != 0 do return -1
   	if classof obj != editable_mesh do return -1
   	
   	m = snapshotasmesh obj
   	meshop.breakVerts m #{1..m.numverts}
   
   	numtverts = getnumtverts m
   	
   	setnumtverts obj numtverts
   	buildtvfaces obj
   
   	for j = 1 to numtverts do settvert obj j (gettvert m j)
   	for j = 1 to m.numfaces do settvface obj j (gettvface m j)
   	
   	if weld == true do
   	(
   		tverts = for j = 1 to numtverts collect (gettvert m j)
   		setnumtverts obj numtverts
   		buildtvfaces obj
   		
   		for j = 1 to numtverts do settvert  obj j tverts[j]
   		
   		for j = 1 to m.numfaces do
   		(
   			face = gettvface m j
   			v1 = face[1]
   			v2 = face[2]
   			v3 = face[3]
   
   			if (found = finditem tverts (gettvert m v1)) != 0 do v1 = found
   			if (found = finditem tverts (gettvert m v2)) != 0 do v2 = found
   			if (found = finditem tverts (gettvert m v3)) != 0 do v3 = found
   
   			settvface obj j [v1,v2,v3]
   		)
   	)
   
   )
   
   gc()
   st = timestamp(); sh = heapfree
   BreakAndWeldAllUvwVerts $ weld:true
   format "faces:% time:% ram:%\n" $.numfaces (timestamp()-st) (sh-heapfree)
   
   )
__________________
Jorge Rodríguez
PolyTools3D

Last edited by PolyTools3D : 02 February 2014 at 02:20 AM.
 
  02 February 2014
faces:99380 time:2839

these are the right numbers
 
  02 February 2014
Here is a compact Break&Weld version that runs a little bit faster
(
  	
  fn BreakAndWeldAllUvwVerts obj =
  (
  	if obj.modifiers.count != 0 do return -1
  	if classof obj != editable_mesh do return -1
  	
  	m = snapshotasmesh obj
  	meshop.breakVerts m #all
  
  	numtverts = getnumtverts m
  	
  	setnumtverts obj numtverts
  	buildtvfaces obj
  	
  	tverts = for j = 1 to numtverts collect (gettvert m j)
  	for j = 1 to numtverts do settvert obj j tverts[j]
  	
  	for j = 1 to m.numfaces do
  	(
  		face = gettvface m j
  		v1 = finditem tverts (gettvert m face[1])
  		v2 = finditem tverts (gettvert m face[2])
  		v3 = finditem tverts (gettvert m face[3])
  		settvface obj j [v1,v2,v3]
  	)
  )
  	
  )
__________________
Jorge Rodríguez
PolyTools3D

Last edited by PolyTools3D : 02 February 2014 at 03:33 AM. Reason: Changed #{1..m.numverts} to #all (Thanks denisT)
 
  02 February 2014
Originally Posted by PolyTools3D:

	meshop.breakVerts m #{1..m.numverts}
 

this is not a first time when i see it in your very nice codes...

	meshop.breakVerts m #all
 

it could mike it nicer
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright ©2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 10:47 PM.


Powered by vBulletin
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.