* bobToolz: new Find Duplicates function: finds & selects duplicate brushes in entire map

This commit is contained in:
Garux 2023-08-30 21:16:21 +06:00
parent d98b1c5d0e
commit 7bd11485d0
9 changed files with 79 additions and 32 deletions

View File

@ -310,7 +310,7 @@ bool DBrush::BBoxCollision( DBrush* chkBrush ){
return true;
}
DPlane* DBrush::HasPlane( DPlane* chkPlane ){
DPlane* DBrush::HasPlane( DPlane* chkPlane ) const {
for ( DPlane *plane : faceList )
{
if ( *plane == *chkPlane ) {
@ -414,6 +414,12 @@ scene::Node* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, scen
return node.get_pointer();
}
void DBrush::selectInRadiant() const {
ASSERT_MESSAGE( QER_entity != nullptr, "QER_entity == nullptr" );
ASSERT_MESSAGE( QER_brush != nullptr, "QER_brush == nullptr" );
select_primitive( QER_brush, QER_entity );
}
void DBrush::CutByPlane( DPlane *cutPlane, DBrush **newBrush1, DBrush **newBrush2 ){
if ( !IsCutByPlane( cutPlane ) ) {
*newBrush1 = NULL;
@ -799,7 +805,7 @@ bool DBrush::ResetTextures( const char* textureName, float fScale[2], float
}
}
bool DBrush::operator ==( DBrush* other ){
bool DBrush::operator ==( const DBrush* other ) const {
for ( DPlane *plane : faceList )
{
if ( !other->HasPlane( plane ) ) {

View File

@ -53,7 +53,7 @@ public:
void RotateAboutCentre( vec3_t vRotation );
DPlane* HasPlaneInverted( DPlane* chkPlane );
DPlane* HasPlane( DPlane* chkPlane );
DPlane* HasPlane( DPlane* chkPlane ) const;
DPlane* AddFace( const vec3_t va, const vec3_t vb, const vec3_t vc, const _QERFaceData* texData );
bool 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 );
@ -71,6 +71,7 @@ public:
void BuildBounds();
void BuildFromWinding( DWinding* w );
scene::Node* BuildInRadiant( bool allowDestruction, int* changeCnt, scene::Node* entity = NULL );
void selectInRadiant() const;
void ResetChecks( std::list<Str>* exclusionList );
@ -93,7 +94,7 @@ public:
DBrush( int ID = -1 );
virtual ~DBrush();
bool operator==( DBrush* other );
bool operator==( const DBrush* other ) const;
// members
scene::Node* QER_entity;

View File

@ -349,6 +349,13 @@ void DEntity::SelectBrushes( bool *selectList ){
}
}
void select_primitive( scene::Node *primitive, scene::Node *entity ){
scene::Path path( NodeReference( GlobalSceneGraph().root() ) );
path.push( NodeReference( *entity ) );
path.push( NodeReference( *primitive ) );
Instance_getSelectable( *GlobalSceneGraph().find( path ) )->setSelected( true );
}
bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
ClearPatches();
ClearBrushes();

View File

@ -116,3 +116,5 @@ public:
void SpawnFloat( const char* key, const char* defaultstring, float* out );
void SpawnVector( const char* key, const char* defaultstring, vec_t* out );
};
void select_primitive( scene::Node *primitive, scene::Node *entity );

View File

@ -120,7 +120,7 @@ bool DPlane::IsRedundant( std::list<DPoint*>& pointList ){
return true;
}
bool DPlane::operator ==( DPlane& other ){
bool DPlane::operator ==( const DPlane& other ) const {
vec3_t chk;
VectorSubtract( other.normal, normal, chk );
if ( fabs( VectorLength( chk ) ) > MAX_ROUND_ERROR ) {

View File

@ -46,7 +46,7 @@ public:
bool AddToBrush( scene::Node& brush );
bool operator !=( DPlane& other );
bool operator ==( DPlane& other );
bool operator ==( const DPlane& other ) const;
bool IsRedundant( std::list<DPoint*>& pointList );
bool PlaneIntersection( DPlane* pl1, DPlane* pl2, vec3_t out );;

View File

@ -57,31 +57,32 @@ const char* PLUGIN_NAME = "bobToolz";
// commands in the menu
constexpr char PLUGIN_COMMANDS[] = "About...,"
"-,"
"Stair Builder...,"
"Door Builder...,"
"Intersect...,"
"Make Chain...,"
"Path Plotter...,"
"-,"
"Reset Textures...,"
"PitOMatic,"
"-,"
"Vis Viewer,"
"Brush Cleanup,"
"Polygon Builder,"
"Caulk Selection,"
"-,"
"Tree Planter,"
"Drop Entity,"
"Plot Splines,"
"-,"
"Merge Patches,"
"Split patches,"
"Split patches cols,"
"Split patches rows,"
"Turn edge"
;
"-,"
"Stair Builder...,"
"Door Builder...,"
"Find Duplicates,"
"Intersect...,"
"Make Chain...,"
"Path Plotter...,"
"-,"
"Reset Textures...,"
"PitOMatic,"
"-,"
"Vis Viewer,"
"Brush Cleanup,"
"Polygon Builder,"
"Caulk Selection,"
"-,"
"Tree Planter,"
"Drop Entity,"
"Plot Splines,"
"-,"
"Merge Patches,"
"Split patches,"
"Split patches cols,"
"Split patches rows,"
"Turn edge"
;
// globals
QWidget *g_pRadiantWnd = nullptr;
@ -160,6 +161,9 @@ extern "C" void QERPlug_Dispatch( const char *p, vec3_t vMin, vec3_t vMax, bool
else if ( string_equal_nocase( p, "intersect..." ) ) {
DoIntersect();
}
else if ( string_equal_nocase( p, "find duplicates" ) ) {
DoFindDuplicates();
}
else if ( string_equal_nocase( p, "make chain..." ) ) {
DoMakeChain();
}

View File

@ -88,7 +88,6 @@ void LoadLists(){
//========================//
void DoIntersect(){
UndoableCommand undo( "bobToolz.intersect" );
IntersectRS rs;
if ( !DoIntersectBox( &rs ) ) {
@ -135,6 +134,33 @@ void DoIntersect(){
delete[] pbSelectList;
}
void DoFindDuplicates()
{
DMap map;
map.LoadAll( false );
std::vector<const DBrush *> brushes;
for( const auto *e : map.entityList )
for( const auto *b : e->brushList )
brushes.push_back( b );
GlobalSelectionSystem().setSelectedAll( false );
for( auto b = brushes.begin(); b != brushes.end(); ++b ){
if( *b != nullptr ){
for( auto b2 = std::next( b ); b2 != brushes.end(); ++b2 ){
if( *b2 != nullptr ){
if( ( *b )->operator==( *b2 ) ){
( *b2 )->selectInRadiant();
*b2 = nullptr;
}
}
}
}
}
}
void DoPolygonsTB(){
DoPolygons();
}

View File

@ -53,6 +53,7 @@ void LoadLists();
// djbob
void DoIntersect();
void DoFindDuplicates();
void DoPolygonsTB();
void DoPolygons();
void DoFixBrushes();