您的位置:首页 > 其它

BIM安装到解析、以及完整项目总结

2018-01-29 15:43 1481 查看
由于项目中用到各类单位建筑消防BIM图,所以研究了近一个月,稍有心得,现在公布出来方便其他人少走弯路;

1、由于BIMserver最新版本一直在更新,所以有很多线解串器插件更不上,我的BIMserver版本为1.5.88,这个版本较为稳定,下载地址:https://github.com/opensourceBIM/BIMserver/releases

2、这里面包含war包和jar包,我是war包;各自根据需要自行下载;

一、BIMserver的安装

第一步:安装BIMserver

运行环境:Linux centOS7、JavaJDK1.8以上、Tomcat8

1、把下载的1.5.88版本war直接复制到服务器webApp中,由于上传的BIM文件超过了tomcat默认内存128M,所以需要进行修改,修改方式分以下几种:

第一种方法:Windows下,在文件/bin/catalina.bat,Unix下,在文件/bin/catalina.sh的前面,增加如下设置:JAVA_OPTS='-Xms【初始化内存大小】
-Xmx【可以使用的最大内存】'需要把这个两个参数值调大。例如:JAVA_OPTS='-Xms256m -Xmx512m'表示初始化内存为256MB,可以使用的最大内存为512MB。

第二种方法: 环境变量中设变量名:JAVA_OPTS     变量值:-Xms512m   -Xmx512m

第三种方法:前两种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的Tomcat等),但是有些安装版的Tomcat下没有catalina.bat,这个时候可
4000
以采用如下方法,当然这个方法也是最通用的方法:打开tomcatHome//bin//tomcat5w.exe,点击Java选项卡,然后将会发现其中有这么两项:Initial
memory pool和Maximum memory pool.Initial memory pool这个就是初始化设置的内存的大小。Maximum memory pool这个是最大内存的大小 设置完了就按确定然后再重启TOMCAT你就会发现tomcat中jvm可用的内存改变了。

我自己是第一种办法设置的(截图为2048M):



然后就是启动了tomca了,启动花费时间较长请耐心等待。


第二步:开始安装解串器各种插件

访问:http://192.168.199.148:8080/bimserver88 这是我服务器+项目名称



(1)依次为:BIM服务器地址 、服务名称、服务说明、服务器图片,(0~0!这个图片是晚上其他地方截取的)点击下一步



(2)依次为:管理员名称、管理员账号、密码(记得账号必须为Email格式)



(3)由于我的服务器是内外,所以必须手动安装插件,点击红框就可以选择了,对应的插件版本为下图



自己到这里进行下载:https://oss.sonatype.org/content/groups/public/org/opensourcebim/

(4)等到所有插件安装完成;


第三步、登录BIMserver后台管理页面

访问:http://192.168.199.148:8080/bimserver88/



这样就会访问登录页面,安装就到这里.


二、后台代码实现

  整体项目构建为SpringMVC、mybaits、maven、jdk1.8编译;



    解释:由于整个项目是分布式的,所以这里面用到了ods-common包(为自己的公共util,本项目实际上只用到了一个OdsResult.java)、pagehelper分页包可以自己下载;
    由于整个项目的配置和类太多这里不方便贴出来,请到
    http://download.csdn.net/download/lustres/10229631     这里下载完整项目,这里我只做简单介绍和OdsResult.java类贴出来;
OdsResult.java类

package com.cqprosper.ods.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
* 自定义响应结构
*/
public class OdsResult implements Serializable{

// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();

// 响应业务状态
private String state;

// 响应消息
private String message;

// 响应中的数据
private Object data;

public static Map buildMap(String name,Object object){
Map map = new HashMap();
map.put("name",name);
map.put("value",object);
return map;
}

public static Map resultMap(String key,Object object){
Map map = new HashMap();
map.put(key,object);
return map;
}

public static OdsResult build(String state, String message, Object data) {
return new OdsResult(state, message, data);
}

public static OdsResult ok(Object data) {
return new OdsResult(data);
}

public static OdsResult ok() {
return new OdsResult(new ArrayList<>());
}

public OdsResult() {

}

public static OdsResult build(String state, String message) {
return new OdsResult(state, message, null);
}

public OdsResult(String state, String message, Object data) {
this.state = state;
this.message = message;
this.data = data;
}

public OdsResult(Object data) {
this.state = "200";
this.message = "OK";
this.data = data;
}

//    public Boolean isOK() {
//        return this.state == 200;
//    }

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public Object getData() {
return data;
}

public void setData(Object data) {
this.data = data;
}

/**
* 将json结
133f4
果集转化为esult对象
*
* @param jsonData json数据
* @param clazz OdsResult中的object类型
* @return
*/
public static OdsResult formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, OdsResult.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("state").toString(), jsonNode.get("message").asText(), obj);
} catch (Exception e) {
return null;
}
}

