00001
00002
00003
00004
00005 #ifndef BALL_STRUCTURE_REDUCEDSURFACE_H
00006 #define BALL_STRUCTURE_REDUCEDSURFACE_H
00007
00008 #ifndef BALL_MATHC_COMMON_H
00009 # include <BALL/MATHS/common.h>
00010 #endif
00011
00012 #ifndef BALL_MATHS_SIMPLEBOX3_H
00013 # include <BALL/MATHS/simpleBox3.h>
00014 #endif
00015
00016 #ifndef BALL_MATHS_CIRCLE3_H
00017 # include <BALL/MATHS/circle3.h>
00018 #endif
00019
00020 #ifndef BALL_MATHS_SPHERE_H
00021 # include <BALL/MATHS/sphere3.h>
00022 #endif
00023
00024 #ifndef BALL_MATHS_VECTOR3_H
00025 # include <BALL/MATHS/vector3.h>
00026 #endif
00027
00028 #ifndef BALL_DATATYPE_HASHSET_H
00029 # include <BALL/DATATYPE/hashMap.h>
00030 #endif
00031
00032 #ifndef BALL_DATATYPE_HASHSET_H
00033 # include <BALL/DATATYPE/hashSet.h>
00034 #endif
00035
00036 #ifndef BALL_COMMON_EXCEPTION_H
00037 # include <BALL/COMMON/exception.h>
00038 #endif
00039
00040 #ifndef BALL_STRUCTURE_RSEDGE_H
00041 # include <BALL/STRUCTURE/RSEdge.h>
00042 #endif
00043
00044 #ifndef BALL_STRUCTURE_RSFACE_H
00045 # include <BALL/STRUCTURE/RSFace.h>
00046 #endif
00047
00048 #ifndef BALL_STRUCTURE_RSVERTEX_H
00049 # include <BALL/STRUCTURE/RSVertex.h>
00050 #endif
00051
00052 #include <set>
00053 #include <list>
00054 #include <deque>
00055 #include <vector>
00056
00057 namespace BALL
00058 {
00059 struct SortedPosition2
00060 {
00061 SortedPosition2(Position a1, Position a2)
00062 : a(a1), b(a2)
00063 {
00064 if (a > b) std::swap(a, b);
00065 }
00066
00067 bool operator==(const SortedPosition2& pos) const
00068 {
00069 return (a == pos.a) && (b == pos.b);
00070 }
00071
00072 Position a;
00073 Position b;
00074 };
00075
00076 struct SortedPosition3
00077 {
00078 SortedPosition3(Position a1, Position a2, Position a3)
00079 : a(a1), b(a2), c(a3)
00080 {
00081 if (a > b) std::swap(a, b);
00082 if (a > c) std::swap(a, c);
00083 if (b > c) std::swap(b, c);
00084 }
00085
00086 bool operator==(const SortedPosition3& pos) const
00087 {
00088 return (a == pos.a) && (b == pos.b) && (c == pos.c);
00089 }
00090
00091 Position a;
00092 Position b;
00093 Position c;
00094 };
00095 }
00096
00097 #ifdef BALL_HAS_BOOST_UNORDERED_MAP
00098 namespace boost
00099 {
00100 #endif
00101
00102 #ifdef BALL_EXTEND_HASH_IN_STD_NS
00103 namespace std
00104 {
00105 #endif // BALL_EXTEND_HASH_IN_STD_NS
00106
00107 #ifdef BALL_HAS_TR1_UNORDERED_MAP
00108 namespace tr1
00109 {
00110 #endif // BALL_HAS_TR1_UNORDERED_MAP
00111 template<>
00112 struct hash<BALL::SortedPosition2> : public std::unary_function<BALL::SortedPosition2, size_t>
00113 {
00114 inline size_t operator()(const BALL::SortedPosition2& p) const
00115 {
00116 return 5323 * p.a + 1847 * p.b;
00117 }
00118 };
00119
00120 template<>
00121 struct hash<BALL::SortedPosition3> : public std::unary_function<BALL::SortedPosition3, size_t>
00122 {
00123 inline size_t operator()(const BALL::SortedPosition3& p) const
00124 {
00125 return 5323 * p.a + 1847 * p.b + 2347 * p.c;
00126 }
00127 };
00128 #ifdef BALL_HAS_TR1_UNORDERED_MAP
00129 }
00130 #endif // BALL_HAS_TR1_UNORDERED_MAP
00131
00132 #ifdef BALL_EXTEND_HASH_IN_STD_NS
00133 }
00134 #endif // BALL_EXTEND_HASH_IN_STD_NS
00135
00136 #ifdef BALL_HAS_BOOST_UNORDERED_MAP
00137 }
00138 #endif
00139
00140 namespace BALL
00141 {
00142 class RSComputer;
00143 class SolventExcludedSurface;
00144 class SESComputer;
00145 class SESSingularityCleaner;
00146 class TriangulatedSES;
00147 class SolventAccessibleSurface;
00148 class TriangulatedSAS;
00149 class SESTriangulator;
00150
00154 class BALL_EXPORT ReducedSurface
00155 {
00156 public:
00157
00170 friend class RSComputer;
00171 friend class SolventExcludedSurface;
00172 friend class SESComputer;
00173 friend class SESSingularityCleaner;
00174 friend class SolventAccessibleSurface;
00175 friend class TriangulatedSES;
00176 friend class TriangulatedSAS;
00177 friend class SESTriangulator;
00178
00179 BALL_CREATE(ReducedSurface)
00180
00181
00184
00189 ReducedSurface();
00190
00195 ReducedSurface(const ReducedSurface& reduced_surface, bool = true);
00196
00200 ReducedSurface(const std::vector< TSphere3<double> >& spheres,
00201 const double& probe_radius);
00202
00205 virtual ~ReducedSurface();
00206
00208
00211
00215 void operator = (const ReducedSurface& reduced_surface);
00216
00220 void set(const ReducedSurface& reduced_surface);
00221
00224 void clear();
00225
00228 void clean();
00229
00231
00234
00238 Size numberOfAtoms() const;
00239
00243 Size numberOfVertices() const;
00244
00248 Size numberOfEdges() const;
00249
00253 Size numberOfFaces() const;
00254
00258 double getProbeRadius() const;
00259
00264 TSphere3<double> getSphere(Position i) const
00265 throw(Exception::IndexOverflow);
00266
00271 RSVertex* getVertex(Position i) const
00272 throw(Exception::IndexOverflow);
00273
00278 RSEdge* getEdge(Position i) const
00279 throw(Exception::IndexOverflow);
00280
00285 RSFace* getFace(Position i) const
00286 throw(Exception::IndexOverflow);
00287
00291 void insert(RSVertex* rsvertex);
00292
00296 void insert(RSEdge* rsedge);
00297
00301 void insert(RSFace* rsface);
00302
00306 double getMaximalRadius() const;
00307
00311 TSimpleBox3<double> getBoundingBox() const;
00312
00317 void deleteSimilarFaces(RSFace* face1, RSFace* face2);
00318
00327 bool getAngle(RSFace* face1, RSFace* face2,
00328 RSVertex* vertex1, RSVertex* vertex2,
00329 TAngle<double>& angle, bool check = false) const;
00330
00333 void compute()
00334 throw(Exception::GeneralException,
00335 Exception::DivisionByZero,
00336 Exception::IndexOverflow);
00337
00339
00340 private:
00341
00342
00343
00344 bool canBeCopied(const ReducedSurface& reduced_surface);
00345
00346
00347
00348 void copy(const ReducedSurface& reduced_surface);
00349
00350
00351
00352 void correctEdges(RSFace* face1, RSFace* face2,
00353 RSEdge* edge1, RSEdge* edge2);
00354
00355
00356
00357 void joinVertices(RSFace* face1, RSFace* face2,
00358 RSVertex* vertex1, RSVertex* vertex2);
00359
00360
00361
00362 void findSimilarVertices(RSFace* face1, RSFace* face2,
00363 std::vector<RSVertex*>& rsvertex1,
00364 std::vector<RSVertex*>& rsvertex2);
00365
00366
00367
00368 void findSimilarEdges(RSFace* face1, RSFace* face2,
00369 std::vector<RSEdge*>& rsedge1,
00370 std::vector<RSEdge*>& rsedge2);
00371
00372 protected:
00373
00374
00375
00376 Size number_of_atoms_;
00377
00378
00379
00380
00381 std::vector< TSphere3<double> > atom_;
00382
00383
00384
00385 double probe_radius_;
00386
00387
00388
00389 Size number_of_vertices_;
00390
00391
00392
00393 std::vector< RSVertex* > vertices_;
00394
00395
00396
00397 Size number_of_edges_;
00398
00399
00400
00401 std::vector< RSEdge* > edges_;
00402
00403
00404
00405 Size number_of_faces_;
00406
00407
00408
00409 std::vector< RSFace* > faces_;
00410
00411
00412
00413 double r_max_;
00414
00415
00416
00417 TSimpleBox3<double> bounding_box_;
00418 };
00419
00423
00427 BALL_EXPORT std::ostream& operator << (std::ostream& s, const ReducedSurface& rs);
00428
00430
00434 class BALL_EXPORT RSComputer
00435 {
00436 public:
00437
00438 BALL_CREATE(RSComputer)
00439
00440
00443
00449 enum ProbeStatus
00450 {
00451 STATUS_OK = 0,
00452 STATUS_NOT_OK,
00453 STATUS_NOT_TESTED
00454 };
00455
00461 enum AtomStatus
00462 {
00463 STATUS_ON_SURFACE = 0,
00464 STATUS_INSIDE,
00465 STATUS_UNKNOWN
00466 };
00468
00469 struct ProbePosition
00470 {
00471 ProbeStatus status[2];
00472 TVector3<double> point[2];
00473 };
00474
00478
00483 RSComputer();
00484
00487 RSComputer(ReducedSurface* rs);
00488
00491 virtual ~RSComputer();
00492
00494
00497
00500 void run()
00501 throw(Exception::GeneralException,
00502 Exception::DivisionByZero,
00503 Exception::IndexOverflow);
00504
00506
00507
00508 private:
00509
00510
00511
00513
00514
00515
00516 void preProcessing();
00517
00518
00519
00520 void getRSComponent()
00521 throw(Exception::GeneralException,
00522 Exception::DivisionByZero,
00523 Exception::IndexOverflow);
00524
00525
00526
00527
00528 bool treatFace(RSFace* face)
00529 throw(Exception::GeneralException,
00530 Exception::DivisionByZero,
00531 Exception::IndexOverflow);
00532
00533
00534
00535
00536 bool treatEdge(RSEdge* edge)
00537 throw(Exception::GeneralException,
00538 Exception::DivisionByZero,
00539 Exception::IndexOverflow);
00540
00541
00542
00543
00544
00545
00546 void correct(Index atom);
00547
00548
00549
00550 void extendComponent()
00551 throw(Exception::GeneralException,
00552 Exception::DivisionByZero,
00553 Exception::IndexOverflow);
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 Index thirdAtom(RSVertex* vertex1, RSVertex* vertex2,
00570 RSFace* face, TSphere3<double>& probe, TAngle<double>& phi)
00571 throw(Exception::GeneralException,
00572 Exception::DivisionByZero,
00573 Exception::IndexOverflow);
00574
00576
00577
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 Position getStartPosition()
00592 throw(Exception::DivisionByZero);
00593
00595
00596
00598
00599
00600
00601
00602
00603 RSFace* findFirstFace()
00604 throw(Exception::DivisionByZero);
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 RSFace* findFace(Position direction, Position extrem)
00616 throw(Exception::DivisionByZero);
00617
00619
00620
00622
00623
00624
00625
00626
00627 RSEdge* findFirstEdge();
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 RSEdge* findEdge(Position direction, Position extrem);
00639
00641
00642
00644
00645
00646
00647
00648
00649 RSVertex* findFirstVertex();
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 Index findFirstAtom(Position direction, Position extrem);
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 Index findSecondAtom(Index atom, Position direction, Position extrem);
00671
00672
00673
00674
00675
00676
00677
00678
00679 void findThirdAtom(Index atom1, Index atom2, const std::deque<Index>& third,
00680 std::deque< std::pair< Index,TSphere3<double> > >& atoms);
00681
00683
00684
00686
00687
00688
00689
00690
00691
00692
00693
00694 const std::deque<Index>& neighboursOfTwoAtoms(const SortedPosition2& pos);
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 void neighboursOfThreeAtoms(Index atom1, Index atom2, Index atom3,
00705 std::deque<Index>& output_list);
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 double getCircleExtremum(const TCircle3<double>& circle,
00717 Position direction, Position extrem);
00718
00720
00721
00723
00724
00725
00726
00727
00728
00729
00730 RSEdge* createFreeEdge(RSVertex* vertex1, RSVertex* vertex2);
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 bool getCircles(Index atom1, Index atom2, TCircle3<double>& circle1,
00744 TCircle3<double>& circle2, TCircle3<double>& circle3);
00745
00746
00747
00748
00749
00750
00751
00752
00753 TVector3<double> getFaceNormal(const TSphere3<double>& atom1, const TSphere3<double>& atom2,
00754 const TSphere3<double>& atom3, const TSphere3<double>& probe);
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 void updateFaceAndEdges(RSVertex* v1, RSVertex* v2, RSVertex* v3,
00767 RSEdge* e1, RSEdge* e2, RSEdge* e3,
00768 RSFace* f, const TSphere3<double>& probe);
00769
00770
00771
00772
00773
00774 RSFace* faceExists(RSFace* face, const std::list< RSVertex* >& vertices);
00775
00777
00778
00780
00781
00782
00783
00784
00785
00786
00787
00788 bool centerOfProbe(const SortedPosition3& pos, TVector3<double>& c1, TVector3<double>& c2);
00789
00790
00791
00792
00793
00794
00795 bool checkProbe(const TSphere3<double>& probe, const SortedPosition3& pos);
00796
00797
00798
00799 void correctProbePosition(Position atom);
00800
00801
00802
00803 void correctProbePosition(const SortedPosition3& pos);
00804
00805
00806
00807 void insert(RSVertex* vertex);
00808
00809
00810
00811 void insert(RSEdge* edge);
00812
00813
00814
00815 void insert(RSFace* face);
00816
00818
00819 protected:
00820
00821
00822
00823
00824 ReducedSurface* rs_;
00825
00826
00827
00828 std::vector< std::deque<Index> > neighbours_;
00829
00830
00831
00832 std::vector< AtomStatus > atom_status_;
00833
00834
00835
00836 HashMap< SortedPosition2, std::deque<Index> > neighbours_of_two_;
00837
00838
00839
00840 HashMap< SortedPosition3, ProbePosition* > probe_positions_;
00841
00842
00843
00844 HashSet<RSVertex*> new_vertices_;
00845
00846
00847
00848 HashSet<RSFace*> new_faces_;
00849
00850
00851
00852 std::vector< std::list<RSVertex*> > vertices_;
00853 };
00854 }
00855
00856 #endif // BALL_STRUCTURE_REDUCEDSURFACE_H