Skip to content

Commit

Permalink
#5231: More footwork on getting it to compile again
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Jun 14, 2020
1 parent 26a84ee commit 9a9a1e5
Show file tree
Hide file tree
Showing 44 changed files with 695 additions and 600 deletions.
4 changes: 4 additions & 0 deletions include/ibrush.h
Expand Up @@ -94,6 +94,10 @@ class IFace
// Submits the current state to the UndoSystem, to make further actions undo-able
virtual void undoSave() = 0;

// Returns true if the texture of this face is not filtered out
// This doesn't take into account whether the owning brush is visible or not
virtual bool isVisible() const = 0;

// Shader accessors
virtual const std::string& getShader() const = 0;
virtual void setShader(const std::string& name) = 0;
Expand Down
9 changes: 9 additions & 0 deletions include/ientity.h
Expand Up @@ -390,6 +390,15 @@ class IEntityModule :

// Access to the settings manager
virtual IEntitySettings& getSettings() = 0;

/**
* Create an instance of the given entity at the given position, and return
* the Node containing the new entity.
*
* @returns: the scene::IEntityNodePtr referring to the new entity.
* @throws: cmd::ExecutionFailure if anything goes wrong or the selection is not suitable.
*/
virtual IEntityNodePtr createEntityFromSelection(const std::string& name, const Vector3& origin) = 0;
};

inline IEntityModule& GlobalEntityModule()
Expand Down
4 changes: 4 additions & 0 deletions include/ipatch.h
Expand Up @@ -160,6 +160,10 @@ class IPatch
virtual void setFixedSubdivisions(bool isFixed, const Subdivisions& divisions) = 0;

virtual void undoSave() = 0;

// This translates the texture as much towards the origin in texture space as possible
// without changing its appearance.
virtual void normaliseTexture() = 0;
};

namespace patch
Expand Down
4 changes: 2 additions & 2 deletions include/iselection.h
Expand Up @@ -34,7 +34,7 @@ class SelectionInfo;
class Face;
class IFace;
class Brush;
class Patch;
class IPatch;

namespace selection
{
Expand Down Expand Up @@ -271,7 +271,7 @@ class SelectionSystem :
* Call the given functor for each selected patch. Selected group nodes like func_statics
* are traversed recursively, invoking the functor for each visible patch in question.
*/
virtual void foreachPatch(const std::function<void(Patch&)>& functor) = 0;
virtual void foreachPatch(const std::function<void(IPatch&)>& functor) = 0;

/// Signal emitted when the selection is changed
virtual SelectionChangedSignal signal_selectionChanged() const = 0;
Expand Down
8 changes: 8 additions & 0 deletions include/ishaderclipboard.h
Expand Up @@ -31,6 +31,9 @@ class IShaderClipboard :
// Returns the material name of the object in the clipboard (or an empty string)
virtual std::string getShaderName() = 0;

// Sets the content of the shaderclipboard to the given material
virtual void setSourceShader(const std::string& shader) = 0;

virtual void pickFromSelectionTest(SelectionTest& test) = 0;

/**
Expand All @@ -56,6 +59,11 @@ class IShaderClipboard :
* Will leave the rest of the surface properties unchanged, if possible.
*/
virtual void pasteMaterialName(SelectionTest& test) = 0;

/**
* Is emitted when the shader source changes.
*/
virtual sigc::signal<void>& signal_sourceChanged() = 0;
};

} // namespace
Expand Down
22 changes: 18 additions & 4 deletions include/iundo.h
Expand Up @@ -72,6 +72,9 @@ class IUndoSystem :
virtual void redo() = 0;
virtual void clear() = 0;

// Returns true if an operation is already started
virtual bool operationStarted() const = 0;

// Emitted after an undo operation is fully completed, allows objects to refresh their state
virtual sigc::signal<void>& signal_postUndo() = 0;

