bobToolz: load all group entities, was hardcoded list of them
fix crash in DEntity::SelectBrushes after DEntity::LoadSelectedBrushes (which may load brushes from other entities) generalize loading options; fix ignored loadPatches option; use only visible brushes in Find Duplicates
This commit is contained in:
parent
bf4db60613
commit
dea7800d3c
|
|
@ -51,26 +51,6 @@
|
||||||
#include "scenelib.h"
|
#include "scenelib.h"
|
||||||
|
|
||||||
|
|
||||||
const char* brushEntityList[] = {
|
|
||||||
"worldspawn",
|
|
||||||
"trigger_always",
|
|
||||||
"trigger_hurt",
|
|
||||||
"trigger_multiple",
|
|
||||||
"trigger_push",
|
|
||||||
"trigger_teleport",
|
|
||||||
"func_bobbing",
|
|
||||||
"func_button",
|
|
||||||
"func_door",
|
|
||||||
"func_group",
|
|
||||||
"func_pendulum",
|
|
||||||
"func_plat",
|
|
||||||
"func_rotating",
|
|
||||||
"func_static",
|
|
||||||
"func_timer",
|
|
||||||
"func_train",
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Construction/Destruction
|
// Construction/Destruction
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -298,15 +278,10 @@ void DEntity::SelectBrushes( bool *selectList ){
|
||||||
|
|
||||||
GlobalSelectionSystem().setSelectedAll( false );
|
GlobalSelectionSystem().setSelectedAll( false );
|
||||||
|
|
||||||
scene::Path path( NodeReference( GlobalSceneGraph().root() ) );
|
|
||||||
path.push( NodeReference( *QER_Entity ) );
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < brushList.size(); ++i )
|
for ( size_t i = 0; i < brushList.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( selectList[i] ) {
|
if ( selectList[i] ) {
|
||||||
path.push( NodeReference( *brushList[i]->QER_brush ) );
|
brushList[i]->selectInRadiant();
|
||||||
Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true );
|
|
||||||
path.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -318,7 +293,7 @@ void select_primitive( scene::Node *primitive, scene::Node *entity ){
|
||||||
Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true );
|
Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
|
bool DEntity::LoadFromEntity( scene::Node& ent, const LoadOptions options ) {
|
||||||
ClearPatches();
|
ClearPatches();
|
||||||
ClearBrushes();
|
ClearBrushes();
|
||||||
ClearEPairs();
|
ClearEPairs();
|
||||||
|
|
@ -327,17 +302,7 @@ bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
|
||||||
|
|
||||||
LoadEPairList( Node_getEntity( ent ) );
|
LoadEPairList( Node_getEntity( ent ) );
|
||||||
|
|
||||||
bool keep = false;
|
if ( !node_is_group( ent ) ) {
|
||||||
int i;
|
|
||||||
for ( i = 0; brushEntityList[i]; i++ )
|
|
||||||
{
|
|
||||||
if ( string_equal_nocase( brushEntityList[i], m_Classname ) ) {
|
|
||||||
keep = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !keep ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,26 +310,37 @@ bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
|
||||||
class load_brushes_t : public scene::Traversable::Walker
|
class load_brushes_t : public scene::Traversable::Walker
|
||||||
{
|
{
|
||||||
DEntity* m_entity;
|
DEntity* m_entity;
|
||||||
|
const LoadOptions m_options;
|
||||||
public:
|
public:
|
||||||
load_brushes_t( DEntity* entity )
|
load_brushes_t( DEntity* entity, const LoadOptions options )
|
||||||
: m_entity( entity ){
|
: m_entity( entity ), m_options( options ){
|
||||||
}
|
}
|
||||||
bool pre( scene::Node& node ) const {
|
bool pre( scene::Node& node ) const {
|
||||||
scene::Path path( NodeReference( GlobalSceneGraph().root() ) );
|
if( !( m_options.loadVisibleOnly && !node.visible() ) ){
|
||||||
path.push( NodeReference( *m_entity->QER_Entity ) );
|
scene::Path path( NodeReference( GlobalSceneGraph().root() ) );
|
||||||
path.push( NodeReference( node ) );
|
path.push( NodeReference( *m_entity->QER_Entity ) );
|
||||||
scene::Instance* instance = GlobalSceneGraph().find( path );
|
path.push( NodeReference( node ) );
|
||||||
ASSERT_MESSAGE( instance != 0, "" );
|
scene::Instance* instance = GlobalSceneGraph().find( path );
|
||||||
|
ASSERT_MESSAGE( instance != 0, "" );
|
||||||
|
|
||||||
if ( Node_isPatch( node ) ) {
|
if( !( m_options.loadSelectedOnly && Instance_isSelected( *instance ) ) ){
|
||||||
m_entity->NewPatch()->LoadFromPatch( *instance );
|
if ( Node_isPatch( node ) ) {
|
||||||
}
|
if( m_options.loadPatches )
|
||||||
else if ( Node_isBrush( node ) ) {
|
m_entity->NewPatch()->LoadFromPatch( *instance );
|
||||||
m_entity->NewBrush()->LoadFromBrush( *instance, true );
|
}
|
||||||
|
else if ( Node_isBrush( node ) ) {
|
||||||
|
m_entity->NewBrush()->LoadFromBrush( *instance, true );
|
||||||
|
if( !m_options.loadDetail && m_entity->brushList.back()->IsDetail() ){
|
||||||
|
delete m_entity->brushList.back();
|
||||||
|
m_entity->brushList.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} load_brushes( this );
|
} load_brushes( this, options );
|
||||||
|
|
||||||
Node_getTraversable( ent )->traverse( load_brushes );
|
Node_getTraversable( ent )->traverse( load_brushes );
|
||||||
}
|
}
|
||||||
|
|
@ -372,10 +348,9 @@ bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DEntity::RemoveNonCheckBrushes( std::list<Str>* exclusionList, bool useDetail ){
|
void DEntity::RemoveNonCheckBrushes( std::list<Str>* exclusionList ){
|
||||||
brushList.erase( std::remove_if( brushList.begin(), brushList.end(), [&]( DBrush *brush ){
|
brushList.erase( std::remove_if( brushList.begin(), brushList.end(), [&]( DBrush *brush ){
|
||||||
if ( ( !useDetail && brush->IsDetail() )
|
if ( std::any_of( exclusionList->cbegin(), exclusionList->cend(), [brush]( const Str& tex ){ return brush->HasTexture( tex.GetBuffer() ); } ) ) {
|
||||||
|| std::any_of( exclusionList->cbegin(), exclusionList->cend(), [brush]( const Str& tex ){ return brush->HasTexture( tex.GetBuffer() ); } ) ) {
|
|
||||||
delete brush;
|
delete brush;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
#include "mathlib.h"
|
#include "mathlib.h"
|
||||||
|
#include "DMap.h"
|
||||||
|
|
||||||
class DEPair;
|
class DEPair;
|
||||||
class DBrush;
|
class DBrush;
|
||||||
|
|
@ -66,7 +67,7 @@ public:
|
||||||
|
|
||||||
void BuildInRadiant( bool allowDestruction );
|
void BuildInRadiant( bool allowDestruction );
|
||||||
void ResetChecks( std::list<Str>* exclusionList );
|
void ResetChecks( std::list<Str>* exclusionList );
|
||||||
void RemoveNonCheckBrushes( std::list<Str>* exclusionList, bool useDetail );
|
void RemoveNonCheckBrushes( std::list<Str>* exclusionList );
|
||||||
|
|
||||||
int GetBrushCount( void );
|
int GetBrushCount( void );
|
||||||
DBrush* FindBrushByPointer( scene::Node& brush );
|
DBrush* FindBrushByPointer( scene::Node& brush );
|
||||||
|
|
@ -103,7 +104,9 @@ public:
|
||||||
|
|
||||||
int FixBrushes();
|
int FixBrushes();
|
||||||
|
|
||||||
bool LoadFromEntity( scene::Node& ent, bool bLoadPatches = false );
|
bool LoadFromEntity( scene::Node& ent, const LoadOptions options = {} );
|
||||||
|
/* these two load any selected primitives to single entity, hence e.g. QER_Entity wont be correct
|
||||||
|
basically use with high care */
|
||||||
void LoadSelectedBrushes();
|
void LoadSelectedBrushes();
|
||||||
void LoadSelectedPatches();
|
void LoadSelectedPatches();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ void DMap::BuildInRadiant( bool bAllowDestruction ){
|
||||||
entity->BuildInRadiant( bAllowDestruction );
|
entity->BuildInRadiant( bAllowDestruction );
|
||||||
}
|
}
|
||||||
|
|
||||||
void DMap::LoadAll( bool bLoadPatches ){
|
void DMap::LoadAll( const LoadOptions options ){
|
||||||
ClearEntities();
|
ClearEntities();
|
||||||
|
|
||||||
GlobalSelectionSystem().setSelectedAll( false );
|
GlobalSelectionSystem().setSelectedAll( false );
|
||||||
|
|
@ -117,19 +117,18 @@ void DMap::LoadAll( bool bLoadPatches ){
|
||||||
class load_entities_t : public scene::Traversable::Walker
|
class load_entities_t : public scene::Traversable::Walker
|
||||||
{
|
{
|
||||||
DMap* m_map;
|
DMap* m_map;
|
||||||
bool m_bLoadPatches;
|
const LoadOptions m_options;
|
||||||
public:
|
public:
|
||||||
load_entities_t( DMap* map, bool bLoadPatches )
|
load_entities_t( DMap* map, const LoadOptions options )
|
||||||
: m_map( map ), m_bLoadPatches( bLoadPatches ){
|
: m_map( map ), m_options( options ){
|
||||||
}
|
}
|
||||||
bool pre( scene::Node& node ) const {
|
bool pre( scene::Node& node ) const {
|
||||||
if ( Node_isEntity( node ) ) {
|
if ( Node_isEntity( node ) && !( m_options.loadVisibleOnly && !node.visible() ) ) {
|
||||||
DEntity* loadEntity = m_map->AddEntity( "", 0 );
|
m_map->AddEntity( "", 0 )->LoadFromEntity( node, m_options );
|
||||||
loadEntity->LoadFromEntity( node, m_bLoadPatches );
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} load_entities( this, bLoadPatches );
|
} load_entities( this, options );
|
||||||
|
|
||||||
Node_getTraversable( GlobalSceneGraph().root() )->traverse( load_entities );
|
Node_getTraversable( GlobalSceneGraph().root() )->traverse( load_entities );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,21 @@
|
||||||
|
|
||||||
class DEntity;
|
class DEntity;
|
||||||
|
|
||||||
|
struct LoadOptions
|
||||||
|
{
|
||||||
|
bool loadPatches = false;
|
||||||
|
bool loadSelectedOnly = false;
|
||||||
|
bool loadVisibleOnly = false;
|
||||||
|
bool loadDetail = true;
|
||||||
|
};
|
||||||
|
|
||||||
class DMap
|
class DMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void RebuildEntity( DEntity* ent );
|
static void RebuildEntity( DEntity* ent );
|
||||||
|
|
||||||
void ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation );
|
void ResetTextures( const char* textureName, float fScale[2], float fShift[2], int rotation, const char* newTextureName, bool bResetTextureName, bool bResetScale[2], bool bResetShift[2], bool bResetRotation );
|
||||||
void LoadAll( bool bLoadPatches = false );
|
void LoadAll( const LoadOptions options = {} );
|
||||||
void BuildInRadiant( bool bAllowDestruction );
|
void BuildInRadiant( bool bAllowDestruction );
|
||||||
int m_nNextEntity;
|
int m_nNextEntity;
|
||||||
DEntity* GetWorldSpawn();
|
DEntity* GetWorldSpawn();
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ SignalHandlerResult DTreePlanter::mouseDown( const WindowVector& position, Butto
|
||||||
|
|
||||||
if ( pLastEntity ) {
|
if ( pLastEntity ) {
|
||||||
DEntity e2;
|
DEntity e2;
|
||||||
e2.LoadFromEntity( pLastEntity->top(), true );
|
e2.LoadFromEntity( pLastEntity->top(), {.loadPatches = true} );
|
||||||
e2.AddEPair( "target", buffer );
|
e2.AddEPair( "target", buffer );
|
||||||
e2.RemoveFromRadiant();
|
e2.RemoveFromRadiant();
|
||||||
e2.BuildInRadiant( false );
|
e2.BuildInRadiant( false );
|
||||||
|
|
|
||||||
|
|
@ -107,18 +107,16 @@ void DoIntersect(){
|
||||||
{
|
{
|
||||||
case BRUSH_OPT_SELECTED:
|
case BRUSH_OPT_SELECTED:
|
||||||
{
|
{
|
||||||
|
|
||||||
world.LoadFromEntity( GlobalRadiant().getMapWorldEntity(), false );
|
|
||||||
world.LoadSelectedBrushes();
|
world.LoadSelectedBrushes();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BRUSH_OPT_WHOLE_MAP:
|
case BRUSH_OPT_WHOLE_MAP:
|
||||||
{
|
{
|
||||||
world.LoadFromEntity( GlobalRadiant().getMapWorldEntity(), false );
|
world.LoadFromEntity( GlobalRadiant().getMapWorldEntity(), {.loadDetail = rs.bUseDetail} );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
world.RemoveNonCheckBrushes( &exclusionList, rs.bUseDetail );
|
world.RemoveNonCheckBrushes( &exclusionList );
|
||||||
|
|
||||||
bool* pbSelectList;
|
bool* pbSelectList;
|
||||||
if ( rs.bDuplicateOnly ) {
|
if ( rs.bDuplicateOnly ) {
|
||||||
|
|
@ -137,7 +135,7 @@ void DoIntersect(){
|
||||||
void DoFindDuplicates()
|
void DoFindDuplicates()
|
||||||
{
|
{
|
||||||
DMap map;
|
DMap map;
|
||||||
map.LoadAll( false );
|
map.LoadAll( {.loadVisibleOnly = true} );
|
||||||
|
|
||||||
std::vector<const DBrush *> brushes;
|
std::vector<const DBrush *> brushes;
|
||||||
|
|
||||||
|
|
@ -159,6 +157,7 @@ void DoFindDuplicates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
globalOutputStream() << "bobToolz Find Duplicates: " << (int)std::count( brushes.cbegin(), brushes.cend(), nullptr ) << " duplicate brushes found.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoPolygonsTB(){
|
void DoPolygonsTB(){
|
||||||
|
|
@ -252,7 +251,7 @@ void DoResetTextures(){
|
||||||
else if ( ret == eIDYES )
|
else if ( ret == eIDYES )
|
||||||
{
|
{
|
||||||
DMap world;
|
DMap world;
|
||||||
world.LoadAll( true );
|
world.LoadAll( {.loadPatches = true} );
|
||||||
world.ResetTextures( texName, rs.fScale, rs.fShift, rs.rotation, rs.newTextureName,
|
world.ResetTextures( texName, rs.fScale, rs.fShift, rs.rotation, rs.newTextureName,
|
||||||
rs.bResetTextureName, rs.bResetScale, rs.bResetShift, rs.bResetRotation );
|
rs.bResetTextureName, rs.bResetScale, rs.bResetShift, rs.bResetRotation );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,8 @@ public:
|
||||||
const char* classname = Node_getEntity( instance.path().top() )->getClassName();
|
const char* classname = Node_getEntity( instance.path().top() )->getClassName();
|
||||||
|
|
||||||
if ( !strcmp( classname, "worldspawn" ) ) {
|
if ( !strcmp( classname, "worldspawn" ) ) {
|
||||||
world.LoadFromEntity( instance.path().top(), false );
|
world.LoadFromEntity( instance.path().top() );
|
||||||
world.RemoveNonCheckBrushes( exclusionList, true );
|
world.RemoveNonCheckBrushes( exclusionList );
|
||||||
world.SaveToFile( pFile );
|
world.SaveToFile( pFile );
|
||||||
}
|
}
|
||||||
else if ( strstr( classname, "info_" ) ) {
|
else if ( strstr( classname, "info_" ) ) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user