| /* |
| ** License Applicability. Except to the extent portions of this file are |
| ** made subject to an alternative license as permitted in the SGI Free |
| ** Software License B, Version 1.1 (the "License"), the contents of this |
| ** file are subject only to the provisions of the License. You may not use |
| ** this file except in compliance with the License. You may obtain a copy |
| ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 |
| ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: |
| ** |
| ** http://oss.sgi.com/projects/FreeB |
| ** |
| ** Note that, as provided in the License, the Software is distributed on an |
| ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS |
| ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND |
| ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A |
| ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. |
| ** |
| ** Original Code. The Original Code is: OpenGL Sample Implementation, |
| ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, |
| ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. |
| ** Copyright in any portions created by third parties is as indicated |
| ** elsewhere herein. All Rights Reserved. |
| ** |
| ** Additional Notice Provisions: The application programming interfaces |
| ** established by SGI in conjunction with the Original Code are The |
| ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released |
| ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version |
| ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X |
| ** Window System(R) (Version 1.3), released October 19, 1998. This software |
| ** was created using the OpenGL(R) version 1.2.1 Sample Implementation |
| ** published by SGI, but has not been independently verified as being |
| ** compliant with the OpenGL(R) version 1.2.1 Specification. |
| ** |
| ** $Date: 2012/03/29 17:22:17 $ $Revision: 1.1.1.1 $ |
| */ |
| /* |
| ** $Header: /cvs/bao-parsec/pkgs/libs/mesa/src/src/glu/sgi/libnurbs/nurbtess/sampleComp.cc,v 1.1.1.1 2012/03/29 17:22:17 uid42307 Exp $ |
| */ |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include "glimports.h" |
| #include "sampleComp.h" |
| #include "sampleCompTop.h" |
| #include "sampleCompBot.h" |
| #include "sampleCompRight.h" |
| |
| |
| |
| #define max(a,b) ((a>b)? a:b) |
| #define min(a,b) ((a>b)? b:a) |
| |
| void sampleConnectedComp(Real* topVertex, Real* botVertex, |
| vertexArray* leftChain, |
| Int leftStartIndex, Int leftEndIndex, |
| vertexArray* rightChain, |
| Int rightStartIndex, Int rightEndIndex, |
| gridBoundaryChain* leftGridChain, |
| gridBoundaryChain* rightGridChain, |
| Int gridIndex1, Int gridIndex2, |
| Int up_leftCornerWhere, |
| Int up_leftCornerIndex, |
| Int up_rightCornerWhere, |
| Int up_rightCornerIndex, |
| Int down_leftCornerWhere, |
| Int down_leftCornerIndex, |
| Int down_rightCornerWhere, |
| Int down_rightCornerIndex, |
| primStream* pStream, |
| rectBlockArray* rbArray |
| ) |
| { |
| |
| sampleCompLeft(topVertex, botVertex, |
| leftChain, |
| leftStartIndex, leftEndIndex, |
| rightChain, |
| rightStartIndex, rightEndIndex, |
| leftGridChain, |
| gridIndex1, |
| gridIndex2, |
| up_leftCornerWhere, |
| up_leftCornerIndex, |
| down_leftCornerWhere, |
| down_leftCornerIndex, |
| pStream); |
| |
| |
| sampleCompRight(topVertex, botVertex, |
| leftChain, |
| leftStartIndex, leftEndIndex, |
| rightChain, |
| rightStartIndex, |
| rightEndIndex, |
| rightGridChain, |
| gridIndex1, gridIndex2, |
| up_rightCornerWhere, |
| up_rightCornerIndex, |
| down_rightCornerWhere, |
| down_rightCornerIndex, |
| pStream); |
| |
| |
| sampleCompTop(topVertex, |
| leftChain, |
| leftStartIndex, |
| rightChain, |
| rightStartIndex, |
| leftGridChain, |
| rightGridChain, |
| gridIndex1, |
| up_leftCornerWhere, |
| up_leftCornerIndex, |
| up_rightCornerWhere, |
| up_rightCornerIndex, |
| pStream); |
| |
| sampleCompBot(botVertex, |
| leftChain, |
| leftEndIndex, |
| rightChain, |
| rightEndIndex, |
| leftGridChain, |
| rightGridChain, |
| gridIndex2, |
| down_leftCornerWhere, |
| down_leftCornerIndex, |
| down_rightCornerWhere, |
| down_rightCornerIndex, |
| pStream); |
| |
| |
| //the center |
| |
| rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2)); |
| |
| |
| } |
| |
| /*notice that we need rightChain because the |
| *corners could be on the rightChain. |
| *here comp means component. |
| */ |
| void sampleCompLeft(Real* topVertex, Real* botVertex, |
| vertexArray* leftChain, |
| Int leftStartIndex, Int leftEndIndex, |
| vertexArray* rightChain, |
| Int rightStartIndex, Int rightEndIndex, |
| gridBoundaryChain* leftGridChain, |
| Int gridIndex1, Int gridIndex2, |
| Int up_leftCornerWhere, |
| Int up_leftCornerIndex, |
| Int down_leftCornerWhere, |
| Int down_leftCornerIndex, |
| primStream* pStream) |
| { |
| /*find out whether there is a trim vertex which is |
| *inbetween the top and bot grid lines or not. |
| */ |
| Int midIndex1; |
| Int midIndex2; |
| Int gridMidIndex1 = 0, gridMidIndex2 = 0; |
| //midIndex1: array[i] <= v, array[i-1] > v |
| //midIndex2: array[i] >= v, array[i+1] < v |
| // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1) |
| // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ?? |
| midIndex1 = leftChain->findIndexBelowGen( |
| leftGridChain->get_v_value(gridIndex1), |
| leftStartIndex, |
| leftEndIndex); |
| |
| midIndex2 = -1; /*initilization*/ |
| if(midIndex1<= leftEndIndex && gridIndex1<gridIndex2) |
| if(leftChain->getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2)) |
| { |
| midIndex2 = leftChain->findIndexAboveGen( |
| leftGridChain->get_v_value(gridIndex2), |
| midIndex1, //midIndex1 <= midIndex2. |
| leftEndIndex); |
| gridMidIndex1 = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1], |
| gridIndex1, gridIndex2); |
| gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1], |
| gridMidIndex1, gridIndex2); |
| } |
| |
| |
| /*to interprete the corner information*/ |
| Real* cornerTop; |
| Real* cornerBot; |
| Int cornerLeftStart; |
| Int cornerLeftEnd; |
| Int cornerRightUpEnd; |
| Int cornerRightDownStart; |
| if(up_leftCornerWhere == 0) /*left corner is on left chain*/ |
| { |
| cornerTop = leftChain->getVertex(up_leftCornerIndex); |
| cornerLeftStart = up_leftCornerIndex+1; |
| cornerRightUpEnd = -1; /*no right*/ |
| } |
| else if(up_leftCornerWhere == 1) /*left corner is on top*/ |
| { |
| cornerTop = topVertex; |
| cornerLeftStart = leftStartIndex; |
| cornerRightUpEnd = -1; /*no right*/ |
| } |
| else /*left corner is on right chain*/ |
| { |
| cornerTop = topVertex; |
| cornerLeftStart = leftStartIndex; |
| cornerRightUpEnd = up_leftCornerIndex; |
| } |
| |
| if(down_leftCornerWhere == 0) /*left corner is on left chain*/ |
| { |
| cornerBot = leftChain->getVertex(down_leftCornerIndex); |
| cornerLeftEnd = down_leftCornerIndex-1; |
| cornerRightDownStart = rightEndIndex+1; /*no right*/ |
| } |
| else if(down_leftCornerWhere == 1) /*left corner is on bot*/ |
| { |
| cornerBot = botVertex; |
| cornerLeftEnd = leftEndIndex; |
| cornerRightDownStart = rightEndIndex+1; /*no right*/ |
| } |
| else /*left corner is on the right chian*/ |
| { |
| cornerBot = botVertex; |
| cornerLeftEnd = leftEndIndex; |
| cornerRightDownStart = down_leftCornerIndex; |
| } |
| |
| |
| |
| |
| /*sample*/ |
| if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/ |
| { |
| |
| sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1), |
| leftChain, |
| cornerLeftStart, |
| midIndex1-1, |
| leftGridChain, |
| gridIndex1, |
| gridMidIndex1, |
| rightChain, |
| rightStartIndex, |
| cornerRightUpEnd, |
| 0, //no right down section |
| -1, |
| pStream); |
| |
| sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2), |
| cornerBot, |
| leftChain, |
| midIndex2+1, |
| cornerLeftEnd, |
| leftGridChain, |
| gridMidIndex2, |
| gridIndex2, |
| rightChain, |
| 0, //no right up section |
| -1, |
| cornerRightDownStart, |
| rightEndIndex, |
| pStream); |
| |
| |
| sampleLeftStripRecF(leftChain, |
| midIndex1, |
| midIndex2, |
| leftGridChain, |
| gridMidIndex1, |
| gridMidIndex2, |
| pStream); |
| } |
| else |
| { |
| sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot, |
| leftChain, |
| cornerLeftStart, |
| cornerLeftEnd, |
| leftGridChain, |
| gridIndex1, |
| gridIndex2, |
| rightChain, |
| rightStartIndex, |
| cornerRightUpEnd, |
| cornerRightDownStart, |
| rightEndIndex, |
| pStream); |
| } |
| } |
| |
| void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2], |
| vertexArray* leftChain, |
| Int leftStart, |
| Int leftEnd, |
| gridBoundaryChain* gridChain, |
| Int gridBeginIndex, |
| Int gridEndIndex, |
| vertexArray* rightChain, |
| Int rightUpBegin, |
| Int rightUpEnd, |
| Int rightDownBegin, |
| Int rightDownEnd, |
| primStream* pStream) |
| { |
| Int i,j,k; |
| |
| /*creat an array to store all the up and down secments of the right chain, |
| *and the left end grid points |
| * |
| *although vertex array is a dynamic array, but to gain efficiency, |
| *it is better to initiliza the exact array size |
| */ |
| vertexArray vArray(gridEndIndex-gridBeginIndex+1 + |
| max(0,rightUpEnd - rightUpBegin+1)+ |
| max(0,rightDownEnd - rightDownBegin+1)); |
| |
| /*append the vertices on the up section of thr right chain*/ |
| for(i=rightUpBegin; i<= rightUpEnd; i++) |
| vArray.appendVertex(rightChain->getVertex(i)); |
| |
| /*append the vertices of the left extremal grid points, |
| *and at the same time, perform triangulation for the stair cases |
| */ |
| vArray.appendVertex(gridChain->get_vertex(gridBeginIndex)); |
| |
| for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; 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*/ |
| } |
| |
| /*then append all the vertices on the down section of the right chain*/ |
| for(i=rightDownBegin; i<= rightDownEnd; i++) |
| vArray.appendVertex(rightChain->getVertex(i)); |
| |
| monoTriangulationRecGen(topVert, botVert, |
| leftChain, leftStart, leftEnd, |
| &vArray, 0, vArray.getNumElements()-1, |
| pStream); |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |