void Surface::closest_points_trimmed(DLIList<CubitVector *> &from_point_list, DLIList<CubitVector *> &point_on_surface_list) { CubitVector *from_point; CubitVector *point_on_surface; from_point_list.reset(); point_on_surface_list.reset(); for (int i=0; i<from_point_list.size(); i++) { from_point = from_point_list.get_and_step(); point_on_surface = point_on_surface_list.get_and_step(); closest_point_trimmed( *from_point, *point_on_surface ); } }
void Surface::are_positions_on( DLIList<CubitVector *> &test_position_list, DLIList<CubitBoolean *> &is_on_list ) { CubitVector *test_position; CubitBoolean *is_on; test_position_list.reset(); is_on_list.reset(); for (int i=0; i<test_position_list.size(); i++) { test_position = test_position_list.get_and_step(); is_on = is_on_list.get_and_step(); *is_on = is_position_on( *test_position ); } }
DagNodeRow::DagNodeRow( DLIList<ModelEntity*>& node_list ) { length_ = node_list.size(); array_ = 0; if( length_ > 0 ) { array_ = new ModelEntity*[length_]; node_list.reset(); for( int i = 0; i < length_; i++ ) array_[i] = node_list.get_and_step(); } }
CubitStatus GeometryHealerTool::force_simplify_to_torus( DLIList<RefFace*> &ref_face_list, DLIList<Body*>& new_body_list, CubitBoolean keep ) { ref_face_list.reset(); DLIList<RefEntity*> ref_entity_list(ref_face_list.size()); CAST_LIST_TO_PARENT( ref_face_list, ref_entity_list ); if (!same_healer_engine(ref_entity_list, CUBIT_TRUE)) { PRINT_ERROR("HEALING faces from different\n" " geometry engines is not allowed.\n"); return CUBIT_FAILURE; } ref_face_list.reset(); GeometryHealerEngine* GHEPtr = get_engine((TopologyEntity*)(ref_face_list.get())); if (GHEPtr) return GHEPtr->force_simplify_to_torus(ref_face_list, new_body_list, keep); else PRINT_ERROR( "Faces are of a geometry engine without a healer\n" " and cannot be healed.\n"); return CUBIT_FAILURE; }
CubitStatus SimplifyTool::simplify_surfaces(DLIList<RefFace*> ref_face_list, double angle_in, DLIList<RefFace*> respect_face_list, DLIList<RefEdge*> respect_edge_list, CubitBoolean respect_rounds, CubitBoolean respect_imprints, CubitBoolean local_normals, CubitBoolean preview) { CubitStatus status = CUBIT_FAILURE; ref_face_list.uniquify_unordered(); while(ref_face_list.size()) { DLIList<RefFace*> ref_faces_in_volume; ref_face_list.reset(); RefFace* cur_face = ref_face_list.get_and_step(); RefVolume* cur_vol = cur_face->ref_volume(); ref_faces_in_volume.append(cur_face); for(int i =1;i<ref_face_list.size();i++) { RefFace* face = ref_face_list.get_and_step(); if(face->ref_volume() == cur_vol) ref_faces_in_volume.append(face); } if(ref_faces_in_volume.size()>1) { status = simplify_surfaces_in_volume( ref_faces_in_volume, angle_in, respect_face_list, respect_edge_list, respect_rounds, respect_imprints, local_normals, preview); } ref_face_list -= ref_faces_in_volume; } if(preview) GfxDebug::flush(); return CUBIT_SUCCESS; }
CubitStatus Surface::closest_points(DLIList<CubitVector *> &location_list, DLIList<CubitVector *> *closest_location_list, DLIList<CubitVector *> *unit_normal_list, DLIList<CubitVector *> *curvature1_list, DLIList<CubitVector *> *curvature2_list) { CubitVector *curvature1, *curvature2; CubitVector *unit_normal; CubitVector *closest_location; CubitVector *location; CubitStatus stat; location_list.reset(); if (closest_location_list) closest_location_list->reset(); if (unit_normal_list) unit_normal_list->reset(); if (curvature1_list) curvature1_list->reset(); if (curvature2_list) curvature2_list->reset(); for (int i=0; i<location_list.size(); i++) { location = location_list.get_and_step(); if (closest_location_list == NULL) closest_location = NULL; else closest_location = closest_location_list->get_and_step(); if (unit_normal_list == NULL) unit_normal = NULL; else unit_normal = unit_normal_list->get_and_step(); if (curvature1_list == NULL) curvature1 = NULL; else curvature1 = curvature1_list->get_and_step(); if (curvature2_list == NULL) curvature2 = NULL; else curvature2 = curvature2_list->get_and_step(); stat = closest_point( *location, closest_location, unit_normal, curvature1, curvature2 ); if (stat != CUBIT_SUCCESS) return stat; } return CUBIT_SUCCESS; }
// Copy names from one entity to another. // Added Aug.14,2000 by J.Kraftcheck for propogating // names after virtual geometry operations. void RefEntityName::copy_refentity_names( const RefEntity *source, RefEntity *target, CubitBoolean update_attribs ) { //No NULL pointers. assert( source && target ); //If we can't have duplicate names, then it is not possible to //copy names. if( ! get_fix_duplicate_names() ) return; //Assume the name is valid already, as it is attached to //the source entity. Also, assume the name is unique to //the source entity. DLIList<CubitString> names; get_refentity_name( source, names ); names.reset(); //For each of the names on the source entity for( int i = names.size(); i > 0; i-- ) { CubitString name = names.get_and_step(); //make the name unique generate_unique_name( name ); //associate name with target nameEntityList.insert( new RefEntityNameMap( name, target ) ); } if( (names.size() > 0) && (update_attribs == CUBIT_TRUE) ) { // now tell the entity to update its name attribute CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME ); // force update by resetting update flag attrib->has_updated( CUBIT_FALSE ); attrib->update(); } }
//=================================================================================== // Function: new_space_LoopParam (Public) // Description: sets up space of flattening // Author: Shiraj Khan // Date: 1/21/2003 //=================================================================================== CubitStatus LoopParamTool::new_space_LoopParam( DLIList<DLIList<CubitPoint *>*> &loops_cubit_points, CubitVector* normal) { int ii; int jj; double sumx = 0.0, sumy = 0.0, sumz = 0.0; double sumxx = 0.0, sumxy = 0.0, sumxz = 0.0; double sumyy = 0.0, sumyz = 0, sumzz = 0.0; double aa[4][4]; double Xc = 0.0, Yc = 0.0, Zc = 0.0; int n = 0; CubitPoint *point, *point1, *point2; CubitVector point_coordinates, point_coordinates1, point_coordinates2; CubitVector cm_plane; // center of mass of a plane CubitVector vec1, vec2, plane_normal; DLIList<CubitPoint *> *sub_loops_cubit_points; for ( ii = 0; ii < loops_cubit_points.size(); ii++ ) { sub_loops_cubit_points = loops_cubit_points.get_and_step(); for ( jj = 0; jj < sub_loops_cubit_points->size(); jj++ ) { point = sub_loops_cubit_points->get_and_step(); point_coordinates = point->coordinates(); sumx = sumx + point_coordinates.x(); sumy = sumy + point_coordinates.y(); sumz = sumz + point_coordinates.z(); sumxx = sumxx + ( point_coordinates.x() * point_coordinates.x() ); sumxy = sumxy + ( point_coordinates.x() * point_coordinates.y() ); sumxz = sumxz + ( point_coordinates.x() * point_coordinates.z() ); sumyy = sumyy + ( point_coordinates.y() * point_coordinates.y() ); sumyz = sumyz + ( point_coordinates.y() * point_coordinates.z() ); sumzz = sumzz + ( point_coordinates.z() * point_coordinates.z() ); n++; } } Xc = sumx / n; Yc = sumy / n; Zc = sumz / n; cm_plane.set(Xc,Yc,Zc); if ( Xc < EPSILON_UPPER && Xc > EPSILON_LOWER ) Xc = 0.0; if ( Yc < EPSILON_UPPER && Yc > EPSILON_LOWER ) Yc = 0.0; if ( Zc < EPSILON_UPPER && Zc > EPSILON_LOWER ) Zc = 0.0; aa[1][1] = sumxx - Xc * sumx; aa[1][2] = sumxy - Yc * sumx; aa[1][3] = sumxz - Zc * sumx; aa[2][1] = sumxy - Xc * sumy; aa[2][2] = sumyy - Yc * sumy; aa[2][3] = sumyz - Zc * sumy; aa[3][1] = sumxz - Xc * sumz; aa[3][2] = sumyz - Yc * sumz; aa[3][3] = sumzz - Zc * sumz; for ( ii = 1; ii <=3; ii++ ) { for ( jj = 1; jj <=3; jj++ ) if ( aa[ii][jj] < EPSILON_UPPER && aa[ii][jj] > EPSILON_LOWER ) aa[ii][jj] = 0.0; } double determinant_aa = aa[1][1] * ( aa[2][2]*aa[3][3] - aa[3][2]*aa[2][3] ) - aa[1][2] * ( aa[2][1]*aa[3][3] - aa[3][1]*aa[2][3] ) + aa[1][3] * ( aa[2][1]*aa[3][2] - aa[3][1]*aa[2][2] ); if ( determinant_aa < EPSILON_UPPER && determinant_aa > EPSILON_LOWER ) determinant_aa = 0.0; loops_cubit_points.reset(); // if determinant is 0.0 ( all the points are lying on the plane), the equation of a plane: //(vec1) crossproduct (vec2) // where vec1 and vec2 are the vectors originating from a common point( center of mass of a plane) and // lying on the plane. if(normal){ a = normal->x(); b = normal->y(); c = normal->z(); d = -(a*Xc + b*Yc + c*Zc ); } else if ( determinant_aa == 0.0 ) { sub_loops_cubit_points = loops_cubit_points.get_and_step(); point1 = sub_loops_cubit_points->get_and_step(); point2 = sub_loops_cubit_points->get_and_step(); point_coordinates1 = point1->coordinates(); point_coordinates2 = point2->coordinates(); vec1 = cm_plane - point_coordinates1; vec2 = cm_plane - point_coordinates2; plane_normal = vec1 * vec2; a = plane_normal.x(); b = plane_normal.y(); c = plane_normal.z(); d = -( a*Xc + b*Yc + c*Zc ); } else // to calculate eigen vector corresponding to the smallest eigen value { // to calculate the inverse of a matrix int i, j, k; int icol = -1, irow = -1, l, ll; double big, z, pivinv, temp; int indxc[4]; int indxr[4]; int ipiv[4]; for ( j = 1; j <= 3; j++) { indxc[j] = 0; indxr[j] = 0; ipiv[j] = 0; } for ( i = 1; i <= 3;i++) { big = 0.0; for ( j = 1; j <= 3; j++) { if ( ipiv[j] != 1 ) { for ( k = 1; k <= 3; k++) { if (ipiv[k] == 0 ) { if (fabs(aa[j][k]) >= big ) { big = fabs(aa[j][k]); irow = j; icol = k; } } else if(ipiv[k]>1) PRINT_ERROR("Matrix is singular1\n"); } } } ipiv[icol]+=1; if ( irow != icol ) { for (l=1; l <= 3;l++) SWAP( aa[irow][l],aa[icol][l] ); } indxr[i] = irow; indxc[i] = icol; if(aa[icol][icol] == 0.0 ) PRINT_ERROR("Matrix is singular2\n"); pivinv = 1.0/aa[icol][icol]; aa[icol][icol] = 1.0; for( l = 1; l <= 3; l++) aa[icol][l] *= pivinv; for ( ll = 1; ll <= 3; ll++) { if ( ll != icol ) { z = aa[ll][icol]; aa[ll][icol] = 0.0; for ( l = 1;l <= 3; l++) aa[ll][l] -= aa[icol][l] * z; } } for ( l = 3; l >= 1; l-- ) { if ( indxr[l] != indxc[l] ) for ( k = 1; k <= 3; k++ ) SWAP( aa[k][indxr[l]], aa[k][indxc[l]] ) } } // Power Method to get the Eigen Vector corresponding to the smallest Eigen value double x[4] = {0.0, 1.0, 1.1, 1.2}; double dd[4]; double zz[4]; int t = 0; double diff1 = 0.0, diff2 = 0.0; int flag; double largest_dd; while ( t <= 100 ) { flag = 1; for ( i = 1; i <= 3; i++ ) { dd[i] = 0.0; for ( j = 1; j <= 3; j++ ) { dd[i] = dd[i] + aa[i][j] * x[j]; if (dd[i] > EPSILON_LOWER && dd[i] < EPSILON_UPPER) dd[i] = 0.0; } } t = t+1; largest_dd = dd[1] > dd[2] ? ( dd[1] > dd[3] ? dd[1] : dd[3] ) : ( dd[2] > dd[3] ? dd[2] : dd[3] ); for ( i = 1; i <= 3; i++ ) { zz[i] = dd[i]/largest_dd; if (zz[i] > EPSILON_LOWER && zz[i] < EPSILON_UPPER) zz[i] = 0.0; } for ( i = 1; i <= 3; i++ ) { diff1 = fabs(x[i] - zz[i]); diff2 = fabs(diff1) - EPSILON_UPPER*fabs(zz[i]); if ( diff2 <= 0.0 ) continue; else { flag = 0; break; } } if ( flag == 1 ) break; if (flag == 0 ) { for ( i = 1; i <= 3; i++ ) x[i] = zz[i]; } } for ( i = 1; i <= 3; i++ ) { x[i] = zz[i]; if ( (x[i] < EPSILON_UPPER) && (x[i] > EPSILON_LOWER) ) x[i] = 0.0; } a = x[1]; b = x[2]; c = x[3]; d = -(a*Xc+b*Yc+c*Zc); } //printf("\n\nEquation of Plane is %fx+%fy+%fz+%f = 0\n",a,b,c,d); loops_cubit_points.reset(); sub_loops_cubit_points = loops_cubit_points.get_and_step(); CubitPoint *p1 = sub_loops_cubit_points->get_and_step(); CubitVector p1_coordinates = p1->coordinates(); double p1x = p1_coordinates.x() - (p1_coordinates.x()*a + p1_coordinates.y()*b + p1_coordinates.z()*c + d)* (a)/(pow(a,2)+pow(b,2)+pow(c,2)); double p1y = p1_coordinates.y() - (p1_coordinates.x()*a + p1_coordinates.y()*b + p1_coordinates.z()*c + d)* (b)/(pow(a,2)+pow(b,2)+pow(c,2)); double p1z = p1_coordinates.z() - (p1_coordinates.x()*a + p1_coordinates.y()*b + p1_coordinates.z()*c + d)* (c)/(pow(a,2)+pow(b,2)+pow(c,2)); p1_coordinates.set(p1x, p1y, p1z); CubitVector surf_normal; surf_normal.x(a); surf_normal.y(b); surf_normal.z(-1.0); surf_normal.normalize(); // use the first two points on the boundary to define gradient vectors // and orient our uv space. CubitPoint *p2; CubitVector p2_coordinates; double p2x, p2y, p2z; double cos = 1.0; // while (cos == 1.0) { p2 = sub_loops_cubit_points->get_and_step(); p2_coordinates = p2->coordinates(); p2x = p2_coordinates.x() - (p2_coordinates.x()*a + p2_coordinates.y()*b + p2_coordinates.z()*c + d)* (a)/(pow(a,2)+pow(b,2)+pow(c,2)); p2y = p2_coordinates.y() - (p2_coordinates.x()*a + p2_coordinates.y()*b + p2_coordinates.z()*c + d)* (b)/(pow(a,2)+pow(b,2)+pow(c,2)); p2z = p2_coordinates.z() - (p2_coordinates.x()*a + p2_coordinates.y()*b + p2_coordinates.z()*c + d)* (c)/(pow(a,2)+pow(b,2)+pow(c,2)); p2_coordinates.set(p2x, p2y, p2z); if ( p1_coordinates == p2_coordinates ) cos = 1.0; else cos = 0.0; } Du = p2_coordinates - p1_coordinates; Du.normalize(); Dv = surf_normal * Du; Dv.normalize(); uvCenter = p1_coordinates; sub_loops_cubit_points->reset(); return CUBIT_SUCCESS; }
// order edges in list beginning at start_point // report the endpoint // return CUBIT_SUCCESS if all edges are connected and ordered successfully // otherwise return CUBIT_FAILURE, in which case no changes are made CubitStatus CubitFacetEdge::order_edge_list(DLIList<CubitFacetEdge*> &edge_list, CubitPoint *start_point, CubitPoint *&end_point) { int i; assert(start_point); end_point = NULL; // invalid input if (0 == edge_list.size()) return CUBIT_FAILURE; // simple case of a single edge - endpoitn if (1 == edge_list.size()) { end_point = edge_list.get()->other_point(start_point); return end_point ? CUBIT_SUCCESS : CUBIT_FAILURE; } edge_list.reset(); // note that a periodic/closed curve will fail // we could handle that case here if needed, but we may need more information // to know where to start and end the curve if (NULL == start_point) return CUBIT_FAILURE; // put edges in a set for faster searching std::set<CubitFacetEdge *> edge_set; for (i=0; i<edge_list.size(); i++) edge_set.insert(dynamic_cast<CubitFacetEdge*> (edge_list.step_and_get())); // a vector for the ordered list std::vector<CubitFacetEdge*> ordered_edges; // find connected edges from the start point CubitPoint *cur_pt = start_point; do { // get edges connected to the current point and find the next edge DLIList<CubitFacetEdge *> pt_edges; cur_pt->edges(pt_edges); std::set<CubitFacetEdge *>::iterator iter_found; CubitFacetEdge *cur_edge = NULL; for (i=0; i<pt_edges.size() && !cur_edge; i++) { CubitFacetEdge *tmp_edge = pt_edges.get_and_step(); iter_found = edge_set.find(tmp_edge); if ( iter_found != edge_set.end() ) cur_edge = tmp_edge; } // if we don't find a connection before we empty the set // then not all the edges are connected -- return failure if (NULL == cur_edge) return CUBIT_FAILURE; // add the edge to the ordered list ordered_edges.push_back( cur_edge ); edge_set.erase(iter_found); cur_pt = cur_edge->other_point(cur_pt); } while ( edge_set.size()); if (ordered_edges.size() != edge_list.size()) return CUBIT_FAILURE; // store the edges in the correct order edge_list.clean_out(); std::vector<CubitFacetEdge*>::iterator iter; for (iter=ordered_edges.begin(); iter!=ordered_edges.end(); iter++) edge_list.append(*iter); // get the end point CubitFacetEdge *edge1 = edge_list[edge_list.size() - 1]; CubitFacetEdge *edge2 = edge_list[edge_list.size() - 2]; end_point = edge1->other_point( edge1->shared_point(edge2) ); return CUBIT_SUCCESS; }
CubitStatus FacetLump::mass_properties( CubitVector& centroid, double& volume ) { int i; DLIList<FacetShell*> shells( myShells.size() ); CAST_LIST( myShells, shells, FacetShell ); assert( myShells.size() == shells.size() ); DLIList<FacetSurface*> surfaces; DLIList<FacetShell*> surf_shells; get_surfaces( surfaces ); DLIList<CubitFacet*> facets, surf_facets; DLIList<CubitPoint*> junk; DLIList<CubitSense> senses; for (i = surfaces.size(); i--; ) { FacetSurface* surf = surfaces.step_and_get(); surf_shells.clean_out(); surf->get_shells( surf_shells ); surf_shells.intersect( shells ); assert( surf_shells.size() ); CubitSense sense = surf->get_shell_sense( surf_shells.get() ); if (surf_shells.size() == 1 && CUBIT_UNKNOWN != sense) { surf_facets.clean_out(); junk.clean_out(); surf->get_my_facets( surf_facets, junk ); facets += surf_facets; for (int j = surf_facets.size(); j--; ) senses.append(sense); } } const CubitVector p0 = bounding_box().center(); CubitVector p1, p2, p3, normal; centroid.set( 0.0, 0.0, 0.0 ); volume = 0.0; facets.reset(); senses.reset(); for (i = facets.size(); i--; ) { CubitFacet* facet = facets.get_and_step(); CubitSense sense = senses.get_and_step(); p1 = facet->point(0)->coordinates(); p2 = facet->point(1)->coordinates(); p3 = facet->point(2)->coordinates(); normal = (p3 - p1) * (p2 - p1); double two_area = normal.length(); if (two_area > CUBIT_RESABS ) { if (CUBIT_REVERSED == sense) normal = -normal; normal /= two_area; double height = normal % (p0 - p1); double vol = two_area * height; volume += vol; centroid += vol * (p0 + p1 + p2 + p3); } } if (volume > CUBIT_RESABS) centroid /= 4.0 * volume; volume /= 6.0; return CUBIT_SUCCESS; }
CubitPoint* CubitFacetData::split_edge( CubitPoint* edge1_pt, CubitPoint* edge2_pt, const CubitVector& position ) { CubitPointData* new_pt = new CubitPointData(position); // split edge, if there is one CubitFacetEdge* edge = edge1_pt->shared_edge( edge2_pt ); CubitFacetEdgeData* new_edge = 0; if ( edge ) { CubitFacetEdgeData* edge_d = dynamic_cast<CubitFacetEdgeData*>(edge); assert(!!edge_d); // make sure new edge has same orientation as old edge new_edge = dynamic_cast<CubitFacetEdgeData*>(new_pt->shared_edge(edge2_pt)); if ( edge->point(0) == edge1_pt ) { edge_d->set_point(new_pt, 1); if ( !new_edge ) { new_edge = new CubitFacetEdgeData( new_pt, edge2_pt ); DLIList<ToolData*> tds; edge->get_all_TDs(&tds); for (int i=0; i<tds.size(); i++) { ToolData* new_td = tds.get_and_step()->propogate(new_edge); if (new_td) new_edge->add_TD(new_td); } } else if( new_edge->point(0) != new_pt ) new_edge->flip(); } else { edge_d->set_point(new_pt, 0); if ( !new_edge ) { new_edge = new CubitFacetEdgeData( edge2_pt, new_pt ); DLIList<ToolData*> tds; edge->get_all_TDs(&tds); for (int i=0; i<tds.size(); i++) { ToolData* new_td = tds.get_and_step()->propogate(new_edge); if (new_td) new_edge->add_TD(new_td); } } else if( new_edge->point(1) != new_pt ) new_edge->flip(); } } // split triangles DLIList<CubitFacet*> facets; edge1_pt->shared_facets( edge2_pt, facets ); facets.reset(); for ( int i = facets.size(); i--; ) { CubitFacet* facet = facets.get_and_step(); CubitFacetData* facet_d = dynamic_cast<CubitFacetData*>(facet); assert(!!facet_d); // fix up existing facet int pt2_index = facet->point_index( edge2_pt ); bool edge_reversed = ( edge1_pt == facet->point( (pt2_index+1) % 3 ) ); int edge_index = (pt2_index + 1 + edge_reversed) % 3; edge2_pt->remove_facet( facet ); facet_d->set_point( new_pt, pt2_index ); new_pt->add_facet( facet ); facet->update_plane(); // make new facet CubitPoint* other_pt = facet->point( edge_index ); CubitFacetData* new_facet; if ( edge_reversed ) new_facet = new CubitFacetData( other_pt, edge2_pt, new_pt ); else new_facet = new CubitFacetData( other_pt, new_pt, edge2_pt ); DLIList<ToolData*> td_list; facet->get_all_TDs(&td_list); for (int i=0; i< td_list.size(); i++) { ToolData* new_td = td_list.get_and_step()->propogate(new_facet); if (new_td) { new_facet->add_TD(new_td); } } if ( new_edge ) { assert(!new_facet->edge(0)); new_facet->edge( new_edge, 0 ); new_edge->add_facet( new_facet ); int sense = new_facet->point( 1 ) == new_edge->point(0) ? 1 : -1; new_facet->edge_use( sense, 0 ); } // move other edge, if there is one int pt1_index = (pt2_index + 2 - edge_reversed) % 3; CubitFacetEdge* other_edge = facet->edge(pt1_index); if ( other_edge ) { other_edge->remove_facet(facet); facet->edge( 0, pt1_index ); int e_index = 1 + edge_reversed; assert(!new_facet->edge(e_index)); new_facet->edge( other_edge, e_index ); other_edge->add_facet(new_facet); int sense = new_facet->point( (e_index+1)%3 ) == other_edge->point(0) ? 1 : -1; new_facet->edge_use( sense, e_index ); } // what about a new edge for each of the adj_facets and its tool data } return new_pt; }
CubitStatus ChollaCurve::order_edges() { int i; bool periodic = false; if (NULL == startPoint) { DLIList<ChollaPoint *> cholla_points = get_points(); periodic = (cholla_points.size() == 1); ChollaPoint *chpt = cholla_points.get(); CubitPoint *start_point = dynamic_cast<CubitPoint *> (chpt->get_facets()); this->set_start( start_point ); if (NULL == start_point) return CUBIT_FAILURE; start_point->set_as_feature(); if (periodic) { this->set_end(start_point); } else { chpt = cholla_points.step_and_get(); CubitPoint *end_point = dynamic_cast<CubitPoint *> (chpt->get_facets()); if (NULL == end_point) return CUBIT_FAILURE; this->set_end(end_point); end_point->set_as_feature(); } } assert(startPoint); assert(endPoint); if (curveEdgeList.size() > 1) { DLIList<CubitFacetEdge*> edges_ordered; CAST_LIST(curveEdgeList, edges_ordered, CubitFacetEdge); CubitStatus stat = CubitFacetEdge::order_edge_list(edges_ordered, startPoint, endPoint); if (CUBIT_FAILURE == stat) return CUBIT_FAILURE; // store the edges in the correct order clean_out_edges(); edges_ordered.reset(); for (i=0; i< edges_ordered.size(); i++) { this->add_facet(edges_ordered.get_and_step()); } } // make sure all the edges are oriented correctly DLIList<FacetEntity *> flist = this->get_facet_list(); flist.reset(); DLIList<CubitFacetEdge *> elist; CAST_LIST( flist, elist, CubitFacetEdge ); elist.reset(); CubitPoint *cur_pt = startPoint, *tmp_pt; for ( i = elist.size(); i > 0; i-- ) { CubitFacetEdge *edge_ptr = elist.get_and_step(); CubitPoint *point0_ptr = edge_ptr->point(0); CubitPoint *point1_ptr = edge_ptr->point(1); if (point0_ptr != cur_pt) { assert( cur_pt == point1_ptr ); edge_ptr->flip(); tmp_pt = point0_ptr; point0_ptr = point1_ptr; point1_ptr = tmp_pt; assert( point0_ptr == edge_ptr->point(0) && point1_ptr == edge_ptr->point(1) ); } cur_pt = point1_ptr; } int mydebug = 0; if (mydebug) { int i; DLIList<FacetEntity *> flist = this->get_facet_list(); flist.reset(); DLIList<CubitFacetEdge *> elist; CAST_LIST( flist, elist, CubitFacetEdge ); elist.reset(); for ( i = elist.size(); i > 0; i-- ) { CubitFacetEdge *edge = elist.get_and_step(); CubitVector pt0_v = edge->point(0)->coordinates(); CubitVector pt1_v = edge->point(1)->coordinates(); GfxDebug::draw_point(pt0_v, CUBIT_GREEN ); GfxDebug::draw_point(pt1_v, CUBIT_RED ); GfxDebug::draw_line( pt0_v, pt1_v, CUBIT_YELLOW ); GfxDebug::flush(); int view = 0; if (view) dview(); } } return CUBIT_SUCCESS; }
//============================================================================= //Function: build_curve_from_edges //Description: insert the ordered and oriented edges into this cholla curve //Notes: traverses starting at start_point and gathers facet edges until it // runs into another curve. // start_point is an existing CubitPoint at either end of the curve // max_edges is the maximum number of edges on this curve. should be // known beforehand (used for error checking). // // ***this function used to be part of split_curve. *** //Author: sjowen //Return: //Date: 09/07/2009 //============================================================================= CubitStatus ChollaCurve::build_curve_from_edges( CubitPoint *start_point, int periodic, int max_edges, CubitFacetEdge *start_edge_ptr, ChollaCurve *parent_curve ) { // find the first edge. Match the chollacurve owner with this curve // do this only if the start_edge_ptr was not passed in DLIList<CubitFacetEdge *> point_edge_list; start_point->edges(point_edge_list); CubitFacetEdge *edge_ptr; if (start_edge_ptr == NULL) { for (int ii=0; ii<point_edge_list.size() && !start_edge_ptr; ii++) { edge_ptr = point_edge_list.get_and_step(); TDGeomFacet *td_geom = TDGeomFacet::get_geom_facet( edge_ptr ); // assumes that the TDGeomFacet info has already been set up for the edges assert(td_geom != NULL); DLIList<ChollaCurve *> cholla_curves; td_geom->get_cholla_curves(cholla_curves); // currently should be only one-to-one relationship // could also be edge on surface in which case no curves associated assert(cholla_curves.size() <= 1); if (cholla_curves.size()) { if (cholla_curves.get() == this) start_edge_ptr = edge_ptr; } } assert(start_edge_ptr != NULL); // didn't find an edge that marched this chollacurve } // create a new curve to hold the edge info this->set_start( start_point ); start_point->set_as_feature(); this->add_facet( start_edge_ptr ); int iedgecount = 0; edge_ptr = start_edge_ptr; CubitPoint *point0_ptr = start_point, *point1_ptr; CubitPoint *end_point = NULL; while(!end_point) { point1_ptr = edge_ptr->other_point( point0_ptr ); if ((edge_ptr = parent_curve->next_edge( point1_ptr, edge_ptr )) == NULL) { end_point = point1_ptr; } else { iedgecount++; if (iedgecount > max_edges) { PRINT_ERROR("ChollaCurve has start, but no end\n"); return CUBIT_FAILURE; } this->add_facet( edge_ptr ); if (periodic && point1_ptr == start_point) end_point = start_point; point0_ptr = point1_ptr; } } this->set_end( end_point ); end_point->set_as_feature(); // make sure all the edges are oriented correctly int i; DLIList<FacetEntity *> flist = this->get_facet_list(); flist.reset(); DLIList<CubitFacetEdge *> elist; CAST_LIST( flist, elist, CubitFacetEdge ); elist.reset(); CubitPoint *cur_pt = start_point, *tmp_pt; for ( i = elist.size(); i > 0; i-- ) { edge_ptr = elist.get_and_step(); point0_ptr = edge_ptr->point(0); point1_ptr = edge_ptr->point(1); if (point0_ptr != cur_pt) { assert( cur_pt == point1_ptr ); edge_ptr->flip(); tmp_pt = point0_ptr; point0_ptr = point1_ptr; point1_ptr = tmp_pt; assert( point0_ptr == edge_ptr->point(0) && point1_ptr == edge_ptr->point(1) ); } cur_pt = point1_ptr; } int mydebug = 0; if (mydebug) { int i; DLIList<FacetEntity *> flist = this->get_facet_list(); flist.reset(); DLIList<CubitFacetEdge *> elist; CAST_LIST( flist, elist, CubitFacetEdge ); elist.reset(); for ( i = elist.size(); i > 0; i-- ) { CubitFacetEdge *edge = elist.get_and_step(); CubitVector pt0_v = edge->point(0)->coordinates(); CubitVector pt1_v = edge->point(1)->coordinates(); GfxDebug::draw_point(pt0_v, CUBIT_GREEN ); GfxDebug::draw_point(pt1_v, CUBIT_RED ); GfxDebug::draw_line( pt0_v, pt1_v, CUBIT_YELLOW ); GfxDebug::flush(); int view = 0; if (view) dview(); } } return CUBIT_SUCCESS; }
CubitStatus Faceter::get_curve_facets( RefEdge* curve, DLIList<CubitPoint*>& segments ) const { //const double COS_ANGLE_TOL = 0.965925826289068312213715; // cos(15) const double COS_ANGLE_TOL = 0.984807753012208020315654; // cos(10) //const double COS_ANGLE_TOL = 0.996194698091745545198705; // cos(5) GMem curve_graphics; const double dist_tol = GEOMETRY_RESABS; const double dist_tol_sqr = dist_tol*dist_tol; Curve* curve_ptr = curve->get_curve_ptr(); curve_ptr->get_geometry_query_engine()->get_graphics( curve_ptr, &curve_graphics ); GPoint* gp = curve_graphics.point_list(); CubitPoint* last = (CubitPoint*) new FaceterPointData( gp->x, gp->y, gp->z ); ((FaceterPointData*)last)->owner(dynamic_cast<RefEntity*>(curve)); CubitVector lastv = last->coordinates(); segments.append( last ); GPoint* end = gp + curve_graphics.pointListCount - 1; for( gp++; gp < end; gp++ ) { CubitVector pos( gp->x, gp->y, gp->z ); CubitVector step1 = (pos - lastv); double len1 = step1.length(); if( len1 < dist_tol ) continue; GPoint* np = gp + 1; CubitVector next( np->x, np->y, np->z ); CubitVector step2 = next - pos; double len2 = step2.length(); if( len2 < dist_tol ) continue; double cosine = (step1 % step2) / (len1 * len2); if( cosine > COS_ANGLE_TOL ) continue; last = new FaceterPointData( pos ); ((FaceterPointData*)last)->owner(dynamic_cast<RefEntity*>(curve)); segments.append( last ); lastv = last->coordinates(); } CubitVector last_pos( gp->x, gp->y, gp->z ); segments.last(); while( (last_pos - (segments.get()->coordinates())).length_squared() < dist_tol_sqr ) { delete segments.pop(); segments.last(); } CubitPoint *tmp_point = (CubitPoint*) new FaceterPointData( last_pos ); segments.append( tmp_point ); ((FaceterPointData*)tmp_point)->owner( dynamic_cast<RefEntity*>(curve) ); // Now check if the segment list is reversed wrt the curve direction. segments.reset(); double u1, u2; if( segments.size() > 2 ) { u1 = curve->u_from_position( (segments.next(1)->coordinates()) ); u2 = curve->u_from_position( (segments.next(2)->coordinates()) ); } else { u1 = curve->u_from_position( (segments.get()->coordinates() ) ); u2 = curve->u_from_position( (segments.next()->coordinates()) ); } if( (u2 < u1) && (curve->start_param() <= curve->end_param()) ) segments.reverse(); //Make sure we don't have duplicate points. int jj; CubitVector curr, prev; for ( jj = segments.size(); jj > 0; jj-- ) { prev = segments.prev()->coordinates(); curr = segments.get_and_step()->coordinates(); if ( prev.about_equal(curr) ) { PRINT_DEBUG_129("Points on curve %d within tolerance...\n", curve->id()); segments.back(); delete segments.remove(); } } return CUBIT_SUCCESS; }
//------------------------------------------------------------------------- // Purpose : Read and remove attributes from underlying entities // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 06/30/03 //------------------------------------------------------------------------- void CompositeGeom::read_attributes( GeometryEntity* geom_ptr ) { DLIList<CubitSimpleAttrib> list; int i; // remove any attributes from previous read rem_all_attributes(); if (geom_ptr) { // Special case for point-curves (no real curves to write // attirbutes to.) Write to passed entity instead. assert(entityList.size() == 0); geom_ptr->get_simple_attribute(COMPOSITE_DATA_ATTRIB_NAME,list); list.reset(); for (i = list.size(); i--; ) { const CubitSimpleAttrib& attrib = list.get_and_step(); assert(attrib.int_data_list().size()); if (attrib.int_data_list()[0] == entityList.size()) { geom_ptr->remove_simple_attribute_virt(attrib); CubitSimpleAttrib c = attrib; c.int_data_list().erase(c.int_data_list().begin()); c.string_data_list().erase(c.string_data_list().begin()); listHead = new CompositeAttrib(c,listHead); } } return; } int index_of_entity_with_attribs = -1; for (i = 0; i < entityList.size(); i++) { list.clean_out(); entityList[i].entity->get_simple_attribute(COMPOSITE_DATA_ATTRIB_NAME,list); if( list.size() ) index_of_entity_with_attribs = i; list.reset(); for (int j = list.size(); j--; ) { const CubitSimpleAttrib& attrib = list.get_and_step(); assert(attrib.int_data_list().size()); if (attrib.int_data_list()[0] == entityList.size()) { // Take the attributes off of the current entity and put them on the first entity // in this list. I believe this is ok to do because the attributes should apply to // the whole composite surface and not just the underlying entity they are on // (the one exception to this might be UNIQUE_ID but I haven't seen any problems // with this yet). The reason for doing this is that there is some code (I believe // in uncomposite() that assumes any attributes will be on the first entity // in the list. Previous code actually moved the entity to the beginning // of the list but this reordering of the list does not fly with composite // curves because there is code depending on the curves in the list being // ordered so that they connect end to end in a contiguous manner (the // faceting code, for one, relies on this). BWC 1/7/07. entityList[i].entity->remove_simple_attribute_virt(attrib); entityList[0].entity->append_simple_attribute_virt(attrib); CubitSimpleAttrib c = attrib; c.int_data_list().erase(c.int_data_list().begin()); c.string_data_list().erase(c.string_data_list().begin()); if( NULL == listHead ) listHead = new CompositeAttrib(c,listHead); else //this assures that we are not adding duplicate attribs { bool is_duplicate = false; CompositeAttrib* curr_attrib = listHead; while( curr_attrib ) { if( curr_attrib->equals( c ) ) { is_duplicate = true; break; } curr_attrib = curr_attrib->next; } if( false == is_duplicate ) listHead = new CompositeAttrib(c,listHead); } } } } }
//------------------------------------------------------------------------- // Purpose : Combine // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 03/04/02 //------------------------------------------------------------------------- CubitStatus CompositeGeom::merge( CompositeGeom& dead, bool prepend ) { int i; if (entityList.size() == 1) { DLIList<CubitSimpleAttrib> list; entityList[0].entity->get_simple_attribute(list); list.reset(); for (i = list.size(); i--; ) { const CubitSimpleAttrib csa = list.get_and_step(); if (csa.character_type() != COMPOSITE_DATA_ATTRIB_NAME) listHead = new CompositeAttrib(csa, listHead); } } // find EntityName attribute CompositeAttrib* this_name = listHead; while (this_name && this_name->name() != "ENTITY_NAME") this_name = this_name->next; // merge entity name attributes CompositeAttrib* dead_name = dead.listHead; if (dead_name) { if (dead_name->name() == "ENTITY_NAME") { dead_name = dead.listHead; dead.listHead = dead_name->next; dead_name->next = 0; } else { while(dead_name->next && dead_name->next->name() != "ENTITY_NAME") dead_name = dead_name->next; if(dead_name->next) { CompositeAttrib* prev = dead_name; prev->next = dead_name = dead_name->next; dead_name->next = 0; } } } int insert ; if ( prepend ) { insert = 0; entityList.size_end( entityList.size() + dead.entityList.size() ); } else { insert = entityList.size(); entityList.size( entityList.size() + dead.entityList.size() ); } for( i = 0; i < dead.entityList.size(); i++ ) { entityList[insert].entity = dead.entityList[i].entity; entityList[insert].sense = dead.entityList[i].sense; insert++; } dead.entityList.size(0); update_cached_data(); return CUBIT_SUCCESS; }
CubitStatus RefEntityName::add_refentity_name(RefEntity *entity, DLIList<CubitString> &names, bool update_attribs, bool check_name_validity) { names.reset(); //int num_new_names = names.size(); DLIList<CubitString> new_names; for (int i=0; i<names.size(); i++) { CubitString name = names[i]; CubitString in_name = name; CubitBoolean warn_name_change = CUBIT_FALSE; // first, clean the name if (check_name_validity) { if (clean(name)) { // assign original name anyway, then // continue on and assign modified name. add_refentity_name(entity, in_name, false, false); warn_name_change = CUBIT_TRUE; } } // now, check for valid name CubitBoolean name_valid = CUBIT_FALSE; if (name == "") { // blank name entered - do nothing } else if (nameEntityList.move_to(name) && nameEntityList.get()->value() == entity) { // Tried to assign same name to entity if ( DEBUG_FLAG(92) ) { // check to see if it's the same as this entity's default name, // if so, it probably came in on an attribute, and we don't need // to hear about it; otherwise, write the warning CubitString def_name; entity->generate_default_name(def_name); if (name != def_name) PRINT_INFO("Entity name '%s' already assigned to %s %d\n", name.c_str(), entity->class_name(), entity->id()); } } else if (nameEntityList.move_to(name) && nameEntityList.get()->value() != entity) { // Tried to assign existing name to another entity PRINT_DEBUG_92( "Entity name '%s' for %s %d is already used by %s %d\n", name.c_str(), entity->class_name(), entity->id(), nameEntityList.get()->value()->class_name(), nameEntityList.get()->value()->id()); // either we fix it and keep it, or we don't and get rid of it name_valid = CUBIT_FALSE; if (get_fix_duplicate_names()) { if (generate_unique_name(name)) { PRINT_DEBUG_92( "\t%s %d name changed to '%s'\n", entity->class_name(), entity->id(), name.c_str()); if(warn_name_change) { PRINT_WARNING("Entity name '%s' can't be used in commands.\n" " Additional name '%s' assigned.\n", in_name.c_str(), name.c_str()); } name_valid = CUBIT_TRUE; } } } else { if(warn_name_change) { PRINT_WARNING("Entity name '%s' can't be used in commands.\n" " Additional name '%s' assigned.\n", in_name.c_str(), name.c_str()); } // else the name must be valid name_valid = CUBIT_TRUE; } if (name_valid == CUBIT_TRUE) { // name is valid if (name != in_name) // name was changed; change in name list too names[i] = name; // save this name to later new_names.append(names[i]); } } if (new_names.size() > 0) { // there are some valid, new names; add them, then update attribute new_names.reset(); CubitString name; for (int i = new_names.size(); i > 0; i--) { name = new_names.get_and_step(); if (nameEntityList.move_to(name) && nameEntityList.get()->value() == entity) { PRINT_DEBUG_92("Already have name %s for %s %d.\n", name.c_str(), entity->class_name(), entity->id()); } else { nameEntityList.insert(new RefEntityNameMap(name, entity)); } } if (update_attribs == CUBIT_TRUE) { // now tell the entity to update its name attribute CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME); // force update by resetting update flag attrib->has_updated(CUBIT_FALSE); attrib->update(); } } return CUBIT_SUCCESS; }
//------------------------------------------------------------------------- // Purpose : Check if loops are spatially equal. // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 04/01/04 //------------------------------------------------------------------------- CubitBoolean Loop::about_spatially_equal( DLIList<CoEdge*>& other_coedges, CubitSense relative_sense, double tolerance_factor, CubitBoolean notify_refEntity ) { DLIList<CoEdge*> this_coedges(other_coedges.size()); // Loops must have same number of coedges to match. this->ordered_co_edges( this_coedges ); if (this_coedges.size() != other_coedges.size()) return CUBIT_FALSE; // Want to compare coedges in order, so make sure we have // them in the correct order. if (relative_sense == CUBIT_REVERSED) this_coedges.reverse(); // Try to match all coedges. Begin with the first coedge // in this loop. For each coedge in the other loop that // it matches, check if all the other coedges match in the // correct order. int other_loop_index = 0; this_coedges.reset(); other_coedges.reset(); CoEdge* this_coedge = this_coedges.get_and_step(); for (int i = other_coedges.size(); i--; ) { // Loop until we find a matching CoEdge CoEdge* other_coedge = other_coedges.get_and_step(); if (!this_coedge->about_spatially_equal( other_coedge, relative_sense, tolerance_factor, notify_refEntity )) continue; // Found a matching coedge. Now try to match all the // others in the correct order. bool match = true; other_loop_index = other_coedges.get_index(); for (int j = other_coedges.size() - 1; j-- && match; ) { this_coedge = this_coedges.get_and_step(); other_coedge = other_coedges.get_and_step(); match = this_coedge->about_spatially_equal( other_coedge, relative_sense, tolerance_factor, notify_refEntity ); } // Matched all coedges, in order. Done. if (match) return CUBIT_TRUE; // Try again, as perhaps the first coedge of this loop // also matches some other one in the second loop and // if we start with that one, the remaining coedges will // also match. this_coedges.reset(); this_coedge = this_coedges.get_and_step(); other_coedges.reset(); other_coedges.step( other_loop_index ); } // If here, loops didn't match. return CUBIT_FALSE; }
//------------------------------------------------------------------------- // Purpose : Gets the angle metric for this Loop. // // Special Notes : The actual computation is done by the underlying geometric // modeling engine as this is a geometric computation. // // Creator : Malcolm J. Panthaki // // Creation Date : 1/10/97 //------------------------------------------------------------------------- CubitStatus Loop::get_angle_metric(double& angle_metric) { // If the OSME knows its angle metric (some modelers cache // some data along these lines), return that value LoopSM* loop_sm = get_loop_sm_ptr(); if (loop_sm && loop_sm->get_angle_metric(angle_metric)) return CUBIT_SUCCESS; // First, get the list of coedges DLIList<CoEdge*> coedges; ordered_co_edges(coedges); // Now build a polygon approximation of the curves in the loop. // The polygon is a straight-line approximation to and is // topologically equivalent to the loop. At any given point, // the polygon may be far from the actual loop, however. // - samitch // If there are no coedges, this is an empty loop if (coedges.size() == 0) { angle_metric = 0; return CUBIT_FAILURE; } // Loop through each coedge int i, j; DLIList<CubitVector*> polygon_points; DLIList<CubitVector*> interior_points; CoEdge* cur_coedge = NULL; coedges.reset(); for (i = coedges.size(); i--; ) { // Get the first point on this curve cur_coedge = coedges.get_and_step(); RefEdge* cur_refedge = cur_coedge->get_ref_edge_ptr(); polygon_points.append(new CubitVector (cur_coedge->get_sense() == CUBIT_FORWARD ? cur_refedge->start_vertex()->coordinates() : cur_refedge->end_vertex()->coordinates())); // Get the interior points for approximation CubitSense return_sense; interior_points.clean_out(); cur_refedge->get_interior_extrema(interior_points, return_sense); // Now put the points into the polygon. // We don't need to re-allocate any CubitVectors because we are just // copying pointers to dynamically allocated CubitVectors. if (cur_coedge->get_sense() == return_sense) { interior_points.reset(); for (j = interior_points.size(); j--; ) polygon_points.append(interior_points.get_and_step()); } else { interior_points.last(); for (j = interior_points.size(); j--; ) polygon_points.append(interior_points.get_and_back()); } } // Now that we have all of the points, compute and sum up // the internal angles on the polygon approximation. double angle, angle_sum = 0; RefFace* surface = cur_coedge->get_ref_face(); CubitVector *point[3], t[2], normal; point[0] = polygon_points.get_and_step(); point[1] = polygon_points.get_and_step(); t[0] = *point[1] - *point[0]; for (i = polygon_points.size(); i--; ) { // Determine proper internal surface angle at point[1] point[2] = polygon_points.get_and_step(); normal = surface->normal_at(*point[1]); t[1] = *point[1] - *point[2] ; angle = normal.vector_angle(t[1], t[0]); // Add up the total angle_sum += angle; // Iterate point[1] = point[2]; t[0] = -t[1]; } angle_metric = angle_sum / CUBIT_PI - polygon_points.size(); // Clean up dynamically allocated vectors for (i = polygon_points.size(); i>0; i--) delete polygon_points.get_and_step(); return CUBIT_SUCCESS; }
void RefEntityName::copy_refentity_names( DLIList<RefEntity*>& source_list, RefEntity* target, CubitBoolean unique_base_names, CubitBoolean update_attribs ) { //Validate input. assert( target != 0 ); if( source_list.size() < 1 ) return; //If we can't have duplicate names, we can't copy. if( ! get_fix_duplicate_names() ) return; //If we need to ensure no duplicate base names... if( unique_base_names ) { //Get a big list of all the names from the source_list RefEntityNameMapList name_list; source_list.reset(); for( int i = source_list.size(); i > 0; i-- ) get_refentity_name( source_list.get_and_step(), name_list ); //If we don't have any names to add, we're done if( name_list.size() < 1 ) return; //Get the first name name_list.sort(); name_list.reset(); CubitString prev_key = name_list.get_and_step()->key(); //Add name to target CubitString name = prev_key; generate_unique_name( name ); nameEntityList.insert( new RefEntityNameMap( name, target ) ); //For the rest of the names... for( int j = name_list.size(); j > 1; j-- ) { CubitString key_ptr = name_list.get_and_step()->key(); //If the name has a different base name than the previous, //add it to the target. if( !same_base_name( prev_key, key_ptr ) ) { name = key_ptr; generate_unique_name( name ); nameEntityList.insert( new RefEntityNameMap( name, target ) ); } prev_key = key_ptr; } //update attribute, if asked to do so if( update_attribs ) { CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME ); attrib->has_updated( CUBIT_FALSE ); attrib->update(); } } else { //If we don't care about unique base names, just add them all. DLIList<CubitString> name_list; for( int i = source_list.size(); i > 0; i-- ) get_refentity_name( source_list.get_and_step(), name_list ); name_list.reset(); add_refentity_name(target, name_list, update_attribs, false); } }
//=============================================================================== // Function : split_surfaces // Member Type: PUBLIC // Description: Split a chain of surfaces into one or more pieces // Author : Steve Storm (CAT) // Date : 01/04 //=============================================================================== CubitStatus SplitSurfaceVirtual::split_surfaces_virtual( DLIList<RefFace*> &ref_face_list, int num_segs, double fraction, double distance, RefEdge *from_curve_ptr, DLIList<RefVertex*> &corner_vertex_list, DLIList<RefVertex*> &through_vertex_list, RefEdge *curve_dir_ptr, CubitBoolean preview_flg, CubitBoolean create_ref_edges_flg ) { // Get parent bodies - all surfs must be from same body int i; DLIList<Body*> old_body_list; RefFace *ref_face_ptr; ref_face_list.reset(); for( i=ref_face_list.size(); i--; ) { ref_face_ptr = ref_face_list.get_and_step(); DLIList<Body*> body_list; ref_face_ptr->bodies( body_list ); old_body_list.merge_unique( body_list ); } if( old_body_list.size() > 1 ) { PRINT_ERROR( "This operation requires all surfaces to be from the same volume\n" ); // Note: this restriction could be pretty easily lifted by sorting the // input lists and calling the SplitSurfaceTool separately for each set of // surfaces on each body. return CUBIT_FAILURE; } //bad geom with no body -- dont try to imprint this... //quick and dirty fix by (aga@cat|1/7/04) if( old_body_list.size() < 1 ) { PRINT_ERROR( "A surface is not contained within a parent body.\n" " It cannot be split.\n"); return CUBIT_FAILURE; } /* KGM -- need this? // Check for virtual geometry if ( contains_intermediate_geometry(ref_face_list) ) { PRINT_ERROR("SPLITTING surfaces containing virtual geometry is not\n" " allowed. Delete virtual geometry on these surfaces\n" " before operation.\n" ); return CUBIT_FAILURE; } */ // Make sure all surfaces are from same geometry engine DLIList<RefEntity*> ref_ent_list; CAST_LIST_TO_PARENT(ref_face_list, ref_ent_list); /* KGM -- need this? if ( !same_modify_engine(ref_ent_list, CUBIT_TRUE) ) { PRINT_ERROR("Performing SPLIT with surfaces containing geometry from\n" "different modeling engines is not allowed.\n" "Delete uncommon geometry on these surfaces before operation.\n\n"); return CUBIT_FAILURE; } */ // get the splitting curves DLIList<DLIList<Curve*>*> curve_lists_list; SplitSurfaceTool sst; CubitStatus err = sst.calculate_split_curves( ref_face_list, num_segs, fraction, distance, from_curve_ptr,corner_vertex_list, through_vertex_list, curve_dir_ptr, preview_flg, create_ref_edges_flg, false, curve_lists_list ); // loop over all the curves GMem gmem; int num_points; DLIList<CubitVector*> segments; int k; for (k=0; k < curve_lists_list.size(); k++) { DLIList<Curve*> *curve_list = curve_lists_list[k]; int i; for (i = 0; i < curve_list->size(); i++) { Curve* curve_ptr = curve_list->get_and_step(); // get the curve facets err = curve_ptr->get_geometry_query_engine()-> get_graphics( curve_ptr, num_points, &gmem ); // load the graphics points into a CubitVector for insert_curve --num_points; int j; for (j = 0; j < num_points; j++) { const GPoint& p = gmem.point_list()[j]; segments.append( new CubitVector( p.x, p.y, p.z ) ); } } } // add last point to the end of the list const GPoint& p = gmem.point_list()[num_points]; segments.append( new CubitVector(p.x, p.y, p.z ) ); // Get the underlying surface (what if it is virtual does this still work?) //Surface *old_surf = ref_face_list[k]->get_surface_ptr(); KGM // now partition the surface DLIList<RefEdge*> new_edges; DLIList<RefFace*> new_faces; err = PartitionTool::instance()->insert_edge( ref_face_list, segments, new_faces, new_edges); //DLIList<Curve*> new_curves; //Surface* new_surf = PartitionEngine::instance().insert_curve( old_surf, segments, new_curves ); // insert_curve allocates memory. Clean up. //while( new_curves.size() ) // delete new_curves.pop(); // called routines allocate memory. Clean up for them. for (k=0; k < curve_lists_list.size(); k++) { DLIList<Curve*> *curve_list = curve_lists_list[k]; while( curve_list->size() ) delete curve_list->pop(); } return CUBIT_SUCCESS; }