Skip to content

Commit

Permalink
added xml export support
Browse files Browse the repository at this point in the history
  • Loading branch information
Krande committed Nov 7, 2024
1 parent f28027b commit 4c38f8d
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 34 deletions.
18 changes: 12 additions & 6 deletions examples/scripts/gxml_develop/flat_plate.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,42 @@


def main():
output_dir = pathlib.Path("temp")
output_dir = pathlib.Path("temp").resolve().absolute()
output_dir.mkdir(exist_ok=True)

dest_sat_file = output_dir / "flat_plate_sesam_10x10.sat"
dest_gxml_file = output_dir / "flat_plate_sesam_10x10.xml"
exported_flat = output_dir / "exported_flat_plate_10x10.xml"
res = ada.from_genie_xml(exported_flat)
startup_js_file = output_dir / 'startup.js'
workspace = output_dir / "workspace/flat_plate_sesam_10x10"
workspace.mkdir(parents=True, exist_ok=True)

pl = ada.Plate("pl", [(0, 0), (10, 0), (10, 10), (0, 10)], 0.1)
pl2 = ada.Plate("pl2", [(0, 0), (10, 0), (10, 10), (0, 10)], 0.1, origin=(10, 10, 0))
pl3 = ada.Plate("pl3", [(0, 0), (10, 0), (10, 2), (8, 2), (8, 4), (10, 4),(10,10), (0, 10)], 0.1, origin=(0, 0, 2))
plates = [pl] #, pl2, pl3]
a = ada.Assembly() / plates
a.to_genie_xml(dest_gxml_file, embed_sat=True)

a = ada.Assembly() / (pl, pl3, pl2)
sw = part_to_sat_writer(a)
sw.write(dest_sat_file)
xml_import = f'XmlImporter = ImportConceptXml();\nXmlImporter.DoImport("{dest_gxml_file.as_posix()}");'
sat_import = f'SatImporter = ImportGeometrySat();\nSatImporter.DoImport("{dest_sat_file.as_posix()}");'

with open(startup_js_file, 'w') as f:
f.write("SatImporter = ImportGeometrySat();\n")
f.write(f'SatImporter.DoImport("{dest_sat_file.resolve().absolute().as_posix()}");')
f.write(xml_import)

genie_exe = os.getenv("ADA_GENIE_EXE")
if genie_exe is None:
print("Please set the environment variable ADA_GENIE_EXE to the path of the Genie executable")
return

args = f"\"{genie_exe}\" {workspace.absolute().as_posix()} /new /com={startup_js_file.resolve().absolute().as_posix()}"
subprocess.run(args, shell=True)
#subprocess.run(args, shell=True)

# If you want to start an external process, you can use the following line:
# os.system(args)
os.system(args)


if __name__ == '__main__':
Expand Down
3 changes: 2 additions & 1 deletion src/ada/cadit/gxml/write/write_beams.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
from typing import TYPE_CHECKING

from .write_utils import add_local_system
from ...sat.write.writer import SatWriter

if TYPE_CHECKING:
from ada import Beam, Part


def add_beams(root: ET.Element, part: Part, sat_map: dict):
def add_beams(root: ET.Element, part: Part, sw: SatWriter = None):
from ada import Beam

for beam in part.get_all_physical_objects(by_type=Beam):
Expand Down
41 changes: 41 additions & 0 deletions src/ada/cadit/gxml/write/write_plates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from __future__ import annotations

import xml.etree.ElementTree as ET
from typing import TYPE_CHECKING

from .write_utils import add_local_system
from ...sat.write.writer import SatWriter

if TYPE_CHECKING:
from ada import Part, Plate

def add_plate(plate: Plate, thck_name: str, structures_elem, sw: SatWriter):
structure = ET.SubElement(structures_elem, "structure")
flat_plate = ET.SubElement(structure, "flat_plate", {"name": plate.name, "thickness_ref": thck_name, "material_ref": plate.material.name})
local_sys = ET.SubElement(flat_plate, "local_system")
ET.SubElement(local_sys, "vector", {"x": str(plate.poly.normal[0]), "y": str(plate.poly.normal[1]), "z": str(plate.poly.normal[2]), "dir": "z"})
ET.SubElement(flat_plate, "front")
ET.SubElement(flat_plate, "back")
ET.SubElement(flat_plate, "segmentation")
geometry = ET.SubElement(flat_plate, "geometry")
sheet = ET.SubElement(geometry, "sheet")
sat_reference = ET.SubElement(sheet, "sat_reference")
ET.SubElement(sat_reference, "face", {"face_ref": sw.face_map.get(plate.guid)})

def add_plates(structure_domain: ET.Element, part: Part, sw: SatWriter):
from ada import Plate

thickness = {}
properties = structure_domain.find("./properties")
thickness_elem = ET.SubElement(properties, "thicknesses")
structures_elem = structure_domain.find("./structures")

