Skip to content

Commit

Permalink
move to release
Browse files Browse the repository at this point in the history
  • Loading branch information
zeffii committed Jul 31, 2016
1 parent 96a957f commit 3ce7865
Show file tree
Hide file tree
Showing 16 changed files with 1,231 additions and 0 deletions.
103 changes: 103 additions & 0 deletions mesh_tiny_cad/BIX.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# ##### 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 #####

# <pep8 compliant>


import bpy
import bmesh
from . import cad_module as cm


def add_line_to_bisection(self):

obj = bpy.context.object
me = obj.data
bm = bmesh.from_edit_mesh(me)

if hasattr(bm.verts, "ensure_lookup_table"):
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()

edges = [e for e in bm.edges if e.select and not e.hide]

if not len(edges) == 2:
msg = "select two coplanar non parallel edges"
self.report({"WARNING"}, msg)
return

[[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edges]
print('vectors found:\n', v1, '\n', v2, '\n', v3, '\n', v4)

dist1 = (v1 - v2).length
dist2 = (v3 - v4).length
bdist = min([dist1, dist2])
edge1 = (v1, v2)
edge2 = (v3, v4)

if not cm.test_coplanar(edge1, edge2):
msg = "edges must be coplanar non parallel edges"
self.report({"WARNING"}, msg)
return

# get pt and pick fartest vertex from (projected) intersections
pt = cm.get_intersection(edge1, edge2)
far1 = v2 if (v1 - pt).length < (v2 - pt).length else v1
far2 = v4 if (v3 - pt).length < (v4 - pt).length else v3
# print('intersection: ', pt)

dex1 = far1 - pt
dex2 = far2 - pt
dex1 = dex1 * (bdist / dex1.length)
dex2 = dex2 * (bdist / dex2.length)
pt2 = pt + (dex1).lerp(dex2, 0.5)
# print('bisector point:', pt2)

pt3 = pt2.lerp(pt, 2.0)

vec1 = bm.verts.new(pt2)
vec2 = bm.verts.new(pt)
vec3 = bm.verts.new(pt3)
bm.edges.new((vec1, vec2))
bm.edges.new((vec2, vec3))
bmesh.update_edit_mesh(me)
# print("done")


class TCLineOnBisection(bpy.types.Operator):
'''Generate the bisector of two selected edges'''
bl_idname = 'tinycad.linetobisect'
bl_label = 'BIX line to bisector'
bl_options = {'REGISTER', 'UNDO'}

@classmethod
def poll(cls, context):
obj = context.active_object
return all([obj is not None, obj.type == 'MESH', obj.mode == 'EDIT'])

def execute(self, context):
add_line_to_bisection(self)
return {'FINISHED'}


def register():
bpy.utils.register_module(__name__)


def unregister():
bpy.utils.unregister_module(__name__)
167 changes: 167 additions & 0 deletions mesh_tiny_cad/CCEN.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# ##### 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 #####

# <pep8 compliant>


import math

import bpy
import bmesh
import mathutils
from mathutils import geometry
from mathutils import Vector


def generate_bmesh_repr(p1, v1, axis, num_verts):
'''
p1: center of circle (local coordinates)
v1: first vertex of circle in (local coordinates)
axis: orientation matrix
origin: obj.location
'''
props = bpy.context.scene.tinycad_props
rescale = props.rescale

# generate geometry up front
chain = []
gamma = 2 * math.pi / num_verts
for i in range(num_verts + 1):
theta = gamma * i
mat_rot = mathutils.Matrix.Rotation(theta, 4, axis)
local_point = (mat_rot * ((v1 - p1) * rescale))
chain.append(local_point + p1)

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)

# add verts
v_refs = []
for p in chain:
v = bm.verts.new(p)
v.select = False # this might be a default.. redundant?
v_refs.append(v)

# join verts, daisy chain
num_verts = len(v_refs)
for i in range(num_verts):
idx1 = i
idx2 = (i + 1) % num_verts
bm.edges.new([v_refs[idx1], v_refs[idx2]])

bmesh.update_edit_mesh(me, True)


def generate_3PT(pts, obj, nv, mode=1):
mw = obj.matrix_world
V = Vector
nv = max(3, nv)

# construction
v1, v2, v3, v4 = V(pts[0]), V(pts[1]), V(pts[1]), V(pts[2])
edge1_mid = v1.lerp(v2, 0.5)
edge2_mid = v3.lerp(v4, 0.5)
axis = geometry.normal(v1, v2, v4)
mat_rot = mathutils.Matrix.Rotation(math.radians(90.0), 4, axis)

