Skip to content

feat: geopath property #551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
db9bcce
add geopath properties
StefanThoene Apr 14, 2025
fb844d0
remove unnecesarry code
StefanThoene Apr 14, 2025
9373e0c
chore: adding changelog file 551.added.md [dependabot-skip]
pyansys-ci-bot Apr 14, 2025
0477e76
Merge branch 'main' into feat/geopath-property
pluAtAnsys Apr 16, 2025
5a4d813
implement feedback from pengyuan
StefanThoene Apr 17, 2025
0d039a8
add tests for geopath
StefanThoene Apr 22, 2025
0879eab
Merge branch 'main' into feat/geopath-property
StefanThoene Apr 22, 2025
c24bf4e
Let the geopath property return an actual GeoRef
StefanThoene Apr 28, 2025
089ad85
adjust simulation example
StefanThoene Apr 28, 2025
e3098a3
allow geometries to be paths Face, Body or SubPart feature as geometries
StefanThoene Apr 29, 2025
34f5292
allow geometries to be paths Face, Body or SubPart feature as geometries
StefanThoene Apr 29, 2025
fd47474
allow Face class to be input for Surface source exitance geometry
StefanThoene Apr 29, 2025
5f752d9
allow Face and body class to be input for Surface source exitance geo…
StefanThoene Apr 29, 2025
4f97a08
Merge branch 'main' into feat/geopath-property
StefanThoene Apr 29, 2025
95cd8c1
Apply suggestions from code review
StefanThoene Apr 29, 2025
03a86bc
fix unit tests
StefanThoene Apr 29, 2025
ffdd77c
Merge branch 'main' into feat/geopath-property
StefanThoene Apr 30, 2025
816105b
Merge branch 'main' into feat/geopath-property
StefanThoene Apr 30, 2025
fd4f28d
Merge branch 'main' into feat/geopath-property
StefanThoene Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changelog.d/551.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
geopath property
31 changes: 18 additions & 13 deletions examples/core/opt-prop.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,24 @@ def create_helper_geometries(project: Project):
"""Create bodies and faces."""

def create_face(body):
(
face = (
body.create_face(name="TheFaceF")
.set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0])
.set_facets([0, 1, 2])
.set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
.commit()
)
return face

data = {"bodies": [], "faces": []}
root_part = project.create_root_part().commit()
body_b1 = root_part.create_body(name="TheBodyB").commit()
body_b2 = root_part.create_body(name="TheBodyC").commit()
body_b3 = root_part.create_body(name="TheBodyD").commit()
body_b4 = root_part.create_body(name="TheBodyE").commit()
for b in [body_b1, body_b2, body_b3, body_b4]:
create_face(b)
data["bodies"].append(root_part.create_body(name="TheBodyB").commit())
data["bodies"].append(root_part.create_body(name="TheBodyC").commit())
data["bodies"].append(root_part.create_body(name="TheBodyD").commit())
data["bodies"].append(root_part.create_body(name="TheBodyE").commit())
for b in data["bodies"]:
data["faces"].append(create_face(b))
return data


# ## Model Setup
Expand Down Expand Up @@ -80,7 +83,9 @@ def create_face(body):

p = Project(speos=speos)
print(p)
create_helper_geometries(p)
data = create_helper_geometries(p)
bodies = data["bodies"]
faces = data["faces"]

# ## Create VOP (volume optical property)
#
Expand All @@ -93,8 +98,8 @@ def create_face(body):
# This optical property will be applied to two bodies named : "TheBodyB" and "TheBodyC".
op1.set_geometries(
geometries=[
GeoRef.from_native_link(geopath="TheBodyB"),
GeoRef.from_native_link(geopath="TheBodyC"),
GeoRef.from_native_link(geopath=bodies[0].geo_path),
GeoRef.from_native_link(geopath=bodies[1].geo_path),
]
)
print(op1)
Expand All @@ -120,8 +125,8 @@ def create_face(body):
# This optical property will be applied to two bodies named : "TheBodyD" and "TheBodyE".
op2.set_geometries(
geometries=[
GeoRef.from_native_link(geopath="TheBodyD"),
GeoRef.from_native_link(geopath="TheBodyE"),
GeoRef.from_native_link(geopath=bodies[2].geo_path),
GeoRef.from_native_link(geopath=bodies[3].geo_path),
]
)
op2.commit()
Expand All @@ -138,7 +143,7 @@ def create_face(body):
op3 = p.create_optical_property(name="Material.FOP")
op3.set_surface_mirror(reflectance=90) # SOP : mirror
# This optical property will be applied a face from TheBodyD named : "TheFaceF".
op3.set_geometries(geometries=[GeoRef.from_native_link(geopath="TheBodyD/TheFaceF")])
op3.set_geometries(geometries=[GeoRef.from_native_link(geopath=faces[2].geo_path)])
op3.commit()
print(op3)

