Branch data Line data Source code
1 : : #include "CubitFacet.hpp"
2 : : #include "CubitPoint.hpp"
3 : : #include "CubitPointData.hpp"
4 : : #include "CubitVector.hpp"
5 : : #include "GeometryDefines.h"
6 : : #include "CubitPlane.hpp"
7 : : #include "CubitFacetEdge.hpp"
8 : : #include "CubitFacetData.hpp"
9 : : #include "CubitFacetEdgeData.hpp"
10 : : #include "CastTo.hpp"
11 : : #include "ToolData.hpp"
12 : : #include "GfxDebug.hpp"
13 : : #include "TDFacetBoundaryPoint.hpp"
14 : : #include "CubitMessage.hpp"
15 : :
16 : : #ifndef CUBIT_MAX
17 : : #define CUBIT_MAX(a,b) (((a) > (b)) ? (a) : (b))
18 : : #endif
19 : : #ifndef CUBIT_MIN
20 : : #define CUBIT_MIN(a,b) (((a) < (b)) ? (a) : (b))
21 : : #endif
22 : : #define min3(a,b,c) CUBIT_MIN((CUBIT_MIN((a),(b))),(c))
23 : : #define max3(a,b,c) CUBIT_MAX((CUBIT_MAX((a),(b))),(c))
24 : : static int counter_id = 0;
25 : :
26 : : //===========================================================================
27 : : //Function Name: CubitFacetData
28 : : //
29 : : //Member Type: PUBLIC
30 : : //Description: constructor
31 : : //===========================================================================
32 : 1056 : CubitFacetData::CubitFacetData( CubitPoint *p1, CubitPoint *p2,
33 : 1056 : CubitPoint *p3 )
34 : : {
35 [ + - ][ + - ]: 1056 : assert( p1 && p2 && p3 );
[ - + ]
36 [ + - ][ + - ]: 1056 : assert( p1 != p2 && p1 != p3 && p2 != p3 );
[ - + ]
37 : 1056 : pointArray[0] = p1;
38 : 1056 : pointArray[1] = p2;
39 : 1056 : pointArray[2] = p3;
40 [ + - ]: 1056 : p1->add_facet(this);
41 [ + - ]: 1056 : p2->add_facet(this);
42 [ + - ]: 1056 : p3->add_facet(this);
43 : :
44 : 1056 : edgeArray[0] = NULL;
45 : 1056 : edgeArray[1] = NULL;
46 : 1056 : edgeArray[2] = NULL;
47 : 1056 : edgeUse[0] = edgeUse[1] = edgeUse[2] = 0;
48 : 1056 : patchCtrlPts = NULL;
49 : :
50 : :
51 : 1056 : counter_id++;
52 : 1056 : entityId = counter_id;
53 : :
54 [ + - ]: 1056 : plane();
55 : :
56 [ + - ]: 1056 : define_bounding_box();
57 : :
58 : 1056 : }
59 : :
60 : : //===========================================================================
61 : : //Function Name: CubitFacetData
62 : : //
63 : : //Member Type: PUBLIC
64 : : //Description: constructor
65 : : //===========================================================================
66 : 528 : CubitFacetData::CubitFacetData( CubitFacetEdge *e1, CubitFacetEdge *e2,
67 : 528 : CubitFacetEdge *e3 )
68 : : {
69 [ + - ][ + - ]: 528 : assert( e1 && e2 && e3 );
[ - + ]
70 [ + - ][ + - ]: 528 : assert( e1 != e2 && e1 != e3 && e2 != e3 );
[ - + ]
71 : :
72 : 528 : edgeArray[0] = e1;
73 : 528 : edgeArray[1] = e2;
74 : 528 : edgeArray[2] = e3;
75 : :
76 [ + - ]: 528 : define_point(e2, e3, 0);
77 [ + - ]: 528 : define_point(e3, e1, 1);
78 [ + - ]: 528 : define_point(e1, e2, 2);
79 [ + - ]: 528 : e1->add_facet(this);
80 [ + - ]: 528 : e2->add_facet(this);
81 [ + - ]: 528 : e3->add_facet(this);
82 : :
83 : 528 : patchCtrlPts = NULL;
84 : :
85 [ + - ]: 528 : plane();
86 : 528 : counter_id++;
87 : 528 : entityId = counter_id;
88 : :
89 [ + - ]: 528 : define_bounding_box();
90 : :
91 : 528 : }
92 : :
93 : : //===========================================================================
94 : : //Function Name: CubitFacetData
95 : : //
96 : : //Member Type: PUBLIC
97 : : //Description: constructor
98 : : //===========================================================================
99 : 0 : CubitFacetData::CubitFacetData( CubitPoint *p1, CubitPoint *p2,
100 : 0 : CubitPoint *p3, int *tool_data)
101 : : {
102 [ # # ][ # # ]: 0 : assert( p1 && p2 && p3 );
[ # # ]
103 [ # # ][ # # ]: 0 : assert( p1 != p2 && p1 != p3 && p2 != p3 );
[ # # ]
104 : 0 : pointArray[0] = p1;
105 : 0 : pointArray[1] = p2;
106 : 0 : pointArray[2] = p3;
107 : :
108 : 0 : edgeArray[0] = NULL;
109 : 0 : edgeArray[1] = NULL;
110 : 0 : edgeArray[2] = NULL;
111 : :
112 [ # # ]: 0 : p1->add_facet(this);
113 [ # # ]: 0 : p2->add_facet(this);
114 [ # # ]: 0 : p3->add_facet(this);
115 : :
116 : 0 : edgeArray[0] = 0;
117 : 0 : edgeArray[1] = 0;
118 : 0 : edgeArray[2] = 0;
119 [ # # ]: 0 : allocate_edge(p2,p3,0);
120 [ # # ]: 0 : allocate_edge(p3,p1,1);
121 [ # # ]: 0 : allocate_edge(p1,p2,2);
122 : :
123 : 0 : patchCtrlPts = NULL;
124 : :
125 [ # # ]: 0 : plane();
126 : 0 : counter_id++;
127 : 0 : entityId = counter_id;
128 : : // update toolID
129 [ # # ]: 0 : if(tool_data)
130 [ # # ]: 0 : set_tool_id(*tool_data);
131 : :
132 [ # # ]: 0 : define_bounding_box();
133 : 0 : }
134 : :
135 : : //===========================================================================
136 : : //Function Name: ~CubitFacetData
137 : : //
138 : : //Member Type: PUBLIC
139 : : //Description: destructor
140 : : //===========================================================================
141 : 0 : CubitFacetData::~CubitFacetData()
142 : : {
143 [ # # ]: 0 : destruct_facet_internals();
144 [ # # ]: 0 : }
145 : :
146 : 0 : void CubitFacetData::destruct_facet_internals()
147 : : {
148 : 0 : int ii = 3;
149 [ # # ]: 0 : for (ii = 2; ii>=0; ii--){
150 : : //remove this triangle-point association at the points.
151 : 0 : CubitPoint *current_point = point(ii);
152 [ # # ]: 0 : if (current_point)
153 : 0 : current_point->remove_facet(this);
154 : :
155 : 0 : pointArray[ii] = NULL;
156 : :
157 : : //remove edge-point association at the edges
158 : :
159 : 0 : CubitFacetEdge *current_edge = edgeArray[ii];
160 : :
161 [ # # ]: 0 : if (current_edge) {
162 : 0 : CubitStatus status = current_edge->remove_facet(this);
163 [ # # ]: 0 : if (CUBIT_SUCCESS != status) {
164 [ # # ][ # # ]: 0 : PRINT_ERROR("Failed to remove facet at current edge.\n");
165 : 0 : return;
166 : : }
167 : : }
168 : 0 : edgeArray[ii] = NULL;
169 : : }
170 : : }
171 : :
172 : :
173 : : //===========================================================================
174 : : //Function Name: closest_point
175 : : //
176 : : //Member Type: PUBLIC
177 : : //Description: return the closest point on plane defined by the facet
178 : : //===========================================================================
179 : 0 : CubitStatus CubitFacetData::closest_point(const CubitVector &point,
180 : : CubitVector &closest_point )
181 : : {
182 [ # # ]: 0 : if( cachedPlane )
183 : : {
184 [ # # ][ # # ]: 0 : closest_point = cachedPlane->project( point );
185 : 0 : return CUBIT_SUCCESS;
186 : : }
187 : :
188 [ # # ]: 0 : CubitVector normal_vec = normal();
189 [ # # ]: 0 : CubitVector P0 = pointArray[0]->coordinates();
190 [ # # ]: 0 : CubitVector point_to_P0 = point - P0;
191 [ # # ]: 0 : CubitVector P0_to_projection;
192 : : //Store the normal squared the the dot product of the normal and vector to the point.
193 [ # # ]: 0 : double normal_length_sq = normal_vec.length_squared();
194 : : //If the normal is zero, get out!
195 [ # # ]: 0 : if ( normal_length_sq < CUBIT_RESABS )
196 : 0 : return CUBIT_FAILURE;
197 [ # # ]: 0 : double point_to_P0_dot_norm = point_to_P0%normal_vec;
198 : : //Use P0_to_projection as a temporary to store half the equation.
199 [ # # ][ # # ]: 0 : P0_to_projection = (point_to_P0_dot_norm/normal_length_sq)*normal_vec;
200 [ # # ][ # # ]: 0 : P0_to_projection = point_to_P0 - P0_to_projection;
201 : : //Now we have the vector from P0, to the closest point. Add the vector
202 : : //to P0, and you have the location!
203 [ # # ][ # # ]: 0 : closest_point = P0 + P0_to_projection;
204 : 0 : return CUBIT_SUCCESS;
205 : : }
206 : :
207 : : //-------------------------------------------------------------------------
208 : : // Purpose : Local modification functions.
209 : : //
210 : : // Special Notes :
211 : : //
212 : : // Creator : Jason Kraftcheck
213 : : //
214 : : // Creation Date : 03/25/00
215 : : //-------------------------------------------------------------------------
216 : 0 : CubitPoint* CubitFacetData::split_edge( int edge_index,
217 : : const CubitVector& position )
218 : : {
219 : 0 : CubitPoint* pt1 = point((edge_index+1)%2);
220 : 0 : CubitPoint* pt2 = point((edge_index+2)%2);
221 : 0 : return split_edge( pt1, pt2, position );
222 : : }
223 : :
224 : 0 : CubitPoint* CubitFacetData::split_edge( CubitPoint* edge1_pt,
225 : : CubitPoint* edge2_pt,
226 : : const CubitVector& position )
227 : : {
228 [ # # ][ # # ]: 0 : CubitPointData* new_pt = new CubitPointData(position);
229 : :
230 : : // split edge, if there is one
231 : :
232 [ # # ]: 0 : CubitFacetEdge* edge = edge1_pt->shared_edge( edge2_pt );
233 : 0 : CubitFacetEdgeData* new_edge = 0;
234 [ # # ]: 0 : if ( edge ) {
235 [ # # ]: 0 : CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge);
236 [ # # ]: 0 : assert(!!edge_d);
237 : :
238 : : // make sure new edge has same orientation as old edge
239 [ # # ][ # # ]: 0 : new_edge = dynamic_cast<CubitFacetEdgeData*>(new_pt->shared_edge(edge2_pt));
240 [ # # ][ # # ]: 0 : if ( edge->point(0) == edge1_pt ) {
241 [ # # ]: 0 : edge_d->set_point(new_pt, 1);
242 [ # # ]: 0 : if ( !new_edge )
243 : : {
244 [ # # ][ # # ]: 0 : new_edge = new CubitFacetEdgeData( new_pt, edge2_pt );
245 [ # # ]: 0 : DLIList<ToolData*> tds;
246 [ # # ]: 0 : edge->get_all_TDs(&tds);
247 [ # # ][ # # ]: 0 : for (int i=0; i<tds.size(); i++)
248 : : {
249 [ # # ][ # # ]: 0 : ToolData* new_td = tds.get_and_step()->propogate(new_edge);
250 [ # # ]: 0 : if (new_td)
251 [ # # ]: 0 : new_edge->add_TD(new_td);
252 [ # # ]: 0 : }
253 : : }
254 [ # # ][ # # ]: 0 : else if( new_edge->point(0) != new_pt )
255 [ # # ]: 0 : new_edge->flip();
256 : : } else {
257 [ # # ]: 0 : edge_d->set_point(new_pt, 0);
258 [ # # ]: 0 : if ( !new_edge )
259 : : {
260 [ # # ][ # # ]: 0 : new_edge = new CubitFacetEdgeData( edge2_pt, new_pt );
261 [ # # ]: 0 : DLIList<ToolData*> tds;
262 [ # # ]: 0 : edge->get_all_TDs(&tds);
263 [ # # ][ # # ]: 0 : for (int i=0; i<tds.size(); i++)
264 : : {
265 [ # # ][ # # ]: 0 : ToolData* new_td = tds.get_and_step()->propogate(new_edge);
266 [ # # ]: 0 : if (new_td)
267 [ # # ]: 0 : new_edge->add_TD(new_td);
268 [ # # ]: 0 : }
269 : : }
270 [ # # ][ # # ]: 0 : else if( new_edge->point(1) != new_pt )
271 [ # # ]: 0 : new_edge->flip();
272 : : }
273 : : }
274 : :
275 : : // split triangles
276 : :
277 [ # # ]: 0 : DLIList<CubitFacet*> facets;
278 [ # # ]: 0 : edge1_pt->shared_facets( edge2_pt, facets );
279 : :
280 [ # # ]: 0 : facets.reset();
281 [ # # ][ # # ]: 0 : for ( int i = facets.size(); i--; ) {
282 : :
283 [ # # ]: 0 : CubitFacet* facet = facets.get_and_step();
284 [ # # ]: 0 : CubitFacetData* facet_d = dynamic_cast<CubitFacetData*>(facet);
285 [ # # ]: 0 : assert(!!facet_d);
286 : :
287 : :
288 : : // fix up existing facet
289 : :
290 [ # # ]: 0 : int pt2_index = facet->point_index( edge2_pt );
291 [ # # ]: 0 : bool edge_reversed = ( edge1_pt == facet->point( (pt2_index+1) % 3 ) );
292 : 0 : int edge_index = (pt2_index + 1 + edge_reversed) % 3;
293 : :
294 [ # # ]: 0 : edge2_pt->remove_facet( facet );
295 [ # # ]: 0 : facet_d->set_point( new_pt, pt2_index );
296 [ # # ]: 0 : new_pt->add_facet( facet );
297 [ # # ]: 0 : facet->update_plane();
298 : :
299 : :
300 : : // make new facet
301 : :
302 [ # # ]: 0 : CubitPoint* other_pt = facet->point( edge_index );
303 : : CubitFacetData* new_facet;
304 [ # # ]: 0 : if ( edge_reversed )
305 [ # # ][ # # ]: 0 : new_facet = new CubitFacetData( other_pt, edge2_pt, new_pt );
306 : : else
307 [ # # ][ # # ]: 0 : new_facet = new CubitFacetData( other_pt, new_pt, edge2_pt );
308 : :
309 [ # # ]: 0 : DLIList<ToolData*> td_list;
310 [ # # ]: 0 : facet->get_all_TDs(&td_list);
311 [ # # ][ # # ]: 0 : for (int i=0; i< td_list.size(); i++)
312 : : {
313 [ # # ][ # # ]: 0 : ToolData* new_td = td_list.get_and_step()->propogate(new_facet);
314 [ # # ]: 0 : if (new_td)
315 : : {
316 [ # # ]: 0 : new_facet->add_TD(new_td);
317 : : }
318 : : }
319 : :
320 [ # # ]: 0 : if ( new_edge ) {
321 [ # # ][ # # ]: 0 : assert(!new_facet->edge(0));
322 [ # # ]: 0 : new_facet->edge( new_edge, 0 );
323 [ # # ]: 0 : new_edge->add_facet( new_facet );
324 [ # # ][ # # ]: 0 : int sense = new_facet->point( 1 ) == new_edge->point(0) ? 1 : -1;
[ # # ]
325 [ # # ]: 0 : new_facet->edge_use( sense, 0 );
326 : : }
327 : :
328 : :
329 : : // move other edge, if there is one
330 : :
331 : 0 : int pt1_index = (pt2_index + 2 - edge_reversed) % 3;
332 [ # # ]: 0 : CubitFacetEdge* other_edge = facet->edge(pt1_index);
333 [ # # ]: 0 : if ( other_edge ) {
334 [ # # ]: 0 : other_edge->remove_facet(facet);
335 [ # # ]: 0 : facet->edge( 0, pt1_index );
336 : 0 : int e_index = 1 + edge_reversed;
337 [ # # ][ # # ]: 0 : assert(!new_facet->edge(e_index));
338 [ # # ]: 0 : new_facet->edge( other_edge, e_index );
339 [ # # ]: 0 : other_edge->add_facet(new_facet);
340 [ # # ][ # # ]: 0 : int sense = new_facet->point( (e_index+1)%3 ) == other_edge->point(0) ? 1 : -1;
[ # # ]
341 [ # # ]: 0 : new_facet->edge_use( sense, e_index );
342 : : }
343 : :
344 : : // what about a new edge for each of the adj_facets and its tool data
345 : :
346 [ # # ]: 0 : }
347 : :
348 [ # # ]: 0 : return new_pt;
349 : : }
350 : :
351 : : //-------------------------------------------------------------------------
352 : : // Purpose : insert a point into the facet
353 : : //
354 : : // Special Notes : create two new facets and return them
355 : : //
356 : : // Creator :
357 : : //
358 : : // Creation Date :
359 : : //-------------------------------------------------------------------------
360 : 0 : CubitPoint* CubitFacetData::insert_point( const CubitVector& position,
361 : : CubitFacet*& new_tri1_out,
362 : : CubitFacet*& new_tri2_out )
363 : : {
364 [ # # ]: 0 : CubitPointData* new_point = new CubitPointData( position );
365 : : CubitFacetData *new_tri1, *new_tri2;
366 [ # # ]: 0 : new_tri1 = new CubitFacetData( point(1), point(2), new_point );
367 [ # # ]: 0 : new_tri2 = new CubitFacetData( point(2), point(0), new_point );
368 : :
369 : 0 : point(2)->remove_facet( this );
370 : 0 : set_point( new_point, 2 );
371 : 0 : new_point->add_facet( this );
372 : :
373 [ # # ]: 0 : if ( edge(0) ) {
374 : 0 : new_tri1->edge( edge(0), 2 );
375 : 0 : new_tri1->edge_use( edge_use(0), 2 );
376 : 0 : edge(0)->remove_facet(this);
377 : 0 : edge(0)->add_facet(new_tri1);
378 : 0 : edge( 0, 0 );
379 : : }
380 : :
381 [ # # ]: 0 : if ( edge(1) ) {
382 : 0 : new_tri2->edge( edge(1), 2 );
383 : 0 : new_tri2->edge_use( edge_use(1), 2 );
384 : 0 : edge(1)->remove_facet(this);
385 : 0 : edge(1)->add_facet(new_tri2);
386 : 0 : edge( 0, 1 );
387 : : }
388 : :
389 : 0 : update_plane();
390 : :
391 : 0 : new_tri1_out = new_tri1;
392 : 0 : new_tri2_out = new_tri2;
393 : 0 : return new_point;
394 : : }
395 : :
396 : :
397 : : //-------------------------------------------------------------------------
398 : : // Purpose : reorient the facet
399 : : //
400 : : // Special Notes : This function should only be used if it is acceptable
401 : : // to change the underlying data representation of the
402 : : // facets (for example the Sierra facet representation
403 : : // cannot change and will not permit changing of the
404 : : // node orders on a facet)
405 : : //
406 : : // Also note that if this function is used, the isBackwards
407 : : // flag on the facet should be set appropriately.
408 : : //
409 : : // Creator : Steve Owen
410 : : //
411 : : // Creation Date : 06/28/00
412 : : //-------------------------------------------------------------------------
413 : 0 : void CubitFacetData::flip()
414 : : {
415 : 0 : CubitVector* ctrl_points=control_points( );
416 : :
417 : 0 : CubitPoint *pt_tmp = pointArray[1];
418 : 0 : pointArray[1] = pointArray[2];
419 : 0 : pointArray[2] = pt_tmp;
420 : :
421 : 0 : CubitFacetEdge *ed_tmp = edgeArray[1];
422 : 0 : edgeArray[1] = edgeArray[2];
423 : 0 : edgeArray[2] = ed_tmp;
424 : :
425 : : //make sure the edgeUses are matched with the correct edge...
426 : 0 : int ed_use_tmp = edgeUse[1];
427 : 0 : edgeUse[1]=edgeUse[2];
428 : 0 : edgeUse[2]=ed_use_tmp;
429 : :
430 : : //now flip the edge uses...
431 : : int ii;
432 [ # # ]: 0 : for (ii=0; ii<3; ii++)
433 : : {
434 [ # # ]: 0 : if (edgeUse[ii] == -1) {
435 : 0 : edgeUse[ii] = 1;
436 : : }
437 [ # # ]: 0 : else if(edgeUse[ii] == 1) {
438 : 0 : edgeUse[ii] = -1;
439 : : }
440 : : }
441 [ # # ]: 0 : if(ctrl_points){
442 [ # # ]: 0 : CubitVector tmp_point;
443 [ # # ]: 0 : tmp_point = ctrl_points[0];
444 [ # # ]: 0 : ctrl_points[0]=ctrl_points[1];
445 [ # # ]: 0 : ctrl_points[1]=tmp_point;
446 [ # # ]: 0 : tmp_point = ctrl_points[2];
447 [ # # ]: 0 : ctrl_points[2]=ctrl_points[5];
448 [ # # ]: 0 : ctrl_points[5]=tmp_point;
449 [ # # ]: 0 : tmp_point = ctrl_points[3];
450 [ # # ]: 0 : ctrl_points[3]=ctrl_points[4];
451 [ # # ]: 0 : ctrl_points[4]=tmp_point;
452 : : }
453 : 0 : update_plane();
454 : : //update the normals on the points (including boundary points)
455 [ # # ]: 0 : for (ii=0; ii<3; ii++)
456 : : {
457 : 0 : pointArray[ii]->compute_avg_normal();
458 : : TDFacetBoundaryPoint* tdfbp =
459 : 0 : TDFacetBoundaryPoint::get_facet_boundary_point(pointArray[ii]);
460 [ # # ]: 0 : if(tdfbp){
461 [ # # ]: 0 : if(!tdfbp->reset_normals()){
462 [ # # ][ # # ]: 0 : PRINT_ERROR("Could not reset all the normals for a point.\n");
463 : : }
464 : : }
465 : : }
466 : :
467 : 0 : }
468 : :
469 : : //===========================================================================
470 : : //Function Name: allocate_edge
471 : : //
472 : : //Member Type: PRIVATE
473 : : //Description: associate facetedge with this facet
474 : : //Special Notes: 1. Assume edge(p1,p2) is in Counter-clockwise direction wrt to// this facet)
475 : : // 2. Helper function to Constructor
476 : : //===========================================================================
477 : 0 : void CubitFacetData::allocate_edge(CubitPoint *p1, CubitPoint *p2, int edge_index){
478 : :
479 [ # # ][ # # ]: 0 : assert(edge_index >= 0 && edge_index < 3);
480 [ # # ][ # # ]: 0 : assert(p1 != NULL && p2 != NULL);
481 : :
482 : 0 : CubitFacetEdge* shared_edge = p1->get_edge(p2);
483 : :
484 [ # # ]: 0 : if(shared_edge == NULL){
485 : : //- if edge don't exist, create it
486 [ # # ]: 0 : edgeArray[edge_index] = (CubitFacetEdge *) new CubitFacetEdgeData(p1,p2);
487 : 0 : edgeUse[edge_index] = 1;
488 : : } else {
489 : 0 : edgeArray[edge_index] = shared_edge;
490 : 0 : shared_edge->add_facet(this);
491 [ # # ]: 0 : if(shared_edge->point(0) == p1)
492 : 0 : edgeUse[edge_index]= 1;
493 : : else
494 : 0 : edgeUse[edge_index] = -1;
495 : :
496 : : }
497 : :
498 : 0 : }
499 : :
500 : :
501 : : //===========================================================================
502 : : //Function Name: define_point
503 : : //
504 : : //Member Type: PRIVATE
505 : : //Description: define the point based on its adjacent edges. define the
506 : : // edge uses too.
507 : : //Special Notes: 1. Assume edge(e1,e2) is in Counter-clockwise direction wrt
508 : : // this facet
509 : : // 2. Helper function to Constructor
510 : : //===========================================================================
511 : 1584 : void CubitFacetData::define_point(CubitFacetEdge *e1,
512 : : CubitFacetEdge *e2,
513 : : int point_index)
514 : : {
515 : :
516 [ + - ][ - + ]: 1584 : assert(point_index >= 0 && point_index < 3);
517 [ + - ][ - + ]: 1584 : assert(e1 != NULL && e2 != NULL);
518 : :
519 : : CubitPoint *pA, *pB, *pC, *pD;
520 : 1584 : pA = e1->point(0);
521 : 1584 : pB = e1->point(1);
522 : 1584 : pC = e2->point(0);
523 : 1584 : pD = e2->point(1);
524 [ + + ][ + + ]: 1584 : if(pC == pB || pC == pA)
525 : : {
526 : 792 : pointArray[point_index] = pC;
527 : 792 : pC->add_facet(this);
528 : 792 : edgeUse[(point_index+2)%3] = 1;
529 : : }
530 [ + + ][ + - ]: 792 : else if(pD == pB || pD == pA)
531 : : {
532 : 792 : pointArray[point_index] = pD;
533 : 792 : pD->add_facet(this);
534 : 792 : edgeUse[(point_index+2)%3] = -1;
535 : : }
536 : : else
537 : : {
538 : 0 : assert(0); // the edges are not adjacent;
539 : : }
540 : :
541 : 1584 : }
542 : :
543 : : //===========================================================================
544 : : //Function Name: define_bounding_box
545 : : //
546 : : //Member Type: PRIVATE
547 : : //Description: compute and store the bounding box
548 : : // Helper function to Constructor
549 : : //===========================================================================
550 : 1584 : void CubitFacetData::define_bounding_box()
551 : : {
552 [ + - ][ + - ]: 1584 : CubitVector bbox_min, bbox_max;
553 : 1584 : CubitPoint *p1 = pointArray[0];
554 : 1584 : CubitPoint *p2 = pointArray[1];
555 : 1584 : CubitPoint *p3 = pointArray[2];
556 [ + - ][ + - ]: 1584 : bbox_min.x(min3(p1->x(),p2->x(),p3->x()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
557 [ + - ][ + - ]: 1584 : bbox_min.y(min3(p1->y(),p2->y(),p3->y()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
558 [ + - ][ + - ]: 1584 : bbox_min.z(min3(p1->z(),p2->z(),p3->z()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
559 [ + - ][ + - ]: 1584 : bbox_max.x(max3(p1->x(),p2->x(),p3->x()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
560 [ + - ][ + - ]: 1584 : bbox_max.y(max3(p1->y(),p2->y(),p3->y()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
561 [ + - ][ + - ]: 1584 : bbox_max.z(max3(p1->z(),p2->z(),p3->z()));
[ + + ][ + - ]
[ + - ][ + - ]
[ + + ][ + - ]
[ + - ][ + + ]
[ + - ][ + - ]
[ + - ][ + - ]
562 [ + - ]: 1584 : bBox.reset(bbox_min,bbox_max);
563 : 1584 : }
564 : :
565 : 0 : CubitStatus CubitFacetData::flip_edge( CubitFacetEdge *edge )
566 : : {
567 : : int i;
568 [ # # ]: 0 : for(i=0; i<3; i++)
569 : : {
570 [ # # ]: 0 : if (edgeArray[i] == edge)
571 : 0 : return flip_edge(i);
572 : : }
573 : 0 : return CUBIT_FAILURE;
574 : : }
575 : :
576 : 0 : CubitStatus CubitFacetData::flip_edge( int this_edge_index )
577 : : {
578 : : // get point indices on this facet
579 : 0 : int this_pt1_index = (this_edge_index+1)%3;
580 : 0 : int this_pt2_index = (this_edge_index+2)%3;
581 : :
582 : : // get edge points
583 [ # # ]: 0 : CubitPoint* point1 = point(this_pt1_index);
584 [ # # ]: 0 : CubitPoint* point2 = point(this_pt2_index);
585 : :
586 : : // can only be one adjacent facet at edge
587 [ # # ]: 0 : DLIList<CubitFacet*> pt_facets;
588 [ # # ]: 0 : point1->shared_facets(point2, pt_facets);
589 [ # # ][ # # ]: 0 : if ( pt_facets.size() != 2 || !pt_facets.move_to(this) )
[ # # ][ # # ]
[ # # ]
[ # # # # ]
590 : 0 : return CUBIT_FAILURE;
591 : :
592 : : // get other facet
593 : 0 : CubitFacetData* other_facet = NULL;
594 [ # # ][ # # ]: 0 : if( pt_facets.get() == this )
595 : : {
596 [ # # ][ # # ]: 0 : other_facet = dynamic_cast<CubitFacetData*>(pt_facets.next());
597 : : }
598 : : else
599 [ # # ][ # # ]: 0 : if( pt_facets.next() == this )
600 : : {
601 [ # # ][ # # ]: 0 : other_facet = dynamic_cast<CubitFacetData*>( pt_facets.get() );
602 : : }
603 : : else
604 : : {
605 : 0 : assert(0);
606 : : return CUBIT_FAILURE;
607 : : }
608 : :
609 [ # # ]: 0 : assert(other_facet);
610 : :
611 : : // get indices on other facet
612 [ # # ]: 0 : int other_pt1_index = other_facet->point_index(point1);
613 : 0 : int other_pt2_index = (other_pt1_index+1)%3;
614 : 0 : int other_edge_index = (other_pt1_index+2)%3;
615 [ # # ][ # # ]: 0 : if ( other_facet->point(other_pt2_index) != point2 ) {
616 : 0 : other_pt2_index = other_edge_index;
617 : 0 : other_edge_index = (other_pt1_index+1)%3;
618 : : }
619 [ # # ][ # # ]: 0 : assert( other_facet->point(other_pt2_index) == point2 );
620 : :
621 : : // check facet orientation
622 [ # # ]: 0 : int this_flip_use = this->edge_use(this_edge_index);
623 [ # # ]: 0 : int other_flip_use = other_facet->edge_use(other_edge_index);
624 [ # # ]: 0 : if ( this_flip_use == other_flip_use )
625 : : {
626 : : // Facets don't have consistant normals!!
627 : 0 : assert(0);
628 : : return CUBIT_FAILURE;
629 : : }
630 : :
631 : : // get the opposite points on facets
632 [ # # ]: 0 : CubitPoint* this_other_pt = this->point(this_edge_index);
633 [ # # ]: 0 : CubitPoint* other_other_pt = other_facet->point(other_edge_index);
634 [ # # ]: 0 : if(this_other_pt == other_other_pt){
635 [ # # ][ # # ]: 0 : PRINT_WARNING("Unable to perform flip.\n");
[ # # ][ # # ]
636 : 0 : return CUBIT_FAILURE;
637 : : }
638 : :
639 : :
640 : : // get the edge that is to be moved from this to the other facet
641 [ # # ]: 0 : CubitFacetEdge* this_trade_edge = this->edge(this_pt2_index);
642 : : // get the edge thatis to be moved from the other facet to this
643 [ # # ]: 0 : CubitFacetEdge* other_trade_edge = other_facet->edge(other_pt1_index);
644 [ # # ]: 0 : if(this_trade_edge == other_trade_edge){
645 [ # # ][ # # ]: 0 : PRINT_WARNING("Unable to perform flip (2).\n");
[ # # ][ # # ]
646 : 0 : return CUBIT_FAILURE;
647 : : }
648 [ # # ]: 0 : int this_trade_use = this->edge_use(this_pt2_index);
649 [ # # ]: 0 : if ( this_trade_edge )
650 : : {
651 [ # # ]: 0 : this_trade_edge->remove_facet(this);
652 [ # # ]: 0 : this_trade_edge->add_facet(other_facet);
653 : : }
654 : :
655 [ # # ]: 0 : int other_trade_use = other_facet->edge_use(other_pt1_index);
656 [ # # ]: 0 : if ( other_trade_edge )
657 : : {
658 [ # # ]: 0 : other_trade_edge->remove_facet(other_facet);
659 [ # # ]: 0 : other_trade_edge->add_facet(this);
660 : : }
661 : :
662 : : // get the edge to flip and change its points
663 : : CubitFacetEdgeData* flip_edge
664 [ # # ][ # # ]: 0 : = dynamic_cast<CubitFacetEdgeData*>(edge(this_edge_index));
665 [ # # ]: 0 : if ( flip_edge )
666 : : {
667 : : // orient edge such that the edge uses stay the same
668 [ # # ]: 0 : int dir = (flip_edge->point(0) == point1);
669 [ # # ]: 0 : flip_edge->set_point( this_other_pt, 1-dir );
670 [ # # ]: 0 : flip_edge->set_point( other_other_pt, dir );
671 : : }
672 : :
673 : :
674 : : // change this facet
675 [ # # ]: 0 : this->edge( other_trade_edge, this_edge_index );
676 [ # # ]: 0 : this->edge_use( other_trade_use, this_edge_index );
677 [ # # ]: 0 : this->edge( flip_edge, this_pt2_index );
678 [ # # ]: 0 : this->edge_use( this_flip_use, this_pt2_index );
679 [ # # ]: 0 : point1->remove_facet(this);
680 [ # # ]: 0 : other_other_pt->add_facet(this);
681 [ # # ]: 0 : this->set_point( other_other_pt, this_pt1_index );
682 : :
683 : :
684 : : // change the other facet
685 [ # # ]: 0 : other_facet->edge( this_trade_edge, other_edge_index );
686 [ # # ]: 0 : other_facet->edge_use( this_trade_use, other_edge_index );
687 [ # # ]: 0 : other_facet->edge( flip_edge, other_pt1_index );
688 [ # # ]: 0 : other_facet->edge_use( other_flip_use, other_pt1_index );
689 [ # # ]: 0 : point2->remove_facet(other_facet);
690 [ # # ]: 0 : this_other_pt->add_facet(other_facet);
691 [ # # ]: 0 : other_facet->set_point( this_other_pt, other_pt2_index );
692 : :
693 : : // make sure everything is correct
694 : : #ifndef NDEBUG
695 [ # # ]: 0 : for ( int i = 0; i < 3; i++ )
696 : : {
697 [ # # ][ # # ]: 0 : if ( this->edge(i) )
698 : : {
699 : : int start_index, end_index;
700 [ # # ][ # # ]: 0 : if ( this->edge_use(i) == 1 )
701 : : {
702 : 0 : start_index = (i+1)%3;
703 : 0 : end_index = (i+2)%3;
704 : : }
705 : : else
706 : : {
707 [ # # ][ # # ]: 0 : assert(this->edge_use(i) == -1);
708 : 0 : start_index = (i+2)%3;
709 : 0 : end_index = (i+1)%3;
710 : : }
711 [ # # ][ # # ]: 0 : assert ( this->edge(i)->point(0) == this->point(start_index) );
[ # # ][ # # ]
712 [ # # ][ # # ]: 0 : assert ( this->edge(i)->point(1) == this->point(end_index) );
[ # # ][ # # ]
713 : : }
714 : :
715 [ # # ][ # # ]: 0 : if ( other_facet->edge(i) )
716 : : {
717 : : int start_index, end_index;
718 [ # # ][ # # ]: 0 : if ( other_facet->edge_use(i) == 1 )
719 : : {
720 : 0 : start_index = (i+1)%3;
721 : 0 : end_index = (i+2)%3;
722 : : }
723 : : else
724 : : {
725 [ # # ][ # # ]: 0 : assert(other_facet->edge_use(i) == -1);
726 : 0 : start_index = (i+2)%3;
727 : 0 : end_index = (i+1)%3;
728 : : }
729 [ # # ][ # # ]: 0 : assert ( other_facet->edge(i)->point(0) == other_facet->point(start_index) );
[ # # ][ # # ]
730 [ # # ][ # # ]: 0 : assert ( other_facet->edge(i)->point(1) == other_facet->point(end_index) );
[ # # ][ # # ]
731 : : }
732 : : }
733 : : #endif
734 : :
735 [ # # ]: 0 : return CUBIT_SUCCESS;
736 [ + - ][ + - ]: 6540 : }
|