Files
create/src/Mod/Mesh/App/Core/SetOperations.h
2021-09-16 17:31:45 +02:00

239 lines
8.1 KiB
C++

/***************************************************************************
* Copyright (c) 2005 Berthold Grupp *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef MESH_SETOPERATIONS_H
#define MESH_SETOPERATIONS_H
#include <list>
#include <map>
#include <set>
#include "MeshKernel.h"
#include "Elements.h"
#include "Iterator.h"
#include "Visitor.h"
#include <Base/Builder3D.h>
// forward declarations
namespace MeshCore
{
class MeshGeomFacet;
class MeshGeomEdge;
class MeshBuilder;
class MeshKernel;
class MeshFacetGrid;
class MeshFacetArray;
class MeshFacetIterator;
/**
* The MeshAlgorithm class provides algorithms base on meshes.
*/
class MeshExport SetOperations
{
public:
enum OperationType { Union, Intersect, Difference, Inner, Outer };
/// Construction
SetOperations (const MeshKernel &cutMesh1, const MeshKernel &cutMesh2, MeshKernel &result, OperationType opType, float minDistanceToPoint = 1e-5f);
/// Destruction
virtual ~SetOperations ();
public:
/** Cut this mesh with another one. The result is a list of polylines
* If the distance of the polyline to one of the points is less than minDistanceToPoint the polyline goes direct to the point
*/
void Do ();
protected:
const MeshKernel &_cutMesh0; /** Mesh for set operations source 1 */
const MeshKernel &_cutMesh1; /** Mesh for set operations source 2 */
MeshKernel &_resultMesh; /** Result mesh */
OperationType _operationType; /** Set Operation Type */
float _minDistanceToPoint; /** Minimal distance to facet corner points */
private:
// Helper class cutting edge to his two attached facets
class Edge
{
public:
MeshPoint pt1, pt2; // edge
Edge ()
{
}
Edge (MeshPoint p1, MeshPoint p2)
{
if (p1 < p2)
{
pt1 = p1;
pt2 = p2;
}
else
{
pt2 = p1;
pt1 = p2;
}
}
bool operator == (const Edge &edge) const
{
return (pt1 == edge.pt1) && (pt2 == edge.pt2);
}
bool operator < (const Edge &edge) const
{
return (pt1 == edge.pt1) ? (pt2 < edge.pt2) : (pt1 < edge.pt1);
}
};
class EdgeInfo
{
public:
int fcounter[2]; // counter of facets attacted to the edge
MeshGeomFacet facets[2][2]; // Geom-Facets attached to the edge
FacetIndex facet[2]; // underlying Facet-Index
EdgeInfo ()
{
fcounter[0] = 0;
fcounter[1] = 0;
facet[0] = 0;
facet[1] = 0;
}
};
//class CollectFacetVisitor : public MeshFacetVisitor
//{
// public:
// std::vector<unsigned long> &_facets;
// MeshKernel &_mesh;
// std::map<Edge, EdgeInfo> &_edges;
// int _side;
// float _mult;
// int _addFacets; // 0: add facets to the result 1: do not add facets to the result
// Base::Builder3D& _builder;
// CollectFacetVisitor (MeshKernel& mesh, std::vector<unsigned long>& facets, std::map<Edge, EdgeInfo>& edges, int side, float mult, Base::Builder3D& builder);
// bool Visit (MeshFacet &rclFacet, const MeshFacet &rclFrom, unsigned long ulFInd, unsigned long ulLevel);
// bool AllowVisit (MeshFacet& rclFacet, MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex);
//};
class CollectFacetVisitor : public MeshFacetVisitor
{
public:
std::vector<FacetIndex> &_facets;
const MeshKernel &_mesh;
std::map<Edge, EdgeInfo> &_edges;
int _side;
float _mult;
int _addFacets; // 0: add facets to the result 1: do not add facets to the result
Base::Builder3D& _builder;
CollectFacetVisitor (const MeshKernel& mesh, std::vector<FacetIndex>& facets, std::map<Edge, EdgeInfo>& edges, int side, float mult, Base::Builder3D& builder);
bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, FacetIndex ulFInd, unsigned long ulLevel);
bool AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, FacetIndex ulFInd, unsigned long ulLevel, unsigned short neighbourIndex);
};
/** all points from cut */
std::set<MeshPoint> _cutPoints;
/** all edges */
std::map<Edge, EdgeInfo> _edges;
/** map from facet index to its cut points (mesh 1 and mesh 2) Key: Facet-Index Value: List of iterators of set<MeshPoint> */
std::map<FacetIndex, std::list<std::set<MeshPoint>::iterator> > _facet2points[2];
/** Facets collected from region growing */
std::vector<MeshGeomFacet> _facetsOf[2];
std::vector<MeshGeomFacet> _newMeshFacets[2];
/** Cut mesh 1 with mesh 2 */
void Cut (std::set<FacetIndex>& facetsNotCuttingEdge0, std::set<FacetIndex>& facetsCuttingEdge1);
/** Trianglute each facets cut with its cutting points */
void TriangulateMesh (const MeshKernel &cutMesh, int side);
/** search facets for adding (with region growing) */
void CollectFacets (int side, float mult);
/** close gap in the mesh */
void CloseGaps (MeshBuilder& meshBuilder);
/** visual debugger */
Base::Builder3D _builder;
};
/*!
Determine the intersections between two meshes.
*/
class MeshExport MeshIntersection
{
public:
struct Tuple {
Base::Vector3f p1, p2;
FacetIndex f1, f2;
};
struct Triple {
Base::Vector3f p;
FacetIndex f1, f2;
};
struct Pair {
Base::Vector3f p;
FacetIndex f;
};
MeshIntersection(const MeshKernel& m1,
const MeshKernel& m2,
float dist)
: kernel1(m1)
, kernel2(m2)
, minDistance(dist)
{
}
~MeshIntersection()
{
}
bool hasIntersection() const;
void getIntersection(std::list<Tuple>&) const;
/*!
From an unsorted list of intersection points make a list of sorted intersection points. If parameter \a onlyclosed
is set to true then only closed intersection curves are taken and all other curves are filtered out.
*/
void connectLines(bool onlyclosed, const std::list<Tuple>&, std::list< std::list<Triple> >&);
private:
static bool testIntersection(const MeshKernel& k1, const MeshKernel& k2);
private:
const MeshKernel& kernel1;
const MeshKernel& kernel2;
float minDistance;
};
} // namespace MeshCore
#endif // MESH_SETOPERATIONS_H