osg与IFC(BIM)

news/2024/10/12 4:27:09

IFC(BIM)

BIM管理中使用的模型格式:IFC

 

IFC简介

IFC模型体系结构由四个层次构成,

从下到上依次是 资源层(Resource Layer)、核心层(Core Layer)、交互层(Interoperability Layer)、领域层(Domain Layer)。

每层中都包含一系列的信息描述模块,并且遵守一个规则:每个层次只能引用同层次和下层的信息资源,而不能引用上层的资源,当上层资源发生变动时,下层是不会受到影响的。

①资源层
IFC体系架构中的最低层,能为其他层所引用。主要是描述标准中用到的基本信息,不针对具体的行业本身,是无整体结构的分散信息,作为描述基础应用于整个信息模型。包括材料资源(Material Resource)、几何限制资源(Geometric Constraint Resource)、成本资源(Costs Resource)等。
②核心层
是IFC体系架构中的第二层,能为交互层与领域层所引用。主要是提供基础的IFC对象模型结构,描述建筑工程信息的整体框架,将资源层信息组织起来,成为一个整体,来反映现实世界的结构。包括核心(The Kernel)和核心扩展(Core Extensions)两个层次的泛化。
③交互层
是IFC体系架构中的第三层,主要是为领域层服务。领域层中的模型可以通过该层来达到信息交互的目的。该层主要解决了领域信息交互的问题,并且在这个层次使各个系统的组成元素细化。包括共享空间元素(SharedSpatialElements)、共享建筑元素(SharedBuildingElements)、共享管理元素(SharedManagement Elements)、共享设备元素(SharedFacilities Elements)和共享建筑服务元素(Shared Bldg Services Elements)等五大类。
④领域层
是IFC体系架构中的最高层。每一个使用或是引用定义在核心和独立资源层上的类信息的模型都是独立的。其主要作用时是深入到各个应用领域的内部,形成专题信息,比如暖通领域(HVAC Domain)、T程管理领域(Construction Management Domain)等,而且还可以根据实际需要不断进行扩展。

==================================================

1) IFC 标准资源层(IFC-Resource Layer):作为整个体系的基本层,IFC 任意层都可引用资源层中的实体。该层主要定义了工程项目的通用信息,这些信息独立于具体建筑,没有整体结构,是分散的基础信息。该层核心内容主要包括属性资源(Property Resource)、表现资源 (Representation Re-source)、结构资源(Structure Resource)。这些实体资源主要用于上层实体资源的定义,以显示上层实体的属性。

2) IFC 标准核心层(IFC-Core Layer):该层之中主要定义了产品、过程、控制等相关信息,主要作用是将下层分散的基础信息组织起来,形成 IFC 模型的基本结构,然后用以描述现实世界中的实物以及抽象的流程。在整个体系之中起到了承上启下的作用。该层提炼定义了适用于整个建筑行业的抽象概念,比如 IFCProduct 实体可以描述建筑项目的建筑场地、建筑空间、建筑构件等。

3) IFC 标准共享层(IFC-Interoperability Layer):共享层主要是服务于领域层,使各个领域间的信息能够交互,同时细化系统的组成元素,具体的建筑构件如板(IFCSlab)、柱(IFCColumn)、梁(IFCBeam)均在这一层被定义。

4) IFC 标准领域层(IFC-Domain Layer):作为 IFC 体系架构的顶层,该层主要定义了面向各个专业领域的实体类型。这些实体都面向各个专业领域具有特定的概念。比如暖通领域(HVAC Domain)的锅炉、管道等。

==================================================

楼层(IfcBuildingStorey):定义水平空间的垂直边界,具有标高属性。楼层与建筑存在关联关系,多个楼层组成了整体的建筑空间,一个楼层可能跨越几个连续的楼层形成复合建筑楼层。

设施(IfcFacility):定义基础设施,例如建筑、道路、桥梁等。

设施组件(IfcFacilityPart):定义基础设施中的组成部分,如桥梁组件(IfcBridgePart)。

场地(IfcSite):定义一个陆地区域,场地可以包括该场地的单个地理参考点的定义(使用经度,纬度和海拔的全球位置)。

空间(IfcSpace):表达具体或抽象的区域边界,是建筑内提供一定功能的区域面积或体积。空间与楼层关联可表示楼层上的房间划分,而与场地关联可表示场地中特定的功能区域。一个空间可能与几个连续的空间形成空间组合,也可以被分解成多个空间。

 

