mFES - molecular Finite Element Solver
0.4
|
00001 #ifndef VOXEL_H 00002 #define VOXEL_H 00003 00004 // c++ -O2 -fopenmp voxel.cpp help.cpp adtree.cpp optmem.cpp -I../../libsrc/include 00005 // c++ -O2 -fopenmp voxel.cpp help.cpp adtree.cpp optmem.cpp -I/home/parallels/ngsolve/sources/netgen-5.1/libsrc/include -o voxel 00006 // tar -czf voxel.tar.gz *.cpp *.pqr 00007 00008 00009 #include <gprim.hpp> 00010 #include <lib/Voxel/adtree.h> 00011 #include <lib/Voxel/help.h> 00012 #include <lib/Voxel/optmem.h> 00013 00014 using namespace netgen; 00015 00016 00017 class Voxel { 00018 00019 public: 00020 00021 Voxel(){ 00022 rball = 1.4; 00023 }; 00024 ~Voxel(){}; 00025 00026 int calcSurface(mMesh &mSurface, vector<Atom> &atomList, INI& ini, string fileName, int gridSize = 64, bool exclusion = false) 00027 { 00028 // int gridSize = atoi(ini.get<string>("model.grid_resolution").c_str()); 00029 rball = atof(ini.get<string>("experiment.probe_radius").c_str()); 00030 00031 float extendR = 0; 00032 if (exclusion){ 00033 float ionc = atof(ini.get<string>("experiment.ionc").c_str()); 00034 if (ionc > 0){ 00035 extendR = atof(ini.get<string>("experiment.ionr").c_str()); 00036 } 00037 } 00038 00039 int nx = gridSize; // number of intervals 00040 int ny = gridSize; 00041 int nz = gridSize; 00042 00043 Array<Point<3> > gridpoints(long(nx+1)*(ny+1)*(nz+1)); 00044 Array<float> values(long(nx+1)*(ny+1)*(nz+1)); 00045 Array<Vec<3> > dvalues(long(nx+1)*(ny+1)*(nz+1)); 00046 00047 clock_t t1 = clock(); 00048 rmax = 0; 00049 00050 for (unsigned int i = 0; i < atomList.size(); i++) 00051 { 00052 Point3<float> coord = atomList.at(i).getCoord(); 00053 double r = atomList.at(i).getRadius()+extendR; 00054 pnts.Append (Point<3>(coord.X(),coord.Y(),coord.Z())); 00055 rad.Append (r); 00056 if (r > rmax) rmax = r; 00057 } 00058 rmax += extendR; 00059 00060 int increase = ceil(rmax)+1; //ceil(rmax); // 5 also works? 00061 cout << "rmax = " << rmax << endl; 00062 00063 clock_t t2 = clock(); 00064 00065 netgen::Box<3> box; 00066 box.Set (pnts[0]); 00067 for (int i = 1; i < pnts.Size(); i++) box.Add (pnts[i]); 00068 box.Increase (increase); 00069 Point<3> pmin = box.PMin(); 00070 Point<3> pmax = box.PMax(); 00071 00072 00073 searchtree = new Point3dTree (pmin, pmax); 00074 for (int i = 0; i < pnts.Size(); i++) 00075 searchtree -> Insert (pnts[i], i); 00076 00077 00078 for (int ix = 0; ix <= nx; ix++) 00079 for (int iy = 0; iy <= ny; iy++) 00080 for (int iz = 0; iz <= nz; iz++) 00081 { 00082 int ind = ix + (nx+1) * (iy + (ny+1)*iz); 00083 gridpoints[ind] = Point<3> (pmin(0) + (pmax(0)-pmin(0))*ix/(nx), 00084 pmin(1) + (pmax(1)-pmin(1))*iy/(ny), 00085 pmin(2) + (pmax(2)-pmin(2))*iz/(nz)); 00086 } 00087 00088 double diag = sqrt ( sqr ((pmax(0)-pmin(0)) / nx) + 00089 sqr ((pmax(1)-pmin(1)) / ny) + 00090 sqr ((pmax(2)-pmin(2)) / nz)); 00091 00092 SetValues (pmin, pmax, diag, gridpoints, values, dvalues); 00093 00094 // smoothing ... 00095 // not always working without intersection e.g. (2lzt, no opt, ARG-61) 00096 int smoothingsteps = 0; 00097 00098 for (int j = 0; j < smoothingsteps; j++) 00099 00100 for (int ix = 1; ix < nx; ix++) 00101 00102 for (int iy = 1; iy < ny; iy++) 00103 00104 for (int iz = 1; iz < nz; iz++) 00105 00106 { 00107 00108 int ind = ix + (nx+1) * (iy + (ny+1)*iz); 00109 00110 int i2[] = { ind+1, ind-1, ind+nx+1, ind-(nx+1), ind+(nx+1)*(ny+1), ind-(nx+1)*(ny+1) }; 00111 00112 double sum = 0.0; 00113 00114 int cnt = 0; 00115 00116 for (int j = 0; j < 6; j++) 00117 00118 if (values[i2[j]] < 1e9) 00119 00120 { 00121 00122 sum += values[i2[j]]; 00123 00124 cnt++; 00125 00126 } 00127 00128 if (cnt) 00129 values[ind] = sum/cnt; 00130 } 00131 00132 00133 clock_t t3 = clock(); 00134 00135 double h = Dist(pmin, pmax)/nx; 00136 for (int i = 0; i < values.Size(); i++) 00137 if (fabs (values[i]) < 0.02 * dvalues[i].Length() * h) 00138 { 00139 gridpoints[i] -= (values[i]/dvalues[i].Length2()) * dvalues[i]; 00140 values[i] = 0; 00141 } 00142 00143 stlout.open (fileName.c_str()); 00144 stlout << "solid" << endl; 00145 stlout.precision(12); 00146 MakeSTL (pmin, pmax, nx, ny, nz, gridpoints, values, dvalues); 00147 stlout << "endsolid" << endl; 00148 00149 clock_t t4 = clock(); 00150 00151 cout << "load: " << double(t2-t1) / CLOCKS_PER_SEC << " secs" << endl; 00152 cout << "find f: " << double(t3-t2) / CLOCKS_PER_SEC << " secs" << endl; 00153 cout << "write stl (" << fileName <<"): " << double(t4-t3) / CLOCKS_PER_SEC << " secs" << endl; 00154 00155 stlout.close(); 00156 return 0; 00157 } 00158 00159 private: 00160 00161 double rball; 00162 double rmax; 00163 ofstream stlout; 00164 00165 Array<Point<3> > pnts; 00166 Array<double> rad; 00167 Point3dTree * searchtree; 00168 00169 void SetValues (Point<3> pmin, Point<3> pmax, double diag, 00170 // int nx, int ny, int nz, 00171 Array<Point<3> > & gridpoints, 00172 Array<float> & values, 00173 Array<Vec<3> > & dvalues) 00174 { 00175 int cnt = 0; 00176 00177 int cnt3a = 0, cnt3b = 0, cnt3c = 0; 00178 00179 cout << "Setting up level-set function" << endl; 00180 00181 #pragma omp parallel 00182 { 00183 Array<int> indices1, indices; 00184 00185 00186 #pragma omp for 00187 for (int i = 0; i < gridpoints.Size(); i++) 00188 { 00189 00190 #pragma omp atomic 00191 cnt++; 00192 00193 00194 if (cnt % 1000 == 0) 00195 { 00196 #pragma omp critical(print) 00197 { 00198 cout << "\r" << int (100 * double(cnt)/gridpoints.Size()) << " %" << flush; 00199 } 00200 } 00201 /* 00202 int ind = ix + (nx+1) * (iy + (ny+1)*iz); 00203 Point<3> p(pmin(0) + (pmax(0)-pmin(0))*ix/nx, 00204 pmin(1) + (pmax(1)-pmin(1))*iy/ny, 00205 pmin(2) + (pmax(2)-pmin(2))*iz/nz); 00206 */ 00207 int ind = i; 00208 int extend = 6; 00209 // if (rmax > 5) 00210 // extend = 2*rmax; 00211 00212 Point<3> p = gridpoints[ind]; 00213 00214 searchtree -> GetIntersecting (p - Vec<3>(extend,extend,extend), p+Vec<3>(extend,extend,extend), indices1); 00215 double minf = 1e10; 00216 Vec<3> df; 00217 00218 00219 indices.SetSize(0); 00220 for (int j = 0; j < indices1.Size(); j++) 00221 if (Dist2 (pnts[indices1[j]], p) < sqr(rad[indices1[j]]+2*rball)) 00222 indices.Append (indices1[j]); 00223 00224 for (int jj = 0; jj < indices.Size(); jj++) 00225 { 00226 int j = indices[jj]; 00227 // double fj = rad[j] * (Dist2 (p, pnts[j]) / sqr(rad[j]) - 1); 00228 double fj = Dist (p, pnts[j]) - rad[j]; 00229 if (fj < minf) 00230 { 00231 minf = fj; 00232 df = 1.0/Dist(p,pnts[j]) * (p-pnts[j]); 00233 } 00234 } 00235 00236 00237 00238 if (minf < -diag) 00239 00240 { 00241 00242 values[ind] = minf; 00243 00244 dvalues[ind] = df; 00245 00246 continue; 00247 00248 } 00249 00250 00251 00252 00253 00254 for (int jj = 0; jj < indices.Size(); jj++) 00255 for (int kk = 0; kk < jj; kk++) 00256 { 00257 int j = indices[jj]; 00258 int k = indices[kk]; 00259 00260 double r1 = rad[j]; 00261 double r2 = rad[k]; 00262 00263 Point<3> c1 = pnts[j]; 00264 Point<3> c2 = pnts[k]; 00265 00266 Vec<3> ex = c2-c1; 00267 double dist2 = ex.Length2(); 00268 if (dist2 > sqr(r1+r2+2*rball)) continue; 00269 double dist = sqrt(dist2); 00270 ex /= dist; 00271 00272 double px = ex * (p - c1); 00273 if (px <= -rball || px > dist+rball+r2) continue; 00274 00275 double py = sqrt ( Dist2(p,c1) - px*px ); 00276 00277 double tx = 1.0 / (2*dist) * (sqr(dist)+(r1-r2)*(2*rball+r1+r2)); 00278 double ty = sqrt (sqr(r1+rball) - tx*tx); 00279 00280 // if ( (py / px < ty / tx) && (py / (dist-px) < ty / (dist-tx))) 00281 if ( (py * tx < ty * px) && ( (dist-tx)*py < ty * (dist-px) ) ) 00282 { 00283 // double fj = rball * (1-(sqr(px-tx)+sqr(py-ty)) / sqr(rball)); 00284 double fj = rball - sqrt(sqr(px-tx)+sqr(py-ty)); 00285 00286 double x0 = tx - ty/(ty-py) * (tx-px); 00287 Point<3> p0 = c1+x0*ex; 00288 Vec<3> dir = p - p0; 00289 dir.Normalize(); 00290 if (fj < minf) 00291 { 00292 minf = fj; 00293 df = dir; 00294 } 00295 } 00296 } 00297 00298 if ((minf < -diag) || (minf > diag + rball)) 00299 00300 { 00301 00302 values[ind] = minf; 00303 00304 dvalues[ind] = df; 00305 00306 continue; 00307 00308 } 00309 00310 for (int jj = 0; jj < indices.Size(); jj++) 00311 for (int kk = 0; kk < jj; kk++) 00312 for (int ll = 0; ll < kk; ll++) 00313 { 00314 #pragma omp atomic 00315 cnt3a++; 00316 00317 int j = indices[jj]; 00318 int k = indices[kk]; 00319 int l = indices[ll]; 00320 00321 double r1 = rad[j]; 00322 double r2 = rad[k]; 00323 double r3 = rad[l]; 00324 00325 Point<3> c1 = pnts[j]; 00326 Point<3> c2 = pnts[k]; 00327 Point<3> c3 = pnts[l]; 00328 00329 if (Dist2(c1, p) > sqr(r1+2*rball)) continue; 00330 if (Dist2(c2, p) > sqr(r2+2*rball)) continue; 00331 if (Dist2(c3, p) > sqr(r3+2*rball)) continue; 00332 00333 00334 Vec<3> t1 = c2-c1; 00335 Vec<3> t2 = c3-c1; 00336 Vec<3> n = Cross(t1, t2); 00337 n.Normalize(); 00338 00339 Mat<2> mat; 00340 Vec<2> rhs, sol; 00341 mat(0,0) = t1*t1; 00342 mat(0,1) = mat(1,0) = t1*t2; 00343 mat(1,1) = t2*t2; 00344 00345 rhs(0) = 0.5 * (sqr(r1+rball) - sqr(r2+rball) + Dist2(c1,c2)); 00346 rhs(1) = 0.5 * (sqr(r1+rball) - sqr(r3+rball) + Dist2(c1,c3)); 00347 00348 mat.Solve (rhs, sol); 00349 00350 Point<3> cp = c1 + sol(0) * t1 + sol(1) * t2; 00351 if ( sqr(r1+rball) <= Dist2(c1,cp) ) continue; 00352 00353 double lamn = sqrt ( sqr(r1+rball) - Dist2(c1,cp) ); 00354 // c = cp +/- lamn n 00355 00356 Vec<2> rhs2, sol2; 00357 rhs2(0) = t1 * (p-c1); 00358 rhs2(1) = t2 * (p-c1); 00359 mat.Solve (rhs2, sol2); 00360 double lamn2 = n * (p-c1); 00361 00362 #pragma omp atomic 00363 cnt3b++; 00364 00365 00366 if ( sol2(0) > sol(0) * fabs(lamn2)/lamn && 00367 sol2(1) > sol(1) * fabs(lamn2)/lamn && 00368 (1-sol2(0)-sol2(1)) > (1-sol(0)-sol(1)) * fabs(lamn2)/lamn) 00369 00370 { 00371 #pragma omp atomic 00372 cnt3c++; 00373 00374 00375 Point<3> sp1 = cp + lamn * n; 00376 Point<3> sp2 = cp - lamn * n; 00377 00378 00379 /* 00380 double fj = max (rball - Dist(sp1, p), rball - Dist(sp2, p)); 00381 if (fj < minf) 00382 { 00383 minf = fj; 00384 00385 Vec<3> dir; 00386 if (lamn2 > 0) 00387 dir = sp1-p; 00388 else 00389 dir = sp2-p; 00390 dir.Normalize(); 00391 df = dir; 00392 } 00393 */ 00394 if (lamn2 > 0) 00395 { 00396 Vec<3> dir = sp1-p; 00397 double len = dir.Length(); 00398 double fj = rball - len; 00399 if (fj < minf) 00400 { 00401 dir.Normalize(); 00402 minf = fj; 00403 df = dir; 00404 } 00405 } 00406 else 00407 { 00408 Vec<3> dir = sp2-p; 00409 double len = dir.Length(); 00410 double fj = rball - len; 00411 if (fj < minf) 00412 { 00413 dir.Normalize(); 00414 minf = fj; 00415 df = dir; 00416 } 00417 } 00418 00419 } 00420 } 00421 00422 if ((minf < -diag) || (minf > diag + rball)) 00423 00424 { 00425 00426 values[ind] = minf; 00427 00428 dvalues[ind] = df; 00429 00430 continue; 00431 00432 } 00433 00434 00435 00436 // if (false) 00437 00438 for (int jj = 0; jj < indices.Size(); jj++) 00439 00440 for (int kk = 0; kk < jj; kk++) 00441 00442 for (int ll = 0; ll < kk; ll++) 00443 00444 for (int mm = 0; mm < ll; mm++) 00445 00446 { 00447 00448 int j = indices[jj]; 00449 00450 int k = indices[kk]; 00451 00452 int l = indices[ll]; 00453 00454 int m = indices[mm]; 00455 00456 00457 00458 double r1 = rad[j]; 00459 00460 double r2 = rad[k]; 00461 00462 double r3 = rad[l]; 00463 00464 double r4 = rad[m]; 00465 00466 00467 00468 Point<3> c1 = pnts[j]; 00469 00470 Point<3> c2 = pnts[k]; 00471 00472 Point<3> c3 = pnts[l]; 00473 00474 Point<3> c4 = pnts[m]; 00475 00476 00477 00478 if (Dist2(c1, p) > sqr(r1+2*rball)) continue; 00479 00480 if (Dist2(c2, p) > sqr(r2+2*rball)) continue; 00481 00482 if (Dist2(c3, p) > sqr(r3+2*rball)) continue; 00483 00484 if (Dist2(c4, p) > sqr(r4+2*rball)) continue; 00485 00486 00487 00488 00489 00490 Vec<3> v1 = c2-c1; 00491 00492 Vec<3> v2 = c3-c1; 00493 00494 Vec<3> v3 = c4-c1; 00495 00496 00497 00498 Mat<3> mat; 00499 00500 Vec<3> rhs, sol; 00501 00502 for (int j = 0; j < 3; j++) 00503 00504 { 00505 00506 mat(j,0) = v1(j); 00507 00508 mat(j,1) = v2(j); 00509 00510 mat(j,2) = v3(j); 00511 00512 rhs(j) = p(j)-c1(j); 00513 00514 } 00515 00516 mat.Solve (rhs, sol); 00517 00518 00519 00520 if (sol(0) < 0 || sol(1) < 0 || sol(2) < 0 || sol(0)+sol(1)+sol(2) > 1) 00521 00522 continue; 00523 00524 00525 00526 if (fabs (Det(mat)) < 1e-10) 00527 00528 { 00529 00530 /* 00531 00532 cout << "indices = " << indices << endl; 00533 00534 cout << "points = " << pnts << endl; 00535 00536 cout << "ci = " << c1 << ", " << c2 << ", " << c3 << ", " << c4 << endl; 00537 00538 cout << "vi = " << v1 << ", " << v2 << ", " << v3 << endl; 00539 00540 */ 00541 00542 continue; 00543 00544 } 00545 00546 00547 00548 /* 00549 00550 cout << "ci = " << c1 << ", " << c2 << ", " << c3 << ", " << c4 << endl; 00551 00552 cout << "p = " << p << ", sol = " << sol << endl; 00553 00554 cout << "det = " << Det(mat) << endl; 00555 00556 */ 00557 00558 00559 00560 Point<3> pts[4] = { c1, c2, c3, c4 }; 00561 00562 double rs[4] = { r1, r2, r3, r4 }; 00563 00564 00565 00566 double vmax = -1e99; 00567 00568 Vec<3> vdir; 00569 00570 00571 00572 for (int i = 0; i < 4; i++) 00573 00574 { 00575 00576 Point<3> fc1 = pts[i]; 00577 00578 Point<3> fc2 = pts[(i+1)%4]; 00579 00580 Point<3> fc3 = pts[(i+2)%4]; 00581 00582 00583 00584 double fr1 = rs[i]; 00585 00586 double fr2 = rs[(i+1)%4]; 00587 00588 double fr3 = rs[(i+2)%4]; 00589 00590 00591 00592 00593 00594 Vec<3> t1 = fc2-fc1; 00595 00596 Vec<3> t2 = fc3-fc1; 00597 00598 Vec<3> n = Cross(t1, t2); 00599 00600 n.Normalize(); 00601 00602 00603 00604 if (n * (pts[(i+3)%4]-fc1) > 0) n *= -1; 00605 00606 00607 00608 Mat<2> mat; 00609 00610 Vec<2> rhs, sol; 00611 00612 mat(0,0) = t1*t1; 00613 00614 mat(0,1) = mat(1,0) = t1*t2; 00615 00616 mat(1,1) = t2*t2; 00617 00618 00619 00620 rhs(0) = 0.5 * (sqr(fr1+rball) - sqr(fr2+rball) + Dist2(fc1,fc2)); 00621 00622 rhs(1) = 0.5 * (sqr(fr1+rball) - sqr(fr3+rball) + Dist2(fc1,fc3)); 00623 00624 00625 00626 mat.Solve (rhs, sol); 00627 00628 00629 00630 Point<3> cp = fc1 + sol(0) * t1 + sol(1) * t2; 00631 00632 if ( sqr(fr1+rball) <= Dist2(fc1,cp) ) 00633 00634 { 00635 00636 vmax = 1e99; 00637 00638 continue; 00639 00640 } 00641 00642 00643 00644 double lamn = sqrt ( sqr(fr1+rball) - Dist2(fc1,cp) ); 00645 00646 // c = cp +/- lamn n 00647 00648 00649 00650 Point<3> sp1 = cp + lamn * n; 00651 00652 00653 00654 // cout << "dist i = " << Dist (sp1, fc1) << ", " << Dist(sp1, fc2) << ", " << Dist(sp1, fc3) << endl; 00655 00656 // cout << "ri+rball = " << fr1+rball << ", " << r2+rball << ", " << r3+rball << endl << endl; 00657 00658 00659 00660 Vec<3> dir = sp1-p; 00661 00662 double len = dir.Length(); 00663 00664 double fj = rball - len; 00665 00666 00667 00668 if (fj > vmax) 00669 00670 { 00671 00672 vmax = fj; 00673 00674 dir.Normalize(); 00675 00676 vdir = dir; 00677 00678 } 00679 00680 } 00681 00682 00683 00684 00685 00686 if (vmax < minf) 00687 00688 { 00689 00690 minf = vmax; 00691 00692 df = vdir; 00693 00694 } 00695 00696 } 00697 00698 00699 00700 00701 00702 00703 00704 00705 00706 values[ind] = minf; 00707 dvalues[ind] = df; 00708 } 00709 } 00710 00711 cout << "\r" << "100 %" << endl; 00712 // cout << "cnt trip-balls: " << cnt3a << " " << cnt3b << " " << cnt3c << endl; 00713 } 00714 00715 00716 00717 void WriteTrig (Point<3> p1, Point<3> p2, Point<3> p3, Vec<3> n) 00718 { 00719 00720 if (Dist (p1, p2) < 1e-10) return; 00721 if (Dist (p1, p3) < 1e-10) return; 00722 if (Dist (p2, p3) < 1e-10) return; 00723 00724 Vec<3> nt = Cross(p2-p1,p3-p1); 00725 if (nt.Length() < 1e-5 * (p2-p1).Length() * (p3-p1).Length()) 00726 { 00727 // if (nt.Length() < 1e-12 * (p2-p1).Length() * (p3-p1).Length()) return; 00728 cout << "flat trig: " << nt.Length() / ((p2-p1).Length() * (p3-p1).Length()) << endl; 00729 } 00730 00731 if (nt * n < 0) Swap (p2, p3); 00732 00733 stlout << "facet normal " << n(0) << " " << n(1) << " " << n(2) << "\n"; 00734 stlout << " outer loop" << "\n"; 00735 stlout << " vertex " << p1(0) << " " << p1(1) << " " << p1(2) << "\n"; 00736 stlout << " vertex " << p2(0) << " " << p2(1) << " " << p2(2) << "\n"; 00737 stlout << " vertex " << p3(0) << " " << p3(1) << " " << p3(2) << "\n"; 00738 stlout << " endloop" << "\n"; 00739 stlout << "endfacet" << "\n"; 00740 } 00741 00742 double CutEdge (double f1, double f2) 00743 { 00744 if (fabs (f1) < 1e-10) return 0; 00745 return f1/(f1-f2); 00746 } 00747 00748 void MakeTetSTL (Point<3> pnts[], double valtet[4], Vec<3> dvaltet[4]) 00749 { 00750 int npos = 0; 00751 for (int j = 0; j < 4; j++) 00752 if (valtet[j] > 0) npos++; 00753 00754 if (npos == 0 || npos == 4) return; 00755 00756 /* 00757 00758 int nzero = 0; 00759 00760 for (int j = 0; j < 4; j++) 00761 00762 if (fabs (valtet[j]) < 1e-10) nzero++; 00763 00764 if (nzero >= 2) 00765 00766 { 00767 00768 cout << nzero << " vertex-values 0 on tet:" << endl; 00769 00770 for (int j = 0; j < 4; j++) 00771 00772 cout << pnts[j] << ": " << valtet[j] << endl; 00773 00774 } 00775 00776 */ 00777 00778 const int edges[6][2] = 00779 { { 0, 1 }, { 0, 2 }, { 0, 3 }, 00780 { 2, 3 }, { 1, 3 }, { 1, 2 } }; 00781 00782 double lame[6] = { -1 }; 00783 Point<3> cutp[4]; 00784 int cutpi = 0; 00785 for (int j = 0; j < 6; j++) 00786 { 00787 int pi1 = edges[j][0]; 00788 int pi2 = edges[j][1]; 00789 if ((valtet[pi1] > 0) != (valtet[pi2] > 0)) 00790 { 00791 Vec<3> ve = pnts[pi2]-pnts[pi1]; 00792 double lam = CutEdge (valtet[pi1], valtet[pi2]); 00793 cutp[cutpi] = pnts[pi1] + lam * (pnts[pi2]-pnts[pi1]); 00794 cutpi++; 00795 } 00796 } 00797 00798 00799 // calc grad f (normal vector) 00800 Mat<3,3> mat; 00801 for (int i = 0; i < 3; i++) 00802 for (int j = 0; j < 3; j++) 00803 mat(i,j) = pnts[i](j) - pnts[3](j); 00804 Vec<3> rhs, sol; 00805 for (int i = 0; i < 3; i++) 00806 rhs(i) = valtet[i] - valtet[3]; 00807 mat.Solve (rhs, sol); 00808 00809 if (npos == 1 || npos == 3) // cut 3 edges 00810 WriteTrig (cutp[0], cutp[1], cutp[2], sol); 00811 00812 if (npos == 2) // cut 4 edges 00813 { 00814 WriteTrig (cutp[0], cutp[1], cutp[2], sol); 00815 WriteTrig (cutp[0], cutp[2], cutp[3], sol); 00816 } 00817 } 00818 00819 00820 void MakeCubeSTL (//Point<3> p1, Point<3> p2, 00821 Point<3> pointcube[8], 00822 double valcube[8], Vec<3> dvalcube[8]) 00823 { 00824 const int tets[6][4] = 00825 { { 0, 1, 2, 4 }, 00826 { 1, 2, 4, 5 }, 00827 { 2, 4, 5, 6 }, 00828 { 1, 3, 2, 5 }, 00829 { 3, 2, 5, 6 }, 00830 { 3, 6, 5, 7 } }; 00831 00832 double valtet[4]; 00833 Vec<3> dvaltet[4]; 00834 Point<3> pnts[4]; 00835 00836 for (int j = 0; j < 6; j++) 00837 { 00838 for (int k = 0; k < 4; k++) 00839 { 00840 valtet[k] = valcube[tets[j][k]]; 00841 dvaltet[k] = dvalcube[tets[j][k]]; 00842 pnts[k] = pointcube[tets[j][k]]; 00843 } 00844 00845 MakeTetSTL (pnts, valtet, dvaltet); 00846 } 00847 } 00848 00849 00850 00851 void MakeSTL (Point<3> pmin, Point<3> pmax, 00852 int nx, int ny, int nz, 00853 Array<Point<3> > & gridpoints, 00854 Array<float> & values, 00855 Array<Vec<3> > & dvalues) 00856 { 00857 double valcube[8]; 00858 Vec<3> dvalcube[8]; 00859 Point<3> pointcube[8]; 00860 00861 cout << "Writing stl file" << endl; 00862 for (int ix = 0; ix < nx; ix++) 00863 { 00864 cout << "\r" << ix << "/" << nx << flush; 00865 for (int iy = 0; iy < ny; iy++) 00866 for (int iz = 0; iz < nz; iz++) 00867 { 00868 for (int jx = 0, jj = 0; jx < 2; jx++) 00869 for (int jy = 0; jy < 2; jy++) 00870 for (int jz = 0; jz < 2; jz++, jj++) 00871 { 00872 int ind = ix+jx + (nx+1) * (iy+jy + (ny+1)*(iz+jz)); 00873 valcube[jj] = values[ind]; 00874 dvalcube[jj] = dvalues[ind]; 00875 pointcube[jj] = gridpoints[ind]; 00876 } 00877 00878 int npos = 0; 00879 for (int j = 0; j < 8; j++) 00880 if (valcube[j] > 0) npos++; 00881 if (npos == 0 || npos == 8) continue; 00882 00883 MakeCubeSTL (pointcube, valcube, dvalcube); 00884 } 00885 } 00886 cout << "\r" << nx << "/" << nx << endl; 00887 } 00888 00889 00890 }; 00891 00892 00893 00894 #endif