Subversion Repositories gelsvn

Rev

Rev 631 | Rev 636 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 631 Rev 633
Line 182... Line 182...
182
    
182
    
183
    bool Manifold::remove_vertex(VertexID vid)
183
    bool Manifold::remove_vertex(VertexID vid)
184
    {
184
    {
185
        if(!in_use(vid))
185
        if(!in_use(vid))
186
            return false;
186
            return false;
187
        
-
 
188
        Walker w = Manifold::walker(vid);
-
 
189
    
187
    
190
        vector<FaceID> faces;
188
        vector<FaceID> faces;
191
        
189
        
192
        for(; !w.full_circle(); w = w.circulate_vertex_ccw())
190
        int N = circulate_vertex_ccw(*this, vid, [&](FaceID f) {
193
            faces.push_back(w.face());
191
            faces.push_back(f);
194
        
192
        });
195
        for(size_t i=0;i<faces.size();++i)
193
        for(size_t i=0;i<N;++i)
196
            remove_face(faces[i]);
194
            remove_face(faces[i]);
197
            
195
            
198
        return true;
196
        return true;
199
    }
197
    }
200
 
198
 
Line 438... Line 436...
438
    
436
    
439
    size_t link_intersection(const Manifold& m, VertexID v0, VertexID v1, vector<VertexID>& lisect)
437
    size_t link_intersection(const Manifold& m, VertexID v0, VertexID v1, vector<VertexID>& lisect)
440
    {
438
    {
441
        // get the one-ring of v0
439
        // get the one-ring of v0
442
        vector<VertexID> link0;
440
        vector<VertexID> link0;
443
        for(Walker vj = m.walker(v0);
441
        circulate_vertex_ccw(m, v0, [&](VertexID vn) {
444
			!vj.full_circle(); vj = vj.circulate_vertex_ccw())
-
 
445
            link0.push_back(vj.vertex());
442
            link0.push_back(vn);
-
 
443
        });
446
		
444
		
447
        // get the one-ring of v1
445
        // get the one-ring of v1
448
        vector<VertexID> link1;
446
        vector<VertexID> link1;
449
        for(Walker vj = m.walker(v1);
447
        circulate_vertex_ccw(m, v1, [&](VertexID vn) {
450
			!vj.full_circle(); vj = vj.circulate_vertex_ccw())
-
 
451
            link1.push_back(vj.vertex());
448
            link1.push_back(vn);
-
 
449
        });
452
		
450
		
453
        // sort the vertices of the two rings
451
        // sort the vertices of the two rings
454
        sort(link0.begin(), link0.end());
452
        sort(link0.begin(), link0.end());
455
        sort(link1.begin(), link1.end());
453
        sort(link1.begin(), link1.end());
456
		
454
		
Line 536... Line 534...
536
                }
534
                }
537
            }
535
            }
538
            
536
            
539
            
537
            
540
            if(v0b != v0a)
538
            if(v0b != v0a)
541
            {
-
 
542
                Walker hew = walker(v0b);
-
 
543
                for(;!hew.full_circle(); hew = hew.circulate_vertex_ccw())
539
                circulate_vertex_ccw(*this, v0b, [&](Walker hew) {
544
                    kernel.set_vert(hew.opp().halfedge(), v0a);
540
                    kernel.set_vert(hew.opp().halfedge(), v0a);
545
            }
541
                });
546
            
542
            
547
            if(v1b != v1a)
543
            if(v1b != v1a)
548
            {
-
 
549
                Walker hew = walker(v1b);
-
 
550
                for(;!hew.full_circle(); hew = hew.circulate_vertex_ccw())
544
                circulate_vertex_ccw(*this, v1b, [&](Walker hew) {
551
                    kernel.set_vert(hew.opp().halfedge(), v1a);
545
                    kernel.set_vert(hew.opp().halfedge(), v1a);
552
            }
546
                });
553
            
547
            
554
            if(v0a != v0b)
548
            if(v0a != v0b)
555
            {
549
            {
556
                HalfEdgeID h1p = kernel.prev(h1);
550
                HalfEdgeID h1p = kernel.prev(h1);
557
                HalfEdgeID h0n = kernel.next(h0);
551
                HalfEdgeID h0n = kernel.next(h0);
Line 1339... Line 1333...
1339
        Walker j  = m.walker(v);
1333
        Walker j  = m.walker(v);
1340
        return boundary(m, j.halfedge());
1334
        return boundary(m, j.halfedge());
1341
    }
1335
    }
1342
    int valency(const Manifold& m, VertexID v)
1336
    int valency(const Manifold& m, VertexID v)
