PP2ExporterDS4



NOTE : I WILL EVENTUALLY CORRECT THIS
BUT UNDER CERTAIN CIRCUMSTANCES THE MORPHS
ARE NOT EXPORTED IF THEY ARE SET AT 0% STRENGTH
SO ... you could set them to 0.001% or something like that 


Introduction

PP2 Exporter was originally written by Duke533

the program was adapted to Daz Studio 3 use by JWAS84

i found the code here http://puzzlekiraly.hu/lom/PP2%20exp%202b.dsa

I corrected 3 things to make it work for Daz Studio 4.5+ ( Daz Studio 4.8 )

note: elsewhere on this site you can find mcjPackager
which will make your life as a props distributor easy


** around line 741
** The call to
** setWSScale( DzMatrix3 )
** was replaced by 
** setWSScale( DzMatrix3(1,0,0,0,1,0,0,0,1,0,0,0) );
**
** the 3 pushbuttons now have a minHeight that make them 
** a normal size in DS4.8 instead of a thin sliver
**
** around line 393 the initValue for Scale transforms 
** will correctly be 1 instead of 0



History


2015 July 24  - made compatible with DS3 

2015 July 20 8:30 pm  - Release





Installation



The zip package is found at the bottom of this page

unzip it in your daz content folder, typically 


C:\Program Files\DAZ\Studio\content\ 
or

C:\Program Files (x86)\DAZ\Studio\content\


once installed, it will appear in your content library, under Studio / Scripts / 


or

C:\Users\Public\Documents\My DAZ 3D Library\


once installed, it will appear in your content library, under My DAZ 3D Library / Scripts / 





Use



Select the root node of your prop, launch the script ...

will be updated




note 1 : the geometry ( the objects that make up your prop ) must be primitives or imported OBJ files for which you own the copyrights



note 2 : the script hides everything in the scene and exports the prop elements one by one,

if there's something else in your scene with locked nodes the script will fail to make it invisible

and that something will be exported as many times as there are props elements

thereby making your prop unusable and possibly containing stuff you're not allowed to distribute


Source code



// DAZ Studio version 3.0  filetype DAZ Script

/***************************************************************************
**		PP2 exporter 2.0b
**		Description: Export Prop with limited Mat support.
**		Authors: JWAS84, DUKE533
****************************************************************************
**		24-02-09 ver 1a			(JWAS84)
**		(c) Copyright NONE. Use for whatever you like.
**		ExportObj Was written by Rob Whisenant.
**		renderIcon Was written by Guandalug
****************************************************************************
**		18-11-09 ver 1b	
**		- working on DS 3!
**		- lot of bug fixes
**		- renderIcon was replaced (DS3 compatible)
**		x only single object suport
****************************************************************************
**		22-11-09 ver 1c	
**		- more bug fixes
**		- multi-object support (weld)
**		- new script icon
**		x code tweaking needed
****************************************************************************
**		27-11-09 ver 2a	
**		- more bug fixes
**		- weld & chold mode
**		- trans. channels save
**		- GUI
**		- new script icon
****************************************************************************
**		29-11-09 var 2b
**		- code tweaking
**		- morph settings
***************************************************************************/

/****************************************************************************
** July 20th 2015
** mCasual/Jacques
** around line 741
** The call to
** setWSScale( DzMatrix3 )
** was replaced by 
** setWSScale( DzMatrix3(1,0,0,0,1,0,0,0,1,0,0,0) );
**
** the 3 pushbuttons now have a minHeight that make them 
** a normal size in DS4.8 instead of a thin sliver
**
** around line 393 the initValue for Scale transforms 
** will correctly be 1 instead of 0
** July 24th 2015
** mCasual/Jacques
** when using DS3 the old scaling method is used
***************************************************************************/

// Variables
var sSrcPath, sObjPath, lObjPath, sFileName, m_oFile;
var nIndent = 0;
var dazScaler = 243.84;	// Scale to DAZ units


var m_Channels = [
				[ "xOffsetA"   ,"OriginX" ,"OriginX"     ,"0.004" ],
		 	 	[ "yOffsetA"   ,"OriginY" ,"OriginY"     ,"0.004" ],
		  		[ "zOffsetA"   ,"OriginZ" ,"OriginZ"     ,"0.004" ],
				[ "translateX" ,"xTran"   ,"X Translate" ,"0.001" ],
				[ "translateY" ,"yTran"   ,"Y Translate" ,"0.001" ],
				[ "translateZ" ,"zTran"   ,"Z Translate" ,"0.001" ],
				[ "rotateX"    ,"xRotate" ,"X Rotate"    ,"1"     ],
				[ "rotateY"    ,"yRotate" ,"Y Rotate"    ,"1"     ],
				[ "rotateZ"    ,"zRotate" ,"Z Rotate"    ,"1"     ],
				[ "scale"      ,"Scale"   ,"Scale"       ,"0.004" ],
				[ "scaleX"     ,"xScale"  ,"X Scale"     ,"0.004" ],
				[ "scaleY"     ,"yScale"  ,"Y Scale"     ,"0.004" ],
				[ "scaleZ"     ,"zScale"  ,"Z Scale"     ,"0.004" ],
		  		[ "xOffsetB"   ,"xOffB"   ,"xOffB"       ,"0.004" ],
		  		[ "yOffsetB"   ,"yOffB"   ,"yOffB"       ,"0.004" ],
		  		[ "zOffsetB"   ,"zOffB"   ,"zOffB"       ,"0.004" ]
];





