Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gmsh
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Larry Price
gmsh
Commits
5db80a8d
Commit
5db80a8d
authored
13 years ago
by
Emilie Sauvage
Browse files
Options
Downloads
Patches
Plain Diff
Implemented a new method of estimating surface curvature
parent
643e9971
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Geo/Curvature.cpp
+395
-1
395 additions, 1 deletion
Geo/Curvature.cpp
Geo/Curvature.h
+89
-2
89 additions, 2 deletions
Geo/Curvature.h
with
484 additions
and
3 deletions
Geo/Curvature.cpp
+
395
−
1
View file @
5db80a8d
...
@@ -10,6 +10,10 @@
...
@@ -10,6 +10,10 @@
#include
<fstream>
#include
<fstream>
#include
<cmath>
#include
<cmath>
#define NEXT(i) ((i)<2 ? (i)+1 : (i)-2)
#define PREV(i) ((i)>0 ? (i)-1 : (i)+2)
//std::cout << "NEXT(1) = " << NEXT(1) << std::endl;
//========================================================================================================
//========================================================================================================
//CONSTRUCTOR
//CONSTRUCTOR
...
@@ -119,6 +123,8 @@ void Curvature::initializeMap()
...
@@ -119,6 +123,8 @@ void Curvature::initializeMap()
//========================================================================================================
//========================================================================================================
//COMPUTE THE NORMAL AT THE VERTEX AND THE AREA AROUND
void
Curvature
::
computeVertexNormals
()
void
Curvature
::
computeVertexNormals
()
{
{
SVector3
vector_AB
;
SVector3
vector_AB
;
...
@@ -278,7 +284,7 @@ void Curvature::curvatureTensor()
...
@@ -278,7 +284,7 @@ void Curvature::curvatureTensor()
//========================================================================================================
//========================================================================================================
void
Curvature
::
computeCurvature
()
void
Curvature
::
computeCurvature
_Simple
()
{
{
SVector3
vector_E
;
SVector3
vector_E
;
SVector3
vector_A
;
SVector3
vector_A
;
...
@@ -355,6 +361,394 @@ void Curvature::computeCurvature()
...
@@ -355,6 +361,394 @@ void Curvature::computeCurvature()
}
}
}
}
//========================================================================================================
// Compute per-vertex point areas
void
Curvature
::
computePointareas
()
{
// if (_pointareas.size() == _VertexToInt.size())
// return;
// need_faces();
std
::
cout
<<
"Computing point areas... "
<<
std
::
endl
;
// std::cout << "The mesh has " << _VertexToInt.size() << " nodes" << std::endl;
SVector3
e
[
3
];
SVector3
l2
;
SVector3
ew
;
_pointareas
.
resize
(
_VertexToInt
.
size
());
_cornerareas
.
resize
(
_ElementToInt
.
size
());
for
(
int
i
=
0
;
i
<
_ptFinalEntityList
.
size
();
++
i
)
{
GEntity
*
entity
=
_ptFinalEntityList
[
i
];
//entity is a pointer to one surface of the group "FinalEntityList"
for
(
int
iElem
=
0
;
iElem
<
entity
->
getNumMeshElements
();
iElem
++
)
//Loop over the element all the element of the "myTag"-surface
{
MElement
*
E
=
entity
->
getMeshElement
(
iElem
);
//Pointer to one element
// The NEW tag of the corresponding element
const
int
EIdx
=
_ElementToInt
[
E
->
getNum
()];
MVertex
*
A
=
E
->
getVertex
(
0
);
//Pointers to vertices of triangle
MVertex
*
B
=
E
->
getVertex
(
1
);
MVertex
*
C
=
E
->
getVertex
(
2
);
//Edges
e
[
0
]
=
SVector3
(
C
->
x
()
-
B
->
x
(),
C
->
y
()
-
B
->
y
(),
C
->
z
()
-
B
->
z
());
//vector side of a triangilar element
e
[
1
]
=
SVector3
(
A
->
x
()
-
C
->
x
(),
A
->
y
()
-
C
->
y
(),
A
->
z
()
-
C
->
z
());
e
[
2
]
=
SVector3
(
B
->
x
()
-
A
->
x
(),
B
->
y
()
-
A
->
y
(),
B
->
z
()
-
A
->
z
());
// Compute corner weights
//SVector3 len = crossprod(e[0], e[1]);
//len = norm
//len2 = normSq
double
area
=
0.5
*
norm
(
crossprod
(
e
[
0
],
e
[
1
]));
//area of a triangle
l2
=
SVector3
(
normSq
(
e
[
0
]),
normSq
(
e
[
1
]),
normSq
(
e
[
2
])
);
ew
=
SVector3
(
l2
[
0
]
*
(
l2
[
1
]
+
l2
[
2
]
-
l2
[
0
]),
l2
[
1
]
*
(
l2
[
2
]
+
l2
[
0
]
-
l2
[
1
]),
l2
[
2
]
*
(
l2
[
0
]
+
l2
[
1
]
-
l2
[
2
])
);
if
(
ew
[
0
]
<=
0.0
)
{
_cornerareas
[
EIdx
][
1
]
=
-
0.25
*
l2
[
2
]
*
area
/
dot
(
e
[
0
],
e
[
2
]);
_cornerareas
[
EIdx
][
2
]
=
-
0.25
*
l2
[
1
]
*
area
/
dot
(
e
[
0
],
e
[
1
]);
_cornerareas
[
EIdx
][
0
]
=
area
-
_cornerareas
[
EIdx
][
1
]
-
_cornerareas
[
EIdx
][
2
];
}
else
if
(
ew
[
1
]
<=
0.0
)
{
_cornerareas
[
EIdx
][
2
]
=
-
0.25
*
l2
[
0
]
*
area
/
dot
(
e
[
1
],
e
[
0
]);
_cornerareas
[
EIdx
][
0
]
=
-
0.25
*
l2
[
2
]
*
area
/
dot
(
e
[
1
],
e
[
2
]);
_cornerareas
[
EIdx
][
1
]
=
area
-
_cornerareas
[
EIdx
][
2
]
-
_cornerareas
[
EIdx
][
0
];
}
else
if
(
ew
[
2
]
<=
0.0
)
{
_cornerareas
[
EIdx
][
0
]
=
-
0.25
*
l2
[
1
]
*
area
/
dot
(
e
[
2
],
e
[
1
]);
_cornerareas
[
EIdx
][
1
]
=
-
0.25
*
l2
[
0
]
*
area
/
dot
(
e
[
2
],
e
[
0
]);
_cornerareas
[
EIdx
][
2
]
=
area
-
_cornerareas
[
EIdx
][
0
]
-
_cornerareas
[
EIdx
][
1
];
}
else
{
float
ewscale
=
0.5
*
area
/
(
ew
[
0
]
+
ew
[
1
]
+
ew
[
2
]);
for
(
int
j
=
0
;
j
<
3
;
j
++
)
_cornerareas
[
EIdx
][
j
]
=
ewscale
*
(
ew
[(
j
+
1
)
%
3
]
+
ew
[(
j
+
2
)
%
3
]);
}
const
int
V0
=
_VertexToInt
[
A
->
getNum
()];
const
int
V1
=
_VertexToInt
[
B
->
getNum
()];
const
int
V2
=
_VertexToInt
[
C
->
getNum
()];
_pointareas
[
V0
]
+=
_cornerareas
[
EIdx
][
0
];
//_pointareas[faces[i][0]] += _cornerareas[i][0];
_pointareas
[
V1
]
+=
_cornerareas
[
EIdx
][
1
];
_pointareas
[
V2
]
+=
_cornerareas
[
EIdx
][
2
];
}
//End of loop over iElem
std
::
cout
<<
"Done computing pointareas"
<<
std
::
endl
;
// std::cout << "_pointareas.size = " << _pointareas.size() << std::endl;
// std::cout << "_cornerareas.size = " << _cornerareas.size() << std::endl;
}
//End of loop over _ptFinalEntityList
}
//End of the method "computePointareas"
//========================================================================================================
//Rotate a coordinate system to be perpendicular to the given normal
void
Curvature
::
rot_coord_sys
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
const
SVector3
&
new_norm
,
SVector3
&
new_u
,
SVector3
&
new_v
)
{
new_u
=
old_u
;
new_v
=
old_v
;
SVector3
old_norm
=
crossprod
(
old_u
,
old_v
);
double
ndot
=
dot
(
old_norm
,
new_norm
);
// if (unlikely(ndot <= -1.0f))
if
(
ndot
<=
-
1.0
f
)
{
new_u
=
-
1.0
*
new_u
;
new_v
=
-
1.0
*
new_v
;
return
;
}
//end of if-condtion
SVector3
perp_old
=
new_norm
-
ndot
*
old_norm
;
SVector3
dperp
=
1.0
f
/
(
1
+
ndot
)
*
(
old_norm
+
new_norm
);
new_u
-=
dperp
*
dot
(
new_u
,
perp_old
);
new_v
-=
dperp
*
dot
(
new_v
,
perp_old
);
}
//========================================================================================================
//Project a curvature tensor from the basis spanned by old_u and old_v
//(which are assumed to be unit-length and perpendicular) to the new_u
//and new_v basis
void
Curvature
::
proj_curv
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
double
old_ku
,
double
old_kuv
,
double
old_kv
,
const
SVector3
&
new_u
,
const
SVector3
&
new_v
,
double
&
new_ku
,
double
&
new_kuv
,
double
&
new_kv
)
{
SVector3
r_new_u
;
SVector3
r_new_v
;
rot_coord_sys
(
new_u
,
new_v
,
crossprod
(
old_u
,
old_v
),
r_new_u
,
r_new_v
);
double
u1
=
dot
(
r_new_u
,
old_u
);
double
v1
=
dot
(
r_new_u
,
old_v
);
double
u2
=
dot
(
r_new_v
,
old_u
);
double
v2
=
dot
(
r_new_v
,
old_v
);
new_ku
=
old_ku
*
u1
*
u1
+
old_kuv
*
(
2.0
f
*
u1
*
v1
)
+
old_kv
*
v1
*
v1
;
new_kuv
=
old_ku
*
u1
*
u2
+
old_kuv
*
(
u1
*
v2
*
u2
*
v1
)
+
old_kv
*
v1
*
v2
;
new_kv
=
old_ku
*
u2
*
u2
+
old_kuv
*
(
2.0
f
*
u2
*
v2
)
+
old_kv
*
v2
*
v2
;
}
//========================================================================================================
//Given a curvature tensor, find principal directions and curvatures
//Makes sure that pdir1 and pdir2 are perpendicular to normal
void
Curvature
::
diagonalize_curv
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
double
ku
,
double
kuv
,
double
kv
,
const
SVector3
&
new_norm
,
SVector3
&
pdir1
,
SVector3
&
pdir2
,
double
&
k1
,
double
&
k2
)
{
SVector3
r_old_u
;
SVector3
r_old_v
;
double
c
=
1.0
;
double
s
=
0.0
;
double
tt
=
0.0
;
rot_coord_sys
(
old_u
,
old_v
,
new_norm
,
r_old_u
,
r_old_v
);
// if(unlikely(kuv !=0.0f))
if
(
kuv
!=
0.0
)
{
//Jacobi rotation to diagonalize
double
h
=
0.5
*
(
kv
-
ku
)
/
kuv
;
tt
=
(
h
<
0.0
)
?
1.0
/
(
h
-
std
::
sqrt
(
1.0
+
h
*
h
))
:
1.0
/
(
h
+
std
::
sqrt
(
1.0
+
h
*
h
));
c
=
1.0
/
std
::
sqrt
(
1.0
+
tt
*
tt
);
s
=
tt
*
c
;
}
k1
=
ku
-
tt
*
kuv
;
k2
=
kv
+
tt
*
kuv
;
if
(
std
::
abs
(
k1
)
>=
std
::
abs
(
k2
))
{
pdir1
=
c
*
r_old_u
-
s
*
r_old_v
;
}
else
{
std
::
swap
(
k1
,
k2
);
pdir1
=
s
*
r_old_u
+
c
*
r_old_v
;
}
pdir2
=
crossprod
(
new_norm
,
pdir1
);
}
//========================================================================================================
void
Curvature
::
computeCurvature_Rusinkiewicz
()
{
initializeMap
();
computeVertexNormals
();
computePointareas
();
SVector3
e
[
3
];
STensor3
w
;
SVector3
t
;
SVector3
n
;
SVector3
b
;
SVector3
m
;
SVector3
dn
;
int
vj
;
double
u
;
double
v
;
double
dnu
;
double
dnv
;
double
c1
;
double
c2
;
double
c12
;
double
wt
;
_pdir1
.
resize
(
_VertexToInt
.
size
());
_pdir2
.
resize
(
_VertexToInt
.
size
());
_curv1
.
resize
(
_VertexToInt
.
size
());
_curv2
.
resize
(
_VertexToInt
.
size
());
_curv12
.
resize
(
_VertexToInt
.
size
());
std
::
cout
<<
"Computing Curvature.."
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
_ptFinalEntityList
.
size
();
++
i
)
{
GEntity
*
entity
=
_ptFinalEntityList
[
i
];
//entity is a pointer to one surface of the group "FinalEntityList"
for
(
int
iElem
=
0
;
iElem
<
entity
->
getNumMeshElements
();
iElem
++
)
//Loop over the element all the element of the "myTag"-surface
{
MElement
*
E
=
entity
->
getMeshElement
(
iElem
);
//Pointer to one element
MVertex
*
A
=
E
->
getVertex
(
0
);
//Pointers to vertices of triangle
MVertex
*
B
=
E
->
getVertex
(
1
);
MVertex
*
C
=
E
->
getVertex
(
2
);
const
int
V0
=
_VertexToInt
[
A
->
getNum
()];
//Tag of the 1st vertex of the triangle
const
int
V1
=
_VertexToInt
[
B
->
getNum
()];
const
int
V2
=
_VertexToInt
[
C
->
getNum
()];
///Set up an initial coordinate system per vertex:
_pdir1
[
V0
]
=
SVector3
(
B
->
x
()
-
A
->
x
(),
B
->
y
()
-
A
->
y
(),
B
->
z
()
-
A
->
z
());
_pdir1
[
V1
]
=
SVector3
(
C
->
x
()
-
B
->
x
(),
C
->
y
()
-
B
->
y
(),
C
->
z
()
-
B
->
z
());
_pdir1
[
V2
]
=
SVector3
(
A
->
x
()
-
C
->
x
(),
A
->
y
()
-
C
->
y
(),
A
->
z
()
-
C
->
z
());
}
}
for
(
int
ivertex
=
0
;
ivertex
<
_VertexToInt
.
size
();
++
ivertex
)
{
_pdir1
[
ivertex
]
=
crossprod
(
_pdir1
[
ivertex
],
_VertexNormal
[
ivertex
]);
_pdir1
[
ivertex
].
normalize
();
_pdir2
[
ivertex
]
=
crossprod
(
_VertexNormal
[
ivertex
],
_pdir1
[
ivertex
]);
}
// Compute curvature per face:
for
(
int
i
=
0
;
i
<
_ptFinalEntityList
.
size
();
++
i
)
{
GEntity
*
entity
=
_ptFinalEntityList
[
i
];
//entity is a pointer to one surface of the group "FinalEntityList"
for
(
int
iElem
=
0
;
iElem
<
entity
->
getNumMeshElements
();
iElem
++
)
//Loop over the element all the element of the "myTag"-surface
{
MElement
*
E
=
entity
->
getMeshElement
(
iElem
);
//Pointer to one element
// The NEW tag of the corresponding element
const
int
EIdx
=
_ElementToInt
[
E
->
getNum
()];
MVertex
*
A
=
E
->
getVertex
(
0
);
//Pointers to vertices of triangle
MVertex
*
B
=
E
->
getVertex
(
1
);
MVertex
*
C
=
E
->
getVertex
(
2
);
e
[
0
]
=
SVector3
(
C
->
x
()
-
B
->
x
(),
C
->
y
()
-
B
->
y
(),
C
->
z
()
-
B
->
z
());
e
[
1
]
=
SVector3
(
A
->
x
()
-
C
->
x
(),
A
->
y
()
-
C
->
y
(),
A
->
z
()
-
C
->
z
());
e
[
2
]
=
SVector3
(
B
->
x
()
-
A
->
x
(),
B
->
y
()
-
A
->
y
(),
B
->
z
()
-
A
->
z
());
//SVector3 e[3] = {SVector3(C->x() - B->x(), C->y() - B->y(), C->z() - B->z()), SVector3(A->x() - C->x(), A->y() - C->y(), A->z() - C->z()), SVector3(B->x() - A->x(), B->y() - A->y(), B->z() - A->z()) };
//N-T-B coordinate system per face
t
=
e
[
0
];
t
.
normalize
();
n
=
crossprod
(
e
[
0
],
e
[
1
]);
b
=
crossprod
(
n
,
t
);
b
.
normalize
();
//Estimate curvature based on variations of normals along edges:
//intialization:
m
=
SVector3
(
0.0
,
0.0
,
0.0
);
//maybe double m[3] = { 0.0, 0.0, 0.0 };
// w *= 0.0; //Reset w to zero
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
w
(
i
,
j
)
=
0.0
;
}
}
//filling:
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
u
=
dot
(
e
[
j
],
t
);
v
=
dot
(
e
[
j
],
b
);
w
(
0
,
0
)
+=
u
*
u
;
w
(
0
,
1
)
+=
u
*
v
;
w
(
2
,
2
)
+=
v
*
v
;
MVertex
*
U
=
E
->
getVertex
(
PREV
(
j
));
MVertex
*
V
=
E
->
getVertex
(
NEXT
(
j
));
const
int
UIdx
=
_VertexToInt
[
U
->
getNum
()];
const
int
VIdx
=
_VertexToInt
[
V
->
getNum
()];
dn
=
_VertexNormal
[
UIdx
]
-
_VertexNormal
[
VIdx
];
dnu
=
dot
(
dn
,
t
);
dnv
=
dot
(
dn
,
b
);
m
[
0
]
+=
dnu
*
u
;
m
[
1
]
+=
dnu
*
v
+
dnv
*
u
;
m
[
2
]
+=
dnv
*
v
;
}
w
(
1
,
1
)
=
w
(
0
,
0
)
+
w
(
2
,
2
);
w
(
1
,
2
)
=
w
(
0
,
1
);
//Least Square Solution
double
diag
[
3
];
if
(
!
ldltdc
(
w
,
diag
))
{
std
::
cout
<<
"ldltdc failed"
<<
std
::
endl
;
continue
;
}
ldltsl
(
w
,
diag
,
m
,
m
);
//Push it back out to the vertices
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
const
int
old_vj
=
E
->
getVertex
(
j
)
->
getNum
();
const
int
vj
=
_VertexToInt
[
old_vj
];
proj_curv
(
t
,
b
,
m
[
0
],
m
[
1
],
m
[
2
],
_pdir1
[
vj
],
_pdir2
[
vj
],
c1
,
c12
,
c2
);
wt
=
_cornerareas
[
EIdx
][
j
]
/
_pointareas
[
vj
];
// wt = 1.0;
_curv1
[
vj
]
+=
wt
*
c1
;
_curv12
[
vj
]
+=
wt
*
c12
;
_curv2
[
vj
]
+=
wt
*
c2
;
}
}
//End of loop over the element (iElem)
}
//End of loop over "_ptFinalEntityList"
//Compute principal directions and curvatures at each vertex
for
(
int
ivertex
=
0
;
ivertex
<
_VertexToInt
.
size
();
++
ivertex
)
{
diagonalize_curv
(
_pdir1
[
ivertex
],
_pdir2
[
ivertex
],
_curv1
[
ivertex
],
_curv12
[
ivertex
],
_curv2
[
ivertex
],
_VertexNormal
[
ivertex
],
_pdir1
[
ivertex
],
_pdir2
[
ivertex
],
_curv1
[
ivertex
],
_curv2
[
ivertex
]);
}
std
::
cout
<<
"Done"
<<
std
::
endl
;
_VertexCurve
.
resize
(
_VertexToInt
.
size
()
);
for
(
int
ivertex
=
0
;
ivertex
<
_VertexToInt
.
size
();
++
ivertex
)
{
_VertexCurve
[
ivertex
]
=
(
_curv1
[
ivertex
]
+
_curv2
[
ivertex
])
*
0.5
;
}
}
//End of the "computeCurvature_Rusinkiewicz" method
//========================================================================================================
//========================================================================================================
void
Curvature
::
writeToFile
(
const
std
::
string
&
filename
)
void
Curvature
::
writeToFile
(
const
std
::
string
&
filename
)
...
...
This diff is collapsed.
Click to expand it.
Geo/Curvature.h
+
89
−
2
View file @
5db80a8d
...
@@ -39,6 +39,20 @@ private:
...
@@ -39,6 +39,20 @@ private:
//Averaged vertex normals
//Averaged vertex normals
std
::
vector
<
SVector3
>
_VertexNormal
;
std
::
vector
<
SVector3
>
_VertexNormal
;
// Vector of principal dircections
std
::
vector
<
SVector3
>
_pdir1
;
std
::
vector
<
SVector3
>
_pdir2
;
// Vector of principal curvature
std
::
vector
<
double
>
_curv1
;
std
::
vector
<
double
>
_curv2
;
std
::
vector
<
double
>
_curv12
;
// Area around point
std
::
vector
<
double
>
_pointareas
;
std
::
vector
<
SVector3
>
_cornerareas
;
//Curvature Tensor per mesh vertex
//Curvature Tensor per mesh vertex
std
::
vector
<
STensor3
>
_CurveTensor
;
std
::
vector
<
STensor3
>
_CurveTensor
;
...
@@ -51,13 +65,75 @@ private:
...
@@ -51,13 +65,75 @@ private:
std
::
vector
<
double
>
_VertexCurve
;
std
::
vector
<
double
>
_VertexCurve
;
//-----------------------------------------
//-----------------------------------------
// PRIVATE METHODS
// PRIVATE METHODS
void
initializeMap
();
void
initializeMap
();
void
computeVertexNormals
();
void
computeVertexNormals
();
void
curvatureTensor
();
void
curvatureTensor
();
static
void
rot_coord_sys
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
const
SVector3
&
new_norm
,
SVector3
&
new_u
,
SVector3
&
new_v
);
void
proj_curv
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
double
old_ku
,
double
old_kuv
,
double
old_kv
,
const
SVector3
&
new_u
,
const
SVector3
&
new_v
,
double
&
new_ku
,
double
&
new_kuv
,
double
&
new_kv
);
void
diagonalize_curv
(
const
SVector3
&
old_u
,
const
SVector3
&
old_v
,
double
ku
,
double
kuv
,
double
kv
,
const
SVector3
&
new_norm
,
SVector3
&
pdir1
,
SVector3
&
pdir2
,
double
&
k1
,
double
&
k2
);
void
computePointareas
();
// Perform LDL^T decomposition of a symmetric positive definite matrix.
// Like Cholesky, but no square roots. Overwrites lower triangle of matrix.
static
inline
bool
ldltdc
(
STensor3
&
A
,
double
rdiag
[
3
])
{
double
v
[
2
];
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
for
(
int
k
=
0
;
k
<
i
;
k
++
)
v
[
k
]
=
A
(
i
,
k
)
*
rdiag
[
k
];
for
(
int
j
=
i
;
j
<
3
;
j
++
)
{
double
sum
=
A
(
i
,
j
);
for
(
int
k
=
0
;
k
<
i
;
k
++
)
sum
-=
v
[
k
]
*
A
(
j
,
k
);
if
(
i
==
j
)
{
//if (unlikely(sum <= T(0)))
if
(
sum
<=
0.0
)
return
false
;
rdiag
[
i
]
=
1.0
/
sum
;
}
else
{
A
(
j
,
i
)
=
sum
;
}
}
}
return
true
;
}
// Solve Ax=B after ldltdc
static
inline
void
ldltsl
(
STensor3
&
A
,
double
rdiag
[
3
],
double
B
[
3
],
double
x
[
3
])
{
int
i
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
double
sum
=
B
[
i
];
for
(
int
k
=
0
;
k
<
i
;
k
++
)
sum
-=
A
(
i
,
k
)
*
x
[
k
];
x
[
i
]
=
sum
*
rdiag
[
i
];
}
for
(
i
=
3
-
1
;
i
>=
0
;
i
--
)
{
double
sum
=
0
;
for
(
int
k
=
i
+
1
;
k
<
3
;
k
++
)
sum
+=
A
(
k
,
i
)
*
x
[
k
];
x
[
i
]
-=
sum
*
rdiag
[
i
];
}
}
public
:
public
:
...
@@ -71,7 +147,18 @@ public:
...
@@ -71,7 +147,18 @@ public:
~
Curvature
();
~
Curvature
();
void
retrievePhysicalSurfaces
(
const
std
::
string
&
face_tag
);
void
retrievePhysicalSurfaces
(
const
std
::
string
&
face_tag
);
void
computeCurvature
();
/// The following function implements algorithm from:
/// Implementation of an Algorithm for Approximating the Curvature Tensor
/// on a Triangular Surface Mesh in the Vish Environment
/// Edwin Matthews, Werner Benger, Marcel Ritter
void
computeCurvature_Simple
();
/// The following function implements algorithm from:
/// Estimating Curvatures and Their Derivatives on Triangle Meshes
/// Szymon Rusinkiewicz, Princeton University
/// Code taken from Rusinkiewicz' 'trimesh2' library
void
computeCurvature_Rusinkiewicz
();
void
writeToFile
(
const
std
::
string
&
filename
);
void
writeToFile
(
const
std
::
string
&
filename
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment