通用应用BIMBase API实现一个两点画线功能了解BIMBase基本工具。
BIMBase API提供了两种实现两点画线功能的机制。一是通过BPPrimitiveTool提供的接口实现,二是在通过类ADS/ARX的拾取点接口实现。

  • BPPrimitiveTool实现
    BPPrimitiveTool是BIMBase API提供的一种交互机制,BPPrimitiveTool类中对于工具启动、左键点击、右键点击、鼠标移动等都提供了虚接口,通过实现这些虚接口即可实现相应的功能,如下代码所示。
class ToolLayoutLineDemo : public BPPrimitiveTool
{
    DefineSuper(BPPrimitiveTool)
public:
    ToolLayoutLineDemo();
    ~ToolLayoutLineDemo();
protected:
    virtual p3d::Utf8CP _getToolName() const {return "layoutLineDemo";}
    virtual void _onPostInstall() override;
    virtual void _onRestartTool() override;
    virtual bool _onDataButton(BPBaseButtonEventCP) override;
    virtual bool _onResetButton(BPBaseButtonEventCP) override;
    virtual void _onDynamicFrame(BPBaseButtonEventCP) override;
    virtual bool _onModelMotion(BPBaseButtonEventCP ev) override;
private:
    int m_nStep;
    GePoint3d m_ptC;
    BPGraphicsPtr m_ptrGraphic;
};

代码2-2 两端点画线(头文件)

#include "pch.h"
#include "ToolLayoutLineDemo.h"

ToolLayoutLineDemo::ToolLayoutLineDemo()
{
    m_nStep = 0;
}

ToolLayoutLineDemo::~ToolLayoutLineDemo()
{
}
void ToolLayoutLineDemo::_onPostInstall()
{
    T_Super::_onPostInstall();    
    BPSnap::getInstance().enableLocate(false);
    BPSnap::getInstance().enableSnap(true);
}
void ToolLayoutLineDemo::_onRestartTool()
{
    ToolLayoutLineDemo* newTool = new ToolLayoutLineDemo();
    newTool->installTool();
}
bool ToolLayoutLineDemo::_onDataButton(BPBaseButtonEventCP ev)
{
    BPViewportP pViewport = ev->getViewport();
    if (NULL == pViewport ) 
        return false;    
    BPModelP pModel = pViewport->getTargetModel();
    if (pModel == nullptr)
        return false;
    GePoint3d ptE = *ev->getPoint();
    if (m_nStep == 0)
    {
        m_ptC = *ev->getPoint();
        m_nStep = 1;
    }
    else if (m_nStep == 1)
    {
        if (m_ptrGraphic.isNull())
            return false;
        m_ptrGraphic->save();
        m_nStep = 0;
    }
    return true;
}
bool ToolLayoutLineDemo::_onResetButton(BPBaseButtonEventCP)
{
    _exitTool();
    return true;
}
void ToolLayoutLineDemo::_onDynamicFrame(BPBaseButtonEventCP ev)
{
    if (NULL == ev)
        return;
    if (m_nStep == 0)
        return;
    BPViewportP pViewport = ev->getViewport();
    if (NULL == pViewport)
        return;
    BPModelP pModel = pViewport->getTargetModel();
    if (pModel == nullptr)
        return;
    IGeCurveBasePtr Line = IGeCurveBase::createSegment (GeSegment3d::create(m_ptC, *ev->getPoint()));
    m_ptrGraphic = pModel->createPhysicalGraphics();
    m_ptrGraphic->addGeCurve(*Line.get());
    m_ptrGraphic->finish();

    BPRedrawEntitys redrawElems;
    redrawElems.setDrawMode(BPDrawMode::enTempDraw);
    redrawElems.setDrawPurpose(BPDrawPurpose::enDynamics);
    redrawElems.setDynamicsViews(pViewport);
    redrawElems.doRedraw(m_ptrGraphic->getEntityR());    
}

bool ToolLayoutLineDemo::_onModelMotion(BPBaseButtonEventCP ev)
{
    if (!getDynamicsStarted())
        _beginDynamics();
    return true;
}
//对工具进行注册
BPTool* CreateLineTool()
{
    ToolLayoutLineDemo* tool = new ToolLayoutLineDemo();
    return tool;
}
AutoDoRegisterFunctionsBegin
BPToolsManager::registerTool("layoutLineDemo", &CreateLineTool);
AutoDoRegisterFunctionsEnd

