Examples#

Example 01 - Contour Model and Export#

Load model, contour composite stress and export H3D / PNG#
 1from hw import *
 2from hw.hv import *
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8h3dFile = os.path.join(scriptDir, "demo_model_export.h3d")
 9jpgFile = os.path.join(scriptDir, "demo_image_export.jpeg")
10
11ses = Session()
12ses.new()
13win = ses.get(Window)
14win.type = "animation"
15
16win.addModelAndResult(modelFile, result=resultFile)
17res = ses.get(Result)
18resScalar = ResultDefinitionScalar(
19    dataType="Composite Stress",
20    dataComponent="vonMises",
21    layer="Max"
22)
23res.plot(resScalar)
24
25exportH3D = ExportModelH3D(
26    animation=True,
27    previewImage=False,
28    compressOutput=True,
29    compressionLoss=0.05,
30    file=h3dFile,
31)
32
33captureImage = CaptureImageTool(
34            type="jpg",
35            width=3000,
36            height=2000,
37            file=jpgFile
38    )
39
40animTool = AnimationTool()
41animTool.currentFrame = 1
42
43evalHWC("view orientation iso")
44exportH3D.export()
45captureImage.capture()
../../_images/image_model_contour_and_export.png

Figure 1. Output of ‘Contour Model and Export’

Example 02 - Part lists with Collections and evalTcl()#

Part lists with Collections and evalTcl() postquery#
 1from hw import *
 2from hw.hv import *
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8
 9ses = Session()
10ses.new()
11page = ses.get(Page)
12win = ses.get(Window)
13win.type = "animation"
14win.addModelAndResult(modelFile, result=resultFile)
15animTool = AnimationTool()
16animTool.currentFrame = 1
17evalHWC("view orientation iso")
18
19print()
20print("Part lists by evalTcl() with postquery package")
21evalTcl("package require postquery")
22partList = [int(x) for x in evalTcl("::hwp::getComponentList").split()]
23print("Part ID List   = ", partList)
24partNameList = evalTcl("::hwp::getComponentList -byname 1").split()
25print("Part Name List = ", partNameList)
26
27print()
28print("Part lists by Collections")
29partCol = Collection(Part)
30partList = [p.id for p in partCol.getEntities()]
31print("Part ID List   = ", partList)
32partNameList = [p.name for p in partCol.getEntities()]
33print("Part Name List = ", partNameList)
../../_images/image_partlists_Collection_and_evalTcl.png

Figure 2. Output of ‘Part lists with Collections and evalTcl() postquery’

Example 03 - Macro with GUI#

Macro with GUI, loop over results, export of images and H3D#
  1from hw import *
  2from hw.hv import *
  3from hwx.xmlui import gui
  4from hwx import gui as gui2
  5import os
  6
  7def MyCustomGui():
  8
  9    # Method called on clicking 'Close'.
 10    def onClose(event):
 11        dialog.Hide()
 12
 13    def onRun(event):
 14        dialog.Hide()
 15        postprocAuto(modelFile.value, resultFile.value, folderSel.value)
 16        gui2.tellUser("Done!")
 17
 18    label1 = gui.Label(text="Model File")
 19    modelFile = gui.OpenFileEntry(placeholdertext="Model File")
 20    label2 = gui.Label(text="Result File")
 21    resultFile = gui.OpenFileEntry(placeholdertext="Result File")
 22    label3 = gui.Label(text="Screenshot Folder")
 23    folderSel = gui.ChooseDirEntry(tooltip="Select output directory")
 24
 25    close = gui.Button("Close", command=onClose)
 26    create = gui.Button("Run", command=onRun)
 27
 28    # Default file settings for quick demo purposes
 29    if True:
 30        src_path = os.path.dirname(os.path.abspath(__file__))
 31        modelFile.value = os.path.join(src_path, "aerobox", "aerobox.fem").replace(
 32            "\\", "/"
 33        )
 34        resultFile.value = os.path.join(
 35            src_path, "aerobox", "aerobox-LC1-2.op2"
 36        ).replace("\\", "/")
 37        folderSel.value = os.path.join(src_path, "outDir").replace("\\", "/")
 38
 39    mainFrame = gui.VFrame(
 40        (label1, 20, modelFile),
 41        (label2, 20, resultFile),
 42        (label3, 20, folderSel),
 43        (create, close),
 44    )
 45
 46    dialog = gui2.Dialog(caption="Post Automation")
 47    dialog.addChildren(mainFrame)
 48    dialog.width = 400
 49    dialog.height = 100
 50    dialog.show()
 51
 52
 53def postprocAuto(modelPath, resultPath, outDir):
 54
 55    # Create Session Pointer
 56    ses = Session()
 57    # New
 58    ses.new()
 59
 60    # Define Capture Image Tool
 61    capture = CaptureImageTool()
 62    capture.type = "jpg"
 63    capture.width = 1200
 64    capture.height = 800
 65
 66    # Define H3D export
 67    exportH3D = ExportModelH3D(
 68        animation=True, previewImage=False, compressOutput=True, compressionLoss=0.05
 69    )
 70
 71    # Dictionary with dataType dependent result scalar settings
 72    resDict = {
 73        "Displacement": ["Mag", "X", "Y", "Z"],
 74        "Composite Stress": ["vonMises", "P1 (major)", "P2 (mid)", "P3 (minor)"],
 75        "Composite Strain": ["vonMises", "XX", "YY", "ZZ"],
 76        "Stress": [
 77            "vonMises",
 78            "MaxShear",
 79            "In-plane P1 (major)",
 80            "In-plane P2 (minor)",
 81        ],
 82    }
 83
 84    # Dictionary with dataType dependent legend settings (precision, numerical format,
 85    legDict = {
 86        "Displacement": [5, "scientific", 2],
 87        "Composite Stress": [6, "engineering", 4],
 88        "Composite Strain": [7, "fixed", 6],
 89        "Stress": [10, "engineering", 2],
 90    }
 91    # Change window type
 92    ses.get(Window).type = "animation"
 93
 94    startPageId = ses.get(Page).id + 1
 95
 96    # Loop over data types, 1 page per data type
 97    for dType in list(resDict.keys()):
 98        ap = Page(title=dType, layout=9)
 99        ses.setActive(Page, page=ap)
