//static int matchCounter = 0; bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex) { if (rclFacet.IsFlag(MeshFacet::MARKED) && rclFrom.IsFlag(MeshFacet::MARKED)) { // facet connected to an edge unsigned long pt0 = rclFrom._aulPoints[neighbourIndex], pt1 = rclFrom._aulPoints[(neighbourIndex+1)%3]; Edge edge(_mesh.GetPoint(pt0), _mesh.GetPoint(pt1)); std::map<Edge, EdgeInfo>::iterator it = _edges.find(edge); if (it != _edges.end()) { if (_addFacets == -1) { // detemine if the facets shoud add or not only once MeshGeomFacet facet = _mesh.GetFacet(rclFrom); // triangulated facet MeshGeomFacet facetOther = it->second.facets[1-_side][0]; // triangulated facet from same edge and other mesh Vector3f normalOther = facetOther.GetNormal(); //Vector3f normal = facet.GetNormal(); Vector3f edgeDir = it->first.pt1 - it->first.pt2; Vector3f ocDir = (edgeDir % (facet.GetGravityPoint() - it->first.pt1)) % edgeDir; ocDir.Normalize(); Vector3f ocDirOther = (edgeDir % (facetOther.GetGravityPoint() - it->first.pt1)) % edgeDir; ocDirOther.Normalize(); //Vector3f dir = ocDir % normal; //Vector3f dirOther = ocDirOther % normalOther; bool match = ((ocDir * normalOther) * _mult) < 0.0f; //if (matchCounter == 1) //{ // // _builder.addSingleArrow(it->second.pt1, it->second.pt1 + edgeDir, 3, 0.0, 1.0, 0.0); // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3.0, 1.0, 0.0, 0.0); // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + ocDir, 3, 1.0, 0.0, 0.0); // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + normal, 3, 1.0, 0.5, 0.0); // // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dir, 3, 1.0, 1.0, 0.0); // _builder.addSingleTriangle(facetOther._aclPoints[0], facetOther._aclPoints[1], facetOther._aclPoints[2], true, 3.0, 0.0, 0.0, 1.0); // // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + ocDirOther, 3, 0.0, 0.0, 1.0); // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + normalOther, 3, 0.0, 0.5, 1.0); // // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirOther, 3, 0.0, 1.0, 1.0); //} // float scalar = dir * dirOther * _mult; // bool match = scalar > 0.0f; //MeshPoint pt0 = it->first.pt1; //MeshPoint pt1 = it->first.pt2; //int i, n0 = -1, n1 = -1, m0 = -1, m1 = -1; //for (i = 0; i < 3; i++) //{ // if ((n0 == -1) && (facet._aclPoints[i] == pt0)) // n0 = i; // if ((n1 == -1) && (facet._aclPoints[i] == pt1)) // n1 = i; // if ((m0 == -1) && (facetOther._aclPoints[i] == pt0)) // m0 = i; // if ((m1 == -1) && (facetOther._aclPoints[i] == pt1)) // m1 = i; //} //if ((n0 != -1) && (n1 != -1) && (m0 != -1) && (m1 != -1)) //{ // bool orient_n = n1 > n0; // bool orient_m = m1 > m0; // Vector3f dirN = facet._aclPoints[n1] - facet._aclPoints[n0]; // Vector3f dirM = facetOther._aclPoints[m1] - facetOther._aclPoints[m0]; // if (matchCounter == 1) // { // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dirN, 3, 1.0, 1.0, 0.0); // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirM, 3, 0.0, 1.0, 1.0); // } // if (_mult > 0.0) // match = orient_n == orient_m; // else // match = orient_n != orient_m; //} if (match) _addFacets = 0; else _addFacets = 1; //matchCounter++; } return false; } } return true; }
CurvatureInfo FacetCurvature::Compute(unsigned long index) const { Base::Vector3f rkDir0, rkDir1, rkPnt; Base::Vector3f rkNormal; MeshGeomFacet face = myKernel.GetFacet(index); Base::Vector3f face_gravity = face.GetGravityPoint(); Base::Vector3f face_normal = face.GetNormal(); std::set<unsigned long> point_indices; FitPointCollector collect(point_indices); float searchDist = myRadius; int attempts=0; do { mySearch.Neighbours(index, searchDist, collect); if (point_indices.empty()) break; float min_points = myMinPoints; float use_points = point_indices.size(); searchDist = searchDist * sqrt(min_points/use_points); } while((point_indices.size() < myMinPoints) && (attempts++ < 3)); std::vector<Base::Vector3f> fitPoints; const MeshPointArray& verts = myKernel.GetPoints(); fitPoints.reserve(point_indices.size()); for (std::set<unsigned long>::iterator it = point_indices.begin(); it != point_indices.end(); ++it) { fitPoints.push_back(verts[*it] - face_gravity); } float fMin, fMax; if (fitPoints.size() >= myMinPoints) { SurfaceFit surf_fit; surf_fit.AddPoints(fitPoints); surf_fit.Fit(); rkNormal = surf_fit.GetNormal(); double dMin, dMax, dDistance; if (surf_fit.GetCurvatureInfo(0.0, 0.0, 0.0, dMin, dMax, rkDir1, rkDir0, dDistance)) { fMin = (float)dMin; fMax = (float)dMax; } else { fMin = FLT_MAX; fMax = FLT_MAX; } } else { // too few points => cannot calc any properties fMin = FLT_MAX; fMax = FLT_MAX; } CurvatureInfo info; if (fMin < fMax) { info.fMaxCurvature = fMax; info.fMinCurvature = fMin; info.cMaxCurvDir = rkDir1; info.cMinCurvDir = rkDir0; } else { info.fMaxCurvature = fMin; info.fMinCurvature = fMax; info.cMaxCurvDir = rkDir0; info.cMinCurvDir = rkDir1; } // Reverse the direction of the normal vector if required // (Z component of "local" normal vectors should be opposite in sign to the "local" view vector) if (rkNormal * face_normal < 0.0) { // Note: Changing the normal directions is similar to flipping over the object. // In this case we must adjust the curvature information as well. std::swap(info.cMaxCurvDir,info.cMinCurvDir); std::swap(info.fMaxCurvature,info.fMinCurvature); info.fMaxCurvature *= (-1.0); info.fMinCurvature *= (-1.0); } return info; }