void IfcPPReaderSTEP::loadModelFromString( std::string& content, shared_ptr<IfcPPModel>& target_model )
{
	progressTextCallback( L"Reading file..." );
	progressValueCallback( 0, "parse" );
	try
	{
		removeComments( content );
		readStreamHeader( content, target_model );
		readStreamData( content, target_model );
		target_model->resolveInverseAttributes();
		target_model->updateCache();
	}
	catch( IfcPPOutOfMemoryException& e)
	{
		throw e;
	}
	catch( IfcPPException& e )
	{
		messageCallback( e.what(), StatusCallback::MESSAGE_TYPE_ERROR, "" );
	}
	catch( std::exception& e )
	{
		messageCallback( e.what(), StatusCallback::MESSAGE_TYPE_ERROR, "" );
	}
	catch( ... )
	{
		messageCallback( "An error occured", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
	}
}
Beispiel #2
0
void ReaderSTEP::loadModelFromString( std::string& content, shared_ptr<BuildingModel>& targetModel)
{
	progressTextCallback( L"Reading file..." );
	progressValueCallback( 0, "parse" );
	try
	{
		removeComments( content );
		readHeader( content, targetModel);
		readData( content, targetModel);
		targetModel->resolveInverseAttributes();
		targetModel->updateCache();

		// currently generated IFC classes are IFC4, files with older versions are converted. So after loading, the schema is always IFC4
		targetModel->getIfcSchemaVersion().m_IFC_FILE_SCHEMA = L"IFC4";
		targetModel->getIfcSchemaVersion().m_ifc_file_schema_enum = BuildingModel::IFC4;
	}
	catch( OutOfMemoryException& e)
	{
		throw e;
	}
	catch( BuildingException& e )
	{
		messageCallback( e.what(), StatusCallback::MESSAGE_TYPE_ERROR, "" );
	}
	catch( std::exception& e )
	{
		messageCallback( e.what(), StatusCallback::MESSAGE_TYPE_ERROR, "" );
	}
	catch( ... )
	{
		messageCallback( "An error occurred", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
	}
}
void IfcPPReaderSTEP::loadModelFromFile( const std::wstring& file_path, shared_ptr<IfcPPModel>& target_model )
{
	// if file content needs to be loaded into a plain model, call resetModel() before loadModelFromFile
	
	std::wstring ext = file_path.substr( file_path.find_last_of( L"." ) + 1 );
	
	if( boost::iequals( ext, "ifc" ) )
	{
		// ok, nothing to do here
	}
	else if( boost::iequals( ext, "ifcXML" ) )
	{
		// TODO: implement xml reader
		messageCallback( "ifcXML not yet implemented", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	else if( boost::iequals( ext, "ifcZIP" ) )
	{
		// TODO: implement zip uncompress
		messageCallback( "ifcZIP not yet implemented", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	else
	{
		std::wstringstream strs;
		strs << "Unsupported file type: " << ext;
		messageCallback( strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}

	// open file
#ifdef _MSC_VER
	std::ifstream infile(file_path.c_str(), std::ifstream::in );
#else
	std::string file_path_str( file_path.begin(), file_path.end() );
	std::ifstream infile(file_path_str.c_str(), std::ifstream::in );
#endif
	if( !infile.is_open() )
	{
		std::wstringstream strs;
		strs << "Could not open file: " << file_path.c_str();
		messageCallback( strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}

	// get length of file content
	std::streampos file_size = infile.tellg();
	infile.seekg( 0, std::ios::end );
	file_size = infile.tellg() - file_size;
	infile.seekg( 0, std::ios::beg );

	// read file content into string
	std::string buffer( (int)file_size, '\0' );
	infile.read( &buffer[0], file_size );
	infile.close();

	loadModelFromString( buffer, target_model );
}
Beispiel #4
0
void IfcPPModel::insertEntity( shared_ptr<IfcPPEntity> e, bool overwrite_existing, bool warn_on_existing_entities )
{
	if( !e )
	{
		return;
	}
	int entity_id = e->m_id;
	if( entity_id < 0 )
	{
		int next_unused_id = getMaxUsedEntityId() + 1;
		e->m_id = next_unused_id;
		entity_id = next_unused_id;
	}

	auto it_find = m_map_entities.find( entity_id );
	if( it_find != m_map_entities.end() )
	{
		// key already exists
		if( overwrite_existing )
		{
			it_find->second = e;
		}
		else
		{
			if( warn_on_existing_entities )
			{
				messageCallback( "Entity already in model", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__, e.get() );
			}
		}
	}
	else
	{
		// the key does not exist in the map
		m_map_entities.insert( it_find, map_t<int,shared_ptr<IfcPPEntity> >::value_type( entity_id, e ) );
	}
#ifdef _DEBUG
	auto product = dynamic_pointer_cast<IfcProduct>( e );
	if( product )
	{
		if( !product->m_GlobalId )
		{
			messageCallback( "IfcProduct->m_GlobalId not set", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__, product.get() );
			return;
		}
		if( product->m_GlobalId->m_value.length() < 22 )
		{
			messageCallback( "IfcProduct->m_GlobalId.length() < 22", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__, product.get() );
		}
	}
#endif

	// TODO: if type is IfcRoot (or subtype), and GlobalID not set, create one
}
Beispiel #5
0
void IfcPPModel::removeEntity( shared_ptr<IfcPPEntity> e )
{
	if( !e )
	{
		messageCallback( "Entity not valid", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__, e.get() );
		return;
	}
	int remove_id = e->m_id;
	auto it_find = m_map_entities.find(remove_id);
	if( it_find == m_map_entities.end() )
	{
		messageCallback( "Entity not found in model", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__, e.get() );
		return;
	}
	shared_ptr<IfcPPEntity> entity_found = it_find->second;
	entity_found->unlinkFromInverseCounterparts();
	IfcPPEntity* entity_remove_ptr = e.get();
		
	if( entity_found.use_count() > 1 )
	{
		// find references to this entity and remove them
		std::vector<std::pair<std::string, shared_ptr<IfcPPObject> > > vec_attributes_inverse;
		entity_found->getAttributesInverse( vec_attributes_inverse );
		for( size_t ii = 0; ii < vec_attributes_inverse.size(); ++ii )
		{
			shared_ptr<IfcPPObject>& attribute_inverse = vec_attributes_inverse[ii].second;

			shared_ptr<IfcPPEntity> attribute_inverse_entity = dynamic_pointer_cast<IfcPPEntity>( attribute_inverse );
			if( attribute_inverse_entity )
			{
				std::vector<std::pair<std::string, shared_ptr<IfcPPObject> > > vec_attributes;
				attribute_inverse_entity->getAttributes( vec_attributes );
				for( size_t jj = 0; jj < vec_attributes.size(); ++jj )
				{
					shared_ptr<IfcPPObject>& attribute = vec_attributes[jj].second;
					if( attribute.get() == entity_remove_ptr )
					{
						vec_attributes.erase( vec_attributes.begin() + jj );
						if( jj > 0 )
						{
							--jj;
						}
					}
				}
			}
		}
	}
	m_map_entities.erase( it_find );
}
Beispiel #6
0
 void System::message(CSOUND *csound, const char *format, va_list valist)
 {
   if (logfile) {
     vfprintf(logfile, format, valist);
     fflush(logfile);
   }
   if(messageCallback) {
     messageCallback(csound, messageLevel, format, valist);
   }
   else {
     vfprintf(stderr, format, valist);
   }
 }
Beispiel #7
0
void IfcPPModel::updateCache()
{
	bool found_project = false;
	bool found_geom_context = false;

	shared_ptr<IfcProject> keep_project = m_ifc_project;
	m_ifc_project.reset();

	// try to find IfcProject and IfcGeometricRepresentationContext
	for( auto it=m_map_entities.begin(); it!=m_map_entities.end(); ++it )
	{
		shared_ptr<IfcPPEntity> obj = it->second;
		if( dynamic_pointer_cast<IfcProject>(obj) )
		{
			if( m_ifc_project )
			{
				messageCallback( "More than one IfcProject in model", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__, m_ifc_project.get() );
			}
			m_ifc_project = dynamic_pointer_cast<IfcProject>( obj );
			found_project = true;
			if( found_geom_context )
			{
				break;
			}
		}
		else if( dynamic_pointer_cast<IfcGeometricRepresentationContext>(obj) )
		{
			auto context = dynamic_pointer_cast<IfcGeometricRepresentationContext>( obj );
			if( context->m_CoordinateSpaceDimension )
			{
				if( context->m_CoordinateSpaceDimension->m_value == 3 )
				{
					m_geom_context_3d = context;
					found_geom_context = true;
					if( found_project )
					{
						break;
					}
				}
			}
		}
	}

	if( found_project )
	{
		m_unit_converter->setIfcProject( m_ifc_project );
	}
}
Beispiel #8
0
int ngrest_server_dispatch(ngrest_server_request* request, ngrest_mod_callbacks callbacks)
{
    try {
        ngrest::MessageContext context;

        context.pool = pooler.obtain();
        PoolRecycler recycler(context.pool);

        context.engine = &engine;
        context.transport = &transport;
        context.request = context.pool->alloc<ngrest::HttpRequest>();
        context.response = context.pool->alloc<ngrest::HttpResponse>();
        context.response->poolBody = pooler.obtain(65536); // 64 KB chunks for output buffer

        ngrest::HttpRequest* httpRequest = static_cast<ngrest::HttpRequest*>(context.request);
        ngrest::HttpResponse* httpResponse = static_cast<ngrest::HttpResponse*>(context.response);

        ModMessageCallback messageCallback(httpResponse);
        context.callback = &messageCallback;

        httpRequest->setMethod(request->method);
        httpRequest->path = request->uri;
        httpRequest->clientHost = request->clientHost;
        httpRequest->clientPort = request->clientPort;

        HeaderIterateContext itCtx = {
            httpRequest,
            nullptr,
            &context
        };

        callbacks.iterate_request_headers(request->req, &itCtx, [](void* context, const char* name, const char* value) {
            HeaderIterateContext* itCtx = reinterpret_cast<HeaderIterateContext*>(context);
            ngrest::Header* header = itCtx->context->pool->alloc<ngrest::Header>();

            char* headerName = itCtx->context->pool->putCString(name, true);
            toLowerCase(headerName);

            header->name = headerName;
            header->value = value;
            if (itCtx->lastHeader == nullptr) {
                itCtx->httpRequest->headers = header;
            } else {
                itCtx->lastHeader->next = header;
            }
            itCtx->lastHeader = header;
            return 1;
        });

        if (request->hasBody) {
            ngrest::MemPool* poolRequest = pooler.obtain(65536);
            PoolRecycler recycler(poolRequest);
            if (request->bodySize > 0)
                poolRequest->reserve(request->bodySize + 1); // '\0'

            const int64_t chunkSize = poolRequest->getChunkSize();
            int64_t bufferSize = chunkSize;
            int64_t read = 0;
            int64_t total = 0;
            char* buffer = poolRequest->grow(chunkSize);
            for (;;) {
                read = callbacks.read_block(request->req, buffer, bufferSize);
                if (read < 0) {
                    callbacks.write_block(request->req, "Failed to read block!", 21);
                    return 500;
                }

                if (!request->bodySize && !read) // eof while body size unknown. stopping read
                    break;

                buffer += read;
                bufferSize -= read;
                if (bufferSize == 0) {
                    buffer = poolRequest->grow(chunkSize);
                    bufferSize = chunkSize;
                }
                total += read;

                if (request->bodySize && total >= request->bodySize)
                    break;  // according to request->bodySize the whole request is read
            }

            poolRequest->shrinkLastChunk(bufferSize);

            ngrest::MemPool::Chunk* body = poolRequest->flatten();
            context.request->body = body->buffer;
            context.request->bodySize = body->size;

            engine.dispatchMessage(&context); // poolRequest will be recycled ouside this scope
        } else {
            engine.dispatchMessage(&context);
        }

        for (const ngrest::Header* header = httpResponse->headers; header; header = header->next) {
            if (!strcmp(header->name, "Content-Type")) {
                callbacks.set_content_type(request->req, header->value);
            } else {
                callbacks.set_response_header(request->req, header->name, header->value);
            }
        }

        ngrest_server_write_response(request, callbacks, httpResponse->poolBody);

        callbacks.finalize_response(request->req, httpResponse->statusCode);

        return 0;
    } catch (const std::exception& e) {
        const char* error = e.what();
        ngrest::LogWarning() << error;
        callbacks.write_block(request->req, error, strlen(error));
    } catch (...) {
        ngrest::LogWarning() << "Unknown exception raised";
        callbacks.write_block(request->req, "Internal server error", 22);
    }

    return 500;
}
void IfcPPReaderSTEP::readStreamData(	std::string& read_in, const IfcPPModel::IfcPPSchemaVersion& ifc_version, boost::unordered_map<int,shared_ptr<IfcPPEntity> >& target_map )
{
	std::string current_numeric_locale(setlocale(LC_NUMERIC, nullptr));
	setlocale(LC_NUMERIC,"C");

	if( ifc_version.m_ifc_file_schema_enum  == IfcPPModel::IFC_VERSION_UNDEFINED || ifc_version.m_ifc_file_schema_enum == IfcPPModel::IFC_VERSION_UNKNOWN )
	{
		std::wstring error_message;
		error_message.append( L"Unsupported IFC version: " );
		error_message.append( ifc_version.m_IFC_FILE_SCHEMA );
		messageCallback( error_message, StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		progressValueCallback(0.0, "parse");
		return;
	}
	
	if( read_in.size() == 0 )
	{
		return;
	}
	messageCallback( std::wstring( L"Detected IFC version: ") + ifc_version.m_IFC_FILE_SCHEMA, StatusCallback::MESSAGE_TYPE_GENERAL_MESSAGE, "" );

	std::stringstream err;
	std::vector<std::string> step_lines;

	std::vector<std::pair<std::string, shared_ptr<IfcPPEntity> > > vec_entities;
	try
	{
		splitIntoStepLines( read_in, step_lines );
		read_in.clear(); // the input string is not needed any more
		const size_t num_lines = step_lines.size();
		vec_entities.resize( num_lines );
		readStepLines( step_lines, vec_entities );
	}
	catch( UnknownEntityException& e )
	{
		std::string unknown_keyword = e.m_keyword;
		err << __FUNC__ << ": unknown entity: " << unknown_keyword.c_str() << std::endl;
	}
	catch( IfcPPOutOfMemoryException& e)
	{
		throw e;
	}
	catch( IfcPPException& e )
	{
		err << e.what();
	}
	catch(std::exception& e)
	{
		err << e.what();
	}
	catch(...)
	{
		err << __FUNC__ << ": error occurred" << std::endl;
	}
	step_lines.clear();

	// copy entities into map so that they can be found during entity attribute initialization
	for( size_t ii_entity = 0; ii_entity < vec_entities.size(); ++ii_entity )
	{
		std::pair<std::string, shared_ptr<IfcPPEntity> >& entity_read_object = vec_entities[ii_entity];
		shared_ptr<IfcPPEntity> entity = entity_read_object.second;

		if( entity ) // skip aborted entities
		{
			target_map.insert( std::make_pair( entity->m_id, entity ) );
		}
	}

	try
	{
		readEntityArguments( ifc_version, vec_entities, target_map );
	}
	catch( IfcPPOutOfMemoryException& e)
	{
		throw e;
	}
	catch( IfcPPException& e )
	{
		err << e.what();
	}
	catch(std::exception& e)
	{
		err << e.what();
	}
	catch(...)
	{
		err << __FUNC__ << ": error occurred" << std::endl;
	}

	setlocale(LC_NUMERIC,current_numeric_locale.c_str());
	if( err.tellp() > 0 )
	{
		messageCallback( err.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
	}
}
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__ );
	}
}
void IfcPPReaderSTEP::readSingleStepLine( const std::string& line, std::pair<std::string, shared_ptr<IfcPPEntity> >& target_read_object )
{
	if( line.size() < 1 )
	{
		return;
	}
	char* stream_pos = (char*)line.c_str();
	if( *stream_pos != '#' )
	{
		return;
	}

	// need at least one integer here
	++stream_pos;
	if( *stream_pos == '\0' )
	{
		return;
	}

	if( !isdigit( *stream_pos ) )
	{
		return;
	}
	char* begin_id = stream_pos;

	// proceed until end of integer
	++stream_pos;
	while( *stream_pos != '\0' )
	{
		if( isdigit( *stream_pos ) )
		{
			++stream_pos;
		}
		else
		{
			break;
		}
	}

	const int entity_id = atoi( std::string( begin_id, stream_pos - begin_id ).c_str() );

	// skip whitespace
	while( isspace( *stream_pos ) ) { ++stream_pos; }

	// next char after whitespace needs to be an "="
	if( *stream_pos != '=' )
	{
		// print error
		return;
	}
	++stream_pos;

	// skip whitespaces
	while( isspace( *stream_pos ) ) { ++stream_pos; }

	// extract keyword
	const char* keyword_begin = stream_pos;
	while( isalnum( *stream_pos ) ) { ++stream_pos; }

	std::string keyword( keyword_begin, stream_pos - keyword_begin );
	std::transform( keyword.begin(), keyword.end(), keyword.begin(), toupper );

	// proceed to '('
	if( *stream_pos != '(' )
	{
		while( *stream_pos != '\0' )
		{
			if( *stream_pos == '(' )
			{
				break;
			}
			++stream_pos;
		}
	}

	if( keyword.size() == 0 )
	{
		std::stringstream strs;
		strs << "Could not read STEP line: " << line.c_str();
		messageCallback( strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	std::map<std::string,IfcPPEntityEnum>::iterator it_entity_enum = map_string2entity_enum.find( keyword );
	if( it_entity_enum == map_string2entity_enum.end() )
	{
		throw UnknownEntityException( keyword );
	}
	else
	{
		IfcPPEntityEnum entity_enum = it_entity_enum->second;
		shared_ptr<IfcPPEntity> obj( createIfcPPEntity( entity_enum ) );
		if( obj )
		{
			obj->m_id = entity_id;
			obj->m_entity_enum = entity_enum;
			target_read_object.second = obj;
			size_t sub_length = line.size() - ( stream_pos - line.c_str() );
			std::string entity_arg( stream_pos, sub_length );
			target_read_object.first.assign( entity_arg.begin(), entity_arg.end() );
		}
		else
		{
			std::stringstream strs;
			strs << "Could not create object of type " << keyword << ", entity id " << entity_id;
			messageCallback( strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		}
	}
}
Beispiel #12
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__ );
	}
}
Beispiel #13
0
void ReaderSTEP::readSingleStepLine( const std::string& line, std::pair<std::string, shared_ptr<BuildingEntity> >& target_read_object )
{
	if( line.empty() )
	{
		return;
	}
	char* stream_pos = const_cast<char*>(line.c_str());
	if( *stream_pos != '#' )
	{
		return;
	}

	// need at least one integer here
	++stream_pos;
	if( *stream_pos == '\0' )
	{
		return;
	}

	if( !isdigit( *stream_pos ) )
	{
		return;
	}
	char* begin_id = stream_pos;

	// proceed until end of integer
	++stream_pos;
	while( *stream_pos != '\0' )
	{
		if( isdigit( *stream_pos ) )
		{
			++stream_pos;
		}
		else
		{
			break;
		}
	}

	const int entity_id = atoi( std::string( begin_id, stream_pos - begin_id ).c_str() );

	// skip whitespace
	while( isspace( *stream_pos ) ) { ++stream_pos; }

	// next char after whitespace needs to be an "="
	if( *stream_pos != '=' )
	{
		// print error
		return;
	}
	++stream_pos;

	// skip whitespaces
	while( isspace( *stream_pos ) ) { ++stream_pos; }

	// extract keyword
	const char* entity_name_begin = stream_pos;
	while( isalnum( *stream_pos ) ) { ++stream_pos; }

	std::string entity_name_upper( entity_name_begin, stream_pos - entity_name_begin );
	std::transform( entity_name_upper.begin(), entity_name_upper.end(), entity_name_upper.begin(), toupper );

	// proceed to '('
	if( *stream_pos != '(' )
	{
		while( *stream_pos != '\0' )
		{
			if( *stream_pos == '(' )
			{
				break;
			}
			++stream_pos;
		}
	}

	if( entity_name_upper.empty() )
	{
		std::stringstream strs;
		strs << "Could not read STEP line: " << line.c_str();
		messageCallback( strs.str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	
	shared_ptr<BuildingEntity> obj( EntityFactory::createEntityObject( entity_name_upper ) );
	if( obj )
	{
		obj->m_entity_id = entity_id;
		target_read_object.second = obj;
		size_t sub_length = line.size() - (stream_pos - line.c_str());
		std::string entity_arg( stream_pos, sub_length );
		target_read_object.first.assign( entity_arg.begin(), entity_arg.end() );
	}
	else
	{
		throw UnknownEntityException( entity_name_upper );
	}
}
Beispiel #14
0
void ReaderSTEP::loadModelFromFile( const std::wstring& filePath, shared_ptr<BuildingModel>& targetModel )
{
	// if file content needs to be loaded into a plain model, call resetModel() before loadModelFromFile
	size_t posDot = filePath.find_last_of(L".");
	if( filePath.size() < posDot + 3 || posDot > filePath.size() )
	{
		messageCallback("not an .ifc file", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__);
		return;
	}
	std::wstring ext = filePath.substr(posDot + 1);
	
	if( boost::iequals( ext, "ifc" ) )
	{
		// ok, nothing to do here
	}
	else if( boost::iequals( ext, "ifcXML" ) )
	{
		// TODO: implement xml reader
		messageCallback( "ifcXML not yet implemented", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	else if( boost::iequals( ext, "ifcZIP" ) || boost::iequals(ext, "zip") )
	{
		messageCallback( "ifcZIP not implemented, see www.ifcquery.com for details", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}
	else
	{
		std::wstringstream strs;
		strs << "Unsupported file type: " << ext;
		messageCallback( strs.str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}

	// open file
	if( !(setlocale(LC_ALL, "en-US") || setlocale(LC_ALL, "en_us.UTF-8") ||  setlocale(LC_ALL, "en_US.utf8")))
	{
		std::wstringstream strs;
		strs << L"setlocale failed" << std::endl;
		messageCallback(strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__);
		return;
	}

	char* buf = nullptr;
	size_t len = std::wcstombs(buf, filePath.c_str(), 0);
	buf = new char[len + 1];
	std::wcstombs(buf, filePath.c_str(), (len + 1) * 6);
	std::string filePathStr(buf);
	delete[] buf;
	std::ifstream infile(filePathStr.c_str(), std::ifstream::in);
	
	if( !infile.is_open() )
	{
		std::wstringstream strs;
		strs << "Could not open file: " << filePath.c_str();
		messageCallback( strs.str().c_str(), StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__ );
		return;
	}

	// get length of file content
	std::streampos file_size = infile.tellg();
	infile.seekg( 0, std::ios::end );
	file_size = infile.tellg() - file_size;
	infile.seekg( 0, std::ios::beg );

	// read file content into string
	std::string buffer( (int)file_size, '\0' );
	infile.read( &buffer[0], file_size );
	infile.close();

	size_t file_header_start = buffer.find("HEADER;");
	size_t file_header_end = buffer.find("ENDSEC;");
	if( file_header_start == std::string::npos || file_header_end == std::string::npos )
	{
		messageCallback("Not a valid IFC file, might be zip archive, see www.ifcquery.com for details", StatusCallback::MESSAGE_TYPE_ERROR, __FUNC__);
		return;
	}

	loadModelFromString( buffer, targetModel);
}
void UnitConverter::setIfcProject( shared_ptr<IfcProject> project )
{
	resetComplete();

	if( !project->m_UnitsInContext )
	{
		messageCallback( "IfcProject.UnitsInContext not defined", StatusCallback::MESSAGE_TYPE_WARNING, __FUNC__ );
		return;
	}

	shared_ptr<IfcUnitAssignment> unit_assignment = project->m_UnitsInContext;
	std::vector<shared_ptr<IfcUnit> >& vec_units = unit_assignment->m_Units;
	for( size_t ii = 0; ii < vec_units.size(); ++ii )
	{
		shared_ptr<IfcUnit> unit = vec_units[ii];
		if( !unit )
		{
			continue;
		}
		shared_ptr<IfcSIUnit> si_unit = dynamic_pointer_cast<IfcSIUnit>( unit );
		if( si_unit )
		{
			//	example: #10 = IFCSIUNIT( *, .LENGTHUNIT., $, .METRE. );
			//  shared_ptr<IfcDimensionalExponents>	m_Dimensions;
			//  shared_ptr<IfcUnitEnum>				m_UnitType;
			//	shared_ptr<IfcSIPrefix>				m_Prefix;					//optional
			//	shared_ptr<IfcSIUnitName>			m_Name;

			shared_ptr<IfcUnitEnum> unit_type = si_unit->m_UnitType;
			shared_ptr<IfcSIUnitName> unit_name = si_unit->m_Name;

			if( unit_type )
			{
				if( unit_type->m_enum == IfcUnitEnum::ENUM_LENGTHUNIT )
				{
					if( unit_name )
					{
						if( unit_name->m_enum == IfcSIUnitName::ENUM_METRE )
						{
							m_length_unit_factor = 1.0;
							m_length_unit_found = true;
						}
					}

					if( si_unit->m_Prefix )
					{
						m_loaded_prefix = si_unit->m_Prefix;
						if( m_prefix_map.find( si_unit->m_Prefix->m_enum ) != m_prefix_map.end() )
						{
							m_length_unit_factor = m_prefix_map[si_unit->m_Prefix->m_enum];
							m_length_unit_found = true;
						}
					}
				}
				else if( unit_type->m_enum == IfcUnitEnum::ENUM_AREAUNIT )
				{
					// TODO: implement
				}
				else if( unit_type->m_enum == IfcUnitEnum::ENUM_VOLUMEUNIT )
				{
					// TODO: implement
				}
				else if( unit_type->m_enum == IfcUnitEnum::ENUM_PLANEANGLEUNIT )
				{
					if( unit_name )
					{
						if( unit_name->m_enum == IfcSIUnitName::ENUM_RADIAN )
						{
							m_angular_unit = RADIAN;
							m_plane_angle_factor = 1.0;
						}
					}
				}
			}
			continue;
		}


		shared_ptr<IfcConversionBasedUnit> conversion_based_unit = dynamic_pointer_cast<IfcConversionBasedUnit>( unit );
		if( conversion_based_unit )
		{
			shared_ptr<IfcMeasureWithUnit> conversion_factor = conversion_based_unit->m_ConversionFactor;
			if( conversion_factor )
			{
				shared_ptr<IfcUnit> unit_component = conversion_factor->m_UnitComponent;
				if( unit_component )
				{
					shared_ptr<IfcSIUnit> unit_component_si = dynamic_pointer_cast<IfcSIUnit>( unit_component );
					if( unit_component_si )
					{
						shared_ptr<IfcUnitEnum> type = unit_component_si->m_UnitType;
						if( type )
						{
							if( type->m_enum == IfcUnitEnum::ENUM_LENGTHUNIT )
							{
								shared_ptr<IfcValue> length_value_select = conversion_factor->m_ValueComponent;
								if( length_value_select )
								{
									shared_ptr<IfcRatioMeasure> ratio_measure = dynamic_pointer_cast<IfcRatioMeasure>( length_value_select );
									if( ratio_measure )
									{
										m_length_unit_factor = ratio_measure->m_value;
										m_length_unit_found = true;
									}
									shared_ptr<IfcLengthMeasure> length_measure = dynamic_pointer_cast<IfcLengthMeasure>( length_value_select );
									if( length_measure )
									{
										m_length_unit_factor = length_measure->m_value;
										m_length_unit_found = true;
									}
								}

								if( boost::iequals( conversion_based_unit->m_Name->m_value.c_str(), L"INCH" ) )
								{
									m_length_unit_factor = 25.4*0.001; // 1 unit is 25.4 mm
									m_length_unit_found = true;
								}
								else if( boost::iequals( conversion_based_unit->m_Name->m_value.c_str(), L"FOOT" ) )
								{
									m_length_unit_factor = 304.8*0.001; // 1 unit is 304.8 mm
									m_length_unit_found = true;
								}
								else if( boost::iequals( conversion_based_unit->m_Name->m_value.c_str(), L"YARD" ) )
								{
									m_length_unit_factor = 914*0.001; // 1 unit is 914 mm
									m_length_unit_found = true;
								}
								else if( boost::iequals( conversion_based_unit->m_Name->m_value.c_str(), L"MILE" ) )
								{
									m_length_unit_factor = 1609*0.001; // 1 unit is 1609 mm
									m_length_unit_found = true;
								}
								
							}
							else if( type->m_enum == IfcUnitEnum::ENUM_PLANEANGLEUNIT )
							{
								shared_ptr<IfcValue> plane_angle_value = conversion_factor->m_ValueComponent;
								if( plane_angle_value )
								{
									if( dynamic_pointer_cast<IfcPlaneAngleMeasure>( plane_angle_value ) )
									{
										shared_ptr<IfcPlaneAngleMeasure> plane_angle_measure = dynamic_pointer_cast<IfcPlaneAngleMeasure>( plane_angle_value );
										m_plane_angle_factor = plane_angle_measure->m_value;
										m_angular_unit = CONVERSION_BASED;
									}
									else if( dynamic_pointer_cast<IfcRatioMeasure>( plane_angle_value ) )
									{
										shared_ptr<IfcRatioMeasure> plane_angle_measure = dynamic_pointer_cast<IfcRatioMeasure>( plane_angle_value );
										m_plane_angle_factor = plane_angle_measure->m_value;
										m_angular_unit = CONVERSION_BASED;
									}
									else if( conversion_based_unit->m_Name )
									{
										if( boost::iequals( conversion_based_unit->m_Name->m_value.c_str(), L"DEGREE" ) )
										{
											m_angular_unit = DEGREE;
											m_plane_angle_factor = M_PI / 180.0;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}