一个基于IFC标准的建筑信息模型有且只能定义一个项目(IfcProject)来作为项目中所有对象的容器,建筑构件大多与楼层或者楼层所拆分的空间建立关联关系,从而确定从属关系以及构件在整个三维模型中的坐标定位。集合关系(IfcRelAggregates)定义一对多的不同空间层次间的从属关系,子空间相互之间通过该关系对象建立从属关系,最终空间结构元素通过该关系对象与项目(IfcProject)建立从属关系。实际的建筑信息模型中可通过集合关系建立一个完整的信息模型空间。

==================================================

IFC格式架构

IFC架构采用EXPRESS语言定义,EXPRESS语言是由STEP开发的概念性架构语言。EXPRESS用于面向对象的信息描述语言,处于STEP的基础和核心地位。它将IFC模型的结构描述为:规范的类,与类相关联的属性,类的约束,以及类与其他约束之间的关系。
IFC架构分为四个层:领域层、共享层、核心层、资源层。

IFC架构将所有的对象与类按概念进行分类:类型、实体、函数、规则、属性集及量集。

IFC数据组成

IFC文件是一种纯文本文件格式,用普通的文本编辑器就可以查看和编辑。
文件以“ISO-10303-21;”开头,以“END-ISO-10303-21;”结束。

中间包括两个部分:一个文件头段和一个数据段。
文件头段以“HEADER;”开始,以“ENDSEC;”结束,里面包含了有关ifc文件本身的信息,例如文件描述、使用的ifc标准版本等。

数据段以“DATA;”开始,以“ENDSEC;”结束,里面包含了要交换的工程信息。

IFC格式优势

使用IFC格式有以下优势:

  • 实现不同软件之间的信息交换

IFC作为一个标准的公开的数据表达和存储方法,不同软件通过对接IFC标准接口,便可以与其他软件系统交换信息,畅通无阻。

  • 提升建筑项目中的沟通、生产力、时间、成本和质量

通过IFC,可以在建筑项目的整个生命周期中提升沟通、生产力、时间、成本和质量,为全球的建筑专业与设备专业中的流程提升与信息共享建立一个普遍意义的基准。

  • 集中存储多个项目的工程信息

BIM数据库可集中存储多个项目的工程信息,并利用文件管理表、语句管理表和属性管理表对IFC模型进行保存,从而保证IFC建筑信息模型的正确性和完整性。

  • 建筑信息查询效率高

BIM数据库利用文件管理表、语句管理表和属性管理表对IFC模型进行保存,使建筑信息查询效率大大提升。

IFC格式查看与转换

要打开IFC文件,可以使用以下软件:

  • Autodesk Revit

Revit是一种建筑信息建模(BIM)软件,支持IFC格式,并可用于导入、编辑和查看IFC文件。

  • Tekla Structures

这是一种结构工程BIM软件,也可以打开和编辑IFC文件。

  • 在线工具

推荐使用NSDT 3DConvert这个强大的在线3D格式转换工具,可以将IFC、STEP、IGES、3DXML等多种BIM/CAD文件转换为GLTF、STL、OBJ、DAE等格式。

==================================================================

OSG与IFC

读写IFC文件的osg插件(osgdb_ifc)

调用第三方库ifcplusplus 实现osg ifc插件

第三方库:https://github.com/ifcquery/ifcplusplus

转自:https://blog.csdn.net/baidu_41914439/article/details/108078092?spm=1001.2014.3001.5502

 

//ReaderWriterIFC.h
#ifndef READERWRITERIFC_H
#define READERWRITERIFC_H#include <osgDB/ReaderWriter>///
// OSG reader plugin for the ".ifc" format.
// 
// This plugin requires the ifcplusplusclass BuildingModel;
class BuildingEntity;
class ReaderSTEP;
class WriterSTEP;
class GeometryConverter;class ReaderWriterIFC : public osgDB::ReaderWriter
{osg::ref_ptr<osg::Group>                    m_rootnode;osg::ref_ptr<osg::Switch>                    m_sw_coord_axes;osg::ref_ptr<osg::Switch>                    m_sw_model;    shared_ptr<GeometryConverter>                m_geometry_converter;shared_ptr<ReaderSTEP>                        m_step_reader;shared_ptr<WriterSTEP>                        m_step_writer; shared_ptr<BuildingModel>                    m_ifc_model;public:ReaderWriterIFC();const char* className() const { return "IFC reader/writer"; }virtual ReadResult readObject(const std::string& filename, const Options* options) const{return readNode(filename, options);}virtual WriteResult writeObject(const osg::Node& node, const std::string& filename, const Options* options) const{return writeNode(node, filename, options);}virtual ReadResult readNode(const std::string& filename, const Options*) const;virtual WriteResult writeNode(const osg::Node&, const std::string& filename, const Options*) const;
};///

