Below is an example demonstrating how you can create a node instance group of like siblings, via script.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ /*********************************************************************/ // String : A function for retrieving a translation if one exists function text( sText ) { // If the version of the application supports qsTr() if( typeof( qsTr ) != "undefined" ){ // Return the translated (if any) text return qsTr( sText ); } // Return the original text return sText; }; /*********************************************************************/ // Boolean : A function for testing whether or not a QObject instance // inherits one of a list of types function inheritsType( oObject, aTypeNames ) { // If the object does not define the 'inherits' function if( !oObject || typeof( oObject.inherits ) != "function" ){ // We are done... it is not a QObject return false; } // Iterate over the list of type names for( var i = 0, nTypes = aTypeNames.length; i < nTypes; i += 1 ){ // If the object does not inherit the 'current' type if( !oObject.inherits( aTypeNames[i] ) ){ // Next!! continue; } // Return the result return true; } // Return the result return false; }; /*********************************************************************/ // Define common message variables var sTitle = text( "Selection Error" ); var sMessage = text( "An instance node in the scene must be selected to continue." ); var sButton = text( "&OK" ); // Get the root of the primary selection var oNode = Scene.getPrimarySelection(); // If nothing is selected or the selected node is not a node instance if( !oNode || !inheritsType( oNode, ["DzInstanceNode"] ) || inheritsType( oNode, ["DzInstanceGroupNode"] ) ){ // Alert the user MessageBox.warning( sMessage, sTitle, sButton ); // We are done... return; } // Declare an array to catch 'like' sibling instances var aInstances = []; // Get the node parent var oParent = oNode.getNodeParent(); // Get the target var oTarget = oNode.getTarget(); // Get the mode property var oModeProperty = oNode.getCopyModeControl(); // Get the mode var nMode = oModeProperty.getValue(); // Declare working variables var oSelectedNode; // Get the selected nodes var sSelectedNodes = Scene.getSelectedNodeList(); // Iterate over the selected nodes for( var i = 0; i < sSelectedNodes.length; i += 1 ){ // Get the 'current' node oSelectedNode = sSelectedNodes[ i ]; // If the node is not an instance, // is an instance group, // node parents are not the same, // targets are not the same, // or the mode is not the same if( !inheritsType( oSelectedNode, ["DzInstanceNode"] ) || inheritsType( oSelectedNode, ["DzInstanceGroupNode"] ) || !pointersAreEqual( oSelectedNode.getNodeParent(), oParent ) || !pointersAreEqual( oSelectedNode.getTarget(), oTarget ) || oSelectedNode.getCopyModeControl().getValue() != nMode ){ // Skip it... continue; } // Add the node aInstances.push( oSelectedNode ); } // If we have instances if( aInstances.length > 0 ){ // Declare working variables var oGroupNode, oInstanceNode, oInstanceItem; // Get the preview property var oPreviewProperty = oSelectedNode.getPreviewControl(); // Get the preview var bPreview = oPreviewProperty.getValue(); // Create a new instance group oGroupNode = new DzInstanceGroupNode(); // Set the name of the instance group; based on the primary selection oGroupNode.name = String("%1_InstanceGroup").arg( oSelectedNode.name ); // Get the label of the source node var sLabel = oSelectedNode.getLabel(); // Strip the number from the label sLabel = Scene.stripLabelNumber( sLabel ); // Get a unique label sLabel = Scene.getUniqueTopLevelLabel( String("%1 Instance Group").arg( sLabel ) ); // Set the label of the instance group oGroupNode.setLabel( sLabel ); // Add the instance group to the scene Scene.addNode( oGroupNode ); // Put the instance group in item editing mode oGroupNode.beginItemEdit(); // Iterate over the instance nodes for( var i = 0; i < aInstances.length; i += 1 ){ // Get the 'current' instance oInstanceNode = aInstances[ i ]; // Add the instance as a child to the group oGroupNode.addNodeChild( oInstanceNode, false ); // Create an instance item oInstanceItem = oGroupNode.createItem(); // Copy pertinent data from the instance oInstanceItem.copyTransformFromNode( oInstanceNode ); oInstanceItem.name = oInstanceNode.name; oInstanceItem.setLabel( oInstanceNode.getLabel() ); // Remove the instance from the scene Scene.removeNode( oInstanceNode ); } // We are done editing items in the instance group oGroupNode.finishItemEdit(); // Set the target oGroupNode.getTargetControl().setValue( oTarget ); // Set the mode oModeProperty.setValue( nMode ); // Set the preview oPreviewProperty.setBoolValue( bPreview ); // Get the bounding box for the instance group var boxBounding = oGroupNode.getLocalBoundingBox(); // If we've got a bounding box if( boxBounding ){ // Get the minimum corner of the bounding box var vecBoundingBottom = boxBounding.min; // Get the center of the bounding box var vecBoundingCenter = boxBounding.getCenter(); // Get the maximum corner of the bounding box var vecBoundingTop = boxBounding.max; // Make sure the top is at least 1 unit away vecBoundingTop.y = Math.max( 1.0, vecBoundingTop.y ); // Start the origin at the center of the bounding box var vecOrigin = vecBoundingCenter; // Set the origin Y to the bottom of the bounding box vecOrigin.y = vecBoundingBottom.y; // Set the origin of the instance group oGroupNode.setOrigin( vecOrigin, true ); // Set the end point oGroupNode.setEndPoint( new DzVec3( vecBoundingCenter.x, vecBoundingTop.y, vecBoundingCenter.z ), true ); } } // If the primary node was parented if( oParent ){ // Parent the instance group to the same node oParent.addNodeChild( oGroupNode, false ); } // Finalize the function and invoke })();