C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

迷路を作る3

こちらの続きです。
迷路を作る2 - C#ATIA

最近知ったTemporaryBRepManagerのパワーを感じたくて、
修正してみました。

#FusionAPI_python test_Maze ver0.0.3
#Author-kantoku
#Description-迷路ボディの作成

'''
The MIT License (MIT)

Copyright (c) 2014 BoppreH

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
'''

import adsk.core, adsk.fusion, traceback
import os, sys, time
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

#thx-boppreh
#https://github.com/boppreh/maze
import maze

unit = 2.0

def run(context):
    row_num = 0
    column_num = 0
    
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        #ユーザー入力
        row_num, column_num = GetMazeSize(ui)
        if row_num == None:
            return
        
        #doc
        NewDoc(app)
        root = app.activeProduct.rootComponent
        
        des = root.parentDesign
        des.designType = adsk.fusion.DesignTypes.DirectDesignType
        bodies = root.bRepBodies
        
        #拡張
        maze.Maze.exp = expWallMap
        
        #time
        t = time.time()
        
        #迷路取得
        mz = maze.Maze.generate(row_num,column_num)
        wall = mz.exp()
        print('迷路取得:{:.2f}s'.format(time.time()- t))
        
        #cog
        halfUnit = unit*0.5
        cogs = []
        for j,y in enumerate(wall):
            for i,x in enumerate(y):
                if x:
                    cogs.append([i*unit + halfUnit, j*unit + halfUnit, halfUnit])
        print('cog:{:.2f}s'.format(time.time()- t))
                    
        #maze3D
        InitBoxs(cogs,bodies)
        print('box:{:.2f}s'.format(time.time()- t))
        
        #ParametricDesign
        des.designType = adsk.fusion.DesignTypes.ParametricDesignType
        
        #finish
        ui.messageBox('done\ntime:{:.2f}s'.format(time.time()- t))

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

def GetMazeSize(ui):
    msg = '作成する迷路のサイズを入力してください。(例: 10,10)'
    txt, cancelled = ui.inputBox(msg, 'Maze', '10,10')
    if cancelled:
        return None, None
    
    ary = txt.split(',')
    if len(ary) != 2:
        return None, None
    
    if not ary[0].isdigit() or not ary[1].isdigit():
        return None, None
    
    return int(ary[0]), int(ary[1])
    
def NewDoc(app):
    return app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)

def InitBoxs(cogs, bodies):
    tmpBrep = adsk.fusion.TemporaryBRepManager.get()    
    
    pnt3D = adsk.core.Point3D
    l_Dir = adsk.core.Vector3D.create(1.0, 0.0, 0.0)
    w_Dir = adsk.core.Vector3D.create(0.0, 1.0, 0.0)
    obb3D = adsk.core.OrientedBoundingBox3D
    
    #OrientedBoundingBox3D
    obbs = [obb3D.create(pnt3D.create(x,y,z),l_Dir,w_Dir,unit,unit,unit) 
        for (x,y,z) in cogs]
            
    #TemporaryBox
    boxs = [tmpBrep.createBox(obb) for obb in obbs]

    union = adsk.fusion.BooleanTypes.UnionBooleanType
    maze3d = boxs[0]
    
    #Union
    [tmpBrep.booleanOperation(maze3d, box, union) for box in boxs]
    
    #Add
    bodies.add(maze3d)
    
    return

#maze.Maze
def expWallMap(self):
    return [convIsWallLst(v) for v in self._to_str_matrix()[::-1]]

def convIsWallLst(lst):
    return [True if v == 'O' else False for v in lst]

自宅の非力なPCで試しましたが、10x10の設定で

Ver0.0.2 : 20.98秒
Ver0.0.3 : 2.90秒

速い! コードも短くなりました。

Ver0.0.2では時間がかかり過ぎそうなので試しませんが、

30x30 : 41.98秒
50x50 : 223.96秒

まぁ そこそこのスピードです。

f:id:kandennti:20190515002135p:plain

さらに驚くことに、あなたにも僕にも、全く役に立たない・・・。