Skip to content

Commit 4195df2

Browse files
author
urianawu
committed
doo-sabin method, use intersection of heCross as new edge endpoints
1 parent 910d57f commit 4195df2

File tree

3 files changed

+97
-16
lines changed

3 files changed

+97
-16
lines changed

src/MeshFactory/MeshNeoWeaver.cpp

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,9 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
773773
vector<he_t> hes;
774774
vector<face_t> faces;
775775

776+
#ifdef DOO_SABIN
776777
//evaluate doo-sabin subd
777-
vector<QVector3D> heCorners(refHeCount);
778+
vector<QVector3D> heCorners(refHeCount*2);
778779
for (int i = 0; i < refFaceCount; i++) {
779780
//loop each face and evaluate new positions
780781
QVector3D fc = ref_mesh->faceCenter(i);
@@ -783,12 +784,13 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
783784
do
784785
{
785786
QVector3D curEc = ref_mesh->edgeCenter(curHE->index);
786-
heCorners[curHE->index]
787+
heCorners[curHE->index<<1] = heCorners[(curHE->prev()->index<<1)+1]
787788
= (fc + prevEc + curEc + ref_mesh->vertFromHe(curHE->index)->pos) / 4;
788789
prevEc = curEc;
789790
curHE = curHE->next();
790791
} while (curHE != ref_mesh->heFromFace(i));
791792
}
793+
#endif
792794
//calculate new edge normal and center
793795

794796
vector<QVector3D> fNorms(refFaceCount);
@@ -817,33 +819,99 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
817819
#ifdef DOO_SABIN
818820
//get center point,
819821
heCenters[i] = heCenters[hefId]
820-
= (heCorners[i] + heCorners[he->next()->index]
821-
+ heCorners[hefId] + heCorners[hef->next()->index]) / 4;
822+
= (heCorners[i<<1] + heCorners[(i<<1)+1]
823+
+ heCorners[hefId<<1] + heCorners[(hefId<<1)+1]) / 4;
822824
//calculate normal of v1, v2, cp and normal of v3, v4, cp,
823-
QVector3D n1 = QVector3D::normal(heCenters[i], heCorners[he->next()->index], heCorners[i]);
824-
QVector3D n2 = QVector3D::normal(heCenters[i], heCorners[hef->next()->index], heCorners[hefId]);
825+
QVector3D n1 = QVector3D::normal(heCenters[i], heCorners[(i<<1)+1], heCorners[i<<1]);
826+
QVector3D n2 = QVector3D::normal(heCenters[i], heCorners[(hefId<<1)+1], heCorners[hefId<<1]);
825827

826828
//and get the average normal
827829
heNorms[i] = heNorms[hefId] = (n1 + n2).normalized();
828-
830+
829831
#else
830832
heNorms[i] = heNorms[hefId]
831833
= (fNorms[he->fid] + fNorms[hef->fid]).normalized();
832834
heCenters[i] = heCenters[hefId] = ref_mesh->edgeCenter(i);
835+
heDirs[i] = ref_mesh->edgeVector(i) * 0.5f;// half length of he
836+
heDirs[hefId] = -heDirs[i];
833837
#endif
834838
}
835839

840+
#ifdef DOO_SABIN
841+
//project heCorners to this plane
842+
for (hdsid_t i = 0; i < refHeCount*2; i++)
843+
{
844+
heCorners[i] = Utils::LinePlaneIntersect(
845+
heCorners[i], heCorners[i] + heNorms[i >> 1],
846+
heCenters[i >> 1], heNorms[i >> 1]);
847+
}
848+
#endif
849+
850+
#ifdef DOO_SABIN
851+
852+
//////////////////////
853+
//get approximate heCross
836854
for (hdsid_t i = 0; i < refHeCount; i++)
837855
{
838856
const he_t* he = &ref_hes[i];
839857
const he_t* hef = he->flip();
840858
hdsid_t hefId = hef->index;
841-
#ifdef DOO_SABIN
842-
heDirs[i] = (heCorners[he->next()->index] - heCorners[i]) * 0.5f;
843-
#else
844-
heDirs[i] = ref_mesh->edgeVector(i) * 0.5f;// half length of he
859+
heDirs[i] = (heCorners[(i << 1) + 1] - heCorners[i << 1])*0.5f;
860+
861+
// 0 (planar): cross product of face normals is zero
862+
// 1 (convex): cross product of face normals is in the same dir with edge dir
863+
// 2 (concave): cross product of face normals is opposite to edge dir
864+
QVector3D crossVec = QVector3D::crossProduct(fNorms[he->fid], fNorms[hef->fid]);
865+
heCurvatureType[i] = crossVec.isNull() ? 0
866+
: QVector3D::dotProduct(crossVec, heDirs[i]) > 0 ? 1 : 2;
867+
}
868+
// update corner flag
869+
// true: both edge are convex or concave
870+
// false: edges has different flag, or one of them is planar
871+
for (auto &he : ref_hes)
872+
{
873+
heCornerConsistent[he.index] = heCurvatureType[he.index]
874+
& heCurvatureType[he.prev()->index];
875+
}
876+
// Cache out Edge Cross Vectors for generating patches on edge.
877+
// If corner has same flag on each edge, aka flag consistent,
878+
// use cross product of edge normals to get corner vectors;
879+
// Otherwise, use average of edge vectors
880+
for (auto &he : ref_hes)
881+
{
882+
heCross[he.index << 1] = heCross[(he.prev()->index << 1) + 1]
883+
= heCornerConsistent[he.index]
884+
? QVector3D::crossProduct(heNorms[he.prev()->index],
885+
heNorms[he.index])
886+
: heDirs[he.index] - heDirs[he.prev()->index];
887+
}
888+
889+
//find new edge endpoint
890+
for (hdsid_t i = 0; i < refHeCount; i++)
891+
{
892+
const he_t* he = &ref_hes[i];
893+
const he_t* hef = he->flip();
894+
hdsid_t hefId = hef->index;
895+
//get intersecting point of two heCross
896+
QVector3D vs;
897+
Utils::LineLineIntersect(
898+
heCorners[i<<1],heCorners[i<<1]+heCross[i<<1],
899+
heCorners[(hefId<<1)+1], heCorners[(hefId << 1) + 1]+heCross[(hefId<<1)+1],
900+
&vs);
901+
heCorners[i << 1] = heCorners[(hefId << 1) + 1] = vs;
902+
}
903+
for (hdsid_t i = 0; i < refHeCount; i++)
904+
{
905+
heDirs[i] = (heCorners[(i << 1) + 1] - heCorners[i << 1])*0.5f;
906+
}
845907
#endif // DOO_SABIN
846908