Expand Down Expand Up @@ -116,15 +119,26 @@ inline IUndoSystem& GlobalUndoSystem()
class UndoableCommand
{
const std::string _command;
bool _shouldFinish;
public:

UndoableCommand(const std::string& command) :
_command(command)
_command(command),
_shouldFinish(false)
{
GlobalUndoSystem().start();
// Avoid double-starting undo operations
if (GlobalUndoSystem().operationStarted())
{
GlobalUndoSystem().start();
_shouldFinish = true;
}
}

~UndoableCommand() {
GlobalUndoSystem().finish(_command);
~UndoableCommand()
{
if (_shouldFinish)
{
GlobalUndoSystem().finish(_command);
}
}
};
62 changes: 62 additions & 0 deletions libs/scene/GroupNodeChecker.h
@@ -0,0 +1,62 @@
#pragma once

#include "iselection.h"
#include "scenelib.h"

namespace scene
{

// Checks the current selection to see whether it consists of
// group nodes only.
class GroupNodeChecker :
public SelectionSystem::Visitor
{
private:
mutable bool _onlyGroups;
mutable std::size_t _numGroups;
mutable scene::INodePtr _firstGroupNode;

public:
GroupNodeChecker() :
_onlyGroups(true),
_numGroups(0)
{}

void visit(const scene::INodePtr& node) const
{
if (!scene::hasChildPrimitives(node))
{
_onlyGroups = false;
}
else
{
_numGroups++;

if (!_firstGroupNode)
{
_firstGroupNode = node;
}
}
}

// Returns true if the current selection consists of group nodes only
// Returns false if any selected node is a non-group or if nothing is selected.
bool onlyGroupsAreSelected() const
{
return _numGroups > 0 && _onlyGroups;
}

// Returns the number of group nodes in the current selection
std::size_t selectedGroupCount() const
{
return _numGroups;
}

// Returns the first group node of the selection or NULL if nothing selected
scene::INodePtr getFirstSelectedGroupNode() const
{
return _firstGroupNode;
}
};

}
41 changes: 41 additions & 0 deletions libs/scene/ModelFinder.cpp
@@ -0,0 +1,41 @@
#include "ModelFinder.h"

#include "ientity.h"

namespace scene
{

ModelFinder::ModelFinder() :
_onlyModels(true)
{}

void ModelFinder::visit(const scene::INodePtr& node) const
{
Entity* entity = Node_getEntity(node);

if (entity != nullptr && entity->isModel())
{
_modelList.push_back(node);
}
else
{
_onlyModels = false;
}
}

ModelFinder::ModelList& ModelFinder::getList()
{
return _modelList;
}

bool ModelFinder::empty() const
{
return _modelList.empty();
}

bool ModelFinder::onlyModels() const
{
return _onlyModels;
}

} // namespace
41 changes: 41 additions & 0 deletions libs/scene/ModelFinder.h
@@ -0,0 +1,41 @@
#pragma once

#include <vector>
#include "iselection.h"
#include "inode.h"

namespace scene
{

// Visitor that checks the current selection for models
class ModelFinder :
public SelectionSystem::Visitor
{
public:
typedef std::vector<scene::INodePtr> ModelList;

private:
mutable ModelList _modelList;
mutable bool _onlyModels;

public:
ModelFinder();

/**
* greebo: Visits every selected instance and adds all
* models to the internal list
*/
void visit(const scene::INodePtr& node) const;

// greebo: Retrieves the result of the search
ModelList& getList();

// Returns TRUE if no models were found.
bool empty() const;

// Returns TRUE if ONLY models were found, no other
// objects like brushes, lights, etc.
bool onlyModels() const;
};

} // namespace
40 changes: 39 additions & 1 deletion libs/scene/Traverse.cpp
@@ -1,8 +1,11 @@
#include "Traverse.h"

#include "scenelib.h"
#include "ibrush.h"
#include "ipatch.h"

namespace scene {
namespace scene
{

class IncludeSelectedWalker :
public scene::NodeVisitor
Expand Down Expand Up @@ -65,4 +68,39 @@ void traverse(const scene::INodePtr& root, scene::NodeVisitor& nodeExporter)
root->traverseChildren(nodeExporter);
}

void foreachVisibleFace(const std::function<void(IFace&)>& functor)
{
GlobalSceneGraph().root()->foreachNode([&](const scene::INodePtr& node)->bool
{
if (Node_isBrush(node) && node->visible())
{
auto* brush = Node_getIBrush(node);
for (std::size_t i = 0; i < brush->getNumFaces(); ++i)
{
auto& face = brush->getFace(i);

if (face.isVisible())
{
functor(face);
}
}
}

return true;
});
}

void foreachVisiblePatch(const std::function<void(IPatch&)>& functor)
{
GlobalSceneGraph().root()->foreachNode([&](const scene::INodePtr& node)->bool
{
if (Node_isPatch(node) && node->visible())
{
functor(*Node_getIPatch(node));
}

return true;
});
}

} // namespace
13 changes: 13 additions & 0 deletions libs/scene/Traverse.h
@@ -1,6 +1,8 @@
#pragma once

#include "inode.h"
class IPatch;
class IFace;

namespace scene
{
Expand All @@ -13,4 +15,15 @@ void traverse(const scene::INodePtr& root, scene::NodeVisitor& nodeExporter);
*/
void traverseSelected(const scene::INodePtr& root, scene::NodeVisitor& nodeExporter);

/**
* Visit each visible face in the global scene graph. Both the brush and the face itself
* must not be hidden or filtered out to be visited.
*/
void foreachVisibleFace(const std::function<void(IFace&)>& functor);

/**
* Visit each visible patch node in the global scene graph.
*/
void foreachVisiblePatch(const std::function<void(IPatch&)>& functor);

} // namespace
34 changes: 34 additions & 0 deletions libs/selectionlib.h
Expand Up @@ -3,6 +3,8 @@
#include <stdexcept>
#include "iselection.h"
#include "ibrush.h"
#include "igroupnode.h"
#include "ientity.h"
#include "ipatch.h"
#include "math/Vector3.h"
#include "math/AABB.h"
Expand Down Expand Up @@ -175,4 +177,36 @@ inline std::string getShaderFromSelection()
}
}

/**
* Tests the current selection and returns true if the selection is suitable
* for reparenting the selected primitives to the (last) selected entity.
*/
inline bool curSelectionIsSuitableForReparent()
{
// Retrieve the selection information structure
const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

if (info.totalCount <= 1 || info.entityCount != 1)
{
return false;
}

scene::INodePtr lastSelected = GlobalSelectionSystem().ultimateSelected();
Entity* entity = Node_getEntity(lastSelected);

// Reject non-entities or models
if (entity == nullptr || entity->isModel())
{
return false;
}

// Accept only group nodes as parent
if (!Node_getGroupNode(lastSelected))
{
return false;
}

return true;
}

} // namespace selection

0 comments on commit 9a9a1e5

Please sign in to comment.