source: ThirdParty/mpqc_open/src/lib/math/isosurf/surf.cc@ b7e5b0

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since b7e5b0 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 25.4 KB
Line 
1//
2// surf.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.com>
7// Maintainer: LPS
8//
9// This file is part of the SC Toolkit.
10//
11// The SC Toolkit is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Library General Public License as published by
13// the Free Software Foundation; either version 2, or (at your option)
14// any later version.
15//
16// The SC Toolkit is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU Library General Public License for more details.
20//
21// You should have received a copy of the GNU Library General Public License
22// along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24//
25// The U.S. Government is granted a limited license as per AL 91-7.
26//
27
28#ifdef __GNUC__
29#pragma implementation
30#endif
31
32#include <util/misc/formio.h>
33#include <util/keyval/keyval.h>
34#include <math/scmat/matrix.h>
35#include <math/scmat/vector3.h>
36#include <math/isosurf/surf.h>
37#include <math/isosurf/isosurf.h>
38#include <util/render/polygons.h>
39
40using namespace std;
41using namespace sc;
42
43#ifndef WRITE_OOGL
44#define WRITE_OOGL 1
45#endif
46
47#if WRITE_OOGL
48#include <util/render/oogl.h>
49#endif
50
51/////////////////////////////////////////////////////////////////////////
52// TriangulatedSurface
53static ClassDesc TriangulatedSurface_cd(
54 typeid(TriangulatedSurface),"TriangulatedSurface",1,"public DescribedClass",
55 create<TriangulatedSurface>, create<TriangulatedSurface>, 0);
56
57TriangulatedSurface::TriangulatedSurface():
58 _verbose(0),
59 _debug(0),
60 _triangle_vertex(0),
61 _triangle_edge(0),
62 _edge_vertex(0),
63 _integrator(new GaussTriangleIntegrator(1))
64{
65 clear();
66}
67
68TriangulatedSurface::TriangulatedSurface(const Ref<KeyVal>& keyval):
69 _triangle_vertex(0),
70 _triangle_edge(0),
71 _edge_vertex(0)
72{
73 _verbose = keyval->booleanvalue("verbose");
74 _debug = keyval->booleanvalue("debug");
75 Ref<TriangleIntegrator> triint;
76 triint << keyval->describedclassvalue("integrator");
77 if (triint.null()) {
78 triint = new GaussTriangleIntegrator(1);
79 }
80 set_integrator(triint);
81 triint << keyval->describedclassvalue("fast_integrator");
82 set_fast_integrator(triint);
83 triint << keyval->describedclassvalue("accurate_integrator");
84 set_accurate_integrator(triint);
85 clear();
86}
87
88TriangulatedSurface::~TriangulatedSurface()
89{
90 clear();
91}
92
93void
94TriangulatedSurface::topology_info(ostream&o)
95{
96 topology_info(nvertex(), nedge(), ntriangle(), o);
97}
98
99void
100TriangulatedSurface::topology_info(int v, int e, int t, ostream&o)
101{
102 // Given v vertices i expect 2*v - 4*n_surface triangles
103 // and 3*v - 6*n_surface edges
104 o << indent
105 << scprintf("n_vertex = %d, n_edge = %d, n_triangle = %d:",
106 v, e, t)
107 << endl;
108 int nsurf_e = ((3*v - e)%6 == 0)? (3*v - e)/6 : -1;
109 int nsurf_t = ((2*v - t)%4 == 0)? (2*v - t)/4 : -1;
110 if ((nsurf_e!=-1) && (nsurf_e == nsurf_t)) {
111 o << indent
112 << scprintf(" this is consistent with n_closed_surface - n_hole = %d",
113 nsurf_e)
114 << endl;
115 }
116 else {
117 o << indent
118 << scprintf(" this implies that some surfaces are not closed")
119 << endl;
120 }
121}
122
123void
124TriangulatedSurface::set_integrator(const Ref<TriangleIntegrator>& i)
125{
126 _integrator = i;
127}
128
129void
130TriangulatedSurface::set_fast_integrator(const Ref<TriangleIntegrator>& i)
131{
132 _fast_integrator = i;
133}
134
135void
136TriangulatedSurface::set_accurate_integrator(const Ref<TriangleIntegrator>& i)
137{
138 _accurate_integrator = i;
139}
140
141Ref<TriangleIntegrator>
142TriangulatedSurface::integrator(int)
143{
144 // currently the argument, the integer index of the triangle, is ignored
145 return _integrator;
146}
147
148Ref<TriangleIntegrator>
149TriangulatedSurface::fast_integrator(int)
150{
151 // currently the argument, the integer index of the triangle, is ignored
152 return _fast_integrator.null()?_integrator:_fast_integrator;
153}
154
155Ref<TriangleIntegrator>
156TriangulatedSurface::accurate_integrator(int)
157{
158 // currently the argument, the integer index of the triangle, is ignored
159 return _accurate_integrator.null()?_integrator:_accurate_integrator;
160}
161
162void
163TriangulatedSurface::clear_int_arrays()
164{
165 if (_triangle_vertex) {
166 for (int i=0; i<_triangles.size(); i++) {
167 delete[] _triangle_vertex[i];
168 }
169 delete[] _triangle_vertex;
170 }
171 _triangle_vertex = 0;
172
173 if (_triangle_edge) {
174 for (int i=0; i<_triangles.size(); i++) {
175 delete[] _triangle_edge[i];
176 }
177 delete[] _triangle_edge;
178 }
179 _triangle_edge = 0;
180
181 if (_edge_vertex) {
182 for (int i=0; i<_edges.size(); i++) {
183 delete[] _edge_vertex[i];
184 }
185 delete[] _edge_vertex;
186 }
187 _edge_vertex = 0;
188
189 _completed_surface = 0;
190}
191
192void
193TriangulatedSurface::clear()
194{
195 _completed_surface = 0;
196
197 clear_int_arrays();
198
199 _have_values = 0;
200 _values.clear();
201
202 _vertices.clear();
203 _edges.clear();
204 _triangles.clear();
205
206 _tmp_edges.clear();
207}
208
209void
210TriangulatedSurface::complete_surface()
211{
212 complete_ref_arrays();
213 complete_int_arrays();
214
215 _completed_surface = 1;
216}
217
218void
219TriangulatedSurface::complete_ref_arrays()
220{
221 _tmp_edges.clear();
222 _index_to_edge.clear();
223 _edge_to_index.clear();
224
225 int i;
226 int ntri = ntriangle();
227 _edges.clear();
228 for (i=0; i<ntri; i++) {
229 Ref<Triangle> tri = triangle(i);
230 add_edge(tri->edge(0));
231 add_edge(tri->edge(1));
232 add_edge(tri->edge(2));
233 }
234 int ne = nedge();
235 _vertices.clear();
236 _index_to_vertex.clear();
237 _vertex_to_index.clear();
238 for (i=0; i<ne; i++) {
239 Ref<Edge> e = edge(i);
240 add_vertex(e->vertex(0));
241 add_vertex(e->vertex(1));
242 }
243}
244
245void
246TriangulatedSurface::complete_int_arrays()
247{
248 clear_int_arrays();
249
250 int i;
251 int ntri = ntriangle();
252 int ne = nedge();
253
254 // construct the array that converts the triangle number and vertex
255 // number within the triangle to the overall vertex number
256 _triangle_vertex = new int*[ntri];
257 for (i=0; i<ntri; i++) {
258 _triangle_vertex[i] = new int[3];
259 for (int j=0; j<3; j++) {
260 Ref<Vertex> v = triangle(i)->vertex(j);
261 _triangle_vertex[i][j] = _vertex_to_index[v];
262 }
263 }
264
265 // construct the array that converts the triangle number and edge number
266 // within the triangle to the overall edge number
267 _triangle_edge = new int*[ntri];
268 for (i=0; i<ntri; i++) {
269 _triangle_edge[i] = new int[3];
270 for (int j=0; j<3; j++) {
271 Ref<Edge> e = triangle(i)->edge(j);
272 _triangle_edge[i][j] = _edge_to_index[e];
273 }
274 }
275
276 // construct the array that converts the edge number and vertex number
277 // within the edge to the overall vertex number
278 _edge_vertex = new int*[ne];
279 for (i=0; i<ne; i++) {
280 _edge_vertex[i] = new int[2];
281 for (int j=0; j<2; j++) {
282 Ref<Vertex> v = edge(i)->vertex(j);
283 _edge_vertex[i][j] = _vertex_to_index[v];
284 }
285 }
286}
287
288void
289TriangulatedSurface::compute_values(Ref<Volume>&vol)
290{
291 int n = _vertices.size();
292 _values.resize(n);
293
294 for (int i=0; i<n; i++) {
295 vol->set_x(vertex(i)->point());
296 _values[i] = vol->value();
297 }
298 _have_values = 1;
299}
300
301double
302TriangulatedSurface::flat_area()
303{
304 double result = 0.0;
305 for (std::set<Ref<Triangle> >::iterator i=_triangles.begin();
306 i!=_triangles.end(); i++) {
307 result += (*i)->flat_area();
308 }
309 return result;
310}
311
312double
313TriangulatedSurface::flat_volume()
314{
315 double result = 0.0;
316 for (int i=0; i<_triangles.size(); i++) {
317
318 // get the vertices of the triangle
319 SCVector3 A(vertex(triangle_vertex(i,0))->point());
320 SCVector3 B(vertex(triangle_vertex(i,1))->point());
321 SCVector3 C(vertex(triangle_vertex(i,2))->point());
322
323 // project the vertices onto the xy plane
324 SCVector3 Axy(A); Axy[2] = 0.0;
325 SCVector3 Bxy(B); Bxy[2] = 0.0;
326 SCVector3 Cxy(C); Cxy[2] = 0.0;
327
328 // construct the legs of the triangle in the xy plane
329 SCVector3 BAxy = Bxy - Axy;
330 SCVector3 CAxy = Cxy - Axy;
331
332 // find the lengths of the legs of the triangle in the xy plane
333 double baxy = sqrt(BAxy.dot(BAxy));
334 double caxy = sqrt(CAxy.dot(CAxy));
335
336 // if one of the legs is of length zero, then there is
337 // no contribution from this triangle
338 if (baxy < 1.e-16 || caxy < 1.e-16) continue;
339
340 // find the sine of the angle between the legs of the triangle
341 // in the xy plane
342 double costheta = BAxy.dot(CAxy)/(baxy*caxy);
343 double sintheta = sqrt(1.0 - costheta*costheta);
344
345 // the area of the triangle in the xy plane
346 double areaxy = 0.5 * baxy * caxy * sintheta;
347
348 // the height of the three corners of the triangle
349 // (relative to the z plane)
350 double hA = A[2];
351 double hB = B[2];
352 double hC = C[2];
353
354 // the volume of the space under the triangle
355 double volume = areaxy * (hA + (hB + hC - 2.0*hA)/3.0);
356
357 // the orientation of the triangle along the projection axis (z)
358 SCVector3 BA(B-A);
359 SCVector3 CA(C-A);
360 double z_orientation = BA.cross(CA)[2];
361
362 if (z_orientation > 0.0) {
363 result += volume;
364 }
365 else {
366 result -= volume;
367 }
368
369 }
370
371 // If the volume is negative, then the surface gradients were
372 // opposite in sign to the direction assumed. Flip the sign
373 // to fix.
374 return fabs(result);
375}
376
377double
378TriangulatedSurface::area()
379{
380 double area = 0.0;
381 TriangulatedSurfaceIntegrator triint(this);
382 for (triint = 0; triint.update(); triint++) {
383 area += triint.w();
384 }
385 return area;
386}
387
388double
389TriangulatedSurface::volume()
390{
391 double volume = 0.0;
392 TriangulatedSurfaceIntegrator triint(this);
393 for (triint = 0; triint.update(); triint++) {
394 volume += triint.weight()*triint.dA()[2]*triint.current()->point()[2];
395 }
396 return volume;
397}
398
399void
400TriangulatedSurface::add_vertex(const Ref<Vertex>&t)
401{
402 int i = _vertices.size();
403 _vertices.insert(t);
404 if (i != _vertices.size()) {
405 _index_to_vertex.push_back(t);
406 _vertex_to_index[t] = i;
407 if (_index_to_vertex.size() != _vertex_to_index.size()) {
408 ExEnv::errn() << "TriangulatedSurface::add_vertex: length mismatch" << endl;
409 abort();
410 }
411 }
412}
413
414void
415TriangulatedSurface::add_edge(const Ref<Edge>&t)
416{
417 int i = _edges.size();
418 _edges.insert(t);
419 if (i != _edges.size()) {
420 _index_to_edge.push_back(t);
421 _edge_to_index[t] = i;
422 if (_index_to_edge.size() != _edge_to_index.size()) {
423 ExEnv::errn() << "TriangulatedSurface::add_edge: length mismatch" << endl;
424 abort();
425 }
426 }
427}
428
429void
430TriangulatedSurface::add_triangle(const Ref<Triangle>&t)
431{
432 if (_completed_surface) clear();
433 int i = _triangles.size();
434 _triangles.insert(t);
435 if (i != _triangles.size()) {
436 _index_to_triangle.push_back(t);
437 _triangle_to_index[t] = i;
438 if (_index_to_triangle.size() != _triangle_to_index.size()) {
439 ExEnv::errn() << "TriangulatedSurface::add_triangle: length mismatch" << endl;
440 abort();
441 }
442 }
443}
444
445void
446TriangulatedSurface::add_triangle(const Ref<Vertex>& v1,
447 const Ref<Vertex>& v2,
448 const Ref<Vertex>& v3)
449{
450 // Find this triangle's edges if they have already be created
451 // for some other triangle.
452 Ref<Edge> e0, e1, e2;
453
454 const std::set<Ref<Edge> > &v1edges = _tmp_edges[v1];
455
456 const std::set<Ref<Edge> > &v2edges = _tmp_edges[v2];
457
458 std::set<Ref<Edge> >::const_iterator ix;
459 for (ix = v1edges.begin(); ix != v1edges.end(); ix++) {
460 const Ref<Edge>& e = *ix;
461 if (e->vertex(0) == v2 || e->vertex(1) == v2) {
462 e0 = e;
463 }
464 else if (e->vertex(0) == v3 || e->vertex(1) == v3) {
465 e2 = e;
466 }
467 }
468 for (ix = v2edges.begin(); ix != v2edges.end(); ix++) {
469 const Ref<Edge>& e = *ix;
470 if (e->vertex(0) == v3 || e->vertex(1) == v3) {
471 e1 = e;
472 }
473 }
474
475 if (e0.null()) {
476 e0 = newEdge(v1,v2);
477 _tmp_edges[v1].insert(e0);
478 _tmp_edges[v2].insert(e0);
479 }
480 if (e1.null()) {
481 e1 = newEdge(v2,v3);
482 _tmp_edges[v2].insert(e1);
483 _tmp_edges[v3].insert(e1);
484 }
485 if (e2.null()) {
486 e2 = newEdge(v3,v1);
487 _tmp_edges[v3].insert(e2);
488 _tmp_edges[v1].insert(e2);
489 }
490
491 int orientation;
492 if (e0->vertex(0) == v1) {
493 orientation = 0;
494 }
495 else {
496 orientation = 1;
497 }
498
499 add_triangle(newTriangle(e0,e1,e2,orientation));
500}
501
502// If a user isn't keeping track of edges while add_triangle is being
503// used to build the surface, then this can be called to see if an edge
504// already exists (at a great performance cost).
505Ref<Edge>
506TriangulatedSurface::find_edge(const Ref<Vertex>& v1, const Ref<Vertex>& v2)
507{
508 std::set<Ref<Triangle> >::iterator i;
509
510 for (i=_triangles.begin(); i!=_triangles.end(); i++) {
511 Ref<Triangle> t = *i;
512 Ref<Edge> e1 = t->edge(0);
513 Ref<Edge> e2 = t->edge(1);
514 Ref<Edge> e3 = t->edge(2);
515 if (e1->vertex(0) == v1 && e1->vertex(1) == v2) return e1;
516 if (e1->vertex(1) == v1 && e1->vertex(0) == v2) return e1;
517 if (e2->vertex(0) == v1 && e2->vertex(1) == v2) return e2;
518 if (e2->vertex(1) == v1 && e2->vertex(0) == v2) return e2;
519 if (e3->vertex(0) == v1 && e3->vertex(1) == v2) return e3;
520 if (e3->vertex(1) == v1 && e3->vertex(0) == v2) return e3;
521 }
522
523 return 0;
524}
525
526void
527TriangulatedSurface::print(ostream&o) const
528{
529 o << indent << "TriangulatedSurface:" << endl;
530 int i;
531
532 int np = nvertex();
533 o << indent << scprintf(" %3d Vertices:",np) << endl;
534 for (i=0; i<np; i++) {
535 Ref<Vertex> p = vertex(i);
536 o << indent << scprintf(" %3d:",i);
537 for (int j=0; j<3; j++) {
538 o << scprintf(" % 15.10f", p->point()[j]);
539 }
540 o << endl;
541 }
542
543 int ne = nedge();
544 o << indent << scprintf(" %3d Edges:",ne) << endl;
545 for (i=0; i<ne; i++) {
546 Ref<Edge> e = edge(i);
547 Ref<Vertex> v0 = e->vertex(0);
548 Ref<Vertex> v1 = e->vertex(1);
549 std::map<Ref<Vertex>,int>::const_iterator v0i=_vertex_to_index.find(v0);
550 std::map<Ref<Vertex>,int>::const_iterator v1i=_vertex_to_index.find(v1);
551 int v0int = v0i==_vertex_to_index.end()? -1: v0i->second;
552 int v1int = v1i==_vertex_to_index.end()? -1: v1i->second;
553 o << indent
554 << scprintf(" %3d: %3d %3d",i, v0int, v1int)
555 << endl;
556 }
557
558 int nt = ntriangle();
559 o << indent << scprintf(" %3d Triangles:",nt) << endl;
560 for (i=0; i<nt; i++) {
561 Ref<Triangle> tri = triangle(i);
562 Ref<Edge> e0 = tri->edge(0);
563 Ref<Edge> e1 = tri->edge(1);
564 Ref<Edge> e2 = tri->edge(2);
565 std::map<Ref<Edge>,int>::const_iterator e0i = _edge_to_index.find(e0);
566 std::map<Ref<Edge>,int>::const_iterator e1i = _edge_to_index.find(e1);
567 std::map<Ref<Edge>,int>::const_iterator e2i = _edge_to_index.find(e2);
568 int e0int = e0i==_edge_to_index.end()? -1: e0i->second;
569 int e1int = e1i==_edge_to_index.end()? -1: e1i->second;
570 int e2int = e2i==_edge_to_index.end()? -1: e2i->second;
571 o << indent
572 << scprintf(" %3d: %3d %3d %3d",i, e0int, e1int, e2int)
573 << endl;
574 }
575}
576
577void
578TriangulatedSurface::print_vertices_and_triangles(ostream&o) const
579{
580 o << indent << "TriangulatedSurface:" << endl;
581 int i;
582
583 int np = nvertex();
584 o << indent << scprintf(" %3d Vertices:",np) << endl;
585 for (i=0; i<np; i++) {
586 Ref<Vertex> p = vertex(i);
587 o << indent << scprintf(" %3d:",i);
588 for (int j=0; j<3; j++) {
589 o << scprintf(" % 15.10f", p->point()[j]);
590 }
591 o << endl;
592 }
593
594 int nt = ntriangle();
595 o << indent << scprintf(" %3d Triangles:",nt) << endl;
596 for (i=0; i<nt; i++) {
597 Ref<Triangle> tri = triangle(i);
598 o << indent
599 << scprintf(" %3d: %3d %3d %3d",i,
600 _triangle_vertex[i][0],
601 _triangle_vertex[i][1],
602 _triangle_vertex[i][2])
603 << endl;
604 }
605}
606
607void
608TriangulatedSurface::render(const Ref<Render> &render)
609{
610 Ref<RenderedPolygons> poly = new RenderedPolygons;
611 poly->initialize(_vertices.size(), _triangles.size(),
612 RenderedPolygons::Vertex);
613 std::set<Ref<Vertex> >::iterator iv;
614 std::set<Ref<Triangle> >::iterator it;
615 std::map<Ref<Vertex>, int> vertex_to_index;
616 int i = 0;
617 for (iv = _vertices.begin(); iv != _vertices.end(); iv++, i++) {
618 Ref<Vertex> v = *iv;
619 vertex_to_index[v] = i;
620 poly->set_vertex(i,
621 v->point()[0],
622 v->point()[1],
623 v->point()[2]);
624 poly->set_vertex_rgb(i, 0.3, 0.3, 0.3);
625 }
626 i = 0;
627 for (it = _triangles.begin(); it != _triangles.end(); it++, i++) {
628 Ref<Triangle> t = *it;
629 poly->set_face(i,
630 vertex_to_index[t->vertex(0)],
631 vertex_to_index[t->vertex(1)],
632 vertex_to_index[t->vertex(2)]);
633 }
634 render->render(poly.pointer());
635}
636
637void
638TriangulatedSurface::print_geomview_format(ostream&o) const
639{
640 o << "OFF" << endl;
641
642 o << nvertex() << " " << ntriangle() << " " << nedge() << endl;
643 int i;
644
645 int np = nvertex();
646 for (i=0; i<np; i++) {
647 Ref<Vertex> p = vertex(i);
648 for (int j=0; j<3; j++) {
649 o << scprintf(" % 15.10f", p->point()[j]);
650 }
651 o << endl;
652 }
653
654 int nt = ntriangle();
655 for (i=0; i<nt; i++) {
656 Ref<Triangle> tri = triangle(i);
657 o << scprintf(" 3 %3d %3d %3d",
658 _triangle_vertex[i][0],
659 _triangle_vertex[i][1],
660 _triangle_vertex[i][2])
661 << endl;
662 }
663}
664
665void
666TriangulatedSurface::recompute_index_maps()
667{
668 int i;
669 std::set<Ref<Vertex> >::iterator iv;
670 std::set<Ref<Edge> >::iterator ie;
671 std::set<Ref<Triangle> >::iterator it;
672
673 // fix the index maps
674 _vertex_to_index.clear();
675 _edge_to_index.clear();
676 _triangle_to_index.clear();
677
678 _index_to_vertex.clear();
679 _index_to_edge.clear();
680 _index_to_triangle.clear();
681
682 _index_to_vertex.resize(_vertices.size());
683 for (i=0, iv = _vertices.begin(); iv != _vertices.end(); i++, iv++) {
684 _vertex_to_index[*iv] = i;
685 _index_to_vertex[i] = *iv;
686 }
687
688 _index_to_edge.resize(_edges.size());
689 for (i=0, ie = _edges.begin(); ie != _edges.end(); i++, ie++) {
690 _edge_to_index[*ie] = i;
691 _index_to_edge[i] = *ie;
692 }
693
694 _index_to_triangle.resize(_triangles.size());
695 for (i=0, it = _triangles.begin(); it != _triangles.end(); i++, it++) {
696 _triangle_to_index[*it] = i;
697 _index_to_triangle[i] = *it;
698 }
699
700}
701
702Edge*
703TriangulatedSurface::newEdge(const Ref<Vertex>& v0, const Ref<Vertex>& v1) const
704{
705 return new Edge(v0,v1);
706}
707
708Triangle*
709TriangulatedSurface::newTriangle(const Ref<Edge>& e0,
710 const Ref<Edge>& e1,
711 const Ref<Edge>& e2,
712 int orientation) const
713{
714 return new Triangle(e0,e1,e2,orientation);
715}
716
717//////////////////////////////////////////////////////////////////////
718// TriangulatedSurfaceIntegrator
719
720TriangulatedSurfaceIntegrator::
721 TriangulatedSurfaceIntegrator(const Ref<TriangulatedSurface>&ts)
722{
723 set_surface(ts);
724 use_default_integrator();
725
726 _itri = 0;
727 _irs = 0;
728}
729
730TriangulatedSurfaceIntegrator::
731 TriangulatedSurfaceIntegrator()
732{
733 use_default_integrator();
734}
735
736void
737TriangulatedSurfaceIntegrator::
738 operator =(const TriangulatedSurfaceIntegrator&i)
739{
740 set_surface(i._ts);
741
742 _integrator = i._integrator;
743 _itri = i._itri;
744 _irs = i._irs;
745}
746
747TriangulatedSurfaceIntegrator::
748 ~TriangulatedSurfaceIntegrator()
749{
750}
751
752void
753TriangulatedSurfaceIntegrator::set_surface(const Ref<TriangulatedSurface>&s)
754{
755 _ts = s;
756 _current = new Vertex();
757}
758
759int
760TriangulatedSurfaceIntegrator::
761 vertex_number(int i)
762{
763 return _ts->triangle_vertex(_itri,i);
764}
765
766Ref<Vertex>
767TriangulatedSurfaceIntegrator::
768 current()
769{
770 return _current;
771}
772
773int
774TriangulatedSurfaceIntegrator::n()
775{
776 int result = 0;
777 int ntri = _ts->ntriangle();
778 for (int i=0; i<ntri; i++) {
779 result += (_ts.pointer()->*_integrator)(i)->n();
780 }
781 return result;
782}
783
784int
785TriangulatedSurfaceIntegrator::update()
786{
787 if (_itri < 0 || _itri >= _ts->ntriangle()) return 0;
788
789 TriangleIntegrator* i = (_ts.pointer()->*_integrator)(_itri).pointer();
790 _s = i->s(_irs);
791 _r = i->r(_irs);
792 _weight = i->w(_irs);
793 Ref<Triangle> t = _ts->triangle(_itri);
794 Ref<TriInterpCoef> coef = i->coef(t->order(),_irs);
795 t->interpolate(coef, _r, _s, _current, _dA);
796 _surface_element = _dA.norm();
797 static double cum;
798 if (_irs == 0) cum = 0.0;
799 cum += _surface_element * _weight;
800 //ExEnv::outn() << scprintf("%2d dA = %12.8f, w = %12.8f, Sum wdA = %12.8f",
801 // _irs, _surface_element, _weight, cum)
802 // << endl;
803
804 return (int) 1;
805}
806
807void
808TriangulatedSurfaceIntegrator::
809 operator ++()
810{
811 int n = (_ts.pointer()->*_integrator)(_itri)->n();
812 if (_irs == n-1) {
813 _irs = 0;
814 if (_grp.null()) _itri++;
815 else _itri += _grp->n();
816 }
817 else {
818 _irs++;
819 }
820}
821
822void
823TriangulatedSurfaceIntegrator::distribute(const Ref<MessageGrp> &grp)
824{
825 _grp = grp;
826}
827
828int
829TriangulatedSurfaceIntegrator::
830 operator = (int i)
831{
832 _itri = i;
833 _irs = 0;
834 return i;
835}
836
837void
838TriangulatedSurfaceIntegrator::use_default_integrator()
839{
840 _integrator = &TriangulatedSurface::integrator;
841}
842
843void
844TriangulatedSurfaceIntegrator::use_fast_integrator()
845{
846 _integrator = &TriangulatedSurface::fast_integrator;
847}
848
849void
850TriangulatedSurfaceIntegrator::use_accurate_integrator()
851{
852 _integrator = &TriangulatedSurface::accurate_integrator;
853}
854
855/////////////////////////////////////////////////////////////////////////
856// TriangulatedImplicitSurface
857static ClassDesc TriangulatedImplicitSurface_cd(
858 typeid(TriangulatedImplicitSurface),"TriangulatedImplicitSurface",1,"public TriangulatedSurface",
859 0, create<TriangulatedImplicitSurface>, 0);
860
861TriangulatedImplicitSurface::
862TriangulatedImplicitSurface(const Ref<KeyVal>&keyval):
863 TriangulatedSurface(keyval)
864{
865 inited_ = 0;
866
867 vol_ << keyval->describedclassvalue("volume");
868 if (keyval->error() != KeyVal::OK) {
869 ExEnv::errn() << "TriangulatedImplicitSurface(const Ref<KeyVal>&keyval): "
870 << "requires \"volume\"" << endl;
871 abort();
872 }
873
874 isovalue_ = keyval->doublevalue("value");
875 if (keyval->error() != KeyVal::OK) isovalue_ = 0.0;
876
877 fix_orientation_ = keyval->booleanvalue("fix_orientation");
878 if (keyval->error() != KeyVal::OK) fix_orientation_ = 1;
879
880 remove_short_edges_ = keyval->booleanvalue("remove_short_edges");
881 if (keyval->error() != KeyVal::OK) remove_short_edges_ = 1;
882
883 remove_slender_triangles_ = keyval->booleanvalue("remove_slender_triangles");
884 if (keyval->error() != KeyVal::OK) remove_slender_triangles_ = 0;
885
886 remove_small_triangles_ = keyval->booleanvalue("remove_small_triangles");
887 if (keyval->error() != KeyVal::OK) remove_small_triangles_ = 0;
888
889 short_edge_factor_ = keyval->doublevalue("short_edge_factor");
890 if (keyval->error() != KeyVal::OK) short_edge_factor_ = 0.4;
891
892 slender_triangle_factor_ = keyval->doublevalue("slender_triangle_factor");
893 if (keyval->error() != KeyVal::OK) slender_triangle_factor_ = 0.2;
894
895 small_triangle_factor_ = keyval->doublevalue("small_triangle_factor");
896 if (keyval->error() != KeyVal::OK) small_triangle_factor_ = 0.2;
897
898 resolution_ = keyval->doublevalue("resolution");
899 if (keyval->error() != KeyVal::OK) resolution_ = 1.0;
900
901 order_ = keyval->intvalue("order");
902 if (keyval->error() != KeyVal::OK) order_ = 1;
903
904 int initialize = keyval->booleanvalue("initialize");
905 if (initialize) init();
906}
907
908void
909TriangulatedImplicitSurface::init()
910{
911 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: init start" << endl;
912 ImplicitSurfacePolygonizer isogen(vol_);
913 isogen.set_resolution(resolution_);
914
915 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: isosurface" << endl;
916 isogen.isosurface(isovalue_,*this);
917#if WRITE_OOGL
918 if (_debug) {
919 render(new OOGLRender("surfiso.oogl"));
920 }
921#endif
922 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: orientation" << endl;
923 if (fix_orientation_) fix_orientation();
924#if WRITE_OOGL
925 if (_debug) {
926 render(new OOGLRender("surffix.oogl"));
927 }
928#endif
929 if (remove_short_edges_) {
930 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: short edges" << endl;
931 remove_short_edges(short_edge_factor_*resolution_,vol_,isovalue_);
932 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: orientation" << endl;
933 if (fix_orientation_) fix_orientation();
934 }
935 if (remove_slender_triangles_ || remove_small_triangles_) {
936 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: slender" << endl;
937 double height_cutoff = slender_triangle_factor_ * resolution_;
938 double area_cutoff = small_triangle_factor_*resolution_*resolution_*0.5;
939 remove_slender_triangles(remove_slender_triangles_, height_cutoff,
940 remove_small_triangles_, area_cutoff,
941 vol_,isovalue_);
942 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: orientation" << endl;
943 if (fix_orientation_) fix_orientation();
944 }
945
946 // see if a higher order approximation to the surface is required
947 if (order_ > 1) {
948 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: order" << endl;
949 int i;
950 for (i=0; i<nedge(); i++) {
951 edge(i)->set_order(order_, vol_, isovalue_);
952 }
953 for (i=0; i<ntriangle(); i++) {
954 triangle(i)->set_order(order_, vol_, isovalue_);
955 }
956 }
957 inited_ = 1;
958 if (_verbose) ExEnv::outn() << "TriangulatedImplicitSurface: init done" << endl;
959}
960
961TriangulatedImplicitSurface::~TriangulatedImplicitSurface()
962{
963}
964
965/////////////////////////////////////////////////////////////////////////////
966
967// Local Variables:
968// mode: c++
969// c-file-style: "CLJ"
970// End:
Note: See TracBrowser for help on using the repository browser.