Expand Down
8 changes: 8 additions & 0 deletions src/ansys/speos/core/body.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ def __init__(

self._geom_features = []

@property
def geo_path(self):
"""Geometry path to be used within other speos objects."""
geo_paths = [self._name]
if isinstance(self._parent_part, part.Part.SubPart):
geo_paths.insert(0, self._parent_part.geo_path)
return "/".join(geo_paths)

def create_face(
self,
name: str,
Expand Down
9 changes: 9 additions & 0 deletions src/ansys/speos/core/face.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ def __init__(
# Create local Face
self._face = ProtoFace(name=name, description=description, metadata=metadata)

@property
def geo_path(self):
"""Geometry path to be used within other speos objects."""
geo_paths = [self._name]
parent = self._parent_body
if isinstance(parent, body.Body):
geo_paths.insert(0, parent.geo_path)
return "/".join(geo_paths)

def set_vertices(self, values: List[float]) -> Face:
"""Set the face vertices.

Expand Down
8 changes: 8 additions & 0 deletions src/ansys/speos/core/part.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ def __init__(

self._geom_features = []

@property
def geo_path(self):
"""Geometry path to be used within other speos objects."""
geo_paths = [self._name]
if isinstance(self._parent_part, Part.SubPart):
geo_paths.insert(0, self._parent_part.geo_path)
return "/".join(geo_paths)

def create_body(
self,
name: str,
Expand Down
25 changes: 16 additions & 9 deletions tests/core/test_opt_prop.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,19 @@ def test_reset_optical_property(speos: Speos):

root_part = p.create_root_part()
body_b = root_part.create_body(name="TheBodyB")
body_b.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
[0, 1, 2]
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
(
body_b.create_face(name="TheFaceF")
.set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0])
.set_facets([0, 1, 2])
.set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
)
root_part.commit()

# Create + commit
op1 = (
p.create_optical_property(name="Material.1")
.set_volume_opaque()
.set_geometries(geometries=[GeoRef.from_native_link("TheBodyB")])
.set_geometries(geometries=[GeoRef.from_native_link(body_b.geo_path)])
.commit()
)
assert op1.vop_template_link is not None
Expand Down Expand Up @@ -233,9 +236,12 @@ def test_get_optical_property(speos: Speos, capsys):

root_part = p.create_root_part()
body_a = root_part.create_body(name="TheBodyA")
body_a.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
[0, 1, 2]
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
face = (
body_a.create_face(name="TheFaceF")
.set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0])
.set_facets([0, 1, 2])
.set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
)
body_b = root_part.create_body(name="TheBodyB")
body_b.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
[0, 1, 2]
Expand All @@ -245,7 +251,7 @@ def test_get_optical_property(speos: Speos, capsys):
op1 = (
p.create_optical_property(name="Material.1")
.set_volume_opaque()
.set_geometries(geometries=[GeoRef.from_native_link("TheBodyA")])
.set_geometries(geometries=[GeoRef.from_native_link(body_a.geo_path)])
.commit()
)

Expand All @@ -269,7 +275,7 @@ def test_get_optical_property(speos: Speos, capsys):
p.create_optical_property(name="OpticalProperty2")
.set_volume_optic(index=1.7, absorption=0.01, constringence=55)
.set_surface_opticalpolished()
.set_geometries(geometries=[GeoRef.from_native_link("TheBodyB")])
.set_geometries(geometries=[GeoRef.from_native_link(body_b.geo_path)])
.commit()
)

Expand All @@ -292,6 +298,7 @@ def test_get_optical_property(speos: Speos, capsys):
p.create_optical_property(name="OpticalProperty3")
.set_volume_none()
.set_surface_library(path=str(Path(test_path) / "R_test.anisotropicbsdf"))
.set_geometries(geometries=[GeoRef.from_native_link(face.geo_path)])
.commit()
)

Expand Down
18 changes: 11 additions & 7 deletions tests/core/test_part.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@ def test_create_body(speos: Speos):
# Add empty body
body1 = root_part.create_body(name="Body.1").commit()
assert len(root_part._geom_features) == 1

assert body1.geo_path == "Body.1"
assert len(root_part.part_link.get().body_guids) == 1
assert root_part.part_link.get().body_guids[0] == body1.body_link.key

# Add another body + commit on root part
body2 = root_part.create_body(name="Body.2")
root_part.commit()
assert len(root_part._geom_features) == 2

assert body2.geo_path == "Body.2"
assert len(root_part.part_link.get().body_guids) == 2
assert root_part.part_link.get().body_guids[1] == body2.body_link.key

Expand All @@ -84,7 +84,7 @@ def test_create_face(speos: Speos):
root_part.commit()
assert len(body1._geom_features) == 1
assert len(body1.body_link.get().face_guids) == 1

assert face0.geo_path == "Body.1/TheFaceF"
# Add a face
face1 = (
body1.create_face(name="Face.1")
Expand All @@ -94,7 +94,7 @@ def test_create_face(speos: Speos):
.commit()
)
assert len(body1._geom_features) == 2

assert face1.geo_path == "Body.1/Face.1"
assert len(body1.body_link.get().face_guids) == 2
assert body1.body_link.get().face_guids[1] == face1.face_link.key
assert face1.face_link.get().vertices == [0, 1, 0, 0, 2, 0, 1, 2, 0]
Expand All @@ -110,7 +110,7 @@ def test_create_face(speos: Speos):
.commit()
)
assert len(body1._geom_features) == 3

assert face2.geo_path == "Body.1/Face.2"
assert len(body1.body_link.get().face_guids) == 3
assert body1.body_link.get().face_guids[2] == face2.face_link.key
assert face2.face_link.get().vertices == [0, 0, 0, 1, 0, 0, 0, 1, 0]
Expand Down Expand Up @@ -140,6 +140,7 @@ def test_create_subpart(speos: Speos):
)
assert len(root_part._geom_features) == 1
assert len(root_part.part_link.get().parts) == 1
assert sp1.geo_path == "SubPart.1"
assert root_part.part_link.get().parts[0] == sp1._part_instance
assert sp1._part_instance.axis_system == [
5,
Expand Down Expand Up @@ -168,6 +169,7 @@ def test_create_subpart(speos: Speos):
root_part.commit()
assert len(root_part._geom_features) == 2
assert len(root_part.part_link.get().parts) == 2
assert sp2.geo_path == "SubPart.2"
assert root_part.part_link.get().parts[1] == sp2._part_instance
assert sp2._part_instance.axis_system == [
15,
Expand Down Expand Up @@ -211,15 +213,15 @@ def test_create_subpart_body(speos: Speos):
# Add empty body
body1 = sp1.create_body(name="Body.1").commit()
assert len(sp1._geom_features) == 1

assert body1.geo_path == "SubPart.1/Body.1"
assert len(sp1.part_link.get().body_guids) == 1
assert sp1.part_link.get().body_guids[0] == body1.body_link.key

# Add another body + commit on root part
body2 = sp1.create_body(name="Body.2")
root_part.commit()
assert len(sp1._geom_features) == 2

assert body2.geo_path == "SubPart.1/Body.2"
assert len(sp1.part_link.get().body_guids) == 2
assert sp1.part_link.get().body_guids[1] == body2.body_link.key

Expand Down Expand Up @@ -266,6 +268,7 @@ def test_create_subpart_subpart(speos: Speos):
1,
]
assert sp11._part_instance.part_guid == sp11.part_link.key
assert sp11.geo_path == "SubPart.1/SubPart.11"
assert (
sp11.part_link.get().name == "SubPart.11"
) # part contained in a sub part gets same name as the sub part
Expand Down Expand Up @@ -294,6 +297,7 @@ def test_create_subpart_subpart(speos: Speos):
1,
]
assert sp12._part_instance.part_guid == sp12.part_link.key
assert sp12.geo_path == "SubPart.1/SubPart.12"
assert (
sp12.part_link.get().name == "SubPart.12"
) # part contained in a sub part gets same name as the sub part
Expand Down