/**
* 没有object对象的转化
*
* @param json
* @return
*/
public static OdsResult format(String json) {
try {
return MAPPER.readValue(json, OdsResult.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* Object是集合转化
*
* @param jsonData json数据
* @param clazz 集合中的类型
* @return
*/
public static OdsResult formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("state").toString(), jsonNode.get("message").asText(), obj);
} catch (Exception e) {
return null;
}
}

}


这个项目的核心方法主要是BimUtil.java类

package com.cqprosper.ods.bim.util;

import com.alibaba.druid.util.StringUtils;
import org.bimserver.client.BimServerClient;
import org.bimserver.client.json.JsonBimServerClientFactory;
import org.bimserver.interfaces.objects.SDeserializerPluginConfiguration;
import org.bimserver.interfaces.objects.SProject;
import org.bimserver.plugins.services.Flow;
import org.bimserver.shared.UsernamePasswordAuthenticationInfo;
import java.io.InputStream;

/**
* @author mc
* @version V1.0
* @description:BIM图工具类
* @company: www.cqprosper.com
* @date 2018-01-18 下午 15:42
*/
public class BimUtil {
private static BimUtil bimUtilConfigManager;
private static BimServerClient client;
private BimUtil(String servers, String userName, String passWord){
try {
JsonBimServerClientFactory factory = new JsonBimServerClientFactory(servers);
client = factory.create(new UsernamePasswordAuthenticationInfo(userName, passWord));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 单列BIM服务器连接
* @param servers
* @param userName
* @param passWord
* @return
*/
public static BimUtil bimUtilConfigManager(String servers, String userName, String passWord){
if (bimUtilConfigManager == null){
bimUtilConfigManager = new BimUtil(servers,userName,passWord);
}
return bimUtilConfigManager;
}

/**
* 与BIM服务器建立连接
* @return
*/
public BimServerClient createConnect(){
return client;
}

/**
* 创建工程
* @param client
* @param projectName
* @param schema
* @return
*/
public static SProject addProject(BimServerClient client , String projectName, String schema){
SProject newProject = null;
try {
newProject = client.getServiceInterface().addProject(projectName,schema);
} catch (org.bimserver.shared.exceptions.ServerException e) {
e.printStackTrace();
} catch (org.bimserver.shared.exceptions.UserException e) {
e.printStackTrace();
}
System.out.println("在BIM服务器上创建工程成功~!");
return newProject;
}

/**
* 上传IFC文件至BIM服务器
* @param client 客户端
* @param poid 工程唯一标示
* @param comment 备注
* @param fileSize 文件大小
* @param filename 文件名称
* @param inputStream 文件流
* @param ifc 默认为ifc,可以指定特定解串器
* @return
*/
public static long doSomethingWithClient(BimServerClient client, long poid, String comment, long fileSize, String filename, InputStream inputStream,String ifc){
if (StringUtils.isEmpty(ifc)){
ifc ="ifc";
}
long start=0L;
try {
SDeserializerPluginConfiguration deserializer = client.getServiceInterface().getSuggestedDeserializerForExtension(ifc, poid);
// Here we actually checkin the IFC file. Flow.SYNC indicates that we only want to continue the code-flow after the checkin has been completed
start = client.checkin(poid, comment, deserializer.getOid(), false, Flow.SYNC, fileSize,filename,inputStream);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("上传文件返回值为:"+start);
return start;
}
}


三、前端BIMsuffer实现

完整demo请到这里下载:http://download.csdn.net/download/lustres/10229865
如果你是后端的话,下面的代码可以找前端实现,我列出一个Dome,请注意中文注释
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>BIMsurfer demo</title>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,600' rel='stylesheet' type='text/css' />

<link rel="stylesheet" href="css/demo.css"/>
<link rel="stylesheet" href="css/apiref.css"/>
<link rel="stylesheet" href="../css/tree.css"/>
<link rel="stylesheet" href="../css/metadata.css"/>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"/>

<script type="text/javascript" src="js/utils.js"></script>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script>
var address = QueryString.address;//这里为BIMserver服务端地址
var token = QueryString.token;//这里为后台传过来token
var windowBimSurfer;

/* Generating a new version based on the current time, this way resources are never cached
When building a version of BIMsurfer V2 this should be replaced by an actual version number in order
To facilitate proper caching
*/
var version = new Date().getTime();

// This has been moved to bimserverapi, can be removed in a day
String.prototype.firstUpper = function () {
return this.charAt(0).toUpperCase() + this.slice(1);
}

// Because the demo is in a subfolder compared to the BIMsurfer API, we tell require JS to use the "../" baseUrl
var require = {
baseUrl: "../",
//urlArgs: "bust=" + version
};
</script>

<script type="text/javascript" src="../bimsurfer/lib/require.js"></script>
<script type="text/javascript">

// Loads a model from BIMServer, builds an explorer tree UI.
// Clicking on a tree node fits the view to its scene object.

loadScripts("http://192.168.199.148:8080/bimserver88/apps/bimserverjavascriptapi/js/", [
"bimserverclient.js",
"model.js",
"bimserverapiwebsocket.js",
"bimserverapipromise.js",
"geometry.js",
"ifc2x3tc1.js",
"ifc4.js",
"translations_en.js",
], function(){
require(["bimsurfer/src/BimSurfer","bimsurfer/src/BimServerModelLoader","bimsurfer/src/StaticTreeRenderer","bimsurfer/src/MetaDataRenderer","bimsurfer/lib/domReady!"],
function (BimSurfer, BimServerModelLoader, StaticTreeRenderer, MetaDataRenderer) {

function processBimSurferModel(bimSurferModel) {

bimSurferModel.getTree().then(function (tree) {
// Build a tree view of the elements in the model. The fact that it
// is 'static' refers to the fact that all branches are loaded and
// rendered immediately.
//alert(1);
var domtree = new StaticTreeRenderer({
domNode: 'treeContainer'
});
domtree.addModel({name: "", id:QueryString.roid, tree:tree});
domtree.build();
console.log(QueryString.roid);
//console.log(tree);
// Add a widget that displays metadata (IfcPropertySet and instance
// attributes) of the selected element.
var metadata = new MetaDataRenderer({
domNode: 'dataContainer'
});

metadata.addModel({name: "", id:QueryString.roid, model:bimSurferModel});
windowBimSurfer = bimSurfer;

bimSurfer.on("selection-changed", function(selected) {
domtree.setSelected(selected, domtree.SELECT_EXCLUSIVE);
metadata.setSelected(selected);
});

domtree.on("click", function (oid, selected) {
// Clicking an explorer node fits the view to its object and selects
if (selected.length) {
bimSurfer.viewFit({
ids: selected,
animate: true
});
}
bimSurfer.setSelection({
ids:selected,
clear:true,
selected:true
});
});

// Write API ref

var flatten = function(n) {
var li = []
var f = function(n) {
li.push(n.id);
(n.children || []).forEach(f);
}
f(n);
return li;
};

var oids = flatten(tree);
_.shuffle(oids);
oids.splice(10);
var guids = bimSurfer.toGuid(oids);

oids = "["+oids.join(", ")+"]";
guids = "["+guids.map(function(s) {return '"'+s+'"';}).join(", ")+"]";

console.log(81);

var METHODS = [
{name:'setVisibility',     args:[{name: "ids", value: oids}, {name: "visible", value:false}]},
{name:'setVisibility',     args:[{name: "types", value: '["IfcWallStandardCase"]'}, {name: "visible", value:false}]},
{name:'setSelectionState', args:[{name: "ids", value: oids}, {name: "selected", value:true}]},
{name:'getSelected', args:[], hasResult: true},
{name:'toId', args:[guids], hasResult: true},
{name:'toGuid', args:[oids], hasResult: true},
{name:'setColor', args:[{name: "ids", value: oids}, {name: "color", value:"{r:1, g:0, b:0, a:1}"}]},
{name:'viewFit', args:[{name: "ids", value: oids}, {name: "animate", value:500}]},
{name:'setCamera', args:[{name: "type", value: "'ortho'"}]},
{name:'getCamera', args:[], hasResult: true},
{name:'reset', args:[{name: "cameraPosition", value: true}]},
];

var n = document.getElementById('apirefContainer');

//console.log(METHODS.toString());
METHODS.forEach(function(m, i) {

n.innerHTML += "<h2>"+m.name+"()</h2>";

var hasNamedArgs = false;
var args = m.args.map(function(a) {
if (a.name) {
hasNamedArgs = true;
return a.name + ":" + a.value;
} else {
return a;
}
}).join(", ");

if (hasNamedArgs) {
args = "{"+args+"}";
}

var cmd = "bimSurfer."+m.name+"("+args+");";
n.innerHTML += "<textarea rows=3 id='code"+i+"' spellcheck=false>"+cmd+"\n</textarea>";
exec_statement = "eval(document.getElementById(\"code"+i+"\").value)"
if (m.hasResult) {
exec_statement = "document.getElementById(\"result"+i+"\").innerHTML = JSON.stringify(" + exec_statement + ").replace(/,/g, \", \")";
} else {
exec_statement += "; window.scrollTo(0,0)"
}
n.innerHTML += "<button onclick='"+exec_statement+"'>run</button>";
if (m.hasResult) {
n.innerHTML += "<pre id='result"+i+"' />";
}
//console.log(n.innerHTML);
});
});
}

var bimSurfer = new BimSurfer({
domNode: "viewerContainer"
});

bimSurfer.on("loading-finished", function(){
document.getElementById("status").innerHTML = "Loading finished";
var domNode = document.getElementById("typeSelector");
domNode.innerHTML = "";
bimSurfer.getTypes().forEach(function(ifc_type) {
var on = ifc_type.visible;
var d = document.createElement("div");
var t = document.createTextNode(ifc_type.name);
var setClass = function() {
d.className = "fa fa-eye " + ["inactive", "active"][on*1];
};
setClass();
d.appendChild(t);
domNode.appendChild(d);
d.onclick = function() {
on = !on;
setClass();
bimSurfer.setVisibility({types:[ifc_type.name], visible:on});
};
});
});
bimSurfer.on("loading-started", function(){
document.getElementById("status").innerHTML = "Loading...";
});

// Lets us play with the Surfer in the console
window.bimSurfer = bimSurfer;

// Create a BIMserver API, we only need one of those for every server we connect to
var bimServerClient = new BimServerClient(address, null);
bimServerClient.init(function(){

bimServerClient.setToken(token, function() {
// Create a model loader, this one is able to load models from a BIMserver and therefore can have BIMserver specific calls
var modelLoader = new BimServerModelLoader(bimServerClient, bimSurfer);

var models = {}; // roid -> Model

// For this example, we'll fetch all the latest revisions of all the subprojects of the main project
var poid = QueryString.poid;//这里为后端传过来的项目poid

var nrProjects;

function loadModels(models, totalBounds) {
var center = [
(totalBounds.min[0] + totalBounds.max[0]) / 2,
(totalBounds.min[1] + totalBounds.max[1]) / 2,
(totalBounds.min[2] + totalBounds.max[2]) / 2
];

var globalTransformationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
-center[0], -center[1], -center[2], 1
];
console.log(totalBounds);
//console.log(models.toString());
//alert(models[0].toString());
//for (var i = 0; i < models.length - 1; i++) {
for (var roid in models) {
var model = models[roid];
console.log(model.toString());
console.log(890);
// Example 1: Load a full model
modelLoader.setGlobalTransformationMatrix(globalTransformationMatrix);
modelLoader.loadFullModel(model).then(function(bimSurferModel){
processBimSurferModel(bimSurferModel);
});

// Example 2: Load a list of objects (all walls and subtypes)
//				                	var objects = [];
//				                	model.getAllOfType("IfcWall", true, function(wall){
//				                		objects.push(wall);
//				                	}).done(function(){
//						                modelLoader.loadObjects(model, objects).then(function(bimSurferModel){
//						                    processBimSurferModel(bimSurferModel);
//						                });
//				                	});

// Example 3: Load the results of a query
//				                	var objects = [];
//				                	var query = {
//				                		types: ["IfcDoor", "IfcWindow"]
//				                	};
//				                	model.query(query, function(object){
//				                		objects.push(object);
//				                	}).done(function(){
//						                modelLoader.loadObjects(model, objects).then(function(bimSurferModel){
//						                    processBimSurferModel(bimSurferModel);
//						                });
//				                	});
}
}

bimServerClient.call("ServiceInterface", "getAllRelatedProjects", {poid: poid}, function(projects){
nrProjects = projects.length;
console.log(nrProjects);
var totalBounds = {
min: [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE],
max: [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE]
};

projects.forEach(function(project){

//if (project.lastRevisionId != -1 && project.oid != poid) {
if (project.lastRevisionId != -1) {

bimServerClient.getModel(project.oid, project.lastRevisionId, project.schema, false, function (model) {
console.log(project.lastRevisionId);
console.log(model);
models[project.lastRevisionId] = model;

bimServerClient.call("ServiceInterface", "getModelMinBounds", {roid: project.lastRevisionId}, function(minBounds){
bimServerClient.call("ServiceInterface", "getModelMaxBounds", {roid: project.lastRevisionId}, function(maxBounds){
if (minBounds.x < totalBounds.min[0]) {
totalBounds.min[0] = minBounds.x;
}
if (minBounds.y < totalBounds.min[1]) {
totalBounds.min[1] = minBounds.y;
}
if (minBounds.z < totalBounds.min[2]) {
totalBounds.min[2] = minBounds.z;
}
if (maxBounds.x > totalBounds.max[0]) {
totalBounds.max[0] = maxBounds.x;
}
if (maxBounds.y > totalBounds.max[1]) {
totalBounds.max[1] = maxBounds.y;
}
if (maxBounds.z > totalBounds.max[2]) {
totalBounds.max[2] = maxBounds.z;
}
nrProjects--;
if (nrProjects == 0) {
console.log(6);
loadModels(models, totalBounds);
}
});
});
});
} else {
nrProjects--;
if (nrProjects == 0) {
console.log(5);
loadModels(models, totalBounds);
}
}
});
});
});
});
});
});

function finish() {
document.getElementById("status").innerHTML = "Loading finished";
var domNode = document.getElementById("typeSelector");
domNode.innerHTML = "";
windowBimSurfer.getTypes().forEach(function (ifc_type) {
var on = ifc_type.visible;
var d = document.createElement("div");
var t = document.createTextNode(ifc_type.name);
var setClass = function () {
d.className = "fa fa-eye " + ["inactive", "active"][on * 1];
};
setClass();
d.appendChild(t);
domNode.appendChild(d);
d.onclick = function () {
on = !on;
setClass();
windowBimSurfer.setVisibility({ types: [ifc_type.name], visible: on });
};
});
}

</script>
</head>
<body>
<div id="maincontainer">
<div id="topsection">
<h1>BIMsurfer demo</h1>
<input type="button" value="finished" onclick="finish()"/>
<div id="typeSelector">
<div> </div>
</div>
</div>
<div id="contentwrapper">
<div id="colmid">
<div id="colright">
<div id="col1wrap">
<div id="col1pad">
<div id="viewerContainer">
</div>
</div>
</div>
<div id="treeContainer" class="bimsurfer-static-tree">
</div>
<div id="dataContainer" class="bimsurfer-metadata">
</div>
</div>
</div>
</div>

</div>
<div id="status"></div>

<div id='apirefContainer'>
<h1>API Reference</h1>
</div>

</body>
</html>


就是这样了,我也是刚刚研究没有多久,如有不正确的请指出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: