Path: blob/devel/ElmerGUI/netgen/libsrc/csg/brick.cpp
3206 views
#include <mystdlib.h>12#include <linalg.hpp>3#include <csg.hpp>45namespace netgen6{78Parallelogram3d :: Parallelogram3d (Point<3> ap1, Point<3> ap2, Point<3> ap3)9{10p1 = ap1;11p2 = ap2;12p3 = ap3;1314CalcData();15}1617Parallelogram3d ::~Parallelogram3d ()18{19;20}2122void Parallelogram3d :: SetPoints (Point<3> ap1,23Point<3> ap2,24Point<3> ap3)25{26p1 = ap1;27p2 = ap2;28p3 = ap3;2930CalcData();31}3233void Parallelogram3d :: CalcData()34{35v12 = p2 - p1;36v13 = p3 - p1;37p4 = p2 + v13;3839n = Cross (v12, v13);40n.Normalize();41}4243int Parallelogram3d ::44IsIdentic (const Surface & s2, int & inv, double eps) const45{46int id =47(fabs (s2.CalcFunctionValue (p1)) <= eps) &&48(fabs (s2.CalcFunctionValue (p2)) <= eps) &&49(fabs (s2.CalcFunctionValue (p3)) <= eps);5051if (id)52{53Vec<3> n2;54n2 = s2.GetNormalVector(p1);55inv = (n * n2) < 0;56}57return id;58}596061double Parallelogram3d :: CalcFunctionValue (const Point<3> & point) const62{63return n * (point - p1);64}6566void Parallelogram3d :: CalcGradient (const Point<3> & point,67Vec<3> & grad) const68{69grad = n;70}7172void Parallelogram3d :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const73{74hesse = 0;75}7677double Parallelogram3d :: HesseNorm () const78{79return 0;80}8182Point<3> Parallelogram3d :: GetSurfacePoint () const83{84return p1;85}8687void Parallelogram3d :: Print (ostream & str) const88{89str << "Parallelogram3d " << p1 << " - " << p2 << " - " << p3 << endl;90}919293void Parallelogram3d ::94GetTriangleApproximation (TriangleApproximation & tas,95const Box<3> & bbox,96double facets) const97{98tas.AddPoint (p1);99tas.AddPoint (p2);100tas.AddPoint (p3);101tas.AddPoint (p4);102tas.AddTriangle (TATriangle (0, 0, 1, 2));103tas.AddTriangle (TATriangle (0, 2, 1, 3));104}105106107108109110111112113114115Brick :: Brick (Point<3> ap1, Point<3> ap2,116Point<3> ap3, Point<3> ap4)117{118faces.SetSize (6);119surfaceids.SetSize (6);120surfaceactive.SetSize(6);121122p1 = ap1; p2 = ap2;123p3 = ap3; p4 = ap4;124125for (int i = 0; i < 6; i++)126{127faces[i] = new Plane (Point<3>(0,0,0), Vec<3> (0,0,1));128surfaceactive[i] = 1;129}130131CalcData();132}133134Brick :: ~Brick ()135{136for (int i = 0; i < 6; i++)137delete faces[i];138}139140Primitive * Brick :: CreateDefault ()141{142return new Brick (Point<3> (0,0,0),143Point<3> (1,0,0),144Point<3> (0,1,0),145Point<3> (0,0,1));146}147148149150Primitive * Brick :: Copy () const151{152return new Brick (p1, p2, p3, p4);153}154155void Brick :: Transform (Transformation<3> & trans)156{157trans.Transform (p1);158trans.Transform (p2);159trans.Transform (p3);160trans.Transform (p4);161162CalcData();163}164165166167168169170171172173INSOLID_TYPE Brick :: BoxInSolid (const BoxSphere<3> & box) const174{175/*176int i;177double maxval;178for (i = 1; i <= 6; i++)179{180double val = faces.Get(i)->CalcFunctionValue (box.Center());181if (i == 1 || val > maxval)182maxval = val;183}184185if (maxval > box.Diam()) return IS_OUTSIDE;186if (maxval < -box.Diam()) return IS_INSIDE;187return DOES_INTERSECT;188*/189190bool inside = 1;191bool outside = 0;192193Point<3> p[8];194for (int j = 0; j < 8; j++)195p[j] = box.GetPointNr(j);196197for (int i = 0; i < 6; i++)198{199bool outsidei = 1;200for (int j = 0; j < 8; j++)201{202// Point<3> p = box.GetPointNr (j);203double val = faces[i]->Plane::CalcFunctionValue (p[j]);204205if (val > 0) inside = 0;206if (val < 0) outsidei = 0;207}208if (outsidei) outside = 1;209}210211if (outside) return IS_OUTSIDE;212if (inside) return IS_INSIDE;213return DOES_INTERSECT;214}215216INSOLID_TYPE Brick :: PointInSolid (const Point<3> & p,217double eps) const218{219double maxval = faces[0] -> Plane::CalcFunctionValue (p);220for (int i = 1; i < 6; i++)221{222double val = faces[i] -> Plane::CalcFunctionValue (p);223if (val > maxval) maxval = val;224}225226if (maxval > eps) return IS_OUTSIDE;227if (maxval < -eps) return IS_INSIDE;228return DOES_INTERSECT;229}230231232INSOLID_TYPE Brick :: VecInSolid (const Point<3> & p,233const Vec<3> & v,234double eps) const235{236INSOLID_TYPE result = IS_INSIDE;237for (int i = 0; i < faces.Size(); i++)238{239INSOLID_TYPE hres = faces[i]->VecInSolid(p, v, eps);240if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE;241else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT;242else result = IS_INSIDE;243}244return result;245246/*247INSOLID_TYPE is = IS_INSIDE;248Vec<3> grad;249double scal;250251for (int i = 0; i < faces.Size(); i++)252{253if (faces[i] -> PointOnSurface (p, eps))254{255GetSurface(i).CalcGradient (p, grad);256scal = v * grad;257258if (scal >= eps)259is = IS_OUTSIDE;260if (scal >= -eps && is == IS_INSIDE)261is = DOES_INTERSECT;262}263}264return is;265*/266267/*268Point<3> p2 = p + 1e-2 * v;269return PointInSolid (p2, eps);270*/271}272273274275276277INSOLID_TYPE Brick :: VecInSolid2 (const Point<3> & p,278const Vec<3> & v1,279const Vec<3> & v2,280double eps) const281{282INSOLID_TYPE result = IS_INSIDE;283for (int i = 0; i < faces.Size(); i++)284{285INSOLID_TYPE hres = faces[i]->VecInSolid2(p, v1, v2, eps);286if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE;287else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT;288else result = IS_INSIDE;289}290return result;291}292293INSOLID_TYPE Brick :: VecInSolid3 (const Point<3> & p,294const Vec<3> & v1,295const Vec<3> & v2,296double eps) const297{298INSOLID_TYPE result = IS_INSIDE;299for (int i = 0; i < faces.Size(); i++)300{301INSOLID_TYPE hres = faces[i]->VecInSolid3(p, v1, v2, eps);302if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE;303else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT;304else result = IS_INSIDE;305}306return result;307}308309INSOLID_TYPE Brick :: VecInSolid4 (const Point<3> & p,310const Vec<3> & v,311const Vec<3> & v2,312const Vec<3> & m,313double eps) const314{315INSOLID_TYPE result = IS_INSIDE;316for (int i = 0; i < faces.Size(); i++)317{318INSOLID_TYPE hres = faces[i]->VecInSolid4(p, v, v2, m, eps);319if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE;320else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT;321else result = IS_INSIDE;322}323return result;324}325326327328329330331332333334335336337338339340341342343344void Brick ::345GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const346{347classname = "brick";348coeffs.SetSize(12);349coeffs.Elem(1) = p1(0);350coeffs.Elem(2) = p1(1);351coeffs.Elem(3) = p1(2);352353coeffs.Elem(4) = p2(0);354coeffs.Elem(5) = p2(1);355coeffs.Elem(6) = p2(2);356357coeffs.Elem(7) = p3(0);358coeffs.Elem(8) = p3(1);359coeffs.Elem(9) = p3(2);360361coeffs.Elem(10) = p4(0);362coeffs.Elem(11) = p4(1);363coeffs.Elem(12) = p4(2);364}365366void Brick :: SetPrimitiveData (ARRAY<double> & coeffs)367{368p1(0) = coeffs.Elem(1);369p1(1) = coeffs.Elem(2);370p1(2) = coeffs.Elem(3);371372p2(0) = coeffs.Elem(4);373p2(1) = coeffs.Elem(5);374p2(2) = coeffs.Elem(6);375376p3(0) = coeffs.Elem(7);377p3(1) = coeffs.Elem(8);378p3(2) = coeffs.Elem(9);379380p4(0) = coeffs.Elem(10);381p4(1) = coeffs.Elem(11);382p4(2) = coeffs.Elem(12);383384CalcData();385}386387388389void Brick :: CalcData()390{391v12 = p2 - p1;392v13 = p3 - p1;393v14 = p4 - p1;394395Point<3> pi[8];396int i1, i2, i3;397int i, j;398399i = 0;400for (i3 = 0; i3 <= 1; i3++)401for (i2 = 0; i2 <= 1; i2++)402for (i1 = 0; i1 <= 1; i1++)403{404pi[i] = p1 + i1 * v12 + i2 * v13 + i3 * v14;405i++;406}407408static int lface[6][4] =409{ { 1, 3, 2, 4 },410{ 5, 6, 7, 8 },411{ 1, 2, 5, 6 },412{ 3, 7, 4, 8 },413{ 1, 5, 3, 7 },414{ 2, 4, 6, 8 } };415416ARRAY<double> data(6);417for (i = 0; i < 6; i++)418{419const Point<3> lp1 = pi[lface[i][0]-1];420const Point<3> lp2 = pi[lface[i][1]-1];421const Point<3> lp3 = pi[lface[i][2]-1];422423Vec<3> n = Cross ((lp2-lp1), (lp3-lp1));424n.Normalize();425426for (j = 0; j < 3; j++)427{428data[j] = lp1(j);429data[j+3] = n(j);430}431faces[i] -> SetPrimitiveData (data);432/*433{434faces.Elem(i+1) -> SetPoints435(pi[lface[i][0]-1],436pi[lface[i][1]-1],437pi[lface[i][2]-1]);438}439*/440}441}442443444void Brick :: Reduce (const BoxSphere<3> & box)445{446double val;447// Point<3> p;448Point<3> p[8];449for(int j=0;j<8;j++)450p[j]=box.GetPointNr(j);451452for (int i = 0; i < 6; i++)453{454bool hasout = 0;455bool hasin = 0;456for (int j = 0; j < 8; j++)457{458// p = box.GetPointNr (j);459val = faces[i]->Plane::CalcFunctionValue (p[j]);460if (val > 0) hasout = 1;461else if (val < 0) hasin = 1;462if (hasout && hasin) break;463}464surfaceactive[i] = hasout && hasin;465}466}467468void Brick :: UnReduce ()469{470for (int i = 0; i < 6; i++)471surfaceactive[i] = 1;472}473474475476OrthoBrick :: OrthoBrick (const Point<3> & ap1, const Point<3> & ap2)477: Brick (ap1,478Point<3> (ap2(0), ap1(1), ap1(2)),479Point<3> (ap1(0), ap2(1), ap1(2)),480Point<3> (ap1(0), ap1(1), ap2(2)))481{482pmin = ap1;483pmax = ap2;484}485486INSOLID_TYPE OrthoBrick :: BoxInSolid (const BoxSphere<3> & box) const487{488if (pmin(0) > box.PMax()(0) ||489pmin(1) > box.PMax()(1) ||490pmin(2) > box.PMax()(2) ||491pmax(0) < box.PMin()(0) ||492pmax(1) < box.PMin()(1) ||493pmax(2) < box.PMin()(2))494return IS_OUTSIDE;495496if (pmin(0) < box.PMin()(0) &&497pmin(1) < box.PMin()(1) &&498pmin(2) < box.PMin()(2) &&499pmax(0) > box.PMax()(0) &&500pmax(1) > box.PMax()(1) &&501pmax(2) > box.PMax()(2))502return IS_INSIDE;503504return DOES_INTERSECT;505}506507508void OrthoBrick :: Reduce (const BoxSphere<3> & box)509{510surfaceactive.Elem(1) =511(box.PMin()(2) < pmin(2)) && (pmin(2) < box.PMax()(2));512surfaceactive.Elem(2) =513(box.PMin()(2) < pmax(2)) && (pmax(2) < box.PMax()(2));514515surfaceactive.Elem(3) =516(box.PMin()(1) < pmin(1)) && (pmin(1) < box.PMax()(1));517surfaceactive.Elem(4) =518(box.PMin()(1) < pmax(1)) && (pmax(1) < box.PMax()(1));519520surfaceactive.Elem(5) =521(box.PMin()(0) < pmin(0)) && (pmin(0) < box.PMax()(0));522surfaceactive.Elem(6) =523(box.PMin()(0) < pmax(0)) && (pmax(0) < box.PMax()(0));524}525}526527528