Extract Information From Binary STL Files

Introduction

This is a problem in extracting information from binary data. In this case we are using STL files.

We are using STL files because they have a simple internal structure.

For examples of code that extracts information from binary data click HERE .

Project #0

What is a STL file?

Project #1

Display the internals of a binary STL file using the code framework below. Fill in the missing code.

Click HERE to download a binary STL file to test with. It defines a cube.

Add comments to the code?

Project #2

Take ASCII STL data (text file?) and create a binary file version of it.

Project #3

Each STL facet has three vertices and a normal vector. What is the normal vector used for?

Code Framework

#!/usr/bin/python3 # =============================================================== # Dsplay STL ("StereoLithography") file internals # =============================================================== import struct # --------------------------------------------------------------- # ---- create a string describing hex byte values # ---- from a byte array # --------------------------------------------------------------- def my_byte_string(byts:bytes) -> None: lst = [] for byt in byts: lst.append('\\x' + f'{byt:02X} ') return ''.join(lst) # --------------------------------------------------------------- # ---- display vector = 3 x 4 byte (32bit) floats # --------------------------------------------------------------- def display_xyz(xyz_byts:bytes,title='xyz') -> None: if len(xyz_byts) != 12: print('OOPS!') return extract data from bytearray print(f'{title:<8} = {x:<6.02f} {y:<6.02f} {z:<6.02f}') return # --------------------------------------------------------------- # ---- display facet # --------------------------------------------------------------- def display_facet(fac_byts:bytearray) -> None: display_xyz(normal vector,'norm') display_xyz(vector 1) display_xyz(vector 2) display_xyz(vector 3) return # --------------------------------------------------------------- # ---- display STL file # ---- # ---- Note: the STL binary file format uses the IEEE integer # ---- and floating point numerical representation # ---- (see the Wikipedia link below) # --------------------------------------------------------------- def display_stl_file(file_path, stl_bytes:bytearray) -> None: print(f'file = {file_path}') extract data from bytearray print(f'title = "{title}"') print(f'facets = {facets}') facet_count = 0 facet_offset = title + facet count for facit in range(facets): facet_count += 1 print(f'------------ facet {facet_count} ------------') display_facet(stl_bytes[facet_offset:facet_offset+50]) facet_offset += 50 display the two bytes at the end return # --------------------------------------------------------------- # ---- open STL (binary) and read it directly into a byte array # --------------------------------------------------------------- def load_stl_to_array(stl_file_path:str) -> bytearray: with open(stl_file_path,'rb') as file: stl_bytes = file.read() return stl_bytes # --------------------------------------------------------------- # ---- main # --------------------------------------------------------------- if __name__ == '__main__': # ---- load file bytes into memory file_path = 'stl_binary_cube.stl' stl_bytes = load_stl_to_array(file_path) # ---- display STL file display_stl_file(file_path,stl_bytes)

Links

Single-precision floating-point format (IEEE 754 standard: binary32) (Wikipedia)

Interpret strings as packed binary data

struct - Interpret bytes as packed binary data

STL (file format) (Wikipedia)

STLB Files - Stereolithography (binary)

FileFormat - STL File

The StL Binary Format

What's inside an .STL? Edit an .STL file using a text editor! (YouTube)