[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2509] contrib/py/scripts/addons/ curve_to_uniform_mesh.py: -curve_to_uniform_mesh.py by Denis Declara
yousef harfoush
bat3a at msn.com
Mon Oct 24 01:00:56 CEST 2011
Revision: 2509
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2509
Author: bat3a
Date: 2011-10-23 23:00:55 +0000 (Sun, 23 Oct 2011)
Log Message:
-----------
-curve_to_uniform_mesh.py by Denis Declara
Added Paths:
-----------
contrib/py/scripts/addons/curve_to_uniform_mesh.py
Added: contrib/py/scripts/addons/curve_to_uniform_mesh.py
===================================================================
--- contrib/py/scripts/addons/curve_to_uniform_mesh.py (rev 0)
+++ contrib/py/scripts/addons/curve_to_uniform_mesh.py 2011-10-23 23:00:55 UTC (rev 2509)
@@ -0,0 +1,440 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_addon_info = {
+ "name": "Curve to Uniform Mesh",
+ "author": "Denis Declara",
+ "version": (0, 1),
+ "blender": (2, 5, 3),
+ "api": 32411,
+ "location": "Toolshelf > search > Curve to Uniform Mesh",
+ "description": "This script converts bezier curves or text objects to a mesh",
+ "warning": "Beta",
+ "wiki_url": "",
+ "tracker_url": "",
+ "category": "Add Curve"}
+
+"""
+This script converts curves and text objects to an even mesh.
+"""
+
+##############################
+import bpy
+from bpy.props import *
+import mathutils
+from mathutils import Vector
+
+#######################################
+### Beginn of custom bezier classes ###
+#######################################
+
+# Simple class which holds a straight bezier segment
+class LinearBezierSegment:
+ s = Vector((0,1,0))
+ e = Vector((0,0,0))
+
+ def __init__ (self, start, end):
+ self.s = start
+ self.e = end
+
+ # This method returns the length of the line segment
+ def calculateLength(self):
+ return (start - end).length()
+
+ # This method evaluates the bezier curve at a
+ # point t in [0, 1]
+ def at(self, t):
+ return self.s + (self.e - self.s) * t
+
+# Simple class which stores one cubic bezier segment
+# That is a segmend with start and end point, plus
+# two control points
+class CubicBezierSegment:
+ s = Vector(( -1, 0, 0)) # First bezier point
+ n1 = Vector((-.5,-.5, 0)) # Right handle of the first bezier point
+ n2 = Vector(( 0, 0, 0)) # Left handle of the second bezier point
+ e = Vector(( 1, 0, 0)) # Second bezier point
+
+ def __init__ (self, start, ctrl1, ctrl2, end):
+ self.s = start
+ self.n1 = ctrl1
+ self.n2 = ctrl2
+ self.e = end
+
+ # This method evaluates the bezier curve at a
+ # point t in [0, 1]
+ def at(self, t):
+ # This method uses the method illustrated in this animation
+ # http://en.wikipedia.org/wiki/File:Bezier_3_big.gif
+
+ # Create the first segments
+ a = LinearBezierSegment(self.s, self.n1).at(t)
+ b = LinearBezierSegment(self.n1, self.n2).at(t)
+ c = LinearBezierSegment(self.n2, self.e ).at(t)
+
+ # Interpolate those segments
+ d = LinearBezierSegment(a, b).at(t)
+ e = LinearBezierSegment(b, c).at(t)
+
+ # And finally interpolate one last time and return
+ f = LinearBezierSegment(d, e).at(t)
+ return f
+
+ # Calculates an approximatino of the length. By subdividing
+ # the curve in straight segments. The amount of segments
+ # is specified by the parameter segments
+ # The bigger the value, the more precise the approximation
+ # will be
+ def calculateLength(self, segments):
+ length = 0.0
+ lastPoint = self.at(0.0)
+ for i in range(0, segments):
+ t = (i + 1) / segments
+ nextPoint = self.at(t)
+ length += (lastPoint - nextPoint).length
+ lastPoint = nextPoint
+ return length
+
+ # This function returns a collection of Vectors, with
+ # as many intermediate points as defined by the parameter
+ # segments. Moreover it will not include the last point
+ # if the argument excludeLast is set to true
+ def getIntermediatePoints(self, segments, excludeLast):
+ if not excludeLast:
+ segments += 1
+
+ points = []
+ for i in range(0, segments):
+ t1 = i / segments
+ points.append(self.at(t1))
+ return points
+
+# This class basically represents a collection of
+# cubic bezier segments, forming a closed curve
+class CubicBezier:
+ segments = [] # Collection of cubic bezier segments
+
+ # Adds a segment at the end of the curve
+ def addSegment(self, segment):
+ self.segments.append(segment)
+
+ # This function calculates the amount of subdivisions for
+ # each individual bezier segment, so that the subdivision
+ # results homogeneous
+ # - FirstPassResolution determines the precision of the length
+ # approximation and therefore of the subdivision
+ # - SegmentsPerUnit determines the density of the subdivision
+ def calculateAdaptiveSegments(self, firstPassResolution = 8, segmentsPerUnit = 8):
+ # If there are no segments in the curve return an empty array
+ if len(self.segments) == 0:
+ return []
+
+ # Create an array with the length of the segments
+ lengths = [segment.calculateLength(firstPassResolution)
+ for segment in self.segments]
+
+ length = 0.0
+ # Sum up the length of each segment
+ for l in lengths:
+ length += l
+
+ # Calculate adaptive subdivisions of segments:
+ nSegments = [0] * len(self.segments)
+ # Determine the amount of subdivisions to perform by
+ # multiplying the density by the total length
+ segmentsToAssign = int(round(segmentsPerUnit * length))
+ # Distribute those subdivisions to the individual bezier
+ # segments evenly, based upon their length
+ for s in range(0, len(self.segments)):
+ nSegments[s] = 1 + int(lengths[s] * segmentsPerUnit)
+ segmentsToAssign -= nSegments[s]
+
+ # If, due to rounding errors, some subdivisions haven't
+ # been assigned, assign those
+ while segmentsToAssign > 0:
+ maxDeltaIndex = 0
+ for s in range(0, len(self.segments)):
+ # Delta0 and Delta1 represent the length of each subdivided segment
+ delta0 = lengths[maxDeltaIndex] / nSegments[maxDeltaIndex]
+ delta1 = lengths[s] / nSegments[s]
+
+ if (delta0 < delta1):
+ maxDeltaIndex = s
+ # Assign one subdivision to the segment which has the biggest
+ # subdivided segments.
+ nSegments[maxDeltaIndex] += 1
+ segmentsToAssign -= 1
+
+ # Finally after long computation return the optimal subdivisions for each segment
+ return nSegments
+
+ # This function returns a collection of Vectors, with
+ # a density of points as defined by the parameter
+ # segmentsPerUnit. Moreover the precision can is set by
+ # the parameter firstPassResolution
+ def getIntermediatePoints(self, firstPassResolution = 8, segmentsPerUnit = 8):
+ points = []
+
+ # Return if there are no segments in the curve
+ if len(self.segments) == 0:
+ return points
+
+ # Calculate adaptive subdivision of segments:
+ nSegments = self.calculateAdaptiveSegments(firstPassResolution, segmentsPerUnit)
+
+ # Ask to each bezier segment to generate as many points as defined by nSegments[i]
+ # and append those to the array points
+ for s in range(0, len(self.segments)):
+ segm = self.segments[s]
+ # Exclude the last point, so we do not get any duplication
+ # in closed curves
+ points.extend(segm.getIntermediatePoints(nSegments[s], True))
+
+ return points
+
+ # Calculates an approximatino of the length. By subdividing
+ # the curve in straight segments. The density of segments
+ # is specified by the parameter segmentsPerUnit
+ # The bigger the value of segmentsPerUnit and firstPassResolution
+ # the more precise the approximation will be
+ def calculateLength(self, firstPassResolution = 8, segmentsPerUnit = 8):
+ # If the curve has no segments the length is of course 0
+ if (len(self.segments) == 0):
+ return 0.0
+
+ length = 0.0
+
+ # Calculate adaptive segments:
+ nSegments = calculateAdaptiveSegments(firstPassResolution, segmentsPerUnit)
+
+ # Calculate adaptive length:
+ length = 0
+ for s in range(0, len(self.segments)):
+ segment = self.segments[s]
+ length += segment.calculateLength(nSegments[s])
+
+ return length
+
+######################################
+### -End of custom bezier classes- ###
+######################################
+
+def main(context, obj, options):
+ #print("\n_______START_______")
+ # main vars
+ fillMesh = options[0]
+ lengthApp = options[1]
+ density = options[2]
+ beautifyIters = options[3]
+ if(options[4] == False): # If the execute checkbox is not checked return
+ return;
+
+ verts = []
+ faces = []
+ curVertex = 0;
+
+ originalName = obj.name
+ isFontObject = (obj.type == 'FONT')
+ if isFontObject:
+ # Convert font objects into curves
+ bpy.ops.object.select_all(action='DESELECT')
+ obj.select = True
+ context.scene.objects.active = obj
+ bpy.ops.object.convert(target='CURVE', keep_original=True)
+ obj = bpy.context.active_object
+
+ # Deselect all of the objects in the scene
+ bpy.ops.object.select_all(action='DESELECT')
+ scene = context.scene
+ splines = obj.data.splines.values()
+
+ # create a mesh datablock
+ mesh = bpy.data.meshes.new("uniform_"+originalName)
+
+ # go through splines
+ for spline in splines:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list