File: SpatialEdge.cpp

package info (click to toggle)
siril 1.4.0~rc2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 47,352 kB
  • sloc: ansic: 174,082; cpp: 28,254; python: 7,891; makefile: 974; xml: 777; sh: 271
file content (179 lines) | stat: -rw-r--r-- 4,867 bytes parent folder | download | duplicates (5)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//#     Filename:       SpatialEdge.cpp
//#
//#     The SpatialEdge class is defined here.
//#
//#     Author:         Peter Z. Kunszt based on A. Szalay's code
//#
//#     Date:           October 15, 1998
//#
//#	    SPDX-FileCopyrightText: 2000 Peter Z. Kunszt Alex S. Szalay, Aniruddha R. Thakar
//#                     The Johns Hopkins University
//#
//#     Modification History:
//#
//#     Oct 18, 2001 : Dennis C. Dinge -- Replaced ValVec with std::vector
//#

#include "SpatialEdge.h"

// ===========================================================================
//
// Macro definitions for readability
//
// ===========================================================================
#define IV(x) tree_.nodes_[index].v_[(x)]
#define IW(x) tree_.nodes_[index].w_[(x)]
#define LAYER tree_.layers_[layerindex_]

// ===========================================================================
//
// Member functions for class SpatialEdge
//
// ===========================================================================

/////////////CONSTRUCTOR//////////////////////////////////
//
SpatialEdge::SpatialEdge(SpatialIndex &tree, size_t layerindex) : tree_(tree), layerindex_(layerindex)
{
    edges_ = new Edge[LAYER.nEdge_ + 1];
    lTab_  = new Edge *[LAYER.nVert_ * 6];

    // initialize lookup table, we depend on that nullptr
    for (size_t i = 0; i < LAYER.nVert_ * 6; i++)
        lTab_[i] = nullptr;

    // first vertex index for the vertices to be generated
    index_ = LAYER.nVert_;
}

/////////////DESTRUCTOR///////////////////////////////////
//
SpatialEdge::~SpatialEdge()
{
    delete[] edges_;
    delete[] lTab_;
}

/////////////MAKEMIDPOINTS////////////////////////////////
// makeMidPoints: interface to this class. Set midpoints of every
//                node in this layer.
void SpatialEdge::makeMidPoints()
{
    size_t c = 0;
    size_t index;

    // build up the new edges

    index = (size_t)LAYER.firstIndex_;
    for (size_t i = 0; i < LAYER.nNode_; i++, index++)
    {
        c = newEdge(c, index, 0);
        c = newEdge(c, index, 1);
        c = newEdge(c, index, 2);
    }
}

/////////////NEWEDGE//////////////////////////////////////
// newEdge: determines whether the edge em is already in the list.  k
//          is the label of the edge within the node Returns index of next
//          edge, if not found, or returns same if it is already there.  Also
//          registers the midpoint in the node.

size_t SpatialEdge::newEdge(size_t emindex, size_t index, int k)
{
    Edge *en, *em;
    size_t swap;

    em = &edges_[emindex];

    switch (k)
    {
        case 0:
            em->start_ = IV(1);
            em->end_   = IV(2);
            break;
        case 1:
            em->start_ = IV(0);
            em->end_   = IV(2);
            break;
        case 2:
            em->start_ = IV(0);
            em->end_   = IV(1);
            break;
    }

    // sort the vertices by increasing index

    if (em->start_ > em->end_)
    {
        swap       = em->start_;
        em->start_ = em->end_;
        em->end_   = swap;
    }

    // check all previous edges for a match, return pointer if
    // already present, log the midpoint with the new face as well

    if ((en = edgeMatch(em)) != nullptr)
    {
        IW(k) = en->mid_;
        return emindex;
    }

    // this is a new edge, immediately process the midpoint,
    // and save it with the nodes and the edge as well

    insertLookup(em);
    IW(k)    = getMidPoint(em);
    em->mid_ = IW(k);
    return ++emindex;
}

/////////////INSERTLOOKUP/////////////////////////////////
// insertLookup: insert the edge em into the lookup table.
//               indexed by em->start_.
//               Every vertex has at most 6 edges, so only
//               that much lookup needs to be done.
void SpatialEdge::insertLookup(Edge *em)
{
    int j = 6 * em->start_;
    int i;

    // do not loop beyond 6

    for (i = 0; i < 6; i++, j++)
    {
        if (lTab_[j] == nullptr)
        {
            lTab_[j] = em;
            return;
        }
    }
}

/////////////EDGEMATCH////////////////////////////////////
// edgeMatch: fast lookup using the first index em->start_.
//            return pointer to edge if matches, null if not.
SpatialEdge::Edge *SpatialEdge::edgeMatch(Edge *em)
{
    int i = 6 * em->start_;

    while (lTab_[i] != nullptr)
    {
        if (em->end_ == lTab_[i]->end_)
            return lTab_[i];

        i++;
    }
    return nullptr;
}

/////////////GETMIDPOINT//////////////////////////////////
// getMidPoint: compute the midpoint of the edge using vector
//              algebra and return its index in the vertex list
size_t SpatialEdge::getMidPoint(Edge *em)
{
    tree_.vertices_[index_] = tree_.vertices_[em->start_] + tree_.vertices_[em->end_];
    tree_.vertices_[index_].normalize();
    return index_++;
}