经过上面三步走的练习,相信大家已经了解插件开发的要素和基础工作流程。本小节以App市场中《围墙清单插件》举例,为大家介绍一个实际插件的组成部分。

2.2.1 围墙清单插件功能分析

插件的制作要以具体的功能场景为依托,不宜过大,明确插件和软件两者概念的区别,才能提高插件的使用率,并在实际应用中为用户切实的解决问题,下面以围墙清单为示例来描述一个插件的完整制作流程。

【需求】

施工过程中围墙的建造需要明确围墙的具体位置、设计高度以及所需的总长度。这些参数将直接影响围墙的结构设计,而围墙出于美观性和提高施工效率的考虑常设有“标准单片长度”。因此施工人员需要了解工程中围墙的完整遮挡个数和补充长度,便于更准确地计算所需材料的数量,避免材料浪费或不足。

【围墙清单插件使用说明】

1. 点击APP市场后,下载安装“围墙清单”插件

2. 点击“自动配置环境”,弹出控制台窗口,自动下载“围墙清单”运行所需要的第三方库

3. 点击“组件建模”菜单下的“参数化组件库”按钮进入“场地建模”类别,布置若干围墙,这里以围墙3为例,布置若干围墙供计算使用

4. 点击“围墙清单”按钮并框选需要进行计算的围墙,右键确认

\

5. 等候1-2秒,会自动弹出计算好的Excel表格

2.2.2 围墙清单插件开发详解

如何找到源码

用户可以在本地文件夹中找到围墙清单的开发源码,位于BIMBase安装目录下的App文件夹中,可以使用Visual Studio Code打开“3围墙清单”文件夹。

围墙清单插件功能实现流程

下面请跟随示例了解“围墙清单”插件功能的实现流程,下文将进行详细的代码剖析。首先,在Visual Studio Code中打开“围墙清单.py”脚本,对照代码内容进行逐步理解:
导入相关功能包

from pyp3d import *
import os
from openpyxl import *
from openpyxl.styles import *

pyp3d:BIMBase软件python开发功能包,包含丰富的几何造型

os:python标准库,提供了与操作系统的交互操作,包括文件执行和目录执行操作

openpyxl:专门用于读写Excel文件,允许用户创建和修改Excel表格。

将脚本位置加入全局变量

path = sys.argv[0]
set_global_variable('\a_path', path[0:-3])

path为当前脚本的绝对路径,将绝对路径的“.py”后缀删除并存入全局变量,便于BIMBase执行时找到脚本位置。(不写这个可能会在BIMBase运行没有反应哦!)
ü获取当前框选到的实体,返回值中每一个entity对应一个几何实体

entitys = get_element_from_boxselect()

遍历当前实体,并逐个判断实体有效性,若为有效,则从entity中取出用于持久化操作的datakey,并从datakey中获取当前实体的全部几何信息。Noumenon是一个无序map,可以通过map的字段筛查,找出有效的围墙实体。

for i in entitys:
   if entityid_isvaid(i):
   # 获取模型属性
datakey = get_datakey_from_entity(i)
      noumenon = get_noumKV_from_instancekey(datakey)

可以进行清单计算的围墙实体均经过特殊处理,noumenon中包含“补充长度”字段,在下面这一步中可以将经过处理的围墙筛选出来

supple_keys_i=[string for string in list(noumenon.keys()) if '补充长度' in string]
   if not supple_keys_i:
continue

在围墙的全部属性中筛选出期望导出进excel表格的属性,其中字段中包含‘\07‘的为固有属性,因此用户若要导出关键信息,此for循环为必要条件。

d = {}
   for k, j in noumenon.items():
      if not isinstance(j, bytearray):
         d[k] = j
      if ('\x07' not in k) and (k not in Tempfilter):
         all.add(k)
   temp.append(d)
   supple_keys_i.reverse()
   supple_keys.append(supple_keys_i)

若存在围墙实体,则根据key作为表头建立Excel表格的内容,并可根据场景需求进行自定义添加。

    if not temp:
       messages("未选择实体!")
       exit()
    supplehead = [i+"(mm)" for i in max(supple_keys)]
    headName = ["序号","构件名称","专业","构件类别","数量","单片围墙高度(mm)","单片围墙长度(mm)","完整围挡个数(片)"]+supplehead+["围墙总长(mm)","备注"]

以下包含通过openxl创建表格的全部内容,为了便于理解,已经逐行添加注释。
# 创建表
wb = Workbook()
# 创建sheet
sheet = wb.create_sheet('清单', 0)
# 合并单元格
sheet.merge_cells(start_row=1, start_column=1,
end_row=1, end_column=len(headName))
sheet.merge_cells(start_row=2, start_column=1,
end_row=2, end_column=len(headName))
sheet.merge_cells(start_row=3, start_column=1,
end_row=3, end_column=len(headName))
# 黑边框定义
border = Border(top=Side(border_style='thin', color='FF000000'),
               right=Side(border_style='thin', color='FF000000'),
               bottom=Side(border_style='thin', color='FF000000'),
               left=Side(border_style='thin', color='FF000000'))
