CString GetUserSelectedObject() { Application app; Model root(app.GetActiveSceneRoot()); CStringArray emptyArray; CRefArray cRefArray = root.FindChildren( L"", L"", emptyArray, true ); CStringArray nameArray(cRefArray.GetCount()); for ( long i=0; i < cRefArray.GetCount(); i++ ) { nameArray[i] = SIObject(cRefArray[i]).GetName(); } //todo qsort the nameArray // Using the COMAPIHandler for creating a "XSIDial.XSIDialog" CComAPIHandler xsidialog; xsidialog.CreateInstance( L"XSIDial.XSIDialog"); CValue index; CValueArray args(cRefArray.GetCount()); for (long y=0; y < cRefArray.GetCount(); y++) args[y]=nameArray[y]; xsidialog.Call(L"Combo",index,L"Select Item",args ); long ind = (LONG)index; return args[ind]; }
//----------------------------------------------------------------------------- void XsiSkeletonExporter::validateAsBone(Skeleton* pSkeleton, DeformerEntry* deformer, DeformerMap& deformers, std::list<DeformerEntry*>& deformerList, AnimationList& animList) { /* The purpose of this method is to find out whether a node in the bone hierarchy is animated, and if not, to eliminate it and propagate it's static transform contribution to it's children. We do this because it's quite easy in XSI to build deep bone chains with intermediate points that are only used for manipulation. We don't want to include all of those. */ // TODO // if we weren't static, create bone if (!deformer->pBone) { String name = XSItoOgre(deformer->obj.GetName()); deformer->pBone = pSkeleton->createBone(name, deformer->boneID); MATH::CTransformation trans; if (deformer->parentName.empty()) { // set transform on bone to global transform since no parents trans = deformer->obj.GetKinematics().GetGlobal().GetTransform(); } else { // set transform on bone to local transform (since child) trans = deformer->obj.GetKinematics().GetLocal().GetTransform(); } deformer->pBone->setPosition(XSItoOgre(trans.GetTranslation())); deformer->pBone->setOrientation(XSItoOgre(trans.GetRotation().GetQuaternion())); deformer->pBone->setScale(XSItoOgre(trans.GetScaling())); // special case a bone which is parented by a chain end if (deformer->parentIsChainEndEffector) { ChainEffector effector(deformer->obj.GetParent()); CRefArray chainBones = effector.GetRoot().GetBones(); // get the last X3DObject endBone = chainBones[chainBones.GetCount()-1]; // offset along X the length of the bone double boneLen = endBone.GetParameterValue(L"Length"); deformer->pBone->setPosition( deformer->pBone->getPosition() + Vector3::UNIT_X * boneLen); } } }
//----------------------------------------------------------------------------- void XsiSkeletonExporter::linkBoneWithParent(DeformerEntry* child, DeformerMap& deformers, std::list<DeformerEntry*>& deformerList) { X3DObject parent(child->obj.GetParent()); String childName = XSItoOgre(child->obj.GetName()); if (child->obj == mXsiSceneRoot /* safety check for start node */) return; // Check for parenting by a chain end effector // These are sneaky little buggers - we actually want to attach the // child to the end of the final bone in the chain if (parent.IsA(XSI::siChainEffectorID)) { ChainEffector effector(parent); CRefArray chainBones = effector.GetRoot().GetBones(); // get the last parent = chainBones[chainBones.GetCount()-1]; child->parentIsChainEndEffector = true; } // is the parent the scene root? if (parent == mXsiSceneRoot) { // we hit the root node } else { String parentName = XSItoOgre(parent.GetName()); // Otherwise, check to see if the parent is in the deformer list DeformerEntry* parentDeformer = getDeformer(parentName, deformers); if (!parentDeformer) { // not found, create entry for parent parentDeformer = new DeformerEntry(deformers.size(), parent); deformers[parentName] = parentDeformer; deformerList.push_back(parentDeformer); LogOgreAndXSI(CString(L"Added ") + parent.GetName() + CString(L" as a parent of ") + child->obj.GetName() ); } // Link child entry with parent (not bone yet) // link child to parent by name child->parentName = parentName; parentDeformer->childNames.push_back(childName); } }
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 XsiSkeletonExporter::processActionSource(const XSI::ActionSource& actSource, DeformerMap& deformers) { // Clear existing deformer links for(DeformerMap::iterator di = deformers.begin(); di != deformers.end(); ++di) { for (int tt = XTT_POS_X; tt < XTT_COUNT; ++tt) { di->second->xsiTrack[tt].ResetObject(); } } // Get all the items CRefArray items = actSource.GetItems(); for (int i = 0; i < items.GetCount(); ++i) { XSI::AnimationSourceItem item = items[i]; // Check the target String target = XSItoOgre(item.GetTarget()); size_t firstDotPos = target.find_first_of("."); size_t lastDotPos = target.find_last_of("."); if (firstDotPos != String::npos && lastDotPos != String::npos) { String targetName = target.substr(0, firstDotPos); String paramName = target.substr(lastDotPos+1, target.size() - lastDotPos - 1); // locate deformer DeformerEntry* deformer = getDeformer(targetName, deformers); if (deformer) { // determine parameter std::map<String, int>::iterator pi = mXSITrackTypeNames.find(paramName); if (pi != mXSITrackTypeNames.end()) { deformer->xsiTrack[pi->second] = item; deformer->hasAnyTracks = true; } } } } }
bool Mesh::MeshIsMassPrimitive(X3DObject& mesh) { CRefArray props = mesh.GetProperties(); for (int i = 0; i < props.GetCount(); i++) { Property prop(props.GetItem(i)); if (!prop.IsValid()) continue; CString propName = prop.GetName(); propName.Lower(); if (propName == L"masssphereprimitiveproperty" || propName == L"masscubeprimitiveproperty" || propName == L"masscylinderprimitiveproperty" || propName == L"massrectangleprimitiveproperty" || propName == L"massdiskprimitiveproperty") { return true; } } return false; }
void findAnimations(XSI::Model& model, Ogre::AnimationList& animList) { if (model.HasMixer()) { // Scan the mixer for all clips // At this point we're only interested in the top-level and do not // cascade into all clip containers, since we're interested in the // top-level timeline splits XSI::Mixer mixer = model.GetMixer(); CRefArray clips = mixer.GetClips(); for (int c = 0; c < clips.GetCount(); ++c) { XSI::Clip clip(clips[c]); XSI::CString clipType = clip.GetType(); if (clipType == siClipAnimationType || clipType == siClipShapeType || clipType == siClipAnimCompoundType || // nested fcurves clipType == siClipShapeCompoundType) // nested shape { XSI::TimeControl timeControl = clip.GetTimeControl(); Ogre::AnimationEntry anim; anim.animationName = XSItoOgre(clip.GetName()); anim.startFrame = timeControl.GetStartOffset(); long length = (1.0 / timeControl.GetScale()) * (timeControl.GetClipOut() - timeControl.GetClipIn() + 1); anim.endFrame = anim.startFrame + length - 1; anim.ikSampleInterval = 5.0f; animList.push_back(anim); } } } }
bool hasSkeleton(X3DObject& si, bool recurse) { if (si.GetEnvelopes().GetCount() > 0) { return true; } if (recurse) { CRefArray children = si.GetChildren(); for(long i = 0; i < children.GetCount(); i++) { X3DObject child(children[i]); bool ret = hasSkeleton(child, recurse); if (ret) return ret; } } return false; }
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; }
SceneNodeXSIPtr buildCommonSceneGraph(XSI::CRef xsiRoot, int& nNumNodes, bool bUnmergeNodes, bool bSelectAll) { ESS_PROFILE_FUNC(); std::list<CSGStackElement> sceneStack; nNumNodes = 0; SceneNodeXSIPtr exoRoot = createNodeXSI(xsiRoot, SceneNode::SCENE_ROOT); X3DObject xRoot(xsiRoot); CRefArray children = xRoot.GetChildren(); for(LONG j=0; j<children.GetCount(); j++) { X3DObject child(children[j]); if(!child.IsValid()) continue; sceneStack.push_back(CSGStackElement(children[j], exoRoot)); } while( !sceneStack.empty() ) { CSGStackElement sElement = sceneStack.back(); CRef xRef = sElement.xNode; X3DObject xNode(xRef); SceneNodePtr eNode = sElement.eNode; sceneStack.pop_back(); nNumNodes++; SceneNodePtr newNode; SceneNode::nodeTypeE type = getNodeType(xNode); if(bUnmergeNodes) { //export case (don't why we don't use it for import) if(isShapeNode(type) ){ newNode = createNodeXSI(xRef, SceneNode::ETRANSFORM); //newNode->name+="Xfo"; SceneNodePtr geoNode = createNodeXSI(xRef, type); geoNode->name+="Shape"; newNode->children.push_back(geoNode); geoNode->parent = newNode.get(); } else{ newNode = createNodeXSI(xRef, type); } } else{ //import newNode = createNodeXSI(xRef, type);//doesn't identify EXTRANFORMS because these are built-in to the shape node if(type == SceneNode::ITRANSFORM || type == SceneNode::NAMESPACE_TRANSFORM){ //newNode->name+="Xfo"; } else{ //newNode->name+="Shape"; } } if(bSelectAll){ newNode->selected = true; } eNode->children.push_back(newNode); newNode->parent = eNode.get(); CRefArray children = xNode.GetChildren(); for(LONG j=0;j<children.GetCount();j++) { X3DObject child(children[j]); if(!child.IsValid()) continue; sceneStack.push_back(CSGStackElement(children[j], newNode)); } } return exoRoot; }
// PPG Event ================================================== XSIPLUGINCALLBACK CStatus sn_null2surface_op_PPGEvent( const CRef& in_ctxt ) { PPGEventContext ctxt( in_ctxt ) ; PPGEventContext::PPGEvent eventID = ctxt.GetEventID() ; if ( eventID == PPGEventContext::siOnInit ) { CRefArray props = ctxt.GetInspectedObjects(); for (LONG i=0; i<props.GetCount( ); i++) { // we don't do anything, but I keep the code around CustomOperator prop( props[i] ); } } else if ( eventID == PPGEventContext::siOnClosed ) { CRefArray props = ctxt.GetInspectedObjects(); for (LONG i=0; i<props.GetCount( ); i++) { // we don't do anything, but I keep the code around CustomOperator prop( props[i] ); } } else if ( eventID == PPGEventContext::siButtonClicked ) { CValue buttonPressed = ctxt.GetAttribute( L"Button" ) ; if(buttonPressed.GetAsText() == L"setInputUV") { CRefArray ops = ctxt.GetInspectedObjects(); for (LONG i=0; i<ops.GetCount( ); i++) { CustomOperator op( ops[i] ); CRef driverRef = InputPort(op.GetInputPorts()[0]).GetTarget(); KinematicState driverState(driverRef); CVector3 driverPos = driverState.GetTransform().GetTranslation(); CRef surfacePrimRef = InputPort(op.GetInputPorts()[2]).GetTarget(); NurbsSurfaceMesh surfaceMesh(Primitive(surfacePrimRef).GetGeometry()); LONG surface_index; double surface_u; double surface_v; double surface_un; double surface_vn; double surface_distance; CVector3 surface_pos; CVector3 surface_utan; CVector3 surface_vtan; CVector3 surface_normal; surfaceMesh.GetClosestSurfacePosition(driverPos,surface_index,surface_distance,surface_un,surface_vn,surface_pos); NurbsSurface surface(surfaceMesh.GetSurfaces()[surface_index]); surface.GetUVFromNormalizedUV(surface_un,surface_vn,surface_u,surface_v); op.PutParameterValue(L"iu_center",surface_u); op.PutParameterValue(L"iv_center",surface_v); } } else if(buttonPressed.GetAsText() == L"setInputXY") { CRefArray ops = ctxt.GetInspectedObjects(); for (LONG i=0; i<ops.GetCount( ); i++) { CustomOperator op( ops[i] ); CRef driverRef = InputPort(op.GetInputPorts()[4]).GetTarget(); KinematicState driverState(driverRef); CVector3 driverPos = driverState.GetTransform().GetTranslation(); // choose the right values based on the axis_mode long axis_mode = (LONG)op.GetParameterValue(L"axis_mode"); double surface_u = 0; double surface_v = 0; switch(axis_mode) { case 0: // X Y plane { surface_u = driverPos.GetX(); surface_v = driverPos.GetY(); break; } case 1: // X Z plane { surface_u = driverPos.GetX(); surface_v = driverPos.GetZ(); break; } case 2: // Y Z plane { surface_u = driverPos.GetY(); surface_v = driverPos.GetZ(); break; } case 3: // Y X plane { surface_u = driverPos.GetY(); surface_v = driverPos.GetX(); break; } case 4: // Z X plane { surface_u = driverPos.GetZ(); surface_v = driverPos.GetX(); break; } case 5: // Z Y plane { surface_u = driverPos.GetZ(); surface_v = driverPos.GetY(); break; } } op.PutParameterValue(L"ix_center",surface_u); op.PutParameterValue(L"iy_center",surface_v); } } else if(buttonPressed.GetAsText() == L"setOutputUV") { CRefArray ops = ctxt.GetInspectedObjects(); for (LONG i=0; i<ops.GetCount( ); i++) { CustomOperator op( ops[i] ); CRef driverRef = InputPort(op.GetInputPorts()[0]).GetTarget(); KinematicState driverState(driverRef); CVector3 driverPos = driverState.GetTransform().GetTranslation(); CRef surfacePrimRef = InputPort(op.GetInputPorts()[2]).GetTarget(); NurbsSurfaceMesh surfaceMesh(Primitive(surfacePrimRef).GetGeometry()); LONG surface_index; double surface_u; double surface_v; double surface_un; double surface_vn; double surface_distance; CVector3 surface_pos; CVector3 surface_utan; CVector3 surface_vtan; CVector3 surface_normal; surfaceMesh.GetClosestSurfacePosition(driverPos,surface_index,surface_distance,surface_un,surface_vn,surface_pos); NurbsSurface surface(surfaceMesh.GetSurfaces()[surface_index]); surface.GetUVFromNormalizedUV(surface_un,surface_vn,surface_u,surface_v); op.PutParameterValue(L"ou_center",surface_u); op.PutParameterValue(L"ov_center",surface_v); } } } else if ( eventID == PPGEventContext::siTabChange ) { CRefArray props = ctxt.GetInspectedObjects(); for (LONG i=0; i<props.GetCount( ); i++) { // we don't do anything, but I keep the code around CustomOperator prop( props[i] ); } } else if ( eventID == PPGEventContext::siParameterChange ) { CRefArray props = ctxt.GetInspectedObjects(); for (LONG i=0; i<props.GetCount( ); i++) { // we don't do anything, but I keep the code around CustomOperator prop( props[i] ); } } return CStatus::OK ; }