2019-07-02 14:44:42 +02:00
|
|
|
from . import gds
|
2019-07-04 21:19:12 +02:00
|
|
|
from concurrent.futures import ThreadPoolExecutor
|
2019-07-02 14:44:42 +02:00
|
|
|
|
|
|
|
import importlib
|
|
|
|
if "gds" in locals():
|
|
|
|
gds = importlib.reload(gds)
|
|
|
|
|
|
|
|
import pathlib
|
|
|
|
import bpy
|
|
|
|
from bpy_extras.wm_utils.progress_report import ProgressReport
|
|
|
|
|
2019-07-02 19:39:34 +02:00
|
|
|
class Progressor:
|
2019-07-03 13:53:25 +02:00
|
|
|
def __init__(self, wm, precision = 0.0001):
|
2019-07-02 19:39:34 +02:00
|
|
|
self.wm = wm
|
|
|
|
self.report = 0
|
|
|
|
self.precision = precision
|
|
|
|
self.next_update = 0
|
|
|
|
|
|
|
|
@property
|
|
|
|
def total(self):
|
|
|
|
return self.report
|
|
|
|
|
|
|
|
@total.setter
|
|
|
|
def total(self, t):
|
|
|
|
if self.report >= t:
|
|
|
|
return
|
|
|
|
|
|
|
|
if self.report:
|
|
|
|
self.wm.progress_end()
|
2019-07-03 13:53:25 +02:00
|
|
|
self.next_update = 0
|
2019-07-02 19:39:34 +02:00
|
|
|
|
|
|
|
self.wm.progress_begin(0, t)
|
|
|
|
self.report = t
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-02 19:39:34 +02:00
|
|
|
@property
|
|
|
|
def current(self):
|
|
|
|
return 0
|
|
|
|
|
|
|
|
@current.setter
|
|
|
|
def current(self, c):
|
|
|
|
prog = float(c)/self.total
|
|
|
|
if prog >= self.next_update:
|
|
|
|
self.next_update = prog + self.precision
|
|
|
|
self.wm.progress_update(c)
|
|
|
|
|
|
|
|
def end(self):
|
|
|
|
if self.report:
|
|
|
|
self.report = 0
|
2019-07-03 13:53:25 +02:00
|
|
|
self.next_update = 0
|
|
|
|
|
2019-07-02 19:39:34 +02:00
|
|
|
self.wm.progress_end()
|
|
|
|
|
|
|
|
def __call__(self, update):
|
|
|
|
self.total = update.total
|
|
|
|
self.current = update.current
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
class SceneInserter(object):
|
2019-07-03 13:53:25 +02:00
|
|
|
class Layer(object):
|
2019-07-04 21:19:12 +02:00
|
|
|
def __init__(self, context, number, thickness=1, datatypes=[], ):
|
|
|
|
self.number = number
|
|
|
|
self.context = context
|
|
|
|
|
|
|
|
# stackup results
|
|
|
|
self.thickness = thickness
|
|
|
|
self.absolute_height = 0
|
|
|
|
|
|
|
|
# stackup
|
|
|
|
self.Prev = None
|
|
|
|
self.Next = None
|
|
|
|
|
|
|
|
self.groups = {}
|
|
|
|
self.materials = {}
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
for datatype in datatypes:
|
|
|
|
self.new_datatype(type)
|
|
|
|
|
|
|
|
def name_for_layer(self, datatype):
|
|
|
|
return "layer{}/{}".format(self.number, datatype)
|
|
|
|
|
|
|
|
def new_datatype(self, datatype):
|
|
|
|
name = self.name_for_layer(datatype)
|
|
|
|
|
|
|
|
if name not in bpy.data.groups:
|
2019-07-03 13:53:25 +02:00
|
|
|
# create new group
|
2019-07-04 21:19:12 +02:00
|
|
|
self.groups[datatype] = bpy.data.groups.new(name)
|
2019-07-03 13:53:25 +02:00
|
|
|
else:
|
2019-07-04 21:19:12 +02:00
|
|
|
self.groups[datatype] = bpy.data.groups[name]
|
|
|
|
|
|
|
|
if name not in bpy.data.materials:
|
|
|
|
self.materials[name] = bpy.data.materials.new(name)
|
|
|
|
else:
|
|
|
|
self.materials[name] = bpy.data.materials[name]
|
|
|
|
|
|
|
|
|
|
|
|
def group_for_datatype(self, dtype):
|
|
|
|
if dtype not in self.groups:
|
|
|
|
self.new_datatype(dtype)
|
|
|
|
|
|
|
|
return self.groups[dtype]
|
|
|
|
|
|
|
|
def insert_after(self, other):
|
|
|
|
end = self
|
|
|
|
|
|
|
|
while end.Next:
|
|
|
|
end = end.Next
|
|
|
|
|
|
|
|
if self.Prev:
|
|
|
|
self.Prev.Next = None
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
self.Prev = None
|
|
|
|
|
|
|
|
# link own list to new list
|
|
|
|
if other.Next:
|
|
|
|
if other.Next.Prev:
|
|
|
|
other.Next.Prev = end
|
|
|
|
|
|
|
|
end.Next = other.Next
|
|
|
|
|
|
|
|
other.Next = self
|
|
|
|
self.Prev = other
|
|
|
|
|
|
|
|
# recalc height
|
|
|
|
end = self
|
|
|
|
while end:
|
|
|
|
end.absolute_height = end.Prev.absolute_height + end.Prev.thickness
|
|
|
|
end = end.Next
|
|
|
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
|
|
def link(self, datatype, obj):
|
|
|
|
self.group_for_datatype(datatype).objects.link(obj)
|
|
|
|
|
|
|
|
mat = self.materials[self.name_for_layer(datatype)]
|
|
|
|
obj.data.materials.append(mat)
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
|
|
|
|
def __init__(self, context, lib, ignore_structures={}, top_cell=None):
|
|
|
|
self.lib = lib
|
|
|
|
self.context = context
|
|
|
|
|
|
|
|
self.layers = {}
|
|
|
|
self.ignore_structures = {}
|
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
self.add_stackup()
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
self.top_cell = top_cell
|
|
|
|
if top_cell == "":
|
|
|
|
self.top_cell = None
|
|
|
|
|
|
|
|
if self.top_cell:
|
|
|
|
self.top_cell = self.top_cell.strip()
|
|
|
|
return
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
for sname in ignore_structures:
|
|
|
|
if sname in lib.structures:
|
|
|
|
self.ignore_structures[sname] = True
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
def add_layer(self, number, thickness=1):
|
|
|
|
self.layers[number] = SceneInserter.Layer(self.context, number, thickness)
|
|
|
|
return self.layers[number]
|
|
|
|
|
|
|
|
def get_layer(self, number):
|
|
|
|
if number not in self.layers:
|
|
|
|
return self.add_layer(number)
|
|
|
|
|
|
|
|
return self.layers[number]
|
|
|
|
|
|
|
|
def add_stackup(self):
|
|
|
|
prev = None
|
|
|
|
for i in range(0,200):
|
|
|
|
l = self.add_layer(i)
|
|
|
|
if prev:
|
|
|
|
l.insert_after(prev)
|
|
|
|
prev = l
|
|
|
|
|
|
|
|
# example stackup for now
|
|
|
|
#self.add_layer(8).insert_after(self.add_layer(6).insert_after(self.add_layer(5).insert_after(self.add_layer(4))))
|
2019-07-03 13:53:25 +02:00
|
|
|
|
|
|
|
def new_empty(self, name):
|
|
|
|
obj = bpy.data.objects.new(name, None)
|
|
|
|
self.link(obj)
|
|
|
|
return obj
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
def link(self, obj):
|
|
|
|
self.context.scene.objects.link(obj)
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
def build_path_element(self, name, root, element):
|
|
|
|
# build path profile
|
|
|
|
widthcurve = bpy.data.curves.new("profile-" + name , "CURVE")
|
|
|
|
bevelobj = bpy.data.objects.new("profile-" + name , widthcurve)
|
|
|
|
bevelobj.parent = root
|
|
|
|
|
|
|
|
# hide the bevel object
|
|
|
|
self.link(bevelobj)
|
|
|
|
|
|
|
|
bevelobj.hide = True
|
|
|
|
bevelobj.hide_render = True
|
|
|
|
|
|
|
|
widthspline = widthcurve.splines.new("POLY")
|
|
|
|
widthspline.use_smooth = False
|
|
|
|
widthspline.use_cyclic_u = True
|
|
|
|
widthspline.points.add(3)
|
|
|
|
|
|
|
|
# create bevel profile
|
|
|
|
width = element.width * self.lib.units_per_dbunit
|
|
|
|
thickness = self.get_layer(element.layer).thickness
|
|
|
|
|
|
|
|
widthspline.points[0].co = (-1*width/2.0, thickness/2.0, 0,0)
|
|
|
|
widthspline.points[1].co = ( width/2.0, thickness/2.0, 0,0)
|
|
|
|
widthspline.points[2].co = ( width/2.0, -1*thickness/2.0, 0,0)
|
|
|
|
widthspline.points[3].co = (-1*width/2.0, -1*thickness/2.0, 0,0)
|
|
|
|
|
|
|
|
# create actual path
|
|
|
|
pathcurve = bpy.data.curves.new(name, "CURVE")
|
|
|
|
|
|
|
|
pathcurve.use_fill_caps = True
|
|
|
|
pathcurve.bevel_object = bevelobj
|
|
|
|
|
|
|
|
pathspline = pathcurve.splines.new("POLY")
|
|
|
|
pathspline.points.add(len(element.points)-1)
|
|
|
|
pathspline.use_smooth = False
|
|
|
|
|
|
|
|
# import path
|
|
|
|
for i, p in enumerate(element.points):
|
|
|
|
pos = self.lib.normalize_coord(p)
|
|
|
|
pathspline.points[i].co = (pos[0], pos[1], 0,0)
|
|
|
|
|
|
|
|
# setup pathobject
|
|
|
|
pathobj = bpy.data.objects.new(name, pathcurve)
|
|
|
|
self.link(pathobj)
|
|
|
|
self.get_layer(element.layer).link(element.datatype, pathobj)
|
|
|
|
|
|
|
|
pathobj.location.z = self.get_layer(element.layer).absolute_height
|
|
|
|
pathobj.parent = root
|
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
def build_object(self, structure, progress=None):
|
2019-07-03 13:53:25 +02:00
|
|
|
# is the object already existent => return new instance
|
|
|
|
if structure.name in bpy.data.objects:
|
|
|
|
return self.new_instance(bpy.data.objects[structure.name])
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
if progress:
|
|
|
|
progress.total += 1 + len(structure.references)
|
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
# for boundary elements
|
|
|
|
class Mesh:
|
|
|
|
def __init__(self):
|
|
|
|
self.verts = []
|
|
|
|
self.faces = []
|
|
|
|
|
|
|
|
boundaries = {}
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
# create control empty
|
|
|
|
root = self.new_empty(structure.name)
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
# reset name in case blender
|
|
|
|
# changes the object name
|
|
|
|
# (e.g. due to duplicates)
|
|
|
|
structure.name = root.name
|
|
|
|
|
|
|
|
#print("structure name: {}".format(structure.name))
|
|
|
|
|
|
|
|
# add all geometry
|
2019-07-04 21:19:12 +02:00
|
|
|
for number, element in enumerate(structure.elements):
|
|
|
|
index = (element.layer, element.datatype)
|
2019-07-03 13:53:25 +02:00
|
|
|
if isinstance(element, gds.Boundary):
|
2019-07-04 21:19:12 +02:00
|
|
|
# every element should be of derived of gds.Drawable
|
|
|
|
if index not in boundaries:
|
|
|
|
boundaries[index] = Mesh()
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
indices = []
|
|
|
|
for point in element.points[:-1]:
|
|
|
|
pos = self.lib.normalize_coord(point)
|
2019-07-04 21:19:12 +02:00
|
|
|
boundaries[index].verts.append((pos[0], pos[1], 0))
|
|
|
|
indices.append(len(boundaries[index].verts)-1)
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
boundaries[index].faces.append(tuple(indices))
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
elif isinstance(element, gds.Path):
|
|
|
|
cname = "{}-{}[{}]".format(structure.name, number, element.layer)
|
|
|
|
self.build_path_element(cname, root, element)
|
|
|
|
|
|
|
|
else:
|
|
|
|
print("import of {} not implemented".format(type(element)))
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
with ThreadPoolExecutor(max_workers=5) as executor:
|
|
|
|
# build structure mesh for boundary elements
|
|
|
|
for ident, template in boundaries.items():
|
|
|
|
def do_boundary(layerident, meshtemplate):
|
|
|
|
layer = self.get_layer(layerident[0])
|
|
|
|
meshname = "{}[{}]".format(structure.name, layerident)
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
mesh = bpy.data.meshes.new(meshname)
|
|
|
|
mesh.from_pydata(meshtemplate.verts, [], meshtemplate.faces)
|
|
|
|
mesh.update()
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
obj = bpy.data.objects.new(meshname, mesh)
|
|
|
|
self.link(obj)
|
|
|
|
layer.link(layerident[1], obj)
|
|
|
|
obj.parent = root
|
|
|
|
|
|
|
|
# create solifiy modifier
|
|
|
|
mod = obj.modifiers.new("Solidify", 'SOLIDIFY')
|
|
|
|
mod.thickness = 1 # probaly meters ?
|
|
|
|
mod.use_even_offset = True
|
|
|
|
mod.offset = 0
|
|
|
|
obj.location.z = layer.absolute_height
|
|
|
|
|
|
|
|
executor.submit(do_boundary, ident, template)
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
if progress:
|
|
|
|
progress.inc()
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
# handle all references
|
|
|
|
# build tree depth first
|
|
|
|
for reference in structure.references:
|
2019-07-03 14:14:30 +02:00
|
|
|
if isinstance(reference.structure, str):
|
|
|
|
if reference.structure not in self.lib.structures:
|
|
|
|
progress.inc()
|
|
|
|
continue
|
|
|
|
|
|
|
|
# resolve structure
|
|
|
|
reference.structure = self.lib.structures[reference.structure]
|
|
|
|
|
|
|
|
obj = self.build_object(reference.structure, progress=progress)
|
2019-07-03 13:53:25 +02:00
|
|
|
|
|
|
|
if hasattr(reference, "size"):
|
2019-07-04 21:19:12 +02:00
|
|
|
# this is an Array reference
|
2019-07-03 13:53:25 +02:00
|
|
|
def add(a,b):
|
|
|
|
return (a[0] + b[0], a[1] + b[1])
|
|
|
|
def inv(a):
|
|
|
|
return (-a[0], -a[1])
|
|
|
|
|
|
|
|
def sub(a, b):
|
|
|
|
return add(inv(a), b)
|
|
|
|
def scale(a, f):
|
|
|
|
return (a[0] * f, a[1] * f)
|
|
|
|
|
|
|
|
vx = sub(reference.bounds[0], reference.position)
|
|
|
|
vy = sub(reference.bounds[1], reference.position)
|
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
xspace = scale(vx, 1.0/reference.size[0] * self.lib.units_per_dbunit)
|
|
|
|
yspace = scale(vy, 1.0/reference.size[1] * self.lib.units_per_dbunit)
|
|
|
|
|
|
|
|
# use array modifiers to create the aref array
|
|
|
|
for child in obj.children:
|
|
|
|
mod_x = child.modifiers.new("ax", "ARRAY")
|
|
|
|
|
|
|
|
mod_x.use_constant_offset = True
|
|
|
|
mod_x.use_relative_offset = False
|
|
|
|
mod_x.constant_offset_displace[0] = xspace[0]
|
|
|
|
mod_x.constant_offset_displace[1] = xspace[1]
|
|
|
|
mod_x.count = reference.size[0]
|
|
|
|
|
|
|
|
mod_y = child.modifiers.new("ay", "ARRAY")
|
|
|
|
|
|
|
|
mod_y.use_constant_offset = True
|
|
|
|
mod_y.use_relative_offset = False
|
|
|
|
mod_y.constant_offset_displace[0] = yspace[0]
|
|
|
|
mod_y.constant_offset_displace[1] = yspace[1]
|
|
|
|
mod_y.count = reference.size[1]
|
2019-07-03 13:53:25 +02:00
|
|
|
else:
|
|
|
|
# this is a single reference
|
|
|
|
# just copy the object
|
|
|
|
pass
|
|
|
|
|
|
|
|
# use single arrow for references
|
|
|
|
obj.empty_draw_type = "SINGLE_ARROW"
|
|
|
|
|
|
|
|
# reparent new instance
|
|
|
|
obj.parent = root
|
|
|
|
|
|
|
|
pos = self.lib.normalize_coord(reference.position)
|
|
|
|
obj.location = (pos[0], pos[1], 0)
|
|
|
|
|
|
|
|
# apply transformations
|
|
|
|
trans = reference.transformation
|
|
|
|
obj.rotation_euler.z = math.radians(trans.rotation)
|
|
|
|
obj.scale = (trans.zoom, trans.zoom, 1)
|
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
if progress:
|
|
|
|
progress.inc()
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
return root
|
|
|
|
|
|
|
|
def new_instance(self, obj):
|
|
|
|
root = obj.copy()
|
|
|
|
self.link(root)
|
|
|
|
|
|
|
|
for child in obj.children:
|
2019-07-04 21:19:12 +02:00
|
|
|
if child.name.find("profile") != -1:
|
|
|
|
# only copy path profiles
|
|
|
|
continue
|
2019-07-03 13:53:25 +02:00
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
childObj = child.copy()
|
2019-07-03 13:53:25 +02:00
|
|
|
childObj.parent = root
|
2019-07-04 21:19:12 +02:00
|
|
|
self.link(childObj)
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
# relink copy to groups
|
|
|
|
for group in child.users_group:
|
|
|
|
group.objects.link(childObj)
|
|
|
|
|
2019-07-04 21:19:12 +02:00
|
|
|
# resetup curves
|
|
|
|
if childObj.type == "CURVE":
|
|
|
|
for spline in childObj.data.splines:
|
|
|
|
spline.use_smooth = False
|
|
|
|
|
|
|
|
|
|
|
|
# copy profile
|
|
|
|
profile = bpy.data.objects["profile-" + child.name].copy()
|
|
|
|
profile.parent = root
|
|
|
|
self.link(profile)
|
|
|
|
|
|
|
|
# resetup path
|
|
|
|
childObj.data.use_fill_caps = True
|
|
|
|
childObj.data.bevel_object = profile
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
return root
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
|
|
|
|
def __call__(self, progress=None):
|
|
|
|
class ProgressTracker:
|
2019-07-03 14:14:30 +02:00
|
|
|
def __init__(self, callback, total=0):
|
2019-07-03 13:53:25 +02:00
|
|
|
self.total = total
|
|
|
|
self.current = 0
|
|
|
|
self.callback = callback
|
|
|
|
|
|
|
|
def inc(self):
|
|
|
|
if self.callback:
|
|
|
|
self.current += 1
|
|
|
|
self.callback(self)
|
|
|
|
|
|
|
|
|
|
|
|
# build one cell only
|
|
|
|
if self.top_cell:
|
|
|
|
if self.top_cell not in self.lib.structures:
|
|
|
|
return None
|
2019-07-03 14:14:30 +02:00
|
|
|
s = self.lib.structures[self.top_cell]
|
|
|
|
|
|
|
|
progressTracker = ProgressTracker(progress, 1+len(s.references))
|
|
|
|
self.build_object(s,progress=progressTracker)
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
return True
|
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
progressTracker = ProgressTracker(progress)
|
|
|
|
progressTracker.total = len(self.lib.structures)
|
|
|
|
|
|
|
|
# self.link_all_refs(progressTracker)
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
# build all structures first
|
|
|
|
# since references could reference unknown objects otherwise
|
|
|
|
for name, value in self.lib.structures.items():
|
|
|
|
progressTracker.inc()
|
|
|
|
if name in self.ignore_structures:
|
|
|
|
continue
|
|
|
|
|
2019-07-03 14:14:30 +02:00
|
|
|
self.build_object(value, progress=progressTracker)
|
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
import math
|
2019-07-02 19:39:34 +02:00
|
|
|
|
2019-07-02 14:44:42 +02:00
|
|
|
def load(context,
|
|
|
|
filepath,
|
|
|
|
*,
|
2019-07-03 13:53:25 +02:00
|
|
|
top_cell_name=""
|
2019-07-02 14:44:42 +02:00
|
|
|
):
|
|
|
|
|
2019-07-02 19:39:34 +02:00
|
|
|
lib = None
|
2019-07-04 21:19:12 +02:00
|
|
|
|
2019-07-02 14:44:42 +02:00
|
|
|
with ProgressReport(context.window_manager) as progress:
|
2019-07-02 19:39:34 +02:00
|
|
|
progress.enter_substeps(2, "Importing GDS %r..." % filepath)
|
|
|
|
prog = Progressor(context.window_manager)
|
2019-07-02 14:44:42 +02:00
|
|
|
with open(filepath, "rb") as f:
|
2019-07-02 19:39:34 +02:00
|
|
|
lib = gds.parse_file(f, progress_func=prog)
|
2019-07-02 14:44:42 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
progress.step("linking references")
|
2019-07-02 19:39:34 +02:00
|
|
|
prog.end()
|
2019-07-02 14:44:42 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
if not SceneInserter(context=context, lib=lib, top_cell=top_cell_name)(prog):
|
|
|
|
return {"CANCELLED"}
|
2019-07-02 14:44:42 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
progress.leave_substeps("Done")
|
2019-07-04 21:19:12 +02:00
|
|
|
prog.end()
|
2019-07-02 20:05:01 +02:00
|
|
|
|
2019-07-03 13:53:25 +02:00
|
|
|
context.scene.update()
|
2019-07-02 19:39:34 +02:00
|
|
|
|
2019-07-02 14:44:42 +02:00
|
|
|
|
|
|
|
return {"FINISHED"}
|
|
|
|
|