Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
OpenWalnut Core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
44
Issues
44
List
Boards
Labels
Service Desk
Milestones
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
beb22bc0
Commit
beb22bc0
authored
Oct 06, 2013
by
Andreas Schwarzkopf
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[FIX
#294
] Fixed errors in subdivision, documentation and style
parent
44030964
Changes
21
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
3339 additions
and
965 deletions
+3339
-965
src/modules/butterfly/ButterflyFactory.cpp
src/modules/butterfly/ButterflyFactory.cpp
+0
-232
src/modules/butterfly/ButterflyFactory.h
src/modules/butterfly/ButterflyFactory.h
+0
-66
src/modules/butterfly/WButterflyCalculator.cpp
src/modules/butterfly/WButterflyCalculator.cpp
+174
-0
src/modules/butterfly/WButterflyCalculator.h
src/modules/butterfly/WButterflyCalculator.h
+152
-0
src/modules/butterfly/WButterflyFactory.cpp
src/modules/butterfly/WButterflyFactory.cpp
+249
-0
src/modules/butterfly/WButterflyFactory.h
src/modules/butterfly/WButterflyFactory.h
+237
-0
src/modules/butterfly/WMButterfly.cpp
src/modules/butterfly/WMButterfly.cpp
+193
-51
src/modules/butterfly/WMButterfly.h
src/modules/butterfly/WMButterfly.h
+188
-27
src/modules/butterfly/WSubdivisionValidator.cpp
src/modules/butterfly/WSubdivisionValidator.cpp
+568
-0
src/modules/butterfly/WSubdivisionValidator.h
src/modules/butterfly/WSubdivisionValidator.h
+478
-0
src/modules/butterfly/structure/MidPoint.h
src/modules/butterfly/structure/MidPoint.h
+0
-52
src/modules/butterfly/structure/VertexFactory.cpp
src/modules/butterfly/structure/VertexFactory.cpp
+0
-245
src/modules/butterfly/structure/VertexFactory.h
src/modules/butterfly/structure/VertexFactory.h
+0
-69
src/modules/butterfly/structure/VertexProperty.cpp
src/modules/butterfly/structure/VertexProperty.cpp
+0
-135
src/modules/butterfly/structure/VertexProperty.h
src/modules/butterfly/structure/VertexProperty.h
+0
-72
src/modules/butterfly/structure/WNewVertex.cpp
src/modules/butterfly/structure/WNewVertex.cpp
+32
-16
src/modules/butterfly/structure/WNewVertex.h
src/modules/butterfly/structure/WNewVertex.h
+135
-0
src/modules/butterfly/structure/WVertexFactory.cpp
src/modules/butterfly/structure/WVertexFactory.cpp
+261
-0
src/modules/butterfly/structure/WVertexFactory.h
src/modules/butterfly/structure/WVertexFactory.h
+213
-0
src/modules/butterfly/structure/WVertexProperty.cpp
src/modules/butterfly/structure/WVertexProperty.cpp
+196
-0
src/modules/butterfly/structure/WVertexProperty.h
src/modules/butterfly/structure/WVertexProperty.h
+263
-0
No files found.
src/modules/butterfly/ButterflyFactory.cpp
deleted
100644 → 0
View file @
44030964
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
/*
* ButterflyFactory.cpp
*
* Created on: 30.06.2013
* Author: renegade
*/
#include "ButterflyFactory.h"
#include "core/kernel/WKernel.h"
namespace
butterfly
{
float
ButterflyFactory
::
w
=
0.0
f
,
ButterflyFactory
::
factor
[
4
][
7
]
=
{{
0.75
f
,
5.0
f
/
12.0
f
,
-
1.0
f
/
12.0
f
,
-
1.0
f
/
12.0
f
,
0.0
f
,
0.0
f
,
0.0
f
},
//NOLINT
{
0.875
f
,
3.0
f
/
8.0
f
,
-
1.0
f
/
8.0
f
,
0.0
f
,
-
1.0
f
/
8.0
f
,
0.0
f
,
0.0
f
},
//NOLINT
{
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
},
//NOLINT
{
0.5
f
-
w
,
0.0
f
,
0.125
f
+
2
*
w
,
-
0.0625
f
-
w
,
w
,
-
0.0625
f
-
w
,
0.125
f
+
2
*
w
}},
//NOLINT
ButterflyFactory
::
s1
=
9.0
f
/
16.0
f
,
ButterflyFactory
::
s2
=
-
1.0
f
/
16.0
f
;
ButterflyFactory
::
ButterflyFactory
()
{
iterations
=
0
;
maxTriangles
=
0
;
verts
=
new
VertexFactory
();
triCount
=
0
;
}
ButterflyFactory
::~
ButterflyFactory
()
{
// TODO(schwarzkopf): Auto-generated destructor stub
}
void
ButterflyFactory
::
assignSettings
(
WPropInt
m_iterations
,
WPropDouble
m_maxTriangles10n
)
{
this
->
iterations
=
m_iterations
->
get
();
this
->
maxTriangles
=
(
size_t
)
pow
(
10
,
m_maxTriangles10n
->
get
()
);
this
->
mesh
=
mesh
;
}
void
ButterflyFactory
::
examineInputMesh
()
{
triCount
=
0
;
verts
=
new
VertexFactory
(
mesh
);
boost
::
shared_ptr
<
WTriangleMesh
>
tmpMesh
(
new
WTriangleMesh
(
0
,
0
)
);
triMesh
=
tmpMesh
;
try
{
while
(
true
)
{
verts
->
registerTriangle
(
mesh
->
getTriVertId0
(
triCount
),
triCount
);
verts
->
registerTriangle
(
mesh
->
getTriVertId1
(
triCount
),
triCount
);
verts
->
registerTriangle
(
mesh
->
getTriVertId2
(
triCount
),
triCount
);
triCount
++
;
}
}
catch
(
...
)
{
}
for
(
size_t
i
=
0
;
i
<
verts
->
getVertexCount
();
i
++
)
{
osg
::
Vec3d
vec
=
mesh
->
getVertex
(
i
);
triMesh
->
addVertex
(
osg
::
Vec3
(
vec
.
x
(),
vec
.
y
(),
vec
.
z
()
)
);
}
verts
->
examineCircularityAll
();
}
boost
::
shared_ptr
<
WTriangleMesh
>
ButterflyFactory
::
getInterpolatedMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
inputMesh
)
{
this
->
mesh
=
inputMesh
;
examineInputMesh
();
for
(
size_t
iteration
=
0
;
iteration
<
iterations
&&
triCount
*
4
<=
maxTriangles
;
iteration
++
)
{
size_t
vertCount
=
verts
->
getVertexCount
();
for
(
size_t
triIdx
=
0
;
triIdx
<
triCount
;
triIdx
++
)
{
size_t
id0
=
mesh
->
getTriVertId0
(
triIdx
);
size_t
id1
=
mesh
->
getTriVertId1
(
triIdx
);
size_t
id2
=
mesh
->
getTriVertId2
(
triIdx
);
if
(
!
verts
->
neighborExists
(
id0
,
id1
)
)
{
verts
->
attachMid
(
id0
,
id1
,
vertCount
++
);
triMesh
->
addVertex
(
calcMid
(
id0
,
id1
)
);
}
if
(
!
verts
->
neighborExists
(
id0
,
id2
)
)
{
verts
->
attachMid
(
id0
,
id2
,
vertCount
++
);
triMesh
->
addVertex
(
calcMid
(
id0
,
id2
)
);
}
if
(
!
verts
->
neighborExists
(
id1
,
id2
)
)
{
verts
->
attachMid
(
id1
,
id2
,
vertCount
++
);
triMesh
->
addVertex
(
calcMid
(
id1
,
id2
)
);
}
long
mid0_1
=
verts
->
getMidID
(
id0
,
id1
),
// NOLINT
mid0_2
=
verts
->
getMidID
(
id0
,
id2
),
mid1_2
=
verts
->
getMidID
(
id1
,
id2
);
triMesh
->
addTriangle
(
id0
,
mid0_1
,
mid0_2
);
triMesh
->
addTriangle
(
id1
,
mid1_2
,
mid0_1
);
triMesh
->
addTriangle
(
id2
,
mid0_2
,
mid1_2
);
triMesh
->
addTriangle
(
mid0_1
,
mid1_2
,
mid0_2
);
}
mesh
=
triMesh
;
if
(
iteration
+
1
<
iterations
)
examineInputMesh
();
}
return
mesh
;
}
osg
::
Vec3
ButterflyFactory
::
calcMid
(
size_t
vertID1
,
size_t
vertID2
)
{
int
bound1
=
verts
->
getBoundCountClass
(
vertID1
),
bound2
=
verts
->
getBoundCountClass
(
vertID2
),
k1
=
verts
->
getNeighbourVertexCount
(
vertID1
),
k2
=
verts
->
getNeighbourVertexCount
(
vertID2
);
if
(
bound1
==
1
)
k1
+=
k1
-
2
;
if
(
bound2
==
1
)
k2
+=
k2
-
2
;
Vec3
final
=
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
);
if
(
bound1
<
2
&&
bound2
<
2
&&
bound1
>=
0
&&
bound2
>=
0
)
{
if
(
bound1
!=
1
||
bound2
!=
1
)
{
//Case 1: two vertices of valence 6
if
(
k1
==
6
&&
k2
==
6
)
{
final
=
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
getKNeighbourValueBoundary
(
vertID1
,
vertID2
,
false
,
false
),
1.0
f
);
final
=
add
(
final
,
getKNeighbourValueBoundary
(
vertID2
,
vertID1
,
true
,
false
),
1.0
f
);
}
else
if
(
k1
!=
6
||
k2
!=
6
)
{
//Case 2/3: at least one vertex of valence!=6
final
=
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
getKNeighbourValueBoundary
(
vertID1
,
vertID2
,
false
,
true
),
0.5
f
);
final
=
add
(
final
,
getKNeighbourValueBoundary
(
vertID2
,
vertID1
,
false
,
true
),
0.5
f
);
}
}
else
{
//Case 4: >=1 vertex on a bound
int
start1
=
verts
->
getNeighbourIndex
(
vertID1
,
vertID2
),
start2
=
verts
->
getNeighbourIndex
(
vertID2
,
vertID1
);
size_t
boundNeighbour
=
verts
->
getVertexProperty
(
vertID1
)
->
getNeighbourVertices
()[
k1
/
2
-
start1
];
final
=
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
mesh
->
getVertex
(
boundNeighbour
),
s2
);
boundNeighbour
=
verts
->
getVertexProperty
(
vertID2
)
->
getNeighbourVertices
()[
k2
/
2
-
start2
];
final
=
add
(
final
,
mesh
->
getVertex
(
boundNeighbour
),
s2
);
final
=
add
(
final
,
mesh
->
getVertex
(
vertID1
),
s1
);
final
=
add
(
final
,
mesh
->
getVertex
(
vertID2
),
s1
);
}
}
else
final
=
calcMean
(
vertID1
,
vertID2
);
return
final
;
}
Vec3
ButterflyFactory
::
calcMean
(
size_t
vertID1
,
size_t
vertID2
)
{
Vec3
p1
=
mesh
->
getVertex
(
vertID1
),
p2
=
mesh
->
getVertex
(
vertID2
);
return
osg
::
Vec3
(
(
p1
.
x
()
+
p2
.
x
()
)
/
2
,
(
p1
.
y
()
+
p2
.
y
()
)
/
2
,
(
p1
.
z
()
+
p2
.
z
()
)
/
2
);
}
Vec3
ButterflyFactory
::
add
(
Vec3
base
,
Vec3
sum
,
float
factor
)
{
float
baseX
=
base
.
x
(),
baseY
=
base
.
y
(),
baseZ
=
base
.
z
();
float
sumX
=
sum
.
x
(),
sumY
=
sum
.
y
(),
sumZ
=
sum
.
z
();
float
x
=
baseX
+
sumX
*
factor
,
y
=
baseY
+
sumY
*
factor
,
z
=
baseZ
+
sumZ
*
factor
;
return
Vec3
(
x
,
y
,
z
);
}
Vec3
ButterflyFactory
::
getKNeighbourValueBoundary
(
size_t
stencilCenterVertID
,
size_t
directedNeighbourVertID
,
bool
isSecondK6
,
bool
treatK6AsKn
)
{
int
start
=
verts
->
getNeighbourIndex
(
stencilCenterVertID
,
directedNeighbourVertID
);
float
k
=
verts
->
getVertexProperty
(
stencilCenterVertID
)
->
getNeighbourVertexCount
();
int
bounds
=
verts
->
getBoundCountClass
(
stencilCenterVertID
);
if
(
bounds
==
1
)
k
+=
k
-
2
;
int
k_row
=
static_cast
<
int
>
(
k
+
0.3
f
)
-
3
;
bool
hasCustomWeight
=
(
k
==
3
||
k
==
4
||
(
k
==
6
&&
!
treatK6AsKn
)
);
Vec3
final
=
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
mesh
->
getVertex
(
stencilCenterVertID
),
hasCustomWeight
?
factor
[
k_row
][
0
]
:
factor
[
0
][
0
]
);
for
(
int
i
=
0
;
i
<
k
;
i
++
)
{
float
j
=
i
-
start
;
if
(
j
<
0.0
f
)
j
=
k
+
j
;
bool
isBehindBound
=
(
bounds
==
1
&&
i
>
k
/
2
);
int
i_mirrored
=
isBehindBound
?
i
-
k
/
2
:
i
,
k_col
=
1
+
static_cast
<
int
>
(
j
+
0.3
f
);
int
neighbourID
=
verts
->
getVertexProperty
(
stencilCenterVertID
)
->
getNeighbourVertices
()[
i_mirrored
];
float
s_j
=
hasCustomWeight
?
factor
[
k_row
][
k_col
]
:
(
0.25
f
+
cos
(
2.0
f
*
M_PI
*
j
/
k
)
+
0.5
f
*
cos
(
4.0
f
*
M_PI
*
j
/
k
)
)
/
k
;
Vec3
value
=
mesh
->
getVertex
(
neighbourID
);
if
(
isBehindBound
)
{
//Case 4: >=1 vertex on a bound
value
=
add
(
mesh
->
getVertex
(
stencilCenterVertID
),
value
,
-
1.0
f
);
value
=
add
(
mesh
->
getVertex
(
stencilCenterVertID
),
value
,
1.0
f
);
}
if
(
!
isSecondK6
||
treatK6AsKn
||
(
j
!=
1
&&
j
!=
5
)
)
final
=
add
(
final
,
value
,
s_j
);
}
return
final
;
}
}
/* namespace std */
src/modules/butterfly/ButterflyFactory.h
deleted
100644 → 0
View file @
44030964
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
/*
* ButterflyFactory.h
*
* Created on: 30.06.2013
* Author: renegade
*/
#ifndef BUTTERFLYFACTORY_H_
#define BUTTERFLYFACTORY_H_
#include "core/kernel/WModule.h"
#include "structure/VertexFactory.h"
using
osg
::
Vec3
;
namespace
butterfly
{
class
ButterflyFactory
{
public:
ButterflyFactory
();
virtual
~
ButterflyFactory
();
void
assignSettings
(
WPropInt
m_iterations
,
WPropDouble
m_maxTriangles10n
);
boost
::
shared_ptr
<
WTriangleMesh
>
getInterpolatedMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
inputMmesh
);
private:
static
float
w
,
factor
[
4
][
7
],
s1
,
s2
;
void
examineInputMesh
();
osg
::
Vec3
calcMid
(
size_t
vertID1
,
size_t
vertID2
);
osg
::
Vec3
calcMean
(
size_t
vertID1
,
size_t
vertID2
);
osg
::
Vec3
add
(
Vec3
base
,
Vec3
sum
,
float
factor
);
Vec3
getKNeighbourValueBoundary
(
size_t
stencilCenterVertID
,
size_t
directedNeighbourVertID
,
bool
isSecondK6
,
bool
treatK6AsKn
);
size_t
iterations
;
size_t
maxTriangles
;
boost
::
shared_ptr
<
WTriangleMesh
>
mesh
,
triMesh
;
VertexFactory
*
verts
;
size_t
triCount
;
};
}
/* namespace butterfly */
#endif // BUTTERFLYFACTORY_H
src/modules/butterfly/WButterflyCalculator.cpp
0 → 100644
View file @
beb22bc0
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
// Additional copyright information:
// This class partially relies on the Butterfly Subdivision algorithm.
// that dates from Denis Zorin, Peter Schroeder, Wim Sweldens, Nira Dyn, David
// Levin and John A. Gregory. The original algorithm is depicted in:
// http://wwwmath.tau.ac.il/~niradyn/papers/butterfly.pdf
// http://mrl.nyu.edu/~dzorin/papers/zorin1996ism.pdf
// This work was required especially in the methods calcNewVertex and
// getInterpolatedValue.
#include <string>
#include <vector>
#include "WButterflyCalculator.h"
#include "WSubdivisionValidator.h"
#include "core/kernel/WKernel.h"
namespace
butterfly
{
float
WButterflyCalculator
::
m_w
=
0.0
f
;
float
WButterflyCalculator
::
m_weights
[
4
][
7
]
=
{{
0.75
f
,
5.0
f
/
12.0
f
,
-
1.0
f
/
12.0
f
,
-
1.0
f
/
12.0
f
,
0.0
f
,
0.0
f
,
0.0
f
},
/*Valence=3*/
//NOLINT
{
0.875
f
,
3.0
f
/
8.0
f
,
-
1.0
f
/
8.0
f
,
0.0
f
,
-
1.0
f
/
8.0
f
,
0.0
f
,
0.0
f
},
/*Valence=4*/
//NOLINT
{
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
,
0.0
f
},
//NOLINT
{
0.5
f
-
m_w
,
0.0
f
,
0.0625
f
+
m_w
,
-
0.0625
f
-
m_w
,
m_w
,
-
0.0625
f
-
m_w
,
0.0625
f
+
m_w
}};
/*Valence=6*/
//NOLINT
float
WButterflyCalculator
::
m_weightCenterAtBorder
=
9.0
f
/
16.0
f
;
float
WButterflyCalculator
::
m_weightRimAtBorder
=
-
1.0
f
/
16.0
f
;
WButterflyCalculator
::
WButterflyCalculator
()
{
m_verts
=
new
WVertexFactory
();
}
WButterflyCalculator
::~
WButterflyCalculator
()
{
// TODO(schwarzkopf): Auto-generated destructor stub
}
void
WButterflyCalculator
::
assignInputMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
inputMesh
,
WVertexFactory
*
vertexProperties
)
{
this
->
m_inputMesh
=
inputMesh
;
this
->
m_verts
=
vertexProperties
;
}
void
WButterflyCalculator
::
setButterflySettingW
(
float
butterflySettingW
)
{
m_w
=
butterflySettingW
;
m_weights
[
3
][
0
]
=
0.5
f
-
m_w
;
m_weights
[
3
][
2
]
=
0.0625
f
+
m_w
;
m_weights
[
3
][
3
]
=
-
0.0625
f
-
m_w
;
m_weights
[
3
][
4
]
=
m_w
;
m_weights
[
3
][
5
]
=
-
0.0625
f
-
m_w
;
m_weights
[
3
][
6
]
=
0.0625
f
+
m_w
;
}
osg
::
Vec3
WButterflyCalculator
::
calcNewVertex
(
size_t
vertID1
,
size_t
vertID2
)
{
int
bound1
=
m_verts
->
getProperty
(
vertID1
)
->
getBoundClass
();
int
bound2
=
m_verts
->
getProperty
(
vertID2
)
->
getBoundClass
();
int
valence1
=
m_verts
->
getProperty
(
vertID1
)
->
getValence
();
int
valence2
=
m_verts
->
getProperty
(
vertID2
)
->
getValence
();
if
(
bound1
==
1
)
valence1
+=
valence1
-
2
;
if
(
bound2
==
1
)
valence2
+=
valence2
-
2
;
Vec3
final
=
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
);
if
(
bound1
<
2
&&
bound2
<
2
&&
bound1
>=
0
&&
bound2
>=
0
)
{
if
(
bound1
!=
1
||
bound2
!=
1
)
{
//Case 1: two vertices of valence 6
if
(
valence1
==
6
&&
valence2
==
6
)
{
final
=
m_verts
->
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
getInterpolatedValue
(
vertID1
,
vertID2
,
false
),
1.0
f
);
final
=
m_verts
->
add
(
final
,
getInterpolatedValue
(
vertID2
,
vertID1
,
false
),
1.0
f
);
}
else
if
(
valence1
!=
6
||
valence2
!=
6
)
{
//Case 2/3: at least one vertex of valence!=6
final
=
m_verts
->
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
getInterpolatedValue
(
vertID1
,
vertID2
,
true
),
0.5
f
);
final
=
m_verts
->
add
(
final
,
getInterpolatedValue
(
vertID2
,
vertID1
,
true
),
0.5
f
);
}
}
else
{
//Case 4: >=1 vertex on a bound
int
start1
=
m_verts
->
getProperty
(
vertID1
)
->
getStencilNeighbourIndex
(
vertID2
);
int
start2
=
m_verts
->
getProperty
(
vertID2
)
->
getStencilNeighbourIndex
(
vertID1
);
size_t
boundNeighbour
=
m_verts
->
getProperty
(
vertID1
)
->
getStencilNeighbourID
(
valence1
/
2
-
start1
);
final
=
m_verts
->
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
m_inputMesh
->
getVertex
(
boundNeighbour
),
m_weightRimAtBorder
);
boundNeighbour
=
m_verts
->
getProperty
(
vertID2
)
->
getStencilNeighbourID
(
valence2
/
2
-
start2
);
final
=
m_verts
->
add
(
final
,
m_inputMesh
->
getVertex
(
boundNeighbour
),
m_weightRimAtBorder
);
final
=
m_verts
->
add
(
final
,
m_inputMesh
->
getVertex
(
vertID1
),
m_weightCenterAtBorder
);
final
=
m_verts
->
add
(
final
,
m_inputMesh
->
getVertex
(
vertID2
),
m_weightCenterAtBorder
);
}
}
else
final
=
calcMean
(
vertID1
,
vertID2
);
return
final
;
}
Vec3
WButterflyCalculator
::
calcMean
(
size_t
vertID1
,
size_t
vertID2
)
{
Vec3
vert1
=
m_inputMesh
->
getVertex
(
vertID1
),
vert2
=
m_inputMesh
->
getVertex
(
vertID2
);
float
coordX
=
(
vert1
.
x
()
+
vert2
.
x
()
)
/
2.0
f
,
coordY
=
(
vert1
.
y
()
+
vert2
.
y
()
)
/
2.0
f
,
coordZ
=
(
vert1
.
z
()
+
vert2
.
z
()
)
/
2.0
f
;
return
osg
::
Vec3
(
coordX
,
coordY
,
coordZ
);
}
Vec3
WButterflyCalculator
::
getInterpolatedValue
(
size_t
stencilCenterVertID
,
size_t
directedNeighbourVertID
,
bool
isIrregular
)
{
WVertexProperty
*
property
=
m_verts
->
getProperty
(
stencilCenterVertID
);
int
start
=
property
->
getStencilNeighbourIndex
(
directedNeighbourVertID
);
float
valence
=
property
->
getValence
();
int
bounds
=
property
->
getBoundClass
();
if
(
bounds
==
1
)
valence
+=
valence
-
2
;
int
weightRow
=
static_cast
<
int
>
(
valence
+
0.3
f
)
-
3
;
bool
hasCustomWeight
=
(
valence
==
3
||
valence
==
4
||
(
valence
==
6
&&
!
isIrregular
)
);
Vec3
final
=
m_verts
->
add
(
Vec3
(
0.0
f
,
0.0
f
,
0.0
f
),
m_inputMesh
->
getVertex
(
stencilCenterVertID
),
hasCustomWeight
?
m_weights
[
weightRow
][
0
]
:
m_weights
[
0
][
0
]
);
for
(
int
index
=
0
;
index
<
valence
;
index
++
)
{
float
neighbour
=
index
-
start
;
if
(
neighbour
<
0.0
f
)
neighbour
=
valence
+
neighbour
;
bool
isBehindBound
=
(
bounds
==
1
&&
index
>
valence
/
2
);
int
i_mirrored
=
isBehindBound
?
index
-
valence
/
2
:
index
,
weightCol
=
1
+
static_cast
<
int
>
(
neighbour
+
0.3
f
);
int
neighbourID
=
property
->
getStencilNeighbourID
(
i_mirrored
);
float
weight
=
hasCustomWeight
?
m_weights
[
weightRow
][
weightCol
]
:
(
0.25
f
+
cos
(
2.0
f
*
M_PI
*
neighbour
/
valence
)
+
0.5
f
*
cos
(
4.0
f
*
M_PI
*
neighbour
/
valence
)
)
/
valence
;
Vec3
value
=
m_inputMesh
->
getVertex
(
neighbourID
);
if
(
isBehindBound
)
{
//Case 4: >=1 vertex on a bound
value
=
m_verts
->
add
(
m_inputMesh
->
getVertex
(
stencilCenterVertID
),
value
,
-
1.0
f
);
value
=
m_verts
->
add
(
m_inputMesh
->
getVertex
(
stencilCenterVertID
),
value
,
1.0
f
);
}
final
=
m_verts
->
add
(
final
,
value
,
weight
);
}
return
final
;
}
}
/* namespace std */
src/modules/butterfly/WButterflyCalculator.h
0 → 100644
View file @
beb22bc0
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
// Additional copyright information:
// This class partially relies on the Butterfly Subdivision algorithm.
// that dates from Denis Zorin, Peter Schroeder, Wim Sweldens, Nira Dyn, David
// Levin and John A. Gregory. The original algorithm is depicted in:
// http://wwwmath.tau.ac.il/~niradyn/papers/butterfly.pdf
// http://mrl.nyu.edu/~dzorin/papers/zorin1996ism.pdf
// This work was required especially in the methods calcNewVertex and
// getInterpolatedValue.
#ifndef WBUTTERFLYCALCULATOR_H_
#define WBUTTERFLYCALCULATOR_H_
#include <string>
#include <vector>
#include "core/kernel/WModule.h"
#include "structure/WVertexFactory.h"
#include "WSubdivisionValidator.h"
using
osg
::
Vec3
;
namespace
butterfly
{
/**
* Class that depicts the whole Butterfly subdivision algorithm but nothing more as such.
*/
class
WButterflyCalculator
{
public:
/**
* Butterfly subdivision tool object creating instance.
*/
WButterflyCalculator
();
/**
* Destroys the Butterfly instance object and its substructures.
*/
virtual
~
WButterflyCalculator
();
/**
* Assigns the input mesh andd its analyzed data that are required for the butterfly subdivision.
* \author schwarzkopf
* \param inputMesh Triangle mesh that should be subdivided
* \param vertexProperties The analyzed data of the input triangle mesh
*/
void
assignInputMesh
(
boost
::
shared_ptr
<
WTriangleMesh
>
inputMesh
,
WVertexFactory
*
vertexProperties
);
/**
* Set the general Butterfly Subdivision setting w that affects the subdivision. See the algorithm
* documentation for the exact meaning. It's usually chosen substantially small. The original
* authors used 0.0f.
* \author schwarzkopf
* \param butterflySettingW The general butterfly subdivision parameter w.
*/
void
setButterflySettingW
(
float
butterflySettingW
);
/**
* Calculate the subdivided new vertex between two vertices using the Butterfly Subdivision.
* algorithm.
* \author schwarzkopf
* \param vertID1 First vertex to subdivide between.
* \param vertID2 Second vertex ID to subdivide between
* \return Calculated coordinates.
*/
osg
::
Vec3
calcNewVertex
(
size_t
vertID1
,
size_t
vertID2
);
private:
/**
* The general Butterfly Subdivision setting w that affects the subdivision. See the algorithm
* documentation for the exact meaning. It's usually chosen substantially small. The original
* authors used 0.0f.
*/
static
float
m_w
;
/**
* Butterfly subdivision Weights for each neighbor which always are applied for valences 3 and 4.
* Valence 6 is applied for Butterfly stencils where both valences are 6.
* The first row starts with valence 6. The first column starts with the center vertex weight.
* Then comes the Neighbor vertex connected to the other stencil center vertex.
*/
static
float
m_weights
[
4
][
7
];
/**
* Weight where both stencil centers lie on a border. This weight is for a stencil center.
*/
static
float
m_weightCenterAtBorder
;
/**
* Weight where both stencil centers lie on a border. This weight is beside the stencil
* centers.
*/
static
float
m_weightRimAtBorder
;
/**
* Calculate a subdivided mit point between two vertices using the mean calculation.
* \author schwarzkopf
* \param vertID1 First vertex to subdivide between.
* \param vertID2 Second vertex ID to subdivide between.
* \return Mean between the two vertices.
*/
osg
::
Vec3
calcMean
(
size_t
vertID1
,
size_t
vertID2
);
/**
* Calculate the coordinates of a stencil half using the Butterfly subdivision algorithm.
* \param stencilCenterVertID Vertex ID of the stencil center. Coordinates are calculated
* for that value.
* \param directedNeighbourVertID Vertex ID of the other half of the whole butterfly stencil.