如何使用ODA IFC SDK处理非拉丁字母?
IFC中的字符串数据始终采用UTF-8格式。当使用getAttr获取字符串时,得到的是UTF-8编码;使用putAttr写入字符串时,SDK默认该字符串为UTF-8格式。这些UTF-8数据在写入STEP物理文件时会隐式转换为控制指令格式(如'\X\C4\X\EF\X\EA\X\DC\X\F1\X\E9\X\E1'),读取时则反向转换。
UTF-8 -> putAttr -> writeFile -> Control Directives -> readFile -> getAttr -> UTF-8 |
处理字符串数据时,可配对使用OdString和OdAnsiString进行转换:
OdString wStr("АБВГДЕЁ"); |
OdAnsiString ansiStr(wStr, OdCodePageId::CP_UTF_8); |
inst->putAttr("string_value", ansiStr); // or inst->putAttr("string_value", ansiStr.c_str()); |
_writeSpf(model, "file.ifc"); // .ifc file will contain ansiStr data converted into internal representation (Control Directives) of such strings |
... |
_readSpf("file.ifc", model); |
inst->getAttr("stringValue") >> ansiStr; // UTF-8 string with original data |
OdString wStr(ansiStr, CP_UTF_8); // WChar string |
如何从IFC模型中获取单位信息?
Units information can be accessed through IfcProject.UnitsInContext attribute using C++ API in following way:
// 1. Using OdIfcFile
OdDAIObjectId idProject = pIfcFile->getProjectId();
// 2. No OdIfcFile way, work with model only
OdDAI::ModelPtr model = pIfcFile->getModel();
const OdDAIObjectIds &projectExtent = model->getEntityExtent("ifcproject")->getArray();
if (projectExtent.size())
{
idProject = projectExtent[0];
}
if (idProject.isValid())
{
OdDAI::ApplicationInstancePtr project = idProject.openObject();
OdDAIObjectId idUnitsInContext;
project->getAttr("unitsincontext") >> idUnitsInContext;
if (idUnitsInContext.isValid())
{
OdDAI::ApplicationInstancePtr unitAssignment = idUnitsInContext.openObject();
OdDAI::Set *units = nullptr;
unitAssignment->getAttr("units") >> units;
if (!units->isNil())
{
for (const OdDAI::Select &selUnit : units->getArray())
{
OdDAIObjectId idUnit = selUnit.getHandle();
OdDAI::ApplicationInstancePtr unit = idUnit.openObject();
const char *unitType = nullptr;
unit->getAttr("unittype") >> unitType;
const char *prefix = nullptr;
unit->getAttr("prefix") >> prefix;
const char *name = nullptr;
unit->getAttr("name") >> name;
oddaiPrintConsoleString(L"\n#%u=%hs:\n UnitType: %hs\n Prefix: %hs\n Name: %hs\n",
(OdUInt64)idUnit.getHandle(), unit->typeName().c_str(), unitType, prefix, name);
}
}
}
}
IFC SDK是否支持评估EXPRESS模式中定义的派生属性和WR规则?
是的,派生属性和Where规则评估由EXPRESS解释器(ISO 10303-11)支持,该解释器是ODA IFC SDK/SDAI的一部分。
如何初始化ODA IFC SDK以使用SDAI API
主要初始化流程与使用IFC SDK C++ API相同:
// Common ODA IFC SDK initialization part
OdStaticRxObject<MyServices> svcs;
odrxInitialize(&svcs);
odIfcInitialize(false /* No CDA */, false /* No geometry calculation needed */);
// SDAI calls can be performed just after common initialization procedure
SdaiSession session = sdaiOpenSession();
SdaiRep repo = _sdaiCreateRepositoryFromFile(session, "c:\\file.ifcXML", "");
SdaiRep repoOpened = sdaiOpenRepositoryBN(session, "c:\\file.ifcXML");
SdaiModel modelRO = sdaiAccessModelBN(repoOpened, "default", sdaiRO);
SdaiSet cartesianPoints = sdaiGetEntityExtentBN(modelRO, "IfcCartesianPoint");
SdaiIterator it = sdaiCreateIterator(cartesianPoints);
for (sdaiBeginning(it); sdaiNext(it);)
{
SdaiAppInstance inst = nullptr;
sdaiGetAggrByIterator(it, sdaiINSTANCE, &inst);
...
}
sdaiDeleteIterator(it);
sdaiCloseSession(session);
// Common ODA IFC SDK uninitialization part
odIfcUninitialize();
odrxUninitialize();
可参考使用SDAI调用的exSDAISAS示例,该示例展示了如何创建使用SDAI的模块。
如何通过SDAI访问Header Section实例?
在sdai.h头文件中声明了以下两个SDAI扩展函数:
SdaiInstance _sdaiHeaderDescription(SdaiRep repository);
SdaiInstance _sdaiHeaderName(SdaiRep repository);
之后可使用标准函数sdaiGetAttrBN/sdaiPutAttrBN访问实例属性值。
FILE_SCHEMA类型的第三个实例无法直接访问,在将存储库写入文件时会自动填充该部分数据。
IFC SDK是否支持.ifcxml格式的导入/导出?
ODA IFC SDK从22.6版本开始支持ifcXML2X3格式。
是否可以在VSF中存储元数据?对于包含元数据的大型石油天然气IFC模型,其Web可视化性能如何?
是的,VSF支持存储元数据。文件中包含元数据不会影响可视化性能。
IFC查看器支持查看哪些文件类型?
Open IFC Viewer支持打开以下文件类型:
IFC(文本格式,即Step Physical File)
ifcXML2X3
HDF5(可视为二进制IFC)
上述三种文件均可打包为IFCZIP格式(同样支持)。此外,Open IFC Viewer支持处理BCF(BIM协作格式)文件。Oda Viewer额外支持打开我们所有兼容的格式,包括.dwg、.dgn、Revit、Navisworks、STL、OBJ等。
Road/Rail IFC API有哪些功能?是否支持面积/体积计算、动态剖面等功能?
IFC SDK提供对模型显式/反向数据的访问及可视化支持。客户方可基于可视化数据自行实现此类计算功能。
cloud.opendesign(网页版)与桌面查看器(ODA Viewer)是否有区别?
Open Cloud的VisualizeJS库基于Visualize SDK开发(通过Emscripten编译为JavaScript),因此功能上无差异,但新功能的上线可能存在短暂延迟。
IFC查看器是否仅限会员及其客户使用,还是可以免费获取?
Open IFC Viewer可免费下载使用。至于我们的其他查看器,它们可作为开发自定义查看器的参考示例。
IFC查看器下载链接:https://openifcviewer.com/
IFC SDK是否提供.NET封装?
是的,我们提供.NET封装(请注意需同时获取Kernel和IFC功能包)。
读取IFC文件时是否会生成并提供反向关系?
是的,反向关系会在文件打开后立即计算生成。
是否可以使用IFC SDK创建建筑模型的所有IFC实体类型?
是的,IFC SDK支持创建建筑模型的所有IFC实体类型。客户能够访问IFC文件中的所有数据,并可根据IFC模式规范填充文件数据。
是否支持所有IFC BREP/切割平面/拉伸几何体的可视化(直接输出或转换为shell表示)?
是的,我们完整支持IFC格式中的高级BREP、面片化BREP、布尔运算、切割平面、拉伸几何等显式几何表达方式。
是否支持Autodesk Civil 3D .dwg文件与IFC互转?例如IFC4x1路线与Civil路线的转换?
是的,我们已使用从Civil获取的文件测试过路线转换功能的兼容性。
我们使用哪种布尔几何内核?
我们实现了ODA Facet Modeler,用于处理面片化几何体。该组件同时作为Drawings SDK的一部分运行,能维护Facet Modeler几何体的正确状态,主要负责控制拓扑和几何结构。具体而言,在打开文件时若检测到几何体需求,我们会尽可能修复几何中的错误拓扑。
当前我们主要以ODA Facet Modeler为基础实现,但通常会与ODA Solid Modeler协同工作,特别是在生成IfcRoad各类扫掠几何体时。
是否支持NURBS几何体?
是的,我们的IfcGeometry模块会从IFC文件中提取所有数据(特别是NURBS几何数据),并将其转换为GUI曲线。因此我们完整支持NURBS几何体、曲线及子曲面。
是否可以在不绘制的情况下查询.ifc实体几何?例如创建设备并获取几何数据。
是的,您可以通过提供的API访问IFC模型中的任何数据。因此无需进行绘制,即可直接获取.ifc文件的构成点、拉伸体、显式或隐式几何数据,并在不进行可视化和矢量化的前提下处理这些数据。
Open IFC可转换哪些标准格式(如STEP、STL等)?
当前Open IFC Viewer支持转换为.pdf格式,但通过Visualize SDK可将加载到Visualize数据库的IFC文件转换为STL等多种格式。因此,可通过Visualize SDK以编程方式实现格式转换。
是否已通过BuildingSMART历史认证的测试文件验证?
是的,我们正在使用BuildingSMART提供的测试文件进行验证。
是否有通过buildingSMART认证的计划?
是的,我们计划在未来进行相关认证。
何时应使用Common Data Access而非C++后期绑定?
Common Data Access作为高级数据访问方式,无需绑定特定格式(如IFC)即可使用。例如:您无需了解任何IFC类,就能通过该方式访问通用数据树状层级结构。
动态绑定有什么优势?你能举一个早期绑定不起作用的例子吗?
当我们开始支持加载IFC 4时,我们无法以早期绑定的方式生成几何体,因为我们必须处理不同的类集合。因此,IFC 2x3方案中的IFC墙与IFC 4方案中的IFC墙是不同的类,我们决定实现后期绑定的SDK工作方式,以便使用相同的代码进行几何体生成。
当然,使用后期绑定从IFC导入数据到应用程序时,使用相同的代码非常简单——这是主要优势。
SDAI是否依赖其他ODA SDK?
目前Kernel和SDAI组件是IFC SDK的基础模块,不依赖其他ODA SDK。
如何获取IFC模型的几何数据?
最终几何数据可以通过IfcProduct实例以两种方式获取:
1. 直接访问ODA格式的几何对象,如FacetModeler::Body或OdBrBrep。相关文章可通过此链接查看:https://docs.opendesign.com/tifc/ifc_access_representation_body_source_code.html,几何提取的代码示例也可在ExIfcTutorials模块的Tutorial_ExtractGeometry中找到,该示例考虑了可能存在的IfcMappedItem实例。
2. 第二种方式是为OdIfcFile实现自己的导出器,这种方式会对最终几何进行三角化处理,因此无法获取IfcAdvancedBrep(OdBrBrep)对象的面/边/顶点几何数据。这种方式的示例是IFC SDK中的ExIfcVectorize。
两种方式都要求IFC文件已加载到OdIfcFile实例中,并且在获取几何数据前调用composeEntities方法。请注意,几何提取唯一正确的方式是将IfcProduct实例作为几何根对象进行处理,因为它们包含底层IfcGeometricRepresentationItem的最终变换。
我使用了Drawings和Kernel归档文件(静态配置mddbg)。构建成功,但运行main.exe时出现以下输出:ERROR: Null Ptr
请注意示例中每个main.cpp文件里的TOOLKIT_IN_DLL定义内容。在静态配置中需要初始化模块:
#ifndef TOOLKIT_IN_DLL
INIT_IFC_STATIC_MODULES_NO_GEOM;
#endif
and
#ifndef TOOLKIT_IN_DLL
ODRX_INIT_STATIC_MODULE_MAP();
#endif
因此在md配置中,每个模块都应预先初始化,这样我们的rt链接器才能正常工作。您的问题似乎与这个初始化过程有关。
对于某个EntityInstance,如何从ifc STEP文件中获取其ID?
您可以获取实体实例的OdDAIObjectId,然后根据需要从中获取#号:
OdIfcEntityPtr pInst = ...; // or IfcWallPtr pWallInst = ...;
OdDAIObjectId id = pInst->id();
OdDbHandle h = id.getHandle();
是否支持IFC4.3?
是的,当前版本的ODA IFC SDK已支持IFC4.3标准。
如何获取IFC中的类型名称?
方法 const OdAnsiString& OdDAI::ApplicationInstance::typeName() const; 可返回应用实例的类型名称。
如何获取属性类型信息?
目前唯一获取属性类型信息的方式是通过以下类型转换实现:
OdArray<OdDAI::AttributePtr>::iterator nextAttribute = leftEntityAttributeFilter.begin();
for (; nextAttribute != leftEntityAttributeFilter.end(); ++nextAttribute)
{
OdDAI::AttributePtr pAttrib = *nextAttribute;
OdDAI::InverseAttributePtr pInverse = OdDAI::InverseAttribute::cast(pAttrib);
if (!pInverse.isNull())
{
odPrintConsoleString(L"\nInverse attribute `%s` (%lu)", pInverse->name().c_str(), (OdUInt64)leftIterator->id().getHandle());
}
}