# 编辑图模关联
创建图模关联组件数据后,可以通过图模关联编辑器进行添加图纸、位置关联、预览设置等操作,在完成操作后,可以通过组件数据管理服务进行数据更新。
# 获取View Token
组件加载需要通过View Token进行鉴权,在组件数据创建成功后,可以通过返回数据中的moduleDataId获取View Token,实现组件管理器的初始化和图模关联组件的加载。View Token获取方法详见接口文档:获取View Token (opens new window)
# 引用BIMFACE JavaScript SDK
在使用BIMFACE JSSDK之前,你需要新建一个HTML文件,并在浏览器中打开。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图模关联编辑</title>
<script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js" charset="utf-8"></script>
</head>
<body>
<script>
// 在这里输入BIMFACE JavaScript SDK提供的方法
</script>
</body>
</html>
# 新建DOM元素
在网页中新建DOM元素,用于显示模型或图纸。
<div id="domId"></div>
# 图模关联数据加载
首先需要构造组件管理器,构造完成后可以通过组件数据的View Token和组件类型加载图模关联组件。在组件加载完成后才可以构造图模关联编辑器,可通过then()方法异步执行。
// 构造组件管理器的配置项
let managerConfig = new Glodon.Bimface.Module.ModuleManagerConfig();
// 构造组件管理器对象
moduleManager = new Glodon.Bimface.Module.ModuleManager(managerConfig);
// 加载组件
moduleManager.loadModule({
// 组件数据的View Token
viewToken: viewToken,
// 组件类型,"Linkage2D3D"为图模关联
moduleType: "Linkage2D3D"
}).then(() => {
// 构造图模关联编辑器的配置项
let editorConfig = new Glodon.Bimface.Module.Linkage2D3D.EditorConfig();
// 指定存放应用界面的DOM容器
editorConfig.domElement = document.getElementById("domId");
// 获取待添加资源列表的方法,该方法需返回一个Promise对象,具体定义见下一小节
editorConfig.getResourceListHandler = getResourceListHandler;
// 添加资源时获取对应viewToken的方法,该方法需返回一个Promise对象,具体定义见下一小节
editorConfig.getViewTokenHandler = getViewTokenHandler;
// 构造图模联动编辑器
editor = new Glodon.Bimface.Module.Linkage2D3D.Editor(editorConfig);
// 获取Viewer3D对象,获取后可以调用Viewer3D类下的方法
viewer3D = editor.getViewer3D();
// 获取ViewerDrawing对象,获取后可以调用ViewerDrawing类下的方法,需要在ViewerDrawing初始化完成后执行
editor.addEventListener(Glodon.Bimface.Module.Linkage2D3D.EditorEvent.ViewerDrawingInitialized, () => {
viewerDrawing = editor.getViewerDrawing();
});
});
# 图模关联编辑组件初始化
在上一步中,我们进行了编辑组件的初始化配置,这一小节我们将对初始化的配置参数进行详细说明。
首先,在构造了EditorConfig后,需要设置DOM容器,并定义getResourceListHandler、getViewTokenHandler两个回调函数。
其中getResourceListHandler为图模关联编辑中添加图纸资源时获取待添加图纸资源列表的方法;getViewTokenHandler为添加资源时获取待添加资源viewToken的方法。
# getResourceListHandler
基于编辑组件添加图纸资源时,将通过该方法获取可添加至关联中的图纸列表。该方法需带有Object类型的入参,如图所示,在资源添加过程中,选中列表内对应文件夹、进行文件搜索等操作时会传递对应的参数至该方法中。
需要注意的是,示例代码中直接使用了BIMFACE的后端接口,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全。
基于传入参数,可调用获取转换资源列表 (opens new window)的后端接口获取符合条件的图纸,仅支持添加与模型处于同一项目且转换成功的二维图纸文件,即在后端接口body中需限制projectId、suffix、outputFormat、status。
# 传入参数
name | type | description |
---|---|---|
config | Object | 传入参数 |
config.parentId | String | 添加资源-点选对应文件夹时,返回该文件夹Id |
config.searchKeyword | String | 添加资源-搜索对应资源时,传入对应搜索关键词 |
# 返回参数
该方法需返回一个Promise对象,在rosolve中返回符合条件的资源列表。
type | description |
---|---|
Promise<Array> | 返回Promise对象,resolve中的第一个参数返回需要展示的资源列表数组 |
返回列表及子项的格式为:
[
{
id: '10000007070001',
isFolder: false,
name: '一层图纸.dwg'
},
{
id: '10000007070002',
isFolder: true,
name: '文件夹-1'
}
]
# 代码示例
// 获取待添加的图纸资源列表的回调
async function getResourceListHandler(config) {
let headers = new Headers();
// 基于Access Token发起后端接口调用,需要注意的是,示例代码中直接使用了BIMFACE的后端接口,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全,后端接口文档参考:https://bimface.com/docs/model-derivative/v1/api-reference/getResourceListUsingPOST.html
headers = {
"Authorization": "Bearer cn-e9725999-0b36-4c0e-bdca-38ea88888888",
"Content-Type": "application/json"
};
// 需传入组件所在的项目ID,获取转换资源列表。
let url = "https://api.bimface.com/v1/10000000006014/translations";
// 后端接口的请求body需限制资源类型
let body = {
// 限制文件类型为dwg
"suffix": "dwg",
// 限制状态为转换成功
"status": 99,
// 限制图纸类型为二维图纸
"outputFormat": "bdv",
// 搜索模式时,基于名称进行模糊匹配或基于ID进行精准匹配
"keyword": config.searchKeyword,
// 获取指定文件夹下的资源
"parentId": config.parentId,
}
// 获取接口返回值
let res = await fetch(url, { method: "POST", headers: headers, body: JSON.stringify(body) });
let resJson = await res.json();
let result = [];
resJson.data && resJson.data.list.forEach((item) => {
// 记录文件ID、文件名称、是否为文件夹
result.push({
id: item.fileId || item.integrateId,
name: item.name,
isFolder: item.isFolder
});
});
return new Promise((resolve) => resolve(result));
}
# getViewTokenHandler
勾选完待添加的图纸后,通过getResourceListHandler方法可以获取待添加图纸资源的View Token。该方法需带有Array类型的入参,如图所示,在点击“添加”按钮时会传递对应的多个图纸资源的信息至该方法中。
基于传入参数,可调用获取View Token (opens new window)后端接口获取View Token。
# 传入参数
name | type | description |
---|---|---|
list | Array | 传入参数,由需要获取View Token的图纸信息组成的数组 |
列表及子项的格式为:
[
{
id: '10000007070001',
isFolder: false,
name: '一层图纸.dwg'
}
]
# 返回参数
该方法需返回一个Promise对象,在resolve中返回获取到的多个viewToken信息。
type | description |
---|---|
Promise<Array> | 返回Promise对象,resolve中的第一个参数返回待添加的资源数组 |
返回列表及子项的格式为:
[
{
id: '10000007070001',
name: '一层平面图.dwg',
viewToken: 'c6eec7b8b4724da2926959b17c351622',
}
]
# 代码示例
// 获取ViewToken的回调
function getViewTokenHandler(list) {
let result = [];
return new Promise((resolve) => {
Promise.all(list.map((item) => getViewToken(item.id, item.name, item.isFolder))).then((data) => {
data.forEach((item) => result.push(...item));
resolve(result);
});
});
}
// 获取单个资源的View Token
async function getViewToken(id, name, isFolder) {
// 判断传入对象是否为文件夹。若为文件夹,则需先获取文件夹内的资源列表,再获取各资源的viewToken
if (isFolder) {
// 获取文件夹内的资源列表
let folderFileList = await getResourceListHandler({ type: "file", parentId: id });
let list = [];
folderFileList.forEach((item) => {
let newItem = {
...item
};
list.push(newItem);
});
let viewTokenList = await getViewTokenHandler(list);
return viewTokenList;
}
let headers = new Headers();
// 基于Access Token发起后端接口调用,需要注意的是,示例代码中直接使用了BIMFACE的后端接口,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全,后端接口文档参考:https://bimface.com/docs/authenticatione/v1/api-reference/getViewTokenByFileIdUsingGET.html
headers = {
"Authorization": "Bearer cn-e9725999-0b36-4c0e-bdca-38ea88888888",
"Content-Type": "application/json"
};
// 基于后端接口获取模型的View Token
let url = `https://api.bimface.com/view/token?fileId=${id}`;
// 获取后端接口返回值
let res = await fetch(url, { method: "GET", headers: headers });
let resJson = await res.json();
let result = [];
result.push({
id: id,
name: name,
viewToken: resJson.data
});
return result;
}
# 编辑组件数据更新
通过编辑器完成图模关联后,需要更新组件数据。因此需要在页面中添加一个按钮,用来控制数据的更新。首先需要构造一个“保存”按钮,然后在按钮的点击事件中实现组件数据的更新流程。在class为buttons的div下输入如下内容:
<button class='button' onclick="save()">保存</button>
我们可以通过css代码对按钮的样式进行定义:
.button {
margin: 5px 0 5px 5px;
width: 100px;
height: 30px;
border-radius: 3px;
border: none;
background: #32D3A6;
color: #FFFFFF;
margin-right: 20px;
margin-bottom: 4px;
}
接下来就需要在“保存”按钮的点击事件中实现关联数据的更新流程。
图模关联编辑组件中提供了获取编辑后的组件数据的接口:getCurrentData(),该接口能够返回当前编辑后最新的组件数据信息,包括关联的图纸列表、位置信息、预览配置等。基于返回的数据可以调用后端接口更新组件数据 (opens new window)进行数据更新。
// 更新组件数据
function save() {
let body = {
// 基于编辑组件返回的数据进行组件数据更新
...editor.getCurrentData()
};
return new Promise((resolve) => {
// 基于后端接口进行组件数据更新,需将ID替换为当前进行编辑的组件数据ID
let url = "https://api.bimface.com/module/v1/module-data/2502933573946112";
let headers = new Headers();
// 基于Access Token发起后端接口调用,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全
headers = {
"Authorization": "Bearer cn-e9725999-0b36-4c0e-bdca-38ea88888888",
"Content-Type": "application/json"
};
fetch(url, { method: "PATCH", headers: headers, body: JSON.stringify(body) }).then((response) => {
console.log('更新成功', response);
})
});
}
# 完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>图模关联编辑</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
.buttons {
font-size: 0;
}
.button {
margin: 5px 0 5px 5px;
width: 100px;
height: 30px;
border-radius: 3px;
border: none;
background: #32D3A6;
color: #FFFFFF;
margin-right: 20px;
margin-bottom: 4px;
}
.main {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
}
.footer {
width: 100%;
height: 50px;
align-items: center;
justify-content: end;
display: flex;
}
#domId {
flex: 1;
}
</style>
<!-- 引用BIMFACE的JavaScript显示组件库 -->
<script src="https://static.bimface.com/api/BimfaceSDKLoader/BimfaceSDKLoader@latest-release.js"
charset="utf-8"></script>
</head>
<body>
<div class="main">
<!-- 定义DOM元素,用于在该DOM元素中显示组件 -->
<div id="domId"></div>
<div class="footer" id="buttons">
<button class="button" onclick="save()">保存</button>
</div>
</div>
<script type="text/javascript">
// 声明变量
let moduleManager;
let editor;
let viewer3D;
let viewerDrawing;
let projectId = "10000000006014";
let moduleDataId = "2502933573946112";
let viewToken = "5789250cb0624f148e120e000482ecb7";
// 构造组件管理器的配置项
let managerConfig = new Glodon.Bimface.Module.ModuleManagerConfig();
// 构造组件管理器对象
moduleManager = new Glodon.Bimface.Module.ModuleManager(managerConfig);
// 加载组件
moduleManager.loadModule({
// 组件数据的View Token
viewToken: viewToken,
// 组件类型,"Linkage2D3D"为图模联动
moduleType: "Linkage2D3D"
}).then(() => {
// 构造图模联动编辑器的配置项
let editorConfig = new Glodon.Bimface.Module.Linkage2D3D.EditorConfig();
// 指定存放应用界面的DOM容器
editorConfig.domElement = document.getElementById("domId");
// 设置图纸工具条Button对象
editorConfig.drawingButtons = ["Home", "RectZoom", "DrawingMeasure", "Map", "Sheets", "Layers", "Setting", "FullScreen"];
// 设置模型工具条Button对象
editorConfig.modelButtons = ['Home', 'View', 'RectangleSelect', 'Measure', 'Section', 'Walk', 'Map', 'Property', 'Setting', 'Information', 'FullScreen'];
// 获取待添加资源列表的方法,该方法需返回一个Promise对象
editorConfig.getResourceListHandler = getResourceListHandler;
// 添加资源时获取对应viewToken的方法,该方法需返回一个Promise对象
editorConfig.getViewTokenHandler = getViewTokenHandler;
// 构造图模联动编辑器
editor = new Glodon.Bimface.Module.Linkage2D3D.Editor(editorConfig);
// 获取Viewer3D对象,获取后可以调用Viewer3D类下的方法
viewer3D = editor.getViewer3D();
// 获取ViewerDrawing对象,获取后可以调用ViewerDrawing类下的方法,需要在ViewerDrawing初始化完成后执行
editor.addEventListener(Glodon.Bimface.Module.Linkage2D3D.EditorEvent.ViewerDrawingInitialized, () => {
viewerDrawing = editor.getViewerDrawing();
});
});
// 获取待添加资源列表的回调
async function getResourceListHandler(config) {
let headers = new Headers();
// 基于Access Token发起后端接口调用,需要注意的是,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全,后端接口文档参考:https://bimface.com/docs/model-derivative/v1/api-reference/getResourceListUsingPOST.html
headers = {
"Authorization": "Bearer cn-79d115e2-3523-4835-bfa1-625e42a2b124",
"Content-Type": "application/json"
};
// 需传入场景所在的项目ID,获取转换资源列表
let url = "https://api.bimface.com/v1/10000000006014/translations";
// 后端接口的请求body需限制资源为dwg文件
let body = {
// 限制资源为dwg文件
"suffix": "dwg",
// 限制状态为转换成功或集成成功
"status": 99,
// 限制图纸类型为二维图纸
"outputFormat": "bdv",
// 搜索模式时,基于名称进行模糊匹配或基于ID进行精准匹配
"keyword": config.searchKeyword,
// 获取指定文件夹下的资源
"parentId": config.parentId,
}
// 获取接口返回值
let res = await fetch(url, { method: "POST", headers: headers, body: JSON.stringify(body) });
let resJson = await res.json();
let result = [];
resJson.data && resJson.data.list.forEach((item) => {
// 记录文件ID、文件名称、是否为文件夹
result.push({
id: item.fileId,
name: item.name,
isFolder: item.isFolder
});
});
return new Promise((resolve) => resolve(result));
}
// 获取ViewToken的回调
function getViewTokenHandler(list) {
let result = [];
return new Promise((resolve) => {
Promise.all(list.map((item) => getViewToken(item.id, item.name, item.isFolder))).then((data) => {
data.forEach((item) => result.push(...item));
resolve(result);
});
});
}
// 获取单个资源的View Token
async function getViewToken(id, name, isFolder) {
// 判断传入对象是否为文件夹。若为文件夹,则需先获取文件夹内的资源列表,再获取各资源的View Token
if (isFolder) {
// 获取文件夹内的资源列表
let folderFileList = await getResourceListHandler({ type: "file", parentId: id });
let list = [];
folderFileList.forEach((item) => {
let newItem = {
...item
};
list.push(newItem);
});
let viewTokenList = await getViewTokenHandler(list);
return viewTokenList;
}
let headers = new Headers();
// 基于Access Token发起后端接口调用,需要特别注意的是,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全,后端接口文档参考:https://bimface.com/docs/authentication/v1/api-reference/getViewTokenByFileIdUsingGET.html
headers = {
"Authorization": "Bearer cn-79d115e2-3523-4835-bfa1-625e42a2b124",
"Content-Type": "application/json"
};
// 基于后端接口获取模型的View Token
let url = `https://api.bimface.com/view/token?fileId=${id}`;
// 获取后端接口返回值
let res = await fetch(url, { method: "GET", headers: headers });
let resJson = await res.json();
let result = [];
result.push({
id: id,
name: name,
viewToken: resJson.data
});
return result;
}
// 更新组件数据
function save() {
let body = {
// 基于编辑组件返回的数据进行组件数据更新
...editor.getCurrentData()
};
return new Promise((resolve) => {
// 基于后端接口进行组件数据更新,需将ID替换为当前进行编辑的组件数据ID
let url = "https://api.bimface.com/module/v1/module-data/2502933573946112";
let headers = new Headers();
// 基于Access Token发起后端接口调用,业务系统集成时,需要对BIMFACE的后端接口进行封装,避免Access Token暴露在前端,从而影响数据安全
headers = {
"Authorization": "Bearer cn-79d115e2-3523-4835-bfa1-625e42a2b124",
"Content-Type": "application/json"
};
fetch(url, { method: "PATCH", headers: headers, body: JSON.stringify(body) }).then((response) => {
console.log('更新成功', response);
});
});
}
</script>
</body>
</html>