00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <OpenFOAM/boolList.H>
00031 #include <OpenFOAM/PointHit_.H>
00032 #include <OpenFOAM/objectHit.H>
00033 #include <OpenFOAM/bandCompression.H>
00034
00035
00036
00037 template
00038 <
00039 class Face,
00040 template<class> class FaceList,
00041 class PointField,
00042 class PointType
00043 >
00044 template <class ToPatch>
00045 Foam::List<Foam::objectHit>
00046 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00047 projectPoints
00048 (
00049 const ToPatch& targetPatch,
00050 const Field<PointType>& projectionDirection,
00051 const intersection::algorithm alg,
00052 const intersection::direction dir
00053 ) const
00054 {
00055
00056
00057 if (projectionDirection.size() != nPoints())
00058 {
00059 FatalErrorIn
00060 (
00061 "PrimitivePatch<Face, FaceList, PointField, PointType>::"
00062 "projectPoints(const PrimitivePatch& "
00063 ", const Field<PointType>&) const"
00064 ) << "Projection direction field does not correspond to "
00065 << "patch points." << endl
00066 << "Size: " << projectionDirection.size()
00067 << " Number of points: " << nPoints()
00068 << abort(FatalError);
00069 }
00070
00071 const labelList& slavePointOrder = localPointOrder();
00072
00073 const labelList& slaveMeshPoints = meshPoints();
00074
00075
00076 List<objectHit> result(nPoints());
00077
00078 const labelListList& masterFaceFaces = targetPatch.faceFaces();
00079
00080 const ToPatch& masterFaces = targetPatch;
00081
00082 const Field<PointType>& masterPoints = targetPatch.points();
00083
00084
00085 Field<PointType> masterFaceCentres(targetPatch.size());
00086
00087 forAll (masterFaceCentres, faceI)
00088 {
00089 masterFaceCentres[faceI] =
00090 average(masterFaces[faceI].points(masterPoints));
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 label curFace = 0;
00102 label nNSquaredSearches = 0;
00103
00104 forAll (slavePointOrder, pointI)
00105 {
00106
00107 const label curLocalPointLabel = slavePointOrder[pointI];
00108
00109 const PointType& curPoint =
00110 points_[slaveMeshPoints[curLocalPointLabel]];
00111
00112 const PointType& curProjectionDir =
00113 projectionDirection[curLocalPointLabel];
00114
00115 bool closer;
00116
00117 boolList visitedTargetFace(targetPatch.size(), false);
00118 bool doNSquaredSearch = false;
00119
00120 bool foundEligible = false;
00121
00122 scalar sqrDistance = GREAT;
00123
00124
00125
00126 if (pointI == 0)
00127 {
00128 doNSquaredSearch = true;
00129 }
00130 else
00131 {
00132 do
00133 {
00134 closer = false;
00135 doNSquaredSearch = false;
00136
00137
00138 PointHit<PointType> curHit =
00139 masterFaces[curFace].ray
00140 (
00141 curPoint,
00142 curProjectionDir,
00143 masterPoints,
00144 alg,
00145 dir
00146 );
00147
00148 visitedTargetFace[curFace] = true;
00149
00150 if (curHit.hit())
00151 {
00152 result[curLocalPointLabel] = objectHit(true, curFace);
00153
00154 break;
00155 }
00156 else
00157 {
00158
00159
00160
00161
00162 if (curHit.eligibleMiss())
00163 {
00164 foundEligible = true;
00165 result[curLocalPointLabel] = objectHit(false, curFace);
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 PointType missPlanePoint =
00175 curPoint + curProjectionDir*curHit.distance();
00176
00177 const labelList& masterNbrs = masterFaceFaces[curFace];
00178
00179 sqrDistance =
00180 magSqr(missPlanePoint - masterFaceCentres[curFace]);
00181
00182 forAll (masterNbrs, nbrI)
00183 {
00184 if
00185 (
00186 magSqr
00187 (
00188 missPlanePoint
00189 - masterFaceCentres[masterNbrs[nbrI]]
00190 )
00191 <= sqrDistance
00192 )
00193 {
00194 closer = true;
00195 curFace = masterNbrs[nbrI];
00196 }
00197 }
00198
00199 if (visitedTargetFace[curFace])
00200 {
00201
00202
00203 doNSquaredSearch = true;
00204 break;
00205 }
00206 }
00207
00208 if (debug) Info<< ".";
00209 } while (closer);
00210 }
00211
00212 if
00213 (
00214 doNSquaredSearch || !foundEligible
00215 )
00216 {
00217 nNSquaredSearches++;
00218
00219 if (debug)
00220 {
00221 Info<< "p " << curLocalPointLabel << ": ";
00222 }
00223
00224 result[curLocalPointLabel] = objectHit(false, -1);
00225 scalar minDistance = GREAT;
00226
00227 forAll (masterFaces, faceI)
00228 {
00229 PointHit<PointType> curHit =
00230 masterFaces[faceI].ray
00231 (
00232 curPoint,
00233 curProjectionDir,
00234 masterPoints,
00235 alg,
00236 dir
00237 );
00238
00239 if (curHit.hit())
00240 {
00241 result[curLocalPointLabel] = objectHit(true, faceI);
00242 curFace = faceI;
00243
00244 break;
00245 }
00246 else if (curHit.eligibleMiss())
00247 {
00248
00249 scalar missDist =
00250 Foam::mag(curHit.missPoint() - curPoint);
00251
00252 if (missDist < minDistance)
00253 {
00254 minDistance = missDist;
00255
00256 result[curLocalPointLabel] = objectHit(false, faceI);
00257 curFace = faceI;
00258 }
00259 }
00260 }
00261
00262 if (debug)
00263 {
00264 Info << result[curLocalPointLabel] << nl;
00265 }
00266 }
00267 else
00268 {
00269 if (debug) Info<< "x";
00270 }
00271 }
00272
00273 if (debug)
00274 {
00275 Info<< nl << "Executed " << nNSquaredSearches
00276 << " n-squared searches out of total of "
00277 << nPoints() << endl;
00278 }
00279
00280 return result;
00281 }
00282
00283
00284 template
00285 <
00286 class Face,
00287 template<class> class FaceList,
00288 class PointField,
00289 class PointType
00290 >
00291 template <class ToPatch>
00292 Foam::List<Foam::objectHit>
00293 Foam::PrimitivePatch<Face, FaceList, PointField, PointType>::
00294 projectFaceCentres
00295 (
00296 const ToPatch& targetPatch,
00297 const Field<PointType>& projectionDirection,
00298 const intersection::algorithm alg,
00299 const intersection::direction dir
00300 ) const
00301 {
00302
00303
00304 if (projectionDirection.size() != this->size())
00305 {
00306 FatalErrorIn
00307 (
00308 "labelList PrimitivePatch<Face, FaceList, PointField, PointType>::"
00309 "projectFaceCentres(const PrimitivePatch& "
00310 ", const Field<PointType>&) const"
00311 ) << "Projection direction field does not correspond to patch faces."
00312 << endl << "Size: " << projectionDirection.size()
00313 << " Number of points: " << this->size()
00314 << abort(FatalError);
00315 }
00316
00317 labelList slaveFaceOrder = bandCompression(faceFaces());
00318
00319
00320 Field<PointType> masterFaceCentres(targetPatch.size());
00321
00322 const labelListList& masterFaceFaces = targetPatch.faceFaces();
00323
00324 const ToPatch& masterFaces = targetPatch;
00325
00326 const typename ToPatch::PointFieldType& masterPoints = targetPatch.points();
00327
00328 forAll (masterFaceCentres, faceI)
00329 {
00330 masterFaceCentres[faceI] =
00331 masterFaces[faceI].centre(masterPoints);
00332 }
00333
00334
00335 List<objectHit> result(this->size());
00336
00337 const PrimitivePatch<Face, FaceList, PointField, PointType>& slaveFaces = *this;
00338 const PointField& slaveGlobalPoints = points();
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 label curFace = 0;
00349 label nNSquaredSearches = 0;
00350
00351 forAll (slaveFaceOrder, faceI)
00352 {
00353
00354 const label curLocalFaceLabel = slaveFaceOrder[faceI];
00355
00356 const point& curFaceCentre =
00357 slaveFaces[curLocalFaceLabel].centre(slaveGlobalPoints);
00358
00359 const vector& curProjectionDir =
00360 projectionDirection[curLocalFaceLabel];
00361
00362 bool closer;
00363
00364 boolList visitedTargetFace(targetPatch.size(), false);
00365 bool doNSquaredSearch = false;
00366
00367 bool foundEligible = false;
00368
00369 scalar sqrDistance = GREAT;
00370
00371
00372
00373 if (faceI == 0)
00374 {
00375 doNSquaredSearch = true;
00376 }
00377 else
00378 {
00379 do
00380 {
00381 closer = false;
00382 doNSquaredSearch = false;
00383
00384
00385 PointHit<PointType> curHit =
00386 masterFaces[curFace].ray
00387 (
00388 curFaceCentre,
00389 curProjectionDir,
00390 masterPoints,
00391 alg,
00392 dir
00393 );
00394
00395 visitedTargetFace[curFace] = true;
00396
00397 if (curHit.hit())
00398 {
00399 result[curLocalFaceLabel] = objectHit(true, curFace);
00400
00401 break;
00402 }
00403 else
00404 {
00405
00406
00407
00408
00409 if (curHit.eligibleMiss())
00410 {
00411 foundEligible = true;
00412 result[curLocalFaceLabel] = objectHit(false, curFace);
00413 }
00414
00415
00416
00417
00418
00419
00420 PointType missPlanePoint =
00421 curFaceCentre + curProjectionDir*curHit.distance();
00422
00423 sqrDistance =
00424 magSqr(missPlanePoint - masterFaceCentres[curFace]);
00425
00426 const labelList& masterNbrs = masterFaceFaces[curFace];
00427
00428 forAll (masterNbrs, nbrI)
00429 {
00430 if
00431 (
00432 magSqr
00433 (
00434 missPlanePoint
00435 - masterFaceCentres[masterNbrs[nbrI]]
00436 )
00437 <= sqrDistance
00438 )
00439 {
00440 closer = true;
00441 curFace = masterNbrs[nbrI];
00442 }
00443 }
00444
00445 if (visitedTargetFace[curFace])
00446 {
00447
00448
00449 doNSquaredSearch = true;
00450 break;
00451 }
00452 }
00453
00454 if (debug) Info<< ".";
00455 } while (closer);
00456 }
00457
00458 if (doNSquaredSearch || !foundEligible)
00459 {
00460 nNSquaredSearches++;
00461
00462 if (debug)
00463 {
00464 Info<< "p " << curLocalFaceLabel << ": ";
00465 }
00466
00467 result[curLocalFaceLabel] = objectHit(false, -1);
00468 scalar minDistance = GREAT;
00469
00470 forAll (masterFaces, faceI)
00471 {
00472 PointHit<PointType> curHit =
00473 masterFaces[faceI].ray
00474 (
00475 curFaceCentre,
00476 curProjectionDir,
00477 masterPoints,
00478 alg,
00479 dir
00480 );
00481
00482 if (curHit.hit())
00483 {
00484 result[curLocalFaceLabel] = objectHit(true, faceI);
00485 curFace = faceI;
00486
00487 break;
00488 }
00489 else if (curHit.eligibleMiss())
00490 {
00491
00492 scalar missDist =
00493 Foam::mag(curHit.missPoint() - curFaceCentre);
00494
00495 if (missDist < minDistance)
00496 {
00497 minDistance = missDist;
00498
00499 result[curLocalFaceLabel] = objectHit(false, faceI);
00500 curFace = faceI;
00501 }
00502 }
00503 }
00504
00505 if (debug)
00506 {
00507 Info << result[curLocalFaceLabel] << nl;
00508 }
00509 }
00510 else
00511 {
00512 if (debug) Info<< "x";
00513 }
00514 }
00515
00516 if (debug)
00517 {
00518 Info<< nl << "Executed " << nNSquaredSearches
00519 << " n-squared searches out of total of "
00520 << this->size() << endl;
00521 }
00522
00523 return result;
00524 }
00525
00526
00527