MCPcopy Create free account
hub / github.com/Meshcapade/difflocks / forward

Method forward

models/strand_codec.py:296–373  ·  view source on GitHub ↗
(self, strand_features, hyperparams, normalization_dict)

Source from the content-addressed store, hash-verified

294
295
296 def forward(self, strand_features, hyperparams, normalization_dict):
297 nr_strands = strand_features.shape[0]
298 strand_features = strand_features.view(nr_strands, 1, -1).repeat(1, self.nr_verts_to_create, 1) # nr_strands x 100 x nr_channels
299 t = self.t.view(1, self.nr_verts_to_create, -1).repeat(nr_strands, 1, 1) #nrstrands, nr_verts, nr_channels
300
301
302 point_indices = None
303 if self.decode_random_verts:
304 # choose a random t for each strand
305 # we can create only up until the very last vertex, except the tip, we need to be able to sample the next vertex so as to get a direction vector
306 probability = torch.ones([nr_strands, self.num_pts - 2], dtype=torch.float32, device=torch.device("cuda"))
307 point_indices = torch.multinomial(probability, self.nr_verts_to_create, replacement=False) # size of the chunk size we selected
308 # add also the next vertex on the strand so that we can compute directions
309 point_indices = torch.cat([point_indices, point_indices + 1], 1)
310
311 t = batched_index_select(t, 1, point_indices)
312
313 # decode xyz
314 h_siren = t
315 z_scaling = self.z_scaling
316 z = strand_features
317 z_initial = z * z_scaling
318 z = z * z_scaling
319
320 #cat also T
321 z=torch.cat([z,t],dim=2)
322
323
324 hair_dir=None
325 for i in range(self.nr_layers):
326 gain = self.gain_per_layer[i]
327
328 h_modulation = self.activ( self.modulation_layers[i](z))
329
330 s = self.siren_layers[i](h_siren)
331
332 #the input to the siren has to be unit gaussian, if we multiply by hmodulation, we are reducing the variance by Zscaling, so we boost the variance back up with this so that h_siren is unit gaussian again
333 h_siren = h_modulation * s * (1.0/(z_scaling*gain))
334
335 z = torch.cat([z_initial, h_modulation,t], 2)
336
337
338
339 pred_dict={}
340
341 if self.decode_type=="xyz":
342 points_pos = self.decode_val(h_siren)
343 if self.decode_random_verts:
344 pred_strands = points_pos
345 else:
346 # start_positions = torch.zeros(nr_strands, 1, 3).cuda()
347 start_positions = self.start_positions.repeat(nr_strands,1,1)
348 pred_strands = torch.cat([start_positions, points_pos], 1)
349 #positions are normalized to be in unit gaussian so we denormalize them to be in real space
350 pred_strands=un_normalize_data(pred_strands, normalization_dict["xyz_mean"], normalization_dict["xyz_std"])
351 elif self.decode_type=="dir":
352 # divide by the nr of points on the strand otherwise the direction will have norm=1 and then when integrated you end up with a gigantic strand that has 100 units
353

Callers

nothing calls this directly

Calls 2

batched_index_selectFunction · 0.90
un_normalize_dataFunction · 0.85

Tested by

no test coverage detected