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