100
101        # Loop over data components, one window per component
102        for i, w in enumerate(ses.getWindows()):
103            dComp = resDict.get(dType)[i]
104            ses.setActive(Window, window=w)
105
106            # Load Model
107            w.addModelAndResult(modelPath, result=resultPath)
108
109            # Set scalar results
110            res = ses.get(Result)
111            resScalar = ses.get(ResultDefinitionScalar)
112            resScalar.setAttributes(dataType=dType, dataComponent=dComp)
113
114            # Plot results
115            res.plot(resScalar)
116
117            # Define legend settings
118            leg = ses.get(LegendScalar)
119            leg.setAttributes(
120                numberOfLevels=legDict.get(dType)[0],
121                numericFormat=legDict.get(dType)[1],
122                numericPrecision=legDict.get(dType)[2],
123            )
124
125            # Define ISO settings
126            resIso = ses.get(ResultDefinitionIso)
127            resIso.setAttributes(dataType=dType, dataComponent=dComp)
128            dispIso = ses.get(ResultDisplayIso)
129            res.plotIso(resIso)
130
131            # Set ISO value dependent on min/max
132            dispIso.value = leg.minValue + (leg.maxValue - leg.minValue) / 5
133
134            # Set animation frame 1
135            animTool = AnimationTool()
136            animTool.currentFrame = 1
137
138            # Capture jpg
139            jpgPath = os.path.join(outDir, dType + " - " + dComp + "_iso_view.jpg")
140            capture.file = jpgPath
141            capture.capture()
142
143            # Capture H3D
144            h3dPath = os.path.join(outDir, dType + " - " + dComp + ".h3d")
145            exportH3D.setAttributes(file=h3dPath, window=w)
146            exportH3D.export()
147
148            # Use Model, Collection and Part class to isolate component
149            if True:
150                mod = ses.get(Model)
151                col = Collection(Part)
152                mod.hide(col)
153                mod.get(Part, 172).visibility = True
154            # Use evalHWC isolate component for export
155            else:
156                evalHWC("hide component all")
157                evalHWC("show component 172")
158
159            # Set Views and export
160            evalHWC("view orientation left")
161            jpgPath = os.path.join(outDir, dType + " - " + dComp + "_left_view.jpg")
162            capture.file = jpgPath
163            evalHWC("show component all")
164            evalHWC("view orientation iso")
165
166    ses.setActive(Page, id=startPageId)
167
168
169if __name__ == "__main__":
170    MyCustomGui()
../../_images/image_Macro_GUI_and_Export.png

Figure 3. Start GUI and exported images / H3D’s of ‘Macro with GUI’

../../_images/image_Macro_Page_per_DataType.PNG

Figure 4. Page created for one data type by ‘Macro with GUI’

Example 04 - Contour Maximum by Sphere#

Contour max sphere by collection with filters, modify legend#
 1from hw import *
 2from hw.hv import *
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8
 9hotspotRadius = 400
