Пример #1
0
eRETURN_TYPE DoIntersect(const cTRIANGLE3 &triangle,
				     const cSEGMENT3 &lseg, BOOL doDebug)
{

  if(DoIntersect(triangle.ComputeBbox(),
				  lseg.ComputeBbox()) == FAILURE)
    return FAILURE;

  cPLANE3 supportingPlane = triangle.SupportingPlane();
  cSEGMENT3 resultingSegment;
  cPOINT3 resultingPoint;
  if (doDebug){
	  printf("supportingPlane: ");
	  supportingPlane.Print();
  }
  if(DoIntersect(supportingPlane, lseg) != SUCCESS)
    return FAILURE;

  eRETURN_TYPE result = Intersection(supportingPlane, lseg,
						  resultingPoint, resultingSegment);


  eCOORD maxCoord = supportingPlane.Normal().AbsMaxCoord();

  cTRIANGLE2 transformedTriangle(triangle.Vertex(0).DropCoord(maxCoord),
				 triangle.Vertex(1).DropCoord(maxCoord),
				 triangle.Vertex(2).DropCoord(maxCoord));

  if(result == RT_POINT3) { //Intersection is a point.
    cPOINT2 transformedPoint = resultingPoint.DropCoord(maxCoord);
    if(transformedTriangle.IsPointInside(transformedPoint))
      return SUCCESS;
    else
      return FAILURE;
  }
  else {
    //Intersection is a line segment.
    //The segment is on the triangle plane.
    //Check for actual intersection.
    //Transform the problem to 2-D problem and try to compute the result.
    cSEGMENT2 transformedSegment(lseg.Source().DropCoord(maxCoord),
						  lseg.Target().DropCoord(maxCoord));

    if(DoIntersect(transformedTriangle,
				    transformedSegment) == SUCCESS)
      return SUCCESS;

    return FAILURE;
  }

  ASSERT(0); //Should be decided even before it gets here.

  return FAILURE;
}
Пример #2
0
eRETURN_TYPE DoIntersect(const cTRIANGLE3 &triangle1,
			 const cTRIANGLE3 &triangle2)
{
  for(INT i = 0; i < 3; i ++)
    if( DoIntersect(triangle2, triangle1.Segment(i)) == SUCCESS )
        return SUCCESS;

  for(INT i = 0; i < 3; i ++)
    if( DoIntersect(triangle1, triangle2.Segment(i)) == SUCCESS )
      return SUCCESS;

  return FAILURE;
}
Пример #3
0
eRETURN_TYPE DoIntersect(const cTRIANGLE2 &triangle,
					    const cSEGMENT2 &segment)
{
  if(DoIntersect(triangle.ComputeBbox(),
				  segment.ComputeBbox()) == FAILURE)
    return FAILURE;

  if(triangle.IsPointInside(segment.Source()))
    return SUCCESS;

  if(triangle.IsPointInside(segment.Target()))
    return SUCCESS;

  for(INT i = 0; i < 3 ; i++){
    if(DoIntersect(triangle.Edge(i), segment) == SUCCESS)
      return SUCCESS;
  }

  return FAILURE;
}
Пример #4
0
eRETURN_TYPE DoIntersect(const cSEGMENT2 &segment1,
				     const cSEGMENT2 &segment2)
{


  if(DoIntersect(segment1.ComputeBbox(),
				  segment2.ComputeBbox()) == FAILURE)
    return FAILURE;

  REAL distance[4];

  //segment1
  cLINE2 segment2Line = segment2.SupportingLine();

  distance[0] = segment2Line.SignedDistance(segment1.Source());

  if(fabs(distance[0]) < cLIMITS::Tolerance())
    distance[0] = 0.0;

  distance[1] = segment2Line.SignedDistance(segment1.Target());

  if(fabs(distance[1]) < cLIMITS::Tolerance())
    distance[1] = 0.0;

  REAL seg1Distance = distance[0]*distance[1];
  if(seg1Distance > 0.0)
    return FAILURE;

  //segment2
  cLINE2 segment1Line = segment1.SupportingLine();

  distance[2] = segment1Line.SignedDistance(segment2.Source());

  if(fabs(distance[2]) < cLIMITS::Tolerance())
    distance[2] = 0.0;

  distance[3] = segment1Line.SignedDistance(segment2.Target());

  if(fabs(distance[3]) < cLIMITS::Tolerance())
    distance[3] = 0.0;

  REAL seg2Distance = distance[2]*distance[3];
  if(seg2Distance > 0.0)
    return FAILURE;

  if(seg1Distance < 0.0 && seg2Distance < 0.0)
    return SUCCESS;

  //Deciding degenerate cases.
  if(distance[0] == 0.0)
    if(segment2.IsOnSegment(segment1.Source()))
      return SUCCESS;

  if(distance[1] == 0.0)
    if(segment2.IsOnSegment(segment1.Target()))
      return SUCCESS;

  if(distance[2] == 0.0)
    if(segment1.IsOnSegment(segment2.Source()))
      return SUCCESS;

  if(distance[3] == 0.0)
    if(segment1.IsOnSegment(segment2.Target()))
      return SUCCESS;

  return FAILURE;

}
Пример #5
0
void SWrapMod::ModifyObject(
		TimeValue t, ModContext &mc, ObjectState *os, INode *node)
{	SWrapObject *obj = (SWrapObject *)GetWSMObject(t);
	INode *pnode;
	TriObject *towrapOb=NULL;Object *pobj=NULL;
	if (obj) pnode=obj->custnode;
	if (obj && nodeRef && pnode) 
	{	Interval valid = FOREVER;
		if (!obj->cmValid.InInterval(t))
		{   pobj = pnode->EvalWorldState(t).obj;
			obj->cmValid=pobj->ObjectValidity(t);
			Matrix3 tm=pnode->GetObjectTM(t,&(obj->cmValid));
			TriObject *wrapOb=IsUseable(pobj,t);
			if (wrapOb)
			{ if (obj->cmesh) delete obj->cmesh; 
			  obj->cmesh=new Mesh;
			   obj->cmesh->DeepCopy(&wrapOb->GetMesh(),
			     PART_GEOM|SELECT_CHANNEL|PART_SUBSEL_TYPE|PART_TOPO|TM_CHANNEL);
			   for (int ic=0;ic<obj->cmesh->getNumVerts();ic++)
			     obj->cmesh->verts[ic]=obj->cmesh->verts[ic]*tm;
			  GetVFLst(obj->cmesh,&obj->vnorms,&obj->fnorms);
			  if (wrapOb!=pobj) wrapOb->DeleteThis();
			}
 		}
		if (!obj->cmesh) return;
		if ((obj->cmesh->getNumVerts()==0)||(obj->cmesh->getNumFaces()==0)) 
			return;		 
//		Matrix3 invtm=Inverse(obj->tm);
		valid=obj->cmValid;
		Matrix3 ctm;
		ctm = nodeRef->GetNodeTM(t,&valid);
		Ray ray;
		Point3 v=-ctm.GetRow(2);
//		Matrix3 nooff=invtm;nooff.NoTrans();
		ray.dir=v;//*nooff;
		int selverts;
		float kdef,standoff;
		obj->pblock->GetValue(PB_USESELVERTS,t,selverts,valid);
		obj->pblock->GetValue(PB_KIDEFAULT,t,kdef,valid);
		obj->pblock->GetValue(PB_STANDOFF,t,standoff,valid);
		BezierShape stowrapOb;
		int found=0;
		Matrix3 towtm(1);
		if (os->GetTM()) 
			towtm=*(os->GetTM());
		Matrix3 invtowtm=Inverse(towtm);
		Point3 vert;
		Class_ID cid=os->obj->ClassID(),es=EDITABLE_SURF_CLASS_ID,efp=FITPOINT_PLANE_CLASS_ID,ecv=EDITABLE_CVCURVE_CLASS_ID,ecfp=EDITABLE_FPCURVE_CLASS_ID;
		if (((cid==EDITABLE_SURF_CLASS_ID)||(cid==FITPOINT_PLANE_CLASS_ID))||((cid==EDITABLE_CVCURVE_CLASS_ID)||(cid==EDITABLE_FPCURVE_CLASS_ID)))
		{ Object* nurbobj=os->obj;
		  int num=nurbobj->NumPoints();
		  for (int i=0;i<num;i++)
		  {	vert=DoIntersect(nurbobj->GetPoint(i)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
		    nurbobj->SetPoint(i,(vert*invtowtm));
		  }
		}
#ifndef NO_PATCHES
		else if (os->obj->IsSubClassOf(patchObjectClassID))
		{ PatchObject* patchob=(PatchObject *)os->obj;
		  PatchMesh *pm=&(patchob->patch);
		  int nv=pm->getNumVerts();
		  BitArray sel = pm->VertSel();
		  for (int i=0;i<nv;i++)
		  { if (!selverts||sel[i])
			{ vert=DoIntersect(pm->getVert(i).p*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
		      vert=vert*invtowtm;
		      pm->setVert(i,vert);
			}
		  }
/*		  pm->buildLinkages();
		  pm->computeInteriors();
		  pm->InvalidateGeomCache();*/
		}
#endif // NO_PATCHES
		else if (towrapOb=IsUseable(os->obj,t))
		{	Point3 tvector;
			float dist;
			float *vssel = NULL;
		  if (selverts) 
			  vssel = towrapOb->GetMesh().getVSelectionWeights();
		  for (int i=0;i<towrapOb->GetMesh().getNumVerts();i++)
		  { 
				if ((!selverts)||(towrapOb->GetMesh().vertSel[i])
							   ||(vssel&&vssel[i]))
				{
					vert = DoIntersect(towrapOb->GetMesh().verts[i]*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms); 
					vert = vert*invtowtm;
					if (vssel&&vssel[i])
					{
						tvector = vert - towrapOb->GetMesh().verts[i];
						dist = Length(tvector);
						if ((float)fabs(dist) > EPSILON)
							tvector = tvector/dist;
						else
							tvector = Zero;
						vert = towrapOb->GetMesh().verts[i] + dist*vssel[i]*tvector;
					}
					towrapOb->GetMesh().verts[i] = vert;
				}
		  }
		  if (towrapOb!=os->obj) 
			  towrapOb->DeleteThis();
		}
		else if((os->obj->IsSubClassOf(splineShapeClassID))||(os->obj->CanConvertToType(splineShapeClassID))) 
		{ SplineShape *attSplShape = (SplineShape *)os->obj->ConvertToType(t,splineShapeClassID);
		if (attSplShape) 
		{ stowrapOb=attSplShape->shape;
		  for (int poly=0; poly<stowrapOb.splineCount; ++poly)
		  { Spline3D *spline = stowrapOb.GetSpline(poly);
			int verts = spline->Verts();
			int knots = spline->KnotCount();
			BitArray sel = stowrapOb.VertexTempSel(poly);
			Point3 cknot,cknot2;
			{ for(int k=0; k<knots; ++k) 
			  {	int vert = k * 3 + 1;
				if (!selverts||sel[vert])  
				{ cknot=DoIntersect(spline->GetKnotPoint(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
				  attSplShape->shape.SetVert(poly,vert,cknot*invtowtm);
				  if (found)
				  { int knotType = spline->GetKnotType(k);
				    if(knotType & KTYPE_BEZIER) 
				    { cknot2= DoIntersect(spline->GetInVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
					attSplShape->shape.SetVert(poly,vert-1,(found?cknot2:cknot)*invtowtm);
				  	  cknot2= DoIntersect(spline->GetOutVec(k)*towtm,ray,obj->cmesh,kdef,standoff,&found,v,obj->vnorms,obj->fnorms);
					  attSplShape->shape.SetVert(poly,vert+1,(found?cknot2:cknot)*invtowtm);
					}
				  }
				}
			  }
			}
		  }
		  if (attSplShape!=os->obj) attSplShape->DeleteThis();
		}
	  }
//	os->obj->PointsWereChanged();
	os->obj->UpdateValidity(GEOM_CHAN_NUM,valid);	
//	NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

  }
}