for plate in part.get_all_physical_objects(by_type=Plate):
if plate.t not in thickness:
thickness[plate.t] = f"Tck{len(thickness)+1}"
tck_elem = ET.Element("thickness", {"name": thickness[plate.t], "default": "true"})
tck_elem.append(ET.Element("constant_thickness", {"th": str(plate.t)}))
thickness_elem.append(tck_elem)

thck_name = thickness[plate.t]
add_plate(plate, thck_name, structures_elem, sw)
23 changes: 3 additions & 20 deletions src/ada/cadit/gxml/write/write_sat_embedded.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,14 @@

import base64
import xml.etree.ElementTree as ET
from typing import TYPE_CHECKING

from ada.cadit.sat.utils import create_sat_from_beams

if TYPE_CHECKING:
from ada import Part


def embed_sat_geometry(root: ET.Element, part: Part) -> dict:
def embed_sat_geometry(root: ET.Element) -> None:
geom = ET.SubElement(root, "geometry")
sat_embedded = ET.SubElement(geom, "sat_embedded", dict(encoding="base64", compression="zip", tag_name="dnvscp"))

# Encode and compress the string
sat_map = dict()
beams_sat = create_sat_from_beams(part)
sat_map.update(beams_sat.sat_map)

data = create_sesam_sat_bytes(beams_sat.sat_text)

encoded_data = base64.b64encode(data).decode()

# Add the encoded data to the element using CDATA
sat_embedded.text = "<![CDATA[" + encoded_data + "]]>"

return sat_map
# Temporary placeholder text for CDATA
sat_embedded.text = "__CDATA_PLACEHOLDER__"


def create_sesam_sat_bytes(sat_body_str: str) -> bytes:
Expand Down
37 changes: 31 additions & 6 deletions src/ada/cadit/gxml/write/write_xml.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
from __future__ import annotations

import base64
import os
import pathlib
import xml.etree.ElementTree as ET
import zipfile
from io import BytesIO
from typing import TYPE_CHECKING, Callable

from .write_bcs import add_boundary_conditions
from .write_beams import add_beams
from .write_masses import add_masses
from .write_materials import add_materials
from .write_plates import add_plates
from .write_sat_embedded import embed_sat_geometry
from .write_sections import add_sections
from ...sat.write.writer import part_to_sat_writer

if TYPE_CHECKING:
from ada import Part
Expand Down Expand Up @@ -41,18 +46,38 @@ def write_xml(part: Part, xml_file, embed_sat=False, writer_postprocessor: Calla
add_materials(properties, part)

# Add SAT geometry (maybe only applicable for plate geometry)
sat_map = dict()
sw = None
if embed_sat:
sat_map = embed_sat_geometry(structure_domain, part)
sw = part_to_sat_writer(part)
embed_sat_geometry(structure_domain)

# Add structural elements
add_beams(structures_elem, part, sat_map)
add_beams(structures_elem, part, sw)
add_plates(structure_domain, part, sw)
add_boundary_conditions(structures_elem, part)
add_masses(structures_elem, part)

if writer_postprocessor:
writer_postprocessor(root, part)

# Write the modified XML back to the file
os.makedirs(xml_file.parent, exist_ok=True)
tree.write(str(xml_file))
xml_file.parent.mkdir(exist_ok=True)
if embed_sat:
# Compress the SAT data
sat_bytes = bytes(sw.to_str(), encoding="utf-8")
compressed_io = BytesIO()
with zipfile.ZipFile(compressed_io, mode="w", compression=zipfile.ZIP_DEFLATED) as zipf:
zipf.writestr("b64temp.sat", sat_bytes)
compressed_data = compressed_io.getvalue()

# Encode the compressed data in base64
encoded_data = base64.b64encode(compressed_data).decode()
xml_str = ET.tostring(tree.getroot(), encoding="unicode")
cdata_section = f"<![CDATA[{encoded_data}]]>"
xml_str = xml_str.replace("__CDATA_PLACEHOLDER__", cdata_section)

# Write the modified XML string to the file
with open(xml_file, "w", encoding="utf-8") as file:
file.write(xml_str)
else:
# Write the modified XML back to the file
tree.write(str(xml_file), encoding="utf-8")
2 changes: 1 addition & 1 deletion src/ada/cadit/sat/write/writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def part_to_sat_writer(part: Part | Assembly) -> SatWriter:
# Plates
for face_id, pl in enumerate(part.get_all_physical_objects(by_type=Plate), start=1):
face_name = f"FACE{face_id:08d}"
sw.face_map[face_name] = pl.guid
sw.face_map[pl.guid] = face_name
new_entities = plate_to_sat_entities(pl, face_name, GeomRepr.SHELL, sw)
for entity in new_entities:
sw.add_entity(entity)
Expand Down

0 comments on commit 4c38f8d

Please sign in to comment.