/* Copyright 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 "Brush.h" #include "LayerBrush.hh" #include "Mesh.h" #include "MeshHistory.h" #include "Optimized.h" using namespace SharpConstruct; std::vector< float > LayerBrush::displacements_; std::vector< float > LayerBrush::color_adds_; LayerBrush::LayerBrush( SculptStart, Mesh& mesh ) : mesh_( mesh ) { displacements_.clear(); color_adds_.clear(); if( mesh_.CurrentBrush().PositionEdit() ) displacements_.resize( mesh_.VisibleElements().Vertices, 0 ); if( mesh_.CurrentBrush().ColorEdit() ) color_adds_.resize( mesh_.VisibleElements().Vertices, 0 ); } LayerBrush::LayerBrush( SculptContinue, Mesh& mesh ) : mesh_( mesh ) { if( mesh_.CurrentBrush().Dot() ) { Optimized::Point3DVector& locbackup = MeshHistory::Instance().GetPreviousComposite().Vertices()->VertexLocations(); Optimized::Point3DVector& norbackup = MeshHistory::Instance().GetPreviousComposite().Vertices()->VertexNormals(); std::vector< Color >& colbackup = MeshHistory::Instance().GetPreviousComposite().Colors()->VertexColors(); const std::vector< unsigned >& modvi( mesh_.ModifiedVertexIndices() ); for( unsigned i = 0; i < modvi.size(); ++i ) { if( mesh_.CurrentBrush().PositionEdit() ) { mesh_.VertexLocations()[ modvi[ i ] ] = locbackup[ modvi[ i ] ]; mesh_.VertexNormals()[ modvi[ i ] ] = norbackup[ modvi[ i ] ]; } if( mesh_.CurrentBrush().ColorEdit() ) mesh_.VertexColors()[ modvi[ i ] ] = colbackup[ modvi[ i ] ]; } } mesh_.ModifiedVertexIndices().clear(); } void LayerBrush::operator()( SculptStart, EditData e ) {} void LayerBrush::operator()( SculptContinue, EditData e ) { mesh_.FindActiveVertices( active_data_, e ); if( mesh_.CurrentBrush().ColorEdit() ) { std::vector< Color >& colbackup = MeshHistory::Instance().GetPreviousComposite().Colors()->VertexColors(); for( unsigned i = 0; i < active_data_.size(); ++i ) { const float colval = active_data_[ i ].Strength() * mesh_.CurrentBrush().Intensity(); if( mesh_.CurrentBrush().Dot() ) { mesh_.VertexColors()[ active_data_[ i ].Index() ] += ( mesh_.CurrentBrush().CurrentColor() - colbackup[ active_data_[ i ].Index() ] ) * colval; } else { color_adds_[ active_data_[ i ].Index() ] += colval; if( color_adds_[ active_data_[ i ].Index() ] > mesh_.CurrentBrush().Intensity() ) color_adds_[ active_data_[ i ].Index() ] = mesh_.CurrentBrush().Intensity(); mesh_.VertexColors()[ active_data_[ i ].Index() ] = colbackup[ active_data_[ i ].Index() ] + ( mesh_.CurrentBrush().CurrentColor() - colbackup[ active_data_[ i ].Index() ] ) * color_adds_[ active_data_[ i ].Index() ]; } } } if( mesh_.CurrentBrush().PositionEdit() ) { Optimized::Point3DVector& locbackup = MeshHistory::Instance().GetPreviousComposite().Vertices()->VertexLocations(); Optimized::Point3D area_normal = mesh_.CalculateAreaNormal( active_data_ ); for( unsigned i = 0; i < active_data_.size(); i++ ) { const float addval( active_data_[ i ].Strength() * mesh_.CurrentBrush().Strength() ); if( mesh_.CurrentBrush().Dot() ) { mesh_.VertexLocations()[ active_data_[ i ].Index() ] = locbackup[ active_data_[ i ].Index() ] + ( area_normal * addval ); } else { displacements_[ active_data_[ i ].Index() ] += addval; if( mesh_.CurrentBrush().Strength() < 0 ) { if( displacements_[ active_data_[ i ].Index() ] < mesh_.CurrentBrush().Strength() ) displacements_[ active_data_[ i ].Index() ] = mesh_.CurrentBrush().Strength(); } else { if( displacements_[ active_data_[ i ].Index() ] > mesh_.CurrentBrush().Strength() ) displacements_[ active_data_[ i ].Index() ] = mesh_.CurrentBrush().Strength(); } mesh_.VertexLocations()[ active_data_[ i ].Index() ] = locbackup[ active_data_[ i ].Index() ] + ( area_normal * displacements_[ active_data_[ i ].Index() ] ); } } } } void LayerBrush::Postwork( SculptStart ) { } void LayerBrush::Postwork( SculptContinue ) { if( mesh_.CurrentBrush().PositionEdit() ) { mesh_.RecalculateDamaged(); mesh_.RecalculateModifiedNormals(); } }