# 居中样式
center = Alignment(horizontal='center', vertical='center')
# 字体字号,加粗
font = Font(size=20, bold=True)
# 字体字号,加粗
font2 = Font(size=10, bold=True)
# 填充单元格颜色
fill = PatternFill(fill_type="solid", start_color="808080")
# 单元格控制
sheet.cell(row=1, column=1).alignment = center
sheet.cell(row=1, column=1).value = "算量清单"
sheet.cell(row=1, column=1).font = font
sheet.cell(row=2, column=1).value = "工程名称"+'   '*ceil((len(headName)+3)/2)+"工程编号"
sheet.cell(row=2, column=1).font = font2
sheet.cell(row=3, column=1).value = "总包单位"+'   '*ceil((len(headName)+3)/2)+"合同编号"
sheet.cell(row=3, column=1).font = font2
# 表头
for i in range(len(headName)):
sheet.cell(row=4, column=1+i).alignment = center
sheet.cell(row=4, column=1+i).value = headName[i]
sheet.cell(row=4, column=1+i).fill = fill
sheet.column_dimensions[chr(i+65)].width = len(headName[i])*2.5

# 内容
for i in range(5,len(temp)+5):
sheet.cell(row=i, column=1).value = i-4
sheet.cell(row=i, column=2).value = temp[i-5]["构件名称"]
sheet.cell(row=i, column=3).value = temp[i-5]["场布分类"]
sheet.cell(row=i, column=4).value = temp[i-5]["构件类型"]
sheet.cell(row=i, column=5).value = 1
sheet.cell(row=i, column=6).value = temp[i-5]["单个围挡高度"]
sheet.cell(row=i, column=7).value = temp[i-5]["柱间距"]
sheet.cell(row=i, column=8).value = temp[i-5]["完整围挡个数"]
for j,supple_key in enumerate(supple_keys[i-5]):
      if temp[i-5][supple_key]>0:
      sheet.cell(row=i, column=9+j).value = round(temp[i-5][supple_key],2)
sheet.cell(row=i, column=len(headName)-1).value = round(temp[i-5]["整体长度"],2)
sheet.cell(row=i, column=len(headName)).value = "含补充段"

将文件保存,文件名为“算量清单(单行)” 保存路径为

wb.save(os.path.dirname(__file__)+'\\算量清单(单行).xlsx')
wb.close()
os.startfile(os.path.dirname(__file__)+'\\算量清单(单行).xlsx')

若用户希望自己创建的插件可以在所有用户的电脑上正常可用,则需要仿照2.2.1中的“自动配置环境”功能来自定义一个bat批处理文件,用于自动部署环境并安装特定的Python包,关键步骤代码及相关注释如下所示。

@echo off 
echo Starting automatic deployment of the environment...
echo.
cd %~dp0
cd ..
cd ..
cd ..
REM 设置pyPath变量为Python解释器的路径
set pyPath=%CD%\PythonScript\python-3.7.9-embed-amd64\
REM 设置pipPath变量为pip工具的路径
set pipPath=%CD%\PythonScript\python-3.7.9-embed-amd64\Scripts\
REM 在命令台打印安装信息,便于用户查看
echo Python interpreter path: %pyPath%
echo.
echo Pip3 path: %pipPath%
echo.
echo Pip3 installing
echo.
REM 使用Python解释器执行get-pip.py脚本来安装pip。这里使用了清华大学的PyPI镜像源来加速安装。
"%pyPath%\python.exe" "%pyPath%\get-pip.py" -i https://pypi.tuna.tsinghua.edu.cn/simple/
echo.
echo openpyxl installing
echo.
REM 使用pip工具安装openpyxl包。openpyxl是一个用于处理Excel文件的Python库。同样,这里使用了清华大学的PyPI镜像源。
"%pipPath%\pip3.exe" install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple/
@PAUSE

用户可以编写脚本来自动运行上述bat批处理文件。

import os
os.startfile(os.path.dirname(__file__)+"\\自动配置环境.bat")

最后,用户需要配置.pyplugin文件,实现插件在BIMBase菜单中正常显示,pyplugin具体内容见章节2.1.2.2,这里暂不做赘述。

<?xml version="1.0" encoding="UTF-8"?>
<BIMPyPlugin>
    <BfaLibName>围墙清单</BfaLibName>
    <PluginVersion>1.0.0</PluginVersion>
    <LoadStatus>true</LoadStatus>
    <Category name="围墙清单">
        <Panel name="围墙清单">
            <Button name="自动配置环境">
                <command>围墙清单\\自动配置环境.py</command>
                <iconPath>插件管理.ico</iconPath>
            </Button>
            <Button name="围墙清单">
                <command>围墙清单\\围墙清单.py</command>
                <iconPath>围墙清单.ico</iconPath>
            </Button>
        </Panel>
    </Category>
</BIMPyPlugin>

完成上述文件编写后,需按照章节2.1.2.3中所述,将文件夹移动到APP文件夹中,重新启动BIMBase,即可在菜单中看到“围墙清单”插件,点击按钮并框选围墙后,右键会在脚本同目录下发现对应的Excel文件


表格内容如下所示,与章节2.2.1中所演示的表格内容相同:


至此,即完成了围墙清单插件python脚本的全部内容。