Path: blob/devel/ElmerGUI/netgen/libsrc/csg/csgeom.cpp
3206 views
#include <mystdlib.h>1#include <myadt.hpp>23#include <linalg.hpp>4#include <csg.hpp>567namespace netgen8{910int CSGeometry :: changeval = 0;11121314TopLevelObject ::15TopLevelObject (Solid * asolid,16Surface * asurface)17{18solid = asolid;19surface = asurface;2021SetRGB (0, 0, 1);22SetTransparent (0);23SetVisible (1);24SetLayer (1);2526if (!surface)27maxh = solid->GetMaxH();28else29maxh = surface->GetMaxH();3031SetBCProp (-1);3233bcname = "default";34}3536void TopLevelObject :: GetData (ostream & ost)37{38ost << red << " " << green << " " << blue << " "39<< transp << " " << visible << " ";40}4142void TopLevelObject :: SetData (istream & ist)43{44ist >> red >> green >> blue >> transp >> visible;45}46474849Box<3> CSGeometry::default_boundingbox (Point<3> (-1000, -1000, -1000),50Point<3> ( 1000, 1000, 1000));515253CSGeometry :: CSGeometry ()54: boundingbox (default_boundingbox),55identicsurfaces (100), filename(""), ideps(1e-9)56{57;58}5960CSGeometry :: CSGeometry (const string & afilename)61: boundingbox (default_boundingbox),62identicsurfaces (100), filename(afilename), ideps(1e-9)63{64changeval++;65}6667CSGeometry :: ~CSGeometry ()68{69Clean();70}717273void CSGeometry :: Clean ()74{75ARRAY< Solid* > to_delete;7677for (int i = 0; i < solids.Size(); i++)78if(!to_delete.Contains(solids[i]->S1()))79to_delete.Append(solids[i]->S1());80for (int i = 0; i < solids.Size(); i++)81if(!to_delete.Contains(solids[i]))82to_delete.Append(solids[i]);83for(int i = 0; i < to_delete.Size(); i++)84delete to_delete[i];8586/*87for (int i = 0; i < solids.Size(); i++)88delete solids[i]->S1();89for (int i = 0; i < solids.Size(); i++)90delete solids[i];91*/9293solids.DeleteAll ();9495for (int i = 0; i < splinecurves2d.Size(); i++)96delete splinecurves2d[i];97splinecurves2d.DeleteAll();9899/*100for (int i = 0; i < surfaces.Size(); i++)101delete surfaces[i];102surfaces.DeleteAll ();103*/104for(int i = 0; i<delete_them.Size(); i++)105delete delete_them[i];106delete_them.DeleteAll();107surfaces.DeleteAll();108109for (int i = 0; i < toplevelobjects.Size(); i++)110delete toplevelobjects[i];111toplevelobjects.DeleteAll ();112for (int i = 0; i < triapprox.Size(); i++)113delete triapprox[i];114triapprox.DeleteAll();115116for(int i = 0; i < identifications.Size(); i++)117delete identifications[i];118identifications.DeleteAll();119120for (int i = 0; i < singfaces.Size(); i++)121delete singfaces[i];122singfaces.DeleteAll();123for (int i = 0; i < singedges.Size(); i++)124delete singedges[i];125singedges.DeleteAll();126for (int i = 0; i < singpoints.Size(); i++)127delete singpoints[i];128singpoints.DeleteAll();129130changeval++;131}132133134135136137class WritePrimitivesIt : public SolidIterator138{139ostream & ost;140public:141WritePrimitivesIt (ostream & aost) : ost(aost) { ; }142virtual ~WritePrimitivesIt () { ; }143144virtual void Do (Solid * sol);145};146147void WritePrimitivesIt :: Do (Solid * sol)148{149Primitive * prim = sol->GetPrimitive();150if (prim)151{152const char * classname;153ARRAY<double> coeffs;154155prim -> GetPrimitiveData (classname, coeffs);156157if (sol->Name())158ost << "primitive "159<< sol->Name() << " "160<< classname << " " << coeffs.Size();161for (int i = 0; i < coeffs.Size(); i++)162ost << " " << coeffs[i];163ost << endl;164}165}166167168169170void CSGeometry :: Save (ostream & ost)171{172ost << "boundingbox "173<< boundingbox.PMin()(0) << " "174<< boundingbox.PMin()(1) << " "175<< boundingbox.PMin()(2) << " "176<< boundingbox.PMax()(0) << " "177<< boundingbox.PMax()(1) << " "178<< boundingbox.PMax()(2) << endl;179180181WritePrimitivesIt wpi(ost);182IterateAllSolids (wpi, 1);183184for (int i = 0; i < solids.Size(); i++)185{186if (!solids[i]->GetPrimitive())187{188ost << "solid " << solids.GetName(i) << " ";189solids[i] -> GetSolidData (ost);190ost << endl;191}192}193194for (int i = 0; i < GetNTopLevelObjects(); i++)195{196TopLevelObject * tlo = GetTopLevelObject (i);197ost << "toplevel ";198if (tlo -> GetSurface())199ost << "surface " << tlo->GetSolid()->Name() << " "200<< tlo->GetSurface()->Name() << " ";201else202ost << "solid " << tlo->GetSolid()->Name() << " ";203tlo->GetData(ost);204ost << endl;205}206207for (int i = 0; i < identifications.Size(); i++)208{209ost << "identify ";210identifications[i] -> GetData (ost);211ost << endl;212}213214ost << "end" << endl;215}216217218void CSGeometry :: Load (istream & ist)219{220// CSGeometry * geo = new CSGeometry;221222char key[100], name[100], classname[100], sname[100];223int ncoeff, i, j;224ARRAY<double> coeff;225226while (ist.good())227{228ist >> key;229if (strcmp (key, "boundingbox") == 0)230{231Point<3> pmin, pmax;232ist >> pmin(0) >> pmin(1) >> pmin(2);233ist >> pmax(0) >> pmax(1) >> pmax(2);234SetBoundingBox (Box<3> (pmin, pmax));235}236if (strcmp (key, "primitive") == 0)237{238ist >> name >> classname >> ncoeff;239coeff.SetSize (ncoeff);240for (i = 0; i < ncoeff; i++)241ist >> coeff[i];242243Primitive * nprim = Primitive::CreatePrimitive (classname);244nprim -> SetPrimitiveData (coeff);245Solid * nsol = new Solid (nprim);246247for (j = 0; j < nprim->GetNSurfaces(); j++)248{249sprintf (sname, "%s,%d", name, j);250AddSurface (sname, &nprim->GetSurface(j));251nprim -> SetSurfaceId (j, GetNSurf());252}253SetSolid (name, nsol);254}255else if (strcmp (key, "solid") == 0)256{257ist >> name;258Solid * nsol = Solid::CreateSolid (ist, solids);259260cout << " I have found solid " << name << " = ";261nsol -> GetSolidData (cout);262cout << endl;263264SetSolid (name, nsol);265}266else if (strcmp (key, "toplevel") == 0)267{268char type[20], solname[50], surfname[50];269const Solid * sol = NULL;270const Surface * surf = NULL;271int nr;272273ist >> type;274if (strcmp (type, "solid") == 0)275{276ist >> solname;277sol = GetSolid (solname);278}279if (strcmp (type, "surface") == 0)280{281ist >> solname >> surfname;282sol = GetSolid (solname);283surf = GetSurface (surfname);284}285nr = SetTopLevelObject ((Solid*)sol, (Surface*)surf);286GetTopLevelObject (nr) -> SetData (ist);287}288else if (strcmp (key, "identify") == 0)289{290char type[10], surfname1[50], surfname2[50];291const Surface * surf1;292const Surface * surf2;293294295ist >> type >> surfname1 >> surfname2;296surf1 = GetSurface(surfname1);297surf2 = GetSurface(surfname2);298299AddIdentification (new PeriodicIdentification300(GetNIdentifications(),301*this, surf1, surf2));302}303else if (strcmp (key, "end") == 0)304break;305}306307changeval++;308}309310311312void CSGeometry :: SaveSurfaces (ostream & out)313{314if(singfaces.Size() > 0 || singedges.Size() > 0 || singpoints.Size() > 0)315{316PrintMessage(3,"Singular faces/edges/points => no csg-information in .vol file");317return;318}319320321322ARRAY<double> coeffs;323const char * classname;324325out << "csgsurfaces " << GetNSurf() << "\n";326for(int i=0; i<GetNSurf(); i++)327{328const OneSurfacePrimitive * sp = dynamic_cast< const OneSurfacePrimitive * > (GetSurface(i));329const ExtrusionFace * ef = dynamic_cast< const ExtrusionFace * > (GetSurface(i));330const RevolutionFace * rf = dynamic_cast< const RevolutionFace * > (GetSurface(i));331332333if(sp)334{335sp->GetPrimitiveData(classname,coeffs);336337out << classname << " ";338}339else if(ef)340{341out << "extrusionface ";342ef->GetRawData(coeffs);343}344else if(rf)345{346out << "revolutionface ";347rf->GetRawData(coeffs);348}349else350throw NgException ("Cannot write csg surface. Please, contact developers!");351352353out << coeffs.Size() << "\n";354for(int j=0; j<coeffs.Size(); j++)355out << coeffs[j] << " ";356357out << "\n";358}359}360361void CSGeometry :: LoadSurfaces (istream & in)362{363ARRAY<double> coeffs;364string classname;365int nsurfaces,size;366367in >> classname;368369if(classname == "csgsurfaces")370in >> nsurfaces;371else372nsurfaces = atoi(classname.c_str());373374Point<3> dummypoint(0,0,0);375Vec<3> dummyvec(0,0,0);376double dummydouble(0.1);377378for(int i=0; i<nsurfaces; i++)379{380in >> classname;381in >> size;382383coeffs.SetSize(size);384385for(int j=0; j<size; j++)386in >> coeffs[j];387388if(classname == "plane")389{390Plane * plane = new Plane(dummypoint,dummyvec);391plane->SetPrimitiveData(coeffs);392393AddSurface(plane);394delete_them.Append(plane);395}396397else if(classname == "sphere")398{399Sphere * sphere = new Sphere(dummypoint,dummydouble);400sphere->SetPrimitiveData(coeffs);401402AddSurface(sphere);403delete_them.Append(sphere);404}405406else if(classname == "cylinder")407{408Cylinder * cylinder = new Cylinder(coeffs);409410AddSurface(cylinder);411delete_them.Append(cylinder);412}413414else if(classname == "cone")415{416Cone * cone = new Cone(dummypoint,dummypoint,dummydouble,dummydouble);417cone->SetPrimitiveData(coeffs);418419AddSurface(cone);420delete_them.Append(cone);421}422423else if(classname == "extrusionface")424{425ExtrusionFace * ef =426new ExtrusionFace(coeffs);427428AddSurface(ef);429delete_them.Append(ef);430}431432else if(classname == "revolutionface")433{434RevolutionFace * rf =435new RevolutionFace(coeffs);436437AddSurface(rf);438delete_them.Append(rf);439}440}441}442443444445446447448void CSGeometry :: AddSurface (Surface * surf)449{450static int cntsurfs = 0;451cntsurfs++;452char name[17];453sprintf (name, "nnsurf%d", cntsurfs);454AddSurface (name, surf);455}456457void CSGeometry :: AddSurface (char * name, Surface * surf)458{459(*testout) << "Adding surface " << name << endl;460surfaces.Set (name, surf);461surf->SetName (name);462changeval++;463}464465void CSGeometry :: AddSurfaces (Primitive * prim)466{467for (int i = 0; i < prim->GetNSurfaces(); i++)468{469AddSurface (&prim->GetSurface(i));470prim->SetSurfaceId (i, GetNSurf()-1);471surf2prim.Append (prim);472}473}474475const Surface * CSGeometry :: GetSurface (const char * name) const476{477if (surfaces.Used(name))478return surfaces.Get(name);479else480return NULL;481}482483/*484const Surface * CSGeometry :: GetSurface (int i) const485{486if (i >= 0 && i < surfaces.Size())487return surfaces[i];488else489throw NgException ("CSGeometry::GetSurface out of range");490}491*/492493494495496void CSGeometry :: SetSolid (const char * name, Solid * sol)497{498Solid * oldsol = NULL;499500if (solids.Used (name))501oldsol = solids.Get(name);502503solids.Set (name, sol);504sol->SetName (name);505506if (oldsol)507{508if (oldsol->op != Solid::ROOT ||509sol->op != Solid::ROOT)510{511cerr << "Setsolid: old or new no root" << endl;512}513oldsol -> s1 = sol -> s1;514}515changeval++;516}517518const Solid * CSGeometry :: GetSolid (const char * name) const519{520if (solids.Used(name))521return solids.Get(name);522else523return NULL;524}525526527528529530const Solid * CSGeometry :: GetSolid (const string & name) const531{532if (solids.Used(name.c_str()))533return solids.Get(name.c_str());534else535return NULL;536}537538539540541void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<2> * spl)542{543splinecurves2d.Set(name,spl);544}545void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<3> * spl)546{547splinecurves3d.Set(name,spl);548}549550551const SplineGeometry<2> * CSGeometry :: GetSplineCurve2d (const string & name) const552{553if (splinecurves2d.Used(name.c_str()))554return splinecurves2d.Get(name.c_str());555else556return NULL;557}558const SplineGeometry<3> * CSGeometry :: GetSplineCurve3d (const string & name) const559{560if (splinecurves3d.Used(name.c_str()))561return splinecurves3d.Get(name.c_str());562else563return NULL;564}565566567568569class RemoveDummyIterator : public SolidIterator570{571public:572573RemoveDummyIterator() { ; }574virtual ~RemoveDummyIterator() { ; }575virtual void Do(Solid * sol);576};577578void RemoveDummyIterator :: Do(Solid * sol)579{580if ( (sol->op == Solid::SUB || sol->op == Solid::SECTION ||581sol->op == Solid::UNION)582&& sol->s1->op == Solid::DUMMY)583sol->s1 = sol->s1->s1;584if ( (sol->op == Solid::SECTION || sol->op == Solid::UNION)585&& sol->s2->op == Solid::DUMMY)586sol->s2 = sol->s2->s1;587}588589590591592593594int CSGeometry :: SetTopLevelObject (Solid * sol, Surface * surf)595{596return toplevelobjects.Append (new TopLevelObject (sol, surf)) - 1;597}598599TopLevelObject * CSGeometry ::600GetTopLevelObject (const Solid * sol, const Surface * surf)601{602for (int i = 0; i < toplevelobjects.Size(); i++)603{604if (toplevelobjects[i]->GetSolid() == sol &&605toplevelobjects[i]->GetSurface() == surf)606return (toplevelobjects[i]);607}608return NULL;609}610611void CSGeometry :: RemoveTopLevelObject (Solid * sol, Surface * surf)612{613for (int i = 0; i < toplevelobjects.Size(); i++)614{615if (toplevelobjects[i]->GetSolid() == sol &&616toplevelobjects[i]->GetSurface() == surf)617{618delete toplevelobjects[i];619toplevelobjects.DeleteElement (i+1);620changeval++;621break;622}623}624}625626void CSGeometry :: AddIdentification (Identification * ident)627{628identifications.Append (ident);629}630631void CSGeometry :: SetFlags (const char * solidname, const Flags & flags)632{633Solid * solid = solids.Elem(solidname);634ARRAY<int> surfind;635636int i;637double maxh = flags.GetNumFlag ("maxh", -1);638if (maxh > 0 && solid)639{640solid->GetSurfaceIndices (surfind);641642for (i = 0; i < surfind.Size(); i++)643{644if (surfaces[surfind[i]]->GetMaxH() > maxh)645surfaces[surfind[i]] -> SetMaxH (maxh);646}647648solid->SetMaxH (maxh);649}650651if ( flags.StringFlagDefined ("bcname") )652{653solid->GetSurfaceIndices (surfind);654string bcn = flags.GetStringFlag("bcname", "default");655for (i = 0; i < surfind.Size(); i++)656{657if(surfaces[surfind[i]]->GetBCName() == "default")658surfaces[surfind[i]]->SetBCName(bcn);659}660}661662if (flags.StringListFlagDefined ("bcname"))663{664const ARRAY<char*> & bcname = flags.GetStringListFlag("bcname");665666Polyhedra * polyh;667if(solid->S1())668polyh = dynamic_cast<Polyhedra *>(solid->S1()->GetPrimitive());669else670polyh = dynamic_cast<Polyhedra *>(solid->GetPrimitive());671672if(polyh)673{674ARRAY < ARRAY<int> * > polysurfs;675polyh->GetPolySurfs(polysurfs);676if(bcname.Size() != polysurfs.Size())677cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size()678<< " surfaces and should get " << bcname.Size() << " bc-names!" << endl;679680for ( i = 0; i < min2(polysurfs.Size(),bcname.Size()); i++)681{682for (int j = 0; j < polysurfs[i]->Size(); j++)683{684if(surfaces[(*polysurfs[i])[j]]->GetBCName() == "default")685surfaces[(*polysurfs[i])[j]]->SetBCName(bcname[i]);686}687delete polysurfs[i];688}689}690else691{692solid->GetSurfaceIndices (surfind);693if(bcname.Size() != surfind.Size())694cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size()695<< " surfaces and should get " << bcname.Size() << " bc-names!" << endl;696697for (i = 0; i < min2(surfind.Size(),bcname.Size()); i++)698{699if(surfaces[surfind[i]]->GetBCName() == "default")700surfaces[surfind[i]]->SetBCName(bcname[i]);701}702}703}704705if (flags.NumFlagDefined ("bc"))706{707solid->GetSurfaceIndices (surfind);708int bc = int (flags.GetNumFlag("bc", -1));709for (i = 0; i < surfind.Size(); i++)710{711if (surfaces[surfind[i]]->GetBCProperty() == -1)712surfaces[surfind[i]]->SetBCProperty(bc);713}714}715716if (flags.NumListFlagDefined ("bc"))717{718const ARRAY<double> & bcnum = flags.GetNumListFlag("bc");719720Polyhedra * polyh;721if(solid->S1())722polyh = dynamic_cast<Polyhedra *>(solid->S1()->GetPrimitive());723else724polyh = dynamic_cast<Polyhedra *>(solid->GetPrimitive());725726if(polyh)727{728ARRAY < ARRAY<int> * > polysurfs;729polyh->GetPolySurfs(polysurfs);730if(bcnum.Size() != polysurfs.Size())731cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size()732<< " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl;733734for ( i = 0; i < min2(polysurfs.Size(),bcnum.Size()); i++)735{736for (int j = 0; j < polysurfs[i]->Size(); j++)737{738if ( surfaces[(*polysurfs[i])[j]]->GetBCProperty() == -1 )739surfaces[(*polysurfs[i])[j]]->SetBCProperty(int(bcnum[i]));740}741delete polysurfs[i];742}743}744else745{746solid->GetSurfaceIndices (surfind);747if(bcnum.Size() != surfind.Size())748cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size()749<< " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl;750751for (i = 0; i < min2(surfind.Size(),bcnum.Size()); i++)752{753if (surfaces[surfind[i]]->GetBCProperty() == -1)754surfaces[surfind[i]]->SetBCProperty(int(bcnum[i]));755}756}757}758759}760761void CSGeometry :: FindIdenticSurfaces (double eps)762{763int inv;764int nsurf = GetNSurf();765766isidenticto.SetSize(nsurf);767for (int i = 0; i < nsurf; i++)768isidenticto[i] = i;769770//(*testout) << "jetzt!" << endl;771for (int i = 0; i < nsurf; i++)772for (int j = i+1; j < nsurf; j++)773{774//(*testout) << "surf" << i << " surf" << j << endl;775if (GetSurface(j) -> IsIdentic (*GetSurface(i), inv, eps))776{777INDEX_2 i2(i, j);778identicsurfaces.Set (i2, inv);779isidenticto[j] = isidenticto[i];780//(*testout) << "surfaces " << i2 << " are identic" << endl;781}782}783784(*testout) << "identicmap:" << endl;785for (int i = 0; i < isidenticto.Size(); i++)786(*testout) << i << " -> " << isidenticto[i] << endl;787788/*789for (int i = 0; i < nsurf; i++)790GetSurface(i)->Print (*testout);791*/792}793794795796void CSGeometry ::797GetSurfaceIndices (const Solid * sol,798const BoxSphere<3> & box,799ARRAY<int> & locsurf) const800{801ReducePrimitiveIterator rpi(box);802UnReducePrimitiveIterator urpi;803804((Solid*)sol) -> IterateSolid (rpi);805sol -> GetSurfaceIndices (locsurf);806((Solid*)sol) -> IterateSolid (urpi);807808for (int i = locsurf.Size()-1; i >= 0; i--)809{810bool indep = 1;811for (int j = 0; j < i; j++)812if (locsurf[i] == locsurf[j])813{814indep = 0;815break;816}817818if (!indep) locsurf.Delete(i);819}820}821822823824825void CSGeometry ::826GetIndependentSurfaceIndices (const Solid * sol,827const BoxSphere<3> & box,828ARRAY<int> & locsurf) const829{830ReducePrimitiveIterator rpi(box);831UnReducePrimitiveIterator urpi;832833((Solid*)sol) -> IterateSolid (rpi);834sol -> GetSurfaceIndices (locsurf);835((Solid*)sol) -> IterateSolid (urpi);836837for (int i = 0; i < locsurf.Size(); i++)838locsurf[i] = isidenticto[locsurf[i]];839840for (int i = locsurf.Size()-1; i >= 0; i--)841{842bool indep = 1;843for (int j = 0; j < i; j++)844if (locsurf[i] == locsurf[j])845{846indep = 0;847break;848}849850if (!indep) locsurf.Delete(i);851}852853854/*855// delete identified856for (int i = locsurf.Size()-1; i >= 0; i--)857{858bool indep = 1;859for (int j = 0; j < i; j++)860{861if (identicsurfaces.Used (INDEX_2::Sort (locsurf[i], locsurf[j])) !=862(isidenticto[locsurf[i]] == isidenticto[locsurf[j]]))863{864cerr << "different result" << endl;865exit(1);866}867868if (isidenticto[locsurf[i]] == isidenticto[locsurf[j]])869{870indep = 0;871break;872}873}874if (!indep)875locsurf.Delete(i);876}877878for (int i = 0; i < locsurf.Size(); i++)879locsurf[i] = isidenticto[locsurf[i]];880*/881}882883884void CSGeometry ::885GetIndependentSurfaceIndices (const Solid * sol,886const Point<3> & p, Vec<3> & v,887ARRAY<int> & locsurf) const888{889cout << "very dangerous" << endl;890Point<3> p2 = p + 1e-2 * v;891BoxSphere<3> box (p2, p2);892box.Increase (1e-3);893box.CalcDiamCenter();894GetIndependentSurfaceIndices (sol, box, locsurf);895}896897898void CSGeometry ::899GetIndependentSurfaceIndices (ARRAY<int> & locsurf) const900{901for (int i = 0; i < locsurf.Size(); i++)902locsurf[i] = isidenticto[locsurf[i]];903904for (int i = locsurf.Size()-1; i >= 0; i--)905{906bool indep = 1;907for (int j = 0; j < i; j++)908if (locsurf[i] == locsurf[j])909{910indep = 0;911break;912}913914if (!indep) locsurf.Delete(i);915}916}917918919920921922923924925926void CSGeometry ::927CalcTriangleApproximation(const Box<3> & aboundingbox,928double detail, double facets)929{930PrintMessage (1, "Calc Triangle Approximation");931932// FindIdenticSurfaces (1e-6);933934int ntlo = GetNTopLevelObjects();935936for (int i = 0; i < triapprox.Size(); i++)937delete triapprox[i];938triapprox.SetSize (ntlo);939940ARRAY<int> surfind;941IndexSet iset(GetNSurf());942943for (int i = 0; i < ntlo; i++)944{945Solid * sol;946Surface * surf;947GetTopLevelObject (i, sol, surf);948949sol -> CalcSurfaceInverse ();950951TriangleApproximation * tams = new TriangleApproximation();952triapprox[i] = tams;953954// sol -> GetSurfaceIndices (surfind);955for (int j = 0; j < GetNSurf(); j++)956// for (int jj = 0; jj < surfind.Size(); jj++)957{958// int j = surfind[jj];959960PrintMessageCR (3, "Surface ", j, "/", GetNSurf());961// PrintMessageCR (3, "Surface ", j, "/", surfind.Size());962963if (surf && surf != GetSurface(j))964continue;965966TriangleApproximation tas;967GetSurface (j) -> GetTriangleApproximation (tas, aboundingbox, facets);968969int oldnp = tams -> GetNP();970971if (!tas.GetNP())972continue;973974for (int k = 0; k < tas.GetNP(); k++)975{976tams -> AddPoint (tas.GetPoint(k));977Vec<3> n = GetSurface(j) -> GetNormalVector (tas.GetPoint(k));978n.Normalize();979if (GetSurface(j)->Inverse()) n *= -1;980tams -> AddNormal (n);981//(*testout) << "point " << tas.GetPoint(k) << " normal " << n << endl;982//cout << "added point, normal=" << n << endl;983}984985986BoxSphere<3> surfbox;987988if (tas.GetNP())989surfbox.Set (tas.GetPoint(0));990for (int k = 1; k < tas.GetNP(); k++)991surfbox.Add (tas.GetPoint(k));992surfbox.Increase (1e-6);993surfbox.CalcDiamCenter();994995Solid * surflocsol = sol -> GetReducedSolid (surfbox);996if (!surflocsol)997continue;998999for (int k = 0; k < tas.GetNT(); k++)1000{1001const TATriangle & tri = tas.GetTriangle (k);10021003// check triangle1004BoxSphere<3> box;1005box.Set (tas.GetPoint (tri[0]));1006box.Add (tas.GetPoint (tri[1]));1007box.Add (tas.GetPoint (tri[2]));1008box.Increase (1e-6);1009box.CalcDiamCenter();101010111012Solid * locsol = surflocsol -> GetReducedSolid (box);10131014if (locsol)1015{1016TATriangle tria(j,1017tri[0] + oldnp,1018tri[1] + oldnp,1019tri[2] + oldnp);10201021RefineTriangleApprox (locsol, j, box, detail,1022tria, *tams, iset);1023delete locsol;1024}1025}1026}10271028tams->RemoveUnusedPoints ();1029PrintMessage (2, "Object ", i, " has ", tams->GetNT(), " triangles");1030}10311032Change();1033}1034103510361037void CSGeometry ::1038RefineTriangleApprox (Solid * locsol,1039int surfind,1040const BoxSphere<3> & box,1041double detail,1042const TATriangle & tria,1043TriangleApproximation & tams,1044IndexSet & iset)1045{10461047//tams.AddTriangle (tria);1048//(*testout) << "tria " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2])1049// << " ( " << tria[0] << " " << tria[1] << " " << tria[2] << ")" <<endl;1050//return;10511052int pinds[6];1053ArrayMem<int,500> surfused(GetNSurf());10541055ReducePrimitiveIterator rpi(box);1056UnReducePrimitiveIterator urpi;10571058locsol -> IterateSolid (rpi);1059// locsol -> GetSurfaceIndices (lsurfi);106010611062// IndexSet iset(GetNSurf());1063locsol -> GetSurfaceIndices (iset);1064const ARRAY<int> & lsurfi = iset.Array();10651066locsol -> IterateSolid (urpi);10671068int surfii = -1;1069for (int i = 0; i < lsurfi.Size(); i++)1070if (lsurfi[i] == surfind)1071{1072surfii = i;1073break;1074}10751076if (surfii == -1)1077return;10781079int cntindep = 0;10801081for (int i = 0; i < lsurfi.Size(); i++)1082{1083int linkto = isidenticto[lsurfi[i]];1084surfused[linkto] = 0;1085}10861087for (int i = 0; i < lsurfi.Size(); i++)1088{1089int linkto = isidenticto[lsurfi[i]];1090if (!surfused[linkto])1091{1092surfused[linkto] = 1;1093cntindep++;1094}1095}10961097int inverse = surfaces[surfind]->Inverse();10981099if (cntindep == 1)1100{1101tams.AddTriangle (tria);1102//(*testout) << "pos1 " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) << endl;1103return;1104}11051106if (cntindep == 2)1107{1108// just 2 surfaces:1109// if smooth, project inner points to edge and finish11101111int otherind = -1;11121113for (int i = 0; i < lsurfi.Size(); i++)1114{1115INDEX_2 i2 (lsurfi[i], surfind);1116i2.Sort();11171118if (i != surfii && !identicsurfaces.Used(i2))1119otherind = lsurfi[i];1120}11211122double kappa = GetSurface(otherind)-> MaxCurvature ();11231124if (kappa * box.Diam() < 0.1)1125{1126int pnums[6];1127static int between[3][3] =1128{ { 1, 2, 3 },1129{ 0, 2, 4 },1130{ 0, 1, 5 } };1131int onsurface[3];11321133for (int j = 0; j < 3; j++)1134{1135int pi = tria[j];1136pnums[j] = pi;113711381139onsurface[j] =1140!locsol->IsStrictIn (tams.GetPoint (pi), 1e-6) &&1141locsol->IsIn (tams.GetPoint (pi), 1e-6);11421143//1144/*1145static int nos=0;1146if(!onsurface[j])1147{1148nos++;1149cout << "NOT ON SURFACE!! "<< nos << endl;1150}1151*/1152}11531154for (int j = 0; j < 3; j++)1155{1156int lpi1 = between[j][0];1157int lpi2 = between[j][1];1158int lpin = between[j][2];1159if (onsurface[lpi1] == onsurface[lpi2])1160pnums[lpin] = -1;1161else1162{1163const Point<3> & p1 = tams.GetPoint (pnums[lpi1]);1164const Point<3> & p2 = tams.GetPoint (pnums[lpi2]);1165double f1 = GetSurface(otherind)->CalcFunctionValue (p1);1166double f2 = GetSurface(otherind)->CalcFunctionValue (p2);11671168Point<3> pn;11691170double l2(100),l1(100);1171if ( fabs (f1-f2) > 1e-20 )1172{1173l2 = -f1/(f2-f1);1174l1 = f2/(f2-f1);1175pn = Point<3>(l1 * p1(0) + l2 * p2(0),1176l1 * p1(1) + l2 * p2(1),1177l1 * p1(2) + l2 * p2(2));1178}1179else1180pn = p1;11811182// if(fabs(pn(0)) > 4 || fabs(pn(1)) > 4 || fabs(pn(2)) > 4)1183// {1184// cout << "p1 " << p1 << " p2 " << p21185// << " f1 " << f1 << " f2 " << f21186// << " l1 " << l1 << " l2 " << l21187// << " pn " << pn << endl;11881189// }119011911192//GetSurface (surfind)->Project (pn);11931194pnums[lpin] = tams.AddPoint (pn);11951196GetSurface (surfind)->Project (pn);11971198Vec<3> n;1199n = GetSurface (surfind)->GetNormalVector (pn);1200if (inverse) n *= -1;1201tams.AddNormal(n);1202}1203}12041205int vcase = 0;1206if (onsurface[0]) vcase++;1207if (onsurface[1]) vcase+=2;1208if (onsurface[2]) vcase+=4;12091210static int trias[8][6] =1211{ { 0, 0, 0, 0, 0, 0 },1212{ 1, 6, 5, 0, 0, 0 },1213{ 2, 4, 6, 0, 0, 0 },1214{ 1, 2, 4, 1, 4, 5 },1215{ 3, 5, 4, 0, 0, 0 },1216{ 1, 6, 4, 1, 4, 3 },1217{ 2, 3, 6, 3, 5, 6 },1218{ 1, 2, 3, 0, 0, 0 } };1219static int ntrias[4] =1220{ 0, 1, 2, 1 };12211222int nvis = 0;1223for (int j = 0; j < 3; j++)1224if (onsurface[j])1225nvis++;12261227for (int j = 0; j < ntrias[nvis]; j++)1228{1229TATriangle ntria(tria.SurfaceIndex(),1230pnums[trias[vcase][3*j]-1],1231pnums[trias[vcase][3*j+1]-1],1232pnums[trias[vcase][3*j+2]-1]);1233//(*testout) << "pos2 " << tams.GetPoint(ntria[0]) << " - " << tams.GetPoint(ntria[1]) << " - " << tams.GetPoint(ntria[2]) << endl1234// << "( " << ntria[0] << " - " << ntria[1] << " - " << ntria[2] << ")" << endl;1235tams.AddTriangle (ntria);1236}12371238/* saturn changes:12391240int pvis[3];1241for (j = 0; j < 3; j++)1242pvis[j] = !locsol->IsStrictIn (tams.GetPoint (j+1), 1e-6) &&1243locsol->IsIn (tams.GetPoint (j+1), 1e-6);12441245int newpi[3];1246for (j = 0; j < 3; j++)1247{1248int pi1 = j;1249int pi2 = (j+1) % 3;1250int pic = j;12511252if (pvis[pi1] != pvis[pi2])1253{1254Point<3> hp = Center (tams.GetPoint (tria.PNum (pi1+1)),1255tams.GetPoint (tria.PNum (pi2+1)));12561257newpi[j] = tams.AddPoint (hp);1258Vec<3> n = tams.GetNormal (pi1);1259tams.AddNormal (n);1260}1261else1262newpi[j] = 0;1263}12641265int nvis = 0;1266for (j = 0; j <= nvis; j++)1267if (pvis[j]) nvis++;12681269int si = tria.SurfaceIndex();1270switch (nvis)1271{1272case 0:1273break;1274case 1:1275{1276int visj;1277for (j = 0; j < 3; j++)1278if (pvis[j]) visj = j;1279int pivis = tria.PNum (visj+1);1280int pic1 = newpi[(visj+1)%3];1281int pic2 = newpi[(visj+2)%3];12821283cout << pivis << "," << pic1 << "," << pic2 << endl;12841285tams.AddTriangle (TATriangle (si, pivis, pic1,pic2));1286break;1287}1288case 2:1289{1290int nvisj;1291for (j = 0; j < 3; j++)1292if (!pvis[j]) nvisj = j;12931294int pivis1 = tria.PNum ((nvisj+1)%3+1);1295int pivis2 = tria.PNum ((nvisj+2)%3+1);1296int pic1 = newpi[nvisj];1297int pic2 = newpi[(nvisj+2)%3];12981299tams.AddTriangle (TATriangle (si, pivis1, pic1,pic2));1300tams.AddTriangle (TATriangle (si, pivis1, pic1,pivis2));1301break;1302}1303case 3:1304{1305tams.AddTriangle (tria);1306break;1307}1308}13091310*/1311return;1312}1313}13141315// bisection1316if (box.Diam() < detail)1317{1318//cout << "returning" << endl;1319return;1320}13211322for (int i = 0; i < 3; i++)1323pinds[i] = tria[i];13241325static int between[3][3] =1326{ { 0, 1, 5 },1327{ 0, 2, 4 },1328{ 1, 2, 3 } };13291330for (int i = 0; i < 3; i++)1331{1332// int pi1 = tria[between[i][0]];13331334Point<3> newp = Center (tams.GetPoint (tria[between[i][0]]),1335tams.GetPoint (tria[between[i][1]]));1336Vec<3> n;13371338GetSurface(surfind)->Project (newp);1339n = GetSurface(surfind)->GetNormalVector (newp);13401341pinds[between[i][2]] = tams.AddPoint (newp);1342if (inverse) n *= -1;1343tams.AddNormal (n);1344}13451346static int trias[4][4] =1347{ { 0, 5, 4 },1348{ 5, 1, 3 },1349{ 4, 3, 2 },1350{ 3, 4, 5 } };13511352for (int i = 0; i < 4; i++)1353{1354TATriangle ntri(surfind,1355pinds[trias[i][0]],1356pinds[trias[i][1]],1357pinds[trias[i][2]]);13581359// check triangle1360BoxSphere<3> nbox;1361nbox.Set (tams.GetPoint (ntri[0]));1362nbox.Add (tams.GetPoint (ntri[1]));1363nbox.Add (tams.GetPoint (ntri[2]));1364nbox.Increase (1e-6);1365nbox.CalcDiamCenter();13661367Solid * nsol = locsol -> GetReducedSolid (nbox);13681369if (nsol)1370{1371RefineTriangleApprox (nsol, surfind, nbox,1372detail, ntri, tams, iset);13731374delete nsol;1375}1376}1377}13781379138013811382class ClearVisitedIt : public SolidIterator1383{1384public:1385ClearVisitedIt () { ; }1386virtual ~ClearVisitedIt () { ; }13871388virtual void Do (Solid * sol)1389{1390sol -> visited = 0;1391}1392};139313941395void CSGeometry ::1396IterateAllSolids (SolidIterator & it, bool only_once)1397{1398if (only_once)1399{1400ClearVisitedIt clit;1401for (int i = 0; i < solids.Size(); i++)1402solids[i] -> IterateSolid (clit, 0);1403}14041405for (int i = 0; i < solids.Size(); i++)1406solids[i] -> IterateSolid (it, only_once);1407}140814091410double CSGeometry :: MaxSize () const1411{1412double maxs, mins;1413maxs = max3 (boundingbox.PMax()(0),1414boundingbox.PMax()(1),1415boundingbox.PMax()(2));1416mins = min3 (boundingbox.PMin()(0),1417boundingbox.PMin()(1),1418boundingbox.PMin()(2));1419return max2 (maxs, -mins) * 1.1;1420}1421}142214231424