简介
OBV为开发者提供了二次开发的接口,供用户开发自己的插件,同时OBV也包含内置插件。
Markup插件
https://cloud.pkpm.cn/devcenter/api/obv/markup/index.html
参考示例:添加批注
Measure插件
https://cloud.pkpm.cn/devcenter/api/obv/measure/index.html
Marker插件
marker用于在构件或图纸上创建关联信息的锚点。锚点可以是三维空间中具体的点位(也可以是二维图纸中的某一个点)。锚点的展示形式可是文字或者图片,并支持设置自定义样式。
【名词解释】
- 锚点:marker,标定marker位置的一个点,默认的锚点显示样式是一个小圆圈中间一个“i”。
- 标签:annotation,每个锚点默认会附带一个标签,锚点和标签之间用线段连接,标签中可记录相应信息。默认标签显示样式是矩形框,框中记录对应文字。标签可设置隐藏。
参考示例:给模型添加标注
获取插件对象
在加载模型时配置加载marker插件,在obv的load3dModels方法之后可通过obvApi获取到插件对象,详细可参考官网示例。
const markerAddinId = 'OBVAddins.Marker';// 插件ID
const addinManager = obvApi.getAddinManager();
markerAddin = addinManager.getAddin(markerAddinId );
createTextSymbolMarker
创建带文字标签的锚点
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| position | THREE.Vector3 | 是 | 锚点的位置。 |
| textSymbol | string | 是 | 锚点中的文字标记,可传入空字符串,传入空字符时串默认显示从1开始递增的数字 |
| tag | string | 是 | 设置tag可用于将锚点进行分组,如果不需要用到可传入空字符串 |
| message | string | 是 | marker的标签中显示的文字 |
| externalId | string | 是 | 外部自定义的锚点的ID,可通过这个ID获取到对应的锚点,可为空字符串 |
| offsetX | number | 否 | 标签相对于锚点的x方向偏移值,向右为x正方向,向下为y正方向,默认为0 |
| offsetY | number | 否 | 标签相对于锚点的y方向偏移值,默认为0 |
| customizedStyles | ICustomizedStyles | 否 | 锚点和标签样式的部分可定义样式属性,具体支持的设置项见下文参数说明 |
| styleCallback | number | 否 | 通过回调函数可以完全自定义标签和锚点的样式,以(annotation, anchor) => {} 的形式返回标签和锚点的dom元素 |
【参数说明】
customizedStyles和styleCallback作用类似,都可用于设置锚点和标签的样式。customizedStyles参数支持的设置项比较有限,推荐用户通过styleCallback的形式自定义锚点样式。 customizedStyles支持的参数有:
/**
* 标签字体颜色
*/
annotationColor?: string;
annotationFontSize?: string;
/**
* 标签背景色
*/
annotationBackgroundColor?: string;
/**
* 标签的边框颜色
*/
annotationBorderColor?: string;
/**
* 锚点的字体颜色
*/
anchorColor?: string;
/**
* 锚点的背景色
*/
anchorBackgroundColor?: string;
/**
* 锚点边框颜色
*/
anchorBorderColor?: string;
/**
* 锚点和标签连接线的颜色
*/
lineColor?: string;
/**
* 锚点和标签连接线的线宽
*/
lineWidth?: number;
/**
* 使用图片作为锚点时指定图片的x偏移,默认为图片中心
*/
picAnchorOffsetX?: number;
/**
* 使用图片作为锚点时指定图片的y偏移
*/
picAnchorOffsetY?: number;
使用styleCallback可以支持完全的用户自定义样式,在实际使用中由于插件内部需要提前计算marker相对位置,用户通过回调函数改变marker样式可能会改变marker的宽高导致插件计算的锚点相对位置失效,因此在回调函数中更改样式后需要主动调用markerAddin.tool.setNumMarkerPosition方法刷新锚点图片位置。具体使用参考示例。
样例(Example):
const customizedStyles = {
anchorColor: 'rgb(57, 72, 71)',// 锚点颜色
anchorBorderColor: 'rgb(31, 147, 225)',// 锚点边框颜色
annotationColor: '#000000',// 标签颜色
annotationBackgroundColor: 'rgb(238,238,238)',// 标签背景色颜色
annotationBorderColor: 'rgb(31, 147, 225)',// 标签边框颜色
annotationFontSize: '12px',// 标签字体大小
lineColor: 'rgb(31, 147, 225)',// 锚点和标签连接线的颜色
lineWidth: 2,// 锚点和标签连线线宽
};
const dbIds = [{modelId: 1, dbId: 13}, {modelId: 1, dbId: 12}];
const offset = [20, 30];
for(const node of dbIds){
// 对于三维,position是一个THREE.Vector3向量;
// 对于矢量二维,position是通过Marker.MarkerEventTypes.VIEWER_CLICKED事件得到的event.data数据;
// 对于doc文档,position也是通过Marker.MarkerEventTypes.VIEWER_CLICKED事件得到的event.data的数据。
// 由于doc类型文档存在多页的情况,因此在doc文档上添加标记时还需要传入页码、canvas大小等信息,这些信息在Marker.MarkerEventTypes.VIEWER_CLICKED事件监听中可以获得
// 此处以三维为例,分别以每个构件的包围盒中心点创建锚点
let bbox = obvApi.getObjectsBounds([node]);
// 如果使用了styleCallback自定义样式,加载插件时的unRepeatMarkerPos属性就无法生效了,因为使用这个回调函数有可能改变anchor的大小,导致计算锚点的平铺位置失效
const center = new THREE.Vector3();
bbox.getCenter(center);
//以此构件包围盒中心点为锚点,创建标记为“i”的锚点标签
markerAddin.createTextSymbolMarker(
center,
'i',
'tag1',
'first marker',
'id-1',
offset[0],
offset[1],
null,
(annotation, anchor) => {
// 在回调函数中更改标签的背景色为indianred
annotation.style.backgroundColor = 'indianred';
});
// 创建以递增数值为锚点标记的带文字marker
// markerAddin.createTextSymbolMarker(center, '', ‘’, ‘定位点’, 'first marker', offset[0], offset[1], customizedStyles, null);
// 创建以数值为锚点标记不带文字标签的marker
// markerAddin.createAnchorMarker(center), '', null, customizedStyles);
}
// 使用图片作为锚点模拟场景中添加监控的效果
const center1 = new THREE.Vector3(-19, -17,-0.45);
// img元素将直接插入到anchor所在的div中
let message1 = `<img src = "./camera.png"/>`;
markerAddin.createAnchorMarker(
center1,
message1,
anchor => {
// 在回调函数中更改图片大小
anchor.firstElementChild.style.width = '58px';
anchor.firstElementChild.style.height = '180px';
// 更改样式后调用setNumMarkerPosition刷新图片锚点位置
markerAddin.tool.setNumMarkerPosition(anchor);
},{
// 使用图片作为锚点时默认绑定图片的中心点,需要设置绑定点的偏移时可以用picAnchorOffsetX、picAnchorOffsetY参数,图片向右向上偏移为正
picAnchorOffsetX: 0,
picAnchorOffsetY: -90,
}
);
createAnchorMarker
创建不带标签的锚点,参考示例见上一节
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| position | THREE.Vector3 | 是 | 锚点三维空间位置 |
| textSymbol | string | 是 | 锚点的显示标记,可传入空字符串,传入空字符串时会根据当前的marker总数量显示为递增的数值 |
| styleCallback | number | 否 | 通过回调函数可以完全自定义标签和锚点的样式,以(anchor) => {} 的形式返回锚点的dom元素 |
createAnnotation
创建不带锚点的文字标签
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| position | THREE.Vector3 | 是 | 锚点三维空间位置 |
| message | string | 是 | 文字标签中显示的信息 |
| styleCallback | number | 否 | 通过回调函数可以完全自定义标签和锚点的样式,以(annotation) => {} 的形式返回标签的dom元素 |
updateMarkerByExternalId
通过externalId更新Marker的相关信息
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| externalId | string | 是 | 锚点外部引用的id |
| tag | string | 是 | 要更新的锚点显示字符 |
| message | string | 是 | 要更新的标签信息 |
| offsetX | number | 否 | 距离锚点的偏移值X |
| offsetY | number | 否 | 距离锚点的偏移值Y |
changeMarkersVisibility
显示/隐藏整个marker,包括锚点、标签和连接线
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| numberIdArr | number[] | 是 | 数字数组,传入需要改变显隐状态的数字id数组,为空数组则表示 显示/隐藏 所有的marker的状态 |
| visibility | boolean | 是 | 设置可见性,为false表示隐藏 |
markerAddin.changeMarkersVisibility([2], false);
显示/隐藏锚点
- showMarkerAnchors
- hideMarkerAnchors
请求参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| numberIdArr | number[] | 是 | 数字数组,传入需要改变显隐状态的数字id数组,为空数组则表示 显示/隐藏 所有的锚点及引线 |
// numberIdArr: number类型的数组,表示marker数字Id的数组,可为空,为空时隐藏所有的锚点及引线
markerAddin.hideMarkerAnchors([2]);
// numberIdArr: number类型的数组,表示marker数字Id的数组,为空时显示所有的锚点及引线
markerAddin.showMarkerAnchors([2]);
显示/隐藏标签
- showAnnotations
- hideAnnotations
// numberIdArr: marker数字Id的数组,可为空,为空时隐藏所有的标签及引线
markerAddin.hideAnnotations([2]);
// numberIdArr: marker数字Id的数组,可为空,为空时显示所有的标签及引线
markerAddin.showAnnotations([2]);
销毁marker
- destroyMarkerByExternalId
- destroyMarkerByNumberedId
- clearMarkers
//通过externalId销毁指定marker,传入string类型字符串
markerAddin.destroyMarkerByExternalId('MyExternalMarker');
//通过NumberId销毁指定marker,传入number类型数值
markerAddin.destroyMarkerByNumberedId(4);
//销毁所有marker,销毁所有后,再次创建marker,数字Id将再次从1开始递增
markerAddin.clearMarkers();
查找对应的marker
- getMarkers
- getMarkerByNumberedId
- getAnnotationByNumberId
//通过外部Id查找指定marker,传入string类型字符串,可为空,为空时返回所有marker
markerAddin.getMarkers('MyExternalMarker');
//通过数字Id查找指定marker
markerAddin.getMarkerByNumberedId(4);
//通过数字Id查找指定标签,找到标签之后可以进行对应的操作,如更改为高亮的样式等
markerAddin.getAnnotationByNumberId(3);
MarkerEventTypes
marker相关的事件命名在OBVAddins.Marker.MarkerEventTypes对象作用域下,具体包含:
- ANNOTATION_DOUBLE_CLICKED
- ANNOTATION_CLICKED
- ANNOTATION_POSITION_CHANGED_EVENT
- MARKER_POSITION_CHANGED_EVENT
- ANCHOR_CLICKED
- ANCHOR_DOUBLE_CLICKED
- MARKER_SELECTED
const annotationClickedEvent = (e) => {
console.log(e);
}
//在插件上添加监听事件
markerAddin.addEventListener(OBVAddins.Marker.MarkerEventTypes.ANNOTATION_DOUBLE_CLICKED, annotationClickedEvent);
//do something else...
// 移除插件上的监听事件
markerAddin.removeEventListener(OBVAddins.Marker.MarkerEventTypes.ANNOTATION_DOUBLE_CLICKED, annotationClickedEvent);
衬图插件
衬图插件可在三维模型中叠加二维图纸展示,衬图能够直观展现图纸和三维模型的一致性。加载衬图插件插件可参考官网示例模型衬图功能
使用衬图功能需要提供对应三维模型的二维矢量图纸,不支持使用doc类型的pdf图纸作为衬图功能的数据输入。不支持在合模模型中使用衬图功能。
衬图插件的使用方法:
* 加载模型时配置加载衬图插件;
* 在三维模型中设置合适的剖切平面作为叠加二维图纸的平面,比如选择在模型二楼的中间位置剖切模型,那么选择的图纸也应该选择对应的二层平面图,这样才能保证在最终结果中正确显示;
* 选择一张二维图纸,加载图纸模型,调用图纸截图接口(takeScreenShot,具体参考二维api接口介绍)截取图纸中有效内容区域。注意截图区域需要设置为2的整数次幂,如2x2,4x4,8x8,16x16...
* 将截图的图纸内容作为平面贴图添加到三维中;
* 使用衬图插件的选取定位点功能分别在三维模型和二维图纸上各选取两个定位点(鼠标左键单击选点),插件中会以两组不同颜色的小球分别表示在三维和二维中选取的定位点,推荐将模型视角调整到对应的正视视角再在平移状态(Pan模式)下选取定位点,这样能尽可能减小操作过程中鼠标旋转导致的视角误差,减小叠加图纸时的实际误差。

