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 #ifndef TrenchBroom_Brush 21 #define TrenchBroom_Brush 22 23 #include "TrenchBroom.h" 24 #include "VecMath.h" 25 #include "Hit.h" 26 #include "ProjectingSequence.h" 27 #include "Model/BrushContentType.h" 28 #include "Model/BrushGeometry.h" 29 #include "Model/Node.h" 30 #include "Model/Object.h" 31 32 namespace TrenchBroom { 33 namespace Model { 34 struct BrushAlgorithmResult; 35 class BrushContentTypeBuilder; 36 class ModelFactory; 37 class PickResult; 38 39 class Brush : public Node, public Object { 40 private: 41 friend class SetTempFaceLinks; 42 public: 43 static const Hit::HitType BrushHit; 44 private: 45 struct ProjectToVertex : public ProjectingSequenceProjector<BrushVertex*, BrushVertex*> { 46 static BrushVertex*& project(BrushVertex*& vertex); 47 }; 48 49 struct ProjectToEdge : public ProjectingSequenceProjector<BrushEdge*, BrushEdge*> { 50 static BrushEdge*& project(BrushEdge*& edge); 51 }; 52 53 class AddFaceToGeometryCallback; 54 class HealEdgesCallback; 55 class AddFacesToGeometry; 56 class CanMoveBoundaryCallback; 57 class CanMoveBoundary; 58 class MoveVerticesCallback; 59 class QueryCallback; 60 public: 61 typedef ConstProjectingSequence<BrushVertexList, ProjectToVertex> VertexList; 62 typedef ConstProjectingSequence<BrushEdgeList, ProjectToEdge> EdgeList; 63 private: 64 BrushFaceList m_faces; 65 BrushGeometry* m_geometry; 66 67 const BrushContentTypeBuilder* m_contentTypeBuilder; 68 mutable BrushContentType::FlagType m_contentType; 69 mutable bool m_transparent; 70 mutable bool m_contentTypeValid; 71 public: 72 Brush(const BBox3& worldBounds, const BrushFaceList& faces); 73 ~Brush(); 74 private: 75 void cleanup(); 76 public: 77 Brush* clone(const BBox3& worldBounds) const; 78 79 AttributableNode* entity() const; 80 public: // face management: 81 const BrushFaceList& faces() const; 82 void setFaces(const BBox3& worldBounds, const BrushFaceList& faces); 83 84 BrushFace* findFaceByNormal(const Vec3& normal) const; 85 86 bool fullySpecified() const; 87 88 void faceDidChange(); 89 private: 90 void addFaces(const BrushFaceList& faces); 91 template <typename I> addFaces(I cur,I end,size_t count)92 void addFaces(I cur, I end, size_t count) { 93 m_faces.reserve(m_faces.size() + count); 94 while (cur != end) { 95 addFace(*cur); 96 ++cur; 97 } 98 } 99 void addFace(BrushFace* face); 100 101 template <typename I> removeFaces(I cur,I end)102 void removeFaces(I cur, I end) { 103 BrushFaceList::iterator rem = m_faces.end(); 104 while (cur != end) { 105 rem = doRemoveFace(m_faces.begin(), rem, *cur); 106 ++cur; 107 } 108 109 m_faces.erase(rem, m_faces.end()); 110 } 111 112 void removeFace(BrushFace* face); 113 BrushFaceList::iterator doRemoveFace(BrushFaceList::iterator begin, BrushFaceList::iterator end, BrushFace* face); 114 115 void detachFaces(const BrushFaceList& faces); 116 void detachFace(BrushFace* face); 117 public: // clone face attributes from matching faces of other brushes 118 void cloneFaceAttributesFrom(const BrushList& brushes); 119 void cloneFaceAttributesFrom(const Brush* brush); 120 void cloneInvertedFaceAttributesFrom(const BrushList& brushes); 121 void cloneInvertedFaceAttributesFrom(const Brush* brush); 122 BrushFace* findFaceWithBoundary(const Plane3& boundary) const; 123 public: // clipping 124 bool clip(const BBox3& worldBounds, BrushFace* face); 125 public: // move face along normal 126 bool canMoveBoundary(const BBox3& worldBounds, const BrushFace* face, const Vec3& delta) const; 127 void moveBoundary(const BBox3& worldBounds, BrushFace* face, const Vec3& delta, const bool lockTexture); 128 public: 129 // geometry access 130 size_t vertexCount() const; 131 VertexList vertices() const; 132 133 size_t edgeCount() const; 134 EdgeList edges() const; 135 136 bool containsPoint(const Vec3& point) const; 137 138 BrushFaceList incidentFaces(const BrushVertex* vertex) const; 139 140 // vertex operations 141 bool canMoveVertices(const BBox3& worldBounds, const Vec3::List& vertexPositions, const Vec3& delta); 142 Vec3::List moveVertices(const BBox3& worldBounds, const Vec3::List& vertexPositions, const Vec3& delta); 143 144 bool canSnapVertices(const BBox3& worldBounds, const Vec3::List& vertexPositions, size_t snapTo); 145 Vec3::List snapVertices(const BBox3& worldBounds, const Vec3::List& vertexPositions, size_t snapTo); 146 147 // edge operations 148 bool canMoveEdges(const BBox3& worldBounds, const Edge3::List& edgePositions, const Vec3& delta); 149 Edge3::List moveEdges(const BBox3& worldBounds, const Edge3::List& edgePositions, const Vec3& delta); 150 bool canSplitEdge(const BBox3& worldBounds, const Edge3& edgePosition, const Vec3& delta); 151 Vec3 splitEdge(const BBox3& worldBounds, const Edge3& edgePosition, const Vec3& delta); 152 153 // face operations 154 bool canMoveFaces(const BBox3& worldBounds, const Polygon3::List& facePositions, const Vec3& delta); 155 Polygon3::List moveFaces(const BBox3& worldBounds, const Polygon3::List& facePositions, const Vec3& delta); 156 bool canSplitFace(const BBox3& worldBounds, const Polygon3& facePosition, const Vec3& delta); 157 Vec3 splitFace(const BBox3& worldBounds, const Polygon3& facePosition, const Vec3& delta); 158 159 // CSG operations 160 BrushList subtract(const ModelFactory& factory, const BBox3& worldBounds, const String& defaultTextureName, const Brush* subtrahend) const; 161 void intersect(const BBox3& worldBounds, const Brush* brush); 162 private: 163 Brush* createBrush(const ModelFactory& factory, const BBox3& worldBounds, const String& defaultTextureName, const BrushGeometry& geometry, const Brush* subtrahend) const; 164 private: 165 void updateFacesFromGeometry(const BBox3& worldBounds); 166 void updatePointsFromVertices(const BBox3& worldBounds); 167 public: // brush geometry 168 void rebuildGeometry(const BBox3& worldBounds); 169 void findIntegerPlanePoints(const BBox3& worldBounds); 170 private: 171 bool checkGeometry() const; 172 public: // content type 173 bool transparent() const; 174 bool hasContentType(const BrushContentType& contentType) const; 175 bool hasContentType(BrushContentType::FlagType contentTypeMask) const; 176 void setContentTypeBuilder(const BrushContentTypeBuilder* contentTypeBuilder); 177 private: 178 BrushContentType::FlagType contentTypeFlags() const; 179 void invalidateContentType(); 180 void validateContentType() const; 181 private: // implement Node interface 182 const String& doGetName() const; 183 const BBox3& doGetBounds() const; 184 185 Node* doClone(const BBox3& worldBounds) const; 186 NodeSnapshot* doTakeSnapshot(); 187 188 bool doCanAddChild(const Node* child) const; 189 bool doCanRemoveChild(const Node* child) const; 190 bool doRemoveIfEmpty() const; 191 192 void doParentDidChange(); 193 194 bool doSelectable() const; 195 196 void doGenerateIssues(const IssueGenerator* generator, IssueList& issues); 197 void doAccept(NodeVisitor& visitor); 198 void doAccept(ConstNodeVisitor& visitor) const; 199 private: // implement Object interface 200 void doPick(const Ray3& ray, PickResult& pickResult) const; 201 void doFindNodesContaining(const Vec3& point, NodeList& result); 202 FloatType doIntersectWithRay(const Ray3& ray) const; 203 204 struct BrushFaceHit { 205 BrushFace* face; 206 FloatType distance; 207 BrushFaceHit(); 208 BrushFaceHit(BrushFace* i_face, FloatType i_distance); 209 }; 210 211 BrushFaceHit findFaceHit(const Ray3& ray) const; 212 213 Node* doGetContainer() const; 214 Layer* doGetLayer() const; 215 Group* doGetGroup() const; 216 217 void doTransform(const Mat4x4& transformation, bool lockTextures, const BBox3& worldBounds); 218 219 class Contains; 220 bool doContains(const Node* node) const; 221 222 class Intersects; 223 bool doIntersects(const Node* node) const; 224 private: 225 Brush(const Brush&); 226 Brush& operator=(const Brush&); 227 }; 228 } 229 } 230 231 #endif /* defined(TrenchBroom_Brush) */ 232