[235] | 1 | #include "Polygon3.h"
|
---|
| 2 | #include "Mesh.h"
|
---|
| 3 | |
---|
[242] | 4 | #define SIDE_TOLERANCE 0.002 // TODO: Test different values |
---|
[238] | 5 | |
---|
[242] | 6 | Polygon3::Polygon3(): mMaterial(NULL) |
---|
[235] | 7 | {} |
---|
| 8 | |
---|
[242] | 9 | Polygon3::Polygon3(const VertexContainer &vertices): mVertices(vertices), mMaterial(NULL) |
---|
[235] | 10 | {} |
---|
| 11 | |
---|
| 12 | Polygon3::Polygon3(Face *face, Mesh *parent) |
---|
| 13 | { |
---|
| 14 | VertexIndexContainer::const_iterator it; |
---|
| 15 | |
---|
| 16 | for (it = face->mVertexIndices.begin(); it != face->mVertexIndices.end(); ++ it) |
---|
| 17 | { |
---|
| 18 | mVertices.push_back(parent->mVertices[*it]); |
---|
[242] | 19 | mMaterial = parent->mMaterial; |
---|
| 20 | |
---|
[237] | 21 | Debug << parent->mVertices[*it] << endl; |
---|
[235] | 22 | } |
---|
| 23 | } |
---|
| 24 | |
---|
[238] | 25 | Plane3 Polygon3::GetSupportingPlane() const |
---|
[235] | 26 | { |
---|
[238] | 27 | Vector3 v1 = mVertices[0] - mVertices[1]; |
---|
[239] | 28 | Vector3 v2 = mVertices[2] - mVertices[1]; |
---|
| 29 | #ifdef _DEBUG |
---|
| 30 | Debug << "plane spanned by " << v1 << ", " << v2 << endl; |
---|
| 31 | #endif |
---|
[235] | 32 | return Plane3(mVertices[0], mVertices[1], mVertices[2]); |
---|
| 33 | } |
---|
| 34 | |
---|
[238] | 35 | void Polygon3::DeletePolygons(PolygonContainer *polys) |
---|
[235] | 36 | { |
---|
[238] | 37 | // don't need to store polygon information => delete polygons
|
---|
[235] | 38 | while(!polys->empty())
|
---|
| 39 | {
|
---|
[238] | 40 | Polygon3 *poly = polys->back();
|
---|
| 41 | polys->pop_back();
|
---|
[235] | 42 | DEL_PTR(poly);
|
---|
| 43 | } |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | void Polygon3::Split(Plane3 *partition, Polygon3 *front, Polygon3 *back, int &splits) |
---|
| 47 | { |
---|
| 48 | splits = 0; |
---|
[237] | 49 | Vector3 ptA = mVertices[mVertices.size() - 1]; |
---|
[235] | 50 | |
---|
[238] | 51 | int sideA = partition->Side(ptA, SIDE_TOLERANCE); |
---|
[235] | 52 | |
---|
| 53 | VertexContainer::const_iterator it; |
---|
| 54 | |
---|
| 55 | // find line - plane intersections |
---|
| 56 | for (it = mVertices.begin(); it != mVertices.end(); ++ it) |
---|
| 57 | { |
---|
| 58 | Vector3 ptB = (*it); |
---|
[238] | 59 | int sideB = partition->Side(ptB, SIDE_TOLERANCE); |
---|
[239] | 60 | |
---|
[235] | 61 | // vertices on different sides => split |
---|
[237] | 62 | if (sideB > 0)
|
---|
| 63 | {
|
---|
| 64 | if (sideA < 0)
|
---|
| 65 | { |
---|
| 66 | //-- plane - line intersection |
---|
| 67 | Vector3 splitPt = partition->FindIntersection(ptA, ptB); |
---|
[235] | 68 | |
---|
[237] | 69 | // add vertex to both polygons |
---|
| 70 | front->mVertices.push_back(splitPt); |
---|
[239] | 71 | back->mVertices.push_back(splitPt); |
---|
[237] | 72 | |
---|
| 73 | ++ splits; |
---|
| 74 | } |
---|
[239] | 75 | front->mVertices.push_back(ptB); |
---|
[237] | 76 | } |
---|
| 77 | else if (sideB < 0)
|
---|
| 78 | {
|
---|
| 79 | if (sideA > 0)
|
---|
[235] | 80 | { |
---|
[237] | 81 | //-- plane - line intersection |
---|
| 82 | Vector3 splitPt = partition->FindIntersection(ptA, ptB); |
---|
| 83 | |
---|
| 84 | // add vertex to both polygons |
---|
| 85 | front->mVertices.push_back(splitPt); |
---|
[239] | 86 | back->mVertices.push_back(splitPt); |
---|
[237] | 87 | |
---|
| 88 | ++ splits; |
---|
[235] | 89 | } |
---|
[239] | 90 | back->mVertices.push_back(ptB); |
---|
[235] | 91 | } |
---|
[237] | 92 | else |
---|
[235] | 93 | { |
---|
[237] | 94 | // vertex on plane => add vertex to both polygons |
---|
[235] | 95 | front->mVertices.push_back(ptB); |
---|
[239] | 96 | back->mVertices.push_back(ptB); |
---|
[235] | 97 | } |
---|
[237] | 98 | |
---|
[235] | 99 | ptA = ptB; |
---|
| 100 | sideA = sideB; |
---|
| 101 | } |
---|
| 102 | } |
---|
| 103 | |
---|
[238] | 104 | int Polygon3::Side(const Plane3 &plane) const |
---|
[235] | 105 | { |
---|
[238] | 106 | int classification = ClassifyPlane(plane); |
---|
| 107 | |
---|
| 108 | if (classification == BACK_SIDE) |
---|
| 109 | return -1; |
---|
| 110 | else if (classification == FRONT_SIDE) |
---|
| 111 | return 1; |
---|
| 112 | |
---|
| 113 | return 0; |
---|
| 114 | } |
---|
| 115 | |
---|
| 116 | int Polygon3::ClassifyPlane(const Plane3 &plane) const |
---|
| 117 | { |
---|
[235] | 118 | VertexContainer::const_iterator it; |
---|
| 119 | |
---|
| 120 | bool onFrontSide = false; |
---|
| 121 | bool onBackSide = false; |
---|
| 122 | |
---|
[238] | 123 | // find possible line-plane intersections |
---|
[235] | 124 | for (it = mVertices.begin(); it != mVertices.end(); ++ it) |
---|
| 125 | { |
---|
[238] | 126 | int side = plane.Side(*it, SIDE_TOLERANCE); |
---|
[235] | 127 | |
---|
| 128 | if (side > 0) |
---|
| 129 | { |
---|
| 130 | onFrontSide = true; |
---|
| 131 | } |
---|
| 132 | else if (side < 0) |
---|
| 133 | { |
---|
| 134 | onBackSide = true; |
---|
| 135 | } |
---|
| 136 | |
---|
[238] | 137 | if (onFrontSide && onBackSide) // split //TODO: check if through vvertex |
---|
[235] | 138 | { |
---|
| 139 | return SPLIT; |
---|
| 140 | } |
---|
| 141 | } |
---|
| 142 | |
---|
| 143 | if (onBackSide) |
---|
| 144 | { |
---|
| 145 | return BACK_SIDE; |
---|
| 146 | } |
---|
| 147 | else if (onFrontSide) |
---|
| 148 | { |
---|
| 149 | return FRONT_SIDE; |
---|
| 150 | } |
---|
| 151 | |
---|
[238] | 152 | // plane and polygon are coincident |
---|
[235] | 153 | return COINCIDENT; |
---|
| 154 | } |
---|
| 155 |
|
---|