const Foam::gpuField<PointType>& Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: getLocalPoints() const { if ( ! gpuLocalPointsPtr_) { gpuLocalPointsPtr_ = new gpuField<PointType>(localPoints()); } return *gpuLocalPointsPtr_; }
std::pair<Coordinate, Coordinate> getRegion(const floatCoordinate & centerPos, const brush_t & brush) { // calcs global AABB of local coordinate system's region const auto posArb = centerPos.toLocal(brush.v1, brush.v2, brush.n); const auto width = brush.radius / state->scale.componentMul(brush.v1).length(); const auto height = brush.radius / state->scale.componentMul(brush.v2).length(); const auto depth = (brush.mode == brush_t::mode_t::three_dim) ? brush.radius / state->scale.componentMul(brush.n).length() : 0; std::vector<floatCoordinate> localPoints(8); for (std::size_t i = 0; i < localPoints.size(); ++i) { // all possible combinations. Ordering like in a truth table (with - and + instead of false and true). I just didn't want to type it all out… localPoints[i].x = (i < 4) ? posArb.x - width : posArb.x + width; localPoints[i].y = (i % 4 < 2) ? posArb.y - height : posArb.y + height; localPoints[i].z = (i % 2 == 0) ? posArb.z - depth : posArb.z + depth; } auto min = floatCoordinate(1, 1, 1) * std::numeric_limits<int>::max(); floatCoordinate max{0, 0, 0}; for (const auto localCoord : localPoints) { const auto worldCoord = localCoord.toWorldFrom(brush.v1, brush.v2, brush.n).abs().capped(Session::singleton().movementAreaMin, Session::singleton().movementAreaMax); min = {std::min(worldCoord.x, min.x), std::min(worldCoord.y, min.y), std::min(worldCoord.z, min.z)}; max = {std::max(worldCoord.x, max.x), std::max(worldCoord.y, max.y), std::max(worldCoord.z, max.z)}; } return std::make_pair(min, max); }
markPointNbrs(surf, faceI, false, okToCollapse); break; } } } } Pout<< "collapseEdge : collapsing " << nCollapsed << " triangles" << endl; nTotalCollapsed += nCollapsed; if (nCollapsed == 0) { break; } // Pack the triangles surf = pack(surf, newPoints, pointMap); } // Remove any unused vertices surf = triSurface(surf.localFaces(), surf.patches(), surf.localPoints()); return nTotalCollapsed; } // ************************************************************************* //
void Foam::cyclicGgiPolyPatch::calcTransforms() const { if (active() && debug) { // Check definition of the cyclic pair checkDefinition(); } // For computing the rotation tensors forwardT and reverseT, we // can see from Robert Magnan's post on the Forum dated // 27/May/2008 that we cannot use the actual implementation of // calcTransformTensors and rotationTensor. // // It is also not possible to use Robert solution because for // non-conformal cyclic meshes, we cannot usualy find a pair of // matching faces for computing the tensors. So we are using // user-supplied values instead. // // Since these tensors are defined as private in the // coupledPolyPatch class definition, we will override these // values here and compute the tensors ourselves using the // Rodrigues Rotation formula. // We compute the rotationTensor from rotationAxis_ and // rotationAngle_ We compute the separation vector from // separationOffset_ // All transforms are constant: size = 1. HJ, 18/Feb/2009 if (mag(rotationAngle_) > SMALL) { // Rotation tensor computed from rotationAxis_ and rotationAngle_ // Note: cyclics already have opposing signs for the rotation // so there is no need for a special practice. HJ, 30/Jun/2009 forwardT_ = tensorField ( 1, RodriguesRotation(rotationAxis_, -rotationAngle_) ); reverseT_ = tensorField ( 1, RodriguesRotation(rotationAxis_, rotationAngle_) ); } else { forwardT_.setSize(0); reverseT_.setSize(0); } // Handling the separation offset separatly if (mag(separationOffset_) > SMALL) { separation_ = vectorField(1, separationOffset_); } else { separation_.setSize(0); } if (debug > 1 && master()) { if (patchToPatch().uncoveredMasterFaces().size() > 0) { // Write uncovered master faces Info<< "Writing uncovered master faces for patch " << name() << " as VTK." << endl; const polyMesh& mesh = boundaryMesh().mesh(); fileName fvPath(mesh.time().path()/"VTK"); mkDir(fvPath); indirectPrimitivePatch::writeVTK ( fvPath/fileName("uncoveredCyclicGgiFaces" + name()), IndirectList<face> ( localFaces(), patchToPatch().uncoveredMasterFaces() ), localPoints() ); } if (patchToPatch().uncoveredSlaveFaces().size() > 0) { // Write uncovered master faces Info<< "Writing uncovered shadow faces for patch " << shadowName() << " as VTK." << endl; const polyMesh& mesh = boundaryMesh().mesh(); fileName fvPath(mesh.time().path()/"VTK"); mkDir(fvPath); indirectPrimitivePatch::writeVTK ( fvPath/fileName("uncoveredCyclicGgiFaces" + shadowName()), IndirectList<face> ( shadow().localFaces(), patchToPatch().uncoveredSlaveFaces() ), shadow().localPoints() ); } // Check for bridge overlap if (!bridgeOverlap()) { if ( patchToPatch().uncoveredMasterFaces().size() > 0 || patchToPatch().uncoveredSlaveFaces().size() > 0 ) { FatalErrorIn("label cyclicGgiPolyPatch::shadowIndex() const") << "cyclic ggi patch " << name() << " with shadow " << shadowName() << " has " << patchToPatch().uncoveredMasterFaces().size() << " uncovered master faces and " << patchToPatch().uncoveredSlaveFaces().size() << " uncovered slave faces. Bridging is switched off. " << abort(FatalError); } } } }