File: component.h

package info (click to toggle)
octave-iso2mesh 1.9.8%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 11,128 kB
  • sloc: cpp: 11,982; ansic: 10,158; sh: 365; makefile: 59
file content (101 lines) | stat: -rw-r--r-- 3,791 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#ifndef COMPONENT_H
#define COMPONENT_H
#include "triangle.h"

//! ComponentStruct references triangles and vertices of a Triangulation
//! and provides serveral convenience functions.

class ComponentStruct {
public:
    List *triangles;
    List *vertices;
    List *boundaries;
    // component = triangles of list
    ComponentStruct() {
        triangles = vertices = boundaries = NULL;
    }
    void clear() {
        if(triangles) triangles->removeNodes();
        if(vertices) vertices->removeNodes();
        if(boundaries) while(List *l = (List*) boundaries->popHead()) delete(l);
    }
    ComponentStruct(List* l) {
        this->triangles = new List(l);
        vertices = boundaries = NULL;
    }
    // component = triangles connected to t
    ComponentStruct(Triangle *t, unsigned b = 2) {
        this->triangles = new List();
        Triangle *t1, *t2, *t3;
        MARK_BIT(t,b);
        List todo(t);
        while (todo.numels()) {
            t = (Triangle *)todo.popHead();
            this->triangles->appendHead(t);
            t1 = t->t1(); t2 = t->t2(); t3 = t->t3();
            if (t1 != NULL && !IS_BIT(t1,b)) {MARK_BIT(t1,b); todo.appendHead(t1);}
            if (t2 != NULL && !IS_BIT(t2,b)) {MARK_BIT(t2,b); todo.appendHead(t2);}
            if (t3 != NULL && !IS_BIT(t3,b)) {MARK_BIT(t3,b); todo.appendHead(t3);}
        }
        this->unmarkBit(b);
        vertices = boundaries = NULL;
    }
    void initializeBoundaries() {
        vertices = getVertices();
        boundaries = getBoundaryLoops();
    }
    void markBit(unsigned b) {
        Triangle *t; Node *n;
        FOREACHVTTRIANGLE(triangles, t, n) MARK_BIT(t,b);
    }
    void unmarkBit(unsigned b) {
        Triangle *t; Node *n;
        FOREACHVTTRIANGLE(triangles, t, n) UNMARK_BIT(t,b);
    }
    // get the vertices of the the component
    List* getVertices(unsigned b = 2) {
        Triangle *t = (Triangle*)this->triangles->head()->data;
        Vertex *v, *v1, *v2, *v3;
        Triangle *t1, *t2, *t3;
        Node *n;
        MARK_BIT(t,b);
        List todo(t), *vertexList = new List();
        while (todo.numels()) {
            t = (Triangle *)todo.popHead();
            t1 = t->t1(); t2 = t->t2(); t3 = t->t3();
            v1 = t->v1(); v2 = t->v2(); v3 = t->v3();
            if (!IS_BIT(v1,b)) {MARK_BIT(v1,b); vertexList->appendHead(v1);}
            if (!IS_BIT(v2,b)) {MARK_BIT(v2,b); vertexList->appendHead(v2);}
            if (!IS_BIT(v3,b)) {MARK_BIT(v3,b); vertexList->appendHead(v3);}
            if (t1 != NULL && !IS_BIT(t1,b)) {MARK_BIT(t1,b); todo.appendHead(t1);}
            if (t2 != NULL && !IS_BIT(t2,b)) {MARK_BIT(t2,b); todo.appendHead(t2);}
            if (t3 != NULL && !IS_BIT(t3,b)) {MARK_BIT(t3,b); todo.appendHead(t3);}
        }
        this->unmarkBit(b);
        FOREACHVVVERTEX(vertexList, v, n) {UNMARK_BIT(v,0); UNMARK_BIT(v,2);}
        return vertexList;
    }
    // get list of boundary loops of the component (= list of list of vertices)
    List* getBoundaryLoops(unsigned b = 2) {
        Vertex *v, *w;
        Node *n;
        List *loopList = new List(), *loop;
        this->vertices = this->getVertices();
        FOREACHVVVERTEX(this->vertices, v, n) {
            // find next vertex of an unmarked boundary
            if (!IS_BIT(v,b) && v->isOnBoundary()) {
                w = v;
                loop = new List();
                do { // mark all vertices at this boundary
                    loop->appendHead(w);
                    MARK_BIT(w,b);
                    w = w->nextOnBoundary();
                } while (w != v);
                loopList->appendHead(loop);
            }
        }
        FOREACHVVVERTEX(this->vertices, v, n) {UNMARK_BIT(v,2);}
        return loopList;
    }
};
#endif // COMPONENT_H