예제 #1
0
Status PotentialCrossDetector::detectInsertVertexOnEdge
(MeshManager &meshManager, const FlowManager &flowManager,
 PolygonManager &polygonManager, Edge *oldEdge, Vertex *newVertex,
 Vertex *oldVertex, Edge **crossedEdge)
{
    // -------------------------------------------------------------------------
    Vertex *vertex1, *vertex2, *vertex3, *vertex4, *vertices[3];
    OrientStatus orient;
    static std::list<Projection>::iterator itPrj;
    static std::list<Vertex *>::iterator itVtx;
    Projection *projection;
    EdgePointer *linkedEdge;
    Edge *edge3;
    static std::list<Edge *> checkedEdges;
    checkedEdges.clear();
    // -------------------------------------------------------------------------
    // collect information
    vertex1 = oldEdge->getEndPoint(FirstPoint);
    vertex2 = oldEdge->getEndPoint(SecondPoint);
    vertices[0] = vertex1;
    vertices[1] = vertex2;
    vertices[2] = newVertex;
    orient = Sphere::orient(vertex1, vertex2, newVertex);
    if (crossedEdge != NULL)
        *crossedEdge = NULL;
    // -------------------------------------------------------------------------
    // branch-1:
    // check the two new edges will not cross by any vertex
    // =========================================================================
    // paired vertices of old edge
    itVtx = oldEdge->detectAgent.vertices.begin();
    while (itVtx != oldEdge->detectAgent.vertices.end()) {
        // test point will be checked later
        if ((*itVtx)->getID() == -1 || *itVtx == oldVertex) {
            itVtx++;
            continue;
        }
        projection = (*itVtx)->detectAgent.getProjection(oldEdge);
        linkedEdge = (*itVtx)->linkedEdges.front();
        while (linkedEdge != NULL) {
            edge3 = linkedEdge->edge;
            if (find(checkedEdges.begin(), checkedEdges.end(), edge3)
                == checkedEdges.end()) {
                vertex3 = edge3->getEndPoint(FirstPoint);
                vertex4 = edge3->getEndPoint(SecondPoint);
                if (projection->getOrient() != orient && orient != OrientOn &&
                    oldVertex != NULL &&
                    oldVertex->detectAgent.getProjection(edge3) != NULL) {
                    if (vertex3 != oldVertex && vertex4 != oldVertex &&
                        Sphere::isIntersect(vertex3, vertex4, oldVertex, newVertex))
                        goto return_insert_vertex_cross_edge;
                } else {
                    if (vertex3 != oldVertex && vertex4 != oldVertex) {
                        if ((vertex1 != vertex3 && vertex1 != vertex4 &&
                             Sphere::isIntersect(vertex1, newVertex, vertex3, vertex4)) ||
                            (vertex2 != vertex3 && vertex2 != vertex4 &&
                             Sphere::isIntersect(vertex2, newVertex, vertex3, vertex4)) ||
                            (vertex1 == vertex3 &&
                             Sphere::orient(vertex1, newVertex, vertex4) !=
                             projection->getOrient()) ||
                            (vertex1 == vertex4 &&
                             Sphere::orient(vertex1, newVertex, vertex3) !=
                             projection->getOrient()) ||
                            (vertex2 == vertex3 &&
                             Sphere::orient(newVertex, vertex2, vertex4) !=
                             projection->getOrient()) ||
                            (vertex2 == vertex4 &&
                             Sphere::orient(newVertex, vertex2, vertex3) !=
                             projection->getOrient()))
                            goto return_insert_vertex_cross_edge;
                    }
                }
                checkedEdges.push_back(edge3);
            }
            linkedEdge = linkedEdge->next;
        }
        itVtx++;
    }
    // =========================================================================
    // paired edges of end points of old edge
    for (int i = 0; i < 3; ++i) {
        itPrj = vertices[i]->detectAgent.getProjections().begin();
        while (itPrj != vertices[i]->detectAgent.getProjections().end()) {
            edge3 = (*itPrj).getEdge();
#ifdef DEBUG
            assert(edge3->endTag != ListElement<Edge>::Null);
#endif
            if (find(checkedEdges.begin(), checkedEdges.end(), edge3)
                != checkedEdges.end()) {
                itPrj++;
                continue;
            }
            vertex3 = edge3->getEndPoint(FirstPoint);
            vertex4 = edge3->getEndPoint(SecondPoint);
            if (vertex3 == oldVertex || vertex4 == oldVertex) {
                itPrj++;
                continue;
            }
            if ((vertex1 != vertex3 && vertex1 != vertex4 &&
                 Sphere::isIntersect(vertex1, newVertex, vertex3, vertex4)) ||
                (vertex2 != vertex3 && vertex2 != vertex4 &&
                 Sphere::isIntersect(vertex2, newVertex, vertex3, vertex4)))
                goto return_insert_vertex_cross_edge;
            checkedEdges.push_back(edge3);
            itPrj++;
        }
    }
    // -------------------------------------------------------------------------
    // branch-2:
    // check the two new edges will not cross by any test point, if so reset it
    itVtx = oldEdge->detectAgent.vertices.begin();
    while (itVtx != oldEdge->detectAgent.vertices.end()) {
        if ((*itVtx)->getID() != -1) {
            itVtx++;
            continue;
        }
        TestPoint *testPoint = static_cast<TestPoint *>(*itVtx);
        edge3 = testPoint->getHostEdge();
        vertex3 = edge3->getEndPoint(FirstPoint);
        vertex4 = edge3->getEndPoint(SecondPoint);
        if ((vertex3 != oldVertex && vertex4 != oldVertex) &&
            ((vertex1 != vertex3 &&
              Sphere::isIntersect(vertex1, newVertex, vertex3, testPoint)) ||
             (vertex1 != vertex4 &&
              Sphere::isIntersect(vertex1, newVertex, vertex4, testPoint)) ||
             (vertex2 != vertex3 &&
              Sphere::isIntersect(vertex2, newVertex, vertex3, testPoint)) ||
             (vertex2 != vertex4 &&
              Sphere::isIntersect(vertex2, newVertex, vertex4, testPoint)))) {
            itVtx++;
            testPoint->reset(meshManager);
        } else
            itVtx++;
    }
    return NoCross;
return_insert_vertex_cross_edge:
    if (crossedEdge != NULL && vertex3 != oldVertex && vertex4 != oldVertex)
        *crossedEdge = edge3;
    return Cross;
}
예제 #2
0
Status PotentialCrossDetector::detectRemoveVertexOnEdges(MeshManager &meshManager,
                                                         EdgePointer *edgePointer,
                                                         Vertex *testPoint,
                                                         Polygon *polygon)
{
    // -------------------------------------------------------------------------
    Vertex *vertex1, *vertex2, *vertex3, *vertex4, *vertex5, *vertex6, *vertices[3];
    Edge *edge1, *edge2, *edge;
    EdgePointer *linkedEdge;
    Polygon *markPolygon;
    static std::list<Edge *> checkedEdges;
    checkedEdges.clear();
    static std::list<Vertex *>::const_iterator itVtx;
    static std::list<Projection>::const_iterator itPrj;
    OrientStatus orient;
    Projection *projection;
    int mode;
    // -------------------------------------------------------------------------
    // collect information
    edge1 = edgePointer->prev->edge;
    edge2 = edgePointer->edge;
    vertex1 = edgePointer->prev->getEndPoint(FirstPoint);
    vertex2 = edgePointer->getEndPoint(FirstPoint);
    vertex3 = edgePointer->getEndPoint(SecondPoint);
    vertices[0] = vertex1;
    vertices[1] = vertex2;
    vertices[2] = vertex3;
    orient = Sphere::orient(vertex1, vertex3, vertex2);
    if (edgePointer->prev->orient == OrientLeft &&
        edgePointer->orient == OrientLeft)
        mode = 1;
    else if (edgePointer->prev->orient == OrientRight &&
             edgePointer->orient == OrientLeft)
        mode = 2;
    else if (edgePointer->prev->orient == OrientLeft &&
             edgePointer->orient == OrientRight)
        mode = 3;
    else if (edgePointer->prev->orient == OrientRight &&
             edgePointer->orient == OrientRight)
        mode = 4;
    else
        REPORT_ERROR("Unhandled branch!");
    // -------------------------------------------------------------------------
    // branch-1:
    // check the new edge will not be crossed by the paired vertices of edge 1/2
    // =========================================================================
    // edge 1
    for (itVtx = edge1->detectAgent.vertices.begin();
         itVtx != edge1->detectAgent.vertices.end(); ++itVtx) {
        projection = (*itVtx)->detectAgent.getProjection(edge1);
        if (mode == 1 || mode == 3) {
            if ((orient == OrientOn || projection->getOrient() != orient) &&
                projection->getOrient() != Sphere::orient(vertex1, vertex3, *itVtx))
                return Cross;
        } else {
            if ((orient == OrientOn || projection->getOrient() == orient) &&
                projection->getOrient() == Sphere::orient(vertex1, vertex3, *itVtx))
                return Cross;
        }
    }
    // =========================================================================
    // edge2
    for (itVtx = edge2->detectAgent.vertices.begin();
         itVtx != edge2->detectAgent.vertices.end(); ++itVtx) {
        projection = (*itVtx)->detectAgent.getProjection(edge2);
        if (mode == 1 || mode == 2) {
            if ((orient == OrientOn || projection->getOrient() != orient) &&
                projection->getOrient() != Sphere::orient(vertex1, vertex3, *itVtx))
                return Cross;
        } else {
            if ((orient == OrientOn || projection->getOrient() == orient) &&
                projection->getOrient() == Sphere::orient(vertex1, vertex3, *itVtx))
                return Cross;
        }
    }
    // -------------------------------------------------------------------------
    // branch-2:
    // check the new test point will not cross any edge, if so reset it
    orient = Sphere::orient(vertex1, vertex3, testPoint);
    if (mode == 1 || mode == 2) {
        if (orient == OrientLeft)
            markPolygon = polygon;
        else
            markPolygon = edgePointer->getPolygon(OrientRight);
    } else {
        if (orient == OrientLeft)
            markPolygon = edgePointer->getPolygon(OrientRight);
        else
            markPolygon = polygon;
    }
    // =========================================================================
    // edge 1
    for (itVtx = edge1->detectAgent.vertices.begin();
         itVtx != edge1->detectAgent.vertices.end(); ++itVtx) {
        vertex4 = *itVtx;
        projection = vertex4->detectAgent.getProjection(edge1);
        if (((mode == 1 || mode == 3) && projection->getOrient() != orient) ||
            ((mode == 2 || mode == 4) && projection->getOrient() == orient))
            continue;
        if (vertex4->getID() == -1)
            continue;
        linkedEdge = vertex4->linkedEdges.front();
        while (linkedEdge != NULL) {
            edge = linkedEdge->edge;
            if (find(checkedEdges.begin(), checkedEdges.end(), edge)
                == checkedEdges.end()) {
                vertex5 = NULL; vertex6 = NULL;
                if (edge->getPolygon(OrientLeft) == markPolygon ||
                    edge->getPolygon(OrientRight) == markPolygon) {
                    vertex5 = edge->getEndPoint(FirstPoint);
                    vertex6 = edge->getEndPoint(SecondPoint);
                }
                if (vertex5 != NULL) {
                    if (((vertex5 != vertex1 && vertex6 != vertex1) &&
                         Sphere::isIntersect(vertex1, testPoint, vertex5, vertex6)) ||
                        ((vertex5 != vertex3 && vertex6 != vertex3) &&
                         Sphere::isIntersect(vertex3, testPoint, vertex5, vertex6)))
                        goto return_nocross_but_reset_testpoint;
                }
                checkedEdges.push_back(edge);
            }
            linkedEdge = linkedEdge->next;
        }
    }
    // =========================================================================
    // edge 2
    for (itVtx = edge2->detectAgent.vertices.begin();
         itVtx != edge2->detectAgent.vertices.end(); ++itVtx) {
        vertex4 = *itVtx;
        projection = vertex4->detectAgent.getProjection(edge2);
        if (((mode == 1 || mode == 2) && projection->getOrient() != orient) ||
            ((mode == 3 || mode == 4) && projection->getOrient() == orient))
            continue;
        if (vertex4->getID() == -1)
            continue;
        linkedEdge = vertex4->linkedEdges.front();
        while (linkedEdge != NULL) {
            edge = linkedEdge->edge;
            if (find(checkedEdges.begin(), checkedEdges.end(), edge)
                == checkedEdges.end()) {
                vertex5 = NULL; vertex6 = NULL;
                if (edge->getPolygon(OrientLeft) == markPolygon ||
                    edge->getPolygon(OrientRight) == markPolygon) {
                    vertex5 = edge->getEndPoint(FirstPoint);
                    vertex6 = edge->getEndPoint(SecondPoint);
                }
                if (vertex5 != NULL) {
                    if (((vertex5 != vertex1 && vertex6 != vertex1) &&
                         Sphere::isIntersect(vertex1, testPoint, vertex5, vertex6)) ||
                        ((vertex5 != vertex3 && vertex6 != vertex3) &&
                         Sphere::isIntersect(vertex3, testPoint, vertex5, vertex6)))
                        goto return_nocross_but_reset_testpoint;
                }
                checkedEdges.push_back(edge);
            }
            linkedEdge = linkedEdge->next;
        }
    }
    // =========================================================================
    for (int i = 0; i < 3; ++i) {
        for (itPrj = vertices[i]->detectAgent.getProjections().begin();
             itPrj != vertices[i]->detectAgent.getProjections().end(); ++itPrj) {
            edge = (*itPrj).getEdge();
            if (find(checkedEdges.begin(), checkedEdges.end(), edge)
                == checkedEdges.end()) {
                vertex5 = NULL; vertex6 = NULL;
                if (edge->getPolygon(OrientLeft) == markPolygon ||
                    edge->getPolygon(OrientRight) == markPolygon) {
                    vertex5 = edge->getEndPoint(FirstPoint);
                    vertex6 = edge->getEndPoint(SecondPoint);
                }
                if (vertex5 != NULL) {
                    if (((vertex5 != vertex1 && vertex6 != vertex1) &&
                         Sphere::isIntersect(vertex1, testPoint, vertex5, vertex6)) ||
                        ((vertex5 != vertex3 && vertex6 != vertex3) &&
                         Sphere::isIntersect(vertex3, testPoint, vertex5, vertex6)))
                        goto return_nocross_but_reset_testpoint;
                }
                checkedEdges.push_back(edge);
            }
        }
    }
    // -------------------------------------------------------------------------
    return NoCross;
return_nocross_but_reset_testpoint:
    Coordinate x1, x2; Location loc;
    x1 = testPoint->getCoordinate(OldTimeLevel);
    Sphere::calcMiddlePoint(vertex1->getCoordinate(NewTimeLevel),
                            vertex3->getCoordinate(NewTimeLevel), x2);
    meshManager.checkLocation(x2, loc);
    testPoint->setCoordinate(x2, NewTimeLevel);
    testPoint->setLocation(loc);
    testPoint->setCoordinate(x1, OldTimeLevel);
    return NoCross;
}
예제 #3
0
Status PotentialCrossDetector::detectReplaceVertex(EdgePointer *edgePointer,
                                                   Vertex *oldVertex,
                                                   Vertex *newVertex)
{
    static std::list<Vertex *>::const_iterator itVtx;
    static std::list<Projection>::const_iterator itPrj;
    Vertex *vertex1, *vertex2, *vertex3, *vertex4;
    Projection *projection;
    OrientStatus orient;
    Edge *edge;
    EdgePointer *linkedEdge = oldVertex->linkedEdges.front();
    for (int i = 0; i < oldVertex->linkedEdges.size(); ++i) {
        // ---------------------------------------------------------------------
        // branch-1
        // =====================================================================
        // check the paired vertices of the linked edge
        edge = linkedEdge->edge;
        vertex1 = NULL, vertex2 = NULL;
        if (edge->getEndPoint(FirstPoint) == oldVertex) {
            vertex1 = newVertex;
            vertex2 = edge->getEndPoint(SecondPoint);
        } else if (edge->getEndPoint(SecondPoint) == oldVertex) {
            vertex1 = edge->getEndPoint(FirstPoint);
            vertex2 = newVertex;
        }
        if (vertex1 != vertex2) {
            for (itVtx = edge->detectAgent.vertices.begin();
                 itVtx != edge->detectAgent.vertices.end(); ++itVtx) {
                vertex3 = *itVtx;
                if (vertex3->getID() == -1 ||
                    vertex3 == vertex1 || vertex3 == vertex2)
                    continue;
                projection = vertex3->detectAgent.getProjection(edge);
                orient = Sphere::orient(vertex1, vertex2, vertex3);
                if (orient != projection->getOrient()) {
                    if (projection->tags.isSet(Approaching))
                        ApproachingVertices::jumpVertex(oldVertex, vertex3);
                    return Cross;
                }
            }
        } else {
            linkedEdge = linkedEdge->next;
            continue;
        }
        // =====================================================================
        // check other linked edges
        if (edge->getEndPoint(FirstPoint) == oldVertex)
            vertex1 = edge->getEndPoint(SecondPoint);
        else
            vertex1 = edge->getEndPoint(FirstPoint);
        EdgePointer *otherLinkedEdge = oldVertex->linkedEdges.front();
        for (int j = 0; j < oldVertex->linkedEdges.size(); ++j) {
            if (otherLinkedEdge != linkedEdge) {
                edge = otherLinkedEdge->edge;
                // check linked edges of paired vertices
                for (itVtx = edge->detectAgent.vertices.begin();
                     itVtx != edge->detectAgent.vertices.end(); ++itVtx) {
                    if ((*itVtx)->getID() == -1) continue;
                    EdgePointer *vertexLinkedEdge = (*itVtx)->linkedEdges.front();
                    for (int k = 0; k < (*itVtx)->linkedEdges.size(); ++k) {
                        vertex2 = vertexLinkedEdge->edge->getEndPoint(FirstPoint);
                        vertex3 = vertexLinkedEdge->edge->getEndPoint(SecondPoint);
                        if ((vertex2 == oldVertex || vertex3 == oldVertex ||
                             vertex2 == newVertex || vertex3 == newVertex) ||
                            vertexLinkedEdge->edge == edgePointer->edge) {
                            vertexLinkedEdge = vertexLinkedEdge->next;
                            continue;
                        }
                        if (vertex2 == vertex1 || vertex3 == vertex1) {
                            OrientStatus orient1, orient2, orient3;
                            orient1 = Sphere::orient(oldVertex, vertex1, *itVtx);
                            orient2 = Sphere::orient(vertex1, newVertex, *itVtx);
                            orient3 = Sphere::orient(newVertex, oldVertex, *itVtx);
                            if (orient1 == orient2 && orient1 == orient3 &&
                                orient1 != OrientOn)
                                return Cross;
                        } else {
                            if (Sphere::isIntersect(vertex1, newVertex,
                                                    vertex2, vertex3))
                                return Cross;
                        }
                        vertexLinkedEdge = vertexLinkedEdge->next;
                    }
                }
                // check the edge itself
                if (edge->getEndPoint(FirstPoint) == oldVertex)
                    vertex2 = edge->getEndPoint(SecondPoint);
                else
                    vertex2 = edge->getEndPoint(FirstPoint);
                EdgePointer *vertexLinkedEdge = vertex2->linkedEdges.front();
                for (int k = 0; k < vertex2->linkedEdges.size(); ++k) {
                    if (vertexLinkedEdge->edge != edge &&
                        vertexLinkedEdge->edge != edgePointer->edge) {
                        vertex3 = vertexLinkedEdge->edge->getEndPoint(FirstPoint);
                        vertex4 = vertexLinkedEdge->edge->getEndPoint(SecondPoint);
                        if (vertex3 != newVertex && vertex4 != newVertex &&
                            vertex3 != vertex1 && vertex4 != vertex1 &&
                            Sphere::isIntersect(vertex1, newVertex, vertex3, vertex4))
                            return Cross;
                    }
                    vertexLinkedEdge = vertexLinkedEdge->next;
                }
            }
            otherLinkedEdge = otherLinkedEdge->next;
        }
        // ---------------------------------------------------------------------
        // branch-2
        // check the paired edges of the old vertex
        for (itPrj = oldVertex->detectAgent.getProjections().begin();
             itPrj != oldVertex->detectAgent.getProjections().end(); ++itPrj) {
            edge = (*itPrj).getEdge();
            if (edge == edgePointer->edge)
                continue;
            if (vertex1 == edge->getEndPoint(FirstPoint)) {
                vertex2 = edge->getEndPoint(SecondPoint);
            } else if (vertex1 == edge->getEndPoint(SecondPoint)) {
                vertex2 = edge->getEndPoint(FirstPoint);
            } else
                continue;
            if (vertex2 == newVertex ||
                !Sphere::isProject(vertex1, newVertex, vertex2))
                continue;
            if (Sphere::orient(vertex1, vertex2, oldVertex) !=
                Sphere::orient(vertex1, vertex2, newVertex))
                return Cross;
        }
        linkedEdge = linkedEdge->next;
    }
    return NoCross;
}