UV image

Hi all.

I am trying to get an image or pixmap of the current UV set for a selected material, throught a script. Any ideas?

Mike

Comments

  • You mean a template?

  • MikeDMikeD Posts: 81
    edited August 10

    You mean a template?

    Yes, like making a template!

    Post edited by MikeD on
  • I think you can get the UVs from DzShape - unfortunately the docs for that are not currently available, so you may have to do a bit of guessing using discovery and the DS 3 scripting docs (and bear in mind that the change log has shown various changes). However, I'm not sure how easy it would be to then build the map.

  • MikeDMikeD Posts: 81

    i can retrieve all properties, methods and signals from the DzShape (and the parent Objects) from here....

    (function(){
    	
    	//Take the selected object
    	var oSelectedNode = Scene.getPrimarySelection();
    	
    	//take the shape
    	var oShape = oSelectedNode.getObject().getCurrentShape();
    	
    	aProperties = Object.getOwnPropertyNames(oShape);
    	print(JSON.stringify(aProperties,null,"\t"));
    		
    })();

    Ok, I took them.... Let me see if I can get something usefull in here....

     

    Thanks a lot for the response Richard... I' ll post the resaults....

  • MikeDMikeD Posts: 81

    No luck with DzShape....

    I can take the UVsets from DzMaterial getActiveUVSet but it is just the vertex map containing the data for a UV set. The problem is to turn this UVSet into an image....

  • Richard HaseltineRichard Haseltine Posts: 55,255
    edited August 10

    It should be a list of UV values, which are coordinates in ( [0,1] , [0,1] ). You'd have to figure out how to extract those, which in turn would probably require getting the list of vertices making up each polygon, and as I said i don't know how you'd then turn a list of lines into a map (if it's even possible). Assuming it actually possible to do the first part (get a list of edge coordinates in 2D-space) I wonder if it would be possible to generate a simple vector image format, which you could then open in a drawing app to get your template.

    Post edited by Richard Haseltine on
  • MikeDMikeD Posts: 81
    edited August 11

    I managed to take the values of the map, but the image is not quite right. The image is made in DAZ with setPixel method. The image was initially inverted in Y axis ...

    I will try to take the UVs from every vertice using facets, and make a connection between them.

    // DAZ Studio version 4.11.0.383 filetype DAZ Script
    
    (function (){
    	
    	//----------------------------------------------------------------//
    	//void: a function to draw a line between 2 points
    	function connectTheVectors(pointA, pointB){
    		
    		//check if pointB is null at the 1st loop
    		if (pointB == null) return;
    		
    		//working variables
    		//remember to inverse Y
    		var Yb = nMulti-Math.round(nMulti*pointB.y);
    		var Ya = nMulti-Math.round(nMulti*pointA.y);
    		var Xb = Math.round(nMulti*pointB.x);
    		var Xa = Math.round(nMulti*pointA.x);
    		
    		//safety check
    		//the 2 points cannot be very far away
    		if (Math.abs(Xa-Xb) > nSafety || Math.abs(Ya-Yb) > nSafety){
    			//go back
    			return;
    		}
    		
    		
    		//find the pitch of a line onnect the two points
    		//(Yb-Ya/Xb-Xa)
    		var nTop = Yb - Ya;
    		var nBot = Xb - Xa;
    		var nAngle = nTop / nBot ;
    		
    		//find the equation constant nB
    		nB = Ya - nAngle*Xa;
    		
    		//the equation is Y = ang*X + nB
    		var nY; //the Y value;
    		
    		//check if Xa<Xb
    		if (Xa<Xb){
    			var nStep = 1;
    		}else{
    			var nStep = -1;
    		}
    		
    		//itarate over the Xa to Xb points
    		// j = Xa + int and is already rounded
    		for (var j = Xa+1; Math.abs(j-Xb) > 0 ; j+=nStep ){
    			
    			//find the Y value by the equation
    			nY = nAngle*j + nB;
    			
    			//round it
    			nY = Math.round(nY);
    			
    			//draw the pixel
    			oUVImage.setPixel(j , nY, oBlack);
    		}
    		
    	};
    	
    	//--------------- end of Subfunctions ----------------------//
    	
    	//set the diamentions of the UV image map
    	var nMulti = 800;
    	
    	//set a safety value for the distance (dX or dY) of 2 values
    	var nSafety = nMulti/8;
    	
    	//Take the selected object
    	var oSelectedNode = Scene.getPrimarySelection();
    	
    	//take the shape
    	var oShape = oSelectedNode.getObject().getCurrentShape();
    	
    	//take the surfaces
    	var aSurfaces = oShape.getAllMaterials();
    	
    	//take the 1st UV set
    	var oUV = aSurfaces[0].getActiveUVSet(oShape);
    	
    	//take the number of informations
    	var nValues = oUV.getNumValues();
    	
    	//create an image nMulti(x)nMulti
    	var oUVImage = new Image ( nMulti, nMulti, 4 );
    	
    	//fill the image with white color
    	oUVImage.fill (Color (255,255,255));
    	
    	//create a black color
    	var oBlack = new Color(0,0,0);
    	
    	//set some working variables
    	var oVector;
    	var oVectorOld = null;
    	
    	//iterate over the UV values
    	for (var i=0; i<nValues; i+=1){
    		
    		//take the UV vector point for i
    		oVector = oUV.getPnt2Vec(i);
    		
    		//place a black dot on the image
    		oUVImage.setPixel(Math.round(nMulti*oVector.x), nMulti-Math.round(nMulti*oVector.y), oBlack);
    		
    		//connect the two points
    		connectTheVectors(oVector, oVectorOld);
    		
    		//set the old Vector
    		oVectorOld = oVector;
    		
    	}
    	
    	
    	// Create a basic dialog
    	var wDlg = new DzBasicDialog();
     
    	// Get the wrapped widget for the dialog
    	var oDlgWgt = wDlg.getWidget();
     
    	// Set the title of the dialog
    	wDlg.caption = "My UV Image";
     
    	// Strip the space for a settings key
    	var sKey = wDlg.caption.replace( / /g, "" ) + "Dlg";
     
    	// Set an [unique] object name on the wrapped dialog widget;
    	oDlgWgt.objectName = sKey;
     
    	// Create a pixmap for the image
    	var pixUVImage = new Pixmap();
    	
    	//Take it from the UV image
    	pixUVImage.fromImage (oUVImage);
     
    	// Create a label and assign the pixmap
    	var lblUVMap = new DzLabel( wDlg );
    	
    	lblUVMap.pixmap = pixUVImage;
    	
    	// Add the label to the dialog
    	wDlg.addWidget( lblUVMap, 0, DzWidget.AlignCenter );
     
    	// Get the minimum size of the dialog
    	var sizeHint = oDlgWgt.minimumSizeHint;
     
    	// Set the fixed size of the dialog
    	wDlg.setFixedSize( sizeHint.width, sizeHint.height );
     
    	// Set the text on the accept button
    	wDlg.setAcceptButtonText( "&Close" );
    	
    	// Hide the cancel button
    	wDlg.showCancelButton( false );
     
    	// Display the dialog
    	wDlg.exec();
    	
    	
    })();

    The above code gave me the result in the attachment... (a test at one of my columns)!

    UV in DAZ 1st attempt.png
    807 x 868 - 52K
    Post edited by MikeD on
  • MikeDMikeD Posts: 81

    Ok! The above code is a first approach but not the idial.

    The correct approach is:

    - Take the edges --> take the vertices (A and B) indexes and the facets (A and B) indexes of each edge

    - Take the facets (A and B) by their indexes

    - Find the Vertices (A and B) of the Facets (A and B) that belong to the specific edge

    - Check their UV indexes

    - If the UVs of the A vertex or the B vertex are not the same between the Facets than we have a discontinue, otherwise they are normal

    - Collect the normal and discontinue vetrexes' UVs indexes in arrays

    - Take the UVSet, as I did in the above code

    -Make lines, using setPixel() method to an Image object and a lot of maths.

    - Show the image

    The result is awesome (attachment):

     

     

    UV in DAZ 2nd attempt.png
    806 x 868 - 44K
  • MikeDMikeD Posts: 81

    Now I have to figure out a way to see if a point of the image is in or out the UV islands...

    wink

  • TotteTotte Posts: 10,600

    Nice work!

  • TotteTotte Posts: 10,600
    MikeD said:

    Ok! The above code is a first approach but not the idial.

    The correct approach is:

    - Take the edges --> take the vertices (A and B) indexes and the facets (A and B) indexes of each edge

    - Take the facets (A and B) by their indexes

    - Find the Vertices (A and B) of the Facets (A and B) that belong to the specific edge

    - Check their UV indexes

    - If the UVs of the A vertex or the B vertex are not the same between the Facets than we have a discontinue, otherwise they are normal

    - Collect the normal and discontinue vetrexes' UVs indexes in arrays

    - Take the UVSet, as I did in the above code

    -Make lines, using setPixel() method to an Image object and a lot of maths.

    - Show the image

    The result is awesome (attachment):

     

    @MikeD:

    I think I got it fairy good after some tweaking and finding a brilliant line drawing routine that I ported to DS, here.

     

    BA Small Crate_wood_uvmeshmap.jpg
    2048 x 2048 - 456K
  • MikeDMikeD Posts: 81

    Pretty nice Totte.... smiley

  • EsemwyEsemwy Posts: 556
    edited September 21

    Guess I'm late to the party, but I thought you might want to consider what I did a while back. I started with mcjtemplate, but rather than outputting an image, I output SVG. When you open an SVG in Photoshop (or Gimp), it asks what you'd like the resolution to be. You do have to draw a bounding box around the image to make it play nice, but otherwise you get resolution independant UVs with no maths necessary for the drawing.

    The Zip contains only the source SVG file.

    zip
    zip
    G8F.svg.zip
    77K
    G8F.jpg
    1000 x 1000 - 421K
    Post edited by Esemwy on
  • TotteTotte Posts: 10,600

    Nice idea!
     

Sign In or Register to comment.