netgen/libsrc/csg/solid.hpp
2018-12-06 17:53:44 +01:00

265 lines
7.6 KiB
C++

#ifndef FILE_SOLID
#define FILE_SOLID
/**************************************************************************/
/* File: solid.hh */
/* Author: Joachim Schoeberl */
/* Date: 1. Dez. 95 */
/**************************************************************************/
#include <functional>
namespace netgen
{
/*
Constructive Solid Model (csg)
*/
class Solid;
class SolidIterator
{
public:
SolidIterator () { ; }
virtual ~SolidIterator () { ; }
virtual void Do (Solid * sol) = 0;
};
class Solid
{
public:
typedef enum optyp1 { TERM, TERM_REF, SECTION, UNION, SUB, ROOT /*, DUMMY */ } optyp;
private:
char * name;
Primitive * prim;
Solid * s1, * s2;
optyp op;
bool visited;
double maxh;
int num_surfs;
// static int cntnames;
public:
Solid (Primitive * aprim);
Solid (optyp aop, Solid * as1, Solid * as2 = NULL);
// default constructor for archive
Solid () {}
~Solid ();
void DoArchive(Archive& archive)
{
archive & name & prim & s1 & s2 & visited & maxh & num_surfs;
if(archive.Output())
archive << int(op);
else
{
int iop;
archive & iop;
op = optyp(iop);
}
}
const char * Name () const { return name; }
void SetName (const char * aname);
Solid * Copy (class CSGeometry & geom) const;
void Transform (Transformation<3> & trans);
void IterateSolid (SolidIterator & it, bool only_once = 0);
void Boundaries (const Point<3> & p, Array<int> & bounds) const;
int NumPrimitives () const;
void GetSurfaceIndices (Array<int> & surfind) const;
void GetSurfaceIndices (IndexSet & iset) const;
void GetTangentialSurfaceIndices (const Point<3> & p, Array<int> & surfids, double eps) const;
void GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, Array<int> & surfids, double eps) const;
void GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, Array<int> & surfids, double eps) const;
void ForEachSurface (const std::function<void(Surface*,bool)> & lambda, bool inv = false) const;
Primitive * GetPrimitive ()
{ return (op == TERM || op == TERM_REF) ? prim : NULL; }
const Primitive * GetPrimitive () const
{ return (op == TERM || op == TERM_REF) ? prim : NULL; }
Solid * S1() { return s1; }
Solid * S2() { return s2; }
// geometric tests
bool IsIn (const Point<3> & p, double eps = 1e-6) const;
bool IsStrictIn (const Point<3> & p, double eps = 1e-6) const;
bool VectorIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const;
bool VectorStrictIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const;
bool VectorIn2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,
double eps) const;
bool VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,
double eps) const;
/// compute localization in point p
void TangentialSolid (const Point<3> & p, Solid *& tansol, Array<int> & surfids, double eps) const;
/// compute localization in point p tangential to vector t
void TangentialSolid2 (const Point<3> & p, const Vec<3> & t,
Solid *& tansol, Array<int> & surfids, double eps) const;
/** compute localization in point p, with second order approximation to edge
p + s t + s*s/2 t2 **/
void TangentialSolid3 (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
Solid *& tansol, Array<int> & surfids, double eps) const;
/** tangential solid, which follows the edge
p + s t + s*s/2 t2
with second order, and the neighbouring face
p + s t + s*s/2 t2 + r m
with first order
**/
void TangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
const Vec<3> & m,
Solid *& tansol, Array<int> & surfids, double eps) const;
void CalcOnePrimitiveSpecialPoints (const Box<3> & box, Array<Point<3> > & pts) const;
///
int Edge (const Point<3> & p, const Vec<3> & v, double eps) const;
///
int OnFace (const Point<3> & p, const Vec<3> & v, double eps) const;
///
void Print (ostream & str) const;
///
void CalcSurfaceInverse ();
///
Solid * GetReducedSolid (const BoxSphere<3> & box) const;
void SetMaxH (double amaxh)
{ maxh = amaxh; }
double GetMaxH () const
{ return maxh; }
void GetSolidData (ostream & ost, int first = 1) const;
static Solid * CreateSolid (istream & ist, const SYMBOLTABLE<Solid*> & solids);
static BlockAllocator ball;
void * operator new(size_t /* s */)
{
return ball.Alloc();
}
void operator delete (void * p)
{
ball.Free (p);
}
protected:
///
void RecBoundaries (const Point<3> & p, Array<int> & bounds,
int & in, int & strin) const;
///
void RecTangentialSolid (const Point<3> & p, Solid *& tansol, Array<int> & surfids,
int & in, int & strin, double eps) const;
void RecTangentialSolid2 (const Point<3> & p, const Vec<3> & vec,
Solid *& tansol, Array<int> & surfids,
int & in, int & strin, double eps) const;
///
void RecTangentialSolid3 (const Point<3> & p, const Vec<3> & vec,const Vec<3> & vec2,
Solid *& tansol, Array<int> & surfids,
int & in, int & strin, double eps) const;
///
void RecTangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
const Vec<3> & m,
Solid *& tansol, Array<int> & surfids,
int & in, int & strin, double eps) const;
///
void RecEdge (const Point<3> & p, const Vec<3> & v,
int & in, int & strin, int & faces, double eps) const;
///
void CalcSurfaceInverseRec (int inv);
///
Solid * RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const;
///
void RecGetSurfaceIndices (Array<int> & surfind) const;
void RecGetTangentialSurfaceIndices (const Point<3> & p, Array<int> & surfids, double eps) const;
void RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, Array<int> & surfids, double eps) const;
void RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,
Array<int> & surfids, double eps) const;
void RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m,
Array<int> & surfids, double eps) const;
void RecGetSurfaceIndices (IndexSet & iset) const;
void RecCalcOnePrimitiveSpecialPoints (Array<Point<3> > & pts) const;
friend class SolidIterator;
friend class ClearVisitedIt;
friend class RemoveDummyIterator;
friend class CSGeometry;
};
inline ostream & operator<< (ostream & ost, const Solid & sol)
{
sol.Print (ost);
return ost;
}
class ReducePrimitiveIterator : public SolidIterator
{
const BoxSphere<3> & box;
public:
ReducePrimitiveIterator (const BoxSphere<3> & abox)
: SolidIterator(), box(abox) { ; }
virtual ~ReducePrimitiveIterator () { ; }
virtual void Do (Solid * sol)
{
if (sol -> GetPrimitive())
sol -> GetPrimitive() -> Reduce (box);
}
};
class UnReducePrimitiveIterator : public SolidIterator
{
public:
UnReducePrimitiveIterator () { ; }
virtual ~UnReducePrimitiveIterator () { ; }
virtual void Do (Solid * sol)
{
if (sol -> GetPrimitive())
sol -> GetPrimitive() -> UnReduce ();
}
};
}
#endif