Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/csg/csgeom.cpp
3206 views
1
#include <mystdlib.h>
2
#include <myadt.hpp>
3
4
#include <linalg.hpp>
5
#include <csg.hpp>
6
7
8
namespace netgen
9
{
10
11
int CSGeometry :: changeval = 0;
12
13
14
15
TopLevelObject ::
16
TopLevelObject (Solid * asolid,
17
Surface * asurface)
18
{
19
solid = asolid;
20
surface = asurface;
21
22
SetRGB (0, 0, 1);
23
SetTransparent (0);
24
SetVisible (1);
25
SetLayer (1);
26
27
if (!surface)
28
maxh = solid->GetMaxH();
29
else
30
maxh = surface->GetMaxH();
31
32
SetBCProp (-1);
33
34
bcname = "default";
35
}
36
37
void TopLevelObject :: GetData (ostream & ost)
38
{
39
ost << red << " " << green << " " << blue << " "
40
<< transp << " " << visible << " ";
41
}
42
43
void TopLevelObject :: SetData (istream & ist)
44
{
45
ist >> red >> green >> blue >> transp >> visible;
46
}
47
48
49
50
Box<3> CSGeometry::default_boundingbox (Point<3> (-1000, -1000, -1000),
51
Point<3> ( 1000, 1000, 1000));
52
53
54
CSGeometry :: CSGeometry ()
55
: boundingbox (default_boundingbox),
56
identicsurfaces (100), filename(""), ideps(1e-9)
57
{
58
;
59
}
60
61
CSGeometry :: CSGeometry (const string & afilename)
62
: boundingbox (default_boundingbox),
63
identicsurfaces (100), filename(afilename), ideps(1e-9)
64
{
65
changeval++;
66
}
67
68
CSGeometry :: ~CSGeometry ()
69
{
70
Clean();
71
}
72
73
74
void CSGeometry :: Clean ()
75
{
76
ARRAY< Solid* > to_delete;
77
78
for (int i = 0; i < solids.Size(); i++)
79
if(!to_delete.Contains(solids[i]->S1()))
80
to_delete.Append(solids[i]->S1());
81
for (int i = 0; i < solids.Size(); i++)
82
if(!to_delete.Contains(solids[i]))
83
to_delete.Append(solids[i]);
84
for(int i = 0; i < to_delete.Size(); i++)
85
delete to_delete[i];
86
87
/*
88
for (int i = 0; i < solids.Size(); i++)
89
delete solids[i]->S1();
90
for (int i = 0; i < solids.Size(); i++)
91
delete solids[i];
92
*/
93
94
solids.DeleteAll ();
95
96
for (int i = 0; i < splinecurves2d.Size(); i++)
97
delete splinecurves2d[i];
98
splinecurves2d.DeleteAll();
99
100
/*
101
for (int i = 0; i < surfaces.Size(); i++)
102
delete surfaces[i];
103
surfaces.DeleteAll ();
104
*/
105
for(int i = 0; i<delete_them.Size(); i++)
106
delete delete_them[i];
107
delete_them.DeleteAll();
108
surfaces.DeleteAll();
109
110
for (int i = 0; i < toplevelobjects.Size(); i++)
111
delete toplevelobjects[i];
112
toplevelobjects.DeleteAll ();
113
for (int i = 0; i < triapprox.Size(); i++)
114
delete triapprox[i];
115
triapprox.DeleteAll();
116
117
for(int i = 0; i < identifications.Size(); i++)
118
delete identifications[i];
119
identifications.DeleteAll();
120
121
for (int i = 0; i < singfaces.Size(); i++)
122
delete singfaces[i];
123
singfaces.DeleteAll();
124
for (int i = 0; i < singedges.Size(); i++)
125
delete singedges[i];
126
singedges.DeleteAll();
127
for (int i = 0; i < singpoints.Size(); i++)
128
delete singpoints[i];
129
singpoints.DeleteAll();
130
131
changeval++;
132
}
133
134
135
136
137
138
class WritePrimitivesIt : public SolidIterator
139
{
140
ostream & ost;
141
public:
142
WritePrimitivesIt (ostream & aost) : ost(aost) { ; }
143
virtual ~WritePrimitivesIt () { ; }
144
145
virtual void Do (Solid * sol);
146
};
147
148
void WritePrimitivesIt :: Do (Solid * sol)
149
{
150
Primitive * prim = sol->GetPrimitive();
151
if (prim)
152
{
153
const char * classname;
154
ARRAY<double> coeffs;
155
156
prim -> GetPrimitiveData (classname, coeffs);
157
158
if (sol->Name())
159
ost << "primitive "
160
<< sol->Name() << " "
161
<< classname << " " << coeffs.Size();
162
for (int i = 0; i < coeffs.Size(); i++)
163
ost << " " << coeffs[i];
164
ost << endl;
165
}
166
}
167
168
169
170
171
void CSGeometry :: Save (ostream & ost)
172
{
173
ost << "boundingbox "
174
<< boundingbox.PMin()(0) << " "
175
<< boundingbox.PMin()(1) << " "
176
<< boundingbox.PMin()(2) << " "
177
<< boundingbox.PMax()(0) << " "
178
<< boundingbox.PMax()(1) << " "
179
<< boundingbox.PMax()(2) << endl;
180
181
182
WritePrimitivesIt wpi(ost);
183
IterateAllSolids (wpi, 1);
184
185
for (int i = 0; i < solids.Size(); i++)
186
{
187
if (!solids[i]->GetPrimitive())
188
{
189
ost << "solid " << solids.GetName(i) << " ";
190
solids[i] -> GetSolidData (ost);
191
ost << endl;
192
}
193
}
194
195
for (int i = 0; i < GetNTopLevelObjects(); i++)
196
{
197
TopLevelObject * tlo = GetTopLevelObject (i);
198
ost << "toplevel ";
199
if (tlo -> GetSurface())
200
ost << "surface " << tlo->GetSolid()->Name() << " "
201
<< tlo->GetSurface()->Name() << " ";
202
else
203
ost << "solid " << tlo->GetSolid()->Name() << " ";
204
tlo->GetData(ost);
205
ost << endl;
206
}
207
208
for (int i = 0; i < identifications.Size(); i++)
209
{
210
ost << "identify ";
211
identifications[i] -> GetData (ost);
212
ost << endl;
213
}
214
215
ost << "end" << endl;
216
}
217
218
219
void CSGeometry :: Load (istream & ist)
220
{
221
// CSGeometry * geo = new CSGeometry;
222
223
char key[100], name[100], classname[100], sname[100];
224
int ncoeff, i, j;
225
ARRAY<double> coeff;
226
227
while (ist.good())
228
{
229
ist >> key;
230
if (strcmp (key, "boundingbox") == 0)
231
{
232
Point<3> pmin, pmax;
233
ist >> pmin(0) >> pmin(1) >> pmin(2);
234
ist >> pmax(0) >> pmax(1) >> pmax(2);
235
SetBoundingBox (Box<3> (pmin, pmax));
236
}
237
if (strcmp (key, "primitive") == 0)
238
{
239
ist >> name >> classname >> ncoeff;
240
coeff.SetSize (ncoeff);
241
for (i = 0; i < ncoeff; i++)
242
ist >> coeff[i];
243
244
Primitive * nprim = Primitive::CreatePrimitive (classname);
245
nprim -> SetPrimitiveData (coeff);
246
Solid * nsol = new Solid (nprim);
247
248
for (j = 0; j < nprim->GetNSurfaces(); j++)
249
{
250
sprintf (sname, "%s,%d", name, j);
251
AddSurface (sname, &nprim->GetSurface(j));
252
nprim -> SetSurfaceId (j, GetNSurf());
253
}
254
SetSolid (name, nsol);
255
}
256
else if (strcmp (key, "solid") == 0)
257
{
258
ist >> name;
259
Solid * nsol = Solid::CreateSolid (ist, solids);
260
261
cout << " I have found solid " << name << " = ";
262
nsol -> GetSolidData (cout);
263
cout << endl;
264
265
SetSolid (name, nsol);
266
}
267
else if (strcmp (key, "toplevel") == 0)
268
{
269
char type[20], solname[50], surfname[50];
270
const Solid * sol = NULL;
271
const Surface * surf = NULL;
272
int nr;
273
274
ist >> type;
275
if (strcmp (type, "solid") == 0)
276
{
277
ist >> solname;
278
sol = GetSolid (solname);
279
}
280
if (strcmp (type, "surface") == 0)
281
{
282
ist >> solname >> surfname;
283
sol = GetSolid (solname);
284
surf = GetSurface (surfname);
285
}
286
nr = SetTopLevelObject ((Solid*)sol, (Surface*)surf);
287
GetTopLevelObject (nr) -> SetData (ist);
288
}
289
else if (strcmp (key, "identify") == 0)
290
{
291
char type[10], surfname1[50], surfname2[50];
292
const Surface * surf1;
293
const Surface * surf2;
294
295
296
ist >> type >> surfname1 >> surfname2;
297
surf1 = GetSurface(surfname1);
298
surf2 = GetSurface(surfname2);
299
300
AddIdentification (new PeriodicIdentification
301
(GetNIdentifications(),
302
*this, surf1, surf2));
303
}
304
else if (strcmp (key, "end") == 0)
305
break;
306
}
307
308
changeval++;
309
}
310
311
312
313
void CSGeometry :: SaveSurfaces (ostream & out)
314
{
315
if(singfaces.Size() > 0 || singedges.Size() > 0 || singpoints.Size() > 0)
316
{
317
PrintMessage(3,"Singular faces/edges/points => no csg-information in .vol file");
318
return;
319
}
320
321
322
323
ARRAY<double> coeffs;
324
const char * classname;
325
326
out << "csgsurfaces " << GetNSurf() << "\n";
327
for(int i=0; i<GetNSurf(); i++)
328
{
329
const OneSurfacePrimitive * sp = dynamic_cast< const OneSurfacePrimitive * > (GetSurface(i));
330
const ExtrusionFace * ef = dynamic_cast< const ExtrusionFace * > (GetSurface(i));
331
const RevolutionFace * rf = dynamic_cast< const RevolutionFace * > (GetSurface(i));
332
333
334
if(sp)
335
{
336
sp->GetPrimitiveData(classname,coeffs);
337
338
out << classname << " ";
339
}
340
else if(ef)
341
{
342
out << "extrusionface ";
343
ef->GetRawData(coeffs);
344
}
345
else if(rf)
346
{
347
out << "revolutionface ";
348
rf->GetRawData(coeffs);
349
}
350
else
351
throw NgException ("Cannot write csg surface. Please, contact developers!");
352
353
354
out << coeffs.Size() << "\n";
355
for(int j=0; j<coeffs.Size(); j++)
356
out << coeffs[j] << " ";
357
358
out << "\n";
359
}
360
}
361
362
void CSGeometry :: LoadSurfaces (istream & in)
363
{
364
ARRAY<double> coeffs;
365
string classname;
366
int nsurfaces,size;
367
368
in >> classname;
369
370
if(classname == "csgsurfaces")
371
in >> nsurfaces;
372
else
373
nsurfaces = atoi(classname.c_str());
374
375
Point<3> dummypoint(0,0,0);
376
Vec<3> dummyvec(0,0,0);
377
double dummydouble(0.1);
378
379
for(int i=0; i<nsurfaces; i++)
380
{
381
in >> classname;
382
in >> size;
383
384
coeffs.SetSize(size);
385
386
for(int j=0; j<size; j++)
387
in >> coeffs[j];
388
389
if(classname == "plane")
390
{
391
Plane * plane = new Plane(dummypoint,dummyvec);
392
plane->SetPrimitiveData(coeffs);
393
394
AddSurface(plane);
395
delete_them.Append(plane);
396
}
397
398
else if(classname == "sphere")
399
{
400
Sphere * sphere = new Sphere(dummypoint,dummydouble);
401
sphere->SetPrimitiveData(coeffs);
402
403
AddSurface(sphere);
404
delete_them.Append(sphere);
405
}
406
407
else if(classname == "cylinder")
408
{
409
Cylinder * cylinder = new Cylinder(coeffs);
410
411
AddSurface(cylinder);
412
delete_them.Append(cylinder);
413
}
414
415
else if(classname == "cone")
416
{
417
Cone * cone = new Cone(dummypoint,dummypoint,dummydouble,dummydouble);
418
cone->SetPrimitiveData(coeffs);
419
420
AddSurface(cone);
421
delete_them.Append(cone);
422
}
423
424
else if(classname == "extrusionface")
425
{
426
ExtrusionFace * ef =
427
new ExtrusionFace(coeffs);
428
429
AddSurface(ef);
430
delete_them.Append(ef);
431
}
432
433
else if(classname == "revolutionface")
434
{
435
RevolutionFace * rf =
436
new RevolutionFace(coeffs);
437
438
AddSurface(rf);
439
delete_them.Append(rf);
440
}
441
}
442
}
443
444
445
446
447
448
449
void CSGeometry :: AddSurface (Surface * surf)
450
{
451
static int cntsurfs = 0;
452
cntsurfs++;
453
char name[17];
454
sprintf (name, "nnsurf%d", cntsurfs);
455
AddSurface (name, surf);
456
}
457
458
void CSGeometry :: AddSurface (char * name, Surface * surf)
459
{
460
(*testout) << "Adding surface " << name << endl;
461
surfaces.Set (name, surf);
462
surf->SetName (name);
463
changeval++;
464
}
465
466
void CSGeometry :: AddSurfaces (Primitive * prim)
467
{
468
for (int i = 0; i < prim->GetNSurfaces(); i++)
469
{
470
AddSurface (&prim->GetSurface(i));
471
prim->SetSurfaceId (i, GetNSurf()-1);
472
surf2prim.Append (prim);
473
}
474
}
475
476
const Surface * CSGeometry :: GetSurface (const char * name) const
477
{
478
if (surfaces.Used(name))
479
return surfaces.Get(name);
480
else
481
return NULL;
482
}
483
484
/*
485
const Surface * CSGeometry :: GetSurface (int i) const
486
{
487
if (i >= 0 && i < surfaces.Size())
488
return surfaces[i];
489
else
490
throw NgException ("CSGeometry::GetSurface out of range");
491
}
492
*/
493
494
495
496
497
void CSGeometry :: SetSolid (const char * name, Solid * sol)
498
{
499
Solid * oldsol = NULL;
500
501
if (solids.Used (name))
502
oldsol = solids.Get(name);
503
504
solids.Set (name, sol);
505
sol->SetName (name);
506
507
if (oldsol)
508
{
509
if (oldsol->op != Solid::ROOT ||
510
sol->op != Solid::ROOT)
511
{
512
cerr << "Setsolid: old or new no root" << endl;
513
}
514
oldsol -> s1 = sol -> s1;
515
}
516
changeval++;
517
}
518
519
const Solid * CSGeometry :: GetSolid (const char * name) const
520
{
521
if (solids.Used(name))
522
return solids.Get(name);
523
else
524
return NULL;
525
}
526
527
528
529
530
531
const Solid * CSGeometry :: GetSolid (const string & name) const
532
{
533
if (solids.Used(name.c_str()))
534
return solids.Get(name.c_str());
535
else
536
return NULL;
537
}
538
539
540
541
542
void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<2> * spl)
543
{
544
splinecurves2d.Set(name,spl);
545
}
546
void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<3> * spl)
547
{
548
splinecurves3d.Set(name,spl);
549
}
550
551
552
const SplineGeometry<2> * CSGeometry :: GetSplineCurve2d (const string & name) const
553
{
554
if (splinecurves2d.Used(name.c_str()))
555
return splinecurves2d.Get(name.c_str());
556
else
557
return NULL;
558
}
559
const SplineGeometry<3> * CSGeometry :: GetSplineCurve3d (const string & name) const
560
{
561
if (splinecurves3d.Used(name.c_str()))
562
return splinecurves3d.Get(name.c_str());
563
else
564
return NULL;
565
}
566
567
568
569
570
class RemoveDummyIterator : public SolidIterator
571
{
572
public:
573
574
RemoveDummyIterator() { ; }
575
virtual ~RemoveDummyIterator() { ; }
576
virtual void Do(Solid * sol);
577
};
578
579
void RemoveDummyIterator :: Do(Solid * sol)
580
{
581
if ( (sol->op == Solid::SUB || sol->op == Solid::SECTION ||
582
sol->op == Solid::UNION)
583
&& sol->s1->op == Solid::DUMMY)
584
sol->s1 = sol->s1->s1;
585
if ( (sol->op == Solid::SECTION || sol->op == Solid::UNION)
586
&& sol->s2->op == Solid::DUMMY)
587
sol->s2 = sol->s2->s1;
588
}
589
590
591
592
593
594
595
int CSGeometry :: SetTopLevelObject (Solid * sol, Surface * surf)
596
{
597
return toplevelobjects.Append (new TopLevelObject (sol, surf)) - 1;
598
}
599
600
TopLevelObject * CSGeometry ::
601
GetTopLevelObject (const Solid * sol, const Surface * surf)
602
{
603
for (int i = 0; i < toplevelobjects.Size(); i++)
604
{
605
if (toplevelobjects[i]->GetSolid() == sol &&
606
toplevelobjects[i]->GetSurface() == surf)
607
return (toplevelobjects[i]);
608
}
609
return NULL;
610
}
611
612
void CSGeometry :: RemoveTopLevelObject (Solid * sol, Surface * surf)
613
{
614
for (int i = 0; i < toplevelobjects.Size(); i++)
615
{
616
if (toplevelobjects[i]->GetSolid() == sol &&
617
toplevelobjects[i]->GetSurface() == surf)
618
{
619
delete toplevelobjects[i];
620
toplevelobjects.DeleteElement (i+1);
621
changeval++;
622
break;
623
}
624
}
625
}
626
627
void CSGeometry :: AddIdentification (Identification * ident)
628
{
629
identifications.Append (ident);
630
}
631
632
void CSGeometry :: SetFlags (const char * solidname, const Flags & flags)
633
{
634
Solid * solid = solids.Elem(solidname);
635
ARRAY<int> surfind;
636
637
int i;
638
double maxh = flags.GetNumFlag ("maxh", -1);
639
if (maxh > 0 && solid)
640
{
641
solid->GetSurfaceIndices (surfind);
642
643
for (i = 0; i < surfind.Size(); i++)
644
{
645
if (surfaces[surfind[i]]->GetMaxH() > maxh)
646
surfaces[surfind[i]] -> SetMaxH (maxh);
647
}
648
649
solid->SetMaxH (maxh);
650
}
651
652
if ( flags.StringFlagDefined ("bcname") )
653
{
654
solid->GetSurfaceIndices (surfind);
655
string bcn = flags.GetStringFlag("bcname", "default");
656
for (i = 0; i < surfind.Size(); i++)
657
{
658
if(surfaces[surfind[i]]->GetBCName() == "default")
659
surfaces[surfind[i]]->SetBCName(bcn);
660
}
661
}
662
663
if (flags.StringListFlagDefined ("bcname"))
664
{
665
const ARRAY<char*> & bcname = flags.GetStringListFlag("bcname");
666
667
Polyhedra * polyh;
668
if(solid->S1())
669
polyh = dynamic_cast<Polyhedra *>(solid->S1()->GetPrimitive());
670
else
671
polyh = dynamic_cast<Polyhedra *>(solid->GetPrimitive());
672
673
if(polyh)
674
{
675
ARRAY < ARRAY<int> * > polysurfs;
676
polyh->GetPolySurfs(polysurfs);
677
if(bcname.Size() != polysurfs.Size())
678
cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size()
679
<< " surfaces and should get " << bcname.Size() << " bc-names!" << endl;
680
681
for ( i = 0; i < min2(polysurfs.Size(),bcname.Size()); i++)
682
{
683
for (int j = 0; j < polysurfs[i]->Size(); j++)
684
{
685
if(surfaces[(*polysurfs[i])[j]]->GetBCName() == "default")
686
surfaces[(*polysurfs[i])[j]]->SetBCName(bcname[i]);
687
}
688
delete polysurfs[i];
689
}
690
}
691
else
692
{
693
solid->GetSurfaceIndices (surfind);
694
if(bcname.Size() != surfind.Size())
695
cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size()
696
<< " surfaces and should get " << bcname.Size() << " bc-names!" << endl;
697
698
for (i = 0; i < min2(surfind.Size(),bcname.Size()); i++)
699
{
700
if(surfaces[surfind[i]]->GetBCName() == "default")
701
surfaces[surfind[i]]->SetBCName(bcname[i]);
702
}
703
}
704
}
705
706
if (flags.NumFlagDefined ("bc"))
707
{
708
solid->GetSurfaceIndices (surfind);
709
int bc = int (flags.GetNumFlag("bc", -1));
710
for (i = 0; i < surfind.Size(); i++)
711
{
712
if (surfaces[surfind[i]]->GetBCProperty() == -1)
713
surfaces[surfind[i]]->SetBCProperty(bc);
714
}
715
}
716
717
if (flags.NumListFlagDefined ("bc"))
718
{
719
const ARRAY<double> & bcnum = flags.GetNumListFlag("bc");
720
721
Polyhedra * polyh;
722
if(solid->S1())
723
polyh = dynamic_cast<Polyhedra *>(solid->S1()->GetPrimitive());
724
else
725
polyh = dynamic_cast<Polyhedra *>(solid->GetPrimitive());
726
727
if(polyh)
728
{
729
ARRAY < ARRAY<int> * > polysurfs;
730
polyh->GetPolySurfs(polysurfs);
731
if(bcnum.Size() != polysurfs.Size())
732
cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size()
733
<< " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl;
734
735
for ( i = 0; i < min2(polysurfs.Size(),bcnum.Size()); i++)
736
{
737
for (int j = 0; j < polysurfs[i]->Size(); j++)
738
{
739
if ( surfaces[(*polysurfs[i])[j]]->GetBCProperty() == -1 )
740
surfaces[(*polysurfs[i])[j]]->SetBCProperty(int(bcnum[i]));
741
}
742
delete polysurfs[i];
743
}
744
}
745
else
746
{
747
solid->GetSurfaceIndices (surfind);
748
if(bcnum.Size() != surfind.Size())
749
cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size()
750
<< " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl;
751
752
for (i = 0; i < min2(surfind.Size(),bcnum.Size()); i++)
753
{
754
if (surfaces[surfind[i]]->GetBCProperty() == -1)
755
surfaces[surfind[i]]->SetBCProperty(int(bcnum[i]));
756
}
757
}
758
}
759
760
}
761
762
void CSGeometry :: FindIdenticSurfaces (double eps)
763
{
764
int inv;
765
int nsurf = GetNSurf();
766
767
isidenticto.SetSize(nsurf);
768
for (int i = 0; i < nsurf; i++)
769
isidenticto[i] = i;
770
771
//(*testout) << "jetzt!" << endl;
772
for (int i = 0; i < nsurf; i++)
773
for (int j = i+1; j < nsurf; j++)
774
{
775
//(*testout) << "surf" << i << " surf" << j << endl;
776
if (GetSurface(j) -> IsIdentic (*GetSurface(i), inv, eps))
777
{
778
INDEX_2 i2(i, j);
779
identicsurfaces.Set (i2, inv);
780
isidenticto[j] = isidenticto[i];
781
//(*testout) << "surfaces " << i2 << " are identic" << endl;
782
}
783
}
784
785
(*testout) << "identicmap:" << endl;
786
for (int i = 0; i < isidenticto.Size(); i++)
787
(*testout) << i << " -> " << isidenticto[i] << endl;
788
789
/*
790
for (int i = 0; i < nsurf; i++)
791
GetSurface(i)->Print (*testout);
792
*/
793
}
794
795
796
797
void CSGeometry ::
798
GetSurfaceIndices (const Solid * sol,
799
const BoxSphere<3> & box,
800
ARRAY<int> & locsurf) const
801
{
802
ReducePrimitiveIterator rpi(box);
803
UnReducePrimitiveIterator urpi;
804
805
((Solid*)sol) -> IterateSolid (rpi);
806
sol -> GetSurfaceIndices (locsurf);
807
((Solid*)sol) -> IterateSolid (urpi);
808
809
for (int i = locsurf.Size()-1; i >= 0; i--)
810
{
811
bool indep = 1;
812
for (int j = 0; j < i; j++)
813
if (locsurf[i] == locsurf[j])
814
{
815
indep = 0;
816
break;
817
}
818
819
if (!indep) locsurf.Delete(i);
820
}
821
}
822
823
824
825
826
void CSGeometry ::
827
GetIndependentSurfaceIndices (const Solid * sol,
828
const BoxSphere<3> & box,
829
ARRAY<int> & locsurf) const
830
{
831
ReducePrimitiveIterator rpi(box);
832
UnReducePrimitiveIterator urpi;
833
834
((Solid*)sol) -> IterateSolid (rpi);
835
sol -> GetSurfaceIndices (locsurf);
836
((Solid*)sol) -> IterateSolid (urpi);
837
838
for (int i = 0; i < locsurf.Size(); i++)
839
locsurf[i] = isidenticto[locsurf[i]];
840
841
for (int i = locsurf.Size()-1; i >= 0; i--)
842
{
843
bool indep = 1;
844
for (int j = 0; j < i; j++)
845
if (locsurf[i] == locsurf[j])
846
{
847
indep = 0;
848
break;
849
}
850
851
if (!indep) locsurf.Delete(i);
852
}
853
854
855
/*
856
// delete identified
857
for (int i = locsurf.Size()-1; i >= 0; i--)
858
{
859
bool indep = 1;
860
for (int j = 0; j < i; j++)
861
{
862
if (identicsurfaces.Used (INDEX_2::Sort (locsurf[i], locsurf[j])) !=
863
(isidenticto[locsurf[i]] == isidenticto[locsurf[j]]))
864
{
865
cerr << "different result" << endl;
866
exit(1);
867
}
868
869
if (isidenticto[locsurf[i]] == isidenticto[locsurf[j]])
870
{
871
indep = 0;
872
break;
873
}
874
}
875
if (!indep)
876
locsurf.Delete(i);
877
}
878
879
for (int i = 0; i < locsurf.Size(); i++)
880
locsurf[i] = isidenticto[locsurf[i]];
881
*/
882
}
883
884
885
void CSGeometry ::
886
GetIndependentSurfaceIndices (const Solid * sol,
887
const Point<3> & p, Vec<3> & v,
888
ARRAY<int> & locsurf) const
889
{
890
cout << "very dangerous" << endl;
891
Point<3> p2 = p + 1e-2 * v;
892
BoxSphere<3> box (p2, p2);
893
box.Increase (1e-3);
894
box.CalcDiamCenter();
895
GetIndependentSurfaceIndices (sol, box, locsurf);
896
}
897
898
899
void CSGeometry ::
900
GetIndependentSurfaceIndices (ARRAY<int> & locsurf) const
901
{
902
for (int i = 0; i < locsurf.Size(); i++)
903
locsurf[i] = isidenticto[locsurf[i]];
904
905
for (int i = locsurf.Size()-1; i >= 0; i--)
906
{
907
bool indep = 1;
908
for (int j = 0; j < i; j++)
909
if (locsurf[i] == locsurf[j])
910
{
911
indep = 0;
912
break;
913
}
914
915
if (!indep) locsurf.Delete(i);
916
}
917
}
918
919
920
921
922
923
924
925
926
927
void CSGeometry ::
928
CalcTriangleApproximation(const Box<3> & aboundingbox,
929
double detail, double facets)
930
{
931
PrintMessage (1, "Calc Triangle Approximation");
932
933
// FindIdenticSurfaces (1e-6);
934
935
int ntlo = GetNTopLevelObjects();
936
937
for (int i = 0; i < triapprox.Size(); i++)
938
delete triapprox[i];
939
triapprox.SetSize (ntlo);
940
941
ARRAY<int> surfind;
942
IndexSet iset(GetNSurf());
943
944
for (int i = 0; i < ntlo; i++)
945
{
946
Solid * sol;
947
Surface * surf;
948
GetTopLevelObject (i, sol, surf);
949
950
sol -> CalcSurfaceInverse ();
951
952
TriangleApproximation * tams = new TriangleApproximation();
953
triapprox[i] = tams;
954
955
// sol -> GetSurfaceIndices (surfind);
956
for (int j = 0; j < GetNSurf(); j++)
957
// for (int jj = 0; jj < surfind.Size(); jj++)
958
{
959
// int j = surfind[jj];
960
961
PrintMessageCR (3, "Surface ", j, "/", GetNSurf());
962
// PrintMessageCR (3, "Surface ", j, "/", surfind.Size());
963
964
if (surf && surf != GetSurface(j))
965
continue;
966
967
TriangleApproximation tas;
968
GetSurface (j) -> GetTriangleApproximation (tas, aboundingbox, facets);
969
970
int oldnp = tams -> GetNP();
971
972
if (!tas.GetNP())
973
continue;
974
975
for (int k = 0; k < tas.GetNP(); k++)
976
{
977
tams -> AddPoint (tas.GetPoint(k));
978
Vec<3> n = GetSurface(j) -> GetNormalVector (tas.GetPoint(k));
979
n.Normalize();
980
if (GetSurface(j)->Inverse()) n *= -1;
981
tams -> AddNormal (n);
982
//(*testout) << "point " << tas.GetPoint(k) << " normal " << n << endl;
983
//cout << "added point, normal=" << n << endl;
984
}
985
986
987
BoxSphere<3> surfbox;
988
989
if (tas.GetNP())
990
surfbox.Set (tas.GetPoint(0));
991
for (int k = 1; k < tas.GetNP(); k++)
992
surfbox.Add (tas.GetPoint(k));
993
surfbox.Increase (1e-6);
994
surfbox.CalcDiamCenter();
995
996
Solid * surflocsol = sol -> GetReducedSolid (surfbox);
997
if (!surflocsol)
998
continue;
999
1000
for (int k = 0; k < tas.GetNT(); k++)
1001
{
1002
const TATriangle & tri = tas.GetTriangle (k);
1003
1004
// check triangle
1005
BoxSphere<3> box;
1006
box.Set (tas.GetPoint (tri[0]));
1007
box.Add (tas.GetPoint (tri[1]));
1008
box.Add (tas.GetPoint (tri[2]));
1009
box.Increase (1e-6);
1010
box.CalcDiamCenter();
1011
1012
1013
Solid * locsol = surflocsol -> GetReducedSolid (box);
1014
1015
if (locsol)
1016
{
1017
TATriangle tria(j,
1018
tri[0] + oldnp,
1019
tri[1] + oldnp,
1020
tri[2] + oldnp);
1021
1022
RefineTriangleApprox (locsol, j, box, detail,
1023
tria, *tams, iset);
1024
delete locsol;
1025
}
1026
}
1027
}
1028
1029
tams->RemoveUnusedPoints ();
1030
PrintMessage (2, "Object ", i, " has ", tams->GetNT(), " triangles");
1031
}
1032
1033
Change();
1034
}
1035
1036
1037
1038
void CSGeometry ::
1039
RefineTriangleApprox (Solid * locsol,
1040
int surfind,
1041
const BoxSphere<3> & box,
1042
double detail,
1043
const TATriangle & tria,
1044
TriangleApproximation & tams,
1045
IndexSet & iset)
1046
{
1047
1048
//tams.AddTriangle (tria);
1049
//(*testout) << "tria " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2])
1050
// << " ( " << tria[0] << " " << tria[1] << " " << tria[2] << ")" <<endl;
1051
//return;
1052
1053
int pinds[6];
1054
ArrayMem<int,500> surfused(GetNSurf());
1055
1056
ReducePrimitiveIterator rpi(box);
1057
UnReducePrimitiveIterator urpi;
1058
1059
locsol -> IterateSolid (rpi);
1060
// locsol -> GetSurfaceIndices (lsurfi);
1061
1062
1063
// IndexSet iset(GetNSurf());
1064
locsol -> GetSurfaceIndices (iset);
1065
const ARRAY<int> & lsurfi = iset.Array();
1066
1067
locsol -> IterateSolid (urpi);
1068
1069
int surfii = -1;
1070
for (int i = 0; i < lsurfi.Size(); i++)
1071
if (lsurfi[i] == surfind)
1072
{
1073
surfii = i;
1074
break;
1075
}
1076
1077
if (surfii == -1)
1078
return;
1079
1080
int cntindep = 0;
1081
1082
for (int i = 0; i < lsurfi.Size(); i++)
1083
{
1084
int linkto = isidenticto[lsurfi[i]];
1085
surfused[linkto] = 0;
1086
}
1087
1088
for (int i = 0; i < lsurfi.Size(); i++)
1089
{
1090
int linkto = isidenticto[lsurfi[i]];
1091
if (!surfused[linkto])
1092
{
1093
surfused[linkto] = 1;
1094
cntindep++;
1095
}
1096
}
1097
1098
int inverse = surfaces[surfind]->Inverse();
1099
1100
if (cntindep == 1)
1101
{
1102
tams.AddTriangle (tria);
1103
//(*testout) << "pos1 " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) << endl;
1104
return;
1105
}
1106
1107
if (cntindep == 2)
1108
{
1109
// just 2 surfaces:
1110
// if smooth, project inner points to edge and finish
1111
1112
int otherind = -1;
1113
1114
for (int i = 0; i < lsurfi.Size(); i++)
1115
{
1116
INDEX_2 i2 (lsurfi[i], surfind);
1117
i2.Sort();
1118
1119
if (i != surfii && !identicsurfaces.Used(i2))
1120
otherind = lsurfi[i];
1121
}
1122
1123
double kappa = GetSurface(otherind)-> MaxCurvature ();
1124
1125
if (kappa * box.Diam() < 0.1)
1126
{
1127
int pnums[6];
1128
static int between[3][3] =
1129
{ { 1, 2, 3 },
1130
{ 0, 2, 4 },
1131
{ 0, 1, 5 } };
1132
int onsurface[3];
1133
1134
for (int j = 0; j < 3; j++)
1135
{
1136
int pi = tria[j];
1137
pnums[j] = pi;
1138
1139
1140
onsurface[j] =
1141
!locsol->IsStrictIn (tams.GetPoint (pi), 1e-6) &&
1142
locsol->IsIn (tams.GetPoint (pi), 1e-6);
1143
1144
//
1145
/*
1146
static int nos=0;
1147
if(!onsurface[j])
1148
{
1149
nos++;
1150
cout << "NOT ON SURFACE!! "<< nos << endl;
1151
}
1152
*/
1153
}
1154
1155
for (int j = 0; j < 3; j++)
1156
{
1157
int lpi1 = between[j][0];
1158
int lpi2 = between[j][1];
1159
int lpin = between[j][2];
1160
if (onsurface[lpi1] == onsurface[lpi2])
1161
pnums[lpin] = -1;
1162
else
1163
{
1164
const Point<3> & p1 = tams.GetPoint (pnums[lpi1]);
1165
const Point<3> & p2 = tams.GetPoint (pnums[lpi2]);
1166
double f1 = GetSurface(otherind)->CalcFunctionValue (p1);
1167
double f2 = GetSurface(otherind)->CalcFunctionValue (p2);
1168
1169
Point<3> pn;
1170
1171
double l2(100),l1(100);
1172
if ( fabs (f1-f2) > 1e-20 )
1173
{
1174
l2 = -f1/(f2-f1);
1175
l1 = f2/(f2-f1);
1176
pn = Point<3>(l1 * p1(0) + l2 * p2(0),
1177
l1 * p1(1) + l2 * p2(1),
1178
l1 * p1(2) + l2 * p2(2));
1179
}
1180
else
1181
pn = p1;
1182
1183
// if(fabs(pn(0)) > 4 || fabs(pn(1)) > 4 || fabs(pn(2)) > 4)
1184
// {
1185
// cout << "p1 " << p1 << " p2 " << p2
1186
// << " f1 " << f1 << " f2 " << f2
1187
// << " l1 " << l1 << " l2 " << l2
1188
// << " pn " << pn << endl;
1189
1190
// }
1191
1192
1193
//GetSurface (surfind)->Project (pn);
1194
1195
pnums[lpin] = tams.AddPoint (pn);
1196
1197
GetSurface (surfind)->Project (pn);
1198
1199
Vec<3> n;
1200
n = GetSurface (surfind)->GetNormalVector (pn);
1201
if (inverse) n *= -1;
1202
tams.AddNormal(n);
1203
}
1204
}
1205
1206
int vcase = 0;
1207
if (onsurface[0]) vcase++;
1208
if (onsurface[1]) vcase+=2;
1209
if (onsurface[2]) vcase+=4;
1210
1211
static int trias[8][6] =
1212
{ { 0, 0, 0, 0, 0, 0 },
1213
{ 1, 6, 5, 0, 0, 0 },
1214
{ 2, 4, 6, 0, 0, 0 },
1215
{ 1, 2, 4, 1, 4, 5 },
1216
{ 3, 5, 4, 0, 0, 0 },
1217
{ 1, 6, 4, 1, 4, 3 },
1218
{ 2, 3, 6, 3, 5, 6 },
1219
{ 1, 2, 3, 0, 0, 0 } };
1220
static int ntrias[4] =
1221
{ 0, 1, 2, 1 };
1222
1223
int nvis = 0;
1224
for (int j = 0; j < 3; j++)
1225
if (onsurface[j])
1226
nvis++;
1227
1228
for (int j = 0; j < ntrias[nvis]; j++)
1229
{
1230
TATriangle ntria(tria.SurfaceIndex(),
1231
pnums[trias[vcase][3*j]-1],
1232
pnums[trias[vcase][3*j+1]-1],
1233
pnums[trias[vcase][3*j+2]-1]);
1234
//(*testout) << "pos2 " << tams.GetPoint(ntria[0]) << " - " << tams.GetPoint(ntria[1]) << " - " << tams.GetPoint(ntria[2]) << endl
1235
// << "( " << ntria[0] << " - " << ntria[1] << " - " << ntria[2] << ")" << endl;
1236
tams.AddTriangle (ntria);
1237
}
1238
1239
/* saturn changes:
1240
1241
int pvis[3];
1242
for (j = 0; j < 3; j++)
1243
pvis[j] = !locsol->IsStrictIn (tams.GetPoint (j+1), 1e-6) &&
1244
locsol->IsIn (tams.GetPoint (j+1), 1e-6);
1245
1246
int newpi[3];
1247
for (j = 0; j < 3; j++)
1248
{
1249
int pi1 = j;
1250
int pi2 = (j+1) % 3;
1251
int pic = j;
1252
1253
if (pvis[pi1] != pvis[pi2])
1254
{
1255
Point<3> hp = Center (tams.GetPoint (tria.PNum (pi1+1)),
1256
tams.GetPoint (tria.PNum (pi2+1)));
1257
1258
newpi[j] = tams.AddPoint (hp);
1259
Vec<3> n = tams.GetNormal (pi1);
1260
tams.AddNormal (n);
1261
}
1262
else
1263
newpi[j] = 0;
1264
}
1265
1266
int nvis = 0;
1267
for (j = 0; j <= nvis; j++)
1268
if (pvis[j]) nvis++;
1269
1270
int si = tria.SurfaceIndex();
1271
switch (nvis)
1272
{
1273
case 0:
1274
break;
1275
case 1:
1276
{
1277
int visj;
1278
for (j = 0; j < 3; j++)
1279
if (pvis[j]) visj = j;
1280
int pivis = tria.PNum (visj+1);
1281
int pic1 = newpi[(visj+1)%3];
1282
int pic2 = newpi[(visj+2)%3];
1283
1284
cout << pivis << "," << pic1 << "," << pic2 << endl;
1285
1286
tams.AddTriangle (TATriangle (si, pivis, pic1,pic2));
1287
break;
1288
}
1289
case 2:
1290
{
1291
int nvisj;
1292
for (j = 0; j < 3; j++)
1293
if (!pvis[j]) nvisj = j;
1294
1295
int pivis1 = tria.PNum ((nvisj+1)%3+1);
1296
int pivis2 = tria.PNum ((nvisj+2)%3+1);
1297
int pic1 = newpi[nvisj];
1298
int pic2 = newpi[(nvisj+2)%3];
1299
1300
tams.AddTriangle (TATriangle (si, pivis1, pic1,pic2));
1301
tams.AddTriangle (TATriangle (si, pivis1, pic1,pivis2));
1302
break;
1303
}
1304
case 3:
1305
{
1306
tams.AddTriangle (tria);
1307
break;
1308
}
1309
}
1310
1311
*/
1312
return;
1313
}
1314
}
1315
1316
// bisection
1317
if (box.Diam() < detail)
1318
{
1319
//cout << "returning" << endl;
1320
return;
1321
}
1322
1323
for (int i = 0; i < 3; i++)
1324
pinds[i] = tria[i];
1325
1326
static int between[3][3] =
1327
{ { 0, 1, 5 },
1328
{ 0, 2, 4 },
1329
{ 1, 2, 3 } };
1330
1331
for (int i = 0; i < 3; i++)
1332
{
1333
// int pi1 = tria[between[i][0]];
1334
1335
Point<3> newp = Center (tams.GetPoint (tria[between[i][0]]),
1336
tams.GetPoint (tria[between[i][1]]));
1337
Vec<3> n;
1338
1339
GetSurface(surfind)->Project (newp);
1340
n = GetSurface(surfind)->GetNormalVector (newp);
1341
1342
pinds[between[i][2]] = tams.AddPoint (newp);
1343
if (inverse) n *= -1;
1344
tams.AddNormal (n);
1345
}
1346
1347
static int trias[4][4] =
1348
{ { 0, 5, 4 },
1349
{ 5, 1, 3 },
1350
{ 4, 3, 2 },
1351
{ 3, 4, 5 } };
1352
1353
for (int i = 0; i < 4; i++)
1354
{
1355
TATriangle ntri(surfind,
1356
pinds[trias[i][0]],
1357
pinds[trias[i][1]],
1358
pinds[trias[i][2]]);
1359
1360
// check triangle
1361
BoxSphere<3> nbox;
1362
nbox.Set (tams.GetPoint (ntri[0]));
1363
nbox.Add (tams.GetPoint (ntri[1]));
1364
nbox.Add (tams.GetPoint (ntri[2]));
1365
nbox.Increase (1e-6);
1366
nbox.CalcDiamCenter();
1367
1368
Solid * nsol = locsol -> GetReducedSolid (nbox);
1369
1370
if (nsol)
1371
{
1372
RefineTriangleApprox (nsol, surfind, nbox,
1373
detail, ntri, tams, iset);
1374
1375
delete nsol;
1376
}
1377
}
1378
}
1379
1380
1381
1382
1383
class ClearVisitedIt : public SolidIterator
1384
{
1385
public:
1386
ClearVisitedIt () { ; }
1387
virtual ~ClearVisitedIt () { ; }
1388
1389
virtual void Do (Solid * sol)
1390
{
1391
sol -> visited = 0;
1392
}
1393
};
1394
1395
1396
void CSGeometry ::
1397
IterateAllSolids (SolidIterator & it, bool only_once)
1398
{
1399
if (only_once)
1400
{
1401
ClearVisitedIt clit;
1402
for (int i = 0; i < solids.Size(); i++)
1403
solids[i] -> IterateSolid (clit, 0);
1404
}
1405
1406
for (int i = 0; i < solids.Size(); i++)
1407
solids[i] -> IterateSolid (it, only_once);
1408
}
1409
1410
1411
double CSGeometry :: MaxSize () const
1412
{
1413
double maxs, mins;
1414
maxs = max3 (boundingbox.PMax()(0),
1415
boundingbox.PMax()(1),
1416
boundingbox.PMax()(2));
1417
mins = min3 (boundingbox.PMin()(0),
1418
boundingbox.PMin()(1),
1419
boundingbox.PMin()(2));
1420
return max2 (maxs, -mins) * 1.1;
1421
}
1422
}
1423
1424