Branch data Line data Source code
1 : : //-------------------------------------------------------------------------
2 : : // Filename : PST_Data.hpp
3 : : //
4 : : // Purpose : Classes for representing geometry facets. Used by
5 : : // PartSurfTess to find the graphis faceting for
6 : : // PartitionSurfaces.
7 : : //
8 : : // Special Notes :
9 : : //
10 : : // Creator : Jason Kraftcheck
11 : : //
12 : : // Creation Date : 05/17/01
13 : : //-------------------------------------------------------------------------
14 : : #ifndef PST_DATA_HPP
15 : : #define PST_DATA_HPP
16 : : #include <vector>
17 : :
18 : : #include "CubitVector.hpp"
19 : : #include "CubitDefines.h"
20 : : #include "DLIList.hpp"
21 : : #include "CubitPlane.hpp"
22 : :
23 : : #define PST_OTHER(A,B,C) (((A)==(B))?(C):(((A)==(C))?(B):0))
24 : :
25 : : class PST_CoEdge;
26 : : class PST_Edge;
27 : : class PST_Point;
28 : : class PST_Face;
29 : : class GMem;
30 : :
31 : : class PST_Entity;
32 : :
33 : : class PST_EntityOwner {
34 : : public:
35 : : virtual void
36 : : notify_split( PST_Entity* old_entity, PST_Entity* new_entity ) = 0;
37 : : };
38 : :
39 : : class PST_Entity
40 : : {
41 : : public:
42 : :
43 : : inline PST_EntityOwner* owner() const;
44 : :
45 : : inline void owner( PST_EntityOwner* );
46 : :
47 : : protected:
48 : :
49 : : inline PST_Entity();
50 : :
51 : : virtual ~PST_Entity() = 0;
52 : :
53 : : private:
54 : :
55 : : PST_EntityOwner* myOwner;
56 : : };
57 : :
58 : :
59 : : //-------------------------------------------------------------------------
60 : : // Purpose : Class representing a vertex in facet data structure
61 : : //
62 : : // Special Notes :
63 : : //
64 : : // Creator : Jason Kraftcheck
65 : : //
66 : : // Creation Date : 05/16/01
67 : : //-------------------------------------------------------------------------
68 : : class PST_Point : public CubitVector, public PST_Entity
69 : : {
70 : : friend class PST_Edge;
71 : :
72 : : public:
73 : :
74 : 0 : PST_Point( const CubitVector& position )
75 : : : CubitVector( position ),
76 : 0 : mark(0), private_mark_(false), edge_(0)
77 : 0 : { }
78 : :
79 : : ~PST_Point() ;
80 : : //- Destroys this point, and all edges and faces that
81 : : //- the point exists in.
82 : :
83 : 0 : PST_Edge* edge()
84 : 0 : { return edge_; }
85 : :
86 : : inline PST_Edge* next( PST_Edge* prev );
87 : :
88 : : PST_Edge* common( PST_Point* pt );
89 : :
90 : : int faces( DLIList<PST_Face*>* list = 0 );
91 : :
92 : : //PST_Face* boundary_face();
93 : :
94 : : void debug_draw( int color = 1, bool flush = true );
95 : : static void debug_draw_points( DLIList<PST_Point*>& list,
96 : : int color, bool flush = true );
97 : :
98 : : int validate( CubitBoolean print = CUBIT_FALSE );
99 : :
100 : : void print();
101 : :
102 : : int mark;
103 : :
104 : : int sequence;
105 : :
106 : : private:
107 : : cBit private_mark_ : 1;
108 : :
109 : : PST_Edge* edge_;
110 : : };
111 : :
112 : : //-------------------------------------------------------------------------
113 : : // Purpose : Association between a PST_Edge and a PST_Face
114 : : //
115 : : // Special Notes : Allocated inline in PST_Edge -- Do NOT memory manage!
116 : : //
117 : : // Creator : Jason Kraftcheck
118 : : //
119 : : // Creation Date : 05/16/01
120 : : //-------------------------------------------------------------------------
121 : : class PST_CoEdge
122 : : {
123 : : friend class PST_Edge;
124 : :
125 : : public:
126 : :
127 : 0 : PST_CoEdge* next()
128 : 0 : { return next_; }
129 : :
130 : 0 : PST_Edge* edge()
131 : 0 : { return edge_; }
132 : :
133 : 0 : PST_Face* face()
134 : 0 : { return face_; }
135 : :
136 : : inline CubitSense sense();
137 : :
138 : : inline PST_Point* start_point();
139 : : inline PST_Point* end_point();
140 : : inline PST_Point* common( PST_CoEdge* coedge );
141 : : inline PST_Point* other( PST_Point* point );
142 : :
143 : : inline const CubitVector& start_coord();
144 : : inline const CubitVector& end_coord();
145 : : inline CubitVector direction();
146 : :
147 : : inline PST_CoEdge* other();
148 : :
149 : : PST_CoEdge* previous();
150 : :
151 : : int validate( CubitBoolean print = CUBIT_FALSE );
152 : :
153 : : private:
154 : :
155 : 0 : PST_CoEdge()
156 : 0 : : next_(0), edge_(0), face_(0)
157 : 0 : { }
158 : :
159 : 0 : PST_CoEdge( PST_Edge* owner )
160 : 0 : : next_(0), edge_(owner), face_(0)
161 : 0 : { }
162 : :
163 : 0 : ~PST_CoEdge()
164 [ # # ]: 0 : { assert( !face_ ); }
165 : :
166 : : PST_CoEdge* next_;
167 : : PST_Edge* edge_;
168 : : PST_Face* face_;
169 : : };
170 : :
171 : :
172 : : //-------------------------------------------------------------------------
173 : : // Purpose : Edge in facet data structure
174 : : //
175 : : // Special Notes :
176 : : //
177 : : // Creator : Jason Kraftcheck
178 : : //
179 : : // Creation Date : 05/16/01
180 : : //-------------------------------------------------------------------------
181 : : class PST_Edge : public PST_Entity
182 : : {
183 : : public:
184 : :
185 : : static void make_gmem( GMem& gmem, DLIList<PST_Face*>& facets );
186 : : static void make_gmem( GMem& gmem, DLIList<PST_Edge*>& edges );
187 : : static void make_facets( GMem& gmem, double tolerance,
188 : : DLIList<PST_Edge*>& edges );
189 : : static void make_facets(
190 : : const std::vector<double>& coordinates,
191 : : const std::vector<int>& connections,
192 : : double tolerance,
193 : : DLIList<PST_Edge*>& edge_list );
194 : :
195 : 0 : PST_Edge( PST_Point* start_pt, PST_Point* end_pt )
196 : : : mark(0), private_mark_(false),
197 [ # # ][ # # ]: 0 : start_(0), end_(0)
198 : : {
199 [ # # ]: 0 : assert( start_pt != end_pt );
200 [ # # ]: 0 : set_start_point( start_pt );
201 [ # # ]: 0 : set_end_point( end_pt );
202 [ # # ][ # # ]: 0 : forward_ = PST_CoEdge(this);
203 [ # # ][ # # ]: 0 : reverse_ = PST_CoEdge(this);
204 : 0 : }
205 : :
206 : :
207 : : static PST_Face* create_face( PST_Point* p1,
208 : : PST_Point* p2,
209 : : PST_Point* p3 );
210 : :
211 : : static PST_Edge* split_face( PST_Point* start,
212 : : PST_Point* end,
213 : : PST_Face* hint = 0 );
214 : : //- This method splits a face by creating an edge
215 : : //- between two existing points on that face.
216 : : //- If the face to split is not specified, both
217 : : //- points must have exactly one face in common.
218 : : //- If the points do not have a common face, have
219 : : //- more than one common face and no face is
220 : : //- specified, do not exist in the passed face,
221 : : //- or already have a common edge, NULL is returned.
222 : :
223 : : static PST_Edge* split_face( PST_CoEdge* after_coedge_1,
224 : : PST_CoEdge* after_coedge_2 );
225 : : //- Split a face with an edge from the end of the first
226 : : //- coedge to the end of the second coedge. NULL is
227 : : //- returned if the coedges do not have a common face,
228 : : //- or the desired edge already exists.
229 : :
230 : : static PST_Edge* insert_in_face( PST_Point* end,
231 : : PST_CoEdge* after_this );
232 : : //- Create a non-manifold edge in a face. The edge is
233 : : //- inserted starting at the end of the passed coedge,
234 : : //- and terminating at the passed point. If the
235 : : //- passed point already exists in a face, null is
236 : : //- returned.
237 : :
238 : : PST_Edge* split( PST_Point* point );
239 : : //- Split an existing edge. Creates a new edge in the
240 : : //- same face(s) as the existing edge. Returns null
241 : : //- if the passed already exists in any face.
242 : :
243 : : ~PST_Edge();
244 : : //- Destroy this edge, splitting or merging faces as
245 : : //- necessary. Does NOT destroy unused points.
246 : :
247 : 0 : PST_Point* start_point()
248 : 0 : { return start_; }
249 : :
250 : 0 : PST_Point* end_point()
251 : 0 : { return end_; }
252 : :
253 : 0 : const CubitVector& start_coord()
254 : 0 : { return *start_; }
255 : :
256 : 0 : const CubitVector& end_coord()
257 : 0 : { return *end_; }
258 : :
259 : 0 : CubitVector direction()
260 : 0 : { return end_coord() - start_coord(); }
261 : :
262 : :
263 : 0 : CubitVector position( double t )
264 [ # # ][ # # ]: 0 : { return start_coord() + t * direction(); }
[ # # ]
265 : :
266 : : double closest_on_line( const CubitVector& pos );
267 : : double closest_on_edge( const CubitVector& pos );
268 : : // Parameter of the closest position on
269 : : // a) the line containing this edge or
270 : : // b) this bounded edge.
271 : :
272 : : double closest_on_line( const CubitVector& base,
273 : : const CubitVector& direction );
274 : : // The parameter of the closest position on
275 : : // the line containing this edge to the passed line.
276 : : // Use position(..) function above to get coordinates.
277 : :
278 : 0 : PST_Point* other( PST_Point* pt )
279 [ # # ][ # # ]: 0 : { return PST_OTHER(pt,start_,end_); }
280 : :
281 : : inline PST_Point* common_point( PST_Edge* edge );
282 : :
283 : 0 : PST_CoEdge* forward()
284 : 0 : { return &forward_; }
285 : :
286 : 0 : PST_CoEdge* reverse()
287 : 0 : { return &reverse_; }
288 : :
289 : 0 : PST_CoEdge* other( PST_CoEdge* coedge )
290 [ # # ][ # # ]: 0 : { return PST_OTHER(coedge,&forward_,&reverse_); }
291 : :
292 : : inline PST_CoEdge* coedge( PST_Face* face );
293 : :
294 : :
295 : 0 : PST_Face* other( PST_Face* face )
296 [ # # ][ # # ]: 0 : { return PST_OTHER(face,forward_.face(),reverse_.face()); }
297 : :
298 : :
299 : : inline PST_Face* common_face( PST_Edge* edge );
300 : :
301 : : inline CubitSense sense( PST_Face* face );
302 : :
303 : 0 : CubitSense sense( PST_CoEdge* coedge )
304 : 0 : { return coedge == forward() ? CUBIT_FORWARD :
305 [ # # ][ # # ]: 0 : coedge == reverse() ? CUBIT_REVERSED : CUBIT_UNKNOWN; }
306 : :
307 : : PST_Edge* other( PST_Point* point, PST_Face* face );
308 : : // Find the other edge in the passed face that
309 : : // shares the passed point. Returns NULL if multiple
310 : : // matches in a non-manifold face.
311 : :
312 : 0 : PST_Edge* next( PST_Point* pt )
313 : 0 : { return pt == start_ ? start_next_ :
314 [ # # ][ # # ]: 0 : pt == end_ ? end_next_ : 0; }
315 : :
316 : : //inline bool boundary();
317 : :
318 : : static void faces( DLIList<PST_Edge*>& edges, DLIList<PST_Face*>& faces );
319 : : static void edges( DLIList<PST_Face*>& faces, DLIList<PST_Edge*>& edges );
320 : : static void edges( DLIList<PST_Point*>& pts, DLIList<PST_Edge*>& edges );
321 : : static void points( DLIList<PST_Edge*>& edges, DLIList<PST_Point*>& pts );
322 : :
323 : : void debug_draw( int color = 1, bool flush = true );
324 : : static void debug_draw_points( DLIList<PST_Edge*>& list,
325 : : int color, int bcolor = 0, bool flush = true );
326 : : static void debug_draw_edges ( DLIList<PST_Edge*>& list,
327 : : int color, int bcolor = 0, bool flush = true );
328 : : static void debug_draw_faces ( DLIList<PST_Edge*>& list,
329 : : int color, bool flush = true );
330 : :
331 : : static int validate( DLIList<PST_Edge*>& edges, CubitBoolean print = CUBIT_FALSE );
332 : : int validate( CubitBoolean print = CUBIT_FALSE );
333 : :
334 : : void print();
335 : :
336 : : int mark;
337 : :
338 : : private:
339 : : cBit private_mark_ : 1;
340 : :
341 : : void remove_point( PST_Point*& ptr, PST_Edge*& next );
342 : 0 : void remove_start_point() { remove_point( start_, start_next_ ); }
343 : 0 : void remove_end_point() { remove_point( end_, end_next_); }
344 : :
345 : : void set_point( PST_Point* pt, PST_Point*& ptr, PST_Edge*& next );
346 : 0 : void set_start_point( PST_Point* pt )
347 : 0 : { set_point( pt, start_, start_next_ ); }
348 : 0 : void set_end_point( PST_Point* pt )
349 : 0 : { set_point( pt, end_, end_next_ ); }
350 : :
351 : : PST_Point* start_;
352 : : PST_Point* end_;
353 : : PST_Edge* start_next_;
354 : : PST_Edge* end_next_;
355 : :
356 : : PST_CoEdge forward_;
357 : : PST_CoEdge reverse_;
358 : : };
359 : :
360 : : //-------------------------------------------------------------------------
361 : : // Purpose : Face in facet data structure
362 : : //
363 : : // Special Notes :
364 : : //
365 : : // Creator : Jason Kraftcheck
366 : : //
367 : : // Creation Date : 05/16/01
368 : : //-------------------------------------------------------------------------
369 : : class PST_Face : public PST_Entity
370 : : {
371 : : friend class PST_Edge;
372 : : friend class PST_Point;
373 : :
374 : : public:
375 : :
376 : 0 : const CubitPlane& plane()
377 : : {
378 [ # # ]: 0 : if( update_plane_ )
379 : 0 : calculate_plane();
380 : 0 : return plane_;
381 : : }
382 : :
383 : 0 : CubitVector normal()
384 : 0 : { return plane().normal(); }
385 : :
386 : :
387 : : double bounding_length();
388 : :
389 : 0 : PST_CoEdge* first_coedge()
390 : 0 : { return coedge_; }
391 : :
392 : : void append_points( DLIList<PST_Point*>& result_list );
393 : :
394 : : PST_Point* opposite( PST_Edge* edge );
395 : : PST_Edge* opposite( PST_Point* point );
396 : : // for triangles
397 : :
398 : : bool two_edges( PST_Point* point, PST_Edge*& edge1, PST_Edge*& edge2 );
399 : :
400 : : bool modified()
401 : : { return modified_; }
402 : :
403 : 0 : void modified( bool b )
404 : : {
405 : 0 : modified_ = b;
406 [ # # ]: 0 : if( b ) update_plane_ = 1;
407 : 0 : }
408 : :
409 : : void debug_draw( int color = 1, bool flush = true );
410 : : static void debug_draw_faces( DLIList<PST_Face*>& list,
411 : : int color, bool flush = true );
412 : :
413 : : int validate( CubitBoolean print = CUBIT_FALSE );
414 : :
415 : : void print();
416 : :
417 : : int mark;
418 : :
419 : : int sequence;
420 : :
421 : : int parent;
422 : :
423 : : private:
424 : :
425 : 0 : PST_Face( PST_CoEdge* coedge )
426 : : : mark(0), sequence(0), parent(0),
427 : : coedge_(coedge),
428 : : //boundary_(0),
429 : : modified_(0),
430 : : update_plane_(1),
431 [ # # ]: 0 : private_mark_(false)
432 : :
433 : 0 : { }
434 : :
435 : 0 : PST_Face( PST_CoEdge* coedge, PST_Face* split_from )
436 : : : mark(0), sequence(0), parent(0),
437 : : coedge_(coedge),
438 : : //boundary_(split_from->boundary()),
439 : : modified_(0),
440 : : update_plane_(1),
441 [ # # ]: 0 : private_mark_(false)
442 [ # # ]: 0 : { split_from->modified(true); }
443 : :
444 : 0 : ~PST_Face()
445 [ # # ][ # # ]: 0 : { assert( !coedge_ ); }
446 : :
447 : : bool calculate_plane();
448 : :
449 : : PST_CoEdge* coedge_;
450 : : CubitPlane plane_;
451 : :
452 : : //cBit boundary_ : 1;
453 : : cBit modified_ : 1;
454 : : cBit update_plane_ : 1;
455 : : cBit private_mark_ : 1;
456 : : };
457 : :
458 : : /*************************************************************************
459 : : * PST_Point
460 : : ************************************************************************/
461 : :
462 : 0 : inline PST_Edge* PST_Point::next( PST_Edge* prev )
463 : : {
464 : 0 : return prev->next(this);
465 : : }
466 : :
467 : : /*************************************************************************
468 : : * PST_CoEdge
469 : : ************************************************************************/
470 : :
471 : 0 : inline CubitSense PST_CoEdge::sense()
472 : : {
473 : 0 : return edge_->sense(this);
474 : : }
475 : :
476 : 0 : inline PST_Point* PST_CoEdge::start_point()
477 : : {
478 [ # # ]: 0 : return sense() == CUBIT_FORWARD ? edge_->start_point() : edge_->end_point();
479 : : }
480 : :
481 : 0 : inline PST_Point* PST_CoEdge::end_point()
482 : : {
483 [ # # ]: 0 : return sense() == CUBIT_FORWARD ? edge_->end_point() : edge_->start_point();
484 : : }
485 : :
486 : 0 : inline PST_Point* PST_CoEdge::other( PST_Point* point )
487 : : {
488 : 0 : return edge_->other( point );
489 : : }
490 : :
491 : 0 : inline const CubitVector& PST_CoEdge::start_coord()
492 : : {
493 [ # # ]: 0 : return sense() == CUBIT_FORWARD ? edge_->start_coord() : edge_->end_coord();
494 : : }
495 : :
496 : 0 : inline const CubitVector& PST_CoEdge::end_coord()
497 : : {
498 [ # # ]: 0 : return sense() == CUBIT_FORWARD ? edge_->end_coord() : edge_->start_coord();
499 : : }
500 : :
501 : 0 : inline CubitVector PST_CoEdge::direction()
502 : : {
503 : 0 : return sense() == CUBIT_FORWARD ?
504 : 0 : edge_->end_coord() - edge_->start_coord() :
505 [ # # ]: 0 : edge_->start_coord() - edge_->end_coord() ;
506 : : }
507 : :
508 : 0 : inline PST_CoEdge* PST_CoEdge::other()
509 : : {
510 : 0 : return edge_->other(this);
511 : : }
512 : :
513 : :
514 : :
515 : : /*************************************************************************
516 : : * PST_Edge
517 : : ************************************************************************/
518 : :
519 : : inline PST_Point* PST_Edge::common_point( PST_Edge* edge )
520 : : {
521 : : PST_Point* result = 0;
522 : :
523 : : if( (edge->start_ == start_) ||
524 : : (edge->end_ == start_) )
525 : : result = start_;
526 : :
527 : : if( (edge->start_ == end_) ||
528 : : (edge->end_ == end_) )
529 : : result = result ? 0 : end_;
530 : :
531 : : return result;
532 : : }
533 : :
534 : : inline PST_CoEdge* PST_Edge::coedge( PST_Face* face )
535 : : {
536 : : PST_CoEdge* result = 0;
537 : :
538 : : if( forward_.face_ == face )
539 : : result = &forward_;
540 : :
541 : : if( reverse_.face_ == face )
542 : : result = result ? 0 : &reverse_;
543 : :
544 : : return result;
545 : : }
546 : :
547 : : inline CubitSense PST_Edge::sense( PST_Face* face )
548 : : {
549 : : CubitSense result = CUBIT_UNKNOWN;
550 : :
551 : : if( forward_.face_ == face )
552 : : result = CUBIT_FORWARD;
553 : :
554 : : if( reverse_.face_ == face )
555 : : result = (result != CUBIT_UNKNOWN) ? CUBIT_UNKNOWN : CUBIT_REVERSED;
556 : :
557 : : return result;
558 : : }
559 : :
560 : 0 : inline PST_Entity::PST_Entity() : myOwner(0) { ; }
561 : :
562 : 0 : inline PST_EntityOwner* PST_Entity::owner() const
563 : 0 : { return myOwner; }
564 : :
565 : : inline void PST_Entity::owner( PST_EntityOwner* ent )
566 : : { myOwner = ent; }
567 : :
568 : :
569 : : /*************************************************************************
570 : : * PST_Face
571 : : ************************************************************************/
572 : :
573 : : // find the minimum edge length and use this for the bounding length
574 : 0 : inline double PST_Face::bounding_length()
575 : : {
576 : : // The coedges appear to be stored in a circular list so
577 : : // get the length of the first edge and then iterate
578 [ # # ]: 0 : PST_CoEdge* coe = this->first_coedge();
579 [ # # ][ # # ]: 0 : CubitVector pos1 = coe->start_coord();
580 [ # # ][ # # ]: 0 : CubitVector pos2 = coe->end_coord();
581 [ # # ]: 0 : CubitVector dist = pos1 - pos2;
582 [ # # ]: 0 : double length = dist.length_squared();
583 : :
584 : : // start the chain at the next coedge
585 [ # # ]: 0 : coe = coe->next();
586 : :
587 : : // walk through the coedges till we get back to the first
588 : : // and find the minimum length edge
589 : : double l;
590 [ # # ][ # # ]: 0 : for ( ; coe != this->first_coedge(); coe = coe->next() )
[ # # ]
591 : : {
592 [ # # ][ # # ]: 0 : pos1 = coe->start_coord();
593 [ # # ][ # # ]: 0 : pos2 = coe->end_coord();
594 [ # # ][ # # ]: 0 : dist = pos1 - pos2;
595 [ # # ]: 0 : l = dist.length_squared();
596 [ # # ]: 0 : if ( l < length)
597 : 0 : length = l;
598 : : }
599 : :
600 : 0 : return sqrt(length);
601 : : }
602 : :
603 : : #endif
604 : :
|