// default settings
setup={};
setup.icon=1;





// **********************************************************************************
// This is the main section that produces the Prop file.
// **********************************************************************************

var selected= Scene.getSelectedNodeList();

if( selected.length==1 ) {

	// Target nodes
	oNode = selected[0];
	oNodes= oNode.getNodeChildren(1);
	oNodes.unshift( oNode );

	// Default files
	var root = App.getContentMgr().getAbsolutePath( "runtime",0 ); 
	setup.pp2= root +"/libraries/props/"+ oNode.name +".pp2";
	setup.obj= root +"/Geometries/"+ oNode.name +".obj";

	// Open gui
	win= initGui();
	loadSetup( win );
	ok= win.exec();

	// If we have filename, carry on, else abort.
	if( ok ) {
			// Save settings
			saveSetup( win );

			oFile= new DzFile( setup.pp2 );
			oFile.open( oFile.ReadWrite | oFile.Truncate );

			// Render an icon into the PROP folder.
			setup.png= setup.pp2.replace(".pp2",".png");
			renderIcon( setup.png );

			// OBJ exporter need unique material names
			setUniqueMetNames();

			// Write PROP file header.
			writeLine("{");
			writeLine("version");
			writeLine("{");
			writeLine("number 4.01");
			writeLine("}");
			writeLine("	//");
			writeLine("	//	PP2 exporter 2a");
			writeLine("	//");

			while( oNode=oNodes[0] ) {
				// Export the OBJ using the DAZ Exporter.
				ExportObj();

				PropName= oNode.name;
				ObjFile= RelativePath( setup.obj );

				// Write PROP geometry statement.
				writeLine(String("prop %1").arg(PropName));
				writeLine("{");
				writeLine("storageOffset 0 0.3487 0");
				writeLine( String("objFileGeom 0 0 %1").arg(ObjFile) );
				writeLine("}");
				writeLine("//");

				// Output the Transformers. This routine will call the function for writing the Materials.
				OutputTransformers(oNode);
				// Meterials section will shift oNodes !
				
				if( setup.single ) { break; }
			}

			// All done, write end of File.
			writeLine("doc");
			writeLine("{");
			writeLine(String("addActor %1").arg( PropName ));
			writeLine("}");
			writeLine("}");

			oFile.close();
			MessageBox.information( "PROP Created..", "Done", "&OK" );
			App.getContentMgr().refresh(1);
	}
	
} else {
		MessageBox.information("You must select an item in the scene first!","Oops!","&OK");
}









