Community
Maya Forum
Welcome to Autodesk’s Maya Forums. Share your knowledge, ask questions, and explore popular Maya topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with Alembic import: Error getting adding to initalShadingGroup.

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
huben_hb
152 Views, 2 Replies

Problem with Alembic import: Error getting adding to initalShadingGroup.

Hello everyone, please help me!

 

I attempted to export an Alembic file in Unreal Engine, as shown in the source code below. However, when I try to import this file into Maya, I receive an error message "Error: Error getting adding to initalShadingGroup."

 

However, when I import this Alembic file into Houdini or Blender, everything works fine. If I re-export the original Alembic file from Houdini and Blender, I can then successfully import it into Maya without any issues.

 

I've reviewed the sample code on this website: https://help.autodesk.com/view/MAYAUL/2022/ENU/?guid=Maya_SDK_cpp_ref_gpu_cache_2_cache_writer_alemb...

 

Is it possible that I've overlooked some settings for Alembic?

 

Thanks a lot!

 

huben_hb_0-1704853334395.png

 

 

bool UChaosCacheAbcExporter::ExportBinary(UObject* Object, const TCHAR* Type, FArchive& Archive, FFeedbackContext* Warn, int32 FileIndex, uint32 PortFlags)
{
	UChaosCacheCollection* ChaosCacheCollectionAsset = Cast<UChaosCacheCollection>(Object);
	if (!ChaosCacheCollectionAsset)
	{
		return false;
	}

	TArray<USkeletalMesh*> SkeletalMeshes;
	TArray<FString> NullSkeletalMeshRef;

	for(auto& Cache: ChaosCacheCollectionAsset->GetCaches())
	{
		if(USkeletalMesh* SkeletalMesh = LoadObject<USkeletalMesh>(nullptr, *Cache->RecordedSkeletalMeshRef))
		{
			SkeletalMeshes.Emplace(SkeletalMesh);
		}
		else if(Cache->RecordedSkeletalMeshRef != "")
		{
			NullSkeletalMeshRef.Emplace(Cache->RecordedSkeletalMeshRef);
		}
	}

	if(SkeletalMeshes.Num() == 0)
	{
		return false;
	}

	if(NullSkeletalMeshRef.Num() > 0)
	{
		FString NoSkeletalMeshTip = L"布料缓存SkeletalMesh不存在, 请确定以下资产存在后重试: \r\n\r\n";

		for(FString StringRef: NullSkeletalMeshRef)
		{
			NoSkeletalMeshTip += StringRef + "\r\n";
		}
		
		FMessageDialog::Open(EAppMsgCategory::Warning, EAppMsgType::Ok,
							FText::FromString(NoSkeletalMeshTip), FText::FromString(L"布料SkeletalMesh不存在"));
		
		return false;
	}
	
	Alembic::Abc::OArchive ChaosCacheArchive(Alembic::AbcCoreOgawa::WriteArchive(), TCHAR_TO_UTF8(*CurrentFilename));
	ChaosCacheArchive.setCompressionHint(-1);
	
	const int32 AbcFrameRate = ChaosCacheCollectionAsset->RecordedOriginFrameRate * ChaosCacheCollectionAsset->RecordedMultiPower;
	
	Alembic::Abc::TimeSamplingPtr TimeSampPtr = std::make_shared<Alembic::Abc::TimeSampling>(1.0 / AbcFrameRate, 0.0);
	int32 Tsi = ChaosCacheArchive.addTimeSampling(*TimeSampPtr);

	Alembic::Abc::OObject ChaosCacheObject(ChaosCacheArchive, Alembic::Abc::kTop, Tsi);
	
	const int32 SampleNum = ChaosCacheCollectionAsset->TotalRecordedFrames;

	std::vector<std::vector<Alembic::AbcGeom::OPolyMesh>> AllAbcPolyMeshes;
	// std::vector<Alembic::AbcMaterial::OMaterial> AbcPolyMeshesMaterials;
	std::vector<std::vector<std::vector<int>>> AllFaceIndices;
	std::vector<std::vector<std::vector<int>>> AllPolygonCounts;
	std::vector<std::vector<std::vector<Alembic::Abc::V3f>>> AllVerticesPoses;
	std::vector<std::vector<std::vector<Alembic::Abc::V2f>>> AllVerticesUVs;
	std::vector<std::vector<std::vector<Alembic::Abc::V3f>>> AllVerticesVelocities;
	std::vector<std::vector<std::vector<Alembic::Abc::N3f>>> AllVerticesNormals;

	// 获取mesh
	for(int MeshId = 0; MeshId < SkeletalMeshes.Num(); MeshId++)
	{
		std::vector<Alembic::AbcGeom::OPolyMesh> AbcPolyMeshes;
		std::vector<std::vector<int>> FaceIndices;
		std::vector<std::vector<int>> PolygonCounts;
		std::vector<std::vector<Alembic::Abc::V3f>> VerticesPoses;
		std::vector<std::vector<Alembic::Abc::V2f>> VerticesUVs;
		std::vector<std::vector<Alembic::Abc::V3f>> VerticesVelocities;
		std::vector<std::vector<Alembic::Abc::N3f>> VerticesNormals;
	
		TArray<UClothingAssetBase*> AssetsInUse;
		SkeletalMeshes[MeshId]->GetClothingAssetsInUse(AssetsInUse);
		const int32 NumMeshAssets = SkeletalMeshes[MeshId]->GetMeshClothingAssets().Num();

		for (int32 BaseAssetIndex = 0; BaseAssetIndex < NumMeshAssets; ++BaseAssetIndex)
		{
			UClothingAssetBase* const InAsset = SkeletalMeshes[MeshId]->GetMeshClothingAssets()[BaseAssetIndex];
			if (InAsset && AssetsInUse.Contains(InAsset))
			{
				AbcPolyMeshes.emplace_back(Alembic::AbcGeom::OPolyMesh(ChaosCacheObject, "cloth" + std::to_string(MeshId) + "_" + std::to_string(BaseAssetIndex), TimeSampPtr));
				// AbcPolyMeshesMaterials.emplace_back(Alembic::AbcMaterial::OMaterial(ChaosCacheObject, "mat" + std::to_string(BaseAssetIndex), TimeSampPtr));
				// Alembic::AbcCoreAbstract::MetaData MatMetaData;
				// Alembic::Abc::OStringProperty MaterialProp(AbcPolyMeshes.back().getSchema().getArbGeomParams(), "DefaultMat");
				// MaterialProp.set("lambert1");
				
				UClothingAssetCommon* const ClothAsset = Cast<UClothingAssetCommon>(InAsset);

				// vertex
				auto & VerticesPosArray = ClothAsset->LodData[0].PhysicalMeshData.Vertices;
				VerticesPoses.emplace_back(std::vector<Alembic::Abc::V3f>(VerticesPosArray.Num()));
				
				// velocity
				VerticesVelocities.emplace_back(std::vector<Alembic::Abc::V3f>(VerticesPosArray.Num()));

				// normal
				auto & VerticesNormalArray = ClothAsset->LodData[0].PhysicalMeshData.Normals;
				std::vector<Alembic::Abc::V3f> VerticesNormal(VerticesNormalArray.Num());
				for(int z = 0; z < VerticesNormalArray.Num(); z++)
				{
					VerticesNormal[z] = {VerticesNormalArray[z].X, VerticesNormalArray[z].Z, -VerticesNormalArray[z].Y};
				}
				VerticesNormals.emplace_back(VerticesNormal);

				// Indices
				auto & Indices = ClothAsset->LodData[0].PhysicalMeshData.Indices;
				std::vector<int> FaceIndice(Indices.Num());
				for(int z = 0; z < Indices.Num(); z++)
				{
					FaceIndice[z] = Indices[z];
				}
				FaceIndices.emplace_back(FaceIndice);
				PolygonCounts.emplace_back(std::vector<int>(FaceIndice.size() / 3, 3));
			}
		}

		AllAbcPolyMeshes.emplace_back(AbcPolyMeshes);
		AllFaceIndices.emplace_back(FaceIndices);
		AllPolygonCounts.emplace_back(PolygonCounts);
		AllVerticesPoses.emplace_back(VerticesPoses);
		AllVerticesVelocities.emplace_back(VerticesVelocities);
		AllVerticesNormals.emplace_back(VerticesNormals);
	}
	
	TArray<UChaosCache*>& ChaosCaches = ChaosCacheCollectionAsset->GetCaches();

	for(int i = 0; i < SampleNum; i++)
	{
		for(int CacheId = 0; CacheId < AllAbcPolyMeshes.size();  CacheId++)
		{
			auto& Cache = ChaosCaches[CacheId];
			auto& [VX] = Cache->ChannelsTracks["VelocityX"];
			auto& [VY] = Cache->ChannelsTracks["VelocityY"];
			auto& [VZ] = Cache->ChannelsTracks["VelocityZ"];
			auto& [PX] = Cache->ChannelsTracks["PositionX"];
			auto& [PY] = Cache->ChannelsTracks["PositionY"];
			auto& [PZ] = Cache->ChannelsTracks["PositionZ"];
			
			int32 PosStart = 0;
			for(int z = 0; z < AllAbcPolyMeshes[CacheId].size(); z++)
			{
				Alembic::AbcGeom::OPolyMeshSchema::Sample MeshSample;

				// Position
				for(int j = 0; j < AllVerticesPoses[CacheId][z].size(); j++)
				{
					const int32 jj = PosStart + j;
					AllVerticesPoses[CacheId][z][j] = {PX[jj].Keys[i].Value, PZ[jj].Keys[i].Value, -PY[jj].Keys[i].Value};
					AllVerticesVelocities[CacheId][z][j] = {VX[jj].Keys[i].Value, VZ[jj].Keys[i].Value, -VY[jj].Keys[i].Value,};
				}

				PosStart += AllVerticesPoses[CacheId][z].size();

				Alembic::Abc::P3fArraySample PosArraySample;
				const Alembic::Abc::V3f* PositionArray = AllVerticesPoses[CacheId][z].data();
				PosArraySample = Alembic::Abc::P3fArraySample(PositionArray, AllVerticesPoses[CacheId][z].size());
				MeshSample.setPositions(PosArraySample);

				// Velocity
				Alembic::Abc::P3fArraySample VelocityArraySample;
				const Alembic::Abc::V3f* VelocityArray = AllVerticesVelocities[CacheId][z].data();
				PosArraySample = Alembic::Abc::P3fArraySample(VelocityArray, AllVerticesVelocities[CacheId][z].size());
				MeshSample.setVelocities((VelocityArraySample));
			
				// Normal
				Alembic::AbcGeom::ON3fGeomParam::Sample NormalSample;
				NormalSample.setScope(Alembic::AbcGeom::kFacevaryingScope);
				const Alembic::Abc::N3f* NormalArray = AllVerticesNormals[CacheId][z].data();
				NormalSample.setVals(Alembic::AbcGeom::N3fArraySample(NormalArray, AllVerticesNormals[CacheId][z].size()));
				NormalSample.setIndices(Alembic::Abc::UInt32ArraySample(reinterpret_cast<const uint32_t*>(AllFaceIndices[CacheId][z].data()), AllFaceIndices[CacheId][z].size()));
				MeshSample.setNormals(NormalSample);
			
				// Triangle
				MeshSample.setFaceCounts(Alembic::Abc::Int32ArraySample(AllPolygonCounts[CacheId][z].data(), AllPolygonCounts[CacheId][z].size()));
				MeshSample.setFaceIndices(Alembic::Abc::Int32ArraySample(AllFaceIndices[CacheId][z].data(), AllFaceIndices[CacheId][z].size()));
		
				AllAbcPolyMeshes[CacheId][z].getSchema().set(MeshSample);
			}
		}
	}

	return true;
}

 

Labels (5)
2 REPLIES 2
Message 2 of 3
cheng_xi_li
in reply to: huben_hb

Hi huben,

 

I think it was caused by how ABCImport was implemented.

 

When there is an animation in ABC, Maya will create an empty mesh and connect it with an Alembic node to provide animated mesh.

 

However, this routine in the ABCImport isn't working right now, the dagPath couldn't be acquired for setting shading group later. Fortunately, ABCImport is provided as a devkit sample, and we can try to fix it.

 

Find createPoly in the MeshHelper.cpp and replace the !schema.isConstant condition with following code:

 

    if (!schema.isConstant())
    {
        MFloatPointArray emptyPt;
        MIntArray emptyInt;
        MFnMesh fnMesh;
        fnMesh.create(0, 0, emptyPt, emptyInt, emptyInt, iParent);
        fnMesh.setName(name);
        obj = fnMesh.object();
    }

 

I've tested the modified ABCImport with Maya 2024.2, and it seems working fine. If this doesn't work, you can try to remove the animation checking and use the non-animated routine.

 

Hope it helps.

 

Yours,

Li

Message 3 of 3
huben_hb
in reply to: cheng_xi_li

Thank you! And I think it will work!

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report