/* ==================== MakeBigBox ==================== */ void MakeBigBox( fp_t size ) { vec3d_t norm; fp_t dist; int i; hobj_t *brushes; hobj_t *brush; hobj_t *surface; int plane; hpair_t *pair; FILE *h; brushes = NewClass( "bspbrushes", "bigbox0" ); brush = NewClass( "bspbrush", "bigbox" ); InsertClass( brushes, brush ); pair = NewHPair2( "ref", "original", "null" ); InsertHPair( brush, pair ); pair = NewHPair2( "int" , "content", "0" ); InsertHPair( brush, pair ); for ( i = 0; i < 3; i++ ) { char tt[256]; surface = NewClass( "surface", "noname" ); InsertClass( brush, surface ); pair = NewHPair2( "int", "content", "0" ); InsertHPair( surface, pair ); Vec3dInit( norm, 0.0, 0.0, 0.0 ); norm[i] = 1.0; dist = size; //tree->max[i] + 64.0; plane = FindPlane( norm, dist ); sprintf( tt, "#%d", p_planes[plane].clsname ); pair = NewHPair2( "ref", "plane", tt ); InsertHPair( surface, pair ); surface = NewClass( "surface", "noname" ); InsertClass( brush, surface ); pair = NewHPair2( "int", "content", "0" ); InsertHPair( surface, pair ); Vec3dInit( norm, 0.0, 0.0, 0.0 ); norm[i] = -1.0; dist = size; //- (tree->min[i] - 64.0); plane = FindPlane( norm, dist ); sprintf( tt, "#%d", p_planes[plane].clsname ); pair = NewHPair2( "ref", "plane", tt ); InsertHPair( surface, pair ); } h = fopen( "_bigbox.hobj", "w" ); if ( !h ) Error( "can't write bigbox class.\n" ); WriteClass( brushes, h ); fclose( h ); }
//===================================================================================== // CreateOutsidePortal //===================================================================================== GBSP_Portal *CreateOutsidePortal(GBSP_Plane *Plane, GBSP_Node *Node) { GBSP_Portal *NewPortal; int32 Side; NewPortal = AllocPortal(); if (!NewPortal) return NULL; NewPortal->Poly = CreatePolyFromPlane(Plane); if (!NewPortal->Poly) { return NULL; } NewPortal->PlaneNum = FindPlane(Plane, &Side); if (NewPortal->PlaneNum == -1) { GHook.Error("CreateOutsidePortal: Could not create plane.\n"); return NULL; } if (!Side) { if (!AddPortalToNodes(NewPortal, Node, OutsideNode)) return NULL; } else { if (!AddPortalToNodes(NewPortal, OutsideNode, Node)) return NULL; } return NewPortal; }
/* ================ MakeHeadnodePortals The created portals will face the global outside_node ================ */ void MakeHeadnodePortals (node_t *node) { vec3_t bounds[2]; int i, j, n; portal_t *p, *portals[6]; plane_t bplanes[6], *pl; int side; Draw_ClearWindow (); // pad with some space so there will never be null volume leafs for (i=0 ; i<3 ; i++) { bounds[0][i] = brushset->mins[i] - SIDESPACE; bounds[1][i] = brushset->maxs[i] + SIDESPACE; } outside_node.contents = CONTENTS_SOLID; outside_node.portals = NULL; for (i=0 ; i<3 ; i++) for (j=0 ; j<2 ; j++) { n = j*3 + i; p = AllocPortal (); portals[n] = p; pl = &bplanes[n]; memset (pl, 0, sizeof(*pl)); if (j) { pl->normal[i] = -1; pl->dist = -bounds[j][i]; } else { pl->normal[i] = 1; pl->dist = bounds[j][i]; } p->planenum = FindPlane (pl, &side); p->winding = BaseWindingForPlane (pl); if (side) AddPortalToNodes (p, &outside_node, node); else AddPortalToNodes (p, node, &outside_node); } // clip the basewindings by all the other planes for (i=0 ; i<6 ; i++) { for (j=0 ; j<6 ; j++) { if (j == i) continue; portals[i]->winding = ClipWinding (portals[i]->winding, &bplanes[j], true); } } }
/* * @brief */ static int32_t PlaneFromPoints(const vec3_t p0, const vec3_t p1, const vec3_t p2) { vec3_t t1, t2, normal; VectorSubtract(p0, p1, t1); VectorSubtract(p2, p1, t2); CrossProduct(t1, t2, normal); VectorNormalize(normal); const dvec_t dist = DotProduct(p0, normal); return FindPlane(normal, dist); }
/** * @brief Creates a new axial brush */ static brush_t *BrushFromBounds(vec3_t mins, vec3_t maxs) { brush_t *b; int32_t i; vec3_t normal; vec_t dist; b = AllocBrush(6); b->num_sides = 6; for (i = 0; i < 3; i++) { VectorClear(normal); normal[i] = 1; dist = maxs[i]; b->sides[i].plane_num = FindPlane(normal, dist); normal[i] = -1; dist = -mins[i]; b->sides[3 + i].plane_num = FindPlane(normal, dist); } CreateBrushWindings(b); return b; }
/* ============================== AddPlaneClasses ============================== */ void AddPlaneClasses( hmanager_t *planehm ) { hobj_search_iterator_t iter; hobj_t *plane; InitClassSearchIterator( &iter, HManagerGetRootClass( planehm ), "*" ); for ( ; ( plane = SearchGetNextClass( &iter ) ) ; ) { vec3d_t norm; fp_t dist; int planenum; hpair_t *pair; char tt[256]; EasyFindVec3d( norm, plane, "norm" ); EasyFindFloat( &dist, plane, "dist" ); planenum = FindPlane( norm, dist ); // printf( "%d ", planenum ); sprintf( tt, "#%d", p_planes[planenum].clsname ); pair = NewHPair2( "ref", "plane", tt ); InsertHPair( plane, pair ); } }
void CreateBrushFaces (void) { int i,j, k; vec_t r; face_t *f; winding_t *w; plane_t plane; mface_t *mf; brush_mins[0] = brush_mins[1] = brush_mins[2] = 99999; brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -99999; brush_faces = NULL; for (i=0 ; i<numbrushfaces ; i++) { mf = &faces[i]; w = BaseWindingForPlane (&mf->plane); for (j=0 ; j<numbrushfaces && w ; j++) { if (j == i) continue; // flip the plane, because we want to keep the back side VectorSubtract (vec3_origin,faces[j].plane.normal, plane.normal); plane.dist = -faces[j].plane.dist; w = ClipWinding (w, &plane, false); } if (!w) continue; // overcontrained plane // this face is a keeper f = AllocFace (); f->numpoints = w->numpoints; if (f->numpoints > MAXEDGES) Error ("f->numpoints > MAXEDGES"); for (j=0 ; j<w->numpoints ; j++) { for (k=0 ; k<3 ; k++) { r = Q_rint (w->points[j][k]); if ( fabs(w->points[j][k] - r) < ZERO_EPSILON) f->pts[j][k] = r; else f->pts[j][k] = w->points[j][k]; if (f->pts[j][k] < brush_mins[k]) brush_mins[k] = f->pts[j][k]; if (f->pts[j][k] > brush_maxs[k]) brush_maxs[k] = f->pts[j][k]; } } FreeWinding (w); f->texturenum = mf->texinfo; f->planenum = FindPlane (&mf->plane, &f->planeside); f->next = brush_faces; brush_faces = f; CheckFace (f); } }
//==================================================================================== // FinishLeafSides //==================================================================================== geBoolean FinishLeafSides(GBSP_Node *Node) { geVec3d Mins, Maxs; GBSP_Plane Plane; int32 Axis, i, Dir; if (!GetLeafBBoxFromPortals(Node, &Mins, &Maxs)) { GHook.Error("FinishLeafSides: Could not get leaf portal BBox.\n"); return GE_FALSE; } if (CNumLeafSides < 4) GHook.Printf("*WARNING* FinishLeafSides: Incomplete leaf volume.\n"); // Add any bevel planes to the sides so we can expand them for axial box collisions else for (Axis=0 ; Axis <3 ; Axis++) { for (Dir=-1 ; Dir <= 1 ; Dir+=2) { // See if the plane is allready in the sides for (i=0; i< CNumLeafSides; i++) { Plane = Planes[LPlaneNumbers[i]]; if (LPlaneSides[i]) { geVec3d_Inverse(&Plane.Normal); Plane.Dist = -Plane.Dist; } if (VectorToSUB(Plane.Normal, Axis) == (geFloat)Dir) break; } if (i >= CNumLeafSides) { // Add a new axial aligned side geVec3d_Clear(&Plane.Normal); VectorToSUB(Plane.Normal, Axis) = (geFloat)Dir; // get the mins/maxs from the gbsp brush if (Dir == 1) Plane.Dist = VectorToSUB(Maxs, Axis); else Plane.Dist = -VectorToSUB(Mins, Axis); LPlaneNumbers[i] = FindPlane(&Plane, &LPlaneSides[i]); if (LPlaneNumbers[i] == -1) { GHook.Error("FinishLeafSides: Could not create the plane.\n"); return GE_FALSE; } CNumLeafSides++; NumLeafBevels++; } } } Node->FirstSide = NumLeafSides; Node->NumSides = CNumLeafSides; for (i=0; i< CNumLeafSides; i++) { if (NumLeafSides >= MAX_LEAF_SIDES) { GHook.Error("FinishLeafSides: Max Leaf Sides.\n"); return GE_FALSE; } LeafSides[NumLeafSides].PlaneNum = LPlaneNumbers[i]; LeafSides[NumLeafSides].PlaneSide = LPlaneSides[i]; NumLeafSides++; } return GE_TRUE; }
/* * @brief */ static void EmitBrushes(void) { int32_t i, j, bnum, s, x; d_bsp_brush_t *db; map_brush_t *b; d_bsp_brush_side_t *cp; vec3_t normal; vec_t dist; int32_t plane_num; d_bsp.num_brush_sides = 0; d_bsp.num_brushes = num_map_brushes; for (bnum = 0; bnum < num_map_brushes; bnum++) { b = &map_brushes[bnum]; db = &d_bsp.brushes[bnum]; db->contents = b->contents; db->first_side = d_bsp.num_brush_sides; db->num_sides = b->num_sides; for (j = 0; j < b->num_sides; j++) { if (d_bsp.num_brush_sides == MAX_BSP_BRUSH_SIDES) Com_Error(ERR_FATAL, "MAX_BSP_BRUSH_SIDES\n"); cp = &d_bsp.brush_sides[d_bsp.num_brush_sides]; d_bsp.num_brush_sides++; cp->plane_num = b->original_sides[j].plane_num; cp->surf_num = b->original_sides[j].texinfo; } // add any axis planes not contained in the brush to bevel off corners for (x = 0; x < 3; x++) { for (s = -1; s <= 1; s += 2) { // add the plane VectorClear(normal); normal[x] = (vec_t) s; if (s == -1) dist = -b->mins[x]; else dist = b->maxs[x]; plane_num = FindPlane(normal, dist); for (i = 0; i < b->num_sides; i++) if (b->original_sides[i].plane_num == plane_num) break; if (i == b->num_sides) { if (d_bsp.num_brush_sides >= MAX_BSP_BRUSH_SIDES) Com_Error(ERR_FATAL, "MAX_BSP_BRUSH_SIDES\n"); d_bsp.brush_sides[d_bsp.num_brush_sides].plane_num = plane_num; d_bsp.brush_sides[d_bsp.num_brush_sides].surf_num = d_bsp.brush_sides[d_bsp.num_brush_sides - 1].surf_num; d_bsp.num_brush_sides++; db->num_sides++; } } } } }
/* * @brief */ static _Bool ParseMapEntity(void) { entity_t *mapent; epair_t *e; side_t *s; int32_t i, j; vec_t newdist; map_brush_t *b; if (!GetToken(true)) return false; if (g_strcmp0(token, "{")) Com_Error(ERR_FATAL, "\"{\" not found\n"); if (num_entities == MAX_BSP_ENTITIES) Com_Error(ERR_FATAL, "MAX_BSP_ENTITIES\n"); mapent = &entities[num_entities]; num_entities++; memset(mapent, 0, sizeof(*mapent)); mapent->first_brush = num_map_brushes; mapent->num_brushes = 0; do { if (!GetToken(true)) Com_Error(ERR_FATAL, "EOF without closing brace\n"); if (!g_strcmp0(token, "}")) break; if (!g_strcmp0(token, "{")) ParseBrush(mapent); else { e = ParseEpair(); e->next = mapent->epairs; mapent->epairs = e; } } while (true); VectorForKey(mapent, "origin", mapent->origin); // if there was an origin brush, offset all of the planes and texinfo if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2]) { for (i = 0; i < mapent->num_brushes; i++) { b = &map_brushes[mapent->first_brush + i]; for (j = 0; j < b->num_sides; j++) { s = &b->original_sides[j]; newdist = map_planes[s->plane_num].dist - DotProduct(map_planes[s->plane_num].normal, mapent->origin); s->plane_num = FindPlane(map_planes[s->plane_num].normal, newdist); s->texinfo = TexinfoForBrushTexture(&map_planes[s->plane_num], &map_brush_textures[s - map_brush_sides], mapent->origin); } MakeBrushWindings(b); } } // group entities are just for editor convenience // toss all brushes into the world entity if (!g_strcmp0("func_group", ValueForKey(mapent, "classname"))) { MoveBrushesToWorld(mapent); mapent->num_brushes = 0; return true; } // areaportal entities move their brushes, but don't eliminate the entity if (!g_strcmp0("func_areaportal", ValueForKey(mapent, "classname"))) { char str[128]; if (mapent->num_brushes != 1) Com_Error( ERR_FATAL, "ParseMapEntity: %i func_areaportal can only be a single brush\n", num_entities - 1); b = &map_brushes[num_map_brushes - 1]; b->contents = CONTENTS_AREA_PORTAL; c_area_portals++; mapent->area_portal_num = c_area_portals; // set the portal number as "style" sprintf(str, "%i", c_area_portals); SetKeyValue(mapent, "areaportal", str); MoveBrushesToWorld(mapent); return true; } return true; }
/* * @brief Adds any additional planes necessary to allow the brush to be expanded * against axial bounding boxes */ static void AddBrushBevels(map_brush_t * b) { int32_t axis, dir; int32_t i, j, k, l, order; side_t sidetemp; map_brush_texture_t tdtemp; side_t *s, *s2; vec3_t normal; vec_t dist; winding_t *w, *w2; vec3_t vec, vec2; vec_t d; // add the axial planes order = 0; for (axis = 0; axis < 3; axis++) { for (dir = -1; dir <= 1; dir += 2, order++) { // see if the plane is already present for (i = 0, s = b->original_sides; i < b->num_sides; i++, s++) { if (map_planes[s->plane_num].normal[axis] == dir) break; } if (i == b->num_sides) { // add a new side if (num_map_brush_sides == MAX_BSP_BRUSH_SIDES) Com_Error(ERR_FATAL, "MAX_BSP_BRUSH_SIDES\n"); num_map_brush_sides++; b->num_sides++; VectorClear(normal); normal[axis] = dir; if (dir == 1) dist = b->maxs[axis]; else dist = -b->mins[axis]; s->plane_num = FindPlane(normal, dist); s->texinfo = b->original_sides[0].texinfo; s->contents = b->original_sides[0].contents; s->bevel = true; c_box_bevels++; } // if the plane is not in it canonical order, swap it if (i != order) { sidetemp = b->original_sides[order]; b->original_sides[order] = b->original_sides[i]; b->original_sides[i] = sidetemp; j = b->original_sides - map_brush_sides; tdtemp = map_brush_textures[j + order]; map_brush_textures[j + order] = map_brush_textures[j + i]; map_brush_textures[j + i] = tdtemp; } } } // add the edge bevels if (b->num_sides == 6) return; // pure axial // test the non-axial plane edges for (i = 6; i < b->num_sides; i++) { s = b->original_sides + i; w = s->winding; if (!w) continue; for (j = 0; j < w->num_points; j++) { k = (j + 1) % w->num_points; VectorSubtract(w->points[j], w->points[k], vec); if (VectorNormalize(vec) < 0.5) { continue; } SnapNormal(vec); for (k = 0; k < 3; k++) { if (vec[k] == -1.0 || vec[k] == 1.0 || (vec[k] == 0.0 && vec[(k + 1) % 3] == 0.0)) { break; // axial } } if (k != 3) { continue; // only test non-axial edges } // try the six possible slanted axials from this edge for (axis = 0; axis < 3; axis++) { for (dir = -1; dir <= 1; dir += 2) { // construct a plane VectorClear(vec2); vec2[axis] = dir; CrossProduct(vec, vec2, normal); if (VectorNormalize(normal) < 0.5) continue; dist = DotProduct(w->points[j], normal); // if all the points on all the sides are // behind this plane, it is a proper edge bevel for (k = 0; k < b->num_sides; k++) { vec_t minBack; // if this plane has already been used, skip it if (PlaneEqual(&map_planes[b->original_sides[k].plane_num], normal, dist)) break; w2 = b->original_sides[k].winding; if (!w2) continue; minBack = 0.0f; for (l = 0; l < w2->num_points; l++) { d = DotProduct(w2->points[l], normal) - dist; if (d > 0.1) break; // point in front if (d < minBack) minBack = d; } // if some point was at the front if (l != w2->num_points) break; // if no points at the back then the winding is on the // bevel plane if (minBack > -0.1f) break; } if (k != b->num_sides) continue; // wasn't part of the outer hull // add this plane if (num_map_brush_sides == MAX_BSP_BRUSH_SIDES) Com_Error(ERR_FATAL, "MAX_BSP_BRUSH_SIDES\n"); s2 = &b->original_sides[b->num_sides++]; s2->plane_num = FindPlane(normal, dist); s2->texinfo = b->original_sides[0].texinfo; s2->contents = b->original_sides[0].contents; s2->bevel = true; num_map_brush_sides++; c_edge_bevels++; } } } } }
// Constructor with two correlation surfaces ------------------------- Simbox::Simbox(const Simbox * simbox, const std::string & interval_name, int n_layers, double ext_dz, double lz_limit, const Surface & top_surface, const Surface & base_surface, const Surface * top_corr_surface, const Surface * base_corr_surface, int other_output, int output_domain, int output_format, std::string & err_text, bool & failed) : Volume(*simbox), top_eroded_surface_(NULL), base_eroded_surface_(NULL) { std::string output_name = ""; if (interval_name != "") output_name = " for interval \'" + interval_name + "\'"; LogKit::LogFormatted(LogKit::Low,"\nCreating a temporary simbox (used for inversion grid) with two correlation surfaces" + output_name + ".\n"); interval_name_ = interval_name; status_ = BOXOK; cosrot_ = cos(simbox->GetAngle()); sinrot_ = sin(simbox->GetAngle()); dx_ = simbox->getdx(); dy_ = simbox->getdy(); dz_ = -1; nx_ = simbox->getnx(); ny_ = simbox->getny(); nz_ = n_layers; nx_pad_ = nx_; ny_pad_ = ny_; nz_pad_ = nz_; x_pad_fac_ = (nx_pad_ / nx_); y_pad_fac_ = (ny_pad_ / ny_); z_pad_fac_ = (nz_pad_ / nz_); lz_eroded_ = 0; inLine0_ = simbox->getIL0(); crossLine0_ = simbox->getXL0(); ilStepX_ = simbox->getILStepX(); ilStepY_ = simbox->getILStepY(); xlStepX_ = simbox->getXLStepX(); xlStepY_ = simbox->getXLStepY(); constThick_ = simbox->getIsConstantThick(); setDepth(top_surface, base_surface, n_layers); SetErodedSurfaces(top_surface, base_surface); //this->calculateDz(lz_limit, err_text); double old_dz = GetLZ() / nz_; // // Check that the two surfaces do not intersect // double x,y; for (size_t i = 0; i < base_surface.GetNI(); i++){ for (size_t j = 0; j < base_surface.GetNJ(); j++){ base_surface.GetXY(i,j,x,y); double z_top_corr = top_corr_surface->GetZ(x,y); double z_base_corr = base_corr_surface->GetZ(x,y); if (!top_corr_surface->IsMissing(z_top_corr) && !base_corr_surface->IsMissing(z_base_corr) && z_top_corr > z_base_corr) { std::string interval_text = ""; if (interval_name != "") interval_text = " for interval " + interval_name; err_text += "Error: The top correlation surface crosses the base correlation surface" + interval_text + ".\n"; failed = true; } } } // // Check that the correlation surfaces cover the inversion surfaces // if (simbox->CheckSurface(*top_corr_surface) == false) { err_text += "Error: Top correlation surface "+ top_corr_surface->GetName() +"does not cover volume.\n"; failed = true; } if (simbox->CheckSurface(*base_corr_surface) == false){ err_text += "Error: Base correlation surface "+ base_corr_surface->GetName() +"does not cover volume.\n"; failed = true; } // // Should the corr surfaces have the same resolution? // if(!failed){ Surface * mean_corr_surface; //NRLib::Vector corr_plane_parameters_top = FindPlane(top_corr_surface); //NRLib::Vector corr_plane_parameters_base = FindPlane(base_corr_surface); Surface * mean_surface; // Use the finest resolution double resolution_top = top_corr_surface->GetDX()*top_corr_surface->GetDY(); double resolution_base = base_corr_surface->GetDX()*base_corr_surface->GetDY(); if(resolution_top != resolution_base){ if(resolution_top > resolution_base){ // base corr surface has higher resolution mean_surface = new Surface(*base_corr_surface); mean_corr_surface = new Surface(*base_corr_surface); } else{ // top corr surface has the highest resolution mean_surface = new Surface(*top_corr_surface); mean_corr_surface = new Surface(*top_corr_surface); } } else{ mean_surface = new Surface(*top_corr_surface); mean_corr_surface = new Surface(*top_corr_surface); } // Initialize mean surface to 0 for(size_t i = 0; i < mean_surface->GetN(); i++){ (*mean_surface)(i) = 0; (*mean_corr_surface)(i) = 0; } // Find mean of top and base surface mean_surface->AddNonConform(&top_surface); mean_surface->AddNonConform(&base_surface); mean_surface->Multiply(0.5); NRLib::Vector ref_plane_parameters = FindPlane(mean_surface); // Find the mean of the top and base correlation surface mean_corr_surface->AddNonConform(top_corr_surface); mean_corr_surface->AddNonConform(base_corr_surface); mean_corr_surface->Multiply(0.5); //NRLib::Vector corr_plane_parameters = FindPlane(mean_corr_surface); // tilt the mean plane with the correlation plane NRLib::Vector corr_plane_parameters_mean = FindPlane(mean_corr_surface); ref_plane_parameters -= corr_plane_parameters_mean; grad_x_ = ref_plane_parameters(1); grad_y_ = ref_plane_parameters(2); // Create plane from parameters and add the original corr surfaces //Surface * ref_plane_base = CreatePlaneSurface(ref_plane_parameters, mean_surface); Surface * ref_plane = CreatePlaneSurface(ref_plane_parameters, mean_surface); // Create new top surface ref_plane->AddNonConform(top_corr_surface); ref_plane->AddNonConform(base_corr_surface); ref_plane->Multiply(0.5); Surface new_top(*ref_plane); new_top.SubtractNonConform(&(top_surface)); double shift_top = new_top.Max(); shift_top *= -1.0; new_top.Add(shift_top); new_top.AddNonConform(&top_surface);//new_top.AddNonConform(&(simbox->GetTopSurface())); //H? // Create new base surface //ref_plane_base->AddNonConform(base_corr_surface); Surface new_base(*ref_plane); new_base.SubtractNonConform(&(base_surface)); double shift_bot = new_base.Min(); shift_bot *= -1.0; double thick = shift_bot-shift_top; double dz = old_dz; if(n_layers < 0) dz = ext_dz; int nz = int(thick/dz); double residual = thick - nz*dz; if (residual > 0.0) { shift_bot += dz-residual; nz++; } if (nz != n_layers && n_layers > 0) { std::string interval_text = ""; if (interval_name != "") interval_text += " in interval " + interval_name; LogKit::LogFormatted(LogKit::High,"\nNumber of layers" + interval_text + " increased from %d", n_layers); LogKit::LogFormatted(LogKit::High," to %d in grid created using the correlation direction.\n",nz); } new_base.Add(shift_bot); new_base.AddNonConform(&(base_surface)); setDepth(new_top, new_base, nz); this->calculateDz(lz_limit, err_text); if((other_output & IO::EXTRA_SURFACES) > 0 && (output_domain & IO::TIMEDOMAIN) > 0) { std::string top_surf_name = IO::PrefixSurface() + IO::PrefixTop() + interval_name + "_" + IO::PrefixTime() + "_Extended"; std::string base_surf_name = IO::PrefixSurface() + IO::PrefixBase() + interval_name + "_" + IO::PrefixTime() + "_Extended"; if (interval_name == ""){ top_surf_name = IO::PrefixSurface() + IO::PrefixTop() + IO::PrefixTime() + "_Extended"; base_surf_name = IO::PrefixSurface() + IO::PrefixBase() + IO::PrefixTime() + "_Extended"; } WriteTopBaseSurfaceGrids(top_surf_name, base_surf_name, IO::PathToInversionResults(), output_format); } delete ref_plane; //delete ref_plane_base; delete mean_surface; delete mean_corr_surface; } }
// // Constructor for intervals with one correlation direction // Simbox::Simbox(const Simbox * simbox, const std::string & interval_name, int n_layers, double ext_dz, double lz_limit, const Surface & top_surface, const Surface & bot_surface, Surface * single_corr_surface, int other_output, int output_domain, int output_format, std::string & err_text, bool & failed) : Volume(*simbox), top_eroded_surface_(NULL), base_eroded_surface_(NULL) { std::string output_name = ""; if (interval_name != "") output_name = " for interval \'" + interval_name + "\'"; LogKit::LogFormatted(LogKit::Low,"\nCreating a temporary simbox (used for inversion grid) with one correlation surface" + output_name + ".\n"); interval_name_ = interval_name; status_ = BOXOK; cosrot_ = cos(simbox->GetAngle()); sinrot_ = sin(simbox->GetAngle()); SetAngle (simbox->GetAngle()); dx_ = simbox->getdx(); dy_ = simbox->getdy(); dz_ = -1; nx_ = simbox->getnx(); ny_ = simbox->getny(); nz_ = n_layers; nx_pad_ = nx_; ny_pad_ = ny_; nz_pad_ = nz_; x_pad_fac_ = (nx_pad_ / nx_); y_pad_fac_ = (ny_pad_ / ny_); z_pad_fac_ = (nz_pad_ / nz_); topName_ = ""; botName_ = ""; lz_eroded_ = 0; inLine0_ = simbox->getIL0(); crossLine0_ = simbox->getXL0(); ilStepX_ = simbox->getILStepX(); ilStepY_ = simbox->getILStepY(); xlStepX_ = simbox->getXLStepX(); xlStepY_ = simbox->getXLStepY(); constThick_ = simbox->getIsConstantThick(); SetSurfaces(top_surface, bot_surface); //Needed for GetLZ() //this->calculateDz(lz_limit, err_text); //calculcateDz also checks for interval-thickness. Since surfaces are eroded they may be zero which gives and error. double old_dz = GetLZ() / nz_; SetErodedSurfaces(top_surface, bot_surface); if (simbox->CheckSurface(*single_corr_surface) != true) { err_text += "Error: Correlation surface "+single_corr_surface->GetName()+" does not cover volume.\n"; failed = true; } // Extend simbox as in ModelGeneral::SetupExtendedTimeSimbox NRLib::Vector corr_plane_parameters = FindPlane(single_corr_surface); Surface * mean_surface; if(single_corr_surface->GetNI() > 2) mean_surface = new Surface(*single_corr_surface); else { mean_surface = new Surface(dynamic_cast<const Surface &>(top_surface)); if(mean_surface->GetNI() == 2) { //Extend corrSurf to cover other surfaces. double minX = mean_surface->GetXMin(); double maxX = mean_surface->GetXMax(); double minY = mean_surface->GetYMin(); double maxY = mean_surface->GetYMax(); if(minX > single_corr_surface->GetXMin()) minX = single_corr_surface->GetXMin(); if(maxX < single_corr_surface->GetXMax()) maxX = single_corr_surface->GetXMax(); if(minY > single_corr_surface->GetYMin()) minY = single_corr_surface->GetYMin(); if(maxY < single_corr_surface->GetYMax()) maxY = single_corr_surface->GetYMax(); single_corr_surface->SetDimensions(minX, minY, maxX-minX, maxY-minY); } } // initialize mean surface to 0 for(size_t i=0;i<mean_surface->GetN();i++) (*mean_surface)(i) = 0; // Find mean of top and base surface mean_surface->AddNonConform(&(top_surface)); mean_surface->AddNonConform(&(bot_surface)); mean_surface->Multiply(0.5); NRLib::Vector ref_plane_parameters = FindPlane(mean_surface); // tilt the mean plane with the correlation plane ref_plane_parameters -= corr_plane_parameters; grad_x_ = ref_plane_parameters(1); grad_y_ = ref_plane_parameters(2); // Create plane from parameters and add the original corr surface Surface * ref_plane = CreatePlaneSurface(ref_plane_parameters, mean_surface); ref_plane->AddNonConform(single_corr_surface); // Create new top surface Surface new_top_surface(*ref_plane); new_top_surface.SubtractNonConform(&(top_surface)); double shift_top = new_top_surface.Max(); shift_top *= -1.0; new_top_surface.Add(shift_top); new_top_surface.AddNonConform(&(top_surface)); // Create new base surface Surface new_base_surface(*ref_plane); new_base_surface.SubtractNonConform(&(bot_surface)); double shift_bot = new_base_surface.Min(); shift_bot *= -1.0; double thick = shift_bot-shift_top; double dz = old_dz; if(n_layers < 0) dz = ext_dz; int nz = int(thick/dz); double residual = thick - nz*dz; if (residual > 0.0) { shift_bot += dz-residual; nz++; } if (nz != n_layers && n_layers > 0) { std::string interval_text = ""; if (interval_name != "") interval_text += " in interval " + interval_name; LogKit::LogFormatted(LogKit::High,"\n Number of layers" + interval_text + " increased from %d", n_layers); LogKit::LogFormatted(LogKit::High," to %d because of the correlation direction.\n",nz); } new_base_surface.Add(shift_bot); new_base_surface.AddNonConform(&(bot_surface)); setDepth(new_top_surface, new_base_surface, nz); this->calculateDz(lz_limit, err_text); if((other_output & IO::EXTRA_SURFACES) > 0 && (output_domain & IO::TIMEDOMAIN) > 0) { std::string top_surf_name = IO::PrefixSurface() + IO::PrefixTop() + interval_name + "_" + IO::PrefixTime() + "_Extended"; std::string base_surf_name = IO::PrefixSurface() + IO::PrefixBase() + interval_name + "_" + IO::PrefixTime() + "_Extended"; if (interval_name == ""){ top_surf_name = IO::PrefixSurface() + IO::PrefixTop() + IO::PrefixTime() + "_Extended"; base_surf_name = IO::PrefixSurface() + IO::PrefixBase() + IO::PrefixTime() + "_Extended"; } WriteTopBaseSurfaceGrids(top_surf_name, base_surf_name, IO::PathToInversionResults(), output_format); } delete mean_surface; delete ref_plane; }
hobj_t * ConvertBrushClass( hobj_t *brushes, hobj_t *brush ) { hpair_t *pair; hobj_search_iterator_t iter; hobj_t *face; int num; // brush data int bcontent; // face data vec3d_t norm, keep_norm; fp_t dist, keep_dist; int fcontent; char ident[TEXTURE_IDENT_SIZE]; fp_t rotate; vec2d_t scale; vec2d_t shift; bool_t no_contents; bool_t no_texdef; int pl; int td; hobj_t *tmp; hobj_t *out; char idtext[256]; // brush contents pair = FindHPair( brush, "content" ); if ( !pair ) Error( "missing brush content.\n" ); HPairCastToInt_safe( &bcontent, pair ); // hack moved to the script ... #if 0 // hack: fix some design leaks ... if ( bcontent == 6 ) bcontent = 4; #endif sprintf( idtext, "#%u", HManagerGetFreeID() ); out = NewClass( "bspbrush", idtext ); sprintf( idtext, "%u", bcontent ); pair = NewHPair2( "int", "content", idtext ); InsertHPair( out, pair ); pair = NewHPair2( "ref", "original", brush->name ); InsertHPair( out, pair ); // brush faces InitClassSearchIterator( &iter, brush, "face" ); for ( num = 0; ( face = SearchGetNextClass( &iter ) ) ; num++ ) { // // face plane // // plane dist pair = FindHPair( face, "dist" ); if ( !pair ) Error( "missing face plane distance.\n" ); HPairCastToFloat_safe( &dist, pair ); keep_dist = dist; // keep dist, cause FindPlane trash it up // plane norm pair = FindHPair( face, "norm" ); if ( !pair ) Error( "missing face plane normal.\n" ); HPairCastToVec3d_safe( norm, pair ); Vec3dCopy( keep_norm, norm ); // keep norm, dto // // face content // pair = FindHPair( face, "content" ); if ( !pair ) { // Error( "missing face content.\n" ); no_contents = true; } else { HPairCastToInt_safe( &fcontent, pair ); no_contents = false; } // // face texdef // // texture ident pair = FindHPair( face, "ident" ); if ( !pair ) { no_texdef = true; } else { HPairCastToString_safe( ident, pair ); no_texdef = false; // texdef rotate pair = FindHPair( face, "rotate" ); if ( !pair ) Error( "missing face texdef rotate.\n" ); HPairCastToFloat_safe( &rotate, pair ); // texdef shift pair = FindHPair( face, "shift" ); if ( !pair ) Error( "missing face texdef shift.\n" ); HPairCastToVec2d_safe( shift, pair ); // texdef scale pair = FindHPair( face, "scale" ); if ( !pair ) Error( "missing face texdef scale.\n" ); HPairCastToVec2d_safe( scale, pair ); } // // finish face // pl = FindPlane( norm, dist ); sprintf( idtext, "#%u", HManagerGetFreeID() ); tmp = NewClass( "surface", idtext ); // clsref_plane sprintf( idtext, "#%u", p_planes[pl].clsname ); pair = NewHPair2( "ref", "plane", idtext ); InsertHPair( tmp, pair ); if ( !no_texdef ) { // clsref_texdef td = FindTexdef( ident, rotate, scale, shift, pl ); sprintf( idtext, "#%u", p_wtexdefs[td].clsname ); pair = NewHPair2( "ref", "texdef", idtext ); InsertHPair( tmp, pair ); // special cpoly hack if ( !strcmp( ident, "devel/cpoly" )) { pair = NewHPair2( "int", "bsp_dont_split", "1" ); InsertHPair( tmp, pair ); stat_cpoly_hack++; } } if ( !no_contents ) { // content sprintf( idtext, "%d", fcontent ); pair = NewHPair2( "int", "content", idtext ); InsertHPair( tmp, pair ); } // insert surface into bspbrush InsertClass( out, tmp ); } total_faces+=num; // return out; InsertClass( brushes, out ); return out; }
/* ================= CreateBrushFaces ================= */ void CreateBrushFaces (void) { int i,j, k; vec_t r; face_t *f, *next; winding_t *w; plane_t clipplane, faceplane; mface_t *mf; vec3_t offset, point; offset[0] = offset[1] = offset[2] = 0; ClearBounds( brush_mins, brush_maxs ); brush_faces = NULL; if (!strncmp(ValueForKey(CurrentEntity, "classname"), "rotate_", 7)) { entity_t *FoundEntity; char *searchstring; char text[20]; searchstring = ValueForKey (CurrentEntity, "target"); FoundEntity = FindTargetEntity(searchstring); if (FoundEntity) GetVectorForKey(FoundEntity, "origin", offset); sprintf(text, "%g %g %g", offset[0], offset[1], offset[2]); SetKeyValue(CurrentEntity, "origin", text); } GetVectorForKey(CurrentEntity, "origin", offset); //printf("%i brushfaces at offset %f %f %f\n", numbrushfaces, offset[0], offset[1], offset[2]); for (i = 0;i < numbrushfaces;i++) { mf = &faces[i]; //printf("plane %f %f %f %f\n", mf->plane.normal[0], mf->plane.normal[1], mf->plane.normal[2], mf->plane.dist); faceplane = mf->plane; w = BaseWindingForPlane (&faceplane); //VectorNegate( faceplane.normal, point ); for (j = 0;j < numbrushfaces && w;j++) { clipplane = faces[j].plane; if( j == i/* || VectorCompare( clipplane.normal, point )*/ ) continue; // flip the plane, because we want to keep the back side VectorNegate(clipplane.normal, clipplane.normal); clipplane.dist *= -1; w = ClipWindingEpsilon (w, &clipplane, ON_EPSILON, true); } if (!w) { //printf("----- skipped plane -----\n"); continue; // overcontrained plane } // this face is a keeper f = AllocFace (); f->winding = w; for (j = 0;j < w->numpoints;j++) { for (k = 0;k < 3;k++) { point[k] = w->points[j][k] - offset[k]; r = Q_rint( point[k] ); if ( fabs( point[k] - r ) < ZERO_EPSILON) w->points[j][k] = r; else w->points[j][k] = point[k]; // check for incomplete brushes if( w->points[j][k] >= BOGUS_RANGE || w->points[j][k] <= -BOGUS_RANGE ) break; } // remove this brush if (k < 3) { FreeFace (f); for (f = brush_faces; f; f = next) { next = f->next; FreeFace (f); } brush_faces = NULL; //printf("----- skipped brush -----\n"); return; } AddPointToBounds( w->points[j], brush_mins, brush_maxs ); } CheckWinding( w ); faceplane.dist -= DotProduct(faceplane.normal, offset); f->texturenum = mf->texinfo; f->planenum = FindPlane (&faceplane, &f->planeside); f->next = brush_faces; brush_faces = f; } // Rotatable objects have to have a bounding box big enough // to account for all its rotations. if (DotProduct(offset, offset)) { vec_t delta; delta = RadiusFromBounds( brush_mins, brush_maxs ); for (k = 0;k < 3;k++) { brush_mins[k] = -delta; brush_maxs[k] = delta; } } //printf("%i : %f %f %f : %f %f %f\n", numbrushfaces, brush_mins[0], brush_mins[1], brush_mins[2], brush_maxs[0], brush_maxs[1], brush_maxs[2]); }
void CreateBrushFaces (void) { int i, j, k; vec3_t offset, point; vec_t r, max, min; face_t *f; winding_t *w; plane_t plane; mface_t *mf; qboolean IsRotate; offset[0] = offset[1] = offset[2] = 0; min = brush_mins[0] = brush_mins[1] = brush_mins[2] = 99999; max = brush_maxs[0] = brush_maxs[1] = brush_maxs[2] = -99999; // Hipnotic rotation IsRotate = !strncmp(ValueForKey(CurrEnt, "classname"), "rotate_", 7); if (IsRotate) FixRotateOrigin(CurrEnt, offset); brush_faces = NULL; for (i=0 ; i<numbrushfaces ; i++) { mf = &faces[i]; w = BaseWindingForPlane (&mf->plane); for (j=0 ; j<numbrushfaces && w ; j++) { if (j == i) continue; // flip the plane, because we want to keep the back side VectorSubtract (vec3_origin,faces[j].plane.normal, plane.normal); plane.dist = -faces[j].plane.dist; w = ClipWinding (w, &plane, false); } if (!w) continue; // overcontrained plane // this face is a keeper f = AllocFace (); ResizeFace (f, w->numpoints); if (f->numpoints > MAXEDGES) Message (MSGERR, "f->numpoints (%d) > MAXEDGES (%d)", f->numpoints, MAXEDGES); for (j=0 ; j<w->numpoints ; j++) { for (k=0 ; k<3 ; k++) { point[k] = w->points[j][k] - offset[k]; r = Q_rint(point[k]); if (fabs(point[k] - r) < ZERO_EPSILON) f->pts[j][k] = r; else f->pts[j][k] = point[k]; if (f->pts[j][k] < brush_mins[k]) brush_mins[k] = f->pts[j][k]; if (f->pts[j][k] > brush_maxs[k]) brush_maxs[k] = f->pts[j][k]; if (IsRotate) { if (f->pts[j][k] < min) min = f->pts[j][k]; if (f->pts[j][k] > max) max = f->pts[j][k]; } } } if (!IsRotate) plane = mf->plane; else { VectorCopy(mf->plane.normal, plane.normal); VectorScale(mf->plane.normal, mf->plane.dist, point); VectorSubtract(point, offset, point); plane.dist = DotProduct(plane.normal, point); } FreeWinding (w); f->texturenum = hullnum ? 0 : mf->texinfo; f->planenum = FindPlane (&plane, &f->planeside); f->next = brush_faces; brush_faces = f; CheckFace (f); } // Rotatable objects must have a bounding box big enough to // account for all its rotations if (IsRotate) { vec_t delta; delta = fabs(max); if (fabs(min) > delta) delta = fabs(min); for (k=0; k<3; k++) { brush_mins[k] = -delta; brush_maxs[k] = delta; } } }