[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3353] contrib/py/scripts/addons/ mesh_bevel_round.py: bevel round: another fix for corner fillets
Howard Trickey
howard.trickey at gmail.com
Tue May 8 13:49:58 CEST 2012
Revision: 3353
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3353
Author: howardt
Date: 2012-05-08 11:49:57 +0000 (Tue, 08 May 2012)
Log Message:
-----------
bevel round: another fix for corner fillets
Modified Paths:
--------------
contrib/py/scripts/addons/mesh_bevel_round.py
Modified: contrib/py/scripts/addons/mesh_bevel_round.py
===================================================================
--- contrib/py/scripts/addons/mesh_bevel_round.py 2012-05-07 13:13:52 UTC (rev 3352)
+++ contrib/py/scripts/addons/mesh_bevel_round.py 2012-05-08 11:49:57 UTC (rev 3353)
@@ -615,7 +615,7 @@
for i in [0, 2, 1, 3]:
pair = pairs[i]
lpt = pair.rounding
- if lpt and lpt.length > 0:
+ if lpt and len(lpt) > 0:
if on_line(lpt[0], [pair.ptcross, ed.vec]):
pt = lpt[0]
else:
@@ -1115,9 +1115,9 @@
vec2 = ed_bronze.ptmid - vpos
normal2 = vec1.cross(vec2)
offset1 = (pt_silver - gold_ptcross).length
- offset2 = (pt_bronze - gold.ptcross).length
+ offset2 = (pt_bronze - gold_ptcross).length
pair_gold.rounding = self.profile_compute_by_offset(['C', self.num_seg],
- gold_ptcross, ve1, offset1, vec2, offset2)
+ gold_ptcross, vec1, offset1, vec2, offset2)
# Corner calculation
def corner_compute(self, vd):
@@ -1152,16 +1152,22 @@
section = self.compute_sections_multi(ed, icorner)
if len(vd.leds) == 1:
# Do we need an extra face between end of beveled
- # edge and vd? We do if the end of the beveled edge
- # isn't in the plane of other faces not adjacent to the edge
- needcornerface = False
- for f in vd.vertex.link_faces:
- if f == ed.lfaces[0] or f == ed.lfaces[1]:
- continue
- plane = face_plane(f)
- if not (on_plane(section[0], plane) and on_plane(section[-1], plane)):
- needcornerface = True
- break
+ # edge and vd? Usually yes, but not in certain cases.
+ # One case where we don't: if there are only 3 faces
+ # at the vertex and the 3rd face contains the
+ # beveled end completely.
+ needcornerface = True
+ vfaces = vd.vertex.link_faces
+ if len(vfaces) == 3:
+ f3 = find(vfaces, lambda f: f != ed.lfaces[0] and f != ed.lfaces[1])
+ if not f3:
+ print("whoops, couldn't find 3rd face")
+ bf3 = self.hsh_faces[f3.index]
+ # test segment containment by containment of midpoint
+ # in face - for this case, should be ok
+ mid = section[0].lerp(section[1], 0.5)
+ if bf3.contains_point(mid):
+ needcornerface = False
if needcornerface:
facepts = section + [vd.vertex.co]
norm = ed.lfaces[0].normal + ed.lfaces[1].normal
@@ -2554,6 +2560,28 @@
return True
return False
+ # Probably should give access to C routine BM_face_point_inside_test
+ # but for now reimplement it here
+ def contains_point(self, v):
+ (ax, ay) = axis_dominant(self.face.normal)
+ co2 = Vector([v[ax], v[ay]])
+ cent = Vector([0.0, 0.0])
+ for l in self.face.loops:
+ v = l.vert.co
+ cent = cent + Vector([v[ax], v[ay]])
+ cent = cent / len(self.face.loops)
+ crosses = 0
+ onepluseps = 1.0 + EPSILON * 150.0
+ out = Vector([1e30, 1e30])
+ for l in self.face.loops:
+ vprev = l.link_loop_prev.vert.co
+ v = l.vert.co
+ v1 = (Vector([vprev[ax], vprev[ay]]) - cent) * onepluseps + cent
+ v2 = (Vector([v[ax], v[ay]]) - cent) * onepluseps + cent
+ if line_segments_cross(v1, v2, co2, out):
+ crosses += 1
+ return crosses % 2 != 0
+
def __str__(self):
return "f%d" % self.index
@@ -2764,7 +2792,7 @@
for i in range(1, n):
center = center + pts[i]
center = center / n
- # Newell method for normal, pretending this is a polynomail
+ # Newell method for normal, pretending this is a polygon
sumx = 0.0
sumy = 0.0
sumz = 0.0
@@ -2789,7 +2817,7 @@
# Return True if point is on the line
def on_line(point, line):
(lv, lvec) = line
- (vint, _) = mathutils.geometry.intersect_point_line(point, lv, lv + vec)
+ (vint, _) = mathutils.geometry.intersect_point_line(point, lv, lv + lvec)
return (point-vint).length < EPSILON
@@ -2815,8 +2843,58 @@
return lp.vert != edge.verts[0]
print("whoops, edge_reversed_in_face: edge not in face")
return False
-
+
+# Find the indices of axes which make for closest
+# alignment with vector axis, for a fast projection
+# of 3d -> 2d
+def axis_dominant(axis):
+ xn = abs(axis[0])
+ yn = abs(axis[1])
+ zn = abs(axis[2])
+ if zn >= xn and zn >= yn:
+ return (0, 1)
+ elif yn >= xn and yn >= zn:
+ return (0, 2)
+ else:
+ return (1, 2)
+
+
+# Return True if v3 is to the right of line v1v2
+# but False if v3 is the same as v1 or v2
+# (all points are 2d Vectors)
+def test_edge_side(v1, v2, v3):
+ inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] - v2[1]) * (v1[0] - v3[0])
+ if inp < 0.0:
+ return False
+ elif inp < 0.0:
+ if v1 == v3 or v2 == v3:
+ return False
+ return True
+
+
+# Return True if two line segments cross each other
+# with careful attention to edge cases
+def line_segments_cross(v1, v2, v3, v4):
+ eps = EPSILON * 15
+ w1 = test_edge_side(v1, v3, v2)
+ w2 = test_edge_side(v2, v4, v1)
+ w3 = not test_edge_side(v1, v2, v3)
+ w4 = test_edge_side(v3, v2, v4)
+ w5 = not test_edge_side(v3, v1, v4)
+ if w1 == w2 == w3 == w4 == w5:
+ return True
+ mv1= (min(v1[0], v2[0]), min(v1[1], v2[1]))
+ mv2 = (max(v1[0], v2[0]), max(v1[1], v2[1]))
+ mv3= (min(v3[0], v4[0]), min(v3[1], v4[1]))
+ mv4 = (max(v3[0], v4[0]), max(v3[1], v4[1]))
+ if abs(v1[1] - v2[1]) < eps and abs(v3[1] - v4[1]) < eps and abs(v1[1] - v3[1]) < eps:
+ return (mv4[0] >= mv1[0] and mv3[0] <= mv2[0])
+ if abs(v1[0] - v2[0]) < eps and abs(v3[0] - v4[0]) < eps and abs(v1[0] - v3[0]) < eps:
+ return (mv4[1] >= mv1[1] and mv3[1] <= mv2[1])
+ return False
+
+
# Three-way compare
def cmp(a, b):
return (a > b) - (a < b)
@@ -2838,6 +2916,9 @@
def V3(v):
return "None" if not v else "(%.2f,%.2f,%.2f)" % (v[0], v[1], v[2])
+def V2(v):
+ return "None" if not v else "(%.2f,%.2f)" % (v[0], v[1])
+
def LV3(lv):
return "None" if not lv else ",".join([V3(v) for v in lv])
More information about the Bf-extensions-cvs
mailing list