// **********************************************************************************
// Routine to write out the Transformers.
//	A lot of default values are set, but we are the creater so we can say what they will be.
//	The values selected are the value that POSER would use as default.
// **********************************************************************************
function OutputTransformers(oNode) {
	parent= oNode.isSelected() ? "UNIVERSE" : oNode.getNodeParent().name;

	// For first section just use Defaults for now.
	writeLine(String("prop %1").arg(PropName));
	writeLine("{");
	writeLine(String("name %1").arg(PropName));
	writeLine("on");
	writeLine("bend               1");
	writeLine("dynamicsLock       1");
	writeLine("hidden             0");
	writeLine("addToMenu          1");
	writeLine("castsShadow        1");
	writeLine("includeInDepthCue  1");
	writeLine("useZBuffer         1");
	writeLine("parent             "+parent);
	writeLine("creaseAngle        80");

	writeLine("channels");
	writeLine("{");

	// Output OffsetsA.
	var orig = oNode.getOrigin();
	var OX= orig.x / dazScaler;
	var OY= orig.y / dazScaler;
	var OZ= orig.z / dazScaler;
	//
	writeOffset( m_Channels[0], OX );
	writeOffset( m_Channels[1], OY );
	writeOffset( m_Channels[2], OZ );

	// Output Translate
	var LP= oNode.getLocalPos();
	if( !setup.pos && oNode.isSelected() ) { LP=DzVec3(); }
	//
	writeTrans( m_Channels[3], LP.x/dazScaler );
	writeTrans( m_Channels[4], LP.y/dazScaler );
	writeTrans( m_Channels[5], LP.z/dazScaler );

	// Output Rotate
	var RX= oNode.getXRotControl().getValue();
	var RY= oNode.getYRotControl().getValue();
	var RZ= oNode.getZRotControl().getValue();
	if( !setup.rot && oNode.isSelected() ) { RX=RY=RZ=0; }
	//
	writeTrans( m_Channels[6], RX );
	writeTrans( m_Channels[7], RY );
	writeTrans( m_Channels[8], RZ );

	// Output Scale
	var LS= oNode.getLocalScale();
	var S1= oNode.getScaleControl().getValue();
	if( !setup.scale && oNode.isSelected() ) { S1=1; LS=DzMatrix3(); }
	//
	writeTrans( m_Channels[9],  S1 );
	writeTrans( m_Channels[10], LS.m11/S1 );
	writeTrans( m_Channels[11], LS.m22/S1 );
	writeTrans( m_Channels[12], LS.m33/S1 );

	// Output OffsetsB.
	writeOffset( m_Channels[13], -OX );
	writeOffset( m_Channels[14], -OY );
	writeOffset( m_Channels[15], -OZ );

	// Deal with MORPHS here.
	ChkMorphs( oNode );

	// Close 'channels'
	writeLine("}")				

	writeLine(String("origin %1 %2 %3").arg(OX).arg(OY).arg(OZ) );

	var oBox = oNode.getEndPoint();
	var PosX = oBox.x / dazScaler;
	var PosY = oBox.y / dazScaler;
	var PosZ = oBox.z / dazScaler;
	writeLine(String("endPoint %1 %2 %3").arg(PosX).arg(PosY).arg(PosZ) );

	var  oOri = oNode.getOrientation();
	writeLine(String("orientation %1 %2 %3").arg( oOri.x ).arg( oOri.y ).arg( oOri.z ) );

	// Use more Default values.
	writeLine("displayOrigin      0");
	writeLine("displayMode USEPARENT");
	writeLine("customMaterial     1");

	// Write out the MATERIAL section from here to keep the format the same as POSER.
	OutputMaterial();

	writeLine("locked 0");
	writeLine("backfaceCull 0");
	writeLine("visibleInReflections 1");
	writeLine("visibleInRender 1");
	writeLine("displacementBounds 0");
	writeLine("shadingRate 0.2");
	writeLine("smoothPolys 1");
	writeLine("}");				// Close 'Prop'
}




// **********************************************************************************
// Check for MORPHS and output data for them.
function ChkMorphs( oNode ) {
	if( setup.morph!=1 ) { return; }

	var oObject = oNode.getObject();
	if( oObject == undefined ){ return; }

	try {
	 oGeom= oObject.getCurrentShape().getGeometry();
	} catch(x){ return; }
			
	var nVerts = oGeom.getNumVertices();
//	writeLine(String("# Vertex count %1").arg(nVerts));

	// Check to see if there are any modifiers (MORPHS). Loop through and write them out.
	var nModifiers = oObject.getNumModifiers();
	for( var ci=0; ci < nModifiers; ci++ ) {

			// Get a valid morph.
			var oMorph = oObject.getModifier(ci);
			if( oMorph.className() != "DzMorph" ) { continue; }

			// Not intersted in modifier with no delta.
			var oMorphDeltas = oMorph.getDeltas();
			if(!oMorphDeltas) { continue; }
			
			// If it has deltas we can start.
			if( oMorphDeltas.hasDeltas() ) {

					var sMorphName   = oMorph.name;
					var nMorphValue  = oMorph.getValueChannel().getValue();
					var oMorphDeltas = oMorph.getDeltas();
					var nMorphDeltas = oMorphDeltas.getNumDeltas();

					writeLine( String("targetGeom %1").arg(sMorphName) );
					writeLine("{");
					writeLine( String("name %1").arg(sMorphName) );
					writeLine("initValue 0");
					writeLine("hidden 0");
					writeLine("forceLimits 1");
					writeLine("min -100000");
					writeLine("max 100000");
					writeLine("trackingScale 0.02");
					writeLine("keys");
					writeLine("{");
					writeLine("static  0");
					writeLine( String("k 0 %1").arg(nMorphValue) );
					writeLine("}");
					writeLine("interpStyleLocked 0");
					writeLine( String("indexes %1").arg(nMorphDeltas) );
					writeLine( String("numbDeltas %1").arg(nVerts) );
					writeLine("deltas"); 
					writeLine("{");

					// For each delta					
					for(var j = 0; j < nMorphDeltas; j++){
						// Get delta and index
						var vecDelta = oMorphDeltas.getDeltaVec(j);
						var nDeltaIdx = oMorphDeltas.getDeltaIndex(j);
						writeLine(String("d %1 %2 %3 %4").arg(nDeltaIdx).arg(vecDelta.x/dazScaler).arg(vecDelta.y/dazScaler).arg(vecDelta.z/dazScaler));
					}
					writeLine("}");
					writeLine("blendType 0");
					writeLine("}");

			}	// Valid Morph
	}	// Next Morph

}









