source: ThirdParty/mpqc_open/src/lib/math/isosurf/isosurf.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: 7.6 KB
Line 
1//
2// isosurf.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 <iostream>
33
34#include <math/isosurf/isosurf.h>
35#include <math/isosurf/implicit.h>
36#include <math/scmat/vector3.h>
37
38using namespace std;
39using namespace sc;
40
41// This static datum is used to interface to the implicit.c routine
42// provided in Graphics Gems IV.
43ImplicitSurfacePolygonizer* ImplicitSurfacePolygonizer::current = 0;
44
45// These functions are used to interface to the implicit.c routine provided
46// in Graphics Gems IV.
47extern "C" int
48ImplicitSurfacePolygonizer_add_triangle_to_current(int i1, int i2, int i3,
49 VERTICES v)
50{
51 return ImplicitSurfacePolygonizer::add_triangle_to_current(i1, i2, i3, v);
52}
53
54extern "C" double
55ImplicitSurfacePolygonizer_value_of_current(double x,double y,double z)
56{
57 return ImplicitSurfacePolygonizer::value_of_current(x,y,z);
58}
59
60////////////////////////////////////////////////////////////////////////////
61// IsosurfaceGen members
62
63IsosurfaceGen::IsosurfaceGen():
64 _resolution(0.25)
65{
66}
67
68IsosurfaceGen::~IsosurfaceGen()
69{
70}
71
72void
73IsosurfaceGen::set_resolution(double r)
74{
75 _resolution = r;
76}
77
78////////////////////////////////////////////////////////////////////////////
79// ImplicitSurfacePolygonizer members
80
81ImplicitSurfacePolygonizer::ImplicitSurfacePolygonizer(const Ref<Volume>&vol):
82 _volume(vol)
83 ,_tmp_vertices(0)
84{
85}
86
87ImplicitSurfacePolygonizer::~ImplicitSurfacePolygonizer()
88{
89}
90
91static SCVector3 current_x;
92void
93ImplicitSurfacePolygonizer::isosurface(double value,
94 TriangulatedSurface& surf)
95{
96 surf.clear();
97
98 // Find the bounding box.
99 SCVector3 p0;
100 SCVector3 p1;
101 _volume->boundingbox(value - 0.001, value + 0.001, p0, p1);
102 SCVector3 diag = p1 - p0;
103 SCVector3 midpoint = 0.5*diag + p0;
104 double biggest_width = diag.maxabs();
105 int bounds = (int)(0.5*biggest_width/_resolution) + 2;
106
107 // polygonize will find a starting point and do bounds checking
108 // from that point. To make sure the bounding box is big enough
109 // its size must be doubled. Since polygonization is implicit
110 // there is no performance penalty.
111 bounds *= 2;
112
113 // Initialize the static pointer to this, so the C polygonizer can find us.
114 current = this;
115 _surf = &surf;
116 _value = value;
117 // Find the polygons.
118 char *msg = polygonize(ImplicitSurfacePolygonizer_value_of_current, _resolution, bounds,
119 midpoint[0], midpoint[1], midpoint[2],
120 ImplicitSurfacePolygonizer_add_triangle_to_current,
121 NOTET);
122 current = 0;
123 _surf = 0;
124 if (msg) {
125 ExEnv::errn() << "ImplicitSurfacePolygonizer::isosurface: failed: "
126 << msg << endl;
127 abort();
128 }
129
130 // Clean up temporaries.
131 _tmp_vertices.clear();
132
133 ExEnv::out0() << "about to complete the surface" << endl;
134
135 // finish the surface
136 surf.complete_surface();
137
138 ExEnv::out0() << "completed the surface" << endl;
139 ExEnv::out0() << "flat area = " << surf.flat_area() << endl;
140 ExEnv::out0() << " ntri = " << setw(10) << surf.ntriangle()
141 << " bytes = "
142 << setw(10) << surf.ntriangle() * sizeof(Triangle)
143 << endl;
144 ExEnv::out0() << " nedg = " << setw(10) << surf.nedge()
145 << " bytes = "
146 << setw(10) << surf.nedge() * sizeof(Edge)
147 << endl;
148 ExEnv::out0() << " nver = " << setw(10) << surf.nvertex()
149 << " bytes = "
150 << setw(10) << surf.nvertex() * sizeof(Vertex)
151 << endl;
152
153 // compute normals if they weren't computed from the gradients
154 if (!_volume->gradient_implemented()) {
155 int i,j;
156 // compute the normals as the average of the normals of
157 // all the connected triangles
158 for (i=0; i<surf.ntriangle(); i++) {
159 Ref<Triangle> t = surf.triangle(i);
160 SCVector3 tmp;
161 SCVector3 BA = t->vertex(1)->point() - t->vertex(0)->point();
162 SCVector3 CA = t->vertex(2)->point() - t->vertex(0)->point();
163 SCVector3 N = BA.cross(CA);
164 double n = N.norm();
165 if (n < 1.0e-8) {
166 tmp = 0.0;
167 }
168 else {
169 n = 1.0/n;
170 for (int j=0; j<3; j++) {
171 tmp[j] = - N[j]*n;
172 }
173 }
174 for (j=0; j<3; j++) {
175 int iv = surf.vertex_index(t->vertex(j));
176 if (iv>=0) {
177 Ref<Vertex> v = surf.vertex(iv);
178 if (v->has_normal()) {
179 tmp += v->normal();
180 }
181 tmp.normalize();
182 v->set_normal(tmp);
183 }
184 }
185 }
186 // normalize all the normals
187 for (i=0; i<surf.nvertex(); i++) {
188 Ref<Vertex> v = surf.vertex(i);
189 if (v->has_normal()) {
190 SCVector3 n = v->normal();
191 n.normalize();
192 v->set_normal(n);
193 }
194 else {
195 ExEnv::outn() << "ERROR: isosurf has a vertex without a triangle" << endl;
196 abort();
197 }
198 }
199 }
200}
201
202double
203ImplicitSurfacePolygonizer::value_of_current(double x,double y,double z)
204{
205 current_x[0] = x; current_x[1] = y; current_x[2] = z;
206 current->_volume->set_x(current_x);
207 return current->_volume->value() - current->_value;
208}
209
210int
211ImplicitSurfacePolygonizer::add_triangle_to_current(int i1, int i2, int i3,
212 VERTICES v)
213{
214 int oldlength = current->_tmp_vertices.size();
215 current->_tmp_vertices.resize(v.count);
216 for (int i=oldlength; i<v.count; i++) {
217 SCVector3 newpoint;
218 newpoint[0] = v.ptr[i].position.x;
219 newpoint[1] = v.ptr[i].position.y;
220 newpoint[2] = v.ptr[i].position.z;
221 current->_volume->set_x(newpoint);
222 SCVector3 normal;
223 if (current->_volume->gradient_implemented()) {
224 current->_volume->get_gradient(normal);
225 normal.normalize();
226 current->_tmp_vertices[i] = new Vertex(newpoint, normal);
227 }
228 else {
229 current->_tmp_vertices[i] = new Vertex(newpoint);
230 }
231 }
232
233 Ref<Vertex> v1 = current->_tmp_vertices[i1];
234 Ref<Vertex> v2 = current->_tmp_vertices[i2];
235 Ref<Vertex> v3 = current->_tmp_vertices[i3];
236
237 static int tricnt = 0;
238 if (++tricnt%100 == 0) {
239 ExEnv::out0() << "adding triangle " << tricnt << endl;
240 ExEnv::out0() << " ntri = " << setw(10) << current->_surf->ntriangle()
241 << " bytes = "
242 << setw(10) << current->_surf->ntriangle() * sizeof(Triangle)
243 << endl;
244 }
245 current->_surf->add_triangle(v1,v2,v3);
246
247 return 1;
248}
249
250/////////////////////////////////////////////////////////////////////////////
251
252// Local Variables:
253// mode: c++
254// c-file-style: "CLJ"
255// End:
Note: See TracBrowser for help on using the repository browser.