the quadifier challenge

Become a member of the CGSociety

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

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  02 February 2013
the quadifier challenge

so the poor ol' artist is crying into his screen, some third party plugin from "klunk enterprises" has converted his treasured model into all tris and he hasn't backed up in like a gazillion years. Can you fix it for me comes the plea :( .

(this didn't happen by the way I had a need for it doing something else, honestly )

anyway the challenge is to quadify the mesh, the function should make sensible decisions with topology and material boundaries. Sorry if this has been done to death and to prove i,m not looking for someone to fix a problem i created here's my attempt

(
   	fn CreateTheNightmare =
   	(	
   		p = Sphere radius:50.0 smooth:on segs:32 isSelected:on
   		converttomesh p
   		meshop.autoEdge p #all 0.0
   		converttoPoly p
   		p;
   	)
   	
   	fn getTheEdgeDir obj ed =
   	(
   		verts = polyop.getVertsUsingEdge obj ed as array;
   		normalize ((polyop.getVert obj verts[2]) - (polyop.getVert obj verts[1]))
   	)
   	
   	fn getTheFaceAngle obj face1 face2 =
   	(
   		dot (polyop.getfacenormal obj face1) (polyop.getfacenormal obj face2)
   	)
   
   	fn quadifier obj quad_tol planar_tol =
   	(
   		getfacedegfn 		= polyop.getfacedeg;
   		getEdgesUsingFacefn = polyop.getEdgesUsingFace;
   		getEdgesUsingVertfn = polyop.getEdgesUsingVert;
   		getfacesUsingEdgefn = polyop.getfacesUsingEdge;
   		getfacematidfn 		= polyop.getfacematid;
   		
   -- get suitable candidates (in this case this will select all the edges) 	
   		
   		numedges = polyop.getnumedges obj;
   		edges = for i = 1 to numedges where 
   			(faces = getfacesUsingEdgefn obj i as array).count == 2 and 
   				getfacedegfn obj faces[1] == 3 and	getfacedegfn obj faces[2] == 3 collect i;
   
   -- refine the selection
   		
   		newedges = for ed in edges where
   		(
   			ebitarray = #{ed}
   			
   			faces = getfacesUsingEdgefn obj ed as array;
   			verts = polyop.getvertsUsingEdge obj ed as array;	
   			
   			f1edges = getEdgesUsingFacefn obj faces[1];
   			f2edges = getEdgesUsingFacefn obj faces[2];
   			v1edges = getEdgesUsingVertfn obj verts[1];
   			v2edges = getEdgesUsingVertfn obj verts[2];
   			
   			e1 = (v1edges * f1edges - ebitarray) as array;
   			e2 = (v1edges * f2edges - ebitarray) as array;
   			ang1 = abs(dot (getTheEdgeDir obj e1[1]) (getTheEdgeDir obj e2[1]));
   			
   			e1 = (v2edges * f1edges - ebitarray) as array;
   			e2 = (v2edges * f2edges - ebitarray) as array;
   			ang2 = abs(dot (getTheEdgeDir obj e1[1]) (getTheEdgeDir obj e2[1]));
   				
   			matid1 = getfacematidfn obj faces[1];	
   			matid2 = getfacematidfn obj faces[2];		
   				
   			ang1 < quad_tol and ang2 < quad_tol and getTheFaceAngle obj faces[1] faces[2] > planar_tol  and  matid1 == matid2;
   				
   		) collect ed;	
   	
   		polyop.setEdgeSelection obj newedges
   		newedges.count
   	)	
   	
   	resetMaxFile #noPrompt;
   	clearlistener();
   	s = CreateTheNightmare();
   	t = timestamp()
   	quadifier s 0.2 0.98 
   	format "time:%\n" (timestamp() - t)
   )


or just use the optimize modifier ?

Last edited by Klunk : 02 February 2013 at 01:21 PM.
 
  02 February 2013
There's a button on the Graphite Toolbar which does this
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/
 
  02 February 2013
this is what i was using for many years. with specific modifications for some specific case (keep face id or sm group zones for example, quadify every element separately, etc.)

mapped fn quadPolyObj obj = if iskindof obj GeometryClass do
(
	local new = snapshot obj isselected:off
	new.transform = matrix3 1
	resetXForm new
	converttomesh new
	local pbomb = Bomb detonation:0 minFragmentSize:2 maxFragmentSize:2 falloff:100
	bindSpaceWarp new pbomb
	local mesh = snapshotasmesh new
	delete pbomb
	meshop.autoEdge mesh mesh.edges 180
	new.mesh = mesh
	
	new.objectoffsetpos = -obj.objectoffsetpos
	new.transform = inverse (obj.objecttransform*(inverse obj.transform))
	resetXForm new
	converttopoly new
	local threshold = new.edgeWeldThreshold
	new.edgeWeldThreshold = 0.00001
	polyop.weldEdgesByThreshold new new.edges
	new.edgeWeldThreshold = threshold
	instancereplace obj new
	delete new
	delete mesh
	obj
)

this is not my idea, and as i said for this long time of using i forgot whose it is. i just optimized and polished it.
in most cases it works very well.
 
  02 February 2013
does the graphite tool protect material boundaries ? quick test says no but I'm not up on graphite and there maybe settings I'm missing.

that's well wacky denis and quick too !

Last edited by Klunk : 02 February 2013 at 01:41 PM.
 
  02 February 2013
Originally Posted by DaveWortley: There's a button on the Graphite Toolbar which does this

i killed the Graphite Toolbar on my machine... so what was it?
 
  02 February 2013
Originally Posted by denisT: i killed the Graphite Toolbar on my machine... so what was it?


basically this:

if PolyBoost.ValidEPbasemacro() do
 	PolyToolsModeling.Quadrify keyboard.shiftpressed keyboard.altpressed
__________________
Scripts :: linkedin
 
  02 February 2013
Originally Posted by Swordslayer: basically this:

if PolyBoost.ValidEPbasemacro() do
  	PolyToolsModeling.Quadrify keyboard.shiftpressed keyboard.altpressed

do you know what shift and alt do?
 
  02 February 2013
Originally Posted by Klunk: does the graphite tool protect material boundaries ? quick test says no but I'm not up on graphite and there maybe settings I'm missing.

that's well wacky denis and quick too !

so graphite tool works... to protect material boundaries you can detach faces by id, apply quadifier, and weld them back.
 
  02 February 2013
Originally Posted by denisT: so graphite tool works...

but of course in Modifier Panel and for selected objects only...
 
  02 February 2013
Originally Posted by denisT: do you know what shift and alt do?


Selection related stuff:

<bool>Quadrify <bool>withinSel <bool>selectOnly
 When withinSelis set to true, applies to the current sub-object selection only.
 When selectOnly is set to true, does not remove but only selects the edges to be removed.
__________________
Scripts :: linkedin
 
  02 February 2013
there is a slight issue with the graphite & denis method, I didn't want all quads. Also the graphite tool doesn't respect the topology in that though the edge is still there it makes it easier to "see" the shape with it.

Last edited by Klunk : 02 February 2013 at 04:00 PM.
 
  02 February 2013
Originally Posted by denisT: this is what i was using for many years. with specific modifications for some specific case (keep face id or sm group zones for example, quadify every element separately, etc.)

 mapped fn quadPolyObj obj = if iskindof obj GeometryClass do
 (
 	local new = snapshot obj isselected:off
 	new.transform = matrix3 1
 	resetXForm new
 	converttomesh new
 	local pbomb = Bomb detonation:0 minFragmentSize:2 maxFragmentSize:2 falloff:100
 	bindSpaceWarp new pbomb
 	local mesh = snapshotasmesh new
 	delete pbomb
 	meshop.autoEdge mesh mesh.edges 180
 	new.mesh = mesh
 	
 	new.objectoffsetpos = -obj.objectoffsetpos
 	new.transform = inverse (obj.objecttransform*(inverse obj.transform))
 	resetXForm new
 	converttopoly new
 	local threshold = new.edgeWeldThreshold
 	new.edgeWeldThreshold = 0.00001
 	polyop.weldEdgesByThreshold new new.edges
 	new.edgeWeldThreshold = threshold
 	instancereplace obj new
 	delete new
 	delete mesh
 	obj
 )
 

this is not my idea, and as i said for this long time of using i forgot whose it is. i just optimized and polished it.
in most cases it works very well.

Similar concept for this script
__________________
Looking in the right side. [bgaTools]
 
  02 February 2013
that script didn't work properly, it added edges to one quad
 
  02 February 2013
Originally Posted by gazybara: Similar concept for this script

well... but i use my script for more than seven years for sure.
 
  02 February 2013
Originally Posted by denisT: well... but i use my script for more than seven years for sure.

This method is not best solution (oldschool - from period when "Bomb" added to max) but do the job.
Another solid script is DETRIANGULATOR but is very slow and is not allways clean all "diagonals".
__________________
Looking in the right side. [bgaTools]
 
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:40 PM.


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