// **********************************************************************************
// 	From here down are the Functions that are called to perform repeated tasks,
// 	or best kept seperate i.e. renderIcon, ExportObj etc.
// **********************************************************************************

// Write Name, color and strength. 
// **********************************************************************************
function WriteColor(Name,oMatColor,oMatStrength) {
	oRed   = oMatColor.red / 255;
	oGreen = oMatColor.green / 255;
	oBlue  = oMatColor.blue / 255;
	writeLine(String("%1 %2 %3 %4 %5").arg(Name).arg(oRed).arg(oGreen).arg(oBlue).arg(oMatStrength));
}


// **********************************************************************************
// Write a channel section to Prop file - Type 1
// **********************************************************************************
function writeTrans( par, nVal ){
	writeLine(String("%1 %2").arg( par[0] ).arg( par[1] ));
	writeLine("{");
	writeLine(String("name %1").arg( par[2] ));
	/* mCasualJacques change - important that the default zero scale is 1 not 0 */
	//writeLine("initValue 0");
	writeLine(String("initValue %1").arg( nVal ));
	/* mCasualJacques change - important that the default zero scale is 1 not 0 */
	
	writeLine("hidden 0");
	writeLine("forceLimits 0");
	writeLine("min -100000");
	writeLine("max 100000");
	writeLine(String("trackingScale %1").arg( par[3] ));
	writeLine("keys");
	writeLine("{");
	writeLine("static  0");
	writeLine(String("k 0 %1").arg( nVal ));
	writeLine("}");
	writeLine("interpStyleLocked 0");
	writeLine("}");
}


// **********************************************************************************
// Write a channel section to Prop file - Type 2
// **********************************************************************************
function writeOffset( par, nVal ){
	writeLine(String("%1 %2").arg( par[0] ).arg( par[1] ));
	writeLine("{");
	writeLine(String("name %1").arg( par[2] ));
	writeLine(String("initValue %1").arg( nVal ));
	writeLine("hidden 1");
	writeLine("forceLimits 0");
	writeLine("min -100000");
	writeLine("max 100000");
	writeLine(String("trackingScale %1").arg( par[3] ));
	writeLine("keys");
	writeLine("{");
	writeLine("static  1");
	writeLine("k 0 0");
	writeLine("}");
	writeLine("interpStyleLocked 0");
	writeLine(String("staticValue %1").arg( nVal ));
	writeLine("}");
}


