cgma
|
00001 #include "SplitCompositeSurfaceTool.hpp" 00002 #include "GeometryModifyTool.hpp" 00003 #include "RefFace.hpp" 00004 #include "CompositeSurface.hpp" 00005 #include "CompositeCurve.hpp" 00006 #include "Curve.hpp" 00007 #include "Point.hpp" 00008 #include "GeometryModifyEngine.hpp" 00009 #include "GeometryQueryTool.hpp" 00010 00011 SplitCompositeSurfaceTool *SplitCompositeSurfaceTool::instance_ = NULL; 00012 00013 SplitCompositeSurfaceTool *SplitCompositeSurfaceTool::instance() 00014 { 00015 if (instance_ == NULL) 00016 instance_ = new SplitCompositeSurfaceTool(); 00017 00018 return instance_; 00019 } 00020 00021 CubitStatus SplitCompositeSurfaceTool::split_surface(RefFace *ref_face_ptr, 00022 DLIList<CubitVector*> &locations, 00023 DLIList<DLIList<CubitVector*>*> &vec_lists, 00024 CubitBoolean preview_flg, 00025 CubitBoolean create_ref_edges_flg, 00026 CubitBoolean clear_previous_previews) 00027 { 00028 get_additional_split_points(ref_face_ptr->get_surface_ptr(), vec_lists); 00029 00030 return GeometryModifyTool::instance()->split_surface(ref_face_ptr, 00031 locations, vec_lists, preview_flg, create_ref_edges_flg, clear_previous_previews); 00032 } 00033 00034 CubitStatus SplitCompositeSurfaceTool::split_surface(DLIList<RefFace*> &ref_face_list, 00035 DLIList<CubitVector*> &locations, 00036 DLIList<DLIList<DLIList<CubitVector*>*>*> &list_of_vec_lists, 00037 CubitBoolean preview_flg, 00038 CubitBoolean create_ref_edges_flg, 00039 CubitBoolean clear_previous_previews) 00040 { 00041 for( int jj = ref_face_list.size() ; jj > 0 ; jj--) 00042 { 00043 DLIList<DLIList<CubitVector*>*> vec_lists = *( list_of_vec_lists.get_and_step() ); 00044 00045 get_additional_split_points(ref_face_list.get_and_step()->get_surface_ptr(), vec_lists ); 00046 } 00047 00048 return GeometryModifyTool::instance()->split_surface(ref_face_list, 00049 locations, list_of_vec_lists, preview_flg, create_ref_edges_flg, clear_previous_previews); 00050 } 00051 00052 void SplitCompositeSurfaceTool::find_faces_for_pos(CubitVector &pos, DLIList<Surface*> surf_list, 00053 CubitPointContainment &containment, 00054 DLIList<Surface*> &out_list) 00055 { 00056 int j; 00057 00058 for(j=surf_list.size(); j>0; j--) 00059 { 00060 Surface *surf_ptr = surf_list.get_and_step(); 00061 containment = surf_ptr->point_containment(pos); 00062 if(containment == CUBIT_PNT_INSIDE || containment == CUBIT_PNT_BOUNDARY) 00063 out_list.append_unique(surf_ptr); 00064 } 00065 } 00066 00067 void SplitCompositeSurfaceTool::get_additional_split_points(Surface *surf, 00068 DLIList<DLIList<CubitVector*>*> &vec_lists) 00069 { 00070 int i, j, k, num_surfs; 00071 DLIList<Surface*> surf_list; 00072 00073 CompositeSurface *cs = dynamic_cast<CompositeSurface*>(surf); 00074 if(cs && (num_surfs = cs->num_surfs()) > 1) 00075 { 00076 for(i=0; i<num_surfs; i++) 00077 { 00078 Surface *surf = cs->get_surface(i); 00079 if(surf) 00080 surf_list.append(surf); 00081 } 00082 00083 DLIList<Curve*> hidden_curves; 00084 cs->get_hidden_curves(hidden_curves); 00085 00086 for(i=vec_lists.size(); i--;) 00087 { 00088 // Remove any hidden curves that already have points on them. 00089 DLIList<Curve*> hidden_curves_without_pts = hidden_curves; 00090 DLIList<CubitVector*> *vec_list = vec_lists.get_and_step(); 00091 for(j=vec_list->size(); j--;) 00092 { 00093 CubitVector *cur_vec = vec_list->get_and_step(); 00094 DLIList<Curve*> crvs_to_remove; 00095 for(k=hidden_curves_without_pts.size(); k>0; k--) 00096 { 00097 Curve *crv = hidden_curves_without_pts.get_and_step(); 00098 CubitVector foot; 00099 crv->closest_point_trimmed(*cur_vec, foot); 00100 if(foot.about_equal(*cur_vec)) 00101 crvs_to_remove.append_unique(crv); 00102 } 00103 hidden_curves_without_pts -= crvs_to_remove; 00104 } 00105 00106 // Now we should only have hidden curves with no points on them. 00107 if(hidden_curves_without_pts.size() > 0) 00108 { 00109 vec_list->reset(); 00110 CubitVector *cur_vec = vec_list->get(); 00111 CubitVector *last_vec = vec_list->prev(); 00112 while(cur_vec != last_vec) 00113 { 00114 vec_list->move_to(cur_vec); 00115 CubitVector *next_vec = vec_list->next(); 00116 DLIList<CubitVector*> tmp_list; 00117 DLIList<double> vals; 00118 tmp_list.append(cur_vec); 00119 tmp_list.append(next_vec); 00120 vals.append(0.0); 00121 vals.append(1.0); 00122 Curve *hidden_curve = hidden_curves_without_pts.get(); 00123 CompositeCurve *cc = dynamic_cast<CompositeCurve*>(hidden_curve); 00124 if(cc) 00125 hidden_curve = cc->get_curve(0); 00126 GeometryModifyEngine *gme = GeometryModifyTool::instance()-> 00127 get_engine(hidden_curve); 00128 TBPoint *pt1 = gme->make_Point(*cur_vec); 00129 TBPoint *pt2 = gme->make_Point(*last_vec); 00130 Curve *tmp_crv = gme->make_Curve(STRAIGHT_CURVE_TYPE, pt1, pt2, NULL); 00131 if(tmp_crv) 00132 { 00133 double arc_length = tmp_crv->get_arc_length(); 00134 for(j=hidden_curves_without_pts.size(); j--;) 00135 { 00136 CubitVector pos1, pos2; 00137 double dist; 00138 Curve *crv = hidden_curves_without_pts.get_and_step(); 00139 GeometryQueryTool::instance()->entity_entity_distance(crv, tmp_crv, pos1, pos2, dist); 00140 CubitVector v1 = *cur_vec - pos1; 00141 CubitVector v2 = *last_vec - pos1; 00142 v1.normalize(); 00143 v2.normalize(); 00144 if(v1 % v2 < .3) 00145 { 00146 CubitVector *new_vec = new CubitVector(pos1); 00147 v1 = (pt1->coordinates() - pos2); 00148 double percent = v1.length()/arc_length; 00149 if(percent > 1.0) 00150 percent = 1.0; 00151 if(percent < 0.0) 00152 percent = 0.0; 00153 tmp_list.reset(); 00154 vals.reset(); 00155 while(percent > vals.get()) 00156 { 00157 vals.step(); 00158 tmp_list.step(); 00159 } 00160 vals.back(); 00161 tmp_list.back(); 00162 vals.insert(percent); 00163 tmp_list.insert(new_vec); 00164 } 00165 } 00166 delete tmp_crv; 00167 } 00168 delete pt1; 00169 delete pt2; 00170 if(tmp_list.size() > 2) 00171 { 00172 vec_list->move_to(cur_vec); 00173 tmp_list.reset(); 00174 tmp_list.step(); 00175 for(j=tmp_list.size(); j>2; j--) 00176 { 00177 vec_list->insert(tmp_list.get()); 00178 tmp_list.step(); 00179 } 00180 } 00181 cur_vec = next_vec; 00182 } 00183 } 00184 } 00185 } 00186 } 00187 00188 // Passed in direction should be normalized by calling function. 00189 void SplitCompositeSurfaceTool::find_face_with_non_zero_param_dir(DLIList<Surface*> &surf_list, 00190 CubitVector &dir, 00191 CubitVector &pos, 00192 Surface *&ret_surf, 00193 double &du, double &dv, 00194 double &step) 00195 { 00196 int i; 00197 ret_surf = NULL; 00198 for(i=surf_list.size(); i>0 && !ret_surf; i--) 00199 { 00200 Surface *surf = surf_list.get_and_step(); 00201 CubitPointContainment cont = surf->point_containment(pos); 00202 if(cont == CUBIT_PNT_INSIDE) 00203 { 00204 double ulow, uhigh, vlow, vhigh; 00205 surf->param_dir(dir, pos, du, dv); 00206 surf->get_param_range_U(ulow, uhigh); 00207 surf->get_param_range_V(vlow, vhigh); 00208 double u_len = fabs(ulow-uhigh); 00209 double v_len = fabs(vlow-vhigh); 00210 double par_tol; 00211 if(u_len > v_len) 00212 par_tol = v_len/100.0; 00213 else 00214 par_tol = u_len/100.0; 00215 par_tol *= par_tol; 00216 double len = du*du + dv*dv; 00217 if(len > par_tol) 00218 { 00219 step = sqrt(u_len*u_len + v_len*v_len)/20.0; 00220 ret_surf = surf; 00221 } 00222 } 00223 else if(cont == CUBIT_PNT_BOUNDARY) 00224 { 00225 double ulow, uhigh, vlow, vhigh; 00226 surf->param_dir(dir, pos, du, dv); 00227 surf->get_param_range_U(ulow, uhigh); 00228 surf->get_param_range_V(vlow, vhigh); 00229 double u_len = fabs(ulow-uhigh); 00230 double v_len = fabs(vlow-vhigh); 00231 double par_tol; 00232 if(u_len > v_len) 00233 par_tol = v_len/100.0; 00234 else 00235 par_tol = u_len/100.0; 00236 par_tol *= par_tol; 00237 double len = du*du + dv*dv; 00238 if(len > par_tol) 00239 { 00240 double u, v; 00241 surf->u_v_from_position(pos, u, v); 00242 CubitVector new_pos = surf->position_from_u_v(u+du, v+dv); 00243 CubitPointContainment new_cont = surf->point_containment(new_pos); 00244 if(new_cont == CUBIT_PNT_INSIDE) 00245 { 00246 step = sqrt(u_len*u_len + v_len*v_len)/20.0; 00247 ret_surf = surf; 00248 } 00249 } 00250 } 00251 } 00252 }