|
cgma
|
#include <AutoMidsurfaceTool.hpp>
Public Member Functions | |
| AutoMidsurfaceTool () | |
| ~AutoMidsurfaceTool () | |
| CubitStatus | midsurface (DLIList< Body * > &body_list_in, DLIList< BodySM * > &body_list_out, DLIList< Body * > &old_bodies_midsurfaced, DLIList< double > &thickness_out, double lower_tol=CUBIT_DBL_MAX, double upper_tol=CUBIT_DBL_MAX, CubitBoolean delete_midsurfaced=CUBIT_FALSE, CubitBoolean preview=CUBIT_FALSE) |
Private Member Functions | |
| CubitBoolean | curve_in_surface (Curve *curve_in, Surface *surf_in) |
| CubitStatus | get_planar_mid_surface (RefFace *ref_face1, RefFace *ref_face2, BodySM *body_sm_to_trim_to, BodySM *&midsurface_body_sm, GeometryModifyEngine *gme_ptr) |
| CubitStatus | find_offset_pair_patches (DLIList< RefFace * > pairs_list_0, DLIList< RefFace * > pairs_list_1, DLIList< RefFace * > &red_faces, DLIList< RefFace * > &yellow_faces, DLIList< double > &offset_distances) |
| CubitStatus | random_loc_on_surface (Surface *face_ptr, CubitVector &loc) |
| CubitBoolean | check_surf_pairs (double min_thick, double max_thick, DLIList< RefFace * > check_list, Body *body_in) |
Definition at line 30 of file AutoMidsurfaceTool.hpp.
Definition at line 35 of file AutoMidsurfaceTool.cpp.
{
}
| AutoMidsurfaceTool::~AutoMidsurfaceTool | ( | ) | [inline] |
Definition at line 35 of file AutoMidsurfaceTool.hpp.
{}
| CubitBoolean AutoMidsurfaceTool::check_surf_pairs | ( | double | min_thick, |
| double | max_thick, | ||
| DLIList< RefFace * > | check_list, | ||
| Body * | body_in | ||
| ) | [private] |
Definition at line 884 of file AutoMidsurfaceTool.cpp.
{
double total_area = 0.0;
DLIList<RefVolume*> vol_list;
body_in->ref_volumes(vol_list);
double total_vol = 0;
for(int vol_cnt = 0; vol_cnt < vol_list.size(); vol_cnt++)
{
CubitVector cg;
double temp_volume;
vol_list[vol_cnt]->mass_properties(cg,temp_volume);
total_vol += temp_volume;
}
for(int i = 0;i<check_list.size();i++)
total_area += check_list[i]->area();
total_area/=2.0;
if(min_thick*total_area < total_vol && max_thick*total_area > total_vol)
return CUBIT_TRUE;
return CUBIT_FALSE;
}
| CubitBoolean AutoMidsurfaceTool::curve_in_surface | ( | Curve * | curve_in, |
| Surface * | surf_in | ||
| ) | [private] |
Definition at line 801 of file AutoMidsurfaceTool.cpp.
{
CubitVector loc_0;
CubitVector loc_1;
CubitVector loc_2;
curve_in->position_from_fraction(0.1,loc_0);
curve_in->position_from_fraction(0.5,loc_1);
curve_in->position_from_fraction(0.9,loc_2);
GeometryQueryEngine* gqe = surf_in->get_geometry_query_engine();
double tol = gqe->get_sme_resabs_tolerance();
CubitVector cl_pnt_0;
CubitVector cl_pnt_1;
CubitVector cl_pnt_2;
surf_in->closest_point(loc_0,&cl_pnt_0);
surf_in->closest_point(loc_1,&cl_pnt_1);
surf_in->closest_point(loc_2,&cl_pnt_2);
if(cl_pnt_0.distance_between(loc_0)<tol &&
cl_pnt_1.distance_between(loc_1)<tol &&
cl_pnt_2.distance_between(loc_2)<tol)
{
return CUBIT_TRUE;
}
return CUBIT_FALSE;
}
| CubitStatus AutoMidsurfaceTool::find_offset_pair_patches | ( | DLIList< RefFace * > | pairs_list_0, |
| DLIList< RefFace * > | pairs_list_1, | ||
| DLIList< RefFace * > & | red_faces, | ||
| DLIList< RefFace * > & | yellow_faces, | ||
| DLIList< double > & | offset_distances | ||
| ) | [private] |
Definition at line 830 of file AutoMidsurfaceTool.cpp.
{
return CUBIT_FAILURE;
}
| CubitStatus AutoMidsurfaceTool::get_planar_mid_surface | ( | RefFace * | ref_face1, |
| RefFace * | ref_face2, | ||
| BodySM * | body_sm_to_trim_to, | ||
| BodySM *& | midsurface_body_sm, | ||
| GeometryModifyEngine * | gme_ptr | ||
| ) | [private] |
Definition at line 695 of file AutoMidsurfaceTool.cpp.
{
CubitVector normal_1, normal_2, point_1, point_2, point_3;
CubitPlane plane_1, plane_2;
CubitVector p_mid, n_mid;
point_1 = ref_face1->center_point();
point_2 = ref_face2->center_point();
normal_1 = ref_face1->normal_at(point_1);
normal_2 = ref_face2->normal_at(point_2);
plane_1 = CubitPlane(normal_1,point_1);
plane_2 = CubitPlane(normal_2,point_2);
if(point_1 == point_2)
{
PRINT_ERROR( "In GeometryModifyTool:: get_planar_mid_surface\n"
" Since both surfaces share the same point, the midsurface is not well-defined\n");
return CUBIT_FAILURE;
}
else
{
CubitVector temp1 = point_2;
temp1 = plane_1.project(temp1);
temp1 -= point_2;
if ( temp1.length_squared() < GEOMETRY_RESABS*GEOMETRY_RESABS )
{
PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
" Since both planes are the same, the midsurface is not well-defined.\n");
return CUBIT_FAILURE;
}
}
if ( ( normal_1.about_equal( normal_2 ) ) || ( (-normal_1).about_equal( normal_2 ) ) )
{
p_mid = (point_1+point_2)/2;
n_mid = plane_1.normal();
}
else
{
CubitVector direction_of_line;
plane_1.intersect(plane_2,p_mid,direction_of_line);
direction_of_line.normalize();
// Find if point_1 and point_2 are on the line of intersection
// If they are, then the mid-plane is not well-defined
CubitVector p1 = point_1-p_mid;
CubitVector p2 = point_2-p_mid;
p1.normalize();
p2.normalize();
if(p1==direction_of_line || p1==-direction_of_line)
{
PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
" P1 is on the line of intersection.\n");
return CUBIT_FAILURE;
}
if(p2==direction_of_line || p2==-direction_of_line)
{
PRINT_ERROR("In GeometryModifyTool:: get_planar_mid_surface\n"
" P2 is on the line of intersection.\n");
return CUBIT_FAILURE;
}
CubitVector v1 = p1 - (p1%direction_of_line)*direction_of_line;
v1.normalize();
CubitVector v2 = p2 - (p2%direction_of_line)*direction_of_line;
v2.normalize();
n_mid = v1 - v2;
n_mid.normalize();
}
CubitPlane mid_plane(n_mid, p_mid);
point_1 = p_mid;
//find three points that will define the infinite plane from the
//mid plane.through the point in any direction just not along the
//normal direction
CubitVector Xdir(1,0,0), Ydir(0,1,0);
CubitVector direction1;
if ( ( ! n_mid.about_equal( Xdir ) ) && ( ! (-n_mid).about_equal( Xdir ) ) )
direction1 = Xdir + n_mid;
else
direction1 = Ydir + n_mid;
point_2 = p_mid + direction1;
point_2 = mid_plane.project(point_2);
direction1 = point_2-point_1;
CubitVector direction2 = direction1*n_mid;
point_3 = point_1 + direction2;
CubitStatus ret = gme_ptr->get_mid_plane(point_1, point_2, point_3,
body_sm_to_trim_to, midsurface_body_sm );
return ret;
}
| CubitStatus AutoMidsurfaceTool::midsurface | ( | DLIList< Body * > & | body_list_in, |
| DLIList< BodySM * > & | body_list_out, | ||
| DLIList< Body * > & | old_bodies_midsurfaced, | ||
| DLIList< double > & | thickness_out, | ||
| double | lower_tol = CUBIT_DBL_MAX, |
||
| double | upper_tol = CUBIT_DBL_MAX, |
||
| CubitBoolean | delete_midsurfaced = CUBIT_FALSE, |
||
| CubitBoolean | preview = CUBIT_FALSE |
||
| ) |
Definition at line 41 of file AutoMidsurfaceTool.cpp.
{
if(lower_limit == CUBIT_DBL_MAX)// no limit set
lower_limit = -CUBIT_DBL_MAX;
double lower_tol = CUBIT_DBL_MAX;
double upper_tol = CUBIT_DBL_MAX;
const double auto_thickness_margin = 0.05; // if the user wants to automatically find the search
// thickness then this var give the search margin around the
// guess
ProgressTool* prog_tool = 0;
if(body_list_in.size()>5)
prog_tool = AppUtil::instance()->progress_tool();
// At lease one body must be provided
if(body_list_in.size() < 1)
{
PRINT_ERROR( "No bodies given for midsurfacing\n" );
return CUBIT_FAILURE;
}
// The surfaceOverlapTool is persistent so we need to save the
// max_gap and such to restore them at the end or if we error out
// save current settings
double max_gap_save = SurfaceOverlapTool::instance()->get_gap_max();
double min_gap_save = SurfaceOverlapTool::instance()->get_gap_min();
int normal_type = SurfaceOverlapTool::instance()->get_normal_type();
CubitBoolean cubit_bool_save = SurfaceOverlapTool::instance()->get_check_within_bodies();
CubitBoolean skip_facing_surfaces = SurfaceOverlapTool::instance()->get_skip_facing_surfaces();
// we want to only find overlap within a body
SurfaceOverlapTool::instance()->set_check_within_bodies(CUBIT_TRUE);
// 1=any, 2=opposite, 3=same - we want to find only the overlaps that normals
// pointing in the opposite directions
SurfaceOverlapTool::instance()->set_normal_type(2);
// Don't pickup surfaces that face each other
SurfaceOverlapTool::instance()->set_skip_facing_surfaces(CUBIT_TRUE);
// list of bodies that fail to midsurface
DLIList<Body*> failing_bodies;
GeometryModifyEngine* gme = 0;
GeometryQueryEngine* gqe = 0;
// loop over every body and try to create midsurface(s)
int i = 0;
CubitStatus return_status = CUBIT_FAILURE;
if(prog_tool)
prog_tool->start(0,body_list_in.size());
for(i = body_list_in.size();i--;)
{
if(prog_tool)
prog_tool->step();
Body* cur_body = body_list_in[i];
if(!cur_body)
continue;
BodySM* body_sm = cur_body->get_body_sm_ptr();
if(!body_sm)
continue;
if(cur_body->is_sheet_body())
{
PRINT_INFO("Body %d is a sheet body.\n",cur_body->id());
continue;
}
// Grab the geometrymodify and geometryquery engines to use later
gqe = cur_body->get_geometry_query_engine();
gme = GeometryModifyTool::instance()->get_engine(body_sm);
if(!gqe || !gme)
continue;
// Here are the steps to finding/creating the midsurface
// 1. If the user did not give a thickness range to search then
// make an educated guess at the proper thickness range. The assumption
// is that the midsurface is a square and the thickness is constant.
// The resulting equation is a third order polynomial that is solved using
// a few newton iterations. The initial thickness guess is Volume/Area
// 2. Using the given search distances use the SurfaceOverlapTool to find
// surface pairs.
// 3. If there is only one surface pair then use the existing midsurface commands
// 4. Find if the surface pairs represent two surface patches
// 5. If there are only two surface patches try to offset one of the patches
// 6. (this step is commented out for now) - If 5 fails or there are more than
// two surface patches then try the following:
// - Use the manual midsurface creation function to create midsurfaces for each
// pair of surfaces.
// - Unite all of the created midsurfaces together
// - remove any surfaces that have a curve touching a surface pair
// - Regularize the resulting body
// 7. Done
{
PRINT_DEBUG_198("AUTOMATICALLY calculating search range\n");
DLIList<RefVolume*> vol_list;
cur_body->ref_volumes(vol_list);
double total_vol = 0;
double total_vol_bb = 0;
for(int vol_cnt = 0; vol_cnt < vol_list.size(); vol_cnt++)
{
CubitVector cg;
double temp_volume;
vol_list[vol_cnt]->mass_properties(cg,temp_volume);
CubitBox vol_bb = vol_list[vol_cnt]->bounding_box();
total_vol += temp_volume;
total_vol_bb += vol_bb.x_range()*vol_bb.y_range()*vol_bb.z_range();
}
if(total_vol<0 || total_vol > total_vol_bb)
{
PRINT_INFO("Could not midsurface Body %d - try healing the body.\n",cur_body->id());
failing_bodies.append(cur_body);
continue;
}
PRINT_DEBUG_198("Volume of %f\n",total_vol);
DLIList<RefFace*> face_list;
cur_body->ref_faces(face_list);
double total_surf = 0;
for(int surf_cnt = 0; surf_cnt < face_list.size(); surf_cnt++)
total_surf += face_list[surf_cnt]->area();
PRINT_DEBUG_198("Area of %f\n",total_surf);
double t_g = total_vol/(total_surf/2.0);
double initial_guess = t_g;
PRINT_DEBUG_198("Initial guess of thickness %f\n",t_g);
// use a newton solver to get a more accurate estimate the thickness of the volume
for(int n_i = 0;n_i<100;n_i++)
{
double tol_newton = GEOMETRY_RESABS;
double t_gn = t_g + tol_newton;
double f_prime = ((2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)
-(2.0*total_vol + sqrt(total_vol*t_gn*t_gn*t_gn)*4.0 - total_surf*t_gn))/
(t_g-t_gn);
// avoid divide by zero
if(fabs(f_prime)<tol_newton)
break;
double t_old = t_g;
t_g = t_g - (2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)/f_prime;
PRINT_DEBUG_198("Guess %d Thickness %f\n",n_i,t_g);
if(fabs(t_g-t_old)<tol_newton)
{
PRINT_DEBUG_198("Converged with thickness of %f in %d steps\n",t_g,n_i);
break;
}
if(t_g<0.0)
{
PRINT_DEBUG_198("thickness less than zero setting back to initial guess\n");
t_g = fabs(initial_guess);
break;
}
}
upper_tol = t_g + t_g*auto_thickness_margin;
lower_tol = t_g - t_g*auto_thickness_margin;
upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;
PRINT_DEBUG_198("Guessing a thickness of %f to %f\n",lower_tol,upper_tol);
}
// set the lower and upper search distances
SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
SurfaceOverlapTool::instance()->set_gap_min(lower_tol);
DLIList<RefFace*> ref_face_list,list1,list2;
DLIList<RefEntity*> faces_to_draw;
cur_body->ref_faces(ref_face_list);
// find the surface pairs
SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);
int tweak_iters = 4;
for(int tweak = 0;tweak<tweak_iters;tweak++)
{
// if we didn't find anything then the part may be long and selender so grow the search thickness
if(list1.size()==0 && list2.size() == 0)
{
if(tweak == tweak_iters-1 && lower_limit != -CUBIT_DBL_MAX && upper_limit != CUBIT_DBL_MAX)
{
// on the last try use the user defined limits
lower_tol = lower_limit;
upper_tol = upper_limit;
}
else
{
lower_tol = (upper_tol + lower_tol)/2.0;
upper_tol += lower_tol*auto_thickness_margin*2;
upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;
}
PRINT_DEBUG_198("Guessing again with thickness of %f to %f\n",lower_tol,upper_tol);
SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
SurfaceOverlapTool::instance()->set_gap_min(lower_tol);
SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);
}
DLIList<RefFace*> check_list;
check_list += list1;
check_list += list2;
if(check_list.size() == 0 )
continue;
// make sure the pairs will match the solid within 10% or so
if(!check_surf_pairs(lower_tol,upper_tol,check_list,cur_body))
{
list1.clean_out();
list2.clean_out();
continue;
}
break;
}
if(list1.size() != list2.size())
{
PRINT_INFO("Could not find workable surface pairs for Body %d - try using the Sheet Offset command. \n",cur_body->id());
failing_bodies.append(cur_body);
continue;
}
else if(list1.size() == 0 || list2.size() == 0)
{
PRINT_INFO("No surface pairs found for Body %d - try changing the search range\n",cur_body->id());
failing_bodies.append(cur_body);
continue;
}
// get the first pair and see if there are only two patches
DLIList<RefFace*> red_faces;
red_faces.append(list1[0]);
DLIList<RefFace*> yellow_faces;
yellow_faces.append(list2[0]);
DLIList<RefFace*> paired_faces;
paired_faces += list1;
paired_faces += list2;
paired_faces.uniquify_unordered();
// red surfaces
while(1)
{
int start_cnt = red_faces.size();
DLIList<RefEdge*> red_edges;
int j = 0;
for(j =0;j<red_faces.size();j++)
red_faces[j]->ref_edges(red_edges);
red_edges.uniquify_unordered();
for(j =0;j<red_edges.size();j++)
red_edges[j]->ref_faces(red_faces);
red_faces.uniquify_unordered();
red_faces.intersect_unordered(paired_faces);
if(start_cnt == red_faces.size())
break;
}
// yellow surfaces
while(1)
{
int start_cnt = yellow_faces.size();
DLIList<RefEdge*> yellow_edges;
int j = 0;
for(j =0;j<yellow_faces.size();j++)
yellow_faces[j]->ref_edges(yellow_edges);
yellow_edges.uniquify_unordered();
for(j =0;j<yellow_edges.size();j++)
yellow_edges[j]->ref_faces(yellow_faces);
yellow_faces.uniquify_unordered();
yellow_faces.intersect_unordered(paired_faces);
if(start_cnt == yellow_faces.size())
break;
}
DLIList<BodySM*> results;
bool midsurface_done = false;
if(DEBUG_FLAG(198))
{
int j = 0;
PRINT_INFO("Trying surface offset to create the mid_surface\n");
PRINT_INFO("Red surface ");
for(j = 0;j < red_faces.size();j++)
{
GfxDebug::draw_ref_face(red_faces[j],CUBIT_RED_INDEX);
PRINT_INFO("%d ",red_faces[j]->id());
}
PRINT_INFO("\nYellow surface ");
for(j = 0;j < yellow_faces.size();j++)
{
GfxDebug::draw_ref_face(yellow_faces[j],CUBIT_YELLOW_INDEX);
PRINT_INFO("%d ",yellow_faces[j]->id());
}
PRINT_INFO("\n");
}
// first check to see if we can use the simple midsurface functions
if(red_faces.size() == 1 && yellow_faces.size() == 1 &&
paired_faces.size() == red_faces.size() + yellow_faces.size())
{
RefFace* face_1 = red_faces[0];
RefFace* face_2 = yellow_faces[0];
midsurface_done = false;
if(face_1->geometry_type() == face_2->geometry_type())
{
Surface* surf_1 = face_1->get_surface_ptr();
Surface* surf_2 = face_2->get_surface_ptr();
BodySM* result_body;
// grab the distance between surfaces
CubitVector temp_vec0;
CubitVector temp_vec1;
double temp_dist = 0;
gqe->entity_entity_distance(
face_1->get_surface_ptr(),
face_2->get_surface_ptr(),
temp_vec0,temp_vec1,temp_dist);
switch(face_1->geometry_type())
{
case CONE_SURFACE_TYPE:
if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
{
midsurface_done = true;
results.append(result_body);
thickness_out.append(fabs(temp_dist));
}
break;
case PLANE_SURFACE_TYPE:
if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
{
midsurface_done = true;
results.append(result_body);
thickness_out.append(fabs(temp_dist));
}
break;
case SPHERE_SURFACE_TYPE:
if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
{
midsurface_done = true;
results.append(result_body);
thickness_out.append(fabs(temp_dist));
}
break;
case TORUS_SURFACE_TYPE:
if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
{
midsurface_done = true;
results.append(result_body);
thickness_out.append(fabs(temp_dist));
}
break;
case CYLINDER_SURFACE_TYPE:
if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
{
midsurface_done = true;
results.append(result_body);
thickness_out.append(fabs(temp_dist));
}
break;
default:
break;
}
}
}
if(!midsurface_done &&
paired_faces.size() == red_faces.size() + yellow_faces.size()) // just do the offset
{
int j = 0;
DLIList<double> offset_distances;
for(j = 0;j<list1.size();j++)
{
CubitVector temp_vec0;
CubitVector temp_vec1;
double temp_dist = 0;
if(!gqe->entity_entity_distance(
list1[j]->get_surface_ptr(),
list2[j]->get_surface_ptr(),
temp_vec0,temp_vec1,temp_dist))
{
break;
}
offset_distances.append(-temp_dist*.5);
}
DLIList<Surface*> red_surfs;
for(j = 0;j<red_faces.size();j++)
red_surfs.append(red_faces[j]->get_surface_ptr());
DLIList<Surface*> yellow_surfs;
for(j = 0;j<yellow_faces.size();j++)
yellow_surfs.append(yellow_faces[j]->get_surface_ptr());
// all of the surfaces are offset the same distance
double offset_distance = offset_distances[0];
bool old_error_flag = GET_ERROR_FLAG();
SET_ERROR_FLAG(false); // don't throw any gme errors
if( gme->create_offset_sheet(red_surfs,offset_distance,
NULL,NULL,results))
{
midsurface_done = true;
for(j = 0;j<results.size();j++) // for every body add a thickness
thickness_out.append(fabs(offset_distance*2.));
}
else if( gme->create_offset_sheet(yellow_surfs,offset_distance,
NULL,NULL,results)) // try the other direction
{
midsurface_done = true;
for(j = 0;j<results.size();j++) // for every body add a thickness
thickness_out.append(fabs(offset_distance*2.));
}
else
{
PRINT_INFO("Could not create midsurface for Body %d - try using the surface offset command\n",cur_body->id());
failing_bodies.append(cur_body);
}
SET_ERROR_FLAG(old_error_flag); // turn errors back on
}
if(!midsurface_done && paired_faces.size() != red_faces.size() + yellow_faces.size())
{
PRINT_INFO("Could not find workable surface pairs for Body %d - try changing the search range or \n"
" using the Sheet Offset command.\n",cur_body->id());
}
/*if(!midsurface_done)
{
if(DEBUG_FLAG(198))
PRINT_INFO("Trying the extend, unite, and trim method\n");
// okay now remove duplicate pairs and unsupported pairs
DLIList<Surface*> surf_list1;
DLIList<Surface*> surf_list2;
bool delete_and_exit = false;
for(int j = 0;j<list1.size();j++)
{
RefFace* face_1 = list1[j];
RefFace* face_2 = list2[j];
if(DEBUG_FLAG(198))
{
PRINT_INFO("Red surface ");
GfxDebug::draw_ref_face(face_1,CUBIT_RED_INDEX);
PRINT_INFO("%d ",face_1->id());
PRINT_INFO("\nYellow surface ");
GfxDebug::draw_ref_face(face_2,CUBIT_YELLOW_INDEX);
PRINT_INFO("%d ",face_2->id());
PRINT_INFO("\n");
}
if(face_1->geometry_type() != face_2->geometry_type())
continue;
Surface* surf_1 = face_1->get_surface_ptr();
surf_list1.append(surf_1);
Surface* surf_2 = face_2->get_surface_ptr();
surf_list2.append(surf_2);
BodySM* result_body;
switch(face_1->geometry_type())
{
case CONE_SURFACE_TYPE:
if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
results.append(result_body);
else
delete_and_exit = true;
break;
case PLANE_SURFACE_TYPE:
if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
results.append(result_body);
else
delete_and_exit = true;
break;
case SPHERE_SURFACE_TYPE:
if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
results.append(result_body);
else
delete_and_exit = true;
break;
case TORUS_SURFACE_TYPE:
if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
results.append(result_body);
else
delete_and_exit = true;
break;
case CYLINDER_SURFACE_TYPE:
if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
results.append(result_body);
else
delete_and_exit = true;
break;
default:
delete_and_exit = true;
break;
}
if(delete_and_exit)
{
PRINT_WARNING("Failed to pair surface %d with surface %d\n",face_1->id(),face_2->id());
break;
}
}
if(delete_and_exit)
{
failing_bodies.append(cur_body);
gqe->delete_solid_model_entities(results);
continue;
}
DLIList<BodySM*> unite_results;
if(results.size()>1)
{
bool reg_result = GeometryModifyTool::instance()->boolean_regularize();
GeometryModifyTool::instance()->boolean_regularize(true);
if(gme->unite(results,unite_results)== CUBIT_SUCCESS)
{
// if the unite works just add them to the result list
results = unite_results;
}
else
{
// clean up the created surfaces and move on to the next
// body
failing_bodies.append(cur_body);
gqe->delete_solid_model_entities(results);
GeometryModifyTool::instance()->boolean_regularize(reg_result);
continue;
}
GeometryModifyTool::instance()->boolean_regularize(reg_result);
}
// trim the hanging surfaces
DLIList<Surface*> paired_surfs;
paired_surfs += surf_list1;
paired_surfs += surf_list2;
DLIList<Curve*> all_curves;
int k = 0;
for(k = 0;k<results.size();k++)
results[k]->curves(all_curves);
all_curves.uniquify_unordered();
DLIList<Surface*> remove_surfs;
for(k = 0;k<all_curves.size();k++)
for(int m = 0;m<paired_surfs.size();m++)
if(curve_in_surface(all_curves[k],paired_surfs[m]))
all_curves[k]->surfaces(remove_surfs);
remove_surfs.uniquify_unordered();
body_list_out += results;
DLIList<BodySM*> tweak_results;
if(gme->tweak_remove(remove_surfs,tweak_results,CUBIT_FALSE))
{
results = tweak_results;
}
else
{
// clean up the created surfaces and move on to the next
// body
failing_bodies.append(cur_body);
gqe->delete_solid_model_entities(results);
continue;
}
DLIList<BodySM*> regularize_results;
// regularize the results
for(k = 0;k < results.size();k++)
{
BodySM* new_body = 0;
if(gme->regularize_body(results[k],new_body))
regularize_results.append(new_body);
else if(DEBUG_FLAG(198))
PRINT_INFO("Regularize failure\n");
}
results = regularize_results;
}*/
if(!midsurface_done)
{
failing_bodies.append(cur_body);
continue;
}
old_bodies_midsurfaced.append(cur_body);
if(delete_midsurfaced && !preview)
GeometryQueryTool::instance()->delete_Body(cur_body);
return_status = CUBIT_SUCCESS;
body_list_out += results;
}
if(prog_tool)
prog_tool->end();
PRINT_INFO("Successfully midsurface %d of %d bodies\n",body_list_out.size(),body_list_in.size());
if(preview)
{
for(int k = 0;k<body_list_out.size();k++)
{
DLIList<Surface*> preview_surfaces;
body_list_out[k]->surfaces(preview_surfaces);
for(int p = 0;p<preview_surfaces.size();p++)
GfxPreview::draw_surface_facets_shaded(preview_surfaces[p],CUBIT_BLUE_INDEX);
}
GfxPreview::flush();
if(gqe)
gqe->delete_solid_model_entities(body_list_out);
body_list_out.clean_out();
}
if(failing_bodies.size() > 0)
{
PRINT_INFO("\n");
PRINT_INFO("Failed to midsurface Body ");
for(i = 0;i<failing_bodies.size();i++)
PRINT_INFO("%d ",failing_bodies[i]->id());
PRINT_INFO("\n");
}
if(DEBUG_FLAG(198))
GfxDebug::flush();
SurfaceOverlapTool::instance()->set_check_within_bodies(cubit_bool_save);
SurfaceOverlapTool::instance()->set_gap_max(max_gap_save);
SurfaceOverlapTool::instance()->set_normal_type(normal_type);
SurfaceOverlapTool::instance()->set_gap_min(min_gap_save);
SurfaceOverlapTool::instance()->set_skip_facing_surfaces(skip_facing_surfaces);
return return_status;
}
| CubitStatus AutoMidsurfaceTool::random_loc_on_surface | ( | Surface * | face_ptr, |
| CubitVector & | loc | ||
| ) | [private] |
Definition at line 840 of file AutoMidsurfaceTool.cpp.
{
GMem g_mem;
GeometryQueryEngine* gqe = face_ptr->get_geometry_query_engine();
unsigned short norm_tol = 10;
double dist_tol = -1.0;
gqe->get_graphics( face_ptr, &g_mem, norm_tol, dist_tol );
if(g_mem.fListCount < 1)
{
// Decrease tolerance and try again (we can get this for small features)
norm_tol /= 2;
gqe->get_graphics( face_ptr, &g_mem, norm_tol, dist_tol);
}
if(g_mem.fListCount < 1)
{
// Lets give up
PRINT_ERROR( "Unable to find location on a surface\n" );
return CUBIT_FAILURE;
}
// Use the first triangle
GPoint p[3];
GPoint* plist = g_mem.point_list();
int* facet_list = g_mem.facet_list();
int c = 0;
p[0] = plist[facet_list[++c]];
p[2] = plist[facet_list[++c]];
p[1] = plist[facet_list[++c]];
// Get centroid
CubitVector p1( p[0].x, p[0].y, p[0].z );
CubitVector p2( p[2].x, p[2].y, p[2].z );
CubitVector p3( p[1].x, p[1].y, p[1].z );
CubitVector center = (p1 + p2 + p3)/3.0;
face_ptr->closest_point_trimmed(center,loc);
return CUBIT_SUCCESS;
}