FreeCAD
124 строки · 3.1 Кб
1# Script to create a Menger sponge
2# (c) 2012 Werner Mayer LGPL
3
4# The script is based on the work of daxmick at
5# https://forum.freecad.org/viewtopic.php?f=3&t=2307
6
7import threading8import Mesh9
10# Create a global mesh and make copies of them
11# This makes the algorithm faster by ~60%.
12box = Mesh.createBox(1,1,1)13
14# Create a Box and Place it a coords (x,y,z)
15def PlaceBox(x,y,z):16global box17mbox=box.copy()18mbox.translate(x,y,z)19return mbox20
21def Sierpinski(level,x0,y0,z0):22#print(threading.current_thread().name)23boxnums = pow(3,level)24thirds = boxnums / 325twothirds = thirds * 226if(level == 0):27rangerx = [x0]28rangery = [y0]29rangerz = [z0]30else:31rangerx = [ x0, x0 + thirds, x0 + twothirds ]32rangery = [ y0, y0 + thirds, y0 + twothirds ]33rangerz = [ z0, z0 + thirds, z0 + twothirds ]34block = 135skip=[5,11,13,14,15,17,23]36mesh=Mesh.Mesh()37for i in rangerx:38for j in rangery:39for k in rangerz:40if block not in skip:41if(level > 0):42mesh.addMesh(Sierpinski(level-1,i,j,k))43else:44mesh.addMesh(PlaceBox(i,j,k))45block+=146return mesh47
48### Multi-threaded ###
49
50class MengerThread(threading.Thread):51def __init__(self,args):52self.args=args53self.mesh=Mesh.Mesh()54threading.Thread.__init__(self)55def run(self):56for i in self.args:57self.mesh.addMesh(Sierpinski(*i))58
59def makeMengerSponge_mt(level=3,x0=0,y0=0,z0=0):60"""61Is much slower than makeMengerSponge!!! :(
62"""
63if level == 0:64mesh=Sierpinski(level,x0,y0,z0)65Mesh.show(mesh)66return67
68boxnums = pow(3,level)69thirds = boxnums / 370twothirds = thirds * 271
72rangerx = [ x0, x0 + thirds, x0 + twothirds ]73rangery = [ y0, y0 + thirds, y0 + twothirds ]74rangerz = [ z0, z0 + thirds, z0 + twothirds ]75block = 176skip=[5,11,13,14,15,17,23]77
78# collect the arguments for the algorithm in a list79args=[]80for i in rangerx:81for j in rangery:82for k in rangerz:83if block not in skip:84args.append((level-1,i,j,k))85block+=186
87numJobs = 488threads=[]89while numJobs > 0:90size = len(args)91count = size / numJobs92numJobs-=193thr=MengerThread(args[:count])94threads.append(thr)95args=args[count:]96
97print("Number of threads: %i" % (len(threads)))98for thr in threads:99thr.start()100for thr in threads:101thr.join()102
103mesh=Mesh.Mesh()104for thr in threads:105mesh.addMesh(thr.mesh)106del thr.mesh107
108print(mesh)109mesh.removeDuplicatedPoints()110mesh.removeFacets(mesh.getInternalFacets())111mesh.rebuildNeighbourHood()112print("Mesh is solid: %s" % (mesh.isSolid()))113Mesh.show(mesh)114
115
116### Single-threaded ###
117
118def makeMengerSponge(level=3,x0=0,y0=0,z0=0):119mesh=Sierpinski(level,x0,y0,z0)120mesh.removeDuplicatedPoints()121mesh.removeFacets(mesh.getInternalFacets())122mesh.rebuildNeighbourHood()123print("Mesh is solid: %s" % (mesh.isSolid()))124Mesh.show(mesh)125