void IfcPPReaderSTEP::readStreamHeader( const std::string& read_in, shared_ptr<IfcPPModel>& target_model )
{
	if( !target_model )
	{
		throw IfcPPException( "Model not set.", __FUNC__ );
	}

	target_model->m_file_header = L"";
	target_model->m_IFC_FILE_DESCRIPTION = L"";
	target_model->m_IFC_FILE_NAME = L"";
	
	size_t file_header_start = read_in.find("HEADER;");
	size_t file_header_end = read_in.find("ENDSEC;");
	if( file_header_start == std::string::npos || file_header_end == std::string::npos )
	{
		return;
	}

	IfcPPModel::IfcPPSchemaVersion schema_version( L"", IfcPPModel::IFC_VERSION_UNDEFINED );
	target_model->setIfcSchemaVersion( schema_version );
	file_header_start += 7;
	std::string file_header = read_in.substr( file_header_start, file_header_end - file_header_start );
	std::vector<std::string> vec_header;
	std::vector<std::wstring> vec_header_wstr;
	vec_header.push_back( file_header );
	decodeArgumentStrings( vec_header, vec_header_wstr );
	
	std::wstring file_header_wstr;
	if( vec_header_wstr.size() > 0 )
	{
		file_header_wstr = vec_header_wstr[0];
	}
	target_model->setFileHeader( file_header_wstr );
	
	std::vector<std::wstring> vec_header_lines;
	// split into lines
	wchar_t* stream_pos = &file_header_wstr[0];
	wchar_t* last_token = stream_pos;

	while( *stream_pos != '\0' )
	{
		if( *stream_pos == '\'' )
		{
			findEndOfWString( stream_pos );
			continue;
		}

		if( *stream_pos == ';' )
		{
			wchar_t* begin_line = last_token;
			std::wstring single_step_line( begin_line, stream_pos-last_token );
			vec_header_lines.push_back( single_step_line );

			++stream_pos;
			while(isspace(*stream_pos)){++stream_pos;}
			last_token = stream_pos;

			continue;
		}
		++stream_pos;
	}

	for( size_t i=0; i<vec_header_lines.size(); ++i )
	{
		std::wstring header_line = vec_header_lines[i];

		if( header_line.find(L"FILE_DESCRIPTION") != std::string::npos )
		{
			target_model->setFileDescription( header_line );
			continue;
		}

		if( header_line.find(L"FILE_NAME") != std::string::npos )
		{
			target_model->setFileName( header_line );
			continue;
		}

		if( header_line.find(L"FILE_SCHEMA") != std::string::npos )
		{
			size_t file_schema_begin = header_line.find(L"FILE_SCHEMA") + 11;
			target_model->getIfcSchemaVersion().m_IFC_FILE_SCHEMA = header_line;

			std::wstring file_schema_args = header_line.substr( 11 );
			size_t find_whitespace = file_schema_args.find(L" ");
			while(find_whitespace != std::string::npos){ file_schema_args.erase(find_whitespace,1); find_whitespace = file_schema_args.find(L" "); }
			
			if( file_schema_args.at(0) =='(' && file_schema_args.at(file_schema_args.size()-1) ==')' )
			{
				file_schema_args = file_schema_args.substr( 1, file_schema_args.size()-2 );
			}
			if( file_schema_args.at(0) =='(' && file_schema_args.at(file_schema_args.size()-1) ==')' )
			{
				file_schema_args = file_schema_args.substr( 1, file_schema_args.size()-2 );
			}
			if( file_schema_args.at(0) =='\'' && file_schema_args.at(file_schema_args.size()-1) =='\'' )
			{
				file_schema_args = file_schema_args.substr( 1, file_schema_args.size()-2 );
			}
				
			if( file_schema_args.substr(0,6).compare(L"IFC2X2") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC2X2;
			}
			else if( file_schema_args.substr(0,6).compare(L"IFC2X3") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC2X3;
			}
			else if( file_schema_args.substr(0,6).compare(L"IFC2X4") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC2X4;
			}
			else if( file_schema_args.substr(0,5).compare(L"IFC2X") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC2X;
			}
			else if( file_schema_args.compare(L"IFC4") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC4;
			}
			else if( file_schema_args.compare(L"IFC4RC4") == 0 )
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC4;
			}
			else
			{
				target_model->m_ifc_schema_version.m_ifc_file_schema_enum = IfcPPModel::IFC_VERSION_UNDEFINED;
			}
		}
	}
}
void IfcPPReaderSTEP::readEntityArguments( const IfcPPModel::IfcPPSchemaVersion& ifc_version,
	const std::vector<std::pair<std::string, shared_ptr<IfcPPEntity> > >& vec_entities, 
	const boost::unordered_map<int,shared_ptr<IfcPPEntity> >& map_entities  )
{
	// second pass, now read arguments
	// every object can be initialized independently in parallel
	const int num_objects = (int)vec_entities.size();
	std::stringstream err;

	// set progress
	double progress = 0.3;
	progressValueCallback( progress, "parse" );
	double last_progress = 0.3;
	const boost::unordered_map<int,shared_ptr<IfcPPEntity> >* map_entities_ptr = &map_entities;
	const std::vector<std::pair<std::string, shared_ptr<IfcPPEntity> > >* vec_entities_ptr = &vec_entities;

#ifdef IFCPP_OPENMP
#pragma omp parallel firstprivate(num_objects) shared(map_entities_ptr,vec_entities_ptr)
#endif
	{
		const boost::unordered_map<int,shared_ptr<IfcPPEntity> > &map_entities_ptr_local = *map_entities_ptr;

#ifdef IFCPP_OPENMP
#pragma omp for schedule(dynamic, 100)
#endif
		for( int i=0; i<num_objects; ++i )
		{
			const std::pair<std::string, shared_ptr<IfcPPEntity> >& entity_read_object = (*vec_entities_ptr)[i];
			const shared_ptr<IfcPPEntity> entity = entity_read_object.second;
			if( !entity )
			{
				continue;
			}
			const std::string& argument_str = entity_read_object.first;
			std::vector<std::string> arguments;
			std::vector<std::wstring> arguments_w;
			tokenizeEntityArguments( argument_str, arguments );

			// character decoding:
			decodeArgumentStrings( arguments, arguments_w );

			if( ifc_version.m_ifc_file_schema_enum != IfcPPModel::IFC4 )
			{
				if( ifc_version.m_ifc_file_schema_enum != IfcPPModel::IFC_VERSION_UNDEFINED && ifc_version.m_ifc_file_schema_enum != IfcPPModel::IFC_VERSION_UNKNOWN )
				{
					IfcPPEntityEnum entity_enum = entity->m_entity_enum;
					applyBackwardCompatibility( ifc_version, entity_enum, arguments_w );
				}
			}

			try
			{
				entity->readStepArguments( arguments_w, map_entities_ptr_local );
			}
			catch( std::exception& e )
			{
#ifdef IFCPP_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_id << "=" << entity->className() << ": " << e.what();
			}
			catch( std::exception* e )
			{
#ifdef IFCPP_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_id << "=" << entity->className() << ": " << e->what();
			}
			catch(...)
			{
#ifdef IFCPP_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_id << "=" << entity->className() << " readStepData: error occurred" << std::endl;
			}

			if( i%10 == 0 )
			{
				progress = 0.3 + 0.6*double(i)/double(num_objects);
				if( progress - last_progress > 0.03 )
				{
#ifdef IFCPP_OPENMP
					if( omp_get_thread_num() == 0 )
#endif
					{
						progressValueCallback( progress, "parse" );
						last_progress = progress;
					}
				}
			}
		}
	}   // implicic barrier
	
	if( err.tellp() > 0 )
	{
		messageCallback( err.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
	}
}
Beispiel #3
0
void ReaderSTEP::readEntityArguments( const BuildingModel::SchemaVersion& ifc_version,
	const std::vector<std::pair<std::string, shared_ptr<BuildingEntity> > >& vec_entities,  const std::map<int,shared_ptr<BuildingEntity> >& map_entities  )
{
	// second pass, now read arguments
	// every object can be initialized independently in parallel
	const int num_objects = static_cast<int>(vec_entities.size());
	std::stringstream err;

	// set progress
	double progress = 0.3;
	progressValueCallback( progress, "parse" );
	double last_progress = 0.3;
	const std::map<int,shared_ptr<BuildingEntity> >* map_entities_ptr = &map_entities;
	const std::vector<std::pair<std::string, shared_ptr<BuildingEntity> > >* vec_entities_ptr = &vec_entities;

	bool canceled = isCanceled();

#ifdef ENABLE_OPENMP
#pragma omp parallel firstprivate(num_objects) shared(map_entities_ptr,vec_entities_ptr)
#endif
	{
		const std::map<int,shared_ptr<BuildingEntity> > &map_entities_ptr_local = *map_entities_ptr;

#ifdef ENABLE_OPENMP
#pragma omp for schedule(dynamic, 100)
#endif
		for( int i=0; i<num_objects; ++i )
		{
			if ( canceled )
			{
				continue;
			}
			
			const std::pair<std::string, shared_ptr<BuildingEntity> >& entity_read_object = (*vec_entities_ptr)[i];
			const shared_ptr<BuildingEntity> entity = entity_read_object.second;
			if( !entity )
			{
				continue;
			}
			const std::string& argument_str = entity_read_object.first;
			std::vector<std::string> arguments;
			std::vector<std::wstring> arguments_w;
			tokenizeEntityArguments( argument_str, arguments );

			// character decoding:
			decodeArgumentStrings( arguments, arguments_w );

			if( ifc_version.m_ifc_file_schema_enum != BuildingModel::IFC4 )
			{
				size_t num_expected_arguments = entity->getNumAttributes();
				if( num_expected_arguments != arguments_w.size() )
				{
					while( arguments_w.size() > num_expected_arguments ) { arguments_w.pop_back(); }
					while( arguments_w.size() < num_expected_arguments ) { arguments_w.emplace_back( L"$" ); }
				}
			}

			if( std::string( entity->className() ).compare( "IfcColourRGB" ) == 0 )
			{
				if( arguments_w.size() < 4 )
				{
					arguments_w.insert( arguments_w.begin(), L"$" );
				}
			}

			try
			{
				entity->readStepArguments( arguments_w, map_entities_ptr_local );
			}
			catch( std::exception& e )
			{
#ifdef ENABLE_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_entity_id << "=" << entity->className() << ": " << e.what();
			}
			catch( std::exception* e )
			{
#ifdef ENABLE_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_entity_id << "=" << entity->className() << ": " << e->what();
			}
			catch(...)
			{
#ifdef ENABLE_OPENMP
#pragma omp critical
#endif
				err << "#" << entity->m_entity_id << "=" << entity->className() << " readStepData: error occurred" << std::endl;
			}

			if( i%10 == 0 )
			{
				progress = 0.3 + 0.6*double(i)/double(num_objects);
				if( progress - last_progress > 0.03 )
				{
#ifdef ENABLE_OPENMP
					if( omp_get_thread_num() == 0 )
#endif
					{
						progressValueCallback( progress, "parse" );
						last_progress = progress;

						if ( isCanceled() )
						{
							canceledCallback();
#ifdef ENABLE_OPENMP
							canceled = true;
#pragma omp flush(canceled)
#else
							break; // If we're not using OpenMP, we can safely break the loop
#endif
						}
					}
				}
			}
		}
	}   // implicic barrier
	
	if( err.tellp() > 0 )
	{
		messageCallback( err.str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
	}
}