领域对象(BPObject
)在BIMBase里边分为图形对象(BPGraphicElement
)和非图形数据(BPNonGraphicElement
),图形对象尤其重要,用户能够看见的对象基本都是图形对象,比如墙、标高、轴网等。对象是可序列化的,即是可被保存到p3d
工程文件中。
3.1.1 相关类图
领域对象类图
图3-1为领域对象类图,基类BPObject
定义了对象的一些通用行为,例如addToProject
、deleteFromProject
等。基于BPOBject
衍生出来两类对象,一类是图形对象(BPGraphicElement
),一类是非图形数据(BPNonGraphicElement
)。图形对象主要包括两个主要的内容,一个是图形BPEntity
,由model
进行管理,一个是数据BPData
,由project
进行管理。非图形数据只包括数据BPData
。BPGraphic
是几何数据的集合,可通过各种几何元素进行构造(线段、弧、曲线集、实体等等),是一种内存数据形式。BPEntity
是物理实体,由几何数据生成的一种可持久化的内存数据。
图3-1 BPObject相关类图
三维图形对象
三维图形对象类图见图3-2,列出的是一些常用的图形对象,墙、梁、板、柱、房间等。

图3-2 三维图形对象类图
- 二维对象
二维对象常用于绘制标注等内容,类图见图3-3。
图3-3 二维对象类图
注意:本书并没有列出所有的类,而是一些重要的基础类,其它类请参考BIMBase C++ API说明文档.chm。
3.1.2 如何获取对象
BIMBase中的对象都有一个BPDataKey
,我们可以通过BPDataKey
从BPProject
中获取这个元素。一般可通过其它接口获取相应的BPDataKey
,然后获取对象。
- 获取选择的对象
使用选择集管理类BPSelectionSetManager
用户可以获得被选中的元素。
for (int i = 0; i < BPSelectionSetManager::getInstance().getCount(); i++)
{
BPEntityPtr ptrEntity = BPSelectionSetManager::getInstance().
getEntityByIndex(i);
if (ptrEntity.isNull())
continue;
BPDataKey key = BPDataUtil::getDataKeyOnEntity(*ptrEntity);
}
代码3-1:通过BPSelectionSetManager获取对象(代码片段)
- 通过class获取对象
BIMBase API提供接口通过class
获取某个类型的所有对象,具体代码如下所示。
BPProjectP pProject = BPApplication::getInstance().
getProjectManager()->getMainProject();
if (pProject == nullptr)
return;
pset<BPEntityId> entitySet;
BPEntityUtil::getEntitiesByClass(entitySet, *pProject, L"schemaName", L"className");
for (auto entityId : entitySet)
{
BPEntity entity(entityId);
BPDataKey key = BPDataUtil::getDataKeyOnEntity(entity);
}
代码3-2:通过class获取对象(代码片段)
- 获取某个模型空间的所有对象
BIMBase API提供接口获取某个模型空间的所有对象,具体代码如下所示。
BPProjectP pProject = BPApplication::getInstance().getProjectManager()->getMainProject();
if (pProject == nullptr)
return;
pset<BPEntityId> entitySet;
BPEntityUtil::getEntitiesOfModel(entitySet,*pProject,pProject->getActiveModel()->getModelId());
for (auto entityId : entitySet)
{
BPEntity entity(entityId);
BPDataKey key = BPDataUtil::getDataKeyOnEntity(entity);
}
代码3-3:获取活动模型空间的所有对象(代码片段)
3.1.3 获取和修改元素参数
- 获取参数
元素都有参数,用户可以通过文档查找对象的所有参数条目,然后通过BPObject
的getValue
接口获取到元素的参数。 - 修改参数
用户可以用BPObject
的setValue
接口修改元素的参数。
3.1.4 重要的方法
- 对象的位置
通过BPGraphicElement
的setPlacement
方法,可设置对象的位置,对象的位置包含对象的偏移和旋转信息。 - 获取对象的图素信息
通过BPGraphicElement
的createPhysicalGraphics
方法,可创建对象的图素信息,用于几何解析和动态绘制。
3.1.5 领域对象的创建
- 内建对象的创建
BIMBase图形对象的创建一般使用对象的构造函数,对象构造出来以后,调用addToProject
接口将对象添加到相应的工程及模型空间。
BPProjectP pProject = BPApplication::getInstance().
getProjectManager()->getMainProject();
if (pProject == nullptr)
return;
BPModelBaseP pModel = pProject->getActiveModel();
if (pModel == nullptr)
return;
//创建线对象
BPModelLine line(GePoint3d::create(3000, 3000, 0), GePoint3d::create(4000, 4000, 0));
//将对象保存到model
::p3d::P3DStatus status = line.addToProject(*pProject, pModel->getModelId());
代码3-4:内建对象的创建(代码片段)
- 自建对象的创建
当BIMBase中已有对象不能满足用户需求时,用户可通过实现一个继承自BPGraphicElement
的类,构造自己的对象,主要分为以下三步:
- 创建对象的数据表(schema),用于在工程中保存对象,具体步骤见附录二;
- 实现继承自
BPGraphicElement
的类,见示例代码3-5,3-6; - 注册构件,一般在插件加载时进行注册,例如在插件的
dllMain
函数中加载。示例代码见3-7;
示例代码3-8为该自建对象cube
的自测函数,类似1.1节的HelloBIMBase
命令的注册,打开BIMBase在命令行输入已经注册的命令“CubeDemo”
,即可在BIMBase中调出自己所创建的对象(无需写出工具再来调用对象)。
注意:
- 具体schema文件生成过程请查看附录二
- schema字段说明见附录三
#pragma once
namespace DemoObject
{
class CubeDemo;
typedef CubeDemo const& CubeDemoCR;
typedef CubeDemo& CubeDemoR;
typedef CubeDemo* CubeDemoP;
typedef RefCountedPtr<CubeDemo> CubeDemoPtr;
class CubeDemo : public BIMBase::Data::BPGraphicElement
{
DefineSuper(BPGraphicElement)
public:
CubeDemo();
~CubeDemo();
int getWidth() const;
void setWidth(int nWidth);
int getLength() const;
void setLength(int nLength);
int getHeight() const;
void setHeight(int nHeight);
protected:
virtual Utf8String _getSchemaName() const override { return PBM_SCHEMA_Demo; };
virtual Utf8String _getClassName() const override { return PBM_CLASS_CUBE_Demo; };
//往数据库中写数据
virtual P3DStatus _copyToData(BPDataR instance, BPProject& project) const override;
//从数据库中读数据
virtual P3DStatus _initFromData(BPDataCR instance) override;
//创建几何造型
virtual BPGraphicsPtr _createPhysicalGraphics(BPProjectR project,PModelIdCR modelId, bool isDynamics) override;
private:
int m_nWidth;
int m_nHeight;
int m_nLenght;
Demo_CREATE(CubeDemo);
};
Demo_EXTENSION(CubeDemo);
}
代码3-5:实现自己的构件对象(头文件)
#include "pch.h"
#include "CubeDemo.h"
#define Property_Lenght "Length"
#define Property_Width "Width"
#define Property_Height "Height"
using namespace DemoObject;
CubeDemo::CubeDemo()
{
m_nLenght = 1000;
m_nWidth = 200;
m_nHeight = 3000;
}
CubeDemo::~CubeDemo()
{}
int CubeDemo::getWidth() const {
return m_nWidth;
}
void CubeDemo::setWidth(int nWidth) {
m_nWidth = nWidth;
}
int CubeDemo::getLength() const {
return m_nLenght;
}
void CubeDemo::setLength(int nLength) {
m_nLenght = nLength;
}
int CubeDemo::getHeight() const {
return m_nHeight;
}
void CubeDemo::setHeight(int nHeight) {
m_nHeight = nHeight;
}
::p3d::P3DStatus CubeDemo::_copyToData(BIMBase::Core::BPDataR instance, BIMBase::Core::BPProject& project) const
{
if (T_Super::_copyToData(instance, project) != P3DStatus::SUCCESS)
return ERROR;
P3DStatus status;
status = instance.setValue(Property_Lenght, BPValue(this->getLength()));
if (P3DStatus::SUCCESS != status)
return ERROR;
status = instance.setValue(Property_Width, BPValue(this->getWidth()));
if (P3DStatus::SUCCESS != status)
return ERROR;
status = instance.setValue(Property_Height, BPValue(this->getHeight()));
if (P3DStatus::SUCCESS != status)
return ERROR;
return SUCCESS;
}
::p3d::P3DStatus CubeDemo::_initFromData(BIMBase::Core::BPDataCR instance)
{
if (T_Super::_initFromData(instance) != P3DStatus::SUCCESS)
return ERROR;
BPValue value;
P3DStatus status;
status = instance.getValue(value, Property_Lenght);
if (P3DStatus::SUCCESS != status)
return ERROR;
setLength(value.getInteger());
status = instance.getValue(value, Property_Width);
if (P3DStatus::SUCCESS != status)
return ERROR;
setWidth(value.getInteger());
status = instance.getValue(value, Property_Height);
if (P3DStatus::SUCCESS != status)
return ERROR;
setHeight(value.getInteger());
return SUCCESS;
}
BPGraphicsPtr CubeDemo::_createPhysicalGraphics(BPProjectR project, PModelIdCR modelId, bool isDynamics)
{
BPModelPtr ptrModel = project.getModelById(modelId);
if (ptrModel.isNull())
return nullptr;
BPGraphicsPtr ptrGraphic = ptrModel->createPhysicalGraphics();
if (ptrGraphic.isNull())
return nullptr;
int nWidth = getWidth();
int nLength = getLength();
int nHeight = getHeight();
//绘制底部外轮廓
pvector<GePoint3d> pts;
pts.push_back(GePoint3d::create(0, -nWidth / 2, 0));
pts.push_back(GePoint3d::create(nLength, -nWidth / 2, 0));
pts.push_back(GePoint3d::create(nLength, nWidth / 2, 0));
pts.push_back(GePoint3d::create(0, nWidth / 2, 0));
pts.push_back(GePoint3d::create(0, -nWidth / 2, 0));
GeCurveArrayPtr ptrOutLines = GeCurveArray::createLinestringArray(pts, GeCurveArray::BOUNDARY_TYPE_Outer);
//向Z方向拉伸
GeVec3d vec = GeVec3d::create(0, 0, nHeight);
GeExtrusionInfo extrData(ptrOutLines, vec, true);
IGeSolidBasePtr ptrExtrusion = IGeSolidBase::createGeExtrusion(extrData);
ptrGraphic->addGeSolidBase(*ptrExtrusion);
return ptrGraphic;
}
代码3-6:实现自己的构件对象(源文件)
//注册运行时类型判断
BPObjectExtensionManager::getInstance().registerBPObjectExtension(PBM_SCHEMA_DEMO,PBM_CLASS_CUBE_DEMO, new CubeDemoExtension());
代码3-7:注册自己的构建对象
void CubeDemoFun()
{
BPProjectP pProject = BPApplication::getInstance().getProjectManager()->getMainProject();
if (pProject == nullptr)
return;
BPModelBaseP pModel = pProject->getActiveModel();
if (pModel == nullptr)
return;
PModelId modelId = pModel->getModelId();
DemoObject::CubeDemo pcube;
pcube.setWidth(2000);
pcube.setLength(3000);
pcube.setHeight(800);
pcube.addToProject(*pProject, modelId);
BPViewportP pViewPort = BPViewManager::getInstance().getActivedViewport();
if (NULL == pViewPort)
return ;
if (pViewPort)
{
pViewPort->updateView();
}
}
AutoDoRegisterFunctionsBegin
BPToolsManager::registerFun(_T("CubeDemo"), &CubeDemoFun);
AutoDoRegisterFunctionsEnd
代码3-8:立方体造型自测函数
示例代码3-4,3-5,3-6实现了一个自定义的立方体构件,如图3-4所示,通过立方体的长、宽、高进行构造。
注意:代码3-6中的Length、Width与Height需要在schema中Class属性定义,否则代码无法运行。
示例代码3-7对象的注册是必不可少的,主要用于在BPObjectExtensionManager
中获取自己的构件,如实现对象属性中需要用到,对象的注册需要在工程启动时就进行。

图3-4 立方体构件
示例代码3-5,3-6实现继承自BPGraphicElement
的类CubeDemo
,CubeDemo
类中主要完成了如下几个工作:
- 定义长、宽、高三个属性及其
get
、set
接口。 - 在
copyToData
中实现保存属性值到数据,在initFromData
中实现从数据中初始化属性值。 - 重写
BPGraphicElement
中的_createPhysicalGraphics
接口,根据CubeDemo
的Length、Width、Height构造立方体图形。
至此,自建对象CubeDemo
构造完毕,可同内建对象一样通过addToProject
接口保存到工程中。