# triangle edges
v1_ = ((v1 - edge1_mid) * mat_rot) + edge1_mid
v2_ = ((v2 - edge1_mid) * mat_rot) + edge1_mid
v3_ = ((v3 - edge2_mid) * mat_rot) + edge2_mid
v4_ = ((v4 - edge2_mid) * mat_rot) + edge2_mid

r = geometry.intersect_line_line(v1_, v2_, v3_, v4_)
if r:
p1, _ = r
cp = mw * p1
bpy.context.scene.cursor_location = cp

if mode == 0:
pass

elif mode == 1:
generate_bmesh_repr(p1, v1, axis, nv)

else:
print('not on a circle')


def get_three_verts_from_selection(obj):
me = obj.data
bm = bmesh.from_edit_mesh(me)

bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()

return [v.co[:] for v in bm.verts if v.select]


def dispatch(context, mode=0):
try:
obj = context.edit_object
pts = get_three_verts_from_selection(obj)
props = context.scene.tinycad_props
generate_3PT(pts, obj, props.num_verts, mode)
except:
print('dispatch failed', mode)


class TCCallBackCCEN(bpy.types.Operator):
bl_idname = 'tinycad.reset_circlescale'
bl_label = 'CCEN circle reset'
bl_options = {'REGISTER'}

def execute(self, context):
context.scene.tinycad_props.rescale = 1
return {'FINISHED'}


class TCCircleCenter(bpy.types.Operator):
'''Recreate a Circle from 3 selected verts, move 3dcursor its center'''

bl_idname = 'tinycad.circlecenter'
bl_label = 'CCEN circle center from selected'
bl_options = {'REGISTER', 'UNDO'}

def draw(self, context):
scn = context.scene
l = self.layout
col = l.column()

col.prop(scn.tinycad_props, 'num_verts', text='num verts')
row = col.row(align=True)
row.prop(scn.tinycad_props, 'rescale', text='rescale')
row.operator('tinycad.reset_circlescale', text="", icon="LINK")

@classmethod
def poll(cls, context):
obj = context.edit_object
return obj is not None and obj.type == 'MESH'

def execute(self, context):
dispatch(context, mode=1)
return {'FINISHED'}


def register():
bpy.utils.register_module(__name__)


def unregister():
bpy.utils.unregister_module(__name__)
84 changes: 84 additions & 0 deletions mesh_tiny_cad/CFG.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# ##### 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 #####

# <pep8 compliant>


import os
import bpy

ICONS = 'BIX CCEN V2X VTX XALL E2F'.split(' ')
icon_collection = {}


class TinyCADProperties(bpy.types.PropertyGroup):

num_verts = bpy.props.IntProperty(
min=3, max=60, default=12)

rescale = bpy.props.FloatProperty(
default=1.0,
precision=4,
min=0.0001)


class VIEW3D_MT_edit_mesh_tinycad(bpy.types.Menu):
bl_label = "TinyCAD"

@classmethod
def poll(cls, context):
return bool(context.object)

def draw(self, context):

pcoll = icon_collection["main"]

def cicon(name):
return pcoll[name].icon_id

op = self.layout.operator
op('tinycad.autovtx', text='VTX | AUTO', icon_value=cicon('VTX'))
op('tinycad.vertintersect', text='V2X | Vertex at intersection', icon_value=cicon('V2X'))
op('tinycad.intersectall', text='XALL | Intersect selected edges', icon_value=cicon('XALL'))
op('tinycad.linetobisect', text='BIX | Bisector of 2 planar edges', icon_value=cicon('BIX'))
op('tinycad.circlecenter', text='CCEN | Resurrect circle center', icon_value=cicon('CCEN'))
op('tinycad.edge_to_face', text='E2F | Extend Edge to Face', icon_value=cicon('E2F'))


def register_icons():
import bpy.utils.previews
pcoll = bpy.utils.previews.new()
icons_dir = os.path.join(os.path.dirname(__file__), "icons")
for icon_name in ICONS:
pcoll.load(icon_name, os.path.join(icons_dir, icon_name + '.png'), 'IMAGE')

icon_collection["main"] = pcoll


def unregister_icons():
for pcoll in icon_collection.values():
bpy.utils.previews.remove(pcoll)
icon_collection.clear()


def register():
bpy.utils.register_module(__name__)


def unregister():
bpy.utils.unregister_module(__name__)
Loading

0 comments on commit 3ce7865

Please sign in to comment.