_TMESH_TMPL_TYPE VOID _TMESH_TMPL_DECL::GetFacetVertices(iFACET facetIndex, eCOORD coord, REAL coordVal, iVERTEX v[2]) { cHALF_EDGE* facetHes[2] = { NULL, NULL }; BOOL verticesAreNew[2] = { false, false }; cHALF_EDGE *startingHe = Facet(facetIndex)->FindMinHalfEdge(coord); cHALF_EDGE *currHe = startingHe; INT i = 0; do { cPOINT3 tailPoint = currHe->Tail()->Point(); cPOINT3 headPoint = currHe->Head()->Point(); REAL heTailCoord = tailPoint[coord]; REAL heHeadCoord = headPoint[coord]; REAL diff1 = coordVal - heTailCoord; REAL diff2 = heHeadCoord - coordVal; if(fabs(diff2) < cLIMITS::Tolerance()) { currHe = currHe->Next(); continue; } if(fabs(diff1) < cLIMITS::Tolerance()) v[i++] = currHe->Tail()->Index(); else if(diff1 * diff2 > 0.0) { cPOINT3 newPoint = ((tailPoint*diff2) + (headPoint*diff1))/(diff1+diff2); v[i++] = NewVertex(newPoint); facetHes[i-1] = currHe; verticesAreNew[i-1] = true; } if(i == 2) break; currHe = currHe->Next(); } while( currHe != startingHe); if(verticesAreNew[0]) SplitEdge(v[0], facetHes[0]->Tail()->Index(), facetHes[0]->Head()->Index()); if(verticesAreNew[1]) SplitEdge(v[1], facetHes[1]->Tail()->Index(), facetHes[1]->Head()->Index()); }
vector<SplitEdge> split(const vector<SplitEdge> &g, int u, int v, int s, int delta, historyIndex &h) { vector<SplitEdge> GHat = g; bool addedWeight = false; bool subtractedU = false; bool subtractedV = false; //cout << endl; for (unsigned i = 0; i < GHat.size(); i++) { if (connects(GHat[i], u, v)) { //cout << "Increasing the weight from " << u << " to " << v << " from " << GHat[i].weight << " to " << GHat[i].weight + delta << endl; GHat[i].weight += delta; addedWeight = true; } if (connects(GHat[i], u, s) && !subtractedU) { //cout << "Decreasing the weight from " << u << " to " << s << " from " << GHat[i].weight << " to " << GHat[i].weight - delta << endl; GHat[i].weight -= delta; subtractedU = true; } if (connects(GHat[i], s, v) && !subtractedV) { //cout << "Decreasing the weight from " << v << " to " << s << " from " << GHat[i].weight << " to " << GHat[i].weight - delta << endl; GHat[i].weight -= delta; subtractedV = true; } } if (!addedWeight) { SplitEdge e = SplitEdge(u, v, delta, u, v); //cout << "Creating edge from " << u << " to " << v << " with weight " << delta << endl; GHat.push_back(e); } if (!subtractedU) { cout << "Error: Couldn't find weight from " << u << " to " << s << " to subtract." << endl; throw logic_error(""); } if (!subtractedV) { cout << "Error: Couldn't find weight from " << v << " to " << s << " to subtract." << endl; throw logic_error(""); } //cout << endl; GHat = removeZeroWeighted(GHat); logSplit(h, s, u, v, delta); return GHat; }
void IntersectionProcessor::ProcessIntersection( const OpsDoublePoint &intersectionPt, WingedEdgeArray &edges) { // loop through the edges generating an EdgeRecord for each of them m_nEdgeRecs = 0; for (int i = 0; i < edges.GetNEdges(); i++) { // if the intersection point is one of the edge endpoints, then // just add it if (intersectionPt == *edges[i]->m_vert[0]) AddEdgeRecord(edges[i], 0); else if (intersectionPt == *edges[i]->m_vert[1]) AddEdgeRecord(edges[i], 1); // else split the edge and add the two resulting edges else { WingedEdge *newEdge; SplitEdge(intersectionPt, edges[i], newEdge); AddEdgeRecord(edges[i], 0); AddEdgeRecord(newEdge, 1); } } // if more than two edge records, or the edges are coincident then sort // them into polar order before joining them about the intersection point if (m_nEdgeRecs > 2 || EdgesCoincident(edges[0], edges[1])) { SortEdges(); JoinEdges(intersectionPt); } // else must have two non-coincident edges joined at a common endpoint - // handle this case directly since it occurs frequently else edges[0]->Join(edges[1], &intersectionPt); #if defined _DEBUG if (traceFile != NULL) TraceIntersection(intersectionPt); #endif } // end: ProcessIntersection()
_Use_decl_annotations_ void KdTreeCompiler2::SplitTriangle(uint32_t triangle, uint32_t axis, float value, uint32_t* front, uint32_t* back) { KdCompilerTriangle* t = &_compilerTriangles[triangle]; // Make copies since if we grow the StaticGeometryVertex list while processing, we don't want to end up with bunk pointers StaticGeometryVertex v0 = _vertices[t->Indices[0]]; StaticGeometryVertex v1 = _vertices[t->Indices[1]]; StaticGeometryVertex v2 = _vertices[t->Indices[2]]; // are any of the points on the plane float d0 = *(&v0.Position.x + axis) - value; float d1 = *(&v1.Position.x + axis) - value; float d2 = *(&v2.Position.x + axis) - value; if (fabsf(d0) < epsilon) { // v0 is on plane, split v1-v2 edge StaticGeometryVertex vNew; SplitEdge(v1, v2, axis, value, &vNew); uint32_t iNew = (uint32_t)_vertices.size(); _vertices.push_back(vNew); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], t->Indices[1], iNew); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], iNew, t->Indices[2]); if (d1 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else if (fabsf(d1) < epsilon) { // v1 is on plane StaticGeometryVertex vNew; SplitEdge(v0, v2, axis, value, &vNew); uint32_t iNew = (uint32_t)_vertices.size(); _vertices.push_back(vNew); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], t->Indices[1], iNew); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[1], t->Indices[2], iNew); if (d0 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else if (fabsf(d2) < epsilon) { // v2 is on plane StaticGeometryVertex vNew; SplitEdge(v0, v1, axis, value, &vNew); uint32_t iNew = (uint32_t)_vertices.size(); _vertices.push_back(vNew); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], iNew, t->Indices[2]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), iNew, t->Indices[1], t->Indices[2]); if (d0 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else { // none are on the plane, do a 1-2 split if (d0 > -epsilon) // v0 is in front of plane { if (d1 > -epsilon) // v1 is in front of plane { // v2 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v2, v0, axis, value, &vNew1); SplitEdge(v2, v1, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[2]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], t->Indices[1], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], iNew2, iNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } else // v1 is behind plane { if (d2 > -epsilon) // v2 is in front { // v1 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v1, v2, axis, value, &vNew1); SplitEdge(v1, v0, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[1]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[2], t->Indices[0], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[2], iNew2, iNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } else // v2 is behind { // v0 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v0, v1, axis, value, &vNew1); SplitEdge(v0, v2, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[0]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[1], t->Indices[2], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[1], iNew2, iNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } } } else // v0 is behind plane { if (d1 < epsilon) // v1 is behind { // v2 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v2, v0, axis, value, &vNew1); SplitEdge(v2, v1, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[2]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], t->Indices[1], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[0], iNew2, iNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } else // v1 is in front { if (d2 < epsilon) // v2 is behind { // v1 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v1, v2, axis, value, &vNew1); SplitEdge(v1, v0, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[1]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[2], t->Indices[0], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[2], iNew2, iNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } else { // v0 is by itself StaticGeometryVertex vNew1, vNew2; SplitEdge(v0, v1, axis, value, &vNew1); SplitEdge(v0, v2, axis, value, &vNew2); uint32_t iNew1 = (uint32_t)_vertices.size(); _vertices.push_back(vNew1); uint32_t iNew2 = (uint32_t)_vertices.size(); _vertices.push_back(vNew2); uint32_t t1 = AllocCompilerTriangle(_vertices.data(), iNew1, iNew2, t->Indices[0]); uint32_t t2 = AllocCompilerTriangle(_vertices.data(), t->Indices[1], t->Indices[2], iNew2); uint32_t t3 = AllocCompilerTriangle(_vertices.data(), t->Indices[1], iNew2, iNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } } } } }
_Use_decl_annotations_ void BspCompiler::SplitTriangle(const Triangle* t, const XMFLOAT4& plane, Triangle** front, Triangle** back) { // are any of the points on the plane float d0 = DistToPlane(plane, t->v0.Position); float d1 = DistToPlane(plane, t->v1.Position); float d2 = DistToPlane(plane, t->v2.Position); if (ABS(d0) < epsilon) { // v0 is on plane, split v1-v2 edge Vertex vNew; SplitEdge(t->v1, t->v2, plane, &vNew); Triangle* t1 = new Triangle(t->v0, t->v1, vNew); Triangle* t2 = new Triangle(t->v0, vNew, t->v2); if (d1 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else if (ABS(d1) < epsilon) { // v1 is on plane Vertex vNew; SplitEdge(t->v0, t->v2, plane, &vNew); Triangle* t1 = new Triangle(t->v0, t->v1, vNew); Triangle* t2 = new Triangle(t->v1, t->v2, vNew); if (d0 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else if (ABS(d2) < epsilon) { // v2 is on plane Vertex vNew; SplitEdge(t->v0, t->v1, plane, &vNew); Triangle* t1 = new Triangle(t->v0, vNew, t->v2); Triangle* t2 = new Triangle(vNew, t->v1, t->v2); if (d0 > 0) { PUSH(front, t1); PUSH(back, t2); } else { PUSH(back, t1); PUSH(front, t2); } } else { // none are on the plane, do a 1-2 split if (d0 > -epsilon) // v0 is in front of plane { if (d1 > -epsilon) // v1 is in front of plane { // v2 is by itself Vertex vNew1, vNew2; SplitEdge(t->v2, t->v0, plane, &vNew1); SplitEdge(t->v2, t->v1, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v2); Triangle* t2 = new Triangle(t->v0, t->v1, vNew2); Triangle* t3 = new Triangle(t->v0, vNew2, vNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } else // v1 is behind plane { if (d2 > -epsilon) // v2 is in front { // v1 is by itself Vertex vNew1, vNew2; SplitEdge(t->v1, t->v2, plane, &vNew1); SplitEdge(t->v1, t->v0, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v1); Triangle* t2 = new Triangle(t->v2, t->v0, vNew2); Triangle* t3 = new Triangle(t->v2, vNew2, vNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } else // v2 is behind { // v0 is by itself Vertex vNew1, vNew2; SplitEdge(t->v0, t->v1, plane, &vNew1); SplitEdge(t->v0, t->v2, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v0); Triangle* t2 = new Triangle(t->v1, t->v2, vNew2); Triangle* t3 = new Triangle(t->v1, vNew2, vNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } } } else // v0 is behind plane { if (d1 < epsilon) // v1 is behind { // v2 is by itself Vertex vNew1, vNew2; SplitEdge(t->v2, t->v0, plane, &vNew1); SplitEdge(t->v2, t->v1, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v2); Triangle* t2 = new Triangle(t->v0, t->v1, vNew2); Triangle* t3 = new Triangle(t->v0, vNew2, vNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } else // v1 is in front { if (d2 < epsilon) // v2 is behind { // v1 is by itself Vertex vNew1, vNew2; SplitEdge(t->v1, t->v2, plane, &vNew1); SplitEdge(t->v1, t->v0, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v1); Triangle* t2 = new Triangle(t->v2, t->v0, vNew2); Triangle* t3 = new Triangle(t->v2, vNew2, vNew1); PUSH(back, t2); PUSH(back, t3); PUSH(front, t1); } else { // v0 is by itself Vertex vNew1, vNew2; SplitEdge(t->v0, t->v1, plane, &vNew1); SplitEdge(t->v0, t->v2, plane, &vNew2); Triangle* t1 = new Triangle(vNew1, vNew2, t->v0); Triangle* t2 = new Triangle(t->v1, t->v2, vNew2); Triangle* t3 = new Triangle(t->v1, vNew2, vNew1); PUSH(front, t2); PUSH(front, t3); PUSH(back, t1); } } } } }
_TMESH_TMPL_TYPE iFACET _TMESH_TMPL_DECL::Clip(iFACET facetIndex, const cSEGMENT3 &cut) { cFACET* facet = Facet(facetIndex); if(facet == NULL || facet->IsDeleted()) return INVALID_IFACET; iVERTEX cutVertices[2] = { INVALID_IVERTEX, INVALID_IVERTEX }; BOOL insertCutVertices[2] = { false, false }; cPOINT3 points[2]; cEDGE splitEdges[2]; const cPOINT3 &cutTail = cut.Source(); const cPOINT3 &cutHead = cut.Target(); typename cFACET::half_edge_circulator currFacetHe = facet->HalfEdgesBegin(); typename cFACET::half_edge_circulator lastFacetHe = facet->HalfEdgesEnd(); INT numCuts = 0; for( ; currFacetHe != lastFacetHe ; currFacetHe++) { cSEGMENT3 heSegment = currFacetHe->Segment(); if(heSegment.HasOn(cutTail)) { if(!(heSegment.Target() == cutTail)) { if(heSegment.Source() == cutTail) { cutVertices[numCuts++] = currFacetHe->Tail()->Index(); } else { insertCutVertices[numCuts] = true; splitEdges[numCuts].v1 = currFacetHe->Tail()->Index(); splitEdges[numCuts].v2 = currFacetHe->Head()->Index(); points[numCuts] = cutTail; numCuts++; } } } if(heSegment.HasOn(cutHead)) { if(!(heSegment.Target() == cutHead)) { if(heSegment.Source() == cutHead) { cutVertices[numCuts++] = currFacetHe->Tail()->Index(); } else { insertCutVertices[numCuts] = true; splitEdges[numCuts].v1 = currFacetHe->Tail()->Index(); splitEdges[numCuts].v2 = currFacetHe->Head()->Index(); points[numCuts] = cutHead; numCuts++; } } } if(numCuts == 2) break; } //Cuts found. assert(numCuts == 2); if(numCuts != 2) return INVALID_IFACET; if(insertCutVertices[0]) { cutVertices[0] = NewVertex(points[0]); SplitEdge(cutVertices[0], splitEdges[0].v1, splitEdges[0].v2); } if(insertCutVertices[1]) { cutVertices[1] = NewVertex(points[1]); SplitEdge(cutVertices[1], splitEdges[1].v1, splitEdges[1].v2); } return InsertDiagonal(facetIndex, cutVertices[0], cutVertices[1]); }
std::vector<c_vector<unsigned, 5> > MutableMesh<ELEMENT_DIM, SPACE_DIM>::SplitLongEdges(double cutoffLength) { assert(ELEMENT_DIM == 2); assert(SPACE_DIM == 3); std::vector<c_vector<unsigned, 5> > history; bool long_edge_exists = true; while(long_edge_exists) { std::set<std::pair<unsigned, unsigned> > long_edges; // Loop over elements to check for Long edges for (typename AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::ElementIterator elem_iter = this->GetElementIteratorBegin(); elem_iter != this->GetElementIteratorEnd(); ++elem_iter) { unsigned num_nodes = ELEMENT_DIM+1; // Loop over element vertices for (unsigned local_index=0; local_index<num_nodes; local_index++) { // Find locations of current node (node a) and anticlockwise node (node b) Node<SPACE_DIM>* p_node_a = elem_iter->GetNode(local_index); unsigned local_index_plus_one = (local_index+1)%num_nodes; /// \todo use iterators to tidy this up Node<SPACE_DIM>* p_node_b = elem_iter->GetNode(local_index_plus_one); // Find distance between nodes double distance_between_nodes = this->GetDistanceBetweenNodes(p_node_a->GetIndex(), p_node_b->GetIndex()); if (distance_between_nodes > cutoffLength) { if (p_node_a->GetIndex() < p_node_b->GetIndex()) { std::pair<unsigned, unsigned> long_edge(p_node_a->GetIndex(),p_node_b->GetIndex()); long_edges.insert(long_edge); } else { std::pair<unsigned, unsigned> long_edge(p_node_b->GetIndex(),p_node_a->GetIndex()); long_edges.insert(long_edge); } } } } if (long_edges.size() > 0) //Split the edges in decreasing order. { while (long_edges.size() > 0) { double longest_edge = 0.0; std::set<std::pair<unsigned, unsigned> >::iterator longest_edge_iter; //Find the longest edge in the set and split it for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = long_edges.begin(); edge_iter != long_edges.end(); ++edge_iter) { unsigned node_a_global_index = edge_iter->first; unsigned node_b_global_index = edge_iter->second; double distance_between_nodes = this->GetDistanceBetweenNodes(node_a_global_index, node_b_global_index); if (distance_between_nodes > longest_edge) { longest_edge = distance_between_nodes; longest_edge_iter = edge_iter; } } assert(longest_edge >0); c_vector<unsigned, 3> new_node_index = SplitEdge(this->GetNode(longest_edge_iter->first), this->GetNode(longest_edge_iter->second)); c_vector<unsigned, 5> node_set; node_set(0) = new_node_index[0]; node_set(1) = longest_edge_iter->first; node_set(2) = longest_edge_iter->second; node_set(3) = new_node_index[1]; node_set(4) = new_node_index[2]; history.push_back(node_set); // Delete pair from set long_edges.erase(*longest_edge_iter); } } else { long_edge_exists = false; } } return history; }
huReturn hookUp(const vector<SplitEdge> &g, int s, vector<SplitEdge> &bIn, int k, vector<vector<int>> &Y, historyIndex &h) { if (cG(s, g) != 0) { cout << "cG(s) problem in hookup" << endl; throw logic_error(""); } vector<SplitEdge> H = g; vector<SplitEdge> G1 = g; vector<SplitEdge> B = bIn; vector<SplitEdge> B1; vector<vector<int>> XS; int maxNodeInd = getMaxNodeInd(G1); for (int i = 0; i < maxNodeInd; i++) XS.push_back(vector<int>()); for (int i = 0; i < maxNodeInd; i++) XS[i].push_back(i); //cout << "About to enter while loop" << endl; while (getNumUsedNodes(H) >= 4) { vector<int> ma = maOrderingHeap(H, s); int v = ma[ma.size() - 2]; int w = ma[ma.size() - 1]; if (v == s || w == s) throw logic_error("SET WAS V - S, S FOUND"); vector<int> X1; H = combineVertices(H, v, w); H = compress(H); XS[v] = setUnion(XS[v], XS[w]); if (XS[w].size() == 0) { cout << "Error: W, " << w << " was merged twice. Quitting" << endl; throw logic_error(""); } XS[w] = vector<int>(); if (cG(v, H) < k) { int numToGet = (int)ceil(.5*(double(k) - double(cG(G1, XS[v])))); vector<SplitEdge> GX = inducedSubgraph(G1, XS[v]); vector<SplitEdge> delB; int added = 0; for (unsigned i = 0; i < GX.size(); i++) { SplitEdge e = SplitEdge(GX[i].end0, GX[i].end1, GX[i].weight, GX[i].orig0, GX[i].orig1); if (isMem(e, B)) { int bW = B[indexOfEdge(B, e.end0, e.end1)].weight; if (bW < e.weight) e.weight = bW; if (e.weight > (numToGet - added)) { e.weight = numToGet - added; } added += e.weight; delB.push_back(e); } if (added == numToGet) break; } if (added != numToGet) { cout << "Error: GX did not contain " << numToGet << " entries in B. Quitting." << endl; throw logic_error(""); } if (!isSubset(delB, B)) { cout << "ERROR: delB is not a subset of B." << endl; cout << "B:" << endl; output(B); cout << "delB:" << endl; output(delB); cout << "This was the GX to choose from:" << endl; output(GX); cout << "V: " << v << endl; cout << "W: " << w << endl; cout << "S: " << s << endl; throw logic_error(""); } B = setRemove(delB, B); B = removeZeroWeighted(B); B1 = setUnion(delB, B1); H = removeZeroWeighted(H); G1 = hookUpHelper(s, G1, delB, h); G1 = removeZeroWeighted(G1); H = removeZeroWeighted(H); bool addedFromXSinH = false; numToGet *= 2; for (unsigned i = 0; i < H.size(); i++) { SplitEdge tester = SplitEdge(s, v, 0, 0, 0); if (equals(tester, H[i])) { //cout << "Increasing weight in hookUp in H between " << H[i].end0 << " and " << H[i].end1 << "from " << H[i].weight << " to " << H[i].weight + numToGet << endl; H[i].weight += numToGet; addedFromXSinH = true; break; } } if (!addedFromXSinH && numToGet != 0) { //cout << "Creating edge in hookUp in H between " << s << " and " << v << " with weight " << numToGet << endl; SplitEdge e(s, v, numToGet, s, v); H.push_back(e); } vector<vector<int>> newY; for (unsigned i = 0; i < Y.size(); i++) { if (!isProperSubset(Y[i], XS[v])) newY.push_back(Y[i]); } bool foundX1inY = false; for (unsigned i = 0; i < newY.size(); i++) { if (setsEqual(newY[i], XS[v])) foundX1inY = true; } if (!foundX1inY) newY.push_back(XS[v]); Y = newY; } } huReturn ret; ret.BP = B1; ret.G1 = G1; ret.Y = Y; return ret; }
bool ON_Brep::SplitKinkyEdge( int edge_index, double kink_tol_radians ) { // Default kink_tol_radians MUST BE ON_PI/180.0. // // The default kink tol must be kept in sync with the default for // TL_Brep::SplitKinkyFace() and ON_Brep::SplitKinkyFace(). // See comments in TL_Brep::SplitKinkyFace() for more details. bool rc = true; if (kink_tol_radians < ON_ZERO_TOLERANCE) kink_tol_radians = ON_ZERO_TOLERANCE; else if (kink_tol_radians > ON_PI - ON_ZERO_TOLERANCE) kink_tol_radians = ON_PI - ON_ZERO_TOLERANCE; double atol = cos(kink_tol_radians); if (edge_index < 0 || edge_index >= m_E.Count()) return false; ON_BrepEdge& E = m_E[edge_index]; if (E.m_c3i < 0) return false; ON_SimpleArray<double> split_t(4); double t0 = E.Domain()[0]; int hint = 0; ON_Curve* curve = m_C3[E.m_c3i]; if (!curve) return false; int scount = curve->SpanCount(); while (split_t.Count() < scount){ double t; if (!E.GetNextDiscontinuity(ON::G1_continuous, t0, E.Domain()[1], &t, &hint, NULL, atol)) break; split_t.Append(t); t0 = t; } if (split_t.Count() >= scount) return false; if (split_t.Count() == 0) return true;//no kinks split_t.Reverse(); for (int i=0; i<split_t.Count(); i++){ //if split parameter is near start or end, just adjust domain. double t0, t1; m_E[edge_index].GetDomain(&t0, &t1); if (t1 - t0 < 10.0*ON_ZERO_TOLERANCE) continue; //6 Dec 2002 Dale Lear: // I added the relative edge_split_s and trm_split_s tests to detect // attempts to trim a nano-gnats-wisker of the end of a trim. // set to true if edge should be trimmed instead of split. bool bTrimEdgeEnd = false; double edge_split_s = ON_Interval(t0,t1).NormalizedParameterAt(split_t[i]); double trim_split_s = 0.5; if (split_t[i] - t0 <= ON_ZERO_TOLERANCE || edge_split_s <= ON_SQRT_EPSILON ) { continue; } if (t1 - split_t[i] <= ON_ZERO_TOLERANCE || edge_split_s >= 1.0-ON_SQRT_EPSILON) { continue; } // trim_t[] = corresponding trim parameters ON_SimpleArray<double> trim_t(m_E[edge_index].m_ti.Count()); if ( !bTrimEdgeEnd ) { for (int j=0; j<m_E[edge_index].m_ti.Count(); j++) { double t; if (!GetTrimParameter(m_E[edge_index].m_ti[j], split_t[i], &t)){ rc = false; continue; } trim_t.Append(t); const ON_BrepTrim& trim = m_T[m_E[edge_index].m_ti[j]]; ON_Interval trim_domain = trim.Domain(); trim_split_s = trim_domain.NormalizedParameterAt(t); if ( trim_split_s <= ON_SQRT_EPSILON || t - trim_domain[0] <= ON_ZERO_TOLERANCE ) { bTrimEdgeEnd = true; break; } if ( trim_split_s >= 1.0-ON_SQRT_EPSILON || trim_domain[1] - t <= ON_ZERO_TOLERANCE ) { bTrimEdgeEnd = true; break; } } } if ( bTrimEdgeEnd ) { // if we get here, a split parameter we got was too close to // the end of the edge or a trim for us to split it. if ( edge_split_s <= 0.01 ) { if ( t0 < split_t[i] ) m_E[edge_index].ON_CurveProxy::Trim(ON_Interval(split_t[i], t1)); } else if ( edge_split_s >= 0.99 ) { if ( split_t[i] < t1 ) m_E[edge_index].ON_CurveProxy::Trim(ON_Interval(t0, split_t[i])); } else { // no decent agreement between trims and edges - continue // with other parameters but this is basically the same // thing as having SplitEdge() fail. rc = false; } continue; } if (!SplitEdge(edge_index, split_t[i], trim_t)){ rc = false; continue; } ON_Curve* new_curve0 = m_E[edge_index].DuplicateCurve(); if (new_curve0){ m_E[edge_index].m_c3i = AddEdgeCurve(new_curve0); m_E[edge_index].SetProxyCurve(new_curve0); } ON_Curve* new_curve1 = m_E.Last()->DuplicateCurve(); if (new_curve1){ m_E.Last()->m_c3i = AddEdgeCurve(new_curve1); m_E.Last()->SetProxyCurve(new_curve1); } } return rc; }
int ON_Brep::SplitEdgeAtParameters( int edge_index, int edge_t_count, const double* edge_t ) { // Default kink_tol_radians MUST BE ON_PI/180.0. // // The default kink tol must be kept in sync with the default for // TL_Brep::SplitKinkyFace() and ON_Brep::SplitKinkyFace(). // See comments in TL_Brep::SplitKinkyFace() for more details. if (0 == edge_t_count) return 0; if (0 == edge_t) return 0; if (edge_index < 0 || edge_index >= m_E.Count()) return 0; ON_BrepEdge& E = m_E[edge_index]; if (E.m_c3i < 0) return 0; ON_Curve* curve = m_C3[E.m_c3i]; if (!curve) return 0; ON_Interval Edomain; if ( !E.GetDomain(&Edomain.m_t[0],&Edomain.m_t[1]) ) return 0; if ( !Edomain.IsIncreasing() ) return 0; // get a list of unique and valid splitting parameters ON_SimpleArray<double> split_t(edge_t_count); { for (int i = 0; i < edge_t_count; i++) { double e = edge_t[i]; if ( !ON_IsValid(e) ) { ON_ERROR("Invalid edge_t[] value"); continue; } if ( e <= Edomain.m_t[0] ) { ON_ERROR("edge_t[] <= start of edge domain"); continue; } if ( e >= Edomain.m_t[1] ) { ON_ERROR("edge_t[] >= end of edge domain"); continue; } split_t.Append(e); } if ( split_t.Count() > 1 ) { // sort split_t[] and remove duplicates ON_SortDoubleArray( ON::heap_sort, split_t.Array(), split_t.Count() ); int count = 1; for ( int i = 1; i < split_t.Count(); i++ ) { if ( split_t[i] > split_t[count-1] ) { if ( i > count ) split_t[count] = split_t[i]; count++; } } split_t.SetCount(count); } } if (split_t.Count() <= 0) return 0; // Reverse split_t[] so the starting segment of the original // edge m_E[edge_index] is the one at m_E[edge_index]. split_t.Reverse(); ON_Curve* new_curve = TuneupSplitteeHelper(m_E[edge_index].ProxyCurve()); if ( 0 != new_curve ) { m_E[edge_index].m_c3i = AddEdgeCurve(new_curve); m_E[edge_index].SetProxyCurve(new_curve); new_curve = 0; } int eti, ti; int successful_split_count = 0; for (int i=0; i<split_t.Count(); i++) { double t0, t1; m_E[edge_index].GetDomain(&t0, &t1); if (t1 - t0 < 10.0*ON_ZERO_TOLERANCE) break; //6 Dec 2002 Dale Lear: // I added the relative edge_split_s and trm_split_s tests to detect // attempts to trim a nano-gnats-wisker off the end of a trim. double edge_split_s = ON_Interval(t0,t1).NormalizedParameterAt(split_t[i]); double trim_split_s = 0.5; if (split_t[i] - t0 <= ON_ZERO_TOLERANCE || edge_split_s <= ON_SQRT_EPSILON ) { // this split is not possible continue; } if (t1 - split_t[i] <= ON_ZERO_TOLERANCE || edge_split_s >= 1.0-ON_SQRT_EPSILON) { // this split is not possible continue; } // trim_t[] = corresponding trim parameters ON_SimpleArray<double> trim_t(m_E[edge_index].m_ti.Count()); for ( eti = 0; eti < m_E[edge_index].m_ti.Count(); eti++) { ti = m_E[edge_index].m_ti[eti]; if ( ti < 0 || ti >= m_T.Count() ) continue; ON_BrepTrim& trim = m_T[ti]; if ( 0 == i ) { // On the first split, make sure the trim curve is up to snuff. new_curve = TuneupSplitteeHelper(trim.ProxyCurve()); if (new_curve) { trim.m_c2i = AddTrimCurve(new_curve); trim.SetProxyCurve(new_curve); new_curve = 0; } } double t = ON_UNSET_VALUE; if (!GetTrimParameter(ti, split_t[i], &t) || !ON_IsValid(t)) break; trim_t.Append(t); const ON_Interval trim_domain = trim.Domain(); trim_split_s = trim_domain.NormalizedParameterAt(t); if ( trim_split_s <= ON_SQRT_EPSILON || t - trim_domain[0] <= ON_ZERO_TOLERANCE ) break; if ( trim_split_s >= 1.0-ON_SQRT_EPSILON || trim_domain[1] - t <= ON_ZERO_TOLERANCE ) break; } if ( trim_t.Count() != m_E[edge_index].m_ti.Count() ) continue; if (!SplitEdge(edge_index, split_t[i], trim_t)) { continue; } // SplitEdge generally adjusts proxy domains instead // of trimming the orginal curve. These DuplicateCurve() // calls make a new curve whose domain exactly matches // the edge. for ( int epart = 0; epart < 2; epart++ ) { ON_BrepEdge* newE = (0 == epart) ? &m_E[edge_index] : m_E.Last(); if ( 0 == newE ) continue; new_curve = TuneupEdgeOrTrimRealCurve(*newE,true); if (new_curve) { newE->m_c3i = AddEdgeCurve(new_curve); newE->SetProxyCurve(new_curve); } for ( eti = 0; eti < newE->m_ti.Count(); eti++ ) { ti = newE->m_ti[eti]; if ( ti < 0 || ti >= m_T.Count() ) continue; ON_BrepTrim& trim = m_T[ti]; new_curve = TuneupEdgeOrTrimRealCurve(trim,false); if (new_curve) { trim.m_c2i = AddTrimCurve(new_curve); trim.SetProxyCurve(new_curve); } } } successful_split_count++; } return successful_split_count; }