Ejemplo n.º 1
0
void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation)
{
	orientation = !orientation;
	ViewEdge::vertex_iterator v;
	ViewEdge::vertex_iterator vend;
	ViewEdge::vertex_iterator vfirst;
	Vec3r previous, current;
	if (true == orientation) {
		v = iViewEdge->vertices_begin();
		vfirst = v;
		vend = iViewEdge->vertices_end();
	}
	else {
		v = iViewEdge->vertices_last();
		vfirst = v;
		vend = iViewEdge->vertices_end();
	}

	if (!_Vertices.empty()) {
		previous = _Vertices.front()->point2d();
		if (orientation)
			++v;
		else
			--v;
		// Ensure the continuity of underlying FEdges
		CurvePoint *cp = _Vertices.front(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f);
		SVertex *sv_last = cp->A();
		SVertex *sv_curr = (*v);
		FEdge *fe = (orientation) ? iViewEdge->fedgeA() : iViewEdge->fedgeB();
		FEdge *fe2 = fe->duplicate();
		fe2->setVertexA(sv_curr);
		fe2->setVertexB(sv_last);
		sv_last->AddFEdge(fe2);
		sv_curr->AddFEdge(fe2);
		sv_curr->shape()->AddEdge(fe2);
	}
	else {
		previous = (*v)->point2d();
	}
	do {
		current = (*v)->point2d();
		Curve::push_vertex_front((*v));
		//_Length += (current - previous).norm();
		previous = current;
		if (orientation)
			++v;
		else
			--v;
	} while ((v != vend) && (v != vfirst));

	if (v == vfirst) {
		//Add last one:
		current = (*v)->point2d();
		Curve::push_vertex_front(*v);
		//_Length += (current - previous).norm();
	}

	if (!_fedgeB)
		_fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA();
}
Ejemplo n.º 2
0
 Vec2f Orientation2DF1D::operator()(Interface1D& inter) {
   FEdge * fe = dynamic_cast<FEdge*>(&inter);
   if(fe){
     Vec3r res = fe->orientation2d();
     return Vec2f(res[0], res[1]);
   }
   return integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
 }
