|
USING PP2 EXPORTER TO CREATE POSER PROPS IN DAZ STUDIO Copyright (c) 2018, Winterbrose Arts and Graphics. All Rights Reserved. | |
Once you have created your static model in Daz Studio, and have exported all individual components as OBJ format files, start New Scene then use desired method. Please note that the Classic Dart OBJ model used in this tutorial was created in the training from Modeling Made Simple Volume 1: Create Static Models. | |
Method A: | |
01. Load Model into Scene - New Scene - Import components - Group components - Rename Group to model name - Select Group in scene tab | |
02. Create Poser Prop - Execute PP2 Exporter - Select PP2 location and name for PP2 - Select Geometries location and name for OBJ - Select Child Nodes Stored as "Child" - Click Save button | |
03. If successful, receive PROP Created message | |
04. Load new Prop model - New Scene - In Poser Formats / My DAZ 3D Library, locate prop in Props folder created - Double click thumbnail to load into scene | |
05. Review Geometries folder | |
06. Review Props folder | |
07. Test New Prop - New Scene - Load new prop into scene - Select first component and repeat 8/9 for each | |
08. In Tool Settings/Geometry Editor - Check Groups for each component | |
09. In Surface tab - Check Surfaces for each component | |
Method B: | |
01. Load Pieces to Build Single Model - New Scene - Import all components - Remove all non-components (ie Camera, Lights) - Export complete model | |
02. Load Single Model - New scene - Import complete model | |
03. Create Poser Prop - Execute PP2 Exporter - Select PP2 location and name for PP2 - Select Geometries location and name for OBJ - Select Child Nodes Stored as "None" - Click Save button | |
04. If successful, receive PROP Created message | |
05. Load new Prop model - New Scene - In Poser Formats / My DAZ 3D Library, locate prop in Props folder created - Double click thumbnail to load into scene | |
06. Review Geometries folder | |
07. Review Props folder | |
08. Test New Prop - New Scene - Load new prop into scene - Select prop in Scene tab | |
09. In Tool Settings/Geometry Editor - Check Groups for complete prop | |
10. In Surface tab - Check Surfaces for complete prop | |
USER GUIDE: Using PP2 Exporter to Create Poser Props in Daz Studio Copyright (c) 2018, Winterbrose Arts and Graphics. All Rights Reserved. |
/*************************************************************************** ** 24-02-09 ver 1a (JWAS84) ** PP2 exporter 2.0d ** 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 **************************************************************************** ** 25-12-11 var 2c ** - fix for non DzDefaultMaterial properties (ie Uber or HSS) **************************************************************************** ** 23-02-12 var 2d ** - fix to avoid mangling Material names unless absolutely ** necessary; **************************************************************************** ** 27-02-18 var 2e (RoLoW) ** PP2 exporter 2.1a ** - added version number variable to display in caption header bar ** - correct scaling to read and use current version of DS scaling ** - matched init value for writetrans routine to same as writeoffset ** - set button sizes to half the height of layout panel ** STILL COPYRIGHT FREE, AS INTENDED. ** (c) Copyright NONE. Use for whatever you like. ****************************************************************************/ // Variables var sSrcPath, sObjPath, lObjPath, sFileName, m_oFile; var nIndent = 0; const dazScaler = 243.84; // Scale to DAZ units var sVersionNumber = "2.1a" 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] )); writeLine(String("initValue %1").arg( nVal )); 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. // ******************************************************************************************** var isDefMat = (Mat.className() == "DzDefaultMaterial" ); // KdColor specifies the material's diffuse color. var s = 0.0; if (isDefMat) { s = Mat.getDiffuseStrength(); } else { s = Mat.findPropertyByLabel( "Diffuse Strength" ).getValue(); } WriteColor("KdColor",Mat.getDiffuseColor(),s); // KaColor specifies the material's ambient color (for ambient lighting). var c; if (isDefMat) { c = Mat.getAmbientColor(); s = Mat.getAmbientStrength(); } else { c = Mat.findPropertyByLabel( "Ambient Color" ).getColorValue(); s = Mat.findPropertyByLabel( "Ambient Strength" ).getValue(); } WriteColor("KaColor", c, s); // KsColor specifies the material's specular color (for specular highlights). if (isDefMat) { c = Mat.getSpecularColor(); s = Mat.getSpecularStrength(); } else { c = Mat.findPropertyByLabel( "Specular Color").getColorValue(); s = Mat.findPropertyByLabel( "Specular Strength" ).getValue(); } WriteColor("KsColor", c, s); // 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. if (isDefMat) { oProperty = Mat.getOpacityControl ().getValue(); } else { oProperty = Mat.findPropertyByLabel( "Opacity Strength" ).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. if (isDefMat) { oProperty = Mat.getBumpStrength(); } else { oProperty = Mat.findPropertyByLabel( "Bump Strength" ).getValue(); } 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. if (isDefMat) { oProperty = Mat.getMultThroughOpacityControl(); } else { oProperty = Mat.findPropertyByLabel( "Multiply Reflection Through Opacity" ); } 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 if (isDefMat) { oProperty = Mat.getBumpMap(); } else { oProperty = Mat.findPropertyByLabel( "Bump Strength" ).getMapValue(); } if( oProperty ) { oFileName = RelativePath( oProperty.getFilename() ); writeLine( String("bumpMap %1").arg(oFileName) ); } else { writeLine("bumpMap NO_MAP"); } // reflectionMap if (isDefMat) { oProperty = Mat.getReflectionMap(); } else { oProperty = Mat.findPropertyByLabel( "Reflection Strength" ).getMapValue(); } 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. if (isDefMat) { c = Mat.getReflectionColor(); } else { c = Mat.findPropertyByLabel("Reflection Color").getColorValue(); } WriteColor("ReflectionColor", c, 1 ); // reflectionStrength is the amount or "depth and clarity" of the reflection. if (isDefMat) { s = Mat.getReflectionStrength(); } else { s = Mat.findPropertyByLabel("Reflection Strength").getValue(); } writeLine( String("reflectionStrength %1").arg(s) ); 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 ); used_names = "|"; 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 ); if (used_names.find( "|" + MatName + "|") >= 0) { Mats[m].name= MatName + "-" + Mats[m].getIndex(); } else { Mats[m].name= MatName used_names += 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() { // find current scaling myScale = oNode.getWSScale(); // 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() ); oNode.setWSScale( myScale ); // 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 v" + sVersionNumber; 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 = group.maxHeight/2; 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.minWidth= 80; btn.minHeight = group.maxHeight/2; 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.minWidth= 80; btn.minHeight = group.maxHeight/2; 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 ); } |
Best
viewed at 1024 x 768 or higher. |
Thanks for Visiting WINTERBROSE Arts & Graphics |