@@ -69,7 +69,9 @@ def extract_materials_from_stp(stp_file):
6969
7070 return stl_materials
7171
72- def extract_solids_from_stp (stp_file ):
72+ def extract_solids_from_stp (stp_file , path = '' ):
73+ if path and not path .endswith ('/' ):
74+ path += '/'
7375 solids , materials = extract_names_from_stp (stp_file )
7476 stl_solids = {}
7577 for i in range (len (list (solids .keys ()))):
@@ -84,7 +86,7 @@ def extract_solids_from_stp(stp_file):
8486 solid_re = re .sub (r'[^a-zA-Z0-9_-]' , '-' , solid )
8587 mat_re = re .sub (r'[^a-zA-Z0-9_-]' , '-' , mat )
8688 name = f'{ str (i ).zfill (3 )} _{ solid_re } _{ mat_re } '
87- stl_solids [f'{ str (i ).zfill (3 )} _{ solid_re } ' ] = name + '.stl'
89+ stl_solids [f'{ str (i ).zfill (3 )} _{ solid_re } ' ] = path + name + '.stl'
8890
8991 return stl_solids
9092
@@ -142,6 +144,58 @@ def extract_names_from_stp(stp_file):
142144
143145 return solid_dict , material_dict
144146
147+ def get_stp_unit_scale (stp_file ):
148+ """
149+ Reads the unit definition from a STEP (.stp or .step) file and determines the
150+ scale factor required to convert the geometry to meters.
151+
152+ This function:
153+ - Opens and scans the header section of the STEP file.
154+ - Detects the SI base unit definition (e.g., millimeter, centimeter, meter).
155+ - Returns a scale factor to convert the geometry to meters.
156+ - Handles missing or unreadable unit information gracefully.
157+
158+ Args:
159+ stp_file (str): Path to the STEP (.stp or .step) file.
160+
161+ Returns:
162+ float: Scale factor to convert STEP geometry to meters.
163+ Defaults to 1.0 if no valid unit information is found.
164+ """
165+
166+ unit_map = {
167+ ".MILLI." : 1e-3 ,
168+ ".CENTI." : 1e-2 ,
169+ ".DECI." : 1e-1 ,
170+ ".KILO." : 1e3 ,
171+ "$" : 1.0 , # '$' indicates no prefix, i.e. plain meters
172+ }
173+
174+ try :
175+ with open (stp_file , "r" , encoding = "utf-8" , errors = "ignore" ) as f :
176+ header = f .read (10000 ) # read only the beginning of the file
177+
178+ match = re .search (
179+ r"SI_UNIT\s*\(\s*(\.\w+\.)?\s*,\s*\.METRE\.\s*\)" ,
180+ header ,
181+ re .IGNORECASE ,
182+ )
183+
184+ if match :
185+ prefix = match .group (1 ).upper () if match .group (1 ) else "$"
186+ scale = unit_map .get (prefix , 1.0 )
187+ print (f"Detected STEP unit: { prefix } → scale to meters: { scale } " )
188+ return scale
189+ else :
190+ print ("No unit found, files remain in original unit." )
191+ return 1.0
192+
193+ except Exception as exc :
194+ print (f"Error reading unit from STEP file: { exc } " )
195+ print ("Files remain in original unit." )
196+
197+ return 1.0
198+
145199def generate_stl_solids_from_stp (stp_file , results_path = '' ):
146200 """
147201 Extracts solid objects from a STEP (.stp) file and exports them as STL files.
@@ -150,10 +204,12 @@ def generate_stl_solids_from_stp(stp_file, results_path=''):
150204 - Imports the STEP file using `cadquery`.
151205 - Extracts solid names and their materials using `extract_names_from_stp()`.
152206 - Sanitizes solid and material names by replacing problematic characters.
153- - Saves each solid as an STL file in the current directory.
207+ - Scales the solid to meter using `get_stp_unit_scale()`.
208+ - Saves each solid as an STL file in the current folder (default) or the given path.
154209
155210 Args:
156211 stp_file (str): Path to the STEP (.stp) file.
212+ results_path (str) (optional): default: '', path to save the STL (.stl) files
157213
158214 Raises:
159215 Exception: If `cadquery` is not installed, it prompts the user to install it.
@@ -176,6 +232,13 @@ def generate_stl_solids_from_stp(stp_file, results_path=''):
176232 ''' )
177233
178234 stp = cq .importers .importStep (stp_file )
235+
236+ scale_factor = get_stp_unit_scale (stp_file )
237+ if scale_factor != 1.0 :
238+ print (f"Scaling geometry to meters (factor={ scale_factor } )." )
239+ scaled_solids = [solid .scale (scale_factor ) for solid in stp .objects [0 ]]
240+ stp .objects = [scaled_solids ]
241+
179242 solid_dict = extract_solids_from_stp (stp_file )
180243
181244 if not results_path .endswith ('/' ):
@@ -188,3 +251,4 @@ def generate_stl_solids_from_stp(stp_file, results_path=''):
188251 obj .exportStl (results_path + name )
189252
190253 return solid_dict
254+
0 commit comments