misc...
* fix: select inside and touching: ignored ANY filters and hiding, and region
* fix: M3 tex paint/grab ignored _hidden_ models
* fix: M3 tex paint/grab ignored group ent (world, triggers, et cetera), model filters
* fix: shift+a by tex: ignored group ent (world, triggers, et cetera) filters
* fix: tex find/replace: ignored any filters, regioning & hiding
* fix: shift+a by classname: ignored filters, hiding, region
* fix: floor walker ignored group ent filters
* fix: csg subtract ignored group ent filters
* fix: invert selection: ignored group ent filters
* fix: tex find/replace: 'select by shader' mode for patches (was replacing with notex instead)
* fix: select inside and touching: were selecting group ents, as single unit (=sensitive to parent node and its bbox)
* fix: csg merge two group ents = empty group ent
* fix: csg subtract group ent completely = empty group ent
* fix: hollow group ent: could produce empty group ent
* func_groups are filtered by world filter only, not entities one
* new func_group filter, filterBar button; Rightclick = create func_group
EXCLUDE_BOTCLIP = 0x00040000,
EXCLUDE_VISPORTALS = 0x00080000,
EXCLUDE_DECALS = 0x00100000,
+ EXCLUDE_FUNC_GROUPS = 0x00200000,
};
class Filter
InstanceWalker( const Functor& functor ) : m_functor( functor ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
- m_functor( instance );
+ //m_functor( instance );
+ //return true;
+ if ( path.top().get().visible() ) {
+ m_functor( instance );
+ }
+ else{
+ return false;
+ }
return true;
}
};
}
};
-filter_entity_classname g_filter_entity_world( "worldspawn" );
+//filter_entity_classname g_filter_entity_world( "worldspawn" );
filter_entity_classname g_filter_entity_func_group( "func_group" );
filter_entity_classname g_filter_entity_light( "light" );
filter_entity_classname g_filter_entity_misc_model( "misc_model" );
filter_entity_doom3model g_filter_entity_doom3model;
+class filter_entity_world : public EntityFilter
+{
+public:
+bool filter( const Entity& entity ) const {
+ return string_equal( entity.getKeyValue( "classname" ), "worldspawn" )
+ || string_equal( entity.getKeyValue( "classname" ), "func_group" );
+}
+};
+
+filter_entity_world g_filter_entity_world;
+
void Entity_InitFilters(){
add_entity_filter( g_filter_entity_world, EXCLUDE_WORLD );
- add_entity_filter( g_filter_entity_func_group, EXCLUDE_WORLD );
+ add_entity_filter( g_filter_entity_func_group, EXCLUDE_FUNC_GROUPS );
add_entity_filter( g_filter_entity_world, EXCLUDE_ENT, true );
add_entity_filter( g_filter_entity_trigger, EXCLUDE_TRIGGERS );
add_entity_filter( g_filter_entity_misc_model, EXCLUDE_MODELS );
Instance_getSelectable( instance )->setSelected( true );
}
}
+ else{
+ return false;
+ }
return true;
}
};
m_bestDown = floorHeight;
}
}
+ else if( !path.top().get().visible() ){
+ return false;
+ }
return true;
}
};
return true;
}
};
-
+/*
class BrushDeleteSelected : public scene::Graph::Walker
{
public:
}
}
};
+*/
+#include "ientity.h"
+class BrushDeleteSelected : public scene::Graph::Walker
+{
+scene::Node* m_keepNode;
+mutable bool m_eraseParent;
+public:
+BrushDeleteSelected( scene::Node* keepNode ): m_keepNode( keepNode ), m_eraseParent( false ){
+}
+BrushDeleteSelected(): m_keepNode( NULL ), m_eraseParent( false ){
+}
+bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ return true;
+}
+void post( const scene::Path& path, scene::Instance& instance ) const {
+ //globalOutputStream() << path.size() << "\n";
+ if ( path.top().get().visible() ) {
+ Brush* brush = Node_getBrush( path.top() );
+ if ( brush != 0
+ && Instance_getSelectable( instance )->isSelected()
+ && path.size() > 1 ) {
+ Path_deleteTop( path );
+ if( Node_getTraversable( path.parent() )->empty() ){
+ m_eraseParent = true;
+ //globalOutputStream() << "Empty node?!.\n";
+ }
+ }
+ }
+ if( m_eraseParent && !Node_isPrimitive( path.top() ) && path.size() > 1 ){
+ //globalOutputStream() << "about to Delete empty node!.\n";
+ m_eraseParent = false;
+ Entity* entity = Node_getEntity( path.top() );
+ if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map )
+ && Node_getTraversable( path.top() )->empty() && path.top().get_pointer() != m_keepNode ) {
+ //globalOutputStream() << "now Deleting empty node!.\n";
+ Path_deleteTop( path );
+ }
+ }
+}
+};
/*
=============
const brush_vector_t& m_brushlist;
std::size_t& m_before;
std::size_t& m_after;
+mutable bool m_eraseParent;
public:
SubtractBrushesFromUnselected( const brush_vector_t& brushlist, std::size_t& before, std::size_t& after )
- : m_brushlist( brushlist ), m_before( before ), m_after( after ){
+ : m_brushlist( brushlist ), m_before( before ), m_after( after ), m_eraseParent( false ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
- return true;
+ if ( path.top().get().visible() ) {
+ return true;
+ }
+ return false;
}
void post( const scene::Path& path, scene::Instance& instance ) const {
if ( path.top().get().visible() ) {
}
}
Path_deleteTop( path );
+ if( Node_getTraversable( path.parent() )->empty() ){
+ m_eraseParent = true;
+ }
}
}
}
+ if( m_eraseParent && !Node_isPrimitive( path.top() ) && path.size() > 1 ){
+ m_eraseParent = false;
+ Entity* entity = Node_getEntity( path.top() );
+ if ( entity != 0 && path.top().get_pointer() != Map_FindWorldspawn( g_map )
+ && Node_getTraversable( path.top() )->empty() ) {
+ Path_deleteTop( path );
+ }
+ }
}
};
ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after merge" );
// free the original brushes
- GlobalSceneGraph().traverse( BrushDeleteSelected() );
+ GlobalSceneGraph().traverse( BrushDeleteSelected( merged_path.parent().get_pointer() ) );
merged_path.pop();
Node_getTraversable( merged_path.top() )->insert( node );
#include "gtkutil/accelerator.h"
#include "generic/callback.h"
-
+#include "entity.h"
int ToggleActions = 0;
return FALSE;
}
+gboolean Func_Groups_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){
+ if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) {
+ UndoableCommand undo( "create func_group" );
+ Entity_createFromSelection( "func_group", g_vector3_identity );
+ ToggleActions = 0;
+ return TRUE;
+ }
+ return FALSE;
+}
+
gboolean Detail_button_press( GtkWidget *widget, GdkEventButton *event, gpointer data ){
if ( event->button == 3 && event->type == GDK_BUTTON_PRESS ) {
GlobalCommands_find( "MakeDetail" ).m_callback();
button = toolbar_append_toggle_button( filter_toolbar, "Details (CTRL + D)\nRightClick: MakeDetail", "f-details.png", "FilterDetails" );
g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( Detail_button_press ), 0 );
+ button = toolbar_append_toggle_button( filter_toolbar, "Func_Groups\nRightClick: create func_group", "f-funcgroups.png", "FilterFuncGroups" );
+ g_signal_connect( G_OBJECT( button ), "button_press_event", G_CALLBACK( Func_Groups_button_press ), 0 );
toolbar_append_toggle_button( filter_toolbar, "Patches (CTRL + P)", "patch_wireframe.png", "FilterPatches" );
gtk_toolbar_append_space( GTK_TOOLBAR( filter_toolbar ) );
//toolbar_append_toggle_button( filter_toolbar, "Decals (SHIFT + D)", "f-decals.png", "FilterDecals" );
gtk_toolbar_append_space( GTK_TOOLBAR( filter_toolbar ) );
toolbar_append_button( filter_toolbar, "InvertFilters", "f-invert.png", "InvertFilters" );
+
toolbar_append_button( filter_toolbar, "ResetFilters", "f-reset.png", "ResetFilters" );
return filter_toolbar;
}
create_check_menu_item_with_mnemonic( menu_in_menu, "Botclips", "FilterBotClips" );
create_check_menu_item_with_mnemonic( menu_in_menu, "Decals", "FilterDecals" );
}
+ create_check_menu_item_with_mnemonic( menu_in_menu, "FuncGroups", "FilterFuncGroups" );
// filter manipulation
menu_separator( menu_in_menu );
create_menu_item_with_mnemonic( menu_in_menu, "Invert filters", "InvertFilters" );
add_filter_command( EXCLUDE_BOTCLIP, "FilterBotClips", Accelerator( 'M', (GdkModifierType)GDK_MOD1_MASK ) );
add_filter_command( EXCLUDE_DECALS, "FilterDecals", Accelerator( 'D', (GdkModifierType)GDK_SHIFT_MASK ) );
}
+ add_filter_command( EXCLUDE_FUNC_GROUPS, "FilterFuncGroups", accelerator_null() );
PerformFiltering();
}
GtkWidget* vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_add( GTK_CONTAINER( window ), vbox );
gtk_widget_show( vbox );
+ gtk_container_set_focus_chain( GTK_CONTAINER( vbox ), NULL );
global_accel_connect_window( window );
m_functor( *patch );
}
}
+ else{
+ return false;
+ }
return true;
}
};
m_functor( *patch );
}
}
+ else{
+ return false;
+ }
return true;
}
};
m_functor( *patch );
}
}
+ else{
+ return false;
+ }
return true;
}
};
}
};
+namespace{
+bool DoingSearch( const char *repl ){
+ return ( repl == NULL || ( strcmp( "textures/", repl ) == 0 ) );
+}
+}
void Scene_PatchFindReplaceShader( scene::Graph& graph, const char* find, const char* replace ){
- Scene_forEachVisiblePatch( PatchFindReplaceShader( find, replace ) );
+ if( DoingSearch( replace ) ){
+ Scene_forEachVisiblePatchInstance( PatchSelectByShader( find ) );
+ }
+ else{
+ Scene_forEachVisiblePatch( PatchFindReplaceShader( find, replace ) );
+ }
}
void Scene_PatchFindReplaceShader_Selected( scene::Graph& graph, const char* find, const char* replace ){
- Scene_forEachVisibleSelectedPatch( PatchFindReplaceShader( find, replace ) );
+ if( DoingSearch( replace ) ){
+ //do nothing, because alternative is replacing to notex
+ //perhaps deselect ones with not matching shaders here?
+ }
+ else{
+ Scene_forEachVisibleSelectedPatch( PatchFindReplaceShader( find, replace ) );
+ }
}
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
- Selectable* selectable = Instance_getSelectable( instance );
+ if( path.top().get().visible() ){
+ Selectable* selectable = Instance_getSelectable( instance );
- // ignore worldspawn
- Entity* entity = Node_getEntity( path.top() );
- if ( entity ) {
- if ( string_equal( entity->getKeyValue( "classname" ), "worldspawn" ) ) {
- return true;
+ // ignore worldspawn
+ Entity* entity = Node_getEntity( path.top() );
+ if ( entity ) {
+ if ( string_equal( entity->getKeyValue( "classname" ), "worldspawn" ) ) {
+ return true;
+ }
}
- }
- if ( ( path.size() > 1 ) &&
- ( !path.top().get().isRoot() ) &&
- ( selectable != 0 )
- ) {
- for ( Unsigned i = 0; i < m_count; ++i )
- {
- if ( policy.Evaluate( m_aabbs[i], instance ) ) {
- selectable->setSelected( true );
+ if ( ( path.size() > 1 ) &&
+ ( !path.top().get().isRoot() ) &&
+ ( selectable != 0 ) &&
+ ( !node_is_group( path.top() ) )
+ ) {
+ for ( Unsigned i = 0; i < m_count; ++i )
+ {
+ if ( policy.Evaluate( m_aabbs[i], instance ) ) {
+ selectable->setSelected( true );
+ }
}
}
}
+ else{
+ return false;
+ }
return true;
}
: m_mode( mode ), m_selectable( 0 ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if( !path.top().get().visible() ){
+ m_selectable = 0;
+ return false;
+ }
Selectable* selectable = Instance_getSelectable( instance );
if ( selectable ) {
switch ( m_mode )
: m_propertyvalues( propertyvalues ), m_prop( prop ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
+ if( !path.top().get().visible() ){
+ return false;
+ }
Entity* entity = Node_getEntity( path.top() );
if ( entity != 0
&& propertyvalues_contain( m_propertyvalues, entity->getKeyValue( m_prop ) ) ) {
}
}
}
+ else{
+ return false;
+ }
return true;
}
};