[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3688] contrib/py/scripts/addons/ mesh_edgetools.py: Updates from the past couple months.

Paul Marshall portsidepaul at hotmail.com
Sat Aug 25 19:19:57 CEST 2012


Revision: 3688
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3688
Author:   brikbot
Date:     2012-08-25 17:19:57 +0000 (Sat, 25 Aug 2012)
Log Message:
-----------
Updates from the past couple months.  The primary changes have been:
1. Added a "dev mode" using bpy.app.debug.  Run Blender in debug (w/ --debug) to expose in development, known buggy functionality, or for testing functionality.
2. Added some functions to check for an active element to make usage more intuitive for users.
3. Continued laying ground work for edge fillets.  This is going to take a while as there is going to be some complex vector math I have to work through (see intersect_line_face to get a feel: that is looking like it will be fairly simple compared to this).

Modified Paths:
--------------
    contrib/py/scripts/addons/mesh_edgetools.py

Modified: contrib/py/scripts/addons/mesh_edgetools.py
===================================================================
--- contrib/py/scripts/addons/mesh_edgetools.py	2012-08-25 11:55:57 UTC (rev 3687)
+++ contrib/py/scripts/addons/mesh_edgetools.py	2012-08-25 17:19:57 UTC (rev 3688)
@@ -27,7 +27,9 @@
 #       to Blender's selection limitations.
 #
 # Tasks:
-#   - Figure out how to do a GUI for "Shaft", especially for controlling radius.
+#   - Figure out how to do a GUI for "Shaft", especially for controlling radius?
+#   - Buggy parts have been hidden behind bpy.app.debug.  Run Blender in debug
+#       to expose those.  Example: Shaft with more than two edges selected.
 #
 # Paul "BrikBot" Marshall
 # Created: January 28, 2012
@@ -156,11 +158,15 @@
         edges.append(edge)
         edges[0] = edge
 
-##    if bpy.app.debug:
-##        print(edge, end = ", ")
-##        print(edges, end = ", ")
-##        print(direction, end = "; ")
+    if bpy.app.debug:
+        print(edge, end = ", ")
+        print(edges, end = ", ")
+        print(direction, end = "; ")
 
+    # Robustness check: direction cannot be zero
+    if direction == 0:
+        direction = 1
+
     newList = []
     for e in edge.verts[0].link_edges:
         if e.select and edges.count(e) == 0:
@@ -174,7 +180,7 @@
                 newList.extend(order_joined_edges(e, edges, direction - 1))
 
     # This will only matter at the first level:
-    direction = direction - 1
+    direction = direction * -1
 
     for e in edge.verts[1].link_edges:
         if e.select and edges.count(e) == 0:
@@ -187,9 +193,9 @@
                 newList.extend(edges)
                 newList.extend(order_joined_edges(e, edges, direction))
 
-##    if bpy.app.debug:
-##        print(newList, end = ", ")
-##        print(direction)
+    if bpy.app.debug:
+        print(newList, end = ", ")
+        print(direction)
 
     return newList
 
@@ -329,17 +335,27 @@
 # connect the point to the each individual point of the triangle will be
 # equal to 2 * PI.  Otherwise, if the point is outside the triangle, then the
 # sum of the angles will be less.
+#
+# @todo
+#   - Figure out how to deal with n-gons.  How the heck is a face with 8 verts
+#       definied mathematically?  How do I then find the intersection point of
+#       a line with said vert?  How do I know if that point is "inside" all the
+#       verts?  I have no clue, and haven't been able to find anything on it so
+#       far.  Maybe if someone (actually reads this and) who knows could note?
 def intersect_line_face(edge, face, is_infinite = False, error = 0.000002):
     int_co = None
-    # If we are dealing with a quad:
-    if len(face.verts) == 4:
+
+    # If we are dealing with a non-planar quad:
+    if len(face.verts) == 4 and not is_face_planar(face):
         edgeA = face.edges[0]
         edgeB = None
         flipB = False
