// Constructor SurfaceOverlapFacet::SurfaceOverlapFacet( GPoint p[3] ) { t.b.x = p[0].x; t.b.y = p[0].y; t.b.z = p[0].z; t.e0.x = p[1].x - p[0].x; t.e0.y = p[1].y - p[0].y; t.e0.z = p[1].z - p[0].z; t.e1.x = p[2].x - p[0].x; t.e1.y = p[2].y - p[0].y; t.e1.z = p[2].z - p[0].z; CubitVector min; min.set( CUBIT_MIN_3( p[0].x, p[1].x, p[2].x ), CUBIT_MIN_3( p[0].y, p[1].y, p[2].y ), CUBIT_MIN_3( p[0].z, p[1].z, p[2].z ) ); CubitVector max; max.set( CUBIT_MAX_3( p[0].x, p[1].x, p[2].x ), CUBIT_MAX_3( p[0].y, p[1].y, p[2].y ), CUBIT_MAX_3( p[0].z, p[1].z, p[2].z ) ); boundingBox.reset( min, max ); }
//=================================================================================== // Function: transform_to_uv (Public) // Description: same as title, the local sizing will be returned in the z coord // Author: chynes // Date: 7/10/02 //=================================================================================== CubitStatus PeriodicParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location) { double u,v; CubitStatus rv = refSurf->u_v_from_position(xyz_location, u, v); // offset values to avoid parameter discontinuity if (uPeriod && u < uOffset) { u += uPeriod; } // mirror surface if required to get correct loop orientation if (mirrorSurface) { u = -u; } if (vPeriod && v < vOffset) { v += vPeriod; } uv_location.set(u,v,1.0); return rv; }
//------------------------------------------------------------------------- // Purpose : // // Special Notes : // // Creator : Jason Kraftcheck // // Creation Date : 05/10/04 //------------------------------------------------------------------------- CubitStatus PartitionBody::mass_properties( CubitVector& result, double& volume ) { DLIList<Lump*> lump_list; lumps( lump_list ); DLIList<PartitionLump*> part_list; CAST_LIST( lump_list, part_list, PartitionLump ); if (part_list.size() < lump_list.size()) return real_body()->mass_properties( result, volume ); CubitVector centroid(0.0, 0.0, 0.0), tmp_centroid; volume = 0.0; double tmp_volume; for (int i = part_list.size(); i--; ) { if (CUBIT_FAILURE == part_list.get_and_step()->mass_properties( tmp_centroid, tmp_volume )) return CUBIT_FAILURE; centroid += tmp_volume * tmp_centroid; volume += tmp_volume; } if (volume > CUBIT_RESABS) { result = centroid / volume; } else { result.set( 0.0, 0.0, 0.0 ); volume = 0.0; } return CUBIT_SUCCESS; }
// Constructor CurveOverlapFacet::CurveOverlapFacet( GPoint p[2] ) { p0.set( p[0].x, p[0].y, p[0].z); p1.set( p[1].x, p[1].y, p[1].z); CubitVector min; min.set( CUBIT_MIN( p[0].x, p[1].x ), CUBIT_MIN( p[0].y, p[1].y ), CUBIT_MIN( p[0].z, p[1].z ) ); CubitVector max; max.set( CUBIT_MAX( p[0].x, p[1].x ), CUBIT_MAX( p[0].y, p[1].y ), CUBIT_MAX( p[0].z, p[1].z ) ); boundingBox.reset( min, max ); facetLength = 0.0; }
//=================================================================================== // Function: transform_to_uv (Public) // Description: same as title, set_up_space must have been already called // the local sizing will be returned in the z coord // of the uv location vector // Author: chynes // Date: 7/10/02 //=================================================================================== CubitStatus FacetParamTool::transform_to_uv(const CubitVector &xyz_location, CubitVector &uv_location) { DLIList<CubitFacet *> facet_list; FacetEvalTool *fetool; CubitFacet *tri_ptr; CubitBoolean outside = CUBIT_FALSE; CubitVector closest_point; CubitVector area_coord; double u, v, s; double compare_tol; // find best compare_tol fetool = CAST_TO(refSurf, FacetSurface)->get_eval_tool(); compare_tol = 1e-3*(fetool->bounding_box().diagonal().length()); // locate point CubitStatus rv = CUBIT_SUCCESS; fetool->get_facets(facet_list); rv = FacetEvalTool::project_to_facets(facet_list, tri_ptr, 0, compare_tol, xyz_location, CUBIT_FALSE, &outside, &closest_point, NULL); // determine barycentric coordinates for in facet if(rv == CUBIT_SUCCESS) { FacetEvalTool::facet_area_coordinate(tri_ptr, closest_point, area_coord); // extract data double u0, u1, u2, v0, v1, v2, s0, s1, s2; CubitPoint *p0, *p1, *p2; tri_ptr->points(p0, p1, p2); p0->get_uvs(tri_ptr, u0, v0, s0); p1->get_uvs(tri_ptr, u1, v1, s1); p2->get_uvs(tri_ptr, u2, v2, s2); // determine u coordinate u = (area_coord.x()*u0) + (area_coord.y()*u1) + (area_coord.z()*u2); // determine v coordinate v = (area_coord.x()*v0) + (area_coord.y()*v1) + (area_coord.z()*v2); // determine sizing s = (area_coord.x()*s0) + (area_coord.y()*s1) + (area_coord.z()*s2); uv_location.set(u,v,s); } return rv; }
//------------------------------------------------------------------------- // Purpose : Finds the closest point on the RefEdge to the input // point and modifies the coordinate values of the input // point to be those of the closest point. // // Special Notes : // // Creator : Malcolm J. Panthaki // // Creation Date : 2/25/97 //------------------------------------------------------------------------- void RefEdge::move_to_curve( CubitVector& vector ) { // Get the Curve associated with this RefEdge Curve* curvePtr = this->get_curve_ptr(); // Move the point to the Curve (the following call modifes the values // of the input "vector", if necessary) CubitVector closest_point; curvePtr->closest_point_trimmed(vector, closest_point); vector.set( closest_point.x(), closest_point.y(), closest_point.z() ); }
CubitStatus PartitionShell::mass_properties( CubitVector& centroid, double& volume ) { PartitionCoSurf* cosurf = 0; DLIList<CubitFacetData*> facets; CubitVector p1, p2, p3, normal; const CubitVector p0(0.0, 0.0, 0.0); centroid.set(0.0, 0.0, 0.0 ); volume = 0.0; while ((cosurf = next_co_surface( cosurf ))) { if (is_nonmanifold( cosurf->get_surface() )) continue; facets.clean_out(); cosurf->get_surface()->get_facet_data( facets ); for (int i = facets.size(); i--; ) { CubitFacet* facet = facets.step_and_get(); 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 (cosurf->sense() == CUBIT_REVERSED) 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; }
//------------------------------------------------------------------------- // Purpose : Find centroid and volume for lumps and shells // // Special Notes : // // Author : Jane Hu // // Creation Date : 11/30/07 //------------------------------------------------------------------------- CubitStatus OCCBody::mass_properties( CubitVector& centroid, double& volume ) { if( myShells.size() == 0 && myLumps.size() == 0) return CUBIT_FAILURE; GProp_GProps myProps; TopoDS_Shape* pshape = myTopoDSShape; if(!pshape || pshape->IsNull())//single lump or shell or surface { DLIList<Lump*> lumps = this->lumps(); if (lumps.size() > 0) pshape = CAST_TO(lumps.get(), OCCLump)->get_TopoDS_Solid(); } if(!pshape || pshape->IsNull()) return CUBIT_FAILURE; BRepGProp::VolumeProperties(*pshape, myProps); volume = myProps.Mass(); gp_Pnt pt = myProps.CentreOfMass(); centroid.set(pt.X(), pt.Y(), pt.Z()); 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; }
//=================================================================================== // Function: transform_to_xyz (Public) // Description: same as title // Author: chynes // Date: 7/10/02 //=================================================================================== CubitStatus FacetParamTool::transform_to_xyz(CubitVector &xyz_location, const CubitVector &uv_location) { CubitStatus rv = CUBIT_SUCCESS; CubitFacet *tri_ptr; FacetSurface *facet_surf = CAST_TO(refSurf, FacetSurface); CubitVector area_coord; double x, y, z; //locate point rv = locate_point_in_uv(facet_surf, uv_location, tri_ptr); if(rv == CUBIT_SUCCESS) { // create uv facet CubitPoint* uvpoint_array[3]; DLIList<CubitPoint *> point_list; CubitPoint *pt_ptr; double u,v; int ii; tri_ptr->points(point_list); for(ii = 0; ii<3; ii++) { pt_ptr = point_list.get_and_step(); pt_ptr->get_uv(tri_ptr, u, v); uvpoint_array[ii] = (CubitPoint *) new CubitPointData(u, v, 0.0); } CubitFacet *uvfacet_ptr = (CubitFacet *) new CubitFacetData( uvpoint_array[0], uvpoint_array[1], uvpoint_array[2] ); // determine barycentric coordinates of uv point in uv facet FacetEvalTool::facet_area_coordinate(uvfacet_ptr, uv_location, area_coord); //delete created objects delete uvfacet_ptr; for(ii = 0; ii<3; ii++) { pt_ptr = uvpoint_array[ii]; delete pt_ptr; } CubitPoint *p0, *p1, *p2; CubitVector coord0, coord1, coord2; tri_ptr->points(p0,p1,p2); coord0 = p0->coordinates(); coord1 = p1->coordinates(); coord2 = p2->coordinates(); //determine x coordinate x = (area_coord.x()*coord0.x()) + (area_coord.y()*coord1.x()) + (area_coord.z()*coord2.x()); //determine y coordinate y = (area_coord.x()*coord0.y()) + (area_coord.y()*coord1.y()) + (area_coord.z()*coord2.y()); //determine z coordinate z = (area_coord.x()*coord0.z()) + (area_coord.y()*coord1.z()) + (area_coord.z()*coord2.z()); xyz_location.set(x,y,z); } return rv; }
CubitStatus SimplifyTool::weighted_average_normal(RefFace* ref_face, CubitVector &normal, double &weight ) { GMem g_mem; unsigned short norm_tol = 30; double dist_tol = -1.0; ref_face->get_geometry_query_engine()-> get_graphics(ref_face->get_surface_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; ref_face->get_geometry_query_engine()-> get_graphics(ref_face->get_surface_ptr(), &g_mem, norm_tol, dist_tol ); } if(g_mem.fListCount < 1) { // Lets give up PRINT_ERROR( "Unable to find average normal of a surface\n" ); return CUBIT_FAILURE; } // Initialize weight = 0.0; normal.set( 0.0, 0.0, 0.0 ); // Loop through the triangles double tri_weight, A, B, C; GPoint p[3]; GPoint* plist = g_mem.point_list(); int* facet_list = g_mem.facet_list(); int c = 0; for( ;c<g_mem.fListCount; ) { p[0] = plist[facet_list[++c]]; p[2] = plist[facet_list[++c]]; p[1] = plist[facet_list[++c]]; 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; CubitVector norm(ref_face->normal_at(center)); // Get triangle area A = p1.y() * p2.z() + p1.z() * p3.y() + p2.y() * p3.z() - p2.z() * p3.y() - p1.y() * p3.z() - p1.z() * p2.y(); B = p1.z() * p2.x() + p1.x() * p3.z() + p2.z() * p3.x() - p2.x() * p3.z() - p1.z() * p3.x() - p1.x() * p2.z(); C = p1.x() * p2.y() + p1.y() * p3.x() + p2.x() * p3.y() - p2.y() * p3.x() - p1.x() * p3.y() - p1.y() * p2.x(); //Note: triangle area = 0.5*(sqrt(A*A+B*B+C*C)); tri_weight = 0.5*(A*A+B*B+C*C); normal += tri_weight * norm; weight += tri_weight; } normal.normalize(); return CUBIT_SUCCESS; }