void MayaMeshWriter::writeUVSets() { MStatus status = MS::kSuccess; const MFnMesh lMesh(mDagPath, &status); if (!status) { MGlobal::displayError( "MFnMesh() failed for MayaMeshWriter::writeUV" ); return; } //Write uvs const UVParamsVec::const_iterator uvItEnd = mUVparams.end(); for (UVParamsVec::iterator uvIt = mUVparams.begin(); uvIt != uvItEnd; ++uvIt) { std::vector<float> uvs; std::vector<Alembic::Util::uint32_t> indices; MString uvSetName(uvIt->getName().c_str()); getUVSet(lMesh, uvSetName, uvs, indices); //cast the vector to the sample type Alembic::AbcGeom::OV2fGeomParam::Sample sample( Alembic::Abc::V2fArraySample( (const Imath::V2f *) &uvs.front(), uvs.size() / 2), Alembic::Abc::UInt32ArraySample(indices), Alembic::AbcGeom::kFacevaryingScope); uvIt->set(sample); } }
bool SuperShaderModelInfo::IsSecondUVSetNeeded() { FBModel *pModel = GetFBModel(); if (pModel == nullptr) return false; FBGeometry *pGeometry = pModel->Geometry; FBStringList uvSets = pGeometry->GetUVSets(); if (uvSets.GetCount() < 2 ) return false; for (int i=0; i<pModel->Textures.GetCount(); ++i) { FBTexture *pTexture = pModel->Textures[i]; FBProperty *lProp = pTexture->PropertyList.Find( "UVSet" ); if (lProp) { FBString str( lProp->AsString() ); for (int j=1; j<uvSets.GetCount(); ++j) { FBString uvSetName(uvSets[j]); if (str == uvSetName) { return true; } } } } return false; }
/* static */ bool UsdMayaTranslatorMesh::_AssignUVSetPrimvarToMesh( const UsdGeomPrimvar& primvar, MFnMesh& meshFn) { const TfToken& primvarName = primvar.GetPrimvarName(); // Get the raw data before applying any indexing. VtVec2fArray uvValues; if (!primvar.Get(&uvValues) || uvValues.empty()) { TF_WARN("Could not read UV values from primvar '%s' on mesh: %s", primvarName.GetText(), primvar.GetAttr().GetPrimPath().GetText()); return false; } // This is the number of UV values assuming the primvar is NOT indexed. VtIntArray assignmentIndices; if (primvar.GetIndices(&assignmentIndices)) { // The primvar IS indexed, so the indices array is what determines the // number of UV values. int unauthoredValuesIndex = primvar.GetUnauthoredValuesIndex(); // Replace any index equal to unauthoredValuesIndex with -1. if (unauthoredValuesIndex != -1) { for (int& index : assignmentIndices) { if (index == unauthoredValuesIndex) { index = -1; } } } // Furthermore, if unauthoredValuesIndex is valid for uvValues, then // remove it from uvValues and shift the indices (we don't want to // import the unauthored value into Maya, where it has no meaning). if (unauthoredValuesIndex >= 0 && static_cast<size_t>(unauthoredValuesIndex) < uvValues.size()) { // This moves [unauthoredValuesIndex + 1, end) to // [unauthoredValuesIndex, end - 1), erasing the // unauthoredValuesIndex. std::move( uvValues.begin() + unauthoredValuesIndex + 1, uvValues.end(), uvValues.begin() + unauthoredValuesIndex); uvValues.pop_back(); for (int& index : assignmentIndices) { if (index > unauthoredValuesIndex) { index = index - 1; } } } } // Go through the UV data and add the U and V values to separate // MFloatArrays. MFloatArray uCoords; MFloatArray vCoords; for (const GfVec2f& v : uvValues) { uCoords.append(v[0]); vCoords.append(v[1]); } MStatus status; MString uvSetName(primvarName.GetText()); if (primvarName == UsdUtilsGetPrimaryUVSetName()) { // We assume that the primary USD UV set maps to Maya's default 'map1' // set which always exists, so we shouldn't try to create it. uvSetName = "map1"; } else { status = meshFn.createUVSet(uvSetName); if (status != MS::kSuccess) { TF_WARN("Unable to create UV set '%s' for mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } } // The following two lines should have no effect on user-visible state but // prevent a Maya crash in MFnMesh.setUVs after creating a crease set. // XXX this workaround is needed pending a fix by Autodesk. MString currentSet = meshFn.currentUVSetName(); meshFn.setCurrentUVSetName(currentSet); // Create UVs on the mesh from the values we collected out of the primvar. // We'll assign mesh components to these values below. status = meshFn.setUVs(uCoords, vCoords, &uvSetName); if (status != MS::kSuccess) { TF_WARN("Unable to set UV data on UV set '%s' for mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } const TfToken& interpolation = primvar.GetInterpolation(); // Build an array of value assignments for each face vertex in the mesh. // Any assignments left as -1 will not be assigned a value. MIntArray uvIds = _GetMayaFaceVertexAssignmentIds(meshFn, interpolation, assignmentIndices, -1); MIntArray vertexCounts; MIntArray vertexList; status = meshFn.getVertices(vertexCounts, vertexList); if (status != MS::kSuccess) { TF_WARN("Could not get vertex counts for UV set '%s' on mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } status = meshFn.assignUVs(vertexCounts, uvIds, &uvSetName); if (status != MS::kSuccess) { TF_WARN("Could not assign UV values to UV set '%s' on mesh: %s", uvSetName.asChar(), meshFn.fullPathName().asChar()); return false; } return true; }