Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
KennethVanhoey
CGoGN
Commits
7cb42175
Commit
7cb42175
authored
Jul 10, 2014
by
Kenneth Vanhoey
Browse files
clamping for cos_angle function
parent
52c137ae
Changes
3
Hide whitespace changes
Inline
Side-by-side
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
Supports
Markdown
0%
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!
Cancel
Please
register
or
sign in
to comment