diff --git a/README.md b/README.md index f7b5127..ccbc404 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ BlenderGDS enables semiconductor layout visualization by importing GDSII files i * IHP Open PDK (SG13G2 & CMOS5L) * SkyWater SKY130 PDK * GlobalFoundries GF180MCU PDK +* SiEPIC EBeam PDK (silicon photonics) ## Installation diff --git a/import_gdsii/__init__.py b/import_gdsii/__init__.py index 255a28a..22cd7aa 100644 --- a/import_gdsii/__init__.py +++ b/import_gdsii/__init__.py @@ -51,6 +51,11 @@ 'config_path': 'configs/gf180mcu.yaml', 'color_path': 'configs/colors/gf180mcu/' }, + 'SIEPIC_EBEAM': { + 'name': 'SiEPIC EBeam PDK', + 'config_path': 'configs/siepic.yaml', + 'color_path': 'configs/colors/siepic/' + }, } @@ -58,7 +63,7 @@ # SCENE SETUP FUNCTIONS # ============================================================================ -def setup_chip_scene(chip_x, chip_y, collection=None): +def setup_chip_scene(x_min, y_min, x_max, y_max, collection=None): """Initialize scene with camera, light, and chip base""" # Determine which collection to use target_collection = collection if collection is not None else bpy.context.collection @@ -126,8 +131,8 @@ def setup_chip_scene(chip_x, chip_y, collection=None): target_collection.objects.link(cam) bpy.context.scene.camera = cam - # Position camera above the chip - cam.location = (chip_x / 2, chip_y / 2, 200) + # Position camera above the chip center + cam.location = ((x_min + x_max) / 2, (y_min + y_max) / 2, 200) cam.rotation_euler = (0, 0, 0) # -------------------------- @@ -137,11 +142,11 @@ def setup_chip_scene(chip_x, chip_y, collection=None): chip_base = bpy.data.objects.new("ChipBase", mesh) target_collection.objects.link(chip_base) - # Define vertices for a plane of correct size - verts = [(0, 0, -1), - (0, chip_y, -1), - (chip_x, chip_y, -1), - (chip_x, 0, -1)] + # Define vertices for a plane spanning the actual chip bbox + verts = [(x_min, y_min, -1), + (x_min, y_max, -1), + (x_max, y_max, -1), + (x_max, y_min, -1)] faces = [(0, 1, 2, 3)] mesh.from_pydata(verts, [], faces) mesh.update() @@ -337,6 +342,7 @@ class GDSIIPreImportDialog(bpy.types.Operator): ('IHP_SG13CMOS5L', "IHP Open PDK SG13CMOS5L", "IHP SG13CMOS5L 130nm CMOS5L process"), ('SKY130', "SkyWater SKY130 PDK", "SkyWater SKY130 130nm process"), ('GF180MCU', "GlobalFoundries GF180MCU PDK", "GlobalFoundries GF180MCU 180nm process"), + ('SIEPIC_EBEAM', "SiEPIC EBeam PDK", "SiEPIC EBeam silicon photonics PDK (220 nm SOI)"), ], default='IHP_SG13G2', ) @@ -607,19 +613,16 @@ def import_gdsii(self, context, filepath): self.crop_y + self.crop_height ) crop_offset = (self.crop_x, self.crop_y) - chip_width = self.crop_width - chip_height = self.crop_height + # Cropped polygons are shifted so the lower-left sits at the origin. + bbox_min = (0.0, 0.0) + bbox_max = (self.crop_width, self.crop_height) print(f"Cropping to region: X={self.crop_x}, Y={self.crop_y}, W={self.crop_width}, H={self.crop_height}") else: # Determine chip dimensions for scene setup lib = gdstk.read_gds(filepath, unit=self.unit_scale) bboxes = [c.bounding_box() for c in lib.top_level() if c.bounding_box() is not None] - xmin = min(b[0][0] for b in bboxes) - ymin = min(b[0][1] for b in bboxes) - xmax = max(b[1][0] for b in bboxes) - ymax = max(b[1][1] for b in bboxes) - chip_width = xmax - xmin - chip_height = ymax - ymin + bbox_min = (min(b[0][0] for b in bboxes), min(b[0][1] for b in bboxes)) + bbox_max = (max(b[1][0] for b in bboxes), max(b[1][1] for b in bboxes)) # Create collection for imported layers collection = None @@ -633,7 +636,7 @@ def import_gdsii(self, context, filepath): # Setup scene if requested if self.setup_scene: - setup_chip_scene(chip_width, chip_height, collection) + setup_chip_scene(bbox_min[0], bbox_min[1], bbox_max[0], bbox_max[1], collection) addon_dir = Path(__file__).parent if use_custom: diff --git a/import_gdsii/configs/colors/siepic/fancy.yaml b/import_gdsii/configs/colors/siepic/fancy.yaml new file mode 100644 index 0000000..884e437 --- /dev/null +++ b/import_gdsii/configs/colors/siepic/fancy.yaml @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2026 Tom +# +# SPDX-License-Identifier: GPL-3.0-or-later + +name: Fancy +description: Fancy color scheme - vivid flat aesthetic +layers: + # Silicon — pink/magenta (matches SiEPIC KLayout default) + Si: + color: [1.00, 0.50, 0.66, 1.0] + metallic: 0.0 + roughness: 1.0 + SiRib90: + color: [0.50, 0.66, 1.00, 1.0] + metallic: 0.0 + roughness: 1.0 + SiLitho193: + color: [0.80, 0.50, 0.66, 1.0] + metallic: 0.0 + roughness: 1.0 + + # SiN — light blue + SiN: + color: [0.65, 0.81, 0.89, 0.95] + metallic: 0.0 + roughness: 1.0 + + # Doping — vivid violet / blue + SiNdope: + color: [0.44, 0.00, 1.00, 0.95] + metallic: 0.0 + roughness: 1.0 + SiNppdope: + color: [0.10, 0.20, 1.00, 0.95] + metallic: 0.0 + roughness: 1.0 + + # Oxide open — orange + OxideOpen: + color: [1.00, 0.68, 0.00, 0.6] + metallic: 0.0 + roughness: 1.0 + + # M1 heater — gold/yellow + M1Heater: + color: [0.92, 0.78, 0.20, 1.0] + metallic: 0.0 + roughness: 1.0 + + # VC — deep purple + VC: + color: [0.23, 0.01, 0.50, 1.0] + metallic: 0.0 + roughness: 1.0 + + # M2 — vivid blue + M2Router: + color: [0.20, 0.44, 0.92, 1.0] + metallic: 0.0 + roughness: 1.0 + + # Metal opening — black + MOpen: + color: [0.00, 0.00, 0.00, 1.0] + metallic: 0.0 + roughness: 1.0 + + # Etches — silvery / pale green + DeepTrench: + color: [0.75, 0.75, 0.75, 1.0] + metallic: 0.0 + roughness: 1.0 + IsolationTrench: + color: [0.75, 0.75, 0.75, 1.0] + metallic: 0.0 + roughness: 1.0 + ShelfEtch: + color: [0.75, 0.88, 0.75, 1.0] + metallic: 0.0 + roughness: 1.0 diff --git a/import_gdsii/configs/colors/siepic/marketing-gold.yaml b/import_gdsii/configs/colors/siepic/marketing-gold.yaml new file mode 100644 index 0000000..fb521ce --- /dev/null +++ b/import_gdsii/configs/colors/siepic/marketing-gold.yaml @@ -0,0 +1,75 @@ +# SPDX-FileCopyrightText: 2026 Tom +# +# SPDX-License-Identifier: GPL-3.0-or-later + +name: Marketing (Gold) +description: Marketing color scheme with gold +layers: + # Silicon — vibrant violet-grey + Si: + color: [0.50, 0.40, 0.65, 1.0] + metallic: 0.6 + roughness: 0.35 + SiRib90: + color: [0.40, 0.50, 0.70, 1.0] + metallic: 0.6 + roughness: 0.35 + SiLitho193: + color: [0.62, 0.40, 0.62, 1.0] + metallic: 0.6 + roughness: 0.35 + + # SiN — clean teal + SiN: + color: [0.55, 0.78, 0.78, 0.85] + roughness: 0.3 + + # Doping — rich pink/violet + SiNdope: + color: [0.65, 0.30, 0.55, 0.95] + metallic: 0.5 + roughness: 0.4 + SiNppdope: + color: [0.40, 0.20, 0.65, 0.95] + metallic: 0.5 + roughness: 0.4 + + # Oxide opening — warm gold tint + OxideOpen: + color: [0.98, 0.78, 0.30, 0.5] + metallic: 0.4 + roughness: 0.3 + + # Heater — gold accent + M1Heater: + color: [0.92, 0.72, 0.22, 1.0] + metallic: 0.8 + roughness: 0.3 + + # VC — gold via + VC: + color: [0.86, 0.62, 0.20, 1.0] + metallic: 0.8 + roughness: 0.3 + + # M2 routing — luxurious gold + M2Router: + color: [0.98, 0.82, 0.32, 1.0] + metallic: 0.85 + roughness: 0.25 + + # Passivation opening — deep contrast + MOpen: + color: [0.06, 0.06, 0.08, 0.9] + roughness: 0.55 + + # Etches — cool dark contrast + DeepTrench: + color: [0.04, 0.04, 0.06, 0.95] + roughness: 0.7 + IsolationTrench: + color: [0.10, 0.10, 0.12, 0.9] + roughness: 0.6 + ShelfEtch: + color: [0.30, 0.28, 0.26, 0.8] + roughness: 0.5 diff --git a/import_gdsii/configs/colors/siepic/marketing.yaml b/import_gdsii/configs/colors/siepic/marketing.yaml new file mode 100644 index 0000000..b38dfdd --- /dev/null +++ b/import_gdsii/configs/colors/siepic/marketing.yaml @@ -0,0 +1,74 @@ +# SPDX-FileCopyrightText: 2026 Tom +# +# SPDX-License-Identifier: GPL-3.0-or-later + +name: Marketing +description: Marketing color scheme +layers: + # Silicon device layer (enhanced purple-grey) + Si: + color: [0.48, 0.42, 0.55, 1.0] + metallic: 0.6 + roughness: 0.35 + SiRib90: + color: [0.42, 0.46, 0.55, 1.0] + metallic: 0.6 + roughness: 0.35 + SiLitho193: + color: [0.55, 0.42, 0.55, 1.0] + metallic: 0.6 + roughness: 0.35 + + # SiN — soft blue tint + SiN: + color: [0.60, 0.72, 0.78, 0.85] + roughness: 0.3 + + # Doping — subtle pink/violet + SiNdope: + color: [0.55, 0.40, 0.55, 0.95] + metallic: 0.5 + roughness: 0.45 + SiNppdope: + color: [0.40, 0.40, 0.70, 0.95] + metallic: 0.5 + roughness: 0.45 + + # Oxide opening — warm translucent + OxideOpen: + color: [0.95, 0.78, 0.55, 0.4] + roughness: 0.25 + + # Heater — warm metal + M1Heater: + color: [0.78, 0.66, 0.40, 1.0] + metallic: 0.7 + roughness: 0.4 + + # VC — dark contrast tungsten + VC: + color: [0.38, 0.40, 0.43, 1.0] + metallic: 0.8 + roughness: 0.35 + + # M2 routing — bright clean aluminum + M2Router: + color: [0.78, 0.80, 0.84, 1.0] + metallic: 0.8 + roughness: 0.25 + + # Passivation opening + MOpen: + color: [0.08, 0.08, 0.10, 0.9] + roughness: 0.55 + + # Etches — cool darker tones + DeepTrench: + color: [0.04, 0.04, 0.06, 0.95] + roughness: 0.7 + IsolationTrench: + color: [0.10, 0.10, 0.14, 0.90] + roughness: 0.6 + ShelfEtch: + color: [0.28, 0.30, 0.32, 0.8] + roughness: 0.5 diff --git a/import_gdsii/configs/colors/siepic/realistic.yaml b/import_gdsii/configs/colors/siepic/realistic.yaml new file mode 100644 index 0000000..d3bae66 --- /dev/null +++ b/import_gdsii/configs/colors/siepic/realistic.yaml @@ -0,0 +1,74 @@ +# SPDX-FileCopyrightText: 2026 Tom +# +# SPDX-License-Identifier: GPL-3.0-or-later + +name: Realistic +description: Realistic color scheme +layers: + # Silicon device layer (slightly purple-grey crystalline appearance) + Si: + color: [0.42, 0.40, 0.45, 1.0] + metallic: 0.6 + roughness: 0.4 + SiRib90: + color: [0.42, 0.40, 0.45, 1.0] + metallic: 0.6 + roughness: 0.4 + SiLitho193: + color: [0.42, 0.40, 0.45, 1.0] + metallic: 0.6 + roughness: 0.4 + + # Silicon nitride (slightly yellow-green, semi-transparent) + SiN: + color: [0.55, 0.55, 0.45, 0.85] + roughness: 0.35 + + # Doped silicon regions (faint reddish tint over Si) + SiNdope: + color: [0.50, 0.40, 0.42, 0.95] + metallic: 0.5 + roughness: 0.45 + SiNppdope: + color: [0.60, 0.35, 0.38, 0.95] + metallic: 0.5 + roughness: 0.45 + + # Oxide opening — translucent window + OxideOpen: + color: [0.85, 0.88, 0.95, 0.35] + roughness: 0.2 + + # TiW heater — darker steel + M1Heater: + color: [0.50, 0.50, 0.55, 1.0] + metallic: 0.7 + roughness: 0.45 + + # Tungsten via + VC: + color: [0.45, 0.46, 0.48, 1.0] + metallic: 0.8 + roughness: 0.4 + + # Aluminum routing metal + M2Router: + color: [0.75, 0.76, 0.77, 1.0] + metallic: 0.8 + roughness: 0.3 + + # Passivation opening (dark cavity) + MOpen: + color: [0.10, 0.10, 0.10, 0.85] + roughness: 0.6 + + # Etched trenches — dark cavities + DeepTrench: + color: [0.05, 0.05, 0.05, 0.95] + roughness: 0.7 + IsolationTrench: + color: [0.10, 0.10, 0.10, 0.90] + roughness: 0.65 + ShelfEtch: + color: [0.25, 0.25, 0.25, 0.80] + roughness: 0.55 diff --git a/import_gdsii/configs/siepic.yaml b/import_gdsii/configs/siepic.yaml new file mode 100644 index 0000000..c42e261 --- /dev/null +++ b/import_gdsii/configs/siepic.yaml @@ -0,0 +1,106 @@ +# SPDX-FileCopyrightText: 2026 Tom +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# SiEPIC EBeam PDK — silicon photonics SOI process +# Reference: https://github.com/SiEPIC/SiEPIC_EBeam_PDK (klayout/EBeam/EBeam.lyp) +# Stack assumes a 220 nm Si device layer on buried oxide, with SiN above the Si +# in the upper cladding, then TiW heater (M1), tungsten via (VC), and Al routing (M2). + +# 220 nm patterned silicon waveguide layer +Si: + index: 1 + type: 0 + z: 0.0 + height: 0.220 + +# 90 nm partial-etch rib (slab portion of rib waveguides) +SiRib90: + index: 2 + type: 0 + z: 0.0 + height: 0.090 + +# Alternate Si lithography mask (193 nm DUV variant) +SiLitho193: + index: 1 + type: 69 + z: 0.0005 + height: 0.220 + +# 400 nm silicon nitride waveguide, sitting in upper cladding above Si +SiN: + index: 4 + type: 0 + z: 0.700 + height: 0.400 + +# N-type doping in Si (offset slightly above Si to keep its top face visible) +SiNdope: + index: 20 + type: 0 + z: 0.001 + height: 0.220 + +# N++ heavy doping (offset further to differentiate from N region) +SiNppdope: + index: 24 + type: 0 + z: 0.0015 + height: 0.220 + +# Oxide opening — window etched through cladding down to BOX +OxideOpen: + index: 6 + type: 0 + z: 0.0 + height: 0.050 + +# M1 heater metal (TiW), sits above Si separated by oxide cladding +M1Heater: + index: 11 + type: 0 + z: 2.000 + height: 0.200 + +# VC — tungsten via from M1 to M2 +VC: + index: 40 + type: 0 + z: 2.200 + height: 0.400 + +# M2 routing metal (aluminum) +M2Router: + index: 12 + type: 0 + z: 2.600 + height: 0.600 + +# Metal opening — passivation opening over bondpads +MOpen: + index: 13 + type: 0 + z: 3.200 + height: 0.050 + +# Deep trench (substrate cavity) +DeepTrench: + index: 201 + type: 0 + z: -2.000 + height: 2.000 + +# Isolation trench (mid-depth) +IsolationTrench: + index: 203 + type: 0 + z: -1.000 + height: 1.000 + +# Shallow shelf etch +ShelfEtch: + index: 205 + type: 0 + z: -0.300 + height: 0.300