Node Unique ID.

RajDargeRajDarge Posts: 17

 

Is there a unique identifier that is exposed to Daz Script that I can use to differentitle between nodes with the same name or label?

How do you detect if node is a duplicate ?

 

 

Post edited by RajDarge on

Comments

  • Ok so I figured out that the uniqueID is dzNode.elementID. 

    Still haven't worked out how to see if its a duplicate or not?

    Any suggestions would be helpful

     

  • ChoholeChohole Posts: 33,604
    edited October 2019

    I am advised


    The documentation for DzElement::elementID (http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/element_dz) explicitly states "Holds the number used to uniquely identify this element in the scene. (Read Only)".

    Post edited by Richard Haseltine on
  • SimonJMSimonJM Posts: 5,947
    edited October 2019
    Chohole said:

    I am advised


    The documentation for DzElement::elementID (http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/element_dz) explicitly states "Holds the number used to uniquely identify this element in the scene. (Read Only)".

    Your underlying link is 'mangled' heading off to a 'mail redirecter' - after tidying it up is is this one here

    Post edited by SimonJM on
  • SimonJM said:
    Chohole said:

    I am advised


    The documentation for DzElement::elementID (http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/element_dz) explicitly states "Holds the number used to uniquely identify this element in the scene. (Read Only)".

    Your underlying link is 'mangled' heading off to a 'mail redirecter' - after tidying it up is is this one here

    Fixed

  • thanks for that answer :), eventually I found it too. 

    However, is there anyway to identify if an node is a duplicate of another?

    When a dulicate is created there is a number inside () created in the label, but unlike an instance that gives you a  DzNode.getTarget(), there doesn't seem to be a Property that tell you what the base node for a duplicate. I was thinking of looking for the shapename as that seems to incorporate the vertex count the name and it is unlikely (but not impossible) that an item will have the same shape name but have a different base  object.  Even less likely with script only acess to this charateristic as far as I can see. 

    If there was a property like DzNode.getReference()  (as opposed to .getTarget) it would be nice, easier to replace all duplicates with instances which is my next task. 

     

  • MikeDMikeD Posts: 294
    edited October 2019

    You can see all DzNodes methods, properties and signals here: http://docs.daz3d.com/doku.php/public/software/dazstudio/4/referenceguide/scripting/api_reference/object_index/node_dz#a_1a3ae5cfb884e967dfcbf9110b2b861169

    However there is no method or property that indicates if a node is a dublicance of another one.

    If the nodes in the scene are identicals you could rely on their names as all the same items should have the same name. However it wont work for different figures (Vic8 and Gia8 etc have the same name "Genesis8Female"), or if a figure has different materials than the other. If this is not a problem than you could group the same named nodes with the next code:

     

    // DAZ Studio version 4.12.0.86 filetype DAZ Script// by MikeD(function(){	/************************************************************	**************  A function to print the results *************	************************************************************/	function printTheResults(aMainArray){		//working variable		var aGroup = new Array;				for (var i=0; i<aMainArray.length; i+=1){			print("");			print("");			print("-------------------------------------------")			print("Nodes named: "+ aMainArray[i].name);			print("");						aGroup = aMainArray[i].group;						//iterate over the group			for (j=0;j<aGroup.length;j+=1){				print ("    ->       "+aGroup[j].getLabel());			}		}			}		/************ main code ************************************/    //get all nodes in the scene    var aAllNodes = Scene.getNodeList();        //set an array to collect the results    var aExit = new Array;        //working variable    var bExist = false;    var oSkeleton;    var nIndex = 0;        //iterate over the nodes    for (var i=0;i<aAllNodes.length; i+=1){    	    	//take the next node    	oNode = aAllNodes[i];    	    	//check if it there is a node    	if (!oNode) continue;    	    	//take the skeleton    	oSkeleton = oNode.getSkeleton();    	    	//if the skeleton does not exists    	if (oSkeleton == null){    		oSkeleton = oNode;    	}    	    	//reset the boolean    	bExist = false;    	    	//check if you already have placed these nodes into groups    	for (var j=0; j<aExit.length; j+=1){    		    		//if the node name exist set the boolean to bypass it    		if (aExit[j].name == oSkeleton.name){    			bExist = true;    			break;    		}    	}    	    	//check if the node name has been found in the groups    	if (bExist){    		    		//bypass this node    		continue;    	}    	    	//if the script is in this line it is the first time    	//this node has been taken    	//set a new object to collect the grouped nodes    	aExit[nIndex] = new Object;    	//set the name by the node    	aExit[nIndex].name = oSkeleton.name;    	    	//set an array of same items    	aExit[nIndex].group = new Array;    	    	//iterate over the other nodes of the scene    	for (var j=0; j<aAllNodes.length; j+=1){    		    		//check if another node in the line    		//has the same name    		if (aAllNodes[j].name == oSkeleton.name){    			    			//we have a match    			aExit[nIndex].group.push(aAllNodes[j]);    		}    	}    	    	nIndex += 1;    	    }    printTheResults(aExit);    })();

     

    The DzNode object also has the 'dublicate()' method that returns the dublicate root node. If you make the dublicate nodes using a script you could collect the dublicates in an array or set an ElementData for these nodes.

     

    If the script is for commercial use, it would need a lot more checks to ensure that a node is a dublicance of another one....

    Post edited by MikeD on
  • wow, thanks for all that code.

    and nicely documented too. 

    In my dive into the DzNode, I did notice that the "label" property seems to be unique. 

    When a duplicate is created via Gui, it gives it a new label, with a Bracketed number giving its iteration. It remains independant of the original, and if you delete the original, the dupolicate remains. 
    If you try and "SceneTab->Edit->Scene Identification" and try and give it a new Label name, if the name is the same as the base node, it wont let you type it in. If you stuff around and delete and type in characters till it again is the same as the base name, it may accept this value, but it wount actually change it. This is not true of the "name" of the node, or "objectName" not sure if there is a difference. So a simple method would be to check the ShapeName of a mesh , and if it is the same shape name as another mesh, check if the DzNode.getLabel() property is the same for both objects. If not then likley you have found a duplicate. You could also get all the labels and look for a base ( I could do that but I am hopeless at regex, still learning these); or just copy the label to the  objectName. 

    My script so far deletes the duplicate from the scene and makes and instance in place . Which is all well and good for props, but a duplicate of a prop is likley very similar to its base object, A duplicate of a figure is a different animal all together. 

    So I will just ignore figures, bones, but rename figures to have the unique ElementID attached to the objectName. 

     

  • Checking for nodes with the same origin, assuming your method is reliable, won't account for differences in morphs or materials, either of which would be reason not to make them instances.

  • ChoholeChohole Posts: 33,604
    snip

    So I will just ignore figures, bones, but rename figures to have the unique ElementID attached to the objectName. 

     

    I am advised to say to you
    be aware... DzElement::elementID does not persist between sessions

  • RajDargeRajDarge Posts: 17
    edited October 2019
    Chohole said:
    snip

    So I will just ignore figures, bones, but rename figures to have the unique ElementID attached to the objectName. 

     

    I am advised to say to you
    be aware... DzElement::elementID does not persist between sessions

    Thanks, I will bear that in mind. It works well enough for the moment, I am attaching it to the objectName or name property of the object so I guess it will survive a save. 
    I decided to abandon the replace duplicate with instance as I was creating all kinds of problems with the tranform data. 
    Often a duplicate is part of a tree or chain of nodes. Taking out one node and replaceing it with an instance is not a simple task as you have to orphan the replaced node, orphan any child nodes of the replaced node, parent them to new node, and then parent that with the old parent. 
    along the way all the transform data was being stuffed, and things were moving all over the place. I tried copying the transform data from the original object, but have the feeling that its applied in parent space, etc. and As each of the parent/node/child shuffles can potentially stuff up the transform I couldn't figure it out. 
    Plus @Richard was right, I'd have to vertex match the object to be sure it was an identical duplicate. So it didn't seem worth it. 

    function replaceParent(newNode,oldNode){	var oldNodeParent = oldNode.getNodeParent();	var TransformPreserve = false;	var oldNodeChildrenArray = oldNode.getNodeChildren( false );	if (oldNodeParent)	{		var newNodeParent = newNode.getNodeParent();		if (!newNodeParent)		{			oldNodeParent.addNodeChild(newNode,TransformPreserve);		}		else		{			newNodeParent.removeNodeChild(newNode,TransformPreserve);			oldNodeParent.addNodeChild(newNode,TransformPreserve);		}	}	if (oldNodeChildrenArray)	{		for (a_idx = 0 ; a_idx < oldNodeChildrenArray.length; a_idx++ )		{			//splice children back in			var oldNodeChild = oldNodeChildrenArray[a_idx]			oldNode.removeNodeChild(oldNodeChild);			newNode.addNodeChild(oldNodeChild,TransformPreserve);		}	}	return newNode;}

    this was the method I used. 

    function copyNodeTransforms(newNode,oldNode){	var oldNodeWSPos = oldNode.getWSPos();//Vec3	var oldNodeWSRot = oldNode.getWSRot();//Quat	var oldNodeWSScl = oldNode.getWSScale() ;//matrix3	var oldNodelclPos = oldNode.getLocalPos();//Vec3	var oldNodelclRot = oldNode.getLocalRot();//Quat	var oldNodelclScl = oldNode.getLocalScale() ;//matrix3	newNode.setLocalTransform(oldNodelclPos,oldNodelclRot,oldNodelclScl);	newNode.setWSTransform(oldNodeWSPos,oldNodeWSRot,oldNodeWSScl);	return newNode}

     

     

    I just wanted a reliable export to obj method, and changing the name was enough to achieve that. 

    Post edited by RajDarge on
Sign In or Register to comment.