refactor: Engine updates and NX hooks improvements
optimization_engine: - Updated nx_solver.py with improvements - Enhanced solve_simulation.py - Updated extractors/__init__.py - Improved NX CAD hooks (expression_manager, feature_manager, geometry_query, model_introspection, part_manager) - Enhanced NX CAE solver_manager hook Documentation: - Updated OP_01_CREATE_STUDY.md protocol - Updated SYS_12_EXTRACTOR_LIBRARY.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,111 @@ import NXOpen.Assemblies
|
||||
import NXOpen.CAE
|
||||
|
||||
|
||||
def extract_part_mass(theSession, part, output_dir):
|
||||
"""
|
||||
Extract mass from a part using NX MeasureManager.
|
||||
|
||||
Writes mass to _temp_mass.txt and _temp_part_properties.json in output_dir.
|
||||
|
||||
Args:
|
||||
theSession: NXOpen.Session
|
||||
part: NXOpen.Part to extract mass from
|
||||
output_dir: Directory to write temp files
|
||||
|
||||
Returns:
|
||||
Mass in kg (float)
|
||||
"""
|
||||
import json
|
||||
|
||||
results = {
|
||||
'part_file': part.Name,
|
||||
'mass_kg': 0.0,
|
||||
'mass_g': 0.0,
|
||||
'volume_mm3': 0.0,
|
||||
'surface_area_mm2': 0.0,
|
||||
'center_of_gravity_mm': [0.0, 0.0, 0.0],
|
||||
'num_bodies': 0,
|
||||
'success': False,
|
||||
'error': None
|
||||
}
|
||||
|
||||
try:
|
||||
# Get all solid bodies
|
||||
bodies = []
|
||||
for body in part.Bodies:
|
||||
if body.IsSolidBody:
|
||||
bodies.append(body)
|
||||
|
||||
results['num_bodies'] = len(bodies)
|
||||
|
||||
if not bodies:
|
||||
results['error'] = "No solid bodies found"
|
||||
raise ValueError("No solid bodies found in part")
|
||||
|
||||
# Get the measure manager
|
||||
measureManager = part.MeasureManager
|
||||
|
||||
# Get unit collection and build mass_units array
|
||||
# API requires: [Area, Volume, Mass, Length] base units
|
||||
uc = part.UnitCollection
|
||||
mass_units = [
|
||||
uc.GetBase("Area"),
|
||||
uc.GetBase("Volume"),
|
||||
uc.GetBase("Mass"),
|
||||
uc.GetBase("Length")
|
||||
]
|
||||
|
||||
# Create mass properties measurement
|
||||
measureBodies = measureManager.NewMassProperties(mass_units, 0.99, bodies)
|
||||
|
||||
if measureBodies:
|
||||
results['mass_kg'] = measureBodies.Mass
|
||||
results['mass_g'] = results['mass_kg'] * 1000.0
|
||||
|
||||
try:
|
||||
results['volume_mm3'] = measureBodies.Volume
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
results['surface_area_mm2'] = measureBodies.Area
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
cog = measureBodies.Centroid
|
||||
if cog:
|
||||
results['center_of_gravity_mm'] = [cog.X, cog.Y, cog.Z]
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
measureBodies.Dispose()
|
||||
except:
|
||||
pass
|
||||
|
||||
results['success'] = True
|
||||
|
||||
except Exception as e:
|
||||
results['error'] = str(e)
|
||||
results['success'] = False
|
||||
|
||||
# Write results to JSON file
|
||||
output_file = os.path.join(output_dir, "_temp_part_properties.json")
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(results, f, indent=2)
|
||||
|
||||
# Write simple mass value for backward compatibility
|
||||
mass_file = os.path.join(output_dir, "_temp_mass.txt")
|
||||
with open(mass_file, 'w') as f:
|
||||
f.write(str(results['mass_kg']))
|
||||
|
||||
if not results['success']:
|
||||
raise ValueError(results['error'])
|
||||
|
||||
return results['mass_kg']
|
||||
|
||||
|
||||
def find_or_open_part(theSession, part_path):
|
||||
"""
|
||||
Find a part if already loaded, otherwise open it.
|
||||
@@ -296,6 +401,15 @@ def solve_assembly_fem_workflow(theSession, sim_file_path, solution_name, expres
|
||||
partSaveStatus_blank.Dispose()
|
||||
print(f"[JOURNAL] M1_Blank saved")
|
||||
|
||||
# STEP 2a: EXTRACT MASS FROM M1_BLANK
|
||||
# Extract mass using MeasureManager after geometry is updated
|
||||
print(f"[JOURNAL] Extracting mass from M1_Blank...")
|
||||
try:
|
||||
mass_kg = extract_part_mass(theSession, workPart, working_dir)
|
||||
print(f"[JOURNAL] Mass extracted: {mass_kg:.6f} kg ({mass_kg * 1000:.2f} g)")
|
||||
except Exception as mass_err:
|
||||
print(f"[JOURNAL] WARNING: Mass extraction failed: {mass_err}")
|
||||
|
||||
updated_expressions = list(expression_updates.keys())
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user