00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_MESH_BOOLEAN_OPERATOR_H__
00009 #define __SP_MESH_BOOLEAN_OPERATOR_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013
00014 #ifdef SP_COMPILE_WITH_MESHBOOLEANOPERATOR
00015
00016
00017 #include "Base/spInputOutputString.hpp"
00018 #include "Base/spDimension.hpp"
00019 #include "SceneGraph/spSceneGraph.hpp"
00020
00021 #include <list>
00022 #include <vector>
00023
00024
00025 namespace sp
00026 {
00027 namespace tool
00028 {
00029
00030
00031 enum EModelCombinations
00032 {
00033 COMBINATION_UNION,
00034 COMBINATION_DIFFERENCE,
00035 COMBINATION_DIFFERENCEINV,
00036 COMBINATION_INTERSECTION,
00037 };
00038
00064 class SP_EXPORT MeshBooleanOperator
00065 {
00066
00067 public:
00068
00069 MeshBooleanOperator();
00070 ~MeshBooleanOperator();
00071
00078 void combineModels(
00079 scene::Mesh* MeshA, scene::Mesh* MeshB, const EModelCombinations Method = COMBINATION_UNION
00080 );
00081
00082
00083
00084 static void setPrecision(const f32 Precision);
00085 static f32 getPrecision();
00086
00087 private:
00088
00089
00090
00091 struct STriangle;
00092 struct SFace;
00093 struct SLine;
00094 struct SModel;
00095 struct SVertex;
00096
00097
00098
00099 enum ELineContactFlags
00100 {
00101 CONTACT_CORNERS = 0x0001,
00102 CONTACT_EDGES = 0x0002,
00103 CONTACT_CUT = 0x0004,
00104 CONTACT_FULL = (CONTACT_CORNERS | CONTACT_EDGES | CONTACT_CUT)
00105 };
00106
00107
00108
00109 struct SVertex
00110 {
00111 SVertex();
00112 SVertex(SModel* Mod, u32 VertexSurface, u32 VertexIndex);
00113 SVertex(const SVertex &other);
00114 ~SVertex();
00115
00116
00117 bool operator == (const SVertex &other) const;
00118 bool operator != (const SVertex &other) const;
00119
00120 SVertex& operator = (const SVertex &other);
00121
00122 SVertex operator + (const SVertex &other) const;
00123 SVertex operator - (const SVertex &other) const;
00124 SVertex operator * (const SVertex &other) const;
00125 SVertex operator / (const SVertex &other) const;
00126
00127 SVertex operator + (const f32 Size) const;
00128 SVertex operator - (const f32 Size) const;
00129 SVertex operator * (const f32 Size) const;
00130 SVertex operator / (const f32 Size) const;
00131
00132
00133 SVertex& set(SModel* Mod, u32 VertexSurface, u32 VertexIndex);
00134
00135 SVertex& interpolate(
00136 const dim::vector3df &Pos, const SVertex &A, const SVertex &B, const SVertex &C
00137 );
00138
00139
00140 u32 Surface, Index;
00141
00142 dim::vector3df Position;
00143 dim::vector3df Normal;
00144 dim::vector3df TexCoord[MAX_COUNT_OF_TEXTURES];
00145 video::color Color;
00146 f32 Fog;
00147 };
00148
00149 struct STriangle
00150 {
00151 STriangle();
00152 ~STriangle();
00153
00154
00155 void computeCutLines(SModel* Mod, SModel* OppositMod);
00156
00157 bool checkNormalEquality(const dim::vector3df &Normal) const;
00158
00159 bool checkCollision(const STriangle &OpTriangle) const;
00160 bool checkCollisionCorners(const STriangle &OpTriangle) const;
00161 bool checkCollisionEdges(const STriangle &OpTriangle) const;
00162 bool checkCollisionOverlap(const STriangle &OpTriangle) const;
00163
00164 bool checkLineEdgesContact(const dim::line3df &Line) const;
00165
00166 void getLineEdgesIntersection(const dim::line3df &Line, std::list<dim::vector3df> &Points) const;
00167
00168 static bool checkPointCornersContact(const dim::triangle3df &OpTriangle, const dim::vector3df &Point);
00169 static bool checkPointInside(const dim::triangle3df &OpTriangle, const dim::vector3df &Point);
00170 static bool checkPointInsideInv(const dim::triangle3df &OpTriangle, const dim::vector3df &Point);
00171
00172
00173 u32 Surface;
00174 u32 Indices[3];
00175 SVertex* Vertices[3];
00176 dim::triangle3df Triangle;
00177 SFace* Face;
00178 dim::plane3df Plane;
00179 };
00180
00181 struct SFace
00182 {
00183 SFace(u32 DefSurface = 0);
00184 ~SFace();
00185
00186
00187 void addCutLine(
00188 const SVertex &A, const SVertex &B, const SVertex &C,
00189 const dim::line3df &Line, const dim::plane3df OppositPlane
00190 );
00191 void optimizeCutLines();
00192
00193 void createCutVertices();
00194 void optimizeCutVertices();
00195
00196 void generateDeltaConnections();
00197 bool checkDeltaConnection() const;
00198 bool checkTriangleCollision() const;
00199
00200 bool checkCutPlanesSide() const;
00201 const SLine* getClosestCutLine(const dim::vector3df &Point) const;
00202
00203 bool checkInsideConcaveFace() const;
00204 void fillCutPointList(std::list<dim::vector3df> &Points) const;
00205 bool isPointInside(const dim::vector3df &Point) const;
00206
00207 void createDefaultFace();
00208 SVertex* getVertex(u32 VertexSurface, u32 VertexIndex);
00209
00210
00211 u32 Surface;
00212 dim::plane3df Plane;
00213 std::vector<STriangle> Triangles, FinalTriangles;
00214 std::list<SLine> CutLines;
00215 std::list<SVertex> CutVertices, OrigVertices;
00216 std::list<SVertex*> Vertices;
00217 STriangle CurTriangle;
00218 };
00219
00220 struct SLine
00221 {
00222 SLine();
00223 ~SLine();
00224
00225
00226 bool checkRedundance(const SLine &other) const;
00227
00228 bool checkCollision(const STriangle &Triangle) const;
00229
00230 static bool checkLineLineIntersection(const dim::line3df &A, const dim::line3df &B);
00231 static bool getLineLineIntersection(const dim::line3df &A, const dim::line3df &B, dim::vector3df &Point);
00232
00233 static bool checkLineLineContact(const dim::line3df &A, const dim::line3df &B, s32 Flags = CONTACT_FULL);
00234
00235
00236 SVertex A, B;
00237 dim::plane3df Plane;
00238 SFace* Face;
00239 };
00240
00241 struct SModel
00242 {
00243 SModel(scene::Mesh* DefMesh);
00244 ~SModel();
00245
00246
00247 bool isPointInside(SModel* OppositMod, dim::vector3df Point);
00248
00249 void createVertices(SModel* OppositMod);
00250 void createFaces();
00251 void computeCutLines(SModel* OppositMod);
00252 void generateDeltaConnections();
00253
00254 void addVertex(video::MeshBuffer* Surface, SVertex* Vertex);
00255 void build();
00256 void clear();
00257
00258
00259 struct STrianglePointDistance
00260 {
00261 dim::triangle3df Triangle;
00262 f32 Distance;
00263 };
00264
00265
00266 scene::Mesh* Mesh;
00267 dim::matrix4f Matrix, NormalMatrix;
00268
00269 std::vector<SFace*> Faces;
00270 };
00271
00272
00273
00274 friend bool cmpModelTrianglePlane(const MeshBooleanOperator::STriangle &obj1, const MeshBooleanOperator::STriangle &obj2);
00275 friend bool cmpModelCutLinePlane(const MeshBooleanOperator::SLine &obj1, const MeshBooleanOperator::SLine &obj2);
00276 friend bool cmpModelCutVertexPosition(const MeshBooleanOperator::SVertex &obj1, const MeshBooleanOperator::SVertex &obj2);
00277
00278 friend bool cmpTrianglePointDistance(
00279 const MeshBooleanOperator::SModel::STrianglePointDistance &obj1,
00280 const MeshBooleanOperator::SModel::STrianglePointDistance &obj2
00281 );
00282
00283
00284
00285 void cutModel(SModel* ModA, SModel* ModB, bool CutFrontSide);
00286
00287
00288
00289 EModelCombinations Method_;
00290
00291 SModel * Model_, * OppositModel_;
00292
00293 static bool CutFrontSide_;
00294 static f32 Precision_;
00295
00296 };
00297
00298
00299 }
00300
00301 }
00302
00303
00304 #endif
00305
00306 #endif
00307
00308
00309
00310