// **********************************************************************************
// Materials Section
// **********************************************************************************
function OutputMaterial() {
	
	nodes= oNode.getNodeChildren(1);
	nodes.unshift( oNode );

	while( oNode=oNodes.shift() ) {

		try {
		 var Mats= oNode.getObject().getCurrentShape().getAllMaterials();
		} catch(x){ break; }

		// Each material has a name, usually corresponding to the material zone (group of polygons) onto which it is applied. 
		// These material names must match the usemtl fields defined within the Wavefront .obj file. 

		for( var m=0; m< Mats.length; m++ ) {

					var Mat= Mats[m];

					for( x=0; x<20; x++ ) {
					  Mat.name= Mat.name.replace( " ", "_" );
					}

					writeLine( String("material %1").arg( Mat.name ) );
					writeLine("{");
					// ********************************************************************************************
					// KdColor, KaColor, KsColor, TextureColor and ReflectionColor each specify RGB values with a strength setting tagged on. 
					// The values for each field are from 0.0 to 1.0.
					// ********************************************************************************************

					// KdColor specifies the material's diffuse color.
					WriteColor("KdColor",Mat.getDiffuseColor(),Mat.getDiffuseStrength());

					// KaColor specifies the material's ambient color (for ambient lighting).
					WriteColor("KaColor",Mat.getAmbientColor(),Mat.getAmbientStrength());

					// KsColor specifies the material's specular color (for specular highlights).
					WriteColor("KsColor",Mat.getSpecularColor(),Mat.getSpecularStrength());

					// TextureColor specifies a color, but the RGB is always 1,1,1. The strength setting affects the textureMap image.
					WriteColor("TextureColor ",Mat.getDiffuseColor(), 1 );

					// NsExponent - Glossiness. Its value ranges from 0 to 100.
					oProperty = (1 - Mat.findPropertyByLabel( "Glossiness" ).getValue()) * 200;
					writeLine(String("NsExponent %1").arg(oProperty));

					// tMin - tMax is the transparency minimum and maximum values. Can't find tMin, use defaults 
					writeLine("tMin 0");
					oProperty = 1 - Mat.getBaseOpacity( );
					writeLine(String("tMax %1").arg(oProperty));

					// tExpo is the transparency falloff.
					oProperty = Mat.getOpacityControl ( ).getValue();
					writeLine(String("tExpo %1").arg(oProperty));

					// bumpStrength is the strength of the bump map (how much apparent elevation is added negative values which range from -1.0 to 1.0. 
					oProperty = Mat.getBumpStrength();
					writeLine(String("bumpStrength %1").arg(oProperty));

					// ksIgnoreTexture determines whether or not to apply texture to specular highlight. 0 or 1. DEFAULT
					writeLine("ksIgnoreTexture 0");

					// reflectThruLights determines whether or not to multiply reflection through lights. 0 or 1. DEFAULT
					writeLine("reflectThruLights 1");

					// reflectThruKd determines whether or not to multiply reflection through object color. 
					oProperty = Mat.getMultThroughOpacityControl( ) ;
					if( oProperty ){ writeLine("reflectThruKd 1"); }
					else           { writeLine("reflectThruKd 0"); }

					// textureMap
					oProperty = Mat.getColorMap();
					if( oProperty ) {
							oFileName = RelativePath( oProperty.getFilename() );
							writeLine( String("textureMap %1").arg(oFileName) );
					} else {
							writeLine("textureMap NO_MAP");
					}

					// bumpMap
					oProperty = Mat.getBumpMap(); 
					if( oProperty ) {
							oFileName = RelativePath( oProperty.getFilename() );
							writeLine( String("bumpMap %1").arg(oFileName) );
					} else {
							writeLine("bumpMap NO_MAP");
					}

					// reflectionMap
					oProperty = Mat.getReflectionMap();
					if( oProperty ) {
							oFileName = RelativePath( oProperty.getFilename() );
							writeLine( String("reflectionMap %1").arg(oFileName) );
					} else {
							writeLine("reflectionMap NO_MAP");
					}

					// transparencyMap
					oProperty = Mat.getOpacityMap();
					if( oProperty ){
							oFileName = RelativePath( oProperty.getFilename() );
							writeLine( String("transparencyMap %1").arg(oFileName) );
					} else {
							writeLine("transparencyMap NO_MAP");
					}

					// ReflectionColor specifies the material's reflection color. 
					WriteColor("ReflectionColor",Mat.getReflectionColor(), 1 );

					// reflectionStrength is the amount or "depth and clarity" of the reflection.
					var reflectionStrength = Mat.getReflectionStrength();
					writeLine( String("reflectionStrength %1").arg(reflectionStrength) );
					writeLine("}");

		}	// Next Mat
		if( !setup.weld ) { break; }

	}	// Next Node
	PreviewMat();

// End Material Section.
}




// ********************************************************************************************
// A Default Preview Material.
// ********************************************************************************************
function PreviewMat() {	

	writeLine("material Preview");
	writeLine("{");
	writeLine("KdColor 0.654622 0.497543 0.861782 1"); 
	writeLine("KaColor 0 0 0 1"); 
	writeLine("KsColor 0.187072 0.0360363 0.131175 1"); 
	writeLine("TextureColor 1 1 1 1"); 
	writeLine("NsExponent 5.0"); 
	writeLine("tMin 0"); 
	writeLine("tMax 0"); 
	writeLine("tExpo 0.6"); 
	writeLine("bumpStrength 1"); 
	writeLine("ksIgnoreTexture 0"); 
	writeLine("reflectThruLights 1"); 
	writeLine("reflectThruKd 0"); 
	writeLine("textureMap NO_MAP");
	writeLine("bumpMap NO_MAP");
	writeLine("reflectionMap NO_MAP");
	writeLine("transparencyMap NO_MAP");
	writeLine("ReflectionColor 1 1 1 1"); 
	writeLine("reflectionStrength 1"); 
	writeLine("}");
}


// **********************************************************************************
// Write a line to the file and deal with indents.
// **********************************************************************************
function writeLine( sData ){
	if( sData=="{" ) { nIndent++; }
	for( var i=1; i<nIndent; i++ ) { oFile.write("\t"); }
	oFile.writeLine( sData );
	if( sData=="}" ){	nIndent--; }
}

// **********************************************************************************
//		Extract Local file name from ABS filename.
// **********************************************************************************
function RelativePath( path ) {
	path= App.getContentMgr().getRelativePath( path,1 );
	var sep= path.left(1)=="/" ? ":" : "\\";
	while( path.search("/") >= 0 ) {
	  path= path.replace( "/", sep );
	}
	path= '"' + path+ '"';
	return path;
}