#endif
//ReaderWriterIFC.cpp
#include <sstream>
#include <memory>
#ifndef WIN32
#include <strings.h>//for strncasecmp
#endif//#include <osg/Notify>
//#include <osg/MatrixTransform>
//#include <osg/Material>
#include <osg/StatusCallback>
#include <osg/PositionAttitudeTransform>
//#include <osg/Texture2D>
//#include <osg/Version>
//#include <osgDB/ConvertUTF>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
//#include <osgDB/ReadFile>
//#include <osgDB/Registry>
#include <osgUtil/Optimizer>
//#include <osgAnimation/AnimationManagerBase>
//#include <osgAnimation/Bone>
//#include <osgAnimation/RigGeometry>
//#include <osgAnimation/Skeleton>
//#include <osgAnimation/VertexInfluence>
//#include <osgGA/GUIActionAdapter>

#include <ifcpp/model/BasicTypes.h>
#include <ifcpp/model/BuildingModel.h>
#include <ifcpp/model/BuildingException.h>
#include <ifcpp/model/BuildingGuid.h>
#include <ifcpp/reader/ReaderSTEP.h>
#include <ifcpp/reader/ReaderUtil.h>
#include <ifcpp/writer/WriterSTEP.h>
#include <ifcpp/IFC4/include/IfcProduct.h>
#include <ifcpp/IFC4/include/IfcSite.h>
#include <ifcpp/IFC4/include/IfcLengthMeasure.h>
#include <ifcpp/IFC4/include/IfcOpeningElement.h>
#include <ifcpp/IFC4/include/IfcOwnerHistory.h>
#include <ifcpp/IFC4/include/IfcGloballyUniqueId.h>
#include <ifcpp/geometry/Carve/GeometryConverter.h>
#include <ifcpp/geometry/Carve/ConverterOSG.h>#if defined(_MSC_VER)#pragma warning( disable : 4505 )#pragma warning( default : 4996 )
#endif#include "ReaderWriterIFC.h"/// Returns true if the given node is a basic root group with no special information.
/// Used in conjunction with UseFbxRoot option.
/// Identity transforms are considered as basic root nodes.
bool isBasicRootNode(const osg::Node& node)
{const osg::Group* osgGroup = node.asGroup();if (!osgGroup || node.asGeode())        // WriterNodeVisitor handles Geodes the "old way" (= Derived from Node, not Group as for now). Geodes may be considered "basic root nodes" when WriterNodeVisitor will be adapted.
    {// Geodes & such are not basic root nodesreturn false;}// Test if we've got an empty transform (= a group!)const osg::Transform* transform = osgGroup->asTransform(); if (transform){const osg::PositionAttitudeTransform* pat = transform->asPositionAttitudeTransform();if (const osg::MatrixTransform* matrixTransform = transform->asMatrixTransform()){if (!matrixTransform->getMatrix().isIdentity()){// Non-identity matrix transformreturn false;}}else if ( pat ){if (pat->getPosition() != osg::Vec3d() ||pat->getAttitude() != osg::Quat() ||pat->getScale() != osg::Vec3d(1.0f, 1.0f, 1.0f) ||pat->getPivotPoint() != osg::Vec3d()){// Non-identity position attribute transformreturn false;}}else{// Other transform (not identity or not predefined type)return false;}}// Test the presence of a non-empty statesetif (node.getStateSet()){osg::ref_ptr<osg::StateSet> emptyStateSet = new osg::StateSet;if (node.getStateSet()->compare(*emptyStateSet, true) != 0){return false;}}return true;
}ReaderWriterIFC::ReaderWriterIFC()
{supportsExtension("ifc", "IFC format");supportsOption("Embedded", "(Write option) Embed textures in IFC file");supportsOption("UseFbxRoot", "(Read/write option) If the source OSG root node is a simple group with no stateset, the writer will put its children directly under the IFC root, and vice-versa for reading");supportsOption("LightmapTextures", "(Read option) Interpret texture maps as overriding the lighting. 3D Studio Max may export files that should be interpreted in this way.");supportsOption("TessellatePolygons", "(Read option) Tessellate mesh polygons. If the model contains concave polygons this may be necessary, however tessellating can be very slow and may erroneously produce triangle shards.");m_ifc_model = shared_ptr<BuildingModel>(new BuildingModel());m_geometry_converter = shared_ptr<GeometryConverter>(new GeometryConverter(m_ifc_model));m_step_reader = shared_ptr<ReaderSTEP>(new ReaderSTEP());m_step_writer = shared_ptr<WriterSTEP>(new WriterSTEP());m_rootnode = new osg::Group();m_rootnode->setName("m_rootnode");m_sw_model = new osg::Switch();m_sw_model->setName("m_sw_model");m_rootnode->addChild(m_sw_model.get());m_sw_coord_axes = new osg::Switch();m_sw_coord_axes->setName("m_sw_coord_axes");m_rootnode->addChild(m_sw_coord_axes.get());
}
std::wstring StringToWstring(const std::string str)
{// string转wstringunsigned len = str.size() * 2;// 预留字节数setlocale(LC_CTYPE, "");     //必须调用此函数wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串mbstowcs(p, str.c_str(), len);// 转换
    std::wstring str1(p);delete[] p;// 释放申请的内存return str1;
}
osgDB::ReaderWriter::ReadResult
ReaderWriterIFC::readNode(const std::string& filenameInit,const Options* options) const
{try{std::string ext(osgDB::getLowerCaseFileExtension(filenameInit));if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;std::string filename(osgDB::findDataFile(filenameInit, options));if (filename.empty()) return ReadResult::FILE_NOT_FOUND;// first remove previously loaded geometry from scenegraphosg::ref_ptr<osg::Switch> model_switch = m_sw_model;        SceneGraphUtils::clearAllChildNodes(model_switch);// reset the IFC modelshared_ptr<GeometryConverter> geometry_converter = m_geometry_converter;geometry_converter->clearMessagesCallback();geometry_converter->resetModel();std::stringstream err;try{osg::StatusCallback& statusCallBack = osg::StatusCallback::getStatusCallback();void* obj = statusCallBack.getMessageCallBack_obj();osg::StatusCallback::Func_call_on_message func = statusCallBack.getMessageCallBack_func();geometry_converter->setMessageCallBack_extern(obj,func);m_step_reader->setMessageCallBack_extern(obj, func);// load file to IFC modelstd::wstring fileName = StringToWstring(filenameInit);m_step_reader->loadModelFromFile(fileName, geometry_converter->getBuildingModel());// convert IFC geometric representations into Carve geometryconst double length_in_meter = geometry_converter->getBuildingModel()->getUnitConverter()->getLengthInMeterFactor();geometry_converter->setCsgEps(1.5e-08*length_in_meter);geometry_converter->convertGeometry();// convert Carve geometry to OSGshared_ptr<ConverterOSG> converter_osg(new ConverterOSG(geometry_converter->getGeomSettings()));converter_osg->setMessageCallBack_extern(obj, func);converter_osg->convertToOSG(geometry_converter->getShapeInputData(), model_switch);// in case there are IFC entities that are not in the spatial structureconst std::map<std::string, shared_ptr<BuildingObject> >& objects_outside_spatial_structure = geometry_converter->getObjectsOutsideSpatialStructure();if (objects_outside_spatial_structure.size() > 0){osg::ref_ptr<osg::Switch> sw_objects_outside_spatial_structure = new osg::Switch();sw_objects_outside_spatial_structure->setName("IfcProduct objects outside spatial structure");converter_osg->addNodes(objects_outside_spatial_structure, sw_objects_outside_spatial_structure);if (sw_objects_outside_spatial_structure->getNumChildren() > 0){model_switch->addChild(sw_objects_outside_spatial_structure);}}}catch (OutOfMemoryException& e){throw e;}catch (BuildingException& e){err << e.what();}catch (std::exception& e){err << e.what();}catch (...){err << "loadModelFromFile, createGeometryOSG failed" << std::endl;}try{if (model_switch){bool optimize = true;if (optimize){osgUtil::Optimizer opt;opt.optimize(model_switch);}// if model bounding sphere is far from origin, move to originconst osg::BoundingSphere& bsphere = model_switch->getBound();if (bsphere.center().length() > 10000){if (bsphere.center().length() / bsphere.radius() > 100){std::unordered_set<osg::Geode*> set_applied;SceneGraphUtils::translateGroup(model_switch, -bsphere.center(), set_applied);}}}}catch (std::exception& e){err << e.what();}geometry_converter->clearInputCache();if (err.tellp() > 0){throw BuildingException(err.str().c_str());}bool refCoordSysChange = false;osg::Matrix mat;//if (zUp)
        {//if (eUp != FbxAxisSystem::eZAxis || fSign != 1.0 || upSign != 1.0)
            {/*               switch (eUp){case FbxAxisSystem::eXAxis:mat.set(0, fSign, 0, 0, -fSign, 0, 0, 0, 0, 0, HorizSign, 0, 0, 0, 0, 1);break;case FbxAxisSystem::eYAxis:mat.set(1, 0, 0, 0, 0, 0, -fSign * HorizSign, 0, 0, fSign, 0, 0, 0, 0, 0, 1);break;case FbxAxisSystem::eZAxis:mat.set(1, 0, 0, 0, 0, fSign, 0, 0, 0, 0, fSign * HorizSign, 0, 0, 0, 0, 1);break;}*/refCoordSysChange = true;}}//else //if (fbxAxis != FbxAxisSystem::OpenGL)
        {//switch (eUp)//{//case FbxAxisSystem::eXAxis://    mat.set(0, -fSign, 0, 0, fSign, 0, 0, 0, 0, 0, HorizSign, 0, 0, 0, 0, 1);//    break;//case FbxAxisSystem::eYAxis://    mat.set(1, 0, 0, 0, 0, -fSign, 0, 0, 0, 0, -fSign * HorizSign, 0, 0, 0, 0, 1);//    break;//case FbxAxisSystem::eZAxis://    mat.set(1, 0, 0, 0, 0, 0, fSign * HorizSign, 0, 0, -fSign, 0, 0, 0, 0, 0, 1);//    break;//}// refCoordSysChange = true;
        }if (refCoordSysChange){osg::Transform* pTransformTemp = model_switch->asTransform();osg::MatrixTransform* pMatrixTransform = pTransformTemp ?pTransformTemp->asMatrixTransform() : NULL;if (pMatrixTransform){pMatrixTransform->setMatrix(pMatrixTransform->getMatrix() * mat);}else{pMatrixTransform = new osg::MatrixTransform(mat);if (isBasicRootNode(*model_switch)){  osg::Group* osgGroup = model_switch->asGroup();for(unsigned int i = 0; i < osgGroup->getNumChildren(); ++i){pMatrixTransform->addChild(osgGroup->getChild(i));}pMatrixTransform->setName(osgGroup->getName());}else{pMatrixTransform->addChild(model_switch);}}//model_switch = pMatrixTransform;
        }model_switch->setName(filenameInit);return model_switch;        }catch (...){OSG_WARN << "Exception thrown while importing \"" << filenameInit << '\"' << std::endl;}return ReadResult::ERROR_IN_READING_FILE;
}osgDB::ReaderWriter::WriteResult ReaderWriterIFC::writeNode(const osg::Node& node,const std::string& filename,const Options* options) const
{try{shared_ptr<GeometryConverter> geom_converter = m_geometry_converter;shared_ptr<BuildingModel>& model = geom_converter->getBuildingModel();std::wstring m_file_path = StringToWstring(filename);model->initFileHeader(m_file_path);std::stringstream stream;m_step_writer->writeModelToStream(stream, model);FILE * pFile = fopen(filename.c_str(), "wt");if (pFile==nullptr){return false;}fprintf(pFile, "%s", stream.str().c_str());fclose(pFile);return WriteResult::FILE_SAVED;}catch (const std::string& s){return s;}catch (const char* s){return std::string(s);}catch (...){}return WriteResult::ERROR_IN_WRITING_FILE;
}///
// Add ourself to the Registry to instantiate the reader/writer.

REGISTER_OSGPLUGIN(ifc, ReaderWriterIFC)

对osg库中增加了StatusCallback来和ifcplusplus库中的对应

//StatusCallback
//消息回调
#pragma once#include <osg/Export>
#include <sstream>
#include <iostream>
#include <vector>//#include "OpenMPIncludes.h"
namespace osg 
{using namespace std;class OSG_EXPORT StatusCallback{public:typedef void(*Func_call_on_message)(void*, std::string type, std::wstring msg,double v);typedef bool(*Func_call_CancelCheck)(void*);static StatusCallback& getStatusCallback();StatusCallback() = default;virtual ~StatusCallback() = default;void setMessageCallBack(void* obj_ptr, Func_call_on_message func){m_obj_call_on_message = obj_ptr;m_func_call_on_message = func;}void* getMessageCallBack_obj(){return m_obj_call_on_message;}Func_call_on_message getMessageCallBack_func(){return m_func_call_on_message;}        virtual void setMessageTarget(StatusCallback* other){m_redirect_target = other;}virtual void unsetMessageCallBack(){m_obj_call_on_message = nullptr;m_func_call_on_message = nullptr;}virtual void setCancelCheck(void* obj_ptr, Func_call_CancelCheck func){m_obj_call_check_cancel = obj_ptr;m_func_check_cancel = func;}virtual void unsetCancelCheck(){m_obj_call_check_cancel = nullptr;m_func_check_cancel = nullptr;}//\brief trigger the callback to pass a message, warning, or error, for example to store in a logfilevirtual void messageCallback( std::string type,std::wstring msg, double v){if (m_redirect_target){m_redirect_target->messageCallback(type, msg, v);return;}if (m_func_call_on_message){if (m_obj_call_on_message){#ifdef ENABLE_OPENMP// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.ScopedLock lock(m_writelock);#endifm_func_call_on_message(m_obj_call_on_message,type, msg, v);}}}//\brief check if cancellation has been requested.virtual bool isCanceled(){if (m_redirect_target){return m_redirect_target->isCanceled();}if (m_func_check_cancel){if (m_obj_call_check_cancel){#ifdef ENABLE_OPENMP// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.ScopedLock lock(m_writelock);#endifreturn m_func_check_cancel(m_obj_call_check_cancel);}}return false;}protected://\brief Pointer to the object on which the message callback function is called.void* m_obj_call_on_message = nullptr;//\brief Pointer to the object on which the cancel check function is called.void* m_obj_call_check_cancel = nullptr;//附加的消息回调,在有消息时进行响应,以支持库外使用Func_call_on_message m_func_call_on_message = nullptr;//\brief Pointer to the predicate that determines whether an operation should be canceled.Func_call_CancelCheck m_func_check_cancel = nullptr;StatusCallback* m_redirect_target = nullptr;#ifdef ENABLE_OPENMPMutex m_writelock;#endif};
}

 

//StatusCallback.cpp
#include <osg/StatusCallback>
using namespace osg;
StatusCallback _StatusCallback;
StatusCallback& StatusCallback::getStatusCallback() { return _StatusCallback; }

在使用时添加作为回调

void messageTarget(void* ptr,std::string type, std::wstring msg,double v)
{MainWindow* myself = (MainWindow*)ptr;if (myself){
#ifdef ENABLE_OPENMPScopedLock lock(myself->m_mutex_messages);
#endifif(v<0)emit myself->TxtOut(QString::fromStdString(type),QString::fromStdWString(msg));else{emit myself->ProgressValue(v,QString::fromStdString(type));}}
}

在初始化时调用

    osg::StatusCallback& gloableStatus = osg::StatusCallback::getStatusCallback();gloableStatus.setMessageCallBack(this, messageTarget);

ifcplusplus库中也要做相应修改

/* -*-c++-*- IfcQuery www.ifcquery.com
*
MIT LicenseCopyright (c) 2017 Fabian GeroldPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/#pragma once#include <sstream>
#include <iostream>
#include <vector>
#include "BasicTypes.h"
#include "GlobalDefines.h"
#include "OpenMPIncludes.h"class BuildingEntity;class IFCQUERY_EXPORT StatusCallback
{
public:typedef void(*Func_call_on_message)(void*, std::string type, std::wstring msg, double v);enum MessageType{MESSAGE_TYPE_UNKNOWN,MESSAGE_TYPE_GENERAL_MESSAGE,MESSAGE_TYPE_PROGRESS_VALUE,    //\brief Progress mechanism to update progress bar or similar.MESSAGE_TYPE_PROGRESS_TEXT,        //\brief Progress mechanism to update text in progress bar or similar.
        MESSAGE_TYPE_MINOR_WARNING,MESSAGE_TYPE_WARNING,MESSAGE_TYPE_ERROR,MESSAGE_TYPE_CLEAR_MESSAGES,MESSAGE_TYPE_CANCELED};/*\class Message\brief Combines all information about a status message, being it a general message, a warning, error, or a notification about a progress (for example during reading of a file).*/class Message{public://\brief Default constructor.
        Message(){m_message_type = MessageType::MESSAGE_TYPE_UNKNOWN;m_reporting_function = "";m_entity = nullptr;m_progress_value = -1;}std::wstring m_message_text;        // Message text.MessageType m_message_type;            // Type of message (warning, error etc.).const char* m_reporting_function;    // Function name where the message is sent from. You can use the __FUNC__ macro from BuildingException.h.BuildingEntity* m_entity;            // IFC entity in case the message applies to a certain entity.double m_progress_value;            // Value of progress [0...1]. If negative value is given, the progress itself is ignored, for example when only the progress text is updated.std::string m_progress_type;        // Type of progress, for example "parse", "geometry".std::wstring m_progress_text;        // A text that describes the current actions. It can be used for example to set a text on the progress bar.
    };StatusCallback() = default;virtual ~StatusCallback() = default;//\brief error callback mechanism to show messages in guivirtual void setMessageCallBack(void* obj_ptr, void(*func)(void*, shared_ptr<Message> t)){m_obj_call_on_message = obj_ptr;m_func_call_on_message = func;}    void setMessageCallBack_extern(void* obj_ptr, Func_call_on_message func){m_obj_call_on_msg_extern = obj_ptr;m_func_call_on_msg_extern = func;}virtual void unsetMessageCallBack_extern(){m_obj_call_on_msg_extern = nullptr;m_func_call_on_msg_extern = nullptr;}virtual void setMessageTarget(StatusCallback* other){m_redirect_target = other;}virtual void unsetMessageCallBack(){m_obj_call_on_message = nullptr;m_func_call_on_message = nullptr;}virtual void setCancelCheck(void* obj_ptr, bool(*func)(void*)){m_obj_call_check_cancel = obj_ptr;m_func_check_cancel = func;}virtual void unsetCancelCheck(){m_obj_call_check_cancel = nullptr;m_func_check_cancel = nullptr;}//\brief trigger the callback to pass a message, warning, or error, for example to store in a logfilevirtual void messageCallback(shared_ptr<Message> m){if (m_redirect_target){m_redirect_target->messageCallback(m);return;}#ifdef _DEBUGif (!m_func_call_on_message || !m_obj_call_on_message){if (m){switch (m->m_message_type){case MESSAGE_TYPE_UNKNOWN:case MESSAGE_TYPE_GENERAL_MESSAGE:case MESSAGE_TYPE_MINOR_WARNING:case MESSAGE_TYPE_WARNING:case MESSAGE_TYPE_ERROR:std::wcout << L"messageCallback not set. Lost message: " << m->m_message_text.c_str() << std::endl;break;}}}if (m->m_message_type == MESSAGE_TYPE_ERROR){std::wcout << L"error: " << m->m_message_text.c_str() << std::endl;}
#endifif (m_func_call_on_message){if (m_obj_call_on_message){
#ifdef ENABLE_OPENMP// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.ScopedLock lock(m_writelock);
#endifm_func_call_on_message(m_obj_call_on_message, m);}}if (m_func_call_on_msg_extern){if (m_obj_call_on_msg_extern){
#ifdef ENABLE_OPENMP// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.ScopedLock lock(m_writelock);
#endifstd::string msgType;switch (m->m_message_type){case MESSAGE_TYPE_UNKNOWN:msgType = "UNKNOWN";break;case MESSAGE_TYPE_GENERAL_MESSAGE:msgType = "GENERAL_MESSAGE";break;case MESSAGE_TYPE_PROGRESS_VALUE:msgType = "PROGRESS_VALUE";break;case MESSAGE_TYPE_PROGRESS_TEXT:msgType = "PROGRESS_TEXT";break;case MESSAGE_TYPE_MINOR_WARNING:msgType = "MINOR_WARNING";break;case MESSAGE_TYPE_WARNING:msgType = "WARNING";break;case MESSAGE_TYPE_ERROR:msgType = "ERROR";break;}if(m->m_progress_value>=0)m_func_call_on_msg_extern(m_obj_call_on_msg_extern, m->m_progress_type, m->m_progress_text,m->m_progress_value);elsem_func_call_on_msg_extern(m_obj_call_on_msg_extern, msgType, m->m_message_text, m->m_progress_value);}}}//\brief check if cancellation has been requested.virtual bool isCanceled(){if (m_redirect_target){return m_redirect_target->isCanceled();}if (m_func_check_cancel){if (m_obj_call_check_cancel){
#ifdef ENABLE_OPENMP// Note: this lock protects accesses only for this instance. If several StatusCallback (or derived) objects are bound to the same callback function, a lock is necessary there.ScopedLock lock(m_writelock);
#endifreturn m_func_check_cancel(m_obj_call_check_cancel);}}return false;}virtual void messageCallback(const std::string& message_text, MessageType type, const char* reporting_function, BuildingEntity* entity = nullptr){shared_ptr<Message> message(new Message());message->m_message_text.assign(message_text.begin(), message_text.end());message->m_message_type = type;message->m_reporting_function = reporting_function;message->m_entity = entity;messageCallback(message);}virtual void messageCallback(const std::wstring& message_text, MessageType type, const char* reporting_function, BuildingEntity* entity = nullptr){shared_ptr<Message> message(new Message());message->m_message_text.assign(message_text);message->m_message_type = type;message->m_reporting_function = reporting_function;message->m_entity = entity;messageCallback(message);}virtual void progressValueCallback(double progress_value, const std::string& progress_type){shared_ptr<Message> progress_message(new Message());progress_message->m_message_type = MessageType::MESSAGE_TYPE_PROGRESS_VALUE;progress_message->m_progress_value = progress_value;progress_message->m_progress_type.assign(progress_type);messageCallback(progress_message);}virtual void progressTextCallback(const std::wstring& progress_text){shared_ptr<Message> progress_message(new Message());progress_message->m_message_type = MessageType::MESSAGE_TYPE_PROGRESS_TEXT;progress_message->m_progress_value = 0;progress_message->m_progress_text.assign(progress_text);messageCallback(progress_message);}virtual void clearMessagesCallback(){shared_ptr<Message> progress_message(new Message());progress_message->m_message_type = MessageType::MESSAGE_TYPE_CLEAR_MESSAGES;messageCallback(progress_message);}virtual void canceledCallback(){shared_ptr<Message> canceled_message(new Message());canceled_message->m_message_type = MessageType::MESSAGE_TYPE_CANCELED;messageCallback(canceled_message);}protected://\brief Pointer to the object on which the message callback function is called.void* m_obj_call_on_message = nullptr;void* m_obj_call_on_msg_extern = nullptr;//\brief Pointer to the object on which the cancel check function is called.void* m_obj_call_check_cancel = nullptr;//\brief Pointer to the callback function for messages.void(*m_func_call_on_message)(void*, shared_ptr<Message> t) = nullptr;//附加的消息回调,在有消息时进行响应,以支持库外使用Func_call_on_message m_func_call_on_msg_extern = nullptr;//\brief Pointer to the predicate that determines whether an operation should be canceled.bool(*m_func_check_cancel)(void*) = nullptr;StatusCallback* m_redirect_target = nullptr;#ifdef ENABLE_OPENMPMutex m_writelock;
#endif
};

 

==========================================================

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/53417.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

面试官:Leader崩溃Follower不够新怎么办?

这是一道非常经典的 Kafka 问题,是关于 Leader 在“异常”情况下的选举问题。 背景 我们知道 Kafka 中的 Partition(分区)是存储消息的最终介质,但 Partition 又有两种分类:Leader Partition:主分区,负责数据写入和读取。 Follower Partition:副本分区,用于数据备份和…

线性规划单纯形求解理论

线性规划(Linear Programming, LP)是优化理论中用于在给定约束条件下最大化或最小化线性目标函数的一种数学方法。线性规划的最优解总是出现在可行域的顶点上,这是因为目标函数在可行域内的变化是线性的,因此在顶点处函数的值可能达到极值(最大或最小)。求解线性规划问题…

如何考取PostgreSQL认证证书?

PostgreSQL数据库炙手可热,国内知名的腾讯云TDSQL、阿里云PolarDB都有PostgreSQL版本的产品,还有人大金仓、华为opengauss、翰高数据库等都跟PostgreSQL有关系,所以考一个PostgreSQL认证非常有必要。要获得PostgreSQL认证,可以从以下几个方面着手: 一、了解PostgreSQL认证…

AI agent里的长期记忆和短期记忆

AI Agent 是时下热门的一个方向,在 OpenAI 应用研究主管 LilianWeng 写的万字长文中[1],她提出 Agent = LLM+ 记忆 + 规划技能 + 工具使用。图1 Overview of a LLM-powered autonomous agent system组件二:记忆我们可以将上下文学习(context)看成是利用模型的短期记忆(也…

Yolov5模型训练+转ncnn模型

配置YOLOv5依赖 打开yolov5开源地址:https://github.com/ultralytics/yolov5 可根据自身要求下载对应版本(无要求可跳过): 下载:下载完成安装依赖包: 如需使用显卡进行训练需按照显卡版本安装部分依赖包:这两个包注掉,然后根据显卡版本安装依赖 在cmd获取显卡版本:nvi…

windows更新在哪里删除,教你关闭windows更新

电脑自动更新的彻底关闭方法可以根据不同的Windows系统版本(如Windows 10、Windows 11等)和用户的具体需求来选择。以下是一些常用的方法: 一、 使用系统设置关闭自动更新 步骤: 1.点击开始菜单,在搜索栏中输入“设置”,并打开设置窗口。 2.在设置窗口中,找到“更新和安…

k8s给多个外部静态IP作负载均衡、反向代理

在 Kubernetes (K8s) 中,Ingress、Endpoints 和 Service 是三个重要的概念,它们协作实现了集群内部和外部应用程序的访问和服务发现。 Ingress:Ingress 用于提供集群外部到集群内部服务的 HTTP/HTTPS 路由。 Ingress 定义了访问集群内部服务的规则,如路径映射、虚拟主机等。 In…

nuxt3项目自定义环境变量,typescript全局提示

最近使用nuxt3框架来写项目,其中有一点就是 typescript 语法提示让人闹心,使用 vscode 编辑器,如果有语法提示进行编码,工作效率可以提升一个档次。本篇文章说的就是如何在 vscode 中使用 nuxt3 框架,自定义环境变量,支持 typescript 语法提示。列出当前使用的环境版本no…