Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/csg/extrusion.cpp
3206 views
1
#include <mystdlib.h>
2
3
#include <linalg.hpp>
4
#include <csg.hpp>
5
6
7
namespace netgen
8
{
9
10
void ExtrusionFace :: Init(void)
11
{
12
p0.SetSize(path->GetNSplines());
13
x_dir.SetSize(path->GetNSplines());
14
y_dir.SetSize(path->GetNSplines());
15
z_dir.SetSize(path->GetNSplines());
16
loc_z_dir.SetSize(path->GetNSplines());
17
spline3_path.SetSize(path->GetNSplines());
18
line_path.SetSize(path->GetNSplines());
19
20
for(int i=0; i<path->GetNSplines(); i++)
21
{
22
spline3_path[i] = dynamic_cast < const SplineSeg3<3>* >(&path->GetSpline(i));
23
line_path[i] = dynamic_cast < const LineSeg<3>* >(&path->GetSpline(i));
24
25
if(line_path[i])
26
{
27
y_dir[i] = line_path[i]->EndPI() - line_path[i]->StartPI();
28
y_dir[i].Normalize();
29
z_dir[i] = glob_z_direction;
30
Orthogonalize(y_dir[i],z_dir[i]);
31
x_dir[i] = Cross(y_dir[i],z_dir[i]);
32
loc_z_dir[i] = z_dir[i];
33
}
34
else
35
{
36
z_dir[i] = glob_z_direction;
37
loc_z_dir[i] = glob_z_direction;
38
}
39
}
40
41
profile->GetCoeff(profile_spline_coeff);
42
latest_point3d = -1.111e30;
43
44
}
45
46
47
ExtrusionFace :: ExtrusionFace(const SplineSeg<2> * profile_in,
48
const SplineGeometry<3> * path_in,
49
const Vec<3> & z_direction) :
50
profile(profile_in), path(path_in), glob_z_direction(z_direction)
51
{
52
deletable = false;
53
54
Init();
55
}
56
57
ExtrusionFace :: ExtrusionFace(const ARRAY<double> & raw_data)
58
{
59
deletable = true;
60
61
int pos=0;
62
63
ARRAY< Point<2> > p(3);
64
65
int ptype = int(raw_data[pos]); pos++;
66
67
for(int i=0; i<ptype; i++)
68
{
69
p[i](0) = raw_data[pos]; pos++;
70
p[i](1) = raw_data[pos]; pos++;
71
}
72
if(ptype == 2)
73
{
74
profile = new LineSeg<2>(GeomPoint<2>(p[0],1),
75
GeomPoint<2>(p[1],1));
76
//(*testout) << "appending LineSeg<2> " << p[0]
77
// << " to " << p[1] << endl;
78
}
79
else if(ptype == 3)
80
{
81
profile = new SplineSeg3<2>(GeomPoint<2>(p[0],1),
82
GeomPoint<2>(p[1],1),
83
GeomPoint<2>(p[2],1));
84
//(*testout) << "appending SplineSeg<3> "
85
// << p[0] << " -- " << p[1] << " -- " << p[2] << endl;
86
}
87
88
path = new SplineGeometry<3>;
89
pos = const_cast< SplineGeometry<3> *>(path)->Load(raw_data,pos);
90
91
for(int i=0; i<3; i++)
92
{
93
glob_z_direction(i) = raw_data[pos];
94
pos++;
95
}
96
97
//(*testout) << "read glob_z_direction " << glob_z_direction << endl;
98
99
Init();
100
101
}
102
103
ExtrusionFace :: ~ExtrusionFace()
104
{
105
if(deletable)
106
{
107
delete profile;
108
delete path;
109
}
110
}
111
112
113
int ExtrusionFace :: IsIdentic (const Surface & s2, int & inv, double eps) const
114
{
115
const ExtrusionFace * ext2 = dynamic_cast<const ExtrusionFace*>(&s2);
116
117
if(!ext2) return 0;
118
119
if(ext2 == this)
120
return 1;
121
122
return 0;
123
}
124
125
void ExtrusionFace :: Orthogonalize(const Vec<3> & v1, Vec<3> & v2) const
126
{
127
v2 -= (v1*v2)*v1;
128
v2.Normalize();
129
}
130
131
132
void ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d,
133
int & seg, double & t) const
134
{
135
if(Dist2(point3d,latest_point3d) < 1e-25*Dist2(path->GetSpline(0).StartPI(),path->GetSpline(0).EndPI()))
136
{
137
point2d = latest_point2d;
138
seg = latest_seg;
139
t = latest_t;
140
return;
141
}
142
143
latest_point3d = point3d;
144
145
double cutdist(-1);
146
147
148
149
150
ARRAY<double> mindist(path->GetNSplines());
151
152
for(int i=0; i<path->GetNSplines(); i++)
153
{
154
155
double auxcut(-1);
156
double auxmin(-1);
157
158
if(spline3_path[i])
159
{
160
Point<3> startp(path->GetSpline(i).StartPI());
161
Point<3> endp(path->GetSpline(i).EndPI());
162
Point<3> tanp(spline3_path[i]->TangentPoint());
163
double da,db,dc;
164
165
double l;
166
Vec<3> dir = endp-startp;
167
l = dir.Length(); dir *= 1./l;
168
Vec<3> topoint = point3d - startp;
169
double s = topoint * dir;
170
if(s<=0)
171
da = topoint.Length();
172
else if(s>=l)
173
da = Dist(endp,point3d);
174
else
175
da = sqrt(topoint.Length2() - s*s);
176
177
dir = tanp - startp;
178
l = dir.Length(); dir *= 1./l;
179
topoint = point3d - startp;
180
s = topoint * dir;
181
if(s<=0)
182
db = topoint.Length();
183
else if(s>=l)
184
db = Dist(tanp,point3d);
185
else
186
db = sqrt(topoint.Length2() - s*s);
187
188
dir = endp - tanp;
189
l = dir.Length(); dir *= 1./l;
190
topoint = point3d - tanp;
191
s = topoint * dir;
192
if(s<=0)
193
dc = topoint.Length();
194
else if(s>=l)
195
dc = Dist(endp,point3d);
196
else
197
dc = sqrt(topoint.Length2() - s*s);
198
199
if(da > db && da > dc)
200
auxcut = da;
201
else
202
auxcut = max2(da,min2(db,dc));
203
204
auxmin = min3(da,db,dc);
205
}
206
else if(line_path[i])
207
{
208
double l;
209
Vec<3> dir = path->GetSpline(i).EndPI() - path->GetSpline(i).StartPI();
210
l = dir.Length(); dir *= 1./l;
211
Vec<3> topoint = point3d - path->GetSpline(i).StartPI();
212
double s = topoint * dir;
213
if(s<=0)
214
auxcut = topoint.Length();
215
else if(s>=l)
216
auxcut = Dist(path->GetSpline(i).EndPI(),point3d);
217
else
218
auxcut = sqrt(topoint.Length2() - s*s);
219
220
auxmin = auxcut;
221
}
222
223
224
mindist[i] = auxmin;
225
226
if(i==0 || auxcut < cutdist)
227
cutdist = auxcut;
228
229
230
231
232
/*
233
double d1 = Dist2(point3d,path.GetSpline(i).StartPI());
234
double d2 = Dist2(point3d,path.GetSpline(i).EndPI());
235
if(d1 <= d2)
236
{
237
mindist[i] = d1;
238
if(i==0 || d2 < cutdist)
239
cutdist = d2;
240
}
241
else
242
{
243
mindist[i] = d2;
244
if(i==0 || d1 < cutdist)
245
cutdist = d1;
246
}
247
*/
248
}
249
250
251
//(*testout) << " cutdist " << cutdist << " mindist " << mindist << endl;
252
253
254
Point<2> testpoint2d;
255
Point<3> testpoint3d;
256
257
double minproj(-1);
258
bool minproj_set(false);
259
260
261
//(*testout) << "point "<< point3d << " candidates: ";
262
for(int i=0; i<path->GetNSplines(); i++)
263
{
264
if(mindist[i] > cutdist) continue;
265
//(*testout) << i << " ";
266
267
double thist = CalcProj(point3d,testpoint2d,i);
268
testpoint3d = p0[i] + testpoint2d(0)*x_dir[i] + testpoint2d(1)*loc_z_dir[i];
269
double d = Dist2(point3d,testpoint3d);
270
//(*testout) << "(d="<<d<<") ";
271
272
if(!minproj_set || d < minproj)
273
{
274
minproj_set = true;
275
minproj = d;
276
point2d = testpoint2d;
277
t = thist;
278
seg = i;
279
latest_seg = i;
280
latest_t = t;
281
latest_point2d = point2d;
282
}
283
}
284
//(*testout) << endl;
285
//(*testout) << " t " << t << endl;
286
287
}
288
289
double ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d,
290
const int seg) const
291
{
292
double t(-1);
293
294
if(line_path[seg])
295
{
296
point2d(0) = (point3d-line_path[seg]->StartPI())*x_dir[seg];
297
point2d(1) = (point3d-line_path[seg]->StartPI())*z_dir[seg];
298
double l = Dist(line_path[seg]->StartPI(),
299
line_path[seg]->EndPI());
300
t = min2(max2((point3d - line_path[seg]->StartPI()) * y_dir[seg],0.),
301
l);
302
p0[seg] = line_path[seg]->StartPI() + t*y_dir[seg];
303
t *= 1./l;
304
}
305
else if(spline3_path[seg])
306
{
307
spline3_path[seg]->Project(point3d,p0[seg],t);
308
309
y_dir[seg] = spline3_path[seg]->GetTangent(t); y_dir[seg].Normalize();
310
loc_z_dir[seg] = z_dir[seg];
311
Orthogonalize(y_dir[seg],loc_z_dir[seg]);
312
x_dir[seg] = Cross(y_dir[seg],loc_z_dir[seg]);
313
Vec<3> dir = point3d-p0[seg];
314
point2d(0) = x_dir[seg]*dir;
315
point2d(1) = loc_z_dir[seg]*dir;
316
}
317
return t;
318
}
319
320
double ExtrusionFace :: CalcFunctionValue (const Point<3> & point) const
321
{
322
Point<2> p;
323
324
double dummyd;
325
int dummyi;
326
327
CalcProj(point,p,dummyi,dummyd);
328
//(*testout) << "spline " << dummyi << " t " << dummyd << endl;
329
330
return profile_spline_coeff(0)*p(0)*p(0) + profile_spline_coeff(1)*p(1)*p(1)
331
+ profile_spline_coeff(2)*p(0)*p(1) + profile_spline_coeff(3)*p(0)
332
+ profile_spline_coeff(4)*p(1) + profile_spline_coeff(5);
333
}
334
335
336
void ExtrusionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const
337
{
338
int i;
339
Point<2> p2d;
340
341
double t_path;
342
int seg;
343
CalcProj(point,p2d,seg,t_path);
344
345
Point<3> phi;
346
Vec<3> phip,phipp,phi_minus_point;
347
348
path->GetSpline(seg).GetDerivatives(t_path,phi,phip,phipp);
349
350
phi_minus_point = phi-point;
351
352
Vec<3> grad_t = phip;
353
354
double facA = phipp*phi_minus_point + phip*phip;
355
356
grad_t *= 1./facA;
357
358
ARRAY < Vec<3> > dphi_dX(3);
359
360
for(i=0; i<3; i++)
361
dphi_dX[i] = grad_t(i)*phip;
362
363
ARRAY < Vec<3> > dy_dir_dX(3);
364
365
double lphip = phip.Length();
366
367
dy_dir_dX[0] = dy_dir_dX[1] = dy_dir_dX[2] =
368
(1./lphip) * phipp - ((phip*phipp)/pow(lphip,3)) * phip;
369
370
for(i=0; i<3; i++)
371
dy_dir_dX[i] *= grad_t(i);
372
373
ARRAY < Vec<3> > dx_dir_dX(3);
374
375
for(i=0; i<3; i++)
376
dx_dir_dX[i] = Cross(dy_dir_dX[i],z_dir[seg]);
377
378
Vec<3> grad_xbar;
379
380
for(i=0; i<3; i++)
381
grad_xbar(i) = -1.*(phi_minus_point * dx_dir_dX[i]) + x_dir[seg](i) - x_dir[seg] * dphi_dX[i];
382
383
double zy = z_dir[seg]*y_dir[seg];
384
385
Vec<3> grad_ybar;
386
Vec<3> aux = z_dir[seg] - zy*y_dir[seg];
387
388
for(i=0; i<3; i++)
389
grad_ybar(i) = ( (z_dir[seg]*dy_dir_dX[i])*y_dir[seg] + zy*dy_dir_dX[i] ) * phi_minus_point +
390
aux[i] -
391
aux * dphi_dX[i];
392
393
394
const double dFdxbar = 2.*profile_spline_coeff(0)*p2d(0) +
395
profile_spline_coeff(2)*p2d(1) + profile_spline_coeff(3);
396
397
const double dFdybar = 2.*profile_spline_coeff(1)*p2d(1) +
398
profile_spline_coeff(2)*p2d(0) + profile_spline_coeff(4);
399
400
401
grad = dFdxbar * grad_xbar + dFdybar * grad_ybar;
402
}
403
404
void ExtrusionFace :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const
405
{
406
const double eps = 1e-7*Dist(path->GetSpline(0).StartPI(),path->GetSpline(0).EndPI());
407
408
/*
409
Point<3> auxpoint1(point),auxpoint2(point);
410
Vec<3> auxvec,auxgrad1,auxgrad2;
411
412
for(int i=0; i<3; i++)
413
{
414
auxpoint1(i) -= eps;
415
auxpoint2(i) += eps;
416
CalcGradient(auxpoint1,auxgrad1);
417
CalcGradient(auxpoint2,auxgrad2);
418
auxvec = (1./(2.*eps)) * (auxgrad2-auxgrad1);
419
for(int j=0; j<3; j++)
420
hesse(i,j) = auxvec(j);
421
auxpoint1(i) = point(i);
422
auxpoint2(i) = point(i);
423
}
424
*/
425
426
427
Vec<3> grad;
428
CalcGradient(point,grad);
429
430
Point<3> auxpoint(point);
431
Vec<3> auxvec,auxgrad;
432
433
for(int i=0; i<3; i++)
434
{
435
auxpoint(i) -= eps;
436
CalcGradient(auxpoint,auxgrad);
437
auxvec = (1./eps) * (grad-auxgrad);
438
for(int j=0; j<3; j++)
439
hesse(i,j) = auxvec(j);
440
auxpoint(i) = point(i);
441
}
442
443
444
445
for(int i=0; i<3; i++)
446
for(int j=i+1; j<3; j++)
447
hesse(i,j) = hesse(j,i) = 0.5*(hesse(i,j)+hesse(j,i));
448
}
449
450
451
452
double ExtrusionFace :: HesseNorm () const
453
{
454
return fabs(profile_spline_coeff(0) + profile_spline_coeff(1)) +
455
sqrt(pow(profile_spline_coeff(0)+profile_spline_coeff(1),2)+4.*pow(profile_spline_coeff(2),2));
456
}
457
458
double ExtrusionFace :: MaxCurvature () const
459
{
460
double retval,actmax;
461
462
retval = profile->MaxCurvature();
463
for(int i=0; i<path->GetNSplines(); i++)
464
{
465
actmax = path->GetSpline(i).MaxCurvature();
466
if(actmax > retval)
467
retval = actmax;
468
}
469
470
return 2.*retval;
471
}
472
473
474
void ExtrusionFace :: Project (Point<3> & p) const
475
{
476
double dummyt;
477
int seg;
478
Point<2> p2d;
479
480
CalcProj(p,p2d,seg,dummyt);
481
482
profile->Project(p2d,p2d,profile_par);
483
484
p = p0[seg] + p2d(0)*x_dir[seg] + p2d(1)*loc_z_dir[seg];
485
486
Vec<2> tangent2d = profile->GetTangent(profile_par);
487
profile_tangent = tangent2d(0)*x_dir[seg] + tangent2d(1)*y_dir[seg];
488
}
489
490
491
492
Point<3> ExtrusionFace :: GetSurfacePoint () const
493
{
494
p0[0] = path->GetSpline(0).GetPoint(0.5);
495
if(!line_path[0])
496
{
497
y_dir[0] = path->GetSpline(0).GetTangent(0.5);
498
y_dir[0].Normalize();
499
loc_z_dir[0] = z_dir[0];
500
Orthogonalize(y_dir[0],loc_z_dir[0]);
501
x_dir[0] = Cross(y_dir[0],loc_z_dir[0]);
502
}
503
504
Point<2> locpoint = profile->GetPoint(0.5);
505
506
return p0[0] + locpoint(0)*x_dir[0] + locpoint(1)*loc_z_dir[0];
507
}
508
509
bool ExtrusionFace :: BoxIntersectsFace(const Box<3> & box) const
510
{
511
Point<3> center = box.Center();
512
513
Project(center);
514
515
//(*testout) << "box.Center() " << box.Center() << " projected " << center << " diam " << box.Diam()
516
// << " dist " << Dist(box.Center(),center) << endl;
517
518
return (Dist(box.Center(),center) < 0.5*box.Diam());
519
}
520
521
522
void ExtrusionFace :: LineIntersections ( const Point<3> & p,
523
const Vec<3> & v,
524
const double eps,
525
int & before,
526
int & after,
527
bool & intersecting ) const
528
{
529
Point<2> p2d;
530
Vec<2> v2d;
531
532
intersecting = false;
533
534
double segt;
535
int seg;
536
537
CalcProj(p,p2d,seg,segt);
538
539
if(seg == 0 && segt < 1e-20)
540
{
541
Vec<3> v1,v2;
542
v1 = path->GetSpline(0).GetTangent(0);
543
v2 = p-p0[seg];
544
if(v1*v2 < -eps)
545
return;
546
}
547
if(seg == path->GetNSplines()-1 && 1.-segt < 1e-20)
548
{
549
Vec<3> v1,v2;
550
v1 = path->GetSpline(seg).GetTangent(1);
551
v2 = p-p0[seg];
552
if(v1*v2 > eps)
553
return;
554
}
555
556
v2d(0) = v * x_dir[seg];
557
v2d(1) = v * loc_z_dir[seg];
558
559
Vec<2> n(v2d(1),-v2d(0));
560
ARRAY < Point<2> > ips;
561
562
563
profile->LineIntersections(v2d(1),
564
-v2d(0),
565
-v2d(1)*p2d(0) + v2d(0)*p2d(1),
566
ips,eps);
567
int comp;
568
569
if(fabs(v2d(0)) >= fabs(v2d(1)))
570
comp = 0;
571
else
572
comp = 1;
573
574
//(*testout) << "p2d " << p2d;
575
576
for(int i=0; i<ips.Size(); i++)
577
{
578
//(*testout) << " ip " << ips[i];
579
580
double t = (ips[i](comp)-p2d(comp))/v2d(comp);
581
582
if(t < -eps)
583
before++;
584
else if(t > eps)
585
after++;
586
else
587
intersecting = true;
588
}
589
//(*testout) << endl;
590
}
591
592
void ExtrusionFace :: Print (ostream & str) const{}
593
594
INSOLID_TYPE ExtrusionFace :: VecInFace ( const Point<3> & p,
595
const Vec<3> & v,
596
const double eps ) const
597
{
598
599
Vec<3> normal1;
600
CalcGradient(p,normal1); normal1.Normalize();
601
602
double d1 = normal1*v;
603
604
605
if(d1 > eps)
606
return IS_OUTSIDE;
607
if(d1 < -eps)
608
return IS_INSIDE;
609
610
611
return DOES_INTERSECT;
612
613
/*
614
Point<2> p2d;
615
616
double t_path;
617
int seg;
618
CalcProj(p,p2d,seg,t_path);
619
620
double t;
621
profile.Project(p2d,p2d,t);
622
623
624
625
Vec<2> profile_tangent = profile.GetTangent(t);
626
627
double d;
628
629
Vec<3> normal1;
630
CalcGradient(p,normal1); normal1.Normalize();
631
632
double d1 = normal1*v;
633
634
Vec<2> v2d;
635
636
v2d(0) = v*x_dir[seg];
637
v2d(1) = v*loc_z_dir[seg];
638
639
640
Vec<2> normal(-profile_tangent(1),profile_tangent(0));
641
642
//d = normal*v2d;
643
644
645
d = d1;
646
647
648
if(d > eps)
649
return IS_OUTSIDE;
650
if(d < -eps)
651
return IS_INSIDE;
652
653
654
return DOES_INTERSECT;
655
*/
656
}
657
658
659
void ExtrusionFace :: GetTriangleApproximation (TriangleApproximation & tas,
660
const Box<3> & boundingbox,
661
double facets) const
662
{
663
int n = int(facets) + 1;
664
665
int i,j,k;
666
667
668
int nump = 0;
669
for(k=0; k<path->GetNSplines(); k++)
670
{
671
for(i=0; i<=n; i++)
672
{
673
Point<3> origin = path->GetSpline(k).GetPoint(double(i)/double(n));
674
if(!line_path[k])
675
{
676
y_dir[k] = path->GetSpline(k).GetTangent(double(i)/double(n));
677
y_dir[k].Normalize();
678
}
679
loc_z_dir[k] = z_dir[k];
680
Orthogonalize(y_dir[k],loc_z_dir[k]);
681
if(!line_path[k])
682
x_dir[k] = Cross(y_dir[k],loc_z_dir[k]);
683
684
for(j=0; j<=n; j++)
685
{
686
Point<2> locp = profile->GetPoint(double(j)/double(n));
687
tas.AddPoint(origin + locp(0)*x_dir[k] + locp(1)*loc_z_dir[k]);
688
nump++;
689
}
690
}
691
}
692
693
for(k=0; k<path->GetNSplines(); k++)
694
for(i=0; i<n; i++)
695
for(j=0; j<n; j++)
696
{
697
int pi = k*(n+1)*(n+1) + (n+1)*i +j;
698
699
tas.AddTriangle( TATriangle (0, pi,pi+1,pi+n+1));
700
tas.AddTriangle( TATriangle (0, pi+1,pi+n+1,pi+n+2));
701
}
702
}
703
704
705
void ExtrusionFace :: GetRawData(ARRAY<double> & data) const
706
{
707
data.DeleteAll();
708
profile->GetRawData(data);
709
path->GetRawData(data);
710
for(int i=0; i<3; i++)
711
data.Append(glob_z_direction[i]);
712
//(*testout) << "written raw data " << data << endl;
713
}
714
715
716
717
Extrusion :: Extrusion(const SplineGeometry<3> & path_in,
718
const SplineGeometry<2> & profile_in,
719
const Vec<3> & z_dir) :
720
path(path_in), profile(profile_in), z_direction(z_dir)
721
{
722
surfaceactive.SetSize(0);
723
surfaceids.SetSize(0);
724
725
for(int j=0; j<profile.GetNSplines(); j++)
726
{
727
ExtrusionFace * face = new ExtrusionFace(&(profile.GetSpline(j)),
728
&path,
729
z_direction);
730
faces.Append(face);
731
surfaceactive.Append(true);
732
surfaceids.Append(0);
733
}
734
735
}
736
737
738
Extrusion :: ~Extrusion()
739
{
740
for(int i=0; i<faces.Size(); i++)
741
delete faces[i];
742
}
743
744
745
746
747
748
INSOLID_TYPE Extrusion :: BoxInSolid (const BoxSphere<3> & box) const
749
{
750
for(int i=0; i<faces.Size(); i++)
751
{
752
if(faces[i]->BoxIntersectsFace(box))
753
return DOES_INTERSECT;
754
}
755
756
return PointInSolid(box.Center(),0);
757
}
758
759
760
INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p,
761
const double eps,
762
ARRAY<int> * const facenums) const
763
{
764
Vec<3> random_vec(-0.4561,0.7382,0.4970247);
765
766
int before(0), after(0);
767
bool intersects(false);
768
bool does_intersect(false);
769
770
for(int i=0; i<faces.Size(); i++)
771
{
772
faces[i]->LineIntersections(p,random_vec,eps,before,after,intersects);
773
774
//(*testout) << "intersects " << intersects << " before " << before << " after " << after << endl;
775
if(intersects)
776
{
777
if(facenums)
778
{
779
facenums->Append(i);
780
does_intersect = true;
781
}
782
else
783
return DOES_INTERSECT;
784
}
785
}
786
787
if(does_intersect)
788
return DOES_INTERSECT;
789
790
791
if(before % 2 == 0)
792
return IS_OUTSIDE;
793
794
return IS_INSIDE;
795
}
796
797
798
INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p,
799
double eps) const
800
{
801
return PointInSolid(p,eps,NULL);
802
}
803
804
INSOLID_TYPE Extrusion :: VecInSolid (const Point<3> & p,
805
const Vec<3> & v,
806
double eps) const
807
{
808
ARRAY<int> facenums;
809
INSOLID_TYPE pInSolid = PointInSolid(p,eps,&facenums);
810
811
if(pInSolid != DOES_INTERSECT)
812
return pInSolid;
813
814
815
double d(0);
816
817
if(facenums.Size() == 1)
818
{
819
Vec<3> normal;
820
faces[facenums[0]]->CalcGradient(p,normal);
821
normal.Normalize();
822
d = normal*v;
823
824
latestfacenum = facenums[0];
825
}
826
else if (facenums.Size() == 2)
827
{
828
Vec<3> checkvec;
829
830
Point<3> dummy(p);
831
faces[facenums[0]]->Project(dummy);
832
if(fabs(faces[facenums[0]]->GetProfilePar()) < 0.1)
833
{
834
int aux = facenums[0];
835
facenums[0] = facenums[1]; facenums[1] = aux;
836
}
837
838
checkvec = faces[facenums[0]]->GetYDir();
839
840
Vec<3> n0, n1;
841
faces[facenums[0]]->CalcGradient(p,n0);
842
faces[facenums[1]]->CalcGradient(p,n1);
843
n0.Normalize();
844
n1.Normalize();
845
846
847
Vec<3> t = Cross(n0,n1);
848
if(checkvec*t < 0) t*= (-1.);
849
850
Vec<3> t0 = Cross(n0,t);
851
Vec<3> t1 = Cross(t,n1);
852
853
t0.Normalize();
854
t1.Normalize();
855
856
857
const double t0v = t0*v;
858
const double t1v = t1*v;
859
860
if(t0v > t1v)
861
{
862
latestfacenum = facenums[0];
863
d = n0*v;
864
}
865
else
866
{
867
latestfacenum = facenums[1];
868
d = n1*v;
869
}
870
871
if(fabs(t0v) < eps && fabs(t1v) < eps)
872
latestfacenum = -1;
873
}
874
875
else
876
{
877
cerr << "WHY ARE THERE " << facenums.Size() << " FACES?" << endl;
878
}
879
880
if(d > eps)
881
return IS_OUTSIDE;
882
if(d < -eps)
883
return IS_INSIDE;
884
885
return DOES_INTERSECT;
886
}
887
888
889
890
// checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid
891
INSOLID_TYPE Extrusion :: VecInSolid2 (const Point<3> & p,
892
const Vec<3> & v1,
893
const Vec<3> & v2,
894
double eps) const
895
{
896
INSOLID_TYPE retval;
897
retval = VecInSolid(p,v1,eps);
898
899
// *testout << "extr, vecinsolid=" << int(retval) << endl;
900
901
if(retval != DOES_INTERSECT)
902
return retval;
903
904
if(latestfacenum >= 0)
905
return faces[latestfacenum]->VecInFace(p,v2,0);
906
else
907
return VecInSolid(p,v2,eps);
908
}
909
910
911
int Extrusion :: GetNSurfaces() const
912
{
913
return faces.Size();
914
}
915
916
Surface & Extrusion :: GetSurface (int i)
917
{
918
return *faces[i];
919
}
920
921
const Surface & Extrusion :: GetSurface (int i) const
922
{
923
return *faces[i];
924
}
925
926
927
void Extrusion :: Reduce (const BoxSphere<3> & box)
928
{
929
for(int i=0; i<faces.Size(); i++)
930
surfaceactive[i] = faces[i]->BoxIntersectsFace(box);
931
}
932
933
void Extrusion :: UnReduce ()
934
{
935
for(int i=0; i<faces.Size(); i++)
936
surfaceactive[i] = true;
937
}
938
939
940
}
941
942