什麼是BIM
BIM的英文全稱是Building Information Modeling,即建築資訊模型化(BIM),是一個完備的資訊模型化的過程(英文MODELING是動名詞;不是簡單的名詞“模型”),能夠将工程項目在全生命周期中各個不同階段的工程資訊、過程和資源內建在一個模型中,友善的被工程各參與方使用。
什麼是ifc
IFC即Industry Foundation Class的縮寫,意思是工業基礎類,IFC标準描述了BIM普遍使用的标準格式,是一個不受任何供應商控制的公開性标準,是建築工程施工行業中最全面的資料模型标準,包含了建築工程領域各個階段所需的工程資料定義。
ifc轉3dtiles的思路
ifc轉3dtiles可以直接借助國内軟體cesiumlab或者國外Autodesk公司的軟體Revit中的一個模型插件BimAngleEngine CLI來實作直接将ifc模型轉化為可以在cesium中加載的3dtiles模型,但是這兩種方式都是需要購買正版軟體或者購買軟體授權期限,而且費用極高。
另外一種思路是利用開源工具實作ifc轉3dtiles,當然,肯定不能直接将ifc直接轉換為3dtiles(至于原因在這裡不做解釋,可以網上去查查),那麼如何轉換呢?我的思路是,先将ifc轉換為obj,再将obj轉換為3dtiles,這兩個轉化步驟在github上都能找到開源的工具,而且使用起來也很友善。
ifc轉obj
借助github開源工具ifcopenshell,考慮到安裝此工具需要依賴很多第三方庫,而且安裝步驟複雜,是以決定使用docker方式進行部署。
1、拉取ifcopenshell鏡像:
docker pull aecgeeks/ifcopenshell
2、切換到root使用者
sudo su
3、建立bim資料目錄:
mkdir /user/home/bim-data
4、給目錄權限:
chmod 777 -R /user/home/bim-data
5、拷貝ifc資料到/user/home/bim-data目錄
6、使用docker指令實作ifc轉obj
docker run -it --privileged=true -u root -v /home/user/bim-data/:/home/user/bim-data aecgeeks/ifcopenshell IfcConvert --y-up -j5 -y ../home/user/bim-data/RST_basic_sample_project.ifc ../home/user/bim-data/RST_basic_sample_project.obj
7、轉換成功後
轉換成功後會生成兩個檔案:*.mtl和*.obj檔案
obj轉3dtiles
1、切換到/home/user目錄
cd /home/user
2、從github上下載下傳最新代碼:
git pull https://github.com/PrincessGod/objTo3d-tiles.git
3、進入objTo3d-tiles目錄
cd objTo3d-tiles
4、建立Dockerfile檔案
touch Dockerfile && chomd 777 Dockerfile
5、進入Dockerfile編輯模式
vim Dockerfile
6、填寫Dockerfile内容
FROM node:18-alpine3.15
WORKDIR ./
COPY package*.json ./
RUN npm install
RUN npm install -g obj23dtiles
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node","./tools/test.js"]
7、建構obj23dtiles鏡像
docker build -t obj23dtiles:v1.0 .
8、使用docker指令實作obj轉3dtiles
sudo docker run -it --privileged=true -u root -v /home/user/bim-data/:/home/user/bim-data obj23dtiles:v1.0 obj23dtiles -i /home/user/bim-data/RST_basic_sample_project.obj --tileset
9、轉換成功後
轉換成功後會生成一個batched*開頭的目錄,裡面内容
使用java微服務方式串聯轉換
@SpringBootApplication
public class App implements CommandLineRunner {
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
private static CountDownLatch countDownLatch = new CountDownLatch(5);
public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(App.class, args)));
}
@Override
public void run(String... args) throws Exception {
if (args.length < 1) {
System.out.println("參數異常!");
return;
}
if(!args[0].endsWith("ifc")){
System.out.println("檔案格式必須是ifc才行!");
return;
}
String ifcPath = args[0];
String objPath = ifcPath.substring(0, ifcPath.lastIndexOf(".")).concat(".obj");
String mtlFileName = ifcPath.substring(ifcPath.lastIndexOf("/") + 1, ifcPath.lastIndexOf(".")).concat(".mtl");
System.out.println(mtlFileName);
System.out.println(objPath);
String cmd1 = "sudo docker run --privileged=true -u root -v /home/user/bim-data:/home/user/bim-data aecgeeks/ifcopenshell IfcConvert --y-up -j5 -y ../" + ifcPath + " ../" + objPath;
String cmd2 = "sed -i '1s/^/mtllib " + mtlFileName + "\\n/' " + objPath + "\n";
String cmd3 = "sudo docker run --privileged=true -u root -v /home/user/bim-data/:/home/user/bim-data obj23dtiles:v1.0 obj23dtiles -i /" + objPath + " --tileset";
executeNewFlow(new String[]{cmd1, cmd2, cmd3});
System.exit(0);
}
public void executeNewFlow(String[] commands) {
Runtime run = Runtime.getRuntime();
fixedThreadPool.execute(
new Runnable() {
public void run() {
try {
Process proc = run.exec("/bin/bash", null, null);
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
for (String line : commands) {
out.println(line);
}
String rspLine = null;
while ((rspLine = in.readLine()) != null) {
System.out.println(rspLine);
if (rspLine.contains("Total:")) {
proc.destroy();
break;
}
}
proc.waitFor();
out.close();
in.close();
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
System.exit(0);
}
}
}
);
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
fixedThreadPool.shutdown();
System.out.println("處理完畢!");
System.exit(0);
}
}
微服務打包上傳jar包
将打好的jar包上傳到/home/user目錄下,并執行如下指令:
java -jar wx-ifc-3dtiles-0.0.1-SNAPSHOT.jar RST_basic_sample_project.ifc RST_basic_sample_project.obj
備注:使用ifcopenshell将ifc轉化為obj的過程中會出現兩個問題:
sed -i '1s/^/mtllib RST_basic_sample_project.mtl \\n' RST_basic_sample_project.obj \n