class FaceShaderObserver
{
public:
- virtual void realiseShader() = 0;
- virtual void unrealiseShader() = 0;
+ virtual void realiseShader() = 0;
-
+ virtual void unrealiseShader() = 0;
};
typedef ReferencePair<FaceShaderObserver> FaceShaderObserverPair;
class FaceShader : public ModuleObserver
{
public:
- class SavedState
- {
- public:
- CopiedString m_shader;
- ContentsFlagsValue m_flags;
+ class SavedState
+ {
+ public:
+ CopiedString m_shader;
+ ContentsFlagsValue m_flags;
- SavedState( const FaceShader& faceShader ){
- m_shader = faceShader.getShader();
- m_flags = faceShader.m_flags;
- }
+ SavedState( const FaceShader& faceShader ){
+ m_shader = faceShader.getShader();
+ m_flags = faceShader.m_flags;
+ }
- void exportState( FaceShader& faceShader ) const {
- faceShader.setShader( m_shader.c_str() );
+ void exportState( FaceShader& faceShader ) const {
+ faceShader.setShader( m_shader.c_str() );
- faceShader.setFlags( m_flags );
+ faceShader.m_flags = m_flags;
- }
- };
+ }
+ };
- CopiedString m_shader;
- Shader* m_state;
- ContentsFlagsValue m_flags;
- FaceShaderObserverPair m_observers;
- bool m_instanced;
- bool m_realised;
+ CopiedString m_shader;
+ Shader* m_state;
+ ContentsFlagsValue m_flags;
+ FaceShaderObserverPair m_observers;
+ bool m_instanced;
+ bool m_realised;
- FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsValue( 0, 0, 0, false ) ) :
- m_shader( shader ),
- m_state( 0 ),
- m_flags( flags ),
- m_instanced( false ),
- m_realised( false ){
- captureShader();
- }
+ FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsValue( 0, 0, 0, false ) ) :
+ m_shader( shader ),
+ m_state( 0 ),
+ m_flags( flags ),
+ m_instanced( false ),
+ m_realised( false ){
+ captureShader();
+ }
- ~FaceShader(){
- releaseShader();
- }
+ ~FaceShader(){
+ releaseShader();
+ }
- // copy-construction not supported
- FaceShader( const FaceShader& other );
+ // copy-construction not supported
+ FaceShader( const FaceShader& other );
- void instanceAttach(){
- m_instanced = true;
- m_state->incrementUsed();
- }
+ void instanceAttach(){
+ m_instanced = true;
+ m_state->incrementUsed();
+ }
- void instanceDetach(){
- m_state->decrementUsed();
- m_instanced = false;
- }
+ void instanceDetach(){
+ m_state->decrementUsed();
+ m_instanced = false;
+ }
- void captureShader(){
- ASSERT_MESSAGE( m_state == 0, "shader cannot be captured" );
- brush_check_shader( m_shader.c_str() );
- m_state = GlobalShaderCache().capture( m_shader.c_str() );
- m_state->attach( *this );
- }
+ void captureShader(){
+ ASSERT_MESSAGE( m_state == 0, "shader cannot be captured" );
+ brush_check_shader( m_shader.c_str() );
+ 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 );
- GlobalShaderCache().release( m_shader.c_str() );
- m_state = 0;
- }
+ void releaseShader(){
+ ASSERT_MESSAGE( m_state != 0, "shader cannot be released" );
+ m_state->detach( *this );
+ GlobalShaderCache().release( m_shader.c_str() );
+ m_state = 0;
+ }
- void realise(){
- ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" );
- m_realised = true;
- m_observers.forEach([](FaceShaderObserver &observer) {
- observer.realiseShader();
- });
- }
+ void realise(){
+ ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" );
+ m_realised = true;
+ m_observers.forEach([](FaceShaderObserver &observer) {
+ observer.realiseShader();
+ });
+ }
- void unrealise(){
- ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" );
- m_observers.forEach([](FaceShaderObserver &observer) {
- observer.unrealiseShader();
- });
- m_realised = false;
- }
+ void unrealise(){
+ ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" );
+ m_observers.forEach([](FaceShaderObserver &observer) {
+ observer.unrealiseShader();
+ });
+ m_realised = false;
+ }
- void attach( FaceShaderObserver& observer ){
- m_observers.attach( observer );
- if ( m_realised ) {
- observer.realiseShader();
- }
+ void attach( FaceShaderObserver& observer ){
+ m_observers.attach( observer );
+ if ( m_realised ) {
+ observer.realiseShader();
}
+ }
- void detach( FaceShaderObserver& observer ){
- if ( m_realised ) {
- observer.unrealiseShader();
- }
- m_observers.detach( observer );
+ void detach( FaceShaderObserver& observer ){
+ if ( m_realised ) {
+ observer.unrealiseShader();
}
+ m_observers.detach( observer );
+ }
- const char* getShader() const {
- return m_shader.c_str();
+ const char* getShader() const {
+ return m_shader.c_str();
+ }
+ void setShader( const char* name ){
+ if ( m_instanced ) {
+ m_state->decrementUsed();
}
- void setShader( const char* name ){
- if ( m_instanced ) {
- m_state->decrementUsed();
- }
- releaseShader();
- m_shader = name;
- captureShader();
- if ( m_instanced ) {
- m_state->incrementUsed();
- }
+ releaseShader();
+ m_shader = name;
+ captureShader();
+ if ( m_instanced ) {
+ m_state->incrementUsed();
}
+ }
- ContentsFlagsValue getFlags() const {
- ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" );
- if ( !m_flags.m_specified ) {
- return ContentsFlagsValue(
- m_state->getTexture().surfaceFlags,
- m_state->getTexture().contentFlags,
- m_state->getTexture().value,
- true
- );
- }
- return m_flags;
+ ContentsFlagsValue getFlags() const {
+ ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" );
+ if ( !m_flags.m_specified ) {
+ return ContentsFlagsValue(
+ m_state->getTexture().surfaceFlags,
+ m_state->getTexture().contentFlags,
+ m_state->getTexture().value,
+ true
+ );
}
+ return m_flags;
+ }
- void setFlags( const ContentsFlagsValue& flags ){
- ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" );
- ContentsFlagsValue_assignMasked( m_flags, flags );
- }
+ void setFlags( const ContentsFlagsValue& flags ){
+ ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" );
+ ContentsFlagsValue_assignMasked( m_flags, flags );
+ }
- Shader* state() const {
- return m_state;
- }
+ Shader* state() const {
+ return m_state;
+ }
- std::size_t width() const {
- if ( m_realised ) {
- return m_state->getTexture().width;
- }
- return 1;
+ std::size_t width() const {
+ if ( m_realised ) {
+ return m_state->getTexture().width;
}
+ return 1;
+ }
- std::size_t height() const {
- if ( m_realised ) {
- return m_state->getTexture().height;
- }
- 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();
- }
- return 0;
+ unsigned int shaderFlags() const {
+ if ( m_realised ) {
+ return m_state->getFlags();
}
+ return 0;
+ }
};
class FacePlane
{
- PlanePoints m_planepts;
- Plane3 m_planeCached;
- Plane3 m_plane;
+ PlanePoints m_planepts;
+ Plane3 m_planeCached;
+ Plane3 m_plane;
public:
- Vector3 m_funcStaticOrigin;
+ Vector3 m_funcStaticOrigin;
- static EBrushType m_type;
+ static EBrushType m_type;
- static bool isDoom3Plane(){
- return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4;
- }
+ static bool isDoom3Plane(){
+ return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4;
+ }
- class SavedState
+ FacePlane& operator=(const FacePlane&) = default;
+
+ class SavedState
+ {
+ public:
+ PlanePoints m_planepts;
+ Plane3 m_plane;
+
+ SavedState( const FacePlane& facePlane ){
+ if ( facePlane.isDoom3Plane() ) {
+ m_plane = facePlane.m_plane;
+ }
+ else
{
- public:
- PlanePoints m_planepts;
- Plane3 m_plane;
+ planepts_assign( m_planepts, facePlane.planePoints() );
+ }
+ }
- SavedState( const FacePlane& facePlane ){
- if ( facePlane.isDoom3Plane() ) {
- m_plane = facePlane.m_plane;
- }
- else
- {
- planepts_assign( m_planepts, facePlane.planePoints() );
- }
- }
+ void exportState( FacePlane& facePlane ) const {
+ if ( facePlane.isDoom3Plane() ) {
+ facePlane.m_plane = m_plane;
+ facePlane.updateTranslated();
+ }
+ else
+ {
+ planepts_assign( facePlane.planePoints(), m_planepts );
+ facePlane.MakePlane();
+ }
+ }
+ };
- void exportState( FacePlane& facePlane ) const {
- if ( facePlane.isDoom3Plane() ) {
- facePlane.m_plane = m_plane;
- facePlane.updateTranslated();
- }
- else
- {
- planepts_assign( facePlane.planePoints(), m_planepts );
- facePlane.MakePlane();
- }
- }
- };
+ FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){
+ }
- FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){
+ FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){
+ if ( !isDoom3Plane() ) {
+ planepts_assign( m_planepts, other.m_planepts );
+ MakePlane();
}
-
- FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){
- if ( !isDoom3Plane() ) {
- planepts_assign( m_planepts, other.m_planepts );
- MakePlane();
- }
- else
- {
- m_plane = other.m_plane;
- updateTranslated();
- }
+ else
+ {
+ m_plane = other.m_plane;
+ updateTranslated();
}
+ }
- void MakePlane(){
- if ( !isDoom3Plane() ) {
+ void MakePlane(){
+ if ( !isDoom3Plane() ) {
#if 0
- if ( check_plane_is_integer( m_planepts ) ) {
- globalErrorStream() << "non-integer planepts: ";
- planepts_print( m_planepts, globalErrorStream() );
- globalErrorStream() << "\n";
- }
- #endif
- m_planeCached = plane3_for_points( m_planepts );
+ if ( check_plane_is_integer( m_planepts ) ) {
+ globalErrorStream() << "non-integer planepts: ";
+ planepts_print( m_planepts, globalErrorStream() );
+ globalErrorStream() << "\n";
}
+ #endif
+ m_planeCached = plane3_for_points( m_planepts );
}
+ }
- void reverse(){
- if ( !isDoom3Plane() ) {
- vector3_swap( m_planepts[0], m_planepts[2] );
- MakePlane();
- }
- else
- {
- m_planeCached = plane3_flipped( m_plane );
- updateSource();
- }
+ void reverse(){
+ if ( !isDoom3Plane() ) {
+ vector3_swap( m_planepts[0], m_planepts[2] );
+ MakePlane();
}
+ else
+ {
+ m_planeCached = plane3_flipped( m_plane );
+ updateSource();
+ }
+ }
- void transform( const Matrix4& matrix, bool mirror ){
- if ( !isDoom3Plane() ) {
+ void transform( const Matrix4& matrix, bool mirror ){
+ if ( !isDoom3Plane() ) {
#if 0
- bool off = check_plane_is_integer( planePoints() );
+ bool off = check_plane_is_integer( planePoints() );
#endif
- matrix4_transform_point( matrix, m_planepts[0] );
- matrix4_transform_point( matrix, m_planepts[1] );
- matrix4_transform_point( matrix, m_planepts[2] );
+ matrix4_transform_point( matrix, m_planepts[0] );
+ matrix4_transform_point( matrix, m_planepts[1] );
+ matrix4_transform_point( matrix, m_planepts[2] );
- if ( mirror ) {
- reverse();
- }
+ if ( mirror ) {
+ reverse();
+ }
#if 0
- if ( check_plane_is_integer( planePoints() ) ) {
- if ( !off ) {
- globalErrorStream() << "caused by transform\n";
- }
+ if ( check_plane_is_integer( planePoints() ) ) {
+ if ( !off ) {
+ globalErrorStream() << "caused by transform\n";
}
- #endif
- MakePlane();
- }
- else
- {
- m_planeCached = Plane3_applyTransform( m_planeCached, matrix );
- updateSource();
}
+ #endif
+ MakePlane();
+ }
+ else
+ {
+ m_planeCached = Plane3_applyTransform( m_planeCached, matrix );
+ updateSource();
}
+ }
- void offset( float offset ){
- if ( !isDoom3Plane() ) {
- Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) );
+ void offset( float offset ){
+ if ( !isDoom3Plane() ) {
+ Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) );
- vector3_subtract( m_planepts[0], move );
- vector3_subtract( m_planepts[1], move );
- vector3_subtract( m_planepts[2], move );
+ vector3_subtract( m_planepts[0], move );
+ vector3_subtract( m_planepts[1], move );
+ vector3_subtract( m_planepts[2], move );
- MakePlane();
- }
- else
- {
- m_planeCached.d += offset;
- updateSource();
- }
+ MakePlane();
}
-
- void updateTranslated(){
- m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin );
+ else
+ {
+ m_planeCached.d += offset;
+ updateSource();
}
+ }
- void updateSource(){
- m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) );
- }
+ void updateTranslated(){
+ m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin );
+ }
+ void updateSource(){
+ m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) );
+ }
- PlanePoints& planePoints(){
- return m_planepts;
- }
- const PlanePoints& planePoints() const {
- return m_planepts;
- }
+ PlanePoints& planePoints(){
+ return m_planepts;
+ }
- const Plane3& plane3() const {
- return m_planeCached;
- }
+ const PlanePoints& planePoints() const {
+ return m_planepts;
+ }
- void setDoom3Plane( const Plane3& plane ){
- m_plane = plane;
- updateTranslated();
- }
+ const Plane3& plane3() const {
+ return m_planeCached;
+ }
- const Plane3& getDoom3Plane() const {
- return m_plane;
- }
+ void setDoom3Plane( const Plane3& plane ){
+ m_plane = plane;
+ updateTranslated();
+ }
- void copy( const FacePlane& other ){
- if ( !isDoom3Plane() ) {
- planepts_assign( m_planepts, other.m_planepts );
- MakePlane();
- }
- else
- {
- m_planeCached = other.m_plane;
- updateSource();
- }
+ const Plane3& getDoom3Plane() const {
+ return m_plane;
+ }
+
+ void copy( const FacePlane& other ){
+ if ( !isDoom3Plane() ) {
+ planepts_assign( m_planepts, other.m_planepts );
+ MakePlane();
+ }
+ else
+ {
+ m_planeCached = other.m_plane;
+ updateSource();
}
+ }
- void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
- if ( !isDoom3Plane() ) {
- m_planepts[0] = p0;
- m_planepts[1] = p1;
- m_planepts[2] = p2;
- MakePlane();
- }
- else
- {
- m_planeCached = plane3_for_points( p2, p1, p0 );
- updateSource();
- }
+ void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
+ if ( !isDoom3Plane() ) {
+ m_planepts[0] = p0;
+ m_planepts[1] = p1;
+ m_planepts[2] = p2;
+ MakePlane();
+ }
+ else
+ {
+ m_planeCached = plane3_for_points( p2, p1, p0 );
+ updateSource();
}
+ }
};
inline void Winding_testSelect( Winding& winding, SelectionTest& test, SelectionIntersection& best ){
class FaceObserver
{
public:
- virtual void planeChanged() = 0;
- virtual void connectivityChanged() = 0;
- virtual void shaderChanged() = 0;
- virtual void evaluateTransform() = 0;
+ virtual void planeChanged() = 0;
-
+ virtual void connectivityChanged() = 0;
-
+ virtual void shaderChanged() = 0;
-
+ virtual void evaluateTransform() = 0;
};
class Face :
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;
+ 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;
};
class BrushVisitor
public BrushDoom3
{
private:
- scene::Node* m_node;
- typedef UniqueSet<BrushObserver*> Observers;
- Observers m_observers;
- UndoObserver* m_undoable_observer;
- MapFile* m_map;
+ scene::Node* m_node;
+ typedef UniqueSet<BrushObserver*> Observers;
+ Observers m_observers;
+ UndoObserver* m_undoable_observer;
+ MapFile* m_map;
- // state
- Faces m_faces;
- // ----
+ // state
+ Faces m_faces;
+ // ----
- // cached data compiled from state
- Array<PointVertex> m_faceCentroidPoints;
- RenderablePointArray m_render_faces;
+ // cached data compiled from state
+ Array<PointVertex> m_faceCentroidPoints;
+ RenderablePointArray m_render_faces;
- Array<PointVertex> m_uniqueVertexPoints;
- typedef std::vector<SelectableVertex> SelectableVertices;
- SelectableVertices m_select_vertices;
- RenderablePointArray m_render_vertices;
+ Array<PointVertex> m_uniqueVertexPoints;
+ typedef std::vector<SelectableVertex> SelectableVertices;
+ SelectableVertices m_select_vertices;
+ RenderablePointArray m_render_vertices;
- Array<PointVertex> m_uniqueEdgePoints;
- typedef std::vector<SelectableEdge> SelectableEdges;
- SelectableEdges m_select_edges;
- RenderablePointArray m_render_edges;
+ Array<PointVertex> m_uniqueEdgePoints;
+ typedef std::vector<SelectableEdge> SelectableEdges;
+ SelectableEdges m_select_edges;
+ RenderablePointArray m_render_edges;
- Array<EdgeRenderIndices> m_edge_indices;
- Array<EdgeFaces> m_edge_faces;
+ Array<EdgeRenderIndices> m_edge_indices;
+ Array<EdgeFaces> m_edge_faces;
- AABB m_aabb_local;
- // ----
+ AABB m_aabb_local;
+ // ----
- Callback<void()> m_evaluateTransform;
- Callback<void()> 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
- // ----
+ mutable bool m_planeChanged; // b-rep evaluation required
+ mutable bool m_transformChanged; // transform evaluation required
+ // ----
public:
- STRING_CONSTANT( Name, "Brush" );
-
- Callback<void()> m_lightsChanged;
-
- // static data
- static Shader* m_state_point;
- // ----
-
- static EBrushType m_type;
- static double m_maxWorldCoord;
-
- Brush( scene::Node& node, const Callback<void()>& evaluateTransform, const Callback<void()>& boundsChanged ) :
- m_node( &node ),
- m_undoable_observer( 0 ),
- m_map( 0 ),
- m_render_faces( m_faceCentroidPoints, GL_POINTS ),
- m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
- m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
- m_evaluateTransform( evaluateTransform ),
- m_boundsChanged( boundsChanged ),
- m_planeChanged( false ),
- m_transformChanged( false ){
- planeChanged();
- }
- 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 ),
- m_render_faces( m_faceCentroidPoints, GL_POINTS ),
- m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
- m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
- m_evaluateTransform( evaluateTransform ),
- m_boundsChanged( boundsChanged ),
- m_planeChanged( false ),
- m_transformChanged( false ){
- copy( other );
- }
-
- Brush( const Brush& other ) :
- TransformNode( other ),
- Bounded( other ),
- Cullable( other ),
- Snappable(),
- Undoable( other ),
- FaceObserver( other ),
- Filterable( other ),
- Nameable( other ),
- BrushDoom3( other ),
- m_node( 0 ),
- m_undoable_observer( 0 ),
- m_map( 0 ),
- m_render_faces( m_faceCentroidPoints, GL_POINTS ),
- m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
- m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
- m_planeChanged( false ),
- m_transformChanged( false ){
- copy( other );
- }
-
- ~Brush(){
- ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" );
- }
-
- // assignment not supported
- Brush& operator=( const Brush& other );
-
- void setDoom3GroupOrigin( const Vector3& origin ){
- //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n";
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->getPlane().m_funcStaticOrigin = origin;
- ( *i )->getPlane().updateTranslated();
- ( *i )->planeChanged();
- }
- planeChanged();
- }
+ STRING_CONSTANT( Name, "Brush" );
- void attach( BrushObserver& observer ){
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- observer.push_back( *( *i ) );
- }
+ Callback<void()> m_lightsChanged;
- for ( SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i )
- {
- observer.edge_push_back( *i );
- }
+ // static data
+ static Shader* m_state_point;
+ // ----
- for ( SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i )
- {
- observer.vertex_push_back( *i );
- }
+ static EBrushType m_type;
+ static double m_maxWorldCoord;
- m_observers.insert( &observer );
- }
+ Brush( scene::Node& node, const Callback<void()>& evaluateTransform, const Callback<void()>& boundsChanged ) :
+ m_node( &node ),
+ m_undoable_observer( 0 ),
+ m_map( 0 ),
+ m_render_faces( m_faceCentroidPoints, GL_POINTS ),
+ m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
+ m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
+ m_evaluateTransform( evaluateTransform ),
+ m_boundsChanged( boundsChanged ),
+ m_planeChanged( false ),
+ m_transformChanged( false ){
+ planeChanged();
+ }
+ 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 ),
+ m_render_faces( m_faceCentroidPoints, GL_POINTS ),
+ m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
+ m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
+ m_evaluateTransform( evaluateTransform ),
+ m_boundsChanged( boundsChanged ),
+ m_planeChanged( false ),
+ m_transformChanged( false ){
+ copy( other );
+ }
+
+ Brush( const Brush& other ) :
+ TransformNode( other ),
+ Bounded( other ),
+ Cullable( other ),
+ Snappable(),
+ Undoable( other ),
+ FaceObserver( other ),
+ Filterable( other ),
+ Nameable( other ),
+ BrushDoom3( other ),
+ m_node( 0 ),
+ m_undoable_observer( 0 ),
+ m_map( 0 ),
+ m_render_faces( m_faceCentroidPoints, GL_POINTS ),
+ m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
+ m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
+ m_planeChanged( false ),
+ m_transformChanged( false ){
+ copy( other );
+ }
+
+ ~Brush(){
+ ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" );
+ }
+
+ // assignment not supported
+ Brush& operator=( const Brush& other );
- void detach( BrushObserver& observer ){
- m_observers.erase( &observer );
+ void setDoom3GroupOrigin( const Vector3& origin ){
+ //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n";
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->getPlane().m_funcStaticOrigin = origin;
+ ( *i )->getPlane().updateTranslated();
+ ( *i )->planeChanged();
}
+ planeChanged();
+ }
- void forEachFace( const BrushVisitor& visitor ) const {
- for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- visitor.visit( *( *i ) );
- }
+ void attach( BrushObserver& observer ){
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ observer.push_back( *( *i ) );
}
- void forEachFace_instanceAttach( MapFile* map ) const {
- for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->instanceAttach( map );
- }
+ for ( SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i )
+ {
+ observer.edge_push_back( *i );
}
- void forEachFace_instanceDetach( MapFile* map ) const {
- for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->instanceDetach( map );
- }
+ for ( SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i )
+ {
+ observer.vertex_push_back( *i );
}
- InstanceCounter m_instanceCounter;
+ m_observers.insert( &observer );
+ }
- void instanceAttach( const scene::Path& path ){
- if ( ++m_instanceCounter.m_count == 1 ) {
- m_map = path_find_mapfile( path.begin(), path.end() );
- m_undoable_observer = GlobalUndoSystem().observer( this );
- GlobalFilterSystem().registerFilterable( *this );
- forEachFace_instanceAttach( m_map );
- }
- else
- {
- ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" );
- }
- }
+ void detach( BrushObserver& observer ){
+ m_observers.erase( &observer );
+ }
- void instanceDetach( const scene::Path& path ){
- if ( --m_instanceCounter.m_count == 0 ) {
- forEachFace_instanceDetach( m_map );
- GlobalFilterSystem().unregisterFilterable( *this );
- m_map = 0;
- m_undoable_observer = 0;
- GlobalUndoSystem().release( this );
- }
+ void forEachFace( const BrushVisitor& visitor ) const {
+ for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ visitor.visit( *( *i ) );
}
+ }
- // nameable
- const char* name() const {
- return "brush";
+ void forEachFace_instanceAttach( MapFile* map ) const {
+ for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->instanceAttach( map );
}
+ }
- void attach( const NameCallback& callback ){
+ void forEachFace_instanceDetach( MapFile* map ) const {
+ for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->instanceDetach( map );
}
+ }
- void detach( const NameCallback& callback ){
- }
+ InstanceCounter m_instanceCounter;
- // filterable
- void updateFiltered(){
- if ( m_node != 0 ) {
- if ( brush_filtered( *this ) ) {
- m_node->enable( scene::Node::eFiltered );
- }
- else
- {
- m_node->disable( scene::Node::eFiltered );
- }
- }
+ void instanceAttach( const scene::Path& path ){
+ if ( ++m_instanceCounter.m_count == 1 ) {
+ m_map = path_find_mapfile( path.begin(), path.end() );
+ m_undoable_observer = GlobalUndoSystem().observer( this );
+ GlobalFilterSystem().registerFilterable( *this );
+ forEachFace_instanceAttach( m_map );
}
-
- // observer
- void planeChanged(){
- m_planeChanged = true;
- aabbChanged();
- m_lightsChanged();
+ else
+ {
+ ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" );
}
+ }
- void shaderChanged(){
- updateFiltered();
- planeChanged();
+ void instanceDetach( const scene::Path& path ){
+ if ( --m_instanceCounter.m_count == 0 ) {
+ forEachFace_instanceDetach( m_map );
+ GlobalFilterSystem().unregisterFilterable( *this );
+ m_map = 0;
+ m_undoable_observer = 0;
+ GlobalUndoSystem().release( this );
}
+ }
- void evaluateBRep() const {
- if ( m_planeChanged ) {
- m_planeChanged = false;
- const_cast<Brush*>( this )->buildBRep();
- }
- }
+ // nameable
+ const char* name() const {
+ return "brush";
+ }
- void transformChanged(){
- m_transformChanged = true;
- planeChanged();
- }
+ void attach( const NameCallback& callback ){
+ }
- typedef MemberCaller<Brush, void(), &Brush::transformChanged> TransformChangedCaller;
+ void detach( const NameCallback& callback ){
+ }
- void evaluateTransform(){
- if ( m_transformChanged ) {
- m_transformChanged = false;
- revertTransform();
- m_evaluateTransform();
+ // filterable
+ void updateFiltered(){
+ if ( m_node != 0 ) {
+ if ( brush_filtered( *this ) ) {
+ m_node->enable( scene::Node::eFiltered );
+ }
+ else
+ {
+ m_node->disable( scene::Node::eFiltered );
}
}
+ }
- const Matrix4& localToParent() const {
- return g_matrix4_identity;
- }
+ // observer
+ void planeChanged(){
+ m_planeChanged = true;
+ aabbChanged();
+ m_lightsChanged();
+ }
- void aabbChanged(){
- m_boundsChanged();
- }
+ void shaderChanged(){
+ updateFiltered();
+ planeChanged();
+ }
- const AABB& localAABB() const {
- evaluateBRep();
- return m_aabb_local;
+ void evaluateBRep() const {
+ if ( m_planeChanged ) {
+ m_planeChanged = false;
+ const_cast<Brush*>( this )->buildBRep();
}
+ }
- VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const {
- return test.TestAABB( m_aabb_local, localToWorld );
- }
+ void transformChanged(){
+ m_transformChanged = true;
+ planeChanged();
+ }
- void renderComponents( SelectionSystem::EComponentMode mode, Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
- switch ( mode )
- {
- case SelectionSystem::eVertex:
- renderer.addRenderable( m_render_vertices, localToWorld );
- break;
- case SelectionSystem::eEdge:
- renderer.addRenderable( m_render_edges, localToWorld );
- break;
- case SelectionSystem::eFace:
- renderer.addRenderable( m_render_faces, localToWorld );
- break;
- default:
- break;
- }
+ typedef MemberCaller<Brush, void(), &Brush::transformChanged> TransformChangedCaller;
+
+ void evaluateTransform(){
+ if ( m_transformChanged ) {
+ m_transformChanged = false;
+ revertTransform();
+ m_evaluateTransform();
}
+ }
- void transform( const Matrix4& matrix ){
- bool mirror = matrix4_handedness( matrix ) == MATRIX4_LEFTHANDED;
+ const Matrix4& localToParent() const {
+ return g_matrix4_identity;
+ }
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->transform( matrix, mirror );
- }
- }
+ void aabbChanged(){
+ m_boundsChanged();
+ }
- void snapto( float snap ){
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->snapto( snap );
- }
+ const AABB& localAABB() const {
+ evaluateBRep();
+ return m_aabb_local;
+ }
+
+ VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const {
+ return test.TestAABB( m_aabb_local, localToWorld );
+ }
+
+ void renderComponents( SelectionSystem::EComponentMode mode, Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
+ switch ( mode )
+ {
+ case SelectionSystem::eVertex:
+ renderer.addRenderable( m_render_vertices, localToWorld );
+ break;
+ case SelectionSystem::eEdge:
+ renderer.addRenderable( m_render_edges, localToWorld );
+ break;
+ case SelectionSystem::eFace:
+ renderer.addRenderable( m_render_faces, localToWorld );
+ break;
+ default:
+ break;
}
+ }
- void revertTransform(){
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->revertTransform();
- }
+ void transform( const Matrix4& matrix ){
+ bool mirror = matrix4_handedness( matrix ) == MATRIX4_LEFTHANDED;
+
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->transform( matrix, mirror );
}
+ }
- void freezeTransform(){
- for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
- {
- ( *i )->freezeTransform();
- }
+ void snapto( float snap ){
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->snapto( snap );
}
+ }
- /// \brief Returns the absolute index of the \p faceVertex.
- std::size_t absoluteIndex( FaceVertexId faceVertex ){
- std::size_t index = 0;
- for ( std::size_t i = 0; i < faceVertex.getFace(); ++i )
- {
- index += m_faces[i]->getWinding().numpoints;
- }
- return index + faceVertex.getVertex();
+ void revertTransform(){
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->revertTransform();
}
+ }
- void appendFaces( const Faces& other ){
- clear();
- for ( Faces::const_iterator i = other.begin(); i != other.end(); ++i )
- {
- push_back( *i );
- }
+ void freezeTransform(){
+ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
+ {
+ ( *i )->freezeTransform();
}
+ }
- /// \brief The undo memento for a brush stores only the list of face references - the faces are not copied.
- class BrushUndoMemento : public UndoMemento
+ /// \brief Returns the absolute index of the \p faceVertex.
+ std::size_t absoluteIndex( FaceVertexId faceVertex ){
+ std::size_t index = 0;
+ for ( std::size_t i = 0; i < faceVertex.getFace(); ++i )
{
- public:
- BrushUndoMemento( const Faces& faces ) : m_faces( faces ){
+ index += m_faces[i]->getWinding().numpoints;
}
+ return index + faceVertex.getVertex();
+ }
- void release(){
- delete this;
+ void appendFaces( const Faces& other ){
+ clear();
+ for ( Faces::const_iterator i = other.begin(); i != other.end(); ++i )
+ {
+ push_back( *i );
}
+ }
- Faces m_faces;
- };
+ /// \brief The undo memento for a brush stores only the list of face references - the faces are not copied.
+ class BrushUndoMemento : public UndoMemento
+ {
+ public:
+ BrushUndoMemento( const Faces& faces ) : m_faces( faces ){
+ }
- void undoSave(){
- if ( m_map != 0 ) {
- m_map->changed();
- }
- if ( m_undoable_observer != 0 ) {
- m_undoable_observer->save( this );
- }
- }
+ void release(){
+ delete this;
+ }
- UndoMemento* exportState() const {
- return new BrushUndoMemento( m_faces );
+ Faces m_faces;
+ };
+
+ void undoSave(){
+ if ( m_map != 0 ) {
+ m_map->changed();
}
+ if ( m_undoable_observer != 0 ) {
+ m_undoable_observer->save( this );
+ }
+ }
- void importState( const UndoMemento* state ){
- undoSave();
- appendFaces( static_cast<const BrushUndoMemento*>( state )->m_faces );
- planeChanged();
+ UndoMemento* exportState() const {
+ return new BrushUndoMemento( m_faces );
+ }
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->DEBUG_verify();
- }
- }
+ void importState( const UndoMemento* state ){
+ undoSave();
+ appendFaces( static_cast<const BrushUndoMemento*>( state )->m_faces );
+ planeChanged();
- bool isDetail(){
- return !m_faces.empty() && m_faces.front()->isDetail();
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->DEBUG_verify();
}
+ }
+
+ bool isDetail(){
+ return !m_faces.empty() && m_faces.front()->isDetail();
+ }
- /// \brief Appends a copy of \p face to the end of the face list.
+ /// \brief Appends a copy of \p face to the end of the face list.
-Face* addFace( const Face& face ){
+ std::shared_ptr<Face> addFace( const Face& face ){
- if ( m_faces.size() == c_brush_maxFaces ) {
- return 0;
- }
- undoSave();
- push_back( std::make_shared<Face>( face, this ) );
- m_faces.back()->setDetail( isDetail() );
- planeChanged();
- return m_faces.back();
+ if ( m_faces.size() == c_brush_maxFaces ) {
+ return 0;
}
- push_back( FaceSmartPointer( new Face( face, this ) ) );
+ undoSave();
++ push_back( std::make_shared<Face>( face, this ) );
+ m_faces.back()->setDetail( isDetail() );
+ planeChanged();
+ return m_faces.back();
+ }
- /// \brief Appends a new face constructed from the parameters to the end of the face list.
+ /// \brief Appends a new face constructed from the parameters to the end of the face list.
-Face* addPlane( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection ){
+ std::shared_ptr<Face> addPlane( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection ){
- if ( m_faces.size() == c_brush_maxFaces ) {
- return 0;
- }
- undoSave();
- push_back( std::make_shared<Face>( p0, p1, p2, shader, projection, this ) );
- m_faces.back()->setDetail( isDetail() );
- planeChanged();
- return m_faces.back();
+ if ( m_faces.size() == c_brush_maxFaces ) {
+ return 0;
}
- push_back( FaceSmartPointer( new Face( p0, p1, p2, shader, projection, this ) ) );
+ undoSave();
++ push_back( std::make_shared<Face>( p0, p1, p2, shader, projection, this ) );
+ m_faces.back()->setDetail( isDetail() );
+ planeChanged();
+ return m_faces.back();
+ }
- static void constructStatic( EBrushType type ){
- m_type = type;
- Face::m_type = type;
- FacePlane::m_type = type;
+ static void constructStatic( EBrushType type ){
+ m_type = type;
+ Face::m_type = type;
+ FacePlane::m_type = type;
- g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE;
- if ( m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4 ) {
- g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
- // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
- }
- else if ( m_type == eBrushTypeHalfLife ) {
- g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE;
- // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
- }
+ g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE;
+ if ( m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4 ) {
+ g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
+ // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
+ }
+ else if ( m_type == eBrushTypeHalfLife ) {
+ g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE;
+ // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
+ }
- Face::m_quantise = ( m_type == eBrushTypeQuake ) ? quantiseInteger : quantiseFloating;
+ Face::m_quantise = ( m_type == eBrushTypeQuake ) ? quantiseInteger : quantiseFloating;
- m_state_point = GlobalShaderCache().capture( "$POINT" );
- }
+ m_state_point = GlobalShaderCache().capture( "$POINT" );
+ }
- static void destroyStatic(){
- GlobalShaderCache().release( "$POINT" );
- }
+ static void destroyStatic(){
+ GlobalShaderCache().release( "$POINT" );
+ }
- std::size_t DEBUG_size(){
- return m_faces.size();
- }
+ std::size_t DEBUG_size(){
+ return m_faces.size();
+ }
- typedef Faces::const_iterator const_iterator;
+ typedef Faces::const_iterator const_iterator;
- const_iterator begin() const {
- return m_faces.begin();
- }
+ const_iterator begin() const {
+ return m_faces.begin();
+ }
- const_iterator end() const {
- return m_faces.end();
- }
+ const_iterator end() const {
+ return m_faces.end();
+ }
-Face* back(){
+ std::shared_ptr<Face> back(){
- return m_faces.back();
- }
+ return m_faces.back();
+ }
-const Face* back() const {
+ const std::shared_ptr<Face> back() const {
- return m_faces.back();
- }
+ 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 )
- {
- ( *i )->reserve( count );
- }
+ void reserve( std::size_t count ){
+ m_faces.reserve( count );
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->reserve( count );
}
+ }
- void push_back( Faces::value_type face ){
- m_faces.push_back( face );
- if ( m_instanceCounter.m_count != 0 ) {
- m_faces.back()->instanceAttach( m_map );
- }
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->push_back( *face );
- ( *i )->DEBUG_verify();
- }
+ void push_back( Faces::value_type face ){
+ m_faces.push_back( face );
+ if ( m_instanceCounter.m_count != 0 ) {
+ m_faces.back()->instanceAttach( m_map );
+ }
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->push_back( *face );
+ ( *i )->DEBUG_verify();
}
+ }
- void pop_back(){
- if ( m_instanceCounter.m_count != 0 ) {
- m_faces.back()->instanceDetach( m_map );
- }
- m_faces.pop_back();
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->pop_back();
- ( *i )->DEBUG_verify();
- }
+ void pop_back(){
+ if ( m_instanceCounter.m_count != 0 ) {
+ m_faces.back()->instanceDetach( m_map );
+ }
+ m_faces.pop_back();
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->pop_back();
+ ( *i )->DEBUG_verify();
}
+ }
- void erase( std::size_t index ){
- if ( m_instanceCounter.m_count != 0 ) {
- m_faces[index]->instanceDetach( m_map );
- }
- m_faces.erase( m_faces.begin() + index );
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->erase( index );
- ( *i )->DEBUG_verify();
- }
+ void erase( std::size_t index ){
+ if ( m_instanceCounter.m_count != 0 ) {
+ m_faces[index]->instanceDetach( m_map );
+ }
+ m_faces.erase( m_faces.begin() + index );
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->erase( index );
+ ( *i )->DEBUG_verify();
}
+ }
- void connectivityChanged(){
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->connectivityChanged();
- }
+ void connectivityChanged(){
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->connectivityChanged();
}
+ }
- void clear(){
- undoSave();
- if ( m_instanceCounter.m_count != 0 ) {
- forEachFace_instanceDetach( m_map );
- }
- m_faces.clear();
- for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
- {
- ( *i )->clear();
- ( *i )->DEBUG_verify();
- }
+ void clear(){
+ undoSave();
+ if ( m_instanceCounter.m_count != 0 ) {
+ forEachFace_instanceDetach( m_map );
}
-
- std::size_t size() const {
- return m_faces.size();
+ m_faces.clear();
+ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
+ {
+ ( *i )->clear();
+ ( *i )->DEBUG_verify();
}
+ }
- bool empty() const {
- return m_faces.empty();
- }
+ std::size_t size() const {
+ return m_faces.size();
+ }
- /// \brief Returns true if any face of the brush contributes to the final B-Rep.
- bool hasContributingFaces() const {
- for ( const_iterator i = begin(); i != end(); ++i )
- {
- if ( ( *i )->contributes() ) {
- return true;
- }
+ bool empty() const {
+ return m_faces.empty();
+ }
+
+ /// \brief Returns true if any face of the brush contributes to the final B-Rep.
+ bool hasContributingFaces() const {
+ for ( const_iterator i = begin(); i != end(); ++i )
+ {
+ if ( ( *i )->contributes() ) {
+ return true;
}
- return false;
}
+ return false;
+ }
- /// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush.
- /// Note: removal of empty faces is not performed during direct brush manipulations, because it would make a manipulation irreversible if it created an empty face.
- void removeEmptyFaces(){
- evaluateBRep();
+ /// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush.
+ /// Note: removal of empty faces is not performed during direct brush manipulations, because it would make a manipulation irreversible if it created an empty face.
+ void removeEmptyFaces(){
+ evaluateBRep();
+ {
+ std::size_t i = 0;
+ while ( i < m_faces.size() )
{
- std::size_t i = 0;
- while ( i < m_faces.size() )
+ if ( !m_faces[i]->contributes() ) {
+ erase( i );
+ planeChanged();
+ }
+ else
{
- if ( !m_faces[i]->contributes() ) {
- erase( i );
- planeChanged();
- }
- else
- {
- ++i;
- }
+ ++i;
}
}
}
public PlaneSelectable,
public LightCullable
{
- class TypeCasts
- {
- InstanceTypeCastTable m_casts;
- public:
- TypeCasts(){
- InstanceStaticCast<BrushInstance, Selectable>::install( m_casts );
- InstanceContainedCast<BrushInstance, Bounded>::install( m_casts );
- InstanceContainedCast<BrushInstance, Cullable>::install( m_casts );
- InstanceStaticCast<BrushInstance, Renderable>::install( m_casts );
- InstanceStaticCast<BrushInstance, SelectionTestable>::install( m_casts );
- InstanceStaticCast<BrushInstance, ComponentSelectionTestable>::install( m_casts );
- InstanceStaticCast<BrushInstance, ComponentEditable>::install( m_casts );
- InstanceStaticCast<BrushInstance, ComponentSnappable>::install( m_casts );
- InstanceStaticCast<BrushInstance, PlaneSelectable>::install( m_casts );
- InstanceIdentityCast<BrushInstance>::install( m_casts );
- InstanceContainedCast<BrushInstance, Transformable>::install( m_casts );
- }
-
- InstanceTypeCastTable& get(){
- return m_casts;
- }
- };
+ class TypeCasts
+ {
+ InstanceTypeCastTable m_casts;
+ public:
+ TypeCasts(){
+ InstanceStaticCast<BrushInstance, Selectable>::install( m_casts );
+ InstanceContainedCast<BrushInstance, Bounded>::install( m_casts );
+ InstanceContainedCast<BrushInstance, Cullable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, Renderable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, SelectionTestable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, ComponentSelectionTestable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, ComponentEditable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, ComponentSnappable>::install( m_casts );
+ InstanceStaticCast<BrushInstance, PlaneSelectable>::install( m_casts );
+ InstanceIdentityCast<BrushInstance>::install( m_casts );
+ InstanceContainedCast<BrushInstance, Transformable>::install( m_casts );
+ }
+
+ InstanceTypeCastTable& get(){
+ return m_casts;
+ }
+ };
- Brush& m_brush;
+ Brush& m_brush;
- FaceInstances m_faceInstances;
+ FaceInstances m_faceInstances;
- typedef std::vector<EdgeInstance> EdgeInstances;
- EdgeInstances m_edgeInstances;
- typedef std::vector<VertexInstance> VertexInstances;
- VertexInstances m_vertexInstances;
+ typedef std::vector<EdgeInstance> EdgeInstances;
+ EdgeInstances m_edgeInstances;
+ typedef std::vector<VertexInstance> VertexInstances;
+ VertexInstances m_vertexInstances;
- ObservedSelectable m_selectable;
+ ObservedSelectable m_selectable;
- mutable RenderableWireframe m_render_wireframe;
- mutable RenderablePointVector m_render_selected;
- mutable AABB m_aabb_component;
- mutable Array<PointVertex> m_faceCentroidPointsCulled;
- RenderablePointArray m_render_faces_wireframe;
- mutable bool m_viewChanged; // requires re-evaluation of view-dependent cached data
+ mutable RenderableWireframe m_render_wireframe;
+ mutable RenderablePointVector m_render_selected;
+ mutable AABB m_aabb_component;
+ mutable Array<PointVertex> m_faceCentroidPointsCulled;
+ RenderablePointArray m_render_faces_wireframe;
+ mutable bool m_viewChanged; // requires re-evaluation of view-dependent cached data
- BrushClipPlane m_clipPlane;
+ BrushClipPlane m_clipPlane;
- static Shader* m_state_selpoint;
+ static Shader* m_state_selpoint;
- const LightList* m_lightList;
+ const LightList* m_lightList;
- TransformModifier m_transform;
+ TransformModifier m_transform;
- BrushInstance( const BrushInstance& other ); // NOT COPYABLE
- BrushInstance& operator=( const BrushInstance& other ); // NOT ASSIGNABLE
+ BrushInstance( const BrushInstance& other ); // NOT COPYABLE
+ BrushInstance& operator=( const BrushInstance& other ); // NOT ASSIGNABLE
+
public:
- static Counter* m_counter;
+ static Counter* m_counter;
- typedef LazyStatic<TypeCasts> StaticTypeCasts;
+ typedef LazyStatic<TypeCasts> StaticTypeCasts;
- void lightsChanged(){
- m_lightList->lightsChanged();
- }
+ void lightsChanged(){
+ m_lightList->lightsChanged();
+ }
- typedef MemberCaller<BrushInstance, void(), &BrushInstance::lightsChanged> LightsChangedCaller;
+ typedef MemberCaller<BrushInstance, void(), &BrushInstance::lightsChanged> LightsChangedCaller;
- STRING_CONSTANT( Name, "BrushInstance" );
+ STRING_CONSTANT( Name, "BrushInstance" );
- BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush ) :
- Instance( path, parent, this, StaticTypeCasts::instance().get() ),
- m_brush( brush ),
- m_selectable( SelectedChangedCaller( *this ) ),
- m_render_selected( GL_POINTS ),
- m_render_faces_wireframe( m_faceCentroidPointsCulled, GL_POINTS ),
- m_viewChanged( false ),
- m_transform( Brush::TransformChangedCaller( m_brush ), ApplyTransformCaller( *this ) ){
- m_brush.instanceAttach( Instance::path() );
- m_brush.attach( *this );
- m_counter->increment();
+ BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush ) :
+ Instance( path, parent, this, StaticTypeCasts::instance().get() ),
+ m_brush( brush ),
+ m_selectable( SelectedChangedCaller( *this ) ),
+ m_render_selected( GL_POINTS ),
+ m_render_faces_wireframe( m_faceCentroidPointsCulled, GL_POINTS ),
+ m_viewChanged( false ),
+ m_transform( Brush::TransformChangedCaller( m_brush ), ApplyTransformCaller( *this ) ){
+ m_brush.instanceAttach( Instance::path() );
+ m_brush.attach( *this );
+ m_counter->increment();
- m_lightList = &GlobalShaderCache().attach( *this );
- m_brush.m_lightsChanged = LightsChangedCaller( *this ); ///\todo Make this work with instancing.
+ m_lightList = &GlobalShaderCache().attach( *this );
+ m_brush.m_lightsChanged = LightsChangedCaller( *this ); ///\todo Make this work with instancing.
- Instance::setTransformChangedCallback( LightsChangedCaller( *this ) );
- }
+ Instance::setTransformChangedCallback( LightsChangedCaller( *this ) );
+ }
- ~BrushInstance(){
- Instance::setTransformChangedCallback( Callback<void()>() );
+ ~BrushInstance(){
+ Instance::setTransformChangedCallback( Callback<void()>() );
- m_brush.m_lightsChanged = Callback<void()>();
- GlobalShaderCache().detach( *this );
+ m_brush.m_lightsChanged = Callback<void()>();
+ GlobalShaderCache().detach( *this );
- m_counter->decrement();
- m_brush.detach( *this );
- m_brush.instanceDetach( Instance::path() );
- }
+ m_counter->decrement();
+ m_brush.detach( *this );
+ m_brush.instanceDetach( Instance::path() );
+ }
- Brush& getBrush(){
- return m_brush;
- }
- const Brush& getBrush() const {
- return m_brush;
- }
+ Brush& getBrush(){
+ return m_brush;
+ }
+ const Brush& getBrush() const {
+ return m_brush;
+ }
- Bounded& get( NullType<Bounded>){
- return m_brush;
- }
+ Bounded& get( NullType<Bounded>){
+ return m_brush;
+ }
- Cullable& get( NullType<Cullable>){
- return m_brush;
- }
+ Cullable& get( NullType<Cullable>){
+ return m_brush;
+ }
- Transformable& get( NullType<Transformable>){
- return m_transform;
- }
+ Transformable& get( NullType<Transformable>){
+ return m_transform;
+ }
- void selectedChanged( const Selectable& selectable ){
- GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable );
- GlobalSelectionSystem().onSelectedChanged( *this, selectable );
+ void selectedChanged( const Selectable& selectable ){
+ GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable );
+ GlobalSelectionSystem().onSelectedChanged( *this, selectable );
- Instance::selectedChanged();
- }
- typedef MemberCaller<BrushInstance, void(const Selectable&), &BrushInstance::selectedChanged> SelectedChangedCaller;
+ Instance::selectedChanged();
+ }
+ typedef MemberCaller<BrushInstance, void(const Selectable&), &BrushInstance::selectedChanged> SelectedChangedCaller;
- void selectedChangedComponent( const Selectable& selectable ){
- GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
- GlobalSelectionSystem().onComponentSelection( *this, selectable );
- }
- typedef MemberCaller<BrushInstance, void(const Selectable&), &BrushInstance::selectedChangedComponent> SelectedChangedComponentCaller;
+ void selectedChangedComponent( const Selectable& selectable ){
+ GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
+ GlobalSelectionSystem().onComponentSelection( *this, selectable );
+ }
+ 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 )
- {
- visitor.visit( *i );
- }
- return visitor;
+ const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& visitor ){
+ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ visitor.visit( *i );
}
+ return visitor;
+ }
- static void constructStatic(){
- m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" );
- }
+ static void constructStatic(){
+ m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" );
+ }
- static void destroyStatic(){
- GlobalShaderCache().release( "$SELPOINT" );
- }
+ static void destroyStatic(){
+ GlobalShaderCache().release( "$SELPOINT" );
+ }
- void clear(){
- m_faceInstances.clear();
- }
+ void clear(){
+ m_faceInstances.clear();
+ }
- void reserve( std::size_t size ){
- m_faceInstances.reserve( size );
- }
+ void reserve( std::size_t size ){
+ m_faceInstances.reserve( size );
+ }
- void push_back( Face& face ){
- m_faceInstances.push_back( FaceInstance( face, SelectedChangedComponentCaller( *this ) ) );
- }
+ 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 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 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 )
- {
- ( *i ).connectivityChanged();
- }
+ void connectivityChanged(){
+ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ ( *i ).connectivityChanged();
}
+ }
- void edge_clear(){
- m_edgeInstances.clear();
- }
+ void edge_clear(){
+ m_edgeInstances.clear();
+ }
- void edge_push_back( SelectableEdge& edge ){
- m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) );
- }
+ void edge_push_back( SelectableEdge& edge ){
+ m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) );
+ }
- void vertex_clear(){
- m_vertexInstances.clear();
- }
+ void vertex_clear(){
+ m_vertexInstances.clear();
+ }
- void vertex_push_back( SelectableVertex& vertex ){
- m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) );
- }
+ void vertex_push_back( SelectableVertex& vertex ){
+ m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) );
+ }
- void DEBUG_verify() const {
- ASSERT_MESSAGE( m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch" );
- }
+ void DEBUG_verify() const {
+ ASSERT_MESSAGE( m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch" );
+ }
- bool isSelected() const {
- return m_selectable.isSelected();
- }
+ bool isSelected() const {
+ return m_selectable.isSelected();
+ }
- void setSelected( bool select ){
- m_selectable.setSelected( select );
- }
+ void setSelected( bool select ){
+ m_selectable.setSelected( select );
+ }
- void update_selected() const {
- m_render_selected.clear();
- for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
- {
- if ( ( *i ).getFace().contributes() ) {
- ( *i ).iterate_selected( m_render_selected );
- }
+ void update_selected() const {
+ m_render_selected.clear();
+ for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ if ( ( *i ).getFace().contributes() ) {
+ ( *i ).iterate_selected( m_render_selected );
}
}
+ }
- void evaluateViewDependent( const VolumeTest& volume, const Matrix4& localToWorld ) const {
- if ( m_viewChanged ) {
- m_viewChanged = false;
+ void evaluateViewDependent( const VolumeTest& volume, const Matrix4& localToWorld ) const {
+ if ( m_viewChanged ) {
+ m_viewChanged = false;
- bool faces_visible[c_brush_maxFaces];
+ bool faces_visible[c_brush_maxFaces];
+ {
+ bool* j = faces_visible;
+ for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j )
{
- bool* j = faces_visible;
- for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j )
- {
- *j = ( *i ).intersectVolume( volume, localToWorld );
- }
+ *j = ( *i ).intersectVolume( volume, localToWorld );
}
-
- m_brush.update_wireframe( m_render_wireframe, faces_visible );
- m_brush.update_faces_wireframe( m_faceCentroidPointsCulled, faces_visible );
}
+
+ m_brush.update_wireframe( m_render_wireframe, faces_visible );
+ m_brush.update_faces_wireframe( m_faceCentroidPointsCulled, faces_visible );
}
+ }
- void renderComponentsSelected( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
- m_brush.evaluateBRep();
+ void renderComponentsSelected( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
+ m_brush.evaluateBRep();
- update_selected();
- if ( !m_render_selected.empty() ) {
- renderer.Highlight( Renderer::ePrimitive, false );
- renderer.SetState( m_state_selpoint, Renderer::eWireframeOnly );
- renderer.SetState( m_state_selpoint, Renderer::eFullMaterials );
- renderer.addRenderable( m_render_selected, localToWorld );
- }
+ update_selected();
+ if ( !m_render_selected.empty() ) {
+ renderer.Highlight( Renderer::ePrimitive, false );
+ renderer.SetState( m_state_selpoint, Renderer::eWireframeOnly );
+ renderer.SetState( m_state_selpoint, Renderer::eFullMaterials );
+ renderer.addRenderable( m_render_selected, localToWorld );
}
+ }
- void renderComponents( Renderer& renderer, const VolumeTest& volume ) const {
- m_brush.evaluateBRep();
+ void renderComponents( Renderer& renderer, const VolumeTest& volume ) const {
+ m_brush.evaluateBRep();
- const Matrix4& localToWorld = Instance::localToWorld();
+ const Matrix4& localToWorld = Instance::localToWorld();
- renderer.SetState( m_brush.m_state_point, Renderer::eWireframeOnly );
- renderer.SetState( m_brush.m_state_point, Renderer::eFullMaterials );
+ renderer.SetState( m_brush.m_state_point, Renderer::eWireframeOnly );
+ renderer.SetState( m_brush.m_state_point, Renderer::eFullMaterials );
- if ( volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace ) {
- evaluateViewDependent( volume, localToWorld );
- renderer.addRenderable( m_render_faces_wireframe, localToWorld );
- }
- else
- {
- m_brush.renderComponents( GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld );
- }
+ if ( volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace ) {
+ evaluateViewDependent( volume, localToWorld );
+ renderer.addRenderable( m_render_faces_wireframe, localToWorld );
+ }
+ else
+ {
+ m_brush.renderComponents( GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld );
}
+ }
- void renderClipPlane( Renderer& renderer, const VolumeTest& volume ) const {
- if ( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected() ) {
- m_clipPlane.render( renderer, volume, localToWorld() );
- }
+ void renderClipPlane( Renderer& renderer, const VolumeTest& volume ) const {
+ if ( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected() ) {
+ m_clipPlane.render( renderer, volume, localToWorld() );
}
+ }
- void renderCommon( Renderer& renderer, const VolumeTest& volume ) const {
- bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent;
+ void renderCommon( Renderer& renderer, const VolumeTest& volume ) const {
+ bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent;
- if ( componentMode && isSelected() ) {
- renderComponents( renderer, volume );
- }
+ if ( componentMode && isSelected() ) {
+ renderComponents( renderer, volume );
+ }
- if ( parentSelected() ) {
- if ( !componentMode ) {
- renderer.Highlight( Renderer::eFace );
- }
- renderer.Highlight( Renderer::ePrimitive );
+ if ( parentSelected() ) {
+ if ( !componentMode ) {
+ renderer.Highlight( Renderer::eFace );
}
+ renderer.Highlight( Renderer::ePrimitive );
}
+ }
- void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
- //renderCommon(renderer, volume);
-
- m_lightList->evaluateLights();
+ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
+ //renderCommon(renderer, volume);
- for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
- {
- renderer.setLights( ( *i ).m_lights );
- ( *i ).render( renderer, volume, localToWorld );
- }
+ m_lightList->evaluateLights();
- renderComponentsSelected( renderer, volume, localToWorld );
+ for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ renderer.setLights( ( *i ).m_lights );
+ ( *i ).render( renderer, volume, localToWorld );
}
- void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
- //renderCommon(renderer, volume);
+ renderComponentsSelected( renderer, volume, localToWorld );
+ }
- evaluateViewDependent( volume, localToWorld );
+ void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
+ //renderCommon(renderer, volume);
- if ( m_render_wireframe.m_size != 0 ) {
- renderer.addRenderable( m_render_wireframe, localToWorld );
- }
+ evaluateViewDependent( volume, localToWorld );
- renderComponentsSelected( renderer, volume, localToWorld );
+ if ( m_render_wireframe.m_size != 0 ) {
+ renderer.addRenderable( m_render_wireframe, localToWorld );
}
- void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
- m_brush.evaluateBRep();
+ renderComponentsSelected( renderer, volume, localToWorld );
+ }
- renderClipPlane( renderer, volume );
+ void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
+ m_brush.evaluateBRep();
- renderSolid( renderer, volume, localToWorld() );
- }
+ renderClipPlane( renderer, volume );
- void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
- m_brush.evaluateBRep();
+ renderSolid( renderer, volume, localToWorld() );
+ }
- renderClipPlane( renderer, volume );
+ void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
+ m_brush.evaluateBRep();
- renderWireframe( renderer, volume, localToWorld() );
- }
+ renderClipPlane( renderer, volume );
- void viewChanged() const {
- m_viewChanged = true;
- }
+ renderWireframe( renderer, volume, localToWorld() );
+ }
- void testSelect( Selector& selector, SelectionTest& test ){
- test.BeginMesh( localToWorld() );
+ void viewChanged() const {
+ m_viewChanged = true;
+ }
- SelectionIntersection best;
- for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
- {
- ( *i ).testSelect( test, best );
- }
- if ( best.valid() ) {
- selector.addIntersection( best );
- }
+ void testSelect( Selector& selector, SelectionTest& test ){
+ test.BeginMesh( localToWorld() );
+
+ SelectionIntersection best;
+ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ ( *i ).testSelect( test, best );
+ }
+ if ( best.valid() ) {
+ selector.addIntersection( best );
}
+ }
- bool isSelectedComponents() const {
- for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
- {
- if ( ( *i ).selectedComponents() ) {
- return true;
- }
+ bool isSelectedComponents() const {
+ for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
+ {
+ if ( ( *i ).selectedComponents() ) {
+ return true;
}
- return false;
}
+ 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 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() );
+ void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
+ test.BeginMesh( localToWorld() );
- switch ( mode )
- {
- case SelectionSystem::eVertex:
+ switch ( mode )
+ {
+ case SelectionSystem::eVertex:
+ {
+ for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i )
{
- for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i )
- {
- ( *i ).testSelect( selector, test );
- }
+ ( *i ).testSelect( selector, test );
}
- break;
- case SelectionSystem::eEdge:
+ }
+ break;
+ case SelectionSystem::eEdge:
+ {
+ for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
{
- for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
+ ( *i ).testSelect( selector, test );
+ }
+ }
+ break;
+ case SelectionSystem::eFace:
+ {
+ if ( test.getVolume().fill() ) {
+ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
{
( *i ).testSelect( selector, test );
}