代码2-3 两端点画线(源文件)

需要指出的是,若想完整运行此代码,需要对pch.hpch.cpp文件进行补充,如代码2-4与代码2-5所示,此说明适用于后续开发资料中的所有例子。

#pragma once

#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN            // 从 Windows 头中排除极少使用的资料
#endif
#include "targetver.h"
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // 某些 CString 构造函数将是显式的
#include <afxwin.h>         // MFC 核心组件和标准组件
#include <afxext.h>         // MFC 扩展
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxole.h>         // MFC OLE 类
#include <afxodlgs.h>       // MFC OLE 对话框类
#include <afxdisp.h>        // MFC 自动化类
#endif // _AFX_NO_OLE_SUPPORT
#ifndef _AFX_NO_DB_SUPPORT
#include <afxdb.h>                      // MFC ODBC 数据库类
#endif // _AFX_NO_DB_SUPPORT
#ifndef _AFX_NO_DAO_SUPPORT
#include <afxdao.h>                     // MFC DAO 数据库类
#endif // _AFX_NO_DAO_SUPPORT
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxdtctl.h>           // MFC 对 Internet Explorer 4 公共控件的支持
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>                     // MFC 对 Windows 公共控件的支持
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxcontrolbars.h>     // 功能区和控件条的 MFC 支持
#include "BcgFrame/BCGCBProInc.h"
#include <boost/integer.hpp>
#include <boost/integer_fwd.hpp>
#include <boost/bimap.hpp>
#include "resource.h"
#include <vector>
#include <map>
#include <algorithm>
#ifndef PI
#define PI ((double)3.1415926535897932)
#endif
using namespace std;
// 1. 图形平台基础数据头文件
#include "BPExportMacros.h"
#include "PKPMExportMacros.h"
#include "P3DDC/P3DDCAPI.h"
#include "P3DGeomObject/P3DGeomObjectPublicAPI.h"
// 2. BIMBase Publish API头文件
#include "JsonCpp/JsonCppAPI.h"
#include "BPBase/BPBaseAPI.h"
#include "BPData/BPDataAPI.h"
#include "BPDataCore/BPDataCoreDef.h"
#include "BPDataCore/BPDataCoreAPI.h"
#include "BPDataCore/BPPlacement.h"
#include "BPDataCore/BPDomainDataInitManager.h"
#include "BPDataCore/BPEntitySymbologyEvent.h"
#include "BPDisplay/BPDisplayAPI.h"
#include "BPInteraction/BPInteractionAPI.h"
#include "BPFrame/BPFrameAPI.h"
#include "BPSolidCore/BPSolidCoreAPI.h"
#include "BPBase/BPPlatformAPI.h"
// 3. 专业平台头文件
#include "TgGe/TgGe.h"
#include "PBClashDetection/PBClashDetectionAPI.h"
#include "PBClashDetection/ClashDetection.h"
#include "PBBimCore/PBBimCoreAPI.h"
#include "BPApp/PBBimAppAPI.h"
#include "PBPlatform/PBPlatformAPI.h"
#include "PBBimCore/PBClippingEvent.h"
#include "PBBimUtilities/rapidjson/document.h"
#include "PBBimUtilities/rapidjson/stringbuffer.h"
#include "PBBimUtilities/rapidjson/Writer.h" 
#include "BPUIFrameWork/BPUIFrameWorkAPI.h"
#include "BPUIFrameWork/BPUIFrameWorkUtil.h"
#include "BPUIFrameWork/BPNewDockContainer.h"
#include "BPUIFrameWork/BPNewDockManager.h"
#include "BPUIFrameWork/RButtonClickItem.h"
#include "BPUIFrameWork/BPViewRButtonClickListener.h"
#include "BPUIFrameWork/BPViewRButtonClickListenerCenter.h"
#include "BPApp/PBToolSettingManager.h"
#include "PBBimUtilities/PBimsErrExceptionUtil.h"
#include "PBBimTools/PBBimToolsAPI.h"
#include "BPPrimaryElement/BPHatchVardef.h"
#include "BPPrimaryElement/BPPrimaryGeomAPI.h"
#include "BPPrimaryElement/BPHatchDefine.h"
#include "BPPrimaryElement/BPHatch.h"
#include "BPPrimaryElement/BPHatchPattern.h"
#include "BPPrimaryElement/BPHatchPatternManager.h"
//2.资源切换头文件
#include "PBBimCore/PBBimExtensionModule.h"
#include "PBBimCore/PBBimCoreAPI.h"
#include "BPUIFrameWork/BPNewDockManager.h"
#include "BPUIFrameWork/BPNewDockContainer.h"
using namespace PBBim;
using namespace PBBim::PBBimCore;
using namespace BIMBase;
using namespace P3DApi::P3DApplication;
using namespace BIMBase::Data;
using namespace BIMBase::Core;
using namespace BIMBase::SolidCore;
//材质
#include"MaterialConfig/BPMaterialEx.h"
//数据交换
#include "DataExchange/DataExchangeAPI.h"
//属性面板相关
#include "Share/Common/WDPublicDef.h"
#include"Share/Common/ExportMacro.h"
#include "WDUi/WDToolProperty.h"
//追踪器相关
#include "Common/SDDef.h"
#include "WDUi/TracerMacros.h"
#include "WDUi/WDTracerCustomFunPool.h"
//施工图相关
#include "BPPrimaryElement/BPTextEntity.h"
//范例相关 需自行补充
#include "resource.h"
#include "ExampleDef.h"
#include "CubeDemo.h"

