ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-2.0/src/openbabel/povrayformat.cpp
Revision: 2445
Committed: Wed Nov 16 21:22:51 2005 UTC (18 years, 7 months ago) by tim
File size: 22420 byte(s)
Log Message:
adding more readers/writers

File Contents

# Content
1 /**********************************************************************
2 Copyright (C) 2002 by Steffen Reith <streit@streit.cc>
3 Some portions Copyright (C) 2003-2005 by Geoffrey R. Hutchison
4 Some portions Copyright (C) 2004 by Chris Morley
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation version 2 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 ***********************************************************************/
15
16 #include "povrayformat.hpp"
17
18 using namespace std;
19 namespace OpenBabel
20 {
21
22
23 /* ---- Make a prefix from title of molecule ---- */
24 string MakePrefix(const char* title)
25 {
26 int pos; /* Position in prefix */
27 char *titleCpy = (char*) NULL;
28 char *str = (char*) NULL;
29 char *last = (char*) NULL;
30
31 /* ---- Copy molecule title to 'str' ---- */
32 if ((titleCpy = strdup(title)) == (char *) NULL)
33 return string("NoMemory");
34
35 /* --- Find last '/' and set 'str' to it if needed ----- */
36 last = strrchr(titleCpy, '/');
37 if (last != (char *) NULL)
38 str = (last + 1);
39 else
40 str = titleCpy;
41
42 /* ---- Check for nonempty string ---- */
43 if (strlen(str) == 0)
44 return string("InValid");
45
46 /* ---- Look for first . and replace with \0 ----- */
47 pos = 0;
48 while((str[pos] != '\0') && (str[pos] != '.'))
49 {
50
51 /* ---- Remove all tabs and spaces ---- */
52 if ((str[pos] == ' ') || (str[pos] == '\t'))
53 str[pos] = '_';
54
55 /* ---- Check next position ---- */
56 pos++;
57
58 }
59
60 /* ---- If we have found a '.' cut the string there ---- */
61 str[pos] = '\0';
62
63 /* ---- Cast to C++ string-type the above operations are a mess with C++ strings ---- */
64 string prefix(str);
65
66 /* ---- Free allocated memory ---- */
67 free(titleCpy);
68
69 /* ---- Return the prefix ---- */
70 return prefix;
71
72 }
73
74 void OutputHeader(ostream &ofs, OBMol &mol, string prefix)
75 {
76 time_t akttime; /* Systemtime */
77 char timestr[TIME_STR_SIZE + 1] = ""; /* Timestring */
78 size_t time_res; /* Result of strftime */
79
80 /* ---- Get the system-time ---- */
81 akttime = time((time_t *) NULL);
82 time_res = strftime(timestr,
83 TIME_STR_SIZE,
84 "%a %b %d %H:%M:%S %Z %Y",
85 localtime((time_t *) &akttime)
86 );
87
88 /* ---- Write some header information ---- */
89 ofs << "//Povray V3.1 code generated by Open Babel" << endl;
90 ofs << "//Author: Steffen Reith <streit@streit.cc>" << endl;
91
92 /* ---- Include timestamp in header ---- */
93 ofs << "//Date: " << timestr << endl << endl;
94
95 /* ---- Include header statement for babel ---- */
96 ofs << "//Include header for povray" << endl;
97 ofs << "#include \"babel31.inc\"" << endl << endl;
98
99 /* ---- You should do a spacefill model for molecules without bonds ---- */
100 if (mol.NumBonds() == 0)
101 {
102
103 /* ---- Check if a spacefill-model is selected ---- */
104 ofs << "#if (BAS | CST)\"" << endl;
105 ofs << "#warning \"Molecule without bonds!\"" << endl;
106 ofs << "#warning \"You should do a spacefill-model\"" << endl;
107 ofs << "#end" << endl << endl;
108
109 }
110
111 /* ---- Set version ---- */
112 ofs << "//Use PovRay3.1" << endl;
113 ofs << "#version 3.1;" << endl << endl;
114
115 /* ---- Print of name of molecule (#\b depends on size of babel.inc!) ---- */
116 ofs << "//Print name of molecule while rendering" << endl;
117 ofs << "#render \"\\b\\b " << mol.GetTitle() << "\\n\\n\"" << endl << endl;
118
119 }
120
121 void CalcBoundingBox(OBMol &mol,
122 double &min_x, double &max_x,
123 double &min_y, double &max_y,
124 double &min_z, double &max_z
125 )
126 {
127 /* ---- Init bounding-box variables ---- */
128 min_x = (double) 0.0;
129 max_x = (double) 0.0;
130 min_y = (double) 0.0;
131 max_y = (double) 0.0;
132 min_z = (double) 0.0;
133 max_z = (double) 0.0;
134
135 /* ---- Check all atoms ---- */
136 for(unsigned int i = 1; i <= mol.NumAtoms(); ++i)
137 {
138
139 /* ---- Get a pointer to ith atom ---- */
140 OBAtom *atom = mol.GetAtom(i);
141
142 /* ---- Check for minimal/maximal x-position ---- */
143 if (atom -> GetX() < min_x)
144 min_x = atom -> GetX();
145 if (atom -> GetX() > max_x)
146 max_x = atom -> GetX();
147
148 /* ---- Check for minimal/maximal y-position ---- */
149 if (atom -> GetY() < min_y)
150 min_y = atom -> GetY();
151 if (atom -> GetY() > max_y)
152 max_y = atom -> GetY();
153
154 /* ---- Check for minimal/maximal z-position ---- */
155 if (atom -> GetZ() < min_z)
156 min_z = atom -> GetZ();
157 if (atom -> GetZ() > max_z)
158 max_z = atom -> GetZ();
159
160 }
161
162 }
163
164 void OutputAtoms(ostream &ofs, OBMol &mol, string prefix)
165 {
166 /* ---- Write all coordinates ---- */
167 ofs << "//Coodinates of atoms 1 - " << mol.NumAtoms() << endl;
168 unsigned int i;
169 for(i = 1; i <= mol.NumAtoms(); ++i)
170 {
171
172 /* ---- Get a pointer to ith atom ---- */
173 OBAtom *atom = mol.GetAtom(i);
174
175 /* ---- Write position of atom i ---- */
176 ofs << "#declare " << prefix << "_pos_" << i << " = <"
177 << atom -> GetX() << ","
178 << atom -> GetY() << ","
179 << atom -> GetZ()
180 << ">;" << endl;
181
182 }
183
184 /* ---- Write povray-description of all atoms ---- */
185 ofs << endl << "//Povray-description of atoms 1 - " << mol.NumAtoms() << endl;
186 for(i = 1; i <= mol.NumAtoms(); ++i)
187 {
188
189 /* ---- Get a pointer to ith atom ---- */
190 OBAtom *atom = mol.GetAtom(i);
191
192 /* ---- Write full description of atom i ---- */
193 ofs << "#declare " << prefix << "_atom" << i << " = ";
194 ofs << "object {" << endl
195 << "\t Atom_" << etab.GetSymbol(atom->GetAtomicNum()) << endl
196 << "\t translate " << prefix << "_pos_" << i << endl << "\t }" << endl;
197
198 }
199
200 /* ---- Add empty line ---- */
201 ofs << endl;
202
203 }
204
205
206 void OutputBASBonds(ostream &ofs, OBMol &mol, string prefix)
207 {
208 /* ---- Write povray-description of all bonds---- */
209 for(unsigned int i = 0; i < mol.NumBonds(); ++i)
210 {
211
212 double x1,y1,z1,x2,y2,z2; /* Start and stop coordinates of a bond */
213 double dist; /* Distance between (x1|y1|z1) and (x2|y2|z2) */
214 double phi,theta; /* Angles between (x1|y1|z1) and (x2|y2|z2) */
215 double dy; /* Distance between (x1|0|z1) and (x2|0|z2) */
216
217 /* ---- Get a pointer to ith atom ---- */
218 OBBond *bond = mol.GetBond(i);
219
220 /* ---- Assign start of bond i ---- */
221 x1 = (bond -> GetBeginAtom()) -> GetX();
222 y1 = (bond -> GetBeginAtom()) -> GetY();
223 z1 = (bond -> GetBeginAtom()) -> GetZ();
224
225 /* ---- Assign end of bond i ---- */
226 x2 = (bond -> GetEndAtom()) -> GetX();
227 y2 = (bond -> GetEndAtom()) -> GetY();
228 z2 = (bond -> GetEndAtom()) -> GetZ();
229
230 /* ---- Calculate length of bond and (x1|0|z1) - (x2|0|z2) ---- */
231 dist = sqrt(SQUARE(x2-x1) + SQUARE(y2-y1) + SQUARE(z2-z1));
232 dy = sqrt(SQUARE(x2-x1) + SQUARE(z2-z1));
233
234 /* ---- Calculate Phi and Theta ---- */
235 phi = (double) 0.0;
236 theta = (double) 0.0;
237 if (fabs(dist) >= EPSILON)
238 phi = acos((y2-y1)/dist);
239 if (fabs(dy) >= EPSILON)
240 theta = acos((x2-x1)/dy);
241
242 /* ---- Full description of bond i ---- */
243 ofs << "#declare " << prefix << "_bond" << i
244 << " = object {" << endl << "\t bond_" << bond -> GetBondOrder() << endl;
245
246 /* ---- Scale bond if needed ---- */
247 if (fabs(dist) >= EPSILON)
248 {
249
250 /* ---- Print povray scale-statement (x-Axis) ---- */
251 ofs << "\t scale <" << dist << ",1.0000,1.0000>\n";
252
253 }
254
255 /* ---- Rotate (Phi) bond if needed ---- */
256 if (fabs(RAD2DEG(-phi) + (double) 90.0) >= EPSILON)
257 {
258
259 /* ---- Rotate along z-axis ---- */
260 ofs << "\t rotate <0.0000,0.0000,"
261 << RAD2DEG(-phi) + (double) 90.0
262 << ">" << endl;
263
264
265 }
266
267 /* ---- Check angle between (x1|0|z1) and (x2|0|z2) ---- */
268 if (theta >= EPSILON)
269 {
270
271 /* ---- Check direction ---- */
272 if ((z2 - z1) >= (double) 0.0)
273 {
274
275 /* ---- Rotate along y-Axis (negative) ---- */
276 ofs << "\t rotate <0.0000,"
277 << RAD2DEG((double) -1.0 * theta) << ",0.0000>"
278 << endl;
279
280 }
281 else
282 {
283
284 /* ---- Rotate along y-Axis (positive) ---- */
285 ofs << "\t rotate <0.0000,"
286 << RAD2DEG(theta) << ",0.0000>"
287 << endl;
288
289 }
290
291 }
292
293 /* ---- Translate bond to start ---- */
294 ofs << "\t translate " << prefix << "_pos_" << bond -> GetBeginAtomIdx()
295 << endl << "\t }" << endl;
296
297 }
298
299 }
300
301 void OutputCSTBonds(ostream &ofs, OBMol &mol, string prefix)
302 {
303 /* ---- Write povray-description of all bonds---- */
304 for(unsigned int i = 0; i < mol.NumBonds(); ++i)
305 {
306
307 double x1,y1,z1,x2,y2,z2; /* Start and stop coordinates of a bond */
308 double dist; /* Distance between (x1|y1|z1) and (x2|y2|z2) */
309 double phi,theta; /* Angles between (x1|y1|z1) and (x2|y2|z2) */
310 double dy; /* Distance between (x1|0|z1) and (x2|0|z2) */
311
312 /* ---- Get a pointer to ith atom ---- */
313 OBBond *bond = mol.GetBond(i);
314
315 /* ---- Assign start of bond i ---- */
316 x1 = (bond -> GetBeginAtom()) -> GetX();
317 y1 = (bond -> GetBeginAtom()) -> GetY();
318 z1 = (bond -> GetBeginAtom()) -> GetZ();
319
320 /* ---- Assign end of bond i ---- */
321 x2 = (bond -> GetEndAtom()) -> GetX();
322 y2 = (bond -> GetEndAtom()) -> GetY();
323 z2 = (bond -> GetEndAtom()) -> GetZ();
324
325 /* ---- Calculate length of bond and (x1|0|z1) - (x2|0|z2) ---- */
326 dist = sqrt(SQUARE(x2-x1) + SQUARE(y2-y1) + SQUARE(z2-z1));
327 dy = sqrt(SQUARE(x2-x1) + SQUARE(z2-z1));
328
329 /* ---- Calculate Phi and Theta ---- */
330 phi = (double) 0.0;
331 theta = (double) 0.0;
332 if (fabs(dist) >= EPSILON)
333 phi = acos((y2-y1)/dist);
334 if (fabs(dy) >= EPSILON)
335 theta = acos((x2-x1)/dy);
336
337 /* ---- Begin of description of bond i (for a capped sticks model) ---- */
338 ofs << "#declare " << prefix << "_bond" << i << " = object {" << endl;
339 ofs << "\t union {" << endl;
340
341 /* ---- Begin of Start-Half of Bond (i) ---- */
342 ofs << "\t object {" << endl << "\t bond_" << bond -> GetBondOrder() << "\n";
343
344 /* ---- Add a pigment - statement for start-atom of bond ---- */
345 ofs << "\t pigment{color Color_"
346 << bond -> GetBeginAtom() -> GetType()
347 << "}" << endl;
348
349 /* ---- Scale bond if needed ---- */
350 if (fabs((double) 2.0 * dist) >= EPSILON)
351 {
352
353 /* ---- Print povray scale-statement (x-Axis) ---- */
354 ofs << "\t scale <" << (double) 0.5 * dist << ",1.0000,1.0000>" << endl;
355
356 }
357
358 /* ---- Rotate (Phi) bond if needed ---- */
359 if (fabs(RAD2DEG(-phi) + (double) 90.0) >= EPSILON)
360 {
361
362 /* ---- Rotate along z-axis ---- */
363 ofs << "\t rotate <0.0000,0.0000,"
364 << RAD2DEG(-phi) + (double) 90.0
365 << ">" << endl;
366
367 }
368
369 /* ---- Check angle between (x1|0|z1) and (x2|0|z2) ---- */
370 if (theta >= EPSILON)
371 {
372
373 /* ---- Check direction ---- */
374 if ((z2 - z1) >= (double) 0.0)
375 {
376
377 /* ---- Rotate along y-Axis (negative) ---- */
378 ofs << "\t rotate <0.0000,"
379 << RAD2DEG((double) -1.0 *theta) << ",0.0000>"
380 << endl;
381
382 }
383 else
384 {
385
386 /* ---- Rotate along y-Axis (positive) ---- */
387 ofs << "\t rotate <0.0000," << RAD2DEG(theta) << ",0.0000>" << endl;
388
389 }
390
391 }
392
393 /* ---- Translate bond to start ---- */
394
395 ofs << "\t translate " << prefix << "_pos_" << bond -> GetBeginAtomIdx() << endl;
396
397 /* ---- End of description of Start-Bond ---- */
398 ofs << "\t }" << endl;
399
400 /* ---- Begin of End-Half of Bond i ---- */
401 ofs << "\t object {" << endl << "\t bond_" << bond -> GetBondOrder() << endl;
402
403 /* ---- Add a pigment - statement for end-atom of bond i ---- */
404 ofs << "\t pigment{color Color_"
405 << bond -> GetEndAtom() -> GetType()
406 << "}" << endl;
407
408 /* ---- Scale bond if needed ---- */
409 if (fabs((double) 2.0 * dist) >= EPSILON)
410 {
411
412 /* ---- Print povray scale-statement (x-Axis) ---- */
413 ofs << "\t scale <" << (double) 0.5 * dist << ",1.0000,1.0000>" << endl;
414
415 }
416
417 /* ---- Rotate (Phi) bond if needed ---- */
418 if (fabs(RAD2DEG(-phi) + (double) 270.0) >= EPSILON)
419 {
420
421 /* ---- Rotate along z-axis (oposite to start half) ---- */
422 ofs << "\t rotate <0.0000,0.0000,"
423 << (RAD2DEG(-phi) + (double) 90.0) + (double) 180.0
424 << ">" << endl;
425
426 }
427
428 /* ---- Check angle between (x1|0|z1) and (x2|0|z2) ---- */
429 if (fabs(theta) >= EPSILON)
430 {
431
432 /* ---- Check direction ---- */
433 if ((z2 - z1) >= (double) 0.0)
434 {
435
436 /* ---- Rotate along y-Axis (negative) (oposite orientation) ---- */
437 ofs << "\t rotate <0.0000,"
438 << RAD2DEG((double) -1.0 * theta)
439 << ",0.0000>"
440 << endl;
441
442 }
443 else
444 {
445
446 /* ---- Rotate along y-Axis (positive) (oposite orientation) ---- */
447 ofs << "\t rotate <0.0000," << RAD2DEG(theta) << ",0.0000>" << endl;
448
449 }
450
451 }
452
453 /* ---- Translate bond to end ---- */
454 ofs << "\t translate " << prefix << "_pos_" << bond -> GetEndAtomIdx() << endl;
455
456 /* ---- End of description of End-Bond ---- */
457 ofs << "\t }" << endl;
458
459 /* ---- End of description of bond i ---- */
460 ofs << "\t }" << endl << "\t }" << endl << endl;
461
462 }
463
464 }
465
466 void OutputUnions(ostream &ofs, OBMol &mol, string prefix)
467 {
468 /* ---- Build union of all atoms ---- */
469 ofs << endl << "//All atoms of molecule " << prefix << endl;
470 ofs << "#ifdef (TRANS)" << endl;
471 ofs << "#declare " << prefix << "_atoms = merge {" << endl;
472 ofs << "#else" << endl;
473 ofs << "#declare " << prefix << "_atoms = union {" << endl;
474 ofs << "#end //(End of TRANS)" << endl;
475
476 /* ---- Write definition of all atoms ---- */
477 for(unsigned int i = 1; i <= mol.NumAtoms(); ++i)
478 {
479
480 /* ---- Write definition of atom i ---- */
481 ofs << "\t object{" << prefix << "_atom" << i << "}" << endl;
482
483 }
484 ofs << "\t }" << endl << endl;
485
486 /* ---- Check for number of bonds ---- */
487 if(mol.NumBonds() > 0)
488 {
489
490 /* ---- Do a BAS or CST model ? ---- */
491 ofs << "//Bonds only needed for ball and sticks or capped sticks models" << endl;
492 ofs << "#if (BAS | CST)" << endl;
493 ofs << "#declare " << prefix <<"_bonds = union {" << endl;
494
495 /* ---- Description of all bonds ---- */
496 for(unsigned int i = 0; i < mol.NumBonds(); ++i)
497 {
498
499 /* ---- Write Definition of Bond i ---- */
500 ofs << "\t object{" << prefix << "_bond" << i << "}" << endl;
501
502 }
503
504 /* ---- End of povray-conditional for ball and sticks ---- */
505 ofs << "\t }" << endl << "#end" << endl << endl;
506
507 }
508
509 }
510
511 void OutputMoleculeBonds(ostream &ofs,
512 string prefix,
513 double min_x, double max_x,
514 double min_y, double max_y,
515 double min_z, double max_z
516 )
517 {
518 /* ---- Write a comment ---- */
519 ofs << endl << "//Definition of molecule " << prefix << endl;
520
521 /* ---- Check for space-fill model ---- */
522 ofs << "#if (SPF)" << endl;
523 ofs << "#declare " << prefix << " = object{"
524 << endl << "\t " << prefix << "_atoms" << endl;
525
526 /* ---- Here we do BAS oder CST models ---- */
527 ofs << "#else" << endl;
528 ofs << "#declare " << prefix << " = union {" << endl;
529
530 /* ---- Add all Atoms ---- */
531 ofs << "\t object{" << prefix << "_atoms}" << endl;
532
533 /* ---- Add difference between bonds and atoms ---- */
534 ofs << "#if (BAS | CST)//(Not really needed at moment!)" << endl;
535
536 /* ---- Use disjunct objects for transparent pics? ---- */
537 ofs << "#if (TRANS)" << endl;
538 ofs << "\t difference {" << endl;
539 ofs << "\t object{" << prefix << "_bonds}" << endl
540 << "\t object{" << prefix << "_atoms}" << endl
541 << "\t }" << endl;
542
543 /* ---- Do a solid model ? ---- */
544 ofs << "#else" << endl;
545 ofs << "\t object{" << prefix << "_bonds}" << endl;
546 ofs << "#end //(End of TRANS)" << endl;
547 ofs << "#end //(End of (BAS|CST))" << endl;
548
549 /* ---- End of CST or BAS model ---- */
550 ofs << "#end //(End of SPF)" << endl;
551
552 /* ---- Add comment (bounding box) ---- */
553 ofs << "//\t bounded_by {" << endl
554 << "//\t box {" << endl
555 << "//\t <"
556 << min_x - MAXRADIUS << ","
557 << min_y - MAXRADIUS << ","
558 << min_z - MAXRADIUS << ">" << endl;
559
560 ofs << "//\t <"
561 << max_x + MAXRADIUS << ","
562 << max_y + MAXRADIUS << ","
563 << max_z + MAXRADIUS << ">" << endl;
564
565 ofs << "\t }" << endl << endl;
566
567 }
568
569 void OutputMoleculeNoBonds(ostream &ofs, string prefix)
570 {
571 /* ---- Print description of molecule without bonds ---- */
572 ofs << endl << "//Definition of Molecule " << prefix << " (no bonds)" << endl;
573 ofs << "#declare " << prefix << " = object {" << prefix << "_atoms}" << endl << endl;
574
575 }
576
577 void OutputCenterComment(ostream &ofs,
578 string prefix,
579 double min_x, double max_x,
580 double min_y, double max_y,
581 double min_z, double max_z
582 )
583 {
584 /* ---- Print center comment (Warn: Vector is multiplied by -1.0)---- */
585 ofs << "//Center of molecule " << prefix << " (bounding box)" << endl;
586 ofs << "#declare " << prefix << "_center = <"
587 << (double) -1.0 * (min_x + max_x) / (double) 2.0 << ","
588 << (double) -1.0 * (min_y + max_y) / (double) 2.0 << ","
589 << (double) -1.0 * (min_z + max_z) / (double) 2.0 << ">" << endl << endl;
590 }
591
592 ////////////////////////////////////////////////////////////////
593
594 bool PovrayFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
595 {
596 OBMol* pmol = dynamic_cast<OBMol*>(pOb);
597 if(pmol==NULL)
598 return false;
599
600 //Define some references so we can use the old parameter names
601 ostream &ofs = *pConv->GetOutStream();
602 OBMol &mol = *pmol;
603 const char* title = pmol->GetTitle();
604
605 static long num = 0;
606 double min_x, max_x, min_y, max_y, min_z, max_z; /* Edges of bounding box */
607 string prefix;
608
609 /* ---- We use the molecule-title as our prefix ---- */
610 if(title != (const char*) NULL)
611 prefix = MakePrefix(title);
612 else if (mol.GetTitle() != (const char *) NULL)
613 prefix = MakePrefix(mol.GetTitle());
614 else
615 prefix = MakePrefix("Unknown");
616
617 /* ---- Check if we have already written a molecule to this file ---- */
618 if (num == 0)
619 {
620
621 /* ---- Print the header ---- */
622 OutputHeader(ofs, mol, prefix);
623
624 }
625 else
626 {
627
628 /* ---- Convert the unique molecule-number to a string and set the prefix ---- */
629 #if defined(HAVE_SSTREAM)
630 ostringstream numStr;
631 numStr << num << ends;
632 prefix += numStr.str().c_str();
633 #else
634
635 ostrstream numStr;
636 numStr << num << ends;
637 prefix += numStr.str();
638 #endif
639
640 }
641
642 /* ---- Print positions and descriptions of all atoms ---- */
643 OutputAtoms(ofs, mol, prefix);
644
645 /* ---- Check #bonds ---- */
646 if (mol.NumBonds() > 0)
647 {
648
649 /* ---- Write an comment ---- */
650 ofs << "//Povray-description of bonds 1 - " << mol.NumBonds() << endl;
651
652 /* ---- Do a ball and sticks model? ---- */
653 ofs << "#if (BAS)" << endl;
654
655 /* ---- Print bonds using "ball and sticks style" ---- */
656 OutputBASBonds(ofs, mol, prefix);
657
658 /* ---- End of povray-conditional for ball and sticks ---- */
659 ofs << "#end //(BAS-Bonds)" << endl << endl;
660
661 /* ---- Do a capped-sticks model? ---- */
662 ofs << "#if (CST)" << endl;
663
664 /* ---- Print bonds using "capped sticks style" ---- */
665 OutputCSTBonds(ofs, mol, prefix);
666
667 /* ---- End of povray-conditional for capped sticks ---- */
668 ofs << "#end // (CST-Bonds)" << endl << endl;
669
670 }
671
672 /* ---- Print out unions of atoms and bonds ---- */
673 OutputUnions(ofs, mol, prefix);
674
675 /* ---- Calculate bounding-box ---- */
676 CalcBoundingBox(mol, min_x, max_x, min_y, max_y, min_z, max_z);
677
678 /* ---- Check #bonds ---- */
679 if (mol.NumBonds() > 0)
680 {
681
682 /* ---- Print out description of molecule ---- */
683 OutputMoleculeBonds(ofs,
684 prefix,
685 min_x, max_x,
686 min_y, max_y,
687 min_z, max_z);
688
689 }
690 else
691 {
692
693 /* ---- Now we can define the molecule without bonds ---- */
694 OutputMoleculeNoBonds(ofs, prefix);
695
696 }
697
698 /* ---- Insert declaration for centering the molecule ---- */
699 OutputCenterComment(ofs,
700 prefix,
701 min_x, max_x,
702 min_y, max_y,
703 min_z, max_z);
704
705 /* ---- Increment the static molecule output-counter ---- */
706 num++;
707
708 /* ---- Everything is ok! ---- */
709 return(true);
710 }
711
712 } //namespace OpenBabel