* bobToolz: new Find Duplicates function: finds & selects duplicate brushes in entire map
This commit is contained in:
parent
d98b1c5d0e
commit
7bd11485d0
|
|
@ -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 ) ) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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 );
|
||||||
|
|
|
||||||
|
|
@ -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 ) {
|
||||||
|
|
|
||||||
|
|
@ -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 );;
|
||||||
|
|
|
||||||
|
|
@ -57,31 +57,32 @@ const char* PLUGIN_NAME = "bobToolz";
|
||||||
|
|
||||||
// commands in the menu
|
// commands in the menu
|
||||||
constexpr char PLUGIN_COMMANDS[] = "About...,"
|
constexpr char PLUGIN_COMMANDS[] = "About...,"
|
||||||
"-,"
|
"-,"
|
||||||
"Stair Builder...,"
|
"Stair Builder...,"
|
||||||
"Door Builder...,"
|
"Door Builder...,"
|
||||||
"Intersect...,"
|
"Find Duplicates,"
|
||||||
"Make Chain...,"
|
"Intersect...,"
|
||||||
"Path Plotter...,"
|
"Make Chain...,"
|
||||||
"-,"
|
"Path Plotter...,"
|
||||||
"Reset Textures...,"
|
"-,"
|
||||||
"PitOMatic,"
|
"Reset Textures...,"
|
||||||
"-,"
|
"PitOMatic,"
|
||||||
"Vis Viewer,"
|
"-,"
|
||||||
"Brush Cleanup,"
|
"Vis Viewer,"
|
||||||
"Polygon Builder,"
|
"Brush Cleanup,"
|
||||||
"Caulk Selection,"
|
"Polygon Builder,"
|
||||||
"-,"
|
"Caulk Selection,"
|
||||||
"Tree Planter,"
|
"-,"
|
||||||
"Drop Entity,"
|
"Tree Planter,"
|
||||||
"Plot Splines,"
|
"Drop Entity,"
|
||||||
"-,"
|
"Plot Splines,"
|
||||||
"Merge Patches,"
|
"-,"
|
||||||
"Split patches,"
|
"Merge Patches,"
|
||||||
"Split patches cols,"
|
"Split patches,"
|
||||||
"Split patches rows,"
|
"Split patches cols,"
|
||||||
"Turn edge"
|
"Split patches rows,"
|
||||||
;
|
"Turn edge"
|
||||||
|
;
|
||||||
|
|
||||||
// globals
|
// globals
|
||||||
QWidget *g_pRadiantWnd = nullptr;
|
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..." ) ) {
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user