MCPcopy Create free account
hub / github.com/MotrixLab/ViMoGen / compute_body_penetration

Function compute_body_penetration

mbench/pose_quality.py:139–198  ·  view source on GitHub ↗

Compute body penetration/collision percentage using BVH collision detection

(full_info_path: str, device: str, **kwargs)

Source from the content-addressed store, hash-verified

137
138
139def compute_body_penetration(full_info_path: str, device: str, **kwargs):
140 """
141 Compute body penetration/collision percentage using BVH collision detection
142 """
143 prompt_dict_ls = load_dimension_info(full_info_path, dimension='Body_Penetration')
144 gender = 'neutral'
145 model_path = 'data/body_models/smpl/SMPL_NEUTRAL.pkl'
146
147 collision_percentage_list = []
148 per_motion_metrics = []
149 skipped = 0
150
151 for prompt_dict in tqdm(prompt_dict_ls):
152 evaluation_file = prompt_dict["evaluation_file"]
153 try:
154 data = load_pose_data(evaluation_file, device, require_vertices=True)
155 except ValueError as e:
156 skipped += 1
157 continue
158
159 pred_joints = torch.as_tensor(data['joints'], device=device, dtype=torch.float32)
160 pred_vertices = torch.as_tensor(data['vertices'], device=device, dtype=torch.float32)
161 motion_length = pred_joints.shape[0]
162
163 # Initialize SMPL model
164 smpl_model = get_smpl_model(gender=gender, model_path=model_path, batch_size=motion_length, device=device)
165 faces_np = np.asarray(smpl_model.faces, dtype=np.int64)
166 faces = torch.as_tensor(faces_np, device=device, dtype=torch.long)
167
168 # Self-collision detection
169 bvh_model = BVH(max_collisions=8)
170 collision_percentage = []
171 for frame_idx in range(pred_vertices.shape[0]):
172 vertices = pred_vertices[frame_idx].unsqueeze(dim=0)
173 triangles = vertices[:, faces]
174 outputs = bvh_model(triangles)
175 outputs = outputs.detach().cpu().numpy().squeeze()
176 collisions = outputs[outputs[:, 0] >= 0, :]
177 collision_percentage.append(collisions.shape[0] / float(triangles.shape[1]) * 100)
178 collision_percentage = np.mean(collision_percentage)
179
180 collision_value = float(collision_percentage)
181 collision_percentage_list.append(collision_value)
182 per_motion_metrics.append(
183 {
184 "id": prompt_dict.get("id"),
185 "prompt": prompt_dict.get("prompt"),
186 "value": collision_value,
187 "evaluation_file": evaluation_file,
188 "motion_duration": prompt_dict.get("motion_duration"),
189 }
190 )
191
192 if skipped > 0:
193 print(f"Body_Penetration: Skipped {skipped} samples (missing SMPLify data). Run SMPLify rendering first.")
194
195 return {
196 "aggregate": summarize_scores(collision_percentage_list),

Callers

nothing calls this directly

Calls 4

load_dimension_infoFunction · 0.90
load_pose_dataFunction · 0.85
get_smpl_modelFunction · 0.85
summarize_scoresFunction · 0.70

Tested by

no test coverage detected