00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __TRANSFORMEDTRIANGLEINLINE_HXX__
00021 #define __TRANSFORMEDTRIANGLEINLINE_HXX__
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 inline void TransformedTriangle::preCalculateTriangleSurroundsEdge()
00033 {
00034 for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1))
00035 {
00036 _triangleSurroundsEdgeCache[edge] = testTriangleSurroundsEdge(edge);
00037 }
00038 }
00039
00040
00041
00042
00043
00044
00045 inline void TransformedTriangle::resetDoubleProducts(const TriSegment seg, const TetraCorner corner)
00046 {
00047
00048 static const DoubleProduct DOUBLE_PRODUCTS[12] =
00049 {
00050 C_YZ, C_ZX, C_XY,
00051 C_YZ, C_ZH, C_YH,
00052 C_ZX, C_ZH, C_XH,
00053 C_XY, C_YH, C_XH
00054 };
00055
00056 for(int i = 0 ; i < 3 ; ++i) {
00057 const DoubleProduct dp = DOUBLE_PRODUCTS[3*corner + i];
00058
00059 LOG(6, std::endl << "resetting inconsistent dp :" << dp << " for corner " << corner);
00060 _doubleProducts[8*seg + dp] = 0.0;
00061 };
00062 }
00063
00064 inline double TransformedTriangle::calcStableC(const TriSegment seg, const DoubleProduct dp) const
00065 {
00066 return _doubleProducts[8*seg + dp];
00067 }
00068
00069 inline double TransformedTriangle::calcStableT(const TetraCorner corner) const
00070 {
00071
00072
00073 return _tripleProducts[corner];
00074 }
00075
00076 inline double TransformedTriangle::calcUnstableC(const TriSegment seg, const DoubleProduct dp) const
00077 {
00078
00079
00080
00081 const int pt1 = seg;
00082 const int pt2 = (seg + 1) % 3;
00083
00084
00085 const int off1 = DP_OFFSET_1[dp];
00086 const int off2 = DP_OFFSET_2[dp];
00087
00088 return _coords[5*pt1 + off1] * _coords[5*pt2 + off2] - _coords[5*pt1 + off2] * _coords[5*pt2 + off1];
00089 }
00090
00091
00092
00093
00094 inline bool TransformedTriangle::testSurfaceEdgeIntersection(const TetraEdge edge) const
00095 {
00096 return _triangleSurroundsEdgeCache[edge] && testEdgeIntersectsTriangle(edge);
00097 }
00098
00099 inline bool TransformedTriangle::testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const
00100 {
00101 return testFacetSurroundsSegment(seg, facet) && testSegmentIntersectsFacet(seg, facet);
00102 }
00103
00104 inline bool TransformedTriangle::testSurfaceRayIntersection(const TetraCorner corner) const
00105 {
00106 return testTriangleSurroundsRay( corner ) && testSurfaceAboveCorner( corner );
00107 }
00108
00109 inline bool TransformedTriangle::testCornerInTetrahedron(const TriCorner corner) const
00110 {
00111 const double pt[4] =
00112 {
00113 _coords[5*corner],
00114 _coords[5*corner + 1],
00115 _coords[5*corner + 2],
00116 _coords[5*corner + 3]
00117 };
00118
00119 for(int i = 0 ; i < 4 ; ++i)
00120 {
00121 if(pt[i] < 0.0 || pt[i] > 1.0)
00122 {
00123 return false;
00124 }
00125 }
00126 return true;
00127 }
00128
00129 inline bool TransformedTriangle::testCornerOnXYZFacet(const TriCorner corner) const
00130 {
00131 #if 0
00132 const double pt[4] =
00133 {
00134 _coords[5*corner],
00135 _coords[5*corner + 1],
00136 _coords[5*corner + 2],
00137 _coords[5*corner + 3]
00138 };
00139 #endif
00140 const double* pt = &_coords[5*corner];
00141
00142 if(pt[3] != 0.0)
00143 {
00144 return false;
00145 }
00146
00147 for(int i = 0 ; i < 3 ; ++i)
00148 {
00149 if(pt[i] < 0.0 || pt[i] > 1.0)
00150 {
00151 return false;
00152 }
00153 }
00154 return true;
00155 }
00156
00157 inline bool TransformedTriangle::testCornerAboveXYZFacet(const TriCorner corner) const
00158 {
00159 const double x = _coords[5*corner];
00160 const double y = _coords[5*corner + 1];
00161 const double h = _coords[5*corner + 3];
00162 const double H = _coords[5*corner + 4];
00163
00164 return h < 0.0 && H >= 0.0 && x >= 0.0 && y >= 0.0;
00165
00166 }
00167
00168 inline bool TransformedTriangle::testEdgeIntersectsTriangle(const TetraEdge edge) const
00169 {
00170
00171
00172
00173
00174
00175 static const TetraCorner TRIPLE_PRODUCTS[12] =
00176 {
00177 X, O,
00178 Y, O,
00179 Z, O,
00180 X, Y,
00181 Y, Z,
00182 Z, X,
00183 };
00184
00185
00186 const double t1 = calcStableT(TRIPLE_PRODUCTS[2*edge]);
00187 const double t2 = calcStableT(TRIPLE_PRODUCTS[2*edge + 1]);
00188
00189
00190 LOG(5, "testEdgeIntersectsTriangle : t1 = " << t1 << " t2 = " << t2 );
00191 return (t1*t2 <= 0.0) && (t1 - t2 != 0.0);
00192 }
00193
00194 inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const
00195 {
00196 #if 0
00197 const double signs[3] =
00198 {
00199 SIGN_FOR_SEG_FACET_INTERSECTION[3*facet],
00200 SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 1],
00201 SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 2]
00202 };
00203 #endif
00204
00205 const double* signs = &SIGN_FOR_SEG_FACET_INTERSECTION[3*facet];
00206 const double c1 = signs[0]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet]);
00207 const double c2 = signs[1]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]);
00208 const double c3 = signs[2]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]);
00209
00210 return (c1*c3 > 0.0) && (c2*c3 > 0.0);
00211 }
00212
00213 inline bool TransformedTriangle::testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const
00214 {
00215
00216
00217 const double coord1 = _coords[5*seg + facet];
00218 const double coord2 = _coords[5*( (seg + 1) % 3) + facet];
00219
00220
00221 LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 );
00222
00223 return (coord1*coord2 <= 0.0) && (coord1 != coord2);
00224 }
00225
00226 inline bool TransformedTriangle::testSegmentIntersectsHPlane(const TriSegment seg) const
00227 {
00228
00229 const double coord1 = _coords[5*seg + 4];
00230 const double coord2 = _coords[5*( (seg + 1) % 3) + 4];
00231
00232 LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 );
00233
00234 return (coord1*coord2 <= 0.0) && (coord1 != coord2);
00235 }
00236
00237 inline bool TransformedTriangle::testSurfaceAboveCorner(const TetraCorner corner) const
00238 {
00239
00240
00241 const double normal = calcStableC(PQ, C_XY) + calcStableC(QR, C_XY) + calcStableC(RP, C_XY);
00242
00243 LOG(6, "surface above corner " << corner << " : " << "n = " << normal << ", t = [" << calcTByDevelopingRow(corner, 1, false) << ", " << calcTByDevelopingRow(corner, 2, false) << ", " << calcTByDevelopingRow(corner, 3, false) );
00244 LOG(6, "] - stable : " << calcStableT(corner) );
00245
00246
00247
00248 if(!_validTP[corner])
00249 {
00250 return ( calcTByDevelopingRow(corner, 1, false) * normal ) >= 0.0;
00251 }
00252 else
00253 {
00254 return ( calcStableT(corner) * normal ) >= 0.0;
00255 }
00256 }
00257
00258 inline bool TransformedTriangle::testTriangleSurroundsRay(const TetraCorner corner) const
00259 {
00260
00261
00262
00263 static const DoubleProduct DP_FOR_RAY_INTERSECTION[4] =
00264 {
00265 DoubleProduct(0),
00266 C_10,
00267 C_01,
00268 C_XY
00269 };
00270
00271 const DoubleProduct dp = DP_FOR_RAY_INTERSECTION[corner];
00272
00273 const double cPQ = calcStableC(PQ, dp);
00274 const double cQR = calcStableC(QR, dp);
00275 const double cRP = calcStableC(RP, dp);
00276
00277
00278
00279 LOG(5, "dp in triSurrRay for corner " << corner << " = [" << cPQ << ", " << cQR << ", " << cRP << "]" );
00280
00281 return ( cPQ*cQR > 0.0 ) && ( cPQ*cRP > 0.0 );
00282
00283 }
00284 #endif