def UFviewer(mbs, dialog): i = int(mbs.variables['solutionViewerStep']) # mbs.systemData.SetTime(t, exudyn.ConfigurationType.Visualization) SetSolutionState(mainSystem, mbs.variables['solutionViewerSolution'], i, exudyn.ConfigurationType.Visualization) #exudyn.DoRendererIdleTasks(timeout) # SC.visualizationSettings.contour.reduceRange = False mbs.SendRedrawSignal() exudyn.DoRendererIdleTasks( ) #as there is no simulation, we must do this for graphicsDataUserFunctions # if mbs.variables['modeShapeSaveImages'] == 0: # SC.RedrawAndSaveImage() #create images for animation # else: # SC.visualizationSettings.exportImages.saveImageFileCounter = 0 #for next mode ... dialog.period = mbs.variables['solutionViewerPeriod'] if mbs.variables['solutionViewerRunModus'] < 2: mbs.variables['solutionViewerStep'] += mbs.variables[ 'solutionViewerRowIncrement'] # print("step=", mbs.variables['solutionViewerStep']) #first variable is scale, which contains step dialog.variableList[0][0].set(mbs.variables['solutionViewerStep']) # for var in dialog.variableList: # #self.mbs.variables[var[1]] = var[0].get() # print(var[1],'=', var[0].get()) if mbs.variables['solutionViewerSaveImages'] == 0: SC.RedrawAndSaveImage() #create images for animation # else: #do not reset image counter to allow creating of multi-view images, slow motion, etc. # SC.visualizationSettings.exportImages.saveImageFileCounter = 0 # if mbs.variables['solutionViewerStep'] > mbs.variables[ 'solutionViewerNSteps'] - 1.: #or (mbs.variables['solutionViewerRunModus'] and mbs.variables['solutionViewerStep']==mbs.variables['solutionViewerNSteps']-1.): mbs.variables['solutionViewerStep'] = 0 dialog.variableList[0][0].set(0) SetSolutionState(mainSystem, mbs.variables['solutionViewerSolution'], 0, exudyn.ConfigurationType.Visualization) # mbs.SendRedrawSignal() # exudyn.DoRendererIdleTasks() #as there is no simulation, we must do this for graphicsDataUserFunctions if mbs.variables[ 'solutionViewerRunModus'] == 1: #one cylce ==> stop dialog.StartSimulation() #start/stop simulation
def AnimateSolution(mbs, solution, rowIncrement = 1, timeout=0.04, createImages = False, runLoop = False): SC = mbs.GetSystemContainer() nRows = solution['nRows'] if nRows == 0: print('ERROR in AnimateSolution: solution file is empty') return if (rowIncrement < 1) or (rowIncrement > nRows): print('ERROR in AnimateSolution: rowIncrement must be at least 1 and must not be larger than the number of rows in the solution file') oldUpdateInterval = SC.visualizationSettings.general.graphicsUpdateInterval SC.visualizationSettings.general.graphicsUpdateInterval = 0.5*min(timeout, 2e-3) #avoid too small values to run multithreading properly mbs.SetRenderEngineStopFlag(False) #not to stop right at the beginning while runLoop and not mbs.GetRenderEngineStopFlag(): for i in range(0,nRows,rowIncrement): if not(mbs.GetRenderEngineStopFlag()): #SetVisualizationState(exudyn, mbs, solution, i) #OLD SetSolutionState(mbs, solution, i, exudyn.ConfigurationType.Visualization) if createImages: SC.RedrawAndSaveImage() #create images for animation #time.sleep(timeout) exudyn.DoRendererIdleTasks(timeout) SC.visualizationSettings.general.graphicsUpdateInterval = oldUpdateInterval #set values back to original
def SolutionViewer(mainSystem, solution=[], rowIncrement=1, timeout=0.04, runOnStart=True, runMode=2): from exudyn.utilities import SetSolutionState, LoadSolutionFile mbs = mainSystem SC = mbs.GetSystemContainer() if solution == []: if not 'simulationSettings' in mbs.sys: raise ValueError( 'SolutionViewer: no solution file found (already simulated?)!') sims = mbs.sys['simulationSettings'] if not sims.solutionSettings.writeSolutionToFile: raise ValueError( 'SolutionViewer: previous simulation has writeSolutionToFile==False; no solution file available!' ) solution = LoadSolutionFile( sims.solutionSettings.coordinatesSolutionFileName ) #load solution file of previous simulation nRows = solution['nRows'] if nRows == 0: print('ERROR in SolutionViewer: solution file is empty') return if (runMode != 0 and runMode != 1 and runMode != 2): print('ERROR in SolutionViewer: illegal run mode:', runMode) return if (rowIncrement < 1) or (rowIncrement > nRows): print( 'ERROR in SolutionViewer: rowIncrement must be at least 1 and must not be larger than the number of rows in the solution file' ) oldUpdateInterval = SC.visualizationSettings.general.graphicsUpdateInterval SC.visualizationSettings.general.graphicsUpdateInterval = 0.5 * min( timeout, 2e-3) #avoid too small values to run multithreading properly mbs.SetRenderEngineStopFlag(False) #not to stop right at the beginning # runLoop = False # while runLoop and not mainSystem.GetRenderEngineStopFlag(): # for i in range(0,nRows,rowIncrement): # if not(mainSystem.GetRenderEngineStopFlag()): # SetSolutionState(mainSystem, solution, i, exudyn.ConfigurationType.Visualization) # exudyn.DoRendererIdleTasks(timeout) SetSolutionState(mainSystem, solution, 0, exudyn.ConfigurationType.Visualization) exudyn.DoRendererIdleTasks(timeout) nSteps = int(nRows) #only make these steps available in slider! maxNSteps = max(500, min( nSteps, 1200)) #do not allow more steps, because dialog may be too large ... resolution = min(1., maxNSteps / nSteps) #do not use values smaller than 1 dialogItems = [ { 'type': 'label', 'text': 'Solution steps:', 'grid': (1, 0) }, { 'type': 'slider', 'range': (0, nSteps - 1), 'value': 0, 'steps': maxNSteps, 'variable': 'solutionViewerStep', 'resolution': resolution, 'grid': (1, 1) }, { 'type': 'label', 'text': 'Increment:', 'grid': (2, 0) }, { 'type': 'slider', 'range': (1, 200), 'value': rowIncrement, 'steps': 200, 'variable': 'solutionViewerRowIncrement', 'grid': (2, 1) }, { 'type': 'label', 'text': 'update period:', 'grid': (3, 0) }, { 'type': 'slider', 'range': (0.005, 1), 'value': timeout, 'steps': 200, 'variable': 'solutionViewerPeriod', 'grid': (3, 1) }, { 'type': 'radio', 'textValueList': [('Continuous run', 0), ('One cycle', 1), ('Static', 2)], 'value': runMode, 'variable': 'solutionViewerRunModus', 'grid': [(4, 0), (4, 1), (4, 2)] }, #{'type':'radio', 'textValueList':[('Mesh+Faces',3), ('Faces only',1), ('Mesh only',2)],'value':3, 'variable':'modeShapeMesh', 'grid': [(8,0),(8,1),(8,2)]}, { 'type': 'radio', 'textValueList': [('Record animation', 0), ('No recording', 1)], 'value': 1, 'variable': 'solutionViewerSaveImages', 'grid': [(5, 0), (5, 1)] }, ] mbs.variables['solutionViewerRowIncrement'] = float(rowIncrement) mbs.variables['solutionViewerNSteps'] = nSteps mbs.variables['solutionViewerSolution'] = solution # mbs.variables['solutionViewerStep'] = 0 # mbs.variables['solutionViewerPeriod'] = timeout def UFviewer(mbs, dialog): i = int(mbs.variables['solutionViewerStep']) # mbs.systemData.SetTime(t, exudyn.ConfigurationType.Visualization) SetSolutionState(mainSystem, mbs.variables['solutionViewerSolution'], i, exudyn.ConfigurationType.Visualization) #exudyn.DoRendererIdleTasks(timeout) # SC.visualizationSettings.contour.reduceRange = False mbs.SendRedrawSignal() exudyn.DoRendererIdleTasks( ) #as there is no simulation, we must do this for graphicsDataUserFunctions # if mbs.variables['modeShapeSaveImages'] == 0: # SC.RedrawAndSaveImage() #create images for animation # else: # SC.visualizationSettings.exportImages.saveImageFileCounter = 0 #for next mode ... dialog.period = mbs.variables['solutionViewerPeriod'] if mbs.variables['solutionViewerRunModus'] < 2: mbs.variables['solutionViewerStep'] += mbs.variables[ 'solutionViewerRowIncrement'] # print("step=", mbs.variables['solutionViewerStep']) #first variable is scale, which contains step dialog.variableList[0][0].set(mbs.variables['solutionViewerStep']) # for var in dialog.variableList: # #self.mbs.variables[var[1]] = var[0].get() # print(var[1],'=', var[0].get()) if mbs.variables['solutionViewerSaveImages'] == 0: SC.RedrawAndSaveImage() #create images for animation # else: #do not reset image counter to allow creating of multi-view images, slow motion, etc. # SC.visualizationSettings.exportImages.saveImageFileCounter = 0 # if mbs.variables['solutionViewerStep'] > mbs.variables[ 'solutionViewerNSteps'] - 1.: #or (mbs.variables['solutionViewerRunModus'] and mbs.variables['solutionViewerStep']==mbs.variables['solutionViewerNSteps']-1.): mbs.variables['solutionViewerStep'] = 0 dialog.variableList[0][0].set(0) SetSolutionState(mainSystem, mbs.variables['solutionViewerSolution'], 0, exudyn.ConfigurationType.Visualization) # mbs.SendRedrawSignal() # exudyn.DoRendererIdleTasks() #as there is no simulation, we must do this for graphicsDataUserFunctions if mbs.variables[ 'solutionViewerRunModus'] == 1: #one cylce ==> stop dialog.StartSimulation() #start/stop simulation exudyn.StartRenderer() if 'renderState' in exudyn.sys: SC.SetRenderState(exudyn.sys['renderState']) #load last model view simulationSettings = exudyn.SimulationSettings( ) #not used, but needed in dialog # self.mbs.sys['solver'].InitializeSolver(self.mbs, self.simulationSettings) simulationSettings.solutionSettings.solutionInformation = '' if not SC.visualizationSettings.general.useMultiThreadedRendering: exudyn.DoRendererIdleTasks() #do an update once dialog = InteractiveDialog(mbs, simulationSettings=simulationSettings, simulationFunction=UFviewer, dialogItems=dialogItems, title='Solution Viewer', doTimeIntegration=False, period=timeout, showTime=True, runOnStart=runOnStart) #SC.WaitForRenderEngineStopFlag() #not needed, Render window closes when dialog is quit exudyn.StopRenderer() #safely close rendering window! SC.visualizationSettings.general.graphicsUpdateInterval = oldUpdateInterval #set values back to original
def UFshowModes(mbs, dialog): i = mbs.variables['modeShapeTimeIndex'] mbs.variables['modeShapeTimeIndex'] += 1 stepsPerPeriod = mbs.variables['modeShapeStepsPerPeriod'] amplitude = mbs.variables['modeShapeAmplitude'] if amplitude == 0: SC.visualizationSettings.bodies.deformationScaleFactor = 0 amplitude = 1 else: SC.visualizationSettings.bodies.deformationScaleFactor = 1 if mbs.variables['modeShapeRunModus'] == 2: #no sin(t) in static case stepsPerPeriod = 1 t = 0 else: t = i / stepsPerPeriod * 2 * pi amplitude *= sin(t) mbs.systemData.SetTime(t, exudyn.ConfigurationType.Visualization) ode2Coords = mbs.systemData.GetODE2Coordinates() selectedMode = int(mbs.variables['modeShapeModeNumber']) outputVariable = exudyn.OutputVariableType( int(mbs.variables['modeShapeOutputVariable'])) ode2Coords[mbs.variables['modeShapeNodeCoordIndex'] + selectedMode] = amplitude mbs.systemData.SetODE2Coordinates( ode2Coords, exudyn.ConfigurationType.Visualization) SC.visualizationSettings.contour.reduceRange = False #check, if automatic range of contour colors shall be recomputed: if (mbs.variables['modeShapeLastSetting'][0] != int( mbs.variables['modeShapeModeNumber']) or mbs.variables['modeShapeLastSetting'][1] != int( mbs.variables['modeShapeOutputVariable']) or mbs.variables['modeShapeLastSetting'][2] != mbs.variables['modeShapeAmplitude'] or mbs.variables['modeShapeLastSetting'][3] != int( mbs.variables['modeShapeComponent'])): #print("set=",mbs.variables['modeShapeLastSetting']) SC.visualizationSettings.contour.reduceRange = True SC.visualizationSettings.general.renderWindowString = renderWindowText + 'mode ' + str( int(mbs.variables['modeShapeModeNumber'])) mbs.variables['modeShapeLastSetting'] = [ int(mbs.variables['modeShapeModeNumber']), int(mbs.variables['modeShapeOutputVariable']), mbs.variables['modeShapeAmplitude'], int(mbs.variables['modeShapeComponent']) ] SC.visualizationSettings.contour.outputVariable = outputVariable SC.visualizationSettings.contour.outputVariableComponent = int( mbs.variables['modeShapeComponent']) #component SC.visualizationSettings.openGL.showFaces = ( mbs.variables['modeShapeMesh'] & 1) == 1 SC.visualizationSettings.openGL.showFaceEdges = ( mbs.variables['modeShapeMesh'] & 2) == 2 mbs.SendRedrawSignal() if not SC.visualizationSettings.general.useMultiThreadedRendering: exudyn.DoRendererIdleTasks() if mbs.variables['modeShapeSaveImages'] == 0: SC.RedrawAndSaveImage() #create images for animation else: SC.visualizationSettings.exportImages.saveImageFileCounter = 0 #for next mode ... dialog.period = mbs.variables['modeShapePeriod'] if mbs.variables['modeShapeTimeIndex'] >= stepsPerPeriod: mbs.variables['modeShapeTimeIndex'] = 0 if mbs.variables['modeShapeRunModus'] > 0: #one cylce or static dialog.StartSimulation()
def AnimateModes(systemContainer, mainSystem, nodeNumber, period=0.04, stepsPerPeriod=30, showTime=True, renderWindowText='', runOnStart=False, runMode=0): SC = systemContainer mbs = mainSystem SC.visualizationSettings.general.graphicsUpdateInterval = 0.25 * min( period, 2e-3) #set according update interval! SC.visualizationSettings.general.showSolverTime = showTime #SC.visualizationSettings.general.showComputationInfo = False SC.visualizationSettings.general.showSolverInformation = False SC.visualizationSettings.general.renderWindowString = renderWindowText + 'mode 0' coordIndex = mbs.GetNodeODE2Index(nodeNumber) nodeCoords = mbs.GetNodeOutput(nodeNumber, exudyn.OutputVariableType.Coordinates, exudyn.ConfigurationType.Reference) numberOfModes = len(nodeCoords) #numberOfModes = mbs.GetNode(nODE2)['numberOfODE2Coordinates'] if (runMode != 0 and runMode != 1 and runMode != 2): print('ERROR in AnimateModes: illegal run mode:', runMode) return #use interactive dialog: dialogItems = [ { 'type': 'label', 'text': 'Mode shape:', 'grid': (1, 0) }, { 'type': 'slider', 'range': (0, numberOfModes - 1), 'value': 0, 'steps': numberOfModes, 'variable': 'modeShapeModeNumber', 'grid': (1, 1) }, { 'type': 'label', 'text': 'Contour plot:', 'grid': (2, 0) }, { 'type': 'radio', 'textValueList': [('None', int(exudyn.OutputVariableType._None)), ('DisplacementLocal', int(exudyn.OutputVariableType.DisplacementLocal)), ('Displacement', int(exudyn.OutputVariableType.Displacement)), ('StressLocal', int(exudyn.OutputVariableType.StressLocal)), ('StrainLocal', int(exudyn.OutputVariableType.StrainLocal))], 'value': int(exudyn.OutputVariableType.DisplacementLocal), 'variable': 'modeShapeOutputVariable', 'grid': [(3, 0), (3, 1), (3, 2), (3, 3), (3, 4)] }, { 'type': 'label', 'text': 'Contour Component (use -1 for norm):', 'grid': (4, 0) }, { 'type': 'slider', 'range': (-1, 5), 'value': 0, 'steps': 7, 'variable': 'modeShapeComponent', 'grid': (4, 1) }, { 'type': 'label', 'text': 'Amplitude:', 'grid': (5, 0) }, { 'type': 'slider', 'range': (0, 0.5), 'value': 0.05, 'steps': 501, 'variable': 'modeShapeAmplitude', 'grid': (5, 1) }, { 'type': 'label', 'text': 'update period:', 'grid': (6, 0) }, { 'type': 'slider', 'range': (0.01, 2), 'value': 0.04, 'steps': 200, 'variable': 'modeShapePeriod', 'grid': (6, 1) }, { 'type': 'radio', 'textValueList': [('Continuous run', 0), ('One cycle', 1), ('Static', 2)], 'value': runMode, 'variable': 'modeShapeRunModus', 'grid': [(7, 0), (7, 1), (7, 2)] }, { 'type': 'radio', 'textValueList': [('Mesh+Faces', 3), ('Faces only', 1), ('Mesh only', 2)], 'value': 3, 'variable': 'modeShapeMesh', 'grid': [(8, 0), (8, 1), (8, 2)] }, { 'type': 'radio', 'textValueList': [('Record animation', 0), ('No recording', 1)], 'value': 1, 'variable': 'modeShapeSaveImages', 'grid': [(9, 0), (9, 1)] }, ] mbs.variables['modeShapePeriod'] = period mbs.variables['modeShapeStepsPerPeriod'] = stepsPerPeriod mbs.variables['modeShapeTimeIndex'] = 0 mbs.variables['modeShapeLastSetting'] = [-1, 0, 0, 0] mbs.variables['modeShapeNodeCoordIndex'] = coordIndex def UFshowModes(mbs, dialog): i = mbs.variables['modeShapeTimeIndex'] mbs.variables['modeShapeTimeIndex'] += 1 stepsPerPeriod = mbs.variables['modeShapeStepsPerPeriod'] amplitude = mbs.variables['modeShapeAmplitude'] if amplitude == 0: SC.visualizationSettings.bodies.deformationScaleFactor = 0 amplitude = 1 else: SC.visualizationSettings.bodies.deformationScaleFactor = 1 if mbs.variables['modeShapeRunModus'] == 2: #no sin(t) in static case stepsPerPeriod = 1 t = 0 else: t = i / stepsPerPeriod * 2 * pi amplitude *= sin(t) mbs.systemData.SetTime(t, exudyn.ConfigurationType.Visualization) ode2Coords = mbs.systemData.GetODE2Coordinates() selectedMode = int(mbs.variables['modeShapeModeNumber']) outputVariable = exudyn.OutputVariableType( int(mbs.variables['modeShapeOutputVariable'])) ode2Coords[mbs.variables['modeShapeNodeCoordIndex'] + selectedMode] = amplitude mbs.systemData.SetODE2Coordinates( ode2Coords, exudyn.ConfigurationType.Visualization) SC.visualizationSettings.contour.reduceRange = False #check, if automatic range of contour colors shall be recomputed: if (mbs.variables['modeShapeLastSetting'][0] != int( mbs.variables['modeShapeModeNumber']) or mbs.variables['modeShapeLastSetting'][1] != int( mbs.variables['modeShapeOutputVariable']) or mbs.variables['modeShapeLastSetting'][2] != mbs.variables['modeShapeAmplitude'] or mbs.variables['modeShapeLastSetting'][3] != int( mbs.variables['modeShapeComponent'])): #print("set=",mbs.variables['modeShapeLastSetting']) SC.visualizationSettings.contour.reduceRange = True SC.visualizationSettings.general.renderWindowString = renderWindowText + 'mode ' + str( int(mbs.variables['modeShapeModeNumber'])) mbs.variables['modeShapeLastSetting'] = [ int(mbs.variables['modeShapeModeNumber']), int(mbs.variables['modeShapeOutputVariable']), mbs.variables['modeShapeAmplitude'], int(mbs.variables['modeShapeComponent']) ] SC.visualizationSettings.contour.outputVariable = outputVariable SC.visualizationSettings.contour.outputVariableComponent = int( mbs.variables['modeShapeComponent']) #component SC.visualizationSettings.openGL.showFaces = ( mbs.variables['modeShapeMesh'] & 1) == 1 SC.visualizationSettings.openGL.showFaceEdges = ( mbs.variables['modeShapeMesh'] & 2) == 2 mbs.SendRedrawSignal() if not SC.visualizationSettings.general.useMultiThreadedRendering: exudyn.DoRendererIdleTasks() if mbs.variables['modeShapeSaveImages'] == 0: SC.RedrawAndSaveImage() #create images for animation else: SC.visualizationSettings.exportImages.saveImageFileCounter = 0 #for next mode ... dialog.period = mbs.variables['modeShapePeriod'] if mbs.variables['modeShapeTimeIndex'] >= stepsPerPeriod: mbs.variables['modeShapeTimeIndex'] = 0 if mbs.variables['modeShapeRunModus'] > 0: #one cylce or static dialog.StartSimulation() exudyn.StartRenderer() if 'renderState' in exudyn.sys: SC.SetRenderState(exudyn.sys['renderState']) #load last model view simulationSettings = exudyn.SimulationSettings( ) #not used, but needed in dialog # self.mbs.sys['solver'].InitializeSolver(self.mbs, self.simulationSettings) simulationSettings.solutionSettings.solutionInformation = 'Mode X' if not SC.visualizationSettings.general.useMultiThreadedRendering: exudyn.DoRendererIdleTasks() #do an update once dialog = InteractiveDialog( mbs, simulationSettings=simulationSettings, simulationFunction=UFshowModes, dialogItems=dialogItems, title='Animate mode shapes', doTimeIntegration=False, period=period, showTime=False, #done in UFshowModes runOnStart=runOnStart) #SC.WaitForRenderEngineStopFlag() #not needed, Render window closes when dialog is quit exudyn.StopRenderer() #safely close rendering window!