ModelBuilder.h
1 #pragma once
2 #include <functional>
3 #include <unordered_map>
4 #include <unordered_set>
5 
6 #include "HIOUtilityHTML.h"
7 #include "GrownKeyPath.h"
8 #include "Line.h"
9 #include "Text.h"
10 #include "lazy.h"
11 #include "sc_store.h"
12 #include "sc_store_utils.h"
13 #include "sc_store_utils_text.h"
14 #include "sc_assemblytree.h"
15 
16 namespace hio_html_internal
17 {
19  {
20  public:
21  static void Init(HOutputHandler * handler);
22  static void Reset();
23 
24  static void ReportProgress(std::string const & message);
25  static void ReportProgress(float percent);
26 
27  private:
28  static HOutputHandler * outputHandler;
29  };
30 
31  static inline unsigned char unit_to_byte(float const & a)
32  {
33  uint32_t v = extract_uint32_t(a);
34 
35  v &= 0x7FFFFFFF;
36  if (v < 0x3B800000)
37  return 0;
38 
39  v--;
40 
41  uint32_t exp = v >> 23;
42  uint32_t man = (v & 0x007FFFFF) | 0x00800000;
43 
44  return (unsigned char)(man >> (16 + 126 - exp));
45  }
46 
47  struct RGBA32Color
48  {
49  RGBA32Color()
50  {}
51 
52  RGBA32Color(RGBAColor const & c)
53  {
54  r = unit_to_byte(c[0]);
55  g = unit_to_byte(c[1]);
56  b = unit_to_byte(c[2]);
57  a = unit_to_byte(c[3]);
58  }
59 
60  RGBA32Color(RGBColor const & c)
61  {
62  r = unit_to_byte(c[0]);
63  g = unit_to_byte(c[1]);
64  b = unit_to_byte(c[2]);
65  a = 255;
66  }
67 
68  unsigned char r;
69  unsigned char g;
70  unsigned char b;
71  unsigned char a;
72  };
73 
74  enum class MeshType
75  {
76  Face,
77  Line,
78  Point,
79  Misc,
80  };
81 
82  enum class MaterialType : char
83  {
84  NoColor = 0,
85  ByIndex,
86  RGBColor,
87  RGBAColor,
88  };
89 
91  {
92  MeshEnvironment(MeshEnvironment const & other) = delete;
93  void operator= (MeshEnvironment const & other) = delete;
94 
95  public:
96  MeshEnvironment() {}
98 
99  void operator= (MeshEnvironment && other);
100 
101  void PatchMeshPointers();
102  bool IsValid() const;
103 
104  SC::Store::Mesh mesh;
105  bool isText;
106  std::vector<SC::Store::Point> points;
107  std::vector<SC::Store::Normal> normals;
108  std::vector<SC::Store::UV> uvs;
109  std::vector<SC::Store::RGBA32> rgba32s;
110  };
111 
113  {
114  public:
115  MeshStatistics();
116 
117  size_t triangleCount;
118  size_t polylineCount;
119  size_t freePointCount;
120  };
121 
122  class HTMLLogger : public SC::Store::Logger {
123  public:
124  virtual void Message(const char * message) const
125  {
126  printf("%s\n", message);
127  }
128  };
129 
131  {
132  public:
133  ModelStatistics();
134 
135  size_t instanceCount;
136 
137  size_t uniqueFaceMeshCount;
138  size_t uniqueLineMeshCount;
139  size_t uniquePointMeshCount;
140  size_t uniqueMiscMeshCount;
141  size_t uniqueImageCount;
142 
143  size_t faceMeshCount;
144  size_t lineMeshCount;
145  size_t pointMeshCount;
146  size_t miscMeshCount;
147  };
148 
149  enum class Visibility : uint32_t {
150  None = 0,
151  Face = 1 << 0,
152  Line = 1 << 1,
153  Point = 1 << 2,
154  Text = 1 << 3,
155  };
156 
158  {
159  public:
160  enum class Batching {
161  Disabled,
162  SegmentLines,
163  SegmentGeometry,
164  };
165 
167 
168  public:
169  std::function<bool(HC_KEY)> assemblyTreeGenerateChild;
170  ModelStatistics * statistics;
171  SC::Store::Color defaultColor;
172  Batching batching;
173  bool excludeInvisibleGeometry;
174  bool excludeLines;
175  bool excludeVertexNormals;
176  bool excludeVertexUVs;
177  bool excludeVertexColors;
178  bool generateImplicitEdges;
179  bool forceNormals;
180  bool verbose;
181  bool storeGeometryUserData;
182  bool forceCounterClockwiseWinding;
183  bool groupAllMeshInstances;
184  bool generateAssemblyTree;
185  bool markMeshesAsManifold;
186  };
187 
188  enum class PolygonHandedness : size_t
189  {
190  Left,
191  Right,
192  None,
193 
194  Default = Left
195  };
196 
198  {
199  public:
200  SimpleMaterial() {}
201  SimpleMaterial(SC::Store::Color const & color);
202  SimpleMaterial(SC::Store::Color const & color, float mirror, float specular, float gloss, std::string texture);
203 
204  size_t Hash() const;
205  bool operator== (SimpleMaterial const & other) const;
206 
207  public:
208  SC::Store::Color color;
209  float mirror;
210  float specular;
211  float gloss;
212  std::string texture;
213  };
214 
216  {
217  size_t operator() (SimpleMaterial const & material) const { return material.Hash(); }
218  };
219 
221  {
222  public:
223  AggregateMaterial() {}
224 
226  HC_KEY scratchSegment,
227  ModelBuilderConfig const & config,
228  KeyArray const & key_path,
229  std::string const & materialMappingKit,
230  Lazy<StringArray> & materialMap);
231 
233  HC_KEY scratchSegment,
234  KeyArray const & key_path,
235  AggregateMaterial const & segmentMaterial,
236  std::string const & localMaterialMappingKit,
237  Lazy<StringArray> & materialMap);
238 
239  private:
240  void Initialize(
241  KeyArray const & key_path,
242  std::string const & materialMappingKit,
243  Lazy<StringArray> & materialMap);
244 
245  HC_KEY modelBuilderScratchSegment;
246 
247  public:
248  SimpleMaterial face;
249  SimpleMaterial line;
250  SimpleMaterial point;
251  SimpleMaterial text;
252  };
253 
255  {
256  public:
257  NetClipRegions() : loops_array(), spaces(), operations(), clip_region_key() {}
258 
259  public:
260  using ClipRegionArray = std::vector<PointArray>;
261 
262  ClipRegionArray loops_array;
263  StringArray spaces;
264  StringArray operations;
265  mutable SC::Store::ClipRegionKey clip_region_key;
266  };
267 
268  struct MatrixEq
269  {
270  bool operator() (SC::Store::Matrix3d const & matrix1, SC::Store::Matrix3d const & matrix2) const;
271  };
272 
273  struct MatrixHasher
274  {
275  size_t operator() (SC::Store::Matrix3d const & matrix) const;
276  };
277 
279  {
280  size_t operator() (SC::Store::MaterialKeys const & materialMap) const;
281  };
283  {
284  size_t KeyHasher(const HC_KEY & key) const
285  {
286  size_t hash = (size_t)key;
287  hash = (hash ^ 61) ^ (hash >> 16);
288  hash = hash + (hash << 3);
289  hash = hash ^ (hash >> 4);
290  hash = hash * 0x27d4eb2d;
291  hash = hash ^ (hash >> 15);
292  return hash;
293  }
294 
295  size_t operator() (std::tuple<HC_KEY, PolygonHandedness, Visibility> const & tuple) const {
296  return KeyHasher(std::get<0>(tuple)) + static_cast<size_t>(std::get<1>(tuple)) + static_cast<uint32_t>(std::get<2>(tuple));
297  }
298  };
299 
300  struct RgbHasher
301  {
302  size_t operator() (RGBColor const & color) const;
303  };
304 
306  Visibility geometryVisibility;
307  Visibility lightingVisibility;
308  };
309 
311  {
312  typedef std::vector<RGBA32Color> RGBA32ColorArray;
313 
314  public:
315  ~ModelBuilder();
316 
317  ModelBuilder(
318  ModelBuilderConfig const & config,
319  SC::Store::Logger & logger,
320  SC::Store::Model & model,
321  SC::Store::InclusionKey inclusionKey,
322  HOutputHandler * handler,
323  HOutputHandlerOptions const * options);
324 
325  bool PreUpdateBySegPath(GrownKeyPath const & segPath);
326  void UpdateBySegPath(GrownKeyPath const & segPath);
327 
328  private:
329  static Lazy<PolygonHandedness> LazyObtainPolygonHandedness(KeyArray const & segPath);
330  Lazy<AggregateMaterial> LazyObtainAggregateMaterial(KeyArray const & segPath, Lazy<StringArray> & materialMap);
331  Lazy<NetClipRegions> LazyObtainNetClipRegions(KeyArray const & segPath);
332 
333  void UpdateBySegPath(GrownKeyPath const & segPath, HC_KEY segKey, bool followReferences);
334 
335  void FollowReference(
336  GrownKeyPath const & segPath,
337  HC_KEY referenceKey,
338  Lazy<TextAttributes> & textAttributes,
339  Lazy<StringArray> & materialMap,
340  Lazy<AggregateMaterial> & material,
341  Lazy<GeomAndLightVisibility> & visibility,
342  Lazy<PolygonHandedness> & polygonHandedness,
343  Lazy<NetClipRegions> & netClipRegions);
344 
345  void TryInsertBatchedMeshes(
346  KeyArray const & keyPath,
347  HC_KEY segmentKey,
348  Lazy<SC::Store::MatrixKey> & matrixKey,
349  Lazy<AggregateMaterial> & material,
350  Visibility visibility,
351  Visibility lightingVisibility,
352  PolygonHandedness polygonHandedness,
353  NetClipRegions const & net_clip_regions);
354 
355  void TryInsert(
356  KeyArray const & keyPath,
357  HC_KEY geometryKey,
358  Lazy<StringArray> & materialMap,
359  Lazy<Matrix> & matrix,
360  Lazy<SC::Store::MatrixKey> & matrixKey,
361  Lazy<AggregateMaterial> & segmentMaterial,
362  Lazy<TextAttributes> & textAttributes,
363  std::string const * localMaterialMappingKit,
364  Visibility visibility,
365  Visibility lightingVisibility,
366  PolygonHandedness polygonHandedness,
367  NetClipRegions const & net_clip_regions);
368 
369  void AddToMeshBatch(
370  HC_KEY geometryKey,
371  Lazy<StringArray> & materialMap,
372  Lazy<Matrix> & matrix,
373  Lazy<TextAttributes> & textAttributes,
374  KeyArray const & keyPath,
375  Visibility visibility,
376  PolygonHandedness polygonHandedness);
377 
378  SC::Store::MeshKey ObtainMeshKey(
379  Visibility visibility,
380  HC_KEY geometryKey,
381  Lazy<StringArray> & materialMap,
382  Lazy<Matrix> & matrix,
383  Lazy<TextAttributes> & textAttributes,
384  KeyArray const & keyPath,
385  PolygonHandedness polygonHandedness,
386  Visibility & usedVisibilities,
387  bool & outIsText);
388 
389  SC::Store::ImageKey ObtainImageKey(HC_KEY imageKey);
390  SC::Store::MatrixKey ObtainMatrixKey(Matrix const & matrixKit);
391  SC::Store::MaterialKey ObtainMaterialKey(SimpleMaterial const & material, KeyArray const & keyPath);
392  SC::Store::MaterialMapKey ObtainMaterialMapKey(SC::Store::MaterialKeys && materialMap);
393 
394  SC::Store::Mesh * CreateShellWireframeMesh(
395  Visibility visibility,
396  Lazy<StringArray> & materialMap,
397  HC_KEY shellKey,
398  PointArray const & points,
399  std::vector<Line> const & lines,
400  PolygonHandedness polygonHandedness);
401 
402  SC::Store::Mesh * CreateLineMesh(
403  Visibility visibility,
404  HC_KEY lineKey,
405  PolygonHandedness polygonHandedness);
406 
407  SC::Store::Mesh * CreateShellMesh(
408  Visibility visibility,
409  HC_KEY shellKey,
410  Lazy<StringArray> & materialMap,
411  KeyArray const & keyPath,
412  PolygonHandedness polygonHandedness);
413 
414  SC::Store::Mesh * CreateTextMesh(
415  HC_KEY textKey,
416  Lazy<Matrix> & matrix,
417  TextAttributes const & textAttributes,
418  PolygonHandedness polygonHandedness);
419 
420  SC::Store::Mesh * CreateMesh(
421  Visibility visibility,
422  HC_KEY key,
423  Lazy<StringArray> & materialMap,
424  Lazy<Matrix> & matrix,
425  Lazy<TextAttributes> & textAttributes,
426  KeyArray const & keyPath,
427  PolygonHandedness polygonHandedness,
428  bool & outIsText);
429 
430  SC::Store::Mesh * CreateMassagedMesh(
431  Visibility visibility,
432  HC_KEY geometryKey,
433  Lazy<StringArray> & materialMap,
434  Lazy<Matrix> & matrix,
435  Lazy<TextAttributes> & textAttributes,
436  KeyArray const & keyPath,
437  PolygonHandedness polygonHandedness);
438 
439  VectorArray GetShellVertexNormals(HC_KEY shellKey);
440 
441  FloatArray GetShellVertexUVs(HC_KEY shellKey);
442 
443  RGBA32ColorArray GetVertexColors(
444  HC_KEY shellKey,
445  Lazy<StringArray> & materialMap,
446  std::string component);
447 
448  bool ApplyTexture(
449  SC::Store::Material & faceMaterial,
450  std::string const & textureDefinition,
451  KeyArray const & keyPath);
452 
453  SC::Store::MaterialKey InsertMaterial(SimpleMaterial const & material, KeyArray const & keyPath);
454  SC::Store::MatrixKey InsertMatrix(SC::Store::Matrix3d const & matrix);
455  SC::Store::MeshKey InsertMesh(SC::Store::Mesh const & mesh);
456  SC::Store::MaterialMapKey InsertMaterialMap(SC::Store::MaterialKeys const & materialMap);
457 
458  SC::Store::InstanceKey Instance(
459  SC::Store::MeshKey meshKey,
460  SC::Store::MatrixKey matrixKey,
461  AggregateMaterial const & material,
462  Visibility visibility,
463  Visibility lightingVisibility,
464  bool isText,
465  NetClipRegions const & net_clip_regions,
466  KeyArray const & keyPath);
467 
468  void CanonicalizeElementIndexMapping(
469  SC::Store::MaterialKeys & materialMap,
470  std::vector<size_t> & faceToElementIndex);
471 
472  std::vector<size_t> ObtainFaceToElementIndexMapping(
473  KeyArray const & keyPath,
474  HC_KEY shellKey,
475  SC::Store::Mesh & mesh);
476 
477  MeshEnvironment & ObtainCompatibleBatchedMesh(SC::Store::Mesh const & overlayMesh, bool isText);
478  void MergeIntoBatchedMesh(SC::Store::Mesh & overlayMesh, bool isText);
479  void MergeSegmentLines(HC_KEY & segKey);
480 
481  SC::Store::Mesh & MeshFromCache(PolygonHandedness polygonHandedness);
482  void MeshElementsFromCache(std::vector<SC::Store::MeshElement> & meshElements, size_t count);
483  void ReleaseToCache(SC::Store::Mesh & mesh);
484  void ReleaseToCache(std::vector<SC::Store::MeshElement> & meshElements);
485  void FinalizeTableDataKey();
486 
487  private:
488  ModelBuilder(ModelBuilder const &) = delete;
489  void operator= (ModelBuilder const &) = delete;
490 
491  private:
492  ModelBuilderConfig const config;
493  SC::Store::Logger & logger;
494  SC::Store::Model & model;
495  SC::Store::InclusionKey inclusionKey;
496 
497  HC_KEY scratchSeg;
498 
499  std::unique_ptr<SC::Store::AssemblyTree> assemblyTree;
500  std::vector<Lazy<uint32_t>> assemblyTreePath;
501  std::unordered_map<HC_KEY, unsigned> generatedSegmentNameIds;
502 
503  std::vector<MeshEnvironment> batchedMeshEnvironments;
504  std::unordered_set<HC_KEY> batchedLines;
505  std::vector<HC_KEY> createdShells;
506 
507  SC::Store::Mesh cachedMesh;
508  std::vector<SC::Store::MeshElement> cachedMeshElements;
509  std::vector<size_t> cachedIndices1;
510  std::vector<size_t> cachedIndices2;
511 
512  PointArray pointBuffer;
513  VectorArray vertexNormalBuffer;
514  FloatArray vertexUVBuffer;
515  RGBA32ColorArray vertexColorBuffer;
516 
517  std::unordered_map<SimpleMaterial, SC::Store::MaterialKey, SimpleMaterialHasher> seenMaterials;
518  std::unordered_map<SC::Store::Matrix3d, SC::Store::MatrixKey, MatrixHasher, MatrixEq> seenMatrices;
519  std::unordered_map<HC_KEY, SC::Store::ImageKey> seenImages;
520  std::unordered_map<SC::Store::MaterialKeys, SC::Store::MaterialMapKey, MaterialKeysHasher> seenMaterialMaps;
521 
522  std::unordered_map <
523  std::tuple<HC_KEY, PolygonHandedness, Visibility>,
524  std::pair<SC::Store::MeshKey, Visibility>,
525  SeenMeshHasher> seenGeometries;
526 
527  std::unordered_map <
528  std::tuple<HC_KEY, PolygonHandedness, Visibility>,
529  std::vector<std::pair<SC::Store::MeshKey, Visibility>>,
530  SeenMeshHasher> seenBatchedGeometries;
531 
532  std::vector<std::pair<MeshStatistics, MeshType>> meshesStats; // Indexed by MeshKey.
533 
534  SC::Store::DataKey tableDataKey;
535  std::vector<std::pair<SC::Store::MeshKey, SC::Store::DataKey>> pendingDataKeys;
536 
537  SC::Store::InstanceKey lastGeneratedInstanceKey;
538 
539  HOutputHandler * outputHandler;
540 
541  std::string driverPath;
542  std::unordered_map<std::string, bool> fontOutlineability;
543  };
544 } //end of hio_html_internal namespace
Definition: lazy.h:6
Definition: ModelBuilder.h:220
Definition: ModelBuilder.h:197
Definition: ModelBuilder.h:310
Definition: ModelBuilder.h:122
Definition: ModelBuilder.h:112
Definition: HDWFMisc.h:22
Definition: ModelBuilder.h:157
Definition: ModelBuilder.h:300
HOutputHandler an abstract base class for model and image output.
Definition: HIOManager.h:1269
Definition: ModelBuilder.h:215
Definition: ModelBuilder.h:282
Definition: ModelBuilder.h:47
Definition: GrownKeyPath.h:7
Definition: HIOManager.h:908
Definition: ModelBuilder.h:305
Definition: ModelBuilder.h:268
Definition: ModelBuilder.h:278
Definition: ModelBuilder.h:18
A class used to denote a line segment by its front and back indices.
Definition: Line.h:8
Definition: ModelBuilder.h:130
Definition: ModelBuilder.h:254
Definition: ModelBuilder.h:90
Definition: ModelBuilder.h:273
Definition: GrownKeyPath.h:5