|
cgma
|
#include <OffsetSplitTool.hpp>
Public Member Functions | |
| OffsetSplitTool () | |
| ~OffsetSplitTool () | |
| CubitStatus | split_surfaces_offset (DLIList< RefFace * > &ref_face_list, DLIList< RefEdge * > &edge_list, int num_segs, double distance, CubitBoolean divide_flg=CUBIT_FALSE, CubitBoolean blunt_flg=CUBIT_FALSE, CubitBoolean preview_flg=CUBIT_FALSE, CubitBoolean create_ref_edges_flg=CUBIT_FALSE) |
Private Member Functions | |
| CubitStatus | draw_preview (DLIList< Curve * > &curve_list, int color=CUBIT_BLUE_INDEX) |
| CubitStatus | draw_preview (Curve *curve_ptr, CubitBoolean flush=CUBIT_TRUE, int color=CUBIT_BLUE_INDEX) |
| Curve * | create_sweep_curve (Curve *curve_in, double distance, double chord_tol, CubitBoolean iterate=CUBIT_FALSE) |
| Surface * | create_sweep_section (Curve *path, double distance, CubitVector up_vector, double fraction=0.0) |
| BodySM * | create_sweep_body (Surface *section, Curve *path) |
| CubitStatus | create_ref_edges (DLIList< Curve * > &curve_list) |
| DLIList< Curve * > | create_divide_curves (DLIList< Curve * > &curve_list, Surface *surface_in, double distance) |
Private Attributes | |
| DLIList< Curve * > | sourceCurves |
Static Private Attributes | |
| static double | tolerance = .001 |
Definition at line 30 of file OffsetSplitTool.hpp.
Definition at line 38 of file OffsetSplitTool.cpp.
{
}
| OffsetSplitTool::~OffsetSplitTool | ( | ) | [inline] |
Definition at line 35 of file OffsetSplitTool.hpp.
{}
| DLIList< Curve * > OffsetSplitTool::create_divide_curves | ( | DLIList< Curve * > & | curve_list, |
| Surface * | surface_in, | ||
| double | distance | ||
| ) | [private] |
Definition at line 682 of file OffsetSplitTool.cpp.
{
DLIList<Curve*> return_list;
curve_list.reset();
int curve_list_size = curve_list.size();
for(int i = curve_list_size; i--;)
{
Curve* cur_curve = curve_list.get_and_step();
GeometryModifyEngine* gme =
GeometryModifyTool::instance()->get_engine( cur_curve );
GeometryQueryEngine* gqe =
cur_curve->get_geometry_query_engine();
// Find the matching source curve.
// there are better ways to do this such as using the surface
// arc intersection but that only seems to work for one engine or another
// not both
for(int j = sourceCurves.size(); j--;)
{
Curve* source_curve = sourceCurves.get_and_step();
CubitVector coord1;
CubitVector coord2;
double distance_out = 0.0;
if(!gqe->entity_entity_distance( source_curve, cur_curve,
coord1, coord2, distance_out ))
continue;
if(fabs(distance_out-distance) < tolerance)
{
// check three points
CubitVector pnt_0;
CubitVector pnt_1;
CubitVector pnt_2;
CubitVector pnt_3;
CubitVector pnt_4;
CubitVector pnt_5;
cur_curve->position_from_fraction(0.0,pnt_0);
source_curve->closest_point(pnt_0,pnt_1);
cur_curve->position_from_fraction(0.5,pnt_2);
source_curve->closest_point(pnt_2,pnt_3);
cur_curve->position_from_fraction(1.0,pnt_4);
source_curve->closest_point(pnt_4,pnt_5);
if(fabs(pnt_0.distance_between(pnt_1) - distance) < tolerance &&
fabs(pnt_2.distance_between(pnt_3) - distance) < tolerance &&
fabs(pnt_4.distance_between(pnt_5) - distance) < tolerance)
{
// ok now just create curves between each end of the surface intersection curves
// and the projection to the source curves
// first curve
TBPoint* start_point_0 = gme->make_Point(pnt_0);
TBPoint* end_point_0 = gme->make_Point(pnt_1);
CubitVector vert3_coord_0 = start_point_0->coordinates();
Curve* new_curve_0 =
gme->make_Curve(STRAIGHT_CURVE_TYPE,
start_point_0,end_point_0,&vert3_coord_0 );
// second curve
TBPoint* start_point_1 = gme->make_Point(pnt_4);
TBPoint* end_point_1 = gme->make_Point(pnt_5);
CubitVector vert3_coord_1 = start_point_1->coordinates();
Curve* new_curve_1 =
gme->make_Curve(STRAIGHT_CURVE_TYPE,
start_point_1,end_point_1,&vert3_coord_1 );
// if the target surface is not a plane then do a projection
if(target_surface->geometry_type() != PLANE_SURFACE_TYPE)
{
DLIList<Curve*> curves_in;
if(new_curve_0)
curves_in.append(new_curve_0);
if(new_curve_1)
curves_in.append(new_curve_1);
DLIList<Curve*> curves_out;
DLIList<Surface*> surface_in;
surface_in.append(target_surface);
if(gme->project_edges(surface_in,curves_in,curves_out))
return_list += curves_out; // add the curves to the return list
}
else // add the curves to the return list
{
if(new_curve_0)
return_list.append(new_curve_0);
if(new_curve_1)
return_list.append(new_curve_1);
}
}
}
}
}
return return_list;
}
| CubitStatus OffsetSplitTool::create_ref_edges | ( | DLIList< Curve * > & | curve_list | ) | [private] |
Definition at line 668 of file OffsetSplitTool.cpp.
{
int i;
Curve *curve_ptr;
curve_list.reset();
for( i=curve_list.size(); i--; )
{
curve_ptr = curve_list.get_and_step();
GeometryQueryTool::instance()->make_free_RefEdge(curve_ptr);
}
return CUBIT_SUCCESS;
}
| BodySM * OffsetSplitTool::create_sweep_body | ( | Surface * | section, |
| Curve * | path | ||
| ) | [private] |
Definition at line 646 of file OffsetSplitTool.cpp.
{
GeometryModifyEngine* gme =
GeometryModifyTool::instance()->get_engine( section );
DLIList<GeometryEntity*> ent_list;
ent_list.append(section);
DLIList<BodySM*> body_list;
DLIList<Curve*> path_list;
path_list.append(path);
gme->sweep_along_curve(ent_list,body_list,path_list, 0.0, 0,
CUBIT_FALSE, CUBIT_FALSE, CUBIT_FALSE);
if(body_list.size())
return body_list.get();
return 0;
}
| Curve * OffsetSplitTool::create_sweep_curve | ( | Curve * | curve_in, |
| double | distance, | ||
| double | chord_tol, | ||
| CubitBoolean | iterate = CUBIT_FALSE |
||
| ) | [private] |
Definition at line 408 of file OffsetSplitTool.cpp.
{
GeometryModifyEngine* gme =
GeometryModifyTool::instance()->get_engine( curve_in );
GeometryQueryEngine* gqe = curve_in->get_geometry_query_engine();
CubitVector start_pos;
CubitVector end_pos;
CubitVector dummy_pos;
CubitVector x_axis;
CubitVector y_axis;
CubitVector z_axis;
CubitVector curvature;
if(!curve_in->position_from_fraction(0.0,start_pos))
return 0;
if(!curve_in->position_from_fraction(1.0,end_pos))
return 0;
curve_in->closest_point(start_pos,dummy_pos,&z_axis,&curvature);
// check to see if the curve is planar
CubitBoolean is_planar = CUBIT_FALSE;
DLIList<Surface*> attached_surfs;
curve_in->surfaces(attached_surfs);
int i = 0;
for(i = 0;i < attached_surfs.size();i++)
{
Surface* cur_surf = attached_surfs.get_and_step();
if(cur_surf &&
cur_surf->geometry_type() == PLANE_SURFACE_TYPE)
{
CubitVector center_vec;
cur_surf->get_point_normal(center_vec,x_axis);
is_planar = CUBIT_TRUE;
break;
}
}
if(is_planar)
{
y_axis = z_axis*x_axis;
}
// If curvature is significant, use it to create the sweep coordinate system
else if(curvature.length() < CUBIT_DBL_MIN)
{
z_axis.orthogonal_vectors(x_axis,y_axis);
}
else
{
y_axis = curvature;
x_axis = z_axis*y_axis;
}
x_axis.normalize();
y_axis.normalize();
z_axis.normalize();
x_axis *=distance;
GeometryType geom_type = curve_in->geometry_type();
if(geom_type == STRAIGHT_CURVE_TYPE) // if the curve is a line just offset it
{
// has problems calculating the intersection curves of surface edges and surfaces
// so rotate the coordinate system to some angle that is less likely to be used
x_axis.normalize();
y_axis.normalize();
CubitVector move_vec = y_axis - x_axis;
y_axis = y_axis+(move_vec*.744561789854);
x_axis = z_axis*y_axis;
x_axis.normalize();
y_axis.normalize();
z_axis.normalize();
x_axis *=distance;
// just offset the curve
Curve* offset_curve = gme->make_Curve(curve_in);
gqe->translate(offset_curve,x_axis);
return offset_curve;
}
else if(geom_type == ARC_CURVE_TYPE ||
geom_type == ELLIPSE_CURVE_TYPE ||
is_planar) // if the curve is a arc just offset it
{
// just offset the curve
Curve* offset_curve = gme->make_Curve(curve_in);
gqe->translate(offset_curve,x_axis);
return offset_curve;
}
DLIList<CubitVector*> pnt_list;
CubitVector* loc_0 = new CubitVector(start_pos);
CubitVector* loc_1 = new CubitVector(end_pos);
pnt_list.append(loc_0);
pnt_list.append(loc_1);
DLIList<double> frac_list;
frac_list.append(0.0);
frac_list.append(1.0);
frac_list.reset();
// create the curve points with a maximum deviation of 'chord_tol'
while(1)
{
double frac_0 = frac_list.get_and_step();
double frac_1 = frac_list.get();
pnt_list.step();
if(frac_0>frac_1)
break;
CubitVector tmp_pos_0;
curve_in->position_from_fraction(frac_0,tmp_pos_0);
CubitVector tmp_pos_1;
curve_in->position_from_fraction(frac_1,tmp_pos_1);
CubitVector tmp_pos_2 = (tmp_pos_0+tmp_pos_1)/2.0;
CubitVector tmp_pos_3;
double mid_frac = (frac_0+frac_1)/2.0;
curve_in->position_from_fraction(mid_frac,tmp_pos_3);
if(tmp_pos_3.distance_between(tmp_pos_2) > chord_tol)
{
CubitVector* loc = new CubitVector(tmp_pos_3);
pnt_list.back();
frac_list.back();
pnt_list.insert(loc);
frac_list.insert(mid_frac);
pnt_list.back();
frac_list.back();
}
}
// generate the offset curve points
CubitVector last_vec = x_axis;
pnt_list.reset();
for(i = 0;i < pnt_list.size();i++)
{
CubitVector curv,tangent,dummy;
CubitVector *cur_pnt = pnt_list.get_and_step();
curve_in->closest_point(*cur_pnt,dummy,&tangent,&curv);
// if the radius of curvature is smaller than the distance of the
// sweep offset then return a NULL curve
if(curvature.length()> CUBIT_DBL_MIN &&
1.0/(curv.length()) <= distance)
{
// clean out the points
for(int i =pnt_list.size();i--;)
delete pnt_list.get_and_step();
PRINT_WARNING("Radius of curvature is smaller than or equal to %f.\n"
"Cannot offset curve.\n",distance);
return 0;
}
CubitVector up_vec = tangent*last_vec;
CubitVector offset_vec = up_vec*tangent;
offset_vec.normalize();
offset_vec *= distance;
cur_pnt->set(*cur_pnt + offset_vec);
last_vec = offset_vec;
}
// create a spline sweep path
pnt_list.reset();
TBPoint* start_point = gme->make_Point(*(pnt_list.get_and_back()));
TBPoint* end_point = gme->make_Point(*(pnt_list.get_and_step()));
// Create the curve
Curve* curve_out =
gme->make_Curve(
SPLINE_CURVE_TYPE,
start_point,end_point,pnt_list);
pnt_list.reset();
for(i =pnt_list.size();i--;)
delete pnt_list.get_and_step();
pnt_list.clean_out();
return curve_out;
}
| Surface * OffsetSplitTool::create_sweep_section | ( | Curve * | path, |
| double | distance, | ||
| CubitVector | up_vector, | ||
| double | fraction = 0.0 |
||
| ) | [private] |
Definition at line 596 of file OffsetSplitTool.cpp.
{
up_vector.normalize();
GeometryModifyEngine* gme =
GeometryModifyTool::instance()->get_engine( path );
CubitVector start_pos;
CubitVector dummy_pos;
CubitVector x_axis;
CubitVector y_axis;
CubitVector z_axis;
if(!path->position_from_fraction(fraction,start_pos))
return 0;
path->closest_point(start_pos,dummy_pos,&z_axis);
y_axis = z_axis*up_vector;
x_axis = up_vector;
x_axis.normalize();
y_axis.normalize();
z_axis.normalize();
TBPoint* start_point = gme->make_Point(start_pos+x_axis);
TBPoint* end_point = gme->make_Point(start_pos-x_axis);
TBPoint* center_point = gme->make_Point(start_pos);
Curve* arc_curve_0 =
gme->create_arc_center_edge(center_point,start_point,end_point,z_axis,distance);
start_point = gme->make_Point(start_pos+x_axis);
end_point = gme->make_Point(start_pos-x_axis);
center_point = gme->make_Point(start_pos);
Curve* arc_curve_1 =
gme->create_arc_center_edge(center_point,start_point,end_point,-z_axis,distance);
DLIList<Curve*> curve_list;
curve_list.append(arc_curve_0);
curve_list.append(arc_curve_1);
Surface* surf_out =
gme->make_Surface(PLANE_SURFACE_TYPE,curve_list,0,false);
return surf_out;
}
| CubitStatus OffsetSplitTool::draw_preview | ( | DLIList< Curve * > & | curve_list, |
| int | color = CUBIT_BLUE_INDEX |
||
| ) | [private] |
Definition at line 360 of file OffsetSplitTool.cpp.
{
int i;
Curve *curve_ptr;
curve_list.reset();
for( i=curve_list.size(); i--; )
{
curve_ptr = curve_list.get_and_step();
draw_preview( curve_ptr, CUBIT_FALSE, color );
}
GfxPreview::flush();
return CUBIT_SUCCESS;
}
| CubitStatus OffsetSplitTool::draw_preview | ( | Curve * | curve_ptr, |
| CubitBoolean | flush = CUBIT_TRUE, |
||
| int | color = CUBIT_BLUE_INDEX |
||
| ) | [private] |
Definition at line 378 of file OffsetSplitTool.cpp.
{
CubitStatus result;
GMem g_mem;
// get the graphics
result = curve_ptr->get_geometry_query_engine()->
get_graphics( curve_ptr, &g_mem );
if (result==CUBIT_FAILURE || g_mem.pointListCount == 0)
{
PRINT_WARNING("Unable to preview a curve\n" );;
double len = curve_ptr->
length_from_u(curve_ptr->start_param(),curve_ptr->end_param());
PRINT_WARNING("Curve len: %f\n",len);
}
// Draw the polyline
GfxPreview::draw_polyline( g_mem.point_list(), g_mem.pointListCount, color );
if( flush )
GfxPreview::flush();
return CUBIT_SUCCESS;
}
| CubitStatus OffsetSplitTool::split_surfaces_offset | ( | DLIList< RefFace * > & | ref_face_list, |
| DLIList< RefEdge * > & | edge_list, | ||
| int | num_segs, | ||
| double | distance, | ||
| CubitBoolean | divide_flg = CUBIT_FALSE, |
||
| CubitBoolean | blunt_flg = CUBIT_FALSE, |
||
| CubitBoolean | preview_flg = CUBIT_FALSE, |
||
| CubitBoolean | create_ref_edges_flg = CUBIT_FALSE |
||
| ) |
Definition at line 42 of file OffsetSplitTool.cpp.
{
ref_face_list.uniquify_unordered();
edge_list.uniquify_unordered();
// Check for valid number of segments
if( num_segs < 1 )
{
PRINT_ERROR( "Number of specified segments must be >= 1\n" );
return CUBIT_FAILURE;
}
if(ref_face_list.size() < 1)
{
PRINT_ERROR( "No surfaces specified for splitting\n" );
return CUBIT_FAILURE;
}
if(edge_list.size() < 1)
{
PRINT_ERROR( "No curves specified for splitting\n" );
return CUBIT_FAILURE;
}
// clear the preview graphics
GfxPreview::clear();
DLIList<Curve*> offset_curves;
DLIList<DLIList<Curve*>*> imprint_list;
for(int seg = 1;seg<num_segs+1;seg++)
{
// set the current distance
double distance = (distance_in/(double)num_segs)*(seg);
// generate a swept body at each curve
DLIList<BodySM*> body_list;
DLIList<TBPoint*> points;
GeometryModifyEngine* gme = 0;
GeometryQueryEngine* gqe = 0;
edge_list.reset();
int i = 0;
for(i =edge_list.size();i--;)
{
RefEdge* ref_edge = edge_list.get_and_step();
Curve* cur_curve = ref_edge->get_curve_ptr();
// add the curve to the class list of source curves
// will use this latter for dividing surfaces
sourceCurves.append(cur_curve);
gqe = cur_curve->get_geometry_query_engine();
gme = GeometryModifyTool::instance()->get_engine(cur_curve);
tolerance = gqe->get_sme_resabs_tolerance();
if(!gme)
{
PRINT_ERROR( "No ModifyEngine found!\n" );
return CUBIT_FAILURE;
}
cur_curve->points(points);
Curve* swept_curve = create_sweep_curve(cur_curve,distance,tolerance,CUBIT_TRUE);
if(!swept_curve)
{
PRINT_WARNING("Failed to create offset geometry for curve %d.\n",ref_edge->id());
continue;
}
CubitVector swpt_loc, source_loc;
cur_curve->position_from_fraction(0.0,source_loc);
swept_curve->position_from_fraction(0.0,swpt_loc);
CubitVector up_vector = swpt_loc-source_loc;
Surface* section = create_sweep_section(cur_curve,distance,up_vector);
if(!section)
{
PRINT_WARNING("Failed to create offset geometry for curve %d.\n",ref_edge->id());
// delete the Curve path
gqe->delete_solid_model_entities(swept_curve);
continue;
}
BodySM* swept_body = create_sweep_body(section,swept_curve);
// delete the Curve path and Surface section
gqe->delete_solid_model_entities(swept_curve);
if(!swept_body)
{
PRINT_WARNING("Failed to create offset geometry for curve %d.\n",ref_edge->id());
continue;
}
body_list.append(swept_body);
}
if(body_list.size() == 0)
{
PRINT_ERROR("Failed to offset any curve.\n");
return CUBIT_FAILURE;
}
DLIList<TBPoint*> blunt_points;
if(blunt_flg == CUBIT_TRUE)
{
for(i = 0; i < points.size(); i++)
{
bool remove_point = true;
CubitVector pnt_loc_0 = points[i]->coordinates();
int j = 0;
for(j = 0;j < points.size(); j++)
{
if(i==j)
continue;
if(points[j] == points[i])
{
remove_point = false;
break;
}
CubitVector pnt_loc_1 = points[j]->coordinates();
if(pnt_loc_1.within_tolerance(pnt_loc_0,tolerance))
{
remove_point = false;
break;
}
}
if(remove_point)
blunt_points.append(points[i]);
}
}
points.uniquify_ordered();
points -= blunt_points;
for(i = points.size(); i--;)
{
BodySM* shpere_body = gme->sphere(distance);
CubitVector trans_dist = points.get_and_step()->coordinates();
gqe->translate(shpere_body,trans_dist);
body_list.append(shpere_body);
}
// create the offset geometry for debuging
#ifdef OFFSET_SPLIT_DEBUG
for(i=body_list.size();i--;)
{
GeometryQueryTool::instance()->make_Body(
gme->copy_body(body_list.get_and_step()));
}
#endif
DLIList<BodySM*> united_body_list;
if(body_list.size() == 1)
united_body_list = body_list;
else
{
if(!gme->unite(body_list,united_body_list))//united_body_list))
{
if(body_list.size() == 1)
PRINT_ERROR( "Offset split failed at the unite step.\n" );
else
PRINT_ERROR( "Offset split failed at the unite step. Try reducing the curve count\n" );
// delete the solid bodies
for(i = body_list.size(); i--;)
gqe->delete_solid_model_entities(body_list.get_and_step());
return CUBIT_FAILURE;
}
}
// get the surfaces contained in the body
DLIList<Surface*> surface_united_list;
for(i = united_body_list.size(); i--;)
{
BodySM* cur_body = united_body_list.get_and_step();
cur_body->surfaces(surface_united_list);
}
ref_face_list.reset();
imprint_list.reset();
for(i = ref_face_list.size(); i--;)
{
Surface* surf_1 = ref_face_list.get_and_step()->get_surface_ptr();
DLIList<Curve*> cur_curves;
for(int j = surface_united_list.size(); j--;)
{
DLIList<Curve*> intersection_curves;
Surface* surf_2 = surface_united_list.get_and_step();
gme->surface_intersection(surf_1,surf_2,intersection_curves,0.0);
// remove any very small curves from the intersection graph
// for some reason seems to return zero length curves
for(int k = intersection_curves.size();k--;)
{
Curve* cur_curve = intersection_curves[k];
double len = cur_curve->
length_from_u(cur_curve->start_param(),cur_curve->end_param());
if(fabs(len) < tolerance)
{
intersection_curves.remove(cur_curve);
gqe->delete_solid_model_entities(cur_curve);
}
}
// do the division if the user asks for it
if(divide_flg &&
num_segs == seg &&
// skip the curves created by sphere surfaces
surf_2->geometry_type() != SPHERE_SURFACE_TYPE &&
surf_2->geometry_type() != PLANE_SURFACE_TYPE)
{
intersection_curves +=
this->create_divide_curves(intersection_curves,surf_1,distance);
}
cur_curves += intersection_curves;
}
DLIList<Curve*>* surf_inter_list = 0;
if(ref_face_list.size() > imprint_list.size())
{
surf_inter_list = new DLIList<Curve*>;
imprint_list.append(surf_inter_list);
}
else
surf_inter_list = imprint_list.get_and_step();
(*surf_inter_list) += cur_curves;
offset_curves += cur_curves;
// draw the preview as the offset curves are being calculated
if(preview_flg && !create_ref_edges_flg)
draw_preview(cur_curves);
}
// delete the solid bodies
for(i = united_body_list.size(); i--;)
gqe->delete_solid_model_entities(united_body_list.get_and_step());
}
// ok, now do the imprint or preview
if(preview_flg)
{
if(!create_ref_edges_flg)
{
//Delete the Curve entities
for(int i=0;i<offset_curves.size();i++)
{
Curve* cur_curve = offset_curves.get_and_step();
cur_curve->get_geometry_query_engine()->
delete_solid_model_entities(cur_curve);
}
}
else
{
create_ref_edges(offset_curves);
}
// delete the list that contained the curves that would have been imprinted
for(int i= imprint_list.size();i--;)
delete imprint_list.get_and_step();
}
// Imprint
else
{
int i = 0;
ref_face_list.reset();
DLIList<Surface*> surface_list;
for( i = ref_face_list.size(); i--;)
surface_list.append(ref_face_list.get_and_step()->get_surface_ptr());
Body *new_body_ptr;
if( GeometryModifyTool::instance()->imprint( surface_list,
imprint_list, new_body_ptr, false, false ) == CUBIT_FAILURE )
{
//Delete the Curve entities
for(i= offset_curves.size();i--;)
{
Curve* cur_curve = offset_curves.get_and_step();
cur_curve->get_geometry_query_engine()->
delete_solid_model_entities(cur_curve);
}
// delete the curves that would have been imprinted
for( i= imprint_list.size();i--;)
delete imprint_list.get_and_step();
return CUBIT_FAILURE;
}
//Delete the Curve entities
for( i= offset_curves.size();i--;)
{
Curve* cur_curve = offset_curves.get_and_step();
cur_curve->get_geometry_query_engine()->
delete_solid_model_entities(cur_curve);
}
// delete the curves that were used for imprinted
for( i= imprint_list.size();i--;)
delete imprint_list.get_and_step();
}
return CUBIT_SUCCESS;
}
DLIList<Curve*> OffsetSplitTool::sourceCurves [private] |
Definition at line 100 of file OffsetSplitTool.hpp.
double OffsetSplitTool::tolerance = .001 [static, private] |
Definition at line 103 of file OffsetSplitTool.hpp.