* 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; return true;
} }
DPlane* DBrush::HasPlane( DPlane* chkPlane ){ DPlane* DBrush::HasPlane( DPlane* chkPlane ) const {
for ( DPlane *plane : faceList ) for ( DPlane *plane : faceList )
{ {
if ( *plane == *chkPlane ) { if ( *plane == *chkPlane ) {
@ -414,6 +414,12 @@ scene::Node* DBrush::BuildInRadiant( bool allowDestruction, int* changeCnt, scen
return node.get_pointer(); 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 ){ void DBrush::CutByPlane( DPlane *cutPlane, DBrush **newBrush1, DBrush **newBrush2 ){
if ( !IsCutByPlane( cutPlane ) ) { if ( !IsCutByPlane( cutPlane ) ) {
*newBrush1 = NULL; *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 ) for ( DPlane *plane : faceList )
{ {
if ( !other->HasPlane( plane ) ) { if ( !other->HasPlane( plane ) ) {

View File

@ -53,7 +53,7 @@ public:
void RotateAboutCentre( vec3_t vRotation ); void RotateAboutCentre( vec3_t vRotation );
DPlane* HasPlaneInverted( DPlane* chkPlane ); 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 ); 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 ); 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 BuildBounds();
void BuildFromWinding( DWinding* w ); void BuildFromWinding( DWinding* w );
scene::Node* BuildInRadiant( bool allowDestruction, int* changeCnt, scene::Node* entity = NULL ); scene::Node* BuildInRadiant( bool allowDestruction, int* changeCnt, scene::Node* entity = NULL );
void selectInRadiant() const;
void ResetChecks( std::list<Str>* exclusionList ); void ResetChecks( std::list<Str>* exclusionList );
@ -93,7 +94,7 @@ public:
DBrush( int ID = -1 ); DBrush( int ID = -1 );
virtual ~DBrush(); virtual ~DBrush();
bool operator==( DBrush* other ); bool operator==( const DBrush* other ) const;
// members // members
scene::Node* QER_entity; 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 ) { bool DEntity::LoadFromEntity( scene::Node& ent, bool bLoadPatches ) {
ClearPatches(); ClearPatches();
ClearBrushes(); ClearBrushes();

View File

@ -116,3 +116,5 @@ public:
void SpawnFloat( const char* key, const char* defaultstring, float* out ); void SpawnFloat( const char* key, const char* defaultstring, float* out );
void SpawnVector( const char* key, const char* defaultstring, vec_t* 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; return true;
} }
bool DPlane::operator ==( DPlane& other ){ bool DPlane::operator ==( const DPlane& other ) const {
vec3_t chk; vec3_t chk;
VectorSubtract( other.normal, normal, chk ); VectorSubtract( other.normal, normal, chk );
if ( fabs( VectorLength( chk ) ) > MAX_ROUND_ERROR ) { if ( fabs( VectorLength( chk ) ) > MAX_ROUND_ERROR ) {

View File

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

View File

@ -60,6 +60,7 @@ constexpr char PLUGIN_COMMANDS[] = "About...,"
"-," "-,"
"Stair Builder...," "Stair Builder...,"
"Door Builder...," "Door Builder...,"
"Find Duplicates,"
"Intersect...," "Intersect...,"
"Make Chain...," "Make Chain...,"
"Path Plotter...," "Path Plotter...,"
@ -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..." ) ) { else if ( string_equal_nocase( p, "intersect..." ) ) {
DoIntersect(); DoIntersect();
} }
else if ( string_equal_nocase( p, "find duplicates" ) ) {
DoFindDuplicates();
}
else if ( string_equal_nocase( p, "make chain..." ) ) { else if ( string_equal_nocase( p, "make chain..." ) ) {
DoMakeChain(); DoMakeChain();
} }

View File

@ -88,7 +88,6 @@ void LoadLists(){
//========================// //========================//
void DoIntersect(){ void DoIntersect(){
UndoableCommand undo( "bobToolz.intersect" );
IntersectRS rs; IntersectRS rs;
if ( !DoIntersectBox( &rs ) ) { if ( !DoIntersectBox( &rs ) ) {
@ -135,6 +134,33 @@ void DoIntersect(){
delete[] pbSelectList; 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(){ void DoPolygonsTB(){
DoPolygons(); DoPolygons();
} }

View File

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