天天看點

基于docker方式:BIM模型轉3dtiles

作者:愛生活的百靈鳥bird

什麼是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目錄

基于docker方式:BIM模型轉3dtiles

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檔案

基于docker方式:BIM模型轉3dtiles

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*開頭的目錄,裡面内容

基于docker方式:BIM模型轉3dtiles
基于docker方式:BIM模型轉3dtiles

使用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