909+
for (hdsid_t i = 0; i < refHeCount; i++)
910+
{
911+
const he_t* he = &ref_hes[i];
912+
const he_t* hef = he->flip();
913+
hdsid_t hefId = hef->index;
914+
847915
heDirLens[i] = heDirs[i].length();
848916
heTans[i] = QVector3D::crossProduct(heNorms[i], heDirs[i]).normalized();
849917

@@ -875,6 +943,7 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
875943
: heDirs[he.index] - heDirs[he.prev()->index];
876944
}
877945

946+
878947
// Solve linear equation to scale he cross vectors
879948
// to make the sum of current and next cross vectors match edge length
880949
for (int i = 0; i < refHeCount; i++)
@@ -934,17 +1003,17 @@ HDS_Mesh* MeshNeoWeaver::createConicalWeaving(const mesh_t* ref_mesh,
9341003
QVector3D cVec_next = heCenters[he_next_Idx] - heCenters[he_fnext_Idx];
9351004
//project to edge plane
9361005
QVector3D cVec_he =
937-
heDirs[i] * QVector3D::dotProduct(heDirs[i], cVec)
1006+
heDirs[i].normalized() * QVector3D::dotProduct(heDirs[i].normalized(), cVec)
9381007
+ heTans[i] * QVector3D::dotProduct(heTans[i], cVec);
9391008
QVector3D cVec_he_next =
940-
heDirs[i] * QVector3D::dotProduct(heDirs[i], cVec_next)
1009+
heDirs[i].normalized() * QVector3D::dotProduct(heDirs[i].normalized(), cVec_next)
9411010
+ heTans[i] * QVector3D::dotProduct(heTans[i], cVec_next);
9421011
//get centerLine which passes the edge center
9431012
//find intersection with heCrosses
9441013
QVector3D pc, pc_next;
9451014
#ifdef DOO_SABIN
946-
QVector3D vs = heCorners[i];
947-
QVector3D ve = heCorners[he_next_Idx];
1015+
QVector3D vs = heCorners[i<<1];
1016+
QVector3D ve = heCorners[(i<<1)+1];
9481017
#else
9491018
QVector3D vs = ref_mesh->vertFromHe(i)->pos;
9501019
QVector3D ve = ref_mesh->vertFromHe(he_next_Idx)->pos;

src/UI/NeoWeavePanel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ NeoWeavePanel::NeoWeavePanel(QWidget *parent) :
1818
connect(ui->patchSizeSpinBox,
1919
static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
2020
[&](double value) {
21-
ui->patchSizeSlider->setValue( value);
21+
ui->patchSizeSlider->setValue(value);
2222
});
2323

2424
// Layer Offset Value

src/Utils/utils.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,18 @@ inline void LineLineIntersect(
168168
//*pb = p3 + mub * p43;
169169
}
170170

171+
//from http://math.stackexchange.com/questions/83990/line-and-plane-intersection-in-3d
172+
inline QVector3D LinePlaneIntersect(
173+
QVector3D la, QVector3D lb,
174+
QVector3D p, QVector3D n)
175+
{
176+
QVector3D ba = lb - la;
177+
float nDotA = QVector3D::dotProduct(n, la);
178+
float nDotBA = QVector3D::dotProduct(n, ba);
179+
180+
return la + (((p.length() - nDotA) / nDotBA) * ba);
181+
}
182+
171183
}
172184

173185
#endif // UTILS_HPP

0 commit comments

Comments
 (0)