+
         for i in range(len(face.edges)):
             if face.edges[i].verts[0] not in edgeA.verts and face.edges[i].verts[1] not in edgeA.verts:
                 edgeB = face.edges[i]
                 break
+
         # I haven't figured out a way to mix this in with the above.  Doing so might remove a
         # few extra instructions from having to be executed saving a few clock cycles:
         for i in range(len(face.edges)):
@@ -348,6 +364,7 @@
             if (edgeA.verts[0] in face.edges[i].verts and edgeB.verts[1] in face.edges[i].verts) or (edgeA.verts[1] in face.edges[i].verts and edgeB.verts[0] in face.edges[i].verts):
                 flipB = True
                 break
+
         # Define calculation coefficient constants:
         # "xx1" is the x coordinate, "xx2" is the y coordinate, and "xx3" is the z
         # coordinate.
@@ -361,6 +378,7 @@
             b21, b22, b23 = edgeB.verts[1].co[0], edgeB.verts[1].co[1], edgeB.verts[1].co[2]
         a31, a32, a33 = edge.verts[0].co[0], edge.verts[0].co[1], edge.verts[0].co[2]
         b31, b32, b33 = edge.verts[1].co[0], edge.verts[1].co[1], edge.verts[1].co[2]
+
         # There are a bunch of duplicate "sub-calculations" inside the resulting
         # equations for t, t12, and t3.  Calculate them once and store them to
         # reduce computational time:
@@ -444,11 +462,14 @@
         n06 = m61 - m62 - m63 + m64 + m65 - m66 - m67 + m68 + m69 - m70 - m71 + m72
         n07 = 2 * n01 + n02 + 2 * n03 + n04 + n05
         n08 = n01 + n02 + n03 + n06
+
         # Calculate t, t12, and t3:
         t = (n07 - sqrt(pow(-n07, 2) - 4 * (n01 + n03 + n04) * n08)) / (2 * n08)
+
         # t12 can be greatly simplified by defining it with t in it:
         # If block used to help prevent any div by zero error.
         t12 = 0
+
         if a31 == b31:
             # The line is parallel to the z-axis:
             if a32 == b32:
@@ -469,6 +490,7 @@
         # The line is along the x/y-axis but is not parallel to either:
         else:
             t12 = -(-(a32 - b32) * (-a31 + a11 * (1 - t) + b11 * t) + (a31 - b31) * (-a32 + a12 * (1 - t) + b12 * t)) / (-(a32 - b32) * ((a21 - a11) * (1 - t) + (b21 - b11) * t) + (a31 - b31) * ((a22 - a21) * (1 - t) + (b22 - b12) * t))
+
         # Likewise, t3 is greatly simplified by defining it in terms of t and t12:
         # If block used to prevent a div by zero error.
         t3 = 0
@@ -479,19 +501,26 @@
         elif a33 != b33:
             t3 = (-a13 + a33 + (a13 - b13) * t + (a13 - a23) * t12 + (a23 - a13 + b13 - b23) * t * t12) / (a33 - b33)
         else:
-            print("The second edge is a zero-length edge!")
+            print("The second edge is a zero-length edge")
             return None
+
         # Calculate the point of intersection:
         x = (1 - t3) * a31 + t3 * b31
         y = (1 - t3) * a32 + t3 * b32
         z = (1 - t3) * a33 + t3 * b33
         int_co = Vector((x, y, z))
+        
+        if bpy.app.debug:
+            print(int_co)
+
         # If the line does not intersect the quad, we return "None":
         if (t < -1 or t > 1 or t12 < -1 or t12 > 1) and not is_infinite:
             int_co = None
+
     elif len(face.verts) == 3:
-        p1, p2, p3 = face.verts[0], face.verts[1], face.verts[2]
-        int_co = intersect_line_plane(edge.verts[0], edge.verts[1], p1, face.normal)
+        p1, p2, p3 = face.verts[0].co, face.verts[1].co, face.verts[2].co
+        int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co, p1, face.normal)
+
         if int_co != None:
             pA = p1 - int_co
             pB = p2 - int_co
