| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| |
|
| | #include <fstream>
|
| | #include <ios>
|
| |
|
| |
|
| | #include <Base/Builder3D.h>
|
| | #include <Base/Sequencer.h>
|
| |
|
| | #include "Algorithm.h"
|
| | #include "Builder.h"
|
| | #include "Definitions.h"
|
| | #include "Elements.h"
|
| | #include "Grid.h"
|
| | #include "Iterator.h"
|
| | #include "SetOperations.h"
|
| | #include "Triangulation.h"
|
| | #include "Visitor.h"
|
| |
|
| |
|
| | using namespace Base;
|
| | using namespace MeshCore;
|
| |
|
| |
|
| | SetOperations::SetOperations(
|
| | const MeshKernel& cutMesh1,
|
| | const MeshKernel& cutMesh2,
|
| | MeshKernel& result,
|
| | OperationType opType,
|
| | float minDistanceToPoint
|
| | )
|
| | : _cutMesh0(cutMesh1)
|
| | , _cutMesh1(cutMesh2)
|
| | , _resultMesh(result)
|
| | , _operationType(opType)
|
| | , _minDistanceToPoint(minDistanceToPoint)
|
| | {}
|
| |
|
| | void SetOperations::Do()
|
| | {
|
| | _minDistanceToPoint = 0.000001F;
|
| | float saveMinMeshDistance = MeshDefinitions::_fMinPointDistance;
|
| | MeshDefinitions::SetMinPointDistance(0.000001F);
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | std::set<FacetIndex> facetsCuttingEdge0, facetsCuttingEdge1;
|
| | Cut(facetsCuttingEdge0, facetsCuttingEdge1);
|
| |
|
| |
|
| | if (facetsCuttingEdge0.empty() || facetsCuttingEdge1.empty()) {
|
| | switch (_operationType) {
|
| | case Union: {
|
| | _resultMesh = _cutMesh0;
|
| | _resultMesh.Merge(_cutMesh1);
|
| | } break;
|
| | case Intersect: {
|
| | _resultMesh.Clear();
|
| | } break;
|
| | case Difference:
|
| | case Inner:
|
| | case Outer: {
|
| | _resultMesh = _cutMesh0;
|
| | } break;
|
| | default: {
|
| | _resultMesh.Clear();
|
| | break;
|
| | }
|
| | }
|
| |
|
| | MeshDefinitions::SetMinPointDistance(saveMinMeshDistance);
|
| | return;
|
| | }
|
| |
|
| | for (auto i = 0UL; i < _cutMesh0.CountFacets(); i++) {
|
| | if (facetsCuttingEdge0.find(i) == facetsCuttingEdge0.end()) {
|
| | _newMeshFacets[0].push_back(_cutMesh0.GetFacet(i));
|
| | }
|
| | }
|
| |
|
| | for (auto i = 0UL; i < _cutMesh1.CountFacets(); i++) {
|
| | if (facetsCuttingEdge1.find(i) == facetsCuttingEdge1.end()) {
|
| | _newMeshFacets[1].push_back(_cutMesh1.GetFacet(i));
|
| | }
|
| | }
|
| |
|
| |
|
| | TriangulateMesh(_cutMesh0, 0);
|
| |
|
| |
|
| | TriangulateMesh(_cutMesh1, 1);
|
| |
|
| | float mult0 {}, mult1 {};
|
| | switch (_operationType) {
|
| | case Union:
|
| | mult0 = -1.0F;
|
| | mult1 = -1.0F;
|
| | break;
|
| | case Intersect:
|
| | mult0 = 1.0F;
|
| | mult1 = 1.0F;
|
| | break;
|
| | case Difference:
|
| | mult0 = -1.0F;
|
| | mult1 = 1.0F;
|
| | break;
|
| | case Inner:
|
| | mult0 = 1.0F;
|
| | mult1 = 0.0F;
|
| | break;
|
| | case Outer:
|
| | mult0 = -1.0F;
|
| | mult1 = 0.0F;
|
| | break;
|
| | default:
|
| | mult0 = 0.0F;
|
| | mult1 = 0.0F;
|
| | break;
|
| | }
|
| |
|
| |
|
| | CollectFacets(0, mult0);
|
| |
|
| | CollectFacets(1, mult1);
|
| |
|
| | std::vector<MeshGeomFacet> facets;
|
| |
|
| | std::vector<MeshGeomFacet>::iterator itf;
|
| | for (itf = _facetsOf[0].begin(); itf != _facetsOf[0].end(); ++itf) {
|
| | if (_operationType == Difference) {
|
| | std::swap(itf->_aclPoints[0], itf->_aclPoints[1]);
|
| | itf->CalcNormal();
|
| | }
|
| |
|
| | facets.push_back(*itf);
|
| | }
|
| |
|
| | for (itf = _facetsOf[1].begin(); itf != _facetsOf[1].end(); ++itf) {
|
| | facets.push_back(*itf);
|
| | }
|
| |
|
| | _resultMesh = facets;
|
| |
|
| |
|
| |
|
| |
|
| | MeshDefinitions::SetMinPointDistance(saveMinMeshDistance);
|
| | }
|
| |
|
| | void SetOperations::Cut(std::set<FacetIndex>& facetsCuttingEdge0, std::set<FacetIndex>& facetsCuttingEdge1)
|
| | {
|
| | MeshFacetGrid grid1(_cutMesh0, 20);
|
| | MeshFacetGrid grid2(_cutMesh1, 20);
|
| |
|
| | unsigned long ctGx1 {}, ctGy1 {}, ctGz1 {};
|
| | grid1.GetCtGrids(ctGx1, ctGy1, ctGz1);
|
| |
|
| | for (auto gx1 = 0UL; gx1 < ctGx1; gx1++) {
|
| | for (auto gy1 = 0UL; gy1 < ctGy1; gy1++) {
|
| | for (auto gz1 = 0UL; gz1 < ctGz1; gz1++) {
|
| | if (grid1.GetCtElements(gx1, gy1, gz1) > 0) {
|
| | std::vector<FacetIndex> vecFacets2;
|
| | grid2.Inside(grid1.GetBoundBox(gx1, gy1, gz1), vecFacets2);
|
| |
|
| | if (!vecFacets2.empty()) {
|
| | std::set<FacetIndex> vecFacets1;
|
| | grid1.GetElements(gx1, gy1, gz1, vecFacets1);
|
| |
|
| | std::set<FacetIndex>::iterator it1;
|
| | for (it1 = vecFacets1.begin(); it1 != vecFacets1.end(); ++it1) {
|
| | FacetIndex fidx1 = *it1;
|
| | MeshGeomFacet f1 = _cutMesh0.GetFacet(*it1);
|
| |
|
| | std::vector<FacetIndex>::iterator it2;
|
| | for (it2 = vecFacets2.begin(); it2 != vecFacets2.end(); ++it2) {
|
| | FacetIndex fidx2 = *it2;
|
| | MeshGeomFacet f2 = _cutMesh1.GetFacet(fidx2);
|
| |
|
| | MeshPoint p0, p1;
|
| |
|
| | int isect = f1.IntersectWithFacet(f2, p0, p1);
|
| | if (isect > 0) {
|
| |
|
| | float minDist1 = _minDistanceToPoint,
|
| | minDist2 = _minDistanceToPoint;
|
| | MeshPoint np0 = p0, np1 = p1;
|
| | for (int i = 0; i < 3; i++)
|
| | {
|
| | float d1 = (f1._aclPoints[i] - p0).Length();
|
| | float d2 = (f1._aclPoints[i] - p1).Length();
|
| | if (d1 < minDist1) {
|
| | minDist1 = d1;
|
| | np0 = f1._aclPoints[i];
|
| | }
|
| | if (d2 < minDist2) {
|
| | minDist2 = d2;
|
| | p1 = f1._aclPoints[i];
|
| | }
|
| | }
|
| |
|
| |
|
| | for (int i = 0; i < 3; i++)
|
| | {
|
| | float d1 = (f2._aclPoints[i] - p0).Length();
|
| | float d2 = (f2._aclPoints[i] - p1).Length();
|
| | if (d1 < minDist1) {
|
| | minDist1 = d1;
|
| | np0 = f2._aclPoints[i];
|
| | }
|
| | if (d2 < minDist2) {
|
| | minDist2 = d2;
|
| | np1 = f2._aclPoints[i];
|
| | }
|
| | }
|
| |
|
| | MeshPoint mp0 = np0;
|
| | MeshPoint mp1 = np1;
|
| |
|
| | if (mp0 != mp1) {
|
| | facetsCuttingEdge0.insert(fidx1);
|
| | facetsCuttingEdge1.insert(fidx2);
|
| |
|
| | _cutPoints.insert(mp0);
|
| | _cutPoints.insert(mp1);
|
| |
|
| | std::pair<std::set<MeshPoint>::iterator, bool> pit0
|
| | = _cutPoints.insert(mp0);
|
| | std::pair<std::set<MeshPoint>::iterator, bool> pit1
|
| | = _cutPoints.insert(mp1);
|
| |
|
| | _edges[Edge(mp0, mp1)] = EdgeInfo();
|
| |
|
| | _facet2points[0][fidx1].push_back(pit0.first);
|
| | _facet2points[0][fidx1].push_back(pit1.first);
|
| | _facet2points[1][fidx2].push_back(pit0.first);
|
| | _facet2points[1][fidx2].push_back(pit1.first);
|
| | }
|
| | else {
|
| | std::pair<std::set<MeshPoint>::iterator, bool> pit
|
| | = _cutPoints.insert(mp0);
|
| |
|
| |
|
| |
|
| |
|
| | {
|
| | facetsCuttingEdge0.insert(fidx1);
|
| | _facet2points[0][fidx1].push_back(pit.first);
|
| | }
|
| |
|
| |
|
| |
|
| | {
|
| | facetsCuttingEdge1.insert(fidx2);
|
| | _facet2points[1][fidx2].push_back(pit.first);
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| |
|
| | void SetOperations::TriangulateMesh(const MeshKernel& cutMesh, int side)
|
| | {
|
| |
|
| | std::map<FacetIndex, 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;
|
| |
|
| | FacetIndex fidx = it1->first;
|
| | MeshGeomFacet f = cutMesh.GetFacet(fidx);
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | for (int i = 0; i < 3; i++)
|
| | {
|
| | pointsSet.insert(f._aclPoints[i]);
|
| | points.push_back(f._aclPoints[i]);
|
| | }
|
| |
|
| |
|
| | 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;
|
| |
|
| |
|
| | 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 (auto& it : facets) {
|
| | if ((it._aulPoints[0] == it._aulPoints[1]) || (it._aulPoints[1] == it._aulPoints[2])
|
| | || (it._aulPoints[2] == it._aulPoints[0])) {
|
| | continue;
|
| | }
|
| |
|
| | MeshGeomFacet facet(
|
| | points[it._aulPoints[0]],
|
| | points[it._aulPoints[1]],
|
| | points[it._aulPoints[2]]
|
| | );
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | 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;
|
| | }
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | facet.CalcNormal();
|
| | if ((facet.GetNormal() * f.GetNormal()) < 0.0F) {
|
| | std::swap(facet._aclPoints[0], facet._aclPoints[1]);
|
| | facet.CalcNormal();
|
| | }
|
| |
|
| |
|
| | for (int j = 0; j < 3; j++) {
|
| | auto eit = _edges.find(Edge(facet._aclPoints[j], facet._aclPoints[(j + 1) % 3]));
|
| |
|
| | if (eit != _edges.end()) {
|
| |
|
| | if (eit->second.fcounter[side] < 2) {
|
| |
|
| |
|
| |
|
| |
|
| | eit->second.facet[side] = fidx;
|
| | eit->second.facets[side][eit->second.fcounter[side]] = facet;
|
| | eit->second.fcounter[side]++;
|
| | facet.SetFlag(MeshFacet::MARKED);
|
| | }
|
| | }
|
| | }
|
| |
|
| | _newMeshFacets[side].push_back(facet);
|
| | }
|
| | }
|
| | }
|
| |
|
| | void SetOperations::CollectFacets(int side, float mult)
|
| | {
|
| |
|
| |
|
| |
|
| | MeshKernel mesh;
|
| | MeshBuilder mb(mesh);
|
| | mb.Initialize(_newMeshFacets[side].size());
|
| | std::vector<MeshGeomFacet>::iterator it;
|
| | for (it = _newMeshFacets[side].begin(); it != _newMeshFacets[side].end(); ++it) {
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | mb.AddFacet(*it, true);
|
| | }
|
| | mb.Finish();
|
| |
|
| | MeshAlgorithm algo(mesh);
|
| | algo.ResetFacetFlag(static_cast<MeshFacet::TFlagType>(MeshFacet::VISIT | MeshFacet::TMP0));
|
| |
|
| |
|
| |
|
| | MeshFacetArray::_TConstIterator itf;
|
| | const MeshFacetArray& rFacets = mesh.GetFacets();
|
| | for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) {
|
| | if (!itf->IsFlag(MeshFacet::VISIT)) {
|
| | std::vector<FacetIndex> facets;
|
| | facets.push_back(itf - rFacets.begin());
|
| | CollectFacetVisitor visitor(mesh, facets, _edges, side, mult, _builder);
|
| | mesh.VisitNeighbourFacets(visitor, itf - rFacets.begin());
|
| |
|
| | if (visitor._addFacets == 0) {
|
| | algo.SetFacetsFlag(facets, MeshFacet::TMP0);
|
| | }
|
| | }
|
| | }
|
| |
|
| |
|
| | for (itf = rFacets.begin(); itf != rFacets.end(); ++itf) {
|
| | if (itf->IsFlag(MeshFacet::TMP0)) {
|
| | _facetsOf[side].push_back(mesh.GetFacet(*itf));
|
| | }
|
| | }
|
| |
|
| |
|
| | }
|
| |
|
| | SetOperations::CollectFacetVisitor::CollectFacetVisitor(
|
| | const MeshKernel& mesh,
|
| | std::vector<FacetIndex>& facets,
|
| | std::map<Edge, EdgeInfo>& edges,
|
| | int side,
|
| | float mult,
|
| | Base::Builder3D& builder
|
| | )
|
| | : _facets(facets)
|
| | , _mesh(mesh)
|
| | , _edges(edges)
|
| | , _side(side)
|
| | , _mult(mult)
|
| | , _builder(builder)
|
| | {}
|
| |
|
| | bool SetOperations::CollectFacetVisitor::Visit(
|
| | const MeshFacet& rclFacet,
|
| | const MeshFacet& rclFrom,
|
| | FacetIndex ulFInd,
|
| | unsigned long ulLevel
|
| | )
|
| | {
|
| | (void)rclFacet;
|
| | (void)rclFrom;
|
| | (void)ulLevel;
|
| | _facets.push_back(ulFInd);
|
| | return true;
|
| | }
|
| |
|
| |
|
| | bool SetOperations::CollectFacetVisitor::AllowVisit(
|
| | const MeshFacet& rclFacet,
|
| | const MeshFacet& rclFrom,
|
| | FacetIndex ulFInd,
|
| | unsigned long ulLevel,
|
| | unsigned short neighbourIndex
|
| | )
|
| | {
|
| | (void)ulFInd;
|
| | (void)ulLevel;
|
| | if (rclFacet.IsFlag(MeshFacet::MARKED) && rclFrom.IsFlag(MeshFacet::MARKED)) {
|
| |
|
| | PointIndex 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) {
|
| |
|
| | MeshGeomFacet facet = _mesh.GetFacet(rclFrom);
|
| | MeshGeomFacet facetOther = it->second.facets[1 - _side][0];
|
| |
|
| |
|
| | Vector3f normalOther = facetOther.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();
|
| |
|
| |
|
| |
|
| |
|
| | bool match = ((ocDir * normalOther) * _mult) < 0.0F;
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| | if (match) {
|
| | _addFacets = 0;
|
| | }
|
| | else {
|
| | _addFacets = 1;
|
| | }
|
| |
|
| |
|
| | }
|
| |
|
| | return false;
|
| | }
|
| | }
|
| |
|
| | return true;
|
| | }
|
| |
|
| |
|
| |
|
| | bool MeshIntersection::hasIntersection() const
|
| | {
|
| | Base::BoundBox3f bbox1 = kernel1.GetBoundBox();
|
| | Base::BoundBox3f bbox2 = kernel2.GetBoundBox();
|
| | if (!(bbox1 && bbox2)) {
|
| | return false;
|
| | }
|
| |
|
| | return (testIntersection(kernel1, kernel2));
|
| | }
|
| |
|
| | void MeshIntersection::getIntersection(std::list<MeshIntersection::Tuple>& intsct) const
|
| | {
|
| | const MeshKernel& k1 = kernel1;
|
| | const MeshKernel& k2 = kernel2;
|
| |
|
| |
|
| | std::vector<Base::BoundBox3f> boxes1;
|
| | MeshFacetIterator cMFI1(k1);
|
| | for (cMFI1.Begin(); cMFI1.More(); cMFI1.Next()) {
|
| | boxes1.push_back((*cMFI1).GetBoundBox());
|
| | }
|
| |
|
| |
|
| | std::vector<Base::BoundBox3f> boxes2;
|
| | MeshFacetIterator cMFI2(k2);
|
| | for (cMFI2.Begin(); cMFI2.More(); cMFI2.Next()) {
|
| | boxes2.push_back((*cMFI2).GetBoundBox());
|
| | }
|
| |
|
| |
|
| | MeshFacetGrid cMeshFacetGrid(k1);
|
| |
|
| | const MeshFacetArray& rFaces2 = k2.GetFacets();
|
| | Base::SequencerLauncher seq("Checking for intersections...", rFaces2.size());
|
| | int index = 0;
|
| | MeshGeomFacet facet1, facet2;
|
| | Base::Vector3f pt1, pt2;
|
| |
|
| |
|
| | for (auto it = rFaces2.begin(); it != rFaces2.end(); ++it, index++) {
|
| | seq.next();
|
| | std::vector<FacetIndex> elements;
|
| | cMeshFacetGrid.Inside(boxes2[index], elements, true);
|
| |
|
| | cMFI2.Set(index);
|
| | facet2 = *cMFI2;
|
| |
|
| | for (FacetIndex element : elements) {
|
| | if (boxes2[index] && boxes1[element]) {
|
| | cMFI1.Set(element);
|
| | facet1 = *cMFI1;
|
| | int ret = facet1.IntersectWithFacet(facet2, pt1, pt2);
|
| | if (ret == 2) {
|
| | Tuple d;
|
| | d.p1 = pt1;
|
| | d.p2 = pt2;
|
| | d.f1 = element;
|
| | d.f2 = index;
|
| | intsct.push_back(d);
|
| | }
|
| | }
|
| | }
|
| | }
|
| | }
|
| |
|
| | bool MeshIntersection::testIntersection(const MeshKernel& k1, const MeshKernel& k2)
|
| | {
|
| |
|
| | std::vector<Base::BoundBox3f> boxes1;
|
| | MeshFacetIterator cMFI1(k1);
|
| | for (cMFI1.Begin(); cMFI1.More(); cMFI1.Next()) {
|
| | boxes1.push_back((*cMFI1).GetBoundBox());
|
| | }
|
| |
|
| |
|
| | std::vector<Base::BoundBox3f> boxes2;
|
| | MeshFacetIterator cMFI2(k2);
|
| | for (cMFI2.Begin(); cMFI2.More(); cMFI2.Next()) {
|
| | boxes2.push_back((*cMFI2).GetBoundBox());
|
| | }
|
| |
|
| |
|
| | MeshFacetGrid cMeshFacetGrid(k1);
|
| |
|
| | const MeshFacetArray& rFaces2 = k2.GetFacets();
|
| | Base::SequencerLauncher seq("Checking for intersections...", rFaces2.size());
|
| | int index = 0;
|
| | MeshGeomFacet facet1, facet2;
|
| | Base::Vector3f pt1, pt2;
|
| |
|
| |
|
| | for (auto it = rFaces2.begin(); it != rFaces2.end(); ++it, index++) {
|
| | seq.next();
|
| | std::vector<FacetIndex> elements;
|
| | cMeshFacetGrid.Inside(boxes2[index], elements, true);
|
| |
|
| | cMFI2.Set(index);
|
| | facet2 = *cMFI2;
|
| |
|
| | for (FacetIndex element : elements) {
|
| | if (boxes2[index] && boxes1[element]) {
|
| | cMFI1.Set(element);
|
| | facet1 = *cMFI1;
|
| | int ret = facet1.IntersectWithFacet(facet2, pt1, pt2);
|
| | if (ret == 2) {
|
| |
|
| | return true;
|
| | }
|
| | }
|
| | }
|
| | }
|
| |
|
| | return false;
|
| | }
|
| |
|
| | void MeshIntersection::connectLines(
|
| | bool onlyclosed,
|
| | const std::list<MeshIntersection::Tuple>& rdata,
|
| | std::list<std::list<MeshIntersection::Triple>>& lines
|
| | )
|
| | {
|
| | float fMinEps = minDistance * minDistance;
|
| |
|
| | std::list<Tuple> data = rdata;
|
| | while (!data.empty()) {
|
| | std::list<Tuple>::iterator pF;
|
| | std::list<Triple> newPoly;
|
| |
|
| |
|
| | Triple front, back;
|
| | front.f1 = data.begin()->f1;
|
| | front.f2 = data.begin()->f2;
|
| | front.p = data.begin()->p1;
|
| | back.f1 = data.begin()->f1;
|
| | back.f2 = data.begin()->f2;
|
| | back.p = data.begin()->p2;
|
| | newPoly.push_back(front);
|
| | newPoly.push_back(back);
|
| | data.erase(data.begin());
|
| |
|
| |
|
| | std::list<Tuple>::iterator pFront, pEnd;
|
| | bool bFoundLine {};
|
| | do {
|
| | float fFrontMin = fMinEps, fEndMin = fMinEps;
|
| | bool bFrontFirst = false, bEndFirst = false;
|
| |
|
| | pFront = data.end();
|
| | pEnd = data.end();
|
| | bFoundLine = false;
|
| |
|
| | for (pF = data.begin(); pF != data.end(); ++pF) {
|
| | if (Base::DistanceP2(front.p, pF->p1) < fFrontMin) {
|
| | fFrontMin = Base::DistanceP2(front.p, pF->p1);
|
| | pFront = pF;
|
| | bFrontFirst = true;
|
| | }
|
| | else if (Base::DistanceP2(back.p, pF->p1) < fEndMin) {
|
| | fEndMin = Base::DistanceP2(back.p, pF->p1);
|
| | pEnd = pF;
|
| | bEndFirst = true;
|
| | }
|
| | else if (Base::DistanceP2(front.p, pF->p2) < fFrontMin) {
|
| | fFrontMin = Base::DistanceP2(front.p, pF->p2);
|
| | pFront = pF;
|
| | bFrontFirst = false;
|
| | }
|
| | else if (Base::DistanceP2(back.p, pF->p2) < fEndMin) {
|
| | fEndMin = Base::DistanceP2(back.p, pF->p2);
|
| | pEnd = pF;
|
| | bEndFirst = false;
|
| | }
|
| |
|
| | if (fFrontMin == 0.0F || fEndMin == 0.0F) {
|
| | break;
|
| | }
|
| | }
|
| |
|
| | if (pFront != data.end()) {
|
| | bFoundLine = true;
|
| | if (bFrontFirst) {
|
| | front.f1 = pFront->f1;
|
| | front.f2 = pFront->f2;
|
| | front.p = pFront->p2;
|
| | newPoly.push_front(front);
|
| | }
|
| | else {
|
| | front.f1 = pFront->f1;
|
| | front.f2 = pFront->f2;
|
| | front.p = pFront->p1;
|
| | newPoly.push_front(front);
|
| | }
|
| |
|
| | data.erase(pFront);
|
| | }
|
| |
|
| | if (pEnd != data.end()) {
|
| | bFoundLine = true;
|
| | if (bEndFirst) {
|
| | back.f1 = pEnd->f1;
|
| | back.f2 = pEnd->f2;
|
| | back.p = pEnd->p2;
|
| | newPoly.push_back(back);
|
| | }
|
| | else {
|
| | back.f1 = pEnd->f1;
|
| | back.f2 = pEnd->f2;
|
| | back.p = pEnd->p1;
|
| | newPoly.push_back(back);
|
| | }
|
| |
|
| | data.erase(pEnd);
|
| | }
|
| | } while (bFoundLine);
|
| |
|
| | if (onlyclosed) {
|
| | if (newPoly.size() > 2
|
| | && Base::DistanceP2(newPoly.front().p, newPoly.back().p) < fMinEps) {
|
| | lines.push_back(newPoly);
|
| | }
|
| | }
|
| | else {
|
| | lines.push_back(newPoly);
|
| | }
|
| | }
|
| | }
|
| |
|