pymeshlabFileImport.py

You can view and download this file on Github: pymeshlabFileImport.py

  1#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2# This is an EXUDYN example
  3#
  4# Details:  demo showing import of simple .obj file using specialized interface functions;
  5#           requires pymeshlab to be installed!
  6#
  7# Author:   Johannes Gerstmayr
  8# Date:     2026-02-11
  9#
 10# Copyright:This file is part of Exudyn. Exudyn is free software. You can redistribute it and/or modify it under the terms of the Exudyn license. See 'LICENSE.txt' for more details.
 11#
 12#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 13
 14import exudyn as exu
 15from exudyn.itemInterface import *
 16from exudyn.utilities import * #includes itemInterface and rigidBodyUtilities
 17import exudyn.graphics as graphics #only import if it does not conflict #includes graphics and rigid body utilities
 18import numpy as np
 19
 20SC = exu.SystemContainer()
 21mbs = SC.AddSystem()
 22
 23
 24#%%++++++++++++++++++++++++++++++++++++++++++++++++++++
 25#physical parameters
 26g =     [0,0,-9.81] #gravity
 27L = 1               #length
 28w = 0.1             #width
 29bodyDim=[L,w,w] #body dimensions
 30p0 =    [0,0,0]     #origin of pendulum
 31pMid0 = np.array([L*0.5,0,0]) #center of mass, body0
 32
 33#ground body
 34oGround = mbs.AddObject(ObjectGround())
 35
 36
 37#%%++++++++++++++++++++++++++++++++++++++++++++++++++++
 38#first link:
 39iCube0 = InertiaCuboid(density=5000, sideLengths=bodyDim)
 40iCube0 = iCube0.Translated([-0.25*L,0,0]) #transform COM, COM not at reference point!
 41
 42#graphics for body
 43#chose one of the files:
 44fileName = '../Examples/testData/objImportTest.obj'
 45
 46graphicsBody0 = graphics.FromPyMeshlabFile(fileName,
 47                                           invertNormals=False,
 48                                           invertTriangles=False,
 49                                           defaultColor = graphics.color.dodgerblue,
 50                                           useDefaultColor = True,
 51                                           verbose=True)
 52
 53#+++++++++++++++++++++++++++++++++++++++++++++
 54# repair with trimesh
 55# [V, F] = graphics.ToPointsAndTrigs( graphicsBody0)
 56# import trimesh
 57# mesh = trimesh.Trimesh(vertices=V, faces=F, process=False)
 58# trimesh.repair.fix_winding(mesh)
 59# mesh.fix_normals()
 60# triangles = mesh.faces
 61# triangles = np.take(triangles, [0,2,1], axis=1)
 62
 63# graphicsBody0 = graphics.FromPointsAndTrigs(points=mesh.vertices,
 64#                                             triangles=triangles,
 65#                                             normals=mesh.vertex_normals,
 66#                                             color=graphics.color.steelblue)
 67#+++++++++++++++++++++++++++++++++++++++++++++
 68
 69#transform or scale:
 70#graphicsBody0 = graphics.Move(graphicsBody0, [0,0,0], 0.001*np.eye(3))
 71
 72#+++++++++++++++++++++++++++++++++++++++++++++
 73#smoothen
 74graphicsBody0 = graphics.AddEdgesAndSmoothenNormals(graphicsBody0, edgeAngle=0.25*pi,
 75                                                    edgeColor=[0,0,0,0])
 76#+++++++++++++++++++++++++++++++++++++++++++++
 77
 78
 79graphicsCOM0 = graphics.Basis(origin=iCube0.com, length=2*w)
 80
 81dictCube0 = mbs.CreateRigidBody(
 82              inertia=iCube0,
 83              referencePosition=pMid0,
 84              referenceRotationMatrix=np.diag([1,1,1]),
 85              gravity=g,
 86              graphicsDataList=[graphicsCOM0, graphicsBody0],
 87              returnDict=True)
 88[n0, b0] = [dictCube0['nodeNumber'], dictCube0['bodyNumber']]
 89
 90
 91#%%++++++++++++++++++++++++++
 92#revolute joint (free z-axis)
 93
 94#revolute joint option 3:
 95mbs.CreateRevoluteJoint(bodyNumbers=[oGround, b0], position=[0,0,0], axis=[0,1,0],
 96                        axisRadius=0.2*w, axisLength=1.4*w)
 97
 98# AddRevolute*Joint(mbs, body0=oGround, body1=b0, point=[0,0,0],
 99#                   axis=[0,0,1], useGlobalFrame=True, showJoint=True,
100#                   axisRadius=0.2*w, axisLength=1.4*w)
101
102#assemble system before solving
103mbs.Assemble()
104simulationSettings = exu.SimulationSettings() #takes currently set values or default values
105
106tEnd = 4 #simulation time
107h = 1e-3 #step size
108simulationSettings.timeIntegration.numberOfSteps = int(tEnd/h)
109simulationSettings.timeIntegration.endTime = tEnd
110simulationSettings.timeIntegration.verboseMode = 1
111#simulationSettings.timeIntegration.simulateInRealtime = True
112simulationSettings.solutionSettings.solutionWritePeriod = 0.005 #store every 5 ms
113
114SC.visualizationSettings.view0.window.renderWindowSize=[1600,1200]
115SC.visualizationSettings.openGL.multiSampling = 1
116SC.visualizationSettings.openGL.lineWidth = 1
117SC.visualizationSettings.openGL.light0.shadow = 0.2*0
118# SC.visualizationSettings.openGL.advanced.lightModelTwoSide = True
119# SC.visualizationSettings.openGL.light0.position = [3,4,10,1]
120SC.visualizationSettings.general.autoFitScene = True
121
122SC.visualizationSettings.nodes.drawNodesAsPoint=False
123SC.visualizationSettings.nodes.showBasis=True
124SC.visualizationSettings.general.useGradientBackground = True
125
126SC.renderer.Start()
127if 'renderState' in exu.sys: #reload old view
128    SC.renderer.SetState(exu.sys['renderState'])
129
130SC.renderer.DoIdleTasks() #stop before simulating
131
132mbs.SolveDynamic(simulationSettings = simulationSettings,
133                 solverType=exu.DynamicSolverType.TrapezoidalIndex2)
134
135SC.renderer.DoIdleTasks() #stop before closing
136SC.renderer.Stop() #safely close rendering window!