1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_STRUCTURE_SOLVENTEXCLUDEDSURFACE_H
6 #define BALL_STRUCTURE_SOLVENTEXCLUDEDSURFACE_H
7 
8 #ifndef BALL_STRUCTURE_SESEDGE_H
9 #	include <BALL/STRUCTURE/SESEdge.h>
10 #endif
11 
12 #ifndef BALL_STRUCTURE_SESFACE_H
13 #	include <BALL/STRUCTURE/SESFace.h>
14 #endif
15 
16 #ifndef BALL_STRUCTURE_SESVERTEX_H
17 #	include <BALL/STRUCTURE/SESVertex.h>
18 #endif
19 
20 #ifndef BALL_STRUCTURE_REDUCEDSURFACE_H
21 #	include <BALL/STRUCTURE/reducedSurface.h>
22 #endif
23 
24 #ifndef BALL_MATHS_ANGLE_H
25 #	include <BALL/MATHS/angle.h>
26 #endif
27 
28 #ifndef BALL_MATHS_CIRCLE3_H
29 #	include <BALL/MATHS/circle3.h>
30 #endif
31 
32 #ifndef BALL_MATHS_SPHERE3_H
33 #	include <BALL/MATHS/sphere3.h>
34 #endif
35 
36 #ifndef BALL_MATHS_VECTOR3_H
37 #	include <BALL/MATHS/vector3.h>
38 #endif
39 
40 #ifndef BALL_MATHS_VECTOR4_H
41 #	include <BALL/MATHS/vector4.h>
42 #endif
43 
44 #ifndef BALL_DATATYPE_HASHGRID_H
45 #	include <BALL/DATATYPE/hashGrid.h>
46 #endif
47 
48 #ifndef BALL_DATATYPE_HASHMAP_H
49 #	include <BALL/DATATYPE/hashMap.h>
50 #endif
51 
52 #include <vector>
53 #include <list>
54 
55 
56 namespace BALL
57 {
58 	class SESComputer;
59 	class SESSingularityCleaner;
60 	class TriangulatedSES;
61 	class SESTriangulator;
62 
63 	/** Generic SolventExcludedSurface Class.
64 	\ingroup Surface
65 	*/
66 	class BALL_EXPORT SolventExcludedSurface
67 	{
68 		public:
69 
70 		/** @name Class friends
71 
72 					- class SESComputer
73 					- class SESSingularityCleaner
74 					- class TriangulatedSES
75 					- class SESTriangulator
76 
77 		*/
78 		friend class SESComputer;
79 		friend class SESSingularityCleaner;
80 		friend class TriangulatedSES;
81 		friend class SESTriangulator;
82 
83 		BALL_CREATE(SolventExcludedSurface)
84 
85   	/**	@name	Type definitions
86 		*/
87 		//@{
88 
89 		typedef std::vector<SESVertex*>::iterator
90 						VertexIterator;
91 		typedef std::vector<SESVertex*>::const_iterator
92 						ConstVertexIterator;
93 		typedef std::vector<SESEdge*>::iterator
94 						EdgeIterator;
95 		typedef std::vector<SESEdge*>::const_iterator
96 						ConstEdgeIterator;
97 		typedef std::list<SESEdge*>::iterator
98 						SingularEdgeIterator;
99 		typedef std::list<SESEdge*>::const_iterator
100 						ConstSingularEdgeIterator;
101 		typedef std::vector<SESFace*>::iterator
102 						ContactFaceIterator;
103 		typedef std::vector<SESFace*>::const_iterator
104 						ConstContactFaceIterator;
105 		typedef std::vector<SESFace*>::iterator
106 						SphericFaceIterator;
107 		typedef std::vector<SESFace*>::const_iterator
108 						ConstSphericFaceIterator;
109 		typedef std::vector<SESFace*>::iterator
110 						ToricFaceIterator;
111 		typedef std::vector<SESFace*>::const_iterator
112 						ConstToricFaceIterator;
113 
114 		//@}
115 		/**	@name	Constructors and Destructors
116 		*/
117 		//@{
118 
119 		/**	Default constructor.
120 				This method creates a new SolventExcludedSurface object.
121 		*/
122 		SolventExcludedSurface();
123 
124 		/**	Copy constructor.
125 				Create a new SolventExcludedSurface object from another.
126 				@param	ses		the SolventExcludedSurface object to be copied
127 				@param	bool	ignored - just for interface consistency
128 		*/
129 		SolventExcludedSurface
130 				(const SolventExcludedSurface& ses, bool = false);
131 
132 		/** Detailed constructor
133 		*/
134 		SolventExcludedSurface(ReducedSurface* reduced_surface);
135 
136 		/**	Destructor.
137 				As there are no dynamic	data structures, nothing happens.
138 		*/
139 		virtual ~SolventExcludedSurface()
140 			;
141 
142 		//@}
143 		/**	@name	Accessors
144 		*/
145 		//@{
146 
147 		void clear();
148 
149 		void clean(const double& density);
150 
151 		/**	Computes the solvent excluded surface from a ReducedSurface object
152 		*/
153 		void compute()
154 			throw(Exception::GeneralException);
155 
156 		void splitSphericFaces()
157 			;
158 
159 		bool check()
160 			;
161 
162 		//@}
163 		/**	@name	External Iterators
164 		*/
165 		//@{
166 
167 		VertexIterator beginVertex()
168 			;
169 		ConstVertexIterator beginVertex() const
170 			;
171 		VertexIterator endVertex()
172 			;
173 		ConstVertexIterator endVertex() const
174 			;
175 
176 		EdgeIterator beginEdge()
177 			;
178 		ConstEdgeIterator beginEdge() const
179 			;
180 		EdgeIterator endEdge()
181 			;
182 		ConstEdgeIterator endEdge() const
183 			;
184 
185 		SingularEdgeIterator beginSingularEdge()
186 			;
187 		ConstSingularEdgeIterator beginSingularEdge() const
188 			;
189 		SingularEdgeIterator endSingularEdge()
190 			;
191 		ConstSingularEdgeIterator endSingularEdge() const
192 			;
193 
194 		ContactFaceIterator beginContactFace()
195 			;
196 		ConstContactFaceIterator beginContactFace() const
197 			;
198 		ContactFaceIterator endContactFace()
199 			;
200 		ConstContactFaceIterator endContactFace() const
201 			;
202 
203 		SphericFaceIterator beginSphericFace()
204 			;
205 		ConstSphericFaceIterator beginSphericFace() const
206 			;
207 		SphericFaceIterator endSphericFace()
208 			;
209 		ConstSphericFaceIterator endSphericFace() const
210 			;
211 
212 		ToricFaceIterator beginToricFace()
213 			;
214 		ConstToricFaceIterator beginToricFace() const
215 			;
216 		ToricFaceIterator endToricFace()
217 			;
218 		ConstToricFaceIterator endToricFace() const
219 			;
220 
221 		//@}
222 
223 		private:
224 
225 		void splitSphericFace(Position i)
226 			;
227 
228 		void deleteSmallToricFace(SESFace* face)
229 			;
230 
231 		void deleteSmallSingularToricFace(SESFace* face)
232 			;
233 
234 		bool cleanToricFace(SESFace* face, const double& sqrt_density)
235 			;
236 
237 		bool cleanSingularToricFace(SESFace* face, const double& sqrt_density)
238 			;
239 
240 		void cleanVertices()
241 			;
242 
243 		void cleanEdges()
244 			;
245 
246 		void cleanContactFaces()
247 			;
248 
249 		void cleanToricFaces()
250 			;
251 
252 		void cleanSphericFaces()
253 			;
254 
255 
256 		protected:
257 
258     /*_ the number of vertices of the solvent exluded surface
259     */
260 		Position number_of_vertices_;
261     /*_ the vertices of the solvent exluded surface
262     */
263 		::std::vector<SESVertex*> vertices_;
264     /*_ the number of edges of the solvent exluded surface
265     */
266 		Position number_of_edges_;
267     /*_ the edges of the solvent exluded surface
268     */
269 		::std::vector<SESEdge*> edges_;
270     /*_ the number of singular edges of the solvent exluded surface
271     */
272 		Position number_of_singular_edges_;
273     /*_ the singular edges of the solvent exluded surface
274     */
275 		::std::list<SESEdge*> singular_edges_;
276     /*_ the number of contact faces of the solvent exluded surface
277     */
278 		Position number_of_contact_faces_;
279     /*_ the contact faces of the solvent exluded surface
280     */
281 		::std::vector<SESFace*> contact_faces_;
282     /*_ the number of toric reentrant faces of the solvent exluded surface
283     */
284 		Position number_of_toric_faces_;
285     /*_ the toric reentrant faces of the solvent exluded surface
286     */
287 		::std::vector<SESFace*> toric_faces_;
288     /*_ the number of spheric reentrant faces of the solvent exluded surface
289     */
290 		Position number_of_spheric_faces_;
291     /*_ the spheric reentrant faces of the solvent exluded surface
292     */
293 		::std::vector<SESFace*> spheric_faces_;
294 		/*_ the corresponding reduced surface
295 		*/
296 		ReducedSurface* reduced_surface_;
297 
298 	};
299 
300 
301 	/**	@name	Storers
302 	*/
303 	//@{
304 
305 	/**	Output- Operator
306 	*/
307 	BALL_EXPORT std::ostream& operator <<
308 			(std::ostream& s, const SolventExcludedSurface& ses);
309 
310 	//@}
311 
312 
313 
314 	/** Generic SESComputer Class.
315 	\ingroup Surface
316 	*/
317 	class BALL_EXPORT SESComputer
318 	{
319 		public:
320 
321 		BALL_CREATE(SESComputer)
322 
323 		/**	@name	Constructors and Destructors
324 		*/
325 		//@{
326 
327 		/**	Default constructor.
328 				This method creates a new SESComputer object.
329 		*/
330 		SESComputer()
331 			;
332 
333 		/** Detailed constructor
334 		*/
335 		SESComputer(SolventExcludedSurface* ses)
336 			;
337 
338 		/**	Destructor.
339 				As there are no dynamic	data structures, nothing happens.
340 		*/
341 		virtual ~SESComputer()
342 			;
343 
344 		//@}
345 		/**	@name	Accessors
346 		*/
347 		//@{
348 
349 		/**	Computes the solvent excluded surface
350 		*/
351 		void run()
352 			throw(Exception::GeneralException);
353 
354 		//@}
355 
356 		private:
357 
358 		/*_	@name	SES computation (private)
359 		*/
360 		//@{
361 
362 		void preProcessing()
363 			;
364 
365 		void get()
366 			;
367 
368 		void createSphericFace(Position j)
369 			;
370 
371 		SESVertex* createVertex
372 			(const TVector3<double>& probe_center,
373 			 Index index)
374 			;
375 
376 		void pushVertex
377 			(SESFace* face,
378 			 const TSphere3<double>& probe,
379 			 RSVertex* rsvertex)
380 			;
381 
382 		SESEdge* createConcaveEdge
383 			(SESFace* spheric_face,
384 			 Position p1,
385 			 Position p2,
386 			 Index index,
387 			 const double& radius_of_probe)
388 			;
389 
390 		void pushConcaveEdge
391 			(SESFace* face,
392 			 Position p1,
393 			 Position p2,
394 			 const double& radius_of_probe)
395 			;
396 
397 		SESEdge* createConvexEdge
398 			(SESFace* toric_face,
399 			 RSVertex* rsvertex)
400 			;
401 
402 		void createToricFace(Position i)
403 			;
404 
405 		void treatSingularToricFace(Position i)
406 			;
407 
408 		void createFreeToricFace(Position i)
409 			;
410 
411 		SESVertex* createSingularVertex
412 				(Position ip,
413 				 const TVector3<double>& dir,
414 				 SESFace* face0,
415 				 SESFace* face1,
416 				 SESFace* face2,
417 				 SESEdge* edge0,
418 				 SESEdge* edge1,
419 				 SESEdge* edge2)
420 			;
421 
422 		void updateEdge
423 				(SESEdge*		edge,
424 				 SESVertex*	vertex1,
425 				 SESVertex*	vertex2,
426 				 bool						is_new)
427 			;
428 
429 		void getPoint
430 			(const TVector3<double>& p1,
431 			 const TVector3<double>& p2,
432 			 const double&						dist,
433 			 TVector3<double>&				result);
434 
435 		Index vertexExists(const TVector3<double>& point);
436 
437 		//@}
438 
439 
440 		protected:
441 
442 		/*_ a pointer to the solvent excluded surface to compute
443 		*/
444 		SolventExcludedSurface* ses_;
445 		/*_ a HashGrid to store and find the vertices in an efficient way
446 		*/
447 		HashGrid3<Index> vertex_grid_;
448 	};
449 
450 
451 
452 
453 	/** Generic SESComputer Class.
454 	\ingroup Surface
455 	*/
456 	class BALL_EXPORT SESSingularityCleaner
457 	{
458 		public:
459 
460 		BALL_CREATE(SESSingularityCleaner)
461 
462 		typedef std::pair< std::pair<TAngle<double>,Index>,TVector3<double> > Intersection;
463 
464 		struct ProbeIntersection
465 		{
466 			TVector3<double> point[2];
467 		};
468 
469 		friend class SESComputer;
470 
471 		/**	@name	Constructors and Destructors
472 		*/
473 		//@{
474 
475 		/**	Default constructor.
476 				This method creates a new SESComputer object.
477 		*/
478 		SESSingularityCleaner()
479 			;
480 
481 		/** Detailed constructor
482 		*/
483 		SESSingularityCleaner
484 				(SolventExcludedSurface*	ses,
485 				 HashGrid3<Index>*				vertex_grid_)
486 			;
487 
488 		/**	Destructor.
489 				As there are no dynamic	data structures, nothing happens.
490 		*/
491 		virtual ~SESSingularityCleaner()
492 			;
493 
494 		//@}
495 		/**	@name	Accessors
496 		*/
497 		//@{
498 
499 		/**	Solves the singularities
500 		*/
501 		bool run()
502 			throw(Exception::GeneralException);
503 
504 		//@}
505 
506 		private:
507 
508 		/**	@name	Treatment of singularities (private)
509 		*/
510 		//@{
511 
512 		Index vertexExists(TVector3<double> point)
513 			;
514 
515 		void treatSingularities()
516 			;
517 
518 		void getSingularFaces(std::list<SESFace*>& faces)
519 			;
520 
521 		bool treatFirstCategory()
522 			;
523 
524 		void treatSecondCategory()
525 			;
526 
527 		void getFirstCategoryFaces(std::list<SESFace*>& first_category_faces)
528 			;
529 
530 		void noCut(SESFace* face1, SESFace* face2)
531 			;
532 
533 		void twoCuts(SESFace* face1, SESFace* face2)
534 			;
535 
536 		void treatSingularEdge
537 			(SESEdge*								edge,
538 			 HashGrid3<Position>&		grid,
539 			 ::std::list<SESEdge*>&	deletable_edges)
540 			;
541 
542 		void getIntersectionsOfSingularEdge
543 			(SESEdge*									edge,
544 			 const TAngle<double>&							phi,
545 			 HashGrid3<Position>&			grid,
546 			 std::list<Intersection>& intersections)
547 			;
548 
549 		bool getIntersectionPointsAndAngles
550 			(const TCircle3<double>&	circle,
551 			 const TVector3<double>&	point,
552 			 Position				index1,
553 			 Position				index2,
554 			 Position				probe_index,
555 			 TAngle<double>&					phi1,
556 			 TVector3<double>&				point1,
557 			 TAngle<double>&					phi2,
558 			 TVector3<double>&				point2)
559 			;
560 
561 		bool isIntersection
562 			 (const TAngle<double>&	 min_phi,
563 				const TAngle<double>&	 max_phi,
564 				const TAngle<double>&	 phi,
565 				const TVector3<double>& middle,
566 				const TSphere3<double>& probe)
567 			;
568 
569 		void buildEndEdges
570 			(SESEdge*												edge,
571 			 const std::list<Intersection>&	min,
572 			 const std::list<Intersection>&	max,
573 			 SESVertex*&										vertex1,
574 			 SESVertex*&										vertex2,
575 			 Index&													actual_min,
576 			 Index&													actual_max)
577 			;
578 
579 		void buildEdge
580 			(SESEdge*								edge,
581 			 Index									face1,
582 			 Index&									face2,
583 			 Index									end,
584 			 SESVertex*&						vertex,
585 			 const HashSet<Index>&	indices,
586 			 bool										minimum);
587 
588 		void getExtrema
589 				(const std::list<Intersection>& intersections,
590 				 std::list<Intersection>& min,
591 				 std::list<Intersection>& max);
592 
593 		void buildEndEdge
594 			(SESEdge*												edge,
595 			 const std::list<Intersection>&	extrema,
596 			 SESVertex*&										vertex,
597 			 Index&													actual_extremum,
598 			 bool														min);
599 
600 		bool probeIntersection
601 			 (Index		 face1,
602 				Index		 face2,
603 				Index		 face3,
604 				TVector3<double>& point1,
605 				TVector3<double>& point2);
606 
607 		void sort
608 				(SESFace* face1,
609 				 SESFace* face2,
610 				 std::vector<SESEdge*>& sesedge1,
611 				 std::vector<SESEdge*>& sesedge2,
612 				 std::vector<SESVertex*>& sesvertex1,
613 				 std::vector<SESVertex*>& sesvertex2);
614 
615 		void sort
616 			 (Index		u1, Index		u2, Index		u3,
617 				Index&	s1,	Index&	s2, Index&	s3);
618 
619 		//@}
620 
621 
622 		protected:
623 
624 		/*_ a pointer to the solvent excluded surface to compute
625 		*/
626 		SolventExcludedSurface* ses_;
627 		/*_ a pointer to a HashGrid to store and find the vertices
628 				in an efficient way
629 		*/
630 		HashGrid3<Index>* vertex_grid_;
631 		/*_ for each triple of probe spheres its intersections
632 		*/
633 		HashMap< Position,
634 						 HashMap< Position,
635 											HashMap< Position,
636 															 ProbeIntersection*
637 														 >
638 										>
639 					 > probe_intersections_;
640 
641 	};
642 
643 
644 } // namespace BALL
645 
646 #endif  // BALL_STRUCTURE_SOLVENTEXCLUDEDSURFACE_H
647