/***************************************************************************** * General routines common to graphics driver. * ****************************************************************************** * (C) Gershon Elber, Technion, Israel Institute of Technology * ****************************************************************************** * Written by: Gershon Elber Ver 0.1, June 1993. * *****************************************************************************/ #include #include #include #include "irit_sm.h" #include "misc_lib.h" #include "ip_cnvrt.h" #include "iritprsr.h" #include "allocate.h" #include "attribut.h" #include "bool_lib.h" #include "user_lib.h" #include "geom_lib.h" #include "grap_loc.h" #include "editcrvs.h" #include "editsrfs.h" #include "editmanp.h" #ifdef HAVE_OGL_CG_LIB #include "opngl_cg.h" #endif /* HAVE_OGL_CG_LIB */ #ifdef OS2GCC #define INCL_DOSPROCESS #include #endif /* OS2GCC */ #ifdef __WINNT__ #include #endif /* __WINNT__ */ #define SPHERE_CONE_DENSITY 300 #define SILH_GRID_SIZE 20 #define COPLANARITY_EPS IRIT_UEPS typedef struct StateNameNumType { IGGlblStateType Num; char *Name; } StateNameNumType; STATIC_DATA StateNameNumType StateNameNum[] = { { IG_STATE_MOUSE_SENSITIVE, "MouseSense" }, { IG_STATE_SCR_OBJ_TGL, "ScrnObjct" }, { IG_STATE_PERS_ORTHO_TGL, "PerpsOrtho" }, { IG_STATE_DEPTH_CUE, "DepthCue" }, { IG_STATE_CACHE_GEOM, "CacheGeom" }, { IG_STATE_DRAW_STYLE, "DrawStyle" }, { IG_STATE_SHADING_MODEL, "ShadingMdl" }, { IG_STATE_BACK_FACE_CULL, "BFaceCull" }, { IG_STATE_DOUBLE_BUFFER, "DblBuffer" }, { IG_STATE_ANTI_ALIASING, "AntiAlias" }, { IG_STATE_DRAW_INTERNAL, "DrawIntrnl" }, { IG_STATE_DRAW_VNORMAL, "DrawVNrml" }, { IG_STATE_DRAW_PNORMAL, "DrawPNrml" }, { IG_STATE_DRAW_POLYGONS, "DrawPlgns" }, { IG_STATE_DRAW_SRF_MESH, "DSrfMesh" }, { IG_STATE_DRAW_SRF_WIRE, "DSrfWire" }, { IG_STATE_DRAW_SRF_BNDRY, "DSrfBndry" }, { IG_STATE_DRAW_SRF_SILH, "DSrfSilh" }, { IG_STATE_DRAW_SRF_POLY, "DSrfPoly" }, { IG_STATE_DRAW_SRF_SKTCH, "DSrfSktch" }, { IG_STATE_FOUR_PER_FLAT, "4PerFlat" }, { IG_STATE_NUM_ISOLINES, "NumIsos" }, { IG_STATE_POLY_APPROX, "PolyAprx" }, { IG_STATE_SAMP_PER_CRV_APPROX, "PllnAprx" }, { IG_STATE_LENGTH_VECTORS, "LenVecs" }, { IG_STATE_WIDTH_LINES, "WidthLines" }, { IG_STATE_WIDTH_POINTS, "WidthPts" }, { IG_STATE_VIEW_FRONT, "Front" }, { IG_STATE_VIEW_SIDE, "Side" }, { IG_STATE_VIEW_TOP, "Top" }, { IG_STATE_VIEW_ISOMETRY, "Isometry" }, { IG_STATE_VIEW_4, "4Views" }, { IG_STATE_CLEAR_VIEW, "Clear" }, { IG_STATE_RES_ADAP_ISO, "ResAdapIso" }, { IG_STATE_RES_RULED_SRF, "ResRldSrf" }, { IG_STATE_RULED_SRF_APPROX, "RuledSrfApx" }, { IG_STATE_ADAP_ISO_DIR, "AdapIsoDir" }, { IG_STATE_LOWRES_RATIO, "LowResRatio" }, { IG_STATE_CLIP_TESS_POLES, "ClipAtPoles" }, { IG_STATE_NONE, NULL } }; STATIC_DATA int GlblQuickLoad = FALSE, GlblThisPickObjTypes = IG_PICK_ANY, GlblDelayedClear = FALSE, GlblProcessCommandMesssages = TRUE, GlblNormalLenAux = 200, GlblPickedPolyIsPolyline; STATIC_DATA MatrixType GlblPushViewMat, GlblPushPrspMat, GlblLastProcessMat; STATIC_DATA RealType GlblPickScale = 1.0, GlblMinFoundDepth = -IRIT_INFNTY; STATIC_DATA char *GlblObjectSearchName = "", *GlblExecAnimEachStep = "", *GlblLightSrc1PosStr = "1.0, 2.0, 5.0, 0.0", *GlblLightSrc2PosStr = "1.0, -1.0, -3.0, 0.0", *GlblBackGroundStr = "0,0,0", *GlblHighlight1Str = "255,0,255", *GlblHighlight2Str = "255,100,200", *GlblFirstLoadedFile = ""; STATIC_DATA IPPolygonStruct *GlblPickedPoly = NULL; STATIC_DATA IPObjectStruct *GlblObjectFoundByName = NULL; GLOBAL_DATA int IGGlblBackGroundColor[3] = { 0, 0, 0 }, IGGlblHighlight1Color[3] = { 255, 0, 255 }, IGGlblHighlight2Color[3] = { 255, 0, 0 }, IGGlblDrawInternal = FALSE, IGGlblDrawVNormal = FALSE, IGGlblDrawPNormal = FALSE, IGGlbl4Views = FALSE, IGGlblMore = FALSE, IGGlblPolygonOptiApprox = 20, IGGlblForceUnitMat = FALSE, IGGlblDrawStyle = 0, IGGlblShadingModel = IG_SHADING_PHONG, IGGlblBackFaceCull = FALSE, IGGlblDoDoubleBuffer = TRUE, IGGlblNumOfIsolines = 10, IGGlblLineWidth = 1, IGGlblAdapIsoDir = CAGD_CONST_U_DIR, IGGlblDepthCue = TRUE, IGGlblCacheGeom = TRUE, IGGlblFourPerFlat = TRUE, IGGlblAntiAliasing = 0, IGGlblDrawPolygons = TRUE, IGGlblDrawSurfaceMesh = FALSE, IGGlblDrawSurfacePoly = FALSE, IGGlblDrawSurfaceWire = TRUE, IGGlblDrawSurfaceBndry = FALSE, IGGlblDrawSurfaceSilh = FALSE, IGGlblDrawSurfaceSketch = FALSE, IGGlblDrawSurfaceRflctLns = FALSE, IGGlblStandAlone = TRUE, IGGlblTransformMode = IG_TRANS_SCREEN, IGGlblViewMode = IG_VIEW_PERSPECTIVE, IGGlblDebugObjectsFlag = FALSE, IGGlblDebugEchoInputFlag = FALSE, IGGlblIntensityHighState = TRUE, IGGlblAbortKeyPressed = FALSE, IGGlblAnimation = FALSE, IGGlblPolygonStrips = FALSE, IGGlblManipulationActive = FALSE, IGGlblLastLowResDraw = FALSE, IGGlblClipAtPoles = FALSE, IGLastWasSolidRendering = FALSE, IGGlblContinuousMotion = FALSE, IGGlblFlipNormalOrient = FALSE, IGGlblClientHandleNumber = -1, IGGlblPickObjTypes = IG_PICK_ANY, IGGlblSavePickedPoly = FALSE, IGGlblCountNumPolys = FALSE, IGGlblNumPolys = 0, IGGlblCountFramePerSec = 0, IGGlblNumFiles = 0, IGGlblIOHandle = -1, IGGlblInitWidgetDisplay = 0, IGGlblActiveXMode = FALSE, IGGlbl3DGlassesImgIndx = -1; GLOBAL_DATA SymbCrvApproxMethodType IGGlblPolylineOptiApprox = SYMB_CRV_APPROX_TOLERANCE; GLOBAL_DATA char *IGGlblImageFileName = "", *IGGlblPolyPickFileName = "", *IGGlblExecAnimation = "", *IGGlblTransPrefPos = "455, 640, 520, 965", *IGGlblViewPrefPos = " 1, 450, 520, 965", **IGGlblFileNames; GLOBAL_DATA RealType IGGlblMinFoundDist = IRIT_INFNTY, IGGlblRelLowresFineNess = 0.3, IGGlblMinPickDist = 0.2, IGGlblPointWidth = 0.02, IGGlblPlgnFineness = 10.0, IGGlblPllnFineness = IG_DEFAULT_PLLN_OPTI_FINENESS, IGGlblChangeFactor = 1.0, IGGlblZMinClip = -2.0, IGGlblZMaxClip = 2.0, IGGlblNormalLen = 0.2, IGGlblEyeDistance = 0.03, IGGlblFramePerSec = 0.0; GLOBAL_DATA PointType IGGlblPickPosE3, IGGlblPickPos; GLOBAL_DATA IGGlasses3DType IGGlbl3DGlassesMode; GLOBAL_DATA IPObjectStruct *IGGlblNewDisplayObjects = NULL, *IGGlblDisplayList = NULL, *IGGlblPickedObj = NULL, *IGGlblPickedPolyObj = NULL; GLOBAL_DATA MatrixType IGGlblCrntViewMat, IGGlblInvCrntViewMat, IGGlblIsometryViewMat = { /* Isometric view, by default. */ { -0.707107, -0.408248, 0.577350, 0.000000 }, { 0.707107, -0.408248, 0.577350, 0.000000 }, { 0.000000, 0.816496, 0.577350, 0.000000 }, { 0.000000, 0.000000, 0.000000, 1.000000 } }; GLOBAL_DATA GMAnimationStruct IGAnimation = { 0.0, /* StartT */ 1.0, /* FinalT */ 0.01, /* Dt */ 0.0, /* RunTime */ FALSE, /* TwoWaysAnimation */ FALSE, /* SaveAnimationGeom */ FALSE, /* SaveAnimationImage */ FALSE, /* BackToOrigin */ 1, /* NumOfRepeat */ FALSE, /* StopAnim */ FALSE, /* SingleStep */ FALSE, /* TextInterface */ 30, /* MiliSecSleep */ 0, /* _Count; */ NULL, /* ExecEachStep */ { 0 }, /* BaseFileName */ }; GLOBAL_DATA IGShadeParamStruct IGShadeParam = { 2, /* Two light sources. */ { { 1.0f, 2.0f, -5.0f, 0.0f }, /* Position of first light source. */ { 3.0f, -1.0f, -10.0f, 0.0f } /* Position of second light source. */ }, { 0.05f, 0.05f, 0.05f, 1.0f }, /* Ambient RGB factors. */ { 0.4f, 0.4f, 0.4f, 1.0f }, /* Diffuse RGB factors. */ { 0.5f, 0.5f, 0.5f, 1.0f }, /* Specular RGB factors. */ { 0.0f, 0.0f, 0.0f, 1.0f }, /* Emissive RGB factors. */ 32.0f /* Shininess factor. */ }; GLOBAL_DATA IGSketchParamStruct IGSketchParam = { 0.9, /* Effect of shading on sketches. */ 0.1, /* Effect of silhouettes on sketches. */ IG_SKETCHING_ISO_PARAM, /* Type of sketched silhouette strokes. */ IG_SKETCHING_ISO_PARAM, /* Type of sketched shading strokes. */ IG_SKETCHING_ISOCLINES, /* Type of sketched importance strokes. */ TRUE, /* Do importance sketching be default. */ TRUE, /* Inverse shading flag. */ 2.5, /* Neutral importance decay. */ 90.0 /* Neutral importance frontal decay. */ }; STATIC_DATA IritConfigStruct SetUp[] = { { "TransPrefPos", "-g", (VoidPtr) &IGGlblTransPrefPos, IC_STRING_TYPE }, { "ViewPrefPos", "-G", (VoidPtr) &IGGlblViewPrefPos, IC_STRING_TYPE }, { "BackGround", "-b", (VoidPtr) &GlblBackGroundStr, IC_STRING_TYPE }, { "Highlight1", "", (VoidPtr) &GlblHighlight1Str, IC_STRING_TYPE }, { "Highlight2", "", (VoidPtr) &GlblHighlight2Str, IC_STRING_TYPE }, { "LightSrcPos", "-S", (VoidPtr) &GlblLightSrc1PosStr, IC_STRING_TYPE }, { "LightSrcPos2", "", (VoidPtr) &GlblLightSrc2PosStr, IC_STRING_TYPE }, { "ExecAnimCmd", "-x", (VoidPtr) &GlblExecAnimEachStep, IC_STRING_TYPE }, { "ExecAnimation", "-X", (VoidPtr) &IGGlblExecAnimation, IC_STRING_TYPE }, { "Internal", "-i", (VoidPtr) &IGGlblDrawInternal, IC_BOOLEAN_TYPE }, { "DrawVNormal", "-n", (VoidPtr) &IGGlblDrawVNormal, IC_BOOLEAN_TYPE }, { "DrawPNormal", "-N", (VoidPtr) &IGGlblDrawPNormal, IC_BOOLEAN_TYPE }, { "MoreVerbose", "-m", (VoidPtr) &IGGlblMore, IC_BOOLEAN_TYPE }, { "UnitMatrix", "-u", (VoidPtr) &IGGlblForceUnitMat, IC_BOOLEAN_TYPE }, { "DrawStyle", "-r", (VoidPtr) &IGGlblDrawStyle, IC_BOOLEAN_TYPE }, { "BFaceCull", "-B", (VoidPtr) &IGGlblBackFaceCull, IC_BOOLEAN_TYPE }, { "DoubleBuffer", "-2", (VoidPtr) &IGGlblDoDoubleBuffer, IC_BOOLEAN_TYPE }, { "DebugObjects", "-d", (VoidPtr) &IGGlblDebugObjectsFlag, IC_BOOLEAN_TYPE }, { "DebugEchoInput", "-D", (VoidPtr) &IGGlblDebugEchoInputFlag,IC_BOOLEAN_TYPE }, { "DepthCue", "-c", (VoidPtr) &IGGlblDepthCue, IC_BOOLEAN_TYPE }, { "CacheGeom", "-C", (VoidPtr) &IGGlblCacheGeom, IC_BOOLEAN_TYPE }, { "FourPerFlat", "-4", (VoidPtr) &IGGlblFourPerFlat, IC_BOOLEAN_TYPE }, { "AntiAlias", "-a", (VoidPtr) &IGGlblAntiAliasing, IC_BOOLEAN_TYPE }, { "DrawSurfaceMesh","-M", (VoidPtr) &IGGlblDrawSurfaceMesh, IC_BOOLEAN_TYPE }, { "DrawSurfacePoly","-P", (VoidPtr) &IGGlblDrawSurfacePoly, IC_BOOLEAN_TYPE }, { "DrawSurfaceWire","-W", (VoidPtr) &IGGlblDrawSurfaceWire, IC_BOOLEAN_TYPE }, { "DrawSurfaceSktc","-W", (VoidPtr) &IGGlblDrawSurfaceSketch, IC_BOOLEAN_TYPE }, { "StandAlone", "-s", (VoidPtr) &IGGlblStandAlone, IC_BOOLEAN_TYPE }, { "PolyStrip", "-R", (VoidPtr) &IGGlblPolygonStrips, IC_BOOLEAN_TYPE }, { "ContMotion", "-T", (VoidPtr) &IGGlblContinuousMotion, IC_BOOLEAN_TYPE }, { "NrmlOrientation","-o", (VoidPtr) &IGGlblFlipNormalOrient, IC_BOOLEAN_TYPE }, { "QuickLoad", "-q", (VoidPtr) &GlblQuickLoad, IC_BOOLEAN_TYPE }, { "NumOfIsolines", "-I", (VoidPtr) &IGGlblNumOfIsolines, IC_INTEGER_TYPE }, { "LineWidth", "-l", (VoidPtr) &IGGlblLineWidth, IC_INTEGER_TYPE }, { "AdapIsoDir", "", (VoidPtr) &IGGlblAdapIsoDir, IC_INTEGER_TYPE }, { "PolygonOpti", "-F", (VoidPtr) &IGGlblPolygonOptiApprox, IC_INTEGER_TYPE }, { "PolylineOpti", "-f", (VoidPtr) &IGGlblPolylineOptiApprox,IC_INTEGER_TYPE }, { "ShadingModel", "-A", (VoidPtr) &IGGlblShadingModel, IC_INTEGER_TYPE }, { "TransMode", "", (VoidPtr) &IGGlblTransformMode, IC_INTEGER_TYPE }, { "ViewMode", "", (VoidPtr) &IGGlblViewMode, IC_INTEGER_TYPE }, { "NormalLength", "-L", (VoidPtr) &GlblNormalLenAux, IC_INTEGER_TYPE }, { "SketchSilStyle", "-k", (VoidPtr) &IGSketchParam.SketchSilType,IC_INTEGER_TYPE }, { "SketchShdStyle", "-k", (VoidPtr) &IGSketchParam.SketchShdType,IC_INTEGER_TYPE }, { "SketchImpStyle", "-k", (VoidPtr) &IGSketchParam.SketchImpType,IC_INTEGER_TYPE }, { "SketchShdInv", "-k", (VoidPtr) &IGSketchParam.SketchInvShd,IC_INTEGER_TYPE }, { "SketchImp", "-k", (VoidPtr) &IGSketchParam.SketchImp, IC_INTEGER_TYPE }, { "PickObjType", "-O", (VoidPtr) &IGGlblPickObjTypes, IC_INTEGER_TYPE }, { "InitWidget", "-w", (VoidPtr) &IGGlblInitWidgetDisplay, IC_INTEGER_TYPE }, { "ZClipMin", "-Z", (VoidPtr) &IGGlblZMinClip, IC_REAL_TYPE }, { "ZClipMax", "-Z", (VoidPtr) &IGGlblZMaxClip, IC_REAL_TYPE }, { "PlgnFineNess", "-F", (VoidPtr) &IGGlblPlgnFineness, IC_REAL_TYPE }, { "PllnFineNess", "-f", (VoidPtr) &IGGlblPllnFineness, IC_REAL_TYPE }, { "PointWidth", "-p", (VoidPtr) &IGGlblPointWidth, IC_REAL_TYPE }, { "RelLowRes", "-E", (VoidPtr) &IGGlblRelLowresFineNess, IC_REAL_TYPE }, { "PickEventDist", "-e", (VoidPtr) &IGGlblMinPickDist, IC_REAL_TYPE }, { "SketchSilPwr", "-k", (VoidPtr) &IGSketchParam.SilPower, IC_REAL_TYPE }, { "SketchShdPwr", "-k", (VoidPtr) &IGSketchParam.ShadePower,IC_REAL_TYPE }, { "SketchImpDecay", "-k", (VoidPtr) &IGSketchParam.SketchImpDecay,IC_REAL_TYPE } }; #define NUM_SET_UP (sizeof(SetUp) / sizeof(IritConfigStruct)) #ifdef NO_CONCAT_STR STATIC_DATA char *GenVersionStr = " Version 9.5, Gershon Elber,\n\ (C) Copyright 1989-2005 Gershon Elber, Non commercial use only."; #else STATIC_DATA char *GenVersionStr = " " IRIT_VERSION ", Gershon Elber, " __DATE__ ", " __TIME__ "\n" IRIT_COPYRIGHT ", Non commercial use only."; #endif /* NO_CONCAT_STR */ STATIC_DATA char #ifdef IRIT_DOUBLE *GenCtrlStr = " s%- u%- n%- N%- i%- c%- C%- m%- a%- q%- g%-\"x1,x2,y1,y2\"!s G%-\"x1,x2,y1,y2\"!s I%-#IsoLines!d F%-PlgnOpti|PlgnFineNess!d!F R%- f%-PllnOpti|PllnFineNess!d!F E%-RelLowRes!F p%-!F l%-LineWidth!d r%- A%-Shader!d B%- 2%- d%- D%- L%-NormalLen!d 4%- k%-SketchSilTyp|SilPwr|ShdTyp|ShdPwr|InvShd|ImpTyp|Imp!d!F!d!F!d!d!F b%-\"R,B,G|(background)\"!s S%-\"x,y,z,w{,a,d,s}\"!s e%-PickDist!F O%-PickObjType!d Z%-ZMin|ZMax!F!F M%- W%-WireSetup!d P%- o%- x%-ExecAnimCmd!s X%-Min,Max,Dt,R{,flags}!s w%-InitWidget!d T%- z%- DFiles!*s"; #else *GenCtrlStr = " s%- u%- n%- N%- i%- c%- C%- m%- a%- q%- g%-\"x1,x2,y1,y2\"!s G%-\"x1,x2,y1,y2\"!s I%-#IsoLines!d F%-PlgnOpti|PlgnFineNess!d!f R%- f%-PllnOpti|PllnFineNess!d!f E%-RelLowRes!f p%-!f l%-LineWidth!d r%- A%-Shader!d B%- 2%- d%- D%- L%-NormalLen!d 4%- k%-SketchSilTyp|SilPwr|ShdTyp|ShdPwr|InvShd|ImpTyp|Imp!d!f!d!f!d!d!f b%-\"R,B,G|(background)\"!s S%-\"x,y,z,w{,a,d,s}\"!s e%-PickDist!f O%-PickObjType!d Z%-ZMin|ZMax!f!f M%- W%-WireSetup!d P%- o%- x%-ExecAnimCmd!s X%-Min,Max,Dt,R{,flags}!s w%-InitWidget!d T%- z%- DFiles!*s"; #endif /* IRIT_DOUBLE */ static void IGHandleStateCommand(char *Str); static void HandleAnimate(char *Params); static int ReplyWithObject(IPObjectStruct *DisplayList, char *ObjName); static int IGDeleteOneObjectAux(IPObjectStruct *PObj, IPObjectStruct *PLst); static void UpdateAllActiveWidgets(IPObjectStruct *PObj, int Added); static RealType IGFindMinimalDist(IPObjectStruct *PObj, IPPolygonStruct **MinPl, PointType MinPt, int *MinPlIsPolyline, PointType LinePos, VectorType LineDir, RealType *HitDepth); static void UnhighObjects(void); static void UnhighObjectsAux(IPObjectStruct *PObj, MatrixType Mat); static void IGFindObjectByNameAux(IPObjectStruct *PObj, MatrixType Mat); static void PickObject(IPObjectStruct *PObj, MatrixType Mat); /***************************************************************************** * DESCRIPTION: M * Sets up configuration of global variables. M * * * PARAMETERS: M * PrgmName: Name of program invoking this module. M * argc, argv: Comand line. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGConfigureGlobals M *****************************************************************************/ void IGConfigureGlobals(char *PrgmName, int argc, char **argv) { int Error, DrawSrfWireSetup = 0, DrawSrfWireFlag = FALSE, TransPosFlag = FALSE, ViewPosFlag = FALSE, IsoLinesFlag = FALSE, SrfFinenessFlag = FALSE, CrvFinenessFlag = FALSE, LineWidthFlag = FALSE, NormalLenFlag = FALSE, BackGroundFlag = FALSE, LightSrcPosFlag = FALSE, MinPickDistFlag = FALSE, PickObjTypeFlag = FALSE, ZClipPlaneFlag = FALSE, PointWidthFlag = FALSE, ShadingModelFlag = FALSE, SketchStyleFlag = FALSE, ExecAnimEachStepFlag = FALSE, ExecAnimationFlag = FALSE, LowResFineNessFlag = FALSE, InitWidgetFlag = FALSE, AntiAliasingFlag = FALSE, DrawSolidFlag = FALSE, VerFlag = FALSE; char Line[LINE_LEN_VLONG]; float Ambient, Diffuse, Specular; IPObjectStruct *PObj; IritConfig(PrgmName, SetUp, NUM_SET_UP); /* Read config. file if exists. */ strcpy(Line, PrgmName); strcat(Line, GenCtrlStr); if ((Error = GAGetArgs(argc, argv, Line, &IGGlblStandAlone, &IGGlblForceUnitMat, &IGGlblDrawVNormal, &IGGlblDrawPNormal, &IGGlblDrawInternal, &IGGlblDepthCue, &IGGlblCacheGeom, &IGGlblMore, &IGGlblAntiAliasing, &GlblQuickLoad, &TransPosFlag, &IGGlblTransPrefPos, &ViewPosFlag, &IGGlblViewPrefPos, &IsoLinesFlag, &IGGlblNumOfIsolines, &SrfFinenessFlag, &IGGlblPolygonOptiApprox, &IGGlblPlgnFineness, &IGGlblPolygonStrips, &CrvFinenessFlag, &IGGlblPolylineOptiApprox, &IGGlblPllnFineness, &LowResFineNessFlag, &IGGlblRelLowresFineNess, &PointWidthFlag, &IGGlblPointWidth, &LineWidthFlag, &IGGlblLineWidth, &DrawSolidFlag, &ShadingModelFlag, &IGGlblShadingModel, &IGGlblBackFaceCull, &IGGlblDoDoubleBuffer, &IGGlblDebugObjectsFlag, &IGGlblDebugEchoInputFlag, &NormalLenFlag, &GlblNormalLenAux, &IGGlblFourPerFlat, &SketchStyleFlag, &IGSketchParam.SketchSilType, &IGSketchParam.SilPower, &IGSketchParam.SketchShdType, &IGSketchParam.ShadePower, &IGSketchParam.SketchInvShd, &IGSketchParam.SketchImpType, &IGSketchParam.SketchImpDecay, &BackGroundFlag, &GlblBackGroundStr, &LightSrcPosFlag, &GlblLightSrc1PosStr, &MinPickDistFlag, &IGGlblMinPickDist, &PickObjTypeFlag, &IGGlblPickObjTypes, &ZClipPlaneFlag, &IGGlblZMinClip, &IGGlblZMaxClip, &IGGlblDrawSurfaceMesh, &DrawSrfWireFlag, &DrawSrfWireSetup, &IGGlblDrawSurfacePoly, &IGGlblFlipNormalOrient, &ExecAnimEachStepFlag, &GlblExecAnimEachStep, &ExecAnimationFlag, &IGGlblExecAnimation, &InitWidgetFlag, &IGGlblInitWidgetDisplay, &IGGlblContinuousMotion, &VerFlag, &IGGlblNumFiles, &IGGlblFileNames )) != 0) { GAStringErrMsg(Error, Line); sprintf(&Line[strlen(Line)], "\n"); GAStringHowTo(GenCtrlStr, &Line[strlen(Line)]); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } #ifdef __WINNT__ if (IGGlblMore) IGRedirectIOToConsole(); #endif /* __WINNT__ */ if (IGGlblDrawStyle == 0) IGGlblDrawStyle = IG_STATE_DRAW_STYLE_WIREFRAME; else IGGlblDrawStyle = IG_STATE_DRAW_STYLE_SOLID; if (DrawSolidFlag) IGGlblDrawStyle = IG_STATE_DRAW_STYLE_SOLID; if (IGGlblAntiAliasing == 0) IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_OFF; else IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_ON; if (AntiAliasingFlag) IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_ON; if (sscanf(GlblBackGroundStr, "%d %d %d", &IGGlblBackGroundColor[0], &IGGlblBackGroundColor[1], &IGGlblBackGroundColor[2]) != 3) sscanf(GlblBackGroundStr, "%d,%d,%d", &IGGlblBackGroundColor[0], &IGGlblBackGroundColor[1], &IGGlblBackGroundColor[2]); if (sscanf(GlblHighlight1Str, "%d %d %d", &IGGlblHighlight1Color[0], &IGGlblHighlight1Color[1], &IGGlblHighlight1Color[2]) != 3) sscanf(GlblHighlight1Str, "%d,%d,%d", &IGGlblHighlight1Color[0], &IGGlblHighlight1Color[1], &IGGlblHighlight1Color[2]); if (sscanf(GlblHighlight2Str, "%d %d %d", &IGGlblHighlight2Color[0], &IGGlblHighlight2Color[1], &IGGlblHighlight2Color[2]) != 3) sscanf(GlblHighlight2Str, "%d,%d,%d", &IGGlblHighlight2Color[0], &IGGlblHighlight2Color[1], &IGGlblHighlight2Color[2]); if (sscanf(GlblLightSrc1PosStr, "%f %f %f %f %f %f %f", &IGShadeParam.LightPos[0][0], &IGShadeParam.LightPos[0][1], &IGShadeParam.LightPos[0][2], &IGShadeParam.LightPos[0][3], &Ambient, &Diffuse, &Specular) == 7 || sscanf(GlblLightSrc1PosStr, "%f,%f,%f,%f,%f,%f,%f", &IGShadeParam.LightPos[0][0], &IGShadeParam.LightPos[0][1], &IGShadeParam.LightPos[0][2], &IGShadeParam.LightPos[0][3], &Ambient, &Diffuse, &Specular) == 7) { /* Need to update intensities as well. */ IGShadeParam.LightAmbient[0] = IGShadeParam.LightAmbient[1] = IGShadeParam.LightAmbient[2] = Ambient; IGShadeParam.LightDiffuse[0] = IGShadeParam.LightDiffuse[1] = IGShadeParam.LightDiffuse[2] = Diffuse; IGShadeParam.LightSpecular[0] = IGShadeParam.LightSpecular[1] = IGShadeParam.LightSpecular[2] = Specular; } else { if (sscanf(GlblLightSrc1PosStr, "%f %f %f %f", &IGShadeParam.LightPos[0][0], &IGShadeParam.LightPos[0][1], &IGShadeParam.LightPos[0][2], &IGShadeParam.LightPos[0][3]) != 4) sscanf(GlblLightSrc1PosStr, "%f,%f,%f,%f", &IGShadeParam.LightPos[0][0], &IGShadeParam.LightPos[0][1], &IGShadeParam.LightPos[0][2], &IGShadeParam.LightPos[0][3]); } if (sscanf(GlblLightSrc2PosStr, "%f %f %f %f", &IGShadeParam.LightPos[1][0], &IGShadeParam.LightPos[1][1], &IGShadeParam.LightPos[1][2], &IGShadeParam.LightPos[1][3]) != 4) sscanf(GlblLightSrc2PosStr, "%f,%f,%f,%f", &IGShadeParam.LightPos[1][0], &IGShadeParam.LightPos[1][1], &IGShadeParam.LightPos[1][2], &IGShadeParam.LightPos[1][3]); if (VerFlag) { sprintf(Line, "%s%s\n\n", PrgmName, GenVersionStr); GAStringHowTo(GenCtrlStr, &Line[strlen(Line)]); IGIritError(Line); IritConfigPrint(SetUp, NUM_SET_UP); if (!IGGlblActiveXMode) exit(0); } if (ShadingModelFlag && (IGGlblShadingModel < IG_SHADING_NONE || IGGlblShadingModel > IG_SHADING_PHONG)) { sprintf(Line, "Shading Model between 0 (None) and 3 (Phong)\n\n%s%s\n\n", PrgmName, GenVersionStr); GAStringHowTo(GenCtrlStr, &Line[strlen(Line)]); IGIritError(Line); if (!IGGlblActiveXMode) exit(0); } if (DrawSrfWireFlag) { IGGlblDrawSurfaceWire = DrawSrfWireSetup & 0x01; IGGlblDrawSurfaceBndry = DrawSrfWireSetup & 0x02; IGGlblDrawSurfaceSilh = DrawSrfWireSetup & 0x04; IGGlblDrawSurfaceSketch = DrawSrfWireSetup & 0x08; IGGlblDrawSurfaceRflctLns = DrawSrfWireSetup & 0x10; } IPSetFlattenObjects(FALSE); if (!IGGlblStandAlone) { if ((IGGlblIOHandle = IPSocClntInit()) < 0) { sprintf(Line, "Failed to establish server connection\n"); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } if (IGGlblDebugEchoInputFlag) IPSocEchoInput(IGGlblIOHandle, TRUE); } IGGlblNormalLen = GlblNormalLenAux / 1000.0; if (IGGlblAdapIsoDir == 1) IGGlblAdapIsoDir = CAGD_CONST_U_DIR; else if (IGGlblAdapIsoDir == 2) IGGlblAdapIsoDir = CAGD_CONST_V_DIR; MatGenUnitMat(GlblLastProcessMat); /* Get the data files: */ if (IGGlblNumFiles > 0) { GlblFirstLoadedFile = IritStrdup(IGGlblFileNames[0]); if ((IGGlblDisplayList = IPGetDataFiles(IGGlblFileNames, IGGlblNumFiles, TRUE, TRUE)) != NULL) { if (!GlblQuickLoad) IGConfirmConvexPolys(IGGlblDisplayList, 0); if ((PObj = IPGetObjectByName("cont_mat", IGGlblDisplayList, FALSE)) != NULL && IP_IS_MAT_OBJ(PObj)) { MAT_COPY(GlblLastProcessMat, PObj -> U.Mat); IGGlblContinuousMotion = TRUE; } for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext) { if (IP_IS_CRV_OBJ(PObj) && AttrGetObjectIntAttrib(PObj, "EditCrvDirectly") == 1) IGCrvEditPreloadEditCurveObj = PObj; if (IP_IS_SRF_OBJ(PObj) && AttrGetObjectIntAttrib(PObj, "EditSrfDirectly") == 1) IGSrfEditPreloadEditSurfaceObj = PObj; } } else { IGIritError("Failed to load the data file specified"); if (!IGGlblActiveXMode) exit(1); } IGGlblViewMode = IPWasPrspMat ? IG_VIEW_PERSPECTIVE : IG_VIEW_ORTHOGRAPHIC; } Cagd2PolyClipPolysAtPoles(IGGlblClipAtPoles); GMSphConeSetConeDensity(SPHERE_CONE_DENSITY); PT_NORMALIZE_FLOAT(IGShadeParam.LightPos[0]); PT_NORMALIZE_FLOAT(IGShadeParam.LightPos[1]); /* Make sure that if we ask to draw solid, depth cueing is disabled. */ if (IGGlblDrawStyle == IG_STATE_DRAW_STYLE_SOLID) IGGlblDepthCue = FALSE; if (!IPWasViewMat && !GlblQuickLoad) { if (IGGlblDisplayList != NULL) { int BBoxPosWeights; RealType s; /* Precompute proper bounding box to begin transformation with. */ GMBBBboxStruct *BBox; VectorType Center, Scaling; MatrixType Mat1, Mat2; /* Ignore zero weights while deriving the bbox. */ BBoxPosWeights = CagdIgnoreNonPosWeightBBox(TRUE); GMBBSetGlblBBObjList(IGGlblDisplayList); BBox = GMBBComputeBboxObjectList(IGGlblDisplayList); CagdIgnoreNonPosWeightBBox(BBoxPosWeights); PT_ADD(Center, BBox -> Max, BBox -> Min); PT_SCALE(Center, 0.5); MatGenMatTrans(-Center[0], -Center[1], -Center[2], Mat1); PT_SUB(Scaling, BBox -> Max, BBox -> Min); s = MAX(Scaling[0], MAX(Scaling[1], Scaling[2])); if (s < IRIT_EPS) s = IRIT_EPS; MatGenMatUnifScale(1.0 / s, Mat2); MatMultTwo4by4(Mat1, Mat1, Mat2); MatMultTwo4by4(IPViewMat, Mat1, IPViewMat); } } if (IGGlblForceUnitMat) { MatGenUnitMat(IPViewMat); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; } GEN_COPY(GlblPushViewMat, IPViewMat, sizeof(MatrixType)); GEN_COPY(GlblPushPrspMat, IPPrspMat, sizeof(MatrixType)); switch (IGGlblViewMode) { /* Update the current view. */ case IG_VIEW_ORTHOGRAPHIC: GEN_COPY(IGGlblCrntViewMat, IPViewMat, sizeof(MatrixType)); break; case IG_VIEW_PERSPECTIVE: MatMultTwo4by4(IGGlblCrntViewMat, IPViewMat, IPPrspMat); break; } if (!GlblQuickLoad) { GMBBSetGlblBBObjList(IGGlblDisplayList); for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext) IGUpdateObjectBBox(PObj); } GMAnimResetAnimStruct(&IGAnimation); GMAnimFindAnimationTime(&IGAnimation, IGGlblDisplayList); if (GlblExecAnimEachStep != NULL && strlen(GlblExecAnimEachStep) > 0) IGAnimation.ExecEachStep = GlblExecAnimEachStep; } /***************************************************************************** * DESCRIPTION: M * Reset all static state variables of the display device into starting M * values. M * * * PARAMETERS: M * None M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGConfigReset M *****************************************************************************/ void IGConfigReset(void) { UpdateAllActiveWidgets(NULL, FALSE); GlblThisPickObjTypes = IG_PICK_ANY; GlblDelayedClear = FALSE; GlblProcessCommandMesssages = TRUE; GlblNormalLenAux = 200; GlblPickScale = 1.0; GlblMinFoundDepth = -IRIT_INFNTY; GlblObjectSearchName = "", GlblExecAnimEachStep = "", GlblLightSrc1PosStr = "1.0, 2.0, -5.0, 0.0", GlblLightSrc2PosStr = "3.0, -1.0, -10.0, 0.0", GlblBackGroundStr = "0,0,0", GlblHighlight1Str = "255,0,255", GlblHighlight2Str = "255,100,200"; GlblObjectFoundByName = NULL; IGGlblBackGroundColor[0] = IGGlblBackGroundColor[1] = IGGlblBackGroundColor[2] = 0; IGGlblHighlight1Color[0] = 255; IGGlblHighlight1Color[0] = 0; IGGlblHighlight1Color[0] = 255; IGGlblHighlight2Color[0] = 255; IGGlblHighlight2Color[1] = 0; IGGlblHighlight2Color[2] = 0; IGGlblDrawInternal = FALSE; IGGlblDrawVNormal = FALSE; IGGlblDrawPNormal = FALSE; IGGlbl4Views = FALSE; IGGlblMore = FALSE; IGGlblPolygonOptiApprox = 0; IGGlblForceUnitMat = FALSE; IGGlblDrawStyle = IG_STATE_DRAW_STYLE_WIREFRAME; IGGlblShadingModel = IG_SHADING_PHONG; IGGlblBackFaceCull = FALSE; IGGlblDoDoubleBuffer = TRUE; IGGlblNumOfIsolines = 10; IGGlblPllnFineness = IG_DEFAULT_SAMPLES_PER_CURVE; IGGlblLineWidth = 1; IGGlblAdapIsoDir = CAGD_CONST_U_DIR; IGGlblDepthCue = TRUE; IGGlblCacheGeom = TRUE; IGGlblFourPerFlat = TRUE; IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_OFF; IGGlblDrawPolygons = TRUE; IGGlblDrawSurfaceMesh = FALSE; IGGlblDrawSurfacePoly = FALSE; IGGlblDrawSurfaceWire = TRUE; IGGlblDrawSurfaceBndry = FALSE; IGGlblDrawSurfaceSilh = FALSE; IGGlblDrawSurfaceSketch = FALSE; IGGlblDrawSurfaceRflctLns = FALSE; IGGlblStandAlone = TRUE; IGGlblTransformMode = IG_TRANS_SCREEN; IGGlblViewMode = IG_VIEW_PERSPECTIVE; IGGlblDebugObjectsFlag = FALSE; IGGlblDebugEchoInputFlag = FALSE; IGGlblIntensityHighState = TRUE; IGGlblAbortKeyPressed = FALSE; IGGlblAnimation = FALSE; IGGlblPolygonStrips = FALSE; IGGlblManipulationActive = FALSE; IGGlblLastLowResDraw = FALSE; IGLastWasSolidRendering = FALSE; IGGlblContinuousMotion = FALSE; IGGlblFlipNormalOrient = FALSE; IGGlblClientHandleNumber = -1; IGGlblPickObjTypes = IG_PICK_ANY; IGGlblCountNumPolys = FALSE; IGGlblNumPolys = 0; IGGlblNumFiles = 0; IGGlblIOHandle = -1; IGGlblInitWidgetDisplay = 0; IGGlblActiveXMode = FALSE; IGGlblPolylineOptiApprox = SYMB_CRV_APPROX_UNIFORM; IGGlblExecAnimation = ""; IGGlblTransPrefPos = "455, 640, 520, 965"; IGGlblViewPrefPos = " 1, 450, 520, 965"; IGGlblMinFoundDist = IRIT_INFNTY; IGGlblRelLowresFineNess = 0.3; IGGlblMinPickDist = 0.2; IGGlblPointWidth = 0.02; IGGlblPlgnFineness = 10.0; IGGlblChangeFactor = 1.0; IGGlblZMinClip = -2.0; IGGlblZMaxClip = 2.0; IGGlblNormalLen = 0.2; IGGlblNewDisplayObjects = NULL; IGGlblDisplayList = NULL; IGGlblPickedObj = NULL; if (IGGlblPickedPolyObj != NULL) { IPFreeObject(IGGlblPickedPolyObj); IGGlblPickedPolyObj = NULL; } } /***************************************************************************** * DESCRIPTION: M * Make sure all polygons are convex. M * * * PARAMETERS: M * PObj: Objects to make sure all its polygons are convex. M * Depth: Of object hierarchy. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGConfirmConvexPolys M *****************************************************************************/ void IGConfirmConvexPolys(IPObjectStruct *PObj, int Depth) { for (; PObj != NULL; PObj = PObj -> Pnext) { if (IP_IS_OLST_OBJ(PObj)) { IPObjectStruct *PTmp; int i = 0; /* Search in its list. */ while ((PTmp = IPListObjectGet(PObj, i++)) != NULL) IGConfirmConvexPolys(PTmp, Depth + 1); } else if (IP_IS_POLY_OBJ(PObj) && IP_IS_POLYGON_OBJ(PObj)) { /* Make sure all polygons are convex. */ IPOpenPolysToClosed(PObj -> U.Pl); IPSetPolyListCirc(TRUE); GMConvexPolyObject(PObj); IPSetPolyListCirc(FALSE); IPClosedPolysToOpen(PObj -> U.Pl); } /* No linked list in inner levels. */ if (Depth > 0) break; } } /***************************************************************************** * DESCRIPTION: M * Are we suppose to handle command messages of the socket? A command message M * will be a string objct sent over the socket with object name "COMMAND_". M * * * PARAMETERS: M * ProcessCommandMessages: Sets the command message handling option. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGProcessCommandMessages M *****************************************************************************/ void IGProcessCommandMessages(int ProcessCommandMessages) { GlblProcessCommandMesssages = ProcessCommandMessages; } /***************************************************************************** * DESCRIPTION: M * Reads an object from communication socket. M * Returns TRUE if screen needs to be redrawn in the case that the M * DisplayList was modified. M * This function DOES NOT BLOCK if no input is unavailable. M * Handles commands via a string object with name "COMMAND_", if required M * * * PARAMETERS: M * ViewMode: Either perspective or orthographics. M * DisplayList: Global object display list. Will be updated in place. M * * * RETURN VALUE: M * int: TRUE, if display needs to be refreshed. M * * * KEYWORDS: M * IGReadObjectsFromSocket M *****************************************************************************/ int IGReadObjectsFromSocket(int ViewMode, IPObjectStruct **DisplayList) { IPObjectStruct *PObjs; if ((PObjs = IPSocReadOneObject(IGGlblIOHandle)) != NULL) { #if defined(OS2GCC) /* We are working here in a separated thread - keep it for a later */ /* use by the main thread - when we do not use the display list. */ while (IGGlblNewDisplayObjects != NULL) IritSleep(10); IritSleep(10); IGGlblNewDisplayObjects = PObjs; return FALSE; #else return IGHandleObjectsFromSocket(ViewMode, PObjs, DisplayList); #endif /* OS2GCC */ } return FALSE; } /***************************************************************************** * DESCRIPTION: M * Reads an object from communication socket. M * Returns TRUE if screen needs to be redrawn in the case that the M * DisplayList was modified. M * This function DOES NOT BLOCK if no input is unavailable. M * Handles commands via a string object with name "COMMAND_", if required M * * * PARAMETERS: M * ViewMode: Either perspective or orthographics. M * PObjs: To insert into the display list. M * DisplayList: Global object display list. Will be updated in place. M * * * RETURN VALUE: M * int: TRUE, if display needs to be refreshed. M * * * KEYWORDS: M * IGHandleObjectsFromSocket M *****************************************************************************/ int IGHandleObjectsFromSocket(int ViewMode, IPObjectStruct *PObjs, IPObjectStruct **DisplayList) { int Redraw = FALSE; char Line[LINE_LEN_LONG]; if (PObjs != NULL) { IPObjectStruct *PObj, *PTmp; Redraw = TRUE; if (GlblDelayedClear) { GlblDelayedClear = FALSE; IGDefaultStateHandler(IG_STATE_CLEAR_VIEW, IG_STATE_ON, TRUE); } while (PObjs != NULL) { PObj = PObjs; PObjs = PObjs -> Pnext; PObj -> Pnext = NULL; PObj -> Count = 0; /* Can be much higher coming from socket. */ if (IGGlblDebugObjectsFlag) IPPutObjectToFile(stderr, PObj, FALSE); if (GlblProcessCommandMesssages) { switch (PObj -> ObjType) { case IP_OBJ_STRING: if (stricmp(PObj -> ObjName, "COMMAND_") == 0) { char *Str = PObj -> U.Str; if (strnicmp(Str, "ANIMATE", 7) == 0) { HandleAnimate(&Str[7]); Redraw = TRUE; } else if (stricmp(Str, "BEEP") == 0) { IGIritBeep(); Redraw = FALSE; } else if (stricmp(Str, "CLEAR") == 0) { IGDefaultStateHandler(IG_STATE_CLEAR_VIEW, IG_STATE_ON, TRUE); } else if (stricmp(Str, "DCLEAR") == 0) { GlblDelayedClear = TRUE; Redraw = FALSE; } else if (stricmp(Str, "DISCONNECT") == 0) { IPCloseStream(IGGlblIOHandle, TRUE); IGGlblStandAlone = TRUE; Redraw = FALSE; } else if (stricmp(Str, "EXIT") == 0) { IPCloseStream(IGGlblIOHandle, TRUE); if (!IGGlblActiveXMode) exit(0); } else if (strnicmp(Str, "EDITCRV", 7) == 0) { if (strlen(&Str[7]) < 2) PTmp = NULL; else PTmp = IGFindObjectByName(&Str[8]); IGPopupCrvEditor(PTmp); } else if (strnicmp(Str, "EDITSRF", 7) == 0) { if (strlen(&Str[7]) < 2) PTmp = NULL; else PTmp = IGFindObjectByName(&Str[8]); IGPopupSrfEditor(PTmp); } else if (strnicmp(Str, "EDITOBJ", 7) == 0) { if (strlen(&Str[7]) < 2) PTmp = NULL; else PTmp = IGFindObjectByName(&Str[8]); IGPopupObjEditor(PTmp, FALSE); } else if (strnicmp(Str, "CLONEOBJ", 8) == 0) { if (strlen(&Str[8]) < 2) PTmp = NULL; else PTmp = IGFindObjectByName(&Str[9]); IGPopupObjEditor(PTmp, TRUE); } else if (strnicmp(Str, "GETOBJ", 6) == 0) { if (strlen(&Str[6]) < 2 || !ReplyWithObject(*DisplayList, &Str[7])) { sprintf(Line, "No such object \"%s\"\n", &Str[6]); IGIritError(Line); } Redraw = FALSE; } else if (strnicmp(Str, "HANDLENUM", 9) == 0) { if (strlen(&Str[9]) < 2 || sscanf(&Str[10], "%d", &IGGlblClientHandleNumber) != 1) { sprintf(Line, "Expected client handle number\n"); IGIritError(Line); } Redraw = FALSE; } else if (strnicmp(Str, "HIGHLIGHT1", 10) == 0) { if (strlen(&Str[10]) > 1 && (PTmp = IGFindObjectByName(&Str[11])) != NULL) IG_SET_HIGHLIGHT1_OBJ(PTmp); } else if (strnicmp(Str, "HIGHLIGHT2", 10) == 0) { if (strlen(&Str[10]) > 1 && (PTmp = IGFindObjectByName(&Str[11])) != NULL) IG_SET_HIGHLIGHT2_OBJ(PTmp); } else if (strnicmp(Str, "IMGSAVE", 7) == 0) { if (strlen(&Str[7]) > 1) IGSaveDisplayAsImage(&Str[8]); Redraw = FALSE; } else if (strnicmp(Str, "MSAVE", 5) == 0) { if (strlen(&Str[5]) > 1) IGSaveCurrentMat(ViewMode, &Str[6]); Redraw = FALSE; } else if (stricmp(Str, "PICKCRSR") == 0) { IGHandlePickObject(IG_PICK_ENTITY_CURSOR); Redraw = FALSE; } else if (stricmp(Str, "PICKDONE") == 0) { IGHandlePickObject(IG_PICK_ENTITY_DONE); Redraw = FALSE; } else if (stricmp(Str, "PICKNAME") == 0) { IGHandlePickObject(IG_PICK_ENTITY_OBJ_NAME); Redraw = FALSE; } else if (stricmp(Str, "PICKOBJ") == 0) { IGHandlePickObject(IG_PICK_ENTITY_OBJECT); Redraw = FALSE; } else if (strnicmp(Str, "REMOVE", 6) == 0) { if (strlen(&Str[6]) > 1) IGAddReplaceObjDisplayList(DisplayList, NULL, &Str[7]); Redraw = TRUE; } else if (strnicmp(Str, "STATE", 5) == 0) { IGHandleStateCommand(Str); } else if (stricmp(Str, "UNHIGHLIGHT") == 0) { UnhighObjects(); } } IPFreeObject(PObj); break; case IP_OBJ_MATRIX: /* The parser will place "VIEW_MAT" and "PRSP_MAT" */ /* in IPViewMat and IPPrspMat, respectively, */ /* so we need do nothing here. */ IPFreeObject(PObj); break; default: IGAddReplaceObjDisplayList(DisplayList, PObj, NULL); break; } } else { IGAddReplaceObjDisplayList(DisplayList, PObj, NULL); } } return Redraw; } else return Redraw; } /***************************************************************************** * DESCRIPTION: * * Process a command that is a view state command. * * * * PARAMETERS: * * Str: Command as "STATE StateName [Param]", where param can be one of * * 0 for IG_STATE_FALSE, 1 for IG_STATE_TRUE, -1 for IG_STATE_TGL. * * Default for no param is IG_STATE_TGL. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void IGHandleStateCommand(char *Str) { int i; if (strlen(&Str[5]) > 1) { Str = &Str[6]; for (i = 0; StateNameNum[i].Name != NULL; i++) { int Len = (int) strlen(StateNameNum[i].Name); if (strnicmp(Str, StateNameNum[i].Name, Len) == 0) { int Param; /* Skip the detected StateName and search for parameters. */ Str = &Str[Len]; if (sscanf(Str, "%d", &Param) != 1) Param = -1; switch (Param) { case -1: Param = IG_STATE_TGL; break; case 0: Param = IG_STATE_OFF; break; case 1: Param = IG_STATE_ON; break; } IGHandleState(StateNameNum[i].Num, Param, TRUE); break; } } } } /***************************************************************************** * DESCRIPTION: * * Honors an animate request from the server. * * * * PARAMETERS: * * Params: A strings contains Tmin Tmax Dt, in this order. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void HandleAnimate(char *Params) { double TMin, TMax, Dt; if (sscanf(Params, "%lf %lf %lf", &TMin, &TMax, &Dt) == 3) { IGAnimation.StartT = TMin; IGAnimation.FinalT = TMax; IGAnimation.Dt = Dt; GMAnimDoAnimation(&IGAnimation, IGGlblDisplayList); } else { char Line[LINE_LEN_LONG]; sprintf(Line, "Animate param, expected \"Tmin Tmax Dt\", found \"%s\"\n", Params); IGIritError(Line); } } /***************************************************************************** * DESCRIPTION: M * Adds or replaces an object on the display list. M * If ObjName is not NULL, that object is removed from the display list. M * Otherwise NewObj is added to the display list, possibly replacing an M * object on the display list with the same name. M * * * PARAMETERS: M * DisplayList: Global display list to update. M * NewObj: New object to add to the global display list. M * ObjName: Name of object to remove from display list. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGAddReplaceObjDisplayList M *****************************************************************************/ void IGAddReplaceObjDisplayList(IPObjectStruct **DisplayList, IPObjectStruct *NewObj, char *ObjName) { int Remove = ObjName != NULL; char *Name = ObjName != NULL ? ObjName : NewObj -> ObjName; IPObjectStruct *PObj; if (NewObj != NULL) { IGConfirmConvexPolys(NewObj, 1); IGUpdateObjectBBox(NewObj); } /* If object has no name or display list is empty, add it. */ if (!Remove && NewObj != NULL && (strlen(NewObj -> ObjName) == 0 || NewObj -> ObjName[0] == '_' || stricmp(NewObj -> ObjName, "none") == 0)) { NewObj -> Pnext = *DisplayList; *DisplayList = NewObj; UpdateAllActiveWidgets(NewObj, TRUE); return; } if (*DisplayList == NULL) { if (NewObj != NULL) { *DisplayList = NewObj; UpdateAllActiveWidgets(NewObj, TRUE); } return; } if (stricmp(Name, (*DisplayList) -> ObjName) == 0) { if (Remove) { PObj = *DisplayList; *DisplayList = (*DisplayList) -> Pnext; IPFreeObject(PObj); } else { NewObj -> Pnext = (*DisplayList) -> Pnext; IPFreeObject(*DisplayList); *DisplayList = NewObj; } UpdateAllActiveWidgets(*DisplayList, FALSE); } else { for (PObj = *DisplayList; PObj -> Pnext != NULL; PObj = PObj -> Pnext) { if (stricmp(Name, PObj -> Pnext -> ObjName) == 0) { IPObjectStruct *PObjTmp = PObj -> Pnext; if (Remove) { PObj -> Pnext = PObjTmp -> Pnext; } else { PObj -> Pnext = NewObj; NewObj -> Pnext = PObjTmp -> Pnext; } IPFreeObject(PObjTmp); UpdateAllActiveWidgets(PObjTmp, FALSE); return; } } /* Name was not found. */ if (!Remove) { NewObj -> Pnext = *DisplayList; *DisplayList = NewObj; UpdateAllActiveWidgets(NewObj, TRUE); } } } /***************************************************************************** * DESCRIPTION: * * Returns into the output channel the object requested via ObjName. * * * * PARAMETERS: * * DisplayList: List of all current objects. * * ObjName: Name of object to search. * * * * RETURN VALUE: * * int: TRUE if succesful, FALSE otherwise. * * * * KEYWORDS: * * ReplayWithObject * *****************************************************************************/ static int ReplyWithObject(IPObjectStruct *DisplayList, char *ObjName) { IPObjectStruct *PObj; for (PObj = DisplayList; PObj != NULL; PObj = PObj -> Pnext) { if (stricmp(ObjName, PObj -> ObjName) == 0) { IPSocWriteOneObject(IGGlblIOHandle, PObj); return TRUE; } } /* Dumps this string object instead, so we will not block the server. */ PObj = IPGenStrObject("_PickFail_", "*** no object ***", NULL); IPSocWriteOneObject(IGGlblIOHandle, PObj); IPFreeObject(PObj); return FALSE; } /***************************************************************************** * DESCRIPTION: M * Saves the current viewing matrices. M * * * PARAMETERS: M * ViewMode: Either perspective or orthographic. M * Name: File name to save current view at. M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IGSubmitCurrentMat M * * * KEYWORDS: M * IGSaveCurrentMat M *****************************************************************************/ void IGSaveCurrentMat(int ViewMode, char *Name) { char *p, FullName[LINE_LEN_LONG]; int i, j; FILE *f; if (Name == NULL) Name = IG_DEFAULT_IRIT_MAT; strcpy(FullName, Name); if ((p = strrchr(FullName, '.')) != NULL && (stricmp(p + 1, IRIT_TEXT_DATA_FILE) != 0 || stricmp(p + 1, IRIT_BINARY_DATA_FILE) != 0 || stricmp(p + 1, IRIT_MATRIX_DATA_FILE) != 0)) *p = 0; strcat(FullName, "."); strcat(FullName, IRIT_MATRIX_DATA_FILE); #if defined(AMIGA) && !defined(__SASC) if (strlen(Name) == 0 || (f = fopen(Name, "w")) == NULL) { #else if (strlen(Name) == 0 || (f = fopen(Name, "wt")) == NULL) { #endif /* defined(AMIGA) && !defined(__SASC) */ IGIritBeep(); return; } fprintf(f, "[OBJECT MATRICES\n [OBJECT VIEW_MAT\n\t[MATRIX"); for (i = 0; i < 4; i++) { fprintf(f, "\n\t "); for (j = 0; j < 4; j++) fprintf(f, "%12.9f ", IPViewMat[i][j]); } fprintf(f, "\n\t]\n ]\n"); if (ViewMode == IG_VIEW_PERSPECTIVE) { fprintf(f, " [OBJECT PRSP_MAT\n\t[MATRIX"); for (i = 0; i < 4; i++) { fprintf(f, "\n\t "); for (j = 0; j < 4; j++) fprintf(f, "%12.9f ", IPPrspMat[i][j]); } fprintf(f, "\n\t]\n ]\n"); } fprintf(f, "]\n"); fclose(f); } /***************************************************************************** * DESCRIPTION: M * Saves the current viewing matrices. M * * * PARAMETERS: M * ViewMode: Either perspective or orthographic. M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IGSaveCurrentMat M * * * KEYWORDS: M * IGSubmitCurrentMat M *****************************************************************************/ void IGSubmitCurrentMat(int ViewMode) { IPObjectStruct *PObj; if (IGGlblStandAlone) { IGIritError("No submissions in stand alone mode"); return; } PObj = IPGenMATObject(IPViewMat); IP_SET_OBJ_NAME2(PObj, "_SubmitMat_"); AttrSetObjectStrAttrib(PObj, "ObjName", "view_mat_dd"); IPSocWriteOneObject(IGGlblIOHandle, PObj); IPFreeObject(PObj); if (ViewMode == IG_VIEW_PERSPECTIVE) { PObj = IPGenMATObject(IPPrspMat); IP_SET_OBJ_NAME2(PObj, "_SubmitMat_"); AttrSetObjectStrAttrib(PObj, "ObjName", "prsp_mat_dd"); IPSocWriteOneObject(IGGlblIOHandle, PObj); IPFreeObject(PObj); } } /***************************************************************************** * DESCRIPTION: M * Saves the picked polygons. M * * * PARAMETERS: M * Pl: Pick poly. M * IsPolyline: TRUE if picked poly a polyline, FALSE if a polygon. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGHighlightSavePickedPoly M *****************************************************************************/ void IGHighlightSavePickedPoly(IPPolygonStruct *Pl, int IsPolyline) { static int PickFileIndex = 1; static char *PickFileName = NULL; char Name[LINE_LEN_LONG]; FILE *f; if (Pl == NULL) return; if (IGGlblPickedPolyObj != NULL) IPFreeObject(IGGlblPickedPolyObj); IGGlblPickedPolyObj = IsPolyline ? IPGenPOLYLINEObject(IPCopyPolygon(Pl)) : IPGenPOLYObject(IPCopyPolygon(Pl)); IG_SET_HIGHLIGHT2_OBJ(IGGlblPickedPolyObj); if (!IGGlblSavePickedPoly) return; if (IGGlblPolyPickFileName != NULL) { /* We have a new prescription of file name - reset the stage. */ if (PickFileName != NULL) IritFree(PickFileName); PickFileName = IGGlblPolyPickFileName; IGGlblPolyPickFileName = NULL; PickFileIndex = 1; } if (PickFileName == NULL || strlen(PickFileName) == 0) return; sprintf(Name, PickFileName, PickFileIndex++); #if defined(AMIGA) && !defined(__SASC) if (strlen(Name) == 0 || (f = fopen(Name, "w")) == NULL) { #else if (strlen(Name) == 0 || (f = fopen(Name, "wt")) == NULL) { #endif /* defined(AMIGA) && !defined(__SASC) */ IGIritBeep(); return; } IPPutObjectToFile(f, IGGlblPickedPolyObj, FALSE); fclose(f); } /***************************************************************************** * DESCRIPTION: M * handles continous motion mode where the object is continuously rotating M * on the screen. Updates the current view matrix based on the last M * transformation applied and redraw. M * * * PARAMETERS: M * None M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IGProcessEvent M * * * KEYWORDS: M * IGHandleContinuousMotion M *****************************************************************************/ void IGHandleContinuousMotion(void) { switch (IGGlblTransformMode) { /* Udpate the global viewing matrix. */ case IG_TRANS_SCREEN: MatMultTwo4by4(IPViewMat, IPViewMat, GlblLastProcessMat); break; case IG_TRANS_OBJECT: MatMultTwo4by4(IPViewMat, GlblLastProcessMat, IPViewMat); break; } IGRedrawViewWindow(); IritSleep(10); } /***************************************************************************** * DESCRIPTION: M * Processes the given event. Returns TRUE if redraw of view window is needed.M * * * PARAMETERS: M * Event: Event to process. M * ChangeFactor: A continuous scale between -1 and 1 to quantify the M * change to apply according to the event type. M * For composed operation contains both X and Y information.M * * * RETURN VALUE: M * int: TRUE if refresh is needed. M * * * SEE ALSO: M * IGHandleContinuousMotion M * * * KEYWORDS: M * IGProcessEvent M *****************************************************************************/ int IGProcessEvent(IGGraphicEventType Event, RealType *ChangeFactor) { int UpdateView = TRUE; MatrixType Mat, TMat; MatGenUnitMat(Mat); switch (Event) { case IG_EVENT_SCR_OBJ_TGL: /* Its Coordinate system - toggle it. */ UpdateView = FALSE; break; case IG_EVENT_PERS_ORTHO_TGL: /* Its View mode - toggle it. */ break; case IG_EVENT_PERS_ORTHO_Z: /* Its Perspective Z focal point modif. */ if (IGGlblViewMode != IG_VIEW_PERSPECTIVE) { IGIritBeep(); UpdateView = FALSE; break; } /* Make it between 0.5 and 1.5: */ *ChangeFactor = *ChangeFactor / 2.0 + 1.0; IPPrspMat[2][2] *= *ChangeFactor; IPPrspMat[2][3] *= *ChangeFactor; IPPrspMat[3][2] *= *ChangeFactor; break; case IG_EVENT_ROTATE: /* Its rotation in both X and Y. */ /* Doing it seperatly for X and Y is not the right thing, but it */ /* does work for us, in interactive use. */ MatGenMatRotY1(DEG2RAD(ChangeFactor[0] * IG_MAX_ROTATE_ANGLE / 150), TMat); MatGenMatRotX1(DEG2RAD(-ChangeFactor[1] * IG_MAX_ROTATE_ANGLE / 150), Mat); MatMultTwo4by4(Mat, TMat, Mat); break; case IG_EVENT_ROTATE_X: /* Its rotation along the X axis. */ MatGenMatRotX1(DEG2RAD(*ChangeFactor * IG_MAX_ROTATE_ANGLE), Mat); break; case IG_EVENT_ROTATE_Y: /* Its rotation along the Y axis. */ MatGenMatRotY1(DEG2RAD(*ChangeFactor * IG_MAX_ROTATE_ANGLE), Mat); break; case IG_EVENT_ROTATE_Z: /* Its rotation along the Z axis. */ MatGenMatRotZ1(DEG2RAD(*ChangeFactor * IG_MAX_ROTATE_ANGLE), Mat); break; case IG_EVENT_TRANSLATE: /* Its translation in both X and Y. */ MatGenMatTrans(ChangeFactor[0] / 300.0, ChangeFactor[1] / 300.0, 0.0, Mat); break; case IG_EVENT_TRANSLATE_X: /* Its translation along the X axis. */ MatGenMatTrans(*ChangeFactor * IG_MAX_TRANSLATE_FACTOR, 0.0, 0.0, Mat); break; case IG_EVENT_TRANSLATE_Y: /* Its translation along the Y axis. */ MatGenMatTrans(0.0, *ChangeFactor * IG_MAX_TRANSLATE_FACTOR, 0.0, Mat); break; case IG_EVENT_TRANSLATE_Z: /* Its translation along the Z axis. */ MatGenMatTrans(0.0, 0.0, *ChangeFactor * IG_MAX_TRANSLATE_FACTOR, Mat); break; case IG_EVENT_SCALE: /* Its scaling along all axes. */ if (*ChangeFactor >= 0.0) /* Make it around 1... */ *ChangeFactor = *ChangeFactor * IG_MAX_SCALE_FACTOR + 1.0; else *ChangeFactor = 1.0 / (-*ChangeFactor * IG_MAX_SCALE_FACTOR + 1.0); MatGenMatUnifScale(*ChangeFactor, Mat); break; case IG_EVENT_NEAR_CLIP: /* Near plane clipping. */ IGGlblZMinClip += *ChangeFactor * IG_MAX_CLIP_FACTOR; IGGlblEyeDistance = 1.0 / (SQR(SQR(IGGlblZMinClip)) + 0.001); break; case IG_EVENT_FAR_CLIP: /* Far plane clipping. */ IGGlblZMaxClip += *ChangeFactor * IG_MAX_CLIP_FACTOR; break; case IG_EVENT_ANIMATION: IGGlblAnimation = TRUE; GMAnimGetAnimInfoText(&IGAnimation); GMAnimDoAnimation(&IGAnimation, IGGlblDisplayList); IGGlblAnimation = FALSE; break; case IG_EVENT_DEPTH_CUE: break; case IG_EVENT_SAVE_MATRIX: IGSaveCurrentMatInFile(IGGlblViewMode); UpdateView = FALSE; break; case IG_EVENT_SUBMIT_MATRIX: IGSubmitCurrentMat(IGGlblViewMode); UpdateView = FALSE; break; case IG_EVENT_PUSH_MATRIX: GEN_COPY(GlblPushViewMat, IPViewMat, sizeof(MatrixType)); GEN_COPY(GlblPushPrspMat, IPPrspMat, sizeof(MatrixType)); break; case IG_EVENT_POP_MATRIX: GEN_COPY(IPViewMat, GlblPushViewMat, sizeof(MatrixType)); GEN_COPY(IPPrspMat, GlblPushPrspMat, sizeof(MatrixType)); break; case IG_EVENT_STATE: IGCreateStateMenu(); break; default: IGIritBeep(); UpdateView = FALSE; } if (UpdateView) { MAT_COPY(GlblLastProcessMat, Mat); switch (IGGlblTransformMode) {/* Udpate the global viewing matrix. */ case IG_TRANS_SCREEN: MatMultTwo4by4(IPViewMat, IPViewMat, Mat); break; case IG_TRANS_OBJECT: MatMultTwo4by4(IPViewMat, Mat, IPViewMat); break; } } return UpdateView; } /***************************************************************************** * DESCRIPTION: M * Free attribute named Name from all objects in PObjs object's hierarchy and M * linked list. M * * * PARAMETERS: M * PObjs: Objects to remove Named attribute from. M * FreePolygons: If TRUE free all polygonal approximations of freeforms. M * FreeIsolines: If TRUE free all isocurve approximations of freeforms. M * FreeSketches: If TRUE free all sketching strokes of freeforms. M * FreeCtlMesh: If TRUE free all control meshes of freeforms. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGActiveListFreePolyIsoAttribute M *****************************************************************************/ void IGActiveListFreePolyIsoAttribute(IPObjectStruct *PObjs, int FreePolygons, int FreeIsolines, int FreeSketches, int FreeCtlMesh) { IPObjectStruct *PObj = PObjs; for (; PObj != NULL; PObj = PObj -> Pnext) { IGActiveFreePolyIsoAttribute(PObj, FreePolygons, FreeIsolines, FreeSketches, FreeCtlMesh); # ifdef HAVE_OGL_CG_LIB IGCGFreeDTexture(PObj); # endif /* HAVE_OGL_CG_LIB */ } } /***************************************************************************** * DESCRIPTION: M * Free attribute named Name from all objects in PObjs object's hierarchy. M * * * PARAMETERS: M * PObjs: Objects to remove Named attribute from. M * Name: Name of attribute to remove. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGActiveListFreeNamedAttribute M *****************************************************************************/ void IGActiveListFreeNamedAttribute(IPObjectStruct *PObjs, char *Name) { IPObjectStruct *PObj = PObjs; for (; PObj != NULL; PObj = PObj -> Pnext) { IGActiveFreeNamedAttribute(PObj, Name); } } /***************************************************************************** * DESCRIPTION: M * Free attribute named Name from all objects in PObj object's hierarchy. M * * * PARAMETERS: M * PObj: Object to remove Named attribute from. M * FreePolygons: If TRUE free all polygonal approximations of freeforms. M * FreeIsolines: If TRUE free all isocurve approximations of freeforms. M * FreeSketches: If TRUE free all sketching strokes of freeforms. M * FreeCtlMesh: If TRUE free all control meshes of freeforms. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGActiveFreePolyIsoAttribute M *****************************************************************************/ void IGActiveFreePolyIsoAttribute(IPObjectStruct *PObj, int FreePolygons, int FreeIsolines, int FreeSketches, int FreeCtlMesh) { if (FreePolygons) { IGActiveFreeNamedAttribute(PObj, "_polygons"); IGActiveFreeNamedAttribute(PObj, "_PolygonsHiRes"); IGActiveFreeNamedAttribute(PObj, "_PolygonsLoRes"); } if (FreeIsolines) { IGActiveFreeNamedAttribute(PObj, "_adap_iso"); IGActiveFreeNamedAttribute(PObj, "_isolines"); IGActiveFreeNamedAttribute(PObj, "_IsolinesHiRes"); IGActiveFreeNamedAttribute(PObj, "_IsolinesLoRes"); } if (FreeSketches) { IGActiveFreeNamedAttribute(PObj, "_sketches"); } if (FreeCtlMesh) { IGActiveFreeNamedAttribute(PObj, "_ctlmesh"); } } /***************************************************************************** * DESCRIPTION: M * Free attribute named Name from Pobj in all object's hierarchy. M * * * PARAMETERS: M * PObj: Objects to remove Named attribute from. M * Name: Name of attribute to remove. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGActiveFreeNamedAttribute M *****************************************************************************/ void IGActiveFreeNamedAttribute(IPObjectStruct *PObj, char *Name) { VoidPtr SphCones; IPObjectStruct *PObjAttr, *PObjTmp; if (strcmp(Name, "_sketches") == 0 && (PObjAttr = AttrGetObjectObjAttrib(PObj, "_sketches")) != NULL && (SphCones = AttrGetObjectPtrAttrib(PObjAttr, "_SphCones")) != NULL) GMSphConeQueryFree(SphCones); AttrFreeOneAttribute(&PObj -> Attr, Name); if ((PObjTmp = AttrGetObjectObjAttrib(PObj, "_Coerced")) != NULL) IGActiveFreeNamedAttribute(PObjTmp, Name); if (IP_IS_OLST_OBJ(PObj)) { IPObjectStruct *PTmp; int i = 0; /* Search in its list. */ while ((PTmp = IPListObjectGet(PObj, i++)) != NULL) IGActiveFreeNamedAttribute(PTmp, Name); } } /***************************************************************************** * DESCRIPTION: M * Update the BBox of the given object if has none. M * * * PARAMETERS: M * PObj: Objects to update its BBOX. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGUpdateObjectBBox M *****************************************************************************/ void IGUpdateObjectBBox(IPObjectStruct *PObj) { if (IP_IS_GEOM_OBJ(PObj) && !IP_HAS_BBOX_OBJ(PObj)) { GMBBBboxStruct *BBox = GMBBComputeBboxObject(PObj); PT_COPY(PObj -> BBox[0], BBox -> Min); PT_COPY(PObj -> BBox[1], BBox -> Max); IP_SET_BBOX_OBJ(PObj); } if (IP_IS_OLST_OBJ(PObj)) { IPObjectStruct *PTmp; int i = 0; /* Search in its list. */ while ((PTmp = IPListObjectGet(PObj, i++)) != NULL) IGUpdateObjectBBox(PTmp); } } /***************************************************************************** * DESCRIPTION: M * Handle the event of a pop up window. This is the default handler which can M * be invoked by other specific handlers for event they do not care about. M * * * PARAMETERS: M * State: State event type to handle. M * StateStatus: IG_STATE_OFF, IG_STATE_ON, IG_STATE_TGL for turning off, M * on or toggling current value. M * IG_STATE_DEC and IG_STATE_INC serves as dec./inc. factors. M * Refresh: Not used. M * * * RETURN VALUE: M * int: TRUE if needs to refresh. M * * * KEYWORDS: M * IGDefaultStateHandler M *****************************************************************************/ int IGDefaultStateHandler(int State, int StateStatus, int Refresh) { int UpdateView = TRUE; MatrixType Mat; char Line[LINE_LEN_LONG]; switch (State) { case IG_STATE_MOUSE_SENSITIVE: if (StateStatus == IG_STATE_INC) IGGlblChangeFactor *= 2.0; else IGGlblChangeFactor *= 0.5; break; case IG_STATE_SCR_OBJ_TGL: if (StateStatus == IG_STATE_TGL) { IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ? IG_TRANS_SCREEN : IG_TRANS_OBJECT; } else { IGGlblTransformMode = StateStatus == IG_STATE_ON ? IG_TRANS_SCREEN : IG_TRANS_OBJECT; } UpdateView = FALSE; break; case IG_STATE_CONT_MOTION: if (StateStatus == IG_STATE_TGL) IGGlblContinuousMotion = !IGGlblContinuousMotion; else IGGlblContinuousMotion = StateStatus == IG_STATE_ON; UpdateView = FALSE; break; case IG_STATE_NRML_ORIENT: if (StateStatus == IG_STATE_TGL) IGGlblFlipNormalOrient = !IGGlblFlipNormalOrient; else IGGlblFlipNormalOrient = StateStatus == IG_STATE_ON; break; case IG_STATE_PERS_ORTHO_TGL: if (StateStatus == IG_STATE_TGL) { IGGlblViewMode = IGGlblViewMode == IG_VIEW_ORTHOGRAPHIC ? IG_VIEW_PERSPECTIVE : IG_VIEW_ORTHOGRAPHIC; } else { IGGlblViewMode = StateStatus == IG_STATE_ON ? IG_VIEW_PERSPECTIVE : IG_VIEW_ORTHOGRAPHIC; } break; case IG_STATE_BACK_FACE_CULL: if (StateStatus == IG_STATE_TGL) IGGlblBackFaceCull = !IGGlblBackFaceCull; else IGGlblBackFaceCull = StateStatus == IG_STATE_ON; break; case IG_STATE_SHADING_MODEL: switch (IGGlblShadingModel) { case IG_SHADING_NONE: IGGlblShadingModel = IG_SHADING_BACKGROUND; break; case IG_SHADING_BACKGROUND: IGGlblShadingModel = IG_SHADING_FLAT; break; case IG_SHADING_FLAT: IGGlblShadingModel = IG_SHADING_GOURAUD; break; case IG_SHADING_GOURAUD: IGGlblShadingModel = IG_SHADING_PHONG; break; case IG_SHADING_PHONG: IGGlblShadingModel = IG_SHADING_NONE; break; } break; case IG_STATE_DEPTH_CUE: if (StateStatus == IG_STATE_TGL) IGGlblDepthCue = !IGGlblDepthCue; else IGGlblDepthCue = StateStatus == IG_STATE_ON; break; case IG_STATE_CACHE_GEOM: sprintf(Line, "You cannot change the geometry caching now\n"); IGIritError(Line); break; case IG_STATE_DRAW_INTERNAL: if (StateStatus == IG_STATE_TGL) IGGlblDrawInternal = !IGGlblDrawInternal; else IGGlblDrawInternal = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_VNORMAL: if (StateStatus == IG_STATE_TGL) IGGlblDrawVNormal = !IGGlblDrawVNormal; else IGGlblDrawVNormal = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_PNORMAL: if (StateStatus == IG_STATE_TGL) IGGlblDrawPNormal = !IGGlblDrawPNormal; else IGGlblDrawPNormal = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_MESH: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceMesh = !IGGlblDrawSurfaceMesh; else IGGlblDrawSurfaceMesh = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_WIRE: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceWire = !IGGlblDrawSurfaceWire; else IGGlblDrawSurfaceWire = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_BNDRY: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceBndry = !IGGlblDrawSurfaceBndry; else IGGlblDrawSurfaceBndry = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_SILH: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceSilh = !IGGlblDrawSurfaceSilh; else IGGlblDrawSurfaceSilh = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_POLY: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfacePoly = !IGGlblDrawSurfacePoly; else IGGlblDrawSurfacePoly = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_POLYGONS: if (StateStatus == IG_STATE_TGL) IGGlblDrawPolygons = !IGGlblDrawPolygons; else IGGlblDrawPolygons = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_SKTCH: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceSketch = !IGGlblDrawSurfaceSketch; else IGGlblDrawSurfaceSketch = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_SRF_RFLCT_LNS: if (StateStatus == IG_STATE_TGL) IGGlblDrawSurfaceRflctLns = !IGGlblDrawSurfaceRflctLns; else IGGlblDrawSurfaceRflctLns = StateStatus == IG_STATE_ON; break; case IG_STATE_DRAW_STYLE: switch (IGGlblDrawStyle) { case IG_STATE_DRAW_STYLE_WIREFRAME: IGGlblDrawStyle = IG_STATE_DRAW_STYLE_SOLID; break; case IG_STATE_DRAW_STYLE_SOLID: IGGlblDrawStyle = IG_STATE_DRAW_STYLE_POINTS; break; case IG_STATE_DRAW_STYLE_POINTS: default: IGGlblDrawStyle = IG_STATE_DRAW_STYLE_WIREFRAME; break; } break; case IG_STATE_DOUBLE_BUFFER: if (StateStatus == IG_STATE_TGL) IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer; else IGGlblDoDoubleBuffer = StateStatus == IG_STATE_ON; break; case IG_STATE_ANTI_ALIASING: switch (IGGlblAntiAliasing) { case IG_STATE_ANTI_ALIAS_OFF: IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_ON; break; case IG_STATE_ANTI_ALIAS_ON: IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_BLEND; break; case IG_STATE_ANTI_ALIAS_BLEND: default: IGGlblAntiAliasing = IG_STATE_ANTI_ALIAS_OFF; break; } break; case IG_STATE_FOUR_PER_FLAT: if (StateStatus == IG_STATE_TGL) IGGlblFourPerFlat = !IGGlblFourPerFlat; else IGGlblFourPerFlat = StateStatus == IG_STATE_ON; IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, TRUE, FALSE, FALSE, FALSE); break; case IG_STATE_NUM_ISOLINES: if (StateStatus == IG_STATE_INC) { if (IGGlblNumOfIsolines == 0) IGGlblNumOfIsolines = 1; else IGGlblNumOfIsolines *= 2; } else if (StateStatus == IG_STATE_DEC) IGGlblNumOfIsolines /= 2; IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, FALSE, TRUE, FALSE, FALSE); break; case IG_STATE_LENGTH_VECTORS: if (StateStatus == IG_STATE_INC) { IGGlblNormalLen *= 2.0; IGGlblPointWidth *= 2.0; } else if (StateStatus == IG_STATE_DEC) { IGGlblNormalLen /= 2.0; IGGlblPointWidth /= 2.0; } IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, FALSE, FALSE, TRUE, FALSE); break; case IG_STATE_POLYGON_APPROX: if (StateStatus == IG_STATE_INC) { if (IGGlblPolygonOptiApprox == 0) { IGGlblPlgnFineness *= 2.0; } else { IGGlblPlgnFineness /= 2.0; } } else if (StateStatus == IG_STATE_DEC) { if (IGGlblPolygonOptiApprox == 0) { IGGlblPlgnFineness /= 2.0; if (IGGlblPolygonOptiApprox == 0 && IGGlblPlgnFineness < 2.0) IGGlblPlgnFineness = 2.0; } else { IGGlblPlgnFineness *= 2.0; } } IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, TRUE, TRUE, TRUE, FALSE); break; case IG_STATE_SAMP_PER_CRV_APPROX: if (StateStatus == IG_STATE_INC) { IGGlblPllnFineness *= IGGlblPolylineOptiApprox == SYMB_CRV_APPROX_UNIFORM ? 2 : 0.5; } else if (StateStatus == IG_STATE_DEC) { IGGlblPllnFineness *= IGGlblPolylineOptiApprox == SYMB_CRV_APPROX_UNIFORM ? 0.5 : 2; if (IGGlblPolylineOptiApprox == SYMB_CRV_APPROX_UNIFORM && IGGlblPllnFineness < 2) IGGlblPllnFineness = 2; } IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, FALSE, TRUE, TRUE, FALSE); break; case IG_STATE_POLY_APPROX: if (StateStatus == IG_STATE_INC) { IGGlblPlgnFineness *= IGGlblPolygonOptiApprox == 0 ? 2.0 : 0.5; } else if (StateStatus == IG_STATE_DEC) { IGGlblPlgnFineness *= IGGlblPolygonOptiApprox == 0 ? 0.5 : 2.0; if (IGGlblPolygonOptiApprox == 0 && IGGlblPlgnFineness < 2.0) IGGlblPlgnFineness = 2.0; } IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, TRUE, FALSE, FALSE, FALSE); break; case IG_STATE_VIEW_FRONT: IGSetDisplay4Views(FALSE); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; MatGenMatRotZ1(DEG2RAD(0.0), Mat); IGUpdateViewConsideringScale(Mat); break; case IG_STATE_VIEW_SIDE: IGSetDisplay4Views(FALSE); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; MatGenMatRotY1(DEG2RAD(90.0), Mat); IGUpdateViewConsideringScale(Mat); break; case IG_STATE_VIEW_TOP: IGSetDisplay4Views(FALSE); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; MatGenMatRotX1(DEG2RAD(90.0), Mat); IGUpdateViewConsideringScale(Mat); break; case IG_STATE_VIEW_ISOMETRY: IGSetDisplay4Views(FALSE); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; IGUpdateViewConsideringScale(IGGlblIsometryViewMat); break; case IG_STATE_VIEW_4: IGSetDisplay4Views(TRUE); IGGlblViewMode = IG_VIEW_ORTHOGRAPHIC; IGInitializeSubViewMat(); break; case IG_STATE_CLEAR_VIEW: IPFreeObjectList(IGGlblDisplayList); IGGlblDisplayList = NULL; IGGlblPickedObj = NULL; if (IGGlblPickedPolyObj != NULL) { IPFreeObject(IGGlblPickedPolyObj); IGGlblPickedPolyObj = NULL; } UpdateAllActiveWidgets(NULL, FALSE); IrtImgReadClrCache(); /* Free all used texture maps. */ break; case IG_STATE_WIDTH_LINES: if (StateStatus == IG_STATE_INC) { IGGlblLineWidth *= 2; } else if (StateStatus == IG_STATE_DEC) { IGGlblLineWidth /= 2; if (IGGlblLineWidth < 1) IGGlblLineWidth = 1; } break; case IG_STATE_WIDTH_POINTS: if (StateStatus == IG_STATE_INC) { IGGlblPointWidth *= 2; } else if (StateStatus == IG_STATE_DEC) { IGGlblPointWidth /= 2; } break; case IG_STATE_NUM_POLY_COUNT: if (StateStatus == IG_STATE_TGL) IGGlblCountNumPolys = !IGGlblCountNumPolys; else IGGlblCountNumPolys = StateStatus == IG_STATE_ON; break; case IG_STATE_FRAME_PER_SEC: if (StateStatus == IG_STATE_TGL) IGGlblCountFramePerSec = !IGGlblCountFramePerSec; else IGGlblCountFramePerSec = StateStatus == IG_STATE_ON; break; case IG_STATE_POLYGON_OPTI: if (StateStatus == IG_STATE_TGL) IGGlblPolygonOptiApprox = !IGGlblPolygonOptiApprox; else IGGlblPolygonOptiApprox = StateStatus == IG_STATE_ON; IGGlblPlgnFineness = IGGlblPolygonOptiApprox ? 0.02 : 20; IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, TRUE, FALSE, FALSE, FALSE); break; case IG_STATE_POLYLINE_OPTI: if (StateStatus == IG_STATE_TGL) { if (IGGlblPolylineOptiApprox == SYMB_CRV_APPROX_UNIFORM) IGGlblPolylineOptiApprox = SYMB_CRV_APPROX_TOLERANCE; else IGGlblPolylineOptiApprox = SYMB_CRV_APPROX_UNIFORM; } else IGGlblPolylineOptiApprox = StateStatus == IG_STATE_ON ? SYMB_CRV_APPROX_TOLERANCE : SYMB_CRV_APPROX_UNIFORM; IGGlblPllnFineness = IGGlblPolylineOptiApprox == SYMB_CRV_APPROX_TOLERANCE ? IG_DEFAULT_PLLN_OPTI_FINENESS : IG_DEFAULT_SAMPLES_PER_CURVE; IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, FALSE, TRUE, FALSE, FALSE); break; case IG_STATE_LOWRES_RATIO: if (StateStatus == IG_STATE_INC) { IGGlblRelLowresFineNess *= 2; if (IGGlblRelLowresFineNess > 1.0) IGGlblRelLowresFineNess = 1.0; } else if (StateStatus == IG_STATE_DEC) { IGGlblRelLowresFineNess /= 2; } break; case IG_STATE_ANIMATION: IGGlblAnimation = TRUE; GMAnimGetAnimInfoText(&IGAnimation); GMAnimDoAnimation(&IGAnimation, IGGlblDisplayList); IGGlblAnimation = FALSE; break; case IG_STATE_CLIP_TESS_POLES: if (StateStatus == IG_STATE_TGL) IGGlblClipAtPoles = !IGGlblClipAtPoles; else IGGlblClipAtPoles = StateStatus == IG_STATE_ON; Cagd2PolyClipPolysAtPoles(IGGlblClipAtPoles); IGActiveListFreePolyIsoAttribute(IGGlblDisplayList, TRUE, TRUE, FALSE, FALSE); break; default: UpdateView = FALSE; break; } return UpdateView; } /***************************************************************************** * DESCRIPTION: M * Delete one object PObj from the global display list. M * * * PARAMETERS: M * PObj: Object to delete. M * * * RETURN VALUE: M * int: TRUE if found and deleted, FALSE otherwise. M * * * KEYWORDS: M * IGDeleteOneObject M *****************************************************************************/ int IGDeleteOneObject(IPObjectStruct *PObj) { IPObjectStruct *PTmp = IGGlblDisplayList, *PPrev = NULL; for ( ; PTmp != NULL; PPrev = PTmp, PTmp = PTmp -> Pnext) { if (PObj == PTmp) { if (PPrev == NULL) { /* It is the first object in the list. */ IGGlblDisplayList = IGGlblDisplayList -> Pnext; } else { PPrev -> Pnext = PTmp -> Pnext; } UpdateAllActiveWidgets(PTmp, FALSE); GMBBSetGlblBBObjList(IGGlblDisplayList); IPFreeObject(PTmp); return TRUE; } else if (IGDeleteOneObjectAux(PObj, PTmp)) { if (IP_IS_OLST_OBJ(PTmp) && IPListObjectLength(PTmp) == 0) IGDeleteOneObject(PTmp); return TRUE; } } return FALSE; /* Not found. */ } /***************************************************************************** * DESCRIPTION: * * Auxiliary function to delete object PObj from the global display list. * *****************************************************************************/ static int IGDeleteOneObjectAux(IPObjectStruct *PObj, IPObjectStruct *PLst) { if (IP_IS_OLST_OBJ(PLst)) { IPObjectStruct *PTmp; int i = 0; /* Search in its list. */ while ((PTmp = IPListObjectGet(PLst, i)) != NULL) { if (PTmp == PObj) { IPListObjectDelete(PLst, i, TRUE); if (IPListObjectLength(PLst) == 0) IGDeleteOneObject(PLst); UpdateAllActiveWidgets(PTmp, FALSE); return TRUE; } else if (IP_IS_OLST_OBJ(PTmp) && IGDeleteOneObjectAux(PObj, PTmp)) return TRUE; i++; } } return FALSE; } /***************************************************************************** * DESCRIPTION: * * Every time the global display list is modified async. (via an input * * stream message), we must deactivate all active widgets. * * * * PARAMETERS: * * PObj: Object that is to be added/removed, or NULL for complete cleanup. * * Added: If TRUE object has been added, FALSE for removal. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void UpdateAllActiveWidgets(IPObjectStruct *PObj, int Added) { if (PObj == NULL || (!Added && PObj == IGCrvEditCurrentObj)) CEditDetachCurve(); if (PObj == NULL || (!Added && PObj == IGSrfEditCurrentObj)) SEditDetachSurface(); if (IGObjManipNumActiveObjs > 0) { int i; if (PObj == NULL) IGObjManipDetachObj(); else { for (i = 0; i < IGObjManipNumActiveObjs; i++) { if (PObj == IGObjManipCurrentObjs[i]) { IGObjManipDetachObj(); break; } } } } } /***************************************************************************** * DESCRIPTION: M * Updates the global view matrix IPViewMat with given matrix Mat M * while preserving the scaling factor in the original global view. M * * * PARAMETERS: M * Mat: N.S.F.I. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGUpdateViewConsideringScale M *****************************************************************************/ void IGUpdateViewConsideringScale(MatrixType Mat) { int i, j; RealType Scale = MatScaleFactorMatrix(IPViewMat) / MatScaleFactorMatrix(Mat); MatrixType TmpMat; MatGenMatUnifScale(Scale, TmpMat); MatMultTwo4by4(Mat, Mat, TmpMat); /* Copy the 3 by 3 block of rotation/scale, leaving translation intact. */ for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) IPViewMat[i][j] = Mat[i][j]; } /***************************************************************************** * DESCRIPTION: M * Traverses the object's hierarchy for display purposes. M * * PARAMETERS: M * PObjList: To traverse and apply. M * CrntViewMat: Viewing matrix. M * ApplyFunc: To invoke on each and every leaf object. M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IPTraverseObjListHierarchy M * * * KEYWORDS: M * IGTraverseObjListHierarchy M *****************************************************************************/ void IGTraverseObjListHierarchy(IPObjectStruct *PObjList, MatrixType CrntViewMat, IPApplyObjFuncType ApplyFunc) { IPTraverseObjListHierarchy(PObjList, CrntViewMat, ApplyFunc); if (IGCrvEditActive) CEditRedrawCrv(); if (IGSrfEditActive) SEditRedrawSrf(); } /***************************************************************************** * DESCRIPTION: M * Handles a predefined animation of the '-X' flag. Will activate the M * animation only on the first time it is called.. M * * * PARAMETERS: M * None M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGPredefinedAnimation M *****************************************************************************/ void IGPredefinedAnimation(void) { if (IGGlblExecAnimation != NULL && strlen(IGGlblExecAnimation) > 0) { int i, j; float Min, Max, Dt, NumRep; char *Flags = NULL, *Params = IGGlblExecAnimation; IGGlblExecAnimation = NULL; IGAnimation.SaveAnimationGeom = IGAnimation.SaveAnimationImage = IGAnimation.BackToOrigin = IGAnimation.TwoWaysAnimation = FALSE; for (i = j = 0; i < (int) strlen(Params); i++) { if (Params[i] == ',') j++; if (j == 4) { /* We have optional flags. */ Params[i] = 0; Flags = &Params[i + 1]; break; } } if (sscanf(Params, "%f,%f,%f,%f", &Min, &Max, &Dt, &NumRep) == 4) { IGAnimation.StartT = Min; IGAnimation.FinalT = Max; IGAnimation.Dt = Dt; IGAnimation.NumOfRepeat = (int) NumRep; if (Flags != NULL) { if (strchr(Flags, 's') != NULL || strchr(Flags, 'S') != NULL) IGAnimation.SaveAnimationGeom = TRUE; if (strchr(Flags, 't') != NULL || strchr(Flags, 'T') != NULL) IGAnimation.TwoWaysAnimation = TRUE; if (strchr(Flags, 'b') != NULL || strchr(Flags, 'B') != NULL) IGAnimation.BackToOrigin = TRUE; } GMAnimDoAnimation(&IGAnimation, IGGlblDisplayList); if (Flags != NULL && (strchr(Flags, 'x') != NULL || strchr(Flags, 'X') != NULL) && !IGGlblActiveXMode) exit(0); } } } /***************************************************************************** * DESCRIPTION: * * Find the minimal distance in PObj to the line defined by LinePos and * * LineDir. * * * * PARAMETERS: * * PObj: List of objects to search for a minimal distance. * * MinPl: Poly with the minimal distance in PObj. * * MinPt: Closest point on the picked object. * * MinPlIsPolyline: TRUE if MinPl is a polyline, FALSE if a polygon. * * LinePos: A point on the line to test against. * * LineDir: The direction of the line. * * HitDepth: In case of zero distance (the ray hits a polygon, update * * the closest depth. * * * * RETURN VALUE: * * RealType: The minimal distance found to the line. * *****************************************************************************/ static RealType IGFindMinimalDist(IPObjectStruct *PObj, IPPolygonStruct **MinPl, PointType MinPt, int *MinPlIsPolyline, PointType LinePos, VectorType LineDir, RealType *HitDepth) { RealType d1, d2, IndexFrac, Dist = IRIT_INFNTY; IPObjectStruct *PObjTmp; *MinPlIsPolyline = TRUE; *MinPl = NULL; *HitDepth = IRIT_INFNTY; if (!IP_HAS_BBOX_OBJ(PObj)) return IRIT_INFNTY; if (UserMinDistLineBBox(LinePos, LineDir, PObj -> BBox) < IGGlblMinPickDist) { PointType Pt; CagdRType *R; switch (PObj -> ObjType) { case IP_OBJ_POINT: case IP_OBJ_VECTOR: case IP_OBJ_CTLPT: switch (PObj -> ObjType) { case IP_OBJ_POINT: PT_COPY(Pt, PObj -> U.Pt); break; case IP_OBJ_VECTOR: PT_COPY(Pt, PObj -> U.Vec); break; case IP_OBJ_CTLPT: R = PObj -> U.CtlPt.Coords; CagdCoercePointTo(Pt, CAGD_PT_E3_TYPE, (CagdRType **) &R, -1, PObj -> U.CtlPt.PtType); break; default: break; } Dist = GMDistPointLine(Pt, LinePos, LineDir); break; case IP_OBJ_POLY: if (IGGlblDrawStyle == IG_STATE_DRAW_STYLE_SOLID) Dist = UserMinDistLinePolygonList(LinePos, LineDir, PObj -> U.Pl, MinPl, MinPt, HitDepth, &IndexFrac); else if (IGGlblDrawStyle == IG_STATE_DRAW_STYLE_WIREFRAME || IGGlblDrawStyle == IG_STATE_DRAW_STYLE_POINTS) Dist = UserMinDistLinePolylineList(LinePos, LineDir, PObj -> U.Pl, TRUE, MinPl, MinPt, &IndexFrac); *MinPlIsPolyline = IP_IS_POLYLINE_OBJ(PObj); break; case IP_OBJ_CURVE: if ((PObjTmp = AttrGetObjectObjAttrib(PObj, "_IsolinesHiRes")) != NULL) { Dist = UserMinDistLinePolylineList(LinePos, LineDir, PObjTmp -> U.Pl, FALSE, MinPl, MinPt, &IndexFrac); *MinPlIsPolyline = TRUE; } break; case IP_OBJ_SURFACE: case IP_OBJ_TRIMSRF: case IP_OBJ_TRIVAR: case IP_OBJ_TRISRF: case IP_OBJ_MODEL: d1 = d2 = IRIT_INFNTY; if (IGGlblDrawSurfacePoly && (PObjTmp = AttrGetObjectObjAttrib(PObj, "_PolygonsHiRes")) != NULL) { if (IGGlblDrawStyle == IG_STATE_DRAW_STYLE_SOLID) d1 = UserMinDistLinePolygonList(LinePos, LineDir, PObjTmp -> U.Pl, MinPl, MinPt, HitDepth, &IndexFrac); else if (IGGlblDrawStyle == IG_STATE_DRAW_STYLE_WIREFRAME || IGGlblDrawStyle == IG_STATE_DRAW_STYLE_POINTS) d1 = UserMinDistLinePolylineList(LinePos, LineDir, PObjTmp -> U.Pl, TRUE, MinPl, MinPt, &IndexFrac); *MinPlIsPolyline = IP_IS_POLYLINE_OBJ(PObjTmp); } if (IGGlblDrawSurfaceWire && (PObjTmp = AttrGetObjectObjAttrib(PObj, "_IsolinesHiRes")) != NULL) { d2 = UserMinDistLinePolylineList(LinePos, LineDir, PObjTmp -> U.Pl, FALSE, MinPl, MinPt, &IndexFrac); *MinPlIsPolyline = TRUE; } Dist = MIN(d1, d2); break; case IP_OBJ_MULTIVAR: if ((PObjTmp = AttrGetObjectObjAttrib(PObj, "_Coerced")) != NULL) { /* Is a curve/surface/trivar - look at the coerced ver. */ return IGFindMinimalDist(PObjTmp, MinPl, MinPt, MinPlIsPolyline, LinePos, LineDir, HitDepth); } default: break; } } return Dist; } /***************************************************************************** * DESCRIPTION: M * Search for an object named Name in the global display list and return M * it if found. M * * * PARAMETERS: M * Name: of object to look for, M * * * RETURN VALUE: M * IPObjectStruct *: Found object, NULL of none. M * * * KEYWORDS: M * IGFindObjectByName M *****************************************************************************/ IPObjectStruct *IGFindObjectByName(char *Name) { MatrixType Mat; MatGenUnitMat(Mat); GlblObjectFoundByName = NULL; GlblObjectSearchName = Name; IPTraverseObjListHierarchy(IGGlblDisplayList, Mat, IGFindObjectByNameAux); return GlblObjectFoundByName; } /***************************************************************************** * DESCRIPTION: * * Call back function of the IGFindObjectByName above. * * * * PARAMETERS: * * PObj: Object to search its name. * * Mat: Viewing matrix of object. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void IGFindObjectByNameAux(IPObjectStruct *PObj, MatrixType Mat) { if (stricmp(PObj -> ObjName, GlblObjectSearchName) == 0) GlblObjectFoundByName = PObj; } /***************************************************************************** * DESCRIPTION: M * Generates a sketch like drawing of the surface on the fly if needed M * and display it. M * * * PARAMETERS: M * PObj: A surface(s) object. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGDrawPolygonSketches M *****************************************************************************/ void IGDrawPolygonSketches(IPObjectStruct *PObj) { IPObjectStruct *PObjSketches; if ((PObjSketches = AttrGetObjectObjAttrib(PObj, "_sketches")) == NULL) { PObjSketches = IGGenPolygonSketches(PObj, 1.0); if (IGGlblCacheGeom) AttrSetObjectObjAttrib(PObj, "_sketches", PObjSketches, FALSE); } IGSketchDrawPolygons(PObjSketches); if (!IGGlblCacheGeom) IPFreeObject(PObjSketches); } /***************************************************************************** * DESCRIPTION: M * Generates a sketch like drawing for the given object with the prescribed M * fineness. M * * * PARAMETERS: M * PObj: A surface(s) object. M * FineNess: Relative fineness to approximate PObj with. M * * * RETURN VALUE: M * IPObjectStruct *: The sketch data. M * * * KEYWORDS: M * IGGenPolygonSketches M *****************************************************************************/ IPObjectStruct *IGGenPolygonSketches(IPObjectStruct *PObj, RealType FineNess) { RealType RelativeFineNess = AttrGetObjectRealAttrib(PObj, "res_sketch"); IPObjectStruct *PPtsObj1, *PPtsObj2, *PPtsObj; if (IP_ATTR_IS_BAD_REAL(RelativeFineNess)) RelativeFineNess = 1.0; PPtsObj1 = IGSketchGenPolySketches(PObj, RelativeFineNess * FineNess, FALSE); if (PPtsObj1 -> U.Pl -> PVertex != NULL) { PPtsObj1 -> Attr = IP_ATTR_COPY_ATTRS(PObj -> Attr); AttrSetObjectPtrAttrib(PPtsObj1, "_SphCones", GMSphConeQueryInit(PPtsObj1)); } PPtsObj2 = IGSketchGenPolyImportanceSketches(PObj, &IGSketchParam, FineNess); PPtsObj = IPGenLISTObject(PPtsObj1); IPListObjectInsert(PPtsObj, 1, PPtsObj2); IPListObjectInsert(PPtsObj, 2, NULL); return PPtsObj; } /***************************************************************************** * DESCRIPTION: M * Draw the boundary and silhouette edges of a polygonal object. M * * * PARAMETERS: M * PObj: A polygonal object. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGDrawPolySilhBndry M *****************************************************************************/ void IGDrawPolySilhBndry(IPObjectStruct *PObj) { if (IGGlblDrawSurfaceBndry) { IPObjectStruct *PObjBndry; if ((PObjBndry = AttrGetObjectObjAttrib(PObj, "_bndry")) == NULL) { GMVrtxListToCircOrLin(PObj -> U.Pl, TRUE); BoolGenAdjacencies(PObj); PObjBndry = GMSilExtractBndry(PObj); GMVrtxListToCircOrLin(PObj -> U.Pl, FALSE); if (IGGlblCacheGeom) AttrSetObjectObjAttrib(PObj, "_bndry", PObjBndry, FALSE); } IGDrawPoly(PObjBndry); if (!IGGlblCacheGeom) IPFreeObject(PObjBndry); } if (IGGlblDrawSurfaceSilh) { VoidPtr PrepSils; IPObjectStruct *PObjSilh; if ((PrepSils = AttrGetObjectPtrAttrib(PObj, "_silh")) == NULL) { GMVrtxListToCircOrLin(PObj -> U.Pl, TRUE); BoolGenAdjacencies(PObj); PrepSils = GMSilPreprocessPolys(PObj, SILH_GRID_SIZE); GMVrtxListToCircOrLin(PObj -> U.Pl, FALSE); /* The following is actually a memory leak as when this Pobj is */ /* freed this pointer will not be released!. */ if (IGGlblCacheGeom) AttrSetObjectPtrAttrib(PObj, "_silh", PrepSils); } PObjSilh = GMSilExtractSil(PrepSils, IGGlblCrntViewMat); IGDrawPoly(PObjSilh); IPFreeObject(PObjSilh); if (!IGGlblCacheGeom) GMSilProprocessFree(PrepSils); } } /***************************************************************************** * DESCRIPTION: M * Get the proper isoparametric curve approximation of the object. M * * * PARAMETERS: M * PObj: To get the iso curves' approximation M * * * RETURN VALUE: M * IPObjectStruct *: The iso curve's approximation. M * * * KEYWORDS: M * IGGetObjIsoLines M *****************************************************************************/ IPObjectStruct *IGGetObjIsoLines(IPObjectStruct *PObj) { IPObjectStruct *PObjPolylines; if (IGGlblManipulationActive) { if ((PObjPolylines = AttrGetObjectObjAttrib(PObj, "_IsolinesLoRes")) == NULL) PObjPolylines = (IPObjectStruct *) AttrGetObjectPtrAttrib(PObj, "_IsolinesLoRes"); } else PObjPolylines = AttrGetObjectObjAttrib(PObj, "_IsolinesHiRes"); return PObjPolylines; } /***************************************************************************** * DESCRIPTION: M * Get the proper polygonal approximation of the object. M * * * PARAMETERS: M * PObj: To get the polygonal approximation M * * * RETURN VALUE: M * IPObjectStruct *: The polygonal approximation. M * * * KEYWORDS: M * IGGetObjPolygons M *****************************************************************************/ IPObjectStruct *IGGetObjPolygons(IPObjectStruct *PObj) { IPObjectStruct *PObjPolygons; if (IGGlblManipulationActive) { if ((PObjPolygons = AttrGetObjectObjAttrib(PObj, "_PolygonsLoRes")) == NULL) PObjPolygons = (IPObjectStruct *) AttrGetObjectPtrAttrib(PObj, "_PolygonsLoRes"); } else PObjPolygons = AttrGetObjectObjAttrib(PObj, "_PolygonsHiRes"); return PObjPolygons; } /***************************************************************************** * DESCRIPTION: * * Unhighlight all objects currently displayed. * * * * PARAMETERS: * * None * * * * RETURN VALUE: * * void * *****************************************************************************/ static void UnhighObjects(void) { MatrixType Mat; MatGenUnitMat(Mat); IPTraverseObjListHierarchy(IGGlblDisplayList, Mat, UnhighObjectsAux); } /***************************************************************************** * DESCRIPTION: * * Call back function of the UnhighObjectByName above. * * * * PARAMETERS: * * PObj: Object to unhighlight. * * Mat: Viewing matrix of object. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void UnhighObjectsAux(IPObjectStruct *PObj, MatrixType Mat) { IG_RST_HIGHLIGHT1_OBJ(PObj); IG_RST_HIGHLIGHT2_OBJ(PObj); } /***************************************************************************** * DESCRIPTION: M * Release the currently picked object if has one. M * * * PARAMETERS: M * None M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IGHandleGenericPickEvent M * * * KEYWORDS: M * IGReleasePickedObject M *****************************************************************************/ void IGReleasePickedObject(void) { if (IGGlblPickedObj) IG_RST_HIGHLIGHT1_OBJ(IGGlblPickedObj); if (IGGlblPickedPolyObj) { IPFreeObject(IGGlblPickedPolyObj); IGGlblPickedPolyObj = NULL; } GlblThisPickObjTypes = IG_PICK_ANY; IGGlblPickedObj = NULL; GlblPickedPoly = NULL; } /***************************************************************************** * DESCRIPTION: M * Reports to the server on a pick event of the cursor/mouse. M * The reported object is a list object of a point and a vector defining the M * cursor line in 3-space. The event type is returned as an "EventType" M * attribute on the reported object. M * * * PARAMETERS: M * ObjectX, ObjectY: Location of the cursor, in object space. M * PickReport: Type of event: motion, button down, etc. M * * * RETURN VALUE: M * void M * * * SEE ALSO: M * IGHandleGenericPickEvent M * * * KEYWORDS: M * IGHandleGenericCursorEvent M *****************************************************************************/ void IGHandleGenericCursorEvent(RealType ObjectX, RealType ObjectY, IGPickReportType PickReport) { STATIC_DATA RealType LastX = IRIT_INFNTY, LastY = IRIT_INFNTY; VectorType V; PointType Pos, Pt1, Pt2; IPObjectStruct *PObj; # ifdef __WINNT__ { static int LastCursorEventTime = 0; if (GetTickCount() - LastCursorEventTime < 100) return; /* No more than 10 events per second. */ LastCursorEventTime = GetTickCount(); } # endif /* __WINNT__ */ if (PickReport == IG_PICK_REP_MOTION && APX_EQ(LastX, ObjectX) && APX_EQ(LastY, ObjectY)) return; LastX = ObjectX; LastY = ObjectY; /* Converts picked location to a line defined via a point and vector. */ Pos[0] = ObjectX; Pos[1] = ObjectY; Pos[2] = 0.0; MatMultPtby4by4(Pt1, Pos, IGGlblInvCrntViewMat); Pos[2] = 1.0; MatMultPtby4by4(Pt2, Pos, IGGlblInvCrntViewMat); PT_SUB(V, Pt2, Pt1); /* Picked location is now defined in Pt1 (pt on line) and V (dir). */ PObj = IPAllocObject("_PickCrsr_", IP_OBJ_LIST_OBJ, NULL); IPListObjectInsert(PObj, 0, IPGenPTObject(&Pt1[0], &Pt1[1], &Pt1[2])); IPListObjectInsert(PObj, 1, IPGenVECObject(&V[0], &V[1], &V[2])); IPListObjectInsert(PObj, 2, NULL); AttrSetObjectIntAttrib(PObj, "EventType", PickReport); IPSocWriteOneObject(IGGlblIOHandle, PObj); IPFreeObject(PObj); } /***************************************************************************** * DESCRIPTION: M * Handle pick events. M * * * PARAMETERS: M * ObjectX, ObjectY: Objects XY coordinates into the screen of pick event. M * PickTypes: Types of object to pick or IG_PICK_ANY for any object. M * * * RETURN VALUE: M * IPObjectStruct *: Picked object or NULL if none. M * * * SEE ALSO: M * IGPickReportCursor, IGReleasePickedObject M * * * KEYWORDS: M * IGHandleGenericPickEvent M *****************************************************************************/ IPObjectStruct *IGHandleGenericPickEvent(RealType ObjectX, RealType ObjectY, int PickTypes) { IGGlblPickPos[0] = ObjectX; IGGlblPickPos[1] = ObjectY; IGGlblPickPos[2] = 0.0; IGGlblMinFoundDist = IGGlblMinPickDist; GlblMinFoundDepth = -IRIT_INFNTY; if (IGGlblPickedObj) IG_RST_HIGHLIGHT1_OBJ(IGGlblPickedObj); if (IGGlblPickedPolyObj) { IPFreeObject(IGGlblPickedPolyObj); IGGlblPickedPolyObj = NULL; } GlblThisPickObjTypes = PickTypes; IGGlblPickedObj = NULL; GlblPickedPoly = NULL; GlblPickScale = MatScaleFactorMatrix(IGGlblCrntViewMat); IGTraverseObjListHierarchy(IGGlblDisplayList, IGGlblCrntViewMat, PickObject); if (GlblPickedPoly != NULL) IGHighlightSavePickedPoly(GlblPickedPoly, GlblPickedPolyIsPolyline); #ifdef DEBUG { IRIT_SET_IF_DEBUG_ON_PARAMETER(_DebugPickEvent, FALSE) { char Line[LINE_LEN_LONG]; sprintf(Line, "Pick event attempted at %f %f, Found Object \"%s\" (Dist %f)\n", ObjectX, ObjectY, IGGlblPickedObj ? IGGlblPickedObj -> ObjName : "NULL", IGGlblMinFoundDist); IGIritError(Line); } } #endif /* DEBUG */ if (IGGlblPickedObj) { IG_SET_HIGHLIGHT1_OBJ(IGGlblPickedObj); IGRedrawViewWindow(); } return IGGlblPickedObj; } /***************************************************************************** * DESCRIPTION: M * Sets the object types that can be picked. The object types are or'ed M * together to form the mask of pickable objects. M * * * PARAMETERS: M * PickObjTypes: Object types that can be picked. M * * * RETURN VALUE: M * int: Old mask of possible pockable objects. M * * * SEE ALSO: M * IGHandleGenericPickEvent M * * * KEYWORDS: M * IGSetPickObjectType M *****************************************************************************/ int IGSetPickObjectType(int PickObjTypes) { int OldPickObjTypes = PickObjTypes; IGGlblPickObjTypes = PickObjTypes; return OldPickObjTypes; } /***************************************************************************** * DESCRIPTION: * * Call back function of the IGHandleGenericPickEvent above. * * * * PARAMETERS: * * PObj: Object to scan for picking. * * Mat: Viewing matrix of object. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void PickObject(IPObjectStruct *PObj, MatrixType Mat) { int MinPlIsPolyline; RealType MinDist, HitDepth; MatrixType InvMat; VectorType RayDir, Dir; PointType Pt1, Pt2, MinPt; IPPolygonStruct *MinPl; /* Check if object is pickable as set by the "pickable object" widget. */ if (((1 << PObj -> ObjType) & IGGlblPickObjTypes) == 0) return; /* Check if this object is pickable by this specific pick request. */ if (((1 << PObj -> ObjType) & GlblThisPickObjTypes) == 0) return; if (!MatInverseMatrix(Mat, InvMat)) return; IGGlblPickPos[2] = 0.0; MatMultPtby4by4(Pt1, IGGlblPickPos, InvMat); IGGlblPickPos[2] = 1.0; MatMultPtby4by4(Pt2, IGGlblPickPos, InvMat); PT_SUB(RayDir, Pt2, Pt1); #ifdef DEBUG { IRIT_SET_IF_DEBUG_ON_PARAMETER(_DebugDrawPickEvent, FALSE) { IPVertexStruct *V2 = IPAllocVertex2(NULL), *V1 = IPAllocVertex2(V2); IPPolygonStruct *Pl = IPAllocPolygon(0, V1, NULL); IPObjectStruct *PObj = IPGenPOLYObject(Pl); PT_COPY(V1 -> Coord, Pt1); PT_COPY(V2 -> Coord, Pt2); IP_SET_POLYLINE_OBJ(PObj); LIST_PUSH(PObj, IGGlblDisplayList); } } #endif /* DEBUG */ /* Take care of special type objects. */ if (IP_IS_STR_OBJ(PObj) && (PObj = AttrGetObjectObjAttrib(PObj, "_geometry")) == NULL) return; /* Find out the closest object in the display list to the picked line. */ MinDist = GlblPickScale * IGFindMinimalDist(PObj, &MinPl, MinPt, &MinPlIsPolyline, Pt1, RayDir, &HitDepth); VEC_COPY(Dir, RayDir); VEC_SCALE(Dir, HitDepth); PT_ADD(Pt1, Pt1, Dir); MatMultPtby4by4(Pt2, Pt1, Mat); if (IGGlblMinFoundDist > MinDist || (APX_EQ(IGGlblMinFoundDist, MinDist) && GlblMinFoundDepth < Pt2[2])) { IGGlblPickedObj = PObj; GlblPickedPoly = MinPl; GlblPickedPolyIsPolyline = MinPlIsPolyline; IGGlblMinFoundDist = MinDist; GlblMinFoundDepth = HitDepth; PT_COPY(IGGlblPickPosE3, MinPt); } } /***************************************************************************** * DESCRIPTION: M * Synthesize the string to present as the title of the window. M * * * PARAMETERS: M * Msg: A string to embed in the header. M * * * RETURN VALUE: M * char *: Created window header. M * * * SEE ALSO: M * IGStrResGenericPickEvent M * * * KEYWORDS: M * IGGenerateWindowHeaderString M *****************************************************************************/ char *IGGenerateWindowHeaderString(char *Msg) { static char Str[LINE_LEN_LONG]; if (Msg == NULL) Msg = ""; if (GlblFirstLoadedFile != NULL) sprintf(Str, "Irit Display (%s)%s", GlblFirstLoadedFile, Msg); else sprintf(Str, "Irit Display%s", Msg); return Str; } /***************************************************************************** * DESCRIPTION: M * Creates a string that represents the result of the last pick operation. M * * * PARAMETERS: M * PObj: Picked object. M * * * RETURN VALUE: M * char *: The string result. M * * * SEE ALSO: M * IGHandleGenericPickEvent, IGGenerateWindowHeaderString M * * * KEYWORDS: M * IGStrResGenericPickEvent M *****************************************************************************/ char *IGStrResGenericPickEvent(IPObjectStruct *PObj) { static char Str[LINE_LEN_LONG]; if (PT_EQ_ZERO(IGGlblPickPosE3) || PObj == NULL) sprintf(Str, " :: Picked \"%s\"", PObj == NULL ? "nothing" : PObj -> ObjName); else sprintf(Str, " :: Picked \"%s\" [%.4lg, %.4lg, %.4lg]", PObj -> ObjName, IGGlblPickPosE3[0], IGGlblPickPosE3[1], IGGlblPickPosE3[2]); return Str; } /***************************************************************************** * DESCRIPTION: M * Converts screen coordinates (from a mouse, for example) to object space. M * * * PARAMETERS: M * ScreenX, ScreenY: Screen space coordinates. M * Pt: Object space coordinates - origin of ray. M * Dir: Object space coordinates - direction of ray. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGGenericScreenToObject M *****************************************************************************/ void IGGenericScreenToObject(RealType ScreenX, RealType ScreenY, PointType Pt, VectorType Dir) { PointType Pt1; Pt[0] = ScreenX; Pt[1] = ScreenY; Pt[2] = 0.0; MatMultPtby4by4(Pt1, Pt, IGGlblInvCrntViewMat); Pt[2] = 1.0; MatMultPtby4by4(Pt, Pt, IGGlblInvCrntViewMat); PT_SUB(Dir, Pt1, Pt); } /***************************************************************************** * DESCRIPTION: M * Update the current frame per second. M * * * PARAMETERS: M * None M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IGUpdateFPS M *****************************************************************************/ void IGUpdateFPS(void) { static int InitCounter = FALSE, FrameCount = 0; static RealType LastT = -1; RealType t; if (LastT < 0) LastT = IritCPUTime(FALSE); if (++FrameCount >= 10) { t = IritCPUTime(FALSE); if (LastT >= t) { IGGlblFramePerSec = 100.0; } else { IGGlblFramePerSec = 10.0 / ((t = IritCPUTime(FALSE)) - LastT); if (IGGlblFramePerSec > 100.0) IGGlblFramePerSec = 100.0; LastT = t; } FrameCount = 0; } } /***************************************************************************** * DESCRIPTION: M * Reads in a texture mapping image if object has "ptexture" attribute and M * set up the texture for further processing. M * * * PARAMETERS: M * PObj: Object to extract its texture mapping function if has one. M * * * RETURN VALUE: M * int: TRUE if object has texture mapping, FALSE otherwise. M * * * KEYWORDS: M * IGInitSrfTexture M *****************************************************************************/ int IGInitSrfTexture(IPObjectStruct *PObj) { int MaxX, MaxY, FlipXYImage = FALSE, HasXYZScale = FALSE; char TextureFName[LINE_LEN_LONG], *Texture = AttrGetObjectStrAttrib(PObj, "ptexture"); IrtImgPixelStruct *Image; RealType ScaleXYZ[3]; if (Texture == NULL) return FALSE; if ((Image = AttrGetObjectPtrAttrib(PObj, "_ImageTexture")) != NULL) return TRUE; if (!IrtImgParsePTextureString(Texture, TextureFName, ScaleXYZ, &FlipXYImage)) return FALSE; HasXYZScale = !APX_EQ(ScaleXYZ[2], IRIT_INFNTY); if ((Image = IrtImgReadImage2(TextureFName, &MaxX, &MaxY)) != NULL) { int Width = MaxX + 1, Height = MaxY + 1; if (FlipXYImage) { Image = IrtImgFlipXYImage(Image, MaxX, MaxY); SWAP(int, Width, Height); } AttrSetObjectPtrAttrib(PObj, "_ImageTexture", Image); AttrSetObjectIntAttrib(PObj, "_ImageWidth", Width); AttrSetObjectIntAttrib(PObj, "_ImageHeight", Height); AttrSetObjectRealAttrib(PObj, "_ImageScaleX", ScaleXYZ[0]); AttrSetObjectRealAttrib(PObj, "_ImageScaleY", ScaleXYZ[1]); if (IP_IS_POLY_OBJ(PObj) && IP_IS_POLYGON_OBJ(PObj)) GMGenUVValsForPolys(PObj, ScaleXYZ[0], ScaleXYZ[1], ScaleXYZ[2], HasXYZScale); return TRUE; } else { /* Remove the "ptexture" attribute so we would not try again... */ AttrFreeObjectAttribute(PObj, "ptexture"); return FALSE; } } /***************************************************************************** * DESCRIPTION: M * Traps Geom_lib errors right here. Call back function of geom_lib. M * * * PARAMETERS: M * ErrID: Error number in geom_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * GeomFatalError M *****************************************************************************/ void GeomFatalError(GeomFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = GeomDescribeError(ErrID); sprintf(Line, "GEOM_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Misc_lib errors right here. Call back function of misc_lib. M * * * PARAMETERS: M * ErrID: Error number in misc_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * MiscFatalError M *****************************************************************************/ void MiscFatalError(MiscFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = MiscDescribeError(ErrID); sprintf(Line, "MISC_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Cagd_lib errors right here. Call back function of cagd_lib. M * * * PARAMETERS: M * ErrID: Error number in cagd_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * CagdFatalError M *****************************************************************************/ void CagdFatalError(CagdFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = CagdDescribeError(ErrID); sprintf(Line, "CAGD_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Symb_lib errors right here. Call back function of symb_lib. M * * * PARAMETERS: M * ErrID: Error number in symb_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * SymbFatalError M *****************************************************************************/ void SymbFatalError(SymbFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = SymbDescribeError(ErrID); sprintf(Line, "SYMB_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Trim_lib errors right here. Call back function of trim_lib. M * * * PARAMETERS: M * ErrID: Error number in trim_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * TrimFatalError M *****************************************************************************/ void TrimFatalError(TrimFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = TrimDescribeError(ErrID); sprintf(Line, "TRIM_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Triv_lib errors right here. Call back function of triv_lib. M * * * PARAMETERS: M * ErrID: Error number in triv_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * TrivFatalError M *****************************************************************************/ void TrivFatalError(TrivFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = TrivDescribeError(ErrID); sprintf(Line, "TRIV_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Trng_lib errors right here. Call back function of trng_lib. M * * * PARAMETERS: M * ErrID: Error number in trng_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * TrngFatalError M *****************************************************************************/ void TrngFatalError(TrngFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = TrngDescribeError(ErrID); sprintf(Line, "TRNG_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps User_lib errors right here. Call back function of user_lib. M * * * PARAMETERS: M * ErrID: Error number in user_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * UserFatalError M *****************************************************************************/ void UserFatalError(UserFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = UserDescribeError(ErrID); sprintf(Line, "USER_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Traps Mvar_lib errors right here. Call back function of trng_lib. M * * * PARAMETERS: M * ErrID: Error number in trng_lib library. M * * * RETURN VALUE: M * void M * M * KEYWORDS: M * MvarFatalError M *****************************************************************************/ void MvarFatalError(MvarFatalErrorType ErrID) { char Line[LINE_LEN_LONG], *ErrorMsg = MvarDescribeError(ErrID); sprintf(Line, "MVAR_LIB fatal error: %s", ErrorMsg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } /***************************************************************************** * DESCRIPTION: M * Default trap for Irit parser errors. M * This function prints the provided error message and dies. M * * * PARAMETERS: M * Msg: Error message. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * IPFatalError, error handling M *****************************************************************************/ void IPFatalError(char *Msg) { char Line[LINE_LEN_LONG]; sprintf(Line, "IP fatal error: %s", Msg); IGIritError(Line); if (!IGGlblActiveXMode) exit(1); } #ifdef DEBUG /***************************************************************************** * DESCRIPTION: * * Auxiliary function of IGPrintGlblDisplayTree * * * * PARAMETERS: * * PLst: N.S.F.I. * * Sp: N.S.F.I. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void IGPrintGlblDisplayTreeAux(IPObjectStruct *PLst, char *Sp) { char Space[1000]; sprintf(Space, "%s ", Sp); if (IP_IS_OLST_OBJ(PLst)) { IPObjectStruct *PTmp; int i = 0; printf("%s[\n", Sp); /* Search in its list. */ while ((PTmp = IPListObjectGet(PLst, i++)) != NULL) { printf("%s\"%s\"\n", Space, PTmp -> ObjName); IGPrintGlblDisplayTreeAux(PTmp, Space); } printf("%s]\n", Sp); } } /***************************************************************************** * DESCRIPTION: * * Prints the global display list * * * * PARAMETERS: * * None * * * * RETURN VALUE: * * void * *****************************************************************************/ static void IGPrintGlblDisplayTree(void) { IPObjectStruct *PTmp = IGGlblDisplayList, *PPrev = NULL; for ( ; PTmp != NULL; PTmp = PTmp -> Pnext) { printf("\"%s\"\n", PTmp -> ObjName); IGPrintGlblDisplayTreeAux(PTmp, ""); } } /***************************************************************************** * DESCRIPTION: * * Dummy function to link at debugging time. * * * * PARAMETERS: * * * * RETURN VALUE: * * void * * * * KEYWORDS: * *****************************************************************************/ static void IGDummyLinkDebug(void) { IPDbg(); } #endif /* DEBUG */