void ViewPort::ShiftView( int x, int y, double pixel_size, double offset_x, double offset_y, bool use_proxy ) { RECT rx, ry; HCURSOR cur; if ( view->bmi && viewDC ) { cur = SetCursor( LoadCursor( 0, IDC_WAIT ) ); // show hourglass, this could be slow view->Shift( x, -y ); // view y is opposite from screen if ( x != 0 ) { if ( x < 0 ) { rx.left = width+x; rx.right = width-1; } else { rx.left = 0; rx.right = x; } rx.top = 0; rx.bottom = height-1; RenderImages( rx, pixel_size, offset_x, offset_y, use_proxy ); // render empty side rectangle } if ( y != 0 ) { if ( -y < 0 ) { ry.top = height-y; ry.bottom = height-1; } else { ry.top = 0; ry.bottom = -y; } ry.left = 0; ry.right = width-1; RenderImages( ry, pixel_size, offset_x, offset_y, use_proxy ); // empty top/bottom rectangle } ImageToViewDC(); // blt to DC DrawContours( pixel_size, offset_x, offset_y ); // draw contours DrawActiveDomain( pixel_size, offset_x, offset_y ); // or domain boundary if this is domain view DrawEditContour( pixel_size, offset_x, offset_y ); // finally render the contour being created SetCursor( cur ); // restore cursor needsRendering = false; // still need an Invalidation of window to display viewDC } }
bool ViewPort::Regenerate( RECT region, double pixel_size, double offset_x, double offset_y, bool use_proxy ) { HCURSOR cur; bool wasregenerated = false; if ( view->bmi && viewDC ) { if ( needsRendering ) // render the domains { cur = SetCursor( LoadCursor( 0, IDC_WAIT ) ); // show hourglass, this could be slow RenderImages( region, pixel_size, offset_x, offset_y, use_proxy ); // render images SetCursor( cur ); // restore cursor } if ( needsRendering || needsDrawing ) // if images were rendered, redraw traces { ImageToViewDC(); // blt to DC DrawContours( pixel_size, offset_x, offset_y ); // draw contours DrawActiveDomain( pixel_size, offset_x, offset_y ); // or domain boundary if this is domain view DrawEditContour( pixel_size, offset_x, offset_y ); // finally render the contour being created } wasregenerated = needsRendering || needsDrawing; // report whether changes were made needsRendering = false; needsDrawing = false; // view bitmap is up to date -- can display it } return( wasregenerated ); }
void ShowScene2(int mode, int view_mode, int quad, GLint s_left, GLint s_down){ if(rotation_type==EYE_CENTERED&&nskyboxinfo>0)draw_skybox(); if(UpdateLIGHTS==1)updateLights(light_position0,light_position1); if(mode==DRAWSCENE){ glPointSize((float)1.0); /* ++++++++++++++++++++++++ draw trees +++++++++++++++++++++++++ */ if(ntreeinfo>0){ CLIP_GEOMETRY; drawtrees(); SNIFF_ERRORS("after drawtrees"); } /* ++++++++++++++++++++++++ draw particles +++++++++++++++++++++++++ */ if(showsmoke==1){ CLIP_VALS; drawpart_frame(); } /* ++++++++++++++++++++++++ draw evacuation +++++++++++++++++++++++++ */ if(showevac==1){ CLIP_VALS; drawevac_frame(); } /* ++++++++++++++++++++++++ draw targets +++++++++++++++++++++++++ */ if(showtarget==1){ CLIP_VALS; drawTargets(); } #ifdef pp_GEOMTEST if(show_geomtest==1){ CLIP_GEOMETRY; draw_geomtestclip(); draw_geomtestoutline(); } if(show_cutcells==1)draw_geom_cutcells(); #endif /* ++++++++++++++++++++++++ draw circular vents +++++++++++++++++++++++++ */ if(ncvents>0&&visCircularVents!=VENT_HIDE){ CLIP_GEOMETRY; DrawCircVents(visCircularVents); } /* ++++++++++++++++++++++++ draw sensors/sprinklers/heat detectors +++++++++++++++++++++++++ */ CLIP_GEOMETRY; draw_devices(); #ifdef pp_PILOT draw_pilot(); #endif SNIFF_ERRORS("after draw_devices"); if(visaxislabels==1){ UNCLIP; outputAxisLabels(); SNIFF_ERRORS("after outputAxisLables"); } /* ++++++++++++++++++++++++ draw user ticks +++++++++++++++++++++++++ */ if(visUSERticks==1){ antialias(ON); UNCLIP; draw_user_ticks(); antialias(OFF); SNIFF_ERRORS("after drawticks"); } /* ++++++++++++++++++++++++ draw ticks +++++++++++++++++++++++++ */ if(visFDSticks==1&&ntickinfo>0){ UNCLIP; drawticks(); SNIFF_ERRORS("after drawticks"); } /* ++++++++++++++++++++++++ draw ticks +++++++++++++++++++++++++ */ if(showgravity==1){ UNCLIP; drawaxis(); SNIFF_ERRORS("after drawaxis"); } /* draw the box framing the simulation (corners at (0,0,0) (xbar,ybar,zbar) */ /* ++++++++++++++++++++++++ draw simulation frame (corners at (0,0,0) and (xbar,ybar,zbar) +++++++++++++++++++++++++ */ if(isZoneFireModel==0&&visFrame==1&&highlight_flag==2){ CLIP_GEOMETRY; drawoutlines(); SNIFF_ERRORS("after drawoutlines"); } if(show_rotation_center==1){ unsigned char pcolor[4]; CLIP_GEOMETRY; glPushMatrix(); glTranslatef(camera_current->xcen,camera_current->ycen,camera_current->zcen); pcolor[0]=255*foregroundcolor[0]; pcolor[1]=255*foregroundcolor[1]; pcolor[2]=255*foregroundcolor[2]; drawsphere(0.03,pcolor); glPopMatrix(); } /* ++++++++++++++++++++++++ draw mesh +++++++++++++++++++++++++ */ if(setPDIM==1){ if(visGrid!=noGridnoProbe){ int igrid; mesh *meshi; UNCLIP; for(igrid=0;igrid<nmeshes;igrid++){ meshi=meshinfo+igrid; drawgrid(meshi); SNIFF_ERRORS("drawgrid"); } } } } /* end of if(mode==DRAWSCENE) code segment */ /* ++++++++++++++++++++++++ draw selected devices +++++++++++++++++++++++++ */ if(mode==SELECTOBJECT){ if(select_device==1){ CLIP_GEOMETRY; draw_devices(); SNIFF_ERRORS("after drawselect_devices"); return; } } /* ++++++++++++++++++++++++ draw selected avatars +++++++++++++++++++++++++ */ if(mode==SELECTOBJECT){ if(select_avatar==1){ CLIP_GEOMETRY; drawselect_avatars(); SNIFF_ERRORS("after drawselect_avatars"); return; } } /* ++++++++++++++++++++++++ draw selected tours +++++++++++++++++++++++++ */ if(mode==SELECTOBJECT){ if(edittour==1&&ntours>0){ CLIP_GEOMETRY; drawselect_tours(); SNIFF_ERRORS("after drawselect_tours"); return; } } /* ++++++++++++++++++++++++ draw tours +++++++++++++++++++++++++ */ if(showtours==1){ CLIP_GEOMETRY; drawtours(); SNIFF_ERRORS("after drawtours"); } /* ++++++++++++++++++++++++ draw stereo parallax indicator +++++++++++++++++++++++++ */ if(show_parallax==1){ UNCLIP; antialias(ON); glLineWidth(linewidth); glBegin(GL_LINES); glColor3fv(foregroundcolor); glVertex3f(0.75,0.0,0.25); glVertex3f(0.75,1.0,0.25); glEnd(); antialias(OFF); } /* ++++++++++++++++++++++++ draw blockages +++++++++++++++++++++++++ */ CLIP_GEOMETRY; drawBlockages(mode,DRAW_OPAQUE); SNIFF_ERRORS("drawBlockages"); /* ++++++++++++++++++++++++ draw triangles +++++++++++++++++++++++++ */ if(ngeominfoptrs>0){ CLIP_GEOMETRY; draw_geom(DRAW_OPAQUE,GEOM_STATIC); draw_geom(DRAW_OPAQUE,GEOM_DYNAMIC); } /* ++++++++++++++++++++++++ draw shooter points +++++++++++++++++++++++++ */ if(showshooter!=0&&shooter_active==1){ CLIP_VALS; draw_shooter(); } /* ++++++++++++++++++++++++ draw terrain +++++++++++++++++++++++++ */ if(visTerrainType!=TERRAIN_HIDDEN&&nterraininfo>0){ int i; //shaded 17 0 //stepped 18 1 //line 19 2 //texture 20 3 //hidden 20 4 CLIP_GEOMETRY; for(i=0;i<nterraininfo;i++){ terraindata *terri; int only_geom; terri = terraininfo + i; if(terri->loaded==1){ only_geom=0; } else{ only_geom=1; } switch(visTerrainType){ case TERRAIN_3D: drawterrain(terri,only_geom); break; case TERRAIN_2D_STEPPED: if(cullfaces==1)glDisable(GL_CULL_FACE); glPushMatrix(); glScalef(SCALE2SMV(1.0),SCALE2SMV(1.0),SCALE2SMV(1.0)); glTranslatef(-xbar0,-ybar0,-zbar0); DrawContours(&meshinfo[i].terrain_contour); glPopMatrix(); if(cullfaces==1)glEnable(GL_CULL_FACE); break; case TERRAIN_2D_LINE: glPushMatrix(); glScalef(SCALE2SMV(1.0),SCALE2SMV(1.0),SCALE2SMV(1.0)); glTranslatef(-xbar0,-ybar0,-zbar0); DrawLineContours(&meshinfo[i].terrain_contour,1.0); glPopMatrix(); break; case TERRAIN_3D_MAP: if(terrain_texture!=NULL&&terrain_texture->loaded==1){ drawterrain_texture(terri,only_geom); } else{ drawterrain(terri,only_geom); } break; default: ASSERT(FFALSE); break; } } } /* ++++++++++++++++++++++++ draw slice files +++++++++++++++++++++++++ */ if(show_gslice_triangles==1||show_gslice_normal==1||show_gslice_normal_keyboard==1||show_gslice_triangulation==1){ CLIP_VALS; drawgslice_outline(); } if((show_slices_and_vectors==1&&showvslice==1)||(showslice==1&&use_transparency_data==0)){ CLIP_VALS; drawslice_frame(); } /* ++++++++++++++++++++++++ draw boundary files +++++++++++++++++++++++++ */ if(showpatch==1){ CLIP_VALS; drawpatch_frame(); } /* ++++++++++++++++++++++++ draw labels +++++++++++++++++++++++++ */ if(visLabels==1){ CLIP_GEOMETRY; drawLabels(); } /* ++++++++++++++++++++++++ draw animated isosurfaces +++++++++++++++++++++++++ */ //if(isoinfo!=NULL)drawspherepoints(sphereinfo); if(showiso==1){ CLIP_VALS; drawiso(DRAW_OPAQUE); } /* ++++++++++++++++++++++++ draw zone fire modeling info +++++++++++++++++++++++++ */ if(nrooms>0){ CLIP_GEOMETRY; drawroomgeom(); SNIFF_ERRORS("after drawroomgeom"); } if(nrooms>0){ if(showzone==1){ CLIP_VALS; drawfiredata(); SNIFF_ERRORS("after drawroomdata"); if(ReadZoneFile==1&&nzvents>0){ drawventdata(); SNIFF_ERRORS("after drawventdata"); } } } //********************************************************************************** //********************************************************************************** //********************************************************************************** // nothing transparent should be drawn before this portion of the code // (ie draw all opaque objects first then draw transparent objects //********************************************************************************** //********************************************************************************** //********************************************************************************** /* ++++++++++++++++++++++++ draw triangles +++++++++++++++++++++++++ */ if(ngeominfoptrs>0){ CLIP_GEOMETRY; draw_geom(DRAW_TRANSPARENT,GEOM_STATIC); draw_geom(DRAW_TRANSPARENT,GEOM_DYNAMIC); } if(showiso==1){ CLIP_VALS; drawiso(DRAW_TRANSPARENT); } /* ++++++++++++++++++++++++ draw transparent faces +++++++++++++++++++++++++ */ CLIP_GEOMETRY; draw_transparent_faces(); /* ++++++++++++++++++++++++ draw 3D smoke +++++++++++++++++++++++++ */ if(show3dsmoke==1||showvolrender==1){ CLIP_VALS; drawsmoke_frame(); } if(active_smokesensors==1&&show_smokesensors!=0){ CLIP_VALS; getsmokesensors(); draw_devices_val(); } /* ++++++++++++++++++++++++ draw zone fire modeling info +++++++++++++++++++++++++ */ if(nrooms>0&&showzone==1){ CLIP_VALS; drawroomdata(); SNIFF_ERRORS("after drawroomdata"); } /* ++++++++++++++++++++++++ draw slice files +++++++++++++++++++++++++ */ if((show_slices_and_vectors==1&&showvslice==1)||(showslice==1&&use_transparency_data==1)){ CLIP_VALS; drawslice_frame(); SNIFF_ERRORS("after drawslice_frame"); } /* ++++++++++++++++++++++++ draw transparent blockages +++++++++++++++++++++++++ */ // draw_demo(20,20); // draw_demo2(1); CLIP_GEOMETRY; drawBlockages(mode,DRAW_TRANSPARENT); SNIFF_ERRORS("after drawBlokcages"); /* ++++++++++++++++++++++++ draw vector slice files +++++++++++++++++++++++++ */ if(showvslice==1){ CLIP_VALS; drawvslice_frame(); } SNIFF_ERRORS("after drawvslice"); /* ++++++++++++++++++++++++ draw plot3d files +++++++++++++++++++++++++ */ if(showplot3d==1){ CLIP_VALS; drawplot3d_frame(); } SNIFF_ERRORS("after drawplot3d"); }
BOOL DTM2D::DrawContours(CONTOUR_MAP *ctr) { /************************************************************************** * * function name: draw_contours * * Generates a contour map from a gridded DTM. Does not produce vector * information, only a plot on screen. * * Reference: * * Chris Johnston 1986 * Contour plots of large data sets. * Computer Language. * May 1986. * * * cell vertex and side numbering * * 2----------1----------3 * | \ / | * | \ / | * | 5 6 | * | \ / | * 0 \ / 2 * | / \ | * | / \ | * | 4 7 | * | / \ | * | / \ | * 1----------3----------0 * description: * * Given a dtm file name, contour interval information, colors, and * the desired area within the DTM, draw contours() draws the contour * lines for the dtm unit. Assumes that all screen scaling and * windowing has already been done. * * return value: * * Returns 0 to indicate success, -1 to indicate error. * **************************************************************************/ long i; // loop counter long j; // loop counter int l; // loop counter for contour levels int start_level; // starting contour level for a column int end_level; // ending contour level for a column int k; // loop counter for cell side crossings int flag; // flag to control pen status (up or down) int cell_index; // index into edge crossing array int exit_key = 0; // keystroke...only [Esc] terminates long start_col; // starting column to be contoured long stop_col; // ending column to be contoured long start_point; // starting point to be contoured long stop_point; // ending point to be contoured long test_point; // temporary value for testing end of grid long leftover_col; // extra columns not contoured on first pass long leftover_point; // extra points not contoured on first pass float ave_elev; // average elevation of a cell float x_mult = 1.0f; // relative distance along a cell edge in X float y_mult = 1.0f; // relative distance along a cell edge in Y double column_x; // X coordinate of column (left side) double x, y; // point on line void *e1 = NULL; // pointer to array of elevation data void *e2 = NULL; // pointer to array of elevation data void *temp = NULL; // temporary...used when swapping e1 and e2 POINT pt; // screen point CONTOUR_MAP temp_ctr; // CONTOUR_MAP structure used for recursive calls MSG stopmsg; WCS wcs; if (!Valid) return(FALSE); // set up scaling using WCS wcs.Scale(ctr->pDC, ctr->world_ll.x, ctr->world_ll.y, ctr->world_ur.x, ctr->world_ur.y); wcs.IsoAdjust(ctr->pDC); // calculate the starting row and column start_col = (long) floor((ctr->lower_left.x - Header.origin_x) / Header.column_spacing); stop_col = (long) ceil((ctr->upper_right.x - Header.origin_x) / Header.column_spacing); start_point = (long) floor((ctr->lower_left.y - Header.origin_y) / Header.point_spacing); stop_point = (long) ceil((ctr->upper_right.y - Header.origin_y) / Header.point_spacing); if (start_col < 0) start_col = 0; if (stop_col > (Header.columns - 1)) stop_col = Header.columns - 1; if (start_point < 0) start_point = 0; if (stop_point > (Header.points - 1)) stop_point = Header.points - 1; // if we have elevations in memory, work from memory if (HaveElevations) { e2 = lpsElevData[start_col]; } else { int sizes[] = {sizeof(short), sizeof(int), sizeof(float), sizeof(double)}; // otherwise read from file // open the dtm file if (!OpenModelFile()) return(FALSE); // allocate memory for 2 profiles of dtm data e1 = (void *) malloc((size_t) Header.points * sizes[Header.z_bytes]); // check for allocation problems if (!e1) { CloseModelFile(); return(FALSE); } e2 = (void *) malloc((size_t) Header.points * sizes[Header.z_bytes]); // check for allocation problems if (!e2) { free(e1); CloseModelFile(); return(FALSE); } // read the first profile into e2...will be swapped to e1 in loop if (LoadDTMProfile(start_col, e2)) { free(e1); free(e2); CloseModelFile(); return(FALSE); } } // sweep through the cells and draw contours for (i = start_col; i < stop_col; i += ctr->column_smooth) { // check for last column if (i + ctr->column_smooth > stop_col) break; // calculate the x for the column column_x = Header.origin_x + ((double) i * Header.column_spacing); // swap pointers to elevation arrays temp = e1; e1 = e2; e2 = temp; // read next profile if (HaveElevations) e2 = lpsElevData[i + ctr->column_smooth]; else { if (LoadDTMProfile(i + ctr->column_smooth, e2)) { free(e1); free(e2); CloseModelFile(); return(FALSE); } } // set color for normal interval ctr->pDC->SelectObject(ctr->cpNormalPen); // calculate test point for end of data test_point = stop_point - ctr->point_smooth; for (j = start_point; j < stop_point; j += ctr->point_smooth) { // check for last point if (j > test_point) break; if (!ctr->DrawZeroLine) { // check for 1 or more void area markers (-1) and skip cell if (ReadColumnValue(e1, j) < 0 || ReadColumnValue(e2, j) < 0 || ReadColumnValue(e1, j+ ctr->point_smooth) < 0 || ReadColumnValue(e2, j + ctr->point_smooth) < 0) continue; } // determine cell min/max elevations start_level = (int) __min(ReadColumnValue(e1, j), ReadColumnValue(e2, j)); start_level = (int) __min(start_level, ReadColumnValue(e1, j + ctr->point_smooth)); start_level = (int) __min(start_level, ReadColumnValue(e2, j + ctr->point_smooth)); start_level = start_level - (start_level % ctr->normal); end_level = (int) __max(ReadColumnValue(e1, j), ReadColumnValue(e2, j)); end_level = (int) __max(end_level, ReadColumnValue(e1, j + ctr->point_smooth)); end_level = (int) __max(end_level, ReadColumnValue(e2, j + ctr->point_smooth)); // check cell for each possible contour level // loop using start_level can start at -1...use loop starting at 0 // to draw 0.0 contour for (l = ctr->DrawZeroLine ? 0 : start_level; l <= end_level; l += ctr->normal) { // calculate the cell index cell_index = 0; if (ReadColumnValue(e2, j) >= l) cell_index = 1; if (ReadColumnValue(e1, j) >= l) cell_index |= 2; if (ReadColumnValue(e1, j + ctr->point_smooth) >= l) cell_index |= 4; if (ReadColumnValue(e2, j + ctr->point_smooth) >= l) cell_index |= 8; // if cell_index is 0 or 15, no contours at this level if (cell_index == 0 || cell_index == 15) continue; // calculate the average elevation for the cell, // use it to adjust the cell_index ave_elev = ((float) ReadColumnValue(e2, j) + (float) ReadColumnValue(e1, j) + (float) ReadColumnValue(e1, j + ctr->point_smooth) + (float) ReadColumnValue(e2, j + ctr->point_smooth)) / 4.0f; if (ave_elev <= (float) l) cell_index = cell_index ^ 15; // if working on a bold interval, set color to bold color if ((l % ctr->bold) == 0) ctr->pDC->SelectObject(ctr->cpBoldPen); // set flag to force move to first crossing point flag = 1; // step through the side or segment crossings held in the // crossing side list for (k = 0; k < em[cell_index] [0]; k ++) { // calculate the cell size multiplier...different logic // for each side or segment. Multiplier ranges from 0 to 1 switch (el[em[cell_index] [1] + k]) { case 0: x_mult = 0.0f; if (ReadColumnValue(e1, j) == ReadColumnValue(e1, j + ctr->point_smooth)) y_mult = 0.5f; else y_mult = ((float) (l - ReadColumnValue(e1, j))) / ((float) (ReadColumnValue(e1, j + ctr->point_smooth) - ReadColumnValue(e1, j))); break; case 1: if (ReadColumnValue(e1, j + ctr->point_smooth) == ReadColumnValue(e2, j + ctr->point_smooth)) x_mult = 0.5f; else x_mult = ((float) (l - ReadColumnValue(e1, j + ctr->point_smooth))) / ((float) (ReadColumnValue(e2, j + ctr->point_smooth) - ReadColumnValue(e1, j + ctr->point_smooth))); y_mult = 1.0f; break; case 2: x_mult = 1.0f; if (ReadColumnValue(e2, j) == ReadColumnValue(e2, j + ctr->point_smooth)) y_mult = 0.5f; else y_mult = 1.0f - (((float) (l - ReadColumnValue(e2, j + ctr->point_smooth))) / ((float) (ReadColumnValue(e2, j) - ReadColumnValue(e2, j + ctr->point_smooth)))); break; case 3: if (ReadColumnValue(e1, j) == ReadColumnValue(e2, j)) x_mult = 0.5f; else x_mult = 1.0f - (((float) (l - ReadColumnValue(e2, j))) / ((float) (ReadColumnValue(e1, j) - ReadColumnValue(e2, j)))); y_mult = 0.0f; break; case 4: if (ave_elev == (float) ReadColumnValue(e1, j)) x_mult = 0.25f; else x_mult = 0.5f * ((float) (l - ReadColumnValue(e1, j))) / (ave_elev - (float) ReadColumnValue(e1, j)); y_mult = x_mult; break; case 5: if (ave_elev == (float) ReadColumnValue(e1, j + ctr->point_smooth)) x_mult = 0.25f; else x_mult = 0.5f * ((float) (l - ReadColumnValue(e1, j + ctr->point_smooth))) / (ave_elev - (float) ReadColumnValue(e1, j + ctr->point_smooth)); y_mult = 1.0f - x_mult; break; case 6: if (ave_elev == (float) ReadColumnValue(e2, j + ctr->point_smooth)) x_mult = 0.75f; else x_mult = 1.0f - (0.5f * ((float) (l - ReadColumnValue(e2, j + ctr->point_smooth))) / (ave_elev - (float) ReadColumnValue(e2, j + ctr->point_smooth))); y_mult = x_mult; break; case 7: if (ave_elev == (float) ReadColumnValue(e2, j)) x_mult = 0.75f; else x_mult = 1.0f - (0.5f * ((float) (l - ReadColumnValue(e2, j))) / (ave_elev - (float) ReadColumnValue(e2, j))); y_mult = 1.0f - x_mult; break; case 8: flag = 1; continue; } // move or draw to the crossing point depending on flag x = column_x + Header.column_spacing * (double) x_mult * (double) ctr->column_smooth; y = Header.origin_y + ((double) j * Header.point_spacing) + Header.point_spacing * (double) y_mult * (double) ctr->point_smooth; // scale to window coords pt.x = wcs.WX(x); pt.y = wcs.WY(y); if (flag) { ctr->pDC->MoveTo(pt); flag = 0; } else { ctr->pDC->LineTo(pt); if ((l % ctr->bold) == 0) ctr->pDC->SetPixel(pt, ctr->bcolor); else ctr->pDC->SetPixel(pt, ctr->ncolor); } } // if working on a bold interval, reset color to normal if ((l % ctr->bold) == 0) ctr->pDC->SelectObject(ctr->cpNormalPen); // if working on 0 contour, jump to actual start level if (l == 0) { l = start_level - ctr->normal; // check for void area markers...(-1) if (ReadColumnValue(e1, j) < 0 || ReadColumnValue(e2, j) < 0 || ReadColumnValue(e1, j + ctr->point_smooth) < 0 || ReadColumnValue(e2, j + ctr->point_smooth) < 0) break; } } } // check for an [Esc] key press if (!ctr->pDC->IsPrinting()) { if (PeekMessage(&stopmsg, ctr->pDC->GetWindow()->m_hWnd, WM_KEYUP, WM_KEYUP, PM_REMOVE)) { if (stopmsg.wParam == VK_ESCAPE) { exit_key = 27; break; } } } } if (!HaveElevations) { // free profile arrays and close dtm file free(e1); free(e2); fclose(modelfile); } if (exit_key == 27) return(TRUE); // check to see if there is an uncontoured strip along right side leftover_col = (stop_col - start_col) % ctr->column_smooth; leftover_point = (stop_point - start_point) % ctr->point_smooth; temp_ctr = *ctr; temp_ctr.column_smooth = (short) leftover_col; temp_ctr.lower_left.x = Header.origin_x + (stop_col - leftover_col) * Header.column_spacing + (Header.column_spacing * 0.1); if (leftover_col) { DrawContours(&temp_ctr); } temp_ctr.column_smooth = ctr->column_smooth; temp_ctr.lower_left.x = ctr->lower_left.x; temp_ctr.lower_left.y = Header.origin_y + (stop_point - leftover_point) * Header.point_spacing + (Header.point_spacing * 0.1); temp_ctr.point_smooth = (short) leftover_point; // check to see if there is an uncontoured strip along the top if (leftover_point) { DrawContours(&temp_ctr); } // draw neat line if (ctr->DrawNeatLine) { ctr->pDC->SelectObject(ctr->cpNormalPen); ctr->pDC->SelectStockObject(NULL_BRUSH); ctr->pDC->Rectangle(wcs.WX(OriginX()), wcs.WY(OriginY()), wcs.WX(OriginX() + Width()), wcs.WY(OriginY() + Height())); } return(TRUE); }