Ejemplo n.º 3
0
void ViewEdge::UpdateFEdges()
{
	FEdge *currentEdge = _FEdgeA;
	do {
		currentEdge->setViewEdge(this);
		currentEdge = currentEdge->nextEdge();
	} while ((currentEdge != NULL) && (currentEdge != _FEdgeB));
	// last one
	_FEdgeB->setViewEdge(this);
}
Ejemplo n.º 4
0
int QuantitativeInvisibilityF1D::operator()(Interface1D &inter)
{
  ViewEdge *ve = dynamic_cast<ViewEdge *>(&inter);
  if (ve) {
    result = ve->qi();
    return 0;
  }
  FEdge *fe = dynamic_cast<FEdge *>(&inter);
  if (fe) {
    result = fe->qi();
    return 0;
  }
  result = integrate(_func, inter.verticesBegin(), inter.verticesEnd(), _integration);
  return 0;
}
Ejemplo n.º 5
0
const ViewEdge *ViewMap::getClosestViewEdge(real x, real y) const
{
	// find the closest of this candidates:
	real minDist = DBL_MAX;
	FEdge *winner = NULL;
	for (fedges_container::const_iterator fe = _FEdges.begin(), feend = _FEdges.end(); fe != feend; fe++) {
		Vec2d A((*fe)->vertexA()->point2D()[0], (*fe)->vertexA()->point2D()[1]);
		Vec2d B((*fe)->vertexB()->point2D()[0], (*fe)->vertexB()->point2D()[1]);
		real dist = GeomUtils::distPointSegment<Vec2r>(Vec2r(x, y), A, B);
		if (dist < minDist) {
			minDist = dist;
			winner = (*fe);
		}
	}
	if (!winner)
		return NULL;

	return winner->viewedge();
}
Ejemplo n.º 6
0
void CulledOccluderSource::cullViewEdges(ViewMap& viewMap, bool extensiveFEdgeSearch)
{
	// Cull view edges by marking them as non-displayable.
	// This avoids the complications of trying to delete edges from the ViewMap.

	// Non-displayable view edges will be skipped over during visibility calculation.

	// View edges will be culled according to their position w.r.t. the viewport proscenium (viewport + 5% border,
	// or some such).

	// Get proscenium boundary for culling
	real viewProscenium[4];
	GridHelpers::getDefaultViewProscenium(viewProscenium);
	real prosceniumOrigin[2];
	prosceniumOrigin[0] = (viewProscenium[1] - viewProscenium[0]) / 2.0;
	prosceniumOrigin[1] = (viewProscenium[3] - viewProscenium[2]) / 2.0;
	if (G.debug & G_DEBUG_FREESTYLE) {
		cout << "Proscenium culling:" << endl;
		cout << "Proscenium: [" << viewProscenium[0] << ", " << viewProscenium[1] << ", " << viewProscenium[2] <<
		        ", " << viewProscenium[3] << "]"<< endl;
		cout << "Origin: [" << prosceniumOrigin[0] << ", " << prosceniumOrigin[1] << "]"<< endl;
	}

	// A separate occluder proscenium will also be maintained, starting out the same as the viewport proscenium, and
	// expanding as necessary so that it encompasses the center point of at least one feature edge in each
	// retained view edge.
	// The occluder proscenium will be used later to cull occluding triangles before they are inserted into the Grid.
	// The occluder proscenium starts out the same size as the view proscenium
	GridHelpers::getDefaultViewProscenium(occluderProscenium);

	// XXX Freestyle is inconsistent in its use of ViewMap::viewedges_container and vector<ViewEdge*>::iterator.
	// Probably all occurences of vector<ViewEdge*>::iterator should be replaced ViewMap::viewedges_container
	// throughout the code.
	// For each view edge
	ViewMap::viewedges_container::iterator ve, veend;

	for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
		// Overview:
		//    Search for a visible feature edge
		//    If none: mark view edge as non-displayable
		//    Otherwise:
		//        Find a feature edge with center point inside occluder proscenium.
		//        If none exists, find the feature edge with center point closest to viewport origin.
		//            Expand occluder proscenium to enclose center point.

		// For each feature edge, while bestOccluderTarget not found and view edge not visibile
		bool bestOccluderTargetFound = false;
		FEdge *bestOccluderTarget = NULL;
		real bestOccluderDistance = 0.0;
		FEdge *festart = (*ve)->fedgeA();
		FEdge *fe = festart;
		// All ViewEdges start culled
		(*ve)->setIsInImage(false);

		// For simple visibility calculation: mark a feature edge that is known to have a center point inside
		// the occluder proscenium. Cull all other feature edges.
		do {
			// All FEdges start culled
			fe->setIsInImage(false);

			// Look for the visible edge that can most easily be included in the occluder proscenium.
			if (!bestOccluderTargetFound) {
				// If center point is inside occluder proscenium,
				if (insideProscenium(occluderProscenium, fe->center2d())) {
					// Use this feature edge for visibility deterimination
					fe->setIsInImage(true);
					expandGridSpaceOccluderProscenium(fe);
					// Mark bestOccluderTarget as found
					bestOccluderTargetFound = true;
					bestOccluderTarget = fe;
				}
				else {
					real d = distance2D(fe->center2d(), prosceniumOrigin);
					// If center point is closer to viewport origin than current target
					if (bestOccluderTarget == NULL || d < bestOccluderDistance) {
						// Then store as bestOccluderTarget
						bestOccluderDistance = d;
						bestOccluderTarget = fe;
					}
				}
			}

			// If feature edge crosses the view proscenium
			if (!(*ve)->isInImage() && crossesProscenium(viewProscenium, fe)) {
				// Then the view edge will be included in the image
				(*ve)->setIsInImage(true);
			}
			fe = fe->nextEdge();
		} while (fe != NULL && fe != festart && !(bestOccluderTargetFound && (*ve)->isInImage()));

		// Either we have run out of FEdges, or we already have the one edge we need to determine visibility
		// Cull all remaining edges.
		while (fe != NULL && fe != festart) {
			fe->setIsInImage(false);
			fe = fe->nextEdge();
		}

		// If bestOccluderTarget was not found inside the occluder proscenium, 
		// we need to expand the occluder proscenium to include it.
		if ((*ve)->isInImage() && bestOccluderTarget != NULL && ! bestOccluderTargetFound) {
			// Expand occluder proscenium to enclose bestOccluderTarget
			Vec3r point = bestOccluderTarget->center2d();
			if (point[0] < occluderProscenium[0]) {
				occluderProscenium[0] = point[0];
			}
			else if (point[0] > occluderProscenium[1]) {
				occluderProscenium[1] = point[0];
			}
			if (point[1] < occluderProscenium[2]) {
				occluderProscenium[2] = point[1];
			}
			else if (point[1] > occluderProscenium[3]) {
				occluderProscenium[3] = point[1];
			}
			// Use bestOccluderTarget for visibility determination
			bestOccluderTarget->setIsInImage(true);
		}
	}

	// We are done calculating the occluder proscenium.
	// Expand the occluder proscenium by an epsilon to avoid rounding errors.
	const real epsilon = 1.0e-6;
	occluderProscenium[0] -= epsilon;
	occluderProscenium[1] += epsilon;
	occluderProscenium[2] -= epsilon;
	occluderProscenium[3] += epsilon;

	// For "Normal" or "Fast" style visibility computation only:

	// For more detailed visibility calculation, make a second pass through the view map, marking all feature edges
	// with center points inside the final occluder proscenium. All of these feature edges can be considered during
	// visibility calculation.

	// So far we have only found one FEdge per ViewEdge. The "Normal" and "Fast" styles of visibility computation
	// want to consider many FEdges for each ViewEdge.
	// Here we re-scan the view map to find any usable FEdges that we skipped on the first pass, or that have become
	// usable because the occluder proscenium has been expanded since the edge was visited on the first pass.
	if (extensiveFEdgeSearch) {
		// For each view edge,
		for (ve = viewMap.ViewEdges().begin(), veend = viewMap.ViewEdges().end(); ve != veend; ve++) {
			if (!(*ve)->isInImage()) {
				continue;
			}
			// For each feature edge,
			FEdge *festart = (*ve)->fedgeA();
			FEdge *fe = festart;
			do {
				// If not (already) visible and center point inside occluder proscenium, 
				if (!fe->isInImage() && insideProscenium(occluderProscenium, fe->center2d())) {
					// Use the feature edge for visibility determination
					fe->setIsInImage(true);
					expandGridSpaceOccluderProscenium(fe);
				}
				fe = fe->nextEdge();
			} while (fe != NULL && fe != festart);
		}
	}

	// Up until now, all calculations have been done in camera space.
	// However, the occluder source's iteration and the grid that consumes the occluders both work in gridspace,
	// so we need a version of the occluder proscenium in gridspace.
	// Set the gridspace occlude proscenium
}
ViewEdge *ViewEdgeXBuilder::BuildSharpViewEdge(const OWXEdge& iWEdge)
{
	// Start a new sharp chain edges
	ViewEdge *newVEdge = new ViewEdge;
	newVEdge->setId(_currentViewId);
	++_currentViewId;
	unsigned size = 0;

	_pCurrentVShape->AddEdge(newVEdge);

	// Find first edge:
	OWXEdge firstWEdge = iWEdge;
	/* OWXEdge previousWEdge = firstWEdge; */ /* UNUSED */
	OWXEdge currentWEdge = firstWEdge;
	list<OWXEdge> edgesChain;
#if 0 /* TK 02-Sep-2012 Experimental fix for incorrect view edge visibility. */
	// bidirectional chaining
	// first direction:
	while (!stopSharpViewEdge(currentWEdge.e)) {
		edgesChain.push_back(currentWEdge);
		++size;
		currentWEdge.e->userdata = (void *)1; // processed
		// Find the next edge!
		currentWEdge = FindNextWEdge(currentWEdge);
	}
	OWXEdge endWEdge = edgesChain.back();
	// second direction
	currentWEdge = FindPreviousWEdge(firstWEdge);
	while (!stopSharpViewEdge(currentWEdge.e)) {
		edgesChain.push_front(currentWEdge);
		++size;
		currentWEdge.e->userdata = (void *)1; // processed
		// Find the previous edge!
		currentWEdge = FindPreviousWEdge(currentWEdge);
	}
#else
	edgesChain.push_back(currentWEdge);
	++size;
	currentWEdge.e->userdata = (void *)1; // processed
	OWXEdge endWEdge = edgesChain.back();
#endif
	firstWEdge = edgesChain.front();

	// build FEdges
	FEdge *feprevious = NULL;
	FEdge *fefirst = NULL;
	FEdge *fe = NULL;
	for (list<OWXEdge>::iterator we = edgesChain.begin(), weend = edgesChain.end(); we != weend; ++we) {
		fe = BuildSharpFEdge(feprevious, (*we));
		fe->setViewEdge(newVEdge);
		if (!fefirst)
			fefirst = fe;
		feprevious = fe;
	}
	// Store the chain starting edge:
	_pCurrentSShape->AddChain(fefirst);
	newVEdge->setNature(iWEdge.e->nature());
	newVEdge->setFEdgeA(fefirst);
	newVEdge->setFEdgeB(fe);

	// is it a closed loop ?
	if ((firstWEdge == endWEdge) && (size != 1)) {
		fefirst->setPreviousEdge(fe);
		fe->setNextEdge(fefirst);
		newVEdge->setA(0);
		newVEdge->setB(0);
	}
	else {
		ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
		ViewVertex *vvb = MakeViewVertex(fe->vertexB());

		((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
		((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);

		newVEdge->setA(vva);
		newVEdge->setB(vvb);
	}

	return newVEdge;
}
ViewEdge *ViewEdgeXBuilder::BuildSmoothViewEdge(const OWXFaceLayer& iFaceLayer)
{
	// Find first edge:
	OWXFaceLayer first = iFaceLayer;
	OWXFaceLayer currentFace = first;

	// bidirectional chaining.
	// first direction
	list<OWXFaceLayer> facesChain;
	unsigned size = 0;
	while (!stopSmoothViewEdge(currentFace.fl)) {
		facesChain.push_back(currentFace);
		++size;
		currentFace.fl->userdata = (void *)1; // processed
		// Find the next edge!
		currentFace = FindNextFaceLayer(currentFace);
	}
	OWXFaceLayer end = facesChain.back();
	// second direction
	currentFace = FindPreviousFaceLayer(first);
	while (!stopSmoothViewEdge(currentFace.fl)) {
		facesChain.push_front(currentFace);
		++size;
		currentFace.fl->userdata = (void *)1; // processed
		// Find the previous edge!
		currentFace = FindPreviousFaceLayer(currentFace);
	}
	first = facesChain.front();

	if (iFaceLayer.fl->nature() & Nature::RIDGE) {
		if (size < 4) {
			return 0;
		}
	}

	// Start a new chain edges
	ViewEdge *newVEdge = new ViewEdge;
	newVEdge->setId(_currentViewId);
	++_currentViewId;

	_pCurrentVShape->AddEdge(newVEdge);

	// build FEdges
	FEdge *feprevious = NULL;
	FEdge *fefirst = NULL;
	FEdge *fe = NULL;
	for (list<OWXFaceLayer>::iterator fl = facesChain.begin(), flend = facesChain.end(); fl != flend; ++fl) {
		fe = BuildSmoothFEdge(feprevious, (*fl));
		if (feprevious && fe == feprevious)
			continue;
		fe->setViewEdge(newVEdge);
		if (!fefirst)
			fefirst = fe;
		feprevious = fe;
	}
	// Store the chain starting edge:
	_pCurrentSShape->AddChain(fefirst);
	newVEdge->setNature(iFaceLayer.fl->nature());
	newVEdge->setFEdgeA(fefirst);
	newVEdge->setFEdgeB(fe);

	// is it a closed loop ?
	if ((first == end) && (size != 1)) {
		fefirst->setPreviousEdge(fe);
		fe->setNextEdge(fefirst);
		newVEdge->setA(0);
		newVEdge->setB(0);
	}
	else {
		ViewVertex *vva = MakeViewVertex(fefirst->vertexA());
		ViewVertex *vvb = MakeViewVertex(fe->vertexB());

		((NonTVertex *)vva)->AddOutgoingViewEdge(newVEdge);
		((NonTVertex *)vvb)->AddIncomingViewEdge(newVEdge);

		newVEdge->setA(vva);
		newVEdge->setB(vvb);
	}

	return newVEdge;
}
Ejemplo n.º 9
0
  /* splits an edge into 2 edges. The new vertex and edge are added
   *  to the sshape list of vertices and edges
   *  a new chain is also created.
   *  returns the new edge.
   *    ioEdge
   *      The edge that gets splitted
   *    newpoint
   *      x,y,z coordinates of the new point.
   */
FEdge* SShape::SplitEdgeIn2(FEdge* ioEdge, SVertex * ioNewVertex)
    {
      SVertex *A = ioEdge->vertexA();
      SVertex *B = ioEdge->vertexB();

      
      // We split edge AB into AA' and A'B. A' and A'B are created.
      // AB becomes (address speaking) AA'. B is updated.
      //--------------------------------------------------
      
      // a new edge, A'B is created.
      FEdge *newEdge;
      if (ioEdge->getNature() & Nature::ALL_INTERSECTION)
	{
	  newEdge = new FEdgeIntersection(ioNewVertex, B);
	  FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge);
	  FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(ioEdge);
	  se->SetMaterialIndex(fes->materialIndex());
	  se->SetFaces(fes->getFace1(), fes->getFace2());

#ifdef DEBUG_INTERSECTION
	  void debugFES(FEdgeIntersection * newEdge);
	  
	  debugFES(se);
	  debugFES(fes);
#endif

	}else
      if(ioEdge->isSmooth()){
        newEdge = new FEdgeSmooth(ioNewVertex, B);
        FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
        FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(ioEdge);
        se->SetMaterialIndex(fes->materialIndex());
	se->SetFace(fes->face());
      }else{
        newEdge = new FEdgeSharp(ioNewVertex, B);
        FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
        FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(ioEdge);
        se->SetaMaterialIndex(fes->aMaterialIndex());
        se->SetbMaterialIndex(fes->bMaterialIndex());
	se->SetEdge(fes->edge());
      }
      newEdge->SetNature(ioEdge->getNature());
      
      
      if(ioEdge->nextEdge() != 0)
        ioEdge->nextEdge()->SetPreviousEdge(newEdge);

      // update edge A'B for the next pointing edge
      newEdge->SetNextEdge(ioEdge->nextEdge());
      // update edge A'B for the previous pointing edge
      newEdge->SetPreviousEdge(0); // because it is now a ViewVertex
      Id id(ioEdge->getId().getFirst(), ioEdge->getId().getSecond()+1);
      newEdge->SetId(ioEdge->getId());
      ioEdge->SetId(id);
   
      // update edge AA' for the next pointing edge
      ioEdge->SetNextEdge(0); // because it is now a TVertex

      // update vertex pointing edges list:
      // -- vertex B --
      B->Replace(ioEdge, newEdge);
      // -- vertex A' --
      ioNewVertex->AddFEdge(ioEdge);
      ioNewVertex->AddFEdge(newEdge);

      // to build a new chain:
      AddChain(newEdge);
      AddEdge(newEdge); // FIXME ??
      
      // The edge AB becomes edge AA'.
      ioEdge->SetVertexB(ioNewVertex);

      // added by Aaron (looks redundant now, can probably be deleted)
      newEdge->SetVertexA(ioNewVertex);
      newEdge->SetVertexB(B);
      
      //      if(ioEdge->isSmooth()){
      //  ((FEdgeSmooth*)newEdge)->SetFace(((FEdgeSmooth*)ioEdge)->face());
      //}
      

      return newEdge;
    }
Ejemplo n.º 10
0
  /* splits an edge into several edges. 
   *  The edge's vertices are passed rather than 
   *  the edge itself. This way, all feature edges (SILHOUETTE,
   *  CREASE, BORDER) are splitted in the same time.
   *  The processed edges are flagged as done (using the userdata
   *  flag).One single new vertex is created whereas 
   *  several splitted edges might created for the different 
   *  kinds of edges. These new elements are added to the lists
   *  maintained by the shape.
   *  new chains are also created.
   *    ioA
   *      The first vertex for the edge that gets splitted
   *    ioB
   *      The second vertex for the edge that gets splitted
   *    iParameters
   *      A vector containing 2D real vectors indicating the parameters
   *      giving the intersections coordinates in 3D and in 2D.
   *      These intersections points must be sorted from B to A.
   *      Each parameter defines the intersection point I as I=A+T*AB.
   *      T<0 and T>1 are then incorrect insofar as they give intersections
   *      points that lie outside the segment.
   *    ioNewEdges
   *      The edges that are newly created (the initial edges are not 
   *      included) are added to this list.
   */
void SShape::SplitEdge(FEdge *fe, const vector<Vec2r>& iParameters, vector<FEdge*>& ioNewEdges)
    {
    
    SVertex *ioA = fe->vertexA();
    SVertex *ioB = fe->vertexB();
    Vec3r A = ioA->point3D();
    Vec3r B = ioB->point3D();
    Vec3r a = ioA->point2D();
    Vec3r b = ioB->point2D();
    SVertex *svA, *svB;

    Vec3r newpoint3d,newpoint2d;
    vector<SVertex*> intersections;
    real t,T;
    for(vector<Vec2r>::const_iterator p=iParameters.begin(),pend=iParameters.end();
    p!=pend;
    p++)
    {
      T=(*p)[0];
      t=(*p)[1];

      if((t < 0) || (t > 1))
        cerr << "Warning: Intersection out of range for edge " << ioA->getId() << " - " << ioB->getId() << endl;
    
      // compute the 3D and 2D coordinates for the intersections points:
      newpoint3d = Vec3r(A + T*(B-A));
      newpoint2d = Vec3r(a + t*(b-a));

      // create new SVertex:
      // (we keep B's id)
      SVertex* newVertex = new SVertex(newpoint3d, ioB->getId());
      newVertex->SetPoint2D(newpoint2d);
      
      // Add this vertex to the intersections list:
      intersections.push_back(newVertex);

      // Add this vertex to this sshape:
      AddNewVertex(newVertex);
    }
    
    for(vector<SVertex*>::iterator sv=intersections.begin(),svend=intersections.end();
    sv!=svend;
    sv++)
    {
      svA = fe->vertexA();
      svB = fe->vertexB();
        
      // We split edge AB into AA' and A'B. A' and A'B are created.
      // AB becomes (address speaking) AA'. B is updated.
      //--------------------------------------------------
      // The edge AB becomes edge AA'.
      (fe)->SetVertexB((*sv));
      // a new edge, A'B is created.
      FEdge *newEdge;
      if (fe->getNature() & Nature::ALL_INTERSECTION)
	{
	  newEdge = new FEdgeIntersection((*sv), svB);
	  FEdgeIntersection * se = dynamic_cast<FEdgeIntersection*>(newEdge);
	  FEdgeIntersection * fes = dynamic_cast<FEdgeIntersection*>(fe);
	  se->SetMaterialIndex(fes->materialIndex());
	  se->SetFaces(fes->getFace1(), fes->getFace2());


#ifdef DEBUG_INTERSECTION
	  void debugFES(FEdgeIntersection * newEdge);
	  
	  debugFES(se);
	  debugFES(fes);
#endif



	}
      else
      if(fe->isSmooth()){
        newEdge = new FEdgeSmooth((*sv), svB);
        FEdgeSmooth * se = dynamic_cast<FEdgeSmooth*>(newEdge);
        FEdgeSmooth * fes = dynamic_cast<FEdgeSmooth*>(fe);
        se->SetMaterialIndex(fes->materialIndex());
      }else{
        newEdge = new FEdgeSharp((*sv), svB);
        FEdgeSharp * se = dynamic_cast<FEdgeSharp*>(newEdge);
        FEdgeSharp * fes = dynamic_cast<FEdgeSharp*>(fe);
        se->SetaMaterialIndex(fes->aMaterialIndex());
        se->SetbMaterialIndex(fes->bMaterialIndex());
	se->SetEdge(fes->edge());
      }
        
      newEdge->SetNature((fe)->getNature());
      

      // to build a new chain:
      AddChain(newEdge);
      // add the new edge to the sshape edges list.
      AddEdge(newEdge);
      // add new edge to the list of new edges passed as argument:
      ioNewEdges.push_back(newEdge);

      // update edge A'B for the next pointing edge
      newEdge->SetNextEdge((fe)->nextEdge());
      fe->nextEdge()->SetPreviousEdge(newEdge);
      Id id(fe->getId().getFirst(), fe->getId().getSecond()+1);
      newEdge->SetId(fe->getId());
      fe->SetId(id);

      // update edge AA' for the next pointing edge
      //ioEdge->SetNextEdge(newEdge);
      (fe)->SetNextEdge(NULL);

      // update vertex pointing edges list:
      // -- vertex B --
      svB->Replace((fe), newEdge);
      // -- vertex A' --
      (*sv)->AddFEdge((fe));
      (*sv)->AddFEdge(newEdge);
    }
          
    }
Ejemplo n.º 11
0
bool FEdge::intersectParametric(FEdge & fe2, Vec3r viewpoint, real t3D, real u3D)
{
  Vec3r A1 = vertexA()->getPoint3D();
  Vec3r B1 = vertexB()->getPoint3D();
  Vec3r A2 = fe2.vertexA()->getPoint3D();
  Vec3r B2 = fe2.vertexB()->getPoint3D();

  if (sameSide(A1,B1,viewpoint, A2, B2) || sameSide(A2, B2, viewpoint, A1, B1))
    return false;

  // now, there *must* be an intersection.

  // for each edge, the normal of the plane containing the edge and the viewpoint
  Vec3r N1 = (A1-viewpoint) ^ (B1-viewpoint);
  Vec3r N2 = (A2-viewpoint) ^ (B2-viewpoint);

  // direction vector of the intersection of the two planes.
  Vec3r V = N1 ^ N2;

  // check if the planes coincide (i.e., source edges are colinear)
  assert(V.norm() > 0);
  
  // ----- compute t parameter ------

  // form a plane for line 1, normal to the plane containing the viewpoint

  Vec3r BA1 = B1 - A1;
  Vec3r hsNormal1 = N1 ^ BA1;
  
  // intersect ray in direction of V through the plane
  real w1;
  GeomUtils::intersection_test res1 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal1, A1, w1);

  if (res1 != GeomUtils::DO_INTERSECT)
    {
      printf("res1 = %d\n", res1);
      printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]);
      printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]);
      printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]);
      printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]);
      printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]);
      printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]);
      printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]);
      printf("V = [%f %f %f]\n", V[0], V[1], V[2]);
      printf("hsNormal1 = [%f %f %f]\n", hsNormal1[0], hsNormal1[1], hsNormal1[2]);
    }

  assert(res1 == GeomUtils::DO_INTERSECT);

  Vec3r pt1 = viewpoint + w1 * V;

  t3D = ((pt1 - A1) * BA1) / (BA1*BA1);

  assert(t3D >=0 && t3D <= 1);

  // if (t3D < 0 || t3D > 1)
    //    return false;


  // ----- compute u parameter ------

  // form a half-space plane for line 2

  Vec3r BA2 = B2 - A2;
  Vec3r hsNormal2 = N2 ^ BA2;
  
  real w2;
  GeomUtils::intersection_test res2 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal2, A2, w2);

  if (res2 != GeomUtils::DO_INTERSECT)
    {
      printf("res1 = %d\n", res1);
      printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]);
      printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]);
      printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]);
      printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]);
      printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]);
      printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]);
      printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]);
      printf("V = [%f %f %f]\n", V[0], V[1], V[2]);
      printf("hsNormal2 = [%f %f %f]\n", hsNormal2[0], hsNormal2[1], hsNormal2[2]);
    }

  assert(res2 == GeomUtils::DO_INTERSECT);

  Vec3r pt2 = viewpoint + w2 * V;

  u3D = ((pt2 - A2) * BA2) / (BA2*BA2);

  assert( u3D >=0 && u3D <=1);

  //  if (u3D < 0 || u3D > 1)
  //    return false;


  
  return true;
}