├── .gitignore
├── README.md
├── cmake
└── FindFLANN.cmake
└── src
├── BinaryNode.h
├── CMakeLists.txt
├── CmdLineParser.cpp
├── CmdLineParser.h
├── Function.h
├── Geometry.h
├── Geometry.inl
├── Hash.h
├── IsoOctree.h
├── IsoOctree.inl
├── Kdtree.h
├── Kdtree.inl
├── MAT.h
├── MAT.inl
├── Main.cpp
├── MarchingCubes.h
├── MarchingCubes.inl
├── Octree.h
├── Octree.inl
├── OctreeBspline.h
├── OctreeBspline.inl
├── Ply.h
├── Ply.inl
├── PlyFile.cpp
├── PlyFile.h
├── PolygonizerHelper.cpp
├── PolygonizerHelper.h
├── Time.cpp
├── Time.h
├── VertexData.h
├── VertexData.inl
├── polygonizer.c
├── polygonizer.h
├── vtkHelper.cpp
└── vtkHelper.h
/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OctreeBSplines
2 | ================
3 |
4 | original name: Implicit Hierarchical B-Splines Surface Reconstruction based on Octree Distance Field
5 |
6 | An implementation of the following paper.
7 |
8 | "Multi-scale surface reconstruction based on a curvature-adaptive signed distance field",
9 | Yizhi Tang, Jieqing Feng. Computer & Graphics (Speical issue of CAD/Graphics 2017).
10 |
11 | The vs2010_64bit executable can be found [here](http://yiztang.com/#CASD)
12 |
--------------------------------------------------------------------------------
/cmake/FindFLANN.cmake:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Find Flann
3 | #
4 | # This sets the following variables:
5 | # FLANN_FOUND - True if FLANN was found.
6 | # FLANN_INCLUDE_DIRS - Directories containing the FLANN include files.
7 | # FLANN_LIBRARIES - Libraries needed to use FLANN.
8 | # FLANN_DEFINITIONS - Compiler flags for FLANN.
9 |
10 | find_package(PkgConfig)
11 | pkg_check_modules(PC_FLANN flann)
12 | set(FLANN_DEFINITIONS ${PC_FLANN_CFLAGS_OTHER})
13 |
14 | find_path(FLANN_INCLUDE_DIR flann/flann.hpp
15 | HINTS ${PC_FLANN_INCLUDEDIR} ${PC_FLANN_INCLUDE_DIRS})
16 |
17 | find_library(FLANN_LIBRARY_DEBUG flann_cpp_s_debug
18 | HINTS ${PC_FLANN_LIBDIR} ${PC_FLANN_LIBRARY_DIRS})
19 |
20 | find_library(FLANN_LIBRARY_RELEASE flann_cpp_s_release
21 | HINTS ${PC_FLANN_LIBDIR} ${PC_FLANN_LIBRARY_DIRS})
22 |
23 | set(FLANN_INCLUDE_DIRS ${FLANN_INCLUDE_DIR})
24 | set(FLANN_LIBRARIES debug ${FLANN_LIBRARY_DEBUG} optimized ${FLANN_LIBRARY_RELEASE})
25 |
26 | include(FindPackageHandleStandardArgs)
27 | find_package_handle_standard_args(Flann DEFAULT_MSG
28 | FLANN_LIBRARY_DEBUG FLANN_LIBRARY_RELEASE FLANN_INCLUDE_DIR)
29 |
30 | mark_as_advanced(FLANN_LIBRARY_DEBUG FLANN_LIBRARY_RELEASE FLANN_INCLUDE_DIR)
31 |
32 |
--------------------------------------------------------------------------------
/src/BinaryNode.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | Redistributions of source code must retain the above copyright notice, this list of
9 | conditions and the following disclaimer. Redistributions in binary form must reproduce
10 | the above copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the distribution.
12 |
13 | Neither the name of the Johns Hopkins University nor the names of its contributors
14 | may be used to endorse or promote products derived from this software without specific
15 | prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 | SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 | DAMAGE.
27 | */
28 | #ifndef BINARY_NODE_INCLUDED
29 | #define BINARY_NODE_INCLUDED
30 |
31 | template
32 | class BinaryNode
33 | {
34 | public:
35 | static inline int CenterCount(int depth){return 1<>=1;
61 | depth++;
62 | }
63 | offset=(idx+1)-(1<
29 | #include
30 | #include
31 | #include
32 | #include "CmdLineParser.h"
33 |
34 |
35 | #ifdef WIN32
36 | int strcasecmp(char* c1,char* c2){return _stricmp(c1,c2);}
37 | #endif
38 |
39 | cmdLineReadable::cmdLineReadable(void){set=0;}
40 | cmdLineReadable::~cmdLineReadable(void){;}
41 | int cmdLineReadable::read(char**,int){
42 | set=1;
43 | return 0;
44 | }
45 |
46 | cmdLineInt::cmdLineInt(void){value=0;}
47 | cmdLineInt::cmdLineInt(const int& v){value=v;}
48 | int cmdLineInt::read(char** argv,int argc){
49 | if(argc>0){
50 | value=atoi(argv[0]);
51 | set=1;
52 | return 1;
53 | }
54 | else{return 0;}
55 | }
56 | cmdLineFloat::cmdLineFloat(void){value=0;}
57 | cmdLineFloat::cmdLineFloat(const float& v){value=v;}
58 | int cmdLineFloat::read(char** argv,int argc){
59 | if(argc>0){
60 | value=(float)atof(argv[0]);
61 | set=1;
62 | return 1;
63 | }
64 | else{return 0;}
65 | }
66 | cmdLineString::cmdLineString(void){value=NULL;}
67 | cmdLineString::~cmdLineString(void){
68 | if(value){
69 | delete[] value;
70 | value=NULL;
71 | }
72 | }
73 | int cmdLineString::read(char** argv,int argc){
74 | if(argc>0){
75 | value=new char[strlen(argv[0])+1];
76 | strcpy(value,argv[0]);
77 | set=1;
78 | return 1;
79 | }
80 | else{return 0;}
81 | }
82 | cmdLinePoint3D::cmdLinePoint3D(void){value[0]=value[1]=value[2]=0;}
83 | cmdLinePoint3D::cmdLinePoint3D(const Point3D& v){value[0]=v[0];value[1]=v[1];value[2]=v[2];}
84 | cmdLinePoint3D::cmdLinePoint3D(const float& v0,const float& v1,const float& v2){value[0]=v0;value[1]=v1;value[2]=v2;}
85 | int cmdLinePoint3D::read(char** argv,int argc){
86 | if(argc>2){
87 | value[0]=(float)atof(argv[0]);
88 | value[1]=(float)atof(argv[1]);
89 | value[2]=(float)atof(argv[2]);
90 | set=1;
91 | return 3;
92 | }
93 | else{return 0;}
94 | }
95 |
96 | char* GetFileExtension(char* fileName){
97 | char* fileNameCopy;
98 | char* ext=NULL;
99 | char* temp;
100 |
101 | fileNameCopy=new char[strlen(fileName)+1];
102 | assert(fileNameCopy);
103 | strcpy(fileNameCopy,fileName);
104 | temp=strtok(fileNameCopy,".");
105 | while(temp!=NULL){
106 | if(ext!=NULL){delete[] ext;}
107 | ext=new char[strlen(temp)+1];
108 | assert(ext);
109 | strcpy(ext,temp);
110 | temp=strtok(NULL,".");
111 | }
112 | delete[] fileNameCopy;
113 | return ext;
114 | }
115 |
116 | void cmdLineParse(int argc, char **argv,char** names,int num,cmdLineReadable** readable,
117 | int dumpError){
118 | int i,j;
119 |
120 | while (argc > 0) {
121 | if (argv[0][0] == '-' && argv[0][1]=='-') {
122 | for(i=0;iread(argv,argc);
126 | argv+=j,argc-=j;
127 | break;
128 | }
129 | }
130 | if(i==num){
131 | if(dumpError){
132 | fprintf(stderr, "invalid option: %s\n",*argv);
133 | fprintf(stderr, "possible options are:\n");
134 | for(i=0;i
31 | #include
32 |
33 | #include "Geometry.h"
34 |
35 | #ifdef WIN32
36 | int strcasecmp(char* c1,char* c2);
37 | #endif
38 |
39 | class cmdLineReadable{
40 | public:
41 | int set;
42 | cmdLineReadable(void);
43 | virtual ~cmdLineReadable(void);
44 | virtual int read(char** argv,int argc);
45 | };
46 |
47 | class cmdLineInt : public cmdLineReadable {
48 | public:
49 | int value;
50 | cmdLineInt();
51 | cmdLineInt(const int& v);
52 | int read(char** argv,int argc);
53 | };
54 | class cmdLineFloat : public cmdLineReadable {
55 | public:
56 | float value;
57 | cmdLineFloat();
58 | cmdLineFloat(const float& f);
59 | int read(char** argv,int argc);
60 | };
61 | class cmdLineString : public cmdLineReadable {
62 | public:
63 | char* value;
64 | cmdLineString();
65 | ~cmdLineString();
66 | int read(char** argv,int argc);
67 | };
68 | class cmdLinePoint3D : public cmdLineReadable {
69 | public:
70 | Point3D value;
71 | cmdLinePoint3D();
72 | cmdLinePoint3D(const Point3D& v);
73 | cmdLinePoint3D(const float& v0,const float& v1,const float& v2);
74 | int read(char** argv,int argc);
75 | };
76 |
77 | // This reads the arguments in argc, matches them against "names" and sets
78 | // the values of "r" appropriately. Parameters start with "--"
79 | void cmdLineParse(int argc, char **argv,char** names,int num,cmdLineReadable** r,
80 | int dumpError=1);
81 |
82 | char* GetFileExtension(char* fileName);
83 |
84 | #endif // CMD_LINE_PARSER_INCLUDED
85 |
--------------------------------------------------------------------------------
/src/Function.h:
--------------------------------------------------------------------------------
1 | #ifndef FUNCTION_INCLUDED
2 | #define FUNCTION_INCLUDED
3 |
4 | class Function
5 | {
6 | public:
7 | virtual float eval(const float pos[3])=0;
8 | };
9 |
10 | #endif
--------------------------------------------------------------------------------
/src/Geometry.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | Redistributions of source code must retain the above copyright notice, this list of
9 | conditions and the following disclaimer. Redistributions in binary form must reproduce
10 | the above copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the distribution.
12 |
13 | Neither the name of the Johns Hopkins University nor the names of its contributors
14 | may be used to endorse or promote products derived from this software without specific
15 | prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 | SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 | DAMAGE.
27 | */
28 | #ifndef GEOMETRY_INCLUDED
29 | #define GEOMETRY_INCLUDED
30 | #include
31 | #include
32 | #include
33 |
34 | template
35 | Real Random(void);
36 |
37 | template
38 | struct Point3D{
39 | Real coords[3];
40 |
41 | Real& operator[] (const int& idx);
42 | const Real& operator[] (const int& idx) const;
43 | Point3D operator + (const Point3D& p) const;
44 | Point3D operator - (const Point3D& p) const;
45 | Point3D operator * (const Real& s) const;
46 | Point3D operator / (const Real& s) const;
47 | Point3D& operator += (const Point3D& p);
48 | Point3D& operator -= (const Point3D& p);
49 | Point3D& operator *= (const Real& s);
50 | Point3D& operator /= (const Real& s);
51 | };
52 |
53 | template
54 | Point3D RandomBallPoint(void);
55 |
56 | template
57 | Point3D RandomSpherePoint(void);
58 |
59 | template
60 | Real Length(const Point3D& p);
61 |
62 | template
63 | Real SquareLength(const Point3D& p);
64 |
65 | template
66 | Real DotProduct(const Point3D& p,const Point3D& q);
67 |
68 | template
69 | Real Distance(const Point3D& p1,const Point3D& p2);
70 |
71 | template
72 | Real SquareDistance(const Point3D& p1,const Point3D& p2);
73 |
74 | template
75 | void CrossProduct(const Point3D& p1,const Point3D& p2,Point3D& p);
76 |
77 | template
78 | Point3D Normal(const Point3D& p1,const Point3D& p2,const Point3D& p3);
79 |
80 | template
81 | Real Area(const Point3D& p1,const Point3D& p2,const Point3D& p3);
82 |
83 | template
84 | Real DistanceToEdge(const Point3D& p,const Point3D e[2]);
85 | template
86 | Real DistanceToTriangle(const Point3D& p,const Point3D t[3]);
87 |
88 | template
89 | Point3D NearestPointOnEdge(const Point3D& p,const Point3D e[2],int& vFlag);
90 | template
91 | Point3D NearestPointOnTriangle(const Point3D& p,const Point3D t[3],int& vFlag);
92 | template
93 | Point3D NearestPointOnPlane(const Point3D& p,const Point3D t,const Point3D n,int& vFlag);
94 |
95 | template
96 | int OutCode(const Point3D& ctr,const Real& w,const Point3D& p);
97 |
98 | template
99 | int PointInCube(const Point3D& ctr,const Real& w,const Point3D& p);
100 | template
101 | int EdgeInCube(const Point3D& ctr,const Real& w,const Point3D e[2]);
102 | template
103 | int TriangleInCube(const Point3D& ctr,const Real& w,const Point3D t[3]);
104 |
105 | class TriangleIndex{
106 | public:
107 | size_t idx[3];
108 | };
109 |
110 | #include "Geometry.inl"
111 |
112 | #endif // GEOMETRY_INCLUDED
113 |
--------------------------------------------------------------------------------
/src/Geometry.inl:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | Redistributions of source code must retain the above copyright notice, this list of
9 | conditions and the following disclaimer. Redistributions in binary form must reproduce
10 | the above copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the distribution.
12 |
13 | Neither the name of the Johns Hopkins University nor the names of its contributors
14 | may be used to endorse or promote products derived from this software without specific
15 | prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 | SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 | DAMAGE.
27 | */
28 | #include
29 | /////////////
30 | // Point3D //
31 | /////////////
32 | template
33 | Real& Point3D::operator[] (const int& idx)
34 | {
35 | return coords[idx];
36 | }
37 | template
38 | const Real& Point3D::operator[] (const int& idx) const
39 | {
40 | return coords[idx];
41 | }
42 | template
43 | Point3D Point3D::operator + (const Point3D& p) const
44 | {
45 | Point3D q;
46 | q.coords[0]=coords[0]+p.coords[0];
47 | q.coords[1]=coords[1]+p.coords[1];
48 | q.coords[2]=coords[2]+p.coords[2];
49 | return q;
50 | }
51 | template
52 | Point3D Point3D::operator - (const Point3D& p) const
53 | {
54 | Point3D q;
55 | q.coords[0]=coords[0]-p.coords[0];
56 | q.coords[1]=coords[1]-p.coords[1];
57 | q.coords[2]=coords[2]-p.coords[2];
58 | return q;
59 | }
60 | template
61 | Point3D Point3D::operator * (const Real& s) const
62 | {
63 | Point3D q;
64 | q.coords[0]=coords[0]*s;
65 | q.coords[1]=coords[1]*s;
66 | q.coords[2]=coords[2]*s;
67 | return q;
68 | }
69 | template
70 | Point3D Point3D::operator / (const Real& s) const
71 | {
72 | Point3D q;
73 | q.coords[0]=coords[0]/s;
74 | q.coords[1]=coords[1]/s;
75 | q.coords[2]=coords[2]/s;
76 | return q;
77 | }
78 | template
79 | Point3D& Point3D::operator += (const Point3D& p)
80 | {
81 | coords[0]+=p.coords[0];
82 | coords[1]+=p.coords[1];
83 | coords[2]+=p.coords[2];
84 | return *this;
85 | }
86 | template
87 | Point3D& Point3D::operator -= (const Point3D& p)
88 | {
89 | coords[0]-=p.coords[0];
90 | coords[1]-=p.coords[1];
91 | coords[2]-=p.coords[2];
92 | return *this;
93 | }
94 | template
95 | Point3D& Point3D::operator *= (const Real& s)
96 | {
97 | coords[0]*=s;
98 | coords[1]*=s;
99 | coords[2]*=s;
100 | return *this;
101 | }
102 | template
103 | Point3D& Point3D::operator /= (const Real& s)
104 | {
105 | coords[0]/=s;
106 | coords[1]/=s;
107 | coords[2]/=s;
108 | return *this;
109 | }
110 | template
111 | Real Random(void){return Real(rand())/RAND_MAX;}
112 |
113 | template
114 | Point3D RandomBallPoint(void){
115 | Point3D p;
116 | while(1){
117 | p.coords[0]=Real(1.0-2.0*Random());
118 | p.coords[1]=Real(1.0-2.0*Random());
119 | p.coords[2]=Real(1.0-2.0*Random());
120 | Real l=SquareLength(p);
121 | if(l<=1){return p;}
122 | }
123 | }
124 | template
125 | Point3D RandomSpherePoint(void){
126 | Point3D p=RandomBallPoint();
127 | return p/Length(p);
128 | }
129 |
130 | template
131 | Real SquareLength(const Point3D& p)
132 | {
133 | return DotProduct(p,p);
134 | }
135 |
136 | template
137 | Real DotProduct(const Point3D& p,const Point3D& q)
138 | {
139 | return p.coords[0]*q.coords[0]+p.coords[1]*q.coords[1]+p.coords[2]*q.coords[2];
140 | }
141 |
142 | template
143 | Real Length(const Point3D& p)
144 | {
145 | return Real(sqrt(SquareLength(p)));
146 | }
147 |
148 | template
149 | Real SquareDistance(const Point3D& p1,const Point3D& p2)
150 | {
151 | return SquareLength(p1-p2);
152 | }
153 |
154 | template
155 | Real Distance(const Point3D& p1,const Point3D& p2){return Real(sqrt(SquareDistance(p1,p2)));}
156 |
157 | template
158 | void CrossProduct(const Point3D& p1,const Point3D& p2,Point3D& p){
159 | p.coords[0]= p1.coords[1]*p2.coords[2]-p1.coords[2]*p2.coords[1];
160 | p.coords[1]=-p1.coords[0]*p2.coords[2]+p1.coords[2]*p2.coords[0];
161 | p.coords[2]= p1.coords[0]*p2.coords[1]-p1.coords[1]*p2.coords[0];
162 | }
163 | template
164 | Point3D Normal(const Point3D& p1,const Point3D& p2,const Point3D& p3)
165 | {
166 | Point3D q1,q2,n;
167 | q1=p2-p1;
168 | q2=p3-p1;
169 | CrossProduct(q1,q2,n);
170 | return n;
171 | }
172 | template
173 | Real Area(const Point3D& p1,const Point3D& p2,const Point3D& p3)
174 | {
175 | Point3D p12=p2-p1,p13=p3-p1;
176 | Point3D tmp;
177 | CrossProduct(p12,p13,tmp);
178 | return Length(tmp);
179 | }
180 |
181 | template
182 | Real DistanceToEdge(const Point3D& p,const Point3D e[2])
183 | {
184 | Point3D q,v;
185 | Real dot;
186 | q=p-e[0];
187 | v=e[1]-e[0];
188 | dot=DotProduct(q,v);
189 | if(dot<=0)
190 | return Length(q);
191 | else if (dot>SquareLength(v))
192 | return Distance(p,e[1]);
193 | else
194 | {
195 | Real t=dot/SquareLength(v);
196 | v=e[0]*(Real(1.0)-t)+e[1]*t;
197 | return Distance(p,v);
198 | }
199 | }
200 | template
201 | Real DistanceToTriangle(const Point3D& p,const Point3D t[3])
202 | {
203 | Point3D e[2];
204 | Point3D q,v,n,nn;
205 |
206 | n=Normal(t[0],t[1],t[2]);
207 | for(int i=0;i<3;i++)
208 | {
209 | v=t[(i+1)%3]-t[i];
210 | q=p-t[i];
211 | CrossProduct(n,v,nn);
212 | if(DotProduct(q,nn)<=0)
213 | {
214 | e[0]=t[i];
215 | e[1]=t[(i+1)%3];
216 | return DistanceToEdge(p,e);
217 | }
218 | }
219 | return fabs(DotProduct(q,n))/Length(n);
220 | }
221 | template
222 | Point3D NearestPointOnEdge(const Point3D& p,const Point3D e[2],int& vFlag)
223 | {
224 | Point3D q,v;
225 | Real dot;
226 |
227 | q=p-e[0];
228 | v=e[1]-e[0];
229 |
230 | dot=DotProduct(q,v);
231 | if(dot<=0)
232 | {
233 | vFlag=1;
234 | return e[0];
235 | }
236 | else if (dot>=SquareLength(v))
237 | {
238 | vFlag=2;
239 | return e[1];
240 | }
241 | else
242 | {
243 | Real t=dot/Real(SquareLength(v));
244 | v=e[0]*(Real(1.0)-t)+e[1]*t;
245 | vFlag=3;
246 | return v;
247 | }
248 | }
249 | template
250 | Point3D NearestPointOnTriangle(const Point3D& p,const Point3D t[3],int& vFlag)
251 | {
252 | Point3D e[2];
253 | Point3D q,v,n,nn,nearest;
254 | vFlag=0;
255 |
256 | n=Normal(t[0],t[1],t[2]);
257 | for(int i=0;i<3;i++)
258 | {
259 | v=t[(i+1)%3]-t[i];
260 | q=p-t[i];
261 |
262 | CrossProduct(n,v,nn);
263 | if(DotProduct(q,nn)<=0)
264 | {
265 | int tempFlag;
266 | e[0]=t[i];
267 | e[1]=t[(i+1)%3];
268 | nearest=NearestPointOnEdge(p,e,tempFlag);
269 | if(tempFlag&1) vFlag|=1<
281 | Point3D NearestPointOnPlane(const Point3D& p,const Point3D t,const Point3D n,int& vFlag)
282 | {
283 | Point3D q,nearest;
284 | vFlag=0;
285 |
286 | q=p-t;
287 | nearest=p-n*DotProduct(q,n);
288 | return nearest;
289 | }
290 |
291 | template
292 | int OutCode(const Point3D& ctr,const Real& w,const Point3D& p)
293 | {
294 | int oc=0;
295 | if(p.coords[0]ctr.coords[0]+w/2)
298 | oc|=2;
299 | if(p.coords[1]ctr.coords[1]+w/2)
302 | oc|=8;
303 | if(p.coords[2]ctr.coords[2]+w/2)
306 | oc|=32;
307 | return oc;
308 | }
309 | template
310 | int PointInCube(const Point3D& ctr,const Real& w,const Point3D& p)
311 | {
312 | return !OutCode(ctr,w,p);
313 | }
314 | template
315 | int EdgeInCube(const Point3D& ctr,const Real& w,const Point3D e[2])
316 | {
317 | int oc[2],dir,off;
318 | Real t,x;
319 | oc[0]=OutCode(ctr,w,e[0]);
320 | oc[1]=OutCode(ctr,w,e[1]);
321 | if(!oc[0] || !oc[1]) return 1;
322 | if(oc[0] & oc[1]) return 0;
323 | #if 1
324 | for(dir=0;dir<3;dir++)
325 | if((oc[0]>>(dir<<1))&3)
326 | {
327 | off=( (oc[0]>>(dir<<1))&2) >> 1;
328 | t=( e[0][dir]-(ctr[dir] - w/2 + w*off) ) / (e[0][dir]-e[1][dir]);
329 | int inside=0;
330 | for(int i=1;i<3;i++)
331 | {
332 | int j=(dir+i)%3;
333 | x=e[0][j]*(Real(1.0)-t)+e[1][j]*t;
334 | if(x>=(ctr[j]-w/2) && x<=(ctr[j]+w/2))
335 | inside++;
336 | }
337 | if(inside==2)
338 | return 1;
339 | }
340 | return 0;
341 | #else
342 | for(dir=0;dir<3;dir++)
343 | if((oc[0]>>(dir<<1))&3)
344 | break;
345 | off=( (oc[0]>>(dir<<1))&2) >> 1;
346 | t=( e[0][dir]-(ctr[dir] -w/2 + w*off) ) / (e[0][dir]-e[1][dir]);
347 | for(int i=1;i<3;i++)
348 | {
349 | int j=(dir+i)%3;
350 | x=e[0][j]*(Real(1.0)-t)+e[1][j]*t;
351 | if(x<(ctr[j]-w/2) || x>(ctr[j]+w/2))
352 | return 0;
353 | }
354 | return 1;
355 | #endif
356 | }
357 | #ifdef ISO_OCTREE_INCLUDED
358 | template
359 | int TriangleInCube(const Point3D& ctr,const Real& w,const Point3D t[3])
360 | {
361 | Point3D e[2],n,nn[3];
362 | int oc[3];
363 | oc[0]=OutCode(ctr,w,t[0]);
364 | oc[1]=OutCode(ctr,w,t[1]);
365 | oc[2]=OutCode(ctr,w,t[2]);
366 | if(!oc[0] || !oc[1] || !oc[2])
367 | return 1;
368 | if(oc[0] & oc[1] & oc[2])
369 | return 0;
370 |
371 | for(int i=0;i<3;i++)
372 | {
373 | e[0]=t[i];
374 | e[1]=t[(i+1)%3];
375 | if(EdgeInCube(ctr,w,e))
376 | return 1;
377 | }
378 |
379 | n=Normal(t[0],t[1],t[2]);
380 | for(int i=0;i<3;i++)
381 | CrossProduct(n,t[(i+1)%3]-t[i],nn[i]);
382 |
383 | for(int i=0;i p;
388 | Cube::EdgeCorners(i,c1,c2);
389 | Cube::FactorCornerIndex(c1,x[0],x[1],x[2]);
390 | for(int j=0;j<3;j++) e[0][j]=ctr[j]-w/2+w*x[j];
391 |
392 | Cube::FactorCornerIndex(c2,x[0],x[1],x[2]);
393 | for(int j=0;j<3;j++) e[1][j]=ctr[j]-w/2+w*x[j];
394 |
395 | dot[0]=DotProduct(n,e[0]-t[0]);
396 | dot[1]=DotProduct(n,e[1]-t[0]);
397 | if(dot[0]*dot[1] >=0 ) continue;
398 | tt=dot[0]/(dot[0]-dot[1]);
399 | p=e[0]*(Real(1.0)-tt)+e[1]*tt;
400 | if(DotProduct(p-t[0],nn[0])>0 && DotProduct(p-t[1],nn[1])>0 && DotProduct(p-t[2],nn[2])>0 )
401 | return 1;
402 | }
403 | return 0;
404 | }
405 | #endif
406 |
407 |
408 |
--------------------------------------------------------------------------------
/src/Hash.h:
--------------------------------------------------------------------------------
1 | #ifndef HASH_INCLUDED
2 | #define HASH_INCLUDED
3 | #ifdef WIN32
4 | #include
5 | using stdext::hash_map;
6 | #else // !WIN32
7 | #include
8 | using namespace __gnu_cxx;
9 |
10 | namespace __gnu_cxx
11 | {
12 | template<> struct hash {
13 | size_t operator()(long long __x) const { return __x; }
14 | };
15 | template<> struct hash {
16 | size_t operator()(const long long __x) const { return __x; }
17 | };
18 |
19 |
20 | template<> struct hash {
21 | size_t operator()(unsigned long long __x) const { return __x; }
22 | };
23 | template<> struct hash {
24 | size_t operator()(const unsigned long long __x) const { return __x; }
25 | };
26 | }
27 | #endif // WIN32
28 | #endif // HASH_INCLUDED
--------------------------------------------------------------------------------
/src/IsoOctree.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2007, Michael Kazhdan
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | Redistributions of source code must retain the above copyright notice, this list of
9 | conditions and the following disclaimer. Redistributions in binary form must reproduce
10 | the above copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the distribution.
12 |
13 | Neither the name of the Johns Hopkins University nor the names of its contributors
14 | may be used to endorse or promote products derived from this software without specific
15 | prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
18 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES
19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
20 | SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
22 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 | DAMAGE.
27 | */
28 | #ifndef ISO_OCTREE_INCLUDED
29 | #define ISO_OCTREE_INCLUDED
30 |
31 | #include "Hash.h"
32 | #include "MarchingCubes.h"
33 | #include "Octree.h"
34 |
35 | class EdgeKey
36 | {
37 | public:
38 | size_t key1,key2;
39 | EdgeKey(void){;}
40 | EdgeKey(const size_t& n1,const size_t &n2);
41 |
42 | EdgeKey& operator = (const EdgeKey& key);
43 | operator size_t () const;
44 | operator size_t ();
45 | bool operator < (const EdgeKey& key) const;
46 |
47 | bool operator != (const EdgeKey& key) const;
48 | };
49 | #ifndef WIN32
50 | class HashEdgeKey
51 | {
52 | public:
53 | long long operator()(const EdgeKey &key) const
54 | {
55 | return (long long)key.key1 | (long long)key.key2 <<32;
56 | }
57 | };
58 | #endif
59 | template
60 | class NeighborKey : public OctNode::NeighborKey
61 | {
62 | void __GetCornerNeighbors(OctNode* node,const int& depth,const int& c,OctNode* neighbors[Cube::CORNERS]);
63 | OctNode* __FaceNeighbor(OctNode* node,const int& depth,int dir,int off);
64 | OctNode* __EdgeNeighbor(OctNode* node,const int& depth,int o,int i1,int i2);
65 | OctNode* __CornerNeighbor(OctNode* node,const int& depth,int x,int y,int z);
66 | public:
67 | void GetCornerNeighbors(OctNode* node,const int& c,OctNode* neighbors[Cube::CORNERS]);
68 | OctNode* FaceNeighbor(OctNode* node,int dir,int off);
69 | OctNode* EdgeNeighbor(OctNode* node,int o,int i1,int i2);
70 | OctNode* CornerNeighbor(OctNode* node,int x,int y,int z);
71 |
72 | static void CornerIndex(const int& c,int idx[3]);
73 | static void EdgeIndex(const int& c,int idx[3]);
74 | static void FaceIndex(const int& c,int idx[3]);
75 |
76 | using OctNode::NeighborKey::depth;
77 | using OctNode::NeighborKey::neighbors;
78 | using OctNode::NeighborKey::setNeighbors;
79 | using OctNode::NeighborKey::getNeighbors;
80 | };
81 |
82 | template
83 | class IsoOctree
84 | {
85 | protected:
86 | class TriangleIndex
87 | {
88 | public:
89 | int idx[3];
90 | };
91 | class RootInfo
92 | {
93 | public:
94 | const OctNode* node;
95 | int edgeIndex;
96 | long long key;
97 | typename OctNode::NodeIndex nIdx;
98 | };
99 | template
100 | class MeshInfo
101 | {
102 | public:
103 | std::vector > vertexNormals;
104 | #ifdef WIN32
105 | stdext::hash_map > edgeNormals;
106 | #else
107 | stdext::hash_map,HashEdgeKey > edgeNormals;
108 | #endif
109 | std::vector > triangleNormals;
110 | std::vector triangles;
111 | std::vector > vertices;
112 | std::vector vertexCurvatures;
113 |
114 | template
115 | void set(const std::vector& vertices,const std::vector >& polygons,const Real& width,
116 | Point3D& translate,Real& scale,const int& noTransform);
117 | template
118 | void set2(const std::vector& vertices,const std::vector >& polygons,const Real& width,
119 | Point3D& translate,Real& scale,const int& noTransform);
120 | };
121 |
122 | template
123 | void getRoots(OctNode* node,const typename OctNode::NodeIndex& nIdx,const Real& isoValue,stdext::hash_map& roots,std::vector& vertices);
124 | int getRootIndex(OctNode* node,const typename OctNode::NodeIndex& nIdx,const int& edgeIndex,RootInfo& ri);
125 | int getRootPosition(const OctNode* node,const typename OctNode::NodeIndex& nIdx,const int& eIndex,const Real& isoValue,Point3D