root/cgm/trunk/geom/virtual/CollapseAngleTool.cpp

Revision 1040, 34.1 KB (checked in by tautges, 2 years ago)

Version 10.2 of cgm.

Line 
1//-------------------------------------------------------------------------
2//- Filename:       CollapseAngleTool
3//- Purpose:  To collapse small angle for preparing for mesh
4//-      "collapse angle less than <angle> mesh_size <length> [preview]\n",
5//-      "collapse angle at vertex <id> curve <id> [arc_length <length>] curve
6//-       <id> [arc_length <length> | perpendicular | same_size | tangent]
7//-      [preview]\n"
8//-
9//- Creator:       Jiangtao Hu
10//- Creation date: 02/09/2005
11//-------------------------------------------------------------------------
12
13// ********** BEGIN STANDARD INCLUDES         **********
14// ********** END STANDARD INCLUDES           **********
15                                                                               
16// ********** BEGIN MOTIF INCLUDES            **********
17// ********** END MOTIF INCLUDES              **********
18                                                                               
19// ********** BEGIN ACIS INCLUDES             **********
20// ********** END ACIS INCLUDES               **********
21                                                                               
22// ********** BEGIN CUBIT INCLUDES            **********
23
24#include "GMem.hpp"                                                           
25#include "GeometryQueryTool.hpp"
26#include "GeomMeasureTool.hpp"
27#include "RefVolume.hpp"
28#include "RefEdge.hpp"
29#include "RefFace.hpp"
30#include "RefVertex.hpp"
31#include "CollapseAngleTool.hpp"
32#include "Point.hpp"
33#include "CubitBox.hpp"
34#include "GfxDebug.hpp"
35#include "PartitionTool.hpp"
36#include "CubitUtil.hpp"
37#include "CompositeTool.hpp"
38// ********** END CUBIT INCLUDES              **********
39
40CollapseAngleTool *CollapseAngleTool::instance_ = NULL;
41// ********** BEGIN PUBLIC FUNCTIONS          **********
42CollapseAngleTool *CollapseAngleTool::instance()
43{
44  if (instance_ == NULL) instance_ = new CollapseAngleTool();
45                                                                               
46  return instance_;
47}
48
49void CollapseAngleTool::collapse_one_angle(RefVertex *vex_ptr,
50                                           RefEdge   *edge_to_remove,
51                                           RefEdge   *the_other_edge,
52                                           double     length1,
53                                           double     length2,
54                                           CubitBoolean get_position,
55                                           CubitVector  &position,
56                                           CubitBoolean preview,
57                                           CubitBoolean if_comp_vertex,
58                                           double       angle)
59{
60    if (CUBIT_TRUE == preview)
61       draw_preview(vex_ptr, edge_to_remove, the_other_edge, length1,
62                    length2, get_position, position);
63    else
64    {
65       collapse_angle( vex_ptr, edge_to_remove, the_other_edge,
66                       length1, length2, get_position, position);
67       if (if_comp_vertex)
68       {
69          DLIList<RefEdge*> edge_list;
70          vex_ptr->ref_edges(edge_list);
71          if (edge_list.size() == 2)
72          {
73             DLIList<RefEdge*> composite_edges;
74             angle *= (CUBIT_PI / 180);
75             int id = vex_ptr->id();
76             CompositeTool::instance()->composite(edge_list, composite_edges,
77                                                  NULL, angle);   
78             if (composite_edges.size() > 0)
79             {
80                DLIList<int> id_list;
81                id_list.append(id);
82                CubitUtil::list_entity_ids("Composite out of vertex ", id_list);
83             }
84          }
85       }
86    }
87}
88
89CubitStatus CollapseAngleTool::auto_collapse(double length,
90                                             double angle,
91                                             CubitBoolean preview,
92                                             CubitBoolean if_comp_vertex,
93                                             double       max_angle)
94{
95    //clear out the partly_drawn_curve list
96    partly_drawn_curve.clean_out();
97    //finding all angles less than 'angle'
98    DLIList<RefEntity*> entity_list;
99    DLIList<RefVolume*> volume_list;
100#ifdef BOYD17
101    DLIList<RefVolume*> final_volume_list;
102#endif
103    RefVolume * ref_volume;
104    DLIList <RefEdge *> large_edge_angles_list;
105    DLIList <RefEdge *> small_edge_angles_list;
106    DLIList <double> large_angles_list;
107    DLIList <double> small_angles_list;
108    int total_interior;
109    int total_fuzzy;
110    CubitStatus  result = CUBIT_SUCCESS;
111
112    // get an instance of GeometryQueryTool
113    GeometryQueryTool *gqt = GeometryQueryTool::instance();
114                                                                               
115    volume_list.clean_out();
116    result = gqt->ref_entity_list("volume", entity_list);
117    if (result == CUBIT_FAILURE || entity_list.size() < 1)
118    {
119      PRINT_ERROR("This command is prepared for volume mesh only.\n"
120                  "The angles must reside on volumes.\n");
121      return result;
122    }
123                                                                               
124    CAST_LIST(entity_list, volume_list, RefVolume);
125                                                                               
126    int i;
127    small_edge_angles_list.clean_out();
128    for (i=0; i < volume_list.size(); i++)
129    {
130       ref_volume = volume_list.get_and_step();
131       assert (ref_volume != NULL);
132       GeomMeasureTool::find_interior_curve_angles(ref_volume,
133                                                   360,
134                                                   angle,
135                                                   large_edge_angles_list,
136                                                   small_edge_angles_list,
137                                                   large_angles_list,
138                                                   small_angles_list,
139                                                   total_interior,
140                                                   total_fuzzy);
141    }
142                                                                               
143    //collapse small angles, use perpendicular to the second curve.
144    int size = small_edge_angles_list.size();
145    int init_size = size+1;
146    int index = 0;
147    RefVertex *vex_ptr = NULL;
148    RefEdge   *edge_to_remove = NULL;
149    RefEdge   *the_other_edge = NULL;
150    double    length1 = -1.0, length2 = -1.0;
151    CubitVector  position;
152
153    CubitBoolean if_step_over = CUBIT_FALSE;
154    while (size != 0)
155    {
156       if (init_size <= size)
157          break;
158       init_size = size;
159       small_edge_angles_list.reset();
160       assert (size%2 == 0);
161       double angle1, angle2;
162#ifdef BOYD17
163       DLIList<RefVertex *> vertex_list;
164#endif
165       if (CUBIT_TRUE == preview || CUBIT_TRUE == if_step_over)
166       {
167          if_step_over = CUBIT_FALSE;
168          for (i=0; i<index; i++)
169            small_edge_angles_list.step();
170       }
171                                                                               
172       //find the vertex for each edge pair.
173       edge_to_remove = small_edge_angles_list.get_and_step();
174       the_other_edge = small_edge_angles_list.get_and_step();
175       index += 2;
176       assert (edge_to_remove != NULL && the_other_edge != NULL);
177       vex_ptr = edge_to_remove->common_ref_vertex(the_other_edge);
178       if (vex_ptr == NULL)
179       {
180          size -= 2;
181          if_step_over = CUBIT_TRUE;
182          continue;
183       }
184                                                           
185       //check to make sure there's one common refface between the edges.
186       if(edge_to_remove->num_of_common_ref_face(the_other_edge) != 1)
187       {
188          PRINT_INFO("Curves %d and %d are not candidates for collapsing because\n",
189                     edge_to_remove->id(), the_other_edge->id());
190          PRINT_INFO("the two curves need to have exactly one common face.\n");
191          size -= 2;
192          if_step_over = CUBIT_TRUE;
193          continue;
194       }
195
196       //find the true to_be_removed edge
197       angle1 = the_surface_angle(edge_to_remove, vex_ptr, length);
198       angle2 = the_surface_angle(the_other_edge, vex_ptr, length);
199       if (angle1 != -1.0 && angle2 != -1.0 &&
200          (fabs(angle1 - CUBIT_PI) > fabs(angle2 - CUBIT_PI)))
201          exchange_edges(edge_to_remove, the_other_edge);
202       else if (angle1 == -1.0 || angle2 == -1.0 ||
203               (fabs(angle1 - CUBIT_PI) == fabs(angle2 - CUBIT_PI)))
204       {
205          //curved curve has higher priority than straight curve.
206          if ((edge_to_remove->geometry_type() == STRAIGHT_CURVE_TYPE)
207              &&(the_other_edge->geometry_type() != STRAIGHT_CURVE_TYPE))
208             exchange_edges(edge_to_remove, the_other_edge);
209                                                                               
210          //shorter curve has higher priority than longer curve.
211          else if (((edge_to_remove->geometry_type() != STRAIGHT_CURVE_TYPE)
212             &&(the_other_edge->geometry_type() != STRAIGHT_CURVE_TYPE)) ||
213              ((edge_to_remove->geometry_type() == STRAIGHT_CURVE_TYPE)
214              &&(the_other_edge->geometry_type() == STRAIGHT_CURVE_TYPE)))
215          {
216             if (edge_to_remove->get_arc_length() >
217                the_other_edge->get_arc_length())
218                exchange_edges(edge_to_remove, the_other_edge);
219          }
220       }//else if
221                                                                               
222       // determine the length1
223       if (length >= (edge_to_remove->get_arc_length() - GEOMETRY_RESABS))
224          length1 = -1.0;
225                                                                               
226       else
227          length1 = length;
228       //determine the position on curve2
229       RefVertex * tmp_vertex = edge_to_remove->other_vertex(vex_ptr);
230       CubitVector tmp_vec = tmp_vertex->coordinates();
231       if (length1 != -1.0)
232       {
233         result = position_from_length(edge_to_remove, vex_ptr, length1, tmp_vec);
234       }
235                                                                               
236       the_other_edge->closest_point(tmp_vec, position);
237                                                                               
238       //check if position is within the_other_edge
239       CubitBox position_box(position);
240       CubitBox edge_box = the_other_edge->bounding_box();
241                                                                               
242       // check if it's a preview command.
243       if (CUBIT_TRUE == preview)
244       {
245          if (!position_box.overlap(0, edge_box))
246             draw_preview(vex_ptr, edge_to_remove, the_other_edge,
247                          length1, -1.0, CUBIT_FALSE, position);
248                                                                               
249          else
250             draw_preview(vex_ptr, edge_to_remove, the_other_edge,
251                          length1, -1.0, CUBIT_TRUE, position);
252          size -= 2;
253          continue;
254       }
255                                                                               
256       //collapse angle
257       else if (!position_box.overlap(0, edge_box))
258          result = collapse_angle( vex_ptr, edge_to_remove, the_other_edge,
259                                   length1, -1.0, CUBIT_FALSE, position);
260       else
261          result = collapse_angle( vex_ptr, edge_to_remove, the_other_edge,
262                                   length1, length2, CUBIT_TRUE, position);
263       if (result != CUBIT_SUCCESS)
264       {
265          result = CUBIT_SUCCESS;
266          continue ;
267       }
268                                                                               
269       if (if_comp_vertex)
270       {
271          DLIList<RefEdge*> edge_list;
272          vex_ptr->ref_edges(edge_list);
273          int id = vex_ptr->id();
274          if (edge_list.size() == 2)
275          {
276             DLIList<RefEdge*> composite_edges;
277             max_angle *= (CUBIT_PI / 180);
278             CompositeTool::instance()->composite(edge_list, composite_edges,
279                                                  NULL, max_angle);
280             if (composite_edges.size() > 0)
281             {
282                DLIList<int> id_list;
283                id_list.append(id);
284                CubitUtil::list_entity_ids("Composite out of vertex ", id_list);
285             }
286          }
287       }
288
289       small_edge_angles_list.clean_out();
290       for (i=0; i < volume_list.size(); i++)
291       {
292          ref_volume = volume_list.get_and_step();
293          assert (ref_volume != NULL);
294          GeomMeasureTool::find_interior_curve_angles(ref_volume,
295                                                      360,
296                                                      angle,
297                                                      large_edge_angles_list,
298                                                      small_edge_angles_list,
299                                                      large_angles_list,
300                                                      small_angles_list,
301                                                      total_interior,
302                                                      total_fuzzy);
303       }
304       size = small_edge_angles_list.size();
305   }//while
306   return result;
307}
308
309// ********** END PUBLIC FUNCTIONS            **********
310                                                                               
311// ********** BEGIN PROTECTED FUNCTIONS       **********
312// ********** END PROTECTED FUNCTIONS         **********
313                                                                               
314// ********** BEGIN PRIVATE FUNCTIONS         **********
315CollapseAngleTool::CollapseAngleTool()
316{
317}
318
319CollapseAngleTool::~CollapseAngleTool()
320{
321}
322
323void  CollapseAngleTool::exchange_edges(RefEdge *&edge,
324                                        RefEdge *&the_other_edge)
325{
326   RefEdge* temp_edge;
327   temp_edge = edge;
328   edge = the_other_edge;
329   the_other_edge = temp_edge;
330}
331
332double CollapseAngleTool::the_surface_angle(RefEdge *edge,
333                                           RefVertex *root_vertex,
334                                           double  length)
335{
336   DLIList <RefFace *> ref_faces;
337   double arc_length = length/2;
338   double fraction;
339                                                                               
340   if (length > edge->get_arc_length())
341     arc_length = edge->get_arc_length()/2;
342                                                                               
343   fraction = edge->fraction_from_arc_length(root_vertex, arc_length);
344                                                                               
345   edge->ref_faces(ref_faces);
346   if (ref_faces.size() != 2)
347      return -1.0;
348                                                                               
349   double angle =  GeometryQueryTool::instance()->
350                 surface_angle(ref_faces.get_and_step(),ref_faces.get(),
351                 edge, NULL, fraction);
352   return angle;
353}
354
355CubitStatus CollapseAngleTool::position_from_length(RefEdge *edge,
356                                                  RefVertex *root_vertex,
357                                                  double  arc_length,
358                                                  CubitVector& v_new)
359{
360   CubitStatus result;
361   double sense = 1.0;
362   if (root_vertex != edge->start_vertex())
363      sense = -1.0;
364   CubitVector v_root = root_vertex->get_point_ptr()->coordinates();
365   result = edge->point_from_arc_length(v_root, arc_length*sense, v_new);
366   return result;
367}
368                                                                                 
369//Only change new_vertex when the partition succeeds.
370CubitStatus CollapseAngleTool::partition_curve(RefEdge *&edge,
371                                              RefVertex *root_vertex,
372                                              double  arc_length,
373                                              RefVertex *&new_vertex)
374{
375   CubitStatus  result = CUBIT_SUCCESS;
376   CubitVector v_new;
377   result = position_from_length(edge, root_vertex, arc_length, v_new);
378   if (result == CUBIT_SUCCESS)
379      result = partition_curve(edge, root_vertex, v_new, new_vertex);
380   return result;
381}
382                                                                               
383                                                                               
384//Only change new_vertex when the partition succeeds.
385CubitStatus CollapseAngleTool::partition_curve(RefEdge *&edge,
386                                              RefVertex *root_vertex,
387                                              CubitVector  &position,
388                                              RefVertex *&new_vertex)
389{
390   CubitStatus  result = CUBIT_SUCCESS;
391   DLIList<CubitVector*> vect_list;
392   vect_list.append(  new CubitVector( position ) );
393   DLIList<RefVertex*> vertex_list;
394   RefVertex* the_vertex = NULL;
395   edge->ref_vertices(vertex_list);
396   if (vertex_list.size() == 1)
397     the_vertex = vertex_list.get();
398
399   DLIList<RefEdge*> tmp_list;
400   result = PartitionTool::instance()->
401          partition( edge, vect_list, tmp_list );
402   delete vect_list.pop();
403   if (!result)
404   {
405      PRINT_ERROR("Split of curve %d failed.\n", edge->id());
406      return result;
407   }
408//Only change new_vertex when the partition succeeds.
409   RefEdge *temp_edge = tmp_list.get_and_step();
410   if (NULL != the_vertex)
411   {
412     new_vertex = temp_edge->other_vertex(the_vertex);
413     double len1 = temp_edge->get_arc_length();
414     double len2 = tmp_list.get()->get_arc_length();
415     if (len1 > len2)
416       edge =  tmp_list.get(); 
417     else   
418       edge = temp_edge;
419   }
420   else if (temp_edge != edge)
421   {
422     new_vertex = edge->common_ref_vertex(temp_edge);
423     if (root_vertex && edge->start_vertex() != root_vertex && 
424         edge->end_vertex() != root_vertex)
425       edge = temp_edge;
426   }
427   else
428   {
429     new_vertex = edge->common_ref_vertex(tmp_list.get());
430     if (root_vertex && edge->start_vertex() != root_vertex &&
431         edge->end_vertex() != root_vertex)
432       edge = tmp_list.get();
433   } 
434
435   return result;
436}
437                                                                               
438CubitStatus CollapseAngleTool::partition_surface(RefFace *common_face,
439                                                RefEdge *&edge_to_remove,
440                                                RefVertex *root,
441                                                RefVertex *vertex1,
442                                                RefVertex *vertex2,
443                                                RefFace  *&result_face)
444{
445   CubitStatus  result = CUBIT_SUCCESS;
446   DLIList<CubitVector*> positions;
447   positions.append(new CubitVector(vertex1->get_point_ptr()->coordinates()));
448   positions.append(new CubitVector(vertex2->get_point_ptr()->coordinates()));
449                                                                               
450   DLIList<RefEdge*> new_edges;
451   result_face = PartitionTool::instance()->
452      insert_edge( common_face, positions, CUBIT_FALSE, new_edges );
453                                                                               
454   RefEdge *new_edge = new_edges.get();
455   if(new_edge)
456   {
457     RefVertex * start = new_edge->start_vertex();
458     RefVertex * end = new_edge->end_vertex();
459     if (start != vertex1 && end != vertex1)
460       edge_to_remove = root->common_ref_edge(start == vertex2 ? end : start);
461   }
462
463   delete positions.get_and_step();
464   delete positions.get();
465   if( result_face == NULL )
466       result = CUBIT_FAILURE;
467                                                                               
468   return result;
469}
470
471CubitStatus CollapseAngleTool::draw_preview(RefVertex *vex_ptr,
472                                           RefEdge   *edge_to_remove,
473                                           RefEdge   *the_other_edge,
474                                           double     length1,
475                                           double     length2,
476                                           CubitBoolean get_position,
477                                           CubitVector &position)
478{
479   CubitStatus result = CUBIT_SUCCESS;
480 
481   //flush out previous drawing
482   GfxDebug::display_all();
483                                                                               
484   //wireframe display of future composite surface per design review.
485   DLIList<RefFace*> ref_faces;
486   edge_to_remove-> ref_faces(ref_faces);
487   RefFace *common_face = edge_to_remove->common_ref_face(the_other_edge);
488   assert(ref_faces.size() == 2);
489                                                                               
490   RefFace *highlight_surf = ref_faces.get_and_step();
491   if (highlight_surf == common_face)
492       highlight_surf = ref_faces.get();
493                                                                               
494   DLIList<RefEdge*> ref_edges;
495   highlight_surf->ref_edges(ref_edges);
496   ref_edges.remove(edge_to_remove);
497                                                                               
498   int i;
499   for (i = 0; i < partly_drawn_curve.size(); i++)
500      ref_edges.remove(partly_drawn_curve.get_and_step());
501
502   for(i = 0; i < ref_edges.size(); i++)
503      GfxDebug::draw_ref_entity(ref_edges.get_and_step(), CUBIT_BLUE);
504                                                                               
505   //check if there will be a cutting edge
506   CubitBoolean if_partition = if_partition_surf(vex_ptr, edge_to_remove,
507                                               common_face);
508   if (length1 == -1.0 && !get_position && length2 == -1.0 && !if_partition)
509   {
510      ref_edges.clean_out();
511      common_face->ref_edges(ref_edges);
512      ref_edges.remove(edge_to_remove);
513                                                                               
514      for (i = 0; i < partly_drawn_curve.size(); i++)
515         ref_edges.remove(partly_drawn_curve.get_and_step());
516
517      for(i = 0; i < ref_edges.size(); i++)
518        GfxDebug::draw_ref_entity(ref_edges.get_and_step(), CUBIT_BLUE);
519      return result;
520   }
521                                                                               
522   CubitVector location, location2, location3;
523   if (length1 == -1.0)
524       location = edge_to_remove->other_vertex(vex_ptr)->coordinates();
525                                                                               
526   if (length1 != -1.0)
527       result = position_from_length(edge_to_remove, vex_ptr,
528                                       length1, location);
529                                                                               
530   if ( !get_position && length2 == -1.0 &&
531        (length1 != -1.0 ||
532         (length1 == -1.0 && if_partition)))
533      location2=the_other_edge->other_vertex(vex_ptr)->coordinates();
534                                                                               
535   else if(get_position)
536      location2 = position;
537                                                                               
538   else if (length2 != -1.0)
539      result = position_from_length(the_other_edge, vex_ptr, length2, location2);
540                                                                               
541   GfxDebug::draw_line(location, location2, CUBIT_BLUE);
542                                                                               
543   //Draw part of curves
544   double length;
545   CubitVector temp_vex;
546   GPoint pts[5];
547   location3 = vex_ptr->coordinates();
548
549   partly_drawn_curve.append(the_other_edge);
550   partly_drawn_curve.append(edge_to_remove);
551   if (the_other_edge->geometry_type() == STRAIGHT_CURVE_TYPE)
552      GfxDebug::draw_line(location3, location2, CUBIT_BLUE);
553                                                                               
554   else
555   {
556      length = the_other_edge->get_arc_length(location2, location3);
557      pts[0].x = location3.x();
558      pts[0].y = location3.y();
559      pts[0].z = location3.z();
560      pts[4].x = location2.x();
561      pts[4].y = location2.y();
562      pts[4].z = location2.z();
563      position_from_length(the_other_edge, vex_ptr, length/4, temp_vex);
564      pts[1].x = temp_vex.x();
565      pts[1].y = temp_vex.y();
566      pts[1].z = temp_vex.z();
567      position_from_length(the_other_edge, vex_ptr, length/2, temp_vex);
568      pts[2].x = temp_vex.x();
569      pts[2].y = temp_vex.y();
570      pts[2].z = temp_vex.z();
571      position_from_length(the_other_edge, vex_ptr, length*0.75, temp_vex);
572      pts[3].x = temp_vex.x();
573      pts[3].y = temp_vex.y();
574      pts[3].z = temp_vex.z();
575      GfxDebug::draw_polyline(pts, 5, CUBIT_BLUE);
576   }
577                                                                               
578   RefVertex *vertex = edge_to_remove->other_vertex(vex_ptr);
579   location3 = vertex->coordinates();
580   if (edge_to_remove->geometry_type() == STRAIGHT_CURVE_TYPE)
581      GfxDebug::draw_line(location3, location, CUBIT_BLUE);
582                                                                               
583   else
584   {
585      length = edge_to_remove->get_arc_length(location, location3);
586      pts[0].x = location3.x();
587      pts[0].y = location3.y();
588      pts[0].z = location3.z();
589      pts[4].x = location.x();
590      pts[4].y = location.y();
591      pts[4].z = location.z();
592                                                                               
593      position_from_length(edge_to_remove, vertex, length/4, temp_vex);
594      pts[1].x = temp_vex.x();
595      pts[1].y = temp_vex.y();
596      pts[1].z = temp_vex.z();
597      position_from_length(edge_to_remove, vertex, length/2, temp_vex);
598      pts[2].x = temp_vex.x();
599      pts[2].y = temp_vex.y();
600      pts[2].z = temp_vex.z();
601      position_from_length(edge_to_remove, vertex, length*0.75, temp_vex);
602      pts[3].x = temp_vex.x();
603      pts[3].y = temp_vex.y();
604      pts[3].z = temp_vex.z();
605      GfxDebug::draw_polyline(pts, 5, CUBIT_BLUE);
606   }
607                                                                               
608   GfxDebug::flush();
609                                                                               
610   return result;
611}
612                                                                               
613CubitBoolean CollapseAngleTool::if_partition_surf(RefVertex *vex_ptr,
614                                                  RefEdge  *edge_to_remove,
615                                                  RefFace  *common_face)
616{
617   CubitBoolean partition_surface_ =CUBIT_FALSE;
618   RefVertex *temp_vtx = NULL;
619   RefEdge * temp_edge = NULL;
620   if (edge_to_remove->start_vertex() == vex_ptr)
621       temp_vtx = edge_to_remove->end_vertex();
622   else
623       temp_vtx = edge_to_remove->start_vertex();
624                                                                               
625   temp_edge = edge_to_remove->get_other_curve(temp_vtx, common_face);
626                                                                               
627   if (temp_edge->num_of_common_ref_face(edge_to_remove) > 1)
628       partition_surface_ = CUBIT_TRUE;
629                                                                               
630   return partition_surface_;
631}
632
633CubitStatus CollapseAngleTool::collapse_angle(RefVertex *vex_ptr,
634                                             RefEdge   *edge_to_remove,
635                                             RefEdge   *the_other_edge,
636                                             double     length1,
637                                             double     length2,
638                                             CubitBoolean get_position,
639                                             CubitVector &position)
640{
641  CubitStatus result = CUBIT_SUCCESS;
642  RefVertex *new_vertex1 = edge_to_remove->other_vertex(vex_ptr);
643  RefVertex *new_vertex2 = the_other_edge->other_vertex(vex_ptr);
644  DLIList<RefFace*> ref_faces;
645  edge_to_remove-> ref_faces(ref_faces);
646  RefFace *common_face = NULL;
647  DLIList<RefFace*> common_face_list;
648  int nfaces = edge_to_remove->num_of_common_ref_face(the_other_edge);
649
650  if (nfaces == 1)
651    common_face = edge_to_remove->common_ref_face(the_other_edge);
652  else
653  {
654    assert (nfaces == 2);
655    edge_to_remove->common_ref_faces(the_other_edge, common_face_list);
656  }
657
658  if (length1 != -1.0)
659  {
660    result = partition_curve(edge_to_remove, vex_ptr, length1, new_vertex1);
661    if (result != CUBIT_SUCCESS)
662    {
663       PRINT_ERROR("Operation failed at vertex %d, curve %d and curve %d.\n",
664                vex_ptr->id(), edge_to_remove->id(), the_other_edge->id());
665       return result;
666    }
667  }
668                                                                               
669  if (get_position)
670  {
671    result = partition_curve(the_other_edge, NULL, position, new_vertex2);
672    if (result != CUBIT_SUCCESS)
673    {
674       PRINT_ERROR("Operation failed at vertex %d, curve %d and curve %d.\n",
675                vex_ptr->id(), edge_to_remove->id(), the_other_edge->id());
676       return result;
677    }
678  }
679                                                                               
680  else if (!get_position && length2 != -1.0)
681  {
682    result = partition_curve(the_other_edge, vex_ptr, length2, new_vertex2);
683    if (result != CUBIT_SUCCESS)
684    {
685       PRINT_ERROR("Operation failed at vertex %d, curve %d and curve %d.\n",
686                vex_ptr->id(), edge_to_remove->id(), the_other_edge->id());
687       return result;
688    }
689  }
690                                                                               
691  if (nfaces > 1) //determine the common face.
692  {
693     CubitBox edge_box(new_vertex1->coordinates());
694     edge_box |= new_vertex2->bounding_box();
695     CubitBox face_box1, face_box2;
696     RefFace *face1, *face2;
697     face1 = common_face_list.get_and_step();
698     face2 = common_face_list.get();
699     face_box1 = face1->bounding_box();
700     face_box2 = face2->bounding_box();
701     if(edge_box.overlap(0, face_box1))
702     {
703       // Face 1 overlaps with the partition points.
704       if(edge_box.overlap(0, face_box2))
705       {
706         // Both face 1 and face 2 overlap with the parition points.
707         // We must do a further check to try to choose the best one.
708         // Take the mid point between the two vertices and calculate
709         // the distance from both faces.  Choose the one with the
710         // smaller distance.  This approach was chosen because there
711         // was a case where one of the potential common faces was
712         // actually a composite that had a 90 degree turn in it
713         // so that the end points of the edge that would be used
714         // to partition it fell on the composite surface but the
715         // rest of the interior of the edge didn't lie on the surface.
716         // However, the edge completely lied on the other potential
717         // surface and so it was the better candidate.
718         CubitVector mid_pos = (new_vertex1->coordinates() +
719                new_vertex2->coordinates())/2;
720         Surface *surf1 = face1->get_surface_ptr();
721         Surface *surf2 = face2->get_surface_ptr();
722         if(surf1 && surf2)
723         {
724           CubitVector pos1, pos2;
725           surf1->closest_point(mid_pos, &pos1);
726           surf2->closest_point(mid_pos, &pos2);
727           if((mid_pos - pos1).length_squared() <
728             (mid_pos - pos2).length_squared())
729           {
730             common_face = face1;
731           }
732           else
733           {
734             common_face = face2;
735           }
736         }
737         else
738         {
739            PRINT_ERROR("Operation failed because one of the potential common faces doesn't have a surface.\n");
740            return CUBIT_FAILURE;
741         }
742       }
743       else
744       {
745         // Only face 1 overlaps so use it as the common face.
746         common_face = face1;
747       }
748     }
749     else if(edge_box.overlap(0, face_box2))
750     {
751       // Only face 2 overlaps so use it as the common face.
752       common_face = face2;
753     }
754     else
755     {
756       // Neither face overlaps so throw an error.
757       PRINT_ERROR("Operation failed to find a valid common face for partitioning.\n");
758       return CUBIT_FAILURE;
759     }
760  }
761
762  CubitBoolean partition_surface_ = CUBIT_FALSE;
763  // check if edge_to_remove is the only one that shares the two surfaces.
764  if (length1 == -1.0)
765     partition_surface_ = if_partition_surf(vex_ptr, edge_to_remove,
766                                            common_face);
767                                                                               
768  RefFace * face_to_remove = common_face;
769  if (length1 != -1.0 || get_position || length2 != -1.0 || partition_surface_)
770  {
771     RefFace *result_face;
772     result = partition_surface(common_face, edge_to_remove, vex_ptr, 
773                                new_vertex1, new_vertex2, result_face);
774     if (result != CUBIT_SUCCESS)
775     {
776       PRINT_ERROR("Split of surface %d failed.\n", common_face->id());
777       PRINT_ERROR("Operation failed at vertex %d, curve %d and curve %d.\n",
778                vex_ptr->id(), edge_to_remove->id(), the_other_edge->id());
779       return result;
780     }
781                                                                               
782     DLIList<RefEdge*> ref_edges;
783     result_face->ref_edges(ref_edges);
784     int i;
785     for (i = 0; i <ref_edges.size(); i++)
786        if (ref_edges.get_and_step() == edge_to_remove)
787        {
788           face_to_remove = result_face;
789           break;
790        }
791  }
792                                                                               
793  if (face_to_remove != common_face)
794  {
795    ref_faces.remove(common_face);
796    ref_faces.append(face_to_remove);
797  }
798                                                                               
799  DLIList<RefFace*> result_faces;
800  CompositeTool::instance()->composite(ref_faces, result_faces);
801                                                                               
802  if( result_faces.size() > 0 )
803  {
804     DLIList<int> id_list;
805     int e;
806     for(  e = 0; e < result_faces.size(); e++)
807     {
808        id_list.append( result_faces.get_and_step()->id() );
809        CubitUtil::list_entity_ids("Created composite surfaces ", id_list );
810     }
811  }
812                                                                               
813  else
814  {
815     PRINT_ERROR("Operation failed at vertex %d, curve %d and curve %d.\n",
816                vex_ptr->id(), edge_to_remove->id(), the_other_edge->id());
817     result = CUBIT_FAILURE;
818  }
819
820  //composite out new_vertex1
821  DLIList<RefEdge*> edge_list;
822  RefEdge* composite_edge = NULL;
823  int id = new_vertex1->id();
824  new_vertex1->ref_edges(edge_list);
825  if (edge_list.size() == 2)
826    composite_edge = CompositeTool::instance()->composite(edge_list);
827  if (composite_edge)
828  {
829     DLIList<int> id_list;
830     id_list.append(id);
831     CubitUtil::list_entity_ids("Composite out of vertex ", id_list);
832  }
833
834  return result;
835}             
Note: See TracBrowser for help on using the browser.