Skip to content

Commit

Permalink
Merge pull request #93 from opensim-org/fix_decorations
Browse files Browse the repository at this point in the history
Call generateDecorations twice for fixed and non-fixed geometry
  • Loading branch information
aymanhab authored Sep 20, 2023
2 parents e40ceee + 2f8f21f commit 65476e6
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ class DecorativeGeometryImplementationGltf(osim.simbody.DecorativeGeometryImplem
groundNode = None # Node corresponding to Model::Ground
modelState = None # reference to state object obtained by initSystem
mapTypesToMaterialIndex = {}

MaterialGrouping = {}
model = None

accessors = None # references to arrays within the gltf structure for convenience
buffers = None
bufferViews = None
Expand Down Expand Up @@ -86,14 +87,30 @@ def implementCircleGeometry(self, arg0):
def implementSphereGeometry(self, arg0):
sphereSource = vtk.vtkSphereSource()
sphereSource.SetRadius(arg0.getRadius()*self.unitConversion)
sphereSource.SetPhiResolution(16)
sphereSource.SetThetaResolution(16)
sphereSource.Update()
polyDataOutput = sphereSource.GetOutput()
self.createGLTFMeshFromPolyData(arg0, "Sphere:", polyDataOutput, self.getMaterialIndexByType())
# print("produce sphere", arg0.getRadius())
return

def implementEllipsoidGeometry(self, arg0):
return _simbody.DecorativeGeometryImplementation_implementEllipsoidGeometry(self, arg0)
sphereSource = vtk.vtkSphereSource()
sphereSource.SetRadius(1.0*self.unitConversion)
sphereSource.SetPhiResolution(16)
sphereSource.SetThetaResolution(16)
# Make a stretching transform to take the sphere into an ellipsoid
stretch = vtk.vtkTransformPolyDataFilter();
stretchSphereToEllipsoid = vtk.vtkTransform();
radiiVec3 = arg0.getRadii()
stretchSphereToEllipsoid.Scale(radiiVec3[0], radiiVec3[1], radiiVec3[2]);
stretch.SetTransform(stretchSphereToEllipsoid);
stretch.SetInputConnection(sphereSource.GetOutputPort());
stretch.Update()
polyDataOutput = stretch.GetOutput()
self.createGLTFMeshFromPolyData(arg0, "Ellipsoid:", polyDataOutput, self.getMaterialIndexByType())
return

def implementFrameGeometry(self, arg0):
# print("produce frame", arg0.getAxisLength())
Expand Down Expand Up @@ -150,8 +167,17 @@ def createGLTFMeshFromPolyData(self, arg0, gltfName, polyDataOutput, materialInd
self.mapMobilizedBodyIndexToNodes[arg0.getBodyId()].children.append(nodeIndex)

def implementTorusGeometry(self, arg0):
return _simbody.DecorativeGeometryImplementation_implementTorusGeometry(self, arg0)

torus=vtk.vtkParametricTorus();
torusSource = vtk.vtkParametricFunctionSource();
torusSource.SetParametricFunction(torus);
torusMapper=vtk.vtkPolyDataMapper();
torusMapper.SetInputConnection(torusSource.GetOutputPort());
torus.SetRingRadius(arg0.getTorusRadius()+arg0.getTubeRadius());
torus.SetCrossSectionRadius(arg0.getTubeRadius());
polyDataOutput = torusSource.GetOutput();
self.createGLTFMeshFromPolyData(arg0, "Torus:", polyDataOutput, self.getMaterialIndexByType())
return

def implementArrowGeometry(self, arg0):
return _simbody.DecorativeGeometryImplementation_implementArrowGeometry(self, arg0)

Expand Down Expand Up @@ -196,6 +222,13 @@ def addDefaultMaterials(self):
# 3 shiny green material for forces
# 4 shiny blue material for experimental markers
# 5 shiny orange material for IMUs
self.MaterialGrouping["ContactHalfSpace"] = "Wrapping"
self.MaterialGrouping["ContactSphere"] = "Wrapping"
self.MaterialGrouping["ContactMesh"] = "Wrapping"
self.MaterialGrouping["WrapSphere"] = "Wrapping"
self.MaterialGrouping["WrapCylinder"] = "Wrapping"
self.MaterialGrouping["WrapEllipsoid"] = "Wrapping"
self.MaterialGrouping["WrapTorus"] = "Wrapping"
self.mapTypesToMaterialIndex["Mesh"] = self.addMaterialToGltf("default", [.87, .78, .6, 1.0])
self.mapTypesToMaterialIndex["Wrapping"] = self.addMaterialToGltf("obstacle", [0, .9, .9, 0.7])
self.mapTypesToMaterialIndex["Marker"] = self.addMaterialToGltf("markerMat", [1.0, .6, .8, 1.0])
Expand All @@ -216,7 +249,11 @@ def addMaterialToGltf(self, matName, color4):

def getMaterialIndexByType(self):
componentType = self.currentComponent.getConcreteClassName()
mat = self.mapTypesToMaterialIndex.get(componentType)
materialGrouping = self.MaterialGrouping.get(componentType)
if (materialGrouping is not None):
mat = self.mapTypesToMaterialIndex.get(materialGrouping)
else:
mat = self.mapTypesToMaterialIndex.get(componentType)
if (mat is not None):
return mat
else:
Expand All @@ -226,7 +263,6 @@ def setNodeTransformFromDecoration(self, node: Node, mesh: Mesh, decorativeGeome
bd = decorativeGeometry.getBodyId()
bdNode = self.mapMobilizedBodyIndexToNodes[bd]
nodeIndex = len(self.nodes)
meshIndex = len(self.meshes)
self.meshes.append(mesh)
bdNode.children.append(nodeIndex)
nodeForDecoration = Node(name=""+bd.getName()+decorativeGeometry.getIndexOnBody())
Expand Down Expand Up @@ -259,17 +295,21 @@ def addMeshForPolyData(self, polyData: vtk.vtkPolyData, mat: int):
tris.Update()
triPolys = tris.GetOutput()

meshBufferIndex = len(self.buffers)
# This follows vtkGLTFExporter flow
pointData = triPolys.GetPoints().GetData();
self.writeBufferAndView(pointData, ARRAY_BUFFER)
bounds = triPolys.GetPoints().GetBounds()
# create accessor
pointAccessor = Accessor()
pointAccessor.bufferView= len(self.bufferViews)-1
pointAccessor.byteOffset = 0
pointAccessor.type = VEC3
pointAccessor.componentType = FLOAT
pointAccessor.count = pointData.GetNumberOfTuples()
maxValue = [bounds[1], bounds[3], bounds[5]]
minValue = [bounds[0], bounds[2], bounds[4]]
pointAccessor.min = minValue
pointAccessor.max = maxValue
self.accessors.append(pointAccessor)
pointAccessorIndex = len(self.accessors)-1

Expand All @@ -295,7 +335,6 @@ def addMeshForPolyData(self, polyData: vtk.vtkPolyData, mat: int):
primitive.material = mat
meshPolys = triPolys.GetPolys()
ia = vtk.vtkUnsignedIntArray()
cellData = meshPolys.GetData()
idList = vtk.vtkIdList()
while meshPolys.GetNextCell(idList):
# do something with the cell
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def convertOsim2Gltf(osimModelFilePath, geometrySearchPath) :
sizeBefore = adg.size()
# print(comp.getAbsolutePathString())
comp.generateDecorations(True, mdh, state, adg);
# we don't know how to handle muscles for now so will leave off, verify everything else displays ok
if (comp.getConcreteClassName()!= "GeometryPath"):
comp.generateDecorations(False, mdh, state, adg);
sizeAfter = adg.size()
if (sizeAfter > sizeBefore):
decorativeGeometryImp.setCurrentComponent(comp)
Expand Down
4 changes: 4 additions & 0 deletions src/components/Components/VisualizationControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ const VisualizationControl : React.FC<VisualizationControlProps> = (props:Visual
<FormControlLabel control={<Checkbox />} label={t('visualizationControl.joints')} />
<FormControlLabel control={<Checkbox checked={curState.getLayerVisibility(1)}/>} label={t('visualizationControl.bodies')}
onChange={()=>{curState.toggleLayerVisibility(1); setCameraLayerMask(curState.cameraLayersMask)}} />
<FormControlLabel control={<Checkbox checked={curState.getLayerVisibility(7)}/>} label={t('visualizationControl.wrapObjects')}
onChange={()=>{curState.toggleLayerVisibility(7); setCameraLayerMask(curState.cameraLayersMask)}} />
<FormControlLabel control={<Checkbox checked={curState.getLayerVisibility(8)}/>} label={t('visualizationControl.contactObjects')}
onChange={()=>{curState.toggleLayerVisibility(8); setCameraLayerMask(curState.cameraLayersMask)}} />
<FormControlLabel control={<Checkbox checked={curState.getLayerVisibility(4)}/>} label={t('visualizationControl.markers')}
onChange={()=>{curState.toggleLayerVisibility(4); setCameraLayerMask(curState.cameraLayersMask)}}/>
</FormGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/OpenSimControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const OpenSimControl = () => {
curState.takeSnapshot = false;
}
else if (curState.cameraLayersMask !== camera.layers.mask) {
for (let layernumber =0; layernumber < 6; layernumber++){
for (let layernumber =0; layernumber < 31; layernumber++){
let newState = curState.getLayerVisibility(layernumber)
if (newState)
camera.layers.enable(layernumber)
Expand Down
10 changes: 9 additions & 1 deletion src/components/pages/OpenSimScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ const OpenSimScene: React.FC<OpenSimSceneProps> = ({ currentModelPath, supportCo
["World", 3],
["Marker", 4],
["ExpMarker", 5],
["expForce", 6]
["expForce", 6],
["WrapSphere", 7],
["WrapCylinder", 7],
["WrapEllipsoid", 7],
["WrapTorus", 7],
["wrapObject", 7],
["ContactSphere", 8],
["ContactMesh", 8],
["ContactHalfSpace", 8]
]);

const mapObjectToLayer = (obj3d: Object3D)=>{
Expand Down
2 changes: 2 additions & 0 deletions src/internationalization/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ i18next
wcs: "WCS",
joints: "Joints",
bodies: "Bodies",
wrapObjects: "WrapObjects",
contactObjects: "Contacts",
markers: "Markers",
speed: "Speed"
},
Expand Down

0 comments on commit 65476e6

Please sign in to comment.