Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/csg/solid.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include <linalg.hpp>
4
#include <csg.hpp>
5
6
7
namespace netgen
8
{
9
//using namespace netgen;
10
11
12
/*
13
SolidIterator :: SolidIterator ()
14
{
15
;
16
}
17
18
SolidIterator :: ~SolidIterator ()
19
{
20
;
21
}
22
*/
23
24
25
26
// int Solid :: cntnames = 0;
27
28
Solid :: Solid (Primitive * aprim)
29
{
30
op = TERM;
31
prim = aprim;
32
s1 = s2 = NULL;
33
maxh = 1e10;
34
name = NULL;
35
}
36
37
Solid :: Solid (optyp aop, Solid * as1, Solid * as2)
38
{
39
op = aop;
40
s1 = as1;
41
s2 = as2;
42
prim = NULL;
43
name = NULL;
44
maxh = 1e10;
45
}
46
47
Solid :: ~Solid ()
48
{
49
// cout << "delete solid, op = " << int(op) << endl;
50
delete [] name;
51
52
switch (op)
53
{
54
case UNION:
55
case SECTION:
56
{
57
if (s1->op != ROOT) delete s1;
58
if (s2->op != ROOT) delete s2;
59
break;
60
}
61
case SUB:
62
// case ROOT:
63
{
64
if (s1->op != ROOT) delete s1;
65
break;
66
}
67
case TERM:
68
{
69
// cout << "has term" << endl;
70
delete prim;
71
break;
72
}
73
default:
74
break;
75
}
76
}
77
78
void Solid :: SetName (const char * aname)
79
{
80
delete [] name;
81
name = new char[strlen (aname)+1];
82
strcpy (name, aname);
83
}
84
85
86
Solid * Solid :: Copy (CSGeometry & geom) const
87
{
88
Solid * nsol(NULL);
89
switch (op)
90
{
91
case TERM: case TERM_REF:
92
{
93
Primitive * nprim = prim->Copy();
94
geom.AddSurfaces (nprim);
95
nsol = new Solid (nprim);
96
break;
97
}
98
99
case SECTION:
100
case UNION:
101
{
102
nsol = new Solid (op, s1->Copy(geom), s2->Copy(geom));
103
break;
104
}
105
106
case SUB:
107
{
108
nsol = new Solid (SUB, s1 -> Copy (geom));
109
break;
110
}
111
112
case ROOT:
113
{
114
nsol = s1->Copy(geom);
115
break;
116
}
117
}
118
119
return nsol;
120
}
121
122
123
void Solid :: Transform (Transformation<3> & trans)
124
{
125
switch (op)
126
{
127
case TERM: case TERM_REF:
128
{
129
prim -> Transform (trans);
130
break;
131
}
132
case SECTION:
133
case UNION:
134
{
135
s1 -> Transform (trans);
136
s2 -> Transform (trans);
137
break;
138
}
139
140
case SUB:
141
case ROOT:
142
{
143
s1 -> Transform (trans);
144
break;
145
}
146
}
147
}
148
149
150
151
void Solid :: IterateSolid (SolidIterator & it,
152
bool only_once)
153
{
154
if (only_once)
155
{
156
if (visited)
157
return;
158
159
visited = 1;
160
}
161
162
it.Do (this);
163
164
switch (op)
165
{
166
case SECTION:
167
{
168
s1->IterateSolid (it, only_once);
169
s2->IterateSolid (it, only_once);
170
break;
171
}
172
case UNION:
173
{
174
s1->IterateSolid (it, only_once);
175
s2->IterateSolid (it, only_once);
176
break;
177
}
178
case SUB:
179
case ROOT:
180
{
181
s1->IterateSolid (it, only_once);
182
break;
183
}
184
}
185
}
186
187
188
189
190
bool Solid :: IsIn (const Point<3> & p, double eps) const
191
{
192
switch (op)
193
{
194
case TERM: case TERM_REF:
195
{
196
INSOLID_TYPE ist = prim->PointInSolid (p, eps);
197
return ( (ist == IS_INSIDE) || (ist == DOES_INTERSECT) ) ? 1 : 0;
198
}
199
case SECTION:
200
return s1->IsIn (p, eps) && s2->IsIn (p, eps);
201
case UNION:
202
return s1->IsIn (p, eps) || s2->IsIn (p, eps);
203
case SUB:
204
return !s1->IsStrictIn (p, eps);
205
case ROOT:
206
return s1->IsIn (p, eps);
207
}
208
return 0;
209
}
210
211
bool Solid :: IsStrictIn (const Point<3> & p, double eps) const
212
{
213
switch (op)
214
{
215
case TERM: case TERM_REF:
216
{
217
INSOLID_TYPE ist = prim->PointInSolid (p, eps);
218
return (ist == IS_INSIDE) ? 1 : 0;
219
}
220
case SECTION:
221
return s1->IsStrictIn(p, eps) && s2->IsStrictIn(p, eps);
222
case UNION:
223
return s1->IsStrictIn(p, eps) || s2->IsStrictIn(p, eps);
224
case SUB:
225
return !s1->IsIn (p, eps);
226
case ROOT:
227
return s1->IsStrictIn (p, eps);
228
}
229
return 0;
230
}
231
232
bool Solid :: VectorIn (const Point<3> & p, const Vec<3> & v,
233
double eps) const
234
{
235
Vec<3> hv;
236
switch (op)
237
{
238
case TERM: case TERM_REF:
239
{
240
INSOLID_TYPE ist = prim->VecInSolid (p, v, eps);
241
return (ist == IS_INSIDE || ist == DOES_INTERSECT) ? 1 : 0;
242
}
243
case SECTION:
244
return s1 -> VectorIn (p, v, eps) && s2 -> VectorIn (p, v, eps);
245
case UNION:
246
return s1 -> VectorIn (p, v, eps) || s2 -> VectorIn (p, v, eps);
247
case SUB:
248
return !s1->VectorStrictIn(p, v, eps);
249
case ROOT:
250
return s1->VectorIn(p, v, eps);
251
}
252
return 0;
253
}
254
255
bool Solid :: VectorStrictIn (const Point<3> & p, const Vec<3> & v,
256
double eps) const
257
{
258
Vec<3> hv;
259
switch (op)
260
{
261
case TERM: case TERM_REF:
262
{
263
INSOLID_TYPE ist = prim->VecInSolid (p, v, eps);
264
return (ist == IS_INSIDE) ? true : false;
265
}
266
case SECTION:
267
return s1 -> VectorStrictIn (p, v, eps) &&
268
s2 -> VectorStrictIn (p, v, eps);
269
case UNION:
270
return s1 -> VectorStrictIn (p, v, eps) ||
271
s2 -> VectorStrictIn (p, v, eps);
272
case SUB:
273
return !s1->VectorIn(p, v, eps);
274
case ROOT:
275
return s1->VectorStrictIn(p, v, eps);
276
}
277
return 0;
278
}
279
280
281
bool Solid::VectorIn2 (const Point<3> & p, const Vec<3> & v1,
282
const Vec<3> & v2, double eps) const
283
{
284
if (VectorStrictIn (p, v1, eps))
285
return 1;
286
if (!VectorIn (p, v1, eps))
287
return 0;
288
289
bool res = VectorIn2Rec (p, v1, v2, eps);
290
return res;
291
}
292
293
bool Solid::VectorIn2Rec (const Point<3> & p, const Vec<3> & v1,
294
const Vec<3> & v2, double eps) const
295
{
296
switch (op)
297
{
298
case TERM: case TERM_REF:
299
return (prim->VecInSolid2 (p, v1, v2, eps) != IS_OUTSIDE); // Is this correct????
300
case SECTION:
301
return s1->VectorIn2Rec (p, v1, v2, eps) &&
302
s2->VectorIn2Rec (p, v1, v2, eps);
303
case UNION:
304
return s1->VectorIn2Rec (p, v1, v2, eps) ||
305
s2->VectorIn2Rec (p, v1, v2, eps);
306
case SUB:
307
return !s1->VectorIn2Rec (p, v1, v2, eps);
308
case ROOT:
309
return s1->VectorIn2Rec (p, v1, v2, eps);
310
}
311
return 0;
312
}
313
314
315
316
317
318
319
void Solid :: Print (ostream & str) const
320
{
321
switch (op)
322
{
323
case TERM: case TERM_REF:
324
{
325
str << prim->GetSurfaceId(0);
326
for (int i = 1; i < prim->GetNSurfaces(); i++)
327
str << "," << prim->GetSurfaceId(i);
328
break;
329
}
330
case SECTION:
331
{
332
str << "(";
333
s1 -> Print (str);
334
str << " AND ";
335
s2 -> Print (str);
336
str << ")";
337
break;
338
}
339
case UNION:
340
{
341
str << "(";
342
s1 -> Print (str);
343
str << " OR ";
344
s2 -> Print (str);
345
str << ")";
346
break;
347
}
348
case SUB:
349
{
350
str << " NOT ";
351
s1 -> Print (str);
352
break;
353
}
354
case ROOT:
355
{
356
str << " [" << name << "=";
357
s1 -> Print (str);
358
str << "] ";
359
break;
360
}
361
}
362
}
363
364
365
366
void Solid :: GetSolidData (ostream & ost, int first) const
367
{
368
switch (op)
369
{
370
case SECTION:
371
{
372
ost << "(";
373
s1 -> GetSolidData (ost, 0);
374
ost << " AND ";
375
s2 -> GetSolidData (ost, 0);
376
ost << ")";
377
break;
378
}
379
case UNION:
380
{
381
ost << "(";
382
s1 -> GetSolidData (ost, 0);
383
ost << " OR ";
384
s2 -> GetSolidData (ost, 0);
385
ost << ")";
386
break;
387
}
388
case SUB:
389
{
390
ost << "NOT ";
391
s1 -> GetSolidData (ost, 0);
392
break;
393
}
394
case TERM: case TERM_REF:
395
{
396
if (name)
397
ost << name;
398
else
399
ost << "(noname)";
400
break;
401
}
402
case ROOT:
403
{
404
if (first)
405
s1 -> GetSolidData (ost, 0);
406
else
407
ost << name;
408
break;
409
}
410
}
411
}
412
413
414
415
static Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE<Solid*> & solids);
416
static Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE<Solid*> & solids);
417
static Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE<Solid*> & solids);
418
419
static void ReadString (istream & ist, char * str)
420
{
421
//char * hstr = str;
422
char ch;
423
424
while (1)
425
{
426
ist.get(ch);
427
if (!ist.good()) break;
428
429
if (!isspace (ch))
430
{
431
ist.putback (ch);
432
break;
433
}
434
}
435
436
while (1)
437
{
438
ist.get(ch);
439
if (!ist.good()) break;
440
if (isalpha(ch) || isdigit(ch))
441
{
442
*str = ch;
443
str++;
444
}
445
else
446
{
447
ist.putback (ch);
448
break;
449
}
450
}
451
*str = 0;
452
// cout << "Read string (" << hstr << ")"
453
// << "put back: " << ch << endl;
454
}
455
456
457
Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE<Solid*> & solids)
458
{
459
// cout << "create expr" << endl;
460
461
Solid *s1, *s2;
462
char str[100];
463
464
s1 = CreateSolidTerm (ist, solids);
465
ReadString (ist, str);
466
if (strcmp (str, "OR") == 0)
467
{
468
// cout << " OR ";
469
s2 = CreateSolidExpr (ist, solids);
470
return new Solid (Solid::UNION, s1, s2);
471
}
472
473
// cout << "no OR found, put back string: " << str << endl;
474
for (int i = int(strlen(str))-1; i >= 0; i--)
475
ist.putback (str[i]);
476
477
return s1;
478
}
479
480
Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE<Solid*> & solids)
481
{
482
// cout << "create term" << endl;
483
484
Solid *s1, *s2;
485
char str[100];
486
487
s1 = CreateSolidPrim (ist, solids);
488
ReadString (ist, str);
489
if (strcmp (str, "AND") == 0)
490
{
491
// cout << " AND ";
492
s2 = CreateSolidTerm (ist, solids);
493
return new Solid (Solid::SECTION, s1, s2);
494
}
495
496
497
// cout << "no AND found, put back string: " << str << endl;
498
for (int i = int(strlen(str))-1; i >= 0; i--)
499
ist.putback (str[i]);
500
501
return s1;
502
}
503
504
Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE<Solid*> & solids)
505
{
506
Solid * s1;
507
char ch;
508
char str[100];
509
510
ist >> ch;
511
if (ch == '(')
512
{
513
s1 = CreateSolidExpr (ist, solids);
514
ist >> ch; // ')'
515
// cout << "close back " << ch << endl;
516
return s1;
517
}
518
ist.putback (ch);
519
520
ReadString (ist, str);
521
if (strcmp (str, "NOT") == 0)
522
{
523
// cout << " NOT ";
524
s1 = CreateSolidPrim (ist, solids);
525
return new Solid (Solid::SUB, s1);
526
}
527
528
(*testout) << "get terminal " << str << endl;
529
s1 = solids.Get(str);
530
if (s1)
531
{
532
// cout << "primitive: " << str << endl;
533
return s1;
534
}
535
cerr << "syntax error" << endl;
536
537
return NULL;
538
}
539
540
541
Solid * Solid :: CreateSolid (istream & ist, const SYMBOLTABLE<Solid*> & solids)
542
{
543
Solid * nsol = CreateSolidExpr (ist, solids);
544
nsol = new Solid (ROOT, nsol);
545
(*testout) << "Print new sol: ";
546
nsol -> Print (*testout);
547
(*testout) << endl;
548
return nsol;
549
}
550
551
552
553
void Solid :: Boundaries (const Point<3> & p, ARRAY<int> & bounds) const
554
{
555
int in, strin;
556
bounds.SetSize (0);
557
RecBoundaries (p, bounds, in, strin);
558
}
559
560
void Solid :: RecBoundaries (const Point<3> & p, ARRAY<int> & bounds,
561
int & in, int & strin) const
562
{
563
switch (op)
564
{
565
case TERM: case TERM_REF:
566
{
567
/*
568
double val;
569
val = surf->CalcFunctionValue (p);
570
in = (val < 1e-6);
571
strin = (val < -1e-6);
572
if (in && !strin) bounds.Append (id);
573
*/
574
if (prim->PointInSolid (p, 1e-6) == DOES_INTERSECT)
575
bounds.Append (prim->GetSurfaceId (1));
576
break;
577
}
578
case SECTION:
579
{
580
int i, in1, in2, strin1, strin2;
581
ARRAY<int> bounds1, bounds2;
582
583
s1 -> RecBoundaries (p, bounds1, in1, strin1);
584
s2 -> RecBoundaries (p, bounds2, in2, strin2);
585
586
if (in1 && in2)
587
{
588
for (i = 1; i <= bounds1.Size(); i++)
589
bounds.Append (bounds1.Get(i));
590
for (i = 1; i <= bounds2.Size(); i++)
591
bounds.Append (bounds2.Get(i));
592
}
593
in = (in1 && in2);
594
strin = (strin1 && strin2);
595
break;
596
}
597
case UNION:
598
{
599
int i, in1, in2, strin1, strin2;
600
ARRAY<int> bounds1, bounds2;
601
602
s1 -> RecBoundaries (p, bounds1, in1, strin1);
603
s2 -> RecBoundaries (p, bounds2, in2, strin2);
604
605
if (!strin1 && !strin2)
606
{
607
for (i = 1; i <= bounds1.Size(); i++)
608
bounds.Append (bounds1.Get(i));
609
for (i = 1; i <= bounds2.Size(); i++)
610
bounds.Append (bounds2.Get(i));
611
}
612
in = (in1 || in2);
613
strin = (strin1 || strin2);
614
break;
615
}
616
case SUB:
617
{
618
int hin, hstrin;
619
s1 -> RecBoundaries (p, bounds, hin, hstrin);
620
in = !hstrin;
621
strin = !hin;
622
break;
623
}
624
625
case ROOT:
626
{
627
s1 -> RecBoundaries (p, bounds, in, strin);
628
break;
629
}
630
}
631
}
632
633
634
void Solid :: TangentialSolid (const Point<3> & p, Solid *& tansol, ARRAY<int> & surfids, double eps) const
635
{
636
int in, strin;
637
RecTangentialSolid (p, tansol, surfids, in, strin, eps);
638
surfids.SetSize (0);
639
if (tansol)
640
tansol -> GetTangentialSurfaceIndices (p, surfids, eps);
641
}
642
643
644
void Solid :: RecTangentialSolid (const Point<3> & p, Solid *& tansol, ARRAY<int> & surfids,
645
int & in, int & strin, double eps) const
646
{
647
tansol = NULL;
648
649
switch (op)
650
{
651
case TERM: case TERM_REF:
652
{
653
INSOLID_TYPE ist = prim->PointInSolid(p, eps);
654
655
in = (ist == IS_INSIDE || ist == DOES_INTERSECT);
656
strin = (ist == IS_INSIDE);
657
658
if (ist == DOES_INTERSECT)
659
{
660
tansol = new Solid (prim);
661
tansol -> op = TERM_REF;
662
}
663
break;
664
}
665
case SECTION:
666
{
667
int in1, in2, strin1, strin2;
668
Solid * tansol1, * tansol2;
669
670
s1 -> RecTangentialSolid (p, tansol1, surfids, in1, strin1, eps);
671
s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps);
672
673
if (in1 && in2)
674
{
675
if (tansol1 && tansol2)
676
tansol = new Solid (SECTION, tansol1, tansol2);
677
else if (tansol1)
678
tansol = tansol1;
679
else if (tansol2)
680
tansol = tansol2;
681
}
682
in = (in1 && in2);
683
strin = (strin1 && strin2);
684
break;
685
}
686
case UNION:
687
{
688
int in1, in2, strin1, strin2;
689
Solid * tansol1, * tansol2;
690
691
s1 -> RecTangentialSolid (p, tansol1, surfids, in1, strin1, eps);
692
s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps);
693
694
if (!strin1 && !strin2)
695
{
696
if (tansol1 && tansol2)
697
tansol = new Solid (UNION, tansol1, tansol2);
698
else if (tansol1)
699
tansol = tansol1;
700
else if (tansol2)
701
tansol = tansol2;
702
}
703
in = (in1 || in2);
704
strin = (strin1 || strin2);
705
break;
706
}
707
case SUB:
708
{
709
int hin, hstrin;
710
Solid * tansol1;
711
712
s1 -> RecTangentialSolid (p, tansol1, surfids, hin, hstrin, eps);
713
714
if (tansol1)
715
tansol = new Solid (SUB, tansol1);
716
in = !hstrin;
717
strin = !hin;
718
break;
719
}
720
case ROOT:
721
{
722
s1 -> RecTangentialSolid (p, tansol, surfids, in, strin, eps);
723
break;
724
}
725
}
726
}
727
728
729
730
731
void Solid :: TangentialSolid2 (const Point<3> & p,
732
const Vec<3> & t,
733
Solid *& tansol, ARRAY<int> & surfids, double eps) const
734
{
735
int in, strin;
736
surfids.SetSize (0);
737
RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps);
738
if (tansol)
739
tansol -> GetTangentialSurfaceIndices2 (p, t, surfids, eps);
740
}
741
742
void Solid :: RecTangentialSolid2 (const Point<3> & p, const Vec<3> & t,
743
Solid *& tansol, ARRAY<int> & surfids,
744
int & in, int & strin, double eps) const
745
{
746
tansol = NULL;
747
748
switch (op)
749
{
750
case TERM: case TERM_REF:
751
{
752
/*
753
double val;
754
val = surf->CalcFunctionValue (p);
755
in = (val < 1e-6);
756
strin = (val < -1e-6);
757
if (in && !strin)
758
tansol = new Solid (surf, id);
759
*/
760
761
INSOLID_TYPE ist = prim->PointInSolid(p, eps);
762
if (ist == DOES_INTERSECT)
763
ist = prim->VecInSolid (p, t, eps);
764
765
in = (ist == IS_INSIDE || ist == DOES_INTERSECT);
766
strin = (ist == IS_INSIDE);
767
768
if (ist == DOES_INTERSECT)
769
{
770
tansol = new Solid (prim);
771
tansol -> op = TERM_REF;
772
}
773
break;
774
}
775
case SECTION:
776
{
777
int in1, in2, strin1, strin2;
778
Solid * tansol1, * tansol2;
779
780
s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, in1, strin1, eps);
781
s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps);
782
783
if (in1 && in2)
784
{
785
if (tansol1 && tansol2)
786
tansol = new Solid (SECTION, tansol1, tansol2);
787
else if (tansol1)
788
tansol = tansol1;
789
else if (tansol2)
790
tansol = tansol2;
791
}
792
in = (in1 && in2);
793
strin = (strin1 && strin2);
794
break;
795
}
796
case UNION:
797
{
798
int in1, in2, strin1, strin2;
799
Solid * tansol1, * tansol2;
800
801
s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, in1, strin1, eps);
802
s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps);
803
804
if (!strin1 && !strin2)
805
{
806
if (tansol1 && tansol2)
807
tansol = new Solid (UNION, tansol1, tansol2);
808
else if (tansol1)
809
tansol = tansol1;
810
else if (tansol2)
811
tansol = tansol2;
812
}
813
in = (in1 || in2);
814
strin = (strin1 || strin2);
815
break;
816
}
817
case SUB:
818
{
819
int hin, hstrin;
820
Solid * tansol1;
821
822
s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, hin, hstrin, eps);
823
824
if (tansol1)
825
tansol = new Solid (SUB, tansol1);
826
in = !hstrin;
827
strin = !hin;
828
break;
829
}
830
case ROOT:
831
{
832
s1 -> RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps);
833
break;
834
}
835
}
836
}
837
838
839
840
841
842
843
844
845
void Solid :: TangentialSolid3 (const Point<3> & p,
846
const Vec<3> & t, const Vec<3> & t2,
847
Solid *& tansol, ARRAY<int> & surfids,
848
double eps) const
849
{
850
int in, strin;
851
surfids.SetSize (0);
852
RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps);
853
854
if (tansol)
855
tansol -> GetTangentialSurfaceIndices3 (p, t, t2, surfids, eps);
856
}
857
858
void Solid :: RecTangentialSolid3 (const Point<3> & p,
859
const Vec<3> & t, const Vec<3> & t2,
860
Solid *& tansol, ARRAY<int> & surfids,
861
int & in, int & strin, double eps) const
862
{
863
tansol = NULL;
864
865
switch (op)
866
{
867
case TERM: case TERM_REF:
868
{
869
INSOLID_TYPE ist = prim->PointInSolid(p, eps);
870
871
if (ist == DOES_INTERSECT)
872
{
873
//(*testout) << "Calling VecInSolid3..." << endl;
874
ist = prim->VecInSolid3 (p, t, t2, eps);
875
//(*testout) << "...done" << endl;
876
}
877
in = (ist == IS_INSIDE || ist == DOES_INTERSECT);
878
strin = (ist == IS_INSIDE);
879
880
if (ist == DOES_INTERSECT)
881
{
882
tansol = new Solid (prim);
883
tansol -> op = TERM_REF;
884
}
885
break;
886
}
887
case SECTION:
888
{
889
int in1, in2, strin1, strin2;
890
Solid * tansol1, * tansol2;
891
892
s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps);
893
s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps);
894
895
if (in1 && in2)
896
{
897
if (tansol1 && tansol2)
898
tansol = new Solid (SECTION, tansol1, tansol2);
899
else if (tansol1)
900
tansol = tansol1;
901
else if (tansol2)
902
tansol = tansol2;
903
}
904
in = (in1 && in2);
905
strin = (strin1 && strin2);
906
break;
907
}
908
case UNION:
909
{
910
int in1, in2, strin1, strin2;
911
Solid * tansol1, * tansol2;
912
913
s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps);
914
s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps);
915
916
if (!strin1 && !strin2)
917
{
918
if (tansol1 && tansol2)
919
tansol = new Solid (UNION, tansol1, tansol2);
920
else if (tansol1)
921
tansol = tansol1;
922
else if (tansol2)
923
tansol = tansol2;
924
}
925
in = (in1 || in2);
926
strin = (strin1 || strin2);
927
break;
928
}
929
case SUB:
930
{
931
int hin, hstrin;
932
Solid * tansol1;
933
934
s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, hin, hstrin, eps);
935
936
if (tansol1)
937
tansol = new Solid (SUB, tansol1);
938
in = !hstrin;
939
strin = !hin;
940
break;
941
}
942
case ROOT:
943
{
944
s1 -> RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps);
945
break;
946
}
947
}
948
}
949
950
951
952
953
954
955
956
957
958
959
960
void Solid :: TangentialEdgeSolid (const Point<3> & p,
961
const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m,
962
Solid *& tansol, ARRAY<int> & surfids,
963
double eps) const
964
{
965
int in, strin;
966
surfids.SetSize (0);
967
968
// *testout << "tangentialedgesolid,sol = " << (*this) << endl;
969
RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps);
970
971
if (tansol)
972
tansol -> RecGetTangentialEdgeSurfaceIndices (p, t, t2, m, surfids, eps);
973
}
974
975
void Solid :: RecTangentialEdgeSolid (const Point<3> & p,
976
const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m,
977
Solid *& tansol, ARRAY<int> & surfids,
978
int & in, int & strin, double eps) const
979
{
980
tansol = NULL;
981
982
switch (op)
983
{
984
case TERM: case TERM_REF:
985
{
986
INSOLID_TYPE ist = prim->PointInSolid(p, eps);
987
988
/*
989
(*testout) << "tangedgesolid, p = " << p << ", t = " << t
990
<< " for prim " << typeid (*prim).name()
991
<< " with surf " << prim->GetSurface() << endl;
992
(*testout) << "ist = " << ist << endl;
993
*/
994
995
if (ist == DOES_INTERSECT)
996
ist = prim->VecInSolid4 (p, t, t2, m, eps);
997
998
// (*testout) << "ist2 = " << ist << endl;
999
1000
in = (ist == IS_INSIDE || ist == DOES_INTERSECT);
1001
strin = (ist == IS_INSIDE);
1002
1003
if (ist == DOES_INTERSECT)
1004
{
1005
tansol = new Solid (prim);
1006
tansol -> op = TERM_REF;
1007
}
1008
break;
1009
}
1010
case SECTION:
1011
{
1012
int in1, in2, strin1, strin2;
1013
Solid * tansol1, * tansol2;
1014
1015
s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps);
1016
s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps);
1017
1018
if (in1 && in2)
1019
{
1020
if (tansol1 && tansol2)
1021
tansol = new Solid (SECTION, tansol1, tansol2);
1022
else if (tansol1)
1023
tansol = tansol1;
1024
else if (tansol2)
1025
tansol = tansol2;
1026
}
1027
in = (in1 && in2);
1028
strin = (strin1 && strin2);
1029
break;
1030
}
1031
case UNION:
1032
{
1033
int in1, in2, strin1, strin2;
1034
Solid * tansol1, * tansol2;
1035
1036
s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps);
1037
s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps);
1038
1039
if (!strin1 && !strin2)
1040
{
1041
if (tansol1 && tansol2)
1042
tansol = new Solid (UNION, tansol1, tansol2);
1043
else if (tansol1)
1044
tansol = tansol1;
1045
else if (tansol2)
1046
tansol = tansol2;
1047
}
1048
in = (in1 || in2);
1049
strin = (strin1 || strin2);
1050
break;
1051
}
1052
case SUB:
1053
{
1054
int hin, hstrin;
1055
Solid * tansol1;
1056
1057
s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, hin, hstrin, eps);
1058
1059
if (tansol1)
1060
tansol = new Solid (SUB, tansol1);
1061
in = !hstrin;
1062
strin = !hin;
1063
break;
1064
}
1065
case ROOT:
1066
{
1067
s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps);
1068
break;
1069
}
1070
}
1071
}
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
int Solid :: Edge (const Point<3> & p, const Vec<3> & v, double eps) const
1089
{
1090
int in, strin, faces;
1091
RecEdge (p, v, in, strin, faces, eps);
1092
return faces >= 2;
1093
}
1094
1095
int Solid :: OnFace (const Point<3> & p, const Vec<3> & v, double eps) const
1096
{
1097
int in, strin, faces;
1098
RecEdge (p, v, in, strin, faces, eps);
1099
return faces >= 1;
1100
}
1101
1102
1103
void Solid :: RecEdge (const Point<3> & p, const Vec<3> & v,
1104
int & in, int & strin, int & faces, double eps) const
1105
{
1106
switch (op)
1107
{
1108
case TERM: case TERM_REF:
1109
{
1110
INSOLID_TYPE ist = prim->VecInSolid (p, v, eps);
1111
in = (ist == IS_INSIDE || ist == DOES_INTERSECT);
1112
strin = (ist == IS_INSIDE);
1113
/*
1114
in = VectorIn (p, v);
1115
strin = VectorStrictIn (p, v);
1116
*/
1117
faces = 0;
1118
1119
if (in && ! strin)
1120
{
1121
// faces = 1;
1122
int i;
1123
Vec<3> grad;
1124
for (i = 0; i < prim->GetNSurfaces(); i++)
1125
{
1126
double val = prim->GetSurface(i).CalcFunctionValue(p);
1127
prim->GetSurface(i).CalcGradient (p, grad);
1128
if (fabs (val) < eps && fabs (v * grad) < 1e-6)
1129
faces++;
1130
}
1131
}
1132
// else
1133
// faces = 0;
1134
break;
1135
}
1136
case SECTION:
1137
{
1138
int in1, in2, strin1, strin2, faces1, faces2;
1139
1140
s1 -> RecEdge (p, v, in1, strin1, faces1, eps);
1141
s2 -> RecEdge (p, v, in2, strin2, faces2, eps);
1142
1143
faces = 0;
1144
if (in1 && in2)
1145
faces = faces1 + faces2;
1146
in = in1 && in2;
1147
strin = strin1 && strin2;
1148
break;
1149
}
1150
case UNION:
1151
{
1152
int in1, in2, strin1, strin2, faces1, faces2;
1153
1154
s1 -> RecEdge (p, v, in1, strin1, faces1, eps);
1155
s2 -> RecEdge (p, v, in2, strin2, faces2, eps);
1156
1157
faces = 0;
1158
if (!strin1 && !strin2)
1159
faces = faces1 + faces2;
1160
in = in1 || in2;
1161
strin = strin1 || strin2;
1162
break;
1163
}
1164
case SUB:
1165
{
1166
int in1, strin1;
1167
s1 -> RecEdge (p, v, in1, strin1, faces, eps);
1168
in = !strin1;
1169
strin = !in1;
1170
break;
1171
}
1172
case ROOT:
1173
{
1174
s1 -> RecEdge (p, v, in, strin, faces, eps);
1175
break;
1176
}
1177
}
1178
}
1179
1180
1181
void Solid :: CalcSurfaceInverse ()
1182
{
1183
CalcSurfaceInverseRec (0);
1184
}
1185
1186
void Solid :: CalcSurfaceInverseRec (int inv)
1187
{
1188
switch (op)
1189
{
1190
case TERM: case TERM_REF:
1191
{
1192
bool priminv;
1193
for (int i = 0; i < prim->GetNSurfaces(); i++)
1194
{
1195
priminv = (prim->SurfaceInverted(i) != 0);
1196
if (inv) priminv = !priminv;
1197
prim->GetSurface(i).SetInverse (priminv);
1198
}
1199
break;
1200
}
1201
case UNION:
1202
case SECTION:
1203
{
1204
s1 -> CalcSurfaceInverseRec (inv);
1205
s2 -> CalcSurfaceInverseRec (inv);
1206
break;
1207
}
1208
case SUB:
1209
{
1210
s1 -> CalcSurfaceInverseRec (1 - inv);
1211
break;
1212
}
1213
case ROOT:
1214
{
1215
s1 -> CalcSurfaceInverseRec (inv);
1216
break;
1217
}
1218
}
1219
}
1220
1221
1222
Solid * Solid :: GetReducedSolid (const BoxSphere<3> & box) const
1223
{
1224
INSOLID_TYPE in;
1225
return RecGetReducedSolid (box, in);
1226
}
1227
1228
Solid * Solid :: RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const
1229
{
1230
Solid * redsol = NULL;
1231
1232
switch (op)
1233
{
1234
case TERM:
1235
case TERM_REF:
1236
{
1237
in = prim -> BoxInSolid (box);
1238
if (in == DOES_INTERSECT)
1239
{
1240
redsol = new Solid (prim);
1241
redsol -> op = TERM_REF;
1242
}
1243
break;
1244
}
1245
case SECTION:
1246
{
1247
INSOLID_TYPE in1, in2;
1248
Solid * redsol1, * redsol2;
1249
1250
redsol1 = s1 -> RecGetReducedSolid (box, in1);
1251
redsol2 = s2 -> RecGetReducedSolid (box, in2);
1252
1253
if (in1 == IS_OUTSIDE || in2 == IS_OUTSIDE)
1254
{
1255
if (in1 == DOES_INTERSECT) delete redsol1;
1256
if (in2 == DOES_INTERSECT) delete redsol2;
1257
in = IS_OUTSIDE;
1258
}
1259
else
1260
{
1261
if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT)
1262
in = DOES_INTERSECT;
1263
else
1264
in = IS_INSIDE;
1265
1266
if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT)
1267
redsol = new Solid (SECTION, redsol1, redsol2);
1268
else if (in1 == DOES_INTERSECT)
1269
redsol = redsol1;
1270
else if (in2 == DOES_INTERSECT)
1271
redsol = redsol2;
1272
}
1273
break;
1274
}
1275
1276
case UNION:
1277
{
1278
INSOLID_TYPE in1, in2;
1279
Solid * redsol1, * redsol2;
1280
1281
redsol1 = s1 -> RecGetReducedSolid (box, in1);
1282
redsol2 = s2 -> RecGetReducedSolid (box, in2);
1283
1284
if (in1 == IS_INSIDE || in2 == IS_INSIDE)
1285
{
1286
if (in1 == DOES_INTERSECT) delete redsol1;
1287
if (in2 == DOES_INTERSECT) delete redsol2;
1288
in = IS_INSIDE;
1289
}
1290
else
1291
{
1292
if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT) in = DOES_INTERSECT;
1293
else in = IS_OUTSIDE;
1294
1295
if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT)
1296
redsol = new Solid (UNION, redsol1, redsol2);
1297
else if (in1 == DOES_INTERSECT)
1298
redsol = redsol1;
1299
else if (in2 == DOES_INTERSECT)
1300
redsol = redsol2;
1301
}
1302
break;
1303
}
1304
1305
case SUB:
1306
{
1307
INSOLID_TYPE in1;
1308
Solid * redsol1 = s1 -> RecGetReducedSolid (box, in1);
1309
1310
switch (in1)
1311
{
1312
case IS_OUTSIDE: in = IS_INSIDE; break;
1313
case IS_INSIDE: in = IS_OUTSIDE; break;
1314
case DOES_INTERSECT: in = DOES_INTERSECT; break;
1315
}
1316
1317
if (redsol1)
1318
redsol = new Solid (SUB, redsol1);
1319
break;
1320
}
1321
1322
case ROOT:
1323
{
1324
INSOLID_TYPE in1;
1325
redsol = s1 -> RecGetReducedSolid (box, in1);
1326
in = in1;
1327
break;
1328
}
1329
}
1330
1331
/*
1332
if (redsol)
1333
(*testout) << "getrecsolid, redsol = " << endl << (*redsol) << endl;
1334
else
1335
(*testout) << "redsol is null" << endl;
1336
*/
1337
1338
return redsol;
1339
}
1340
1341
1342
int Solid :: NumPrimitives () const
1343
{
1344
switch (op)
1345
{
1346
case TERM: case TERM_REF:
1347
{
1348
return 1;
1349
}
1350
case UNION:
1351
case SECTION:
1352
{
1353
return s1->NumPrimitives () + s2 -> NumPrimitives();
1354
}
1355
case SUB:
1356
case ROOT:
1357
{
1358
return s1->NumPrimitives ();
1359
}
1360
}
1361
return 0;
1362
}
1363
1364
void Solid :: GetSurfaceIndices (ARRAY<int> & surfind) const
1365
{
1366
surfind.SetSize (0);
1367
RecGetSurfaceIndices (surfind);
1368
}
1369
1370
void Solid :: RecGetSurfaceIndices (ARRAY<int> & surfind) const
1371
{
1372
switch (op)
1373
{
1374
case TERM: case TERM_REF:
1375
{
1376
/*
1377
int i;
1378
for (i = 1; i <= surfind.Size(); i++)
1379
if (surfind.Get(i) == prim->GetSurfaceId())
1380
return;
1381
surfind.Append (prim->GetSurfaceId());
1382
break;
1383
*/
1384
for (int j = 0; j < prim->GetNSurfaces(); j++)
1385
if (prim->SurfaceActive (j))
1386
{
1387
bool found = 0;
1388
int siprim = prim->GetSurfaceId(j);
1389
1390
for (int i = 0; i < surfind.Size(); i++)
1391
if (surfind[i] == siprim)
1392
{
1393
found = 1;
1394
break;
1395
}
1396
if (!found) surfind.Append (siprim);
1397
}
1398
break;
1399
}
1400
case UNION:
1401
case SECTION:
1402
{
1403
s1 -> RecGetSurfaceIndices (surfind);
1404
s2 -> RecGetSurfaceIndices (surfind);
1405
break;
1406
}
1407
case SUB:
1408
case ROOT:
1409
{
1410
s1 -> RecGetSurfaceIndices (surfind);
1411
break;
1412
}
1413
}
1414
}
1415
1416
1417
1418
void Solid :: GetTangentialSurfaceIndices (const Point<3> & p, ARRAY<int> & surfind, double eps) const
1419
{
1420
surfind.SetSize (0);
1421
RecGetTangentialSurfaceIndices (p, surfind, eps);
1422
}
1423
1424
void Solid :: RecGetTangentialSurfaceIndices (const Point<3> & p, ARRAY<int> & surfind, double eps) const
1425
{
1426
switch (op)
1427
{
1428
case TERM: case TERM_REF:
1429
{
1430
/*
1431
for (int j = 0; j < prim->GetNSurfaces(); j++)
1432
if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps)
1433
if (!surfind.Contains (prim->GetSurfaceId(j)))
1434
surfind.Append (prim->GetSurfaceId(j));
1435
*/
1436
prim->GetTangentialSurfaceIndices (p, surfind, eps);
1437
break;
1438
}
1439
case UNION:
1440
case SECTION:
1441
{
1442
s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps);
1443
s2 -> RecGetTangentialSurfaceIndices (p, surfind, eps);
1444
break;
1445
}
1446
case SUB:
1447
case ROOT:
1448
{
1449
s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps);
1450
break;
1451
}
1452
}
1453
}
1454
1455
1456
1457
1458
1459
1460
void Solid :: GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v,
1461
ARRAY<int> & surfind, double eps) const
1462
{
1463
surfind.SetSize (0);
1464
RecGetTangentialSurfaceIndices2 (p, v, surfind, eps);
1465
}
1466
1467
void Solid :: RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v,
1468
ARRAY<int> & surfind, double eps) const
1469
{
1470
switch (op)
1471
{
1472
case TERM: case TERM_REF:
1473
{
1474
for (int j = 0; j < prim->GetNSurfaces(); j++)
1475
{
1476
if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps)
1477
{
1478
Vec<3> grad;
1479
prim->GetSurface(j).CalcGradient (p, grad);
1480
if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2())
1481
{
1482
if (!surfind.Contains (prim->GetSurfaceId(j)))
1483
surfind.Append (prim->GetSurfaceId(j));
1484
}
1485
}
1486
}
1487
break;
1488
}
1489
case UNION:
1490
case SECTION:
1491
{
1492
s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps);
1493
s2 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps);
1494
break;
1495
}
1496
case SUB:
1497
case ROOT:
1498
{
1499
s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps);
1500
break;
1501
}
1502
}
1503
}
1504
1505
1506
1507
1508
1509
1510
1511
1512
void Solid :: GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,
1513
ARRAY<int> & surfind, double eps) const
1514
{
1515
surfind.SetSize (0);
1516
RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps);
1517
}
1518
1519
void Solid :: RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2,
1520
ARRAY<int> & surfind, double eps) const
1521
{
1522
switch (op)
1523
{
1524
case TERM: case TERM_REF:
1525
{
1526
for (int j = 0; j < prim->GetNSurfaces(); j++)
1527
{
1528
if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps)
1529
{
1530
Vec<3> grad;
1531
prim->GetSurface(j).CalcGradient (p, grad);
1532
if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2())
1533
{
1534
// (*testout) << "p2" << endl;
1535
Mat<3> hesse;
1536
prim->GetSurface(j).CalcHesse (p, hesse);
1537
double hv2 = v2 * grad + v * (hesse * v);
1538
1539
if (fabs (hv2) < 1e-6)
1540
{
1541
if (!surfind.Contains (prim->GetSurfaceId(j)))
1542
surfind.Append (prim->GetSurfaceId(j));
1543
}
1544
}
1545
}
1546
}
1547
break;
1548
}
1549
case UNION:
1550
case SECTION:
1551
{
1552
s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps);
1553
s2 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps);
1554
break;
1555
}
1556
case SUB:
1557
case ROOT:
1558
{
1559
s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps);
1560
break;
1561
}
1562
}
1563
}
1564
1565
1566
1567
1568
1569
void Solid :: RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m,
1570
ARRAY<int> & surfind, double eps) const
1571
{
1572
switch (op)
1573
{
1574
case TERM: case TERM_REF:
1575
{
1576
// *testout << "check vecinsolid4, p = " << p << ", v = " << v << "; m = " << m << endl;
1577
if (prim->VecInSolid4 (p, v, v2, m, eps) == DOES_INTERSECT)
1578
{
1579
prim->GetTangentialVecSurfaceIndices2 (p, v, m, surfind, eps);
1580
/*
1581
for (int j = 0; j < prim->GetNSurfaces(); j++)
1582
{
1583
if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps)
1584
{
1585
Vec<3> grad;
1586
prim->GetSurface(j).CalcGradient (p, grad);
1587
*testout << "grad = " << grad << endl;
1588
if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2() &&
1589
sqr (grad * m) < 1e-6 * m.Length2() * grad.Length2() ) // new, 18032006 JS
1590
1591
{
1592
*testout << "add surf " << prim->GetSurfaceId(j) << endl;
1593
if (!surfind.Contains (prim->GetSurfaceId(j)))
1594
surfind.Append (prim->GetSurfaceId(j));
1595
}
1596
}
1597
}
1598
*/
1599
}
1600
break;
1601
}
1602
case UNION:
1603
case SECTION:
1604
{
1605
s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps);
1606
s2 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps);
1607
break;
1608
}
1609
case SUB:
1610
case ROOT:
1611
{
1612
s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps);
1613
break;
1614
}
1615
}
1616
}
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
void Solid :: GetSurfaceIndices (IndexSet & iset) const
1630
{
1631
iset.Clear();
1632
RecGetSurfaceIndices (iset);
1633
}
1634
1635
void Solid :: RecGetSurfaceIndices (IndexSet & iset) const
1636
{
1637
switch (op)
1638
{
1639
case TERM: case TERM_REF:
1640
{
1641
/*
1642
int i;
1643
for (i = 1; i <= surfind.Size(); i++)
1644
if (surfind.Get(i) == prim->GetSurfaceId())
1645
return;
1646
surfind.Append (prim->GetSurfaceId());
1647
break;
1648
*/
1649
for (int j = 0; j < prim->GetNSurfaces(); j++)
1650
if (prim->SurfaceActive (j))
1651
{
1652
int siprim = prim->GetSurfaceId(j);
1653
iset.Add (siprim);
1654
}
1655
break;
1656
}
1657
case UNION:
1658
case SECTION:
1659
{
1660
s1 -> RecGetSurfaceIndices (iset);
1661
s2 -> RecGetSurfaceIndices (iset);
1662
break;
1663
}
1664
case SUB:
1665
case ROOT:
1666
{
1667
s1 -> RecGetSurfaceIndices (iset);
1668
break;
1669
}
1670
}
1671
}
1672
1673
1674
void Solid :: CalcOnePrimitiveSpecialPoints (const Box<3> & box, ARRAY<Point<3> > & pts) const
1675
{
1676
double eps = 1e-8 * box.Diam ();
1677
1678
pts.SetSize (0);
1679
this -> RecCalcOnePrimitiveSpecialPoints (pts);
1680
for (int i = pts.Size()-1; i >= 0; i--)
1681
{
1682
if (!IsIn (pts[i],eps) || IsStrictIn (pts[i],eps))
1683
pts.Delete (i);
1684
}
1685
}
1686
1687
void Solid :: RecCalcOnePrimitiveSpecialPoints (ARRAY<Point<3> > & pts) const
1688
{
1689
switch (op)
1690
{
1691
case TERM: case TERM_REF:
1692
{
1693
prim -> CalcSpecialPoints (pts);
1694
break;
1695
}
1696
case UNION:
1697
case SECTION:
1698
{
1699
s1 -> RecCalcOnePrimitiveSpecialPoints (pts);
1700
s2 -> RecCalcOnePrimitiveSpecialPoints (pts);
1701
break;
1702
}
1703
case SUB:
1704
case ROOT:
1705
{
1706
s1 -> RecCalcOnePrimitiveSpecialPoints (pts);
1707
break;
1708
}
1709
}
1710
}
1711
1712
1713
1714
1715
BlockAllocator Solid :: ball(sizeof (Solid));
1716
}
1717
1718