代码2-4 头文件列表

#include "pch.h"

#pragma comment (lib, "P3DDC.lib")
#pragma comment (lib, "P3DGeomBase.lib")
#pragma comment (lib, "P3DGeomObject.lib")
#pragma comment (lib, "BPDataCore.lib")
#pragma comment (lib, "TgGe.lib")
#pragma comment (lib, "BPPlatform.lib")
#pragma comment (lib, "BPSolidCore.lib")
#pragma comment (lib, "BPDataExt.lib")
#pragma comment (lib, "JsonCpp.lib")
#pragma comment (lib, "BPDrawingCommon.lib")
#pragma comment (lib, "BPUIFrameWork.lib")
#pragma comment (lib, "BPApp.lib")
#pragma comment (lib, "BPApp.lib")
#pragma comment (lib, "BPMaterialConfig.lib")
#pragma comment (lib, "BPDataCore.lib")
#pragma comment (lib, "BPParametricBase.lib")
#pragma comment (lib, "BPPrimaryElement.lib")
#pragma comment (lib, "BPPluginManager.lib")

#ifdef DEBUG
#pragma comment (lib, "WDUiD.lib")
#else
#pragma comment (lib, "WDUi.lib")
#endif

代码2-5 lib库列表

该例子通过重写BPPrimitiveTool类中_onDataButton接口实现在第一次左键点击时确认线段的第一个点,第二次左键时得到线段的第二个点,并用第一个点和第二个点构造线段并保存到工程;重写_onDynamicFrame接口,通过得到的动态点与第一个点构造线段并动态显示,实现线段的动态预览。
通过重写BPPrimitiveTool实现的工具需要使用BPToolsManager管理类进行注册才能在软件中进行调用。

  • 通过类ADS/ARX的拾取点接口实现
    通过BIMBase API提供的拾取点接口,在注册的命令中实现两点画线功能。
    该例子通过BIMBase API提供的getPoint接口实现交互,获取线段的端点坐标,构造线段并保存到工程。
void AdsLineDemo()
{
    BPProjectP pProject = BPApplication::getInstance().getProjectManager()->getMainProject();
    if (pProject == nullptr)
        return ;
    BPModelBaseP pModel = pProject->getActiveModel();
    if (pModel == nullptr)
        return;
    BPGraphicsPtr ptrGraphic = pModel->creatPhysicalGraphics();
    if (ptrGraphic.isNull())
        return;

    double pFirst[3], pSecond[3];
    getPoint(nullptr, "Select first point", pFirst);
    getPoint(nullptr, "Select second point", pSecond);

    GePoint3d ptFirst = GePoint3d::create(pFirst[0], pFirst[1], pFirst[2]);
    GePoint3d ptSecond = GePoint3d::create(pSecond[0], pSecond[1], pSecond[2]);
    ptrGraphic->addGeCurve(*IGeCurveBase::createSegment(GeSegment3d::create(ptFirst, ptSecond)));
    ptrGraphic->save();
    }
AutoDoRegisterFunctionsBegin
BPToolsManager::registerFun(_T("AdsLineDemo"), &AdsLineDemo);
AutoDoRegisterFunctionsEnd

}

代码2-6 类ADS/ARX接口实现两点画线(代码片段)