int TexelDelta( face_t *f, dplane_t *plane ) { int current, delta; current = delta = 0; // Does the plane split the face? if ( FaceSide (f, plane) == SIDE_ON ) { face_t *front, *back; // Compute the change in texture cache from splitting the face current = TexelSize( f ); // Speculatively split the face SplitFaceTmp(f, plane, &front, &back); if (!front || !back) // Didn't actually split the face delta = 0; else { delta = 0;//TexelSize( front ) + TexelSize( back ) - current; // Change in texel size FreeFace( front ); // Free new faces FreeFace( back ); } } return delta; }
/* ================== ChoosePlaneFromList The real BSP hueristic ================== */ static surface_t * ChoosePlaneFromList(surface_t *surfaces, vec3_t mins, vec3_t maxs) { int k; surface_t *p, *p2, *bestsurface; int bestvalue; vec_t bestdistribution, value; plane_t *plane; face_t *f; /* pick the plane that splits the least */ bestvalue = INT_MAX; bestdistribution = VECT_MAX; bestsurface = NULL; for (p = surfaces; p; p = p->next) { if (p->onnode) continue; plane = &pPlanes[p->planenum]; k = 0; for (p2 = surfaces; p2; p2 = p2->next) { if (p2 == p || p2->onnode) continue; if (plane->type < 3 && plane->type == pPlanes[p2->planenum].type) continue; for (f = p2->faces; f; f = f->next) { if (FaceSide(f, plane) == SIDE_ON) { k++; if (k >= bestvalue) break; } } if (k > bestvalue) break; } if (k > bestvalue) continue; /* * if equal numbers axial planes win, otherwise decide on spatial * subdivision */ if (k < bestvalue || (k == bestvalue && plane->type < 3)) { if (plane->type < 3) { value = SplitPlaneMetric(plane, mins, maxs); if (value > bestdistribution && k == bestvalue) continue; bestdistribution = value; } /* currently the best! */ bestvalue = k; bestsurface = p; } } return bestsurface; }
ON_Brep* ON_BrepRegion::RegionBoundaryBrep( ON_Brep* brep ) const { ON_Workspace ws; if ( 0 == m_rtop ) return 0; const ON_Brep* rtop_brep = m_rtop->Brep(); if ( rtop_brep == brep || 0 == rtop_brep || rtop_brep->m_F.Count() <= 0 || m_fsi.Count() <= 0 ) return 0; ON_SimpleArray<const ON_BrepFaceSide*> FS(m_fsi.Count()); ON_SimpleArray<int> subfi(m_fsi.Count()); int rfsi, i; for ( rfsi = 0; rfsi < m_fsi.Count(); rfsi++ ) { const ON_BrepFaceSide* fs = FaceSide(rfsi); if ( 0 == fs || fs->m_fi < 0 || fs->m_fi >= rtop_brep->m_F.Count() ) return 0; for ( i = 0; i < FS.Count(); i++ ) { if ( fs->m_fi == FS[i]->m_fi ) break; } if ( i < FS.Count() ) continue; FS.Append(fs); subfi.Append(fs->m_fi); } brep = rtop_brep->SubBrep(subfi.Count(),subfi.Array(),brep); if ( !brep ) return 0; if ( brep->m_F.Count() != FS.Count() ) return 0; for ( i = 0; i < FS.Count(); i++ ) { ON_BrepFace& face = brep->m_F[i]; face.m_bRev = ( FS[i]->m_srf_dir < 0 ); } ON_BOOL32 bIsOriented = false; ON_BOOL32 bHasBoundary = true; if ( brep->IsManifold(&bIsOriented,&bHasBoundary) ) { if ( bIsOriented && !bHasBoundary ) { if ( 1 == m_type ) brep->m_is_solid = 2; else if ( 0 == m_type ) brep->m_is_solid = 1; } } return brep; }
/* ================== ChoosePlaneFromList Choose the plane that splits the least faces ================== */ surface_t *ChoosePlaneFromList (surface_t *surfaces, vec3_t mins, vec3_t maxs) { int j,k,l; surface_t *p, *p2, *bestsurface; vec_t bestvalue, bestdistribution, value, dist; dplane_t *plane; face_t *f; // // pick the plane that splits the least // bestvalue = 99999; bestsurface = NULL; bestdistribution = 9e30; for (p=surfaces ; p ; p=p->next) { if (p->onnode) continue; plane = &dplanes[p->planenum]; k = 0; for (p2=surfaces ; p2 ; p2=p2->next) { if (p2 == p) continue; if (p2->onnode) continue; for (f=p2->faces ; f ; f=f->next) { if (FaceSide (f, plane) == SIDE_ON) { k++; if (k >= bestvalue) break; } } if (k > bestvalue) break; } if (k > bestvalue) continue; // if equal numbers, axial planes win, then decide on spatial subdivision if (k < bestvalue || (k == bestvalue && plane->type < PLANE_ANYX) ) { // check for axis aligned surfaces l = plane->type; if (l <= PLANE_Z) { // axial aligned // // calculate the split metric along axis l // value = 0; for (j=0 ; j<3 ; j++) { if (j == l) { dist = plane->dist * plane->normal[l]; value += (maxs[l]-dist)*(maxs[l]-dist); value += (dist-mins[l])*(dist-mins[l]); } else value += 2*(maxs[j]-mins[j])*(maxs[j]-mins[j]); } if (value > bestdistribution && k == bestvalue) continue; bestdistribution = value; } // // currently the best! // bestvalue = k; bestsurface = p; } } return bestsurface; }