netgen/libsrc/csg/surface.hpp

397 lines
11 KiB
C++
Raw Normal View History

2009-01-13 04:40:13 +05:00
#ifndef FILE_SURFACE
#define FILE_SURFACE
/**************************************************************************/
/* File: surface.hh */
/* Author: Joachim Schoeberl */
/* Date: 1. Dez. 95 */
/**************************************************************************/
2009-09-07 17:50:13 +06:00
namespace netgen
{
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
class TriangleApproximation;
2009-01-13 04:40:13 +05:00
2010-04-04 12:24:24 +06:00
2009-09-07 17:50:13 +06:00
/**
Basis class for implicit surface geometry.
This class is used for generation of surface meshes
2010-04-04 12:24:24 +06:00
in NETGEN
2009-01-13 04:40:13 +05:00
*/
2009-09-07 17:50:13 +06:00
class Surface
{
protected:
/// invert normal vector
bool inverse;
/// maximal h in surface
double maxh;
/// name of surface
char * name;
/// boundary condition nr
int bcprop;
2010-04-04 12:24:24 +06:00
/// boundary condition label
2009-09-07 17:50:13 +06:00
string bcname;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
public:
Surface ();
/** @name Tangential plane.
The tangential plane is used for surface mesh generation.
*/
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual ~Surface();
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
protected:
/** @name Points in the surface defining tangential plane.
Tangential plane is taken in p1, the local x-axis
is directed to p2.
2009-01-13 04:40:13 +05:00
*/
2009-09-07 17:50:13 +06:00
//@{
///
Point<3> p1;
///
Point<3> p2;
//@}
/** @name Base-vectos for local coordinate system. */
//@{
/// in plane, directed p1->p2
Vec<3> ex;
/// in plane
Vec<3> ey;
/// outer normal direction
Vec<3> ez;
//@}
public:
2018-11-29 22:35:30 +05:00
virtual void DoArchive(Archive& archive)
{
archive & inverse & maxh & name & bcprop & bcname
& p1 & p2 & ex & ey & ez;
}
2009-09-07 17:50:13 +06:00
void SetName (const char * aname);
const char * Name () const { return name; }
//@{
/**
Defines tangential plane in ap1.
2010-04-04 12:24:24 +06:00
The local x-coordinate axis points to the direction of ap2 */
2009-09-07 17:50:13 +06:00
virtual void DefineTangentialPlane (const Point<3> & ap1,
const Point<3> & ap2);
/// Transforms 3d point p3d to local coordinates pplane
virtual void ToPlane (const Point<3> & p3d, Point<2> & pplane,
double h, int & zone) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/// Transforms point pplane in local coordinates to 3d point
virtual void FromPlane (const Point<2> & pplane,
Point<3> & p3d, double h) const;
//@}
2009-01-13 04:40:13 +05:00
2010-04-04 12:24:24 +06:00
/// Project point p onto surface (closest point)
2009-09-07 17:50:13 +06:00
virtual void Project (Point<3> & p) const;
2009-01-13 04:40:13 +05:00
2010-04-04 12:24:24 +06:00
/// Project along direction
2009-09-07 17:50:13 +06:00
virtual void SkewProject(Point<3> & p, const Vec<3> & direction) const;
2009-01-13 04:40:13 +05:00
2010-04-04 12:24:24 +06:00
/// Is current surface identic to surface 2 ?
2009-09-07 17:50:13 +06:00
virtual int IsIdentic (const Surface & /* s2 */, int & /* inv */,
double /* eps */) const
{ return 0; }
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
///
virtual int PointOnSurface (const Point<3> & p,
double eps = 1e-6) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/** @name Implicit function.
Calculate function value and derivatives.
*/
//@{
/// Calculate implicit function value in point point
virtual double CalcFunctionValue (const Point<3> & point) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Calc gradient of implicit function.
gradient should be O(1) at surface
2009-01-13 04:40:13 +05:00
*/
2009-09-07 17:50:13 +06:00
virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Calculate second derivatives of implicit function.
*/
virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Returns outer normal vector.
*/
// virtual void GetNormalVector (const Point<3> & p, Vec<3> & n) const;
virtual Vec<3> GetNormalVector (const Point<3> & p) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Upper bound for spectral norm of Hesse-matrix
*/
virtual double HesseNorm () const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Upper bound for spectral norm of Hesse-matrix in the
rad - environment of point c.
*/
virtual double HesseNormLoc (const Point<3> & /* c */,
double /* rad */) const
{ return HesseNorm (); }
//@}
///
virtual double MaxCurvature () const;
///
virtual double MaxCurvatureLoc (const Point<3> & /* c */ ,
double /* rad */) const;
/** Returns any point in the surface.
Needed to start surface mesh generation e.g. on sphere */
virtual Point<3> GetSurfacePoint () const = 0;
///
bool Inverse () const { return inverse; }
///
void SetInverse (bool ainverse) { inverse = ainverse; }
///
virtual void Print (ostream & str) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
///
virtual void Reduce (const BoxSphere<3> & /* box */) { };
///
virtual void UnReduce () { };
/// set max h in surface
void SetMaxH (double amaxh) { maxh = amaxh; }
///
double GetMaxH () const { return maxh; }
///
int GetBCProperty () const { return bcprop; }
///
void SetBCProperty (int abc) { bcprop = abc; }
/** Determine local mesh-size.
Find
\[ h \leq hmax, \]
such that
\[ h \times \kappa (x) \leq c \qquad \mbox{in} B(x, h), \]
where kappa(x) is the curvature in x. */
virtual double LocH (const Point<3> & p, double x,
2014-08-30 06:15:59 +06:00
double c,
const MeshingParameters & mparam,
double hmax) const;
2009-09-07 17:50:13 +06:00
/**
Gets Approximation by triangles,
where qual is about the number of triangles per radius
*/
virtual void GetTriangleApproximation (TriangleApproximation & /* tas */,
const Box<3> & /* boundingbox */,
double /* facets */ ) const { };
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
string GetBCName() const { return bcname; }
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
void SetBCName( string abc ) { bcname = abc; }
2009-01-13 04:40:13 +05:00
};
2009-09-07 17:50:13 +06:00
inline ostream & operator<< (ostream & ost, const Surface & surf)
{
surf.Print(ost);
return ost;
}
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
typedef enum { IS_OUTSIDE = 0, IS_INSIDE = 1, DOES_INTERSECT = 2}
INSOLID_TYPE;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
class DummySurface : public Surface
{
2011-08-29 16:09:11 +06:00
virtual double CalcFunctionValue (const Point<3> & /* point */) const
2009-09-07 17:50:13 +06:00
{ return 0; }
2009-02-25 21:06:34 +05:00
2011-08-29 16:09:11 +06:00
virtual void CalcGradient (const Point<3> & /* point */, Vec<3> & grad) const
2009-09-07 17:50:13 +06:00
{ grad = Vec<3> (0,0,0); }
2009-02-25 21:06:34 +05:00
2009-09-07 17:50:13 +06:00
virtual Point<3> GetSurfacePoint () const
{ return Point<3> (0,0,0); }
2009-02-25 21:06:34 +05:00
2009-09-07 17:50:13 +06:00
virtual double HesseNorm () const
{ return 0; }
2009-02-25 21:06:34 +05:00
2011-08-29 16:09:11 +06:00
virtual void Project (Point<3> & /* p */) const
2009-09-07 17:50:13 +06:00
{ ; }
2009-02-25 21:06:34 +05:00
2009-09-07 17:50:13 +06:00
virtual void Print (ostream & ost) const
{ ost << "dummy surface"; }
};
2009-02-25 21:06:34 +05:00
2009-09-07 17:50:13 +06:00
class Primitive
{
2018-11-29 22:35:30 +05:00
protected:
2019-07-09 13:39:16 +05:00
NgArray<int> surfaceids;
NgArray<int> surfaceactive;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
public:
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
Primitive ();
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual ~Primitive();
2009-01-13 04:40:13 +05:00
2018-11-29 22:35:30 +05:00
virtual void DoArchive(Archive& archive)
{
archive & surfaceids & surfaceactive;
}
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/*
Check, whether box intersects solid defined by surface.
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
return values:
0 .. box outside solid \\
1 .. box in solid \\
2 .. can't decide (allowed, iff box is close to solid)
*/
virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const = 0;
virtual INSOLID_TYPE PointInSolid (const Point<3> & p,
double eps) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual void GetTangentialSurfaceIndices (const Point<3> & p,
2019-07-09 13:39:16 +05:00
NgArray<int> & surfind, double eps) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual INSOLID_TYPE VecInSolid (const Point<3> & p,
const Vec<3> & v,
double eps) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
// checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid
virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p,
const Vec<3> & v1,
const Vec<3> & v2,
double eps) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
// checks if p + s v1 + s*s/2 v2 is inside
virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p,
const Vec<3> & v1,
const Vec<3> & v2,
double eps) const;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
// like VecInSolid2, but second order approximation
virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p,
const Vec<3> & v,
const Vec<3> & v2,
const Vec<3> & m,
double eps) const;
2009-01-13 04:40:13 +05:00
// for a point p in the surface, into which (closed) surfaces does v point into ?
2009-09-07 17:50:13 +06:00
virtual void GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v,
2019-07-09 13:39:16 +05:00
NgArray<int> & surfind, double eps) const;
2009-01-13 04:40:13 +05:00
// a point p in the surface, and v a tangential vector
// for arbitrary small, but positive t consider q := Project(p+t*v)
// into which (closed) surfaces does v2 point into, when starting from q ?
2009-09-07 17:50:13 +06:00
virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,
2019-07-09 13:39:16 +05:00
NgArray<int> & surfind, double eps) const;
2009-01-13 04:40:13 +05:00
2019-07-09 13:39:16 +05:00
virtual void CalcSpecialPoints (NgArray<Point<3> > & /* pts */) const { ; }
2009-09-07 17:50:13 +06:00
virtual void AnalyzeSpecialPoint (const Point<3> & /* pt */,
2019-07-09 13:39:16 +05:00
NgArray<Point<3> > & /* specpts */) const { ; }
2009-09-07 17:50:13 +06:00
virtual Vec<3> SpecialPointTangentialVector (const Point<3> & /* p */,
int /* s1 */, int /* s2 */) const
{ return Vec<3> (0,0,0); }
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual int GetNSurfaces() const = 0;
virtual Surface & GetSurface (int i = 0) = 0;
virtual const Surface & GetSurface (int i = 0) const = 0;
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
int GetSurfaceId (int i = 0) const;
void SetSurfaceId (int i, int id);
int SurfaceActive (int i) const { return surfaceactive[i]; }
virtual int SurfaceInverted (int /* i */ = 0) const { return 0; }
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual void GetPrimitiveData (const char *& classname,
2019-07-09 13:39:16 +05:00
NgArray<double> & coeffs) const;
virtual void SetPrimitiveData (NgArray<double> & coeffs);
2009-09-07 17:50:13 +06:00
static Primitive * CreatePrimitive (const char * classname);
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual void Reduce (const BoxSphere<3> & /* box */) { };
virtual void UnReduce () { };
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
virtual Primitive * Copy () const;
virtual void Transform (Transformation<3> & trans);
};
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
class OneSurfacePrimitive : public Surface, public Primitive
{
public:
OneSurfacePrimitive();
~OneSurfacePrimitive();
2009-01-13 04:40:13 +05:00
2018-11-29 22:35:30 +05:00
virtual void DoArchive(Archive& archive)
{
Surface::DoArchive(archive);
Primitive::DoArchive(archive);
}
2009-09-07 17:50:13 +06:00
virtual INSOLID_TYPE PointInSolid (const Point<3> & p,
double eps) const;
virtual INSOLID_TYPE VecInSolid (const Point<3> & p,
const Vec<3> & v,
2009-01-13 04:40:13 +05:00
double eps) const;
2009-09-07 17:50:13 +06:00
virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p,
const Vec<3> & v1,
const Vec<3> & v2,
double eps) const;
virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p,
const Vec<3> & v1,
const Vec<3> & v2,
double eps) const;
virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p,
const Vec<3> & v,
const Vec<3> & v2,
const Vec<3> & m,
double eps) const;
virtual int GetNSurfaces() const;
virtual Surface & GetSurface (int i = 0);
virtual const Surface & GetSurface (int i = 0) const;
};
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
/**
Projects point to edge.
2018-01-08 20:45:53 +05:00
The point hp is projected to the edge described by f1 and f2.
2009-09-07 17:50:13 +06:00
It is assumed that the edge is non-degenerated, and the
(generalized) Newton method converges.
*/
extern void ProjectToEdge (const Surface * f1,
const Surface * f2,
Point<3> & hp);
2009-01-13 04:40:13 +05:00
2009-09-07 17:50:13 +06:00
}
2009-01-13 04:40:13 +05:00
#endif