Skip to content

Commit

Permalink
FEAT: added CQUAD models to import_nastran (#4725)
Browse files Browse the repository at this point in the history
Co-authored-by: maxcapodi78 <Shark78>
  • Loading branch information
maxcapodi78 authored May 27, 2024
1 parent 4c4932b commit feb2fef
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
1 change: 1 addition & 0 deletions _unittest/example_models/T20/test_cad.nas
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ CPENTA 25328 9 26 28 25 34 35 30
CHEXA 1 105 40 41 42 43 44 45
* 46 47
CTETRA 1 115 50 51 52 53
CQUAD 1 115 50 51 52 53 40

ENDDATA
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Expand Down
4 changes: 4 additions & 0 deletions _unittest/example_models/T20/test_cad_2.nas
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ GRID* 5 812.95973 486.74968*
* 1495.9564
GRID* 6 812.99916 484.24676*
* 1470.1764
GRID* 7 812.99916 484.24676*
* 1070.1764
CTRIA3* 75986 19 4 5
* 6
CQUAD4* 75987 19 4 5
* 6 7


ENDDATA
Expand Down
63 changes: 54 additions & 9 deletions pyaedt/modeler/modeler3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,7 @@ def import_nastran(
import_as_light_weight=False,
decimation=0,
group_parts=True,
enable_planar_merge="Auto",
):
"""Import Nastran file into 3D Modeler by converting the faces to stl and reading it. The solids are
translated directly to AEDT format.
Expand All @@ -906,6 +907,8 @@ def import_nastran(
original size and removes 90% of the input triangles.
group_parts : bool, optional
Whether to group imported parts by object ID. The default is ``True``.
enable_planar_merge : str, optional
Whether to enable or not planar merge. It can be ``"True"``, ``"False"`` or ``"Auto"``.
Returns
-------
Expand Down Expand Up @@ -958,9 +961,9 @@ def _write_solid_stl(triangle, pp):
line_type = line[:8].strip()
if line.startswith("$") or line.startswith("*"):
continue
elif line_type in ["GRID", "CTRIA3"]:
elif line_type in ["GRID", "CTRIA3", "CQUAD4"]:
grid_id = int(line[8:16])
if line_type == "CTRIA3":
if line_type in ["CTRIA3", "CQUAD4"]:
tria_id = int(line[16:24])
if tria_id not in nas_to_dict["Triangles"]:
nas_to_dict["Triangles"][tria_id] = []
Expand All @@ -977,17 +980,32 @@ def _write_solid_stl(triangle, pp):
nas_to_dict["PointsId"][grid_id] = pid
nas_to_dict["Points"].append([float(n1), float(n2), float(n3)])
pid += 1
else:
elif line_type == "CTRIA3":
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n2)],
nas_to_dict["PointsId"][int(n3)],
]
nas_to_dict["Triangles"][tria_id].append(tri)

elif line_type in ["GRID*", "CTRIA3*"]:
elif line_type == "CQUAD4":
n4 = line[48:56].strip()
if "-" in n4[1:] and "e" not in n4[1:].lower():
n4 = n4[0] + n4[1:].replace("-", "e-")
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n2)],
nas_to_dict["PointsId"][int(n3)],
]
nas_to_dict["Triangles"][tria_id].append(tri)
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n3)],
nas_to_dict["PointsId"][int(n4)],
]
nas_to_dict["Triangles"][tria_id].append(tri)
elif line_type in ["GRID*", "CTRIA3*", "CQUAD4*"]:
grid_id = int(line[8:24])
if line_type == "CTRIA3*":
if line_type in ["CTRIA3*", "CQUAD4*"]:
tria_id = int(line[24:40])
if tria_id not in nas_to_dict["Triangles"]:
nas_to_dict["Triangles"][tria_id] = []
Expand All @@ -999,9 +1017,11 @@ def _write_solid_stl(triangle, pp):
n2 = n2[0] + n2[1:].replace("-", "e-")

n3 = line[72:88].strip()
idx = 88
if not n3 or n3.startswith("*"):
lk += 1
n3 = lines[lk][8:24].strip()
idx = 24
if "-" in n3[1:] and "e" not in n3[1:].lower():
n3 = n3[0] + n3[1:].replace("-", "e-")
if line_type == "GRID*":
Expand All @@ -1011,14 +1031,32 @@ def _write_solid_stl(triangle, pp):
continue
nas_to_dict["PointsId"][grid_id] = pid
pid += 1
else:
elif line_type == "CTRIA3*":
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n2)],
nas_to_dict["PointsId"][int(n3)],
]
nas_to_dict["Triangles"][tria_id].append(tri)

elif line_type == "CQUAD4*":
n4 = lines[lk][idx : idx + 16].strip()
if not n4 or n4.startswith("*"):
lk += 1
n4 = lines[lk][8:24].strip()
if "-" in n4[1:] and "e" not in n4[1:].lower():
n4 = n4[0] + n4[1:].replace("-", "e-")
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n2)],
nas_to_dict["PointsId"][int(n3)],
]
nas_to_dict["Triangles"][tria_id].append(tri)
tri = [
nas_to_dict["PointsId"][int(n1)],
nas_to_dict["PointsId"][int(n3)],
nas_to_dict["PointsId"][int(n4)],
]
nas_to_dict["Triangles"][tria_id].append(tri)
elif line_type in [
"CTETRA",
"CPYRAM",
Expand Down Expand Up @@ -1121,6 +1159,7 @@ def _write_solid_stl(triangle, pp):
if nas_to_dict["Triangles"] or nas_to_dict["Solids"] or nas_to_dict["Lines"]:
self.logger.info("Creating STL file with detected faces")
output_stl = ""
enable_stl_merge = False if enable_planar_merge == "False" else True
if nas_to_dict["Triangles"]:
output_stl = os.path.join(self._app.working_directory, self._app.design_name + "_tria.stl")
f = open(output_stl, "w")
Expand Down Expand Up @@ -1150,13 +1189,15 @@ def decimate(points_in, faces_in, points_out, faces_out):
self.logger.error("Package fast-decimation is needed to perform model simplification.")
self.logger.error("Please install it using pip.")
f.write("solid Sheet_{}\n".format(tri_id))

if enable_planar_merge == "Auto" and len(tri_out) > 20000:
enable_stl_merge = False
for triangle in tri_out:
_write_solid_stl(triangle, p_out)
f.write("endsolid\n")
if nas_to_dict["Triangles"]:
f.close()
output_solid = ""
enable_solid_merge = False if enable_planar_merge == "False" else True
if nas_to_dict["Solids"]:
output_solid = os.path.join(self._app.working_directory, self._app.design_name + "_solids.stl")
f = open(output_solid, "w")
Expand All @@ -1175,6 +1216,8 @@ def decimate(points_in, faces_in, points_out, faces_out):
except Exception:
self.logger.error("Package fast-decimation is needed to perform model simplification.")
self.logger.error("Please install it using pip.")
if enable_planar_merge == "Auto" and len(tri_out) > 20000:
enable_solid_merge = False
for triangle in tri_out:
_write_solid_stl(triangle, p_out)
f.write("endsolid\n")
Expand All @@ -1188,12 +1231,14 @@ def decimate(points_in, faces_in, points_out, faces_out):
output_stl,
create_lightweigth_part=import_as_light_weight,
healing=False,
merge_planar_faces=enable_stl_merge,
)
if output_solid:
self.import_3d_cad(
output_solid,
create_lightweigth_part=import_as_light_weight,
healing=False,
merge_planar_faces=enable_solid_merge,
)
self.logger.info("Model imported")

Expand Down

0 comments on commit feb2fef

Please sign in to comment.