Пример #1
0
bool FileSequenceParameter::valueValid( const Object *value, std::string *reason ) const
{
	/// we can't call PathParameter::valueValid() because that would do existence checking on
	/// our path specifier with the # characters in it, and that would yield the wrong results
	/// so we call StringParameter.valueValid and do the rest ourselves.
	if ( !StringParameter::valueValid( value ) )
	{
		return false;
	}

	const StringData *stringDataValue = assertedStaticCast<const StringData>( value );
	const std::string &stringValue = stringDataValue->readable();

	if ( allowEmptyString() && !stringValue.size() )
	{
		return true;
	}

	if ( ! boost::regex_match( stringValue, FileSequence::fileNameValidator() ) )
	{
		if ( reason )
		{
			*reason = "Value must contain one sequence of at least one # character to specify frame number.";
		}
		return false;
	}

	FileSequencePtr fileSequence = nullptr;
	try
	{
		fileSequence = new FileSequence( stringValue );
	}
	catch ( Exception &e )
	{
		if ( reason )
		{
			*reason = "Not a valid file sequence specification";
		}
		return false;
	}

	assert( fileSequence );

	if ( m_extensions.size() )
	{
		std::string ext = boost::filesystem::extension( boost::filesystem::path( fileSequence->getFileName() ) );
		if ( ext.size() && ext[0] == '.' )
		{
			ext = ext.substr( 1, ext.size() - 1 );
		}

		if ( std::find( m_extensions.begin(), m_extensions.end(), ext ) == m_extensions.end() )
		{
			if ( reason )
			{
				*reason = "File sequence extension not valid";
			}
			return false;
		}
	}

	if ( mustExist() )
	{
		FileSequencePtr s = nullptr;
		ls( fileSequence->getFileName(), s, m_minSequenceSize );

		if ( !s )
		{
			if ( reason )
			{
				*reason = "File sequence does not exist";
			}
			return false;
		}
	}
	else if ( mustNotExist() )
	{
		FileSequencePtr s = nullptr;
		ls( fileSequence->getFileName(), s, m_minSequenceSize );

		if ( s )
		{
			if ( reason )
			{
				*reason = "File sequence already exists";
			}
			return false;
		}
	}

	return true;
}
void IECore::ls( const std::string &sequencePath, FileSequencePtr &sequence, size_t minSequenceSize )
{
	sequence = 0;
	boost::smatch matches;
	bool m = boost::regex_match( sequencePath, matches, FileSequence::fileNameValidator() );
	if ( !m )
	{
		return;
	}

	const std::string paddingStr( matches[2].first, matches[2].second );
	const unsigned padding = paddingStr.size();

 	std::vector< std::string > files;

	boost::filesystem::path dir = boost::filesystem::path( sequencePath ).branch_path();

	std::string baseSequencePath = boost::filesystem::path( sequencePath ).filename().string();

	const std::string::size_type first = baseSequencePath.find_first_of( '#' );
	assert( first != std::string::npos );
	const std::string prefix = baseSequencePath.substr( 0, first );

	const std::string::size_type last = baseSequencePath.find_last_of( '#' );
	assert( last != std::string::npos );
	const std::string suffix = baseSequencePath.substr( last + 1, baseSequencePath.size() - last - 1 );

	boost::filesystem::path dirToCheck( dir );
	if ( dirToCheck.string() == "" )
	{
		dirToCheck = ".";
	}

	boost::filesystem::directory_iterator end;

	for ( boost::filesystem::directory_iterator it( dirToCheck ); it != end; ++it )
	{
		const std::string fileName = it->path().filename().string();

		if ( fileName.size() >= std::min( prefix.size(), suffix.size() ) && fileName.substr( 0, prefix.size() ) == prefix && fileName.substr( fileName.size() - suffix.size(), suffix.size() ) == suffix )
		{
			files.push_back( ( dir / boost::filesystem::path( fileName ) ).string() );
		}
	}

	std::vector< FileSequencePtr > sequences;
	findSequences( files, sequences, minSequenceSize );

	for ( std::vector< FileSequencePtr >::iterator it = sequences.begin(); it != sequences.end() ; ++it )
	{
		if ( (*it)->getPadding() == padding )
		{
			sequence = *it;
			return;
		}
		// Also accept frame ranges with number of digits greater than the padding.
		if ( (*it)->getPadding() == 1 && (*it)->getFrameList()->typeId() == FrameRangeTypeId )
		{
			FrameRangePtr fr = staticPointerCast< FrameRange >( (*it)->getFrameList() );
			FrameList::Frame startFrame, endFrame;
			startFrame = fr->getStart();
			endFrame = fr->getEnd();
			// if goes through 0 then this is a no.
			if ( !(startFrame < 0 && endFrame > 0) )
			{
				unsigned int startDigits = 1;
				if ( startFrame > 0 )
					startDigits = static_cast<unsigned int>(floor(log10( static_cast<double>(abs(startFrame)) ))) + 1;

				if ( startDigits >= padding )
				{
					sequence = *it;
					sequence->setPadding( padding );
					return;
				}
			}
		}
	}
}
Пример #3
0
void IECore::ls( const std::string &sequencePath, FileSequencePtr &sequence, size_t minSequenceSize )
{
	sequence = nullptr;
	boost::smatch matches;
	bool m = boost::regex_match( sequencePath, matches, FileSequence::fileNameValidator() );
	if ( !m )
	{
		return;
	}

	const std::string paddingStr( matches[2].first, matches[2].second );
	const unsigned padding = paddingStr.size();

 	std::vector< std::string > files;

	boost::filesystem::path dir = boost::filesystem::path( sequencePath ).parent_path();

	std::string baseSequencePath = boost::filesystem::path( sequencePath ).PATH_TO_STRING;

	const std::string::size_type first = baseSequencePath.find_first_of( '#' );
	assert( first != std::string::npos );
	const std::string prefix = baseSequencePath.substr( 0, first );

	const std::string::size_type last = baseSequencePath.find_last_of( '#' );
	assert( last != std::string::npos );
	const std::string suffix = baseSequencePath.substr( last + 1, baseSequencePath.size() - last - 1 );

	boost::filesystem::path dirToCheck( dir );
	if ( dirToCheck.string() == "" )
	{
		dirToCheck = ".";
	}

	boost::filesystem::directory_iterator end;

	for ( boost::filesystem::directory_iterator it( dirToCheck ); it != end; ++it )
	{
		const std::string fileName = it->path().PATH_TO_STRING;

		if ( fileName.size() >= std::min( prefix.size(), suffix.size() ) && fileName.substr( 0, prefix.size() ) == prefix && fileName.substr( fileName.size() - suffix.size(), suffix.size() ) == suffix )
		{
			files.push_back( ( dir / boost::filesystem::path( fileName ) ).string() );
		}
	}

	std::vector< FileSequencePtr > sequences;
	findSequences( files, sequences, minSequenceSize );

	for ( std::vector< FileSequencePtr >::iterator it = sequences.begin(); it != sequences.end() ; ++it )
	{
		if ( (*it)->getPadding() == padding )
		{
			sequence = *it;
			return;
		}
		// Also accept frame ranges with number of digits greater than the padding.
		if ( (*it)->getPadding() == 1 )
		{
			FrameList::Frame startFrame, endFrame;

			if( FrameRange *fr = runTimeCast<FrameRange>( (*it)->getFrameList() ) )
			{
				// Can do a quick validation if the range is a FrameRange, by looking at the start and end only
				startFrame = fr->getStart();
				endFrame = fr->getEnd();
			}
			else
			{
				// Otherwise, have to get the full list
				std::vector<FrameList::Frame> frames;
				(*it)->getFrameList()->asList(frames);
				// I know that there will be at least one frame, since the file sequence was found
				startFrame = frames[ 0 ];
				endFrame = frames[ 0 ];
				for ( unsigned i=0; i < frames.size(); i++ )
				{
					if ( frames[ i ] < startFrame )
					{
						startFrame = frames[ i ];
					}
					else if ( frames[ i ] > endFrame )
					{
						endFrame = frames[ i ];
					}
				}
			}

			// if goes through 0 then this is a no.
			if ( !(startFrame < 0 && endFrame > 0) )
			{
				unsigned int startDigits = 1;
				if ( startFrame > 0 )
					startDigits = static_cast<unsigned int>(floor(log10( static_cast<double>(std::abs(startFrame)) ))) + 1;

				if ( startDigits >= padding )
				{
					sequence = *it;
					sequence->setPadding( padding );
					return;
				}
			}
		}
	}
}