@@ -14,7 +14,6 @@ public class Remesher {
14
14
public bool EnableSplits = true ;
15
15
public bool EnableSmoothing = true ;
16
16
17
-
18
17
public double MinEdgeLength = 0.001f ;
19
18
public double MaxEdgeLength = 0.1f ;
20
19
@@ -25,6 +24,14 @@ public enum SmoothTypes {
25
24
public SmoothTypes SmoothType = SmoothTypes . Uniform ;
26
25
27
26
27
+ // other options
28
+
29
+ // if true, then when two Fixed vertices have the same non-invalid SetID,
30
+ // we treat them as not fixed and allow collapse
31
+ public bool AllowCollapseFixedVertsWithSameSetID = true ;
32
+
33
+
34
+
28
35
public Remesher ( DMesh3 m ) {
29
36
mesh = m ;
30
37
}
@@ -97,25 +104,30 @@ ProcessResult ProcessEdge(int edgeID)
97
104
Vector3d vB = mesh . GetVertex ( b ) ;
98
105
double edge_len_sqr = ( vA - vB ) . LengthSquared ;
99
106
100
- bool aFixed = vertex_is_fixed ( a ) ;
101
- bool bFixed = vertex_is_fixed ( b ) ;
102
- bool bothFixed = ( aFixed && bFixed ) ;
107
+ // check if we should collapse, and also find which vertex we should collapse to,
108
+ // in cases where we have constraints/etc
109
+ int collapse_to = - 1 ;
110
+ bool bCanCollapse = EnableCollapses
111
+ && constraint . CanCollapse
112
+ && edge_len_sqr < MinEdgeLength * MinEdgeLength
113
+ && can_collapse ( a , b , out collapse_to ) ;
114
+
103
115
104
116
// optimization: if edge cd exists, we cannot collapse or flip. look that up here?
105
117
// funcs will do it internally...
106
118
// (or maybe we can collapse if cd exists? edge-collapse doesn't check for it explicitly...)
107
119
108
120
// if edge length is too short, we want to collapse it
109
121
bool bTriedCollapse = false ;
110
- if ( EnableCollapses && constraint . CanCollapse && bothFixed == false && edge_len_sqr < MinEdgeLength * MinEdgeLength ) {
122
+ if ( bCanCollapse ) {
111
123
112
124
int iKeep = b , iCollapse = a ;
113
125
Vector3d vNewPos = ( vA + vB ) * 0.5 ;
114
126
115
127
// if either vtx is fixed, collapse to that position
116
- if ( bFixed ) {
128
+ if ( collapse_to == b ) {
117
129
vNewPos = vB ;
118
- } else if ( aFixed ) {
130
+ } else if ( collapse_to == a ) {
119
131
iKeep = a ; iCollapse = b ;
120
132
vNewPos = vA ;
121
133
}
@@ -214,13 +226,46 @@ void update_constraints_after_split(int edgeID, int va, int vb, DMesh3.EdgeSplit
214
226
// cannot do outside loop because then pair of fixed verts connected
215
227
// by unconstrained edge will produce a new fixed vert, which is bad
216
228
// (eg on minimal triangulation of capped cylinder)
217
- if ( vertex_is_fixed ( va ) && vertex_is_fixed ( vb ) )
229
+ VertexConstraint ca = constraints . GetVertexConstraint ( va ) ;
230
+ VertexConstraint cb = constraints . GetVertexConstraint ( vb ) ;
231
+ if ( ca . Fixed && cb . Fixed ) {
232
+ int nSetID = ( ca . FixedSetID > 0 && ca . FixedSetID == cb . FixedSetID ) ?
233
+ ca . FixedSetID : VertexConstraint . InvalidSetID ;
218
234
constraints . SetOrUpdateVertexConstraint ( splitInfo . vNew ,
219
- new VertexConstraint ( true ) ) ;
235
+ new VertexConstraint ( true , nSetID ) ) ;
236
+ }
220
237
}
221
238
}
222
239
223
240
241
+ bool can_collapse ( int a , int b , out int collapse_to )
242
+ {
243
+ collapse_to = - 1 ;
244
+ if ( constraints == null )
245
+ return true ;
246
+ VertexConstraint ca = constraints . GetVertexConstraint ( a ) ;
247
+ VertexConstraint cb = constraints . GetVertexConstraint ( b ) ;
248
+ if ( ca . Fixed == false && cb . Fixed == false )
249
+ return true ;
250
+ if ( ca . Fixed == true && cb . Fixed == false ) {
251
+ collapse_to = a ;
252
+ return true ;
253
+ }
254
+ if ( cb . Fixed == true && ca . Fixed == false ) {
255
+ collapse_to = b ;
256
+ return true ;
257
+ }
258
+ // if both fixed, and options allow, treat this edge as unconstrained (eg collapse to midpoint)
259
+ // [RMS] tried picking a or b here, but something weird happens, where
260
+ // eg cylinder cap will entirely erode away. Somehow edge lengths stay below threshold??
261
+ if ( AllowCollapseFixedVertsWithSameSetID
262
+ && ca . FixedSetID >= 0
263
+ && ca . FixedSetID == cb . FixedSetID ) {
264
+ return true ;
265
+ }
266
+
267
+ return false ;
268
+ }
224
269
225
270
226
271
bool vertex_is_fixed ( int vid )
@@ -258,7 +303,7 @@ void FullProjectionPass()
258
303
if ( vertex_is_fixed ( vID ) )
259
304
continue ;
260
305
Vector3d curpos = mesh . GetVertex ( vID ) ;
261
- Vector3d projected = target . Project ( curpos ) ;
306
+ Vector3d projected = target . Project ( curpos , vID ) ;
262
307
mesh . SetVertex ( vID , projected ) ;
263
308
}
264
309
}
0 commit comments