- 调用衬图显示接口将贴图缩放至合适比例,最终的显示效果如下图所示。

使用衬图功能时,加载三维模型和图纸的流程和其他示例中展示的一样。以下介绍衬图功能需要使用到的相关接口。
setCutPlanes
在模型中设置剖切面,效果同三维api setClipPlane接口。
参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| x | number | true | 法线方向x分量 |
| y | number | true | 法线方向y分量 |
| z | number | true | 法线方向z分量 |
| w | number | true | 平面到原点的距离 |
clearCutPlane
清除模型中设置的剖切面,效果同三维api restoreClipPlane接口。
add2dPlane
将二维截图数据作为贴图,展示到三维模型对应的剖切平面上
参数(Parameters):
| 名称(Name) | 类型(Type) | 必填(Required) | 描述(Description) |
|---|---|---|---|
| url | String | 是 | 需要加载图片的源数据 |
snapIn2d
交互接口,snapIn2d激活衬图插件的点选工具,调用此接口后,可以在三维模型上进行选点操作。 样例(Example):
// 切换到叠加图纸所在的正视方向,这里以俯视图为例
obvApi.viewTop();
// 切换到pan平移模式,减少鼠标旋转带来的误差
obvApi.setActionPan();
// 调用snapIn2d进入衬图捕捉点模式,此时可以鼠标点击在模型俯视图上选择定位点
paste2dAddin.snapIn2d();
clearPrevPoint
清除上一个定位点。在进入衬图捕捉状态后可用。对于选点过程中点选失误的定位点,可以调用此接口清除。再次调用会清除倒数第二个定位点,直到清除完所有定位点。
clearPinPoint
一次清除所有定位点。
alignPlane
选择好定位点后,调用alignPlane将图纸以三维的一个定位点位置重合。
scalePlane
选择好定位点后,可调用scalePlane将图纸按照选点比例自动计算并缩放至理想大小。
样例(Example):
// 定位缩放图纸
paste2dAddin.alignPlane();
paste2dAddin.scalePlane();
// 清除页面上的定位点
paste2dAddin.clearPinPoint();
hidePlane
清除叠加的二维图纸。一般在恢复为原始视图时和clearCutPlane接口一起调用。
样例(Example):
// 清除叠加图纸
paste2dAddin.hidePlane();
// 清除剖切平面
paste2dAddin.clearCutPlane();
Flatten(压平)插件
Flatten插件为OBV提供了对倾斜摄影模型模型进行压平的功能。该工具可以实时绘制多个压平区域,实现模型压平效果。此外,工具支持压平区域的实时编辑,其中包括:增删压平区域、修改压平区域轮廓、修改压平区域高度、存储及读取压平区域。目前最多支持64个压平区域,每个压平区域最多支持126个顶点。
如何加载
使用插件需要在加载三维模型时传入相应的配置,传入的config应如下所示
const viewer3dConfig = {
addinConfigs: [
{
id: 'OBVAddins.Flatten',
noButton: false,
}
],
};
如何获取插件
let flattenAddin;
// 插件ID
const flattenAddinId = 'OBVAddins.Flatten';
// 获取管理插件的addinManager
const addinManager = obvApi.getAddinManager();
// 通过addinManager获取插件
flattenAddin = addinManager.getAddin(flattenAddinId);
// 如果插件没有加载过,需要加载到平台中
if (!flattenAddin) {
// 如果没有插件,则需要重新load插件
addinManager.loadAddin(flattenAddin);
flattenAddin = addinManager.getAddin(flattenAddinId)
}
如何使用
首先在工具栏点击激活插件,插件激活后即可调用接口,接口如下:
1.绘制压平区域
- flattenAddin.drawFlattenArea();
调用此接口后,鼠标点击场景内物体,逐点创建压平区域。
绘制完毕后,右键单击任意区域弹出完成绘制按钮,点击该按钮,完成绘制。
场景内可同时创建多个压平区域,压平区域不可重叠,不可自相交,否则将产生错误的压平效果。
2. 选择压平区域
- flattenAddin.selectFlattenArea();
调用此接口后进入选择模式,此时点击压平区域即可选中该压平区域,然后单击顶点即可对多边形进行编辑。 编辑完成后,右键单击任意区域弹出完成编辑按钮,点击该按钮,完成编辑。
3.删除压平区域
- flattenAddin.deleteFlattenArea();
在选中压平区域的情况下,调用此接口可以删除压平区域。
4.保存压平区域
- flattenAddin.saveDatatexture();
调用此接口可将场景内的压平区域信息保存为json格式。
5. 读取压平区域
- flattenAddin.readDatatexture(data);
在场景内没有任何压平区域的情况下,调用此接口,传入json格式的压平区域信息,可恢复此前保存的压平效果。