1343
    {
1337
    {
1344
        // perform full circulation to get valency
-
 
1345
        Walker vj = m.walker(v);
-
 
1346
        while(!vj.full_circle())
-
 
1347
            vj = vj.circulate_vertex_cw();
1338
        return circulate_vertex_ccw(m,v, [](Walker){});
1348
        return vj.no_steps();
-
 
1349
    }
1339
    }
1350
    
1340
    
1351
    Manifold::Vec normal(const Manifold& m, VertexID v)
1341
    Manifold::Vec normal(const Manifold& m, VertexID v)
1352
    {
1342
    {
1353
        Manifold::Vec p0 = m.pos(v);
1343
        Manifold::Vec p0 = m.pos(v);
1354
        vector<Manifold::Vec> one_ring;
1344
        vector<Manifold::Vec> one_ring;
1355
        
1345
        
1356
        // run through outgoing edges, and store them normalized
1346
        // run through outgoing edges, and store them normalized
1357
        for(Walker vj = m.walker(v); !vj.full_circle(); vj = vj.circulate_vertex_ccw()){
1347
        int N = circulate_vertex_ccw(m, v, [&](VertexID vn) {
1358
            Manifold::Vec edge = m.pos(vj.vertex())-p0;
1348
            Manifold::Vec edge = m.pos(vn) - p0;
1359
            float l = length(edge);
1349
            double l = length(edge);
-
 
1350
            if(l > 0.0)
1360
            if(l > 0.0f) one_ring.push_back(edge/l);
1351
                one_ring.push_back(edge/l);
1361
        }
1352
        });
1362
        
1353
        
1363
        Manifold::Vec n(0);
-
 
1364
        size_t N = one_ring.size();
-
 
1365
        if(N<2)
1354
        if(N<2)
1366
            return Manifold::Vec(0);
1355
            return Manifold::Vec(0);
1367
        
1356
        
1368
        size_t N_count = N;
1357
        size_t N_count = N;
1369
        size_t N_start = 0;
1358
        size_t N_start = 0;
1370
        if(boundary(m, v))
1359
        if(boundary(m, v))
1371
            N_start = 1;
1360
            N_start = 1;
1372
        
1361
        
1373
        // sum up the normals of each face surrounding the vertex
1362
        // sum up the normals of each face surrounding the vertex
-
 
1363
        Manifold::Vec n(0);
1374
        for(size_t i = N_start; i < N_count; ++i){
1364
        for(size_t i = N_start; i < N_count; ++i){
1375
            Manifold::Vec e0 = one_ring[i];
1365
            Manifold::Vec e0 = one_ring[i];
1376
            Manifold::Vec e1 = one_ring[(i+1) % N];
1366
            Manifold::Vec e1 = one_ring[(i+1) % N];
1377
            
1367
            
1378
            Manifold::Vec n_part = normalize(cross(e0, e1));
1368
            Manifold::Vec n_part = normalize(cross(e0, e1));
Line 1386... Line 1376...
1386
        return n;
1376
        return n;
1387
    }
1377
    }
1388
    
1378
    
1389
    bool connected(const Manifold& m, VertexID v0, VertexID v1)
1379
    bool connected(const Manifold& m, VertexID v0, VertexID v1)
1390
    {
1380
    {
1391
        for(Walker vj = m.walker(v0); !vj.full_circle(); vj = vj.circulate_vertex_cw()){
-
 
1392
            if(vj.vertex() == v1)
1381
        bool c=false;
1393
                return true;
1382
        circulate_vertex_ccw(m, v0, [&](VertexID v){ c |= (v==v1);});
1394
        }
-
 
1395
        return false;
1383
        return c;
1396
    }
1384
    }
1397
    
1385
    
1398
    int no_edges(const Manifold& m, FaceID f)
1386
    int no_edges(const Manifold& m, FaceID f)
1399
    {
1387
    {
1400
        // perform full circulation to get valency
-
 
1401
        Walker w = m.walker(f);
-
 
1402
        for(; !w.full_circle(); w = w.circulate_face_cw());
1388
        return circulate_face_ccw(m, f, [](Walker w){});
1403
        return w.no_steps();
-
 
1404
    }
1389
    }
-
 
1390
    
1405
    Manifold::Vec normal(const Manifold& m, FaceID f)
1391
    Manifold::Vec normal(const Manifold& m, FaceID f)
1406
    {
1392
    {
1407
        vector<Manifold::Vec> v;
1393
        vector<Manifold::Vec> v;
1408
        
1394
        
1409
        int k=0;
-
 
1410
        for(Walker  w = m.walker(f); !w.full_circle(); w = w.circulate_face_ccw(),++k)
1395
        int k= circulate_face_ccw(m, f, [&](VertexID vid) {
1411
            v.push_back(m.pos(w.vertex()));
1396
            v.push_back(m.pos(vid));
-
 
1397
        });
1412
        
1398
        
1413
        Manifold::Vec norm(0);
1399
        Manifold::Vec norm(0);
1414
        for(int i=0;i<k;++i)
1400
        for(int i=0;i<k;++i)
1415
        {
1401
        {
1416
            norm[0] += (v[i][1]-v[(i+1)%k][1])*(v[i][2]+v[(i+1)%k][2]);
1402
            norm[0] += (v[i][1]-v[(i+1)%k][1])*(v[i][2]+v[(i+1)%k][2]);
Line 1422... Line 1408...
1422
            norm /= sqrt(l);
1408
            norm /= sqrt(l);
1423
        return norm;
1409
        return norm;
1424
    }
1410
    }
1425
    
1411
    
1426
    
1412
    
1427
    float area(const Manifold& m, FaceID fid)
1413
    double area(const Manifold& m, FaceID fid)
1428
    {
1414
    {
1429
        // Get all projected vertices
1415
        // Get all projected vertices
1430
        vector<Manifold::Vec> vertices;
1416
        vector<Manifold::Vec> vertices;
1431
        Walker w = m.walker(fid);
-
 
1432
        for(; !w.full_circle(); w = w.circulate_face_ccw())
1417
        int N = circulate_face_ccw(m, fid, [&](VertexID vid) {
1433
            vertices.push_back(m.pos(w.vertex()));
1418
            vertices.push_back(m.pos(vid));
1434
        float area = 0;
1419
        });
-
 
1420
 
-
 
1421
        
1435
        size_t N = vertices.size();
1422
        double area = 0;
1436
        Manifold::Vec norm = normal(m,fid);
1423
        Manifold::Vec norm = normal(m,fid);
1437
        for(int i = 1; i < N-1; ++i)
1424
        for(int i = 1; i < N-1; ++i)
1438
            area += 0.5 * dot(norm,cross(vertices[i]-vertices[0], vertices[(i+1 )]-vertices[0]));
1425
            area += 0.5 * dot(norm,cross(vertices[i]-vertices[0], vertices[(i+1 )]-vertices[0]));
1439
        return area;
1426
        return area;
1440
    }
1427
    }
1441
    
1428
    
1442
    Manifold::Vec centre(const Manifold& m, FaceID f)
1429
    Manifold::Vec centre(const Manifold& m, FaceID f)
1443
    {
1430
    {
1444
        Manifold::Vec c(0);
1431
        Manifold::Vec c(0);
1445
        Walker w = m.walker(f);
-
 
1446
        
-
 
1447
        for(; !w.full_circle(); w = w.circulate_face_ccw()) c += m.pos(w.vertex());
1432
        int n = circulate_face_ccw(m, f, [&](VertexID v) {c+=m.pos(v);});
1448
        
-
 
1449
        c /= w.no_steps();
-
 
1450
        return c;
1433
        return c / n;
1451
    }
1434
    }
1452
    
1435
    
1453
    float perimeter(const Manifold& m, FaceID f)
1436
    double perimeter(const Manifold& m, FaceID f)
1454
    {
1437
    {
1455
        float p=0.0;
1438
        double l=0.0;
1456
        Walker w = m.walker(f);
-
 
1457
        
-
 
1458
        for(; !w.full_circle(); w = w.circulate_face_cw()) p += length(m, w.halfedge());
1439
        circulate_face_ccw(m, f, [&](HalfEdgeID h) { l+= length(m, h);});
1459
        return p;
1440
        return l;
1460
    }
1441
    }
1461
    
1442
    
1462
    bool boundary(const Manifold& m, HalfEdgeID h)
1443
    bool boundary(const Manifold& m, HalfEdgeID h)
1463
    {
1444
    {
1464
        Walker w = m.walker(h);
1445
        Walker w = m.walker(h);
1465
        return w.face() == InvalidFaceID || w.opp().face() == InvalidFaceID;
1446
        return w.face() == InvalidFaceID || w.opp().face() == InvalidFaceID;
1466
    }
1447
    }
1467
    
1448
    
1468
    float length(const Manifold& m, HalfEdgeID h)
1449
    double length(const Manifold& m, HalfEdgeID h)
1469
    {
1450
    {
1470
        Walker w = m.walker(h);
1451
        Walker w = m.walker(h);
1471
        return (m.pos(w.vertex()) - m.pos(w.opp().vertex())).length();
1452
        return (m.pos(w.vertex()) - m.pos(w.opp().vertex())).length();
1472
    }
1453
    }
1473
}
1454
}