YSRESULT YsShellExtEdge_EdgeStaplingUtil::StapleMinimumOpenAngleCorner(YsShellExtEdit &shl)
{
	YsShellVertexHandle cornerVtHd,connVtHd[2];
	if(YSOK==GetMinimumOpenAngleCorner(cornerVtHd,connVtHd,shl.Conv()))
	{
		// Check again.  This crack may have already been fixed.
		if(YSTRUE!=YsShellExt_TopologyUtil::IsSingleUseEdge(shl.Conv(),cornerVtHd,connVtHd[0]) ||
		   YSTRUE!=YsShellExt_TopologyUtil::IsSingleUseEdge(shl.Conv(),cornerVtHd,connVtHd[1]))
		{
			return YSERR;
		}

		// Either connVtHd[0] must be between connVtHd[1] and cornerVtHd or connVtHd[1] must be between connVtHd[0] and cornerVtHd
		YSBOOL inBetweenCheck=YSFALSE;
		for(int i=0; i<2; ++i)
		{
			const YsVec3 edVtPos[2]=
			{
				shl.GetVertexPosition(connVtHd[1-i]),
				shl.GetVertexPosition(cornerVtHd)
			};
			const YsVec3 tstPos=shl.GetVertexPosition(connVtHd[i]);
			if(YSTRUE==YsCheckInBetween3(tstPos,edVtPos))
			{
				inBetweenCheck=YSTRUE;
				break;
			}
		}
		if(YSTRUE!=inBetweenCheck)
		{
			return YSERR;
		}


		YsShellExtEdit_TopologyUtil topoUtil;

		YsShellVertexHandle edVtHd[2],toInsert;
		if(shl.GetEdgeLength(cornerVtHd,connVtHd[0])<shl.GetEdgeLength(cornerVtHd,connVtHd[1]))
		{
			edVtHd[0]=cornerVtHd;
			edVtHd[1]=connVtHd[1];
			toInsert=connVtHd[0];
		}
		else
		{
			edVtHd[0]=cornerVtHd;
			edVtHd[1]=connVtHd[0];
			toInsert=connVtHd[1];
		}
		YsShellExtEdit_InsertVertexOnEdge(shl,edVtHd,toInsert);
		return UpdateCornerAfterStapling(cornerVtHd,shl.Conv());
	}
	return YSERR;
}
Example #2
0
YSRESULT YsClipLineSeg3
   (YsVec3 &newP1,YsVec3 &newP2,const YsVec3 &p1,const YsVec3 &p2,const YsVec3 &range1,const YsVec3 &range2)
{
	int j,nInComp;
	YsVec3 min,max;
	YsBoundingBoxMaker3 bbx;
	bbx.Begin(range1);
	bbx.Add(range2);
	bbx.Get(min,max);

	nInComp=0;
	for(j=0; j<3; j++)
	{
		if(min.GetValue()[j]<=p1.GetValue()[j] && p1.GetValue()[j]<=max.GetValue()[j] &&
		   min.GetValue()[j]<=p2.GetValue()[j] && p2.GetValue()[j]<=max.GetValue()[j])
		{
			nInComp++;
		}

		if(p1.GetValue()[j]<min.GetValue()[j] &&
		   p2.GetValue()[j]<min.GetValue()[j])
		{
			return YSERR;
		}
		if(p1.GetValue()[j]>max.GetValue()[j] &&
		   p2.GetValue()[j]>max.GetValue()[j])
		{
			return YSERR;
		}
	}

	if(nInComp==3)
	{
		newP1=p1;
		newP2=p2;
		return YSOK;
	}

	YsVec3 c1,c2;
	if(YsClipInfiniteLine3(c1,c2,p1,p2-p1,min,max)==YSOK)
	{
		if(YsCheckInBetween3(c1,p1,p2)==YSTRUE &&
		   YsCheckInBetween3(c2,p1,p2)==YSTRUE)
		{
			newP1=c1;
			newP2=c2;
			return YSOK;
		}
		else if(YsCheckInBetween3(c1,p1,p2)==YSTRUE)
		{
			// p1-c1 or c1-p2
			if(YsCheckInBetween3(p1,c1,c2)==YSTRUE)
			{
				newP1=p1;
				newP2=c1;
			}
			else
			{
				newP1=c1;
				newP2=p2;
			}
			return YSOK;
		}
		else if(YsCheckInBetween3(c2,p1,p2)==YSTRUE)
		{
			// p1-c2 or c2-p2
			if(YsCheckInBetween3(p1,c1,c2)==YSTRUE)
			{
				newP1=p1;
				newP2=c2;
			}
			else
			{
				newP1=c2;
				newP2=p2;
			}
			return YSOK;
		}
		else
		{
			return YSERR;
		}
	}
	else
	{
		return YSERR;
	}
}
Example #3
0
YSBOOL YsCollisionOfPolygon::CheckCollision(YsVec3 &firstFound) const
{
	int i,j;
	const YsVec3 *v1,*v2,*u1,*u2;
	YSSIDE is;
	YsVec3 crs;

	if(YsCheckBoundingBoxCollision3(p1min,p1max,p2min,p2max)==YSTRUE)
 	{
		if(np1>=2 || np2>=3) // Polygon/LineSeg1 vs Plane2
		{
			for(i=0; i<np1; i++)
			{
				v1=&p1[i];
				v2=&p1[(i+1)%np1];
				if(pln2.GetPenetration(crs,*v1,*v2)==YSOK)
				{
					is=CheckInsideOfPolygon2(crs);
					// is=YsCheckInsidePolygon3(crs,np2,p2);
					if(is==YSINSIDE || is==YSBOUNDARY)
					{
						firstFound=crs;
						return YSTRUE;
					}
				}
				if(pln2.CheckOnPlane(*v1)==YSTRUE)
				{
					is=CheckInsideOfPolygon2(*v1);
					// is=YsCheckInsidePolygon3(*v1,np2,p2);
					if(is==YSINSIDE || is==YSBOUNDARY)
					{
						firstFound=*v1;
						return YSTRUE;
					}
				}
			}
		}
		if(np1>=3 || np2>=2) // Polygon/LineSeg2 vs Plane1
		{
			for(i=0; i<np2; i++)
			{
				v1=&p2[i];
				v2=&p2[(i+1)%np2];
				if(pln1.GetPenetration(crs,*v1,*v2)==YSOK)
				{
					is=CheckInsideOfPolygon1(crs);
					// is=YsCheckInsidePolygon3(crs,np1,p1);
					if(is==YSINSIDE || is==YSBOUNDARY)
					{
						firstFound=crs;
						return YSTRUE;
					}
				}
				if(pln1.CheckOnPlane(*v1)==YSTRUE)
				{
					is=CheckInsideOfPolygon1(*v1);
					// is=YsCheckInsidePolygon3(*v1,np1,p1);
					if(is==YSINSIDE || is==YSBOUNDARY)
					{
						firstFound=*v1;
						return YSTRUE;
					}
				}
			}
		}

		// If two edges are close to each other...
		// Threshold is 1% of longer edge.
		for(i=0; i<np1; i++)
		{
			v1=&p1[i];
			v2=&p1[(i+1)%np1];

			for(j=0; j<np2; j++)
			{
				u1=&p2[j];
				u2=&p2[(j+1)%np2];

				YsVec3 n1,n2;
				if(YsGetNearestPointOfTwoLine(n1,n2,*v1,*v2,*u1,*u2)==YSOK &&
				   YsCheckInBetween3(n1,*v1,*v2)==YSTRUE &&
				   YsCheckInBetween3(n2,*u1,*u2)==YSTRUE)
				{
					if((n1-n2).GetSquareLength()<YsToleranceSqr)
					{
						firstFound=n1;
						return YSTRUE;
					}
				}
			}
		}
	}
	return YSFALSE;
}