10
11# Load Model
12ses = Session()
13ses.new()
14page = ses.get(Page)
15win = ses.get(Window)
16win.type = "animation"
17win.addModelAndResult(modelFile, result=resultFile)
18
19# Contour scalar
20res = ses.get(Result)
21resScalar = ses.get(ResultDefinitionScalar)
22resScalar.setAttributes(
23    dataType="Composite Stress", dataComponent="vonMises", layer="Max"
24)
25res.plot(resScalar)
26
27# Create Collection via TopN filter
28maxElemCol = Collection(Element, populate=False)
29elemFilter = FilterByScalar(operator="topN", value=1)
30maxElemCol.addByFilter(elemFilter)
31
32# Get centroid of element with maximum scalar value
33maxElem = maxElemCol.getEntities()[0]
34centroid = maxElem.centroid
35
36# Create collection with given radius
37sphereCol = Collection(Element, populate=False)
38sphereFilter = FilterBySphere(
39    x=centroid[0], y=centroid[1], z=centroid[2], radius=hotspotRadius
40)
41sphereCol.addByFilter(sphereFilter)
42
43# Define font
44headFont = Font(size=14, style="bold")
45
46# Modify legend
47legend = ses.get(LegendScalar)
48legend.setAttributes(
49    headerText="Hostpot Radius = " + str(hotspotRadius),
50    headerVisible=True,
51    headerFont=headFont,
52    numberOfLevels=8,
53    numericFormat="fixed",
54    numericPrecision=0,
55)
56
57# Contour only sphere collection
58resScalar.collection = sphereCol
59res.plot(resScalar)
60
61# Attach max note with evalHWC
62maxId = str(maxElem.id)
63maxLabel = "Max Element " + maxId
64evalHWC('annotation note create "' + maxLabel + '"')
65evalHWC('annotation note "'
66        + maxLabel
67        + '" attach entity element '
68        + maxId
69)
70evalHWC(
71    'annotation note "'
72    + maxLabel
73    + '" \
74    display text= "Max Element: {entity.id}\\nMax Value: {entity.contour_val}" \
75    movetoentity=true \
76    filltransparency=false \
77    fillcolor="255 255 255"'
78)
79
80# Set frame with AnimationTool()
81animTool = AnimationTool()
82animTool.currentFrame = 1
83
84# Modify view with evalHWC
85evalHWC("view orientation iso")
../../_images/image_Contour_by_Sphere.png

Figure 5. Output of ‘Contour Maximum by Sphere

Example 05 - Notes attached to Entities#

Create Notes attached to Entities#
 1from hw import *
 2from hw.hv import *
 3import os
 4
 5scriptDir = os.path.abspath(os.path.dirname(__file__))
 6modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 7resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 8
 9ses = Session()
10ses.new()
11win = ses.get(Window)
12win.type = "animation"
13
14win.addModelAndResult(modelFile, result=resultFile)
15res = ses.get(Result)
16resScalar = ResultDefinitionScalar(
17    dataType="Composite Stress",
18    dataComponent="vonMises",
19    layer="Max"
20)
21res.plot(resScalar)
22animTool = AnimationTool()
23animTool.currentFrame = 1
24evalHWC("view orientation iso")
25
26noteDict = {
27    "elements": [493, 353, 674, 733],
28    "fontSizes": [16, 12, 12, 12],
29    "colors": ["#FF0000", "#FFFFFF", "#FFFFFF", "#FFFFFF"],
30}
31
32for elem, fsize, col in zip(
33    noteDict.get("elements"), noteDict.get("fontSizes"), noteDict.get("colors")
34):
35    n = Note(
36        label="Element " + str(elem),
37        attachmentType="element",
38        attachment=[1, "element", elem],
39        text="Element: {entity.id}\nValue = {entity.contour_val}",
40        textColorMode="user",
41        textColor=col,
42        borderColorMode="user",
43        borderColor=(20, 20, 20),
44        fontSize=fsize,
45        transparency=False,
46        moveToEntity=True,
47        screenAnchor=False,
48    )
49
50fieldDic = n.getFieldDictionary()
51for key in list(fieldDic.keys()):
52    print("{:35s} {:3s} {:50s}".format(key, " = ", fieldDic[key]))
../../_images/image_HV_notes.png

Figure 6. Notes attached to entities with getFieldDictionary() output

Example 06 - Planar and Spherical Section Cuts#

Position sections at entities filtered by Collections#
 1from hw import *
 2from hw.hv import *
 3import os
 4
 5ses = Session()
 6ses.new()
 7
 8scriptDir = os.path.abspath(os.path.dirname(__file__))
 9modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
10resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
11
12# Dictionary with dataType dependent result scalar settings
13resDict = {
14    "Displacement": ["Mag", "X", "Y", "Z"],
15    "Stress": ["vonMises", "MaxShear", "In-plane P1 (major)", "In-plane P2 (minor)"],
16}
17
18# Change window type
19ses.get(Window).type = "animation"
20
21startPageId = ses.get(Page).id + 1
22
23# Loop over data types, 1 page per data type
24for dType in list(resDict.keys()):
25    ap = Page(title=dType, layout=9)
26    ses.setActive(Page, page=ap)
27
28    # Loop over data components, one window per component
29    for i, w in enumerate(ses.getWindows()):
30        dComp = resDict.get(dType)[i]
31        ses.setActive(Window, window=w)
32
33        # Load Model
34        w.addModelAndResult(modelFile, result=resultFile)
35
36        # Set scalar results
37        res = ses.get(Result)
38        resScalar = ses.get(ResultDefinitionScalar)
39        resScalar.setAttributes(dataType=dType, dataComponent=dComp)
40
41        # Plot results
42        res.plot(resScalar)
43
44        # Set frame with AnimationTool()
45        animTool = AnimationTool()
46        # animTool.currentFrame=1
47
48        # Modify view with evalHWC
49        evalHWC("view orientation iso")
50
51        # Add SectionCut at Max Entity
52        entityFilter = FilterByScalar(operator="topN", value=1)
53        if dType == "Displacement":
54            # Set animation frame 1
55            animTool = AnimationTool()
56            animTool.currentFrame = 1
57            # Create Collection via TopN filter
58            maxNodeCol = Collection(Node, populate=False)
59            maxNodeCol.addByFilter(entityFilter)
60            # Get centroid of element with maximum scalar value
61            maxNode = maxNodeCol.getEntities()[0]
62            # Add SectionCut Planar
63            secPlanar = SectionCutPlanar(
64                label="Node " + str(maxNode.id),
65                gridSpaceX=100,
66                gridSpaceY=100,
67                gridText=True,
68            )
69            secPlanar.setOrientationByAxis("y")
70            secPlanar.setBaseNode(maxNode.id)
71            evalHWC("view fit")
72            secPlanar.setAttributes(featureLines=True, transparency=True)
73        elif dType == "Stress":
74            # Create Collection via TopN filter
75            maxElemCol = Collection(Element, populate=False)
76            maxElemCol.addByFilter(entityFilter)
77            # Get centroid of element with maximum scalar value
78            maxElem = maxElemCol.getEntities()[0]
79            baseCoords = maxElem.centroid
80            # Add Section Cut Spherical
81            secRadius = 600
82            secSphere = SectionCutSpherical(
83                label="Element " + str(maxElem.id), radius=secRadius
84            )
85            secSphere.center = baseCoords
86            evalHWC("view fit")
87            secSphere.setAttributes(featureLines=True, transparency=True)
../../_images/image_HV_sections.PNG

Figure 7. Planar and spherical sections positioned using Collections and TopN filter

Example 07 - Log HWC in Python#

Using evalHWC() wrapper to log HWC in Python syntax#
 1import os
 2from hw.utils import *
 3
 4scriptDir = os.path.abspath(os.path.dirname(__file__))
 5modelFile = os.path.join(scriptDir, "aerobox", "aerobox.fem")
 6resultFile = os.path.join(scriptDir, "aerobox", "aerobox-LC1-2.op2")
 7##################################################
 8# BEGIN: HyperWorks 24
 9# TIME:  08:22:17 PM
10# DATE:  02/04/24
11##################################################
12
13evalHWC("delete session")
14evalHWC("hwd page current activewindow=1")
15evalHWC("hwd window type=HyperView")
16evalHWC("delete session")
17evalHWC("hwd window type = HyperView")
18evalHWC("open animation  modelandresult " + modelFile + " " + resultFile)
19evalHWC("view fit allframes = true")
20evalHWC("hwd page current layout = 9")
21evalHWC("hwd window copy")
22evalHWC("hwd window paste window = 2")
23evalHWC("hwd page current activewindow = 3")
24evalHWC("hwd window paste")
25evalHWC("hwd page current activewindow = 4")
26evalHWC("hwd window paste")
27evalHWC("hwd page copy")
28evalHWC("hwd page add title = Untitled")
29evalHWC("hwd page paste")
30evalHWC("hwd page overlay page = 2")
../../_images/image_HV_Python_evalHWC.PNG

Figure 8. Recording of copying/overlaying windows and pages