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__ ); } }
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 ); }
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 }
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 ); }
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); } }
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 ); } }
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__ ); } } }
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__ ); } }
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 ); } }
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; } } } } } } } } } } }