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
This commit is contained in:
Garux 2017-08-01 14:27:03 +03:00
parent 7ca59bef0a
commit dce6730b39
14 changed files with 164 additions and 27 deletions

View File

@ -47,6 +47,7 @@ enum
EXCLUDE_BOTCLIP = 0x00040000,
EXCLUDE_VISPORTALS = 0x00080000,
EXCLUDE_DECALS = 0x00100000,
EXCLUDE_FUNC_GROUPS = 0x00200000,
};
class Filter

View File

@ -762,7 +762,14 @@ public:
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;
}
};

View File

@ -307,7 +307,7 @@ bool filter( const Entity& entity ) const {
}
};
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" );
@ -327,9 +327,20 @@ bool filter( const Entity& entity ) const {
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 );

View File

@ -696,6 +696,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
Instance_getSelectable( instance )->setSelected( true );
}
}
else{
return false;
}
return true;
}
};

View File

@ -1249,6 +1249,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
m_bestDown = floorHeight;
}
}
else if( !path.top().get().visible() ){
return false;
}
return true;
}
};

View File

@ -379,7 +379,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
return true;
}
};
/*
class BrushDeleteSelected : public scene::Graph::Walker
{
public:
@ -397,7 +397,47 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
}
}
};
*/
#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 );
}
}
}
};
/*
=============
@ -568,12 +608,16 @@ class SubtractBrushesFromUnselected : public scene::Graph::Walker
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() ) {
@ -626,9 +670,20 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
}
}
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 );
}
}
}
};
@ -868,7 +923,7 @@ void CSG_Merge( void ){
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 );

View File

@ -11,7 +11,7 @@
#include "gtkutil/accelerator.h"
#include "generic/callback.h"
#include "entity.h"
int ToggleActions = 0;
@ -147,6 +147,16 @@ gboolean Trigger_button_press( GtkWidget *widget, GdkEventButton *event, gpointe
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();
@ -181,6 +191,8 @@ GtkToolbar* create_filter_toolbar(){
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 ) );
@ -216,6 +228,7 @@ GtkToolbar* create_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;
}

View File

@ -205,6 +205,7 @@ void Filters_constructMenu( GtkMenu* menu_in_menu ){
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" );
@ -252,6 +253,7 @@ void ConstructFilters(){
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();
}

View File

@ -2778,6 +2778,7 @@ void MainFrame::Create(){
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 );

View File

@ -1810,6 +1810,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
m_functor( *patch );
}
}
else{
return false;
}
return true;
}
};
@ -1834,6 +1837,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
m_functor( *patch );
}
}
else{
return false;
}
return true;
}
};
@ -1857,6 +1863,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
m_functor( *patch );
}
}
else{
return false;
}
return true;
}
};

View File

@ -453,12 +453,28 @@ void operator()( Patch& patch ) const {
}
};
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 ) );
}
}

View File

@ -110,26 +110,32 @@ SelectByBounds( AABB* aabbs, Unsigned count )
}
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;
}
}
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 );
// 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 ) &&
( !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;
@ -275,6 +281,10 @@ InvertSelectionWalker( SelectionSystem::EMode mode )
: 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 )
@ -608,6 +618,9 @@ EntityFindByPropertyValueWalker( const char *prop, const PropertyValues& propert
: 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 ) ) ) {

View File

@ -1392,6 +1392,9 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
}
}
}
else{
return false;
}
return true;
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B