mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 22:00:33 +05:00
296 lines
8.9 KiB
C++
296 lines
8.9 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;
|
|
};
|
|
|
|
|
|
inline INSOLID_TYPE Intersection (INSOLID_TYPE ina, INSOLID_TYPE inb)
|
|
{
|
|
if (ina == IS_INSIDE && inb == IS_INSIDE) return IS_INSIDE;
|
|
if (ina == IS_OUTSIDE || inb == IS_OUTSIDE) return IS_OUTSIDE;
|
|
return DOES_INTERSECT;
|
|
}
|
|
|
|
inline INSOLID_TYPE Union (INSOLID_TYPE ina, INSOLID_TYPE inb)
|
|
{
|
|
if (ina == IS_INSIDE || inb == IS_INSIDE) return IS_INSIDE;
|
|
if (ina == IS_OUTSIDE && inb == IS_OUTSIDE) return IS_OUTSIDE;
|
|
return DOES_INTERSECT;
|
|
}
|
|
|
|
inline INSOLID_TYPE Complement (INSOLID_TYPE in)
|
|
{
|
|
if (in == IS_INSIDE) return IS_OUTSIDE;
|
|
if (in == IS_OUTSIDE) return IS_INSIDE;
|
|
return DOES_INTERSECT;
|
|
}
|
|
|
|
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, NgArray<int> & bounds) const;
|
|
int NumPrimitives () const;
|
|
void GetSurfaceIndices (NgArray<int> & surfind) const;
|
|
void GetSurfaceIndices (IndexSet & iset) const;
|
|
|
|
void GetTangentialSurfaceIndices (const Point<3> & p, NgArray<int> & surfids, double eps) const;
|
|
void GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, NgArray<int> & surfids, double eps) const;
|
|
void GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, NgArray<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
|
|
|
|
INSOLID_TYPE PointInSolid (const Point<3> & p, double eps) const;
|
|
INSOLID_TYPE VecInSolid (const Point<3> & p, const Vec<3> & v, double eps) const;
|
|
|
|
// checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid
|
|
INSOLID_TYPE VecInSolid2 (const Point<3> & p, const Vec<3> & v1,
|
|
const Vec<3> & v2, double eps) const;
|
|
|
|
|
|
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;
|
|
*/
|
|
bool VectorStrictIn2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,
|
|
double eps) const;
|
|
|
|
/// compute localization in point p
|
|
unique_ptr<Solid> TangentialSolid (const Point<3> & p, NgArray<int> & surfids, double eps) const;
|
|
|
|
/// compute localization in point p tangential to vector t
|
|
unique_ptr<Solid> TangentialSolid2 (const Point<3> & p, const Vec<3> & t,
|
|
NgArray<int> & surfids, double eps) const;
|
|
|
|
/** compute localization in point p, with second order approximation to edge
|
|
p + s t + s*s/2 t2 **/
|
|
unique_ptr<Solid> TangentialSolid3 (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
|
|
NgArray<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
|
|
**/
|
|
unique_ptr<Solid> TangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
|
|
const Vec<3> & m,
|
|
NgArray<int> & surfids, double eps) const;
|
|
|
|
|
|
void CalcOnePrimitiveSpecialPoints (const Box<3> & box, NgArray<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 shared_ptr<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, NgArray<int> & bounds,
|
|
int & in, int & strin) const;
|
|
///
|
|
void RecTangentialSolid (const Point<3> & p, Solid *& tansol, NgArray<int> & surfids,
|
|
bool & in, bool & strin, double eps) const;
|
|
|
|
void RecTangentialSolid2 (const Point<3> & p, const Vec<3> & vec,
|
|
Solid *& tansol, NgArray<int> & surfids,
|
|
bool & in, bool & strin, double eps) const;
|
|
///
|
|
void RecTangentialSolid3 (const Point<3> & p, const Vec<3> & vec,const Vec<3> & vec2,
|
|
Solid *& tansol, NgArray<int> & surfids,
|
|
bool & in, bool & strin, double eps) const;
|
|
///
|
|
void RecTangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2,
|
|
const Vec<3> & m,
|
|
Solid *& tansol, NgArray<int> & surfids,
|
|
bool & in, bool & strin, double eps) const;
|
|
|
|
///
|
|
void RecEdge (const Point<3> & p, const Vec<3> & v,
|
|
bool & in, bool & strin, int & faces, double eps) const;
|
|
///
|
|
void CalcSurfaceInverseRec (int inv);
|
|
///
|
|
Solid * RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const;
|
|
///
|
|
void RecGetSurfaceIndices (NgArray<int> & surfind) const;
|
|
void RecGetTangentialSurfaceIndices (const Point<3> & p, NgArray<int> & surfids, double eps) const;
|
|
void RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, NgArray<int> & surfids, double eps) const;
|
|
void RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,
|
|
NgArray<int> & surfids, double eps) const;
|
|
void RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m,
|
|
NgArray<int> & surfids, double eps) const;
|
|
void RecGetSurfaceIndices (IndexSet & iset) const;
|
|
|
|
void RecCalcOnePrimitiveSpecialPoints (NgArray<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
|
|
{
|
|
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
|