1 /*
2  Copyright (C) 2010-2014 Kristian Duske
3 
4  This file is part of TrenchBroom.
5 
6  TrenchBroom is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  TrenchBroom is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "World.h"
21 
22 #include "Model/AssortNodesVisitor.h"
23 #include "Model/Brush.h"
24 #include "Model/BrushFace.h"
25 #include "Model/CollectNodesWithDescendantSelectionCountVisitor.h"
26 #include "Model/Entity.h"
27 #include "Model/Group.h"
28 #include "Model/IssueGenerator.h"
29 #include "Model/Layer.h"
30 #include "Model/NodeVisitor.h"
31 
32 #include <cassert>
33 
34 namespace TrenchBroom {
35     namespace Model {
World(MapFormat::Type mapFormat,const BrushContentTypeBuilder * brushContentTypeBuilder,const BBox3 & worldBounds)36         World::World(MapFormat::Type mapFormat, const BrushContentTypeBuilder* brushContentTypeBuilder, const BBox3& worldBounds) :
37         m_factory(mapFormat, brushContentTypeBuilder),
38         m_defaultLayer(NULL) {
39             addOrUpdateAttribute(AttributeNames::Classname, AttributeValues::WorldspawnClassname);
40             createDefaultLayer(worldBounds);
41         }
42 
defaultLayer() const43         Layer* World::defaultLayer() const {
44             assert(m_defaultLayer != NULL);
45             return m_defaultLayer;
46         }
47 
allLayers() const48         LayerList World::allLayers() const {
49             CollectLayersVisitor visitor;
50             iterate(visitor);
51             return visitor.layers();
52         }
53 
customLayers() const54         LayerList World::customLayers() const {
55             const NodeList& children = Node::children();
56             CollectLayersVisitor visitor;
57             accept(children.begin() + 1, children.end(), visitor);
58             return visitor.layers();
59         }
60 
createDefaultLayer(const BBox3 & worldBounds)61         void World::createDefaultLayer(const BBox3& worldBounds) {
62             m_defaultLayer = createLayer("Default Layer", worldBounds);
63             addChild(m_defaultLayer);
64         }
65 
registeredIssueGenerators() const66         const IssueGeneratorList& World::registeredIssueGenerators() const {
67             return m_issueGeneratorRegistry.registeredGenerators();
68         }
69 
quickFixes(const IssueType issueTypes) const70         IssueQuickFixList World::quickFixes(const IssueType issueTypes) const {
71             return m_issueGeneratorRegistry.quickFixes(issueTypes);
72         }
73 
registerIssueGenerator(IssueGenerator * issueGenerator)74         void World::registerIssueGenerator(IssueGenerator* issueGenerator) {
75             m_issueGeneratorRegistry.registerGenerator(issueGenerator);
76             invalidateAllIssues();
77         }
78 
unregisterAllIssueGenerators()79         void World::unregisterAllIssueGenerators() {
80             m_issueGeneratorRegistry.unregisterAllGenerators();
81             invalidateAllIssues();
82         }
83 
84         class World::InvalidateAllIssuesVisitor : public NodeVisitor {
85         private:
doVisit(World * world)86             void doVisit(World* world)   { invalidateIssues(world);  }
doVisit(Layer * layer)87             void doVisit(Layer* layer)   { invalidateIssues(layer);  }
doVisit(Group * group)88             void doVisit(Group* group)   { invalidateIssues(group);  }
doVisit(Entity * entity)89             void doVisit(Entity* entity) { invalidateIssues(entity); }
doVisit(Brush * brush)90             void doVisit(Brush* brush)   { invalidateIssues(brush);  }
91 
invalidateIssues(Node * node)92             void invalidateIssues(Node* node) { node->invalidateIssues(); }
93         };
94 
invalidateAllIssues()95         void World::invalidateAllIssues() {
96             InvalidateAllIssuesVisitor visitor;
97             acceptAndRecurse(visitor);
98         }
99 
doGetBounds() const100         const BBox3& World::doGetBounds() const {
101             // TODO: this should probably return the world bounds, as it does in Layer::doGetBounds
102             static const BBox3 bounds;
103             return bounds;
104         }
105 
doClone(const BBox3 & worldBounds) const106         Node* World::doClone(const BBox3& worldBounds) const {
107             World* world = m_factory.createWorld(worldBounds);
108             cloneAttributes(world);
109             return world;
110         }
111 
doCloneRecursively(const BBox3 & worldBounds) const112         Node* World::doCloneRecursively(const BBox3& worldBounds) const {
113             const NodeList& myChildren = children();
114             assert(myChildren[0] == m_defaultLayer);
115 
116             World* world = m_factory.createWorld(worldBounds);
117             cloneAttributes(world);
118 
119             world->defaultLayer()->addChildren(cloneRecursively(worldBounds, m_defaultLayer->children()));
120 
121             if (myChildren.size() > 1) {
122                 NodeList childClones;
123                 childClones.reserve(myChildren.size() - 1);
124                 cloneRecursively(worldBounds, myChildren.begin() + 1, myChildren.end(), std::back_inserter(childClones));
125                 world->addChildren(childClones);
126             }
127 
128             return world;
129         }
130 
131         class CanAddChildToWorld : public ConstNodeVisitor, public NodeQuery<bool> {
132         private:
doVisit(const World * world)133             void doVisit(const World* world)   { setResult(false); }
doVisit(const Layer * layer)134             void doVisit(const Layer* layer)   { setResult(true); }
doVisit(const Group * group)135             void doVisit(const Group* group)   { setResult(false); }
doVisit(const Entity * entity)136             void doVisit(const Entity* entity) { setResult(false); }
doVisit(const Brush * brush)137             void doVisit(const Brush* brush)   { setResult(false); }
138         };
139 
doCanAddChild(const Node * child) const140         bool World::doCanAddChild(const Node* child) const {
141             CanAddChildToWorld visitor;
142             child->accept(visitor);
143             return visitor.result();
144         }
145 
146         class CanRemoveChildFromWorld : public ConstNodeVisitor, public NodeQuery<bool> {
147         private:
148             const World* m_this;
149         public:
CanRemoveChildFromWorld(const World * i_this)150             CanRemoveChildFromWorld(const World* i_this) :
151             m_this(i_this) {}
152         private:
doVisit(const World * world)153             void doVisit(const World* world)   { setResult(false); }
doVisit(const Layer * layer)154             void doVisit(const Layer* layer)   { setResult(layer != m_this->defaultLayer()); }
doVisit(const Group * group)155             void doVisit(const Group* group)   { setResult(false); }
doVisit(const Entity * entity)156             void doVisit(const Entity* entity) { setResult(false); }
doVisit(const Brush * brush)157             void doVisit(const Brush* brush)   { setResult(false); }
158         };
159 
doCanRemoveChild(const Node * child) const160         bool World::doCanRemoveChild(const Node* child) const {
161             CanRemoveChildFromWorld visitor(this);
162             child->accept(visitor);
163             return visitor.result();
164         }
165 
doRemoveIfEmpty() const166         bool World::doRemoveIfEmpty() const {
167             return false;
168         }
169 
doSelectable() const170         bool World::doSelectable() const {
171             return false;
172         }
173 
doPick(const Ray3 & ray,PickResult & pickResult) const174         void World::doPick(const Ray3& ray, PickResult& pickResult) const {
175             const NodeList& children = Node::children();
176             NodeList::const_iterator it, end;
177             for (it = children.begin(), end = children.end(); it != end; ++it) {
178                 const Node* child = *it;
179                 child->pick(ray, pickResult);
180             }
181         }
182 
doFindNodesContaining(const Vec3 & point,NodeList & result)183         void World::doFindNodesContaining(const Vec3& point, NodeList& result) {
184             const NodeList& children = Node::children();
185             NodeList::const_iterator it, end;
186             for (it = children.begin(), end = children.end(); it != end; ++it) {
187                 Node* child = *it;
188                 child->findNodesContaining(point, result);
189             }
190         }
191 
doIntersectWithRay(const Ray3 & ray) const192         FloatType World::doIntersectWithRay(const Ray3& ray) const {
193             return Math::nan<FloatType>();
194         }
195 
doGenerateIssues(const IssueGenerator * generator,IssueList & issues)196         void World::doGenerateIssues(const IssueGenerator* generator, IssueList& issues) {
197             generator->generate(this, issues);
198         }
199 
doAccept(NodeVisitor & visitor)200         void World::doAccept(NodeVisitor& visitor) {
201             visitor.visit(this);
202         }
203 
doAccept(ConstNodeVisitor & visitor) const204         void World::doAccept(ConstNodeVisitor& visitor) const {
205             visitor.visit(this);
206         }
207 
doFindAttributableNodesWithAttribute(const AttributeName & name,const AttributeValue & value,AttributableNodeList & result) const208         void World::doFindAttributableNodesWithAttribute(const AttributeName& name, const AttributeValue& value, AttributableNodeList& result) const {
209             VectorUtils::append(result, m_attributableIndex.findAttributableNodes(AttributableNodeIndexQuery::exact(name), value));
210         }
211 
doFindAttributableNodesWithNumberedAttribute(const AttributeName & prefix,const AttributeValue & value,AttributableNodeList & result) const212         void World::doFindAttributableNodesWithNumberedAttribute(const AttributeName& prefix, const AttributeValue& value, AttributableNodeList& result) const {
213             VectorUtils::append(result, m_attributableIndex.findAttributableNodes(AttributableNodeIndexQuery::numbered(prefix), value));
214         }
215 
doAddToIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)216         void World::doAddToIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) {
217             m_attributableIndex.addAttribute(attributable, name, value);
218         }
219 
doRemoveFromIndex(AttributableNode * attributable,const AttributeName & name,const AttributeValue & value)220         void World::doRemoveFromIndex(AttributableNode* attributable, const AttributeName& name, const AttributeValue& value) {
221             m_attributableIndex.removeAttribute(attributable, name, value);
222         }
223 
doAttributesDidChange()224         void World::doAttributesDidChange() {}
225 
doIsAttributeNameMutable(const AttributeName & name) const226         bool World::doIsAttributeNameMutable(const AttributeName& name) const {
227             if (name == AttributeNames::Classname)
228                 return false;
229             if (name == AttributeNames::Mods)
230                 return false;
231             if (name == AttributeNames::EntityDefinitions)
232                 return false;
233             if (name == AttributeNames::Wad)
234                 return false;
235             if (name == AttributeNames::Textures)
236                 return false;
237             return true;
238         }
239 
doIsAttributeValueMutable(const AttributeName & name) const240         bool World::doIsAttributeValueMutable(const AttributeName& name) const {
241             if (name == AttributeNames::Mods)
242                 return false;
243             if (name == AttributeNames::EntityDefinitions)
244                 return false;
245             if (name == AttributeNames::Wad)
246                 return false;
247             if (name == AttributeNames::Textures)
248                 return false;
249             return true;
250         }
251 
doGetLinkSourceAnchor() const252         Vec3 World::doGetLinkSourceAnchor() const {
253             return Vec3::Null;
254         }
255 
doGetLinkTargetAnchor() const256         Vec3 World::doGetLinkTargetAnchor() const {
257             return Vec3::Null;
258         }
259 
doGetFormat() const260         MapFormat::Type World::doGetFormat() const {
261             return m_factory.format();
262         }
263 
doCreateWorld(const BBox3 & worldBounds) const264         World* World::doCreateWorld(const BBox3& worldBounds) const {
265             return m_factory.createWorld(worldBounds);
266         }
267 
doCreateLayer(const String & name,const BBox3 & worldBounds) const268         Layer* World::doCreateLayer(const String& name, const BBox3& worldBounds) const {
269             return m_factory.createLayer(name, worldBounds);
270         }
271 
doCreateGroup(const String & name) const272         Group* World::doCreateGroup(const String& name) const {
273             return m_factory.createGroup(name);
274         }
275 
doCreateEntity() const276         Entity* World::doCreateEntity() const {
277             return m_factory.createEntity();
278         }
279 
doCreateBrush(const BBox3 & worldBounds,const BrushFaceList & faces) const280         Brush* World::doCreateBrush(const BBox3& worldBounds, const BrushFaceList& faces) const {
281             return m_factory.createBrush(worldBounds, faces);
282         }
283 
doCreateFace(const Vec3 & point1,const Vec3 & point2,const Vec3 & point3,const BrushFaceAttributes & attribs) const284         BrushFace* World::doCreateFace(const Vec3& point1, const Vec3& point2, const Vec3& point3, const BrushFaceAttributes& attribs) const {
285             return m_factory.createFace(point1, point2, point3, attribs);
286         }
287 
doCreateFace(const Vec3 & point1,const Vec3 & point2,const Vec3 & point3,const BrushFaceAttributes & attribs,const Vec3 & texAxisX,const Vec3 & texAxisY) const288         BrushFace* World::doCreateFace(const Vec3& point1, const Vec3& point2, const Vec3& point3, const BrushFaceAttributes& attribs, const Vec3& texAxisX, const Vec3& texAxisY) const {
289             return m_factory.createFace(point1, point2, point3, attribs, texAxisX, texAxisY);
290         }
291     }
292 }
293