Foam::vector Foam::featurePointConformer::sharedFaceNormal ( const extendedFeatureEdgeMesh& feMesh, const label edgeI, const label nextEdgeI ) const { const labelList& edgeInormals = feMesh.edgeNormals()[edgeI]; const labelList& nextEdgeInormals = feMesh.edgeNormals()[nextEdgeI]; const vector& A1 = feMesh.normals()[edgeInormals[0]]; const vector& A2 = feMesh.normals()[edgeInormals[1]]; const vector& B1 = feMesh.normals()[nextEdgeInormals[0]]; const vector& B2 = feMesh.normals()[nextEdgeInormals[1]]; // Info<< " A1 = " << A1 << endl; // Info<< " A2 = " << A2 << endl; // Info<< " B1 = " << B1 << endl; // Info<< " B2 = " << B2 << endl; const scalar A1B1 = mag((A1 & B1) - 1.0); const scalar A1B2 = mag((A1 & B2) - 1.0); const scalar A2B1 = mag((A2 & B1) - 1.0); const scalar A2B2 = mag((A2 & B2) - 1.0); // Info<< " A1B1 = " << A1B1 << endl; // Info<< " A1B2 = " << A1B2 << endl; // Info<< " A2B1 = " << A2B1 << endl; // Info<< " A2B2 = " << A2B2 << endl; if (A1B1 < A1B2 && A1B1 < A2B1 && A1B1 < A2B2) { return 0.5*(A1 + B1); } else if (A1B2 < A1B1 && A1B2 < A2B1 && A1B2 < A2B2) { return 0.5*(A1 + B2); } else if (A2B1 < A1B1 && A2B1 < A1B2 && A2B1 < A2B2) { return 0.5*(A2 + B1); } else { return 0.5*(A2 + B2); } }
bool Foam::featurePointConformer::createSpecialisedFeaturePoint ( const extendedFeatureEdgeMesh& feMesh, const labelList& pEds, const pointFeatureEdgesTypes& pFEdgesTypes, const List<extendedFeatureEdgeMesh::edgeStatus>& allEdStat, const label ptI, DynamicList<Vb>& pts ) const { if ( !pFEdgesTypes.found(extendedFeatureEdgeMesh::EXTERNAL) || !pFEdgesTypes.found(extendedFeatureEdgeMesh::INTERNAL) ) { return false; } if ( pFEdgesTypes[extendedFeatureEdgeMesh::EXTERNAL] == 2 && pFEdgesTypes[extendedFeatureEdgeMesh::INTERNAL] == 1 && pEds.size() == 3 ) { if (debug) Info<< "nExternal == 2 && nInternal == 1" << endl; const Foam::point& featPt = feMesh.points()[ptI]; if ( Pstream::parRun() && !foamyHexMesh_.decomposition().positionOnThisProcessor(featPt) ) { return false; } label nVert = foamyHexMesh_.number_of_vertices(); const label initialNumOfPoints = pts.size(); const scalar ppDist = foamyHexMesh_.pointPairDistance(featPt); const vectorField& normals = feMesh.normals(); const labelListList& edgeNormals = feMesh.edgeNormals(); label concaveEdgeI = -1; labelList convexEdgesI(2, label(-1)); label nConvex = 0; forAll(pEds, i) { const extendedFeatureEdgeMesh::edgeStatus& eS = allEdStat[i]; if (eS == extendedFeatureEdgeMesh::INTERNAL) { concaveEdgeI = pEds[i]; } else if (eS == extendedFeatureEdgeMesh::EXTERNAL) { convexEdgesI[nConvex++] = pEds[i]; } else if (eS == extendedFeatureEdgeMesh::FLAT) { WarningIn("Foam::conformalVoronoiMesh::" "createSpecialisedFeaturePoint") << "Edge " << eS << " is flat" << endl; } else { FatalErrorIn("Foam::conformalVoronoiMesh::" "createSpecialisedFeaturePoint") << "Edge " << eS << " not concave/convex" << exit(FatalError); } } const vector& concaveEdgePlaneANormal = normals[edgeNormals[concaveEdgeI][0]]; const vector& concaveEdgePlaneBNormal = normals[edgeNormals[concaveEdgeI][1]]; // Intersect planes parallel to the concave edge planes offset // by ppDist and the plane defined by featPt and the edge vector. plane planeA ( featPt + ppDist*concaveEdgePlaneANormal, concaveEdgePlaneANormal ); plane planeB ( featPt + ppDist*concaveEdgePlaneBNormal, concaveEdgePlaneBNormal ); const vector& concaveEdgeDir = feMesh.edgeDirection ( concaveEdgeI, ptI ); // Todo,needed later but want to get rid of this. const Foam::point concaveEdgeLocalFeatPt = featPt + ppDist*concaveEdgeDir; // Finding the nearest point on the intersecting line to the edge // point. Floating point errors often occur using planePlaneIntersect plane planeF(concaveEdgeLocalFeatPt, concaveEdgeDir); const Foam::point concaveEdgeExternalPt = planeF.planePlaneIntersect ( planeA, planeB ); // Redefine planes to be on the feature surfaces to project through planeA = plane(featPt, concaveEdgePlaneANormal); planeB = plane(featPt, concaveEdgePlaneBNormal); const Foam::point internalPtA = concaveEdgeExternalPt - 2.0*planeA.distance(concaveEdgeExternalPt) *concaveEdgePlaneANormal; pts.append ( Vb ( internalPtA, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtInternalFeaturePoint, Pstream::myProcNo() ) ); const label internalPtAIndex(pts.last().index()); const Foam::point internalPtB = concaveEdgeExternalPt - 2.0*planeB.distance(concaveEdgeExternalPt) *concaveEdgePlaneBNormal; pts.append ( Vb ( internalPtB, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtInternalFeaturePoint, Pstream::myProcNo() ) ); const label internalPtBIndex(pts.last().index()); // Add the external points Foam::point externalPtD; Foam::point externalPtE; vector convexEdgePlaneCNormal(vector::zero); vector convexEdgePlaneDNormal(vector::zero); const labelList& concaveEdgeNormals = edgeNormals[concaveEdgeI]; const labelList& convexEdgeANormals = edgeNormals[convexEdgesI[0]]; const labelList& convexEdgeBNormals = edgeNormals[convexEdgesI[1]]; forAll(concaveEdgeNormals, edgeNormalI) { bool convexEdgeA = false; bool convexEdgeB = false; forAll(convexEdgeANormals, edgeAnormalI) { const vector& concaveNormal = normals[concaveEdgeNormals[edgeNormalI]]; const vector& convexNormal = normals[convexEdgeANormals[edgeAnormalI]]; if (debug) { Info<< "Angle between vectors = " << degAngleBetween(concaveNormal, convexNormal) << endl; } // Need a looser tolerance, because sometimes adjacent triangles // on the same surface will be slightly out of alignment. if (areParallel(concaveNormal, convexNormal, tolParallel)) { convexEdgeA = true; } } forAll(convexEdgeBNormals, edgeBnormalI) { const vector& concaveNormal = normals[concaveEdgeNormals[edgeNormalI]]; const vector& convexNormal = normals[convexEdgeBNormals[edgeBnormalI]]; if (debug) { Info<< "Angle between vectors = " << degAngleBetween(concaveNormal, convexNormal) << endl; } // Need a looser tolerance, because sometimes adjacent triangles // on the same surface will be slightly out of alignment. if (areParallel(concaveNormal, convexNormal, tolParallel)) { convexEdgeB = true; } } if ((convexEdgeA && convexEdgeB) || (!convexEdgeA && !convexEdgeB)) { WarningIn ( "Foam::conformalVoronoiMesh" "::createSpecialisedFeaturePoint" ) << "Both or neither of the convex edges share the concave " << "edge's normal." << " convexEdgeA = " << convexEdgeA << " convexEdgeB = " << convexEdgeB << endl; // Remove points that have just been added before returning for (label i = 0; i < 2; ++i) { pts.remove(); nVert--; } return false; } if (convexEdgeA) { forAll(convexEdgeANormals, edgeAnormalI) { const vector& concaveNormal = normals[concaveEdgeNormals[edgeNormalI]]; const vector& convexNormal = normals[convexEdgeANormals[edgeAnormalI]]; if ( !areParallel(concaveNormal, convexNormal, tolParallel) ) { convexEdgePlaneCNormal = convexNormal; plane planeC(featPt, convexEdgePlaneCNormal); externalPtD = internalPtA + 2.0*planeC.distance(internalPtA) *convexEdgePlaneCNormal; pts.append ( Vb ( externalPtD, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtExternalFeaturePoint, Pstream::myProcNo() ) ); ftPtPairs_.addPointPair ( internalPtAIndex, pts.last().index() ); } } } if (convexEdgeB) { forAll(convexEdgeBNormals, edgeBnormalI) { const vector& concaveNormal = normals[concaveEdgeNormals[edgeNormalI]]; const vector& convexNormal = normals[convexEdgeBNormals[edgeBnormalI]]; if ( !areParallel(concaveNormal, convexNormal, tolParallel) ) { convexEdgePlaneDNormal = convexNormal; plane planeD(featPt, convexEdgePlaneDNormal); externalPtE = internalPtB + 2.0*planeD.distance(internalPtB) *convexEdgePlaneDNormal; pts.append ( Vb ( externalPtE, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtExternalFeaturePoint, Pstream::myProcNo() ) ); ftPtPairs_.addPointPair ( internalPtBIndex, pts.last().index() ); } } } } pts.append ( Vb ( concaveEdgeExternalPt, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtExternalFeaturePoint, Pstream::myProcNo() ) ); ftPtPairs_.addPointPair ( internalPtBIndex, pts.last().index() ); ftPtPairs_.addPointPair ( internalPtAIndex, pts.last().index() ); const label concaveEdgeExternalPtIndex(pts.last().index()); const scalar totalAngle = radToDeg ( constant::mathematical::pi + radAngleBetween(concaveEdgePlaneANormal, concaveEdgePlaneBNormal) ); if (totalAngle > foamyHexMeshControls_.maxQuadAngle()) { // Add additional mitreing points //scalar angleSign = 1.0; vector convexEdgesPlaneNormal = 0.5*(convexEdgePlaneCNormal + convexEdgePlaneDNormal); plane planeM(featPt, convexEdgesPlaneNormal); // if // ( // geometryToConformTo_.outside // ( // featPt - convexEdgesPlaneNormal*ppDist // ) // ) // { // angleSign = -1.0; // } // scalar phi = // angleSign*acos(concaveEdgeDir & -convexEdgesPlaneNormal); // // scalar guard = // ( // 1.0 + sin(phi)*ppDist/mag // ( // concaveEdgeLocalFeatPt - concaveEdgeExternalPt // ) // )/cos(phi) - 1.0; const Foam::point internalPtF = concaveEdgeExternalPt //+ (2.0 + guard)*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt); + 2.0*(concaveEdgeLocalFeatPt - concaveEdgeExternalPt); pts.append ( Vb ( internalPtF, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtInternalFeaturePoint, Pstream::myProcNo() ) ); const label internalPtFIndex(pts.last().index()); ftPtPairs_.addPointPair ( concaveEdgeExternalPtIndex, pts.last().index() ); const Foam::point externalPtG = internalPtF + 2.0*planeM.distance(internalPtF)*convexEdgesPlaneNormal; pts.append ( Vb ( externalPtG, foamyHexMesh_.vertexCount() + pts.size(), Vb::vtExternalFeaturePoint, Pstream::myProcNo() ) ); ftPtPairs_.addPointPair ( internalPtFIndex, pts.last().index() ); } if (debug) { for (label ptI = initialNumOfPoints; ptI < pts.size(); ++ptI) { Info<< "Point " << ptI << " : "; meshTools::writeOBJ(Info, topoint(pts[ptI].point())); } } return true; }