/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include static Error TraverseToScreen(Object, float); static Error ScaleScreen(Object, Object, float); static Error GetFactor(int, Camera, float *); static Camera MakeNewCamera(Camera, float); Error m_ScaleScreen (Object *in, Object *out) { float factor; int final_res; Object incopy=NULL; Camera new_camera; if (!in[0]) { DXSetError(ERROR_BAD_PARAMETER, "object must be specified"); goto error; } if ((DXGetObjectClass(in[0]) != CLASS_STRING) && (DXGetObjectClass(in[0]) != CLASS_ARRAY)) { incopy = DXCopy(in[0], COPY_STRUCTURE); if (!incopy) goto error; } else { DXSetError(ERROR_MISSING_DATA,"object must be specified"); goto error; } if (!incopy && !in[2]) { out[0] = incopy; out[1] = in[3]; return OK; } if (in[1]) if (!DXExtractFloat(in[1], &factor)) { DXSetError(ERROR_BAD_PARAMETER, "scale_factor must be a scalar value"); goto error; } if (in[2]) if (!DXExtractInteger(in[2], &final_res)) { DXSetError(ERROR_BAD_PARAMETER, "final_res must be an integer"); goto error; } if (in[1] && in[2]) { DXWarning("both scale_factor and final_res are specified. Only scale_factor will be used"); } if (in[3]) { if ((DXGetObjectClass(in[3]) != CLASS_CAMERA)) { DXSetError(ERROR_BAD_PARAMETER,"current_camera must be a camera"); goto error; } } if (!in[1] && in[2] && !in[3]) { DXSetError(ERROR_INVALID_DATA,"if final_res is specified, current_camera must be specified"); goto error; } /* figure out the appropriate scale factor */ if (!in[1]){ if (in[3]) { if (!GetFactor(final_res, (Camera)in[3], &factor)) goto error; } else { factor = 1; } } if (!TraverseToScreen(incopy, factor)) goto error; out[0] = incopy; /* make the output camera, if appropriate */ if (in[3]) { new_camera = MakeNewCamera((Camera)in[3], factor); if (!new_camera) { goto error; } out[1] = (Object)new_camera; } else out[1] = NULL; return OK; error: DXDelete((Object)incopy); return ERROR; } static Error TraverseToScreen(Object o, float factor) { /* should traverse down to view-port relative coordinates */ Object subo; int i, position; switch (DXGetObjectClass(o)) { case (CLASS_GROUP): for (i=0; subo = DXGetEnumeratedMember((Group)o, i, NULL); i++) { if (!TraverseToScreen(subo, factor)) goto error; } break; case (CLASS_FIELD): return OK; case (CLASS_CLIPPED): if (!DXGetClippedInfo((Clipped)o, &subo, NULL)) goto error; if (!TraverseToScreen(subo, factor)) goto error; break; case (CLASS_XFORM): if (!DXGetXformInfo((Xform)o, &subo, NULL)) goto error; if (!TraverseToScreen(subo, factor)) goto error; break; case (CLASS_SCREEN): if (!DXGetScreenInfo((Screen)o, &subo, &position, NULL)) goto error; if ((position == SCREEN_VIEWPORT)||(position == SCREEN_WORLD)) { if (!ScaleScreen(o, subo, factor)) goto error; } else if (!TraverseToScreen(subo, factor)) goto error; break; default: break; } return OK; error: return ERROR; } static Error ScaleScreen(Object parent, Object child, float factor) { Object new; /* now scale */ new = (Object)DXNewXform(child, DXScale(factor, factor, 1.0)); if (!DXSetScreenObject((Screen)parent, new)) goto error; return OK; error: return ERROR; } static Error GetFactor(int res, Camera cam, float *factor) { int xres; /* extract the current x resolution of the camera */ if (!DXGetCameraResolution(cam, &xres, NULL)) goto error; if (xres == 0) { DXSetError(ERROR_INVALID_DATA,"x resolution of current_camera = 0"); goto error; } *factor = (float)res/(float)xres; return OK; error: return ERROR; } static Camera MakeNewCamera(Camera cam, float factor) { int xres, newres; ModuleInput in[2]; ModuleOutput out[1]; Error result; Camera newcam; if (!DXGetCameraResolution(cam, &xres, NULL)) return NULL; newres = factor*xres; newcam = (Camera)DXCopy((Object)cam, COPY_STRUCTURE); if (!newcam) return NULL; if (!DXSetResolution(newcam, newres, 1)) return NULL; return newcam; }