📄 samplemonopoly.cc
字号:
/*
*(1)find the last grid line which doesn'; pass below
* this first edge, sample this region: one trim edge and
* possily multiple grid lines.
*/
Real *upperVert, *lowerVert; /*the end points of the first trim edge*/
upperVert = leftChain->getVertex(topLeftIndex);
lowerVert = leftChain->getVertex(topLeftIndex+1);
Int index = leftGridChainStartIndex;
while(leftGridChain->get_v_value(index) >= lowerVert[1]){
index++;
if(index > leftGridChainEndIndex)
break;
}
index--;
sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert,
leftGridChain,
leftGridChainStartIndex,
index,
pStream);
sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex,
leftGridChain, index, leftGridChainEndIndex,
pStream);
}
void sampleLeftStripRec(vertexArray* leftChain,
Int topLeftIndex,
Int botLeftIndex,
gridBoundaryChain* leftGridChain,
Int leftGridChainStartIndex,
Int leftGridChainEndIndex,
primStream* pStream
)
{
/*now top left trim vertex is below the top grid line.
*/
/*stop condition: if topLeftIndex >= botLeftIndex, then stop.
*/
if(topLeftIndex >= botLeftIndex)
return;
/*find the last trim vertex which is above the second top grid line:
* index1.
*and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain,
* leftGridChainStartIndex).
* index1 could be equal to topLeftIndex.
*/
Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
assert(leftGridChainStartIndex < leftGridChainEndIndex);
Int index1 = topLeftIndex;
while(leftChain->getVertex(index1)[1] > secondGridChainV)
index1++;
index1--;
sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
/*
* Let the next trim vertex be nextTrimVertIndex (which should be
* below the second grid line).
* Find the last grid line index2 which is above nextTrimVert.
* sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
* leftGridChain, leftGridChainStartIndex+1, index2).
*/
Real *uppervert, *lowervert;
uppervert = leftChain->getVertex(index1);
lowervert = leftChain->getVertex(index1+1);
Int index2 = leftGridChainStartIndex+1;
while(leftGridChain->get_v_value(index2) >= lowervert[1])
{
index2++;
if(index2 > leftGridChainEndIndex)
break;
}
index2--;
sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
/* sampleLeftStripRec(leftChain,
nextTrimVertIndex,
botLeftIndex,
leftGridChain,
index2,
leftGridChainEndIndex
)
*
*/
sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
}
/***************begin RecF***********************/
/* the gridlines from leftGridChainStartIndex to
* leftGridChainEndIndex are assumed to form a
* connected component.
* the trim vertex of topLeftIndex is assumed to
* be below the first gridline, and the tim vertex
* of botLeftIndex is assumed to be above the last
* grid line.
* If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without
* outputing any triangles.
* Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output.
*/
void sampleLeftStripRecF(vertexArray* leftChain,
Int topLeftIndex,
Int botLeftIndex,
gridBoundaryChain* leftGridChain,
Int leftGridChainStartIndex,
Int leftGridChainEndIndex,
primStream* pStream
)
{
/*now top left trim vertex is below the top grid line.
*/
/*stop condition: if topLeftIndex > botLeftIndex, then stop.
*/
if(topLeftIndex > botLeftIndex)
return;
/*if there is only one grid Line, return.*/
if(leftGridChainStartIndex>=leftGridChainEndIndex)
return;
assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) &&
leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex));
/*firs find the first trim vertex which is below or equal to the second top grid line:
* index1.
*/
Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
Int index1 = topLeftIndex;
while(leftChain->getVertex(index1)[1] > secondGridChainV){
index1++;
if(index1>botLeftIndex)
break;
}
/*now leftChain->getVertex(index-1)[1] > secondGridChainV and
* leftChain->getVertex(index)[1] <= secondGridChainV
*If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to
*perform sampleOneGridStep.
*/
if(index1>botLeftIndex)
index1--;
else if(leftChain->getVertex(index1)[1] < secondGridChainV)
index1--;
/*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and
* leftChain->getVertex(index1+1)[1] <= secondGridChainV
*/
sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
/*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest.
*/
if(leftChain->getVertex(index1)[1] == secondGridChainV)
{
sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream);
}
else if(index1 < botLeftIndex)
{
/* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV,
* let the next trim vertex be nextTrimVertIndex (which should be strictly
* below the second grid line).
* Find the last grid line index2 which is above nextTrimVert.
* sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
* leftGridChain, leftGridChainStartIndex+1, index2).
*/
Real *uppervert, *lowervert;
uppervert = leftChain->getVertex(index1);
lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex
Int index2 = leftGridChainStartIndex+1;
while(leftGridChain->get_v_value(index2) >= lowervert[1])
{
index2++;
if(index2 > leftGridChainEndIndex)
break;
}
index2--;
sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
/*recursion*/
sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
}
}
/***************End RecF***********************/
/*sample the left area in between one trim edge and multiple grid lines.
* all the grid lines should be in between the two end poins of the
*trim edge.
*/
void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
gridBoundaryChain* gridChain,
Int beginIndex,
Int endIndex,
primStream* pStream)
{
Int i,j,k;
vertexArray vArray(endIndex-beginIndex+1);
vArray.appendVertex(gridChain->get_vertex(beginIndex));
for(k=1, i=beginIndex+1; i<=endIndex; i++, k++)
{
vArray.appendVertex(gridChain->get_vertex(i));
/*output the fan of the grid points of the (i)th and (i-1)th grid line.
*/
if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
{
pStream->begin();
pStream->insert(gridChain->get_vertex(i-1));
for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
pStream->end(PRIMITIVE_STREAM_FAN);
}
else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
{
pStream->begin();
pStream->insert(gridChain->get_vertex(i));
for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
pStream->end(PRIMITIVE_STREAM_FAN);
}
/*otherwisem, the two are equal, so there is no fan to outout*/
}
monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex,
0, /*decreasing chain*/
pStream);
}
/*return i, such that from begin to i-1 the chain is strictly u-monotone.
*/
Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end)
{
Int i=begin;
Real prevU = chain->getVertex(i)[0];
Real thisU;
for(i=begin+1; i<=end; i++){
thisU = chain->getVertex(i)[0];
if(prevU < thisU){
prevU = thisU;
}
else
break;
}
return i;
}
/*check whether there is a vertex whose v value is strictly
*inbetween vup vbelow
*if no middle exists return -1, else return the idnex.
*/
Int checkMiddle(vertexArray* chain, Int begin, Int end,
Real vup, Real vbelow)
{
Int i;
for(i=begin; i<=end; i++)
{
if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow)
return i;
}
return -1;
}
/*the degenerat case of sampleLeftOneGridStep*/
void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain,
Int beginLeftIndex,
Int endLeftIndex,
gridBoundaryChain* leftGridChain,
Int leftGridChainStartIndex,
primStream* pStream)
{
/*since there is no middle, there is at most one point which is on the
*second grid line, there could be multiple points on the first (top)
*grid line.
*/
leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream);
monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex),
leftGridChain->get_vertex(leftGridChainStartIndex+1),
leftChain,
beginLeftIndex,
endLeftIndex,
1, //is increase chain.
pStream);
}
/*sampling the left area in between two grid lines.
*/
void sampleLeftOneGridStep(vertexArray* leftChain,
Int beginLeftIndex,
Int endLeftIndex,
gridBoundaryChain* leftGridChain,
Int leftGridChainStartIndex,
primStream* pStream
)
{
if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex,
leftGridChain->get_v_value(leftGridChainStartIndex),
leftGridChain->get_v_value(leftGridChainStartIndex+1))<0)
{
sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream);
return;
}
//copy into a polygon
{
directedLine* poly = NULL;
sampledLine* sline;
directedLine* dline;
gridWrap* grid = leftGridChain->getGrid();
Real vert1[2];
Real vert2[2];
Int i;
Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1);
Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex);
Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1);
Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex);
Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
//the upper gridline
vert1[1] = vert2[1] = upperV;
for(i=innerInd; i>upperInd; i--)
{
vert1[0]=grid->get_u_value(i);
vert2[0]=grid->get_u_value(i-1);
sline = new sampledLine(vert1, vert2);
dline = new directedLine(INCREASING, sline);
if(poly == NULL)
poly = dline;
else
poly->insert(dline);
}
//the edge connecting upper grid with left chain
vert1[0] = grid->get_u_value(upperInd);
vert1[1] = upperV;
sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex));
dline = new directedLine(INCREASING, sline);
if(poly == NULL)
poly = dline;
else
poly->insert(dline);
//the left chain
for(i=beginLeftIndex; i<endLeftIndex; i++)
{
sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1));
dline = new directedLine(INCREASING, sline);
poly->insert(dline);
}
//the edge connecting left chain with lower gridline
vert2[0] = grid->get_u_value(lowerInd);
vert2[1] = lowerV;
sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2);
dline = new directedLine(INCREASING, sline);
poly->insert(dline);
//the lower grid line
vert1[1] = vert2[1] = lowerV;
for(i=lowerInd; i<innerInd; i++)
{
vert1[0] = grid->get_u_value(i);
vert2[0] = grid->get_u_value(i+1);
sline = new sampledLine(vert1, vert2);
dline = new directedLine(INCREASING, sline);
poly->insert(dline);
}
//the vertical grid line segement
vert1[0]=vert2[0] = grid->get_u_value(innerInd);
vert2[1]=upperV;
vert1[1]=lowerV;
sline=new sampledLine(vert1, vert2);
dline=new directedLine(INCREASING, sline);
poly->insert(dline);
monoTriangulationOpt(poly, pStream);
//cleanup
poly->deleteSinglePolygonWithSline();
return;
}
Int i;
if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >=
leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -