void OutputArrayPositions( std::ofstream& in_mfw, CDoubleArray& in_array, MATH::CTransformation& localTransform) { MATH::CVector3 position; MATH::CVector3 worldPosition; double x, y, z; bar.PutMinimum(0); bar.PutMaximum(in_array.GetCount()/3); for ( LONG i=0; i<in_array.GetCount(); i += 3 ) { bar.PutValue(i); CString str; position.PutX(in_array[i]); position.PutY(in_array[i+1]); position.PutZ(in_array[i+2]); worldPosition = MATH::MapObjectPositionToWorldSpace(localTransform, position); x = worldPosition.GetX(); y = worldPosition.GetY(); z = worldPosition.GetZ(); str = L"v " + FormatNumber(x) + L" " + FormatNumber(y) + L" " + FormatNumber(z); in_mfw << str.GetAsciiString(); in_mfw << "\n"; gV++; //bar.Increment(); } }
void OutputVertices( std::ofstream& in_mfw, CGeometryAccessor& in_ga, X3DObject& xobj) { bar.PutStatusText( L"Vertices..." ); // polygon vertex positions CDoubleArray vtxPosArray; CStatus st = in_ga.GetVertexPositions(vtxPosArray); st.AssertSucceeded( L"GetVertexPositions" ); MATH::CTransformation localTransformation = xobj.GetKinematics().GetLocal().GetTransform(); CString string = L"#begin " + CString(in_ga.GetVertexCount()) + L" vertices\n"; in_mfw << string.GetAsciiString(); OutputArrayPositions( in_mfw, vtxPosArray, localTransformation ); string = L"#end " + CString(in_ga.GetVertexCount()) + L" vertices\n"; in_mfw << string.GetAsciiString(); in_mfw << "\n"; if(Get3DCoatParam(L"bExpUV").GetValue()) { // uv props: siClusterPropertyUVType CRefArray uvProps = in_ga.GetUVs(); if(uvProps.GetCount() > 0) { OutputClusterPropertyValues( in_mfw, in_ga, uvProps ); } } if(Get3DCoatParam(L"bExpNorm").GetValue()) { // polygon node normals CFloatArray nodeArray; st = in_ga.GetNodeNormals(nodeArray); st.AssertSucceeded( L"GetNodeNormals" ); //app.LogMessage(L"NormalArray: " + nodeArray.GetAsText()); string = L"#begin " + CString(in_ga.GetNodeCount()) + L" normals\n"; in_mfw << string.GetAsciiString(); OutputArray( in_mfw, nodeArray, 3, L"vn " ); string = L"#end " + CString(in_ga.GetNodeCount()) + L" normals\n"; in_mfw << string.GetAsciiString(); in_mfw << "\n"; } }
void FindFolder3DCoatV(CustomProperty& prop, TCHAR* path) { CString exePath = CUtils::BuildPath(path, L"3D-Coat-V3"); if(FileOrDirectoryExists(exePath.GetAsciiString(), true)) { prop.GetParameter(L"exeLocation").PutValue(exePath + CUtils::Slash()); } else { exePath = CUtils::BuildPath(path, L"3D-Coat-V4"); if(FileOrDirectoryExists(exePath.GetAsciiString(), true)) { prop.GetParameter(L"exeLocation").PutValue(exePath + CUtils::Slash()); } else { prop.GetParameter(L"exeLocation").PutValue(L""); } } }
// Callback for the siOnActivateEvent event. SICALLBACK siOnActivateEvent_OnEvent( CRef& in_ctxt ) { Context ctxt( in_ctxt ); //Application().LogMessage(L"siOnActivateEvent_OnEvent called",siVerboseMsg); //Application().LogMessage(L"State: " + CString(ctxt.GetAttribute(L"State")),siVerboseMsg); bool bState = ctxt.GetAttribute(L"State"); if(bState) { CustomProperty prop = app.GetActiveSceneRoot().GetProperties().GetItem(L"AppLink_3DCoat"); if (prop.IsValid()) { if(prop.GetParameter("bEvent").GetValue()) { CString s_CoatLocation = prop.GetParameter(L"coatLocation").GetValue(); CString exportPath = CUtils::BuildPath(s_CoatLocation, L"export.txt"); CString objPath; std::ifstream fileref(exportPath.GetAsciiString()); bool bfile = false; if(fileref.good()) { std::string row; std::getline(fileref, row); objPath = row.c_str(); bfile = true; } fileref.close(); if(bfile) { UIToolkit uitool = Application().GetUIToolkit(); LONG out; uitool.MsgBox(L"Import file?", siMsgOkCancel|siMsgInformation|MB_APPLMODAL, L"", (LONG) out); if(out == siMsgOk) { app.LogMessage(L"Start Import!"); CValueArray args(2); args[0] = objPath; args[1] = prop.GetParameterValue( L"bReplace" ); CValue noret; app.ExecuteCommand( L"Coat3DImport", args, noret ) ; } } } } } // Return value is ignored as this event can not be aborted. return CStatus::OK; }
CStatus AlembicWriteJob::Process() { // check filenames if(mFileName.IsEmpty()) { Application().LogMessage(L"[alembic] No filename specified.",siErrorMsg); return CStatus::InvalidArgument; } // check objects if(mSelection.GetCount() == 0) { Application().LogMessage(L"[alembic] No objects specified.",siErrorMsg); return CStatus::InvalidArgument; } // check frames if(mFrames.size() == 0) { Application().LogMessage(L"[alembic] No frames specified.",siErrorMsg); return CStatus::InvalidArgument; } // init archive (use a locally scoped archive) CString sceneFileName = L"Exported from: "+Application().GetActiveProject().GetActiveScene().GetParameterValue(L"FileName").GetAsText(); mArchive = CreateArchiveWithInfo( Alembic::AbcCoreHDF5::WriteArchive(), mFileName.GetAsciiString(), "Softimage Alembic Plugin", sceneFileName.GetAsciiString(), Alembic::Abc::ErrorHandler::kThrowPolicy); // get the frame rate double frameRate = 25.0; CValue returnVal; CValueArray args(1); args[0] = L"PlayControl.Rate"; Application().ExecuteCommand(L"GetValue",args,returnVal); frameRate = returnVal; if(frameRate == 0.0) frameRate = 25.0; double timePerSample = 1.0 / frameRate; // create the sampling AbcA::TimeSampling sampling(timePerSample,0.0); mTs = mArchive.addTimeSampling(sampling); Alembic::Abc::OBox3dProperty boxProp = Alembic::AbcGeom::CreateOArchiveBounds(mArchive,mTs); // create object for each std::vector<AlembicObjectPtr> objects; for(LONG i=0; i<mSelection.GetCount(); i++) { X3DObject xObj(mSelection[i]); if(xObj.GetType().IsEqualNoCase(L"camera")) { AlembicObjectPtr ptr; ptr.reset(new AlembicCamera(xObj.GetActivePrimitive().GetRef(),this)); objects.push_back(ptr); } else if(xObj.GetType().IsEqualNoCase(L"polymsh")) { AlembicObjectPtr ptr; ptr.reset(new AlembicPolyMesh(xObj.GetActivePrimitive().GetRef(),this)); objects.push_back(ptr); } } ProgressBar prog; prog = Application().GetUIToolkit().GetProgressBar(); prog.PutMinimum(0); prog.PutMaximum((LONG)(mFrames.size() * objects.size())); prog.PutValue(0); prog.PutCancelEnabled(true); prog.PutVisible(true); for(unsigned int frame=0; frame < (unsigned int)mFrames.size(); frame++) { for(size_t i=0; i<objects.size(); i++) { prog.PutCaption(L"Frame "+CString(mFrames[frame])+L" of "+objects[i]->GetRef().GetAsText()); CStatus status = objects[i]->Save(mFrames[frame]); if(status != CStatus::OK) return status; if(prog.IsCancelPressed()) break; prog.Increment(); } if(prog.IsCancelPressed()) break; } prog.PutVisible(false); return CStatus::OK; }
XSIPLUGINCALLBACK CStatus Coat3DExport_Execute( CRef& in_ctxt ) { // Unpack the command argument values Context ctxt( in_ctxt ); CValueArray args = ctxt.GetAttribute(L"Arguments"); CString string; // A 3d object with a mesh geometry must be selected Selection selection(app.GetSelection()); bool isPolymesh = true; for(int i =0; i< selection.GetCount(); i++) { X3DObject obj(selection[i]); //app.LogMessage(L"obj.IsA(siPolygonMeshID): " + CString(obj.GetType())); if(obj.GetType() != L"polymsh" ) { isPolymesh = false; break; } } if (selection.GetCount() > 0 && isPolymesh) { gV = 0; gVn = 0; gVt = 0; gVprev = 0; gVnPrev = 0; gVtPrev = 0; // prepare the output text file CString strOut = Get3DCoatParam( L"tempLocation" ).GetValue(); std::ofstream mfw; mfw.open(strOut.GetAsciiString(), std::ios_base::out | std::ios_base::trunc); if (mfw.is_open()) { bar.PutMaximum( selection.GetCount() ); bar.PutStep( 1 ); bar.PutVisible( true ); OutputHeader( mfw); // output the data for (int i=0; i < selection.GetCount(); i++) { gObjCnt = i; gVprev = gV; gVtPrev = gVt; gVnPrev = gVn; X3DObject xobj(selection.GetItem(i)); bar.PutValue(i); bar.PutCaption( L"Exporting " + xobj.GetName()); mfw << "\n"; mfw << "# Hierarchy (from self to top father)\n"; string = L"g " + xobj.GetName() + L"\n"; mfw << string.GetAsciiString(); mfw << "\n"; // Get a geometry accessor from the selected object Primitive prim = xobj.GetActivePrimitive(); PolygonMesh mesh = prim.GetGeometry(); if (!mesh.IsValid()) return CStatus::False; CGeometryAccessor ga = mesh.GetGeometryAccessor(); OutputVertices( mfw, ga, xobj ); if (bar.IsCancelPressed()) return CStatus::False; OutputPolygonComponents( mfw, ga ); if (bar.IsCancelPressed()) return CStatus::False; //bar.Increment(); } } mfw.close(); if(Get3DCoatParam(L"bExpMat").GetValue()) { OutputMaterials(selection ); } bar.PutStatusText( L"import.txt" ); OutputImportTxt(); bar.PutVisible(false); app.LogMessage(L"Export done!"); } else { app.LogMessage(L"Please, select objects!", siWarningMsg); return CStatus::False; } return CStatus::OK; }
XSIPLUGINCALLBACK CStatus OutputImportTxt() { // prepare the import.txt file CString strOut = CUtils::BuildPath(Get3DCoatParam( L"coatLocation" ).GetValue(), L"import.txt"); std::ofstream tfw; tfw.open(strOut.GetAsciiString(), std::ios_base::out | std::ios_base::trunc ); if (tfw.is_open()) { CString objTmp = Get3DCoatParam( L"tempLocation" ).GetValue(); tfw << objTmp.GetAsciiString(); tfw << "\n"; CString objOut = objTmp.GetSubString(0, objTmp.ReverseFindString(CUtils::Slash())+1); objOut += L"output.obj"; tfw << objOut.GetAsciiString(); tfw << "\n"; int typePaint = Get3DCoatParam( L"typePaint" ).GetValue(); //Paint mesh in 3D-Coat using per-pixel painting [ppp] //Paint mesh in 3D-Coat using microvertex painting [mv] //Paint mesh in 3D-Coat using Ptex [ptex] //Perform UV-mapping in 3D-Coat [uv] //Drop reference mesh to 3D-Coat [ref] //Drop retopo mesh as new layer in 3D-Coat [retopo] //Drop mesh in 3D-Coat as voxel object [vox] //Drop mesh in 3D-Coat as new pen alpha [alpha] //Drop mesh in 3D-Coat as new merging primitive for voxels [prim] //Drop mesh in 3D-Coat as a curve profile [curv] //Drop mesh in 3D-Coat for Auto-retopology [autopo] CString strPaint = L"["; switch (typePaint) { case 0: strPaint += L"ppp"; break; case 1: strPaint += L"mv"; break; case 2: strPaint += L"ptex"; break; case 3: strPaint += L"uv"; break; case 4: strPaint += L"ref"; break; case 5: strPaint += L"retopo"; break; case 6: strPaint += L"vox"; break; case 7: strPaint += L"alpha"; break; case 8: strPaint += L"prim"; break; case 9: strPaint += L"curv"; break; case 10: strPaint += L"autopo"; break; } strPaint += L"]"; tfw << strPaint.GetAsciiString(); bool bExpSkipIm = Get3DCoatParam( L"bExpSkipImp" ).GetValue(); if(bExpSkipIm) { tfw << "\n"; tfw << "[SkipImport]"; } bool bExpSkipExp = Get3DCoatParam( L"bExpSkipExp" ).GetValue(); if(bExpSkipExp) { tfw << "\n"; tfw << "[SkipExport]"; } tfw.close(); } return CStatus::OK; }
void OutputPolygonComponents( std::ofstream& in_mfw, CGeometryAccessor& in_ga) { // polygon node indices CLongArray polyNodeIdxArray; CStatus st = in_ga.GetNodeIndices(polyNodeIdxArray); st.AssertSucceeded( L"GetNodeIndices"); //app.LogMessage(L"NodeIdx: " + polyNodeIdxArray.GetAsText()); CLongArray polySizeArray; st = in_ga.GetPolygonVerticesCount(polySizeArray); st.AssertSucceeded( L"GetPolygonVerticesCount" ); //app.LogMessage(L"GetPolygonVerticesCount: " + polySizeArray.GetAsText()); // polygon vertex indices CLongArray polyVtxIdxArray; st = in_ga.GetVertexIndices(polyVtxIdxArray); st.AssertSucceeded( L"GetVertexIndices" ); CString string = L"#begin " + CString(in_ga.GetPolygonCount()) + L" faces\n"; in_mfw << string.GetAsciiString(); // get the material objects used by the mesh CRefArray materials = in_ga.GetMaterials(); CRefArray uvProps = in_ga.GetUVs(); // get the material indices used by each polygon CLongArray pmIndices; in_ga.GetPolygonMaterialIndices(pmIndices); CString prevMat = L""; CString curMat = L""; bar.PutMinimum(0); bar.PutMaximum(polySizeArray.GetCount()); bar.PutStatusText(L"Faces..."); bool bUV = (bool)Get3DCoatParam(L"bExpUV").GetValue(); bool bNrm = (bool)Get3DCoatParam(L"bExpNorm").GetValue(); bool bMtl = (bool)Get3DCoatParam(L"bExpMat").GetValue(); bool bUVCnt = (uvProps.GetCount() > 0)?true:false; CString strVertices; for (LONG i=0, offset=0; i < polySizeArray.GetCount(); i++) { bar.PutValue(i); strVertices = ""; strVertices += CString(polyVtxIdxArray[offset] + 1 + gVprev);// vertices idx[0] if(bUV && bUVCnt) { strVertices += L"/"; //strVertices += CString(polyNodeIdxArray[offset] + 1 + gVtPrev);// texture nodes idx[0] strVertices += CString(g_aNodeIsland[offset] + 1 + gVtPrev);// texture nodes idx[0] if(bNrm) { strVertices += L"/"; strVertices += CString(polyNodeIdxArray[offset] + 1 + gVnPrev);// normal vertices idx[0] } } else if(bNrm) { strVertices += L"//"; strVertices += CString(polyNodeIdxArray[offset] + 1 + gVnPrev);// normal vertices idx[0] } for (LONG j=1; j<polySizeArray[i]; j++) { strVertices += L" "; strVertices += CString(polyVtxIdxArray[offset+j] + 1 + gVprev);// vertices idx[12] if(bUV && bUVCnt) { strVertices += L"/"; //strVertices += CString(polyNodeIdxArray[offset+j] + 1 + gVtPrev);// texture nodes idx[12] strVertices += CString(g_aNodeIsland[offset+j] + 1 + gVtPrev);// texture nodes idx[0] if(bNrm) { strVertices += L"/"; strVertices += CString(polyNodeIdxArray[offset+j] + 1 + gVnPrev);// normal vertices idx[12] } } else if(bNrm) { strVertices += L"//"; strVertices += CString(polyNodeIdxArray[offset+j] + 1 + gVnPrev);// normal vertices idx[12] } } if(bMtl) { Material mat(materials[ pmIndices[i] ]); curMat = mat.GetName(); if(curMat != prevMat) { in_mfw << "usemtl "; in_mfw << curMat.GetAsciiString(); in_mfw << "\n"; prevMat = curMat; } } in_mfw << "f "; in_mfw << strVertices.GetAsciiString(); in_mfw << "\n"; offset += polySizeArray[i]; //bar.Increment(); } string = L"#end " + CString(in_ga.GetPolygonCount()) + L" faces\n"; in_mfw << string.GetAsciiString(); in_mfw << "\n"; }
void OutputClusterPropertyValues( std::ofstream& in_mfw, CGeometryAccessor& in_ga, CRefArray& in_array) { LONG nVals = in_array.GetCount(); double s; ClusterProperty cp(in_array[0]); CFloatArray valueArray; CBitArray flags; cp.GetValues( valueArray, flags ); LONG nValueSize = cp.GetValueSize(); bar.PutValue(0); bar.PutStatusText(L"Optimize UV..."); // polygon node indices CLongArray polyNodeIdxArray; CStatus st = in_ga.GetNodeIndices(polyNodeIdxArray); st.AssertSucceeded( L"GetNodeIndices"); //app.LogMessage(L"polyNodeIdxArray: " + polyNodeIdxArray.GetAsText()); g_aNodeIsland = polyNodeIdxArray; std::vector<float> newValueArray; newValueArray.clear(); for ( LONG j=0; j < polyNodeIdxArray.GetCount(); j++) { float u = valueArray[polyNodeIdxArray[j]*3]; float v = valueArray[polyNodeIdxArray[j]*3+1]; //app.LogMessage(L"u = " + CString(u)+ "; v = "+ CString(v)); LONG nmb = 0; bool bIs = false; for ( ULONG k = 0; k < newValueArray.size(); k += 3 ) { if(fabs(newValueArray.at(k) - u) < 0.000002 && fabs(newValueArray.at(k+1) - v) < 0.000002) { nmb = k/3; bIs = true; break; //app.LogMessage(L"Yarr!: g_aNodeIsland["+ CString(j)+"] = "+ CString(k/3)); } } if(bIs) { g_aNodeIsland[j] = nmb; //app.LogMessage(L"Yarr!: g_aNodeIsland["+ CString(j)+"] = "+ CString(nmb)); } else { newValueArray.push_back(u); newValueArray.push_back(v); newValueArray.push_back(0.0f); g_aNodeIsland[j] = (LONG)(newValueArray.size()/3-1); //app.LogMessage(L"g_aNodeIsland["+ CString(j)+"] = "+ CString(newValueArray.size()/3-1)); } } in_mfw << "#begin "; in_mfw << CString((ULONG)newValueArray.size()/nValueSize).GetAsciiString(); in_mfw << "\n"; bar.PutStatusText(L"Clusters..."); bar.PutMinimum(0); bar.PutMaximum((LONG)newValueArray.size()/nValueSize); for ( ULONG j=0; j < newValueArray.size(); j += nValueSize) { //bar.PutValue(j); s = newValueArray.at(j); CString strValues = FormatNumber(s); for ( LONG k=1; k<nValueSize; k++ ) { s = newValueArray.at(j+k); strValues += L" " + FormatNumber(s); } in_mfw << "vt "; in_mfw << strValues.GetAsciiString(); in_mfw << "\n"; gVt++; bar.Increment(); } CString string = L"#end " + CString((ULONG)newValueArray.size()/nValueSize) + L"\n"; in_mfw << string.GetAsciiString(); in_mfw << "\n"; }
XSIPLUGINCALLBACK CStatus OutputMaterials( Selection& in_sel ) { // prepare the mtl file Project prj = app.GetActiveProject(); Scene scn = prj.GetActiveScene(); CString tmpLocation = Get3DCoatParam( L"tempLocation" ).GetValue(); ULONG npos = tmpLocation.ReverseFindString(L"."); CString substr = tmpLocation.GetSubString(0, npos+1); CString strOut = substr + L"mtl"; //app.LogMessage(L"strOut:" + strOut); std::ofstream matfw; matfw.open(strOut.GetAsciiString(), std::ios_base::out | std::ios_base::trunc); if (matfw.is_open()) { CRefArray tempMats; for(int i=0; i< in_sel.GetCount(); i++) { X3DObject xobj(in_sel.GetItem(i)); // Get a geometry accessor from the selected object Primitive prim = xobj.GetActivePrimitive(); PolygonMesh mesh = prim.GetGeometry(); if (!mesh.IsValid()) return CStatus::False; CGeometryAccessor ga = mesh.GetGeometryAccessor(); // get the material objects used by the mesh CRefArray materials = ga.GetMaterials(); for (LONG n=0; n < materials.GetCount(); n++) { bar.PutStatusText( L"materials" ); Material mat(materials[n]); bool inMats = false; //app.LogMessage(CString(n) +L" : "+ CString(i)+ L" :" + mat.GetName()); for(int m = 0; m < tempMats.GetCount(); m++) { Material tmat(tempMats[m]); if(mat.GetName() == tmat.GetName()) { inMats = true; break; } } //app.LogMessage(CString(inMats)); if(!inMats) { CString string = L"newmtl " + mat.GetName() + L"\n"; matfw << string.GetAsciiString(); Parameter surf = mat.GetParameters().GetItem(L"surface"); Shader lShader(surf.GetSource()); //app.LogMessage(L"shader: " + lShader.GetFullName()); //app.LogMessage(L"shader: " + lShader.GetProgID()); if ( lShader.GetProgID() == L"Softimage.material-phong.1" ) { float r, g, b, a; lShader.GetColorParameterValue(L"ambient", r, g, b, a ); CString ka = L"Ka " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b); lShader.GetColorParameterValue(L"diffuse", r, g, b, a ); CString kd = L"Kd " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b); lShader.GetColorParameterValue(L"specular", r, g, b, a ); CString ks = L"Ks " + FormatNumber(r) + L" " + FormatNumber(g) + L" " + FormatNumber(b); float ns = lShader.GetParameterValue(L"shiny"); float d = 1.0f; CValue illum = 2; matfw << ka.GetAsciiString(); matfw << "\n"; matfw << kd.GetAsciiString(); matfw << "\n"; matfw << ks.GetAsciiString(); matfw << "\n"; matfw << "Ns "; matfw << FormatNumber(ns).GetAsciiString(); matfw << "\n"; matfw << "d "; matfw << FormatNumber(d).GetAsciiString(); matfw << "\n"; matfw << "illum "; matfw << illum.GetAsText().GetAsciiString(); matfw << "\n"; Parameter diff = lShader.GetParameters().GetItem(L"diffuse"); Shader lImageD(diff.GetSource()); if (lImageD.GetProgID() == L"Softimage.txt2d-image-explicit.1") { Parameter tex = lImageD.GetParameters().GetItem(L"tex"); ImageClip2 lTextureD(tex.GetSource()); //app.LogMessage( L"Found texture shader: " + lTexture.GetFullName() + L", Class: " + lTexture.GetClassIDName() + L", Type: " + lTexture.GetType() ); app.LogMessage(L"texture GetFileName: " + lTextureD.GetFileName()); matfw << "map_Kd "; matfw << lTextureD.GetFileName().GetAsciiString(); matfw << "\n"; } Parameter spec = lShader.GetParameters().GetItem(L"specular"); Shader lImageS(spec.GetSource()); if (lImageS.GetProgID() == L"Softimage.txt2d-image-explicit.1") { Parameter tex = lImageD.GetParameters().GetItem(L"tex"); ImageClip2 lTextureS(tex.GetSource()); //app.LogMessage( L"Found texture shader: " + lTexture.GetFullName() + L", Class: " + lTexture.GetClassIDName() + L", Type: " + lTexture.GetType() ); //app.LogMessage(L"texture GetFileName: " + lTexture.GetFileName()); matfw << "map_Ks "; matfw << lTextureS.GetFileName().GetAsciiString(); matfw << "\n"; } } tempMats.Add(mat); matfw << "\n"; matfw << "\n"; } } } matfw.close(); } return CStatus::OK; }
XSI::CStatus AlembicSubD::Save(double time) { // store the transform Primitive prim(GetRef(REF_PRIMITIVE)); bool globalSpace = GetJob()->GetOption(L"globalSpace"); // query the global space CTransformation globalXfo; if(globalSpace) globalXfo = KinematicState(GetRef(REF_GLOBAL_TRANS)).GetTransform(time); CTransformation globalRotation; globalRotation.SetRotation(globalXfo.GetRotation()); // store the metadata SaveMetaData(GetRef(REF_NODE),this); // check if the mesh is animated if(mNumSamples > 0) { if(!isRefAnimated(GetRef(REF_PRIMITIVE), false, globalSpace)) return CStatus::OK; } // determine if we are a pure point cache bool purePointCache = (bool)GetJob()->GetOption(L"exportPurePointCache"); // access the mesh PolygonMesh mesh = prim.GetGeometry(time); CVector3Array pos = mesh.GetVertices().GetPositionArray(); LONG vertCount = pos.GetCount(); // prepare the bounding box Abc::Box3d bbox; // allocate the points and normals std::vector<Abc::V3f> posVec(vertCount); for(LONG i=0;i<vertCount;i++) { if(globalSpace) pos[i] = MapObjectPositionToWorldSpace(globalXfo,pos[i]); posVec[i].x = (float)pos[i].GetX(); posVec[i].y = (float)pos[i].GetY(); posVec[i].z = (float)pos[i].GetZ(); bbox.extendBy(posVec[i]); } // allocate the sample for the points if(posVec.size() == 0) { bbox.extendBy(Abc::V3f(0,0,0)); posVec.push_back(Abc::V3f(FLT_MAX,FLT_MAX,FLT_MAX)); } Abc::P3fArraySample posSample(&posVec.front(),posVec.size()); // store the positions && bbox mSubDSample.setPositions(posSample); mSubDSample.setSelfBounds(bbox); customAttributes.exportCustomAttributes(mesh); // abort here if we are just storing points if(purePointCache) { if(mNumSamples == 0) { // store a dummy empty topology mFaceCountVec.push_back(0); mFaceIndicesVec.push_back(0); Abc::Int32ArraySample faceCountSample(&mFaceCountVec.front(),mFaceCountVec.size()); Abc::Int32ArraySample faceIndicesSample(&mFaceIndicesVec.front(),mFaceIndicesVec.size()); mSubDSample.setFaceCounts(faceCountSample); mSubDSample.setFaceIndices(faceIndicesSample); } mSubDSchema.set(mSubDSample); mNumSamples++; return CStatus::OK; } // check if we support changing topology bool dynamicTopology = (bool)GetJob()->GetOption(L"exportDynamicTopology"); CPolygonFaceRefArray faces = mesh.GetPolygons(); LONG faceCount = faces.GetCount(); LONG sampleCount = mesh.GetSamples().GetCount(); // create a sample look table LONG offset = 0; CLongArray sampleLookup(sampleCount); for(LONG i=0;i<faces.GetCount();i++) { PolygonFace face(faces[i]); CLongArray samples = face.GetSamples().GetIndexArray(); for(LONG j=samples.GetCount()-1;j>=0;j--) sampleLookup[offset++] = samples[j]; } // check if we should export the velocities if(dynamicTopology) { ICEAttribute velocitiesAttr = mesh.GetICEAttributeFromName(L"PointVelocity"); if(velocitiesAttr.IsDefined() && velocitiesAttr.IsValid()) { CICEAttributeDataArrayVector3f velocitiesData; velocitiesAttr.GetDataArray(velocitiesData); mVelocitiesVec.resize(vertCount); for(LONG i=0;i<vertCount;i++) { CVector3 vel; vel.PutX(velocitiesData[i].GetX()); vel.PutY(velocitiesData[i].GetY()); vel.PutZ(velocitiesData[i].GetZ()); if(globalSpace) vel = MapObjectPositionToWorldSpace(globalRotation,vel); mVelocitiesVec[i].x = (float)vel.GetX(); mVelocitiesVec[i].y = (float)vel.GetY(); mVelocitiesVec[i].z = (float)vel.GetZ(); } if(mVelocitiesVec.size() == 0) mVelocitiesVec.push_back(Abc::V3f(0,0,0)); Abc::V3fArraySample sample = Abc::V3fArraySample(&mVelocitiesVec.front(),mVelocitiesVec.size()); mSubDSample.setVelocities(sample); } } // if we are the first frame! if(mNumSamples == 0 || dynamicTopology) { // we also need to store the face counts as well as face indices if(mFaceIndicesVec.size() != sampleCount || sampleCount == 0) { mFaceCountVec.resize(faceCount); mFaceIndicesVec.resize(sampleCount); offset = 0; for(LONG i=0;i<faceCount;i++) { PolygonFace face(faces[i]); CLongArray indices = face.GetVertices().GetIndexArray(); mFaceCountVec[i] = indices.GetCount(); for(LONG j=indices.GetCount()-1;j>=0;j--) mFaceIndicesVec[offset++] = indices[j]; } if(mFaceIndicesVec.size() == 0) { mFaceCountVec.push_back(0); mFaceIndicesVec.push_back(0); } Abc::Int32ArraySample faceCountSample(&mFaceCountVec.front(),mFaceCountVec.size()); Abc::Int32ArraySample faceIndicesSample(&mFaceIndicesVec.front(),mFaceIndicesVec.size()); mSubDSample.setFaceCounts(faceCountSample); mSubDSample.setFaceIndices(faceIndicesSample); } // set the subd level Property geomApproxProp; prim.GetParent3DObject().GetPropertyFromName(L"geomapprox",geomApproxProp); mSubDSample.setFaceVaryingInterpolateBoundary(geomApproxProp.GetParameterValue(L"gapproxmordrsl")); // also check if we need to store UV CRefArray clusters = mesh.GetClusters(); if((bool)GetJob()->GetOption(L"exportUVs")) { CGeometryAccessor accessor = mesh.GetGeometryAccessor(siConstructionModeSecondaryShape); CRefArray uvPropRefs = accessor.GetUVs(); // if we now finally found a valid uvprop if(uvPropRefs.GetCount() > 0) { // ok, great, we found UVs, let's set them up if(mNumSamples == 0) { mUvVec.resize(uvPropRefs.GetCount()); if((bool)GetJob()->GetOption(L"indexedUVs")) mUvIndexVec.resize(uvPropRefs.GetCount()); // query the names of all uv properties std::vector<std::string> uvSetNames; for(LONG i=0;i< uvPropRefs.GetCount();i++) uvSetNames.push_back(ClusterProperty(uvPropRefs[i]).GetName().GetAsciiString()); Abc::OStringArrayProperty uvSetNamesProperty = Abc::OStringArrayProperty( mSubDSchema, ".uvSetNames", mSubDSchema.getMetaData(), GetJob()->GetAnimatedTs() ); Abc::StringArraySample uvSetNamesSample(&uvSetNames.front(),uvSetNames.size()); uvSetNamesProperty.set(uvSetNamesSample); } // loop over all uvsets for(LONG uvI=0;uvI<uvPropRefs.GetCount();uvI++) { mUvVec[uvI].resize(sampleCount); CDoubleArray uvValues = ClusterProperty(uvPropRefs[uvI]).GetElements().GetArray(); for(LONG i=0;i<sampleCount;i++) { mUvVec[uvI][i].x = (float)uvValues[sampleLookup[i] * 3 + 0]; mUvVec[uvI][i].y = (float)uvValues[sampleLookup[i] * 3 + 1]; } // now let's sort the normals size_t uvCount = mUvVec[uvI].size(); size_t uvIndexCount = 0; if((bool)GetJob()->GetOption(L"indexedUVs")) { std::map<SortableV2f,size_t> uvMap; std::map<SortableV2f,size_t>::const_iterator it; size_t sortedUVCount = 0; std::vector<Abc::V2f> sortedUVVec; mUvIndexVec[uvI].resize(mUvVec[uvI].size()); sortedUVVec.resize(mUvVec[uvI].size()); // loop over all uvs for(size_t i=0;i<mUvVec[uvI].size();i++) { it = uvMap.find(mUvVec[uvI][i]); if(it != uvMap.end()) mUvIndexVec[uvI][uvIndexCount++] = (Abc::uint32_t)it->second; else { mUvIndexVec[uvI][uvIndexCount++] = (Abc::uint32_t)sortedUVCount; uvMap.insert(std::pair<Abc::V2f,size_t>(mUvVec[uvI][i],(Abc::uint32_t)sortedUVCount)); sortedUVVec[sortedUVCount++] = mUvVec[uvI][i]; } } // use indexed uvs if they use less space mUvVec[uvI] = sortedUVVec; uvCount = sortedUVCount; sortedUVCount = 0; sortedUVVec.clear(); } AbcG::OV2fGeomParam::Sample uvSample(Abc::V2fArraySample(&mUvVec[uvI].front(),uvCount),AbcG::kFacevaryingScope); if(mUvIndexVec.size() > 0 && uvIndexCount > 0) uvSample.setIndices(Abc::UInt32ArraySample(&mUvIndexVec[uvI].front(),uvIndexCount)); if(uvI == 0) { mSubDSample.setUVs(uvSample); } else { // create the uv param if required if(mNumSamples == 0) { CString storedUvSetName = CString(L"uv") + CString(uvI); mUvParams.push_back(AbcG::OV2fGeomParam( mSubDSchema, storedUvSetName.GetAsciiString(), uvIndexCount > 0, AbcG::kFacevaryingScope, 1, GetJob()->GetAnimatedTs())); } mUvParams[uvI-1].set(uvSample); } } // create the uv options if(mUvOptionsVec.size() == 0) { mUvOptionsProperty = Abc::OFloatArrayProperty(mSubDSchema, ".uvOptions", mSubDSchema.getMetaData(), GetJob()->GetAnimatedTs() ); for(LONG uvI=0;uvI<uvPropRefs.GetCount();uvI++) { //ESS_LOG_ERROR( "Cluster Property child name: " << ClusterProperty(uvPropRefs[uvI]).GetFullName().GetAsciiString() ); //ESS_LOG_ERROR( "Cluster Property child type: " << ClusterProperty(uvPropRefs[uvI]).GetType().GetAsciiString() ); ClusterProperty clusterProperty = (ClusterProperty) uvPropRefs[uvI]; bool subdsmooth = false; if( clusterProperty.GetType() == L"uvspace") { subdsmooth = (bool)clusterProperty.GetParameter(L"subdsmooth").GetValue(); // ESS_LOG_ERROR( "subdsmooth: " << subdsmooth ); } CRefArray children = clusterProperty.GetNestedObjects(); bool uWrap = false; bool vWrap = false; for(LONG i=0; i<children.GetCount(); i++) { ProjectItem child(children.GetItem(i)); CString type = child.GetType(); // ESS_LOG_ERROR( " Cluster Property child type: " << type.GetAsciiString() ); if(type == L"uvprojdef") { uWrap = (bool)child.GetParameter(L"wrap_u").GetValue(); vWrap = (bool)child.GetParameter(L"wrap_v").GetValue(); break; } } // uv wrapping mUvOptionsVec.push_back(uWrap ? 1.0f : 0.0f); mUvOptionsVec.push_back(vWrap ? 1.0f : 0.0f); mUvOptionsVec.push_back(subdsmooth ? 1.0f : 0.0f); } mUvOptionsProperty.set(Abc::FloatArraySample(&mUvOptionsVec.front(),mUvOptionsVec.size())); } } } // sweet, now let's have a look at face sets if(GetJob()->GetOption(L"exportFaceSets") && mNumSamples == 0) { for(LONG i=0;i<clusters.GetCount();i++) { Cluster cluster(clusters[i]); if(!cluster.GetType().IsEqualNoCase(L"poly")) continue; CLongArray elements = cluster.GetElements().GetArray(); if(elements.GetCount() == 0) continue; std::string name(cluster.GetName().GetAsciiString()); mFaceSetsVec.push_back(std::vector<Abc::int32_t>()); std::vector<Abc::int32_t> & faceSetVec = mFaceSetsVec.back(); for(LONG j=0;j<elements.GetCount();j++) faceSetVec.push_back(elements[j]); if(faceSetVec.size() > 0) { AbcG::OFaceSet faceSet = mSubDSchema.createFaceSet(name); AbcG::OFaceSetSchema::Sample faceSetSample(Abc::Int32ArraySample(&faceSetVec.front(),faceSetVec.size())); faceSet.getSchema().set(faceSetSample); } } } // save the sample mSubDSchema.set(mSubDSample); // check if we need to export the bindpose if(GetJob()->GetOption(L"exportBindPose") && prim.GetParent3DObject().GetEnvelopes().GetCount() > 0 && mNumSamples == 0) { mBindPoseProperty = Abc::OV3fArrayProperty(mSubDSchema, ".bindpose", mSubDSchema.getMetaData(), GetJob()->GetAnimatedTs()); // store the positions of the modeling stack into here PolygonMesh bindPoseGeo = prim.GetGeometry(time, siConstructionModeModeling); CVector3Array bindPosePos = bindPoseGeo.GetPoints().GetPositionArray(); mBindPoseVec.resize((size_t)bindPosePos.GetCount()); for(LONG i=0;i<bindPosePos.GetCount();i++) { mBindPoseVec[i].x = (float)bindPosePos[i].GetX(); mBindPoseVec[i].y = (float)bindPosePos[i].GetY(); mBindPoseVec[i].z = (float)bindPosePos[i].GetZ(); } Abc::V3fArraySample sample; if(mBindPoseVec.size() > 0) sample = Abc::V3fArraySample(&mBindPoseVec.front(),mBindPoseVec.size()); mBindPoseProperty.set(sample); } } else { mSubDSchema.set(mSubDSample); } mNumSamples++; return CStatus::OK; }
SICALLBACK AppLink_3DCoat_DefineLayout( CRef& in_ctxt ) { Context ctxt(in_ctxt); PPGLayout ppg = ctxt.GetSource(); PPGItem item; Plugin pl(app.GetPlugins().GetItem(L"AppLink_3DCoat_Plugin")); CString logoPath = CUtils::BuildPath(app.GetInstallationPath(pl.GetOrigin()), L"AppLink_3DCoat", L"Application", L"Plugins", L"3dcoatLogo.bmp"); CString txt = L"*Select folder ..\\My Documents\\3D-CoatV3\\Exchange"; ppg.Clear(); ppg.AddTab(L"General"); item = ppg.AddItem(L"Logo",L"", siControlBitmap); item.PutAttribute(siUIFilePath, logoPath); item.PutAttribute(siUINoLabel, true); ppg.AddGroup(L"Locations"); item = ppg.AddItem( L"tempLocation", L"", siControlFilePath ); //item.PutAttribute( siUIInitialDir, L"project" ) ; //item.PutAttribute( siUIFileFilter, L"3D files (*.obj,*.lwo)|*.obj,*.lwo|All Files (*.*)|*.*||" ) ; item = ppg.AddItem( L"coatLocation", L"", siControlFolder ) ; item.PutAttribute( siUIInitialDir, L"user" ) ; ppg.AddStaticText(txt.GetAsciiString()); //item = ppg.AddItem( L"coatExe", L"", siControlFilePath); //item.PutAttribute( siUIInitialDir, L"user" ); //item.PutAttribute( siUIFileFilter, L"Exe files (*.exe)|*.exe|All Files (*.*)|*.*||" ) ; ppg.EndGroup(); //Paint mesh in 3D-Coat using per-pixel painting [ppp] //Paint mesh in 3D-Coat using microvertex painting [mv] //Paint mesh in 3D-Coat using Ptex [ptex] //Perform UV-mapping in 3D-Coat [uv] //Drop reference mesh to 3D-Coat [ref] //Drop retopo mesh as new layer in 3D-Coat [retopo] //Drop mesh in 3D-Coat as voxel object [vox] //Drop mesh in 3D-Coat as new pen alpha [alpha] //Drop mesh in 3D-Coat as new merging primitive for voxels [prim] //Drop mesh in 3D-Coat as a curve profile [curv] //Drop mesh in 3D-Coat for Auto-retopology [autopo] ppg.AddGroup(L"Export"); CValueArray sizeItems( 22 ) ; sizeItems[0] = L"Per-pixel painting"; sizeItems[1] = (LONG)0 ; sizeItems[2] = L"Microvertex painting"; sizeItems[3] = (LONG)1 ; sizeItems[4] = L"Ptex"; sizeItems[5] = (LONG)2 ; sizeItems[6] = L"Perform UV-mapping"; sizeItems[7] = (LONG)3 ; sizeItems[8] = L"Drop reference mesh"; sizeItems[9] = (LONG)4 ; sizeItems[10] = L"Drop retopo mesh as new layer"; sizeItems[11] = (LONG)5 ; sizeItems[12] = L"Drop mesh as voxel object"; sizeItems[13] = (LONG)6 ; sizeItems[14] = L"Drop mesh as new pen alpha"; sizeItems[15] = (LONG)7 ; sizeItems[16] = L"Drop mesh as new merging primitive for voxels"; sizeItems[17] = (LONG)8 ; sizeItems[18] = L"Drop mesh as a curve profile"; sizeItems[19] = (LONG)9 ; sizeItems[20] = L"Drop mesh for Auto-retopology"; sizeItems[21] = (LONG)10 ; ppg.AddEnumControl( L"typePaint", sizeItems, L"", siControlCombo ) ; ppg.AddItem(L"bExpNorm"); ppg.AddItem(L"bExpMat"); ppg.AddItem(L"bExpUV"); ppg.AddItem(L"bExpSkipImp"); ppg.AddItem(L"bExpSkipExp"); //ppg.AddItem(L"bCopyTexE"); item = ppg.AddButton( L"Coat3DExport", L"Export to 3DCoat" ); item.PutAttribute(siUICX, (LONG)ppg.GetAttribute(siUICX)); ppg.EndGroup(); ppg.AddGroup(L"Import"); ppg.AddItem(L"bImpNorm"); ppg.AddItem(L"bImpMat"); CValueArray sizeItems2( 4 ); sizeItems2[0] = L"Normal map"; sizeItems2[1] = (LONG)0 ; sizeItems2[2] = L"Bump map"; sizeItems2[3] = (LONG)1 ; ppg.AddEnumControl( L"swMap", sizeItems2, L"", siControlCombo ) ; ppg.AddItem(L"bImpUV"); ppg.AddRow(); ppg.AddItem(L"bReplace"); ppg.AddItem(L"bEvent"); ppg.EndRow(); //ppg.AddItem(L"bCopyTexI"); item = ppg.AddButton( L"Coat3DImport", L"Import from 3DCoat" ); item.PutAttribute(siUICX, (LONG)ppg.GetAttribute(siUICX)); ppg.EndGroup(); ppg.AddTab(L"3D-Coat Location"); item = ppg.AddItem( L"exeLocation", L"", siControlFilePath ); item.PutAttribute( siUIFileFilter, L"Exe files (*.exe)|*.exe|All Files (*.*)|*.*||" ); item.PutAttribute( siUIOpenFile, true ); ppg.AddItem(L"bStart"); return CStatus::OK; }
SICALLBACK AppLink_3DCoat_PPGEvent( const CRef& in_ctxt ) { //Application app; PPGEventContext ctxt( in_ctxt ) ; CustomProperty prop = ctxt.GetSource(); PPGEventContext::PPGEvent eventID = ctxt.GetEventID() ; //CString s_ExeLocation = prop.GetParameter(L"coatExe").GetValue(); if ( eventID == PPGEventContext::siOnInit ) { CString s_ExportLocation = prop.GetParameter(L"tempLocation").GetValue(); CString s_CoatLocation = prop.GetParameter(L"coatLocation").GetValue(); Plugin pl(app.GetPlugins().GetItem(L"AppLink_3DCoat_Plugin")); pluginPath = CUtils::BuildPath(app.GetInstallationPath(pl.GetOrigin()), L"AppLink_3DCoat", L"Application", L"Plugins"); if(prop.GetParameter(L"tempLocation").GetValue() == L"") { Project prj = app.GetActiveProject(); Scene scn = prj.GetActiveScene(); CString tempPath = CUtils::BuildPath(app.GetInstallationPath(siProjectPath), L"3DCoat", scn.GetName(), scn.GetName() + L".obj"); prop.GetParameter(L"tempLocation").PutValue(tempPath); prop.GetParameter(L"tempLocation").PutCapabilityFlag(siReadOnly, true); } if(prop.GetParameter(L"coatLocation").GetValue() == L"") { TCHAR Path[MAX_PATH]; if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, Path))) { CString exchPath = CUtils::BuildPath(Path, L"3D-CoatV3", L"Exchange"); prop.GetParameter(L"coatLocation").PutValue(exchPath); } } //prop.GetParameter(L"bImpNorm").PutCapabilityFlag(siNotInspectable, true); //prop.GetParameter(L"bImpNewMat").PutCapabilityFlag(siReadOnly, true); ctxt.PutAttribute(L"Refresh",true); } else if ( eventID == PPGEventContext::siButtonClicked ) { CValue buttonPressed = ctxt.GetAttribute( L"Button" ); CString tempLocation = prop.GetParameter(L"tempLocation").GetValue(); CString coatLocation = prop.GetParameter(L"coatLocation").GetValue(); if( buttonPressed.GetAsText() == L"Coat3DExport" ) { CustomProperty in_pset = ctxt.GetSource(); if(CUtils::EnsureFolderExists(tempLocation, true)) { CValueArray args(6); args[0] = tempLocation; args[1] = coatLocation; args[2] = in_pset.GetParameterValue( L"typePaint" ); //args[3] = in_pset.GetParameterValue( L"bCopyTexE" ); args[3] = in_pset.GetParameterValue( L"bExpMat" ); args[4] = in_pset.GetParameterValue( L"bExpUV" ); args[5] = in_pset.GetParameterValue( L"bExpNorm" ); CValue retVal; app.ExecuteCommand( L"Coat3DExport", args, retVal ); CString exeLocation = prop.GetParameter(L"exeLocation").GetValue(); bool bStart = prop.GetParameter(L"bStart").GetValue(); if(exeLocation != L"" && bStart) { if(!Find3DCoat()) { if((int)::ShellExecute(NULL, TEXT("open"), exeLocation.GetAsciiString(), NULL, NULL, SW_SHOWNORMAL) <= 32) { app.LogMessage(L"3D-Coat.exe not found!", siWarningMsg); } } else { app.LogMessage(L"3D-Coat.exe is run!", siWarningMsg); } } } else { app.LogMessage(L"Note temp path exists!", siErrorMsg); } } else if( buttonPressed.GetAsText() == L"Coat3DImport" ) { CustomProperty in_pset = ctxt.GetSource(); CString exportPath = CUtils::BuildPath(coatLocation, L"export.txt"); CString objPath; std::ifstream mfrExportTxt; mfrExportTxt.open (exportPath.GetAsciiString());//c:\Documents and Settings\user\My Documents\3D-CoatV3\Exchange\export.txt //app.LogMessage(L"Export.txt is it! :" + strOut); if(mfrExportTxt.good()) { std::string row; std::getline(mfrExportTxt, row); objPath = row.c_str(); //app.LogMessage(L"first row: " + CString(row.c_str())); } else { UIToolkit uitool = app.GetUIToolkit(); LONG out; uitool.MsgBox(L"import file not found!", siMsgOkOnly|siMsgExclamation, L"", (LONG) out); if(out == siMsgOk) { return CStatus::False; } } mfrExportTxt.close(); app.LogMessage(coatLocation); app.LogMessage(exportPath); if(objPath != L"") { CValueArray args(2); args[0] = objPath; args[1] = in_pset.GetParameterValue( L"bReplace" ); CValue noret; app.ExecuteCommand( L"Coat3DImport", args, noret ); } } } else if ( eventID == PPGEventContext::siParameterChange ) { Parameter changed = ctxt.GetSource(); CustomProperty prop = changed.GetParent(); CString paramName = changed.GetScriptName(); if ( paramName == L"bImpMat" ) { CValue bFlag = prop.GetParameter(L"bImpMat").GetValue(); //prop.GetParameter(L"swMap").PutCapabilityFlag(siNotInspectable, !bFlag); prop.GetParameter(L"swMap").PutCapabilityFlag(siReadOnly, !bFlag); } ctxt.PutAttribute(L"Refresh",true); } return CStatus::OK ; }