]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/brush.h
redo !103, refix #76, was reintroduced in 957d2ff
[xonotic/netradiant.git] / radiant / brush.h
index 0fb6ffe225c2b0d3dbe45d0a8b3d5fb08a07079f..7748327d089b520da17d63caa28ceffe2c5d4af7 100644 (file)
@@ -102,7 +102,6 @@ inline void print_3x3( const Matrix4& m ){
 }
 
 
-
 inline bool texdef_sane( const texdef_t& texdef ){
        return fabs( texdef.shift[0] ) < ( 1 << 16 )
                   && fabs( texdef.shift[1] ) < ( 1 << 16 );
@@ -308,23 +307,8 @@ class FaceShaderObserver
 {
 public:
 virtual void realiseShader() = 0;
-virtual void unrealiseShader() = 0;
-};
-
-class FaceShaderObserverRealise
-{
-public:
-void operator()( FaceShaderObserver& observer ) const {
-       observer.realiseShader();
-}
-};
 
-class FaceShaderObserverUnrealise
-{
-public:
-void operator()( FaceShaderObserver& observer ) const {
-       observer.unrealiseShader();
-}
+virtual void unrealiseShader() = 0;
 };
 
 typedef ReferencePair<FaceShaderObserver> FaceShaderObserverPair;
@@ -335,12 +319,14 @@ class ContentsFlagsValue
 public:
 ContentsFlagsValue(){
 }
+
 ContentsFlagsValue( int surfaceFlags, int contentFlags, int value, bool specified ) :
        m_surfaceFlags( surfaceFlags ),
        m_contentFlags( contentFlags ),
        m_value( value ),
        m_specified( specified ){
 }
+
 int m_surfaceFlags;
 int m_contentFlags;
 int m_value;
@@ -376,7 +362,7 @@ SavedState( const FaceShader& faceShader ){
 
 void exportState( FaceShader& faceShader ) const {
        faceShader.setShader( m_shader.c_str() );
-       faceShader.setFlags( m_flags );
+       faceShader.m_flags = m_flags;
 }
 };
 
@@ -395,9 +381,11 @@ FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsV
        m_realised( false ){
        captureShader();
 }
+
 ~FaceShader(){
        releaseShader();
 }
+
 // copy-construction not supported
 FaceShader( const FaceShader& other );
 
@@ -405,6 +393,7 @@ void instanceAttach(){
        m_instanced = true;
        m_state->incrementUsed();
 }
+
 void instanceDetach(){
        m_state->decrementUsed();
        m_instanced = false;
@@ -416,6 +405,7 @@ void captureShader(){
        m_state = GlobalShaderCache().capture( m_shader.c_str() );
        m_state->attach( *this );
 }
+
 void releaseShader(){
        ASSERT_MESSAGE( m_state != 0, "shader cannot be released" );
        m_state->detach( *this );
@@ -426,11 +416,16 @@ void releaseShader(){
 void realise(){
        ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" );
        m_realised = true;
-       m_observers.forEach( FaceShaderObserverRealise() );
+       m_observers.forEach([](FaceShaderObserver &observer) {
+               observer.realiseShader();
+       });
 }
+
 void unrealise(){
        ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" );
-       m_observers.forEach( FaceShaderObserverUnrealise() );
+       m_observers.forEach([](FaceShaderObserver &observer) {
+               observer.unrealiseShader();
+       });
        m_realised = false;
 }
 
@@ -462,6 +457,7 @@ void setShader( const char* name ){
                m_state->incrementUsed();
        }
 }
+
 ContentsFlagsValue getFlags() const {
        ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" );
        if ( !m_flags.m_specified ) {
@@ -474,6 +470,7 @@ ContentsFlagsValue getFlags() const {
        }
        return m_flags;
 }
+
 void setFlags( const ContentsFlagsValue& flags ){
        ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" );
        ContentsFlagsValue_assignMasked( m_flags, flags );
@@ -489,12 +486,14 @@ std::size_t width() const {
        }
        return 1;
 }
+
 std::size_t height() const {
        if ( m_realised ) {
                return m_state->getTexture().height;
        }
        return 1;
 }
+
 unsigned int shaderFlags() const {
        if ( m_realised ) {
                return m_state->getFlags();
@@ -504,14 +503,14 @@ unsigned int shaderFlags() const {
 };
 
 
-
-
 class FaceTexdef : public FaceShaderObserver
 {
 // not copyable
 FaceTexdef( const FaceTexdef& other );
+
 // not assignable
 FaceTexdef& operator=( const FaceTexdef& other );
+
 public:
 class SavedState
 {
@@ -543,6 +542,7 @@ FaceTexdef(
        m_scaleApplied( false ){
        m_shader.attach( *this );
 }
+
 ~FaceTexdef(){
        m_shader.detach( *this );
 }
@@ -552,6 +552,7 @@ void addScale(){
        m_scaleApplied = true;
        m_projection.m_brushprimit_texdef.addScale( m_shader.width(), m_shader.height() );
 }
+
 void removeScale(){
        ASSERT_MESSAGE( m_scaleApplied, "texture scale aready removed" );
        m_scaleApplied = false;
@@ -563,6 +564,7 @@ void realiseShader(){
                addScale();
        }
 }
+
 void unrealiseShader(){
        if ( m_projectionInitialised && m_scaleApplied ) {
                removeScale();
@@ -613,6 +615,7 @@ TextureProjection normalised() const {
        tmp.removeScale( m_shader.width(), m_shader.height() );
        return TextureProjection( m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t );
 }
+
 void setBasis( const Vector3& normal ){
        Matrix4 basis;
        Normal_GetTransform( normal, basis );
@@ -683,6 +686,7 @@ void exportState( FacePlane& facePlane ) const {
 
 FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){
 }
+
 FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){
        if ( !isDoom3Plane() ) {
                planepts_assign( m_planepts, other.m_planepts );
@@ -719,6 +723,7 @@ void reverse(){
                updateSource();
        }
 }
+
 void transform( const Matrix4& matrix, bool mirror ){
        if ( !isDoom3Plane() ) {
 
@@ -749,6 +754,7 @@ void transform( const Matrix4& matrix, bool mirror ){
                updateSource();
        }
 }
+
 void offset( float offset ){
        if ( !isDoom3Plane() ) {
                Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) );
@@ -769,6 +775,7 @@ void offset( float offset ){
 void updateTranslated(){
        m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin );
 }
+
 void updateSource(){
        m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) );
 }
@@ -777,16 +784,20 @@ void updateSource(){
 PlanePoints& planePoints(){
        return m_planepts;
 }
+
 const PlanePoints& planePoints() const {
        return m_planepts;
 }
+
 const Plane3& plane3() const {
        return m_planeCached;
 }
+
 void setDoom3Plane( const Plane3& plane ){
        m_plane = plane;
        updateTranslated();
 }
+
 const Plane3& getDoom3Plane() const {
        return m_plane;
 }
@@ -802,6 +813,7 @@ void copy( const FacePlane& other ){
                updateSource();
        }
 }
+
 void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
        if ( !isDoom3Plane() ) {
                m_planepts[0] = p0;
@@ -842,9 +854,11 @@ virtual bool filter( const Face& face ) const = 0;
 };
 
 bool face_filtered( Face& face );
+
 void add_face_filter( FaceFilter& filter, int mask, bool invert = false );
 
 void Brush_addTextureChangedCallback( const SignalHandler& callback );
+
 void Brush_textureChanged();
 
 
@@ -854,8 +868,11 @@ class FaceObserver
 {
 public:
 virtual void planeChanged() = 0;
+
 virtual void connectivityChanged() = 0;
+
 virtual void shaderChanged() = 0;
+
 virtual void evaluateTransform() = 0;
 };
 
@@ -911,6 +928,7 @@ MapFile* m_map;
 
 // assignment not supported
 Face& operator=( const Face& other );
+
 // copy-construction not supported
 Face( const Face& other );
 
@@ -929,6 +947,7 @@ Face( FaceObserver* observer ) :
        m_texdef.setBasis( m_plane.plane3().normal() );
        planeChanged();
 }
+
 Face(
        const Vector3& p0,
        const Vector3& p1,
@@ -949,6 +968,7 @@ Face(
        planeChanged();
        updateFiltered();
 }
+
 Face( const Face& other, FaceObserver* observer ) :
        m_refcount( 0 ),
        m_shader( other.m_shader.getShader(), other.m_shader.m_flags ),
@@ -963,6 +983,7 @@ Face( const Face& other, FaceObserver* observer ) :
        planeChanged();
        updateFiltered();
 }
+
 ~Face(){
        m_shader.detach( *this );
 }
@@ -975,6 +996,7 @@ void planeChanged(){
 void realiseShader(){
        m_observer->shaderChanged();
 }
+
 void unrealiseShader(){
 }
 
@@ -999,6 +1021,7 @@ void render( RenderStateFlags state ) const {
 void updateFiltered(){
        m_filtered = face_filtered( *this );
 }
+
 bool isFiltered() const {
        return m_filtered;
 }
@@ -1016,6 +1039,7 @@ void undoSave(){
 UndoMemento* exportState() const {
        return new SavedState( *this );
 }
+
 void importState( const UndoMemento* data ){
        undoSave();
 
@@ -1031,6 +1055,7 @@ void importState( const UndoMemento* data ){
 void IncRef(){
        ++m_refcount;
 }
+
 void DecRef(){
        if ( --m_refcount == 0 ) {
                delete this;
@@ -1079,6 +1104,7 @@ void revertTransform(){
        planepts_assign( m_move_planeptsTransformed, m_move_planepts );
        m_texdefTransformed = m_texdef.m_projection;
 }
+
 void freezeTransform(){
        undoSave();
        m_plane = m_planeTransformed;
@@ -1141,6 +1167,7 @@ void shaderChanged(){
 const char* GetShader() const {
        return m_shader.getShader();
 }
+
 void SetShader( const char* name ){
        undoSave();
        m_shader.setShader( name );
@@ -1150,6 +1177,7 @@ void SetShader( const char* name ){
 void revertTexdef(){
        m_texdefTransformed = m_texdef.m_projection;
 }
+
 void texdefChanged(){
        revertTexdef();
        EmitTextureCoordinates();
@@ -1159,6 +1187,7 @@ void texdefChanged(){
 void GetTexdef( TextureProjection& projection ) const {
        projection = m_texdef.normalised();
 }
+
 void SetTexdef( const TextureProjection& projection ){
        undoSave();
        m_texdef.setTexdef( projection );
@@ -1168,6 +1197,7 @@ void SetTexdef( const TextureProjection& projection ){
 void GetFlags( ContentsFlagsValue& flags ) const {
        flags = m_shader.getFlags();
 }
+
 void SetFlags( const ContentsFlagsValue& flags ){
        undoSave();
        m_shader.setFlags( flags );
@@ -1215,6 +1245,7 @@ void construct_centroid(){
 const Winding& getWinding() const {
        return m_winding;
 }
+
 Winding& getWinding(){
        return m_winding;
 }
@@ -1223,21 +1254,27 @@ const Plane3& plane3() const {
        m_observer->evaluateTransform();
        return m_planeTransformed.plane3();
 }
+
 FacePlane& getPlane(){
        return m_plane;
 }
+
 const FacePlane& getPlane() const {
        return m_plane;
 }
+
 FaceTexdef& getTexdef(){
        return m_texdef;
 }
+
 const FaceTexdef& getTexdef() const {
        return m_texdef;
 }
+
 FaceShader& getShader(){
        return m_shader;
 }
+
 const FaceShader& getShader() const {
        return m_shader;
 }
@@ -1245,6 +1282,7 @@ const FaceShader& getShader() const {
 bool isDetail() const {
        return ( m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK ) != 0;
 }
+
 void setDetail( bool detail ){
        undoSave();
        if ( detail && !isDetail() ) {
@@ -1259,6 +1297,7 @@ void setDetail( bool detail ){
 bool contributes() const {
        return m_winding.numpoints > 2;
 }
+
 bool is_bounded() const {
        for ( Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i )
        {
@@ -1284,6 +1323,7 @@ FaceVertexId( std::size_t face, std::size_t vertex )
 std::size_t getFace() const {
        return m_face;
 }
+
 std::size_t getVertex() const {
        return m_vertex;
 }
@@ -1299,6 +1339,7 @@ struct EdgeRenderIndices
        EdgeRenderIndices()
                : first( 0 ), second( 0 ){
        }
+
        EdgeRenderIndices( const RenderIndex _first, const RenderIndex _second )
                : first( _first ), second( _second ){
        }
@@ -1312,6 +1353,7 @@ struct EdgeFaces
        EdgeFaces()
                : first( c_brush_maxFaces ), second( c_brush_maxFaces ){
        }
+
        EdgeFaces( const faceIndex_t _first, const faceIndex_t _second )
                : first( _first ), second( _second ){
        }
@@ -1342,6 +1384,7 @@ const PointVertex* m_vertices;
 };
 
 class Brush;
+
 typedef std::vector<Brush*> brush_vector_t;
 
 class BrushFilter
@@ -1351,6 +1394,7 @@ virtual bool filter( const Brush& brush ) const = 0;
 };
 
 bool brush_filtered( Brush& brush );
+
 void add_brush_filter( BrushFilter& filter, int mask, bool invert = false );
 
 
@@ -1402,6 +1446,7 @@ FaceVertexId m_faceVertex;
 SelectableEdge( Faces& faces, FaceVertexId faceVertex )
        : m_faces( faces ), m_faceVertex( faceVertex ){
 }
+
 SelectableEdge& operator=( const SelectableEdge& other ){
        m_faceVertex = other.m_faceVertex;
        return *this;
@@ -1429,6 +1474,7 @@ FaceVertexId m_faceVertex;
 SelectableVertex( Faces& faces, FaceVertexId faceVertex )
        : m_faces( faces ), m_faceVertex( faceVertex ){
 }
+
 SelectableVertex& operator=( const SelectableVertex& other ){
        m_faceVertex = other.m_faceVertex;
        return *this;
@@ -1447,16 +1493,23 @@ class BrushObserver
 {
 public:
 virtual void reserve( std::size_t size ) = 0;
+
 virtual void clear() = 0;
+
 virtual void push_back( Face& face ) = 0;
+
 virtual void pop_back() = 0;
+
 virtual void erase( std::size_t index ) = 0;
+
 virtual void connectivityChanged() = 0;
 
 virtual void edge_clear() = 0;
+
 virtual void edge_push_back( SelectableEdge& edge ) = 0;
 
 virtual void vertex_clear() = 0;
+
 virtual void vertex_push_back( SelectableVertex& vertex ) = 0;
 
 virtual void DEBUG_verify() const = 0;
@@ -1510,8 +1563,8 @@ Array<EdgeFaces> m_edge_faces;
 AABB m_aabb_local;
 // ----
 
-Callback m_evaluateTransform;
-Callback m_boundsChanged;
+Callback<void()> m_evaluateTransform;
+Callback<void()> m_boundsChanged;
 
 mutable bool m_planeChanged;   // b-rep evaluation required
 mutable bool m_transformChanged;   // transform evaluation required
@@ -1520,7 +1573,7 @@ mutable bool m_transformChanged;   // transform evaluation required
 public:
 STRING_CONSTANT( Name, "Brush" );
 
-Callback m_lightsChanged;
+Callback<void()> m_lightsChanged;
 
 // static data
 static Shader* m_state_point;
@@ -1529,7 +1582,7 @@ static Shader* m_state_point;
 static EBrushType m_type;
 static double m_maxWorldCoord;
 
-Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
+Brush( scene::Node& node, const Callback<void()>& evaluateTransform, const Callback<void()>& boundsChanged ) :
        m_node( &node ),
        m_undoable_observer( 0 ),
        m_map( 0 ),
@@ -1542,7 +1595,7 @@ Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& bou
        m_transformChanged( false ){
        planeChanged();
 }
-Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
+Brush( const Brush& other, scene::Node& node, const Callback<void()>& evaluateTransform, const Callback<void()>& boundsChanged ) :
        m_node( &node ),
        m_undoable_observer( 0 ),
        m_map( 0 ),
@@ -1555,6 +1608,7 @@ Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform,
        m_transformChanged( false ){
        copy( other );
 }
+
 Brush( const Brush& other ) :
        TransformNode( other ),
        Bounded( other ),
@@ -1575,6 +1629,7 @@ Brush( const Brush& other ) :
        m_transformChanged( false ){
        copy( other );
 }
+
 ~Brush(){
        ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" );
 }
@@ -1611,6 +1666,7 @@ void attach( BrushObserver& observer ){
 
        m_observers.insert( &observer );
 }
+
 void detach( BrushObserver& observer ){
        m_observers.erase( &observer );
 }
@@ -1628,6 +1684,7 @@ void forEachFace_instanceAttach( MapFile* map ) const {
                ( *i )->instanceAttach( map );
        }
 }
+
 void forEachFace_instanceDetach( MapFile* map ) const {
        for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
        {
@@ -1636,6 +1693,7 @@ void forEachFace_instanceDetach( MapFile* map ) const {
 }
 
 InstanceCounter m_instanceCounter;
+
 void instanceAttach( const scene::Path& path ){
        if ( ++m_instanceCounter.m_count == 1 ) {
                m_map = path_find_mapfile( path.begin(), path.end() );
@@ -1648,6 +1706,7 @@ void instanceAttach( const scene::Path& path ){
                ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" );
        }
 }
+
 void instanceDetach( const scene::Path& path ){
        if ( --m_instanceCounter.m_count == 0 ) {
                forEachFace_instanceDetach( m_map );
@@ -1662,8 +1721,10 @@ void instanceDetach( const scene::Path& path ){
 const char* name() const {
        return "brush";
 }
+
 void attach( const NameCallback& callback ){
 }
+
 void detach( const NameCallback& callback ){
 }
 
@@ -1686,6 +1747,7 @@ void planeChanged(){
        aabbChanged();
        m_lightsChanged();
 }
+
 void shaderChanged(){
        updateFiltered();
        planeChanged();
@@ -1702,7 +1764,8 @@ void transformChanged(){
        m_transformChanged = true;
        planeChanged();
 }
-typedef MemberCaller<Brush, &Brush::transformChanged> TransformChangedCaller;
+
+typedef MemberCaller<Brush, void(), &Brush::transformChanged> TransformChangedCaller;
 
 void evaluateTransform(){
        if ( m_transformChanged ) {
@@ -1711,12 +1774,15 @@ void evaluateTransform(){
                m_evaluateTransform();
        }
 }
+
 const Matrix4& localToParent() const {
        return g_matrix4_identity;
 }
+
 void aabbChanged(){
        m_boundsChanged();
 }
+
 const AABB& localAABB() const {
        evaluateBRep();
        return m_aabb_local;
@@ -1751,18 +1817,21 @@ void transform( const Matrix4& matrix ){
                ( *i )->transform( matrix, mirror );
        }
 }
+
 void snapto( float snap ){
        for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
        {
                ( *i )->snapto( snap );
        }
 }
+
 void revertTransform(){
        for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
        {
                ( *i )->revertTransform();
        }
 }
+
 void freezeTransform(){
        for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
        {
@@ -1794,6 +1863,7 @@ class BrushUndoMemento : public UndoMemento
 public:
 BrushUndoMemento( const Faces& faces ) : m_faces( faces ){
 }
+
 void release(){
        delete this;
 }
@@ -1872,6 +1942,7 @@ static void constructStatic( EBrushType type ){
 
        m_state_point = GlobalShaderCache().capture( "$POINT" );
 }
+
 static void destroyStatic(){
        GlobalShaderCache().release( "$POINT" );
 }
@@ -1885,6 +1956,7 @@ typedef Faces::const_iterator const_iterator;
 const_iterator begin() const {
        return m_faces.begin();
 }
+
 const_iterator end() const {
        return m_faces.end();
 }
@@ -1892,9 +1964,11 @@ const_iterator end() const {
 Face* back(){
        return m_faces.back();
 }
+
 const Face* back() const {
        return m_faces.back();
 }
+
 void reserve( std::size_t count ){
        m_faces.reserve( count );
        for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
@@ -1902,6 +1976,7 @@ void reserve( std::size_t count ){
                ( *i )->reserve( count );
        }
 }
+
 void push_back( Faces::value_type face ){
        m_faces.push_back( face );
        if ( m_instanceCounter.m_count != 0 ) {
@@ -1913,6 +1988,7 @@ void push_back( Faces::value_type face ){
                ( *i )->DEBUG_verify();
        }
 }
+
 void pop_back(){
        if ( m_instanceCounter.m_count != 0 ) {
                m_faces.back()->instanceDetach( m_map );
@@ -1924,6 +2000,7 @@ void pop_back(){
                ( *i )->DEBUG_verify();
        }
 }
+
 void erase( std::size_t index ){
        if ( m_instanceCounter.m_count != 0 ) {
                m_faces[index]->instanceDetach( m_map );
@@ -1935,6 +2012,7 @@ void erase( std::size_t index ){
                ( *i )->DEBUG_verify();
        }
 }
+
 void connectivityChanged(){
        for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
        {
@@ -1955,9 +2033,11 @@ void clear(){
                ( *i )->DEBUG_verify();
        }
 }
+
 std::size_t size() const {
        return m_faces.size();
 }
+
 bool empty() const {
        return m_faces.empty();
 }
@@ -2105,6 +2185,7 @@ void edge_push_back( FaceVertexId faceVertex ){
                ( *i )->edge_push_back( m_select_edges.back() );
        }
 }
+
 void edge_clear(){
        m_select_edges.clear();
        for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
@@ -2112,6 +2193,7 @@ void edge_clear(){
                ( *i )->edge_clear();
        }
 }
+
 void vertex_push_back( FaceVertexId faceVertex ){
        m_select_vertices.push_back( SelectableVertex( m_faces, faceVertex ) );
        for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
@@ -2119,6 +2201,7 @@ void vertex_push_back( FaceVertexId faceVertex ){
                ( *i )->vertex_push_back( m_select_vertices.back() );
        }
 }
+
 void vertex_clear(){
        m_select_vertices.clear();
        for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
@@ -2325,7 +2408,6 @@ void buildBRep();
 };
 
 
-
 class FaceInstance;
 
 class FaceInstanceSet
@@ -2336,6 +2418,7 @@ public:
 void insert( FaceInstance& faceInstance ){
        m_faceInstances.append( faceInstance );
 }
+
 void erase( FaceInstance& faceInstance ){
        m_faceInstances.erase( faceInstance );
 }
@@ -2351,6 +2434,7 @@ void foreach( Functor functor ){
 bool empty() const {
        return m_faceInstances.empty();
 }
+
 FaceInstance& last() const {
        return m_faceInstances.back();
 }
@@ -2376,6 +2460,7 @@ inline VertexSelection::iterator VertexSelection_insert( VertexSelection& self,
        }
        return i;
 }
+
 inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){
        VertexSelection::iterator i = VertexSelection_find( self, value );
        if ( i != self.end() ) {
@@ -2386,10 +2471,12 @@ inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){
 inline bool triangle_reversed( std::size_t x, std::size_t y, std::size_t z ){
        return !( ( x < y && y < z ) || ( z < x && x < y ) || ( y < z && z < x ) );
 }
+
 template<typename Element>
 inline Vector3 triangle_cross( const BasicVector3<Element>& x, const BasicVector3<Element> y, const BasicVector3<Element>& z ){
        return vector3_cross( y - x, z - x );
 }
+
 template<typename Element>
 inline bool triangles_same_winding( const BasicVector3<Element>& x1, const BasicVector3<Element> y1, const BasicVector3<Element>& z1, const BasicVector3<Element>& x2, const BasicVector3<Element> y2, const BasicVector3<Element>& z2 ){
        return vector3_dot( triangle_cross( x1, y1, z1 ), triangle_cross( x2, y2, z2 ) ) > 0;
@@ -2407,13 +2494,17 @@ public:
 void addLight( const RendererLight& light ){
        m_lights.push_back( &light );
 }
+
 void clear(){
        m_lights.clear();
 }
+
 void evaluateLights() const {
 }
+
 void lightsChanged() const {
 }
+
 void forEachLight( const RendererLightCallback& callback ) const {
        for ( Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i )
        {
@@ -2443,6 +2534,7 @@ FaceInstance( Face& face, const SelectionChangeCallback& observer ) :
        m_selectableEdges( observer ),
        m_selectionChanged( observer ){
 }
+
 FaceInstance( const FaceInstance& other ) :
        m_face( other.m_face ),
        m_selectable( SelectedChangedCaller( *this ) ),
@@ -2450,6 +2542,7 @@ FaceInstance( const FaceInstance& other ) :
        m_selectableEdges( other.m_selectableEdges ),
        m_selectionChanged( other.m_selectionChanged ){
 }
+
 FaceInstance& operator=( const FaceInstance& other ){
        m_face = other.m_face;
        return *this;
@@ -2458,6 +2551,7 @@ FaceInstance& operator=( const FaceInstance& other ){
 Face& getFace(){
        return *m_face;
 }
+
 const Face& getFace() const {
        return *m_face;
 }
@@ -2472,14 +2566,17 @@ void selectedChanged( const Selectable& selectable ){
        }
        m_selectionChanged( selectable );
 }
-typedef MemberCaller1<FaceInstance, const Selectable&, &FaceInstance::selectedChanged> SelectedChangedCaller;
+
+typedef MemberCaller<FaceInstance, void(const Selectable&), &FaceInstance::selectedChanged> SelectedChangedCaller;
 
 bool selectedVertices() const {
        return !m_vertexSelection.empty();
 }
+
 bool selectedEdges() const {
        return !m_edgeSelection.empty();
 }
+
 bool isSelected() const {
        return m_selectable.isSelected();
 }
@@ -2487,6 +2584,7 @@ bool isSelected() const {
 bool selectedComponents() const {
        return selectedVertices() || selectedEdges() || isSelected();
 }
+
 bool selectedComponents( SelectionSystem::EComponentMode mode ) const {
        switch ( mode )
        {
@@ -2500,6 +2598,7 @@ bool selectedComponents( SelectionSystem::EComponentMode mode ) const {
                return false;
        }
 }
+
 void setSelected( SelectionSystem::EComponentMode mode, bool select ){
        switch ( mode )
        {
@@ -2533,6 +2632,7 @@ void SelectedVertices_foreach( Functor functor ) const {
                }
        }
 }
+
 template<typename Functor>
 void SelectedEdges_foreach( Functor functor ) const {
        for ( VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i )
@@ -2545,6 +2645,7 @@ void SelectedEdges_foreach( Functor functor ) const {
                }
        }
 }
+
 template<typename Functor>
 void SelectedFaces_foreach( Functor functor ) const {
        if ( isSelected() ) {
@@ -2560,23 +2661,16 @@ void SelectedComponents_foreach( Functor functor ) const {
 }
 
 void iterate_selected( AABB& aabb ) const {
-       SelectedComponents_foreach( AABBExtendByPoint( aabb ) );
-}
-
-class RenderablePointVectorPushBack
-{
-RenderablePointVector& m_points;
-public:
-RenderablePointVectorPushBack( RenderablePointVector& points ) : m_points( points ){
-}
-void operator()( const Vector3& point ) const {
-       const Colour4b colour_selected( 0, 0, 255, 255 );
-       m_points.push_back( pointvertex_for_windingpoint( point, colour_selected ) );
+       SelectedComponents_foreach([&](const Vector3 &point) {
+               aabb_extend_by_point_safe(aabb, point);
+       });
 }
-};
 
 void iterate_selected( RenderablePointVector& points ) const {
-       SelectedComponents_foreach( RenderablePointVectorPushBack( points ) );
+       SelectedComponents_foreach([&](const Vector3 &point) {
+               const Colour4b colour_selected(0, 0, 255, 255);
+               points.push_back(pointvertex_for_windingpoint(point, colour_selected));
+       });
 }
 
 bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
@@ -2599,6 +2693,7 @@ void testSelect( SelectionTest& test, SelectionIntersection& best ){
                m_face->testSelect( test, best );
        }
 }
+
 void testSelect( Selector& selector, SelectionTest& test ){
        SelectionIntersection best;
        testSelect( test, best );
@@ -2606,6 +2701,7 @@ void testSelect( Selector& selector, SelectionTest& test ){
                Selector_add( selector, m_selectable, best );
        }
 }
+
 void testSelect_centroid( Selector& selector, SelectionTest& test ){
        if ( m_face->contributes() && !m_face->isFiltered() ) {
                SelectionIntersection best;
@@ -2630,6 +2726,7 @@ void selectPlane( Selector& selector, const Line& line, PlanesIterator first, Pl
 
        selectedPlaneCallback( getFace().plane3() );
 }
+
 void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlanes ){
        if ( selectedPlanes.contains( plane3_flipped( getFace().plane3() ) ) ) {
                Selector_add( selector, m_selectable );
@@ -2697,9 +2794,11 @@ void snapComponents( float snap ){
                m_face->freezeTransform();
        }
 }
+
 void update_move_planepts_vertex( std::size_t index ){
        m_face->update_move_planepts_vertex( index, m_face->m_move_planepts );
 }
+
 void update_move_planepts_vertex2( std::size_t index, std::size_t other ){
        const std::size_t numpoints = m_face->getWinding().numpoints;
        ASSERT_MESSAGE( index < numpoints, "select_vertex: invalid index" );
@@ -2727,6 +2826,7 @@ void update_move_planepts_vertex2( std::size_t index, std::size_t other ){
        m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex;
        planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
 }
+
 void update_selection_vertex(){
        if ( m_vertexSelection.size() == 0 ) {
                m_selectableVertices.setSelected( false );
@@ -2753,6 +2853,7 @@ void update_selection_vertex(){
                }
        }
 }
+
 void select_vertex( std::size_t index, bool select ){
        if ( select ) {
                VertexSelection_insert( m_vertexSelection, getFace().getWinding()[index].adjacent );
@@ -2781,6 +2882,7 @@ void update_move_planepts_edge( std::size_t index ){
        m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex;
        planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
 }
+
 void update_selection_edge(){
        if ( m_edgeSelection.size() == 0 ) {
                m_selectableEdges.setSelected( false );
@@ -2798,6 +2900,7 @@ void update_selection_edge(){
                }
        }
 }
+
 void select_edge( std::size_t index, bool select ){
        if ( select ) {
                VertexSelection_insert( m_edgeSelection, getFace().getWinding()[index].adjacent );
@@ -2838,6 +2941,7 @@ public:
 static void constructStatic(){
        m_state = GlobalShaderCache().capture( "$CLIPPER_OVERLAY" );
 }
+
 static void destroyStatic(){
        GlobalShaderCache().release( "$CLIPPER_OVERLAY" );
 }
@@ -2889,7 +2993,6 @@ inline void Face_addLight( const FaceInstance& face, const Matrix4& localToWorld
 }
 
 
-
 typedef std::vector<FaceInstance> FaceInstances;
 
 class EdgeInstance : public Selectable
@@ -2903,6 +3006,7 @@ void select_edge( bool select ){
        faceVertex = next_edge( m_edge->m_faces, faceVertex );
        m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select );
 }
+
 bool selected_edge() const {
        FaceVertexId faceVertex = m_edge->m_faceVertex;
        if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) {
@@ -2928,6 +3032,7 @@ EdgeInstance& operator=( const EdgeInstance& other ){
 void setSelected( bool select ){
        select_edge( select );
 }
+
 bool isSelected() const {
        return selected_edge();
 }
@@ -2956,6 +3061,7 @@ void select_vertex( bool select ){
        }
        while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
 }
+
 bool selected_vertex() const {
        FaceVertexId faceVertex = m_vertex->m_faceVertex;
        do
@@ -2981,6 +3087,7 @@ VertexInstance& operator=( const VertexInstance& other ){
 void setSelected( bool select ){
        select_vertex( select );
 }
+
 bool isSelected() const {
        return selected_vertex();
 }
@@ -3029,6 +3136,7 @@ TypeCasts(){
        InstanceIdentityCast<BrushInstance>::install( m_casts );
        InstanceContainedCast<BrushInstance, Transformable>::install( m_casts );
 }
+
 InstanceTypeCastTable& get(){
        return m_casts;
 }
@@ -3071,7 +3179,8 @@ typedef LazyStatic<TypeCasts> StaticTypeCasts;
 void lightsChanged(){
        m_lightList->lightsChanged();
 }
-typedef MemberCaller<BrushInstance, &BrushInstance::lightsChanged> LightsChangedCaller;
+
+typedef MemberCaller<BrushInstance, void(), &BrushInstance::lightsChanged> LightsChangedCaller;
 
 STRING_CONSTANT( Name, "BrushInstance" );
 
@@ -3092,10 +3201,11 @@ BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush )
 
        Instance::setTransformChangedCallback( LightsChangedCaller( *this ) );
 }
+
 ~BrushInstance(){
-       Instance::setTransformChangedCallback( Callback() );
+       Instance::setTransformChangedCallback( Callback<void()>() );
 
-       m_brush.m_lightsChanged = Callback();
+       m_brush.m_lightsChanged = Callback<void()>();
        GlobalShaderCache().detach( *this );
 
        m_counter->decrement();
@@ -3113,9 +3223,11 @@ const Brush& getBrush() const {
 Bounded& get( NullType<Bounded>){
        return m_brush;
 }
+
 Cullable& get( NullType<Cullable>){
        return m_brush;
 }
+
 Transformable& get( NullType<Transformable>){
        return m_transform;
 }
@@ -3126,13 +3238,13 @@ void selectedChanged( const Selectable& selectable ){
 
        Instance::selectedChanged();
 }
-typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChanged> SelectedChangedCaller;
+typedef MemberCaller<BrushInstance, void(const Selectable&), &BrushInstance::selectedChanged> SelectedChangedCaller;
 
 void selectedChangedComponent( const Selectable& selectable ){
        GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
        GlobalSelectionSystem().onComponentSelection( *this, selectable );
 }
-typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChangedComponent> SelectedChangedComponentCaller;
+typedef MemberCaller<BrushInstance, void(const Selectable&), &BrushInstance::selectedChangedComponent> SelectedChangedComponentCaller;
 
 const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& visitor ){
        for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
@@ -3145,6 +3257,7 @@ const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& vis
 static void constructStatic(){
        m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" );
 }
+
 static void destroyStatic(){
        GlobalShaderCache().release( "$SELPOINT" );
 }
@@ -3152,6 +3265,7 @@ static void destroyStatic(){
 void clear(){
        m_faceInstances.clear();
 }
+
 void reserve( std::size_t size ){
        m_faceInstances.reserve( size );
 }
@@ -3159,14 +3273,17 @@ void reserve( std::size_t size ){
 void push_back( Face& face ){
        m_faceInstances.push_back( FaceInstance( face, SelectedChangedComponentCaller( *this ) ) );
 }
+
 void pop_back(){
        ASSERT_MESSAGE( !m_faceInstances.empty(), "erasing invalid element" );
        m_faceInstances.pop_back();
 }
+
 void erase( std::size_t index ){
        ASSERT_MESSAGE( index < m_faceInstances.size(), "erasing invalid element" );
        m_faceInstances.erase( m_faceInstances.begin() + index );
 }
+
 void connectivityChanged(){
        for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
        {
@@ -3177,6 +3294,7 @@ void connectivityChanged(){
 void edge_clear(){
        m_edgeInstances.clear();
 }
+
 void edge_push_back( SelectableEdge& edge ){
        m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) );
 }
@@ -3184,6 +3302,7 @@ void edge_push_back( SelectableEdge& edge ){
 void vertex_clear(){
        m_vertexInstances.clear();
 }
+
 void vertex_push_back( SelectableVertex& vertex ){
        m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) );
 }
@@ -3195,6 +3314,7 @@ void DEBUG_verify() const {
 bool isSelected() const {
        return m_selectable.isSelected();
 }
+
 void setSelected( bool select ){
        m_selectable.setSelected( select );
 }
@@ -3346,12 +3466,14 @@ bool isSelectedComponents() const {
        }
        return false;
 }
+
 void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){
        for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
        {
                ( *i ).setSelected( mode, select );
        }
 }
+
 void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
        test.BeginMesh( localToWorld() );
 
@@ -3411,6 +3533,7 @@ void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback&
                ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), brushPlanes, j, selectedPlaneCallback );
        }
 }
+
 void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ){
        for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
        {
@@ -3425,6 +3548,7 @@ void transformComponents( const Matrix4& matrix ){
                ( *i ).transformComponents( matrix );
        }
 }
+
 const AABB& getSelectedComponentsBounds() const {
        m_aabb_component = AABB();
 
@@ -3442,6 +3566,7 @@ void snapComponents( float snap ){
                ( *i ).snapComponents( snap );
        }
 }
+
 void evaluateTransform(){
        Matrix4 matrix( m_transform.calculateTransform() );
        //globalOutputStream() << "matrix: " << matrix << "\n";
@@ -3454,12 +3579,14 @@ void evaluateTransform(){
                transformComponents( matrix );
        }
 }
+
 void applyTransform(){
        m_brush.revertTransform();
        evaluateTransform();
        m_brush.freezeTransform();
 }
-typedef MemberCaller<BrushInstance, &BrushInstance::applyTransform> ApplyTransformCaller;
+
+typedef MemberCaller<BrushInstance, void(), &BrushInstance::applyTransform> ApplyTransformCaller;
 
 void setClipPlane( const Plane3& plane ){
        m_clipPlane.setPlane( m_brush, plane );
@@ -3468,6 +3595,7 @@ void setClipPlane( const Plane3& plane ){
 bool testLight( const RendererLight& light ) const {
        return light.testAABB( worldAABB() );
 }
+
 void insertLight( const RendererLight& light ){
        const Matrix4& localToWorld = Instance::localToWorld();
        for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
@@ -3475,6 +3603,7 @@ void insertLight( const RendererLight& light ){
                Face_addLight( *i, localToWorld, light );
        }
 }
+
 void clearLights(){
        for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
        {
@@ -3495,6 +3624,7 @@ const Functor& m_functor;
 public:
 BrushSelectedVisitor( const Functor& functor ) : m_functor( functor ){
 }
+
 void visit( scene::Instance& instance ) const {
        BrushInstance* brush = Instance_getBrush( instance );
        if ( brush != 0 ) {
@@ -3516,6 +3646,7 @@ const Functor& m_functor;
 public:
 BrushVisibleSelectedVisitor( const Functor& functor ) : m_functor( functor ){
 }
+
 void visit( scene::Instance& instance ) const {
        BrushInstance* brush = Instance_getBrush( instance );
        if ( brush != 0
@@ -3537,6 +3668,7 @@ const BrushInstanceVisitor& m_visitor;
 public:
 BrushForEachFace( const BrushInstanceVisitor& visitor ) : m_visitor( visitor ){
 }
+
 void operator()( BrushInstance& brush ) const {
        brush.forEachFaceInstance( m_visitor );
 }
@@ -3550,6 +3682,7 @@ public:
 FaceInstanceVisitFace( const Functor& functor )
        : functor( functor ){
 }
+
 void visit( FaceInstance& face ) const {
        functor( face.getFace() );
 }
@@ -3569,6 +3702,7 @@ public:
 FaceVisitAll( const Functor& functor )
        : functor( functor ){
 }
+
 void visit( Face& face ) const {
        functor( face );
 }
@@ -3594,6 +3728,7 @@ public:
 FaceInstanceVisitAll( const Functor& functor )
        : functor( functor ){
 }
+
 void visit( FaceInstance& face ) const {
        functor( face );
 }
@@ -3617,6 +3752,7 @@ class InstanceIfVisible : public Functor
 public:
 InstanceIfVisible( const Functor& functor ) : Functor( functor ){
 }
+
 void operator()( scene::Instance& instance ){
        if ( instance.path().top().get().visible() ) {
                Functor::operator()( instance );
@@ -3631,6 +3767,7 @@ const Functor& m_functor;
 public:
 BrushVisibleWalker( const Functor& functor ) : m_functor( functor ){
 }
+
 bool pre( const scene::Path& path, scene::Instance& instance ) const {
        if ( path.top().get().visible() ) {
                BrushInstance* brush = Instance_getBrush( instance );