|
1 | 1 | #include "MeshNeoWeaver.h"
|
2 |
| -#define LERP_BRIDGE 1 |
| 2 | +//#define LERP_BRIDGE 1 |
3 | 3 | #define DOO_SABIN 1
|
4 | 4 | HDS_Mesh* MeshNeoWeaver::create(const mesh_t* ref,
|
5 | 5 | const confMap &conf)
|
6 | 6 | {
|
7 | 7 | if (!ref) return nullptr;
|
8 | 8 |
|
9 |
| - return createConicalWeaving(ref, conf); |
| 9 | + //return createConicalWeaving(ref, conf); |
10 | 10 | //return createClassicalWeaving(ref, conf);
|
11 | 11 | //return createWeaving(ref, conf);
|
12 | 12 | //return createOctWeaving(ref, conf);
|
| 13 | + return createTriangleWeaving(ref, conf); |
13 | 14 | }
|
14 | 15 |
|
15 | 16 | HDS_Mesh* MeshNeoWeaver::createOctWeaving(const mesh_t* ref_mesh,
|
@@ -1420,6 +1421,190 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
|
1420 | 1421 | return ret;
|
1421 | 1422 | }
|
1422 | 1423 |
|
| 1424 | +HDS_Mesh* MeshNeoWeaver::createTriangleWeaving(const mesh_t* ref_mesh, |
| 1425 | + const confMap &conf) { |
| 1426 | + // scaling |
| 1427 | + const Float patchScale = conf.at("patchScale"); |
| 1428 | + const bool patchUniform = (conf.at("patchUniform") == 1.0f); |
| 1429 | + const Float layerOffset = conf.at("layerOffset"); |
| 1430 | + const Float patchStripScale = conf.at("patchStripScale"); // 0.25 by default |
| 1431 | + const uint32_t patchSeg = 2;// static_cast<uint32_t>(conf.at("patchSeg")); |
| 1432 | + const uint32_t patchCurvedSample = 3; |
| 1433 | + auto &ref_verts = ref_mesh->verts(); |
| 1434 | + auto &ref_hes = ref_mesh->halfedges(); |
| 1435 | + auto &ref_faces = ref_mesh->faces(); |
| 1436 | + size_t refHeCount = ref_hes.size(); |
| 1437 | + size_t refEdgeCount = refHeCount >> 1; |
| 1438 | + size_t refFaceCount = ref_faces.size(); |
| 1439 | + |
| 1440 | + mesh_t::resetIndex(); |
| 1441 | + vector<vert_t> verts; |
| 1442 | + vector<he_t> hes; |
| 1443 | + vector<face_t> faces; |
| 1444 | + // cache edge centers |
| 1445 | + vector<QVector3D> heCenters(refHeCount); |
| 1446 | + for (auto &he: ref_hes) |
| 1447 | + { |
| 1448 | + heCenters[he.index] = ref_mesh->edgeCenter(he); |
| 1449 | + } |
| 1450 | + // cache edge patch pos |
| 1451 | + vector<QVector3D> cornerPatchPos(refHeCount * 3); |
| 1452 | + for (auto &he: ref_hes) |
| 1453 | + { |
| 1454 | + QVector3D c = (heCenters[he.index] + heCenters[he.next()->index])/2; |
| 1455 | + cornerPatchPos[he.index*3 + 0] = |
| 1456 | + Utils::Lerp(c, ref_mesh->vertFromHe(he.index)->pos, patchScale); |
| 1457 | + cornerPatchPos[he.index*3 + 1] = |
| 1458 | + Utils::Lerp(c, ref_mesh->vertFromHe(he.next()->index)->pos, patchScale); |
| 1459 | + cornerPatchPos[he.index*3 + 2] = |
| 1460 | + Utils::Lerp(c, ref_mesh->vertFromHe(he.next()->next()->index)->pos, patchScale); |
| 1461 | + } |
| 1462 | + // cache edge patch norm |
| 1463 | + vector<QVector3D> heNorm(refHeCount); |
| 1464 | + for (auto &he : ref_hes) |
| 1465 | + { |
| 1466 | + if (he.flip_offset>0) continue; |
| 1467 | + heNorm[he.index] = heNorm[he.flip()->index] = |
| 1468 | + QVector3D::normal(cornerPatchPos[he.flip()->index * 3 + 1], |
| 1469 | + cornerPatchPos[he.index * 3 + 1], |
| 1470 | + cornerPatchPos[he.index * 3]); |
| 1471 | + } |
| 1472 | + // Construct bridge patch |
| 1473 | + const int nESamples = 1; |
| 1474 | + const int nFSamples = 1; |
| 1475 | + const int sPatchFaceCount = nESamples * 3 + (nFSamples + 2) * 2; |
| 1476 | + |
| 1477 | + const int sPatchHeCount = sPatchFaceCount * 4; |
| 1478 | + const int sPatchVertCount = sPatchFaceCount * 2 + 2; |
| 1479 | + const int sPatchCount = refEdgeCount; |
| 1480 | + faces.resize(sPatchCount * sPatchFaceCount); |
| 1481 | + hes.resize(sPatchCount * sPatchHeCount); |
| 1482 | + verts.resize(sPatchCount * sPatchVertCount); |
| 1483 | + |
| 1484 | + for (hdsid_t i = 0; i < refEdgeCount; i++) |
| 1485 | + { |
| 1486 | + int patchFaceOffset = i * sPatchFaceCount; |
| 1487 | + int patchHEOffset = i * sPatchHeCount; |
| 1488 | + int patchVertOffset = i * sPatchVertCount; |
| 1489 | + auto curHE = hes.data() + patchHEOffset; |
| 1490 | + auto curVert = verts.data() + patchVertOffset; |
| 1491 | + auto curFace = faces.data() + patchFaceOffset; |
| 1492 | + |
| 1493 | + for (int j = 0; j < sPatchFaceCount; j++) |
| 1494 | + { |
| 1495 | + constructFace(curHE, 4, curFace); |
| 1496 | + if (j != sPatchFaceCount - 1) |
| 1497 | + { |
| 1498 | + (curHE + 2)->flip_offset = 2; |
| 1499 | + (curHE + 4)->flip_offset = -2; |
| 1500 | + } |
| 1501 | + constructHEPair(curVert, curHE++); |
| 1502 | + constructHEPair(curVert + 1, curHE++); |
| 1503 | + constructHEPair(curVert + 3, curHE++); |
| 1504 | + constructHEPair(curVert + 2, curHE++); |
| 1505 | + curFace++; |
| 1506 | + curVert += 2; |
| 1507 | + } |
| 1508 | + } |
| 1509 | + |
| 1510 | + // start from one edge and move to next woven edge |
| 1511 | + vector<bool> visitedHE(refHeCount, false); |
| 1512 | + vector<bool> heOnTopFlag(refHeCount, false); |
| 1513 | + vector<hdsid_t> heToPatch(refHeCount); |
| 1514 | + hdsid_t curPatchID = 0; |
| 1515 | + QVector3D patchPos[sPatchVertCount];// [sPatchMaxVertices]; |
| 1516 | + for (int i = 0; i < refHeCount; i++) |
| 1517 | + { |
| 1518 | + if (visitedHE[i]) continue; |
| 1519 | + |
| 1520 | + auto he = &ref_hes[i]; |
| 1521 | + auto curHE = he; |
| 1522 | + |
| 1523 | + do |
| 1524 | + { |
| 1525 | + // neighboring edge ids |
| 1526 | + hdsid_t neiEdgeIDs[]{ |
| 1527 | + curHE->prev()->flip()->index, |
| 1528 | + curHE->prev()->index, |
| 1529 | + curHE->index, |
| 1530 | + curHE->flip()->index, |
| 1531 | + curHE->flip()->prev()->index, |
| 1532 | + curHE->flip()->prev()->flip()->index |
| 1533 | + }; |
| 1534 | + //get bezier control points |
| 1535 | + // Quad--Tri--Quad--Tri(face band)--Quad(Edge band) |
| 1536 | + auto patchVerts = &verts[curPatchID * sPatchVertCount]; |
| 1537 | + int segSamples[]{ 0, nESamples * 2, 2, nFSamples * 2,2, |
| 1538 | + nESamples * 2, 2, nFSamples * 2,2, |
| 1539 | + nESamples * 2 }; |
| 1540 | + int segIndex[10]; |
| 1541 | + for (int i = 0; i < 10; i++) |
| 1542 | + { |
| 1543 | + segIndex[i] = segSamples[i] + (i > 0 ? segIndex[i - 1] : 0); |
| 1544 | + } |
| 1545 | + |
| 1546 | + patchPos[segIndex[0]+1] = cornerPatchPos[neiEdgeIDs[0] * 3]; |
| 1547 | + patchPos[segIndex[0]] = cornerPatchPos[neiEdgeIDs[0] * 3 + 1]; |
| 1548 | + //face patch |
| 1549 | + patchPos[segIndex[1]+1] = patchPos[segIndex[2]+1] = |
| 1550 | + patchPos[segIndex[3]+1] = patchPos[segIndex[4]+1] = |
| 1551 | + cornerPatchPos[neiEdgeIDs[1] * 3 + 1]; |
| 1552 | + patchPos[segIndex[1]] = cornerPatchPos[neiEdgeIDs[1] * 3]; |
| 1553 | + patchPos[segIndex[2]] = patchPos[segIndex[3]] = |
| 1554 | + (cornerPatchPos[neiEdgeIDs[1] * 3]+ cornerPatchPos[neiEdgeIDs[1] * 3+2]) / 2; |
| 1555 | + patchPos[segIndex[4]] = cornerPatchPos[neiEdgeIDs[1] * 3 + 2]; |
| 1556 | + //second face patch |
| 1557 | + patchPos[segIndex[5]] = patchPos[segIndex[6]] = |
| 1558 | + patchPos[segIndex[7]] = patchPos[segIndex[8]] = |
| 1559 | + cornerPatchPos[neiEdgeIDs[4] * 3 + 1]; |
| 1560 | + patchPos[segIndex[5] + 1] = cornerPatchPos[neiEdgeIDs[4] * 3+2]; |
| 1561 | + patchPos[segIndex[6] + 1] = patchPos[segIndex[7] + 1] = |
| 1562 | + (cornerPatchPos[neiEdgeIDs[4] * 3] + cornerPatchPos[neiEdgeIDs[4] * 3 + 2]) / 2; |
| 1563 | + patchPos[segIndex[8] + 1] = cornerPatchPos[neiEdgeIDs[4] * 3]; |
| 1564 | + //edge patch |
| 1565 | + patchPos[segIndex[9] + 1] = cornerPatchPos[neiEdgeIDs[5] * 3 + 1]; |
| 1566 | + patchPos[segIndex[9]] = cornerPatchPos[neiEdgeIDs[5] * 3]; |
| 1567 | + |
| 1568 | + // update bridge up/down |
| 1569 | + for (int i = 3; i < 7; i++) |
| 1570 | + { |
| 1571 | + patchPos[segIndex[i]] += heNorm[neiEdgeIDs[2]] * layerOffset; |
| 1572 | + patchPos[segIndex[i]+1] += heNorm[neiEdgeIDs[2]] * layerOffset; |
| 1573 | + } |
| 1574 | + for (int i = 7; i < 10; i++) |
| 1575 | + { |
| 1576 | + patchPos[segIndex[i]] -= heNorm[neiEdgeIDs[4]] * layerOffset; |
| 1577 | + patchPos[segIndex[i] + 1] -= heNorm[neiEdgeIDs[4]] * layerOffset; |
| 1578 | + } |
| 1579 | + |
| 1580 | + // Assign evaluated positions to patch |
| 1581 | + for (int j = 0; j < sPatchVertCount; j++) |
| 1582 | + { |
| 1583 | + (patchVerts + j)->pos = patchPos[j]; |
| 1584 | + } |
| 1585 | + // Update he-to-patch lookup table |
| 1586 | + heToPatch[neiEdgeIDs[3]] = -curPatchID; |
| 1587 | + heToPatch[neiEdgeIDs[2]] = curPatchID++; |
| 1588 | + visitedHE[neiEdgeIDs[2]] = visitedHE[neiEdgeIDs[3]] = true; |
| 1589 | + |
| 1590 | + heOnTopFlag[neiEdgeIDs[1]] = true; |
| 1591 | + // Move to he corresponding to next connected trip |
| 1592 | + curHE = curHE->rotCCW()->next()->flip(); |
| 1593 | + } while (curHE != he); |
| 1594 | + } |
| 1595 | + |
| 1596 | + // Finalize Mesh |
| 1597 | + unordered_set<hdsid_t> exposedHEs; |
| 1598 | + for (auto &he : hes) |
| 1599 | + { |
| 1600 | + if (he.flip_offset == 0) exposedHEs.insert(he.index); |
| 1601 | + } |
| 1602 | + fillNullFaces(hes, faces, exposedHEs); |
| 1603 | + HDS_Mesh* ret = new HDS_Mesh(verts, hes, faces); |
| 1604 | + //ret->updatePieceSet(); |
| 1605 | + |
| 1606 | + return ret; |
| 1607 | +} |
1423 | 1608 | HDS_Mesh* MeshNeoWeaver::createBiTriWeaving(const mesh_t* ref_mesh,
|
1424 | 1609 | const confMap &conf)
|
1425 | 1610 | {
|
|
0 commit comments