]> git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/brush.h
Q3map2:
[xonotic/netradiant.git] / radiant / brush.h
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #if !defined( INCLUDED_BRUSH_H )
23 #define INCLUDED_BRUSH_H
24
25 /// \file
26 /// \brief The brush primitive.
27 ///
28 /// A collection of planes that define a convex polyhedron.
29 /// The Boundary-Representation of this primitive is a manifold polygonal mesh.
30 /// Each face polygon is represented by a list of vertices in a \c Winding.
31 /// Each vertex is associated with another face that is adjacent to the edge
32 /// formed by itself and the next vertex in the winding. This information can
33 /// be used to find edge-pairs and vertex-rings.
34
35
36 #include "debugging/debugging.h"
37
38 #include "itexdef.h"
39 #include "iundo.h"
40 #include "iselection.h"
41 #include "irender.h"
42 #include "imap.h"
43 #include "ibrush.h"
44 #include "igl.h"
45 #include "ifilter.h"
46 #include "nameable.h"
47 #include "moduleobserver.h"
48
49 #include <set>
50
51 #include "cullable.h"
52 #include "renderable.h"
53 #include "selectable.h"
54 #include "editable.h"
55 #include "mapfile.h"
56
57 #include "math/frustum.h"
58 #include "selectionlib.h"
59 #include "render.h"
60 #include "texturelib.h"
61 #include "container/container.h"
62 #include "generic/bitfield.h"
63 #include "signal/signalfwd.h"
64
65 #include "winding.h"
66 #include "brush_primit.h"
67
68 const unsigned int BRUSH_DETAIL_FLAG = 27;
69 const unsigned int BRUSH_DETAIL_MASK = ( 1 << BRUSH_DETAIL_FLAG );
70
71 enum EBrushType
72 {
73         eBrushTypeQuake,
74         eBrushTypeQuake2,
75         eBrushTypeQuake3,
76         eBrushTypeQuake3BP,
77         eBrushTypeDoom3,
78         eBrushTypeQuake4,
79         eBrushTypeHalfLife,
80 };
81
82
83 #define BRUSH_CONNECTIVITY_DEBUG 0
84 #define BRUSH_DEGENERATE_DEBUG 0
85
86 template<typename TextOuputStreamType>
87 inline TextOuputStreamType& ostream_write( TextOuputStreamType& ostream, const Matrix4& m ){
88         return ostream << "(" << m[0] << " " << m[1] << " " << m[2] << " " << m[3] << ", "
89                                    << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << ", "
90                                    << m[8] << " " << m[9] << " " << m[10] << " " << m[11] << ", "
91                                    << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << ")";
92 }
93
94 inline void print_vector3( const Vector3& v ){
95         globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n";
96 }
97
98 inline void print_3x3( const Matrix4& m ){
99         globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) "
100                                                  << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) "
101                                                  << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n";
102 }
103
104
105
106 inline bool texdef_sane( const texdef_t& texdef ){
107         return fabs( texdef.shift[0] ) < ( 1 << 16 )
108                    && fabs( texdef.shift[1] ) < ( 1 << 16 );
109 }
110
111 inline void Winding_DrawWireframe( const Winding& winding ){
112         glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex );
113         glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) );
114 }
115
116 inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderStateFlags state ){
117         glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex );
118
119         if ( ( state & RENDER_BUMP ) != 0 ) {
120                 Vector3 normals[c_brush_maxFaces];
121                 typedef Vector3* Vector3Iter;
122                 for ( Vector3Iter i = normals, end = normals + winding.numpoints; i != end; ++i )
123                 {
124                         *i = normal;
125                 }
126                 if ( GlobalShaderCache().useShaderLanguage() ) {
127                         glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals );
128                         glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord );
129                         glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent );
130                         glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent );
131                 }
132                 else
133                 {
134                         glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( Vector3 ), normals );
135                         glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord );
136                         glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent );
137                         glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent );
138                 }
139         }
140         else
141         {
142                 if ( state & RENDER_LIGHTING ) {
143                         Vector3 normals[c_brush_maxFaces];
144                         typedef Vector3* Vector3Iter;
145                         for ( Vector3Iter i = normals, last = normals + winding.numpoints; i != last; ++i )
146                         {
147                                 *i = normal;
148                         }
149                         glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals );
150                 }
151
152                 if ( state & RENDER_TEXTURE ) {
153                         glTexCoordPointer( 2, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->texcoord );
154                 }
155         }
156 #if 0
157         if ( state & RENDER_FILL ) {
158                 glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) );
159         }
160         else
161         {
162                 glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) );
163         }
164 #else
165         glDrawArrays( GL_POLYGON, 0, GLsizei( winding.numpoints ) );
166 #endif
167
168 #if 0
169         const Winding& winding = winding;
170
171         if ( state & RENDER_FILL ) {
172                 glBegin( GL_POLYGON );
173         }
174         else
175         {
176                 glBegin( GL_LINE_LOOP );
177         }
178
179         if ( state & RENDER_LIGHTING ) {
180                 glNormal3fv( normal );
181         }
182
183         for ( int i = 0; i < winding.numpoints; ++i )
184         {
185                 if ( state & RENDER_TEXTURE ) {
186                         glTexCoord2fv( &winding.points[i][3] );
187                 }
188                 glVertex3fv( winding.points[i] );
189         }
190         glEnd();
191 #endif
192 }
193
194
195 #include "shaderlib.h"
196
197 typedef DoubleVector3 PlanePoints[3];
198
199 inline bool planepts_equal( const PlanePoints planepts, const PlanePoints other ){
200         return planepts[0] == other[0] && planepts[1] == other[1] && planepts[2] == other[2];
201 }
202
203 inline void planepts_assign( PlanePoints planepts, const PlanePoints other ){
204         planepts[0] = other[0];
205         planepts[1] = other[1];
206         planepts[2] = other[2];
207 }
208
209 inline void planepts_quantise( PlanePoints planepts, double snap ){
210         vector3_snap( planepts[0], snap );
211         vector3_snap( planepts[1], snap );
212         vector3_snap( planepts[2], snap );
213 }
214
215 inline float vector3_max_component( const Vector3& vec3 ){
216         return std::max( fabsf( vec3[0] ), std::max( fabsf( vec3[1] ), fabsf( vec3[2] ) ) );
217 }
218
219 inline void edge_snap( Vector3& edge, double snap ){
220         float scale = static_cast<float>( ceil( fabs( snap / vector3_max_component( edge ) ) ) );
221         if ( scale > 0.0f ) {
222                 vector3_scale( edge, scale );
223         }
224         vector3_snap( edge, snap );
225 }
226
227 inline void planepts_snap( PlanePoints planepts, double snap ){
228         Vector3 edge01( vector3_subtracted( planepts[1], planepts[0] ) );
229         Vector3 edge12( vector3_subtracted( planepts[2], planepts[1] ) );
230         Vector3 edge20( vector3_subtracted( planepts[0], planepts[2] ) );
231
232         double length_squared_01 = vector3_dot( edge01, edge01 );
233         double length_squared_12 = vector3_dot( edge12, edge12 );
234         double length_squared_20 = vector3_dot( edge20, edge20 );
235
236         vector3_snap( planepts[0], snap );
237
238         if ( length_squared_01 < length_squared_12 ) {
239                 if ( length_squared_12 < length_squared_20 ) {
240                         edge_snap( edge01, snap );
241                         edge_snap( edge12, snap );
242                         planepts[1] = vector3_added( planepts[0], edge01 );
243                         planepts[2] = vector3_added( planepts[1], edge12 );
244                 }
245                 else
246                 {
247                         edge_snap( edge20, snap );
248                         edge_snap( edge01, snap );
249                         planepts[1] = vector3_added( planepts[0], edge20 );
250                         planepts[2] = vector3_added( planepts[1], edge01 );
251                 }
252         }
253         else
254         {
255                 if ( length_squared_01 < length_squared_20 ) {
256                         edge_snap( edge01, snap );
257                         edge_snap( edge12, snap );
258                         planepts[1] = vector3_added( planepts[0], edge01 );
259                         planepts[2] = vector3_added( planepts[1], edge12 );
260                 }
261                 else
262                 {
263                         edge_snap( edge12, snap );
264                         edge_snap( edge20, snap );
265                         planepts[1] = vector3_added( planepts[0], edge12 );
266                         planepts[2] = vector3_added( planepts[1], edge20 );
267                 }
268         }
269 }
270
271 inline PointVertex pointvertex_for_planept( const DoubleVector3& point, const Colour4b& colour ){
272         return PointVertex(
273                            Vertex3f(
274                                    static_cast<float>( point.x() ),
275                                    static_cast<float>( point.y() ),
276                                    static_cast<float>( point.z() )
277                                    ),
278                            colour
279                            );
280 }
281
282 inline PointVertex pointvertex_for_windingpoint( const Vector3& point, const Colour4b& colour ){
283         return PointVertex(
284                            vertex3f_for_vector3( point ),
285                            colour
286                            );
287 }
288
289 inline bool check_plane_is_integer( const PlanePoints& planePoints ){
290         return !float_is_integer( planePoints[0][0] )
291                    || !float_is_integer( planePoints[0][1] )
292                    || !float_is_integer( planePoints[0][2] )
293                    || !float_is_integer( planePoints[1][0] )
294                    || !float_is_integer( planePoints[1][1] )
295                    || !float_is_integer( planePoints[1][2] )
296                    || !float_is_integer( planePoints[2][0] )
297                    || !float_is_integer( planePoints[2][1] )
298                    || !float_is_integer( planePoints[2][2] );
299 }
300
301 inline void brush_check_shader( const char* name ){
302         if ( !shader_valid( name ) ) {
303                 globalErrorStream() << "brush face has invalid texture name: '" << name << "'\n";
304         }
305 }
306
307 class FaceShaderObserver
308 {
309 public:
310 virtual void realiseShader() = 0;
311 virtual void unrealiseShader() = 0;
312 };
313
314 class FaceShaderObserverRealise
315 {
316 public:
317 void operator()( FaceShaderObserver& observer ) const {
318         observer.realiseShader();
319 }
320 };
321
322 class FaceShaderObserverUnrealise
323 {
324 public:
325 void operator()( FaceShaderObserver& observer ) const {
326         observer.unrealiseShader();
327 }
328 };
329
330 typedef ReferencePair<FaceShaderObserver> FaceShaderObserverPair;
331
332
333 class ContentsFlagsValue
334 {
335 public:
336 ContentsFlagsValue(){
337 }
338 ContentsFlagsValue( int surfaceFlags, int contentFlags, int value, bool specified ) :
339         m_surfaceFlags( surfaceFlags ),
340         m_contentFlags( contentFlags ),
341         m_value( value ),
342         m_specified( specified ){
343 }
344 int m_surfaceFlags;
345 int m_contentFlags;
346 int m_value;
347 bool m_specified;
348 };
349
350 inline void ContentsFlagsValue_assignMasked( ContentsFlagsValue& flags, const ContentsFlagsValue& other ){
351         bool detail = bitfield_enabled( flags.m_contentFlags, BRUSH_DETAIL_MASK );
352         flags = other;
353         if ( detail ) {
354                 flags.m_contentFlags = bitfield_enable( flags.m_contentFlags, BRUSH_DETAIL_MASK );
355         }
356         else
357         {
358                 flags.m_contentFlags = bitfield_disable( flags.m_contentFlags, BRUSH_DETAIL_MASK );
359         }
360 }
361
362
363 class FaceShader : public ModuleObserver
364 {
365 public:
366 class SavedState
367 {
368 public:
369 CopiedString m_shader;
370 ContentsFlagsValue m_flags;
371
372 SavedState( const FaceShader& faceShader ){
373         m_shader = faceShader.getShader();
374         m_flags = faceShader.m_flags;
375 }
376
377 void exportState( FaceShader& faceShader ) const {
378         faceShader.setShader( m_shader.c_str() );
379         faceShader.setFlags( m_flags );
380 }
381 };
382
383 CopiedString m_shader;
384 Shader* m_state;
385 ContentsFlagsValue m_flags;
386 FaceShaderObserverPair m_observers;
387 bool m_instanced;
388 bool m_realised;
389
390 FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsValue( 0, 0, 0, false ) ) :
391         m_shader( shader ),
392         m_state( 0 ),
393         m_flags( flags ),
394         m_instanced( false ),
395         m_realised( false ){
396         captureShader();
397 }
398 ~FaceShader(){
399         releaseShader();
400 }
401 // copy-construction not supported
402 FaceShader( const FaceShader& other );
403
404 void instanceAttach(){
405         m_instanced = true;
406         m_state->incrementUsed();
407 }
408 void instanceDetach(){
409         m_state->decrementUsed();
410         m_instanced = false;
411 }
412
413 void captureShader(){
414         ASSERT_MESSAGE( m_state == 0, "shader cannot be captured" );
415         brush_check_shader( m_shader.c_str() );
416         m_state = GlobalShaderCache().capture( m_shader.c_str() );
417         m_state->attach( *this );
418 }
419 void releaseShader(){
420         ASSERT_MESSAGE( m_state != 0, "shader cannot be released" );
421         m_state->detach( *this );
422         GlobalShaderCache().release( m_shader.c_str() );
423         m_state = 0;
424 }
425
426 void realise(){
427         ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" );
428         m_realised = true;
429         m_observers.forEach( FaceShaderObserverRealise() );
430 }
431 void unrealise(){
432         ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" );
433         m_observers.forEach( FaceShaderObserverUnrealise() );
434         m_realised = false;
435 }
436
437 void attach( FaceShaderObserver& observer ){
438         m_observers.attach( observer );
439         if ( m_realised ) {
440                 observer.realiseShader();
441         }
442 }
443
444 void detach( FaceShaderObserver& observer ){
445         if ( m_realised ) {
446                 observer.unrealiseShader();
447         }
448         m_observers.detach( observer );
449 }
450
451 const char* getShader() const {
452         return m_shader.c_str();
453 }
454 void setShader( const char* name ){
455         if ( m_instanced ) {
456                 m_state->decrementUsed();
457         }
458         releaseShader();
459         m_shader = name;
460         captureShader();
461         if ( m_instanced ) {
462                 m_state->incrementUsed();
463         }
464 }
465 ContentsFlagsValue getFlags() const {
466         ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" );
467         if ( !m_flags.m_specified ) {
468                 return ContentsFlagsValue(
469                                    m_state->getTexture().surfaceFlags,
470                                    m_state->getTexture().contentFlags,
471                                    m_state->getTexture().value,
472                                    true
473                                    );
474         }
475         return m_flags;
476 }
477 void setFlags( const ContentsFlagsValue& flags ){
478         ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" );
479         ContentsFlagsValue_assignMasked( m_flags, flags );
480 }
481
482 Shader* state() const {
483         return m_state;
484 }
485
486 std::size_t width() const {
487         if ( m_realised ) {
488                 return m_state->getTexture().width;
489         }
490         return 1;
491 }
492 std::size_t height() const {
493         if ( m_realised ) {
494                 return m_state->getTexture().height;
495         }
496         return 1;
497 }
498 unsigned int shaderFlags() const {
499         if ( m_realised ) {
500                 return m_state->getFlags();
501         }
502         return 0;
503 }
504 };
505
506
507
508
509 class FaceTexdef : public FaceShaderObserver
510 {
511 // not copyable
512 FaceTexdef( const FaceTexdef& other );
513 // not assignable
514 FaceTexdef& operator=( const FaceTexdef& other );
515 public:
516 class SavedState
517 {
518 public:
519 TextureProjection m_projection;
520
521 SavedState( const FaceTexdef& faceTexdef ){
522         m_projection = faceTexdef.m_projection;
523 }
524
525 void exportState( FaceTexdef& faceTexdef ) const {
526         Texdef_Assign( faceTexdef.m_projection, m_projection );
527 }
528 };
529
530 FaceShader& m_shader;
531 TextureProjection m_projection;
532 bool m_projectionInitialised;
533 bool m_scaleApplied;
534
535 FaceTexdef(
536         FaceShader& shader,
537         const TextureProjection& projection,
538         bool projectionInitialised = true
539         ) :
540         m_shader( shader ),
541         m_projection( projection ),
542         m_projectionInitialised( projectionInitialised ),
543         m_scaleApplied( false ){
544         m_shader.attach( *this );
545 }
546 ~FaceTexdef(){
547         m_shader.detach( *this );
548 }
549
550 void addScale(){
551         ASSERT_MESSAGE( !m_scaleApplied, "texture scale aready added" );
552         m_scaleApplied = true;
553         m_projection.m_brushprimit_texdef.addScale( m_shader.width(), m_shader.height() );
554 }
555 void removeScale(){
556         ASSERT_MESSAGE( m_scaleApplied, "texture scale aready removed" );
557         m_scaleApplied = false;
558         m_projection.m_brushprimit_texdef.removeScale( m_shader.width(), m_shader.height() );
559 }
560
561 void realiseShader(){
562         if ( m_projectionInitialised && !m_scaleApplied ) {
563                 addScale();
564         }
565 }
566 void unrealiseShader(){
567         if ( m_projectionInitialised && m_scaleApplied ) {
568                 removeScale();
569         }
570 }
571
572 void setTexdef( const TextureProjection& projection ){
573         removeScale();
574         Texdef_Assign( m_projection, projection );
575         addScale();
576 }
577
578 void shift( float s, float t ){
579         ASSERT_MESSAGE( texdef_sane( m_projection.m_texdef ), "FaceTexdef::shift: bad texdef" );
580         removeScale();
581         Texdef_Shift( m_projection, s, t );
582         addScale();
583 }
584
585 void scale( float s, float t ){
586         removeScale();
587         Texdef_Scale( m_projection, s, t );
588         addScale();
589 }
590
591 void rotate( float angle ){
592         removeScale();
593         Texdef_Rotate( m_projection, angle );
594         addScale();
595 }
596
597 void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){
598         Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat );
599 }
600
601 void fitW( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){
602         Texdef_FitTextureW( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat );
603 }
604
605 void fitH( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){
606         Texdef_FitTextureH( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat );
607 }
608
609 void emitTextureCoordinates( Winding& winding, const Vector3& normal, const Matrix4& localToWorld ){
610         Texdef_EmitTextureCoordinates( m_projection, m_shader.width(), m_shader.height(), winding, normal, localToWorld );
611 }
612
613 void transform( const Plane3& plane, const Matrix4& matrix ){
614         removeScale();
615         Texdef_transformLocked( m_projection, m_shader.width(), m_shader.height(), plane, matrix );
616         addScale();
617 }
618
619 TextureProjection normalised() const {
620         brushprimit_texdef_t tmp( m_projection.m_brushprimit_texdef );
621         tmp.removeScale( m_shader.width(), m_shader.height() );
622         return TextureProjection( m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t );
623 }
624 void setBasis( const Vector3& normal ){
625         Matrix4 basis;
626         Normal_GetTransform( normal, basis );
627         m_projection.m_basis_s = Vector3( basis.xx(), basis.yx(), basis.zx() );
628         m_projection.m_basis_t = Vector3( -basis.xy(), -basis.yy(), -basis.zy() );
629 }
630 };
631
632 inline void planepts_print( const PlanePoints& planePoints, TextOutputStream& ostream ){
633         ostream << "( " << planePoints[0][0] << " " << planePoints[0][1] << " " << planePoints[0][2] << " ) "
634                         << "( " << planePoints[1][0] << " " << planePoints[1][1] << " " << planePoints[1][2] << " ) "
635                         << "( " << planePoints[2][0] << " " << planePoints[2][1] << " " << planePoints[2][2] << " )";
636 }
637
638
639 inline Plane3 Plane3_applyTranslation( const Plane3& plane, const Vector3& translation ){
640         Plane3 tmp( plane3_translated( Plane3( plane.normal(), -plane.dist() ), translation ) );
641         return Plane3( tmp.normal(), -tmp.dist() );
642 }
643
644 inline Plane3 Plane3_applyTransform( const Plane3& plane, const Matrix4& matrix ){
645         Plane3 tmp( plane3_transformed( Plane3( plane.normal(), -plane.dist() ), matrix ) );
646         return Plane3( tmp.normal(), -tmp.dist() );
647 }
648
649 class FacePlane
650 {
651 PlanePoints m_planepts;
652 Plane3 m_planeCached;
653 Plane3 m_plane;
654 public:
655 Vector3 m_funcStaticOrigin;
656
657 static EBrushType m_type;
658
659 static bool isDoom3Plane(){
660         return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4;
661 }
662
663 class SavedState
664 {
665 public:
666 PlanePoints m_planepts;
667 Plane3 m_plane;
668
669 SavedState( const FacePlane& facePlane ){
670         if ( facePlane.isDoom3Plane() ) {
671                 m_plane = facePlane.m_plane;
672         }
673         else
674         {
675                 planepts_assign( m_planepts, facePlane.planePoints() );
676         }
677 }
678
679 void exportState( FacePlane& facePlane ) const {
680         if ( facePlane.isDoom3Plane() ) {
681                 facePlane.m_plane = m_plane;
682                 facePlane.updateTranslated();
683         }
684         else
685         {
686                 planepts_assign( facePlane.planePoints(), m_planepts );
687                 facePlane.MakePlane();
688         }
689 }
690 };
691
692 FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){
693 }
694 FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){
695         if ( !isDoom3Plane() ) {
696                 planepts_assign( m_planepts, other.m_planepts );
697                 MakePlane();
698         }
699         else
700         {
701                 m_plane = other.m_plane;
702                 updateTranslated();
703         }
704 }
705
706 void MakePlane(){
707         if ( !isDoom3Plane() ) {
708 #if 0
709                 if ( check_plane_is_integer( m_planepts ) ) {
710                         globalErrorStream() << "non-integer planepts: ";
711                         planepts_print( m_planepts, globalErrorStream() );
712                         globalErrorStream() << "\n";
713                 }
714 #endif
715                 m_planeCached = plane3_for_points( m_planepts );
716         }
717 }
718
719 void reverse(){
720         if ( !isDoom3Plane() ) {
721                 vector3_swap( m_planepts[0], m_planepts[2] );
722                 MakePlane();
723         }
724         else
725         {
726                 m_planeCached = plane3_flipped( m_plane );
727                 updateSource();
728         }
729 }
730 void transform( const Matrix4& matrix, bool mirror ){
731         if ( !isDoom3Plane() ) {
732
733 #if 0
734                 bool off = check_plane_is_integer( planePoints() );
735 #endif
736
737                 matrix4_transform_point( matrix, m_planepts[0] );
738                 matrix4_transform_point( matrix, m_planepts[1] );
739                 matrix4_transform_point( matrix, m_planepts[2] );
740
741                 if ( mirror ) {
742                         reverse();
743                 }
744
745 #if 0
746                 if ( check_plane_is_integer( planePoints() ) ) {
747                         if ( !off ) {
748                                 globalErrorStream() << "caused by transform\n";
749                         }
750                 }
751 #endif
752                 MakePlane();
753         }
754         else
755         {
756                 m_planeCached = Plane3_applyTransform( m_planeCached, matrix );
757                 updateSource();
758         }
759 }
760 void offset( float offset ){
761         if ( !isDoom3Plane() ) {
762                 Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) );
763
764                 vector3_subtract( m_planepts[0], move );
765                 vector3_subtract( m_planepts[1], move );
766                 vector3_subtract( m_planepts[2], move );
767
768                 MakePlane();
769         }
770         else
771         {
772                 m_planeCached.d += offset;
773                 updateSource();
774         }
775 }
776
777 void updateTranslated(){
778         m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin );
779 }
780 void updateSource(){
781         m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) );
782 }
783
784
785 PlanePoints& planePoints(){
786         return m_planepts;
787 }
788 const PlanePoints& planePoints() const {
789         return m_planepts;
790 }
791 const Plane3& plane3() const {
792         return m_planeCached;
793 }
794 void setDoom3Plane( const Plane3& plane ){
795         m_plane = plane;
796         updateTranslated();
797 }
798 const Plane3& getDoom3Plane() const {
799         return m_plane;
800 }
801
802 void copy( const FacePlane& other ){
803         if ( !isDoom3Plane() ) {
804                 planepts_assign( m_planepts, other.m_planepts );
805                 MakePlane();
806         }
807         else
808         {
809                 m_planeCached = other.m_plane;
810                 updateSource();
811         }
812 }
813 void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
814         if ( !isDoom3Plane() ) {
815                 m_planepts[0] = p0;
816                 m_planepts[1] = p1;
817                 m_planepts[2] = p2;
818                 MakePlane();
819         }
820         else
821         {
822                 m_planeCached = plane3_for_points( p2, p1, p0 );
823                 updateSource();
824         }
825 }
826 };
827
828 inline void Winding_testSelect( Winding& winding, SelectionTest& test, SelectionIntersection& best ){
829         test.TestPolygon( VertexPointer( reinterpret_cast<VertexPointer::pointer>( &winding.points.data()->vertex ), sizeof( WindingVertex ) ), winding.numpoints, best );
830 }
831
832 const double GRID_MIN = 0.125;
833
834 inline double quantiseInteger( double f ){
835         return float_to_integer( f );
836 }
837
838 inline double quantiseFloating( double f ){
839         return float_snapped( f, 1.f / ( 1 << 16 ) );
840 }
841
842 typedef double ( *QuantiseFunc )( double f );
843
844 class Face;
845
846 class FaceFilter
847 {
848 public:
849 virtual bool filter( const Face& face ) const = 0;
850 };
851
852 bool face_filtered( Face& face );
853 void add_face_filter( FaceFilter& filter, int mask, bool invert = false );
854
855 void Brush_addTextureChangedCallback( const SignalHandler& callback );
856 void Brush_textureChanged();
857
858
859 extern bool g_brush_texturelock_enabled;
860
861 class FaceObserver
862 {
863 public:
864 virtual void planeChanged() = 0;
865 virtual void connectivityChanged() = 0;
866 virtual void shaderChanged() = 0;
867 virtual void evaluateTransform() = 0;
868 };
869
870 class Face :
871         public OpenGLRenderable,
872         public Filterable,
873         public Undoable,
874         public FaceShaderObserver
875 {
876 std::size_t m_refcount;
877
878 class SavedState : public UndoMemento
879 {
880 public:
881 FacePlane::SavedState m_planeState;
882 FaceTexdef::SavedState m_texdefState;
883 FaceShader::SavedState m_shaderState;
884
885 SavedState( const Face& face ) : m_planeState( face.getPlane() ), m_texdefState( face.getTexdef() ), m_shaderState( face.getShader() ){
886 }
887
888 void exportState( Face& face ) const {
889         m_planeState.exportState( face.getPlane() );
890         m_shaderState.exportState( face.getShader() );
891         m_texdefState.exportState( face.getTexdef() );
892 }
893
894 void release(){
895         delete this;
896 }
897 };
898
899 public:
900 static QuantiseFunc m_quantise;
901 static EBrushType m_type;
902
903 PlanePoints m_move_planepts;
904 PlanePoints m_move_planeptsTransformed;
905 private:
906 FacePlane m_plane;
907 FacePlane m_planeTransformed;
908 FaceShader m_shader;
909 FaceTexdef m_texdef;
910 TextureProjection m_texdefTransformed;
911
912 Winding m_winding;
913 Vector3 m_centroid;
914 bool m_filtered;
915
916 FaceObserver* m_observer;
917 UndoObserver* m_undoable_observer;
918 MapFile* m_map;
919
920 // assignment not supported
921 Face& operator=( const Face& other );
922 // copy-construction not supported
923 Face( const Face& other );
924
925 public:
926
927 Face( FaceObserver* observer ) :
928         m_refcount( 0 ),
929         m_shader( texdef_name_default() ),
930         m_texdef( m_shader, TextureProjection(), false ),
931         m_filtered( false ),
932         m_observer( observer ),
933         m_undoable_observer( 0 ),
934         m_map( 0 ){
935         m_shader.attach( *this );
936         m_plane.copy( Vector3( 0, 0, 0 ), Vector3( 64, 0, 0 ), Vector3( 0, 64, 0 ) );
937         m_texdef.setBasis( m_plane.plane3().normal() );
938         planeChanged();
939 }
940 Face(
941         const Vector3& p0,
942         const Vector3& p1,
943         const Vector3& p2,
944         const char* shader,
945         const TextureProjection& projection,
946         FaceObserver* observer
947         ) :
948         m_refcount( 0 ),
949         m_shader( shader ),
950         m_texdef( m_shader, projection ),
951         m_observer( observer ),
952         m_undoable_observer( 0 ),
953         m_map( 0 ){
954         m_shader.attach( *this );
955         m_plane.copy( p0, p1, p2 );
956         m_texdef.setBasis( m_plane.plane3().normal() );
957         planeChanged();
958         updateFiltered();
959 }
960 Face( const Face& other, FaceObserver* observer ) :
961         m_refcount( 0 ),
962         m_shader( other.m_shader.getShader(), other.m_shader.m_flags ),
963         m_texdef( m_shader, other.getTexdef().normalised() ),
964         m_observer( observer ),
965         m_undoable_observer( 0 ),
966         m_map( 0 ){
967         m_shader.attach( *this );
968         m_plane.copy( other.m_plane );
969         planepts_assign( m_move_planepts, other.m_move_planepts );
970         m_texdef.setBasis( m_plane.plane3().normal() );
971         planeChanged();
972         updateFiltered();
973 }
974 ~Face(){
975         m_shader.detach( *this );
976 }
977
978 void planeChanged(){
979         revertTransform();
980         m_observer->planeChanged();
981 }
982
983 void realiseShader(){
984         m_observer->shaderChanged();
985 }
986 void unrealiseShader(){
987 }
988
989 void instanceAttach( MapFile* map ){
990         m_shader.instanceAttach();
991         m_map = map;
992         m_undoable_observer = GlobalUndoSystem().observer( this );
993         GlobalFilterSystem().registerFilterable( *this );
994 }
995 void instanceDetach( MapFile* map ){
996         GlobalFilterSystem().unregisterFilterable( *this );
997         m_undoable_observer = 0;
998         GlobalUndoSystem().release( this );
999         m_map = 0;
1000         m_shader.instanceDetach();
1001 }
1002
1003 void render( RenderStateFlags state ) const {
1004         Winding_Draw( m_winding, m_planeTransformed.plane3().normal(), state );
1005 }
1006
1007 void updateFiltered(){
1008         m_filtered = face_filtered( *this );
1009 }
1010 bool isFiltered() const {
1011         return m_filtered;
1012 }
1013
1014 void undoSave(){
1015         if ( m_map != 0 ) {
1016                 m_map->changed();
1017         }
1018         if ( m_undoable_observer != 0 ) {
1019                 m_undoable_observer->save( this );
1020         }
1021 }
1022
1023 // undoable
1024 UndoMemento* exportState() const {
1025         return new SavedState( *this );
1026 }
1027 void importState( const UndoMemento* data ){
1028         undoSave();
1029
1030         static_cast<const SavedState*>( data )->exportState( *this );
1031
1032         planeChanged();
1033         m_observer->connectivityChanged();
1034         texdefChanged();
1035         m_observer->shaderChanged();
1036         updateFiltered();
1037 }
1038
1039 void IncRef(){
1040         ++m_refcount;
1041 }
1042 void DecRef(){
1043         if ( --m_refcount == 0 ) {
1044                 delete this;
1045         }
1046 }
1047
1048 void flipWinding(){
1049         m_plane.reverse();
1050         planeChanged();
1051 }
1052
1053 bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
1054         return volume.TestPlane( Plane3( plane3().normal(), -plane3().dist() ), localToWorld );
1055 }
1056
1057 void render( Renderer& renderer, const Matrix4& localToWorld ) const {
1058         renderer.SetState( m_shader.state(), Renderer::eFullMaterials );
1059         renderer.addRenderable( *this, localToWorld );
1060 }
1061
1062 void transform( const Matrix4& matrix, bool mirror ){
1063         if ( g_brush_texturelock_enabled ) {
1064                 Texdef_transformLocked( m_texdefTransformed, m_shader.width(), m_shader.height(), m_plane.plane3(), matrix );
1065         }
1066
1067         m_planeTransformed.transform( matrix, mirror );
1068
1069 #if 0
1070         ASSERT_MESSAGE( projectionaxis_for_normal( normal ) == projectionaxis_for_normal( plane3().normal() ), "bleh" );
1071 #endif
1072         m_observer->planeChanged();
1073
1074         if ( g_brush_texturelock_enabled ) {
1075                 Brush_textureChanged();
1076         }
1077 }
1078
1079 void assign_planepts( const PlanePoints planepts ){
1080         m_planeTransformed.copy( planepts[0], planepts[1], planepts[2] );
1081         m_observer->planeChanged();
1082 }
1083
1084 /// \brief Reverts the transformable state of the brush to identity.
1085 void revertTransform(){
1086         m_planeTransformed = m_plane;
1087         planepts_assign( m_move_planeptsTransformed, m_move_planepts );
1088         m_texdefTransformed = m_texdef.m_projection;
1089 }
1090 void freezeTransform(){
1091         undoSave();
1092         m_plane = m_planeTransformed;
1093         planepts_assign( m_move_planepts, m_move_planeptsTransformed );
1094         m_texdef.m_projection = m_texdefTransformed;
1095 }
1096
1097 void update_move_planepts_vertex( std::size_t index, PlanePoints planePoints ){
1098         std::size_t numpoints = getWinding().numpoints;
1099         ASSERT_MESSAGE( index < numpoints, "update_move_planepts_vertex: invalid index" );
1100
1101         std::size_t opposite = Winding_Opposite( getWinding(), index );
1102         std::size_t adjacent = Winding_wrap( getWinding(), opposite + numpoints - 1 );
1103         planePoints[0] = getWinding()[opposite].vertex;
1104         planePoints[1] = getWinding()[index].vertex;
1105         planePoints[2] = getWinding()[adjacent].vertex;
1106         // winding points are very inaccurate, so they must be quantised before using them to generate the face-plane
1107         planepts_quantise( planePoints, GRID_MIN );
1108 }
1109
1110 void snapto( float snap ){
1111         if ( contributes() ) {
1112 #if 0
1113                 ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane before snap to grid" );
1114                 planepts_snap( m_plane.planePoints(), snap );
1115                 ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane after snap to grid" );
1116 #else
1117                 PlanePoints planePoints;
1118                 update_move_planepts_vertex( 0, planePoints );
1119                 vector3_snap( planePoints[0], snap );
1120                 vector3_snap( planePoints[1], snap );
1121                 vector3_snap( planePoints[2], snap );
1122                 assign_planepts( planePoints );
1123                 freezeTransform();
1124 #endif
1125                 SceneChangeNotify();
1126                 if ( !plane3_valid( m_plane.plane3() ) ) {
1127                         globalErrorStream() << "WARNING: invalid plane after snap to grid\n";
1128                 }
1129         }
1130 }
1131
1132 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1133         Winding_testSelect( m_winding, test, best );
1134 }
1135
1136 void testSelect_centroid( SelectionTest& test, SelectionIntersection& best ){
1137         test.TestPoint( m_centroid, best );
1138 }
1139
1140 void shaderChanged(){
1141         EmitTextureCoordinates();
1142         Brush_textureChanged();
1143         m_observer->shaderChanged();
1144         updateFiltered();
1145         planeChanged();
1146         SceneChangeNotify();
1147 }
1148
1149 const char* GetShader() const {
1150         return m_shader.getShader();
1151 }
1152 void SetShader( const char* name ){
1153         undoSave();
1154         m_shader.setShader( name );
1155         shaderChanged();
1156 }
1157
1158 void revertTexdef(){
1159         m_texdefTransformed = m_texdef.m_projection;
1160 }
1161 void texdefChanged(){
1162         revertTexdef();
1163         EmitTextureCoordinates();
1164         Brush_textureChanged();
1165 }
1166
1167 void GetTexdef( TextureProjection& projection ) const {
1168         projection = m_texdef.normalised();
1169 }
1170 void SetTexdef( const TextureProjection& projection ){
1171         undoSave();
1172         m_texdef.setTexdef( projection );
1173         texdefChanged();
1174 }
1175
1176 void GetFlags( ContentsFlagsValue& flags ) const {
1177         flags = m_shader.getFlags();
1178 }
1179 void SetFlags( const ContentsFlagsValue& flags ){
1180         undoSave();
1181         m_shader.setFlags( flags );
1182         m_observer->shaderChanged();
1183         updateFiltered();
1184 }
1185
1186 void ShiftTexdef( float s, float t ){
1187         undoSave();
1188         m_texdef.shift( s, t );
1189         texdefChanged();
1190 }
1191
1192 void ScaleTexdef( float s, float t ){
1193         undoSave();
1194         m_texdef.scale( s, t );
1195         texdefChanged();
1196 }
1197
1198 void RotateTexdef( float angle ){
1199         undoSave();
1200         m_texdef.rotate( angle );
1201         texdefChanged();
1202 }
1203
1204 void FitTexture( float s_repeat, float t_repeat ){
1205         undoSave();
1206         m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat );
1207         texdefChanged();
1208 }
1209
1210 void FitTextureW( float s_repeat, float t_repeat ){
1211         undoSave();
1212         m_texdef.fitW( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat );
1213         texdefChanged();
1214 }
1215
1216 void FitTextureH( float s_repeat, float t_repeat ){
1217         undoSave();
1218         m_texdef.fitH( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat );
1219         texdefChanged();
1220 }
1221
1222 void EmitTextureCoordinates(){
1223         Texdef_EmitTextureCoordinates( m_texdefTransformed, m_shader.width(), m_shader.height(), m_winding, plane3().normal(), g_matrix4_identity );
1224 }
1225
1226
1227 const Vector3& centroid() const {
1228         return m_centroid;
1229 }
1230
1231 void construct_centroid(){
1232         Winding_Centroid( m_winding, plane3(), m_centroid );
1233 }
1234
1235 const Winding& getWinding() const {
1236         return m_winding;
1237 }
1238 Winding& getWinding(){
1239         return m_winding;
1240 }
1241
1242 const Plane3& plane3() const {
1243         m_observer->evaluateTransform();
1244         return m_planeTransformed.plane3();
1245 }
1246 FacePlane& getPlane(){
1247         return m_plane;
1248 }
1249 const FacePlane& getPlane() const {
1250         return m_plane;
1251 }
1252 FaceTexdef& getTexdef(){
1253         return m_texdef;
1254 }
1255 const FaceTexdef& getTexdef() const {
1256         return m_texdef;
1257 }
1258 FaceShader& getShader(){
1259         return m_shader;
1260 }
1261 const FaceShader& getShader() const {
1262         return m_shader;
1263 }
1264
1265 bool isDetail() const {
1266         return ( m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK ) != 0;
1267 }
1268 void setDetail( bool detail ){
1269         undoSave();
1270         if ( detail && !isDetail() ) {
1271                 m_shader.m_flags.m_contentFlags |= BRUSH_DETAIL_MASK;
1272         }
1273         else if ( !detail && isDetail() ) {
1274                 m_shader.m_flags.m_contentFlags &= ~BRUSH_DETAIL_MASK;
1275         }
1276         m_observer->shaderChanged();
1277 }
1278
1279 bool contributes() const {
1280         return m_winding.numpoints > 2;
1281 }
1282 bool is_bounded() const {
1283         for ( Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i )
1284         {
1285                 if ( ( *i ).adjacent == c_brush_maxFaces ) {
1286                         return false;
1287                 }
1288         }
1289         return true;
1290 }
1291 };
1292
1293
1294 class FaceVertexId
1295 {
1296 std::size_t m_face;
1297 std::size_t m_vertex;
1298
1299 public:
1300 FaceVertexId( std::size_t face, std::size_t vertex )
1301         : m_face( face ), m_vertex( vertex ){
1302 }
1303
1304 std::size_t getFace() const {
1305         return m_face;
1306 }
1307 std::size_t getVertex() const {
1308         return m_vertex;
1309 }
1310 };
1311
1312 typedef std::size_t faceIndex_t;
1313
1314 struct EdgeRenderIndices
1315 {
1316         RenderIndex first;
1317         RenderIndex second;
1318
1319         EdgeRenderIndices()
1320                 : first( 0 ), second( 0 ){
1321         }
1322         EdgeRenderIndices( const RenderIndex _first, const RenderIndex _second )
1323                 : first( _first ), second( _second ){
1324         }
1325 };
1326
1327 struct EdgeFaces
1328 {
1329         faceIndex_t first;
1330         faceIndex_t second;
1331
1332         EdgeFaces()
1333                 : first( c_brush_maxFaces ), second( c_brush_maxFaces ){
1334         }
1335         EdgeFaces( const faceIndex_t _first, const faceIndex_t _second )
1336                 : first( _first ), second( _second ){
1337         }
1338 };
1339
1340 class RenderableWireframe : public OpenGLRenderable
1341 {
1342 public:
1343 void render( RenderStateFlags state ) const {
1344 #if 1
1345         glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices->colour );
1346         glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices->vertex );
1347         glDrawElements( GL_LINES, GLsizei( m_size << 1 ), RenderIndexTypeID, m_faceVertex.data() );
1348 #else
1349         glBegin( GL_LINES );
1350         for ( std::size_t i = 0; i < m_size; ++i )
1351         {
1352                 glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x );
1353                 glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x );
1354         }
1355         glEnd();
1356 #endif
1357 }
1358
1359 Array<EdgeRenderIndices> m_faceVertex;
1360 std::size_t m_size;
1361 const PointVertex* m_vertices;
1362 };
1363
1364 class Brush;
1365 typedef std::vector<Brush*> brush_vector_t;
1366
1367 class BrushFilter
1368 {
1369 public:
1370 virtual bool filter( const Brush& brush ) const = 0;
1371 };
1372
1373 bool brush_filtered( Brush& brush );
1374 void add_brush_filter( BrushFilter& filter, int mask, bool invert = false );
1375
1376
1377 /// \brief Returns true if 'self' takes priority when building brush b-rep.
1378 inline bool plane3_inside( const Plane3& self, const Plane3& other, bool selfIsLater ){
1379         if ( vector3_equal_epsilon( self.normal(), other.normal(), 0.001 ) ) {
1380                 // same plane? prefer the one with smaller index
1381                 if ( self.dist() == other.dist() ) {
1382                         return selfIsLater;
1383                 }
1384                 return self.dist() < other.dist();
1385         }
1386         return true;
1387 }
1388
1389 typedef SmartPointer<Face> FaceSmartPointer;
1390 typedef std::vector<FaceSmartPointer> Faces;
1391
1392 /// \brief Returns the unique-id of the edge adjacent to \p faceVertex in the edge-pair for the set of \p faces.
1393 inline FaceVertexId next_edge( const Faces& faces, FaceVertexId faceVertex ){
1394         std::size_t adjacent_face = faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent;
1395         std::size_t adjacent_vertex = Winding_FindAdjacent( faces[adjacent_face]->getWinding(), faceVertex.getFace() );
1396
1397         ASSERT_MESSAGE( adjacent_vertex != c_brush_maxFaces, "connectivity data invalid" );
1398         if ( adjacent_vertex == c_brush_maxFaces ) {
1399                 return faceVertex;
1400         }
1401
1402         return FaceVertexId( adjacent_face, adjacent_vertex );
1403 }
1404
1405 /// \brief Returns the unique-id of the vertex adjacent to \p faceVertex in the vertex-ring for the set of \p faces.
1406 inline FaceVertexId next_vertex( const Faces& faces, FaceVertexId faceVertex ){
1407         FaceVertexId nextEdge = next_edge( faces, faceVertex );
1408         return FaceVertexId( nextEdge.getFace(), Winding_next( faces[nextEdge.getFace()]->getWinding(), nextEdge.getVertex() ) );
1409 }
1410
1411 class SelectableEdge
1412 {
1413 Vector3 getEdge() const {
1414         const Winding& winding = getFace().getWinding();
1415         return vector3_mid( winding[m_faceVertex.getVertex()].vertex, winding[Winding_next( winding, m_faceVertex.getVertex() )].vertex );
1416 }
1417
1418 public:
1419 Faces& m_faces;
1420 FaceVertexId m_faceVertex;
1421
1422 SelectableEdge( Faces& faces, FaceVertexId faceVertex )
1423         : m_faces( faces ), m_faceVertex( faceVertex ){
1424 }
1425 SelectableEdge& operator=( const SelectableEdge& other ){
1426         m_faceVertex = other.m_faceVertex;
1427         return *this;
1428 }
1429
1430 Face& getFace() const {
1431         return *m_faces[m_faceVertex.getFace()];
1432 }
1433
1434 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1435         test.TestPoint( getEdge(), best );
1436 }
1437 };
1438
1439 class SelectableVertex
1440 {
1441 Vector3 getVertex() const {
1442         return getFace().getWinding()[m_faceVertex.getVertex()].vertex;
1443 }
1444
1445 public:
1446 Faces& m_faces;
1447 FaceVertexId m_faceVertex;
1448
1449 SelectableVertex( Faces& faces, FaceVertexId faceVertex )
1450         : m_faces( faces ), m_faceVertex( faceVertex ){
1451 }
1452 SelectableVertex& operator=( const SelectableVertex& other ){
1453         m_faceVertex = other.m_faceVertex;
1454         return *this;
1455 }
1456
1457 Face& getFace() const {
1458         return *m_faces[m_faceVertex.getFace()];
1459 }
1460
1461 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1462         test.TestPoint( getVertex(), best );
1463 }
1464 };
1465
1466 class BrushObserver
1467 {
1468 public:
1469 virtual void reserve( std::size_t size ) = 0;
1470 virtual void clear() = 0;
1471 virtual void push_back( Face& face ) = 0;
1472 virtual void pop_back() = 0;
1473 virtual void erase( std::size_t index ) = 0;
1474 virtual void connectivityChanged() = 0;
1475
1476 virtual void edge_clear() = 0;
1477 virtual void edge_push_back( SelectableEdge& edge ) = 0;
1478
1479 virtual void vertex_clear() = 0;
1480 virtual void vertex_push_back( SelectableVertex& vertex ) = 0;
1481
1482 virtual void DEBUG_verify() const = 0;
1483 };
1484
1485 class BrushVisitor
1486 {
1487 public:
1488 virtual void visit( Face& face ) const = 0;
1489 };
1490
1491 class Brush :
1492         public TransformNode,
1493         public Bounded,
1494         public Cullable,
1495         public Snappable,
1496         public Undoable,
1497         public FaceObserver,
1498         public Filterable,
1499         public Nameable,
1500         public BrushDoom3
1501 {
1502 private:
1503 scene::Node* m_node;
1504 typedef UniqueSet<BrushObserver*> Observers;
1505 Observers m_observers;
1506 UndoObserver* m_undoable_observer;
1507 MapFile* m_map;
1508
1509 // state
1510 Faces m_faces;
1511 // ----
1512
1513 // cached data compiled from state
1514 Array<PointVertex> m_faceCentroidPoints;
1515 RenderablePointArray m_render_faces;
1516
1517 Array<PointVertex> m_uniqueVertexPoints;
1518 typedef std::vector<SelectableVertex> SelectableVertices;
1519 SelectableVertices m_select_vertices;
1520 RenderablePointArray m_render_vertices;
1521
1522 Array<PointVertex> m_uniqueEdgePoints;
1523 typedef std::vector<SelectableEdge> SelectableEdges;
1524 SelectableEdges m_select_edges;
1525 RenderablePointArray m_render_edges;
1526
1527 Array<EdgeRenderIndices> m_edge_indices;
1528 Array<EdgeFaces> m_edge_faces;
1529
1530 AABB m_aabb_local;
1531 // ----
1532
1533 Callback m_evaluateTransform;
1534 Callback m_boundsChanged;
1535
1536 mutable bool m_planeChanged;   // b-rep evaluation required
1537 mutable bool m_transformChanged;   // transform evaluation required
1538 // ----
1539
1540 public:
1541 STRING_CONSTANT( Name, "Brush" );
1542
1543 Callback m_lightsChanged;
1544
1545 // static data
1546 static Shader* m_state_point;
1547 // ----
1548
1549 static EBrushType m_type;
1550 static double m_maxWorldCoord;
1551
1552 Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
1553         m_node( &node ),
1554         m_undoable_observer( 0 ),
1555         m_map( 0 ),
1556         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1557         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1558         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1559         m_evaluateTransform( evaluateTransform ),
1560         m_boundsChanged( boundsChanged ),
1561         m_planeChanged( false ),
1562         m_transformChanged( false ){
1563         planeChanged();
1564 }
1565 Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
1566         m_node( &node ),
1567         m_undoable_observer( 0 ),
1568         m_map( 0 ),
1569         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1570         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1571         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1572         m_evaluateTransform( evaluateTransform ),
1573         m_boundsChanged( boundsChanged ),
1574         m_planeChanged( false ),
1575         m_transformChanged( false ){
1576         copy( other );
1577 }
1578 Brush( const Brush& other ) :
1579         TransformNode( other ),
1580         Bounded( other ),
1581         Cullable( other ),
1582         Snappable(),
1583         Undoable( other ),
1584         FaceObserver( other ),
1585         Filterable( other ),
1586         Nameable( other ),
1587         BrushDoom3( other ),
1588         m_node( 0 ),
1589         m_undoable_observer( 0 ),
1590         m_map( 0 ),
1591         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1592         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1593         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1594         m_planeChanged( false ),
1595         m_transformChanged( false ){
1596         copy( other );
1597 }
1598 ~Brush(){
1599         ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" );
1600 }
1601
1602 // assignment not supported
1603 Brush& operator=( const Brush& other );
1604
1605 void setDoom3GroupOrigin( const Vector3& origin ){
1606         //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n";
1607         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1608         {
1609                 ( *i )->getPlane().m_funcStaticOrigin = origin;
1610                 ( *i )->getPlane().updateTranslated();
1611                 ( *i )->planeChanged();
1612         }
1613         planeChanged();
1614 }
1615
1616 void attach( BrushObserver& observer ){
1617         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1618         {
1619                 observer.push_back( *( *i ) );
1620         }
1621
1622         for ( SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i )
1623         {
1624                 observer.edge_push_back( *i );
1625         }
1626
1627         for ( SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i )
1628         {
1629                 observer.vertex_push_back( *i );
1630         }
1631
1632         m_observers.insert( &observer );
1633 }
1634 void detach( BrushObserver& observer ){
1635         m_observers.erase( &observer );
1636 }
1637
1638 void forEachFace( const BrushVisitor& visitor ) const {
1639         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1640         {
1641                 visitor.visit( *( *i ) );
1642         }
1643 }
1644
1645 void forEachFace_instanceAttach( MapFile* map ) const {
1646         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1647         {
1648                 ( *i )->instanceAttach( map );
1649         }
1650 }
1651 void forEachFace_instanceDetach( MapFile* map ) const {
1652         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1653         {
1654                 ( *i )->instanceDetach( map );
1655         }
1656 }
1657
1658 InstanceCounter m_instanceCounter;
1659 void instanceAttach( const scene::Path& path ){
1660         if ( ++m_instanceCounter.m_count == 1 ) {
1661                 m_map = path_find_mapfile( path.begin(), path.end() );
1662                 m_undoable_observer = GlobalUndoSystem().observer( this );
1663                 GlobalFilterSystem().registerFilterable( *this );
1664                 forEachFace_instanceAttach( m_map );
1665         }
1666         else
1667         {
1668                 ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" );
1669         }
1670 }
1671 void instanceDetach( const scene::Path& path ){
1672         if ( --m_instanceCounter.m_count == 0 ) {
1673                 forEachFace_instanceDetach( m_map );
1674                 GlobalFilterSystem().unregisterFilterable( *this );
1675                 m_map = 0;
1676                 m_undoable_observer = 0;
1677                 GlobalUndoSystem().release( this );
1678         }
1679 }
1680
1681 // nameable
1682 const char* name() const {
1683         return "brush";
1684 }
1685 void attach( const NameCallback& callback ){
1686 }
1687 void detach( const NameCallback& callback ){
1688 }
1689
1690 // filterable
1691 void updateFiltered(){
1692         if ( m_node != 0 ) {
1693                 if ( brush_filtered( *this ) ) {
1694                         m_node->enable( scene::Node::eFiltered );
1695                 }
1696                 else
1697                 {
1698                         m_node->disable( scene::Node::eFiltered );
1699                 }
1700         }
1701 }
1702
1703 // observer
1704 void planeChanged(){
1705         m_planeChanged = true;
1706         aabbChanged();
1707         m_lightsChanged();
1708 }
1709 void shaderChanged(){
1710         updateFiltered();
1711         planeChanged();
1712 }
1713
1714 void evaluateBRep() const {
1715         if ( m_planeChanged ) {
1716                 m_planeChanged = false;
1717                 const_cast<Brush*>( this )->buildBRep();
1718         }
1719 }
1720
1721 void transformChanged(){
1722         m_transformChanged = true;
1723         planeChanged();
1724 }
1725 typedef MemberCaller<Brush, &Brush::transformChanged> TransformChangedCaller;
1726
1727 void evaluateTransform(){
1728         if ( m_transformChanged ) {
1729                 m_transformChanged = false;
1730                 revertTransform();
1731                 m_evaluateTransform();
1732         }
1733 }
1734 const Matrix4& localToParent() const {
1735         return g_matrix4_identity;
1736 }
1737 void aabbChanged(){
1738         m_boundsChanged();
1739 }
1740 const AABB& localAABB() const {
1741         evaluateBRep();
1742         return m_aabb_local;
1743 }
1744
1745 VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const {
1746         return test.TestAABB( m_aabb_local, localToWorld );
1747 }
1748
1749 void renderComponents( SelectionSystem::EComponentMode mode, Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
1750         switch ( mode )
1751         {
1752         case SelectionSystem::eVertex:
1753                 renderer.addRenderable( m_render_vertices, localToWorld );
1754                 break;
1755         case SelectionSystem::eEdge:
1756                 renderer.addRenderable( m_render_edges, localToWorld );
1757                 break;
1758         case SelectionSystem::eFace:
1759                 renderer.addRenderable( m_render_faces, localToWorld );
1760                 break;
1761         default:
1762                 break;
1763         }
1764 }
1765
1766 void transform( const Matrix4& matrix ){
1767         bool mirror = matrix4_handedness( matrix ) == MATRIX4_LEFTHANDED;
1768
1769         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1770         {
1771                 ( *i )->transform( matrix, mirror );
1772         }
1773 }
1774 void snapto( float snap ){
1775         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1776         {
1777                 ( *i )->snapto( snap );
1778         }
1779 }
1780 void revertTransform(){
1781         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1782         {
1783                 ( *i )->revertTransform();
1784         }
1785 }
1786 void freezeTransform(){
1787         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1788         {
1789                 ( *i )->freezeTransform();
1790         }
1791 }
1792
1793 /// \brief Returns the absolute index of the \p faceVertex.
1794 std::size_t absoluteIndex( FaceVertexId faceVertex ){
1795         std::size_t index = 0;
1796         for ( std::size_t i = 0; i < faceVertex.getFace(); ++i )
1797         {
1798                 index += m_faces[i]->getWinding().numpoints;
1799         }
1800         return index + faceVertex.getVertex();
1801 }
1802
1803 void appendFaces( const Faces& other ){
1804         clear();
1805         for ( Faces::const_iterator i = other.begin(); i != other.end(); ++i )
1806         {
1807                 push_back( *i );
1808         }
1809 }
1810
1811 /// \brief The undo memento for a brush stores only the list of face references - the faces are not copied.
1812 class BrushUndoMemento : public UndoMemento
1813 {
1814 public:
1815 BrushUndoMemento( const Faces& faces ) : m_faces( faces ){
1816 }
1817 void release(){
1818         delete this;
1819 }
1820
1821 Faces m_faces;
1822 };
1823
1824 void undoSave(){
1825         if ( m_map != 0 ) {
1826                 m_map->changed();
1827         }
1828         if ( m_undoable_observer != 0 ) {
1829                 m_undoable_observer->save( this );
1830         }
1831 }
1832
1833 UndoMemento* exportState() const {
1834         return new BrushUndoMemento( m_faces );
1835 }
1836
1837 void importState( const UndoMemento* state ){
1838         undoSave();
1839         appendFaces( static_cast<const BrushUndoMemento*>( state )->m_faces );
1840         planeChanged();
1841
1842         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1843         {
1844                 ( *i )->DEBUG_verify();
1845         }
1846 }
1847
1848 bool isDetail(){
1849         return !m_faces.empty() && m_faces.front()->isDetail();
1850 }
1851
1852 /// \brief Appends a copy of \p face to the end of the face list.
1853 Face* addFace( const Face& face ){
1854         if ( m_faces.size() == c_brush_maxFaces ) {
1855                 return 0;
1856         }
1857         undoSave();
1858         push_back( FaceSmartPointer( new Face( face, this ) ) );
1859         m_faces.back()->setDetail( isDetail() );
1860         planeChanged();
1861         return m_faces.back();
1862 }
1863
1864 /// \brief Appends a new face constructed from the parameters to the end of the face list.
1865 Face* addPlane( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection ){
1866         if ( m_faces.size() == c_brush_maxFaces ) {
1867                 return 0;
1868         }
1869         undoSave();
1870         push_back( FaceSmartPointer( new Face( p0, p1, p2, shader, projection, this ) ) );
1871         m_faces.back()->setDetail( isDetail() );
1872         planeChanged();
1873         return m_faces.back();
1874 }
1875
1876 static void constructStatic( EBrushType type ){
1877         m_type = type;
1878         Face::m_type = type;
1879         FacePlane::m_type = type;
1880
1881         g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE;
1882         if ( m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4 ) {
1883                 g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
1884                 // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
1885         }
1886         else if ( m_type == eBrushTypeHalfLife ) {
1887                 g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE;
1888                 // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
1889         }
1890
1891         Face::m_quantise = ( m_type == eBrushTypeQuake ) ? quantiseInteger : quantiseFloating;
1892
1893         m_state_point = GlobalShaderCache().capture( "$POINT" );
1894 }
1895 static void destroyStatic(){
1896         GlobalShaderCache().release( "$POINT" );
1897 }
1898
1899 std::size_t DEBUG_size(){
1900         return m_faces.size();
1901 }
1902
1903 typedef Faces::const_iterator const_iterator;
1904
1905 const_iterator begin() const {
1906         return m_faces.begin();
1907 }
1908 const_iterator end() const {
1909         return m_faces.end();
1910 }
1911
1912 Face* back(){
1913         return m_faces.back();
1914 }
1915 const Face* back() const {
1916         return m_faces.back();
1917 }
1918 void reserve( std::size_t count ){
1919         m_faces.reserve( count );
1920         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1921         {
1922                 ( *i )->reserve( count );
1923         }
1924 }
1925 void push_back( Faces::value_type face ){
1926         m_faces.push_back( face );
1927         if ( m_instanceCounter.m_count != 0 ) {
1928                 m_faces.back()->instanceAttach( m_map );
1929         }
1930         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1931         {
1932                 ( *i )->push_back( *face );
1933                 ( *i )->DEBUG_verify();
1934         }
1935 }
1936 void pop_back(){
1937         if ( m_instanceCounter.m_count != 0 ) {
1938                 m_faces.back()->instanceDetach( m_map );
1939         }
1940         m_faces.pop_back();
1941         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1942         {
1943                 ( *i )->pop_back();
1944                 ( *i )->DEBUG_verify();
1945         }
1946 }
1947 void erase( std::size_t index ){
1948         if ( m_instanceCounter.m_count != 0 ) {
1949                 m_faces[index]->instanceDetach( m_map );
1950         }
1951         m_faces.erase( m_faces.begin() + index );
1952         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1953         {
1954                 ( *i )->erase( index );
1955                 ( *i )->DEBUG_verify();
1956         }
1957 }
1958 void connectivityChanged(){
1959         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1960         {
1961                 ( *i )->connectivityChanged();
1962         }
1963 }
1964
1965
1966 void clear(){
1967         undoSave();
1968         if ( m_instanceCounter.m_count != 0 ) {
1969                 forEachFace_instanceDetach( m_map );
1970         }
1971         m_faces.clear();
1972         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1973         {
1974                 ( *i )->clear();
1975                 ( *i )->DEBUG_verify();
1976         }
1977 }
1978 std::size_t size() const {
1979         return m_faces.size();
1980 }
1981 bool empty() const {
1982         return m_faces.empty();
1983 }
1984
1985 /// \brief Returns true if any face of the brush contributes to the final B-Rep.
1986 bool hasContributingFaces() const {
1987         for ( const_iterator i = begin(); i != end(); ++i )
1988         {
1989                 if ( ( *i )->contributes() ) {
1990                         return true;
1991                 }
1992         }
1993         return false;
1994 }
1995
1996 /// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush.
1997 /// 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.
1998 void removeEmptyFaces(){
1999         evaluateBRep();
2000
2001         {
2002                 std::size_t i = 0;
2003                 while ( i < m_faces.size() )
2004                 {
2005                         if ( !m_faces[i]->contributes() ) {
2006                                 erase( i );
2007                                 planeChanged();
2008                         }
2009                         else
2010                         {
2011                                 ++i;
2012                         }
2013                 }
2014         }
2015 }
2016
2017 /// \brief Constructs \p winding from the intersection of \p plane with the other planes of the brush.
2018 void windingForClipPlane( Winding& winding, const Plane3& plane ) const {
2019         FixedWinding buffer[2];
2020         bool swap = false;
2021
2022         // get a poly that covers an effectively infinite area
2023         Winding_createInfinite( buffer[swap], plane, m_maxWorldCoord + 1 );
2024
2025         // chop the poly by all of the other faces
2026         {
2027                 for ( std::size_t i = 0; i < m_faces.size(); ++i )
2028                 {
2029                         const Face& clip = *m_faces[i];
2030
2031                         if ( plane3_equal( clip.plane3(), plane )
2032                                  || !plane3_valid( clip.plane3() ) || !plane_unique( i )
2033                                  || plane3_opposing( plane, clip.plane3() ) ) {
2034                                 continue;
2035                         }
2036
2037                         buffer[!swap].clear();
2038
2039 #if BRUSH_CONNECTIVITY_DEBUG
2040                         globalOutputStream() << "clip vs face: " << i << "\n";
2041 #endif
2042
2043                         {
2044                                 // flip the plane, because we want to keep the back side
2045                                 Plane3 clipPlane( vector3_negated( clip.plane3().normal() ), -clip.plane3().dist() );
2046                                 Winding_Clip( buffer[swap], plane, clipPlane, i, buffer[!swap] );
2047                         }
2048
2049 #if BRUSH_CONNECTIVITY_DEBUG
2050                         for ( FixedWinding::Points::iterator k = buffer[!swap].points.begin(), j = buffer[!swap].points.end() - 1; k != buffer[!swap].points.end(); j = k, ++k )
2051                         {
2052                                 if ( vector3_length_squared( vector3_subtracted( ( *k ).vertex, ( *j ).vertex ) ) < 1 ) {
2053                                         globalOutputStream() << "v: " << std::distance( buffer[!swap].points.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n";
2054                                 }
2055                         }
2056 #endif
2057
2058                         //ASSERT_MESSAGE(buffer[!swap].numpoints != 1, "created single-point winding");
2059
2060                         swap = !swap;
2061                 }
2062         }
2063
2064         Winding_forFixedWinding( winding, buffer[swap] );
2065
2066 #if BRUSH_CONNECTIVITY_DEBUG
2067         Winding_printConnectivity( winding );
2068
2069         for ( Winding::iterator i = winding.begin(), j = winding.end() - 1; i != winding.end(); j = i, ++i )
2070         {
2071                 if ( vector3_length_squared( vector3_subtracted( ( *i ).vertex, ( *j ).vertex ) ) < 1 ) {
2072                         globalOutputStream() << "v: " << std::distance( winding.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n";
2073                 }
2074         }
2075 #endif
2076 }
2077
2078 void update_wireframe( RenderableWireframe& wire, const bool* faces_visible ) const {
2079         wire.m_faceVertex.resize( m_edge_indices.size() );
2080         wire.m_vertices = m_uniqueVertexPoints.data();
2081         wire.m_size = 0;
2082         for ( std::size_t i = 0; i < m_edge_faces.size(); ++i )
2083         {
2084                 if ( faces_visible[m_edge_faces[i].first]
2085                          || faces_visible[m_edge_faces[i].second] ) {
2086                         wire.m_faceVertex[wire.m_size++] = m_edge_indices[i];
2087                 }
2088         }
2089 }
2090
2091
2092 void update_faces_wireframe( Array<PointVertex>& wire, const bool* faces_visible ) const {
2093         std::size_t count = 0;
2094         for ( std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i )
2095         {
2096                 if ( faces_visible[i] ) {
2097                         ++count;
2098                 }
2099         }
2100
2101         wire.resize( count );
2102         Array<PointVertex>::iterator p = wire.begin();
2103         for ( std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i )
2104         {
2105                 if ( faces_visible[i] ) {
2106                         *p++ = m_faceCentroidPoints[i];
2107                 }
2108         }
2109 }
2110
2111 /// \brief Makes this brush a deep-copy of the \p other.
2112 void copy( const Brush& other ){
2113         for ( Faces::const_iterator i = other.m_faces.begin(); i != other.m_faces.end(); ++i )
2114         {
2115                 addFace( *( *i ) );
2116         }
2117         planeChanged();
2118 }
2119
2120 private:
2121 void edge_push_back( FaceVertexId faceVertex ){
2122         m_select_edges.push_back( SelectableEdge( m_faces, faceVertex ) );
2123         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2124         {
2125                 ( *i )->edge_push_back( m_select_edges.back() );
2126         }
2127 }
2128 void edge_clear(){
2129         m_select_edges.clear();
2130         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2131         {
2132                 ( *i )->edge_clear();
2133         }
2134 }
2135 void vertex_push_back( FaceVertexId faceVertex ){
2136         m_select_vertices.push_back( SelectableVertex( m_faces, faceVertex ) );
2137         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2138         {
2139                 ( *i )->vertex_push_back( m_select_vertices.back() );
2140         }
2141 }
2142 void vertex_clear(){
2143         m_select_vertices.clear();
2144         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2145         {
2146                 ( *i )->vertex_clear();
2147         }
2148 }
2149
2150 /// \brief Returns true if the face identified by \p index is preceded by another plane that takes priority over it.
2151 bool plane_unique( std::size_t index ) const {
2152         // duplicate plane
2153         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2154         {
2155                 if ( index != i && !plane3_inside( m_faces[index]->plane3(), m_faces[i]->plane3(), index < i ) ) {
2156                         return false;
2157                 }
2158         }
2159         return true;
2160 }
2161
2162 /// \brief Removes edges that are smaller than the tolerance used when generating brush windings.
2163 void removeDegenerateEdges(){
2164         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2165         {
2166                 Winding& winding = m_faces[i]->getWinding();
2167                 for ( Winding::iterator j = winding.begin(); j != winding.end(); )
2168                 {
2169                         std::size_t index = std::distance( winding.begin(), j );
2170                         std::size_t next = Winding_next( winding, index );
2171                         if ( Edge_isDegenerate( winding[index].vertex, winding[next].vertex ) ) {
2172 #if BRUSH_DEGENERATE_DEBUG
2173                                 globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate edge adjacent to " << winding[index].adjacent << "\n";
2174 #endif
2175                                 Winding& other = m_faces[winding[index].adjacent]->getWinding();
2176                                 std::size_t adjacent = Winding_FindAdjacent( other, i );
2177                                 if ( adjacent != c_brush_maxFaces ) {
2178                                         other.erase( other.begin() + adjacent );
2179                                 }
2180                                 winding.erase( j );
2181                         }
2182                         else
2183                         {
2184                                 ++j;
2185                         }
2186                 }
2187         }
2188 }
2189
2190 /// \brief Invalidates faces that have only two vertices in their winding, while preserving edge-connectivity information.
2191 void removeDegenerateFaces(){
2192         // save adjacency info for degenerate faces
2193         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2194         {
2195                 Winding& degen = m_faces[i]->getWinding();
2196
2197                 if ( degen.numpoints == 2 ) {
2198 #if BRUSH_DEGENERATE_DEBUG
2199                         globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate winding adjacent to " << degen[0].adjacent << ", " << degen[1].adjacent << "\n";
2200 #endif
2201                         // this is an "edge" face, where the plane touches the edge of the brush
2202                         {
2203                                 Winding& winding = m_faces[degen[0].adjacent]->getWinding();
2204                                 std::size_t index = Winding_FindAdjacent( winding, i );
2205                                 if ( index != c_brush_maxFaces ) {
2206 #if BRUSH_DEGENERATE_DEBUG
2207                                         globalOutputStream() << "Brush::buildWindings: face " << degen[0].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[1].adjacent << "\n";
2208 #endif
2209                                         winding[index].adjacent = degen[1].adjacent;
2210                                 }
2211                         }
2212
2213                         {
2214                                 Winding& winding = m_faces[degen[1].adjacent]->getWinding();
2215                                 std::size_t index = Winding_FindAdjacent( winding, i );
2216                                 if ( index != c_brush_maxFaces ) {
2217 #if BRUSH_DEGENERATE_DEBUG
2218                                         globalOutputStream() << "Brush::buildWindings: face " << degen[1].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[0].adjacent << "\n";
2219 #endif
2220                                         winding[index].adjacent = degen[0].adjacent;
2221                                 }
2222                         }
2223
2224                         degen.resize( 0 );
2225                 }
2226         }
2227 }
2228
2229 /// \brief Removes edges that have the same adjacent-face as their immediate neighbour.
2230 void removeDuplicateEdges(){
2231         // verify face connectivity graph
2232         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2233         {
2234                 //if(m_faces[i]->contributes())
2235                 {
2236                         Winding& winding = m_faces[i]->getWinding();
2237                         for ( std::size_t j = 0; j != winding.numpoints; )
2238                         {
2239                                 std::size_t next = Winding_next( winding, j );
2240                                 if ( winding[j].adjacent == winding[next].adjacent ) {
2241 #if BRUSH_DEGENERATE_DEBUG
2242                                         globalOutputStream() << "Brush::buildWindings: face " << i << ": removed duplicate edge adjacent to face " << winding[j].adjacent << "\n";
2243 #endif
2244                                         winding.erase( winding.begin() + next );
2245                                 }
2246                                 else
2247                                 {
2248                                         ++j;
2249                                 }
2250                         }
2251                 }
2252         }
2253 }
2254
2255 /// \brief Removes edges that do not have a matching pair in their adjacent-face.
2256 void verifyConnectivityGraph(){
2257         // verify face connectivity graph
2258         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2259         {
2260                 //if(m_faces[i]->contributes())
2261                 {
2262                         Winding& winding = m_faces[i]->getWinding();
2263                         for ( Winding::iterator j = winding.begin(); j != winding.end(); )
2264                         {
2265 #if BRUSH_CONNECTIVITY_DEBUG
2266                                 globalOutputStream() << "Brush::buildWindings: face " << i << ": adjacent to face " << ( *j ).adjacent << "\n";
2267 #endif
2268                                 // remove unidirectional graph edges
2269                                 if ( ( *j ).adjacent == c_brush_maxFaces
2270                                          || Winding_FindAdjacent( m_faces[( *j ).adjacent]->getWinding(), i ) == c_brush_maxFaces ) {
2271 #if BRUSH_CONNECTIVITY_DEBUG
2272                                         globalOutputStream() << "Brush::buildWindings: face " << i << ": removing unidirectional connectivity graph edge adjacent to face " << ( *j ).adjacent << "\n";
2273 #endif
2274                                         winding.erase( j );
2275                                 }
2276                                 else
2277                                 {
2278                                         ++j;
2279                                 }
2280                         }
2281                 }
2282         }
2283 }
2284
2285 /// \brief Returns true if the brush is a finite volume. A brush without a finite volume extends past the maximum world bounds and is not valid.
2286 bool isBounded(){
2287         for ( const_iterator i = begin(); i != end(); ++i )
2288         {
2289                 if ( !( *i )->is_bounded() ) {
2290                         return false;
2291                 }
2292         }
2293         return true;
2294 }
2295
2296 /// \brief Constructs the polygon windings for each face of the brush. Also updates the brush bounding-box and face texture-coordinates.
2297 bool buildWindings(){
2298
2299         {
2300                 m_aabb_local = AABB();
2301
2302                 for ( std::size_t i = 0; i < m_faces.size(); ++i )
2303                 {
2304                         Face& f = *m_faces[i];
2305
2306                         if ( !plane3_valid( f.plane3() ) || !plane_unique( i ) ) {
2307                                 f.getWinding().resize( 0 );
2308                         }
2309                         else
2310                         {
2311 #if BRUSH_CONNECTIVITY_DEBUG
2312                                 globalOutputStream() << "face: " << i << "\n";
2313 #endif
2314                                 windingForClipPlane( f.getWinding(), f.plane3() );
2315
2316                                 // update brush bounds
2317                                 const Winding& winding = f.getWinding();
2318                                 for ( Winding::const_iterator i = winding.begin(); i != winding.end(); ++i )
2319                                 {
2320                                         aabb_extend_by_point_safe( m_aabb_local, ( *i ).vertex );
2321                                 }
2322
2323                                 // update texture coordinates
2324                                 f.EmitTextureCoordinates();
2325                         }
2326                 }
2327         }
2328
2329         bool degenerate = !isBounded();
2330
2331         if ( !degenerate ) {
2332                 // clean up connectivity information.
2333                 // these cleanups must be applied in a specific order.
2334                 removeDegenerateEdges();
2335                 removeDegenerateFaces();
2336                 removeDuplicateEdges();
2337                 verifyConnectivityGraph();
2338         }
2339
2340         return degenerate;
2341 }
2342
2343 /// \brief Constructs the face windings and updates anything that depends on them.
2344 void buildBRep();
2345 };
2346
2347
2348
2349 class FaceInstance;
2350
2351 class FaceInstanceSet
2352 {
2353 typedef SelectionList<FaceInstance> FaceInstances;
2354 FaceInstances m_faceInstances;
2355 public:
2356 void insert( FaceInstance& faceInstance ){
2357         m_faceInstances.append( faceInstance );
2358 }
2359 void erase( FaceInstance& faceInstance ){
2360         m_faceInstances.erase( faceInstance );
2361 }
2362
2363 template<typename Functor>
2364 void foreach( Functor functor ){
2365         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
2366         {
2367                 functor( *( *i ) );
2368         }
2369 }
2370
2371 bool empty() const {
2372         return m_faceInstances.empty();
2373 }
2374 FaceInstance& last() const {
2375         return m_faceInstances.back();
2376 }
2377 };
2378
2379 extern FaceInstanceSet g_SelectedFaceInstances;
2380
2381 typedef std::list<std::size_t> VertexSelection;
2382
2383 inline VertexSelection::iterator VertexSelection_find( VertexSelection& self, std::size_t value ){
2384         return std::find( self.begin(), self.end(), value );
2385 }
2386
2387 inline VertexSelection::const_iterator VertexSelection_find( const VertexSelection& self, std::size_t value ){
2388         return std::find( self.begin(), self.end(), value );
2389 }
2390
2391 inline VertexSelection::iterator VertexSelection_insert( VertexSelection& self, std::size_t value ){
2392         VertexSelection::iterator i = VertexSelection_find( self, value );
2393         if ( i == self.end() ) {
2394                 self.push_back( value );
2395                 return --self.end();
2396         }
2397         return i;
2398 }
2399 inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){
2400         VertexSelection::iterator i = VertexSelection_find( self, value );
2401         if ( i != self.end() ) {
2402                 self.erase( i );
2403         }
2404 }
2405
2406 inline bool triangle_reversed( std::size_t x, std::size_t y, std::size_t z ){
2407         return !( ( x < y && y < z ) || ( z < x && x < y ) || ( y < z && z < x ) );
2408 }
2409 template<typename Element>
2410 inline Vector3 triangle_cross( const BasicVector3<Element>& x, const BasicVector3<Element> y, const BasicVector3<Element>& z ){
2411         return vector3_cross( y - x, z - x );
2412 }
2413 template<typename Element>
2414 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 ){
2415         return vector3_dot( triangle_cross( x1, y1, z1 ), triangle_cross( x2, y2, z2 ) ) > 0;
2416 }
2417
2418
2419 typedef const Plane3* PlanePointer;
2420 typedef PlanePointer* PlanesIterator;
2421
2422 class VectorLightList : public LightList
2423 {
2424 typedef std::vector<const RendererLight*> Lights;
2425 Lights m_lights;
2426 public:
2427 void addLight( const RendererLight& light ){
2428         m_lights.push_back( &light );
2429 }
2430 void clear(){
2431         m_lights.clear();
2432 }
2433 void evaluateLights() const {
2434 }
2435 void lightsChanged() const {
2436 }
2437 void forEachLight( const RendererLightCallback& callback ) const {
2438         for ( Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i )
2439         {
2440                 callback( *( *i ) );
2441         }
2442 }
2443 };
2444
2445 class FaceInstance
2446 {
2447 Face* m_face;
2448 ObservedSelectable m_selectable;
2449 ObservedSelectable m_selectableVertices;
2450 ObservedSelectable m_selectableEdges;
2451 SelectionChangeCallback m_selectionChanged;
2452
2453 VertexSelection m_vertexSelection;
2454 VertexSelection m_edgeSelection;
2455
2456 public:
2457 mutable VectorLightList m_lights;
2458
2459 FaceInstance( Face& face, const SelectionChangeCallback& observer ) :
2460         m_face( &face ),
2461         m_selectable( SelectedChangedCaller( *this ) ),
2462         m_selectableVertices( observer ),
2463         m_selectableEdges( observer ),
2464         m_selectionChanged( observer ){
2465 }
2466 FaceInstance( const FaceInstance& other ) :
2467         m_face( other.m_face ),
2468         m_selectable( SelectedChangedCaller( *this ) ),
2469         m_selectableVertices( other.m_selectableVertices ),
2470         m_selectableEdges( other.m_selectableEdges ),
2471         m_selectionChanged( other.m_selectionChanged ){
2472 }
2473 FaceInstance& operator=( const FaceInstance& other ){
2474         m_face = other.m_face;
2475         return *this;
2476 }
2477
2478 Face& getFace(){
2479         return *m_face;
2480 }
2481 const Face& getFace() const {
2482         return *m_face;
2483 }
2484
2485 void selectedChanged( const Selectable& selectable ){
2486         if ( selectable.isSelected() ) {
2487                 g_SelectedFaceInstances.insert( *this );
2488         }
2489         else
2490         {
2491                 g_SelectedFaceInstances.erase( *this );
2492         }
2493         m_selectionChanged( selectable );
2494 }
2495 typedef MemberCaller1<FaceInstance, const Selectable&, &FaceInstance::selectedChanged> SelectedChangedCaller;
2496
2497 bool selectedVertices() const {
2498         return !m_vertexSelection.empty();
2499 }
2500 bool selectedEdges() const {
2501         return !m_edgeSelection.empty();
2502 }
2503 bool isSelected() const {
2504         return m_selectable.isSelected();
2505 }
2506
2507 bool selectedComponents() const {
2508         return selectedVertices() || selectedEdges() || isSelected();
2509 }
2510 bool selectedComponents( SelectionSystem::EComponentMode mode ) const {
2511         switch ( mode )
2512         {
2513         case SelectionSystem::eVertex:
2514                 return selectedVertices();
2515         case SelectionSystem::eEdge:
2516                 return selectedEdges();
2517         case SelectionSystem::eFace:
2518                 return isSelected();
2519         default:
2520                 return false;
2521         }
2522 }
2523 void setSelected( SelectionSystem::EComponentMode mode, bool select ){
2524         switch ( mode )
2525         {
2526         case SelectionSystem::eFace:
2527                 m_selectable.setSelected( select );
2528                 break;
2529         case SelectionSystem::eVertex:
2530                 ASSERT_MESSAGE( !select, "select-all not supported" );
2531
2532                 m_vertexSelection.clear();
2533                 m_selectableVertices.setSelected( false );
2534                 break;
2535         case SelectionSystem::eEdge:
2536                 ASSERT_MESSAGE( !select, "select-all not supported" );
2537
2538                 m_edgeSelection.clear();
2539                 m_selectableEdges.setSelected( false );
2540                 break;
2541         default:
2542                 break;
2543         }
2544 }
2545
2546 template<typename Functor>
2547 void SelectedVertices_foreach( Functor functor ) const {
2548         for ( VertexSelection::const_iterator i = m_vertexSelection.begin(); i != m_vertexSelection.end(); ++i )
2549         {
2550                 std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *i );
2551                 if ( index != c_brush_maxFaces ) {
2552                         functor( getFace().getWinding()[index].vertex );
2553                 }
2554         }
2555 }
2556 template<typename Functor>
2557 void SelectedEdges_foreach( Functor functor ) const {
2558         for ( VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i )
2559         {
2560                 std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *i );
2561                 if ( index != c_brush_maxFaces ) {
2562                         const Winding& winding = getFace().getWinding();
2563                         std::size_t adjacent = Winding_next( winding, index );
2564                         functor( vector3_mid( winding[index].vertex, winding[adjacent].vertex ) );
2565                 }
2566         }
2567 }
2568 template<typename Functor>
2569 void SelectedFaces_foreach( Functor functor ) const {
2570         if ( isSelected() ) {
2571                 functor( centroid() );
2572         }
2573 }
2574
2575 template<typename Functor>
2576 void SelectedComponents_foreach( Functor functor ) const {
2577         SelectedVertices_foreach( functor );
2578         SelectedEdges_foreach( functor );
2579         SelectedFaces_foreach( functor );
2580 }
2581
2582 void iterate_selected( AABB& aabb ) const {
2583         SelectedComponents_foreach( AABBExtendByPoint( aabb ) );
2584 }
2585
2586 class RenderablePointVectorPushBack
2587 {
2588 RenderablePointVector& m_points;
2589 public:
2590 RenderablePointVectorPushBack( RenderablePointVector& points ) : m_points( points ){
2591 }
2592 void operator()( const Vector3& point ) const {
2593         const Colour4b colour_selected( 0, 0, 255, 255 );
2594         m_points.push_back( pointvertex_for_windingpoint( point, colour_selected ) );
2595 }
2596 };
2597
2598 void iterate_selected( RenderablePointVector& points ) const {
2599         SelectedComponents_foreach( RenderablePointVectorPushBack( points ) );
2600 }
2601
2602 bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
2603         return m_face->intersectVolume( volume, localToWorld );
2604 }
2605
2606 void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
2607         if ( !m_face->isFiltered() && m_face->contributes() && intersectVolume( volume, localToWorld ) ) {
2608                 renderer.PushState();
2609                 if ( selectedComponents() ) {
2610                         renderer.Highlight( Renderer::eFace );
2611                 }
2612                 m_face->render( renderer, localToWorld );
2613                 renderer.PopState();
2614         }
2615 }
2616
2617 void testSelect( SelectionTest& test, SelectionIntersection& best ){
2618         if ( !m_face->isFiltered() ) {
2619                 m_face->testSelect( test, best );
2620         }
2621 }
2622 void testSelect( Selector& selector, SelectionTest& test ){
2623         SelectionIntersection best;
2624         testSelect( test, best );
2625         if ( best.valid() ) {
2626                 Selector_add( selector, m_selectable, best );
2627         }
2628 }
2629 void testSelect_centroid( Selector& selector, SelectionTest& test ){
2630         if ( m_face->contributes() && !m_face->isFiltered() ) {
2631                 SelectionIntersection best;
2632                 m_face->testSelect_centroid( test, best );
2633                 if ( best.valid() ) {
2634                         Selector_add( selector, m_selectable, best );
2635                 }
2636         }
2637 }
2638
2639 void selectPlane( Selector& selector, const Line& line, PlanesIterator first, PlanesIterator last, const PlaneCallback& selectedPlaneCallback ){
2640         for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i )
2641         {
2642                 Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
2643                 double dot = vector3_dot( getFace().plane3().normal(), v );
2644                 if ( dot <= 0 ) {
2645                         return;
2646                 }
2647         }
2648
2649         Selector_add( selector, m_selectable );
2650
2651         selectedPlaneCallback( getFace().plane3() );
2652 }
2653 void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlanes ){
2654         if ( selectedPlanes.contains( plane3_flipped( getFace().plane3() ) ) ) {
2655                 Selector_add( selector, m_selectable );
2656         }
2657 }
2658
2659 void transformComponents( const Matrix4& matrix ){
2660         if ( isSelected() ) {
2661                 m_face->transform( matrix, false );
2662         }
2663         if ( selectedVertices() ) {
2664                 if ( m_vertexSelection.size() == 1 ) {
2665                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2666                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2667                 }
2668                 else if ( m_vertexSelection.size() == 2 ) {
2669                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2670                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2671                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2672                 }
2673                 else if ( m_vertexSelection.size() >= 3 ) {
2674                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2675                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2676                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2677                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2678                 }
2679         }
2680         if ( selectedEdges() ) {
2681                 if ( m_edgeSelection.size() == 1 ) {
2682                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2683                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2684                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2685                 }
2686                 else if ( m_edgeSelection.size() >= 2 ) {
2687                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2688                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2689                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2690                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2691                 }
2692         }
2693 }
2694
2695 void snapto( float snap ){
2696         m_face->snapto( snap );
2697 }
2698
2699 void snapComponents( float snap ){
2700         if ( isSelected() ) {
2701                 snapto( snap );
2702         }
2703         if ( selectedVertices() ) {
2704                 vector3_snap( m_face->m_move_planepts[0], snap );
2705                 vector3_snap( m_face->m_move_planepts[1], snap );
2706                 vector3_snap( m_face->m_move_planepts[2], snap );
2707                 m_face->assign_planepts( m_face->m_move_planepts );
2708                 planepts_assign( m_face->m_move_planeptsTransformed, m_face->m_move_planepts );
2709                 m_face->freezeTransform();
2710         }
2711         if ( selectedEdges() ) {
2712                 vector3_snap( m_face->m_move_planepts[0], snap );
2713                 vector3_snap( m_face->m_move_planepts[1], snap );
2714                 vector3_snap( m_face->m_move_planepts[2], snap );
2715                 m_face->assign_planepts( m_face->m_move_planepts );
2716                 planepts_assign( m_face->m_move_planeptsTransformed, m_face->m_move_planepts );
2717                 m_face->freezeTransform();
2718         }
2719 }
2720 void update_move_planepts_vertex( std::size_t index ){
2721         m_face->update_move_planepts_vertex( index, m_face->m_move_planepts );
2722 }
2723 void update_move_planepts_vertex2( std::size_t index, std::size_t other ){
2724         const std::size_t numpoints = m_face->getWinding().numpoints;
2725         ASSERT_MESSAGE( index < numpoints, "select_vertex: invalid index" );
2726
2727         const std::size_t opposite = Winding_Opposite( m_face->getWinding(), index, other );
2728
2729         if ( triangle_reversed( index, other, opposite ) ) {
2730                 std::swap( index, other );
2731         }
2732
2733         ASSERT_MESSAGE(
2734                 triangles_same_winding(
2735                         m_face->getWinding()[opposite].vertex,
2736                         m_face->getWinding()[index].vertex,
2737                         m_face->getWinding()[other].vertex,
2738                         m_face->getWinding()[0].vertex,
2739                         m_face->getWinding()[1].vertex,
2740                         m_face->getWinding()[2].vertex
2741                         ),
2742                 "update_move_planepts_vertex2: error"
2743                 );
2744
2745         m_face->m_move_planepts[0] = m_face->getWinding()[opposite].vertex;
2746         m_face->m_move_planepts[1] = m_face->getWinding()[index].vertex;
2747         m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex;
2748         planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
2749 }
2750 void update_selection_vertex(){
2751         if ( m_vertexSelection.size() == 0 ) {
2752                 m_selectableVertices.setSelected( false );
2753         }
2754         else
2755         {
2756                 m_selectableVertices.setSelected( true );
2757
2758                 if ( m_vertexSelection.size() == 1 ) {
2759                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_vertexSelection.begin() );
2760
2761                         if ( index != c_brush_maxFaces ) {
2762                                 update_move_planepts_vertex( index );
2763                         }
2764                 }
2765                 else if ( m_vertexSelection.size() == 2 ) {
2766                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_vertexSelection.begin() );
2767                         std::size_t other = Winding_FindAdjacent( getFace().getWinding(), *( ++m_vertexSelection.begin() ) );
2768
2769                         if ( index != c_brush_maxFaces
2770                                  && other != c_brush_maxFaces ) {
2771                                 update_move_planepts_vertex2( index, other );
2772                         }
2773                 }
2774         }
2775 }
2776 void select_vertex( std::size_t index, bool select ){
2777         if ( select ) {
2778                 VertexSelection_insert( m_vertexSelection, getFace().getWinding()[index].adjacent );
2779         }
2780         else
2781         {
2782                 VertexSelection_erase( m_vertexSelection, getFace().getWinding()[index].adjacent );
2783         }
2784
2785         SceneChangeNotify();
2786         update_selection_vertex();
2787 }
2788
2789 bool selected_vertex( std::size_t index ) const {
2790         return VertexSelection_find( m_vertexSelection, getFace().getWinding()[index].adjacent ) != m_vertexSelection.end();
2791 }
2792
2793 void update_move_planepts_edge( std::size_t index ){
2794         std::size_t numpoints = m_face->getWinding().numpoints;
2795         ASSERT_MESSAGE( index < numpoints, "select_edge: invalid index" );
2796
2797         std::size_t adjacent = Winding_next( m_face->getWinding(), index );
2798         std::size_t opposite = Winding_Opposite( m_face->getWinding(), index );
2799         m_face->m_move_planepts[0] = m_face->getWinding()[index].vertex;
2800         m_face->m_move_planepts[1] = m_face->getWinding()[adjacent].vertex;
2801         m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex;
2802         planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
2803 }
2804 void update_selection_edge(){
2805         if ( m_edgeSelection.size() == 0 ) {
2806                 m_selectableEdges.setSelected( false );
2807         }
2808         else
2809         {
2810                 m_selectableEdges.setSelected( true );
2811
2812                 if ( m_edgeSelection.size() == 1 ) {
2813                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_edgeSelection.begin() );
2814
2815                         if ( index != c_brush_maxFaces ) {
2816                                 update_move_planepts_edge( index );
2817                         }
2818                 }
2819         }
2820 }
2821 void select_edge( std::size_t index, bool select ){
2822         if ( select ) {
2823                 VertexSelection_insert( m_edgeSelection, getFace().getWinding()[index].adjacent );
2824         }
2825         else
2826         {
2827                 VertexSelection_erase( m_edgeSelection, getFace().getWinding()[index].adjacent );
2828         }
2829
2830         SceneChangeNotify();
2831         update_selection_edge();
2832 }
2833
2834 bool selected_edge( std::size_t index ) const {
2835         return VertexSelection_find( m_edgeSelection, getFace().getWinding()[index].adjacent ) != m_edgeSelection.end();
2836 }
2837
2838 const Vector3& centroid() const {
2839         return m_face->centroid();
2840 }
2841
2842 void connectivityChanged(){
2843         // This occurs when a face is added or removed.
2844         // The current vertex and edge selections no longer valid and must be cleared.
2845         m_vertexSelection.clear();
2846         m_selectableVertices.setSelected( false );
2847         m_edgeSelection.clear();
2848         m_selectableEdges.setSelected( false );
2849 }
2850 };
2851
2852 class BrushClipPlane : public OpenGLRenderable
2853 {
2854 Plane3 m_plane;
2855 Winding m_winding;
2856 static Shader* m_state;
2857 public:
2858 static void constructStatic(){
2859         m_state = GlobalShaderCache().capture( "$CLIPPER_OVERLAY" );
2860 }
2861 static void destroyStatic(){
2862         GlobalShaderCache().release( "$CLIPPER_OVERLAY" );
2863 }
2864
2865 void setPlane( const Brush& brush, const Plane3& plane ){
2866         m_plane = plane;
2867         if ( plane3_valid( m_plane ) ) {
2868                 brush.windingForClipPlane( m_winding, m_plane );
2869         }
2870         else
2871         {
2872                 m_winding.resize( 0 );
2873         }
2874 }
2875
2876 void render( RenderStateFlags state ) const {
2877         if ( ( state & RENDER_FILL ) != 0 ) {
2878                 Winding_Draw( m_winding, m_plane.normal(), state );
2879         }
2880         else
2881         {
2882                 Winding_DrawWireframe( m_winding );
2883
2884                 // also draw a line indicating the direction of the cut
2885                 Vector3 lineverts[2];
2886                 Winding_Centroid( m_winding, m_plane, lineverts[0] );
2887                 lineverts[1] = vector3_added( lineverts[0], vector3_scaled( m_plane.normal(), Brush::m_maxWorldCoord * 4 ) );
2888
2889                 glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), &lineverts[0] );
2890                 glDrawArrays( GL_LINES, 0, GLsizei( 2 ) );
2891         }
2892 }
2893
2894 void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
2895         renderer.SetState( m_state, Renderer::eWireframeOnly );
2896         renderer.SetState( m_state, Renderer::eFullMaterials );
2897         renderer.addRenderable( *this, localToWorld );
2898 }
2899 };
2900
2901 inline void Face_addLight( const FaceInstance& face, const Matrix4& localToWorld, const RendererLight& light ){
2902         const Plane3& facePlane = face.getFace().plane3();
2903         const Vector3& origin = light.aabb().origin;
2904         Plane3 tmp( plane3_transformed( Plane3( facePlane.normal(), -facePlane.dist() ), localToWorld ) );
2905         if ( !plane3_test_point( tmp, origin )
2906                  || !plane3_test_point( tmp, vector3_added( origin, light.offset() ) ) ) {
2907                 face.m_lights.addLight( light );
2908         }
2909 }
2910
2911
2912
2913 typedef std::vector<FaceInstance> FaceInstances;
2914
2915 class EdgeInstance : public Selectable
2916 {
2917 FaceInstances& m_faceInstances;
2918 SelectableEdge* m_edge;
2919
2920 void select_edge( bool select ){
2921         FaceVertexId faceVertex = m_edge->m_faceVertex;
2922         m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select );
2923         faceVertex = next_edge( m_edge->m_faces, faceVertex );
2924         m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select );
2925 }
2926 bool selected_edge() const {
2927         FaceVertexId faceVertex = m_edge->m_faceVertex;
2928         if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) {
2929                 return false;
2930         }
2931         faceVertex = next_edge( m_edge->m_faces, faceVertex );
2932         if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) {
2933                 return false;
2934         }
2935
2936         return true;
2937 }
2938
2939 public:
2940 EdgeInstance( FaceInstances& faceInstances, SelectableEdge& edge )
2941         : m_faceInstances( faceInstances ), m_edge( &edge ){
2942 }
2943 EdgeInstance& operator=( const EdgeInstance& other ){
2944         m_edge = other.m_edge;
2945         return *this;
2946 }
2947
2948 void setSelected( bool select ){
2949         select_edge( select );
2950 }
2951 bool isSelected() const {
2952         return selected_edge();
2953 }
2954
2955
2956 void testSelect( Selector& selector, SelectionTest& test ){
2957         SelectionIntersection best;
2958         m_edge->testSelect( test, best );
2959         if ( best.valid() ) {
2960                 Selector_add( selector, *this, best );
2961         }
2962 }
2963 };
2964
2965 class VertexInstance : public Selectable
2966 {
2967 FaceInstances& m_faceInstances;
2968 SelectableVertex* m_vertex;
2969
2970 void select_vertex( bool select ){
2971         FaceVertexId faceVertex = m_vertex->m_faceVertex;
2972         do
2973         {
2974                 m_faceInstances[faceVertex.getFace()].select_vertex( faceVertex.getVertex(), select );
2975                 faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
2976         }
2977         while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
2978 }
2979 bool selected_vertex() const {
2980         FaceVertexId faceVertex = m_vertex->m_faceVertex;
2981         do
2982         {
2983                 if ( !m_faceInstances[faceVertex.getFace()].selected_vertex( faceVertex.getVertex() ) ) {
2984                         return false;
2985                 }
2986                 faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
2987         }
2988         while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
2989         return true;
2990 }
2991
2992 public:
2993 VertexInstance( FaceInstances& faceInstances, SelectableVertex& vertex )
2994         : m_faceInstances( faceInstances ), m_vertex( &vertex ){
2995 }
2996 VertexInstance& operator=( const VertexInstance& other ){
2997         m_vertex = other.m_vertex;
2998         return *this;
2999 }
3000
3001 void setSelected( bool select ){
3002         select_vertex( select );
3003 }
3004 bool isSelected() const {
3005         return selected_vertex();
3006 }
3007
3008 void testSelect( Selector& selector, SelectionTest& test ){
3009         SelectionIntersection best;
3010         m_vertex->testSelect( test, best );
3011         if ( best.valid() ) {
3012                 Selector_add( selector, *this, best );
3013         }
3014 }
3015 };
3016
3017 class BrushInstanceVisitor
3018 {
3019 public:
3020 virtual void visit( FaceInstance& face ) const = 0;
3021 };
3022
3023 class BrushInstance :
3024         public BrushObserver,
3025         public scene::Instance,
3026         public Selectable,
3027         public Renderable,
3028         public SelectionTestable,
3029         public ComponentSelectionTestable,
3030         public ComponentEditable,
3031         public ComponentSnappable,
3032         public PlaneSelectable,
3033         public LightCullable
3034 {
3035 class TypeCasts
3036 {
3037 InstanceTypeCastTable m_casts;
3038 public:
3039 TypeCasts(){
3040         InstanceStaticCast<BrushInstance, Selectable>::install( m_casts );
3041         InstanceContainedCast<BrushInstance, Bounded>::install( m_casts );
3042         InstanceContainedCast<BrushInstance, Cullable>::install( m_casts );
3043         InstanceStaticCast<BrushInstance, Renderable>::install( m_casts );
3044         InstanceStaticCast<BrushInstance, SelectionTestable>::install( m_casts );
3045         InstanceStaticCast<BrushInstance, ComponentSelectionTestable>::install( m_casts );
3046         InstanceStaticCast<BrushInstance, ComponentEditable>::install( m_casts );
3047         InstanceStaticCast<BrushInstance, ComponentSnappable>::install( m_casts );
3048         InstanceStaticCast<BrushInstance, PlaneSelectable>::install( m_casts );
3049         InstanceIdentityCast<BrushInstance>::install( m_casts );
3050         InstanceContainedCast<BrushInstance, Transformable>::install( m_casts );
3051 }
3052 InstanceTypeCastTable& get(){
3053         return m_casts;
3054 }
3055 };
3056
3057
3058 Brush& m_brush;
3059
3060 FaceInstances m_faceInstances;
3061
3062 typedef std::vector<EdgeInstance> EdgeInstances;
3063 EdgeInstances m_edgeInstances;
3064 typedef std::vector<VertexInstance> VertexInstances;
3065 VertexInstances m_vertexInstances;
3066
3067 ObservedSelectable m_selectable;
3068
3069 mutable RenderableWireframe m_render_wireframe;
3070 mutable RenderablePointVector m_render_selected;
3071 mutable AABB m_aabb_component;
3072 mutable Array<PointVertex> m_faceCentroidPointsCulled;
3073 RenderablePointArray m_render_faces_wireframe;
3074 mutable bool m_viewChanged;   // requires re-evaluation of view-dependent cached data
3075
3076 BrushClipPlane m_clipPlane;
3077
3078 static Shader* m_state_selpoint;
3079
3080 const LightList* m_lightList;
3081
3082 TransformModifier m_transform;
3083
3084 BrushInstance( const BrushInstance& other ); // NOT COPYABLE
3085 BrushInstance& operator=( const BrushInstance& other ); // NOT ASSIGNABLE
3086 public:
3087 static Counter* m_counter;
3088
3089 typedef LazyStatic<TypeCasts> StaticTypeCasts;
3090
3091 void lightsChanged(){
3092         m_lightList->lightsChanged();
3093 }
3094 typedef MemberCaller<BrushInstance, &BrushInstance::lightsChanged> LightsChangedCaller;
3095
3096 STRING_CONSTANT( Name, "BrushInstance" );
3097
3098 BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush ) :
3099         Instance( path, parent, this, StaticTypeCasts::instance().get() ),
3100         m_brush( brush ),
3101         m_selectable( SelectedChangedCaller( *this ) ),
3102         m_render_selected( GL_POINTS ),
3103         m_render_faces_wireframe( m_faceCentroidPointsCulled, GL_POINTS ),
3104         m_viewChanged( false ),
3105         m_transform( Brush::TransformChangedCaller( m_brush ), ApplyTransformCaller( *this ) ){
3106         m_brush.instanceAttach( Instance::path() );
3107         m_brush.attach( *this );
3108         m_counter->increment();
3109
3110         m_lightList = &GlobalShaderCache().attach( *this );
3111         m_brush.m_lightsChanged = LightsChangedCaller( *this ); ///\todo Make this work with instancing.
3112
3113         Instance::setTransformChangedCallback( LightsChangedCaller( *this ) );
3114 }
3115 ~BrushInstance(){
3116         Instance::setTransformChangedCallback( Callback() );
3117
3118         m_brush.m_lightsChanged = Callback();
3119         GlobalShaderCache().detach( *this );
3120
3121         m_counter->decrement();
3122         m_brush.detach( *this );
3123         m_brush.instanceDetach( Instance::path() );
3124 }
3125
3126 Brush& getBrush(){
3127         return m_brush;
3128 }
3129 const Brush& getBrush() const {
3130         return m_brush;
3131 }
3132
3133 Bounded& get( NullType<Bounded>){
3134         return m_brush;
3135 }
3136 Cullable& get( NullType<Cullable>){
3137         return m_brush;
3138 }
3139 Transformable& get( NullType<Transformable>){
3140         return m_transform;
3141 }
3142
3143 void selectedChanged( const Selectable& selectable ){
3144         GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable );
3145         GlobalSelectionSystem().onSelectedChanged( *this, selectable );
3146
3147         Instance::selectedChanged();
3148 }
3149 typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChanged> SelectedChangedCaller;
3150
3151 void selectedChangedComponent( const Selectable& selectable ){
3152         GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
3153         GlobalSelectionSystem().onComponentSelection( *this, selectable );
3154 }
3155 typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChangedComponent> SelectedChangedComponentCaller;
3156
3157 const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& visitor ){
3158         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3159         {
3160                 visitor.visit( *i );
3161         }
3162         return visitor;
3163 }
3164
3165 static void constructStatic(){
3166         m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" );
3167 }
3168 static void destroyStatic(){
3169         GlobalShaderCache().release( "$SELPOINT" );
3170 }
3171
3172 void clear(){
3173         m_faceInstances.clear();
3174 }
3175 void reserve( std::size_t size ){
3176         m_faceInstances.reserve( size );
3177 }
3178
3179 void push_back( Face& face ){
3180         m_faceInstances.push_back( FaceInstance( face, SelectedChangedComponentCaller( *this ) ) );
3181 }
3182 void pop_back(){
3183         ASSERT_MESSAGE( !m_faceInstances.empty(), "erasing invalid element" );
3184         m_faceInstances.pop_back();
3185 }
3186 void erase( std::size_t index ){
3187         ASSERT_MESSAGE( index < m_faceInstances.size(), "erasing invalid element" );
3188         m_faceInstances.erase( m_faceInstances.begin() + index );
3189 }
3190 void connectivityChanged(){
3191         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3192         {
3193                 ( *i ).connectivityChanged();
3194         }
3195 }
3196
3197 void edge_clear(){
3198         m_edgeInstances.clear();
3199 }
3200 void edge_push_back( SelectableEdge& edge ){
3201         m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) );
3202 }
3203
3204 void vertex_clear(){
3205         m_vertexInstances.clear();
3206 }
3207 void vertex_push_back( SelectableVertex& vertex ){
3208         m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) );
3209 }
3210
3211 void DEBUG_verify() const {
3212         ASSERT_MESSAGE( m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch" );
3213 }
3214
3215 bool isSelected() const {
3216         return m_selectable.isSelected();
3217 }
3218 void setSelected( bool select ){
3219         m_selectable.setSelected( select );
3220 }
3221
3222 void update_selected() const {
3223         m_render_selected.clear();
3224         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3225         {
3226                 if ( ( *i ).getFace().contributes() ) {
3227                         ( *i ).iterate_selected( m_render_selected );
3228                 }
3229         }
3230 }
3231
3232 void evaluateViewDependent( const VolumeTest& volume, const Matrix4& localToWorld ) const {
3233         if ( m_viewChanged ) {
3234                 m_viewChanged = false;
3235
3236                 bool faces_visible[c_brush_maxFaces];
3237                 {
3238                         bool* j = faces_visible;
3239                         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j )
3240                         {
3241                                 *j = ( *i ).intersectVolume( volume, localToWorld );
3242                         }
3243                 }
3244
3245                 m_brush.update_wireframe( m_render_wireframe, faces_visible );
3246                 m_brush.update_faces_wireframe( m_faceCentroidPointsCulled, faces_visible );
3247         }
3248 }
3249
3250 void renderComponentsSelected( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3251         m_brush.evaluateBRep();
3252
3253         update_selected();
3254         if ( !m_render_selected.empty() ) {
3255                 renderer.Highlight( Renderer::ePrimitive, false );
3256                 renderer.SetState( m_state_selpoint, Renderer::eWireframeOnly );
3257                 renderer.SetState( m_state_selpoint, Renderer::eFullMaterials );
3258                 renderer.addRenderable( m_render_selected, localToWorld );
3259         }
3260 }
3261
3262 void renderComponents( Renderer& renderer, const VolumeTest& volume ) const {
3263         m_brush.evaluateBRep();
3264
3265         const Matrix4& localToWorld = Instance::localToWorld();
3266
3267         renderer.SetState( m_brush.m_state_point, Renderer::eWireframeOnly );
3268         renderer.SetState( m_brush.m_state_point, Renderer::eFullMaterials );
3269
3270         if ( volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace ) {
3271                 evaluateViewDependent( volume, localToWorld );
3272                 renderer.addRenderable( m_render_faces_wireframe, localToWorld );
3273         }
3274         else
3275         {
3276                 m_brush.renderComponents( GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld );
3277         }
3278 }
3279
3280 void renderClipPlane( Renderer& renderer, const VolumeTest& volume ) const {
3281         if ( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected() ) {
3282                 m_clipPlane.render( renderer, volume, localToWorld() );
3283         }
3284 }
3285
3286 void renderCommon( Renderer& renderer, const VolumeTest& volume ) const {
3287         bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent;
3288
3289         if ( componentMode && isSelected() ) {
3290                 renderComponents( renderer, volume );
3291         }
3292
3293         if ( parentSelected() ) {
3294                 if ( !componentMode ) {
3295                         renderer.Highlight( Renderer::eFace );
3296                 }
3297                 renderer.Highlight( Renderer::ePrimitive );
3298         }
3299 }
3300
3301 void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3302         //renderCommon(renderer, volume);
3303
3304         m_lightList->evaluateLights();
3305
3306         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3307         {
3308                 renderer.setLights( ( *i ).m_lights );
3309                 ( *i ).render( renderer, volume, localToWorld );
3310         }
3311
3312         renderComponentsSelected( renderer, volume, localToWorld );
3313 }
3314
3315 void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3316         //renderCommon(renderer, volume);
3317
3318         evaluateViewDependent( volume, localToWorld );
3319
3320         if ( m_render_wireframe.m_size != 0 ) {
3321                 renderer.addRenderable( m_render_wireframe, localToWorld );
3322         }
3323
3324         renderComponentsSelected( renderer, volume, localToWorld );
3325 }
3326
3327 void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
3328         m_brush.evaluateBRep();
3329
3330         renderClipPlane( renderer, volume );
3331
3332         renderSolid( renderer, volume, localToWorld() );
3333 }
3334
3335 void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
3336         m_brush.evaluateBRep();
3337
3338         renderClipPlane( renderer, volume );
3339
3340         renderWireframe( renderer, volume, localToWorld() );
3341 }
3342
3343 void viewChanged() const {
3344         m_viewChanged = true;
3345 }
3346
3347 void testSelect( Selector& selector, SelectionTest& test ){
3348         test.BeginMesh( localToWorld() );
3349
3350         SelectionIntersection best;
3351         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3352         {
3353                 ( *i ).testSelect( test, best );
3354         }
3355         if ( best.valid() ) {
3356                 selector.addIntersection( best );
3357         }
3358 }
3359
3360 bool isSelectedComponents() const {
3361         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3362         {
3363                 if ( ( *i ).selectedComponents() ) {
3364                         return true;
3365                 }
3366         }
3367         return false;
3368 }
3369 void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){
3370         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3371         {
3372                 ( *i ).setSelected( mode, select );
3373         }
3374 }
3375 void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
3376         test.BeginMesh( localToWorld() );
3377
3378         switch ( mode )
3379         {
3380         case SelectionSystem::eVertex:
3381         {
3382                 for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i )
3383                 {
3384                         ( *i ).testSelect( selector, test );
3385                 }
3386         }
3387         break;
3388         case SelectionSystem::eEdge:
3389         {
3390                 for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
3391                 {
3392                         ( *i ).testSelect( selector, test );
3393                 }
3394         }
3395         break;
3396         case SelectionSystem::eFace:
3397         {
3398                 if ( test.getVolume().fill() ) {
3399                         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3400                         {
3401                                 ( *i ).testSelect( selector, test );
3402                         }
3403                 }
3404                 else
3405                 {
3406                         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3407                         {
3408                                 ( *i ).testSelect_centroid( selector, test );
3409                         }
3410                 }
3411         }
3412         break;
3413         default:
3414                 break;
3415         }
3416 }
3417
3418 void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ){
3419         test.BeginMesh( localToWorld() );
3420
3421         PlanePointer brushPlanes[c_brush_maxFaces];
3422         PlanesIterator j = brushPlanes;
3423
3424         for ( Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i )
3425         {
3426                 *j++ = &( *i )->plane3();
3427         }
3428
3429         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3430         {
3431                 ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), brushPlanes, j, selectedPlaneCallback );
3432         }
3433 }
3434 void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ){
3435         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3436         {
3437                 ( *i ).selectReversedPlane( selector, selectedPlanes );
3438         }
3439 }
3440
3441
3442 void transformComponents( const Matrix4& matrix ){
3443         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3444         {
3445                 ( *i ).transformComponents( matrix );
3446         }
3447 }
3448 const AABB& getSelectedComponentsBounds() const {
3449         m_aabb_component = AABB();
3450
3451         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3452         {
3453                 ( *i ).iterate_selected( m_aabb_component );
3454         }
3455
3456         return m_aabb_component;
3457 }
3458
3459 void snapComponents( float snap ){
3460         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3461         {
3462                 ( *i ).snapComponents( snap );
3463         }
3464 }
3465 void evaluateTransform(){
3466         Matrix4 matrix( m_transform.calculateTransform() );
3467         //globalOutputStream() << "matrix: " << matrix << "\n";
3468
3469         if ( m_transform.getType() == TRANSFORM_PRIMITIVE ) {
3470                 m_brush.transform( matrix );
3471         }
3472         else
3473         {
3474                 transformComponents( matrix );
3475         }
3476 }
3477 void applyTransform(){
3478         m_brush.revertTransform();
3479         evaluateTransform();
3480         m_brush.freezeTransform();
3481 }
3482 typedef MemberCaller<BrushInstance, &BrushInstance::applyTransform> ApplyTransformCaller;
3483
3484 void setClipPlane( const Plane3& plane ){
3485         m_clipPlane.setPlane( m_brush, plane );
3486 }
3487
3488 bool testLight( const RendererLight& light ) const {
3489         return light.testAABB( worldAABB() );
3490 }
3491 void insertLight( const RendererLight& light ){
3492         const Matrix4& localToWorld = Instance::localToWorld();
3493         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3494         {
3495                 Face_addLight( *i, localToWorld, light );
3496         }
3497 }
3498 void clearLights(){
3499         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3500         {
3501                 ( *i ).m_lights.clear();
3502         }
3503 }
3504 };
3505
3506 inline BrushInstance* Instance_getBrush( scene::Instance& instance ){
3507         return InstanceTypeCast<BrushInstance>::cast( instance );
3508 }
3509
3510
3511 template<typename Functor>
3512 class BrushSelectedVisitor : public SelectionSystem::Visitor
3513 {
3514 const Functor& m_functor;
3515 public:
3516 BrushSelectedVisitor( const Functor& functor ) : m_functor( functor ){
3517 }
3518 void visit( scene::Instance& instance ) const {
3519         BrushInstance* brush = Instance_getBrush( instance );
3520         if ( brush != 0 ) {
3521                 m_functor( *brush );
3522         }
3523 }
3524 };
3525
3526 template<typename Functor>
3527 inline const Functor& Scene_forEachSelectedBrush( const Functor& functor ){
3528         GlobalSelectionSystem().foreachSelected( BrushSelectedVisitor<Functor>( functor ) );
3529         return functor;
3530 }
3531
3532 template<typename Functor>
3533 class BrushVisibleSelectedVisitor : public SelectionSystem::Visitor
3534 {
3535 const Functor& m_functor;
3536 public:
3537 BrushVisibleSelectedVisitor( const Functor& functor ) : m_functor( functor ){
3538 }
3539 void visit( scene::Instance& instance ) const {
3540         BrushInstance* brush = Instance_getBrush( instance );
3541         if ( brush != 0
3542                  && instance.path().top().get().visible() ) {
3543                 m_functor( *brush );
3544         }
3545 }
3546 };
3547
3548 template<typename Functor>
3549 inline const Functor& Scene_forEachVisibleSelectedBrush( const Functor& functor ){
3550         GlobalSelectionSystem().foreachSelected( BrushVisibleSelectedVisitor<Functor>( functor ) );
3551         return functor;
3552 }
3553
3554 class BrushForEachFace
3555 {
3556 const BrushInstanceVisitor& m_visitor;
3557 public:
3558 BrushForEachFace( const BrushInstanceVisitor& visitor ) : m_visitor( visitor ){
3559 }
3560 void operator()( BrushInstance& brush ) const {
3561         brush.forEachFaceInstance( m_visitor );
3562 }
3563 };
3564
3565 template<class Functor>
3566 class FaceInstanceVisitFace : public BrushInstanceVisitor
3567 {
3568 const Functor& functor;
3569 public:
3570 FaceInstanceVisitFace( const Functor& functor )
3571         : functor( functor ){
3572 }
3573 void visit( FaceInstance& face ) const {
3574         functor( face.getFace() );
3575 }
3576 };
3577
3578 template<typename Functor>
3579 inline const Functor& Brush_forEachFace( BrushInstance& brush, const Functor& functor ){
3580         brush.forEachFaceInstance( FaceInstanceVisitFace<Functor>( functor ) );
3581         return functor;
3582 }
3583
3584 template<class Functor>
3585 class FaceVisitAll : public BrushVisitor
3586 {
3587 const Functor& functor;
3588 public:
3589 FaceVisitAll( const Functor& functor )
3590         : functor( functor ){
3591 }
3592 void visit( Face& face ) const {
3593         functor( face );
3594 }
3595 };
3596
3597 template<typename Functor>
3598 inline const Functor& Brush_forEachFace( const Brush& brush, const Functor& functor ){
3599         brush.forEachFace( FaceVisitAll<Functor>( functor ) );
3600         return functor;
3601 }
3602
3603 template<typename Functor>
3604 inline const Functor& Brush_forEachFace( Brush& brush, const Functor& functor ){
3605         brush.forEachFace( FaceVisitAll<Functor>( functor ) );
3606         return functor;
3607 }
3608
3609 template<class Functor>
3610 class FaceInstanceVisitAll : public BrushInstanceVisitor
3611 {
3612 const Functor& functor;
3613 public:
3614 FaceInstanceVisitAll( const Functor& functor )
3615         : functor( functor ){
3616 }
3617 void visit( FaceInstance& face ) const {
3618         functor( face );
3619 }
3620 };
3621
3622 template<typename Functor>
3623 inline const Functor& Brush_ForEachFaceInstance( BrushInstance& brush, const Functor& functor ){
3624         brush.forEachFaceInstance( FaceInstanceVisitAll<Functor>( functor ) );
3625         return functor;
3626 }
3627
3628 template<typename Functor>
3629 inline const Functor& Scene_forEachBrush( scene::Graph& graph, const Functor& functor ){
3630         graph.traverse( InstanceWalker< InstanceApply<BrushInstance, Functor> >( functor ) );
3631         return functor;
3632 }
3633
3634 template<typename Type, typename Functor>
3635 class InstanceIfVisible : public Functor
3636 {
3637 public:
3638 InstanceIfVisible( const Functor& functor ) : Functor( functor ){
3639 }
3640 void operator()( scene::Instance& instance ){
3641         if ( instance.path().top().get().visible() ) {
3642                 Functor::operator()( instance );
3643         }
3644 }
3645 };
3646
3647 template<typename Functor>
3648 class BrushVisibleWalker : public scene::Graph::Walker
3649 {
3650 const Functor& m_functor;
3651 public:
3652 BrushVisibleWalker( const Functor& functor ) : m_functor( functor ){
3653 }
3654 bool pre( const scene::Path& path, scene::Instance& instance ) const {
3655         if ( path.top().get().visible() ) {
3656                 BrushInstance* brush = Instance_getBrush( instance );
3657                 if ( brush != 0 ) {
3658                         m_functor( *brush );
3659                 }
3660         }
3661         return true;
3662 }
3663 };
3664
3665 template<typename Functor>
3666 inline const Functor& Scene_forEachVisibleBrush( scene::Graph& graph, const Functor& functor ){
3667         graph.traverse( BrushVisibleWalker<Functor>( functor ) );
3668         return functor;
3669 }
3670
3671 template<typename Functor>
3672 inline const Functor& Scene_ForEachBrush_ForEachFace( scene::Graph& graph, const Functor& functor ){
3673         Scene_forEachBrush( graph, BrushForEachFace( FaceInstanceVisitFace<Functor>( functor ) ) );
3674         return functor;
3675 }
3676
3677 // d1223m
3678 template<typename Functor>
3679 inline const Functor& Scene_ForEachBrush_ForEachFaceInstance( scene::Graph& graph, const Functor& functor ){
3680         Scene_forEachBrush( graph, BrushForEachFace( FaceInstanceVisitAll<Functor>( functor ) ) );
3681         return functor;
3682 }
3683
3684 template<typename Functor>
3685 inline const Functor& Scene_ForEachSelectedBrush_ForEachFace( scene::Graph& graph, const Functor& functor ){
3686         Scene_forEachSelectedBrush( BrushForEachFace( FaceInstanceVisitFace<Functor>( functor ) ) );
3687         return functor;
3688 }
3689
3690 template<typename Functor>
3691 inline const Functor& Scene_ForEachSelectedBrush_ForEachFaceInstance( scene::Graph& graph, const Functor& functor ){
3692         Scene_forEachSelectedBrush( BrushForEachFace( FaceInstanceVisitAll<Functor>( functor ) ) );
3693         return functor;
3694 }
3695
3696 template<typename Functor>
3697 class FaceVisitorWrapper
3698 {
3699 const Functor& functor;
3700 public:
3701 FaceVisitorWrapper( const Functor& functor ) : functor( functor ){
3702 }
3703
3704 void operator()( FaceInstance& faceInstance ) const {
3705         functor( faceInstance.getFace() );
3706 }
3707 };
3708
3709 template<typename Functor>
3710 inline const Functor& Scene_ForEachSelectedBrushFace( scene::Graph& graph, const Functor& functor ){
3711         g_SelectedFaceInstances.foreach( FaceVisitorWrapper<Functor>( functor ) );
3712         return functor;
3713 }
3714
3715
3716 #endif