OpenWalnut  1.5.0dev
WButterflyFactory.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include "WButterflyFactory.h"
30 #include "WSubdivisionValidator.h"
31 #include "core/kernel/WKernel.h"
32 
33 
34 namespace butterfly
35 {
37  {
38  m_iterations = 0;
39  m_maxTriangles = 0;
40  m_verts = new WVertexFactory();
41  m_triCount = 0;
42  m_vertCount = 0;
44  m_cpuThreadCount = 8;
46  }
47 
49  {
50  // TODO(schwarzkopf): Auto-generated destructor stub
51  }
52  void WButterflyFactory::setButterflySettingW( float butterflySettingW )
53  {
54  m_butterflyCalculator->setButterflySettingW( butterflySettingW );
55  }
56  void WButterflyFactory::setIterationsSettings( float m_iterations, float m_maxTriangles10n )
57  {
58  this->m_iterations = m_iterations;
59  this->m_maxTriangles = ( size_t ) pow( 10, m_maxTriangles10n );
60  }
61  void WButterflyFactory::setCpuThreadCount( size_t cpuThreadCount )
62  {
63  m_cpuThreadCount = cpuThreadCount;
64  m_cpuThreads.reserve( m_cpuThreadCount );
66  }
67 
68  void WButterflyFactory::assignProgressCombiner( std::shared_ptr< WProgressCombiner > progress )
69  {
70  this->m_associatedProgressCombiner = progress;
71  }
72  void WButterflyFactory::setProgressSettings( size_t iteration, size_t steps )
73  {
74  m_associatedProgressCombiner->removeSubProgress( m_progressStatus );
75  std::ostringstream headerText;
76  headerText << "Iteration " << iteration;
77  m_progressStatus = std::shared_ptr< WProgress >( new WProgress( headerText.str(), steps ) );
79  }
80 
82  {
83  return this->m_validator;
84  }
86  {
87  size_t vertSize = m_inputMesh->vertSize();
88  size_t threads = m_cpuThreadCount <= vertSize ?m_cpuThreadCount :vertSize;
89  for ( size_t thread = 0; thread < threads; thread++ )
90  {
91  size_t firstVert = vertSize * thread / threads;
92  size_t lastVert = vertSize * ( thread + 1 ) / threads - 1;
93  m_cpuThreads[thread] = new boost::thread( &WVertexFactory::examineStencilRange,
94  m_verts, firstVert, lastVert, m_progressStatus );
95  }
96  for ( size_t thread = 0; thread < threads; thread++ )
97  m_cpuThreads[thread]->join();
98  }
100  {
101  for ( size_t triID = 0; triID < m_triCount; triID++ )
102  {
103  size_t vertID0 = m_inputMesh->getTriVertId0( triID );
104  size_t vertID1 = m_inputMesh->getTriVertId1( triID );
105  size_t vertID2 = m_inputMesh->getTriVertId2( triID );
106  m_verts->attachNewVertex( vertID0, vertID1 );
107  m_verts->attachNewVertex( vertID0, vertID2 );
108  m_verts->attachNewVertex( vertID1, vertID2 );
109  m_progressStatus->increment( 1 );
110  }
111  }
113  {
114  if ( iteration == 1 )
115  {
122  }
123  }
125  {
126  std::shared_ptr< WTriangleMesh > tmpMesh( new WTriangleMesh( 0, 0 ) );
127  m_outputMesh = tmpMesh;
130  m_triCount = m_inputMesh->triangleSize();
131  for ( size_t triID = 0; triID < m_triCount; triID++ )
132  {
133  m_verts->registerTriangle( m_inputMesh->getTriVertId0( triID ), triID );
134  m_verts->registerTriangle( m_inputMesh->getTriVertId1( triID ), triID );
135  m_verts->registerTriangle( m_inputMesh->getTriVertId2( triID ), triID );
136  m_progressStatus->increment( 1 );
137  }
138  applyMeshPreprocessing( iteration );
141 
142  for ( size_t vertID = 0; vertID < m_verts->getVertexCount(); vertID++ )
143  {
144  m_progressStatus->increment( 1 );
145  osg::Vec3d vec = m_inputMesh->getVertex( vertID );
146  m_outputMesh->addVertex( osg::Vec3( vec.x(), vec.y(), vec.z() ) );
147  }
150  }
151  std::shared_ptr< WTriangleMesh > WButterflyFactory::getSubdividedMesh( std::shared_ptr< WTriangleMesh > edgedMesh )
152  {
153  m_inputMesh = edgedMesh;
154  for ( size_t iteration = 1; iteration <= m_iterations &&
155  ( iteration == 1 || m_outputMesh->triangleSize() <= m_maxTriangles ); iteration++ )
156  {
157  setProgressSettings( iteration, m_inputMesh->triangleSize() * 3
158  + m_inputMesh->vertSize() * 3 );
159 
160  examineVertexNeighborhood( iteration );
164  if ( m_outputMesh->triangleSize() <= m_maxTriangles )
165  {
166  if ( m_inputMesh != edgedMesh )
167  {
168  m_inputMesh->~WTriangleMesh();
169  m_inputMesh->~WTransferable();
170  m_inputMesh->~WPrototyped();
171  }
172 
174  }
175  else
176  {
177  m_outputMesh->~WTriangleMesh();
178  m_outputMesh->~WTransferable();
179  m_outputMesh->~WPrototyped();
180  }
184  }
185  m_progressStatus->finish();
186  return m_inputMesh;
187  }
189  {
190  size_t vertSize = m_inputMesh->vertSize();
191  size_t threads = m_cpuThreadCount <= vertSize ?m_cpuThreadCount :vertSize;
192  for ( size_t thread = 0; thread < threads; thread++ )
193  {
194  size_t firstVert = vertSize * thread / threads;
195  size_t lastVert = vertSize * ( thread + 1 ) / threads - 1;
196  m_cpuThreads[thread] = new boost::thread( &WButterflyFactory::interpolateNewVerticesRange,
197  this, firstVert, lastVert );
198  }
199  for ( size_t thread = 0; thread < threads; thread++ )
200  m_cpuThreads[thread]->join();
201  }
202  void WButterflyFactory::interpolateNewVerticesRange( size_t fromVertex, size_t toVertex )
203  {
204  for ( size_t vertID1 = fromVertex; vertID1 <= toVertex; vertID1++ )
205  {
206  WVertexProperty* property = m_verts->getProperty( vertID1 );
207  vector<WNewVertex*> newVertices = property->getNewVerticesToHigherNeighborID();
208  for ( size_t newVert = 0; newVert < newVertices.size(); newVert++ )
209  {
210  WNewVertex* newVertex = newVertices[newVert];
211  size_t vertID2 = newVertex->getToID();
212  Vec3 newCoord = m_butterflyCalculator->calcNewVertex( vertID1, vertID2 );
213  newCoord = m_validator->getValidatedSubdivision( vertID1, vertID2, newCoord );
214  newVertex->setValid( m_validator->isValidSubdivision( vertID1, vertID2, newCoord ) );
215  newVertex->setCoordinate( newCoord );
216  }
217  m_progressStatus->increment( 1 );
218  }
219  }
221  {
222  for ( size_t vertID1 = 0; vertID1 < m_inputMesh->vertSize(); vertID1++ )
223  {
224  WVertexProperty* property = m_verts->getProperty( vertID1 );
225  vector<WNewVertex*> newVertices = property->getNewVerticesToHigherNeighborID();
226  for ( size_t newVert = 0; newVert < newVertices.size(); newVert++ )
227  {
228  WNewVertex* newVertex = newVertices[newVert];
229  if ( newVertex->isValid() )
230  {
231  m_outputMesh->addVertex( newVertex->getCoordinate() );
232  newVertex->setNewVertexID( m_vertCount++ );
233  }
234  m_progressStatus->increment( 1 );
235  }
236  }
237  for ( size_t triID = 0; triID < m_triCount &&
238  m_outputMesh->triangleSize() <= m_maxTriangles; triID++ )
239  {
240  if ( m_verts->isValidTriangle( triID ) )
241  {
242  size_t vertID0 = m_inputMesh->getTriVertId0( triID );
243  size_t vertID1 = m_inputMesh->getTriVertId1( triID );
244  size_t vertID2 = m_inputMesh->getTriVertId2( triID );
245  m_validator->subdivideTriangle( vertID0, vertID1, vertID2 );
246  }
247  m_progressStatus->increment( 1 );
248  }
249  }
250 } /* namespace std */
Class managing progress inside of modules.
Definition: WProgress.h:42
Triangle mesh data structure allowing for convenient access of the elements.
Definition: WTriangleMesh.h:46
Object that contains all necessary properties of a vertex necessary for a sufficient analysis.
std::vector< WNewVertex * > getNewVerticesToHigherNeighborID()
Returns the properties of new registered vertices of the current vertex.
Class that depicts the whole Butterfly subdivision algorithm but nothing more as such.
void assignInputMesh(std::shared_ptr< WTriangleMesh > inputMesh, WVertexFactory *vertexProperties)
Assigns the input mesh andd its analyzed data that are required for the butterfly subdivision.
void setButterflySettingW(float butterflySettingW)
Set the general Butterfly Subdivision setting w that affects the subdivision.
osg::Vec3 calcNewVertex(size_t vertID1, size_t vertID2)
Calculate the subdivided new vertex between two vertices using the Butterfly Subdivision.
virtual ~WButterflyFactory()
Destroys the Butterfly instance object and its substructures.
WSubdivisionValidator * getValidator()
Returns the Butterfly subdivision validator.
size_t m_cpuThreadCount
CPU threads count for multithreading support.
void addInterpolatedContent()
Adds interpolated vertices and triangles to the output triangle mesh.
std::shared_ptr< WProgressCombiner > m_associatedProgressCombiner
Progress combiner for changing the plugin status in the modules overview.
void setCpuThreadCount(size_t cpuThreadCount)
Sets the count of CPU threads to use.
void setProgressSettings(size_t iteration, size_t steps)
Sets progress which iteration step and kind of cumputing step is currently done.
vector< boost::thread * > m_cpuThreads
CPU threads object for multithreading support.
size_t m_iterations
Iteration steps to apply iteratedly.
WSubdivisionValidator * m_validator
Triangle mesh validation instance.
WVertexFactory * m_verts
Data set used for analyzation of the triangle mesh.
std::shared_ptr< WTriangleMesh > getSubdividedMesh(std::shared_ptr< WTriangleMesh > edgedMmesh)
Launch the Butterfly subdivision.
size_t m_maxTriangles
Maximal allowed triangle count applyable for subdivision.
void examineStencilAll()
Examines Butterfly stencils of all vertices and stores data.
std::shared_ptr< WTriangleMesh > m_inputMesh
Base triangle mesh used for calculations.
void attachUncalculatedNewVertices()
Attachs new vertices that are used for the subdivision.
size_t m_triCount
Total triangle count.
void applyMeshPreprocessing(size_t iteration)
Applies triangle mesh preprocessing if vertex flip or triangle flip setting is not default.
WButterflyCalculator * m_butterflyCalculator
Instance for interpolating new vertices.
std::shared_ptr< WProgress > m_progressStatus
Current progress status.
size_t m_vertCount
Current count of currently added vertices during interpolation.
void setButterflySettingW(float butterflySettingW)
Set the general Butterfly Subdivision setting w that affects the subdivision.
void assignProgressCombiner(std::shared_ptr< WProgressCombiner > associatedProgressCombiner)
Assigns a ProbressCombiner to the Butterfly factory.
std::shared_ptr< WTriangleMesh > m_outputMesh
Triangle mesh that is set up by interpolation.
WButterflyFactory()
Butterfly subdivision tool object creating instance.
void interpolateNewVerticesRange(size_t fromVertex, size_t toVertex)
Calculates coordinates of the new vertices.
void setIterationsSettings(float m_iterations, float m_maxTriangles10n)
Assign main butterfly subdivision iterations settings.
void interpolateNewVertices()
Calculates coordinates of the new vertices.
void examineVertexNeighborhood(size_t iteration)
Examine The triangle mesh before Butterfly subdivision.
Depicts a point that is subdivided on a line between two vertices.
Definition: WNewVertex.h:40
void setNewVertexID(size_t newVertexID)
Sets the proposed ID for that new vertex.
Definition: WNewVertex.cpp:47
size_t getToID()
Returns the second vertex ID where the new vertex lies between these two points.
Definition: WNewVertex.cpp:52
void setValid(bool isValid)
Sets the new vertex property whether it's valid for butterfly subdivision or not.
Definition: WNewVertex.cpp:56
osg::Vec3 getCoordinate()
Returns coordinates of the new vertex.
Definition: WNewVertex.cpp:64
bool isValid()
Returns whether the new vertex is marked to be valid for the butterfly subdivison of a line between t...
Definition: WNewVertex.cpp:60
void setCoordinate(osg::Vec3 coordinate)
Sets coordinates of the new vertex.
Definition: WNewVertex.cpp:68
Class that validates the Butterfly subdivision.
bool isValidSubdivision(size_t vertID1, size_t vertID2, osg::Vec3 newVert)
This function checks a subdivided line between two vertices for correctness.
float getMinSubdividedLineLengthMultiplierPerIteration()
Gets the factor where the minimal subdivided line length is multiplied by in each Subdivision iterati...
void setMinSubdividedLineLength(float minSubdividedLineLength)
Sets the minimal subdividable line length.
osg::Vec3 getValidatedSubdivision(size_t vertID1, size_t vertID2, osg::Vec3 interpolatedVertex)
Corrects Coordinates if they are determined to be invalid using validation settings.
void subdivideTriangle(size_t vertID0, size_t vertID1, size_t vertID2)
Subdivides the triangle at three vertex IDs regarding the not subdividable new vertices at lines betw...
std::shared_ptr< WTriangleMesh > joinNarrowVertices(std::shared_ptr< WTriangleMesh > inputMesh)
Joins Vertices where a triangle side is smaller than the longest one multiplied by a factor.
std::shared_ptr< WTriangleMesh > flipTrianglesAtLowAngles(std::shared_ptr< WTriangleMesh > inputMesh)
Searchs for all triangles which has two angles below a preset value.
float getMinSubdividedLineLength()
Gets the minimal subdividable line length.
void generateStatisticalInformation()
Generating statistical information of the triangle mesh.
void setTriangleMesh(std::shared_ptr< WTriangleMesh > processedMesh, WVertexFactory *vertexFactory)
Assign analyzable triangle mesh.
Class that manages all vertex properties.
WVertexProperty * getProperty(size_t vertexID)
Get properties of a vertex.
bool isValidTriangle(size_t triangleID)
Examine triangle by its ID for validity.
size_t getVertexCount()
Returns the Property List's vertex count.
void setTriangleMesh(std::shared_ptr< WTriangleMesh > triangleMesh)
Sets the WTriangleMesh.
void examineStencilRange(size_t fromVertex, size_t toVertex, std::shared_ptr< WProgress > progress)
Examines Butterfly stencils of all vertices and applies settings data to the vertex.
void attachNewVertex(size_t fromID, size_t toID)
Registering a subdividable new vertex of an ID between two vertices.
void registerTriangle(size_t vertexID, size_t triangleID)
Registers triangle to all its vertex IDs.
virtual ~WVertexFactory()
Destroys the vertex factory object.