// **********************************************************************************
// Render an icon for the PROP.
// **********************************************************************************
function renderIcon( file ) {
		if( setup.icon==0 ) { return; }
		if( setup.icon==1 ) {
			Scene.saveThumbnail( file );
		} else {
			var RMgr= App.getRenderMgr();
			var Opts= App.getRenderOptions();
			Opts.applyChanges();
			Opts.imageSize= Size(91,91);
			Opts.renderImgToId=2;
			Opts.renderImgFilename=file;
			RMgr.doRender();
			Opts.resetOptions();
		}
}


// **********************************************************************************
// Set unique meterial names before combine
// **********************************************************************************
function setUniqueMetNames() {
		nodes= oNode.getNodeChildren(1);
		nodes.unshift( oNode );
		for( i=0; i< nodes.length; i++ ) {
			try {
				var Mats= nodes[i].getObject().getCurrentShape().getAllMaterials();
			} catch(x){ continue; }
			for( m=0; m< Mats.length; m++ ){
				MatName= Mats[m].name;
				MatName= MatName.replace( /[0-9]+-/, "" );
				MatName= MatName.replace( "Default", nodes[i].name );
				Mats[m].name= Mats[m].getIndex() +"-"+ MatName;
			}					
		}
}




// **********************************************************************************
// Export the OBJ data to the file location provided.
// **********************************************************************************
function ExportObj() {
		hideUnselected();
		centerNodes();
		getObjName();
		const oEXPORT_MANAGER = App.getExportMgr(); 
		const oOBJECT_EXPORTER = oEXPORT_MANAGER.findExporterByClassName( 'DzObjExporter' ); 
		const oEXPORTER_SETTINGS = new DzFileIOSettings(); 
		oOBJECT_EXPORTER.getDefaultOptions( oEXPORTER_SETTINGS ); 
		oEXPORTER_SETTINGS.setStringValue( 'Preset', 'Custom (1 unit = 1cm)' ); 
		oEXPORTER_SETTINGS.setStringValue( 'Scale', '243.84' ); 
		oEXPORTER_SETTINGS.setBoolValue( 'SwapYZ', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'IgnoreInvisible', true ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WeldSeams', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteO', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteG', true ); 
		oEXPORTER_SETTINGS.setBoolValue( 'GroupNodes', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'GroupSurfaces', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'GroupSingle', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'GroupGeom', true ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteVN', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteVT', true ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteUsemtl', true ); 
		oEXPORTER_SETTINGS.setBoolValue( 'WriteMtllib', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'CollectMaps', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'ConvertMaps', false ); 
		oEXPORTER_SETTINGS.setBoolValue( 'RemoveUnusedVerts', false ); 
		oEXPORTER_SETTINGS.setIntValue( 'RunSilent', 1 ); 
		oOBJECT_EXPORTER.writeFile( setup.obj, oEXPORTER_SETTINGS );
		restoreNodes();
}









// **********************************************************************************
// Get unique names for obj files
// **********************************************************************************
function getObjName() {
		if( oNode.isSelected() ) {
			childIndex=1; return;
		}
		setup.obj= setup.obj.replace( /(.cn)?[0-9]{0,2}.obj$/ ,"" );
		setup.obj= setup.obj +".cn"+ childIndex +".obj";
		childIndex++;
}


// get the object nodes only
function getObjNodes() {
		var nodes= Scene.getNodeList();
		for( i=0; i<nodes.length; i++ ) {
		 if( nodes[i].getObject()==null ) {
				nodes.splice(i,1);
		}}
		return nodes;
}


// hide unselected nodes
function hideUnselected() {
		var nodes= getObjNodes();
		for( i=0; i<nodes.length; i++ ) {
		 nodes[i].setVisible( 0 );
		}
		oNode.setVisible( 1 );
		// export children too
		if( setup.weld ) {
			var nodes= oNode.getNodeChildren(1);
			for( i=0; i<nodes.length; i++ ) {
			 nodes[i].setVisible( 1 );
			}
		}
}


// set the exportin position
function centerNodes() {
		// backup pos & rot
		oNode.Pos= oNode.getWSPos();
		oNode.Rot= oNode.getWSRot();
		// backup scale
		oNode.Sc1= oNode.getScaleControl().getValue();
		oNode.ScX= oNode.getXScaleControl().getValue();
		oNode.ScY= oNode.getYScaleControl().getValue();
		oNode.ScZ= oNode.getZScaleControl().getValue();
		// reset rotation
		oNode.setWSRot( DzQuat(0,0,0,0) );
		oNode.setLocalRot( oNode.getWSRot().inverse() );
		
		//changes by mCasualJacques July 20 2015 ** begin ** 
		var DSVersion = new Number( App.versionString );
		if( DSVersion >= 4 )
		{		
			oNode.setWSScale( DzMatrix3(1,0,0,0,1,0,0,0,1,0,0,0) );
		}
		else
		{
			oNode.setWSScale( DzMatrix3() );
		}
		//changes by mCasualJacques July 20 2015 ** end ** 
		
		// center obj
		oNode.setWSPos( oNode.getOrigin() );
		resetMorphs();
}


function restoreNodes() {
		oNode.setWSPos( oNode.Pos );
		oNode.setWSRot( oNode.Rot );
		oNode.Sc1= oNode.getScaleControl().setValue( oNode.Sc1 );
		oNode.ScX= oNode.getXScaleControl().setValue( oNode.ScX );
		oNode.ScY= oNode.getYScaleControl().setValue( oNode.ScY );
		oNode.ScZ= oNode.getZScaleControl().setValue( oNode.ScZ );
		restoreMorphs();
		// unhide all
		var nodes= getObjNodes();
		for( i=0; i<nodes.length; i++ ) {
		 nodes[i].setVisible( 1 );
		}
}


function resetMorphs() {
		oNode.mod= new Array();
		if( setup.morph==2 ) { return; }
		var oObject = oNode.getObject();
		if( oObject == undefined ){ return; }
		var nModifiers = oObject.getNumModifiers();
		for( i=0; i < nModifiers; i++ ) {
			var oMorph = oObject.getModifier(i);
			if( oMorph.className() != "DzMorph" ) { continue; }
			oNode.mod[i]= oMorph.getValueChannel().getValue();
			oMorph.getValueChannel().setValue( 0 );
		}
}


function restoreMorphs() {
		var oObject = oNode.getObject();
		if( oObject == undefined ){ return; }
		for( i=0; i < oNode.mod.length; i++ ) {
			var val= oNode.mod[i];
			if( val==0 ) { continue; }
			oObject.getModifier(i).getValueChannel().setValue( val );
		}
}






//////////////////////////////////////
//////////  GUI ONLY   ///////////////
//////////////////////////////////////

function initGui() {
		// DIALOG
		win= new DzDialog;
		win.caption= "PP2 exporter";
		win.width = 260;
		win.height= 150;
		// Main Layout
		var winLyt= new DzVBoxLayout( win );
		winLyt.autoAdd= true;
		winLyt.margin= 5;
		winLyt.spacing= 5;
		
		// PP2 & OBJ files
		var VBox= new DzVGroupBox( win );
		VBox.title = "Destination Files";
		VBox.columns = 2;
		VBox.insideSpacing= 8;
		
		label= new DzLabel( VBox );
		label.text = "PP2:";
		label.maxWidth= 20;
		
		win.pp2= new DzPushButton( VBox );
		//win.pp2.maxWidth= 200;
		win.pp2.whatsThis= "PP2 file path and file name";
		connect( win.pp2, "clicked()", openPP2 );
		win.pp2.text= trim( setup.pp2 );
		
		label= new DzLabel( VBox );
		label.text = "OBJ:";
		label.maxWidth= 20;
		
		win.obj= new DzPushButton( VBox );
		win.obj.text= "DzLineEdit Highlighted";
		win.obj.maxWidth= 200;
		//win.obj.whatsThis= "OBJ file path and file name";
		connect( win.obj, "clicked()", openOBJ );
		win.obj.text= trim( setup.obj );
		
		// Multi-object mode
		win.mode= new DzVButtonGroup( win );
		win.mode.title= "Child Nodes Stored as";
		win.mode.columns= 3;
		
		wBtn= new DzRadioButton( win.mode );
		wBtn.text= "None";
		wBtn.whatsThis= "Child nodes will be ignored";
		wBtn= new DzRadioButton( win.mode );
		wBtn.text= "Child";
		wBtn.whatsThis= "Child nodes will be stored";
		wBtn= new DzRadioButton( win.mode );
		wBtn.text= "Weld";
		wBtn.whatsThis= "Child nodes will be combined";
		win.mode.selected= 1;

		// Morphs mode
		win.morph= new DzVButtonGroup( win );
		win.morph.title= "Morphs saving method";
		win.morph.columns= 3;
		
		wBtn= new DzRadioButton( win.morph );
		wBtn.text= "Ignore";
		wBtn.whatsThis= "Morphs will be ignored";
		wBtn= new DzRadioButton( win.morph );
		wBtn.text= "Save";
		wBtn.whatsThis= "Morphs will bee saved";
		wBtn= new DzRadioButton( win.morph );
		wBtn.text= "Apply";
		wBtn.whatsThis= "Morphs will bee applyed bedore export";
		win.morph.selected= 1;
				
		// Transformation channels
		var group= new DzVButtonGroup( win );
		group.title= "Transformation Channels";
		group.columns= 3;
		
		win.pos= new DzCheckBox( group );
		win.pos.text= "Position";
		win.pos.whatsThis= "Position parameters will bee stored";
		win.rot= new DzCheckBox( group );
		win.rot.text= "Rotation";
		win.rot.whatsThis= "Rotation parameters will bee stored";
		win.scale= new DzCheckBox( group );
		win.scale.text= "Scale";
		win.scale.whatsThis= "Scale parameters will bee stored";
		win.scale.checked=1;
		
		// Dialog buttons
		var group= new DzGroupBox( win );
		group.maxHeight= 35;
		group.flat= true;
		
		var layout= new DzGridLayout( group );
		layout.margin= layout.spacing= 5;
		
		var oHelpMgr   = App.getHelpMgr();
		var oActionMgr = MainWindow.getActionMgr();
		var oHelpAction= oActionMgr.findAction( "DzWhatsThisAction" );
		
		// "What's This?" push button
		var helpBtn= new DzPushButton( group );
		helpBtn.minHeight= 18;
		helpBtn.pixmap= new Pixmap( String( "%1/images/icons/whatsthissmallicon.png" ).arg( App.getResourcesPath() ) );
		helpBtn.clicked.connect( oHelpAction, "trigger()" );
		helpBtn.whatsThis = oHelpMgr.getHelpString( "WhatsThis" );
		layout.addWidget( helpBtn, 0, 0 );
		
		// Stretch the column between the left and right sides
		layout.setColStretch( 1,1 );
		
		// Create the cancel push button
		var btn= new DzPushButton( group );
		btn.text= "Cancel";
		btn.minHeight= 18;
		win.setRejectButton( btn );
		btn.whatsThis= "Close this dialog";
		layout.addWidget( btn, 0, 2 );
		
		// Create the accept push button
		var btn= new DzPushButton( group );
		btn.text= "Save";
		btn.minHeight= 18;
		win.setAcceptButton( btn );
		btn.whatsThis= "Save poser PP2";
		layout.addWidget( btn, 0, 3 );

		return win;
}



function openPP2() {
		var pp2= FileDialog.doFileDialog( 0, "Select PP2 file name", setup.pp2 , "Prop Files (*.pp2)" );
		if( pp2 ) {
			setup.pp2= pp2;
			win.pp2.text= trim(pp2);
		}
}


function openOBJ() {
		var obj= FileDialog.doFileDialog( 0, "Select OBJ file name", setup.obj , "Geometry Files (*.obj)" );
		if( obj ) {
			setup.obj= obj;
			win.obj.text= trim(obj);
		}
}


function trim( path ) {
			if( path.length<23 ) { return path; }
			i= path.findRev( "/", path.length-20 );
			path= "..."+ path.mid( i,50 );
			return path;
}


function loadSetup( win ) {
		var reg= new DzAppSettings("PP2ex");
		if( reg.getIntValue("true")==0 ) { return; }
	
		var path= reg.getStringValue("pp2");
		var dir = path.left( path.findRev("/")+1 );
		setup.pp2= dir + oNode.name +".pp2";
		win.pp2.text= trim( setup.pp2 );
	
		var path= reg.getStringValue("obj");
		var dir = path.left( path.findRev("/")+1 );
		setup.obj= dir + oNode.name +".obj";
		win.obj.text= trim( setup.obj );

		win.mode.selected	= reg.getIntValue("mode");
		win.morph.selected= reg.getIntValue("morph");
		win.pos.checked	= reg.getIntValue("pos");
		win.rot.checked	= reg.getIntValue("rot");
		win.scale.checked	= reg.getIntValue("scale");	
}


function saveSetup( win ) {
		var reg= new DzAppSettings("PP2ex");
		reg.setIntValue("true",1);

		reg.setStringValue( "pp2", setup.pp2 );
		reg.setStringValue( "obj", setup.obj );	

		setup.mode = win.mode.selected;
		setup.morph= win.morph.selected;
		setup.pos  = win.pos.checked;
		setup.rot  = win.rot.checked;
		setup.scale= win.scale.checked;

		setup.single= setup.mode==0 ? 1 : 0;
		setup.weld  = setup.mode==2 ? 1 : 0;

		reg.setIntValue( "mode", setup.mode );
		reg.setIntValue( "morph", setup.morph );
		reg.setIntValue( "pos", setup.pos );
		reg.setIntValue( "rot", setup.rot ); 
		reg.setIntValue( "scale", setup.scale );
}






ċ
PP2ExporterDS4.zip
(19k)
mCasual Jacques,
Jul 24, 2015, 11:52 AM
Comments