/****************************************************************************** * Mdl_gen.c - generic routine to interface to different free from types. * ******************************************************************************* * (C) Gershon Elber, Technion, Israel Institute of Technology * ******************************************************************************* * Written by Alexander Bogdanov June 1997 * ******************************************************************************/ #include "irit_sm.h" #include "mdl_loc.h" #include "allocate.h" #include "geom_lib.h" #include "cagd_lib.h" #ifdef DEBUG #undef MdlTrimSegFree #undef MdlTrimSegFreeList #undef MdlTrimSegRefFree #undef MdlTrimSegRefFreeList #undef MdlLoopFree #undef MdlLoopFreeList #undef MdlTrimSrfFree #undef MdlTrimSrfFreeList #undef MdlModelFree #undef MdlModelFreeList #endif /* DEBUG */ /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Segments structure. M * * * PARAMETERS: M * MTSeg: A Trimming Segment to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSegFree, allocation M *****************************************************************************/ void MdlTrimSegFree(MdlTrimSegStruct *MTSeg) { CagdCrvFree(MTSeg -> UVCrvFirst); CagdCrvFree(MTSeg -> UVCrvSecond); CagdCrvFree(MTSeg -> EucCrv); IP_ATTR_FREE_ATTRS(MTSeg -> Attr); IritFree(MTSeg); } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Segments List structure. M * * * PARAMETERS: M * MTSegList: A Trimming Segment List to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSegFreeList, allocation M *****************************************************************************/ void MdlTrimSegFreeList(MdlTrimSegStruct *MTSegList) { MdlTrimSegStruct *SegTemp; while (MTSegList) { SegTemp = MTSegList -> Pnext; MdlTrimSegFree(MTSegList); MTSegList = SegTemp; } } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Segment Reference structure. M * * * PARAMETERS: M * MTSegRef: A Segments Reference to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSegRefFree, allocation M *****************************************************************************/ void MdlTrimSegRefFree(MdlTrimSegRefStruct *MTSegRef) { IP_ATTR_FREE_ATTRS(MTSegRef -> Attr); IritFree(MTSegRef); } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Segment Reference List structure. M * * * PARAMETERS: M * MTSegRefList: A list of loops to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSegRefFreeList, allocation M *****************************************************************************/ void MdlTrimSegRefFreeList(MdlTrimSegRefStruct *MTSegRefList) { MdlTrimSegRefStruct *SegRefTemp; while (MTSegRefList) { SegRefTemp = MTSegRefList -> Pnext; MdlTrimSegRefFree(MTSegRefList); MTSegRefList = SegRefTemp; } } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Loop structure. M * * * PARAMETERS: M * MdlLoop: A loop to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlLoopFree, allocation M *****************************************************************************/ void MdlLoopFree(MdlLoopStruct *MdlLoop) { MdlTrimSegRefFreeList(MdlLoop -> SegRefList); IP_ATTR_FREE_ATTRS(MdlLoop -> Attr); IritFree(MdlLoop); } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Loop List structure. M * * * PARAMETERS: M * MdlLoopList: A list of loops to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlLoopFreeList, allocation M *****************************************************************************/ void MdlLoopFreeList(MdlLoopStruct *MdlLoopList) { MdlLoopStruct *LoopTemp; while (MdlLoopList) { LoopTemp = MdlLoopList -> Pnext; MdlLoopFree(MdlLoopList); MdlLoopList = LoopTemp; } } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Surface structure. M * * * PARAMETERS: M * TrimSrf: A surface to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSrfFree, allocation M *****************************************************************************/ void MdlTrimSrfFree(MdlTrimSrfStruct *TrimSrf) { CagdSrfFree(TrimSrf -> Srf); MdlLoopFreeList(TrimSrf -> LoopList); IP_ATTR_FREE_ATTRS(TrimSrf -> Attr); IritFree(TrimSrf); } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model Trimming Surface List structure. M * * * PARAMETERS: M * MdlTrimSrfList: A list of trimming curve to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlTrimSrfFreeList, allocation M *****************************************************************************/ void MdlTrimSrfFreeList(MdlTrimSrfStruct *MdlTrimSrfList) { MdlTrimSrfStruct *TrimSrfTemp; while (MdlTrimSrfList) { TrimSrfTemp = MdlTrimSrfList -> Pnext; MdlTrimSrfFree(MdlTrimSrfList); MdlTrimSrfList = TrimSrfTemp; } } /***************************************************************************** * DESCRIPTION: M * Deallocates a Model structure. M * * * PARAMETERS: M * Model: A Model to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlModelFree, allocation M *****************************************************************************/ void MdlModelFree(MdlModelStruct *Model) { MdlTrimSrfFreeList(Model -> TrimSrfList); MdlTrimSegFreeList(Model -> TrimSegList); IP_ATTR_FREE_ATTRS(Model -> Attr); IritFree(Model); } /***************************************************************************** * DESCRIPTION: M * Deallocates a list of Model structures. M * * * PARAMETERS: M * Model: A list of trimmed surface to free. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlModelFreeList, allocation M *****************************************************************************/ void MdlModelFreeList(MdlModelStruct *Model) { MdlModelStruct *ModelTemp; while (Model) { ModelTemp = Model -> Pnext; MdlModelFree(Model); Model = ModelTemp; } } /***************************************************************************** * DESCRIPTION: M * Duplicates a trimming segments structure. M * The reference pointers to the (upto) two surfaces are replaced with the M * indices of the surfaces in TrimSrfList. M * * * PARAMETERS: M * MdlTrimSeg: A trimming segment to duplicate. M * TrimSrfList: The original trimmed surfaces. M * * * RETURN VALUE: M * MdlTrimSegStruct *: A trimming segment structure. M * * * KEYWORDS: M * MdlTrimSegCopy, allocation M *****************************************************************************/ MdlTrimSegStruct *MdlTrimSegCopy(MdlTrimSegStruct *MdlTrimSeg, MdlTrimSrfStruct *TrimSrfList) { MdlTrimSegStruct *NewMdlTrimSeg = (MdlTrimSegStruct *) IritMalloc(sizeof(MdlTrimSegStruct)); if (MdlTrimSeg -> SrfFirst) NewMdlTrimSeg -> SrfFirst = (MdlTrimSrfStruct *) MdlGetSrfIndex(MdlTrimSeg -> SrfFirst, TrimSrfList); else NewMdlTrimSeg -> SrfFirst = NULL; if (MdlTrimSeg -> SrfSecond) NewMdlTrimSeg -> SrfSecond = (MdlTrimSrfStruct *) MdlGetSrfIndex(MdlTrimSeg -> SrfSecond, TrimSrfList); else NewMdlTrimSeg -> SrfSecond = NULL; if (MdlTrimSeg -> UVCrvFirst) NewMdlTrimSeg -> UVCrvFirst = CagdCrvCopy(MdlTrimSeg -> UVCrvFirst); else NewMdlTrimSeg -> UVCrvFirst = NULL; if (MdlTrimSeg -> UVCrvSecond) NewMdlTrimSeg -> UVCrvSecond = CagdCrvCopy(MdlTrimSeg -> UVCrvSecond); else NewMdlTrimSeg -> UVCrvSecond = NULL; if (MdlTrimSeg -> EucCrv) NewMdlTrimSeg -> EucCrv = CagdCrvCopy(MdlTrimSeg -> EucCrv); else NewMdlTrimSeg -> EucCrv = NULL; NewMdlTrimSeg -> Pnext = NULL; NewMdlTrimSeg -> Attr = NULL; return NewMdlTrimSeg; } /***************************************************************************** * DESCRIPTION: M * Allocates and copies a list of trimming segment structures. M * The reference pointers to the (upto) two surfaces are replaced with the M * indices of the surfaces in TrimSrfList. M * * * PARAMETERS: M * MdlTrimSegList: To be copied. M * TrimSrfList: The original trimmed surfaces. M * * * RETURN VALUE: M * MdlTrimSegStruct *: A duplicated list of trimming segments. M * * * KEYWORDS: M * MdlTrimSegCopyList, copy M *****************************************************************************/ MdlTrimSegStruct *MdlTrimSegCopyList(MdlTrimSegStruct *MdlTrimSegList, MdlTrimSrfStruct *TrimSrfList) { MdlTrimSegStruct *MdlTrimSegTemp, *NewMdlTrimSegList; if (MdlTrimSegList == NULL) return NULL; MdlTrimSegTemp = NewMdlTrimSegList = MdlTrimSegCopy(MdlTrimSegList, TrimSrfList); MdlTrimSegList = MdlTrimSegList -> Pnext; while (MdlTrimSegList) { MdlTrimSegTemp -> Pnext = MdlTrimSegCopy(MdlTrimSegList, TrimSrfList); MdlTrimSegTemp = MdlTrimSegTemp -> Pnext; MdlTrimSegList = MdlTrimSegList -> Pnext; } return NewMdlTrimSegList; } /***************************************************************************** * DESCRIPTION: M * Duplicates a trimming segment reference structure. M * The reference pointer to the trimming segment is replaced with the M * index of trimming segment in TrimSegList. M * * * PARAMETERS: M * MTSegRefList: A trimming curve segment reference to duplicate. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlTrimSegRefStruct *: A trimming segment reference structure. M * * * KEYWORDS: M * MdlTrimSegRefCopy, allocation M *****************************************************************************/ MdlTrimSegRefStruct *MdlTrimSegRefCopy(MdlTrimSegRefStruct *MTSegRefList, MdlTrimSegStruct *TrimSegList) { MdlTrimSegRefStruct *NewMdlTrimSegRef = (MdlTrimSegRefStruct *) IritMalloc(sizeof(MdlTrimSegRefStruct)); NewMdlTrimSegRef -> TrimSeg = (MdlTrimSegStruct *) MdlGetLoopSegIndex(MTSegRefList, TrimSegList); NewMdlTrimSegRef -> Pnext = NULL; NewMdlTrimSegRef -> Reversed = MTSegRefList -> Reversed; NewMdlTrimSegRef -> Attr = NULL; return NewMdlTrimSegRef; } /***************************************************************************** * DESCRIPTION: M * Allocates and copies a list of trimming segment reference structures. M * The reference pointer to the trimming segment is replaced with the M * index of trimming segment in TrimSegList. M * * * PARAMETERS: M * MTSegRefList: To be copied. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlTrimSegRefStruct *: A duplicated list of trimming segments. M * * * KEYWORDS: M * MdlTrimSegRefCopyList, copy M *****************************************************************************/ MdlTrimSegRefStruct *MdlTrimSegRefCopyList(MdlTrimSegRefStruct *MTSegRefList, MdlTrimSegStruct *TrimSegList) { MdlTrimSegRefStruct *MTSegRefTemp, *NewMTSegRefList; if (MTSegRefList == NULL) return NULL; MTSegRefTemp = NewMTSegRefList = MdlTrimSegRefCopy(MTSegRefList, TrimSegList); MTSegRefList = MTSegRefList -> Pnext; while (MTSegRefList) { MTSegRefTemp -> Pnext = MdlTrimSegRefCopy(MTSegRefList, TrimSegList); MTSegRefTemp = MTSegRefTemp -> Pnext; MTSegRefList = MTSegRefList -> Pnext; } return NewMTSegRefList; } /***************************************************************************** * DESCRIPTION: M * Duplicates a trimming surface structure. M * * * PARAMETERS: M * MdlLoop: A trimming surface to duplicate. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlLoopStruct *: A trimming surface structure. M * * * KEYWORDS: M * MdlLoopCopy, allocation M *****************************************************************************/ MdlLoopStruct *MdlLoopCopy(MdlLoopStruct *MdlLoop, MdlTrimSegStruct *TrimSegList) { MdlLoopStruct *NewMdlLoop = (MdlLoopStruct *) IritMalloc(sizeof(MdlLoopStruct)); NewMdlLoop -> SegRefList = MdlTrimSegRefCopyList(MdlLoop -> SegRefList, TrimSegList); NewMdlLoop -> Pnext = NULL; NewMdlLoop -> Attr = NULL; return NewMdlLoop; } /***************************************************************************** * DESCRIPTION: M * Allocates and copies a list of Loops structures. M * * * PARAMETERS: M * MdlLoopList: To be copied. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlLoopStruct *: A duplicated list of Loops. M * * * KEYWORDS: M * MdlLoopCopyList, copy M *****************************************************************************/ MdlLoopStruct *MdlLoopCopyList(MdlLoopStruct *MdlLoopList, MdlTrimSegStruct *TrimSegList) { MdlLoopStruct *MdlLoopTemp, *NewMdlLoopList; if (MdlLoopList == NULL) return NULL; MdlLoopTemp = NewMdlLoopList = MdlLoopCopy(MdlLoopList, TrimSegList); MdlLoopList = MdlLoopList -> Pnext; while (MdlLoopList) { MdlLoopTemp -> Pnext = MdlLoopCopy(MdlLoopList, TrimSegList); MdlLoopTemp = MdlLoopTemp -> Pnext; MdlLoopList = MdlLoopList -> Pnext; } return NewMdlLoopList; } /***************************************************************************** * DESCRIPTION: M * Duplicates a trimming surface structure. M * * * PARAMETERS: M * MdlTrimSrf: A trimming surface to duplicate. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlTrimSrfStruct *: A trimming surface structure. M * * * KEYWORDS: M * MdlTrimSrfCopy, allocation M *****************************************************************************/ MdlTrimSrfStruct *MdlTrimSrfCopy(MdlTrimSrfStruct *MdlTrimSrf, MdlTrimSegStruct *TrimSegList) { MdlTrimSrfStruct *NewMdlTrimSrf = (MdlTrimSrfStruct *) IritMalloc(sizeof(MdlTrimSrfStruct)); NewMdlTrimSrf -> LoopList = MdlLoopCopyList(MdlTrimSrf -> LoopList, TrimSegList); NewMdlTrimSrf -> Srf = CagdSrfCopy(MdlTrimSrf -> Srf); NewMdlTrimSrf -> Pnext = NULL; NewMdlTrimSrf -> Attr = NULL; return NewMdlTrimSrf; } /***************************************************************************** * DESCRIPTION: M * Allocates and copies a list of trimming surface structures. M * * * PARAMETERS: M * MdlTrimSrfList: To be copied. M * TrimSegList: The original trimmed segments. M * * * RETURN VALUE: M * MdlTrimSrfStruct *: A duplicated list of trimming surfaces. M * * * KEYWORDS: M * MdlTrimSrfCopyList, copy M *****************************************************************************/ MdlTrimSrfStruct *MdlTrimSrfCopyList(MdlTrimSrfStruct *MdlTrimSrfList, MdlTrimSegStruct *TrimSegList) { MdlTrimSrfStruct *MdlTrimSrfTemp, *NewMdlTrimSrfList; if (MdlTrimSrfList == NULL) return NULL; MdlTrimSrfTemp = NewMdlTrimSrfList = MdlTrimSrfCopy(MdlTrimSrfList, TrimSegList); MdlTrimSrfList = MdlTrimSrfList -> Pnext; while (MdlTrimSrfList) { MdlTrimSrfTemp -> Pnext = MdlTrimSrfCopy(MdlTrimSrfList, TrimSegList); MdlTrimSrfTemp = MdlTrimSrfTemp -> Pnext; MdlTrimSrfList = MdlTrimSrfList -> Pnext; } return NewMdlTrimSrfList; } /***************************************************************************** * DESCRIPTION: M * Duplicates a Model structure. M * * * PARAMETERS: M * Model: A Model to duplicate. M * * * RETURN VALUE: M * MdlModelStruct *: A Model structure. M * * * KEYWORDS: M * MdlModelCopy, allocation M *****************************************************************************/ MdlModelStruct *MdlModelCopy(MdlModelStruct *Model) { MdlModelStruct *NewModel = (MdlModelStruct *) IritMalloc(sizeof(MdlModelStruct)); NewModel -> Pnext = NULL; NewModel -> TrimSrfList = MdlTrimSrfCopyList(Model -> TrimSrfList, Model -> TrimSegList); NewModel -> TrimSegList = MdlTrimSegCopyList(Model -> TrimSegList, Model -> TrimSrfList); NewModel -> Attr = NULL; MdlPatchTrimmingSegPointers(NewModel); return NewModel; } /***************************************************************************** * DESCRIPTION: M * Allocates and copies a list of Model structures. M * * * PARAMETERS: M * ModelList: To be copied. M * * * RETURN VALUE: M * MdlModelStruct *: A duplicated list of trimming surfaces. M * * * KEYWORDS: M * MdlModelCopyList, copy M *****************************************************************************/ MdlModelStruct *MdlModelCopyList(MdlModelStruct *ModelList) { MdlModelStruct *ModelTemp, *NewModelList; if (ModelList == NULL) return NULL; ModelTemp = NewModelList = MdlModelCopy(ModelList); ModelList = ModelList -> Pnext; while (ModelList) { ModelTemp -> Pnext = MdlModelCopy(ModelList); ModelTemp = ModelTemp -> Pnext; ModelList = ModelList -> Pnext; } return NewModelList; } /***************************************************************************** * DESCRIPTION: M * Allocates a model trimming segment structure. Allows periodic and float M * end conditions - converts them to open end. M * * * PARAMETERS: M * UVCrv1: A UV curve for SrfFirst. Must be an E2 curve. M * UVCrv2: A UV curve for SrfSecond. Must be an E2 curve. M * EucCrv1: Optional Euclidean curve for SrfFirst. Must be an E3 curve. M * SrfFirst: First surface of the segment. M * SrfSecond: Second surface of the segment. M * * * RETURN VALUE: M * MdlTrimSegStruct *: A model trimming segment structure. M * * * KEYWORDS: M * MdlTrimSegNew, allocation M *****************************************************************************/ MdlTrimSegStruct *MdlTrimSegNew(CagdCrvStruct *UVCrv1, CagdCrvStruct *UVCrv2, CagdCrvStruct *EucCrv1, MdlTrimSrfStruct *SrfFirst, MdlTrimSrfStruct *SrfSecond) { MdlTrimSegStruct *MdlTrimSeg = (MdlTrimSegStruct *) IritMalloc(sizeof(MdlTrimSegStruct)); if (UVCrv1 != NULL && CAGD_IS_BSPLINE_CRV(UVCrv1)) { if (!BspCrvHasOpenEC(UVCrv1)) { /* Must be open end trimming curve. */ CagdCrvStruct *TCrv; if (CAGD_IS_PERIODIC_CRV(UVCrv1)) { TCrv = CnvrtPeriodic2FloatCrv(UVCrv1); CagdCrvFree(UVCrv1); UVCrv1 = TCrv; } TCrv = CnvrtFloat2OpenCrv(UVCrv1); CagdCrvFree(UVCrv1); UVCrv1 = TCrv; } } if ((MdlTrimSeg -> UVCrvFirst = UVCrv1) != NULL) MdlTrimSeg -> UVCrvFirst -> Pnext = NULL; if (UVCrv2 != NULL && CAGD_IS_BSPLINE_CRV(UVCrv2)) { if (!BspCrvHasOpenEC(UVCrv2)) { /* Must be open end trimming curve. */ CagdCrvStruct *TCrv; if (CAGD_IS_PERIODIC_CRV(UVCrv2)) { TCrv = CnvrtPeriodic2FloatCrv(UVCrv2); CagdCrvFree(UVCrv2); UVCrv1 = TCrv; } TCrv = CnvrtFloat2OpenCrv(UVCrv2); CagdCrvFree(UVCrv2); UVCrv2 = TCrv; } } if ((MdlTrimSeg -> UVCrvSecond = UVCrv2) != NULL) MdlTrimSeg -> UVCrvSecond -> Pnext = NULL; if (EucCrv1 != NULL && CAGD_IS_BSPLINE_CRV(EucCrv1)) { if (!BspCrvHasOpenEC(EucCrv1)) {/* Must be open end trimming curve. */ CagdCrvStruct *TCrv; if (CAGD_IS_PERIODIC_CRV(EucCrv1)) { TCrv = CnvrtPeriodic2FloatCrv(EucCrv1); CagdCrvFree(EucCrv1); EucCrv1 = TCrv; } TCrv = CnvrtFloat2OpenCrv(EucCrv1); CagdCrvFree(EucCrv1); EucCrv1 = TCrv; } } if ((MdlTrimSeg -> EucCrv = EucCrv1) != NULL) MdlTrimSeg -> EucCrv -> Pnext = NULL; MdlTrimSeg -> Pnext = NULL; MdlTrimSeg -> SrfFirst = SrfFirst; MdlTrimSeg -> SrfSecond = SrfSecond; MdlTrimSeg -> Attr = NULL; return MdlTrimSeg; } /***************************************************************************** * DESCRIPTION: M * Allocates a model trimming segment reference structure. M * * * PARAMETERS: M * MdlTrimSeg: List of model trimming segments forming the trimming M * curve. M * * * RETURN VALUE: M * MdlTrimSegRefStruct *: A trimmig curve. M * * * KEYWORDS: M * MdlTrimSegRefNew, allocation M *****************************************************************************/ MdlTrimSegRefStruct *MdlTrimSegRefNew(MdlTrimSegStruct *MdlTrimSeg) { MdlTrimSegRefStruct *SegRef = (MdlTrimSegRefStruct *) IritMalloc(sizeof(MdlTrimSegRefStruct)); SegRef -> TrimSeg = MdlTrimSeg; SegRef -> Pnext = NULL; SegRef -> Reversed = FALSE; SegRef -> Attr = NULL; return SegRef; } /***************************************************************************** * DESCRIPTION: M * Allocates a model loop structure. M * * * PARAMETERS: M * MdlTrimSegRefList: List of model loops forming the trimming loop. M * * * RETURN VALUE: M * MdlLoopStruct *: A model loop. M * * * KEYWORDS: M * MdlLoopNew, allocation M *****************************************************************************/ MdlLoopStruct *MdlLoopNew(MdlTrimSegRefStruct *MdlTrimSegRefList) { MdlLoopStruct *Loop = (MdlLoopStruct *) IritMalloc(sizeof(MdlLoopStruct)); Loop -> SegRefList = MdlTrimSegRefList; Loop -> Pnext = NULL; Loop -> Attr = NULL; return Loop; } /***************************************************************************** * DESCRIPTION: M * Constructor for a model trimmed surface. M * * * PARAMETERS: M * Srf: Surface to make into a trimmed surface. M * LoopList: A list of loops. M * HasTopLvlTrim: Do we have a top level outer most trimming curve? M * * * RETURN VALUE: M * MdlTrimSrfStruct *: The trimmed surface. M * * * KEYWORDS: M * MdlTrimSrfNew, allocation, M *****************************************************************************/ MdlTrimSrfStruct *MdlTrimSrfNew(CagdSrfStruct *Srf, MdlLoopStruct *LoopList, CagdBType HasTopLvlTrim) { int i, j, k; CagdRType UMin, UMax, VMin, VMax; MdlTrimSegStruct *MdlTrimSeg; MdlTrimSegRefStruct *MdlTrimSegRef; MdlTrimSrfStruct *MdlTrimSrf = (MdlTrimSrfStruct *) IritMalloc(sizeof(MdlTrimSrfStruct)); CagdSrfDomain(Srf, &UMin, &UMax, &VMin, &VMax); MdlTrimSrf -> Pnext = NULL; MdlTrimSrf -> Attr = NULL; MdlTrimSrf -> Srf = Srf; if (! HasTopLvlTrim) { int MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType), ULen = Srf -> ULength, VLen = Srf -> VLength; CagdRType **UVPoints, **EucPoints, **SrfPoints = Srf -> Points; MdlLoopStruct *Loop; CagdCrvStruct *UVCrv1, *UVCrv2, *UVCrv3, *UVCrv4, *RevCrv, *EucCrv1, *EucCrv2, *EucCrv3, *EucCrv4; CagdBType IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf); UVCrv1 = BspCrvNew(2, 2, CAGD_PT_E2_TYPE); BspKnotUniformOpen(2, 2, UVCrv1 -> KnotVector); UVPoints = UVCrv1 -> Points; UVPoints[1][0] = UMin; UVPoints[2][0] = VMin; UVPoints[1][1] = UMin; UVPoints[2][1] = VMax; EucCrv1 = BspCrvNew(VLen, Srf -> VOrder, Srf -> PType); EucPoints = EucCrv1 -> Points; CAGD_GEN_COPY( EucCrv1 -> KnotVector, Srf -> VKnotVector, sizeof(CagdRType) * (CAGD_SRF_VPT_LST_LEN(Srf) + Srf -> VOrder)); for (i = IsNotRational; i <= MaxCoord; i++) for (j = 0, k = 0; k < VLen ; j += ULen, k++) EucPoints[i][k] = SrfPoints[i][j]; MdlTrimSeg = MdlTrimSegNew(UVCrv1, NULL, EucCrv1, MdlTrimSrf, NULL); MdlTrimSegRef = MdlTrimSegRefNew(MdlTrimSeg); Loop = MdlLoopNew(MdlTrimSegRef); UVCrv2 = BspCrvNew(2, 2, CAGD_PT_E2_TYPE); BspKnotUniformOpen(2, 2, UVCrv2 -> KnotVector); UVPoints = UVCrv2 -> Points; UVPoints[1][0] = UMin; UVPoints[2][0] = VMax; UVPoints[1][1] = UMax; UVPoints[2][1] = VMax; EucCrv2 = BspCrvNew(ULen, Srf -> UOrder, Srf -> PType); CAGD_GEN_COPY( EucCrv2 -> KnotVector, Srf -> UKnotVector, sizeof(CagdRType) * (CAGD_SRF_UPT_LST_LEN(Srf) + Srf -> UOrder)); EucPoints = EucCrv2 -> Points; for (i = IsNotRational; i <= MaxCoord; i++) for (j = 0; j < ULen ; j++) EucPoints[i][j] = Srf -> Points[i][j]; MdlTrimSeg -> Pnext = MdlTrimSegNew(UVCrv2, NULL, EucCrv2, MdlTrimSrf, NULL); MdlTrimSegRef -> Pnext = MdlTrimSegRefNew(MdlTrimSeg -> Pnext); UVCrv3 = BspCrvNew(2, 2, CAGD_PT_E2_TYPE); BspKnotUniformOpen(2, 2, UVCrv3 -> KnotVector); UVPoints = UVCrv3 -> Points; UVPoints[1][0] = UMax; UVPoints[2][0] = VMax; UVPoints[1][1] = UMax; UVPoints[2][1] = VMin; EucCrv3 = BspCrvNew(VLen, Srf -> VOrder, Srf -> PType); CAGD_GEN_COPY( EucCrv3 -> KnotVector, Srf -> VKnotVector, sizeof(CagdRType) * (CAGD_SRF_VPT_LST_LEN(Srf) + Srf -> VOrder)); EucPoints = EucCrv3 -> Points; for (i = IsNotRational; i <= MaxCoord; i++) for (j = ULen-1, k = 0; j < VLen * ULen; j += ULen, k++) EucPoints[i][k] = Srf -> Points[i][j]; RevCrv = CagdCrvReverse(EucCrv3); CagdCrvFree(EucCrv3); EucCrv3 = RevCrv; MdlTrimSeg -> Pnext -> Pnext = MdlTrimSegNew(UVCrv3, NULL, EucCrv3, MdlTrimSrf, NULL); MdlTrimSegRef -> Pnext -> Pnext = MdlTrimSegRefNew(MdlTrimSeg -> Pnext -> Pnext); UVCrv4 = BspCrvNew(2, 2, CAGD_PT_E2_TYPE); BspKnotUniformOpen(2, 2, UVCrv4 -> KnotVector); UVPoints = UVCrv4 -> Points; UVPoints[1][0] = UMax; UVPoints[2][0] = VMin; UVPoints[1][1] = UMin; UVPoints[2][1] = VMin; EucCrv4 = BspCrvNew(ULen, Srf -> UOrder, Srf -> PType); CAGD_GEN_COPY( EucCrv4 -> KnotVector, Srf -> UKnotVector, sizeof(CagdRType) * (CAGD_SRF_UPT_LST_LEN(Srf) + Srf -> UOrder)); EucPoints = EucCrv4 -> Points; for (i = IsNotRational; i <= MaxCoord; i++) for (j = ULen * (VLen - 1), k = 0; j < ULen * VLen ; j++, k++) EucPoints[i][k] = Srf -> Points[i][j]; RevCrv = CagdCrvReverse(EucCrv4); CagdCrvFree(EucCrv4); EucCrv4 = RevCrv; MdlTrimSeg -> Pnext -> Pnext -> Pnext = MdlTrimSegNew(UVCrv4, NULL, EucCrv4, MdlTrimSrf, NULL); MdlTrimSegRef -> Pnext -> Pnext -> Pnext = MdlTrimSegRefNew(MdlTrimSeg -> Pnext -> Pnext -> Pnext); MdlTrimSrf -> LoopList = Loop; } else MdlTrimSrf -> LoopList = LoopList; return MdlTrimSrf; } /***************************************************************************** * DESCRIPTION: M * Constructor for a model trimmed surface. M * * * PARAMETERS: M * Srf: The original surface to be trimmed. M * LoopList: A list of trimming loops. M * HasTopLvlTrim: If FALSE, add outer loops boundary. M * * * RETURN VALUE: M * MdlTrimSrfStruct *: The trimmed surface. M * * * KEYWORDS: M * MdlTrimSrfNew2, allocation M *****************************************************************************/ MdlTrimSrfStruct *MdlTrimSrfNew2(CagdSrfStruct *Srf, CagdCrvStruct *LoopList, CagdBType HasTopLvlTrim) { MdlLoopStruct *LoopList2 = NULL; MdlLoopStruct *Loop; CagdCrvStruct *LoopListNext; MdlTrimSrfStruct *MdlTrimSrf = (MdlTrimSrfStruct *) IritMalloc(sizeof(MdlTrimSrfStruct)); MdlTrimSrf -> Srf = Srf; while (LoopList) { LoopListNext = LoopList -> Pnext; Loop = MdlLoopNew(MdlTrimSegRefNew(MdlTrimSegNew(LoopList, NULL, NULL, MdlTrimSrf, NULL))); LoopList = LoopListNext; LIST_PUSH(Loop, LoopList2); } return MdlTrimSrfNew(Srf, LoopList2, HasTopLvlTrim); } /***************************************************************************** * DESCRIPTION: M * Constructor for a Model. M * * * PARAMETERS: M * Srf: The original surface to be trimmed. M * LoopList: A list of trimming loops M * HasTopLvlTrim: If FALSE, add outer loops boundary. M * * * RETURN VALUE: M * MdlModelStruct *: The Model. M * * * KEYWORDS: M * MdlModelNew, Allocation M *****************************************************************************/ MdlModelStruct *MdlModelNew(CagdSrfStruct *Srf, CagdCrvStruct *LoopList, CagdBType HasTopLvlTrim) { MdlModelStruct *MdlModel = (MdlModelStruct *) IritMalloc(sizeof(MdlModelStruct)); MdlModel -> TrimSrfList = MdlTrimSrfNew2(Srf, LoopList, HasTopLvlTrim); if (LoopList) MdlModel -> TrimSegList = MdlModel -> TrimSrfList -> LoopList -> SegRefList -> TrimSeg; else if (HasTopLvlTrim) MdlModel -> TrimSegList = NULL; else MdlModel -> TrimSegList = MdlModel -> TrimSrfList -> LoopList -> SegRefList -> TrimSeg; MdlModel -> Pnext = NULL; MdlModel -> Attr = NULL; return MdlModel; } /***************************************************************************** * DESCRIPTION: M * Constructor for a Model. No attempt is mode to verify the consistency M * of the given data and proper pointers between the different data strcutres.M * * * PARAMETERS: M * TrimSrfs: Trimming surfaces. M * TrimSegs: A list of trimming segments. M * * * RETURN VALUE: M * MdlModelStruct *: The construct Model. M * * * SEE ALSO: M * MdlModelNew, MdlPatchTrimmingSegPointers M * * * KEYWORDS: M * MdlModelNew2, Allocation M *****************************************************************************/ MdlModelStruct *MdlModelNew2(MdlTrimSrfStruct *TrimSrfs, MdlTrimSegStruct *TrimSegs) { MdlModelStruct *MdlModel = (MdlModelStruct *) IritMalloc(sizeof(MdlModelStruct)); MdlModel -> TrimSrfList = TrimSrfs; MdlModel -> TrimSegList = TrimSegs; MdlModel -> Pnext = NULL; MdlModel -> Attr = NULL; return MdlModel; } /***************************************************************************** * DESCRIPTION: M * Linearly transforms, in place, given model as specified by Translate and M * Scale. M * * * PARAMETERS: M * Model: Model to transform. M * Translate: Translation factor. M * Scale: Scaling factor. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlModelTransform, models M *****************************************************************************/ void MdlModelTransform(MdlModelStruct *Model, CagdRType *Translate, CagdRType Scale) { MdlTrimSrfStruct *TrimSrfList = Model -> TrimSrfList; MdlTrimSegStruct *TrimSegList = Model -> TrimSegList; /* Transform the geometry. */ for ( ; TrimSrfList != NULL; TrimSrfList = TrimSrfList -> Pnext) CagdSrfTransform(TrimSrfList -> Srf, Translate, Scale); /* And remove all Euclidean trimming curves. */ for ( ; TrimSegList != NULL; TrimSegList = TrimSegList -> Pnext) { if (TrimSegList -> EucCrv != NULL) { CagdCrvFree(TrimSegList -> EucCrv); TrimSegList -> EucCrv = NULL; } } } /***************************************************************************** * DESCRIPTION: M * Transforms, in place, the given model as specified by homogeneous matrix M * Mat. M * * * PARAMETERS: M * Model: Model to transform. M * Mat: Homogeneous transformation to apply to TV. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * MdlModelMatTransform, models M *****************************************************************************/ void MdlModelMatTransform(MdlModelStruct *Model, CagdMType Mat) { MdlTrimSrfStruct *TrimSrfList = Model -> TrimSrfList; MdlTrimSegStruct *TrimSegList = Model -> TrimSegList; /* Transform the geometry. */ for ( ; TrimSrfList != NULL; TrimSrfList = TrimSrfList -> Pnext) { CagdSrfStruct *TSrf = CagdSrfMatTransform(TrimSrfList -> Srf, Mat); CagdSrfFree(TrimSrfList -> Srf); TrimSrfList -> Srf = TSrf; } /* And remove all Euclidean trimming curves. */ for ( ; TrimSegList != NULL; TrimSegList = TrimSegList -> Pnext) { if (TrimSegList -> EucCrv != NULL) { CagdCrvFree(TrimSegList -> EucCrv); TrimSegList -> EucCrv = NULL; } } }