From f3a8352e35a3f34922461b174cf4155cc8359b02 Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:08:17 +0100 Subject: [PATCH 01/12] Create scdm folder --- ansys_optical_automation/scdm_script_tool/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 ansys_optical_automation/scdm_script_tool/.gitkeep diff --git a/ansys_optical_automation/scdm_script_tool/.gitkeep b/ansys_optical_automation/scdm_script_tool/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/ansys_optical_automation/scdm_script_tool/.gitkeep @@ -0,0 +1 @@ + From f3784f9ba9d7c90b90f252ea4dbe1d5c5cb50c2a Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:09:55 +0100 Subject: [PATCH 02/12] Create scdm folder --- ansys_optical_automation/application/scdm_script_tool/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 ansys_optical_automation/application/scdm_script_tool/.gitkeep diff --git a/ansys_optical_automation/application/scdm_script_tool/.gitkeep b/ansys_optical_automation/application/scdm_script_tool/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/ansys_optical_automation/application/scdm_script_tool/.gitkeep @@ -0,0 +1 @@ + From fd4f706b689f153dc6a3d9f6d01f7986a98da21d Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:11:51 +0100 Subject: [PATCH 03/12] Add files via upload First upload --- ...eractive Simulation of Visible Elements.py | 361 ++++++++++++++++++ .../Raytracing Visible Elements.scscript | Bin 0 -> 7822 bytes 2 files changed, 361 insertions(+) create mode 100644 ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py create mode 100644 ansys_optical_automation/application/scdm_script_tool/Raytracing Visible Elements.scscript diff --git a/ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py new file mode 100644 index 00000000..b40fefab --- /dev/null +++ b/ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py @@ -0,0 +1,361 @@ +# Python Script, API Version = V252 +from __future__ import print_function + +""" +Script overview +--------------- +This script prepares a Speos Interactive Simulation by: +1) Collecting all Speos materials in the document. +2) Resolving every linked geometry (faces/features) to its owning DesignBody + (document-level IDocObject), so the simulation runs on full bodies. +3) Optionally filtering by visibility. +4) Deduplicating bodies (a body may appear via multiple materials). +5) Selecting all visible surface sources. +6) Creating an Interactive Simulation with a **unique name**. If the base name + is already taken by any object, the script appends _1, _2, ... or a random + suffix to avoid conflicts. +""" + +# ============================================================================= +# Configuration +# ============================================================================= +REQUIRE_VISIBLE = False # Set to True to include only visible bodies + +# ============================================================================= +# Helper Functions +# ============================================================================= +def ensure_body_docobject(dobj): + """ + Resolve any linked Speos or SpaceClaim object to its owning DesignBody + and return a document-level object (IDocObject) suitable for simulation. + + This function promotes lower-level geometry references (faces, features, + or temporary links) to their parent DesignBody, ensuring that only + complete physical bodies are passed to the simulation. + + Parameters + ---------- + dobj : object + A linked Speos or SpaceClaim object, possibly a FaceStub, Feature, or + another entity that belongs to a DesignBody. + + Returns + ------- + IDocObject + The DesignBody document object if found; otherwise the input object. + + Notes + ----- + - Speos materials often reference faces or features instead of full bodies. + Passing those directly to the simulation can create anonymous “Solid” + entries or duplicate geometry. + - This function uses several fallback strategies (.Root, .GetDocObject(), + .GetBody()) to climb back to the owning DesignBody. + - If resolution fails, the original object is returned so that + `Selection.Create()` may still normalize it automatically. + + Examples + -------- + >>> body = ensure_body_docobject(face_stub) + >>> print(body.GetName()) + 'Body - Light Guide' + """ + # 1) Already a body-level docobject + if hasattr(dobj, "GetName") and hasattr(dobj, "IsVisible"): + return dobj + + # 2) Try GetDocObject() and its Root + if hasattr(dobj, "GetDocObject"): + try: + doc = dobj.GetDocObject() + if doc is not None: + if hasattr(doc, "IsVisible") and hasattr(doc, "GetName"): + return doc + root = getattr(doc, "Root", None) + if root is not None and hasattr(root, "IsVisible") and hasattr(root, "GetName"): + return root + except: + pass + + # 3) Try Root directly + root = getattr(dobj, "Root", None) + if root is not None: + if hasattr(root, "IsVisible") and hasattr(root, "GetName"): + return root + if hasattr(root, "GetDocObject"): + try: + bdoc = root.GetDocObject() + if bdoc is not None and hasattr(bdoc, "IsVisible") and hasattr(bdoc, "GetName"): + return bdoc + except: + pass + + # 4) Try GetBody() fallback + if hasattr(dobj, "GetBody"): + try: + b = dobj.GetBody() + if b is not None: + if hasattr(b, "GetDocObject"): + bd = b.GetDocObject() + if bd is not None and hasattr(bd, "IsVisible") and hasattr(bd, "GetName"): + return bd + if hasattr(b, "IsVisible") and hasattr(b, "GetName"): + return b + except: + pass + + # Fallback: return as-is + return dobj + + +def docobject_idkey(dobj): + """ + Build a stable unique key for a document object to enable deduplication. + + This function extracts a consistent identifier from a SpaceClaim/Speos + document object (IDocObject) using the following priority: + ReferenceId > Id > Name > repr(). + + Parameters + ---------- + dobj : IDocObject + The document object to generate an identifier for. + + Returns + ------- + tuple + A (type, string) tuple usable as a hashable key in a set or dict. + + Notes + ----- + Deduplication avoids adding the same geometry multiple times when materials + overlap (e.g., volumic + surfacic on one body). + + Examples + -------- + >>> key = docobject_idkey(my_body) + >>> print(key) + ('ref', '123456') + """ + rid = getattr(dobj, "ReferenceId", None) + if rid: + return ("ref", str(rid)) + oid = getattr(dobj, "Id", None) + if oid: + return ("id", str(oid)) + try: + return ("name", dobj.GetName()) + except: + return ("obj", repr(dobj)) + + +def is_visible_safe(dobj): + """ + Safely check whether a geometry or document object is visible in the model. + + This function wraps `dobj.IsVisible(None)` in a try/except block to prevent + crashes when an object does not expose a valid visibility property (common + with certain Speos or SpaceClaim linked objects). If the check fails, it + returns True by default. + + Parameters + ---------- + dobj : IDocObject or similar + The object whose visibility is being queried. + + Returns + ------- + bool + True if the object is visible, or if visibility cannot be determined. + False only if the object explicitly reports invisibility. + + Notes + ----- + The function defaults to True on error to avoid excluding valid bodies from + the simulation in ambiguous cases. + + Examples + -------- + >>> is_visible_safe(body) + True + """ + try: + return dobj.IsVisible(None) + except: + return True # Be permissive if uncertain + + +def assign_unique_name(target_obj, base_name, max_seq=100): + """ + Assign a unique name to a Speos/SpaceClaim object. + + The function first tries the base name. If it is already taken by any + object, it attempts base_name_1, base_name_2, ..., up to `max_seq`. + If all those fail (name collision or API rejection), it appends a random + 6-hex suffix to guarantee uniqueness. + + Parameters + ---------- + target_obj : object + The object whose `Name` attribute will be set. + base_name : str + Desired base name (e.g., "Raytracing of Visible Elements"). + max_seq : int, optional + Maximum integer suffix to try before switching to a random suffix. + + Returns + ------- + str + The name that was successfully assigned to the object. + + Notes + ----- + - Some environments reject a name if *any* other object in the document + uses it (not only simulations). Hence we try/except on the setter. + - This is robust in IronPython (no f-strings). It uses old-style formatting. + + Examples + -------- + >>> name = assign_unique_name(interactive, "Raytracing of Visible Elements") + >>> print(name) + 'Raytracing of Visible Elements_2' + """ + # 1) Try the base name directly + try: + target_obj.Name = base_name + return target_obj.Name + except: + pass + + # 2) Try numbered suffixes + i = 1 + while i <= max_seq: + trial = "%s_%d" % (base_name, i) + try: + target_obj.Name = trial + return target_obj.Name + except: + i += 1 + + # 3) Fallback: random short suffix + try: + import uuid + trial = "%s_%s" % (base_name, uuid.uuid4().hex[:6].upper()) + target_obj.Name = trial + return target_obj.Name + except: + # Last resort: keep incrementing until one works + j = max_seq + 1 + while True: + trial = "%s_%d" % (base_name, j) + try: + target_obj.Name = trial + return target_obj.Name + except: + j += 1 + + +# ============================================================================= +# Main Script +# ============================================================================= +root = GetRootPart() + +print("Total bodies in root:", root.GetAllBodies().Count) + +# 1) Collect all Speos materials +material_list_names = [ + obj.GetName() for obj in root.CustomObjects + if obj.Type == "SPEOS_SC.SIM.SpeosWrapperMaterial" +] +print("Speos materials found:", material_list_names) + +# 2) Collect all geometries linked to those materials +candidate_doc_bodies = [] + +for material_name in material_list_names: + m = SpeosSim.Material.Find(material_name) + if m is None: + print("WARNING: Material not found:", material_name) + continue + + opt_type = str(m.OpticalPropertiesType) + print("\nMaterial:", material_name, "| OpticalPropertiesType:", opt_type) + + if opt_type == "Volumic": + linked = list(m.VolumeGeometries.LinkedObjects) + print(" VolumeGeometries.LinkedObjects:", len(linked)) + for dobj in linked: + body_dobj = ensure_body_docobject(dobj) + candidate_doc_bodies.append(body_dobj) + + elif opt_type == "Surfacic": + linked = list(m.OrientedFaces.LinkedObjects) + print(" OrientedFaces.LinkedObjects:", len(linked)) + for face_dobj in linked: + body_dobj = ensure_body_docobject(face_dobj) + candidate_doc_bodies.append(body_dobj) + +print("\nCandidate doc bodies BEFORE filtering:", len(candidate_doc_bodies)) + +# 3) Optional visibility filter +if REQUIRE_VISIBLE: + candidate_doc_bodies = [d for d in candidate_doc_bodies if is_visible_safe(d)] + print("After visibility filter:", len(candidate_doc_bodies)) +else: + print("Visibility filter DISABLED") + +# 4) Deduplicate +seen = set() +unique_doc_bodies = [] +for d in candidate_doc_bodies: + key = docobject_idkey(d) + if key not in seen: + seen.add(key) + unique_doc_bodies.append(d) + +print("Unique bodies to simulate:", len(unique_doc_bodies)) +for d in unique_doc_bodies: + try: + print(" -", d.GetName()) + except: + print(" - ") + +# 5) Collect visible Speos surface sources +visible_source_docobjects = [] +for obj in root.CustomObjects: + if obj.Type == "SPEOS_SC.SIM.SpeosWrapperSourceSurface": + src = SpeosSim.SourceSurface.Find(obj.GetName()) + if src is not None and src.Visible: + visible_source_docobjects.append(obj) + +print("\nVisible surface sources (count):", len(visible_source_docobjects)) +for obj in visible_source_docobjects: + try: + print(" -", obj.GetName()) + except: + pass + +# 6) Build and configure Interactive Simulation (with guaranteed unique name) +base_sim_name = "Raytracing of Visible Elements" +interactive = SpeosSim.SimulationInteractive.Create() +final_name = assign_unique_name(interactive, base_sim_name) +print("Created simulation with name:", final_name) + +if len(unique_doc_bodies) > 0: + sel_geos = Selection.Create(unique_doc_bodies) + print("Selection.Create for geometries -> Items:", sel_geos.Count) + interactive.Geometries.Set(sel_geos.Items) +else: + print("WARNING: No bodies found to assign to the simulation geometries.") + +if len(visible_source_docobjects) > 0: + sel_src = Selection.Create(visible_source_docobjects) + print("Selection.Create for sources -> Items:", sel_src.Count) + interactive.Sources.Set(sel_src.Items) +else: + print("WARNING: No visible surface sources found to assign.") + +# 7) Run (optional) +# interactive.Compute() + +print("\nInteractive simulation prepared:", interactive.Name) diff --git a/ansys_optical_automation/application/scdm_script_tool/Raytracing Visible Elements.scscript b/ansys_optical_automation/application/scdm_script_tool/Raytracing Visible Elements.scscript new file mode 100644 index 0000000000000000000000000000000000000000..ffc3b21dc303592052ced4ab50f2fd35499c179f GIT binary patch literal 7822 zcmbW61yEdDwuT!E9)e4wjXS~J0|fUV3EngWn#SD;?g@n8?iMt-26wj*+=7P2^(A-a z&AWHr%+#xQcI{KO>#YCZa#o!>UoCYdBxC{r0DuP2j+Qt4bTZJa`xF2$=L7&y0ptK< zCv!(@duQq#5&%=y@38-U)fp_=EyvUpF5q-hVW7{_^4$5&}`wU6dmZr+@kgf4oOM_4m=+VNI^qFOvPJHa`&R zNa=@5HjJ|a7KN(hO^ihNgi?d*3P-^bDL@h9JM7tM4^59q#&wtka) zO{guF*th>Y2<7sn)M3?Y?syvpm}b)+{hV2HTik@FU+i;!j&Q18YT_Dr61O*%cZmA; zch=Td`v&$pd07e7FAyA%NYN{3X3S$-$99Di^lE~`ULu@e%pMq6;fCpL+N61{2l!}P zRH6Cg*5-Hgir?3TY};%@NG}PG;G_-PphyoWE{<%5r)_VlE)Sc%B5{Ov=yWhf^y@Jb z(;jwKiRH~GV0`83=iAFj?K=bek2mP;etv_a#B#SCa~A^UoL7snQuveG55%e!$a{Pr zdM)v7IDuGsFUhR={RB#}`d3U_;!)Xd5d!)a;kG!*C1`!Q9BkXU|wT8Ff zw<5XTz48rPWo`%qXL|#G_z8tZ*7!X*`#SKqi)N;`yE}zUd!g(&^gdl}N~^suGO@xK z=8cLBqs?1)*-`)!t|(kmd89e?7&Xeyt@ywEN*q;~vKrjw8ADLB7GQxX?j_#~A8tr` z_>4ZHLegkaFX?ZR3=Z3!nkNpA{Cv28MTVIQ;VRT#MCyLwMUSmo;xDSL=t|K!bk$4|m*N{^<(#&^;$)LDLPKa_*-D90q% zk-Uu^%`h95XW4e@girfXl?lH?dQ`vOz{cby`U@;NNqL)3T*qdw@~2RZX;KkT7JXrX zLOzU)RkRR}TYMkYBiGS)U`;J7B>ZQmG?`m3xJ)a{2pJj*8FmWsPMLQ3 zrk^||3n`*&=gNRaLffas%Z0q(-SEY;kPQkx!xU^)$ZhAL?T?lWeBUFRLb#P30T*%f z3aY%Vc~!LuLS@j6?@%U>D<4zgkgy0X_f&KCX@9c^iT=u+98vRc5bad2T@ zTK3Ke6@){Ql8^t&4O+80Uby}i2UPT`?E?Oqv@HE|{09Fi7QZV;#=erFlN>$ER38FU zI`g4J$GC?N^4mHJJ1abLEkWD(tfu@PRD}5}%WTGXI(u!Z7Im=!sOhrE0NJ=y=Hu}_ zbiDe+!+DVHqP4&F5R>U+Q{Y9M*8u#96!(CYSswgJK93upvlV*2vM)4Y;mvmqD;unWCH++Kp-tZj)3hmEoKIUkXg;XJD=(cQl z0p(S@Bu~=)ZJBXxaXMB@L0r4Rt64I)sy>?F&%xUm3t#9s(pzXDL2|tYU9A?_u4*%@ z9I%-Ogq2m*Iqjo`^|bPeh0f>fJKu_z<#dg45sedvE7MYAOGfpmFkUSPtHZo5OA3Zx zoCQ~gHeV12htW=hptleKk@W`a{ClJ3;I1((C*BhI)#!Bo_7Q8%{1=FF((L0r0R$|x zO+CSqOIGzHzPTtqCI(g2K~T6|-Cgj0WzkOTME{h4Hl&u=gLIJ?{OC$qwKIGtW7p{y z0eO4i17&S37NPh&@xJi&LP14-g|>)ur_jM*D#fj!F=V%SqESj|%qSEg3h2$v5eNgf z#cv>EtB@hFoJXvW9$kW`VqJYv2bfq!N(U@voVD3`9OJWsTJ*EkDsC(VD6`k1?xUiw zorTgr+wca2qb*$8)dWa%hE68kP{DSLqP0biP+Y3{p@x+&y7?}bt|)J=yzpI**K+&R zGQ^vAT(~8}t+McDv!^)2KtJ5{H*g!GqGEdm)%k-R!>#}-LdsgQF?nS#>$97M6-z0| zIcQpDQZB~xn=lIjpNOWA2@D4QsA0N~5`X3oCHX1m3~YAE>vuK&Q1^qLoyTE$y0672)md zDEod%vkS&UHtFpeZ4G)`c4MUx=MXH>OEQDM_#9WP#tQRiGtPsIRxR)|JJq2MtDp_N z0A_d#`toAMd&J={-fOgd4}$#9n-OuVR!FAM3(~#|SkghQ(4A1zsww(oNqH6#vJsg# zo;cvW(WCHEEpS12W6Sk*SjiQqC`7VKHZR2bWYu<+GPnjBdU$vvdTTdQc^%-I{_KOA$l{f_k||Ph*fM>fjBv zLxCBxFu5)lN4sZ$5IhU7Q()c1tCm$ZT1G1sOt2m~e|6^@a|9^Q$GvZ^s7`??4o9pV zi{Gfp4nK}m;!g)IHEy?4O5Cl5QtG9Vuqf2_hAeV~D-((BvgeR}8b4WYB2Sc>SU(7twZP?-D3;puI?#Pxs=)ahAE<^aa2QNezG|Uv)qPBk*whzGJw_B- zzt0P1`;rDGUz@9Y^CkB>7gbBdJbmKA9Zf^_{6D|=3P85c}d zVb%})2eZulJ`lbV$Gp(m^ctW^qu61i*c$^nghJ$+s@Ewx{wp$b(PhXkng>*UV2-+8 z@7gUvksH;q_DHz{5q>+9x|0;fX3T)LkdVdIbxZYbDfaTS72r>$H&k9DYqMKN5gC?- z<)H`1ly1MiRQyGy%|9j=nD61pxm4p9Nx6{B0+ew*o#<0lPrt-hIP*ZN@E6VYiBzUx zYoucA+6)BDl9+eIsSdkxC7exdaGp}ph=n~g>(O4e&w{GaN)H^^ z3UgtlT}>4w_puRnf?wSL$K9H>u=Hy=U$FB7OYg-ZWpZP=D>FCIo2Nx{XokwE)z+_q z8^f4H6Ybj}I|_jz9{h7Ot0y*Y0a_RA02Z*diomvQRXS4GrT9YC1|P6n@XG_q3Cy z12#GgOl$p+ClfZ;43m9#e5Pl4WQ&n6fvYlEy$*@A5~lNyY)2L#YlMK3KN_eQhx3ws zDVmn?kWQ?s*>`?&b-lU1eBC@JUq)xaFwjOyhP;QbsOb4)H+`wvI|E4kiCH3f@|H21 z%I|X!V=XpzT4M5gx+z-YHxyT%}0BuNQCKOre>xD47D{9X!Cu3l$jzzB-EQ z29O?USl=7`k#86_snOqMRBE|##e`NmB@JU>Ut&DOuNhUeC$73(OL9(YTY5yNof>b} z4`yy7Yi{0@Xy($~WXMGH+USjx2jo|^qb4~U4LcaX5F`70@${`v!bs*_JTeW0+^PZl zZCq~F-R5u1LTQ~B=sS%v##FPqhvKK&&K*hprJYnc@3UcrEE_jllw@`@eDsbyXRJ7tXveF^wxOV0LQYK16FV?}2k)E;l53^$twCvES?(=6$bomWs|p9g`3 zDJGwu9idpcq}}H#pbL-qLhf76x~7^85{DEG;li+;!($x>bKfGZ(!J#9x~pB*$e+Vp zRn%WoN%C~&*b^(=B)*cMom!m`QCAJ>=t06Pc?td(LWwVR=Sg7xN<2W|g^9n0WSJC65QGbkK44!l*?@*76==(9h=C=YU8V2}KWlG?9 zP8MH{Q$vyCL+CZouOy*gpT{X~kk{}|PXtp!-?0ZtLe!;()Z?TI5s{(qfV6S`eP)u| z8k%S%Z%M7p5J^m6!RiK0Aw#jT~s9RLvKVdNkz zTB~^@GxaulU{P~P3INpd9XcCK0+SvT6C~ulFp#KM_lBw55j-C?g71)59uu`5``7%0 zb;W(}(yY*bO40-|a4~6Q&-j@uXR+Y*TT;`G`yWwtm@Z9ds6TLG z<#dm9kD-F|SS69Kv;B|XIYvvN;`W{JdQ&588f`Ek6?b!@rORx{?A=MHC1;p3QRE?# zCw569W2;#_11NCG3TF6{Nny});hOpZs3j27yE+vW=Gy+amf^X+Y_sCYG z>=^{bTD9bw{1G}@PrIcwo{DGE;-Vo2f6XGWeB?TKH+jSK3@x5u`{B+U_;e;0De)`y zqp9AVY1}(3J8iu5Tyb~BxYS6TuBG#_iv6q;XOLtFM)2IzEF?tHXA(5b3NpKVJsRPR z3nMd9%6dkhYKWXJfy6+L3a>p-Du955 zhWmz*jCd|)M}5bRc3HS*0n@FvMkt~;VM`9Lr6tes<;@WpYNdtX+dP%bqXPmp?uPk? z#=G+;r^s3<0`$6`I7^3I7sdW%gXMIT1A>JfyaK%iKX5BwTOPRxl;8iWyM$t89BpV!PiOMLV)^T6B7y0 zbRV7b_(-y!RX0nkzR`X{F0{siGOZ>y&5VOWPXD}|w9ZW7ILbVSqL&nQkoG>`)ji6- zaQQGT3~>=TR9|s%y$E26yE*-A|89iU!Ydb_aZKxUm*T`=UFGb)3-XT7!@G01cM^Z* zxp3x~(MmFa>LKl6*ew5f_ez&IZ4QBs_m}B(jf5Re*W#xm@%{N1-!FD?o(`QdpP-6O z-3!ke>2hdk)#679U%nyBPxO z23;0R7d@*`FaaUoX7HTB@my86Zc2~*Y)MrVlr{IcWm6I`^$IGOEtYcdm`-*1?~gyv z5sguiH#DV;y&>}^v8!P8#fL=fYpO-^vpI{xMk$YoL}+VShn!?n5(5)w2Bc^?7oiQ) zRuM2kMOnCDPRR<{K_^5jZHf0{7dhkJHEdbUmxrtEHK{}61aGHP@B7AC*0%WSurq$e zJamHf#TB_PcTjIPq!*p8quZMvMmz2;AAdpip}e>5SNC(RZ8wWjoc8|s@~HL(hHZ%> zr-G4A*N&SW(dw*{Y$ht;eM$S5>wAj;ca0eM845ivgGV55Ek9NEvL&>7?*tcjD+J+P zkN2kdOr`zY-NkOz+cTu&sKMbVEVGOcme0jFK83!2LG`Gf@-gMa^K^GI4LTI(u2PfT zQs{9xLW;Y+H*+6LwiogF{5W_nCGCj0=Nr`q*#|sIm!zJbW|UW^W!Dg0P~r?DU*!;_ z$pD1f9>Lh)Jj=k>`5}iwpH;4ov1j@d^3NnOnDKIS?V&_*zGbt>wT<5Vd)2*om~{>n zEsiZYS#;$?mMhZni{s!F}`Mcim|v6h(e#K)+l-R!-<>RefVUpq~Ei1ECb zdi^|t&*Y_jqwmoKX?bv>+mjumTkA@g-jH#5CR;a~R}tIXSqnR**h`EbP1U9J+oKQ4 z`(G62K`>wsgR)(C)G5a%;QmTNHK4^`_W2vt$ zf~94(w1qMjLv>#^!%NOgPWE`%6Kl>hL$2%mYkxnf4olSR2lYzT*J|!W3D}b?^`I51 zQ)$k{5*0{L$6Y0Dm zWs*^QUGzd5%+&T1({F{{j5Q@|Hu2UWk9lZ&$yM1ibOyOZ35{`s{PXxR?25Vs7&I}B zb2(S6yFn9FMQm>Osjo#T%F{7l6!&_&E$!s4h4W!;iZt=4O~qmg0+?a5feodZP4R_(8kp%M8%-Llk6??aO1 z4`!<7)r4GXT!!T{kz%!L@)Qf?lFn0EQmD3RGd~1!b$iwHP7O+HgLCiucvY`Y{7HJ+ zx*bKSF-hoihT~{G?A6;2-K5@7 z0;9N^VtDeR1m%RB1uStVrO&CYI=5RMDjCgF6)xk78ji$>wVBKq8TmFeXXQ9MXd@ru zn{eDelhA-K-+$U#O_*A^cWH1tz&C_o?;qQXw3eud6WZP`RI3*TYZ@z&m+!Z{jZ?n( z`h)DbF!HSm(Lqib!&lBSl}j~W@{f=jJ}cv<9|Jxd3<-PM9|Qzq$?YA^; z6^`90+Umml^eH3am5e>s@NS0dFdU%mCsVdC8bpc63m1;f{mBr^lxqENwZ+)6w~}36 zvo{=HJ{HPg6AYX@kJ!GFksG+b)t|5D9sI`Gf1aqO_`@@yn5QK9I5UI8Cs!2c-P~IA zIhW^A#Mj@Ym^VBL8Pmh%?f8?zgcZ^?!_1`5$N4?^otX8AYj<1C4uxwBL6MZx}Mo3^--?-wlSVW$h%#nI?RRMI0NtT_Cpq?w~(?-H8;w z@~~|l+oNda=rUMg{HRY;OT(ZtkapvMb~J_@OcJ%w8{Na8bwh3j9nrFbcCnXR^Tk5yK@t+^Z=d=Ka3L8?Ao1| z$7ZyQl94J`{=>|%7Dhna_jC@0o%378b$*T-xPd4kVPX%$$&i=DY_99qIJ)>NHVBk5L)=IV537dSgx-p{bWMTc#|7O_d3juVX0ZZ*(Rk z$kY$|U6?s436PVXw$CPgBA&I2NN3lU*6<`W^X8*ZJYM$n^X@XWm-Tp`)@P~Zba6}W z>K2N6PJoeq4d79u)lY*$A4wmID|dSBdIkj6V8sVIq>%;wtr;opBNs={o82!ycA{8U zErb(|kM~DjCTpDaVeOwZV6>(0>*AFv4e?_2XVP!coJQg5IOFR*vzd=Pby}csJb3xa zcEeyN1M$rDtgi99FcMo`xtgcPQZ~)@`K)2~OhN=^St02@RYWWHB%NX*q5TbWKU0!8V>=h$<`0l_ zj}LVhaD32Vm3CK8M|_0}%5fNN|K)AR>s{1=iSIKNWQ5OHPu+fV1;!ucu-}CnN%VxZ?7Tp((&ojJ_H+72QHa&fj~7X(R&i~iw9{VUYY zNepD=>})U0$?0Tn1%{eBalq`scE6rj!W^Nd&cB9^5Kenja~o3#n3J1}i=Wf{Z);+A z{=FuUxTxB%*&MAcz|`u$_O5CQ1&e_=|6V}^QU84dzvmMJIfLDuIqhvtt?fY6oc~7n zKaBVP5&r}0{vTqefAQ}Avkm7T$0)9@gn-Bn_;=;hKa%B7x4$3FKa2hfyMKxYB>k$) z{t12mS@>7B{j+fG58*$K Date: Fri, 14 Nov 2025 12:13:28 +0100 Subject: [PATCH 04/12] Delete ansys_optical_automation/scdm_script_tool/.gitkeep --- ansys_optical_automation/scdm_script_tool/.gitkeep | 1 - 1 file changed, 1 deletion(-) delete mode 100644 ansys_optical_automation/scdm_script_tool/.gitkeep diff --git a/ansys_optical_automation/scdm_script_tool/.gitkeep b/ansys_optical_automation/scdm_script_tool/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/ansys_optical_automation/scdm_script_tool/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - From 180a1edc9298cc94529ef002ea194936c4c843ca Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Fri, 14 Nov 2025 12:13:57 +0100 Subject: [PATCH 05/12] Delete ansys_optical_automation/application/scdm_script_tool/.gitkeep --- ansys_optical_automation/application/scdm_script_tool/.gitkeep | 1 - 1 file changed, 1 deletion(-) delete mode 100644 ansys_optical_automation/application/scdm_script_tool/.gitkeep diff --git a/ansys_optical_automation/application/scdm_script_tool/.gitkeep b/ansys_optical_automation/application/scdm_script_tool/.gitkeep deleted file mode 100644 index 8b137891..00000000 --- a/ansys_optical_automation/application/scdm_script_tool/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - From cc41e1467fdb73a9d046cea30c4a4a897df0c95c Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:17:15 +0200 Subject: [PATCH 06/12] Rename Interactive Simulation of Visible Elements.py to example_Interactive Simulation of Visible Elements.py Title changed --- ...s.py => example_Interactive Simulation of Visible Elements.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ansys_optical_automation/application/scdm_script_tool/{Interactive Simulation of Visible Elements.py => example_Interactive Simulation of Visible Elements.py} (100%) diff --git a/ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py similarity index 100% rename from ansys_optical_automation/application/scdm_script_tool/Interactive Simulation of Visible Elements.py rename to ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py From 634893daf0a8b59c3101a47d9c4f634b3f5e2524 Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:19:45 +0200 Subject: [PATCH 07/12] Update example_Interactive Simulation of Visible Elements.py Generic error added instead of "pass" --- .../example_Interactive Simulation of Visible Elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index b40fefab..22b59575 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -74,8 +74,8 @@ def ensure_body_docobject(dobj): root = getattr(doc, "Root", None) if root is not None and hasattr(root, "IsVisible") and hasattr(root, "GetName"): return root - except: - pass + except Exception as e:  +    print("Exception found: " + str(e)) # 3) Try Root directly root = getattr(dobj, "Root", None) From 8b0a35e94b500773fd62f445344c262130249300 Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:20:55 +0200 Subject: [PATCH 08/12] Update example_Interactive Simulation of Visible Elements.py Generic error added instead of pass --- .../example_Interactive Simulation of Visible Elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index 22b59575..1df34d3c 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -87,8 +87,8 @@ def ensure_body_docobject(dobj): bdoc = root.GetDocObject() if bdoc is not None and hasattr(bdoc, "IsVisible") and hasattr(bdoc, "GetName"): return bdoc - except: - pass + except Exception as e:  +    print("Exception found: " + str(e)) # 4) Try GetBody() fallback if hasattr(dobj, "GetBody"): From 7262dfde5497da1acbfca24ee455d21056fea9bc Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Tue, 28 Apr 2026 18:21:54 +0200 Subject: [PATCH 09/12] Update example_Interactive Simulation of Visible Elements.py Generic error added instead of pass --- .../example_Interactive Simulation of Visible Elements.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index 1df34d3c..bae54653 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -101,8 +101,8 @@ def ensure_body_docobject(dobj): return bd if hasattr(b, "IsVisible") and hasattr(b, "GetName"): return b - except: - pass + except Exception as e:  +    print("Exception found: " + str(e)) # Fallback: return as-is return dobj From a1634f7436eaf3e71daa81aec43cd8ebf8f4e7c7 Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Wed, 29 Apr 2026 15:49:29 +0200 Subject: [PATCH 10/12] Update example_Interactive Simulation of Visible Elements.py --- .../example_Interactive Simulation of Visible Elements.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index bae54653..431b3639 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -185,7 +185,7 @@ def is_visible_safe(dobj): return True # Be permissive if uncertain -def assign_unique_name(target_obj, base_name, max_seq=100): +#def assign_unique_name(target_obj, base_name, max_seq=100): """ Assign a unique name to a Speos/SpaceClaim object. @@ -338,8 +338,8 @@ def assign_unique_name(target_obj, base_name, max_seq=100): # 6) Build and configure Interactive Simulation (with guaranteed unique name) base_sim_name = "Raytracing of Visible Elements" interactive = SpeosSim.SimulationInteractive.Create() -final_name = assign_unique_name(interactive, base_sim_name) -print("Created simulation with name:", final_name) +# final_name = assign_unique_name(interactive, base_sim_name) +# print("Created simulation with name:", final_name) if len(unique_doc_bodies) > 0: sel_geos = Selection.Create(unique_doc_bodies) From 3ebd7e55a4d668238f8f4a8847647bead7a5b220 Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Wed, 29 Apr 2026 16:31:00 +0200 Subject: [PATCH 11/12] Update example_Interactive Simulation of Visible Elements.py --- .../example_Interactive Simulation of Visible Elements.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index 431b3639..43e84a96 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -87,8 +87,8 @@ def ensure_body_docobject(dobj): bdoc = root.GetDocObject() if bdoc is not None and hasattr(bdoc, "IsVisible") and hasattr(bdoc, "GetName"): return bdoc - except Exception as e:  -    print("Exception found: " + str(e)) + except Exception as e: + print("Exception found: " + str(e)) # 4) Try GetBody() fallback if hasattr(dobj, "GetBody"): @@ -101,8 +101,8 @@ def ensure_body_docobject(dobj): return bd if hasattr(b, "IsVisible") and hasattr(b, "GetName"): return b - except Exception as e:  -    print("Exception found: " + str(e)) + except Exception as e: + print("Exception found: " + str(e)) # Fallback: return as-is return dobj From 31c42653664de14816792573b9ccfbc38970e2fc Mon Sep 17 00:00:00 2001 From: Alessia Fra <135629112+alessiafra@users.noreply.github.com> Date: Wed, 29 Apr 2026 17:00:24 +0200 Subject: [PATCH 12/12] Update example_Interactive Simulation of Visible Elements.py --- ...eractive Simulation of Visible Elements.py | 64 +++++++++++++------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py index 43e84a96..69de650f 100644 --- a/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py +++ b/ansys_optical_automation/application/scdm_script_tool/example_Interactive Simulation of Visible Elements.py @@ -1,6 +1,7 @@ -# Python Script, API Version = V252 +# Python Script, API Version = V261 from __future__ import print_function + """ Script overview --------------- @@ -16,11 +17,13 @@ suffix to avoid conflicts. """ + # ============================================================================= # Configuration # ============================================================================= REQUIRE_VISIBLE = False # Set to True to include only visible bodies + # ============================================================================= # Helper Functions # ============================================================================= @@ -47,7 +50,7 @@ def ensure_body_docobject(dobj): Notes ----- - Speos materials often reference faces or features instead of full bodies. - Passing those directly to the simulation can create anonymous “Solid” + Passing those directly to the simulation can create anonymous "Solid" entries or duplicate geometry. - This function uses several fallback strategies (.Root, .GetDocObject(), .GetBody()) to climb back to the owning DesignBody. @@ -56,8 +59,8 @@ def ensure_body_docobject(dobj): Examples -------- - >>> body = ensure_body_docobject(face_stub) - >>> print(body.GetName()) +>>> body = ensure_body_docobject(face_stub) +>>> print(body.GetName()) 'Body - Light Guide' """ # 1) Already a body-level docobject @@ -74,8 +77,9 @@ def ensure_body_docobject(dobj): root = getattr(doc, "Root", None) if root is not None and hasattr(root, "IsVisible") and hasattr(root, "GetName"): return root - except Exception as e:  -    print("Exception found: " + str(e)) + + except Exception as e: + print("Exception found: " + str(e)) # 3) Try Root directly root = getattr(dobj, "Root", None) @@ -87,8 +91,9 @@ def ensure_body_docobject(dobj): bdoc = root.GetDocObject() if bdoc is not None and hasattr(bdoc, "IsVisible") and hasattr(bdoc, "GetName"): return bdoc + except Exception as e: - print("Exception found: " + str(e)) + print("Exception found: " + str(e)) # 4) Try GetBody() fallback if hasattr(dobj, "GetBody"): @@ -101,13 +106,16 @@ def ensure_body_docobject(dobj): return bd if hasattr(b, "IsVisible") and hasattr(b, "GetName"): return b + except Exception as e: - print("Exception found: " + str(e)) + print("Exception found: " + str(e)) # Fallback: return as-is return dobj + + def docobject_idkey(dobj): """ Build a stable unique key for a document object to enable deduplication. @@ -133,8 +141,8 @@ def docobject_idkey(dobj): Examples -------- - >>> key = docobject_idkey(my_body) - >>> print(key) +>>> key = docobject_idkey(my_body) +>>> print(key) ('ref', '123456') """ rid = getattr(dobj, "ReferenceId", None) @@ -149,6 +157,8 @@ def docobject_idkey(dobj): return ("obj", repr(dobj)) + + def is_visible_safe(dobj): """ Safely check whether a geometry or document object is visible in the model. @@ -176,7 +186,7 @@ def is_visible_safe(dobj): Examples -------- - >>> is_visible_safe(body) +>>> is_visible_safe(body) True """ try: @@ -185,7 +195,9 @@ def is_visible_safe(dobj): return True # Be permissive if uncertain -#def assign_unique_name(target_obj, base_name, max_seq=100): + + +def assign_unique_name(target_obj, base_name, max_seq=100): """ Assign a unique name to a Speos/SpaceClaim object. @@ -216,16 +228,17 @@ def is_visible_safe(dobj): Examples -------- - >>> name = assign_unique_name(interactive, "Raytracing of Visible Elements") - >>> print(name) +>>> name = assign_unique_name(interactive, "Raytracing of Visible Elements") +>>> print(name) 'Raytracing of Visible Elements_2' """ # 1) Try the base name directly try: target_obj.Name = base_name return target_obj.Name - except: - pass + + except Exception as e: + print("Exception found: " + str(e)) # 2) Try numbered suffixes i = 1 @@ -255,6 +268,8 @@ def is_visible_safe(dobj): j += 1 + + # ============================================================================= # Main Script # ============================================================================= @@ -332,14 +347,15 @@ def is_visible_safe(dobj): for obj in visible_source_docobjects: try: print(" -", obj.GetName()) - except: - pass + + except Exception as e: + print("Exception found: " + str(e)) # 6) Build and configure Interactive Simulation (with guaranteed unique name) base_sim_name = "Raytracing of Visible Elements" interactive = SpeosSim.SimulationInteractive.Create() -# final_name = assign_unique_name(interactive, base_sim_name) -# print("Created simulation with name:", final_name) +final_name = assign_unique_name(interactive, base_sim_name) +print("Created simulation with name:", final_name) if len(unique_doc_bodies) > 0: sel_geos = Selection.Create(unique_doc_bodies) @@ -359,3 +375,11 @@ def is_visible_safe(dobj): # interactive.Compute() print("\nInteractive simulation prepared:", interactive.Name) + +# Get object 'Raytracing of Visible Elements' +raytracingofVisibleElements = SpeosSim.SimulationInteractive.Find("Raytracing of Visible Elements") +# EndBlock + +# Get object 'Raytracing of Visible Elements_1' +raytracingofVisibleElements = SpeosSim.SimulationInteractive.Find("Raytracing of Visible Elements_1") +# EndBlock