Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
David Cazier
CGoGN
Commits
7cb42175
Commit
7cb42175
authored
Jul 10, 2014
by
Kenneth Vanhoey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clamping for cos_angle function
parent
52c137ae
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
164 additions
and
151 deletions
+164
-151
include/Algo/Filtering/bilateral.h
include/Algo/Filtering/bilateral.h
+16
-5
include/Algo/Geometry/normal.hpp
include/Algo/Geometry/normal.hpp
+143
-143
include/Geometry/basic.h
include/Geometry/basic.h
+5
-3
No files found.
include/Algo/Filtering/bilateral.h
View file @
7cb42175
...
...
@@ -59,13 +59,24 @@ void sigmaBilateral(typename PFP::MAP& map, const VertexAttribute<typename PFP::
sigmaS
=
2.5
f
*
(
sumAngles
/
float
(
nbEdges
)
)
;
}
/**
* \brief Function applying a bilateral filter smoothing on the mesh.
* \param map the map of the mesh
* \param positionIn the current positions container of the mesh
* \param positionOut the smoothed positions after the function call
* \param normal the normals
*/
template
<
typename
PFP
>
void
filterBilateral
(
typename
PFP
::
MAP
&
map
,
const
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
position
,
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
position2
,
const
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
normal
)
void
filterBilateral
(
typename
PFP
::
MAP
&
map
,
const
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
positionIn
,
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
positionOut
,
const
VertexAttribute
<
typename
PFP
::
VEC3
,
typename
PFP
::
MAP
>&
normal
)
{
typedef
typename
PFP
::
VEC3
VEC3
;
float
sigmaC
,
sigmaS
;
sigmaBilateral
<
PFP
>
(
map
,
position
,
normal
,
sigmaC
,
sigmaS
)
;
sigmaBilateral
<
PFP
>
(
map
,
position
In
,
normal
,
sigmaC
,
sigmaS
)
;
TraversorV
<
typename
PFP
::
MAP
>
t
(
map
)
;
for
(
Dart
d
=
t
.
begin
();
d
!=
t
.
end
();
d
=
t
.
next
())
...
...
@@ -80,7 +91,7 @@ void filterBilateral(typename PFP::MAP& map, const VertexAttribute<typename PFP:
Traversor2VE
<
typename
PFP
::
MAP
>
te
(
map
,
d
)
;
for
(
Dart
it
=
te
.
begin
();
it
!=
te
.
end
();
it
=
te
.
next
())
{
VEC3
vec
=
Algo
::
Surface
::
Geometry
::
vectorOutOfDart
<
PFP
>
(
map
,
it
,
position
)
;
VEC3
vec
=
Algo
::
Surface
::
Geometry
::
vectorOutOfDart
<
PFP
>
(
map
,
it
,
position
In
)
;
float
h
=
normal_d
*
vec
;
float
t
=
vec
.
norm
()
;
float
wcs
=
exp
(
(
-
1.0
f
*
(
t
*
t
)
/
(
2.0
f
*
sigmaC
*
sigmaC
)
)
+
(
-
1.0
f
*
(
h
*
h
)
/
(
2.0
f
*
sigmaS
*
sigmaS
)
)
)
;
...
...
@@ -88,10 +99,10 @@ void filterBilateral(typename PFP::MAP& map, const VertexAttribute<typename PFP:
normalizer
+=
wcs
;
}
position
2
[
d
]
=
position
[
d
]
+
((
sum
/
normalizer
)
*
normal_d
)
;
position
Out
[
d
]
=
position
In
[
d
]
+
((
sum
/
normalizer
)
*
normal_d
)
;
}
else
position
2
[
d
]
=
position
[
d
]
;
position
Out
[
d
]
=
position
In
[
d
]
;
}
}
...
...
include/Algo/Geometry/normal.hpp
View file @
7cb42175
...
...
@@ -45,177 +45,177 @@ namespace Geometry
template
<
typename
PFP
,
typename
V_ATT
>
typename
V_ATT
::
DATA_TYPE
triangleNormal
(
typename
PFP
::
MAP
&
map
,
Face
f
,
const
V_ATT
&
position
)
{
typename
V_ATT
::
DATA_TYPE
N
=
Geom
::
triangleNormal
(
position
[
f
.
dart
],
position
[
map
.
phi1
(
f
)],
position
[
map
.
phi_1
(
f
)]
)
;
N
.
normalize
()
;
return
N
;
typename
V_ATT
::
DATA_TYPE
N
=
Geom
::
triangleNormal
(
position
[
f
.
dart
],
position
[
map
.
phi1
(
f
)],
position
[
map
.
phi_1
(
f
)]
)
;
N
.
normalize
()
;
return
N
;
}
template
<
typename
PFP
,
typename
V_ATT
>
typename
V_ATT
::
DATA_TYPE
newellNormal
(
typename
PFP
::
MAP
&
map
,
Face
f
,
const
V_ATT
&
position
)
{
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
);
foreach_incident2
<
VERTEX
>
(
map
,
f
,
[
&
]
(
Vertex
v
)
{
const
VEC3
&
P
=
position
[
v
];
const
VEC3
&
Q
=
position
[
map
.
phi1
(
v
)];
N
[
0
]
+=
(
P
[
1
]
-
Q
[
1
])
*
(
P
[
2
]
+
Q
[
2
]);
N
[
1
]
+=
(
P
[
2
]
-
Q
[
2
])
*
(
P
[
0
]
+
Q
[
0
]);
N
[
2
]
+=
(
P
[
0
]
-
Q
[
0
])
*
(
P
[
1
]
+
Q
[
1
]);
});
N
.
normalize
();
return
N
;
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
);
foreach_incident2
<
VERTEX
>
(
map
,
f
,
[
&
]
(
Vertex
v
)
{
const
VEC3
&
P
=
position
[
v
];
const
VEC3
&
Q
=
position
[
map
.
phi1
(
v
)];
N
[
0
]
+=
(
P
[
1
]
-
Q
[
1
])
*
(
P
[
2
]
+
Q
[
2
]);
N
[
1
]
+=
(
P
[
2
]
-
Q
[
2
])
*
(
P
[
0
]
+
Q
[
0
]);
N
[
2
]
+=
(
P
[
0
]
-
Q
[
0
])
*
(
P
[
1
]
+
Q
[
1
]);
});
N
.
normalize
();
return
N
;
}
template
<
typename
PFP
,
typename
V_ATT
>
typename
V_ATT
::
DATA_TYPE
faceNormal
(
typename
PFP
::
MAP
&
map
,
Face
f
,
const
V_ATT
&
position
)
{
if
(
map
.
faceDegree
(
f
)
==
3
)
return
triangleNormal
<
PFP
>
(
map
,
f
,
position
)
;
else
return
newellNormal
<
PFP
>
(
map
,
f
,
position
)
;
if
(
map
.
faceDegree
(
f
)
==
3
)
return
triangleNormal
<
PFP
>
(
map
,
f
,
position
)
;
else
return
newellNormal
<
PFP
>
(
map
,
f
,
position
)
;
}
template
<
typename
PFP
,
typename
V_ATT
>
typename
V_ATT
::
DATA_TYPE
vertexNormal
(
typename
PFP
::
MAP
&
map
,
Vertex
v
,
const
V_ATT
&
position
)
{
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
)
;
foreach_incident2
<
FACE
>
(
map
,
v
,
[
&
]
(
Face
f
)
{
VEC3
n
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
if
(
!
n
.
hasNan
())
{
VEC3
v1
=
vectorOutOfDart
<
PFP
>
(
map
,
f
.
dart
,
position
)
;
VEC3
v2
=
vectorOutOfDart
<
PFP
>
(
map
,
map
.
phi_1
(
f
),
position
)
;
n
*=
convexFaceArea
<
PFP
>
(
map
,
f
,
position
)
/
(
v1
.
norm2
()
*
v2
.
norm2
())
;
N
+=
n
;
}
});
N
.
normalize
()
;
return
N
;
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
)
;
foreach_incident2
<
FACE
>
(
map
,
v
,
[
&
]
(
Face
f
)
{
VEC3
n
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
if
(
!
n
.
hasNan
())
{
VEC3
v1
=
vectorOutOfDart
<
PFP
>
(
map
,
f
.
dart
,
position
)
;
VEC3
v2
=
vectorOutOfDart
<
PFP
>
(
map
,
map
.
phi_1
(
f
),
position
)
;
n
*=
convexFaceArea
<
PFP
>
(
map
,
f
,
position
)
/
(
v1
.
norm2
()
*
v2
.
norm2
())
;
N
+=
n
;
}
});
N
.
normalize
()
;
return
N
;
}
template
<
typename
PFP
,
typename
V_ATT
>
typename
V_ATT
::
DATA_TYPE
vertexBorderNormal
(
typename
PFP
::
MAP
&
map
,
Vertex
v
,
const
V_ATT
&
position
)
{
assert
(
map
.
dimension
()
==
3
);
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
)
;
std
::
vector
<
Dart
>
faces
;
faces
.
reserve
(
16
);
map
.
foreach_dart_of_vertex
(
v
,
[
&
]
(
Dart
d
)
{
faces
.
push_back
(
d
);
});
CellMarker
<
typename
PFP
::
MAP
,
FACE
>
f
(
map
);
for
(
std
::
vector
<
Dart
>::
iterator
it
=
faces
.
begin
()
;
it
!=
faces
.
end
()
;
++
it
)
{
if
(
!
f
.
isMarked
(
*
it
)
&&
map
.
isBoundaryIncidentFace
(
*
it
))
{
f
.
mark
(
*
it
);
VEC3
n
=
faceNormal
<
PFP
>
(
map
,
*
it
,
position
);
if
(
!
n
.
hasNan
())
{
VEC3
v1
=
vectorOutOfDart
<
PFP
>
(
map
,
*
it
,
position
);
VEC3
v2
=
vectorOutOfDart
<
PFP
>
(
map
,
map
.
phi_1
(
*
it
),
position
);
n
*=
convexFaceArea
<
PFP
>
(
map
,
*
it
,
position
)
/
(
v1
.
norm2
()
*
v2
.
norm2
());
N
+=
n
;
}
}
}
N
.
normalize
()
;
return
N
;
assert
(
map
.
dimension
()
==
3
);
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
VEC3
N
(
0
)
;
std
::
vector
<
Dart
>
faces
;
faces
.
reserve
(
16
);
map
.
foreach_dart_of_vertex
(
v
,
[
&
]
(
Dart
d
)
{
faces
.
push_back
(
d
);
});
CellMarker
<
typename
PFP
::
MAP
,
FACE
>
f
(
map
);
for
(
std
::
vector
<
Dart
>::
iterator
it
=
faces
.
begin
()
;
it
!=
faces
.
end
()
;
++
it
)
{
if
(
!
f
.
isMarked
(
*
it
)
&&
map
.
isBoundaryIncidentFace
(
*
it
))
{
f
.
mark
(
*
it
);
VEC3
n
=
faceNormal
<
PFP
>
(
map
,
*
it
,
position
);
if
(
!
n
.
hasNan
())
{
VEC3
v1
=
vectorOutOfDart
<
PFP
>
(
map
,
*
it
,
position
);
VEC3
v2
=
vectorOutOfDart
<
PFP
>
(
map
,
map
.
phi_1
(
*
it
),
position
);
n
*=
convexFaceArea
<
PFP
>
(
map
,
*
it
,
position
)
/
(
v1
.
norm2
()
*
v2
.
norm2
());
N
+=
n
;
}
}
}
N
.
normalize
()
;
return
N
;
}
template
<
typename
PFP
,
typename
V_ATT
,
typename
F_ATT
>
void
computeNormalFaces
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
F_ATT
&
face_normal
,
unsigned
int
thread
)
{
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeNormalFaces
<
PFP
,
V_ATT
,
F_ATT
>
(
map
,
position
,
face_normal
);
return
;
}
foreach_cell
<
FACE
>
(
map
,
[
&
]
(
Face
f
)
{
face_normal
[
f
]
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
},
AUTO
,
thread
);
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeNormalFaces
<
PFP
,
V_ATT
,
F_ATT
>
(
map
,
position
,
face_normal
);
return
;
}
foreach_cell
<
FACE
>
(
map
,
[
&
]
(
Face
f
)
{
face_normal
[
f
]
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
},
AUTO
,
thread
);
}
template
<
typename
PFP
,
typename
V_ATT
>
void
computeNormalVertices
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
V_ATT
&
normal
,
unsigned
int
thread
)
{
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeNormalVertices
<
PFP
,
V_ATT
>
(
map
,
position
,
normal
);
return
;
}
foreach_cell
<
VERTEX
>
(
map
,
[
&
]
(
Vertex
v
)
{
normal
[
v
]
=
vertexNormal
<
PFP
>
(
map
,
v
,
position
)
;
},
FORCE_CELL_MARKING
,
thread
);
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeNormalVertices
<
PFP
,
V_ATT
>
(
map
,
position
,
normal
);
return
;
}
foreach_cell
<
VERTEX
>
(
map
,
[
&
]
(
Vertex
v
)
{
normal
[
v
]
=
vertexNormal
<
PFP
>
(
map
,
v
,
position
)
;
},
FORCE_CELL_MARKING
,
thread
);
}
template
<
typename
PFP
,
typename
V_ATT
>
typename
PFP
::
REAL
computeAngleBetweenNormalsOnEdge
(
typename
PFP
::
MAP
&
map
,
Edge
e
,
const
V_ATT
&
position
)
{
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
if
(
map
.
isBoundaryEdge
(
e
))
return
0
;
Vertex
v1
(
e
.
dart
);
Vertex
v2
=
map
.
phi2
(
e
)
;
const
VEC3
n1
=
faceNormal
<
PFP
>
(
map
,
Face
(
v1
),
position
)
;
const
VEC3
n2
=
faceNormal
<
PFP
>
(
map
,
Face
(
v2
),
position
)
;
VEC3
edge
=
position
[
v2
]
-
position
[
v1
]
;
edge
.
normalize
()
;
typename
PFP
::
REAL
s
=
edge
*
(
n1
^
n2
)
;
typename
PFP
::
REAL
c
=
n1
*
n2
;
typename
PFP
::
REAL
a
(
0
)
;
// the following trick is useful for avoiding NaNs (due to floating point errors)
if
(
c
>
0.5
)
a
=
asin
(
s
)
;
else
{
if
(
c
<
-
1
)
c
=
-
1
;
if
(
s
>=
0
)
a
=
acos
(
c
)
;
else
a
=
-
acos
(
c
)
;
}
// if (isnan(a))
if
(
a
!=
a
)
std
::
cerr
<<
"Warning : computeAngleBetweenNormalsOnEdge returns NaN on edge "
<<
v1
<<
"-"
<<
v2
<<
std
::
endl
;
return
a
;
typedef
typename
V_ATT
::
DATA_TYPE
VEC3
;
if
(
map
.
isBoundaryEdge
(
e
))
return
0
;
Vertex
v1
(
e
.
dart
);
Vertex
v2
=
map
.
phi2
(
e
)
;
const
VEC3
n1
=
faceNormal
<
PFP
>
(
map
,
Face
(
v1
),
position
)
;
const
VEC3
n2
=
faceNormal
<
PFP
>
(
map
,
Face
(
v2
),
position
)
;
VEC3
edge
=
position
[
v2
]
-
position
[
v1
]
;
edge
.
normalize
()
;
typename
PFP
::
REAL
s
=
edge
*
(
n1
^
n2
)
;
typename
PFP
::
REAL
c
=
n1
*
n2
;
typename
PFP
::
REAL
a
(
0
)
;
// the following trick is useful for avoiding NaNs (due to floating point errors)
if
(
c
>
0.5
)
a
=
asin
(
s
)
;
else
{
if
(
c
<
-
1
)
c
=
-
1
;
if
(
s
>=
0
)
a
=
acos
(
c
)
;
else
a
=
-
acos
(
c
)
;
}
// if (isnan(a))
if
(
a
!=
a
)
std
::
cerr
<<
"Warning : computeAngleBetweenNormalsOnEdge returns NaN on edge "
<<
v1
<<
"-"
<<
v2
<<
std
::
endl
;
return
a
;
}
template
<
typename
PFP
,
typename
V_ATT
,
typename
E_ATT
>
void
computeAnglesBetweenNormalsOnEdges
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
E_ATT
&
angles
,
unsigned
int
thread
)
{
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeAnglesBetweenNormalsOnEdges
<
PFP
,
V_ATT
,
E_ATT
>
(
map
,
position
,
angles
);
return
;
}
foreach_cell
<
EDGE
>
(
map
,
[
&
]
(
Edge
e
)
{
angles
[
e
]
=
computeAngleBetweenNormalsOnEdge
<
PFP
>
(
map
,
e
,
position
)
;
},
AUTO
,
thread
);
if
((
CGoGN
::
Parallel
::
NumberOfThreads
>
1
)
&&
(
thread
==
0
))
{
Parallel
::
computeAnglesBetweenNormalsOnEdges
<
PFP
,
V_ATT
,
E_ATT
>
(
map
,
position
,
angles
);
return
;
}
foreach_cell
<
EDGE
>
(
map
,
[
&
]
(
Edge
e
)
{
angles
[
e
]
=
computeAngleBetweenNormalsOnEdge
<
PFP
>
(
map
,
e
,
position
)
;
},
AUTO
,
thread
);
}
...
...
@@ -225,28 +225,28 @@ namespace Parallel
template
<
typename
PFP
,
typename
V_ATT
>
void
computeNormalVertices
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
V_ATT
&
normal
)
{
CGoGN
::
Parallel
::
foreach_cell
<
VERTEX
>
(
map
,
[
&
]
(
Vertex
v
,
unsigned
int
/*thr*/
)
{
normal
[
v
]
=
vertexNormal
<
PFP
>
(
map
,
v
,
position
)
;
},
FORCE_CELL_MARKING
);
CGoGN
::
Parallel
::
foreach_cell
<
VERTEX
>
(
map
,
[
&
]
(
Vertex
v
,
unsigned
int
/*thr*/
)
{
normal
[
v
]
=
vertexNormal
<
PFP
>
(
map
,
v
,
position
)
;
},
FORCE_CELL_MARKING
);
}
template
<
typename
PFP
,
typename
V_ATT
,
typename
F_ATT
>
void
computeNormalFaces
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
F_ATT
&
normal
)
{
CGoGN
::
Parallel
::
foreach_cell
<
FACE
>
(
map
,
[
&
]
(
Face
f
,
unsigned
int
/*thr*/
)
{
normal
[
f
]
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
});
CGoGN
::
Parallel
::
foreach_cell
<
FACE
>
(
map
,
[
&
]
(
Face
f
,
unsigned
int
/*thr*/
)
{
normal
[
f
]
=
faceNormal
<
PFP
>
(
map
,
f
,
position
)
;
});
}
template
<
typename
PFP
,
typename
V_ATT
,
typename
E_ATT
>
void
computeAnglesBetweenNormalsOnEdges
(
typename
PFP
::
MAP
&
map
,
const
V_ATT
&
position
,
E_ATT
&
angles
)
{
CGoGN
::
Parallel
::
foreach_cell
<
EDGE
>
(
map
,[
&
](
Edge
e
,
unsigned
int
/*thr*/
)
{
angles
[
e
]
=
computeAngleBetweenNormalsOnEdge
<
PFP
>
(
map
,
e
,
position
)
;
});
CGoGN
::
Parallel
::
foreach_cell
<
EDGE
>
(
map
,[
&
](
Edge
e
,
unsigned
int
/*thr*/
)
{
angles
[
e
]
=
computeAngleBetweenNormalsOnEdge
<
PFP
>
(
map
,
e
,
position
)
;
});
}
}
// namespace Parallel
...
...
include/Geometry/basic.h
View file @
7cb42175
...
...
@@ -76,9 +76,11 @@ Vector<DIM,T> isobarycenter(const Vector<DIM,T>& v1, const Vector<DIM,T>& v2, co
template
<
typename
VEC
>
typename
VEC
::
DATA_TYPE
cos_angle
(
const
VEC
&
a
,
const
VEC
&
b
)
{
typename
VEC
::
DATA_TYPE
na2
=
a
.
norm2
()
;
typename
VEC
::
DATA_TYPE
nb2
=
b
.
norm2
()
;
return
(
a
*
b
)
/
sqrt
(
na2
*
nb2
)
;
typename
VEC
::
DATA_TYPE
na2
=
a
.
norm2
()
;
typename
VEC
::
DATA_TYPE
nb2
=
b
.
norm2
()
;
typename
VEC
::
DATA_TYPE
res
=
(
a
*
b
)
/
sqrt
(
na2
*
nb2
)
;
return
res
>
1.0
?
1.0
:
(
res
<
-
1.0
?
-
1.0
:
res
)
;
}
// angle formed by 2 vectors
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment