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; }
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; }