bool MeshEvalDentsOnSurface::Evaluate() { this->indices.clear(); MeshRefPointToFacets clPt2Facets(_rclMesh); const MeshPointArray& rPntAry = _rclMesh.GetPoints(); MeshFacetArray::_TConstIterator f_beg = _rclMesh.GetFacets().begin(); MeshGeomFacet rTriangle; Base::Vector3f tmp; unsigned long ctPoints = _rclMesh.CountPoints(); for (unsigned long index=0; index < ctPoints; index++) { std::vector<unsigned long> point; point.push_back(index); // get the local neighbourhood of the point std::set<unsigned long> nb = clPt2Facets.NeighbourPoints(point,1); const std::set<unsigned long>& faces = clPt2Facets[index]; for (std::set<unsigned long>::iterator pt = nb.begin(); pt != nb.end(); ++pt) { const MeshPoint& mp = rPntAry[*pt]; for (std::set<unsigned long>::const_iterator ft = faces.begin(); ft != faces.end(); ++ft) { // the point must not be part of the facet we test if (f_beg[*ft]._aulPoints[0] == *pt) continue; if (f_beg[*ft]._aulPoints[1] == *pt) continue; if (f_beg[*ft]._aulPoints[2] == *pt) continue; // is the point projectable onto the facet? rTriangle = _rclMesh.GetFacet(f_beg[*ft]); if (rTriangle.IntersectWithLine(mp,rTriangle.GetNormal(),tmp)) { const std::set<unsigned long>& f = clPt2Facets[*pt]; this->indices.insert(this->indices.end(), f.begin(), f.end()); break; } } } } // remove duplicates std::sort(this->indices.begin(), this->indices.end()); this->indices.erase(std::unique(this->indices.begin(), this->indices.end()), this->indices.end()); return this->indices.empty(); }
void MeshBuilder::AddFacet (const MeshGeomFacet& facet, bool takeFlag, bool takeProperty) { unsigned char flag = 0; unsigned long prop = 0; if (takeFlag) flag = facet._ucFlag; if (takeProperty) prop = facet._ulProp; AddFacet(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], facet.GetNormal(), flag, prop); }
void MeshKernel::AddFacet(const MeshGeomFacet &rclSFacet) { unsigned long i; MeshFacet clFacet; // set corner points for (i = 0; i < 3; i++) { _clBoundBox.Add(rclSFacet._aclPoints[i]); clFacet._aulPoints[i] = _aclPointArray.GetOrAddIndex(rclSFacet._aclPoints[i]); } // adjust orientation to normal AdjustNormal(clFacet, rclSFacet.GetNormal()); unsigned long ulCt = _aclFacetArray.size(); // set neighbourhood unsigned long ulP0 = clFacet._aulPoints[0]; unsigned long ulP1 = clFacet._aulPoints[1]; unsigned long ulP2 = clFacet._aulPoints[2]; unsigned long ulCC = 0; for (TMeshFacetArray::iterator pF = _aclFacetArray.begin(); pF != _aclFacetArray.end(); ++pF, ulCC++) { for (int i=0; i<3;i++) { unsigned long ulP = pF->_aulPoints[i]; unsigned long ulQ = pF->_aulPoints[(i+1)%3]; if (ulQ == ulP0 && ulP == ulP1) { clFacet._aulNeighbours[0] = ulCC; pF->_aulNeighbours[i] = ulCt; } else if (ulQ == ulP1 && ulP == ulP2) { clFacet._aulNeighbours[1] = ulCC; pF->_aulNeighbours[i] = ulCt; } else if (ulQ == ulP2 && ulP == ulP0) { clFacet._aulNeighbours[2] = ulCC; pF->_aulNeighbours[i] = ulCt; } } } // insert facet into array _aclFacetArray.push_back(clFacet); }
bool MeshTrimming::CreateFacets(unsigned long ulFacetPos, int iSide, const std::vector<Base::Vector3f>& raclPoints, std::vector<MeshGeomFacet>& aclNewFacets) { MeshGeomFacet clFac; // no valid triangulation possible if (iSide == -1) return false; // two points found if (raclPoints.size() == 2) { MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos]; AdjustFacet(facet, iSide); Base::Vector3f clP1(raclPoints[0]), clP2(raclPoints[1]); if (iSide == 1) { // swap P1 and P2 clP1 = raclPoints[1]; clP2 = raclPoints[0]; } // check which facets can be inserted int iCtPts=0; Base::Vector3f clFacPnt; Base::Vector2D clProjPnt; for (int i=0; i<3; i++) { clFacPnt = (*myProj)(myMesh._aclPointArray[facet._aulPoints[i]]); clProjPnt = Base::Vector2D(clFacPnt.x, clFacPnt.y); if (myPoly.Contains(clProjPnt) == myInner) ++iCtPts; } if (iCtPts == 2) { // erstes Dreieck clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = myMesh._aclPointArray[facet._aulPoints[2]]; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); } else if (iCtPts == 1) { // erstes Dreieck clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[0]]; clFac._aclPoints[1] = myMesh._aclPointArray[facet._aulPoints[1]]; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); // zweites Dreieck clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[1]]; clFac._aclPoints[1] = clP1; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); } else return false; } // four points found else if (raclPoints.size() == 4) { MeshFacet& facet = myMesh._aclFacetArray[ulFacetPos]; AdjustFacet(facet, iSide); MeshFacet clOrg(myMesh._aclFacetArray[ulFacetPos]); clFac = myMesh.GetFacet(ulFacetPos); // intersection points Base::Vector3f clP1(raclPoints[0]), clP2(raclPoints[1]), clP3(raclPoints[2]), clP4(raclPoints[3]); // check which facets can be inserted int iCtPts=0; Base::Vector3f clFacPnt; Base::Vector2D clProjPnt; for (int i=0; i<3; i++) { clFacPnt = (*myProj)(myMesh._aclPointArray[facet._aulPoints[i]]); clProjPnt = Base::Vector2D(clFacPnt.x, clFacPnt.y); if (myPoly.Contains(clProjPnt) == myInner) ++iCtPts; } // sort the intersection points in a certain order if (iCtPts == 0 || iCtPts == 3) { if (iSide == 1) { // swap the points clP1 = clP2; clP2 = raclPoints[0]; clP3 = clP4; clP4 = raclPoints[2]; } if ((clP1-clFac._aclPoints[1]).Length() > (clP3-clFac._aclPoints[1]).Length()) { // swap P1 and P3 Base::Vector3f tmp(clP1); clP1 = clP3; clP3 = tmp; } if ((clP2-clFac._aclPoints[0]).Length() > (clP4-clFac._aclPoints[0]).Length()) { // swap P2 and P4 Base::Vector3f tmp(clP2); clP2 = clP4; clP4 = tmp; } } else { if (iSide == 0) { Base::Vector3f clNormal(clFac.GetNormal()); MeshGeomFacet clTmpFac; clTmpFac._aclPoints[0] = clFac._aclPoints[1]; clTmpFac._aclPoints[1] = clP2; clTmpFac._aclPoints[2] = clP1; if (clTmpFac.GetNormal() * clNormal > 0) { Base::Vector3f tmp(clP1); clP1 = clP2; clP2 = tmp; } else { Base::Vector3f tmp(clP1); clP1 = clP4; clP4 = clP2; clP2 = clP3; clP3 = tmp; } } else if (iSide == 1) { if ((clP2-clFac._aclPoints[1]).Length() > (clP4-clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP4; clP4 = tmp; tmp = clP2; clP2 = clP3; clP3 = tmp; } else { Base::Vector3f tmp(clP1); clP1 = clP2; clP2 = tmp; tmp = clP3; clP3 = clP4; clP4 = tmp; } } else { if ((clP1-clFac._aclPoints[1]).Length() > (clP3-clFac._aclPoints[1]).Length()) { Base::Vector3f tmp(clP1); clP1 = clP3; clP3 = tmp; tmp = clP2; clP2 = clP4; clP4 = tmp; } } } // now create the new facets if (iCtPts == 0) { // insert first facet clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[0]]; clFac._aclPoints[1] = myMesh._aclPointArray[facet._aulPoints[1]]; clFac._aclPoints[2] = clP1; aclNewFacets.push_back(clFac); // insert second facet clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[0]]; clFac._aclPoints[1] = clP1; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); // finally insert third facet clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[2]]; clFac._aclPoints[1] = clP4; clFac._aclPoints[2] = clP3; aclNewFacets.push_back(clFac); } else if (iCtPts == 1) { // insert first facet clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = clP2; clFac._aclPoints[2] = myMesh._aclPointArray[facet._aulPoints[1]]; aclNewFacets.push_back(clFac); // finally insert second facet clFac._aclPoints[0] = clP4; clFac._aclPoints[1] = clP3; clFac._aclPoints[2] = myMesh._aclPointArray[facet._aulPoints[2]]; aclNewFacets.push_back(clFac); } else if (iCtPts == 2) { // insert first facet clFac._aclPoints[0] = myMesh._aclPointArray[facet._aulPoints[0]]; clFac._aclPoints[1] = clP2; clFac._aclPoints[2] = clP4; aclNewFacets.push_back(clFac); // insert second facet clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = clP4; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); // finally insert third facet clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = clP3; clFac._aclPoints[2] = clP4; aclNewFacets.push_back(clFac); } else { // insert first facet clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = clP3; clFac._aclPoints[2] = clP4; aclNewFacets.push_back(clFac); // finally insert second facet clFac._aclPoints[0] = clP1; clFac._aclPoints[1] = clP4; clFac._aclPoints[2] = clP2; aclNewFacets.push_back(clFac); } } else return false; return true; }
//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; }
void SetOperations::TriangulateMesh (const MeshKernel &cutMesh, int side) { // Triangulate Mesh std::map<unsigned long, std::list<std::set<MeshPoint>::iterator> >::iterator it1; for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); it1++) { std::vector<Vector3f> points; std::set<MeshPoint> pointsSet; unsigned long fidx = it1->first; MeshGeomFacet f = cutMesh.GetFacet(fidx); //if (side == 1) // _builder.addSingleTriangle(f._aclPoints[0], f._aclPoints[1], f._aclPoints[2], 3, 0, 1, 1); // facet corner points //const MeshFacet& mf = cutMesh._aclFacetArray[fidx]; int i; for (i = 0; i < 3; i++) { pointsSet.insert(f._aclPoints[i]); points.push_back(f._aclPoints[i]); } // triangulated facets std::list<std::set<MeshPoint>::iterator>::iterator it2; for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++) { if (pointsSet.find(*(*it2)) == pointsSet.end()) { pointsSet.insert(*(*it2)); points.push_back(*(*it2)); } } Vector3f normal = f.GetNormal(); Vector3f base = points[0]; Vector3f dirX = points[1] - points[0]; dirX.Normalize(); Vector3f dirY = dirX % normal; // project points to 2D plane i = 0; std::vector<Vector3f>::iterator it; std::vector<Vector3f> vertices; for (it = points.begin(); it != points.end(); it++) { Vector3f pv = *it; pv.TransformToCoordinateSystem(base, dirX, dirY); vertices.push_back(pv); } DelaunayTriangulator tria; tria.SetPolygon(vertices); tria.TriangulatePolygon(); std::vector<MeshFacet> facets = tria.GetFacets(); for (std::vector<MeshFacet>::iterator it = facets.begin(); it != facets.end(); ++it) { if ((it->_aulPoints[0] == it->_aulPoints[1]) || (it->_aulPoints[1] == it->_aulPoints[2]) || (it->_aulPoints[2] == it->_aulPoints[0])) { // two same triangle corner points continue; } MeshGeomFacet facet(points[it->_aulPoints[0]], points[it->_aulPoints[1]], points[it->_aulPoints[2]]); //if (side == 1) // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1); //if (facet.Area() < 0.0001f) //{ // too small facet // continue; //} float dist0 = facet._aclPoints[0].DistanceToLine (facet._aclPoints[1],facet._aclPoints[1] - facet._aclPoints[2]); float dist1 = facet._aclPoints[1].DistanceToLine (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[2]); float dist2 = facet._aclPoints[2].DistanceToLine (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[1]); if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) || (dist2 < _minDistanceToPoint)) { continue; } //dist0 = (facet._aclPoints[0] - facet._aclPoints[1]).Length(); //dist1 = (facet._aclPoints[1] - facet._aclPoints[2]).Length(); //dist2 = (facet._aclPoints[2] - facet._aclPoints[3]).Length(); //if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) || (dist2 < _minDistanceToPoint)) //{ // continue; //} facet.CalcNormal(); if ((facet.GetNormal() * f.GetNormal()) < 0.0f) { // adjust normal std::swap(facet._aclPoints[0], facet._aclPoints[1]); facet.CalcNormal(); } int j; for (j = 0; j < 3; j++) { std::map<Edge, EdgeInfo>::iterator eit = _edges.find(Edge(facet._aclPoints[j], facet._aclPoints[(j+1)%3])); if (eit != _edges.end()) { if (eit->second.fcounter[side] < 2) { //if (side == 0) // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1); eit->second.facet[side] = fidx; eit->second.facets[side][eit->second.fcounter[side]] = facet; eit->second.fcounter[side]++; facet.SetFlag(MeshFacet::MARKED); // set all facets connected to an edge: MARKED } } } _newMeshFacets[side].push_back(facet); } // for (i = 0; i < (out->numberoftriangles * 3); i += 3) } // for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); it1++) }
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; }
bool MeshProjection::projectLineOnMesh(const MeshFacetGrid& grid, const Base::Vector3f& v1, unsigned long f1, const Base::Vector3f& v2, unsigned long f2, const Base::Vector3f& vd, std::vector<Base::Vector3f>& polyline) { Base::Vector3f dir(v2 - v1); Base::Vector3f base(v1), normal(vd % dir); normal.Normalize(); dir.Normalize(); std::vector<unsigned long> facets; // special case: start and endpoint inside same facet if (f1 == f2) { polyline.push_back(v1); polyline.push_back(v2); return true; } // cut all facets between the two endpoints MeshGridIterator gridIter(grid); for (gridIter.Init(); gridIter.More(); gridIter.Next()) { // bbox cuts plane if (bboxInsideRectangle(gridIter.GetBoundBox(), v1, v2, vd)) gridIter.GetElements(facets); } std::sort(facets.begin(), facets.end()); facets.erase(std::unique(facets.begin(), facets.end()), facets.end()); // cut all facets with plane std::list< std::pair<Base::Vector3f, Base::Vector3f> > cutLine; //unsigned long start = 0, end = 0; for (std::vector<unsigned long>::iterator it = facets.begin(); it != facets.end(); ++it) { Base::Vector3f e1, e2; MeshGeomFacet tria = kernel.GetFacet(*it); if (bboxInsideRectangle(tria.GetBoundBox(), v1, v2, vd)) { if (tria.IntersectWithPlane(base, normal, e1, e2)) { if ((*it != f1) && (*it != f2)) { // inside cut line if ((isPointInsideDistance(v1, v2, e1) == false) || (isPointInsideDistance(v1, v2, e2) == false)) { continue; } cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(e1, e2)); } else { if (*it == f1) { // start facet if (((e2 - v1) * dir) > 0.0f) cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e2)); else cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v1, e1)); //start = it - facets.begin(); } if (*it == f2) { // end facet if (((e2 - v2) * -dir) > 0.0f) cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e2)); else cutLine.push_back(std::pair<Base::Vector3f, Base::Vector3f>(v2, e1)); //end = it - facets.begin(); } } } } } return connectLines(cutLine, v1, v2, polyline); }
void CurveProjectorShape::projectCurve( const TopoDS_Edge& aEdge, std::vector<FaceSplitEdge> &vSplitEdges) { Standard_Real fFirst, fLast; Handle(Geom_Curve) hCurve = BRep_Tool::Curve( aEdge,fFirst,fLast ); // getting start point gp_Pnt gpPt = hCurve->Value(fFirst); // projection of the first point Base::Vector3f cStartPoint = Base::Vector3f((float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z()); Base::Vector3f cResultPoint, cSplitPoint, cPlanePnt, cPlaneNormal; unsigned long uStartFacetIdx,uCurFacetIdx; unsigned long uLastFacetIdx=ULONG_MAX-1; // use another value as ULONG_MAX unsigned long auNeighboursIdx[3]; bool GoOn; if( !findStartPoint(_Mesh,cStartPoint,cResultPoint,uStartFacetIdx) ) return; uCurFacetIdx = uStartFacetIdx; do{ MeshGeomFacet cCurFacet= _Mesh.GetFacet(uCurFacetIdx); _Mesh.GetFacetNeighbours ( uCurFacetIdx, auNeighboursIdx[0], auNeighboursIdx[1], auNeighboursIdx[2]); Base::Vector3f PointOnEdge[3]; GoOn = false; int NbrOfHits = 0,HitIdx=0; for(int i=0; i<3; i++) { // ignore last visited facet if ( auNeighboursIdx[i] == uLastFacetIdx ) continue; // get points of the edge i const Base::Vector3f& cP0 = cCurFacet._aclPoints[i]; const Base::Vector3f& cP1 = cCurFacet._aclPoints[(i+1)%3]; if ( auNeighboursIdx[i] != ULONG_MAX ) { // calculate the normal by the edge vector and the middle between the two face normals MeshGeomFacet N = _Mesh.GetFacet( auNeighboursIdx[i] ); cPlaneNormal = ( N.GetNormal() + cCurFacet.GetNormal() ) % ( cP1 - cP0 ); cPlanePnt = cP0; }else{ // with no neighbours the face normal is used cPlaneNormal = cCurFacet.GetNormal() % ( cP1 - cP0 ); cPlanePnt = cP0; } Handle(Geom_Plane) hPlane = new Geom_Plane(gp_Pln(gp_Pnt(cPlanePnt.x,cPlanePnt.y,cPlanePnt.z), gp_Dir(cPlaneNormal.x,cPlaneNormal.y,cPlaneNormal.z))); GeomAPI_IntCS Alg(hCurve,hPlane); if ( Alg.IsDone() ) { // deciding by the number of result points (intersections) if( Alg.NbPoints() == 1) { gp_Pnt P = Alg.Point(1); float l = ((Base::Vector3f((float)P.X(),(float)P.Y(),(float)P.Z()) - cP0) * (cP1 - cP0) ) / ((cP1 - cP0) * (cP1 - cP0)); // is the Point on the Edge of the facet? if(l<0.0 || l>1.0) PointOnEdge[i] = Base::Vector3f(FLOAT_MAX,0,0); else{ cSplitPoint = (1-l) * cP0 + l * cP1; PointOnEdge[i] = (1-l)*cP0 + l * cP1; NbrOfHits ++; HitIdx = i; } // no intersection }else if(Alg.NbPoints() == 0){ PointOnEdge[i] = Base::Vector3f(FLOAT_MAX,0,0); // more the one intersection (@ToDo) }else if(Alg.NbPoints() > 1){ PointOnEdge[i] = Base::Vector3f(FLOAT_MAX,0,0); Base::Console().Log("MeshAlgos::projectCurve(): More then one intersection in Facet %lu, Edge %d\n",uCurFacetIdx,i); } } } uLastFacetIdx = uCurFacetIdx; if(NbrOfHits == 1) { uCurFacetIdx = auNeighboursIdx[HitIdx]; FaceSplitEdge splitEdge; splitEdge.ulFaceIndex = uCurFacetIdx; splitEdge.p1 = cResultPoint; splitEdge.p2 = cSplitPoint; vSplitEdges.push_back( splitEdge ); cResultPoint = cSplitPoint; GoOn = true; }else{ Base::Console().Log("MeshAlgos::projectCurve(): Possible reentry in Facet %lu\n", uCurFacetIdx); } if( uCurFacetIdx == uStartFacetIdx ) GoOn = false; }while(GoOn); }