@@ -84,9 +84,8 @@ struct SmoothBezier {
84
84
const glm::vec3 edgeVec =
85
85
impl->vertPos_ [edge.endVert ] - impl->vertPos_ [edge.startVert ];
86
86
const glm::vec3 edgeNormal =
87
- (impl->faceNormal_ [edge.face ] +
88
- impl->faceNormal_ [impl->halfedge_ [edge.pairedHalfedge ].face ]) /
89
- 2 .0f ;
87
+ impl->faceNormal_ [edge.face ] +
88
+ impl->faceNormal_ [impl->halfedge_ [edge.pairedHalfedge ].face ];
90
89
glm::vec3 dir =
91
90
glm::cross (glm::cross (edgeNormal, edgeVec), vertNormal[edge.startVert ]);
92
91
tangent = CircularTangent (dir, edgeVec);
@@ -966,7 +965,7 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {
966
965
group.push_back (normals.size () - 1 );
967
966
float dot = glm::dot (here.edgeVec , next.edgeVec );
968
967
const float phi =
969
- dot >= 1 ? 0
968
+ dot >= 1 ? kTolerance
970
969
: (dot <= -1 ? glm::pi <float >() : glm::acos (dot));
971
970
normals.back () += faceNormal_[next.face ] * phi;
972
971
});
@@ -1014,6 +1013,35 @@ void Manifold::Impl::SetNormals(int normalIdx, float minSharpAngle) {
1014
1013
}
1015
1014
}
1016
1015
1016
+ /* *
1017
+ * Tangents get flattened to create sharp edges by setting their weight to zero.
1018
+ * This is the natural limit of reducing the weight to increase the sharpness
1019
+ * smoothly. This limit gives a decent shape, but it causes the parameterization
1020
+ * to be stretched and compresses it near the edges, which is good for resolving
1021
+ * tight curvature, but bad for property interpolation. This function fixes the
1022
+ * parameter stretch at the limit for sharp edges, since there is no curvature
1023
+ * to resolve. Note this also changes the overall shape - making it more evenly
1024
+ * curved.
1025
+ */
1026
+ void Manifold::Impl::LinearizeFlatTangents () {
1027
+ const int n = halfedgeTangent_.size ();
1028
+ for_each_n (autoPolicy (n), zip (halfedgeTangent_.begin (), countAt (0 )), n,
1029
+ [this ](thrust::tuple<glm::vec4&, int > inOut) {
1030
+ glm::vec4& tangent = thrust::get<0 >(inOut);
1031
+ const int halfedge = thrust::get<1 >(inOut);
1032
+ if (tangent.w != 0 ) {
1033
+ return ;
1034
+ }
1035
+
1036
+ const glm::vec4 otherTangent =
1037
+ halfedgeTangent_[halfedge_[halfedge].pairedHalfedge ];
1038
+ glm::vec3 edge = vertPos_[halfedge_[halfedge].endVert ] +
1039
+ glm::vec3 (otherTangent) -
1040
+ vertPos_[halfedge_[halfedge].startVert ];
1041
+ tangent = glm::vec4 (edge / 3 .0f , 1 );
1042
+ });
1043
+ }
1044
+
1017
1045
/* *
1018
1046
* Calculates halfedgeTangent_, allowing the manifold to be refined and
1019
1047
* smoothed. The tangents form weighted cubic Beziers along each edge. This
@@ -1094,6 +1122,7 @@ void Manifold::Impl::CreateTangents(int normalIdx) {
1094
1122
});
1095
1123
}
1096
1124
}
1125
+ LinearizeFlatTangents ();
1097
1126
}
1098
1127
1099
1128
/* *
@@ -1207,6 +1236,7 @@ void Manifold::Impl::CreateTangents(std::vector<Smoothness> sharpenedEdges) {
1207
1236
});
1208
1237
}
1209
1238
}
1239
+ LinearizeFlatTangents ();
1210
1240
}
1211
1241
1212
1242
/* *
@@ -1517,6 +1547,7 @@ void Manifold::Impl::Refine(std::function<int(glm::vec3)> edgeDivisions) {
1517
1547
// being non-coplanar, and hence not being related to the original faces.
1518
1548
meshRelation_.originalID = ReserveIDs (1 );
1519
1549
InitializeOriginal ();
1550
+ CreateFaces ();
1520
1551
}
1521
1552
1522
1553
halfedgeTangent_.resize (0 );
0 commit comments