Skip to content

Commit

Permalink
Fix issues with lines being hidden in DSG mode (#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
randallfrank authored Oct 24, 2024
1 parent edd26b0 commit b2e0368
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
78 changes: 44 additions & 34 deletions src/ansys/pyensight/core/utils/omniverse_dsg_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from ansys.pyensight.core.utils.dsg_server import Part, UpdateHandler
import numpy
import png
from pxr import Gf, Sdf, Usd, UsdGeom, UsdLux, UsdShade
from pxr import Gf, Kind, Sdf, Usd, UsdGeom, UsdLux, UsdShade


class OmniverseWrapper(object):
Expand Down Expand Up @@ -299,16 +299,10 @@ def create_dsg_mesh_block(
mesh.CreateFaceVertexCountsAttr([3] * (conn.size // 3))
mesh.CreateFaceVertexIndicesAttr(conn)
if (tcoords is not None) and variable:
# USD 22.08 changed the primvar API
if hasattr(mesh, "CreatePrimvar"):
texCoords = mesh.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
else:
primvarsAPI = UsdGeom.PrimvarsAPI(mesh)
texCoords = primvarsAPI.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
primvarsAPI = UsdGeom.PrimvarsAPI(mesh)
texCoords = primvarsAPI.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
texCoords.Set(tcoords)
texCoords.SetInterpolation("vertex")
part_prim = part_stage.GetPrimAtPath("/" + partname)
Expand Down Expand Up @@ -372,7 +366,7 @@ def create_dsg_lines(
):
# 1D texture map for variables https://graphics.pixar.com/usd/release/tut_simple_shading.html
# create the part usd object
partname = self.clean_name(name + part_hash.hexdigest())
partname = self.clean_name(name + part_hash.hexdigest()) + "_l"
stage_name = "/Parts/" + partname + ".usd"
part_stage_url = self.stage_url(os.path.join("Parts", partname + ".usd"))
part_stage = None
Expand All @@ -391,9 +385,7 @@ def create_dsg_lines(
width = diagonal * math.fabs(width)
self.line_width = width

# For the present, only line colors are supported, no texturing
# var_cmd = variable
var_cmd = None
var_cmd = variable

if not os.path.exists(part_stage_url):
part_stage = Usd.Stage.CreateNew(part_stage_url)
Expand All @@ -407,21 +399,22 @@ def create_dsg_lines(
lines.CreateTypeAttr().Set("linear")
lines.CreateWidthsAttr([width])
lines.SetWidthsInterpolation("constant")
# Rounded endpoint are a primvar
primvarsAPI = UsdGeom.PrimvarsAPI(lines)
endCaps = primvarsAPI.CreatePrimvar(
"endcaps", Sdf.ValueTypeNames.Int, UsdGeom.Tokens.constant
)
endCaps.Set(2) # Rounded = 2

prim = lines.GetPrim()
prim.CreateAttribute(
"omni:scene:visualization:drawWireframe", Sdf.ValueTypeNames.Bool
).Set(wireframe)
if (tcoords is not None) and var_cmd:
# USD 22.08 changed the primvar API
if hasattr(lines, "CreatePrimvar"):
texCoords = lines.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
else:
primvarsAPI = UsdGeom.PrimvarsAPI(lines)
texCoords = primvarsAPI.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
primvarsAPI = UsdGeom.PrimvarsAPI(lines)
texCoords = primvarsAPI.CreatePrimvar(
"st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying
)
texCoords.Set(tcoords)
texCoords.SetInterpolation("vertex")
part_prim = part_stage.GetPrimAtPath("/" + partname)
Expand Down Expand Up @@ -615,7 +608,6 @@ def update_camera(self, camera):
trans_row = look_at.GetRow(3)
trans_row = Gf.Vec4d(-trans_row[0], -trans_row[1], -trans_row[2], trans_row[3])
look_at.SetRow(3, trans_row)
# print(look_at)
cam.transform = look_at

# set the updated camera
Expand Down Expand Up @@ -650,10 +642,17 @@ def create_dsg_group(
if not group_prim:
group_prim = UsdGeom.Xform.Define(self._stage, path)
# At present, the group transforms have been cooked into the vertices so this is not needed
matrixOp = group_prim.AddXformOp(
matrix_op = group_prim.AddXformOp(
UsdGeom.XformOp.TypeTransform, UsdGeom.XformOp.PrecisionDouble
)
matrixOp.Set(Gf.Matrix4d(*matrix).GetTranspose())
matrix_op.Set(Gf.Matrix4d(*matrix).GetTranspose())
# Map kinds
kind = Kind.Tokens.group
if obj_type == "ENS_CASE":
kind = Kind.Tokens.assembly
elif obj_type == "ENS_PART":
kind = Kind.Tokens.component
Usd.ModelAPI(group_prim).SetKind(kind)
logging.info(f"Created group:'{name}' {str(obj_type)}")
return group_prim

Expand Down Expand Up @@ -743,8 +742,10 @@ def finalize_part(self, part: Part) -> None:
]

if part.cmd.render == part.cmd.CONNECTIVITY:
has_triangles = False
command, verts, conn, normals, tcoords, var_cmd = part.nodal_surface_rep()
if command is not None:
has_triangles = True
# Generate the mesh block
_ = self._omni.create_dsg_mesh_block(
name,
Expand All @@ -764,12 +765,21 @@ def finalize_part(self, part: Part) -> None:
if self._omni.use_lines:
command, verts, tcoords, var_cmd = part.line_rep()
if command is not None:
line_color = [
part.cmd.line_color[0] * part.cmd.diffuse,
part.cmd.line_color[1] * part.cmd.diffuse,
part.cmd.line_color[2] * part.cmd.diffuse,
part.cmd.line_color[3],
]
# If there are no triangle (ideally if these are not hidden line
# edges), then use the base color for the part. If there are
# triangles, then assume these are hidden line edges and use the
# line_color.
line_color = color
if has_triangles:
line_color = [
part.cmd.line_color[0] * part.cmd.diffuse,
part.cmd.line_color[1] * part.cmd.diffuse,
part.cmd.line_color[2] * part.cmd.diffuse,
part.cmd.line_color[3],
]
# TODO: texture coordinates on lines are current invalid in OV
var_cmd = None
tcoords = None
# Generate the lines
_ = self._omni.create_dsg_lines(
name,
Expand Down
8 changes: 7 additions & 1 deletion src/ansys/pyensight/core/utils/omniverse_glb_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,13 @@ def upload_file(self, glb_filename: str, timeline: List[float] = [0.0, 0.0]) ->
# Walk texture nodes -> DSG Variable buffers
for tex_idx, texture in enumerate(self._gltf.textures):
image = self._gltf.images[texture.source]
raw_png = self._gltf.get_data_from_buffer_uri(image.uri)
if image.uri is None:
bv = self._gltf.bufferViews[image.bufferView]
raw_png = self._gltf.binary_blob()[
bv.byteOffset : bv.byteOffset + bv.byteLength
]
else:
raw_png = self._gltf.get_data_from_buffer_uri(image.uri)
png_img = Image.open(io.BytesIO(raw_png))
raw_rgba = png_img.tobytes()
raw_rgba = raw_rgba[0 : len(raw_rgba) // png_img.size[1]]
Expand Down

0 comments on commit b2e0368

Please sign in to comment.