/* Copyright 2004, 2005 Nicholas Bishop * * This file is part of SharpConstruct. * * SharpConstruct is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * SharpConstruct 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SharpConstruct; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "MeshHistory.h" using namespace SharpConstruct; MeshHistory::MeshHistory( unsigned int max ) : _maximum( max ), _current_index( 0 ), _current_maximum_index( 0 ), _current_mesh( 0 ) { Clear(); } MeshHistory::~MeshHistory() {} MeshHistory& MeshHistory::Instance() { static MeshHistory instance( 2 ); return instance; } void MeshHistory::AddMesh( bool v, bool c, bool p, bool copy ) { if( _current_index == _maximum - 1 ) { if( !_meshes[ 1 ].Vertices() ) _meshes[ 1 ].SetVertices( _meshes[ 0 ].Vertices() ); if( !_meshes[ 1 ].Colors() ) _meshes[ 1 ].SetColors( _meshes[ 0 ].Colors() ); if( !_meshes[ 1 ].Polygons() ) _meshes[ 1 ].SetPolygons( _meshes[ 0 ].Polygons() ); _meshes.erase( _meshes.begin() ); _current_index--; _current_maximum_index--; } _meshes.resize( _current_index + 1 ); _meshes.push_back( PartialMesh() ); if( v ) { _meshes.back().SetVertices( new PartialMesh::PartialVertexData ); if( copy ) *_meshes.back().Vertices() = *_current_composite.Vertices(); } if( c ) { _meshes.back().SetColors( new PartialMesh::PartialColorData ); if( copy ) *_meshes.back().Colors() = *_current_composite.Colors(); } if( p ) { _meshes.back().SetPolygons( new PartialMesh::PartialPolygonData ); if( copy ) *_meshes.back().Polygons() = *_current_composite.Polygons(); } _meshes.back().Saved() = false; _meshes.back().VisibleElements() = _meshes[ _meshes.size() - 2 ].VisibleElements(); _meshes.back().Filename() = _meshes[ _meshes.size() - 2 ].Filename(); if( _current_index == _current_maximum_index ) _current_maximum_index++; else _current_maximum_index = _current_index + 1; _current_index++; _update_proxy(); } void MeshHistory::Undo() { _current_index--; if( _current_index < 0 ) _current_index = 0; _update_proxy(); } void MeshHistory::Redo() { _current_index++; if( _current_index > _current_maximum_index ) _current_index = _current_maximum_index; _update_proxy(); } void MeshHistory::Clear() { _current_index = 0; _current_maximum_index = 0; _meshes.clear(); _meshes.resize( 1 ); _meshes.front().SetVertices( new PartialMesh::PartialVertexData ); _meshes.front().SetColors( new PartialMesh::PartialColorData ); _meshes.front().SetPolygons( new PartialMesh::PartialPolygonData ); _current_composite.SetVertices( _meshes.front().Vertices() ); _current_composite.SetColors( _meshes.front().Colors() ); _current_composite.SetPolygons( _meshes.front().Polygons() ); _update_proxy(); } MeshHistory::PartialMesh& MeshHistory::GetPreviousComposite() { return _previous_composite; } MeshHistory::PartialMesh& MeshHistory::CurrentComposite() { return _current_composite; } Mesh& MeshHistory::GetCurrentMesh() { return *_current_mesh; } int MeshHistory::Maximum() const { return _maximum; } void MeshHistory::SetMaximum( unsigned int max ) { _maximum = max; if( max < _meshes.size() ) { _meshes.erase( _meshes.begin(), _meshes.begin() + ( _meshes.size() - max - 1 ) ); _current_maximum_index = max; _current_index = max - 1; } _update_proxy(); } bool MeshHistory::UndoPossible() const { if( _current_index > 0 ) return true; return false; } bool MeshHistory::RedoPossible() const { if( _current_index < _current_maximum_index ) return true; return false; } bool MeshHistory::Saved() const { return _meshes[ _current_index ].Saved(); } sigc::signal< void, bool, bool >& MeshHistory::Changed() { return _changed; } MeshHistory::UpdateSignal& MeshHistory::SignalEntireSectionChanged() { return signal_entire_section_changed_; } void MeshHistory::_print_debug_info() { /*std::cout << "_meshes.size()=" << _meshes.size() << std::endl; std::cout << "&_meshes[_current_index]=" << &_meshes[_current_index] << std::endl; for( unsigned i = 0; i < _meshes.size(); i++ ) { std::cout << i << ": " << _meshes[ i ].Vertices(); std::cout << " " << _meshes[ i ].Colors(); std::cout << " " << _meshes[ i ].Polygons() << std::endl; }*/ /*std::cout << "c: " << _current_pmv << " " << _current_pmc << " " << _current_pmp << std::endl; std::cout << "l: " << &_current_pmv->Vertices()->VertexLocations() << " " << &_current_mesh->VertexLocations() << std::endl; std::cout << "q: " << &_current_pmp->Polygons()->Quads() << " " << &_current_mesh->Quads() << std::endl; std::cout << "_current_mesh=" << _current_mesh << std::endl; std::cout << "trigs.size=" << _current_pmp->Polygons()->Triangles().size() << std::endl; std::cout << "quads.size=" << _current_pmp->Polygons()->Quads().size() << std::endl;*/ } bool MeshHistory::_update_composite() { int ndx; // Find current Vertex data ndx = _current_index; while( !_meshes[ ndx ].Vertices() ) ndx--; _current_composite.SetVertices( _meshes[ ndx ].Vertices() ); // Find previous Vertex data ndx = std::max( ndx - 1, 0 ); while( ndx > 0 && !_meshes[ ndx ].Vertices() ) ndx--; _previous_composite.SetVertices( _meshes[ ndx ].Vertices() ); // Find current Color data ndx = _current_index; while( !_meshes[ ndx ].Colors() ) ndx--; _current_composite.SetColors( _meshes[ ndx ].Colors() ); // Find previous Color data ndx = std::max( ndx - 1, 0 ); while( ndx >= 0 && !_meshes[ ndx ].Colors() ) ndx--; _previous_composite.SetColors( _meshes[ ndx ].Colors() ); // Store current partial polygon data PartialMesh::PartialPolygonData* old = _current_composite.Polygons(); // Find current Polygon data ndx = _current_index; while( !_meshes[ ndx ].Polygons() ) ndx--; _current_composite.SetPolygons( _meshes[ ndx ].Polygons() ); // Find previous Polygon data ndx = std::max( ndx - 1, 0 ); while( ndx >= 0 && !_meshes[ ndx ].Polygons() ) ndx--; _previous_composite.SetPolygons( _meshes[ ndx ].Polygons() ); // Return whether polygons have changed return old != _current_composite.Polygons(); } void MeshHistory::_update_proxy() { bool p = _update_composite(); delete _current_mesh; _current_mesh = new Mesh( _current_composite.Vertices()->VertexLocations(), _current_composite.Vertices()->VertexNormals(), _current_composite.Colors()->VertexColors(), _current_composite.Polygons()->TriangleNormals(), _current_composite.Polygons()->QuadNormals(), _current_composite.Polygons()->Triangles(), _current_composite.Polygons()->Quads(), _current_composite.Polygons()->VertexUsers(), _meshes[ _current_index ].Saved(), _meshes[ _current_index ].VisibleElements(), _meshes[ _current_index ].Filename() ); if( !_current_mesh->VisibleElements().Enabled ) { _current_mesh->VisibleElements().Vertices = _current_mesh->VertexLocations().size(); _current_mesh->VisibleElements().Triangles = _current_mesh->Triangles().size(); _current_mesh->VisibleElements().Quads = _current_mesh->Quads().size(); } Changed()( p, false ); }