/***************************************************************************** * Function: GetSelectedText * *****************************************************************************/ static int GetSelectedText( _DtCanvasStruct *canvas, _DtCvSelectData next, _DtCvSelectData end, unsigned int mask, _DtCvPointer *ret_data) { _DtCvUnit maxY; _DtCvUnit botY; int i; int lineCnt = 0; int junk; int result = 0; int cpyCnt = 0; int txtCnt = canvas->txt_cnt; _DtCvFlags endFlag; _DtCvValue processing = True; _DtCvDspLine *lines = canvas->txt_lst; for (i = 0; i < txtCnt; i++) _DtCvClearProcessed(lines[i]); MarkLinesOutsideBoundary(canvas, next.y, next.x, end.y, end.x); maxY = next.y; if (next.line_idx == -1) { /* * find the first selected line */ if (FindNextMinY(lines, txtCnt, -1, &next.y) == False) return 0; next.x = 0; lineCnt = FindMinX(lines, txtCnt, next.y, &next.line_idx); next.char_idx = 0; } else lineCnt = FindMinX(lines, txtCnt, next.y, &junk); while (processing == True && result == 0) { /* * process the next line of text. */ do { endFlag = 0; cpyCnt = lines[next.line_idx].length - next.char_idx; if (next.line_idx == end.line_idx) cpyCnt = cpyCnt - lines[next.line_idx].length + end.char_idx; else if (lineCnt == 1) endFlag = _DtCvEND_OF_LINE; result = BuildLine(canvas, mask, maxY, next.x, next.line_idx, next.char_idx, cpyCnt, endFlag, &next.x, &botY, ret_data); if (botY > maxY) maxY = botY; next.char_idx = 0; lineCnt = FindMinX(lines, txtCnt, next.y, &next.line_idx); } while (result == 0 && lineCnt > 0); if (result == 0) { next.x = 0; processing = FindNextMinY(lines, txtCnt, -1, &next.y); if (processing == True) lineCnt = FindMinX(lines, txtCnt, next.y, &next.line_idx); } } return result; } /* End GetSelectedText */
/***************************************************************************** * Function: GetSegsInArea() * * Purpose: Retrieve the segments making up the selection. * *****************************************************************************/ static _DtCvStatus GetSegsInArea ( _DtCanvasStruct *canvas, _DtCvSelectData *beg, _DtCvSelectData *end, _DtCvSegPts ***ret_segs, _DtCvUnit *ret_y1, _DtCvUnit *ret_y2) { int cnt; int count; int start; int length; int lineCnt; int result = 0; _DtCvValue processing = True; _DtCvUnit minY; _DtCvUnit maxY; _DtCvUnit botY; _DtCvSelectData next; _DtCvSegPts *newPt; _DtCvSegmentI *pSeg; _DtCvDspLine *lines = canvas->txt_lst; *ret_segs = NULL; if (beg->x == -1) return _DtCvSTATUS_NONE; /* * make sure the selection points are in the correct order. */ CheckAndSwitchPoints(beg, end); /* * clear the processed bit */ for (cnt = 0; cnt < canvas->txt_cnt; cnt++) _DtCvClearProcessed(lines[cnt]); /* * initialize the working structure * mark all the lines outside the selection regiion as invalid */ next = *beg; MarkLinesOutsideBoundary(canvas, next.y, next.x, end->y, end->x); /* * start the minimum and maximum Y at this location. */ minY = next.y; maxY = end->y; /* * is there a line at this location? */ if (next.line_idx == -1) { /* * find the first selected line within the region. */ if (FindNextMinY(lines, canvas->txt_cnt, -1, &next.y) == False) processing = False; /* empty of any text */ else { /* * now find the first line that is on this 'line' and * the number of lines. */ next.x = 0; lineCnt = FindMinX(lines, canvas->txt_cnt, next.y, &next.line_idx); next.char_idx = 0; } } else /* find the number of lines on this 'line' */ lineCnt = FindMinX(lines, canvas->txt_cnt, next.y, &cnt); /* * loop will there are segments to process */ while (processing == True && result == 0) { /* * process the next line of text. */ while (result == 0 && lineCnt > 0) { /* * for each segment in this line (that is selected) * create a segment point for it. */ length = lines[next.line_idx].length; start = lines[next.line_idx].byte_index; /* * if this is the last line, shorten the length * by the ending index. */ if (next.line_idx == end->line_idx) length = end->char_idx; /* * move through the line's segments until we * hit the segment starting the selection */ pSeg = lines[next.line_idx].seg_ptr; count = next.char_idx; while (NULL != pSeg && 0 < count) { /* * get the byte count of this segment */ _DtCvGetWidthOfSegment(canvas, pSeg, start, length, &cnt, NULL, NULL); /* * is the byte count of this segment larger than * the starting index of the selection? If not, * the selection is after this segment. */ if (count >= cnt) { start = 0; length -= cnt; pSeg = pSeg->next_disp; } else { length -= count; start = start + count; } count -= cnt; } while (0 == result && NULL != pSeg && 0 < length) { /* * start with error condition. If the malloc works * the error result gets reset to valid. */ result = -1; newPt = (_DtCvSegPts *) malloc (sizeof(_DtCvSegPts)); if (NULL != newPt) { /* * indicate everything is okay. */ result = 0; /* * get the width of this segment */ _DtCvGetWidthOfSegment(canvas, pSeg, start, length, &cnt, NULL, NULL); /* * now set the segment point information and add it to the * array of segment points. */ newPt->offset = start; newPt->len = cnt; newPt->segment = pSeg; *ret_segs = (_DtCvSegPts **) _DtCvAddPtrToArray( (void **) *ret_segs, (void *) newPt); if (NULL == *ret_segs) result = -1; pSeg = pSeg->next_disp; length -= cnt; start = 0; } } /* * does this line extend below the selection y? * if so, report it as the maximum y. */ botY = lines[next.line_idx].baseline + lines[next.line_idx].descent; if (botY > maxY) maxY = botY; /* * indicate this line has been processed. */ _DtCvSetProcessed(lines[next.line_idx]); /* * get the next line */ next.char_idx = 0; lineCnt = FindMinX(lines, canvas->txt_cnt, next.y, &next.line_idx); } if (result == 0) { next.x = 0; processing = FindNextMinY(lines,canvas->txt_cnt, -1, &next.y); if (processing == True) lineCnt = FindMinX(lines,canvas->txt_cnt,next.y,&next.line_idx); } } /* * if no errors, add a null to the array */ if (0 != result) { *ret_segs = (_DtCvSegPts **) _DtCvAddPtrToArray((void **) *ret_segs, (void *) NULL); if (NULL == *ret_segs) result = -1; } /* * if errors, free the segment points and return a bad status. */ if (0 != result) { if (NULL != *ret_segs) { for (lineCnt = 0; NULL != (*ret_segs)[lineCnt]; lineCnt++) free((*ret_segs)[lineCnt]); free(*ret_segs); } return _DtCvSTATUS_BAD; } if (NULL != ret_y1) *ret_y1 = minY; if (NULL != ret_y2) *ret_y2 = minY; return _DtCvSTATUS_OK; }
BOOL CConvexHullGenerator::Generate(void) { int iMaxXIndex; int iMinXIndex; CHalfSpaceHelper cHalfSpace; int iFarIndex; SFloat3* psPosition; CArrayExtremeTrianglePtr apcTriangles; CExtremeTriangle* pcTriangle; CExtremeTriangle* pcDeleted; SFreeListIterator sIter; CArrayExtremeTrianglePtr cDeleted; CArrayExtremeTrianglePtr cFixedDeleted; int j; SConvexHullHoleEdge sEdges; int k; int aiIndex[3]; int iIndex; CExtremeTriangle* pcSelected; CTextFile cTextFile; int iTriangle; float fMinX; float fMaxX; iMaxXIndex = FindMaxX(&fMinX); iMinXIndex = FindMinX(&fMaxX); iFarIndex = FindFurthestPoint(iMaxXIndex, iMinXIndex); if (iFarIndex == -1) { gcUserError.Set("Could not find a third point generating Convex Hull."); return FALSE; } apcTriangles.Init(2048); if (!FindFirstPairTriangles(&apcTriangles, iMaxXIndex, iMinXIndex, iFarIndex)) { gcUserError.Set("Could not find the first triangle pair generating Convex Hull."); return FALSE; } cDeleted.Init(512); cFixedDeleted.Init(512); for (iTriangle = 0; iTriangle < apcTriangles.NumElements(); iTriangle++) { pcSelected = *apcTriangles.Get(iTriangle); if ((pcSelected == NULL) || (pcSelected->maiVisible.NumElements() == 0)) { continue; } aiIndex[0] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition); aiIndex[1] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition1); aiIndex[2] = GetIndex(mpsPoints, iStride, pcSelected->mpsPosition2); iFarIndex = pcSelected->FindFurthestPoint(mpsPoints, iStride); if (iFarIndex == -1) { gcUserError.Set("Could not find furthest point!"); return FALSE; } cDeleted.FakeSetUsedElements(0); //It's sort of safe to do this. psPosition = GetPosition(mpsPoints, iStride, iFarIndex); pcTriangle = (CExtremeTriangle*)mcTriangles.StartIteration(&sIter); while (pcTriangle) { if (pcTriangle->maiVisible.NumElements() > 0) { if (pcTriangle->NotContains(psPosition)) { cDeleted.Add(&pcTriangle); } } pcTriangle = (CExtremeTriangle*)mcTriangles.Iterate(&sIter); } RemoveDiscontiguousTriangles(pcSelected, &cDeleted, &cFixedDeleted); for (j = 0; j < cDeleted.NumElements(); j++) { pcDeleted = *cDeleted.Get(j); FindEdges(&sEdges, pcDeleted, &cDeleted); for (k = 0; k < sEdges.iNumEdges; k++) { pcTriangle = AddTriangle(GetPosition(mpsPoints, iStride, sEdges.aaiEdgeIndices[k][0]), GetPosition(mpsPoints, iStride, sEdges.aaiEdgeIndices[k][1]), GetPosition(mpsPoints, iStride, iFarIndex)); apcTriangles.Add(&pcTriangle); AddPointsFromTriangles(pcTriangle, &cDeleted, iFarIndex); } } for (j = 0; j < cDeleted.NumElements(); j++) { pcDeleted = *cDeleted.Get(j); pcDeleted->Kill(); mcTriangles.Remove(pcDeleted); iIndex = apcTriangles.FindWithIntKey((int)(size_t)pcDeleted, 0); *(apcTriangles.Get(iIndex)) = NULL; } } cDeleted.Kill(); cFixedDeleted.Kill(); apcTriangles.Kill(); RemoveSlivers(); if (mszHullName) { CChars szTemp; szTemp.Init("Writing Hull file ["); szTemp.Append(mszHullName); szTemp.Append("]\n"); szTemp.Kill(); cTextFile.Init(); DumpTriangleObj(&cTextFile.mcText, iTriangle); cTextFile.Write(mszHullName); cTextFile.Kill(); } return TRUE; }