Пример #1
0
void Chain::push_viewedge_back(ViewEdge *iViewEdge, bool 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.back()->point2d();
    if (orientation)
      ++v;
    else
      --v;
    // Ensure the continuity of underlying FEdges
    CurvePoint *cp =
        _Vertices.back();  // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f);
    SVertex *sv_first = (*vfirst);
    FEdge *fe = _fedgeB->duplicate();
    fe->setTemporary(true);
    fe->setVertexB(sv_first);
    fe->vertexA()->shape()->AddEdge(fe);
    fe->vertexA()->AddFEdge(fe);
    fe->vertexB()->AddFEdge(fe);
    cp->setA(sv_first);
  }
  else {
    previous = (*v)->point2d();
  }
  do {
    current = (*v)->point2d();
    Curve::push_vertex_back(*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_back(*v);
    //_Length += (current - previous).norm();
  }

  _fedgeB = (orientation) ? iViewEdge->fedgeB() : iViewEdge->fedgeA();
}
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;
}
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;
}
Пример #4
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;
}