HRESULT OpenDiskOrVolumeOrFile(HANDLE & h, LPWSTR name, bool isRead, UINT64 * psize = nullptr) { DWORD desiredAccess = isRead ? GENERIC_READ : GENERIC_READ|GENERIC_WRITE; DWORD devFlags = isRead ? FILE_FLAG_NO_BUFFERING : FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; DWORD fileCreation = isRead ? OPEN_EXISTING : CREATE_ALWAYS; auto v = FindVolume(name); if (v) { auto hr = v->Open(desiredAccess, devFlags, h); if (hr) return hr; if (psize) *psize = v->size; return 0; } auto d = FindDrive(name); if (d) { auto hr = d->Open(isRead, desiredAccess, devFlags, h); if (hr) return hr; if (psize) *psize = d->size; return 0; } auto p = FindPartition(name); if (p) { auto hr = p->Open(isRead, desiredAccess, devFlags, h); if (hr) return hr; if (psize) *psize = p->size; return 0; } h = CreateFile( name, desiredAccess, FILE_SHARE_READ, nullptr, fileCreation, FILE_FLAG_SEQUENTIAL_SCAN, nullptr); if (h==INVALID_HANDLE_VALUE) return GetLastError(); if (psize) { LARGE_INTEGER large; if (!GetFileSizeEx(h, &large)) return GetLastError(); *psize = large.QuadPart; } return 0; }
// The function that tests whether a 2D surface is a lateral of a valid QuadToTri // region and whether there are conflicts. If surface is not part of valid QuadToTri region // or if there are QuadToTri conflicts, return 0. Note that RemoveDuplicateSurfaces() // makes this DIFFICULT. Also, the tri_quad_flag determins whether the surface // should be meshed with triangles or quadrangles: // tri_quad_values: 0 = no override, 1 = mesh as quads, 2 = mesh as triangles. // Added 2010-12-09. int IsValidQuadToTriLateral(GFace *face, int *tri_quad_flag, bool *detectQuadToTriLateral ) { (*tri_quad_flag) = 0; (*detectQuadToTriLateral) = false; GModel *model = face->model(); ExtrudeParams *ep = face->meshAttributes.extrude; if( !ep || !ep->mesh.ExtrudeMesh || !ep->geo.Mode == EXTRUDED_ENTITY ){ Msg::Error("In IsValidQuadToTriLateral(), face %d is not a structured extrusion.", face->tag() ); return 0; } GEdge *face_source = model->getEdgeByTag( std::abs( ep->geo.Source ) ); if( !face_source ){ Msg::Error("In IsValidQuadToTriLateral(), face %d has no source edge.", face->tag() ); } // It seems the member pointers to neighboring regions for extruded lateral faces are not set. // For now, have to loop through // ALL the regions to see if the presently considered face belongs to the region and if // any neighboring region is QUADTRI. // The following loop will find all the regions that the face bounds, and determine // whether the face is a lateral of the region (including whether the region is even extruded). // After that information is determined, function can test for QuadToTri neighbor conflicts. std::vector<GRegion *> lateral_regions; std::vector<GRegion *> adjacent_regions; int numRegions = 0; int numLateralRegions = 0; numRegions = GetNeighborRegionsOfFace(face, adjacent_regions); for( int i_reg = 0; i_reg < numRegions; i_reg++ ){ GRegion *region = adjacent_regions[i_reg]; // is region in the current model's region's or is it deleted? if( !FindVolume( ( region->tag() ) ) ) continue; // is the region mesh extruded? if( !region->meshAttributes.extrude || ( region->meshAttributes.extrude && !region->meshAttributes.extrude->mesh.ExtrudeMesh ) ) continue; if( region->meshAttributes.extrude->geo.Mode != EXTRUDED_ENTITY ) continue; // Test whether the face is a lateral if( IsSurfaceALateralForRegion(region, face) ){ lateral_regions.push_back(region); numLateralRegions++; if( region->meshAttributes.extrude->mesh.QuadToTri ) (*detectQuadToTriLateral) = true; } } // MAIN test of whether this is even a quadToTri extrusion lateral // the only return 0 path that is NOT an error if( !(*detectQuadToTriLateral) ) return 0; // now will start conflict checks if(numRegions > 2){ Msg::Error("In IsValidQuadToTriLateral(), too many regions adjacent to surface %d.", face->tag() ); return 0; } bool detect_conflict = false; // Set the tri_quad_flag that lets ExtrudeMesh override ep->Recombine; // tri_quad_values: 0 = no override, 1 = mesh as quads, 2 = mesh as triangles. // if this face is a free surface: if( adjacent_regions.size() == 1 ){ if( lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_NOVERTS_1_RECOMB || lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_ADDVERTS_1_RECOMB ){ (*tri_quad_flag) = 1; } if( lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_NOVERTS_1 || lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_ADDVERTS_1 ){ (*tri_quad_flag) = 2; } else (*tri_quad_flag) = 0; } else if( adjacent_regions.size() > 1 ){ GRegion *adj_region = NULL; ExtrudeParams *adj_ep = NULL; if( lateral_regions[0] == adjacent_regions[0] ) adj_region = adjacent_regions[1]; else adj_region = adjacent_regions[0]; adj_ep = adj_region->meshAttributes.extrude; // if Neighbor is Transfinite, go with the default, non-QuadTri recombine for this surface if( adj_region && adj_region->meshAttributes.method == MESH_TRANSFINITE ) (*tri_quad_flag) = 0; // if a neighbor // has no extrusion structure, // don't even consider QuadToTri Recomb on this face. else if( adj_region && !(adj_ep && adj_ep->mesh.ExtrudeMesh) ) (*tri_quad_flag) = 2; // This face is the source face of a second // neighboring extrusion. else if( adj_ep && adj_ep->mesh.ExtrudeMesh && model->getFaceByTag( std::abs( adj_ep->geo.Source ) ) == face ){ if( lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_NOVERTS_1_RECOMB || lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_ADDVERTS_1_RECOMB ) (*tri_quad_flag) = 1; else if( lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_NOVERTS_1 || lateral_regions[0]->meshAttributes.extrude->mesh.QuadToTri == QUADTRI_ADDVERTS_1 ) (*tri_quad_flag) = 2; else (*tri_quad_flag) = 0; } // if both neighbors are structured but none of the previous apply: else if( adj_ep && adj_ep->mesh.ExtrudeMesh ){ if( (adj_ep && !adj_ep->mesh.QuadToTri && adj_ep->mesh.Recombine) || (ep && !ep->mesh.QuadToTri && ep->mesh.Recombine) ) (*tri_quad_flag) = 1; else if( (adj_ep && !adj_ep->mesh.QuadToTri && !adj_ep->mesh.Recombine) || (ep && !ep->mesh.QuadToTri && !ep->mesh.Recombine) ) (*tri_quad_flag) = 2; // if both are quadToTri ALWAYS try to recombine else if( ep->mesh.QuadToTri && adj_ep && adj_ep->mesh.QuadToTri ) (*tri_quad_flag) = 1; else (*tri_quad_flag) = 0; } // any other adjacent surface, just default to the QuadToTri region's non-QuadToTri // default recombination method. Any mistakes at this point are not this feature's. else (*tri_quad_flag) = 0; } // if this executes, there's a mistake here : else{ detect_conflict = true; (*tri_quad_flag) = 0; } if( detect_conflict ) return 0; else return 1; }
// The function that tests whether a surface is a QuadToTri top surface and whether // there are conflicts. If surface is not a top for a valid QuadToTri region or if // there are QuadToTri conflicts, return 0. // if the surface turns out to be the source of a toroidal loop extrusion (which will then // NOT have geo.Mode == COPIED_ENTITY), return 2 (this will require special meshing considerations). // Note that RemoveDuplicateSurfaces() makes this DIFFICULT. // Also, the type of QuadToTri interface is placed into the // pointer argument quadToTri. . // Added 2010-12-09. int IsValidQuadToTriTop(GFace *face, int *quadToTri, bool *detectQuadToTriTop) { (*quadToTri) = NO_QUADTRI; (*detectQuadToTriTop) = false; int is_toroidal_quadtri = 0; GModel *model = face->model(); // First thing is first: determine if this is a toroidal quadtri extrusion. if so, can skip the rest // It seems the member pointers to neighboring regions for extruded top faces are not set. // For now, have to loop through // ALL the regions to see if the presently considered face belongs to the region. // The following loop will find all the regions that the face bounds, and determine // whether the face is a top face of the region (including whether the region is even extruded). // After that information is determined, function can test for QuadToTri neighbor conflicts. // first determine if this is toroidal quadtotri is_toroidal_quadtri = IsInToroidalQuadToTri(face); if( is_toroidal_quadtri ) (*detectQuadToTriTop) = true; else{ std::vector<GRegion *> top_regions; std::vector<GRegion *> adjacent_regions; std::vector<GRegion *> all_regions; int numRegions = 0; int numTopRegions = 0; std::set<GRegion *, GEntityLessThan>::iterator itreg; for( itreg = model->firstRegion(); itreg != model->lastRegion(); itreg++ ) all_regions.push_back( (*itreg) ); for(unsigned int i_reg = 0; i_reg < all_regions.size(); i_reg++ ){ // save time if( numRegions >= 2 ) break; GRegion *region = all_regions[i_reg]; // is region in the current model's regions or is it deleted? if( !FindVolume( ( region->tag() ) ) ) continue; // does face belong to region? std::list<GFace *> region_faces = std::list<GFace *>( region->faces() ); if( std::find( region_faces.begin(), region_faces.end(), face ) != region_faces.end() ){ adjacent_regions.push_back(region); numRegions++; } else continue; // is region a structured extruded? if( !(region->meshAttributes.extrude && region->meshAttributes.extrude->mesh.ExtrudeMesh && region->meshAttributes.extrude->geo.Mode == EXTRUDED_ENTITY) ) continue; // Test whether the face is a top for the region if( IsSurfaceATopForRegion(region, face) ){ top_regions.push_back(region); numTopRegions++; if( region->meshAttributes.extrude->mesh.QuadToTri ) (*detectQuadToTriTop) = true; } } // MAIN test of whether this is even a quadToTri extrusion lateral // the only return 0 path that is NOT an error if( !(*detectQuadToTriTop) ) return 0; ExtrudeParams *ep = face->meshAttributes.extrude; if(!ep && !is_toroidal_quadtri){ Msg::Error("In IsValidQuadToTriTop(), no extrude info for surface %d.", face->tag() ); return 0; } if( ep->geo.Mode != COPIED_ENTITY ){ Msg::Error("In IsValidQuadToTriTop(), surface %d is not copied from source.", face->tag() ); return 0; } if( ep->mesh.QuadToTri == 0){ Msg::Error("In IsValidQuadToTriTop(), surface %d was determined to be the top surface " "for a QuadToTri extrusion, but does not have QuadToTri parameters set within itself.", face->tag() ); return 0; } GFace *face_source = model->getFaceByTag(std::abs(ep->geo.Source)); if(!face_source){ Msg::Error("In IsValidQuadToTriTop(), unknown source face number %d.", face->meshAttributes.extrude->geo.Source); return 0; } if(numRegions > 2){ Msg::Error("In IsValidQuadToTriTop(), too many regions adjacent to surface %d.", face->tag() ); return 0; } if( top_regions.size() ){ (*quadToTri) = top_regions[0]->meshAttributes.extrude->mesh.QuadToTri; } // Make sure that face is the top for only one region. if not, then there will likely // be conflicts (two regions extruded into each other). if( top_regions.size() > 1 ){ Msg::Error("In IsValidQuadToTriTop(), QuadToTri top surface %d identified as top " "surface for more than one region. Likely conflict.", face->tag() ); return 0; } } // end of else that executes if NOT toroidal extrusion // this is technically redundant...but if changes are made, it's good to keep this here at the end for safety if( !(*detectQuadToTriTop) ) return 0; if( !is_toroidal_quadtri ) return 1; else if( is_toroidal_quadtri == 1 ) { return 2;} // for toroidal extrusion else return 3; }
double ECHARM_cell::FindVectorSquaredReciprocal(int vIndex[3]) { double double_result = 0.0; double double_temp[6]; int i; if(IsOrthogonal()) { for(i=0;i<3;i++) double_result += fSquare(vIndex[i] / fSize->GetComponent(i)); } else { double_temp[0] = fSize->GetComponent(1) * fSize->GetComponent(2) * sin(fAngle->GetComponent(1)) / FindVolume(); double_temp[1] = fSize->GetComponent(0) * fSize->GetComponent(2) * sin(fAngle->GetComponent(0)) / FindVolume(); double_temp[2] = fSize->GetComponent(0) * fSize->GetComponent(1) * sin(fAngle->GetComponent(2)) / FindVolume(); double_temp[3] = fSize->GetComponent(0) * fSize->GetComponent(1) * fSize->GetComponent(2) * fSize->GetComponent(2) * (cos(fAngle->GetComponent(0)) * cos(fAngle->GetComponent(1)) - cos(fAngle->GetComponent(2))) / FindVolume(); double_temp[4] = fSize->GetComponent(0) * fSize->GetComponent(1) * fSize->GetComponent(1) * fSize->GetComponent(2) * (cos(fAngle->GetComponent(2)) * cos(fAngle->GetComponent(0)) - cos(fAngle->GetComponent(1))) / FindVolume(); double_temp[5] = fSize->GetComponent(0) * fSize->GetComponent(0) * fSize->GetComponent(1) * fSize->GetComponent(2) * (cos(fAngle->GetComponent(1)) * cos(fAngle->GetComponent(2)) - cos(fAngle->GetComponent(0))) / FindVolume(); for(i=0;i<3;i++) double_temp[i] = double_temp[i] * double_temp[i] * vIndex[i] * vIndex[i]; double_temp[3] *= (2 * vIndex[0] * vIndex[1]); double_temp[4] *= (2 * vIndex[2] * vIndex[0]); double_temp[5] *= (2 * vIndex[2] * vIndex[2]); for(i=0;i<6;i++) double_result += double_temp[i]; } double_result *= (4 * M_PI * M_PI); return double_result; }