NVIDIA DeepLearning Dataset Synthesizer (NDDS)
 All Classes Namespaces Functions Variables Typedefs Pages
DRUtils.h
1 /*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10 
11 #pragma once
12 
13 #include "DomainRandomizationDNNPCH.h"
14 #include "DRUtils.generated.h"
15 
16 DECLARE_LOG_CATEGORY_EXTERN(LogNVDRUtils, Log, All)
17 
18 USTRUCT(BlueprintType)
19 struct DOMAINRANDOMIZATIONDNN_API FRandomRotationData
20 {
21  GENERATED_BODY()
22 
23 public:
24  FRandomRotationData();
25 
26  // Get a random rotation from the constrained data
27  FRotator GetRandomRotation() const;
28 
29  // Get a random rotation related to (the constrained data is applied around) a fixed rotation
30  FRotator GetRandomRotationRelative(const FRotator& BaseRotation) const;
31 
32  bool ShouldRandomized() const
33  {
34  return bRandomizeRotationInACone || bRandomizePitch || bRandomizeRoll || bRandomizeYaw;
35  }
36 
37 protected: // Editor properties
38  // If true, generate random rotation inside a cone
39  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
40  bool bRandomizeRotationInACone;
41 
42  // Half of the angle (in degree) of the cone where we want to generate the rotation inside
43  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeRotationInACone))
44  float RandomConeHalfAngle;
45 
46  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
47  bool bRandomizePitch;
48 
49  // The range of pitch angle (in degree)
50  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizePitch))
51  FFloatInterval PitchRange;
52 
53  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
54  bool bRandomizeRoll;
55 
56  // The range of roll angle (in degree)
57  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeRoll))
58  FFloatInterval RollRange;
59 
60  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
61  bool bRandomizeYaw;
62 
63  // The range of yaw angle (in degree)
64  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeYaw))
65  FFloatInterval YawRange;
66 };
67 
68 USTRUCT(BlueprintType)
69 struct DOMAINRANDOMIZATIONDNN_API FRandomLocationData
70 {
71  GENERATED_BODY()
72 public:
73  FRandomLocationData();
74 
75  // Get a random location from the constrained data
76  FVector GetRandomLocation() const;
77 
78  // Get a random location related to (the constrained data is applied around) a fixed location
79  FVector GetRandomLocationRelative(const FVector& BaseLocation) const;
80 
81  // Get a random location in an object's local space
82  FVector GetRandomLocationInLocalSpace(const FTransform& ObjectTransform) const;
83 
84  bool ShouldRandomized() const
85  {
86  return bRandomizeXAxis || bRandomizeYAxis || bRandomizeZAxis;
87  }
88 
89 public:
90  // If true, the location can be along X axis in world space
91  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
92  bool bRandomizeXAxis;
93 
94  // The range of location in the X axis (in world space)
95  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeXAxis))
96  FFloatInterval XAxisRange;
97 
98  // If true, the location can be along Y axis in world space
99  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
100  bool bRandomizeYAxis;
101 
102  // The range of location in the Y axis (in world space)
103  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeYAxis))
104  FFloatInterval YAxisRange;
105 
106  // If true, the location can be along Z axis in world space
107  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
108  bool bRandomizeZAxis;
109 
110  // The range of location in the Y axis (in world space)
111  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeZAxis))
112  FFloatInterval ZAxisRange;
113 };
114 
115 USTRUCT(BlueprintType)
116 struct DOMAINRANDOMIZATIONDNN_API FRandomScale3DData
117 {
118  GENERATED_BODY()
119 
120 public:
121  FRandomScale3DData();
122 
123  // Get a random 3d scale from the constrained data
124  FVector GetRandomScale3D() const;
125 
126  bool ShouldRandomized() const
127  {
128  return bUniformScale || bRandomizeXAxis || bRandomizeYAxis || bRandomizeZAxis;
129  }
130 
131 public:
132  // If true, all the axes will use the same scale value
133  // Otherwise, the actor can have different scales in different axis
134  // NOTE: If this is true, the scale will be chosen in UniformScaleRange and the separated axis scale range will be ignored
135  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
136  bool bUniformScale;
137 
138  UPROPERTY(EditAnywhere, meta = (EditCondition = bUniformScale))
139  FFloatInterval UniformScaleRange;
140 
141  // If true, the actor can be scaled along the X axis in world space
142  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
143  bool bRandomizeXAxis;
144 
145  // The range of scale in the X axis (in world space)
146  // NOTE: Minimum value is set at 0.001
147  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeXAxis))
148  FFloatInterval XAxisRange;
149 
150  // If true, the actor can be scaled along the Y axis in world space
151  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
152  bool bRandomizeYAxis;
153 
154  // The range of scale in the Y axis (in world space)
155  // NOTE: Minimum value is set at 0.001
156  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeYAxis))
157  FFloatInterval YAxisRange;
158 
159  // If true, the actor can be scaled along the Z axis in world space
160  UPROPERTY(EditAnywhere, meta = (PinHiddenByDefault, InlineEditConditionToggle))
161  bool bRandomizeZAxis;
162 
163  // The range of scale in the Z axis (in world space)
164  // NOTE: Minimum value is set at 0.001
165  UPROPERTY(EditAnywhere, meta = (EditCondition = bRandomizeZAxis))
166  FFloatInterval ZAxisRange;
167 };
168 
169 UENUM()
170 enum class ERandomColorType : uint8
171 {
172  RandomizeAllColor = 0,
173  RandomizeBetweenTwoColors,
174  RandomizeAroundAColor,
175  RandomColorType_MAX UMETA(Hidden)
176 };
177 
178 USTRUCT(BlueprintType)
179 struct DOMAINRANDOMIZATIONDNN_API FRandomColorData
180 {
181  GENERATED_BODY()
182 
183 public:
184  FRandomColorData();
185 
186 #if WITH_EDITORONLY_DATA
187  void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent);
188 #endif //WITH_EDITORONLY_DATA
189 
190  FLinearColor GetRandomColor() const;
191 
192  static FLinearColor GetRandomAnyColor();
193  static FLinearColor GetRandomColorInRange(const FLinearColor& Color1, const FLinearColor& Color2, const bool& bRandomizeInHSV);
194  static FLinearColor GetRandomColorAround(const FLinearColor& BaseColor, const float& HueDelta, const float& SaturationDelta, const float& ValueDelta);
195 
196 public:
197  UPROPERTY(BlueprintReadWrite, EditAnywhere)
198  ERandomColorType RandomizationType;
199 
200  UPROPERTY(EditAnywhere, Category = Randomization, meta = (PinHiddenByDefault, InlineEditConditionToggle))
201  bool bRandomizeBetweenTwoColors;
202 
203  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeBetweenTwoColors"))
204  FLinearColor FirstColor;
205 
206  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeBetweenTwoColors"))
207  FLinearColor SecondColor;
208 
209  // If true, the color will be chosen randomly in the HSV value instead of the RGB one
210  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeBetweenTwoColors"))
211  bool bRandomizeInHSV;
212 
213  UPROPERTY(EditAnywhere, Category = Randomization, meta = (PinHiddenByDefault, InlineEditConditionToggle))
214  bool bRandomizeAroundAColor;
215 
216  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeAroundAColor"))
217  FLinearColor MainColor;
218 
219  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeAroundAColor"))
220  float MaxHueChange;
221 
222  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeAroundAColor"))
223  float MaxSaturationChange;
224 
225  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bRandomizeAroundAColor"))
226  float MaxValueChange;
227 };
228 
229 UENUM()
230 enum class EMaterialSelectionType : uint8
231 {
232  // Modify all the materials in the mesh
233  ModifyAllMaterials = 0,
234 
235  // Modify all the materials in the MaterialIndexes list
236  ModifyMaterialsInIndexesList,
237 
238  // Modify all the materials in the MaterialSlotNames list
239  ModifyMaterialInSlotNamesList,
240 
241  MaterialSelectionType_MAX UMETA(Hidden)
242 };
243 
244 // FRandomMaterialSelection represent how to select materials from a mesh to modify
245 USTRUCT(BlueprintType)
246 struct DOMAINRANDOMIZATIONDNN_API FRandomMaterialSelection
247 {
248  GENERATED_BODY()
249 
250 public:
251  FRandomMaterialSelection();
252 
253 #if WITH_EDITORONLY_DATA
254  void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent);
255 #endif //WITH_EDITORONLY_DATA
256 
257  // Find the indexes of all the material we want to modify in a mesh
258  TArray<int32> GetAffectMaterialIndexes(const class UMeshComponent* MeshComp) const;
259 
260 public: // Editor properties
261  // Decide how to select materials from the owner's mesh to modify
262  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization)
263  EMaterialSelectionType MaterialSelectionType;
264 
265  UPROPERTY(EditAnywhere, Category = Randomization, meta = (PinHiddenByDefault, InlineEditConditionToggle))
266  bool bSelectMaterialByIndexes;
267 
268  UPROPERTY(EditAnywhere, Category = Randomization, meta = (PinHiddenByDefault, InlineEditConditionToggle))
269  bool bSelectMaterialBySlotNames;
270 
271  // List of indexes of materials in the owner mesh to modify
272  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bSelectMaterialByIndexes"))
273  TArray<int32> MaterialIndexes;
274 
275  // List of names of materials in the owner mesh to modify
276  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Randomization, meta = (EditCondition = "bSelectMaterialBySlotNames"))
277  TArray<FName> MaterialSlotNames;
278 };
279 
280 USTRUCT(BlueprintType)
281 struct DOMAINRANDOMIZATIONDNN_API FRandUtils
282 {
283  GENERATED_BODY()
284 
285 public:
286  static float RandGaussian(const float mean, const float variance);
287  static FVector2D RandGaussian2D(const float mean, const float variance);
288 
289 };
290 
291 // Utility functions
292 namespace DRUtils
293 {
294  // Get the first valid mesh component in an actor
295  extern UMeshComponent* GetFirstValidMeshComponent(AActor* OwnerActor);
296 
297  // Get the valid mesh components in an actor
298  extern TArray<UMeshComponent*> GetValidChildMeshComponents(AActor* OwnerActor);
299 }
300 
301 // This struct manage a large amount numbers of assets by
302 USTRUCT(BlueprintType)
303 struct DOMAINRANDOMIZATIONDNN_API FRandomAssetStreamer
304 {
305  GENERATED_BODY()
306 
307 public:
308  FRandomAssetStreamer();
309  FRandomAssetStreamer(const FRandomAssetStreamer& OtherStreamer);
310  ~FRandomAssetStreamer();
311 
312  FRandomAssetStreamer& operator= (const FRandomAssetStreamer& OtherStreamer);
313 
314  void Init(const TArray<FDirectoryPath>& InAssetDirectories, UClass* InAssetClass);
315  void ScanPath();
316 
317  bool HasAssets() const;
318  FSoftObjectPath GetNextAssetReference();
319 
320  template <typename AssetClassType>
321  AssetClassType* GetNextAsset()
322  {
323  FSoftObjectPath NextAssetRef = GetNextAssetReference();
324  return (NextAssetRef.IsValid()
325  ? Cast<AssetClassType>(NextAssetRef.ResolveObject())
326  : nullptr);
327  }
328 
329  bool IsLoadingAssets() const;
330 
331 protected:
332  void LoadNextBatch(bool bAsyncLoad = true);
333  void OnAssetBatchLoaded();
334 
335 private:
336 
337  struct FRandomAssetStreamerCallback
338  {
339  public:
340  FRandomAssetStreamer* AssetStreamer;
341 
342  void Callback()
343  {
344  if (AssetStreamer)
345  {
346  AssetStreamer->OnAssetBatchLoaded();
347  }
348  }
349  };
350 
351 protected: // Transient properties
352  // Path to the directory where we want to get the assets from
353  UPROPERTY(Transient)
354  TArray<FDirectoryPath> AssetDirectories;
355 
356  // Class of assets to get
357  UPROPERTY(Transient)
358  UClass* ManagedAssetClass;
359 
360  // List of all the assets in the managed directory
361  UPROPERTY(Transient)
362  TArray<FSoftObjectPath> AllAssetReferences;
363 
364  // Circular queue of loaded assets
365  UPROPERTY(Transient)
366  TArray<FSoftObjectPath> LoadedAssetReferences;
367 
368  // List of assets is streaming in
369  UPROPERTY(Transient)
370  TArray<FSoftObjectPath> LoadingAssetReferences;
371 
372  UPROPERTY(Transient)
373  int32 LastLoadedAssetIndex;
374 
375  UPROPERTY(Transient)
376  int32 LastUsedAssetIndex;
377 
378  UPROPERTY(Transient)
379  int32 UnusedAssetCount;
380 
381  FStreamableManager AssetStreamer;
382 
383  TSharedPtr<FStreamableHandle> StreamableHandlePtr;
384  TSharedPtr<FRandomAssetStreamerCallback> StreamerCallbackPtr;
385 };
386 
387 // This enum is used by random material components to select which components it should modify material
388 UENUM()
389 enum class EAffectedMaterialOwnerComponentType : uint8
390 {
391  OnlyAffectMeshComponents = 0,
392  OnlyAffectDecalComponents,
393  AffectBothMeshAndDecalComponents,
394  AffectedMaterialOwnerComponentType_MAX UMETA(Hidden)
395 };