@@ -500,9 +529,16 @@
             aBC = acos(pB.dot(pC))
             aCA = acos(pC.dot(pA))
             sumA = aAB + aBC + aCA
+
             # If the point is outside the triangle:
             if (sumA > (pi + error) and sumA < (pi - error)) and not is_infinite:
                 int_co = None
+
+    # This is the default case where we either have a planar quad or an n-gon.
+    else:
+        int_co = intersect_line_plane(edge.verts[0].co, edge.verts[1].co,
+                                      face.verts[0].co, face.normal)
+
     return int_co
 
 
@@ -545,10 +581,16 @@
     return (angle < error and angle > -error) or (angle < (180 + error) and angle > (180 - error))
 
 
-# fillet_geom_data
+# fillet_axis
 #
-# Calculates the base geometry data for the fillet.  The seems to be issues
-# some of the vector math right now.  Will need to be debuged.
+# Calculates the base geometry data for the fillet. This assumes that the faces
+# are planar:
+#
+# @todo
+#   - Redesign so that the faces do not have to be planar
+#
+# There seems to be issues some of the vector math right now.  Will need to be
+# debuged.
 def fillet_axis(edge, radius):
     vectors = [None, None, None, None]
     
@@ -607,6 +649,10 @@
     return [v1, v2]
 
 
+def fillet_point(t, face1, face2):
+    return
+
+
 # ------------------- EDGE TOOL METHODS -------------------
 
 # Extends an "edge" in two directions:
@@ -928,7 +974,8 @@
         # Until I can figure out a better way of handeling it:
         if len(edges) < 2:
             bpy.ops.object.editmode_toggle()
-            self.report({'ERROR_INVALID_INPUT'}, "You must select two edges.")
+            self.report({'ERROR_INVALID_INPUT'},
+                        "You must select two edges.")
             return {'CANCELLED'}
 
         verts = [edges[0].verts[0],
@@ -940,7 +987,8 @@
 
         # If the two edges are parallel:
         if cos == None:
-            self.report({'WARNING'}, "Selected lines are parallel: results may be unpredictable.")
+            self.report({'WARNING'},
+                        "Selected lines are parallel: results may be unpredictable.")
             vectors.append(verts[0].co - verts[1].co)
             vectors.append(verts[0].co - verts[2].co)
             vectors.append(vectors[0].cross(vectors[1]))
@@ -949,7 +997,8 @@
         else:
             # Warn the user if they have not chosen two planar edges:
             if not is_same_co(cos[0], cos[1]):
-                self.report({'WARNING'}, "Selected lines are not planar: results may be unpredictable.")
+                self.report({'WARNING'},
+                            "Selected lines are not planar: results may be unpredictable.")
 
             # This makes the +/- behavior predictable:
             if (verts[0].co - cos[0]).length < (verts[1].co - cos[0]).length:
@@ -1017,7 +1066,16 @@
     bl_description = "Create a shaft mesh around an axis"
     bl_options = {'REGISTER', 'UNDO'}
 
+    # Selection defaults:
     shaftType = 0
+
+    # For tracking if the user has changed selection:
+    last_edge = IntProperty(name = "Last Edge",
+                            description = "Tracks if user has changed selected edge",
+                            min = 0, max = 1,
+                            default = 0)
+    last_flip = False
+    
     edge = IntProperty(name = "Edge",
                        description = "Edge to shaft around.",
                        min = 0, max = 1,
@@ -1064,6 +1122,10 @@
 
 
     def invoke(self, context, event):
+        # Make sure these get reset each time we run:
+        self.last_edge = 0
+        self.edge = 0
+
         return self.execute(context)
 
     
@@ -1082,12 +1144,7 @@
         verts = []
 
         # Pre-caclulated values:
-        
-        # Selects which edge to use
-        if self.edge == 0:
-            edge = [0, 1]
-        else:
-            edge = [1, 0]
+
         rotRange = [radians(self.start), radians(self.finish)]

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list