MCPcopy Create free account
hub / github.com/IfcOpenShell/IfcOpenShell / get_image

Method get_image

src/bonsai/bonsai/tool/loader.py:297–367  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

295 image_url = None
296
297 def get_image() -> Union[bpy.types.Image, None]:
298 # TODO: orphaned textures after shader recreated?
299 if texture["type"] == "IfcImageTexture":
300 # IFC2X3 uses UrlReference, IFC4+ uses URLReference.
301 original_image_url = texture.get("URLReference") or texture.get("UrlReference", "")
302 is_relative = not os.path.isabs(original_image_url)
303 nonlocal image_url
304 image_url = Path(original_image_url)
305 if is_relative:
306 ifc_path = Path(tool.Ifc.get_path())
307 image_url = ifc_path.parent / image_url
308 image_url = image_url.absolute().resolve()
309
310 if not image_url.exists():
311 print(f"WARNING. Couldn't find texture by path {image_url}, it will be skipped.")
312 return
313
314 # keep url relative if it was before
315 image_url = str(image_url)
316 if is_relative and bpy.data.filepath:
317 image_url = bpy.path.relpath(image_url)
318 return bpy.data.images.load(image_url)
319
320 elif texture["type"] == "IfcBlobTexture":
321 # https://blender.stackexchange.com/questions/173206/how-to-efficiently-convert-a-pil-image-to-bpy-types-image
322 # https://blender.stackexchange.com/questions/62072/does-blender-have-a-method-to-a-get-png-formatted-bytearray-for-an-image-via-pyt
323 import io
324
325 from PIL import Image
326
327 value = texture["RasterCode"]
328 image_bytes = int(value, 2).to_bytes(len(value) // 8, "big")
329 pil_image = Image.open(io.BytesIO(image_bytes))
330 byte_to_normalized = 1.0 / 255.0
331 bpy_image = bpy.data.images.new("blob_texture", width=pil_image.width, height=pil_image.height)
332 # PIL returns rows ordered from top to bottom, blender from bottom to top
333 pil_pixel_data = np.asarray(pil_image.convert("RGBA"), dtype=np.float32)
334 bpy_image.pixels[:] = (pil_pixel_data * byte_to_normalized)[::-1].ravel()
335 bpy_image.pack()
336 return bpy_image
337
338 # IfcPixelTexture
339 n_components = texture["ColourComponents"]
340 width, height = texture["Width"], texture["Height"]
341 blender_pixel_data = np.ones(width * height * 4, dtype=np.float32)
342
343 # according to https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/lexical/IfcPixelTexture.htm
344 # 1 component - grey scale intensity value
345 # 2 components - grey scale + alpha
346 # 3 components - RGB
347 # 4 components - RGBA
348 for i, pixel_str in enumerate(iterable=texture["Pixel"]):
349 pixel_bytes = int(pixel_str, 2).to_bytes(len(pixel_str) // 8, "big")
350 pixel_values = np.array(list(pixel_bytes)) / 255
351 cur_pos = i * 4
352
353 if n_components in (1, 2):
354 blender_pixel_data[cur_pos : cur_pos + 3] = pixel_values[0]

Callers

nothing calls this directly

Calls 7

printFunction · 0.85
openMethod · 0.80
newMethod · 0.80
getMethod · 0.45
get_pathMethod · 0.45
loadMethod · 0.45
convertMethod · 0.45

Tested by

no test coverage detected