blender/intern/bsp/intern/BSP_MeshPrimitives.h

281 lines
5.8 KiB
C++

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file bsp/intern/BSP_MeshPrimitives.h
* \ingroup bsp
*/
#ifndef __BSP_MESHPRIMITIVES_H__
#define __BSP_MESHPRIMITIVES_H__
#include "CTR_TaggedIndex.h"
#include "MT_Vector3.h"
#include "MT_Plane3.h"
#include <vector>
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_VertexInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_EdgeInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_FaceInd;
typedef CTR_TaggedIndex<24,0x00ffffff> BSP_FragInd;
typedef std::vector<BSP_VertexInd> BSP_VertexList;
typedef std::vector<BSP_EdgeInd> BSP_EdgeList;
typedef std::vector<BSP_FaceInd> BSP_FaceList;
/**
* Enum representing classification of primitives
* with respect to a hyperplane.
*/
enum BSP_Classification{
e_unclassified = 0,
e_classified_in = 1,
e_classified_out = 2,
e_classified_on = 4,
e_classified_spanning = 7
};
/**
* @section Mesh linkage
* The mesh is linked in a similar way to the decimation mesh,
* although the primitives are a little more general and not
* limited to manifold meshes.
* Vertices -> (2+)Edges
* Edges -> (1+)Polygons
* Edges -> (2)Vertices.
* Polygons -> (3+)Vertices.
*
* this structure allows for arbitrary polygons (assumed to be convex).
* Edges can point to more than 2 polygons (non-manifold)
*
* We also define 2 different link types between edges and their
* neighbouring polygons. A weak link and a strong link.
* A weak link means the polygon is in a different mesh fragment
* to the other polygon. A strong link means the polygon is in the
* same fragment.
* This is not entirely consistent as it means edges have to be associated
* with fragments, in reality only polygons will be - edges and vertices
* will live in global pools. I guess we should mark edges as being on plane
* boundaries. This leaves a problem with non-manifold edges because for example
* 3 of 4 possible edges could lie in 1 fragment and the remaining edge lie in
* another, there is no way to work out then from one polygon which neighbouring
* polygons are in the same/different mesh fragment.
*
* By definition an edge will only ever lie on 1 hyperplane. We can then just
* tag neighbouring polygons with one of 3 tags to group them.
*/
class BSP_MVertex {
public :
MT_Point3 m_pos;
BSP_EdgeList m_edges;
/**
* TODO
* Is this boolean necessary or can we nick a few bits of m_edges[0]
* for example?
* The only problem with this is that if the vertex is degenerate then
* m_edges[0] may not exist. If the algorithm guarentees that this is
* not the case then it should be changed.
*/
bool m_select_tag;
int m_open_tag;
BSP_MVertex(
);
BSP_MVertex(
const MT_Point3 & pos
);
BSP_MVertex &
operator = (
const BSP_MVertex & other
) {
m_pos = other.m_pos;
m_edges = other.m_edges;
m_select_tag = other.m_select_tag;
m_open_tag = other.m_open_tag;
return (*this);
};
bool
RemoveEdge(
BSP_EdgeInd e
);
void
AddEdge(
BSP_EdgeInd e
);
void
SwapEdge(
BSP_EdgeInd e_old,
BSP_EdgeInd e_new
);
/**
* These operations are ONLY valid when the
* vertex has some edges associated with it.
* This is left to the user to guarentee.
* Also note that these tag's are not guarenteed
* to survive after a call to RemoveEdge(),
* because we use edges for the open tag.
*/
int
OpenTag(
) const;
void
SetOpenTag(
int tag
);
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
};
class BSP_MEdge {
public :
BSP_VertexInd m_verts[2];
BSP_FaceList m_faces;
BSP_MEdge(
);
bool operator == (
BSP_MEdge & rhs
);
void
SwapFace(
BSP_FaceInd old_f,
BSP_FaceInd new_f
);
BSP_VertexInd
OpVertex(
BSP_VertexInd vi
) const;
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
/**
* We use one of the vertex indices for tag informtaion.
* This means these tags will not survive if you change
* the vertex indices.
*/
int
OpenTag(
) const;
void
SetOpenTag(
int tag
) ;
};
class BSP_MFace {
public :
BSP_VertexList m_verts;
// We also store the plane equation of this
// face. Generating on the fly during tree
// construction can lead to a lot of numerical errors.
// because the polygon size can get very small.
MT_Plane3 m_plane;
int m_open_tag;
unsigned int m_orig_face;
BSP_MFace(
);
// Invert the face , done by reversing the vertex order
// and inverting the face normal.
void
Invert(
);
/**
* Tagging
* We use the tag from m_verts[1] for the select tag
* and the the tag from m_verts[0] for the open tag.
* There is always a chance that the polygon contains
* no vertices but this should be checked at construction
* time.
* Also note that changing the vertex indices of this polygon
* will likely remove tagging information.
*
*/
bool
SelectTag(
) const;
void
SetSelectTag(
bool tag
);
int
OpenTag(
) const;
void
SetOpenTag(
int tag
) ;
};
#endif