@@ -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 ;
0 commit comments