1 /* Copyright 2004, 2005 Nicholas Bishop
2  *
3  * This file is part of SharpConstruct.
4  *
5  * SharpConstruct is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * SharpConstruct is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with SharpConstruct; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
18 
19 #include "MeshHistory.h"
20 
21 using namespace SharpConstruct;
22 
MeshHistory(unsigned int max)23 MeshHistory::MeshHistory( unsigned int max )
24 : _maximum( max ), _current_index( 0 ), _current_maximum_index( 0 ),
25   _current_mesh( 0 )
26 {
27 	Clear();
28 }
29 
~MeshHistory()30 MeshHistory::~MeshHistory()
31 {}
32 
Instance()33 MeshHistory& MeshHistory::Instance()
34 {
35 	static MeshHistory instance( 2 );
36 	return instance;
37 }
38 
AddMesh(bool v,bool c,bool p,bool copy)39 void MeshHistory::AddMesh( bool v, bool c, bool p, bool copy )
40 {
41 	if( _current_index == _maximum - 1 )
42 	{
43 		if( !_meshes[ 1 ].Vertices() )
44 			_meshes[ 1 ].SetVertices( _meshes[ 0 ].Vertices() );
45 		if( !_meshes[ 1 ].Colors() )
46 			_meshes[ 1 ].SetColors( _meshes[ 0 ].Colors() );
47 		if( !_meshes[ 1 ].Polygons() )
48 			_meshes[ 1 ].SetPolygons( _meshes[ 0 ].Polygons() );
49 
50 		_meshes.erase( _meshes.begin() );
51 		_current_index--;
52 		_current_maximum_index--;
53 	}
54 
55 	_meshes.resize( _current_index + 1 );
56 	_meshes.push_back( PartialMesh() );
57 	if( v )
58 	{
59 		_meshes.back().SetVertices( new PartialMesh::PartialVertexData );
60 		if( copy )
61 			*_meshes.back().Vertices() = *_current_composite.Vertices();
62 	}
63 	if( c )
64 	{
65 		_meshes.back().SetColors( new PartialMesh::PartialColorData );
66 		if( copy )
67 			*_meshes.back().Colors() = *_current_composite.Colors();
68 	}
69 	if( p )
70 	{
71 		_meshes.back().SetPolygons( new PartialMesh::PartialPolygonData );
72 		if( copy )
73 			*_meshes.back().Polygons() = *_current_composite.Polygons();
74 	}
75 	_meshes.back().Saved() = false;
76 	_meshes.back().VisibleElements() = _meshes[ _meshes.size() - 2 ].VisibleElements();
77 	_meshes.back().Filename() = _meshes[ _meshes.size() - 2 ].Filename();
78 
79 	if( _current_index == _current_maximum_index )
80 		_current_maximum_index++;
81 	else
82 		_current_maximum_index = _current_index + 1;
83 	_current_index++;
84 	_update_proxy();
85 }
86 
Undo()87 void MeshHistory::Undo()
88 {
89 	_current_index--;
90 	if( _current_index < 0 )
91 		_current_index = 0;
92 
93 	_update_proxy();
94 }
95 
Redo()96 void MeshHistory::Redo()
97 {
98 	_current_index++;
99 	if( _current_index > _current_maximum_index )
100 		_current_index = _current_maximum_index;
101 
102 	_update_proxy();
103 }
104 
Clear()105 void MeshHistory::Clear()
106 {
107 	_current_index = 0;
108 	_current_maximum_index = 0;
109 
110 	_meshes.clear();
111 
112 	_meshes.resize( 1 );
113 	_meshes.front().SetVertices( new PartialMesh::PartialVertexData );
114 	_meshes.front().SetColors( new PartialMesh::PartialColorData );
115 	_meshes.front().SetPolygons( new PartialMesh::PartialPolygonData );
116 
117 	_current_composite.SetVertices( _meshes.front().Vertices() );
118 	_current_composite.SetColors( _meshes.front().Colors() );
119 	_current_composite.SetPolygons( _meshes.front().Polygons() );
120 
121 	_update_proxy();
122 }
123 
GetPreviousComposite()124 MeshHistory::PartialMesh& MeshHistory::GetPreviousComposite()
125 {
126 	return _previous_composite;
127 }
128 
CurrentComposite()129 MeshHistory::PartialMesh& MeshHistory::CurrentComposite()
130 {
131 	return _current_composite;
132 }
GetCurrentMesh()133 Mesh& MeshHistory::GetCurrentMesh()
134 {
135 	return *_current_mesh;
136 }
137 
Maximum() const138 int MeshHistory::Maximum() const
139 {
140 	return _maximum;
141 }
SetMaximum(unsigned int max)142 void MeshHistory::SetMaximum( unsigned int max )
143 {
144 	_maximum = max;
145 
146 	if( max < _meshes.size() )
147 	{
148 		_meshes.erase( _meshes.begin(), _meshes.begin() + ( _meshes.size() - max - 1 ) );
149 		_current_maximum_index = max;
150 		_current_index = max - 1;
151 	}
152 
153 	_update_proxy();
154 }
155 
UndoPossible() const156 bool MeshHistory::UndoPossible() const
157 {
158 	if( _current_index > 0 )
159 		return true;
160 	return false;
161 }
162 
RedoPossible() const163 bool MeshHistory::RedoPossible() const
164 {
165 	if( _current_index < _current_maximum_index )
166 		return true;
167 	return false;
168 }
169 
Saved() const170 bool MeshHistory::Saved() const
171 {
172 	return _meshes[ _current_index ].Saved();
173 }
174 
Changed()175 sigc::signal< void, bool, bool >& MeshHistory::Changed()
176 {
177 	return _changed;
178 }
179 
SignalEntireSectionChanged()180 MeshHistory::UpdateSignal& MeshHistory::SignalEntireSectionChanged()
181 {
182 	return signal_entire_section_changed_;
183 }
184 
_print_debug_info()185 void MeshHistory::_print_debug_info()
186 {
187 	/*std::cout << "_meshes.size()=" << _meshes.size() << std::endl;
188 	std::cout << "&_meshes[_current_index]=" << &_meshes[_current_index] << std::endl;
189 	for( unsigned i = 0; i < _meshes.size(); i++ )
190 	{
191 		std::cout << i << ": " << _meshes[ i ].Vertices();
192 		std::cout <<      " " << _meshes[ i ].Colors();
193 		std::cout <<      " " << _meshes[ i ].Polygons() << std::endl;
194 		}*/
195 	/*std::cout << "c: " << _current_pmv << " " << _current_pmc << " " << _current_pmp << std::endl;
196 	std::cout << "l: " << &_current_pmv->Vertices()->VertexLocations() << " " << &_current_mesh->VertexLocations() << std::endl;
197 	std::cout << "q: " << &_current_pmp->Polygons()->Quads() << " " << &_current_mesh->Quads() << std::endl;
198 	std::cout << "_current_mesh=" << _current_mesh << std::endl;
199 	std::cout << "trigs.size=" << _current_pmp->Polygons()->Triangles().size() << std::endl;
200 	std::cout << "quads.size=" << _current_pmp->Polygons()->Quads().size() << std::endl;*/
201 }
202 
_update_composite()203 bool MeshHistory::_update_composite()
204 {
205 	int ndx;
206 
207 	// Find current Vertex data
208 	ndx = _current_index;
209 	while( !_meshes[ ndx ].Vertices() )
210 		ndx--;
211 	_current_composite.SetVertices( _meshes[ ndx ].Vertices() );
212 	// Find previous Vertex data
213 	ndx = std::max( ndx - 1, 0 );
214 	while( ndx > 0 && !_meshes[ ndx ].Vertices() )
215 		ndx--;
216 	_previous_composite.SetVertices( _meshes[ ndx ].Vertices() );
217 
218 	// Find current Color data
219 	ndx = _current_index;
220 	while( !_meshes[ ndx ].Colors() )
221 		ndx--;
222 	_current_composite.SetColors( _meshes[ ndx ].Colors() );
223 	// Find previous Color data
224 	ndx = std::max( ndx - 1, 0 );
225 	while( ndx >= 0 && !_meshes[ ndx ].Colors() )
226 		ndx--;
227 	_previous_composite.SetColors( _meshes[ ndx ].Colors() );
228 
229 	// Store current partial polygon data
230 	PartialMesh::PartialPolygonData* old = _current_composite.Polygons();
231 
232 	// Find current Polygon data
233 	ndx = _current_index;
234 	while( !_meshes[ ndx ].Polygons() )
235 		ndx--;
236 	_current_composite.SetPolygons( _meshes[ ndx ].Polygons() );
237 	// Find previous Polygon data
238 	ndx = std::max( ndx - 1, 0 );
239 	while( ndx >= 0 && !_meshes[ ndx ].Polygons() )
240 		ndx--;
241 	_previous_composite.SetPolygons( _meshes[ ndx ].Polygons() );
242 
243 	// Return whether polygons have changed
244 	return old != _current_composite.Polygons();
245 }
246 
_update_proxy()247 void MeshHistory::_update_proxy()
248 {
249 	bool p = _update_composite();
250 
251 	delete _current_mesh;
252 	_current_mesh = new Mesh( _current_composite.Vertices()->VertexLocations(),
253 				  _current_composite.Vertices()->VertexNormals(),
254 				  _current_composite.Colors()->VertexColors(),
255 				  _current_composite.Polygons()->TriangleNormals(),
256 				  _current_composite.Polygons()->QuadNormals(),
257 				  _current_composite.Polygons()->Triangles(),
258 				  _current_composite.Polygons()->Quads(),
259 				  _current_composite.Polygons()->VertexUsers(),
260 				  _meshes[ _current_index ].Saved(),
261 				  _meshes[ _current_index ].VisibleElements(),
262 				  _meshes[ _current_index ].Filename() );
263 
264 	if( !_current_mesh->VisibleElements().Enabled )
265 	{
266 		_current_mesh->VisibleElements().Vertices = _current_mesh->VertexLocations().size();
267 		_current_mesh->VisibleElements().Triangles = _current_mesh->Triangles().size();
268 		_current_mesh->VisibleElements().Quads = _current_mesh->Quads().size();
269 	}
270 
271 
272 	Changed()( p, false );
273 }
274