Skip to content

Commit

Permalink
Fix broken cleanup, skinned mesh race condition (#250)
Browse files Browse the repository at this point in the history
* Fix broken cleanup, skinned mesh edge case

* Remove log
  • Loading branch information
brentyi authored Jul 22, 2024
1 parent 5a10456 commit f236041
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 18 deletions.
2 changes: 0 additions & 2 deletions examples/23_smpl_visualizer_skinned.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,6 @@ def main(model_path: Path) -> None:
# Match transform control gizmos to joint positions.
for i, control in enumerate(gui_elements.transform_controls):
control.position = smpl_outputs.T_parent_joint[i, :3, 3]
print(control.position)

skinned_handle.bones[i].wxyz = tf.SO3.from_matrix(
smpl_outputs.T_world_joint[i, :3, :3]
).wxyz
Expand Down
3 changes: 0 additions & 3 deletions src/viser/client/src/MessageHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -476,9 +476,6 @@ function useMessageHandler() {
);
},
() => {
bones.forEach((bone) => {
bone.remove();
});
skeleton.dispose();
cleanupMesh();
},
Expand Down
11 changes: 0 additions & 11 deletions src/viser/client/src/SceneTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,6 @@ export function SceneNodeThreeObject(props: {
const makeObject = viewer.useSceneTree(
(state) => state.nodeFromName[props.name]?.makeObject,
);
const cleanup = viewer.useSceneTree(
(state) => state.nodeFromName[props.name]?.cleanup,
);
const unmountWhenInvisible = viewer.useSceneTree(
(state) => state.nodeFromName[props.name]?.unmountWhenInvisible,
);
Expand Down Expand Up @@ -256,14 +253,6 @@ export function SceneNodeThreeObject(props: {
}
});

// Clean up when done.
React.useEffect(() => {
return () => {
cleanup && cleanup();
delete viewer.nodeRefFromName.current[props.name];
};
});

// Clicking logic.
const sendClicksThrottled = useThrottledMessageSender(50);
const [hovered, setHovered] = React.useState(false);
Expand Down
16 changes: 14 additions & 2 deletions src/viser/client/src/SceneTreeState.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import React, { useContext } from "react";
import { MakeObject, SceneNode } from "./SceneTree";
import { CoordinateFrame } from "./ThreeAssets";
import * as THREE from "three";
import { create } from "zustand";
import { subscribeWithSelector } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
import { ViewerContext } from "./App";

interface SceneTreeState {
nodeFromName: { [name: string]: undefined | SceneNode };
Expand Down Expand Up @@ -37,6 +38,7 @@ rootNodeTemplate.children.push("/WorldAxes");
/** Declare a scene state, and return a hook for accessing it. Note that we put
effort into avoiding a global state! */
export function useSceneTreeState() {
const viewer = useContext(ViewerContext)!;
return React.useState(() =>
create(
subscribeWithSelector(
Expand All @@ -51,8 +53,10 @@ export function useSceneTreeState() {
addSceneNode: (node) =>
set((state) => {
const existingNode = state.nodeFromName[node.name];
if (existingNode) {
if (existingNode !== undefined) {
// Node already exists.
delete viewer.nodeRefFromName.current[node.name];
existingNode.cleanup && existingNode.cleanup(); // Free resources.
state.nodeFromName[node.name] = {
...node,
children: existingNode.children,
Expand Down Expand Up @@ -83,7 +87,10 @@ export function useSceneTreeState() {
findChildrenRecursive(name);

removeNames.forEach((removeName) => {
const node = state.nodeFromName[removeName]!;
node.cleanup && node.cleanup(); // Free resources.
delete state.nodeFromName[removeName];
delete viewer.nodeRefFromName.current[removeName];
});

// Remove node from parent's children list.
Expand All @@ -99,6 +106,11 @@ export function useSceneTreeState() {
if (key !== "" && key !== "/WorldAxes")
delete state.nodeFromName[key];
}
Object.values(state.nodeFromName).forEach((node) => {
// Free resources.
if (node === undefined || node.cleanup === undefined) return;
node.cleanup();
});
state.nodeFromName[""] = rootNodeTemplate;
state.nodeFromName["/WorldAxes"] = rootAxesNode;
}),
Expand Down

0 comments on commit f236041

Please sign in to comment.