// 1. Calculate max radius and then max displacement for each edge.
// 2. tmin=minimum of the maximum displacements.
// 3. Calculate radius from the tmin for each edge.
YSRESULT YsShellExt_RoundUtil3d::SetUpRoundVertex(const YsShell &shl,YSSIZE_T nVt,const YsShellVertexHandle vtHdArray[])
{
	const YsShellSearchTable *search=shl.GetSearchTable();
	if(NULL==search)
	{
		YsPrintf("%s\n",__FUNCTION__);
		YsPrintf("  This function requires a search table.\n");
		return YSERR;
	}

	CleanUp();
	for(YSSIZE_T vtIdx=0; vtIdx<nVt; ++vtIdx)
	{
		YsArray <YsShellVertexHandle> connVtHdArray;
		if(YSOK==search->GetConnectedVertexList(connVtHdArray,shl,vtHdArray[vtIdx]))
		{
			for(auto connVtHd : connVtHdArray)
			{
				cornerArray.Increment();
				cornerArray.Last().Initialize();
				cornerArray.Last().fromVtHd=vtHdArray[vtIdx];
				cornerArray.Last().toVtHd=connVtHd;
				cornerArray.Last().toPos=shl.GetVertexPosition(connVtHd);
			}
		}
	}

	if(YSOK!=CalculateRoundingDirectionAll(shl))
	{
		CleanUp();
		return YSERR;
	}

	return YSOK;
}
YsVec3 YsShellExt_RoundUtil3d::CalculateRoundingDirction(const YsShell &shl,YsShellVertexHandle fromVtHd,YSSIZE_T nTo,const YsShellVertexHandle toVtHd[]) const
{
	const YsVec3 fromPos=shl.GetVertexPosition(fromVtHd);
	YsVec3 vecSum=YsOrigin();
	for(YSSIZE_T idx=0; idx<nTo; ++idx)
	{
		const YsVec3 vec=YsUnitVector(shl.GetVertexPosition(toVtHd[idx])-fromPos);
		vecSum+=vec;
	}
	vecSum.Normalize();
	return vecSum;
}
Ejemplo n.º 3
0
void PrepareShell(YsShell &shl)
{
	int idx[8];
	idx[0]=shl.AddVertex(YsVec3(-2.5, 1.0, 1.0));
	idx[1]=shl.AddVertex(YsVec3( 2.5, 1.0, 1.0));
	idx[2]=shl.AddVertex(YsVec3(-2.5, 1.0,-1.0));
	idx[3]=shl.AddVertex(YsVec3( 2.5, 1.0,-1.0));
	idx[4]=shl.AddVertex(YsVec3(-2.5,-1.0,-1.0));
	idx[5]=shl.AddVertex(YsVec3( 2.5,-1.0,-1.0));
	idx[6]=shl.AddVertex(YsVec3(-2.5,-1.0, 1.0));
	idx[7]=shl.AddVertex(YsVec3( 2.5,-1.0, 1.0));

	int plg[4];
	plg[0]=idx[0];
	plg[1]=idx[1];
	plg[2]=idx[3];
	plg[3]=idx[2];
	shl.AddPolygon(4,plg);

	plg[0]=idx[2];
	plg[1]=idx[3];
	plg[2]=idx[5];
	plg[3]=idx[4];
	shl.AddPolygon(4,plg);

	plg[0]=idx[4];
	plg[1]=idx[5];
	plg[2]=idx[7];
	plg[3]=idx[6];
	shl.AddPolygon(4,plg);

	plg[0]=idx[6];
	plg[1]=idx[7];
	plg[2]=idx[1];
	plg[3]=idx[0];
	shl.AddPolygon(4,plg);

	plg[0]=idx[0];
	plg[1]=idx[2];
	plg[2]=idx[4];
	plg[3]=idx[6];
	shl.AddPolygon(4,plg);

	plg[0]=idx[7];
	plg[1]=idx[5];
	plg[2]=idx[3];
	plg[3]=idx[1];
	shl.AddPolygon(4,plg);
}
const double YsShellExt_RoundUtil3d::CalculateMaximumRadius(const YsShell &shl) const
{
	if(0==cornerArray.GetN())
	{
printf("%s %d\n",__FUNCTION__,__LINE__);
		return 0.0;
	}

	double maxRadius=YsInfinity;
	for(auto corner : cornerArray)
	{
		if(YSTRUE==corner.notReallyDistanceLimited)
		{
			continue;
		}

		YsVec3 toVec=corner.toPos-shl.GetVertexPosition(corner.fromVtHd);
		const double L=toVec.GetLength();
		if(YsTolerance>L)
		{
printf("%s %d\n",__FUNCTION__,__LINE__);
			return 0.0;
		}
		toVec/=L;

		YsVec3 cenVec=corner.roundDir;
		if(YSOK!=cenVec.Normalize() || YsTolerance>cenVec*toVec)
		{
printf("%s\n",cenVec.Txt());
printf("%s\n",toVec.Txt());
printf("%lf\n",cenVec*toVec);
printf("%s %d\n",__FUNCTION__,__LINE__);
			return 0.0;
		}

		const double theata=acos(YsBound(toVec*cenVec,-1.0,1.0));

		const double maxRadiusForCorner=L*tan(theata);

		if(maxRadiusForCorner<maxRadius)
		{
			printf("Max radius limited by %s\n",shl.GetVertexPosition(corner.fromVtHd).Txt());
			maxRadius=maxRadiusForCorner;
		}
	}

	return maxRadius;
}
const double YsShellExt_RoundUtil::CalculateMaximumRadius(const YsShell &shl) const
{
	double maxRadTotal=0.0;
	for(YSSIZE_T idx=0; idx<cornerArray.GetN(); ++idx)
	{
		const RoundCorner &corner=cornerArray[idx];

		const double edgeLen[2]=
		{
			shl.GetEdgeLength(corner.fromVtHd,corner.toVtHd[0]),
			shl.GetEdgeLength(corner.fromVtHd,corner.toVtHd[1])
		};
		const double maxTanDist=YsSmaller(edgeLen[0],edgeLen[1]);
		const double maxRad=CalculateRadiusFromTangentDistance(shl,corner.fromVtHd,corner.toVtHd,maxTanDist);

		if(YsTolerance>maxRad)
		{
			return 0.0;
		}

		if(0==idx || maxRad<maxRadTotal)
		{
			maxRadTotal=maxRad;
		}
	}
	return maxRadTotal;
}
YSRESULT YsShellExt_RoundUtil3d::CalculateRoundingAll(const YsShell &shl,const double radius)
{
	YsArray <unsigned int> vtKeyArray;
	YsArray <HalfRoundCorner *> cornerPtrArray;
	for(auto &corner : cornerArray)
	{
		vtKeyArray.Append(shl.GetSearchKey(corner.fromVtHd));
		cornerPtrArray.Append(&corner);
	}

	YsQuickSort <unsigned int,HalfRoundCorner *> (vtKeyArray.GetN(),vtKeyArray,cornerPtrArray);

	YsArray <HalfRoundCorner *> cornerPerVertex;
	for(YSSIZE_T idx=0; idx<cornerPtrArray.GetN(); ++idx)
	{
		cornerPerVertex.Append(cornerPtrArray[idx]);
		if(cornerPtrArray.GetN()-1==idx || vtKeyArray[idx]!=vtKeyArray[idx+1])
		{
			if(YSOK!=CalculateRoundingPerVertex(shl,cornerPerVertex,radius))
			{
				return YSERR;
			}
			cornerPerVertex.CleanUp();
		}
	}

	return YSOK;
}
Ejemplo n.º 7
0
void MoveShell(YsShell &sh,YsVec3 &mov)
{
	YsMatrix4x4 mat,trn,viw,iViw;

	sh.GetMatrix(mat);

	viw=eyeAtt.GetMatrix();
	iViw=viw;
	iViw.Invert();

	trn.Initialize();
	trn.Translate(mov);

	mat=viw*trn*iViw*mat;

	sh.SetMatrix(mat);
}
Ejemplo n.º 8
0
void RotateShell(YsShell &sh,double pitch,double yaw)
{
	YsMatrix4x4 mat,rot,viw,iViw;

	sh.GetMatrix(mat);

	viw=eyeAtt.GetMatrix();
	iViw=viw;
	iViw.Invert();

	rot.Initialize();
	rot.RotateZY(pitch);
	rot.RotateXZ(yaw);

	mat=viw*rot*iViw*mat;

	sh.SetMatrix(mat);
}
Ejemplo n.º 9
0
void YsBoundingBoxMaker3::Make(const YsShell &shl,YSSIZE_T nVt,const YsShellVertexHandle vtHd[])
{
	int i;
	YsVec3 pos;
	Begin();
	for(i=0; i<nVt; i++)
	{
		shl.GetVertexPosition(pos,vtHd[i]);
		Add(pos);
	}
}
YsVec3 YsShellExt_RoundUtil3d::CalculateRoundingDirction(const YsShell &shl,const YsArray <HalfRoundCorner *> &roundCornerPerVertex) const
{
	const YsVec3 fromPos=shl.GetVertexPosition(roundCornerPerVertex[0]->fromVtHd);
	YsVec3 vecSum=YsOrigin();
	for(auto corner : roundCornerPerVertex)
	{
		const YsVec3 vec=YsUnitVector(corner->toPos-fromPos);
		vecSum+=vec;
	}
	vecSum.Normalize();
	return vecSum;
}
// 1. Calculate max radius and then max displacement for each edge.
// 2. tmin=minimum of the maximum displacements.
// 3. Calculate radius from the tmin for each edge.
YSRESULT YsShellExt_RoundUtil3d::CalculateRoundingPerVertex(const YsShell &shl,const YsArray <YsShellExt_RoundUtil3d::HalfRoundCorner *> &roundCornerPerVertex,const double radius) const
{
	const YsVec3 m=CalculateRoundingDirction(shl,roundCornerPerVertex);
	const YsVec3 fromPos=shl.GetVertexPosition(roundCornerPerVertex[0]->fromVtHd);

	double tMin=-1.0;
	for(auto corner : roundCornerPerVertex)
	{
		const YsVec3 toPos=corner->toPos;

		const double L=(toPos-fromPos).GetLength();
		const double r=(YSTRUE==corner->notReallyDistanceLimited ? radius : YsSmaller(radius,CalculateRadiusFromLimit(fromPos,toPos,m,L)));

		const double t=CalculateDisplacementFromRadius(fromPos,toPos,m,r);

		if(-0.1>tMin || t<tMin)
		{
			tMin=t;
		}
	}

	if(YsTolerance>tMin)
	{
		return YSERR;
	}

	const YsVec3 roundedCornerPos=fromPos+m*tMin;

	for(auto corner : roundCornerPerVertex)
	{
		const YsVec3 toPos=corner->toPos;

		const double r=CalculateRadiusFromDisplacement(fromPos,toPos,m,tMin);
		if(YsTolerance>r)
		{
			return YSERR;
		}

		YsVec3 center;
		if(YSOK!=CalculateCenterFromRadius(center,fromPos,toPos,m,r))
		{
			return YSERR;
		}


		corner->roundedCornerPos=roundedCornerPos;
		YsGetNearestPointOnLine3(corner->foot,fromPos,toPos,center);
		corner->radius=r;
		corner->center=center;
	}

	return YSOK;
}
YSRESULT YsShellExt_RoundUtil::SetUpRoundPolygon(const YsShell &shl,YsShellPolygonHandle plHd,const YsShellVertexStore *roundVtx)
{
	YsArray <YsShellVertexHandle> plVtHd;
	shl.GetPolygon(plVtHd,plHd);
	for(YSSIZE_T idx=0; idx<plVtHd.GetN(); ++idx)
	{
		const YsShellVertexHandle fromVtHd=plVtHd[idx];
		if(NULL==roundVtx || YSTRUE==roundVtx->IsIncluded(fromVtHd))
		{
			const YsShellVertexHandle toVtHd[2]=
			{
				plVtHd.GetCyclic(idx-1),
				plVtHd.GetCyclic(idx+1)
			};
			AddRoundCorner(shl,fromVtHd,toVtHd);
		}
	}
	targetPlKeyArray.Append(shl.GetSearchKey(plHd));

	return YSOK;
}
/*static*/ double YsShellExt_RoundUtil::CalculateRadiusFromTangentDistance(const YsShell &shl,YsShellVertexHandle fromVtHd,const YsShellVertexHandle toVtHd[2],const double dist)
{
	const double edLen[2]=
	{
		(shl.GetVertexPosition(toVtHd[0])-shl.GetVertexPosition(fromVtHd)).GetLength(),
		(shl.GetVertexPosition(toVtHd[1])-shl.GetVertexPosition(fromVtHd)).GetLength()
	};
	const YsVec3 edVec[2]=
	{
		(shl.GetVertexPosition(toVtHd[0])-shl.GetVertexPosition(fromVtHd))/edLen[0],
		(shl.GetVertexPosition(toVtHd[1])-shl.GetVertexPosition(fromVtHd))/edLen[1]
	};
	const double theata=YsPi-acos(YsBound(edVec[0]*edVec[1],-1.0,1.0));

	const double t=tan(theata/2.0);
	if(YsTolerance>t)
	{
		return 0.0;
	}

	return dist/t;
}
YsArray <const YsShellExt_RoundUtil3d::HalfRoundCorner *> YsShellExt_RoundUtil3d::MakeSortedHalfRoundCorner(const YsShell &shl) const
{
	YsArray <unsigned int> vtKeyArray;
	YsArray <const HalfRoundCorner *> cornerPtrArray;
	for(auto &corner : cornerArray)
	{
		vtKeyArray.Append(shl.GetSearchKey(corner.fromVtHd));
		cornerPtrArray.Append(&corner);
	}

	YsQuickSort <unsigned int,const HalfRoundCorner *> (vtKeyArray.GetN(),vtKeyArray,cornerPtrArray);

	return cornerPtrArray;
}
YSRESULT YsShellExt_PatchBetweenTwoConstEdge::SetVertexSequence(const YsShell &srcShl,
                       YSSIZE_T nVt0,const YsShellVertexHandle vtHdArray0[],YSBOOL isLoop0,
                       YSSIZE_T nVt1,const YsShellVertexHandle vtHdArray1[],YSBOOL isLoop1)
{
	if((YSTRUE!=isLoop0 && 2>nVt0) || (YSTRUE==isLoop0 && 3>nVt0) ||
	   (YSTRUE!=isLoop1 && 2>nVt1) || (YSTRUE==isLoop1 && 3>nVt1))
	{
		return YSERR;
	}

	YsArray <YsShellVertexHandle> newVtHdArray[2];

	shl.CleanUp();

	isLoop[0]=isLoop0;
	isLoop[1]=isLoop1;

	for(int seq=0; seq<2; ++seq)
	{
		const YSSIZE_T nVt=(0==seq ? nVt0 : nVt1);
		const YsShellVertexHandle *vtHdArray=(0==seq ? vtHdArray0 : vtHdArray1);
		const YSBOOL isLoop=(0==seq ? isLoop0 : isLoop1);

		totalLen[seq]=0.0;

		for(YSSIZE_T idx=0; idx<nVt; ++idx)
		{
			auto vtHd=shl.AddVertex(srcShl.GetVertexPosition(vtHdArray[idx]));
			patchVtKeyToSrcVtHd.AddElement(shl.GetSearchKey(vtHd),vtHdArray[idx]);
			patchVtKeyToSeqId.AddElement(shl.GetSearchKey(vtHd),seq);
			rawVtHdSeq[seq].Append(vtHd);

			if(0<idx)
			{
				totalLen[seq]+=shl.GetEdgeLength(rawVtHdSeq[seq][idx-1],vtHd);
			}
		}

		if(YSTRUE==isLoop && 3<=rawVtHdSeq[seq].GetN())
		{
			totalLen[seq]+=shl.GetEdgeLength(rawVtHdSeq[seq][0],rawVtHdSeq[seq].Last());
		}

		vtHdSeq[seq]=rawVtHdSeq[seq];
		seqCeHd[seq]=shl.AddConstEdge(rawVtHdSeq[seq],isLoop);
	}

	return YSOK;
}
YSBOOL YsShellExt_RoundUtil3d::IsEdgeUsing(const YsShellVertexHandle edVtHd0,const YsShellVertexHandle edVtHd1,const YsShell &shl,const YsShellPolygonStore &polygonStore) const
{
	const YsShellSearchTable *search=shl.GetSearchTable();

	int nEdPl;
	const YsShellPolygonHandle *edPlHd;
	if(YSOK==search->FindPolygonListByEdge(nEdPl,edPlHd,shl,edVtHd0,edVtHd1))
	{
		for(int plIdx=0; plIdx<nEdPl; ++plIdx)
		{
			if(YSTRUE==polygonStore.IsIncluded(edPlHd[plIdx]))
			{
				return YSTRUE;
			}
		}
	}
	return YSFALSE;
}
YsArray <YSSIZE_T> YsShellExt_RoundUtil3d::FindHalfRoundCornerFromPolygon(const YsShell &shl,YsShellPolygonHandle plHd) const
{
	YsArray <YsShellVertexHandle,4> plVtHd;
	shl.GetPolygon(plVtHd,plHd);

	YsArray <YSSIZE_T> idxArray;
	for(YSSIZE_T i=0; i<plVtHd.GetN(); ++i)
	{
		for(YSSIZE_T j=0; j<cornerArray.GetN(); ++j)
		{
			if(plVtHd[i]==cornerArray[j].fromVtHd && YSTRUE==plVtHd.IsIncluded(cornerArray[j].toVtHd))
			{
				idxArray.Append(j);
			}
		}
	}

	return idxArray;
}
YSRESULT YsShellExt_RoundUtil::CalculateRoundingAll(const YsShell &shl,const double radius,int nDiv)
{
	if(1>nDiv)
	{
		nDiv=1;
	}

	for(auto &corner : cornerArray)
	{
		corner.subDiv[0].CleanUp();
		corner.subDiv[1].CleanUp();

		const YsVec3 vtPos[3]=
		{
			shl.GetVertexPosition(corner.fromVtHd),
			shl.GetVertexPosition(corner.toVtHd[0]),
			shl.GetVertexPosition(corner.toVtHd[1])
		};
		const double edLen[2]=
		{
			(shl.GetVertexPosition(corner.toVtHd[0])-shl.GetVertexPosition(corner.fromVtHd)).GetLength(),
			(shl.GetVertexPosition(corner.toVtHd[1])-shl.GetVertexPosition(corner.fromVtHd)).GetLength()
		};
		const YsVec3 edVec[2]=
		{
			(shl.GetVertexPosition(corner.toVtHd[0])-shl.GetVertexPosition(corner.fromVtHd))/edLen[0],
			(shl.GetVertexPosition(corner.toVtHd[1])-shl.GetVertexPosition(corner.fromVtHd))/edLen[1]
		};
		const double theata=YsPi-acos(YsBound(edVec[0]*edVec[1],-1.0,1.0));
		const double L=radius*tan(theata/2.0);

		if(angleThr>theata)
		{
			return YSERR;
		}

		YsPlane pln[3];
		if(YSOK!=pln[0].MakePlaneFromTriangle(vtPos[0],vtPos[1],vtPos[2]))
		{
			return YSERR;
		}
		pln[1].Set(vtPos[0]+edVec[0]*L,edVec[0]);
		pln[2].Set(vtPos[0]+edVec[1]*L,edVec[1]);

		// Haven't I written three-plane intersection?
		// Plane equation:
		//    (p-o)*n=0
		//    pn-on=0
		//    nx*px+ny*py+nz*pz=on
		{
			YsMatrix3x3 mat;
			YsVec3 rhs;
			for(int i=0; i<3; ++i)
			{
				rhs[i]=pln[i].GetNormal()*pln[i].GetOrigin();
				for(int j=0; j<3; ++j)
				{
					mat.Set(i+1,j+1,pln[i].GetNormal()[j]);
				}
			}

			if(YSOK!=mat.Invert())
			{
				YsPrintf("Cannot calculate the center.\n");
				return YSERR;
			}
			corner.center=mat*rhs;
		}

		corner.roundedCornerPos=YsUnitVector(vtPos[0]-corner.center);
		corner.roundedCornerPos=corner.center+corner.roundedCornerPos*radius;

		for(int edIdx=0; edIdx<2; ++edIdx)
		{
			for(int i=0; i<nDiv; ++i)
			{
				corner.subDiv[edIdx].Increment();
				corner.subDiv[edIdx].Last().vtHd=NULL;
				if(0==i)
				{
					corner.subDiv[edIdx].Last().pos=vtPos[0]+edVec[edIdx]*L;;
				}
				if(0<i)
				{
					const double t=1.0-(double)i/(double)nDiv;
					YsVec3 pos=vtPos[0]+edVec[edIdx]*L*t;

					pos-=corner.center;
					pos.Normalize();
					pos*=radius;
					pos+=corner.center;

					corner.subDiv[edIdx].Last().pos=pos;
				}
			}
		}
	}

	return YSOK;
}
YsArray <YsShellExt_RoundUtil::VertexPositionPair> YsShellExt_RoundUtil::MakeRoundedVertexSequence(const YsShell &shl,YSSIZE_T nVt,const YsShellVertexHandle vtHdArrayIn[],YSBOOL isLoop) const
{
	YsArray <YsShellVertexHandle> orgVtHdArray(nVt,vtHdArrayIn);
	YsArray <VertexPositionPair> newVtHdArray;

	for(YSSIZE_T orgVtIdx=0; orgVtIdx<orgVtHdArray.GetN(); ++orgVtIdx)
	{
		YSBOOL rounded=YSFALSE;
		for(const auto &roundCorner : cornerArray)
		{
			if(roundCorner.fromVtHd==orgVtHdArray[orgVtIdx])
			{
				int forward=0,backward=1;

				if(roundCorner.toVtHd[0]==orgVtHdArray.GetCyclic(orgVtIdx-1))
				{
					forward=1;
					backward=0;
				}
				else if(roundCorner.toVtHd[1]==orgVtHdArray.GetCyclic(orgVtIdx-1))
				{
					forward=0;
					backward=1;
				}
				else
				{
					continue;
				}

				YSBOOL skipFirst=YSFALSE;

				if(0<newVtHdArray.GetN() && newVtHdArray.Last().pos==roundCorner.subDiv[backward].Last().pos)
				{
					skipFirst=YSTRUE;
				}

				newVtHdArray.Append(roundCorner.subDiv[backward]);

				newVtHdArray.Increment();
				newVtHdArray.Last().vtHd=orgVtHdArray[orgVtIdx];
				newVtHdArray.Last().pos=roundCorner.roundedCornerPos;

				for(YSSIZE_T i=roundCorner.subDiv[forward].GetN()-1; 0<=i; --i)
				{
					if(YSTRUE==skipFirst)
					{
						skipFirst=YSFALSE;
						continue;
					}
					newVtHdArray.Append(roundCorner.subDiv[forward][i]);
				}

				rounded=YSTRUE;
			}
		}
		if(YSTRUE!=rounded)
		{
			newVtHdArray.Increment();
			newVtHdArray.Last().vtHd=orgVtHdArray[orgVtIdx];
			newVtHdArray.Last().pos=shl.GetVertexPosition(newVtHdArray.Last().vtHd);
		}
	}

	if(2<=newVtHdArray.GetN() && YSTRUE==isLoop && newVtHdArray[0].pos==newVtHdArray.Last().pos)
	{
		newVtHdArray.DeleteLast();
	}

	return newVtHdArray;
}
Ejemplo n.º 20
0
void DrawShell(YsShell &shell,YsColor &col,YSBOOL inPolygon)
{
	int i,j,k;
	int nVtx,nPlg;
	YsVec3 vtx[256];

	if(inPolygon==YSTRUE)
	{
		glEnable(GL_LIGHTING);
	}
	else
	{
		glDisable(GL_LIGHTING);
	}

	nPlg=shell.GetNumPolygon();
	for(i=0; i<nPlg; i++)
	{
		nVtx=shell.GetNumVertexOfPolygon(i);
		if(nVtx>0)
		{
			double r,g,b;
			YsVec3 nom;

			shell.GetVertexListOfPolygon(vtx,256,i);
			nom=(vtx[1]-vtx[0])^(vtx[2]-vtx[1]);
			nom.Normalize();

			col.GetDoubleRGB(r,g,b);

			glColor3d(r,g,b);

			if(inPolygon==YSFALSE || YsCheckConvex3(nVtx,vtx)==YSTRUE)
			{
				switch(inPolygon)
				{
				case YSFALSE:
					glBegin(GL_LINE_LOOP);
					break;
				case YSTRUE:
					glBegin(GL_POLYGON);
					break;
				}
				glNormal3d(nom.x(),nom.y(),nom.z());
				for(j=0; j<nVtx; j++)
				{
					glVertex3d(vtx[j].x(),vtx[j].y(),vtx[j].z());
				}
				glEnd();
			}
			else
			{
				YsSword swd;
				swd.SetInitialPolygon(nVtx,vtx);
				swd.Convexnize();
				for(j=0; j<swd.GetNumPolygon(); j++)
				{
					nVtx=swd.GetNumVertexOfPolygon(j);
					swd.GetVertexListOfPolygon(vtx,256,j);
					glBegin(GL_POLYGON);
					for(k=0; k<nVtx; k++)
					{
						glVertex3dv(vtx[k].GetValue());
					}
					glEnd();
				}
			}
		}
	}
}