You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
6.1KB

  1. import pya
  2. import os
  3. from PIL import Image
  4. base_dir = os.path.dirname(os.path.abspath(__file__))
  5. #for some reason pya is not getting the size so using PIL
  6. im = Image.open(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_0_final.png"))
  7. #width, height = [100, 100]
  8. width, height = im.size
  9. im.close()
  10. # create layout
  11. layout = pya.Layout()
  12. layout.dbu = 0.01
  13. image = layout.create_cell("Image")
  14. layer1_index = layout.insert_layer(pya.LayerInfo.new(1, 0))
  15. layer2_index = layout.insert_layer(pya.LayerInfo.new(2, 0))
  16. image1 = pya.Image(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_0_final.png"))
  17. # The dimension of one pixel
  18. pixelSize = 2000
  19. # image distance in pixels minus the 2 pixel offset
  20. shift_mult = 5
  21. image_dist = (shift_mult * 3 * 2)
  22. image1_region = pya.Region()
  23. image2_region = pya.Region()
  24. image1_region_bb = pya.Region()
  25. image2_region_bb = pya.Region()
  26. final_region = pya.Region()
  27. # Iterate over all rows in image1
  28. for y in range(height):
  29. # Iterate over all columns in image1
  30. for x in range(width):
  31. # Use each channel for a different layer
  32. # d > 0.5 selects all pixels with a level > 50% in that channel
  33. d = image1.get_pixel(x, y, 0)
  34. if d < 0.5:
  35. # Create a polygon corresponding to one pixel
  36. p1 = pya.DPoint((x * pixelSize) - (0.5 * width * pixelSize), (y * pixelSize) - (0.5 * width * pixelSize))
  37. p2 = pya.DPoint(((x + 1) * pixelSize) - (0.5 * width * pixelSize), ((y + 1) * pixelSize) - (0.5 * width * pixelSize))
  38. dbox = pya.DBox(p1, p2)
  39. box = pya.Box.from_dbox(dbox)
  40. poly = pya.Polygon(box)
  41. image1_region.insert(poly)
  42. image1._destroy()
  43. image2 = pya.Image(os.path.join(base_dir, "..", "visualizations", "11735", "shadow_img_1_final.png"))
  44. # Iterate over all rows in image2
  45. for y in range(image_dist, height - image_dist):
  46. # Iterate over all columns in image2
  47. for x in range(image_dist, width - image_dist):
  48. # Use each channel for a different layer
  49. # d > 0.5 selects all pixels with a level > 50% in that channel
  50. d = image2.get_pixel(x, y, 0)
  51. if d < 0.5:
  52. # Create a polygon corresponding to one pixel
  53. p1 = pya.DPoint((x * pixelSize) - (0.5 * width * pixelSize), (y * pixelSize) - (0.5 * width * pixelSize))
  54. p2 = pya.DPoint(((x + 1) * pixelSize) - (0.5 * width * pixelSize), ((y + 1) * pixelSize) - (0.5 * width * pixelSize))
  55. dbox = pya.DBox(p1, p2)
  56. box = pya.Box.from_dbox(dbox)
  57. poly = pya.Polygon(box)
  58. image2_region.insert(poly)
  59. print("pixel import finished")
  60. image2._destroy()
  61. image1_bb = pya.Box(-0.5 * width * pixelSize, -0.5 * height * pixelSize, 0.5 * width * pixelSize, 0.5 * width * pixelSize)
  62. image2_bb = pya.Box(((-0.5 * width) + image_dist) * pixelSize, ((-0.5 * height) + image_dist) * pixelSize, ((0.5 * width) - image_dist) * pixelSize, ((0.5 * height) - image_dist) * pixelSize)
  63. image1_region_bb.insert(image1_bb)
  64. image2_region_bb.insert(image2_bb)
  65. #if you resize image1, you must sent merged_semantics to True!!!!
  66. #image1_region.merged_semantics = False
  67. #image2_region.merged_semantics = False
  68. #image1_region_inverse.merged_semantics = False
  69. #image2_region_inverse.merged_semantics = False
  70. #image1_region_bb.merged_semantics = False
  71. #image2_region_bb.merged_semantics = False
  72. #final_region.merged_semantics = False
  73. #image1_region.strict_handling = True
  74. #image2_region.strict_handling = True
  75. #image1_region_inverse.strict_handling = True
  76. #image2_region_inverse.strict_handling = True
  77. #image2_region.strict_handling = True
  78. #image1_region_bb.strict_handling = True
  79. #image2_region_bb.strict_handling = True
  80. #final_region.strict_handling = True
  81. #image1_region.size(25) #opting not to resize image1
  82. image2_region.size(150)
  83. print("resize finished")
  84. image_layout = pya.Layout()
  85. image = image_layout.create_cell("Image")
  86. image_layout.dbu = 0.01
  87. layer1_image_index = image_layout.insert_layer(pya.LayerInfo.new(1, 0))
  88. layer2_image_index = image_layout.insert_layer(pya.LayerInfo.new(2, 0))
  89. print("finalizing layout for image_overlapped.gds")
  90. #normal
  91. image.shapes(layer1_index).insert(image1_region)
  92. image_layout.clip(image.cell_index(), image1_bb)
  93. processor = pya.ShapeProcessor()
  94. processor.merge(image_layout, image, layer1_image_index, image.shapes(layer1_image_index), False, 0, False, True)
  95. print("layer1 finished")
  96. image.shapes(layer2_image_index).insert(image2_region_bb & image2_region)
  97. print("layer2 finished")
  98. print("layout for image_overlapped.gds finished")
  99. image_layout.write(os.path.join(base_dir, "..", "gds", "image_overlapped.gds"))
  100. print("image_overlapped.gds written")
  101. image_inv_layout = pya.Layout()
  102. image_inv = image_inv_layout.create_cell("Image_Inverse")
  103. image_inv_layout.dbu = 0.01
  104. layer1_image_inv_index = image_inv_layout.insert_layer(pya.LayerInfo.new(1, 0))
  105. layer2_image_inv_index = image_inv_layout.insert_layer(pya.LayerInfo.new(2, 0))
  106. print("finalizing layout for image_overlapped_inverse.gds")
  107. #inverted
  108. #image_inv.shapes(layer1_index).insert(pya.Box(-7500000, -6850000, 7500000, 6850000 - 1850000)) #printable area wafer 1
  109. #image_inv.shapes(layer2_index).insert(pya.Box(-7500000, 6850000, 7500000, -1 * (6850000 - 1850000))) #printable area wafer 2
  110. #the printable areas are rotated for the overlay with the alignment marks
  111. image_inv.shapes(layer1_index).insert(pya.Box(-7500000, -6850000, 7500000, 6850000 - 1850000).transformed(pya.Trans(1, False, 0, 0))) #printable area wafer 1
  112. image_inv.shapes(layer2_index).insert(pya.Box(-7500000, 6850000, 7500000, -1 * (6850000 - 1850000)).transformed(pya.Trans(1, False, 0, 0))) #printable area wafer 2
  113. processor = pya.ShapeProcessor()
  114. processor.boolean(image_layout, image, layer1_image_index, image_inv_layout, image_inv, layer1_image_inv_index, image_inv.shapes(layer1_image_inv_index), 3, False, False, True)
  115. print("layer1 finished")
  116. processor = pya.ShapeProcessor()
  117. processor.boolean(image_layout, image, layer2_image_index, image_inv_layout, image_inv, layer2_image_inv_index, image_inv.shapes(layer2_image_inv_index), 3, False, False, True)
  118. print("layer2 finished")
  119. print("layout for image_overlapped_inverse.gds finished")
  120. image_inv_layout.write(os.path.join(base_dir, "..", "gds", "inverted_tonality", "image_overlapped_inverse.gds"))
  121. print("image_overlapped_inverse.gds written")