Notifications
Clear all

[Closed] Howcan I detect pc2 point cache file is empty?

I want to avoid loading empty point cache file.
What would be the best way to detect if point cache file is empty?

4 Replies
 lo1

The following is a method I use to query various information from PC2 files. It’s generally based on the PointCache code in the SDK examples.

def_visible_primitive(GetPointCacheFileInfo, "GetPointCacheFileInfo");
	Value* GetPointCacheFileInfo_cf(Value **arg_list, int count)
	{
			check_arg_count(GetPointCacheFileInfo, 1, count);
		MSTR filename = arg_list[0]->to_string();

		HANDLE hFile = ::CreateFile(filename.data(),
						GENERIC_READ,
						FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,	// allow file to be overwritten or deleted out from under us!
						0,
						OPEN_EXISTING,
						0,
						NULL);
		if (!hFile)
		{
			return &undefined;
		}

		::SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

		char m_cacheSignature[12];
		int	m_cacheVersion;
		int	m_cacheNumPoints;
		int	m_cacheNumSamples;
		float m_cacheStartFrame;
		float m_cacheSampleRate;

		
		DWORD numRead;
		if (!ReadFile(hFile, &m_cacheSignature, sizeof(m_cacheSignature), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }
		if (!ReadFile(hFile, &m_cacheVersion, sizeof(m_cacheVersion), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }
		if (!ReadFile(hFile, &m_cacheNumPoints, sizeof(m_cacheNumPoints), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }
		if (!ReadFile(hFile, &m_cacheStartFrame, sizeof(m_cacheStartFrame), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }
		if (!ReadFile(hFile, &m_cacheSampleRate, sizeof(m_cacheSampleRate), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }
		if (!ReadFile(hFile, &m_cacheNumSamples, sizeof(m_cacheNumSamples), &numRead, NULL) || numRead == 0) { ::CloseHandle(hFile); return &undefined; }

		::CloseHandle(hFile);

		one_typed_value_local(Array* result);
		vl.result = new Array(4);
		vl.result->append(Float::intern((float)m_cacheStartFrame));
		vl.result->append(Float::intern((float)m_cacheSampleRate));
		vl.result->append(Integer::intern(m_cacheNumSamples));
		vl.result->append(Integer::intern(m_cacheNumPoints));
		return_value(vl.result);
	}

I usually just query the file size of the cache file. Here is a sample of the main FN for a cache cycle tool I wrote to cache out selected geo.

PCMod=Point_Cache()
addmodifier CREAM._objAr[i] PCMod
			
ModFilename=CREAM._CacheDir+CREAM._objAr[i].name
PCMod.filename=(ModFilename+".xml")
cacheOps.RecordCache PCMod
fsize=getfilesize (CREAM._cachedir+CREAM._objAr[i].name+".mc")

After applying a cache mod and simming it, it reads the size of the cache file.

if fsize>1000 then
			(
				collapsestack CREAM._objAr[i]
				addmodifier CREAM._objAr[i] PCMod
				PCMod.filename=(ModFilename+".xml")
				append CREAM._cacheAr[1] CREAM._objAr[i].name
			)
			else
			(
				deletemodifier CREAM._objAr[i] PCMod
				deletefile (ModFilename+".xml")
				deletefile (ModFilename+".mc")
				append CREAM._cacheAr[2] CREAM._objAr[i].name
			)

If the cache file size is larger than 1kb (what I have found the size of a blank cache file to be), then it collapses the stack and adds a new cache mod and plugs in the cache file, otherwise it deletes the cache mod, the xml file and the mc file. The last line in each just appends an array that is called by a messagebox to let me know what has been cached and what hasn’t.

A Maxscript version returning similar data to Lo’s SDK sample


	/*
	[NAME]: GetPCFileData
	[FUNCTION]:
		function to retrieve extra PC2 data from files	
	[ARGUMENTS]:
		<STRING> PCMod:A pointcache file path
		<NODE> PCMod: A pointcache modifier
	[RETURN]:
		<ARRAY>
		-- Return Structure
		-- 2 NumPoints
		-- 3 Start
		-- 4 SampleRate
		-- 5 Evaluations
		-- 6 End
	*/
	fn GetPCFileData PCMod = 
	(
		if Classof PCMod == string then PCFile = PCMod else PcFile = PCMod.filename
		if doesfileexist PCFile then 
		(
		FileError = false
		PCArrayData = #()
		PCArrayData[6] = 0 
		afStream = fOpen PCFile "rb"
		if ((ReadString afStream) != "POINTCACHE2") then FileError = true else PCArrayData[1] = "POINTCACHE2"
		if ((ReadLong afStream) != 1 ) then FileError = true 			
		if not FileError then
			(				
			--NumPoints
			PCArrayData[2]	= ReadLong afStream
			--Start
			PCArrayData[3]	= ReadFloat afStream
			--SampleRate
			PCArrayData[4]	= ReadFloat afStream
			--Evaluations
			PCArrayData[5]	= ReadLong afStream
			--End
			PCArrayData[6]	= (PCArrayData[3] + ((PCArrayData[5]-1) * PCArrayData[4])) 				
			)
		fClose afStream 
		PCArrayData
		)
		else #("--","--","--","--","--","--")
	)

Thanks Guys!