1 /*************************************************************************
2  *                                                                       *
3  * Vega FEM Simulation Library Version 3.1                               *
4  *                                                                       *
5  * "distance field" library , Copyright (C) 2007 CMU, 2016 USC           *
6  * All rights reserved.                                                  *
7  *                                                                       *
8  * Code authors: Hongyi Xu, Jernej Barbic                                *
9  * http://www.jernejbarbic.com/code                                      *
10  *                                                                       *
11  * Research: Jernej Barbic, Hongyi Xu, Doug L. James                     *
12  *                                                                       *
13  * Funding: National Science Foundation, Link Foundation,                *
14  *          Zumberge Research and Innovation Fund at USC                 *
15  *                                                                       *
16  * This library is free software; you can redistribute it and/or         *
17  * modify it under the terms of the BSD-style license that is            *
18  * included with this library in the file LICENSE.txt                    *
19  *                                                                       *
20  * This library is distributed in the hope that it will be useful,       *
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file     *
23  * LICENSE.TXT for more details.                                         *
24  *                                                                       *
25  *************************************************************************/
26 
27 /*
28   This class computes a signed distance field from polygon soup geometry, as described in:
29 
30   Hongyi Xu, Jernej Barbic:
31   Signed Distance Fields for Polygon Soup Meshes, Graphics Interface 2014, Montreal, Canada
32 */
33 
34 
35 #ifndef _SIGNEDDISTANCEFIELDFROMPOLYGONSOUP_H_
36 #define _SIGNEDDISTANCEFIELDFROMPOLYGONSOUP_H_
37 
38 #include <vector>
39 #include "distanceField.h"
40 #include "distanceFieldMT.h"
41 #include "distanceFieldNarrowBand.h"
42 #include "closestPointField.h"
43 #include "objMesh.h"
44 
45 class SignedDistanceFieldFromPolygonSoup
46 {
47 public:
48   // if useCubicBox=0, the bounding box will not be a cube, but the aspect ratios of the bounding box will be set so that voxels are cubes, by following the resolutionX, resolutionY, resolutionZ parameters in the Compute* routines below
49   // if useCubicBox=1, the bounding box will be a cube, but the voxels will not necessarily be cubes
50   SignedDistanceFieldFromPolygonSoup(ObjMesh * objMesh, double expansionRatio = 1.5, bool useCubicBox = 1,
51       Vec3d * bbmin = NULL, Vec3d * bbmax = NULL);
~SignedDistanceFieldFromPolygonSoup()52   ~SignedDistanceFieldFromPolygonSoup() {}
53 
54   // Compute a signed distance field from polygon soup geometry, as described in:
55   // Hongyi Xu, Jernej Barbic:
56   // Signed Distance Fields for Polygon Soup Meshes, Graphics Interface 2014, Montreal, Canada
57   //
58   // An unsigned field will be created first (or loaded from precomputedUnsignedFieldFilename if not NULL).
59   // Then, a new mesh is created around the sigma isosurface. Next, a signed field is computed based on this new mesh. Finally, this signed field is offset by -sigma, to approximate the isosurface at the original mesh.
60   // "sigma" is given in absolute units (not grid units)
61   // subtractSigma: whether to subtract sigma from the computed signed distance field (to match the "zero" isosurface)
62   // computeVoronoiDiagram: whether to compute Voronoi diagram (stored in DistanceField)
63   // closestPointFlag: whether to return a ClosestPointField or not (default: return DistanceField)
64   DistanceField * ComputeDistanceField(int resolutionX, int resolutionY, int resolutionZ, double sigma, int subtractSigma = 1,
65       int numThreads = 0, bool computeVoronoiDiagram = false, int maxTriCount = 15, int maxDepth = 10, int closestPointFlag = 0,
66       const char * precomputedUnsignedFieldFilename = NULL);
67 
68   // Compute a distance field in a narrow band around the geometry
69   // bandwidth: the width of the band (in either direction) around the geometry where the distance field is computed
70   // "bandwidth" and "sigma" are given in absolute units (not grid units)
71   DistanceFieldNarrowBand * ComputeDistanceFieldNarrowBand(int resolutionX, int resolutionY, int resolutionZ, double bandwidth,
72       double sigma, int subtractSigma = 1, int maxTriCount = 15, int maxDepth = 10, const char * precomputedUnsignedFieldFilename = NULL);
73 
74 protected:
75   ObjMesh * objMesh;
76 
77   double expansionRatio;
78   bool useCubicBox;
79   Vec3d bbmin, bbmax;
80   bool autoBoundingBox;
81 
82   //remove the interior components inside the isosurface
83   ObjMesh * RemoveInteriorComponents(ObjMesh * isoMesh);
84 
85   //construct the pseudo-normal for each component for pseudo-normal test
86   bool ConstructPseudoNormalComponents(ObjMesh * isoMesh, std::vector<TriangleWithCollisionInfoAndPseudoNormals*>* triangleList);
87 
88   //pseudo-normal test to determine the relation between two components
89   bool CheckInAndOutViaNormalTest(std::vector<TriangleWithCollisionInfoAndPseudoNormals*>* triangleList, int compIndex1, int compIndex2);
90 
91   //pre-removal via bounding box test. If a bounding box is completely inside another bounding box, the smaller one can be removed.
92   bool CheckInAndOutViaBoundingBox(std::vector<Vec3d> & bmin, std::vector<Vec3d> & bmax, int compIndex1, int compIndex2);
93 
94   //extract isosurface using marching cubes from unsigned distance field.
95   ObjMesh * ComputeIsosurface(DistanceFieldBase * distanceField, double sigma);
96 
97   bool setBoundingBox(DistanceFieldBase* field, int resolutionX, int resolutionY, int resolutionZ);
98 };
99 
100 #endif
101 
102