Path: blob/devel/ElmerGUI/netgen/libsrc/csg/surface.cpp
3206 views
#include <mystdlib.h>12#include <myadt.hpp>3#include <csg.hpp>45#include <linalg.hpp>6#include <meshing.hpp>789namespace netgen10{11Surface :: Surface ()12{13maxh = 1e10;14name = new char[7];15strcpy (name, "noname");16bcprop = -1;17bcname = "default";18}1920Surface :: ~Surface()21{22delete [] name;23}242526void Surface :: SetName (const char * aname)27{28delete [] name;29name = new char[strlen (aname)+1];30strcpy (name, aname);31}323334int Surface :: PointOnSurface (const Point<3> & p,35double eps) const36{37double val = CalcFunctionValue (p);38return fabs (val) < eps;39}404142void Surface :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const43{44double dx = 1e-5;45Point<3> hp1, hp2;46Vec<3> g1, g2;4748for (int i = 0; i < 3; i++)49{50hp1 = point;51hp2 = point;5253hp1(i) += dx;54hp2(i) -= dx;5556CalcGradient (hp1, g1);57CalcGradient (hp2, g2);5859for (int j = 0; j < 3; j++)60hesse(i, j) = (g1(j) - g2(j)) / (2 * dx);61}62}6364/*65void Surface :: GetNormalVector (const Point<3> & p, Vec<3> & n) const66{67CalcGradient (p, n);68n.Normalize();69}70*/71Vec<3> Surface :: GetNormalVector (const Point<3> & p) const72{73Vec<3> n;74CalcGradient (p, n);75n.Normalize();76return n;77}7879void Surface :: DefineTangentialPlane (const Point<3> & ap1,80const Point<3> & ap2)81{82p1 = ap1;83p2 = ap2;8485ez = GetNormalVector (p1);86ex = p2 - p1;87ex -= (ex * ez) * ez;88ex.Normalize();89ey = Cross (ez, ex);90}9192void Surface :: ToPlane (const Point<3> & p3d, Point<2> & pplane,93double h, int & zone) const94{95Vec<3> p1p, n;9697n = GetNormalVector (p3d);98if (n * ez < 0)99{100zone = -1;101pplane(0) = 1e8;102pplane(1) = 1e9;103return;104}105106p1p = p3d - p1;107pplane(0) = (p1p * ex) / h;108pplane(1) = (p1p * ey) / h;109zone = 0;110}111112void Surface :: FromPlane (const Point<2> & pplane,113Point<3> & p3d, double h) const114{115p3d = p1116+ (h * pplane(0)) * ex117+ (h * pplane(1)) * ey;118119Project (p3d);120}121122void Surface :: Project (Point<3> & p) const123{124Vec<3> n;125double val;126127for (int i = 1; i <= 10; i++)128{129val = CalcFunctionValue (p);130if (fabs (val) < 1e-12) return;131132CalcGradient (p, n);133p -= (val / Abs2 (n)) * n;134}135}136137void Surface :: SkewProject (Point<3> & p, const Vec<3> & direction) const138{139Point<3> startp(p);140double t_old(0),t_new(1);141Vec<3> grad;142for(int i=0; fabs(t_old-t_new) > 1e-20 && i<15; i++)143{144t_old = t_new;145CalcGradient(p,grad);146t_new = t_old - CalcFunctionValue(p)/(grad*direction);147p = startp + t_new*direction;148}149}150151152double Surface :: MaxCurvature () const153{154return 0.5 * HesseNorm ();155}156157double Surface ::158MaxCurvatureLoc (const Point<3> & /* c */ , double /* rad */) const159{160return MaxCurvature ();161}162163164165double Surface :: LocH (const Point<3> & p, double x,166double c, double hmax) const167// finds h <= hmax, s.t. h * \kappa_x*h < c168{169/*170double h, hmin, kappa;171hmin = 0;172173while (hmin < 0.9 * hmax)174{175h = 0.5 * (hmin + hmax);176kappa = 2 * MaxCurvatureLoc (p, x * h);177178if (kappa * h >= c)179hmax = h;180else181hmin = h;182}183return h;184*/185186double hret;187double kappa = MaxCurvatureLoc (p, x*hmax);188189kappa *= c * mparam.curvaturesafety;190191if (hmax * kappa < 1)192hret = hmax;193else194hret = 1 / kappa;195196if (maxh < hret)197hret = maxh;198199return hret;200}201202203204205Primitive :: Primitive ()206{207surfaceids.SetSize (1);208surfaceactive.SetSize (1);209surfaceactive[0] = 1;210}211212Primitive :: ~Primitive()213{214;215}216217int Primitive :: GetSurfaceId (int i) const218{219return surfaceids[i];220}221222void Primitive :: SetSurfaceId (int i, int id)223{224surfaceids[i] = id;225}226227228229230void Primitive :: GetPrimitiveData (const char *& classname,231ARRAY<double> & coeffs) const232{233classname = "undef";234coeffs.SetSize (0);235}236237void Primitive :: SetPrimitiveData (ARRAY<double> & coeffs)238{239;240}241242Primitive * Primitive :: CreatePrimitive (const char * classname)243{244if (strcmp (classname, "sphere") == 0)245return Sphere::CreateDefault();246if (strcmp (classname, "plane") == 0)247return Plane::CreateDefault();248if (strcmp (classname, "cylinder") == 0)249return Cylinder::CreateDefault();250if (strcmp (classname, "cone") == 0)251return Cone::CreateDefault();252if (strcmp (classname, "brick") == 0)253return Brick::CreateDefault();254255256stringstream ost;257ost << "Primitve::CreatePrimitive not implemented for " << classname << endl;258throw NgException (ost.str());259}260261262Primitive * Primitive :: Copy () const263{264stringstream ost;265ost << "Primitve::Copy not implemented for " << typeid(*this).name() << endl;266throw NgException (ost.str());267}268269270void Primitive :: Transform (Transformation<3> & trans)271{272stringstream ost;273ost << "Primitve::Transform not implemented for " << typeid(*this).name() << endl;274throw NgException (ost.str());275}276277void Primitive :: GetTangentialSurfaceIndices (const Point<3> & p,278ARRAY<int> & surfind, double eps) const279{280for (int j = 0; j < GetNSurfaces(); j++)281if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps)282if (!surfind.Contains (GetSurfaceId(j)))283surfind.Append (GetSurfaceId(j));284}285286287void Primitive ::288GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v,289ARRAY<int> & surfind, double eps) const290{291cout << "get tangvecsurfind not implemented" << endl;292surfind.SetSize (0);293}294295void Primitive ::296GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2,297ARRAY<int> & surfind, double eps) const298{299for (int j = 0; j < GetNSurfaces(); j++)300{301if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps)302{303Vec<3> grad;304GetSurface(j).CalcGradient (p, grad);305if (sqr (grad * v1) < 1e-6 * v1.Length2() * grad.Length2() &&306sqr (grad * v2) < 1e-6 * v2.Length2() * grad.Length2() ) // new, 18032006 JS307{308if (!surfind.Contains (GetSurfaceId(j)))309surfind.Append (GetSurfaceId(j));310}311}312}313}314315316317318INSOLID_TYPE Primitive ::319VecInSolid2 (const Point<3> & p,320const Vec<3> & v1,321const Vec<3> & v2,322double eps) const323{324//(*testout) << "Primitive::VecInSolid2" << endl;325Point<3> hp = p + 1e-3 * v1 + 1e-5 * v2;326327INSOLID_TYPE res = PointInSolid (hp, eps);328// (*testout) << "vectorin2, type = " << typeid(*this).name() << ", res = " << res << endl;329330return res;331}332333INSOLID_TYPE Primitive ::334VecInSolid3 (const Point<3> & p,335const Vec<3> & v1,336const Vec<3> & v2,337double eps) const338{339//(*testout) << "Primitive::VecInSolid3" << endl;340return VecInSolid (p, v1, eps);341}342343INSOLID_TYPE Primitive ::344VecInSolid4 (const Point<3> & p,345const Vec<3> & v,346const Vec<3> & v2,347const Vec<3> & m,348double eps) const349{350return VecInSolid2 (p, v, m, eps);351}352353354355356357OneSurfacePrimitive :: OneSurfacePrimitive()358{359;360}361362OneSurfacePrimitive :: ~OneSurfacePrimitive()363{364;365}366367368INSOLID_TYPE OneSurfacePrimitive ::369PointInSolid (const Point<3> & p,370double eps) const371{372double hv1 = (GetSurface(0).CalcFunctionValue(p));373if (hv1 <= -eps)374return IS_INSIDE;375if (hv1 >= eps)376return IS_OUTSIDE;377return DOES_INTERSECT;378}379380381INSOLID_TYPE OneSurfacePrimitive ::382VecInSolid (const Point<3> & p, const Vec<3> & v,383double eps) const384{385double hv1 = (GetSurface(0).CalcFunctionValue(p));386if (hv1 <= -eps)387return IS_INSIDE;388if (hv1 >= eps)389return IS_OUTSIDE;390391392Vec<3> hv;393GetSurface(0).CalcGradient (p, hv);394395hv1 = v * hv;396397if (hv1 <= -eps)398return IS_INSIDE;399if (hv1 >= eps)400return IS_OUTSIDE;401402return DOES_INTERSECT;403}404405406INSOLID_TYPE OneSurfacePrimitive ::407VecInSolid2 (const Point<3> & p,408const Vec<3> & v1,409const Vec<3> & v2,410double eps) const411{412double hv1 = (GetSurface(0).CalcFunctionValue(p));413if (hv1 <= -eps)414return IS_INSIDE;415if (hv1 >= eps)416return IS_OUTSIDE;417418Vec<3> hv;419420GetSurface(0).CalcGradient (p, hv);421422hv1 = v1 * hv;423if (hv1 <= -eps)424return IS_INSIDE;425if (hv1 >= eps)426return IS_OUTSIDE;427428double hv2 = v2 * hv;429if (hv2 <= 0)430return IS_INSIDE;431else432return IS_OUTSIDE;433}434435436437INSOLID_TYPE OneSurfacePrimitive ::438VecInSolid3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,439double eps) const440{441//(*testout) << "OneSurfacePrimitive::VecInSolid3" << endl;442double hv1 = (GetSurface(0).CalcFunctionValue(p));443if (hv1 <= -eps)444return IS_INSIDE;445if (hv1 >= eps)446return IS_OUTSIDE;447448Vec<3> grad;449GetSurface(0).CalcGradient (p, grad);450451hv1 = v * grad;452if (hv1 <= -eps) return IS_INSIDE;453if (hv1 >= eps) return IS_OUTSIDE;454455Mat<3> hesse;456GetSurface(0).CalcHesse (p, hesse);457458double hv2 = v2 * grad + v * (hesse * v);459460if (hv2 <= -eps) return IS_INSIDE;461if (hv2 >= eps) return IS_OUTSIDE;462463return DOES_INTERSECT;464}465466467468469INSOLID_TYPE OneSurfacePrimitive ::470VecInSolid4 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,471const Vec<3> & m,472double eps) const473{474double hv1 = (GetSurface(0).CalcFunctionValue(p));475if (hv1 <= -eps)476return IS_INSIDE;477if (hv1 >= eps)478return IS_OUTSIDE;479480Vec<3> grad;481GetSurface(0).CalcGradient (p, grad);482483hv1 = v * grad;484if (hv1 <= -eps) return IS_INSIDE;485if (hv1 >= eps) return IS_OUTSIDE;486487Mat<3> hesse;488GetSurface(0).CalcHesse (p, hesse);489490double hv2 = v2 * grad + v * (hesse * v);491492if (hv2 <= -eps) return IS_INSIDE;493if (hv2 >= eps) return IS_OUTSIDE;494495496double hv3 = m * grad;497if (hv3 <= -eps) return IS_INSIDE;498if (hv3 >= eps) return IS_OUTSIDE;499500return DOES_INTERSECT;501}502503504505506507508509int OneSurfacePrimitive :: GetNSurfaces() const510{511return 1;512}513514Surface & OneSurfacePrimitive :: GetSurface (int i)515{516return *this;517}518519const Surface & OneSurfacePrimitive :: GetSurface (int i) const520{521return *this;522}523524525526527528529void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp)530{531Vec<2> rs, lam;532Vec<3> a1, a2;533Mat<2> a;534535int i = 10;536while (i > 0)537{538i--;539rs(0) = f1 -> CalcFunctionValue (hp);540rs(1) = f2 -> CalcFunctionValue (hp);541f1->CalcGradient (hp, a1);542f2->CalcGradient (hp, a2);543544double alpha = fabs(a1*a2)/sqrt(a1.Length2()*a2.Length2());545if(fabs(1.-alpha) < 1e-6)546{547if(fabs(rs(0)) >= fabs(rs(1)))548f1 -> Project(hp);549else550f2 -> Project(hp);551}552else553{554555a(0,0) = a1 * a1;556a(0,1) = a(1,0) = a1 * a2;557a(1,1) = a2 * a2;558559a.Solve (rs, lam);560561hp -= lam(0) * a1 + lam(1) * a2;562}563564if (Abs2 (rs) < 1e-24 && i > 1) i = 1;565}566}567}568569570