Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-03-05 04:32:28 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-03-05 04:32:28 +0300
commitaec5a36c12a3ec1d068adb8270017e509087dff6 (patch)
treedcc0408cf538f1fb39a41dd84c775342863b8a32
parent353492b181e08663b8cd3bc5733920b6fcdbcbe4 (diff)
Cleanup: tabs -> spaces
-rw-r--r--add_mesh_BoltFactory/__init__.py2
-rw-r--r--archipack/archipack_gl.py4
-rw-r--r--archipack/archipack_keymaps.py2
-rw-r--r--blenderkit/bg_blender.py1
-rw-r--r--blenderkit/colors.py2
-rw-r--r--blenderkit/oauth.py2
-rw-r--r--blenderkit/tasks_queue.py2
-rw-r--r--blenderkit/utils.py2
-rw-r--r--btrace/bTrace_props.py2
-rw-r--r--io_export_dxf/model/dxfLibrary.py1354
-rw-r--r--io_export_dxf/model/model.py68
-rw-r--r--io_export_dxf/test2.txt2
-rw-r--r--io_mesh_atomic/utility_gui.py1
-rw-r--r--io_mesh_uv_layout/export_uv_eps.py2
-rw-r--r--io_mesh_uv_layout/export_uv_svg.py2
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py2
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_scene.py1
-rw-r--r--magic_uv/lib/bglx.py1
-rw-r--r--materials_library_vx/categories.txt2
-rw-r--r--mesh_inset/__init__.py4
-rw-r--r--mesh_snap_utilities_line/snap_context_l/utils_projection.py1
-rw-r--r--mesh_tools/mesh_offset_edges.py4
-rw-r--r--node_arrange.py644
-rw-r--r--object_carver/__init__.py444
-rw-r--r--object_carver/carver_draw.py940
-rw-r--r--object_carver/carver_operator.py2620
-rw-r--r--object_carver/carver_preferences.py354
-rw-r--r--object_carver/carver_profils.py806
-rw-r--r--object_carver/carver_utils.py1580
-rw-r--r--object_collection_manager/internals.py1
-rw-r--r--oscurart_tools/files/reload_images.py2
-rw-r--r--oscurart_tools/files/save_incremental.py2
-rw-r--r--oscurart_tools/mesh/apply_linked_meshes.py5
-rw-r--r--oscurart_tools/mesh/flipped_uvs.py2
-rw-r--r--oscurart_tools/mesh/overlap_island.py3
-rw-r--r--oscurart_tools/mesh/overlap_uvs.py1
-rw-r--r--oscurart_tools/mesh/remove_modifiers.py3
-rw-r--r--oscurart_tools/mesh/select_doubles.py3
-rw-r--r--oscurart_tools/mesh/vertex_color_id.py3
-rw-r--r--oscurart_tools/object/distribute.py1
-rw-r--r--oscurart_tools/object/search_and_select.py3
-rw-r--r--oscurart_tools/render/batch_maker.py1
-rw-r--r--oscurart_tools/render/material_overrides.py1
-rw-r--r--power_sequencer/scripts/BPSRender/bpsrender/__init__.py1
-rw-r--r--presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py2
-rw-r--r--presets/pov/world/4_Cartoony_Sky.py2
-rw-r--r--presets/pov/world/5_Under_Water.py2
-rw-r--r--rigify/base_generate.py1
-rw-r--r--rigify/rot_mode.py2
-rw-r--r--rigify/utils/metaclass.py1
-rw-r--r--space_view3d_math_vis/draw.py2
-rw-r--r--space_view3d_pie_menus/pie_origin.py2
-rw-r--r--space_view3d_spacebar_menu/__init__.py28
-rw-r--r--space_view3d_spacebar_menu/edit_mesh.py302
-rw-r--r--space_view3d_spacebar_menu/snap_origin_cursor.py406
-rw-r--r--space_view3d_stored_views/io.py2
-rw-r--r--space_view3d_stored_views/operators.py2
-rw-r--r--space_view3d_stored_views/properties.py2
-rw-r--r--sun_position/geo.py4
59 files changed, 4801 insertions, 4842 deletions
diff --git a/add_mesh_BoltFactory/__init__.py b/add_mesh_BoltFactory/__init__.py
index 1a765908..d763d13f 100644
--- a/add_mesh_BoltFactory/__init__.py
+++ b/add_mesh_BoltFactory/__init__.py
@@ -45,7 +45,7 @@ import bpy
def register():
- Boltfactory.register()
+ Boltfactory.register()
diff --git a/archipack/archipack_gl.py b/archipack/archipack_gl.py
index f3ef034a..f0bf8482 100644
--- a/archipack/archipack_gl.py
+++ b/archipack/archipack_gl.py
@@ -85,7 +85,7 @@ in vec2 pos;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
}
'''
@@ -97,7 +97,7 @@ out vec4 fragColor;
void main()
{
- fragColor = color;
+ fragColor = color;
}
'''
diff --git a/archipack/archipack_keymaps.py b/archipack/archipack_keymaps.py
index f5b95957..05458b9c 100644
--- a/archipack/archipack_keymaps.py
+++ b/archipack/archipack_keymaps.py
@@ -119,4 +119,4 @@ class Keymaps:
k.alt, k.ctrl, k.shift, k.type, k.value, sub, k.name)
file = open(filename, "w")
file.write(str)
- file.close() \ No newline at end of file
+ file.close()
diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py
index e8ccb04d..8a37f6ce 100644
--- a/blenderkit/bg_blender.py
+++ b/blenderkit/bg_blender.py
@@ -239,4 +239,3 @@ def unregister():
bpy.utils.unregister_class(KillBgProcess)
if bpy.app.timers.is_registered(bg_update):
bpy.app.timers.unregister(bg_update)
-
diff --git a/blenderkit/colors.py b/blenderkit/colors.py
index d01bdb0a..c61d9fa0 100644
--- a/blenderkit/colors.py
+++ b/blenderkit/colors.py
@@ -20,4 +20,4 @@
TEXT = (.9, .9, .9, .6)
GREEN = (.9, 1, .9, .6)
-RED = (1, .5, .5, .8) \ No newline at end of file
+RED = (1, .5, .5, .8)
diff --git a/blenderkit/oauth.py b/blenderkit/oauth.py
index 95c6bae6..06e57298 100644
--- a/blenderkit/oauth.py
+++ b/blenderkit/oauth.py
@@ -104,4 +104,4 @@ class SimpleOAuthAuthenticator(object):
return self._get_tokens(authorization_code=authorization_code)
def get_refreshed_token(self, refresh_token):
- return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token") \ No newline at end of file
+ return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token")
diff --git a/blenderkit/tasks_queue.py b/blenderkit/tasks_queue.py
index 95ffb1a6..4f500bbf 100644
--- a/blenderkit/tasks_queue.py
+++ b/blenderkit/tasks_queue.py
@@ -103,5 +103,3 @@ def register():
def unregister():
bpy.app.handlers.load_post.remove(scene_load)
-
-
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index fe80e1a0..b9bd17f1 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -558,4 +558,4 @@ def guard_from_crash():
return False;
if bpy.context.preferences.addons['blenderkit'].preferences is None:
return False;
- return True \ No newline at end of file
+ return True
diff --git a/btrace/bTrace_props.py b/btrace/bTrace_props.py
index 4476e0f6..b7e824c8 100644
--- a/btrace/bTrace_props.py
+++ b/btrace/bTrace_props.py
@@ -565,5 +565,3 @@ class TracerProperties(PropertyGroup):
description="",
default='tool_help'
)
-
-
diff --git a/io_export_dxf/model/dxfLibrary.py b/io_export_dxf/model/dxfLibrary.py
index 2dffaabe..50aa4d56 100644
--- a/io_export_dxf/model/dxfLibrary.py
+++ b/io_export_dxf/model/dxfLibrary.py
@@ -89,94 +89,94 @@ ______________________________________________________________
#import BPyMessages
try:
- import copy
- #from struct import pack
+ import copy
+ #from struct import pack
except:
- copy = None
+ copy = None
####1) Private (only for developers)
_HEADER_POINTS=['insbase','extmin','extmax']
#---helper functions-----------------------------------
def _point(x,index=0):
- """Convert tuple to a dxf point"""
- return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
+ """Convert tuple to a dxf point"""
+ return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
def _points(plist):
- """Convert a list of tuples to dxf points"""
- out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
- return out
+ """Convert a list of tuples to dxf points"""
+ out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
+ return out
#---base classes----------------------------------------
class _Call:
- """Makes a callable class."""
- def copy(self):
- """Returns a copy."""
- return copy.deepcopy(self)
+ """Makes a callable class."""
+ def copy(self):
+ """Returns a copy."""
+ return copy.deepcopy(self)
- def __call__(self,**attrs):
- """Returns a copy with modified attributes."""
- copied=self.copy()
- for attr in attrs:setattr(copied,attr,attrs[attr])
- return copied
+ def __call__(self,**attrs):
+ """Returns a copy with modified attributes."""
+ copied=self.copy()
+ for attr in attrs:setattr(copied,attr,attrs[attr])
+ return copied
#-------------------------------------------------------
class _Entity(_Call):
- """Base class for _common group codes for entities."""
- def __init__(self,paperspace=None,color=None,layer='0',
- lineType=None,lineTypeScale=None,lineWeight=None,
- extrusion=None,elevation=None,thickness=None,
- parent=None):
- """None values will be omitted."""
- self.paperspace = paperspace
- self.color = color
- self.layer = layer
- self.lineType = lineType
- self.lineTypeScale = lineTypeScale
- self.lineWeight = lineWeight
- self.extrusion = extrusion
- self.elevation = elevation
- self.thickness = thickness
- #self.visible = visible
- self.parent = parent
-
- def _common(self):
- """Return common group codes as a string."""
- if self.parent:parent=self.parent
- else:parent=self
- result =''
- if parent.paperspace==1: result+=' 67\n1\n'
- if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
- if parent.color!=None: result+=' 62\n%s\n'%parent.color
- if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
- # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
- # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
- if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
- if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
- if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
- if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
- return result
+ """Base class for _common group codes for entities."""
+ def __init__(self,paperspace=None,color=None,layer='0',
+ lineType=None,lineTypeScale=None,lineWeight=None,
+ extrusion=None,elevation=None,thickness=None,
+ parent=None):
+ """None values will be omitted."""
+ self.paperspace = paperspace
+ self.color = color
+ self.layer = layer
+ self.lineType = lineType
+ self.lineTypeScale = lineTypeScale
+ self.lineWeight = lineWeight
+ self.extrusion = extrusion
+ self.elevation = elevation
+ self.thickness = thickness
+ #self.visible = visible
+ self.parent = parent
+
+ def _common(self):
+ """Return common group codes as a string."""
+ if self.parent:parent=self.parent
+ else:parent=self
+ result =''
+ if parent.paperspace==1: result+=' 67\n1\n'
+ if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
+ if parent.color!=None: result+=' 62\n%s\n'%parent.color
+ if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
+ # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
+ # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
+ if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
+ if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
+ if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
+ if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
+ return result
#--------------------------
class _Entities:
- """Base class to deal with composed objects."""
- def __dxf__(self):
- return []
+ """Base class to deal with composed objects."""
+ def __dxf__(self):
+ return []
- def __str__(self):
- return ''.join([str(x) for x in self.__dxf__()])
+ def __str__(self):
+ return ''.join([str(x) for x in self.__dxf__()])
#--------------------------
class _Collection(_Call):
- """Base class to expose entities methods to main object."""
- def __init__(self,entities=[]):
- self.entities=copy.copy(entities)
- #link entities methods to drawing
- for attr in dir(self.entities):
- if attr[0]!='_':
- attrObject=getattr(self.entities,attr)
- if callable(attrObject):
- setattr(self,attr,attrObject)
+ """Base class to expose entities methods to main object."""
+ def __init__(self,entities=[]):
+ self.entities=copy.copy(entities)
+ #link entities methods to drawing
+ for attr in dir(self.entities):
+ if attr[0]!='_':
+ attrObject=getattr(self.entities,attr)
+ if callable(attrObject):
+ setattr(self,attr,attrObject)
####2) Constants
#---color values
@@ -199,7 +199,7 @@ TOP_CENTER = 2
TOP_RIGHT = 3
MIDDLE_LEFT = 4
MIDDLE_CENTER = 5
-MIDDLE_RIGHT = 6
+MIDDLE_RIGHT = 6
BOTTOM_LEFT = 7
BOTTOM_CENTER = 8
BOTTOM_RIGHT = 9
@@ -212,14 +212,14 @@ AT_LEAST = 1 #taller characters will override
EXACT = 2 #taller characters will not override
#---polyline flag 70
-CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
-CURVE_FIT =2 # Curve-fit vertices have been added
-SPLINE_FIT =4 # Spline-fit vertices have been added
-POLYLINE_3D =8 # This is a 3D polyline
-POLYGON_MESH =16 # This is a 3D polygon mesh
-CLOSED_N =32 # The polygon mesh is closed in the N direction
-POLYFACE_MESH =64 # The polyline is a polyface mesh
-CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
+CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
+CURVE_FIT =2 # Curve-fit vertices have been added
+SPLINE_FIT =4 # Spline-fit vertices have been added
+POLYLINE_3D =8 # This is a 3D polyline
+POLYGON_MESH =16 # This is a 3D polygon mesh
+CLOSED_N =32 # The polygon mesh is closed in the N direction
+POLYFACE_MESH =64 # The polyline is a polyface mesh
+CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
#---polyline flag 75, = curve type
QUADRIC_NURBS = 5
@@ -237,7 +237,7 @@ MIDDLE = 4 #if vertical alignment = 0
FIT = 5 #if vertical alignment = 0
#vertical
BASELINE = 0
-BOTTOM = 1
+BOTTOM = 1
MIDDLE = 2
TOP = 3
@@ -245,682 +245,682 @@ TOP = 3
#---entitities -----------------------------------------------
#--------------------------
class Arc(_Entity):
- """Arc, angles in degrees."""
- def __init__(self,center=(0,0,0),radius=1,
- startAngle=0.0,endAngle=90,**common):
- """Angles in degrees."""
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- self.startAngle=startAngle
- self.endAngle=endAngle
- def __str__(self):
- return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
- (self._common(),_point(self.center),
- self.radius,self.startAngle,self.endAngle)
+ """Arc, angles in degrees."""
+ def __init__(self,center=(0,0,0),radius=1,
+ startAngle=0.0,endAngle=90,**common):
+ """Angles in degrees."""
+ _Entity.__init__(self,**common)
+ self.center=center
+ self.radius=radius
+ self.startAngle=startAngle
+ self.endAngle=endAngle
+ def __str__(self):
+ return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
+ (self._common(),_point(self.center),
+ self.radius,self.startAngle,self.endAngle)
#-----------------------------------------------
class Circle(_Entity):
- """Circle"""
- def __init__(self,center=(0,0,0),radius=1,**common):
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- def __str__(self):
- return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
- (self._common(),_point(self.center),self.radius)
+ """Circle"""
+ def __init__(self,center=(0,0,0),radius=1,**common):
+ _Entity.__init__(self,**common)
+ self.center=center
+ self.radius=radius
+ def __str__(self):
+ return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
+ (self._common(),_point(self.center),self.radius)
#-----------------------------------------------
class Face(_Entity):
- """3dface"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- while len(points)<4: #fix for r12 format
- points.append(points[-1])
- self.points=points
+ """3dface"""
+ def __init__(self,points,**common):
+ _Entity.__init__(self,**common)
+ while len(points)<4: #fix for r12 format
+ points.append(points[-1])
+ self.points=points
- def __str__(self):
- out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
- return out
+ def __str__(self):
+ out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
+ return out
#-----------------------------------------------
class Insert(_Entity):
- """Block instance."""
- def __init__(self,name,point=(0,0,0),
- xscale=None,yscale=None,zscale=None,
- cols=None,colspacing=None,rows=None,rowspacing=None,
- rotation=None,
- **common):
- _Entity.__init__(self,**common)
- self.name=name
- self.point=point
- self.xscale=xscale
- self.yscale=yscale
- self.zscale=zscale
- self.cols=cols
- self.colspacing=colspacing
- self.rows=rows
- self.rowspacing=rowspacing
- self.rotation=rotation
-
- def __str__(self):
- result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
- (self.name,self._common(),_point(self.point))
- if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
- if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
- if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
- if self.rotation:result+=' 50\n%s\n'%self.rotation
- if self.cols!=None:result+=' 70\n%s\n'%self.cols
- if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
- if self.rows!=None:result+=' 71\n%s\n'%self.rows
- if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
- return result
+ """Block instance."""
+ def __init__(self,name,point=(0,0,0),
+ xscale=None,yscale=None,zscale=None,
+ cols=None,colspacing=None,rows=None,rowspacing=None,
+ rotation=None,
+ **common):
+ _Entity.__init__(self,**common)
+ self.name=name
+ self.point=point
+ self.xscale=xscale
+ self.yscale=yscale
+ self.zscale=zscale
+ self.cols=cols
+ self.colspacing=colspacing
+ self.rows=rows
+ self.rowspacing=rowspacing
+ self.rotation=rotation
+
+ def __str__(self):
+ result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
+ (self.name,self._common(),_point(self.point))
+ if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
+ if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
+ if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
+ if self.rotation:result+=' 50\n%s\n'%self.rotation
+ if self.cols!=None:result+=' 70\n%s\n'%self.cols
+ if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
+ if self.rows!=None:result+=' 71\n%s\n'%self.rows
+ if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
+ return result
#-----------------------------------------------
class Line(_Entity):
- """Line"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nLINE\n%s%s\n' %(
- self._common(), _points(self.points))
+ """Line"""
+ def __init__(self,points,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self):
+ return ' 0\nLINE\n%s%s\n' %(
+ self._common(), _points(self.points))
#-----------------------------------------------
class PolyLine(_Entity):
- def __init__(self,points,org_point=[0,0,0],flag70=0,flag75=0,width=None,**common):
- #width = number, or width = list [width_start=None, width_end=None]
- #for 2d-polyline: points = [ [[x, y, z], vflag=None, [width_start=None, width_end=None], bulge=0 or None] ...]
- #for 3d-polyline: points = [ [[x, y, z], vflag=None], ...]
- #for polyface: points = [points_list, faces_list]
- _Entity.__init__(self,**common)
- self.points=points
- self.org_point=org_point
- self.pflag70 = flag70
- self.pflag75 = flag75
- self.polyface = False
- self.polyline2d = False
- self.faces = [] # dummy value
- self.width= None # dummy value
- if self.pflag70 & POLYFACE_MESH:
- self.polyface=True
- self.points=points[0]
- self.faces=points[1]
- self.p_count=len(self.points)
- self.f_count=len(self.faces)
- elif not (self.pflag70 & POLYLINE_3D):
- self.polyline2d = True
- if width:
- if type(width)!='list': width=[width,width]
- self.width=width
-
- def __str__(self):
- result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.pflag70)
- result+=' 66\n1\n'
- result+='%s\n' %_point(self.org_point)
- if self.polyface:
- result+=' 71\n%s\n' %self.p_count
- result+=' 72\n%s\n' %self.f_count
- elif self.polyline2d:
- if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
- if self.pflag75:
- result+=' 75\n%s\n' %self.pflag75
- for point in self.points:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- if self.polyface:
- result+='%s\n' %_point(point)
- result+=' 70\n192\n'
- elif self.polyline2d:
- result+='%s\n' %_point(point[0])
- flag = point[1]
- if len(point)>2:
- [width1, width2] = point[2]
- if width1!=None: result+=' 40\n%s\n' %width1
- if width2!=None: result+=' 41\n%s\n' %width2
- if len(point)==4:
- bulge = point[3]
- if bulge: result+=' 42\n%s\n' %bulge
- if flag:
- result+=' 70\n%s\n' %flag
- else:
- result+='%s\n' %_point(point[0])
- flag = point[1]
- if flag:
- result+=' 70\n%s\n' %flag
-
- for face in self.faces:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- result+='%s\n' %_point(self.org_point)
- result+=' 70\n128\n'
- result+=' 71\n%s\n' %face[0]
- result+=' 72\n%s\n' %face[1]
- result+=' 73\n%s\n' %face[2]
- if len(face)==4: result+=' 74\n%s\n' %face[3]
- result+=' 0\nSEQEND\n'
- result+=' 8\n%s\n' %self.layer
- return result
+ def __init__(self,points,org_point=[0,0,0],flag70=0,flag75=0,width=None,**common):
+ #width = number, or width = list [width_start=None, width_end=None]
+ #for 2d-polyline: points = [ [[x, y, z], vflag=None, [width_start=None, width_end=None], bulge=0 or None] ...]
+ #for 3d-polyline: points = [ [[x, y, z], vflag=None], ...]
+ #for polyface: points = [points_list, faces_list]
+ _Entity.__init__(self,**common)
+ self.points=points
+ self.org_point=org_point
+ self.pflag70 = flag70
+ self.pflag75 = flag75
+ self.polyface = False
+ self.polyline2d = False
+ self.faces = [] # dummy value
+ self.width= None # dummy value
+ if self.pflag70 & POLYFACE_MESH:
+ self.polyface=True
+ self.points=points[0]
+ self.faces=points[1]
+ self.p_count=len(self.points)
+ self.f_count=len(self.faces)
+ elif not (self.pflag70 & POLYLINE_3D):
+ self.polyline2d = True
+ if width:
+ if type(width)!='list': width=[width,width]
+ self.width=width
+
+ def __str__(self):
+ result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.pflag70)
+ result+=' 66\n1\n'
+ result+='%s\n' %_point(self.org_point)
+ if self.polyface:
+ result+=' 71\n%s\n' %self.p_count
+ result+=' 72\n%s\n' %self.f_count
+ elif self.polyline2d:
+ if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
+ if self.pflag75:
+ result+=' 75\n%s\n' %self.pflag75
+ for point in self.points:
+ result+=' 0\nVERTEX\n'
+ result+=' 8\n%s\n' %self.layer
+ if self.polyface:
+ result+='%s\n' %_point(point)
+ result+=' 70\n192\n'
+ elif self.polyline2d:
+ result+='%s\n' %_point(point[0])
+ flag = point[1]
+ if len(point)>2:
+ [width1, width2] = point[2]
+ if width1!=None: result+=' 40\n%s\n' %width1
+ if width2!=None: result+=' 41\n%s\n' %width2
+ if len(point)==4:
+ bulge = point[3]
+ if bulge: result+=' 42\n%s\n' %bulge
+ if flag:
+ result+=' 70\n%s\n' %flag
+ else:
+ result+='%s\n' %_point(point[0])
+ flag = point[1]
+ if flag:
+ result+=' 70\n%s\n' %flag
+
+ for face in self.faces:
+ result+=' 0\nVERTEX\n'
+ result+=' 8\n%s\n' %self.layer
+ result+='%s\n' %_point(self.org_point)
+ result+=' 70\n128\n'
+ result+=' 71\n%s\n' %face[0]
+ result+=' 72\n%s\n' %face[1]
+ result+=' 73\n%s\n' %face[2]
+ if len(face)==4: result+=' 74\n%s\n' %face[3]
+ result+=' 0\nSEQEND\n'
+ result+=' 8\n%s\n' %self.layer
+ return result
#-----------------------------------------------
class Point(_Entity):
- """Point."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self): # TODO:
- return ' 0\nPOINT\n%s%s\n' %(self._common(),
- _points(self.points)
- )
+ """Point."""
+ def __init__(self,points=None,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self): # TODO:
+ return ' 0\nPOINT\n%s%s\n' %(self._common(),
+ _points(self.points)
+ )
#-----------------------------------------------
class Solid(_Entity):
- """Colored solid fill."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nSOLID\n%s%s\n' %(self._common(),
- _points(self.points[:2]+[self.points[3],self.points[2]])
- )
+ """Colored solid fill."""
+ def __init__(self,points=None,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self):
+ return ' 0\nSOLID\n%s%s\n' %(self._common(),
+ _points(self.points[:2]+[self.points[3],self.points[2]])
+ )
#-----------------------------------------------
class Text(_Entity):
- """Single text line."""
- def __init__(self,text='',point=(0,0,0),alignment=None,
- flag=None,height=1,justifyhor=None,justifyver=None,
- rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
- _Entity.__init__(self,**common)
- self.text=text
- self.point=point
- self.alignment=alignment
- self.flag=flag
- self.height=height
- self.justifyhor=justifyhor
- self.justifyver=justifyver
- self.rotation=rotation
- self.obliqueAngle=obliqueAngle
- self.style=style
- self.xscale=xscale
- def __str__(self):
- result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
- (self._common(),_point(self.point),self.height,self.text)
- if self.rotation: result+=' 50\n%s\n'%self.rotation
- if self.xscale: result+=' 41\n%s\n'%self.xscale
- if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
- if self.style: result+=' 7\n%s\n'%self.style
- if self.flag: result+=' 71\n%s\n'%self.flag
- if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
- if self.alignment: result+='%s\n'%_point(self.alignment,1)
- if self.justifyver: result+=' 73\n%s\n'%self.justifyver
- return result
+ """Single text line."""
+ def __init__(self,text='',point=(0,0,0),alignment=None,
+ flag=None,height=1,justifyhor=None,justifyver=None,
+ rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
+ _Entity.__init__(self,**common)
+ self.text=text
+ self.point=point
+ self.alignment=alignment
+ self.flag=flag
+ self.height=height
+ self.justifyhor=justifyhor
+ self.justifyver=justifyver
+ self.rotation=rotation
+ self.obliqueAngle=obliqueAngle
+ self.style=style
+ self.xscale=xscale
+ def __str__(self):
+ result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
+ (self._common(),_point(self.point),self.height,self.text)
+ if self.rotation: result+=' 50\n%s\n'%self.rotation
+ if self.xscale: result+=' 41\n%s\n'%self.xscale
+ if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
+ if self.style: result+=' 7\n%s\n'%self.style
+ if self.flag: result+=' 71\n%s\n'%self.flag
+ if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
+ if self.alignment: result+='%s\n'%_point(self.alignment,1)
+ if self.justifyver: result+=' 73\n%s\n'%self.justifyver
+ return result
#-----------------------------------------------
class Mtext(Text):
- """Surrogate for mtext, generates some Text instances."""
- def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
- Text.__init__(self,text=text,point=point,**options)
- if down:spacingFactor*=-1
- self.spacingFactor=spacingFactor
- self.spacingWidth=spacingWidth
- self.width=width
- self.down=down
- def __str__(self):
- texts=self.text.replace('\r\n','\n').split('\n')
- if not self.down:texts.reverse()
- result=''
- x=y=0
- if self.spacingWidth:spacingWidth=self.spacingWidth
- else:spacingWidth=self.height*self.spacingFactor
- for text in texts:
- while text:
- result+='%s' %Text(text[:self.width],
- point=(self.point[0]+x*spacingWidth,
- self.point[1]+y*spacingWidth,
- self.point[2]),
- alignment=self.alignment,flag=self.flag,height=self.height,
- justifyhor=self.justifyhor,justifyver=self.justifyver,
- rotation=self.rotation,obliqueAngle=self.obliqueAngle,
- style=self.style,xscale=self.xscale,parent=self
- )
- text=text[self.width:]
- if self.rotation:x+=1
- else:y+=1
- return result[1:]
+ """Surrogate for mtext, generates some Text instances."""
+ def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
+ Text.__init__(self,text=text,point=point,**options)
+ if down:spacingFactor*=-1
+ self.spacingFactor=spacingFactor
+ self.spacingWidth=spacingWidth
+ self.width=width
+ self.down=down
+ def __str__(self):
+ texts=self.text.replace('\r\n','\n').split('\n')
+ if not self.down:texts.reverse()
+ result=''
+ x=y=0
+ if self.spacingWidth:spacingWidth=self.spacingWidth
+ else:spacingWidth=self.height*self.spacingFactor
+ for text in texts:
+ while text:
+ result+='%s' %Text(text[:self.width],
+ point=(self.point[0]+x*spacingWidth,
+ self.point[1]+y*spacingWidth,
+ self.point[2]),
+ alignment=self.alignment,flag=self.flag,height=self.height,
+ justifyhor=self.justifyhor,justifyver=self.justifyver,
+ rotation=self.rotation,obliqueAngle=self.obliqueAngle,
+ style=self.style,xscale=self.xscale,parent=self
+ )
+ text=text[self.width:]
+ if self.rotation:x+=1
+ else:y+=1
+ return result[1:]
#-----------------------------------------------
##class _Mtext(_Entity):
- """Mtext not functioning for minimal dxf."""
- """
- def __init__(self,text='',point=(0,0,0),attachment=1,
- charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
- spacingStyle=None,spacingFactor=None,style=None,width=100,
- xdirection=None,**common):
- _Entity.__init__(self,**common)
- self.text=text
- self.point=point
- self.attachment=attachment
- self.charWidth=charWidth
- self.charHeight=charHeight
- self.direction=direction
- self.height=height
- self.rotation=rotation
- self.spacingStyle=spacingStyle
- self.spacingFactor=spacingFactor
- self.style=style
- self.width=width
- self.xdirection=xdirection
- def __str__(self):
- input=self.text
- text=''
- while len(input)>250:
- text+='3\n%s\n'%input[:250]
- input=input[250:]
- text+='1\n%s\n'%input
- result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
- (self._common(),_point(self.point),self.charHeight,self.width,
- self.attachment,self.direction,text,
- self.height,
- self.rotation)
- if self.style:result+='7\n%s\n'%self.style
- if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
- if self.charWidth:result+='42\n%s\n'%self.charWidth
- if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
- if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
- return result
- """
+ """Mtext not functioning for minimal dxf."""
+ """
+ def __init__(self,text='',point=(0,0,0),attachment=1,
+ charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
+ spacingStyle=None,spacingFactor=None,style=None,width=100,
+ xdirection=None,**common):
+ _Entity.__init__(self,**common)
+ self.text=text
+ self.point=point
+ self.attachment=attachment
+ self.charWidth=charWidth
+ self.charHeight=charHeight
+ self.direction=direction
+ self.height=height
+ self.rotation=rotation
+ self.spacingStyle=spacingStyle
+ self.spacingFactor=spacingFactor
+ self.style=style
+ self.width=width
+ self.xdirection=xdirection
+ def __str__(self):
+ input=self.text
+ text=''
+ while len(input)>250:
+ text+='3\n%s\n'%input[:250]
+ input=input[250:]
+ text+='1\n%s\n'%input
+ result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
+ (self._common(),_point(self.point),self.charHeight,self.width,
+ self.attachment,self.direction,text,
+ self.height,
+ self.rotation)
+ if self.style:result+='7\n%s\n'%self.style
+ if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
+ if self.charWidth:result+='42\n%s\n'%self.charWidth
+ if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
+ if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
+ return result
+ """
#---tables ---------------------------------------------------
#-----------------------------------------------
class Block(_Collection):
- """Use list methods to add entities, eg append."""
- def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
- self.entities=copy.copy(entities)
- _Collection.__init__(self,entities)
- self.layer=layer
- self.name=name
- self.flag=0
- self.base=base
- def __str__(self): # TODO:
- e=''.join([str(x)for x in self.entities])
- return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
- (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
+ """Use list methods to add entities, eg append."""
+ def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
+ self.entities=copy.copy(entities)
+ _Collection.__init__(self,entities)
+ self.layer=layer
+ self.name=name
+ self.flag=0
+ self.base=base
+ def __str__(self): # TODO:
+ e=''.join([str(x)for x in self.entities])
+ return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
+ (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
#-----------------------------------------------
class Layer(_Call):
- """Layer"""
- def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
- self.name=name
- self.color=color
- self.lineType=lineType
- self.flag=flag
- def __str__(self):
- return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
- (self.name.upper(),self.flag,self.color,self.lineType)
+ """Layer"""
+ def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
+ self.name=name
+ self.color=color
+ self.lineType=lineType
+ self.flag=flag
+ def __str__(self):
+ return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
+ (self.name.upper(),self.flag,self.color,self.lineType)
#-----------------------------------------------
class LineType(_Call):
- """Custom linetype"""
- def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
- self.name=name
- self.description=description
- self.elements=copy.copy(elements)
- self.flag=flag
- def __str__(self):
- result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
- (self.name.upper(),self.flag,self.description)
- if self.elements:
- elements = ' 73\n%s\n' %(len(self.elements)-1)
- elements += ' 40\n%s\n' %(self.elements[0])
- for e in self.elements[1:]:
- elements += ' 49\n%s\n' %e
- result += elements
- return result
+ """Custom linetype"""
+ def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
+ self.name=name
+ self.description=description
+ self.elements=copy.copy(elements)
+ self.flag=flag
+ def __str__(self):
+ result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
+ (self.name.upper(),self.flag,self.description)
+ if self.elements:
+ elements = ' 73\n%s\n' %(len(self.elements)-1)
+ elements += ' 40\n%s\n' %(self.elements[0])
+ for e in self.elements[1:]:
+ elements += ' 49\n%s\n' %e
+ result += elements
+ return result
#-----------------------------------------------
class Style(_Call):
- """Text style"""
- def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
- mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
- self.name=name
- self.flag=flag
- self.height=height
- self.widthFactor=widthFactor
- self.obliqueAngle=obliqueAngle
- self.mirror=mirror
- self.lastHeight=lastHeight
- self.font=font
- self.bigFont=bigFont
- def __str__(self):
- return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
- (self.name.upper(),self.flag,self.flag,self.widthFactor,
- self.obliqueAngle,self.mirror,self.lastHeight,
- self.font.upper(),self.bigFont.upper())
+ """Text style"""
+ def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
+ mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
+ self.name=name
+ self.flag=flag
+ self.height=height
+ self.widthFactor=widthFactor
+ self.obliqueAngle=obliqueAngle
+ self.mirror=mirror
+ self.lastHeight=lastHeight
+ self.font=font
+ self.bigFont=bigFont
+ def __str__(self):
+ return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
+ (self.name.upper(),self.flag,self.flag,self.widthFactor,
+ self.obliqueAngle,self.mirror,self.lastHeight,
+ self.font.upper(),self.bigFont.upper())
#-----------------------------------------------
class VPort(_Call):
- def __init__(self,name,flag=0,
- leftBottom=(0.0,0.0),
- rightTop=(1.0,1.0),
- center=(0.5,0.5),
- snap_base=(0.0,0.0),
- snap_spacing=(0.1,0.1),
- grid_spacing=(0.1,0.1),
- direction=(0.0,0.0,1.0),
- target=(0.0,0.0,0.0),
- height=1.0,
- ratio=1.0,
- lens=50.0,
- frontClipping=0.0,
- backClipping=0.0,
- snap_rotation=0.0,
- twist=0.0,
- mode=0,
- circle_zoom=100,
- fast_zoom=1,
- ucsicon=1,
- snap_on=0,
- grid_on=0,
- snap_style=0,
- snap_isopair=0
- ):
- self.name=name
- self.flag=flag
- self.leftBottom=leftBottom
- self.rightTop=rightTop
- self.center=center
- self.snap_base=snap_base
- self.snap_spacing=snap_spacing
- self.grid_spacing=grid_spacing
- self.direction=direction
- self.target=target
- self.height=float(height)
- self.ratio=float(ratio)
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.snap_rotation=float(snap_rotation)
- self.twist=float(twist)
- self.mode=mode
- self.circle_zoom=circle_zoom
- self.fast_zoom=fast_zoom
- self.ucsicon=ucsicon
- self.snap_on=snap_on
- self.grid_on=grid_on
- self.snap_style=snap_style
- self.snap_isopair=snap_isopair
- def __str__(self):
- output = [' 0', 'VPORT',
- ' 2', self.name,
- ' 70', self.flag,
- _point(self.leftBottom),
- _point(self.rightTop,1),
- _point(self.center,2), # View center point (in DCS)
- _point(self.snap_base,3),
- _point(self.snap_spacing,4),
- _point(self.grid_spacing,5),
- _point(self.direction,6), #view direction from target (in WCS)
- _point(self.target,7),
- ' 40', self.height,
- ' 41', self.ratio,
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.snap_rotation,
- ' 51', self.twist,
- ' 71', self.mode,
- ' 72', self.circle_zoom,
- ' 73', self.fast_zoom,
- ' 74', self.ucsicon,
- ' 75', self.snap_on,
- ' 76', self.grid_on,
- ' 77', self.snap_style,
- ' 78', self.snap_isopair
- ]
-
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
+ def __init__(self,name,flag=0,
+ leftBottom=(0.0,0.0),
+ rightTop=(1.0,1.0),
+ center=(0.5,0.5),
+ snap_base=(0.0,0.0),
+ snap_spacing=(0.1,0.1),
+ grid_spacing=(0.1,0.1),
+ direction=(0.0,0.0,1.0),
+ target=(0.0,0.0,0.0),
+ height=1.0,
+ ratio=1.0,
+ lens=50.0,
+ frontClipping=0.0,
+ backClipping=0.0,
+ snap_rotation=0.0,
+ twist=0.0,
+ mode=0,
+ circle_zoom=100,
+ fast_zoom=1,
+ ucsicon=1,
+ snap_on=0,
+ grid_on=0,
+ snap_style=0,
+ snap_isopair=0
+ ):
+ self.name=name
+ self.flag=flag
+ self.leftBottom=leftBottom
+ self.rightTop=rightTop
+ self.center=center
+ self.snap_base=snap_base
+ self.snap_spacing=snap_spacing
+ self.grid_spacing=grid_spacing
+ self.direction=direction
+ self.target=target
+ self.height=float(height)
+ self.ratio=float(ratio)
+ self.lens=float(lens)
+ self.frontClipping=float(frontClipping)
+ self.backClipping=float(backClipping)
+ self.snap_rotation=float(snap_rotation)
+ self.twist=float(twist)
+ self.mode=mode
+ self.circle_zoom=circle_zoom
+ self.fast_zoom=fast_zoom
+ self.ucsicon=ucsicon
+ self.snap_on=snap_on
+ self.grid_on=grid_on
+ self.snap_style=snap_style
+ self.snap_isopair=snap_isopair
+ def __str__(self):
+ output = [' 0', 'VPORT',
+ ' 2', self.name,
+ ' 70', self.flag,
+ _point(self.leftBottom),
+ _point(self.rightTop,1),
+ _point(self.center,2), # View center point (in DCS)
+ _point(self.snap_base,3),
+ _point(self.snap_spacing,4),
+ _point(self.grid_spacing,5),
+ _point(self.direction,6), #view direction from target (in WCS)
+ _point(self.target,7),
+ ' 40', self.height,
+ ' 41', self.ratio,
+ ' 42', self.lens,
+ ' 43', self.frontClipping,
+ ' 44', self.backClipping,
+ ' 50', self.snap_rotation,
+ ' 51', self.twist,
+ ' 71', self.mode,
+ ' 72', self.circle_zoom,
+ ' 73', self.fast_zoom,
+ ' 74', self.ucsicon,
+ ' 75', self.snap_on,
+ ' 76', self.grid_on,
+ ' 77', self.snap_style,
+ ' 78', self.snap_isopair
+ ]
+
+ output_str = ''
+ for s in output:
+ output_str += '%s\n' %s
+ return output_str
#-----------------------------------------------
class View(_Call):
- def __init__(self,name,flag=0,
- width=1.0,
- height=1.0,
- center=(0.5,0.5),
- direction=(0.0,0.0,1.0),
- target=(0.0,0.0,0.0),
- lens=50.0,
- frontClipping=0.0,
- backClipping=0.0,
- twist=0.0,mode=0
- ):
- self.name=name
- self.flag=flag
- self.width=float(width)
- self.height=float(height)
- self.center=center
- self.direction=direction
- self.target=target
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.twist=float(twist)
- self.mode=mode
- def __str__(self):
- output = [' 0', 'VIEW',
- ' 2', self.name,
- ' 70', self.flag,
- ' 40', self.height,
- _point(self.center),
- ' 41', self.width,
- _point(self.direction,1),
- _point(self.target,2),
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.twist,
- ' 71', self.mode
- ]
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
+ def __init__(self,name,flag=0,
+ width=1.0,
+ height=1.0,
+ center=(0.5,0.5),
+ direction=(0.0,0.0,1.0),
+ target=(0.0,0.0,0.0),
+ lens=50.0,
+ frontClipping=0.0,
+ backClipping=0.0,
+ twist=0.0,mode=0
+ ):
+ self.name=name
+ self.flag=flag
+ self.width=float(width)
+ self.height=float(height)
+ self.center=center
+ self.direction=direction
+ self.target=target
+ self.lens=float(lens)
+ self.frontClipping=float(frontClipping)
+ self.backClipping=float(backClipping)
+ self.twist=float(twist)
+ self.mode=mode
+ def __str__(self):
+ output = [' 0', 'VIEW',
+ ' 2', self.name,
+ ' 70', self.flag,
+ ' 40', self.height,
+ _point(self.center),
+ ' 41', self.width,
+ _point(self.direction,1),
+ _point(self.target,2),
+ ' 42', self.lens,
+ ' 43', self.frontClipping,
+ ' 44', self.backClipping,
+ ' 50', self.twist,
+ ' 71', self.mode
+ ]
+ output_str = ''
+ for s in output:
+ output_str += '%s\n' %s
+ return output_str
#-----------------------------------------------
def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options):
- width=abs(rightTop[0]-leftBottom[0])
- height=abs(rightTop[1]-leftBottom[1])
- center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
- return View(name=name,width=width,height=height,center=center,**options)
+ width=abs(rightTop[0]-leftBottom[0])
+ height=abs(rightTop[1]-leftBottom[1])
+ center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
+ return View(name=name,width=width,height=height,center=center,**options)
#---drawing
#-----------------------------------------------
class Drawing(_Collection):
- """Dxf drawing. Use append or any other list methods to add objects."""
- def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
- layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
- views=[],vports=[],entities=None,fileName='test.dxf'):
- # TODO: replace list with None,arial
- if not entities:
- entities=[]
- _Collection.__init__(self,entities)
- self.insbase=insbase
- self.extmin=extmin
- self.extmax=extmax
- self.layers=copy.copy(layers)
- self.linetypes=copy.copy(linetypes)
- self.styles=copy.copy(styles)
- self.views=copy.copy(views)
- self.vports=copy.copy(vports)
- self.blocks=copy.copy(blocks)
- self.fileName=fileName
- #print 'deb: blocks=',blocks #----------
- #private
- #self.acadver='9\n$ACADVER\n1\nAC1006\n'
- self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
- """DXF AutoCAD-Release format codes:
- AC1021 2008, 2007
- AC1018 2006, 2005, 2004
- AC1015 2002, 2000i, 2000
- AC1014 R14,14.01
- AC1012 R13
- AC1009 R12,11
- AC1006 R10
- AC1004 R9
- AC1002 R2.6
- AC1.50 R2.05
- """
-
- def _name(self,x):
- """Helper function for self._point"""
- return ' 9\n$%s\n' %x.upper()
-
- def _point(self,name,x):
- """Point setting from drawing like extmin,extmax,..."""
- return '%s%s' %(self._name(name),_point(x))
-
- def _section(self,name,x):
- """Sections like tables,blocks,entities,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
-
- def _table(self,name,x):
- """Tables like ltype,layer,style,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
-
- def __str__(self):
- """Returns drawing as dxf string."""
- header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
- header=self._section('header',header)
-
- tables=[self._table('vport',[str(x) for x in self.vports]),
- self._table('ltype',[str(x) for x in self.linetypes]),
- self._table('layer',[str(x) for x in self.layers]),
- self._table('style',[str(x) for x in self.styles]),
- self._table('view',[str(x) for x in self.views]),
- ]
- tables=self._section('tables',tables)
- blocks=self._section('blocks',[str(x) for x in self.blocks])
- entities=self._section('entities',[str(x) for x in self.entities])
- all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
- return all
-
- def _write_section(self,file,name,data):
- file.write(' 0\nSECTION\n 2\n%s\n'%name.upper())
- for x in data:
- file.write(str(x))
- file.write(' 0\nENDSEC\n')
-
- def saveas(self,fileName,buffer=0):
- """Writes DXF file. Needs target file name. If optional parameter buffer>0, then switch to old behavior: store entire output string in RAM.
- """
- self.fileName=fileName
- if buffer: self.save()
- else: self.export()
-
- def save(self):
- outfile=open(self.fileName,'w')
- outfile.write(str(self))
- outfile.close()
-
- def export(self):
- outfile=open(self.fileName,'w')
- header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
- self._write_section(outfile,'header',header)
- tables=[self._table('vport',[str(x) for x in self.vports]),
- self._table('ltype',[str(x) for x in self.linetypes]),
- self._table('layer',[str(x) for x in self.layers]),
- self._table('style',[str(x) for x in self.styles]),
- self._table('view',[str(x) for x in self.views]),
- ]
- self._write_section(outfile,'tables',tables)
- self._write_section(outfile,'blocks',self.blocks)
- self._write_section(outfile,'entities',self.entities)
- outfile.write(' 0\nEOF\n')
- outfile.close()
+ """Dxf drawing. Use append or any other list methods to add objects."""
+ def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
+ layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
+ views=[],vports=[],entities=None,fileName='test.dxf'):
+ # TODO: replace list with None,arial
+ if not entities:
+ entities=[]
+ _Collection.__init__(self,entities)
+ self.insbase=insbase
+ self.extmin=extmin
+ self.extmax=extmax
+ self.layers=copy.copy(layers)
+ self.linetypes=copy.copy(linetypes)
+ self.styles=copy.copy(styles)
+ self.views=copy.copy(views)
+ self.vports=copy.copy(vports)
+ self.blocks=copy.copy(blocks)
+ self.fileName=fileName
+ #print 'deb: blocks=',blocks #----------
+ #private
+ #self.acadver='9\n$ACADVER\n1\nAC1006\n'
+ self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
+ """DXF AutoCAD-Release format codes:
+ AC1021 2008, 2007
+ AC1018 2006, 2005, 2004
+ AC1015 2002, 2000i, 2000
+ AC1014 R14,14.01
+ AC1012 R13
+ AC1009 R12,11
+ AC1006 R10
+ AC1004 R9
+ AC1002 R2.6
+ AC1.50 R2.05
+ """
+
+ def _name(self,x):
+ """Helper function for self._point"""
+ return ' 9\n$%s\n' %x.upper()
+
+ def _point(self,name,x):
+ """Point setting from drawing like extmin,extmax,..."""
+ return '%s%s' %(self._name(name),_point(x))
+
+ def _section(self,name,x):
+ """Sections like tables,blocks,entities,..."""
+ if x: xstr=''.join(x)
+ else: xstr=''
+ return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
+
+ def _table(self,name,x):
+ """Tables like ltype,layer,style,..."""
+ if x: xstr=''.join(x)
+ else: xstr=''
+ return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
+
+ def __str__(self):
+ """Returns drawing as dxf string."""
+ header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
+ header=self._section('header',header)
+
+ tables=[self._table('vport',[str(x) for x in self.vports]),
+ self._table('ltype',[str(x) for x in self.linetypes]),
+ self._table('layer',[str(x) for x in self.layers]),
+ self._table('style',[str(x) for x in self.styles]),
+ self._table('view',[str(x) for x in self.views]),
+ ]
+ tables=self._section('tables',tables)
+ blocks=self._section('blocks',[str(x) for x in self.blocks])
+ entities=self._section('entities',[str(x) for x in self.entities])
+ all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
+ return all
+
+ def _write_section(self,file,name,data):
+ file.write(' 0\nSECTION\n 2\n%s\n'%name.upper())
+ for x in data:
+ file.write(str(x))
+ file.write(' 0\nENDSEC\n')
+
+ def saveas(self,fileName,buffer=0):
+ """Writes DXF file. Needs target file name. If optional parameter buffer>0, then switch to old behavior: store entire output string in RAM.
+ """
+ self.fileName=fileName
+ if buffer: self.save()
+ else: self.export()
+
+ def save(self):
+ outfile=open(self.fileName,'w')
+ outfile.write(str(self))
+ outfile.close()
+
+ def export(self):
+ outfile=open(self.fileName,'w')
+ header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
+ self._write_section(outfile,'header',header)
+ tables=[self._table('vport',[str(x) for x in self.vports]),
+ self._table('ltype',[str(x) for x in self.linetypes]),
+ self._table('layer',[str(x) for x in self.layers]),
+ self._table('style',[str(x) for x in self.styles]),
+ self._table('view',[str(x) for x in self.views]),
+ ]
+ self._write_section(outfile,'tables',tables)
+ self._write_section(outfile,'blocks',self.blocks)
+ self._write_section(outfile,'entities',self.entities)
+ outfile.write(' 0\nEOF\n')
+ outfile.close()
#---extras
#-----------------------------------------------
class Rectangle(_Entity):
- """Rectangle, creates lines."""
- def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
- _Entity.__init__(self,**common)
- self.point=point
- self.width=width
- self.height=height
- self.solid=solid
- self.line=line
- def __str__(self):
- result=''
- points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
- (self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
- (self.point[0],self.point[1]+self.height,self.point[2]),self.point]
- if self.solid:
- result+= Solid(points=points[:-1],parent=self.solid)
- if self.line:
- for i in range(4):
- result+= Line(points=[points[i],points[i+1]],parent=self)
- return result[1:]
+ """Rectangle, creates lines."""
+ def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
+ _Entity.__init__(self,**common)
+ self.point=point
+ self.width=width
+ self.height=height
+ self.solid=solid
+ self.line=line
+ def __str__(self):
+ result=''
+ points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
+ (self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
+ (self.point[0],self.point[1]+self.height,self.point[2]),self.point]
+ if self.solid:
+ result+= Solid(points=points[:-1],parent=self.solid)
+ if self.line:
+ for i in range(4):
+ result+= Line(points=[points[i],points[i+1]],parent=self)
+ return result[1:]
#-----------------------------------------------
class LineList(_Entity):
- """Like polyline, but built of individual lines."""
- def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
- _Entity.__init__(self,**common)
- self.closed=closed
- self.points=copy.copy(points)
- def __str__(self):
- if self.closed:
- points=self.points+[self.points[0]]
- else: points=self.points
- result=''
- for i in range(len(points)-1):
- result+= Line(points=[points[i][0],points[i+1][0]],parent=self)
- return result[1:]
+ """Like polyline, but built of individual lines."""
+ def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
+ _Entity.__init__(self,**common)
+ self.closed=closed
+ self.points=copy.copy(points)
+ def __str__(self):
+ if self.closed:
+ points=self.points+[self.points[0]]
+ else: points=self.points
+ result=''
+ for i in range(len(points)-1):
+ result+= Line(points=[points[i][0],points[i+1][0]],parent=self)
+ return result[1:]
#-----------------------------------------------------
def test():
- #Blocks
- b=Block('test')
- b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
- b.append(Arc(center=(1,0,0),color=2))
-
- #Drawing
- d=Drawing()
- #tables
- d.blocks.append(b) #table blocks
- d.styles.append(Style()) #table styles
- d.views.append(View('Normal')) #table view
- d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
-
- #entities
- d.append(Circle(center=(1,1,0),color=3))
- d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
- d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
- d.append(Line(points=[(0,0,0),(1,1,1)]))
- d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
- d.append(Text('Please donate!',point=(3,0,1)))
- #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
- d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
- #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
-
- #d.saveas('c:\\test.dxf')
- d.saveas('test.dxf')
+ #Blocks
+ b=Block('test')
+ b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
+ b.append(Arc(center=(1,0,0),color=2))
+
+ #Drawing
+ d=Drawing()
+ #tables
+ d.blocks.append(b) #table blocks
+ d.styles.append(Style()) #table styles
+ d.views.append(View('Normal')) #table view
+ d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
+
+ #entities
+ d.append(Circle(center=(1,1,0),color=3))
+ d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
+ d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
+ d.append(Line(points=[(0,0,0),(1,1,1)]))
+ d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
+ d.append(Text('Please donate!',point=(3,0,1)))
+ #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
+ d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
+ #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
+
+ #d.saveas('c:\\test.dxf')
+ d.saveas('test.dxf')
#-----------------------------------------------------
if __name__=='__main__':
- if not copy:
- Draw.PupMenu('Error%t|This script requires a full python install')
- else: test()
+ if not copy:
+ Draw.PupMenu('Error%t|This script requires a full python install')
+ else: test()
diff --git a/io_export_dxf/model/model.py b/io_export_dxf/model/model.py
index 54e12f3a..698f5102 100644
--- a/io_export_dxf/model/model.py
+++ b/io_export_dxf/model/model.py
@@ -1,36 +1,36 @@
class DxfDrawing(object):
- """
- Represents intermediate model of DXF drawing. It is useful in iterating
- through exported object and for easy change the DXF handling library.
- """
- def __init__(self):
- self._entities = {}
- self._layers = {}
- self._views = []
- self._vports = []
- self._blocks = []
-
- def isEmpty(self):
- return len(self._entities) == 0
-
- def addEntity(self, type, **kwargs):
- if type not in self._entities:
- self._entities[type] = []
- self._entities[type].append(kwargs)
-
- def addLayer(self, name, color):
- self._layers[name] = color
-
- def containsLayer(self, name):
- return name in self._layers
-
- def addBlock(self, block):
- self._blocks.append(block)
-
- def containsBlock(self, blockname):
- return blockname in self._blocks
-
- def convert(self, **kwargs):
- """ Converts this drawing into DXF representation object """
- raise NotImplementedError()
+ """
+ Represents intermediate model of DXF drawing. It is useful in iterating
+ through exported object and for easy change the DXF handling library.
+ """
+ def __init__(self):
+ self._entities = {}
+ self._layers = {}
+ self._views = []
+ self._vports = []
+ self._blocks = []
+
+ def isEmpty(self):
+ return len(self._entities) == 0
+
+ def addEntity(self, type, **kwargs):
+ if type not in self._entities:
+ self._entities[type] = []
+ self._entities[type].append(kwargs)
+
+ def addLayer(self, name, color):
+ self._layers[name] = color
+
+ def containsLayer(self, name):
+ return name in self._layers
+
+ def addBlock(self, block):
+ self._blocks.append(block)
+
+ def containsBlock(self, blockname):
+ return blockname in self._blocks
+
+ def convert(self, **kwargs):
+ """ Converts this drawing into DXF representation object """
+ raise NotImplementedError()
diff --git a/io_export_dxf/test2.txt b/io_export_dxf/test2.txt
index fd95ef1c..8ccff989 100644
--- a/io_export_dxf/test2.txt
+++ b/io_export_dxf/test2.txt
@@ -1 +1 @@
-migius commit test 2b \ No newline at end of file
+migius commit test 2b
diff --git a/io_mesh_atomic/utility_gui.py b/io_mesh_atomic/utility_gui.py
index 97395036..295d1490 100644
--- a/io_mesh_atomic/utility_gui.py
+++ b/io_mesh_atomic/utility_gui.py
@@ -418,4 +418,3 @@ class SticksAllSmallerButton(Operator):
None,
1.0/scn.sticks_all)
return {'FINISHED'}
-
diff --git a/io_mesh_uv_layout/export_uv_eps.py b/io_mesh_uv_layout/export_uv_eps.py
index 3280cefa..45f64bb7 100644
--- a/io_mesh_uv_layout/export_uv_eps.py
+++ b/io_mesh_uv_layout/export_uv_eps.py
@@ -89,4 +89,4 @@ def draw_polygon_path(uvs, width, height):
def footer():
yield "showpage\n"
- yield "%%EOF\n" \ No newline at end of file
+ yield "%%EOF\n"
diff --git a/io_mesh_uv_layout/export_uv_svg.py b/io_mesh_uv_layout/export_uv_svg.py
index d00f9402..8aba2142 100644
--- a/io_mesh_uv_layout/export_uv_svg.py
+++ b/io_mesh_uv_layout/export_uv_svg.py
@@ -61,4 +61,4 @@ def get_color_string(color):
def footer():
yield '\n'
- yield '</svg>\n' \ No newline at end of file
+ yield '</svg>\n'
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
index 2a885971..b176ca45 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
@@ -29,7 +29,7 @@ def get_sk_drivers(blender_armature):
continue
# child.data can be an armature - which has no shapekeys
if not hasattr(child.data, 'shape_keys'):
- continue
+ continue
if not child.data.shape_keys:
continue
if not child.data.shape_keys.animation_data:
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
index ca2f8052..3c2a8619 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
@@ -91,4 +91,3 @@ class BlenderScene():
vnode = gltf.vnodes[vnode.children[0]]
bpy.context.view_layer.objects.active = vnode.blender_object
-
diff --git a/magic_uv/lib/bglx.py b/magic_uv/lib/bglx.py
index 24200caf..6bc885c6 100644
--- a/magic_uv/lib/bglx.py
+++ b/magic_uv/lib/bglx.py
@@ -272,4 +272,3 @@ def glTexParameteri(target, pname, param):
def glTexEnvi(target, pname, param):
pass
-
diff --git a/materials_library_vx/categories.txt b/materials_library_vx/categories.txt
index e5970daf..fce9151e 100644
--- a/materials_library_vx/categories.txt
+++ b/materials_library_vx/categories.txt
@@ -68,4 +68,4 @@
"Metallic Paint Clean"
]
]
-] \ No newline at end of file
+]
diff --git a/mesh_inset/__init__.py b/mesh_inset/__init__.py
index 9f7cf1b8..4dbd8472 100644
--- a/mesh_inset/__init__.py
+++ b/mesh_inset/__init__.py
@@ -200,7 +200,7 @@ class MESH_OT_InsetStraightSkeleton(bpy.types.Operator):
obj = bpy.context.active_object
mesh = obj.data
do_inset(mesh, self.inset_amount, self.inset_height, self.region,
- self.quadrangulate)
+ self.quadrangulate)
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
@@ -246,7 +246,7 @@ def calc_select_center(context):
center = center / n
world_center = ob.matrix_world @ center
world_center_2d = view3d_utils.location_3d_to_region_2d( \
- context.region, context.region_data, world_center)
+ context.region, context.region_data, world_center)
return (world_center_2d, world_center)
def do_inset(mesh, amount, height, region, quadrangulate):
diff --git a/mesh_snap_utilities_line/snap_context_l/utils_projection.py b/mesh_snap_utilities_line/snap_context_l/utils_projection.py
index a9b0f021..b941f7db 100644
--- a/mesh_snap_utilities_line/snap_context_l/utils_projection.py
+++ b/mesh_snap_utilities_line/snap_context_l/utils_projection.py
@@ -214,4 +214,3 @@ def intersect_ray_segment_fac(v0, v1, ray_direction, ray_origin):
c = n - t
cray = c.cross(ray_direction)
return cray.dot(n) / nlen
-
diff --git a/mesh_tools/mesh_offset_edges.py b/mesh_tools/mesh_offset_edges.py
index 30248304..1471d256 100644
--- a/mesh_tools/mesh_offset_edges.py
+++ b/mesh_tools/mesh_offset_edges.py
@@ -8,7 +8,7 @@
#
# 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
+# 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
@@ -20,7 +20,7 @@
bl_info = {
"name": "Offset Edges",
"author": "Hidesato Ikeya, Veezen fix 2.8 (temporary)",
- #i tried edit newest version, but got some errors, works only on 0,2,6
+ #i tried edit newest version, but got some errors, works only on 0,2,6
"version": (0, 2, 6),
"blender": (2, 80, 0),
"location": "VIEW3D > Edge menu(CTRL-E) > Offset Edges",
diff --git a/node_arrange.py b/node_arrange.py
index e7b03c57..6d3ed807 100644
--- a/node_arrange.py
+++ b/node_arrange.py
@@ -17,17 +17,17 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- "name": "Node Arrange",
- "author": "JuhaW",
- "version": (0, 2, 2),
- "blender": (2, 80, 4),
- "location": "Node Editor > Properties > Trees",
- "description": "Node Tree Arrangement Tools",
- "warning": "",
+ "name": "Node Arrange",
+ "author": "JuhaW",
+ "version": (0, 2, 2),
+ "blender": (2, 80, 4),
+ "location": "Node Editor > Properties > Trees",
+ "description": "Node Tree Arrangement Tools",
+ "warning": "",
"doc_url": "https://docs.blender.org/manual/en/dev/addons/"
"node/node_arrange.html",
- "tracker_url": "https://github.com/JuhaW/NodeArrange/issues",
- "category": "Node"
+ "tracker_url": "https://github.com/JuhaW/NodeArrange/issues",
+ "category": "Node"
}
@@ -129,406 +129,406 @@ class NA_OT_AlignNodes(Operator):
return {'FINISHED'}
class values():
- average_y = 0
- x_last = 0
- margin_x = 100
- mat_name = ""
- margin_y = 20
+ average_y = 0
+ x_last = 0
+ margin_x = 100
+ mat_name = ""
+ margin_y = 20
class NA_PT_NodePanel(Panel):
- bl_label = "Node Arrange"
- bl_space_type = "NODE_EDITOR"
- bl_region_type = "UI"
- bl_category = "Arrange"
-
- def draw(self, context):
- if context.active_node is not None:
- layout = self.layout
- row = layout.row()
- col = layout.column
- row.operator('node.button')
-
- row = layout.row()
- row.prop(bpy.context.scene, 'nodemargin_x', text="Margin x")
- row = layout.row()
- row.prop(bpy.context.scene, 'nodemargin_y', text="Margin y")
- row = layout.row()
- row.prop(context.scene, 'node_center', text="Center nodes")
-
- row = layout.row()
- row.operator('node.na_align_nodes', text="Align to Selected")
-
- row = layout.row()
- node = context.space_data.node_tree.nodes.active
- if node and node.select:
- row.prop(node, 'location', text = "Node X", index = 0)
- row.prop(node, 'location', text = "Node Y", index = 1)
- row = layout.row()
- row.prop(node, 'width', text = "Node width")
-
- row = layout.row()
- row.operator('node.button_odd')
+ bl_label = "Node Arrange"
+ bl_space_type = "NODE_EDITOR"
+ bl_region_type = "UI"
+ bl_category = "Arrange"
+
+ def draw(self, context):
+ if context.active_node is not None:
+ layout = self.layout
+ row = layout.row()
+ col = layout.column
+ row.operator('node.button')
+
+ row = layout.row()
+ row.prop(bpy.context.scene, 'nodemargin_x', text="Margin x")
+ row = layout.row()
+ row.prop(bpy.context.scene, 'nodemargin_y', text="Margin y")
+ row = layout.row()
+ row.prop(context.scene, 'node_center', text="Center nodes")
+
+ row = layout.row()
+ row.operator('node.na_align_nodes', text="Align to Selected")
+
+ row = layout.row()
+ node = context.space_data.node_tree.nodes.active
+ if node and node.select:
+ row.prop(node, 'location', text = "Node X", index = 0)
+ row.prop(node, 'location', text = "Node Y", index = 1)
+ row = layout.row()
+ row.prop(node, 'width', text = "Node width")
+
+ row = layout.row()
+ row.operator('node.button_odd')
class NA_OT_NodeButton(Operator):
- '''Arrange Connected Nodes/Arrange All Nodes'''
- bl_idname = 'node.button'
- bl_label = 'Arrange All Nodes'
+ '''Arrange Connected Nodes/Arrange All Nodes'''
+ bl_idname = 'node.button'
+ bl_label = 'Arrange All Nodes'
- def execute(self, context):
- nodemargin(self, context)
- bpy.context.space_data.node_tree.nodes.update()
- bpy.ops.node.view_all()
+ def execute(self, context):
+ nodemargin(self, context)
+ bpy.context.space_data.node_tree.nodes.update()
+ bpy.ops.node.view_all()
- return {'FINISHED'}
+ return {'FINISHED'}
- # not sure this is doing what you expect.
- # blender.org/api/blender_python_api_current/bpy.types.Operator.html#invoke
- def invoke(self, context, value):
- values.mat_name = bpy.context.space_data.node_tree
- nodemargin(self, context)
- return {'FINISHED'}
+ # not sure this is doing what you expect.
+ # blender.org/api/blender_python_api_current/bpy.types.Operator.html#invoke
+ def invoke(self, context, value):
+ values.mat_name = bpy.context.space_data.node_tree
+ nodemargin(self, context)
+ return {'FINISHED'}
class NA_OT_NodeButtonOdd(Operator):
- 'Show the nodes for this material'
- bl_idname = 'node.button_odd'
- bl_label = 'Select Unlinked'
+ 'Show the nodes for this material'
+ bl_idname = 'node.button_odd'
+ bl_label = 'Select Unlinked'
- def execute(self, context):
- values.mat_name = bpy.context.space_data.node_tree
- #mat = bpy.context.object.active_material
- nodes_iterate(context.space_data.node_tree, False)
- return {'FINISHED'}
+ def execute(self, context):
+ values.mat_name = bpy.context.space_data.node_tree
+ #mat = bpy.context.object.active_material
+ nodes_iterate(context.space_data.node_tree, False)
+ return {'FINISHED'}
class NA_OT_NodeButtonCenter(Operator):
- 'Show the nodes for this material'
- bl_idname = 'node.button_center'
- bl_label = 'Center nodes (0,0)'
+ 'Show the nodes for this material'
+ bl_idname = 'node.button_center'
+ bl_label = 'Center nodes (0,0)'
- def execute(self, context):
- values.mat_name = "" # reset
- mat = bpy.context.object.active_material
- nodes_center(mat)
- return {'FINISHED'}
+ def execute(self, context):
+ values.mat_name = "" # reset
+ mat = bpy.context.object.active_material
+ nodes_center(mat)
+ return {'FINISHED'}
def nodemargin(self, context):
- values.margin_x = context.scene.nodemargin_x
- values.margin_y = context.scene.nodemargin_y
+ values.margin_x = context.scene.nodemargin_x
+ values.margin_y = context.scene.nodemargin_y
- ntree = context.space_data.node_tree
+ ntree = context.space_data.node_tree
- #first arrange nodegroups
- n_groups = []
- for i in ntree.nodes:
- if i.type == 'GROUP':
- n_groups.append(i)
+ #first arrange nodegroups
+ n_groups = []
+ for i in ntree.nodes:
+ if i.type == 'GROUP':
+ n_groups.append(i)
- while n_groups:
- j = n_groups.pop(0)
- nodes_iterate(j.node_tree)
- for i in j.node_tree.nodes:
- if i.type == 'GROUP':
- n_groups.append(i)
+ while n_groups:
+ j = n_groups.pop(0)
+ nodes_iterate(j.node_tree)
+ for i in j.node_tree.nodes:
+ if i.type == 'GROUP':
+ n_groups.append(i)
- nodes_iterate(ntree)
+ nodes_iterate(ntree)
- # arrange nodes + this center nodes together
- if context.scene.node_center:
- nodes_center(ntree)
+ # arrange nodes + this center nodes together
+ if context.scene.node_center:
+ nodes_center(ntree)
class NA_OT_ArrangeNodesOp(bpy.types.Operator):
- bl_idname = 'node.arrange_nodetree'
- bl_label = 'Nodes Private Op'
-
- mat_name : bpy.props.StringProperty()
- margin_x : bpy.props.IntProperty(default=120)
- margin_y : bpy.props.IntProperty(default=120)
-
- def nodemargin2(self, context):
- mat = None
- mat_found = bpy.data.materials.get(self.mat_name)
- if self.mat_name and mat_found:
- mat = mat_found
- #print(mat)
-
- if not mat:
- return
- else:
- values.mat_name = self.mat_name
- scn = context.scene
- scn.nodemargin_x = self.margin_x
- scn.nodemargin_y = self.margin_y
- nodes_iterate(mat)
- if scn.node_center:
- nodes_center(mat)
-
- def execute(self, context):
- self.nodemargin2(context)
- return {'FINISHED'}
-
-
-def outputnode_search(ntree): # return node/None
-
- outputnodes = []
- for node in ntree.nodes:
- if not node.outputs:
- for input in node.inputs:
- if input.is_linked:
- outputnodes.append(node)
- break
-
- if not outputnodes:
- print("No output node found")
- return None
- return outputnodes
-
-
-###############################################################
-def nodes_iterate(ntree, arrange=True):
-
- nodeoutput = outputnode_search(ntree)
- if nodeoutput is None:
- #print ("nodeoutput is None")
- return None
- a = []
- a.append([])
- for i in nodeoutput:
- a[0].append(i)
-
-
- level = 0
-
- while a[level]:
- a.append([])
-
- for node in a[level]:
- inputlist = [i for i in node.inputs if i.is_linked]
-
- if inputlist:
-
- for input in inputlist:
- for nlinks in input.links:
- node1 = nlinks.from_node
- a[level + 1].append(node1)
-
- else:
- pass
+ bl_idname = 'node.arrange_nodetree'
+ bl_label = 'Nodes Private Op'
+
+ mat_name : bpy.props.StringProperty()
+ margin_x : bpy.props.IntProperty(default=120)
+ margin_y : bpy.props.IntProperty(default=120)
+
+ def nodemargin2(self, context):
+ mat = None
+ mat_found = bpy.data.materials.get(self.mat_name)
+ if self.mat_name and mat_found:
+ mat = mat_found
+ #print(mat)
+
+ if not mat:
+ return
+ else:
+ values.mat_name = self.mat_name
+ scn = context.scene
+ scn.nodemargin_x = self.margin_x
+ scn.nodemargin_y = self.margin_y
+ nodes_iterate(mat)
+ if scn.node_center:
+ nodes_center(mat)
- level += 1
+ def execute(self, context):
+ self.nodemargin2(context)
+ return {'FINISHED'}
- del a[level]
- level -= 1
- #remove duplicate nodes at the same level, first wins
- for x, nodes in enumerate(a):
- a[x] = list(OrderedDict(zip(a[x], repeat(None))))
+def outputnode_search(ntree): # return node/None
- #remove duplicate nodes in all levels, last wins
- top = level
- for row1 in range(top, 1, -1):
- for col1 in a[row1]:
- for row2 in range(row1-1, 0, -1):
- for col2 in a[row2]:
- if col1 == col2:
- a[row2].remove(col2)
- break
+ outputnodes = []
+ for node in ntree.nodes:
+ if not node.outputs:
+ for input in node.inputs:
+ if input.is_linked:
+ outputnodes.append(node)
+ break
- """
- for x, i in enumerate(a):
- print (x)
- for j in i:
- print (j)
- #print()
- """
- """
- #add node frames to nodelist
- frames = []
- print ("Frames:")
- print ("level:", level)
- print ("a:",a)
- for row in range(level, 0, -1):
+ if not outputnodes:
+ print("No output node found")
+ return None
+ return outputnodes
- for i, node in enumerate(a[row]):
- if node.parent:
- print ("Frame found:", node.parent, node)
- #if frame already added to the list ?
- frame = node.parent
- #remove node
- del a[row][i]
- if frame not in frames:
- frames.append(frame)
- #add frame to the same place than node was
- a[row].insert(i, frame)
- pprint.pprint(a)
- """
- #return None
- ########################################
+###############################################################
+def nodes_iterate(ntree, arrange=True):
+ nodeoutput = outputnode_search(ntree)
+ if nodeoutput is None:
+ #print ("nodeoutput is None")
+ return None
+ a = []
+ a.append([])
+ for i in nodeoutput:
+ a[0].append(i)
- if not arrange:
- nodelist = [j for i in a for j in i]
- nodes_odd(ntree, nodelist=nodelist)
- return None
+ level = 0
- ########################################
+ while a[level]:
+ a.append([])
- levelmax = level + 1
- level = 0
- values.x_last = 0
+ for node in a[level]:
+ inputlist = [i for i in node.inputs if i.is_linked]
- while level < levelmax:
+ if inputlist:
- values.average_y = 0
- nodes = [x for x in a[level]]
- #print ("level, nodes:", level, nodes)
- nodes_arrange(nodes, level)
+ for input in inputlist:
+ for nlinks in input.links:
+ node1 = nlinks.from_node
+ a[level + 1].append(node1)
- level = level + 1
-
- return None
+ else:
+ pass
+
+ level += 1
+
+ del a[level]
+ level -= 1
+
+ #remove duplicate nodes at the same level, first wins
+ for x, nodes in enumerate(a):
+ a[x] = list(OrderedDict(zip(a[x], repeat(None))))
+
+ #remove duplicate nodes in all levels, last wins
+ top = level
+ for row1 in range(top, 1, -1):
+ for col1 in a[row1]:
+ for row2 in range(row1-1, 0, -1):
+ for col2 in a[row2]:
+ if col1 == col2:
+ a[row2].remove(col2)
+ break
+
+ """
+ for x, i in enumerate(a):
+ print (x)
+ for j in i:
+ print (j)
+ #print()
+ """
+ """
+ #add node frames to nodelist
+ frames = []
+ print ("Frames:")
+ print ("level:", level)
+ print ("a:",a)
+ for row in range(level, 0, -1):
+
+ for i, node in enumerate(a[row]):
+ if node.parent:
+ print ("Frame found:", node.parent, node)
+ #if frame already added to the list ?
+ frame = node.parent
+ #remove node
+ del a[row][i]
+ if frame not in frames:
+ frames.append(frame)
+ #add frame to the same place than node was
+ a[row].insert(i, frame)
+
+ pprint.pprint(a)
+ """
+ #return None
+ ########################################
+
+
+
+ if not arrange:
+ nodelist = [j for i in a for j in i]
+ nodes_odd(ntree, nodelist=nodelist)
+ return None
+
+ ########################################
+
+ levelmax = level + 1
+ level = 0
+ values.x_last = 0
+
+ while level < levelmax:
+
+ values.average_y = 0
+ nodes = [x for x in a[level]]
+ #print ("level, nodes:", level, nodes)
+ nodes_arrange(nodes, level)
+
+ level = level + 1
+
+ return None
###############################################################
def nodes_odd(ntree, nodelist):
- nodes = ntree.nodes
- for i in nodes:
- i.select = False
+ nodes = ntree.nodes
+ for i in nodes:
+ i.select = False
- a = [x for x in nodes if x not in nodelist]
- # print ("odd nodes:",a)
- for i in a:
- i.select = True
+ a = [x for x in nodes if x not in nodelist]
+ # print ("odd nodes:",a)
+ for i in a:
+ i.select = True
def nodes_arrange(nodelist, level):
- parents = []
- for node in nodelist:
- parents.append(node.parent)
- node.parent = None
- bpy.context.space_data.node_tree.nodes.update()
+ parents = []
+ for node in nodelist:
+ parents.append(node.parent)
+ node.parent = None
+ bpy.context.space_data.node_tree.nodes.update()
- #print ("nodes arrange def")
- # node x positions
+ #print ("nodes arrange def")
+ # node x positions
- widthmax = max([x.dimensions.x for x in nodelist])
- xpos = values.x_last - (widthmax + values.margin_x) if level != 0 else 0
- #print ("nodelist, xpos", nodelist,xpos)
- values.x_last = xpos
+ widthmax = max([x.dimensions.x for x in nodelist])
+ xpos = values.x_last - (widthmax + values.margin_x) if level != 0 else 0
+ #print ("nodelist, xpos", nodelist,xpos)
+ values.x_last = xpos
- # node y positions
- x = 0
- y = 0
+ # node y positions
+ x = 0
+ y = 0
- for node in nodelist:
+ for node in nodelist:
- if node.hide:
- hidey = (node.dimensions.y / 2) - 8
- y = y - hidey
- else:
- hidey = 0
+ if node.hide:
+ hidey = (node.dimensions.y / 2) - 8
+ y = y - hidey
+ else:
+ hidey = 0
- node.location.y = y
- y = y - values.margin_y - node.dimensions.y + hidey
+ node.location.y = y
+ y = y - values.margin_y - node.dimensions.y + hidey
- node.location.x = xpos #if node.type != "FRAME" else xpos + 1200
+ node.location.x = xpos #if node.type != "FRAME" else xpos + 1200
- y = y + values.margin_y
+ y = y + values.margin_y
- center = (0 + y) / 2
- values.average_y = center - values.average_y
+ center = (0 + y) / 2
+ values.average_y = center - values.average_y
- #for node in nodelist:
+ #for node in nodelist:
- #node.location.y -= values.average_y
+ #node.location.y -= values.average_y
- for i, node in enumerate(nodelist):
- node.parent = parents[i]
+ for i, node in enumerate(nodelist):
+ node.parent = parents[i]
def nodetree_get(mat):
- return mat.node_tree.nodes
+ return mat.node_tree.nodes
def nodes_center(ntree):
- bboxminx = []
- bboxmaxx = []
- bboxmaxy = []
- bboxminy = []
-
- for node in ntree.nodes:
- if not node.parent:
- bboxminx.append(node.location.x)
- bboxmaxx.append(node.location.x + node.dimensions.x)
- bboxmaxy.append(node.location.y)
- bboxminy.append(node.location.y - node.dimensions.y)
-
- # print ("bboxminy:",bboxminy)
- bboxminx = min(bboxminx)
- bboxmaxx = max(bboxmaxx)
- bboxminy = min(bboxminy)
- bboxmaxy = max(bboxmaxy)
- center_x = (bboxminx + bboxmaxx) / 2
- center_y = (bboxminy + bboxmaxy) / 2
- '''
- print ("minx:",bboxminx)
- print ("maxx:",bboxmaxx)
- print ("miny:",bboxminy)
- print ("maxy:",bboxmaxy)
-
- print ("bboxes:", bboxminx, bboxmaxx, bboxmaxy, bboxminy)
- print ("center x:",center_x)
- print ("center y:",center_y)
- '''
-
- x = 0
- y = 0
-
- for node in ntree.nodes:
-
- if not node.parent:
- node.location.x -= center_x
- node.location.y += -center_y
+ bboxminx = []
+ bboxmaxx = []
+ bboxmaxy = []
+ bboxminy = []
+
+ for node in ntree.nodes:
+ if not node.parent:
+ bboxminx.append(node.location.x)
+ bboxmaxx.append(node.location.x + node.dimensions.x)
+ bboxmaxy.append(node.location.y)
+ bboxminy.append(node.location.y - node.dimensions.y)
+
+ # print ("bboxminy:",bboxminy)
+ bboxminx = min(bboxminx)
+ bboxmaxx = max(bboxmaxx)
+ bboxminy = min(bboxminy)
+ bboxmaxy = max(bboxmaxy)
+ center_x = (bboxminx + bboxmaxx) / 2
+ center_y = (bboxminy + bboxmaxy) / 2
+ '''
+ print ("minx:",bboxminx)
+ print ("maxx:",bboxmaxx)
+ print ("miny:",bboxminy)
+ print ("maxy:",bboxmaxy)
+
+ print ("bboxes:", bboxminx, bboxmaxx, bboxmaxy, bboxminy)
+ print ("center x:",center_x)
+ print ("center y:",center_y)
+ '''
+
+ x = 0
+ y = 0
+
+ for node in ntree.nodes:
+
+ if not node.parent:
+ node.location.x -= center_x
+ node.location.y += -center_y
classes = [
- NA_PT_NodePanel,
- NA_OT_NodeButton,
- NA_OT_NodeButtonOdd,
- NA_OT_NodeButtonCenter,
- NA_OT_ArrangeNodesOp,
+ NA_PT_NodePanel,
+ NA_OT_NodeButton,
+ NA_OT_NodeButtonOdd,
+ NA_OT_NodeButtonCenter,
+ NA_OT_ArrangeNodesOp,
NA_OT_AlignNodes
]
def register():
- for c in classes:
- bpy.utils.register_class(c)
+ for c in classes:
+ bpy.utils.register_class(c)
- bpy.types.Scene.nodemargin_x = bpy.props.IntProperty(default=100, update=nodemargin)
- bpy.types.Scene.nodemargin_y = bpy.props.IntProperty(default=20, update=nodemargin)
- bpy.types.Scene.node_center = bpy.props.BoolProperty(default=True, update=nodemargin)
+ bpy.types.Scene.nodemargin_x = bpy.props.IntProperty(default=100, update=nodemargin)
+ bpy.types.Scene.nodemargin_y = bpy.props.IntProperty(default=20, update=nodemargin)
+ bpy.types.Scene.node_center = bpy.props.BoolProperty(default=True, update=nodemargin)
def unregister():
- for c in classes:
- bpy.utils.unregister_class(c)
+ for c in classes:
+ bpy.utils.unregister_class(c)
- del bpy.types.Scene.nodemargin_x
- del bpy.types.Scene.nodemargin_y
- del bpy.types.Scene.node_center
+ del bpy.types.Scene.nodemargin_x
+ del bpy.types.Scene.nodemargin_y
+ del bpy.types.Scene.node_center
if __name__ == "__main__":
- register()
+ register()
diff --git a/object_carver/__init__.py b/object_carver/__init__.py
index 4c68ce0b..883d5b76 100644
--- a/object_carver/__init__.py
+++ b/object_carver/__init__.py
@@ -17,18 +17,18 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- "name": "Carver",
- "author": "Pixivore, Cedric LEPILLER, Ted Milker, Clarkx",
- "description": "Multiple tools to carve or to create objects",
- "version": (1, 2, 0),
- "blender": (2, 80, 0),
- "location": "3D View > Ctrl/Shift/x",
- "warning": "",
+ "name": "Carver",
+ "author": "Pixivore, Cedric LEPILLER, Ted Milker, Clarkx",
+ "description": "Multiple tools to carve or to create objects",
+ "version": (1, 2, 0),
+ "blender": (2, 80, 0),
+ "location": "3D View > Ctrl/Shift/x",
+ "warning": "",
"doc_url": "https://docs.blender.org/manual/en/dev/addons/"
"object/carver.html",
- "support": 'COMMUNITY',
- "category": "Object"
- }
+ "support": 'COMMUNITY',
+ "category": "Object"
+ }
import bpy
import imp
@@ -61,249 +61,249 @@ imp.reload(carver_operator)
# "or to create objects"
# )
#
-# #Icons : \blender-2.80\2.80\datafiles\icons
-# #Todo: Create a new icon for Carver
+# #Icons : \blender-2.80\2.80\datafiles\icons
+# #Todo: Create a new icon for Carver
# bl_icon = "ops.mesh.knife_tool"
# bl_widget = None
# bl_keymap = (
# ("carver.operator", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
-# )
+# )
#
# def draw_settings(context, layout, tool):
# layout.prop(tool.operator_properties, "carver")
class CarverPreferences(AddonPreferences):
- bl_idname = __name__
+ bl_idname = __name__
- Enable_Tab_01: BoolProperty(
- name="Info",
- description="Some general information and settings about the add-on",
- default=False
- )
- Enable_Tab_02: BoolProperty(
- name="Hotkeys",
- description="List of the shortcuts used during carving",
- default=False
- )
- Key_Create: StringProperty(
- name="Object creation",
- description="Object creation",
- maxlen=1,
- default="C"
- )
- Key_Update: StringProperty(
- name="Auto Bevel Update",
- description="Auto Bevel Update",
- maxlen=1,
- default="A",
- )
- Key_Bool: StringProperty(
- name="Boolean type",
- description="Boolean operation type",
- maxlen=1,
- default="T",
- )
- Key_Brush: StringProperty(
- name="Brush Mode",
- description="Brush Mode",
- maxlen=1,
- default="B",
- )
- Key_Help: StringProperty(
- name="Help display",
- description="Help display",
- maxlen=1,
- default="H",
- )
- Key_Instant: StringProperty(
- name="Instantiate",
- description="Instantiate object",
- maxlen=1,
- default="I",
- )
- Key_Close: StringProperty(
- name="Close polygonal shape",
- description="Close polygonal shape",
- maxlen=1,
- default="X",
- )
- Key_Apply: StringProperty(
- name="Apply operation",
- description="Apply operation",
- maxlen=1,
- default="Q",
- )
- Key_Scale: StringProperty(
- name="Scale object",
- description="Scale object",
- maxlen=1,
- default="S",
- )
- Key_Gapy: StringProperty(
- name="Gap rows",
- description="Scale gap between columns",
- maxlen=1,
- default="J",
- )
- Key_Gapx: StringProperty(
- name="Gap columns",
- description="Scale gap between columns",
- maxlen=1,
- default="U",
- )
- Key_Depth: StringProperty(
- name="Depth",
- description="Cursor depth or solidify pattern",
- maxlen=1,
- default="D",
- )
- Key_BrushDepth: StringProperty(
- name="Brush Depth",
- description="Brush depth",
- maxlen=1,
- default="C",
- )
- Key_Subadd: StringProperty(
- name="Add subdivision",
- description="Add subdivision",
- maxlen=1,
- default="X",
- )
- Key_Subrem: StringProperty(
- name="Remove subdivision",
- description="Remove subdivision",
- maxlen=1,
- default="W",
- )
- Key_Randrot: StringProperty(
- name="Random rotation",
- description="Random rotation",
- maxlen=1,
- default="R",
- )
- ProfilePrefix: StringProperty(
- name="Profile prefix",
- description="Prefix to look for profiles with",
- default="Carver_Profile-",
- )
- LineWidth: IntProperty(
- name="Line Width",
- description="Thickness of the drawing lines",
- default=1,
- )
- Key_Snap: StringProperty(
- name="Grid Snap",
- description="Grid Snap",
- maxlen=1,
- default="G",
- )
+ Enable_Tab_01: BoolProperty(
+ name="Info",
+ description="Some general information and settings about the add-on",
+ default=False
+ )
+ Enable_Tab_02: BoolProperty(
+ name="Hotkeys",
+ description="List of the shortcuts used during carving",
+ default=False
+ )
+ Key_Create: StringProperty(
+ name="Object creation",
+ description="Object creation",
+ maxlen=1,
+ default="C"
+ )
+ Key_Update: StringProperty(
+ name="Auto Bevel Update",
+ description="Auto Bevel Update",
+ maxlen=1,
+ default="A",
+ )
+ Key_Bool: StringProperty(
+ name="Boolean type",
+ description="Boolean operation type",
+ maxlen=1,
+ default="T",
+ )
+ Key_Brush: StringProperty(
+ name="Brush Mode",
+ description="Brush Mode",
+ maxlen=1,
+ default="B",
+ )
+ Key_Help: StringProperty(
+ name="Help display",
+ description="Help display",
+ maxlen=1,
+ default="H",
+ )
+ Key_Instant: StringProperty(
+ name="Instantiate",
+ description="Instantiate object",
+ maxlen=1,
+ default="I",
+ )
+ Key_Close: StringProperty(
+ name="Close polygonal shape",
+ description="Close polygonal shape",
+ maxlen=1,
+ default="X",
+ )
+ Key_Apply: StringProperty(
+ name="Apply operation",
+ description="Apply operation",
+ maxlen=1,
+ default="Q",
+ )
+ Key_Scale: StringProperty(
+ name="Scale object",
+ description="Scale object",
+ maxlen=1,
+ default="S",
+ )
+ Key_Gapy: StringProperty(
+ name="Gap rows",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="J",
+ )
+ Key_Gapx: StringProperty(
+ name="Gap columns",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="U",
+ )
+ Key_Depth: StringProperty(
+ name="Depth",
+ description="Cursor depth or solidify pattern",
+ maxlen=1,
+ default="D",
+ )
+ Key_BrushDepth: StringProperty(
+ name="Brush Depth",
+ description="Brush depth",
+ maxlen=1,
+ default="C",
+ )
+ Key_Subadd: StringProperty(
+ name="Add subdivision",
+ description="Add subdivision",
+ maxlen=1,
+ default="X",
+ )
+ Key_Subrem: StringProperty(
+ name="Remove subdivision",
+ description="Remove subdivision",
+ maxlen=1,
+ default="W",
+ )
+ Key_Randrot: StringProperty(
+ name="Random rotation",
+ description="Random rotation",
+ maxlen=1,
+ default="R",
+ )
+ ProfilePrefix: StringProperty(
+ name="Profile prefix",
+ description="Prefix to look for profiles with",
+ default="Carver_Profile-",
+ )
+ LineWidth: IntProperty(
+ name="Line Width",
+ description="Thickness of the drawing lines",
+ default=1,
+ )
+ Key_Snap: StringProperty(
+ name="Grid Snap",
+ description="Grid Snap",
+ maxlen=1,
+ default="G",
+ )
- def draw(self, context):
- scene = context.scene
- layout = self.layout
+ def draw(self, context):
+ scene = context.scene
+ layout = self.layout
- icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
- box = layout.box()
+ icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
+ box = layout.box()
- box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
- if self.Enable_Tab_01:
- box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
- box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
- icon="LAYER_USED")
- box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
- icon="LAYER_USED")
- box.prop(self, "ProfilePrefix", text="Profile prefix")
- row = box.row(align=True)
- row.label(text="Line width:")
- row.prop(self, "LineWidth", text="")
+ box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
+ if self.Enable_Tab_01:
+ box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
+ box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
+ icon="LAYER_USED")
+ box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
+ icon="LAYER_USED")
+ box.prop(self, "ProfilePrefix", text="Profile prefix")
+ row = box.row(align=True)
+ row.label(text="Line width:")
+ row.prop(self, "LineWidth", text="")
- icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
- box = layout.box()
- box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
- if self.Enable_Tab_02:
- split = box.split(align=True)
- box = split.box()
- col = box.column(align=True)
- col.label(text="Object Creation:")
- col.prop(self, "Key_Create", text="")
- col.label(text="Auto bevel update:")
- col.prop(self, "Key_Update", text="")
- col.label(text="Boolean operation type:")
- col.prop(self, "Key_Bool", text="")
- col.label(text="Brush Depth:")
- col.prop(self, "Key_BrushDepth", text="")
+ icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
+ box = layout.box()
+ box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
+ if self.Enable_Tab_02:
+ split = box.split(align=True)
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Object Creation:")
+ col.prop(self, "Key_Create", text="")
+ col.label(text="Auto bevel update:")
+ col.prop(self, "Key_Update", text="")
+ col.label(text="Boolean operation type:")
+ col.prop(self, "Key_Bool", text="")
+ col.label(text="Brush Depth:")
+ col.prop(self, "Key_BrushDepth", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Brush Mode:")
- col.prop(self, "Key_Brush", text="")
- col.label(text="Help display:")
- col.prop(self, "Key_Help", text="")
- col.label(text="Instantiate object:")
- col.prop(self, "Key_Instant", text="")
- col.label(text="Random rotation:")
- col.prop(self, "Key_Randrot", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Brush Mode:")
+ col.prop(self, "Key_Brush", text="")
+ col.label(text="Help display:")
+ col.prop(self, "Key_Help", text="")
+ col.label(text="Instantiate object:")
+ col.prop(self, "Key_Instant", text="")
+ col.label(text="Random rotation:")
+ col.prop(self, "Key_Randrot", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Close polygonal shape:")
- col.prop(self, "Key_Close", text="")
- col.label(text="Apply operation:")
- col.prop(self, "Key_Apply", text="")
- col.label(text="Scale object:")
- col.prop(self, "Key_Scale", text="")
- col.label(text="Subdiv add:")
- col.prop(self, "Key_Subadd", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Close polygonal shape:")
+ col.prop(self, "Key_Close", text="")
+ col.label(text="Apply operation:")
+ col.prop(self, "Key_Apply", text="")
+ col.label(text="Scale object:")
+ col.prop(self, "Key_Scale", text="")
+ col.label(text="Subdiv add:")
+ col.prop(self, "Key_Subadd", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Gap rows:")
- col.prop(self, "Key_Gapy", text="")
- col.label(text="Gap columns:")
- col.prop(self, "Key_Gapx", text="")
- col.label(text="Depth / Solidify:")
- col.prop(self, "Key_Depth", text="")
- col.label(text="Subdiv Remove:")
- col.prop(self, "Key_Subrem", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Gap rows:")
+ col.prop(self, "Key_Gapy", text="")
+ col.label(text="Gap columns:")
+ col.prop(self, "Key_Gapx", text="")
+ col.label(text="Depth / Solidify:")
+ col.prop(self, "Key_Depth", text="")
+ col.label(text="Subdiv Remove:")
+ col.prop(self, "Key_Subrem", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Grid Snap:")
- col.prop(self, "Key_Snap", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Grid Snap:")
+ col.prop(self, "Key_Snap", text="")
addon_keymaps = []
def register():
- print("Registered Carver")
+ print("Registered Carver")
- bpy.utils.register_class(CarverPreferences)
- # Todo : Add an icon in the toolbat
- # bpy.utils.register_tool(CarverTool, separator=True, group=True)
- carver_operator.register()
+ bpy.utils.register_class(CarverPreferences)
+ # Todo : Add an icon in the toolbat
+ # bpy.utils.register_tool(CarverTool, separator=True, group=True)
+ carver_operator.register()
- # add keymap entry
- kcfg = bpy.context.window_manager.keyconfigs.addon
- if kcfg:
- km = kcfg.keymaps.new(name='3D View', space_type='VIEW_3D')
- kmi = km.keymap_items.new("carver.operator", 'X', 'PRESS', shift=True, ctrl=True)
- addon_keymaps.append((km, kmi))
+ # add keymap entry
+ kcfg = bpy.context.window_manager.keyconfigs.addon
+ if kcfg:
+ km = kcfg.keymaps.new(name='3D View', space_type='VIEW_3D')
+ kmi = km.keymap_items.new("carver.operator", 'X', 'PRESS', shift=True, ctrl=True)
+ addon_keymaps.append((km, kmi))
def unregister():
- # Todo : Add an icon in the toolbat
- # bpy.utils.unregister_tool(CarverTool)
- carver_operator.unregister()
- bpy.utils.unregister_class(CarverPreferences)
+ # Todo : Add an icon in the toolbat
+ # bpy.utils.unregister_tool(CarverTool)
+ carver_operator.unregister()
+ bpy.utils.unregister_class(CarverPreferences)
- print("Unregistered Carver")
+ print("Unregistered Carver")
- # remove keymap entry
- for km, kmi in addon_keymaps:
- km.keymap_items.remove(kmi)
- addon_keymaps.clear()
+ # remove keymap entry
+ for km, kmi in addon_keymaps:
+ km.keymap_items.remove(kmi)
+ addon_keymaps.clear()
if __name__ == "__main__":
- register()
+ register()
diff --git a/object_carver/carver_draw.py b/object_carver/carver_draw.py
index 922807ee..f2a3aadc 100644
--- a/object_carver/carver_draw.py
+++ b/object_carver/carver_draw.py
@@ -6,494 +6,494 @@ import numpy as np
import gpu
from gpu_extras.batch import batch_for_shader
from math import(
- cos,
- sin,
- ceil,
- floor,
- )
+ cos,
+ sin,
+ ceil,
+ floor,
+ )
from bpy_extras.view3d_utils import (
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
from .carver_utils import (
- draw_circle,
- draw_shader,
- objDiagonal,
- mini_grid,
- )
+ draw_circle,
+ draw_shader,
+ objDiagonal,
+ mini_grid,
+ )
from mathutils import (
- Color,
- Euler,
- Vector,
- Quaternion,
+ Color,
+ Euler,
+ Vector,
+ Quaternion,
)
def get_text_info(self, context, help_txt):
- """ Return the dimensions of each part of the text """
+ """ Return the dimensions of each part of the text """
- #Extract the longest first option in sublist
- max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
+ #Extract the longest first option in sublist
+ max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
- #Extract the longest key in sublist
- max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
+ #Extract the longest key in sublist
+ max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
- #Space between option and key with a comma separator (" : ")
- comma = blf.dimensions(0, "_:_")[0]
+ #Space between option and key with a comma separator (" : ")
+ comma = blf.dimensions(0, "_:_")[0]
- #Get a default height for all the letters
- line_height = (blf.dimensions(0, "gM")[1] * 1.45)
+ #Get a default height for all the letters
+ line_height = (blf.dimensions(0, "gM")[1] * 1.45)
- #Get the total height of the text
- bloc_height = 0
- for row in help_txt:
- bloc_height += line_height
+ #Get the total height of the text
+ bloc_height = 0
+ for row in help_txt:
+ bloc_height += line_height
- return(help_txt, bloc_height, max_option, max_key, comma)
+ return(help_txt, bloc_height, max_option, max_key, comma)
def draw_string(self, color1, color2, left, bottom, text, max_option, divide = 1):
- """ Draw the text like 'option : key' or just 'option' """
-
- font_id = 0
- ui_scale = bpy.context.preferences.system.ui_scale
-
- blf.enable(font_id,blf.SHADOW)
- blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
- blf.shadow_offset(font_id,2,-2)
- line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
- y_offset = 5
-
- # Test if the text is a list formatted like : ('option', 'key')
- if isinstance(text,list):
- spacer_text = " : "
- spacer_width = blf.dimensions(font_id, spacer_text)[0]
- for string in text:
- blf.position(font_id, (left), (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, string[0])
- blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
- blf.draw(font_id, spacer_text)
- blf.color(font_id, *color2)
- blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
- blf.draw(font_id, string[1])
- y_offset += line_height
- else:
- # The text is formatted like : ('option')
- blf.position(font_id, left, (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, text)
- y_offset += line_height
-
- blf.disable(font_id,blf.SHADOW)
+ """ Draw the text like 'option : key' or just 'option' """
+
+ font_id = 0
+ ui_scale = bpy.context.preferences.system.ui_scale
+
+ blf.enable(font_id,blf.SHADOW)
+ blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
+ blf.shadow_offset(font_id,2,-2)
+ line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
+ y_offset = 5
+
+ # Test if the text is a list formatted like : ('option', 'key')
+ if isinstance(text,list):
+ spacer_text = " : "
+ spacer_width = blf.dimensions(font_id, spacer_text)[0]
+ for string in text:
+ blf.position(font_id, (left), (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, string[0])
+ blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
+ blf.draw(font_id, spacer_text)
+ blf.color(font_id, *color2)
+ blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
+ blf.draw(font_id, string[1])
+ y_offset += line_height
+ else:
+ # The text is formatted like : ('option')
+ blf.position(font_id, left, (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, text)
+ y_offset += line_height
+
+ blf.disable(font_id,blf.SHADOW)
# Opengl draw on screen
def draw_callback_px(self, context):
- font_id = 0
- region = context.region
- UIColor = (0.992, 0.5518, 0.0, 1.0)
-
- # Cut Type
- RECTANGLE = 0
- LINE = 1
- CIRCLE = 2
- self.carver_prefs = context.preferences.addons[__package__].preferences
-
- # Color
- color1 = (1.0, 1.0, 1.0, 1.0)
- color2 = UIColor
-
- #The mouse is outside the active region
- if not self.in_view_3d:
- color1 = color2 = (1.0, 0.2, 0.1, 1.0)
-
- # Primitives type
- PrimitiveType = "Rectangle"
- if self.CutType == CIRCLE:
- PrimitiveType = "Circle"
- if self.CutType == LINE:
- PrimitiveType = "Line"
-
- # Width screen
- overlap = context.preferences.system.use_region_overlap
-
- t_panel_width = 0
- if overlap:
- for region in context.area.regions:
- if region.type == 'TOOLS':
- t_panel_width = region.width
-
- # Initial position
- region_width = int(region.width / 2.0)
- y_txt = 10
-
-
- # Draw the center command from bottom to top
-
- # Get the size of the text
- text_size = 18 if region.width >= 850 else 12
- ui_scale = bpy.context.preferences.system.ui_scale
- blf.size(0, round(text_size * ui_scale), 72)
-
- # Help Display
- if (self.ObjectMode is False) and (self.ProfileMode is False):
-
- # Depth Cursor
- TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = "(ON)" if self.snapCursor else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Close poygonal shape
- if self.CreateMode and self.CutType == LINE:
- TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
- BoolStr = "(ON)" if self.Closed else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode is False:
- # Apply Booleans
- TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
- BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
- help_txt += [[TypeStr, BoolStr]]
-
- #Auto update for bevel
- TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
- BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Circle subdivisions
- if self.CutType == CIRCLE:
- TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
- BoolStr = str((int(360 / self.stepAngle[self.step])))
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode:
- help_txt += [["Type [Space]", PrimitiveType]]
- else:
- help_txt += [["Cut Type [Space]", PrimitiveType]]
-
- else:
- # Instantiate
- TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
- BoolStr = "(ON)" if self.Instantiate else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Random rotation
- if self.alt:
- TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
- BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Thickness
- if self.BrushSolidify:
- TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
- if self.ProfileMode:
- BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- if self.ObjectMode:
- BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- # Brush depth
- if (self.ObjectMode):
- TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
- BoolStr = str(round(self.BrushDepthOffset, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- xCmd = region_width - (max_option + max_key + comma) / 2
- draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
-
-
- # Separator (Line)
- LineWidth = (max_option + max_key + comma) / 2
- if region.width >= 850:
- LineWidth = 140
-
- LineWidth = (max_option + max_key + comma)
- coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
- (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
- draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
-
- # Command Display
- if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
- BooleanMode = "Create"
- else:
- if self.ObjectMode or self.ProfileMode:
- BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
- BooleanMode = \
- "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
- else:
- BooleanMode = \
- "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
-
- # Display boolean mode
- text_size = 40 if region.width >= 850 else 20
- blf.size(0, round(text_size * ui_scale), 72)
-
- draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
- y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
-
- if region.width >= 850:
-
- if self.AskHelp is False:
- # "H for Help" text
- blf.size(0, round(13 * ui_scale), 72)
- help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
- txt_width = blf.dimensions(0, help_txt)[0]
- txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
-
- # Draw a rectangle and put the text "H for Help"
- xrect = 40
- yrect = 40
- rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
- (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
- draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
-
- else:
- #Draw the help text
- xHelp = 30 + t_panel_width
- yHelp = 10
-
- if self.ObjectMode or self.ProfileMode:
- if self.ProfileMode:
- help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
- else:
- help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
-
- else:
- help_txt =[
- ["Profil Brush", self.carver_prefs.Key_Brush],\
- ["Move Cursor", "Ctrl + LMB"]
- ]
-
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- if self.CreateMode is False:
- help_txt +=[
- ["Create geometry", self.carver_prefs.Key_Create],\
- ]
- else:
- help_txt +=[
- ["Cut", self.carver_prefs.Key_Create],\
- ]
- if self.CutMode == RECTANGLE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "LMB"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == CIRCLE:
- help_txt +=[
- ["Rotation and Radius", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
- ["Incremental rotation", "Ctrl"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == LINE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "Space"],\
- ["Rebool", "Shift"],\
- ["Snap", "Ctrl"],\
- ["Scale Snap", "WheelMouse"],\
- ]
- else:
- # ObjectMode
- help_txt +=[
- ["Difference", "Space"],\
- ["Rebool", "Shift + Space"],\
- ["Duplicate", "Alt + Space"],\
- ["Scale", self.carver_prefs.Key_Scale],\
- ["Rotation", "LMB + Move"],\
- ["Step Angle", "CTRL + LMB + Move"],\
- ]
-
- if self.ProfileMode:
- help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
-
- help_txt +=[
- ["Create / Delete rows", chr(8597)],\
- ["Create / Delete cols", chr(8596)],\
- ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
- ]
-
- blf.size(0, round(15 * ui_scale), 72)
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
-
- if self.ProfileMode:
- xrect = region.width - t_panel_width - 80
- yrect = 80
- coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
-
- # Draw rectangle background in the lower right
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Use numpy to get the vertices and indices of the profile object to draw
- WidthProfil = 50
- location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
- ProfilScale = 20.0
- coords = []
- mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
- mesh.calc_loop_triangles()
- vertices = np.empty((len(mesh.vertices), 3), 'f')
- indices = np.empty((len(mesh.loop_triangles), 3), 'i')
- mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
- mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
-
- for idx, vals in enumerate(vertices):
- coords.append([
- vals[0] * ProfilScale + location.x,
- vals[1] * ProfilScale + location.y,
- vals[2] * ProfilScale + location.z
- ])
-
- #Draw the silhouette of the mesh
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
-
- if self.CutMode:
-
- if len(self.mouse_path) > 1:
- x0 = self.mouse_path[0][0]
- y0 = self.mouse_path[0][1]
- x1 = self.mouse_path[1][0]
- y1 = self.mouse_path[1][1]
-
- # Cut rectangle
- if self.CutType == RECTANGLE:
- coords = [
- (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
- (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
- ]
- indices = ((0, 1, 2), (2, 0, 3))
-
- self.rectangle_coord = coords
-
- draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
-
- #Draw points
- draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Cut Line
- elif self.CutType == LINE:
- coords = []
- indices = []
- top_grid = False
-
- for idx, vals in enumerate(self.mouse_path):
- coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
- indices.append([idx])
-
- # Draw lines
- if self.Closed:
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
- else:
- draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
-
- # Draw points
- draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
-
- # Draw polygon
- if (self.shift) or (self.CreateMode and self.Closed):
- draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Circle Cut
- elif self.CutType == CIRCLE:
- # Create a circle using a tri fan
- tris_coords, indices = draw_circle(self, x0, y0)
-
- # Remove the vertex in the center to get the outer line of the circle
- line_coords = tris_coords[1:]
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
- if self.ShowCursor:
- region = context.region
- rv3d = context.space_data.region_3d
-
- if self.ObjectMode:
- ob = self.ObjectBrush
- if self.ProfileMode:
- ob = self.ProfileBrush
- mat = ob.matrix_world
-
- # 50% alpha, 2 pixel width line
- bgl.glEnable(bgl.GL_BLEND)
-
- bbox = [mat @ Vector(b) for b in ob.bound_box]
- objBBDiagonal = objDiagonal(self.CurrentSelection[0])
-
- if self.shift:
- gl_size = 4
- UIColor = (0.5, 1.0, 0.0, 1.0)
- else:
- gl_size = 2
- UIColor = (1.0, 0.8, 0.0, 1.0)
-
- line_coords = []
- idx = 0
- CRadius = ((bbox[7] - bbox[0]).length) / 2
- for i in range(int(len(self.CLR_C) / 3)):
- vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
- self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
- self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
- vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
- if vector2d is not None:
- line_coords.append((vector2d[0], vector2d[1]))
- idx += 1
- if len(line_coords) > 0 :
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
-
- # Object display
- if self.quat_rot is not None:
- ob.location = self.CurLoc
- v = Vector()
- v.x = v.y = 0.0
- v.z = self.BrushDepthOffset
- ob.location += self.quat_rot @ v
-
- e = Euler()
- e.x = 0.0
- e.y = 0.0
- e.z = self.aRotZ / 25.0
-
- qe = e.to_quaternion()
- qRot = self.quat_rot @ qe
- ob.rotation_mode = 'QUATERNION'
- ob.rotation_quaternion = qRot
- ob.rotation_mode = 'XYZ'
-
- if self.ProfileMode:
- if self.ProfileBrush is not None:
- self.ProfileBrush.location = self.CurLoc
- self.ProfileBrush.rotation_mode = 'QUATERNION'
- self.ProfileBrush.rotation_quaternion = qRot
- self.ProfileBrush.rotation_mode = 'XYZ'
-
- # Opengl defaults
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
+ font_id = 0
+ region = context.region
+ UIColor = (0.992, 0.5518, 0.0, 1.0)
+
+ # Cut Type
+ RECTANGLE = 0
+ LINE = 1
+ CIRCLE = 2
+ self.carver_prefs = context.preferences.addons[__package__].preferences
+
+ # Color
+ color1 = (1.0, 1.0, 1.0, 1.0)
+ color2 = UIColor
+
+ #The mouse is outside the active region
+ if not self.in_view_3d:
+ color1 = color2 = (1.0, 0.2, 0.1, 1.0)
+
+ # Primitives type
+ PrimitiveType = "Rectangle"
+ if self.CutType == CIRCLE:
+ PrimitiveType = "Circle"
+ if self.CutType == LINE:
+ PrimitiveType = "Line"
+
+ # Width screen
+ overlap = context.preferences.system.use_region_overlap
+
+ t_panel_width = 0
+ if overlap:
+ for region in context.area.regions:
+ if region.type == 'TOOLS':
+ t_panel_width = region.width
+
+ # Initial position
+ region_width = int(region.width / 2.0)
+ y_txt = 10
+
+
+ # Draw the center command from bottom to top
+
+ # Get the size of the text
+ text_size = 18 if region.width >= 850 else 12
+ ui_scale = bpy.context.preferences.system.ui_scale
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ # Help Display
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+
+ # Depth Cursor
+ TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = "(ON)" if self.snapCursor else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Close poygonal shape
+ if self.CreateMode and self.CutType == LINE:
+ TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
+ BoolStr = "(ON)" if self.Closed else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode is False:
+ # Apply Booleans
+ TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
+ BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ #Auto update for bevel
+ TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
+ BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Circle subdivisions
+ if self.CutType == CIRCLE:
+ TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
+ BoolStr = str((int(360 / self.stepAngle[self.step])))
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode:
+ help_txt += [["Type [Space]", PrimitiveType]]
+ else:
+ help_txt += [["Cut Type [Space]", PrimitiveType]]
+
+ else:
+ # Instantiate
+ TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
+ BoolStr = "(ON)" if self.Instantiate else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Random rotation
+ if self.alt:
+ TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
+ BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Thickness
+ if self.BrushSolidify:
+ TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
+ if self.ProfileMode:
+ BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ if self.ObjectMode:
+ BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Brush depth
+ if (self.ObjectMode):
+ TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
+ BoolStr = str(round(self.BrushDepthOffset, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ xCmd = region_width - (max_option + max_key + comma) / 2
+ draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
+
+
+ # Separator (Line)
+ LineWidth = (max_option + max_key + comma) / 2
+ if region.width >= 850:
+ LineWidth = 140
+
+ LineWidth = (max_option + max_key + comma)
+ coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
+ (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
+ draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
+
+ # Command Display
+ if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
+ BooleanMode = "Create"
+ else:
+ if self.ObjectMode or self.ProfileMode:
+ BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
+ BooleanMode = \
+ "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
+ else:
+ BooleanMode = \
+ "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
+
+ # Display boolean mode
+ text_size = 40 if region.width >= 850 else 20
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
+ y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
+
+ if region.width >= 850:
+
+ if self.AskHelp is False:
+ # "H for Help" text
+ blf.size(0, round(13 * ui_scale), 72)
+ help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
+ txt_width = blf.dimensions(0, help_txt)[0]
+ txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
+
+ # Draw a rectangle and put the text "H for Help"
+ xrect = 40
+ yrect = 40
+ rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
+ (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
+ draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
+
+ else:
+ #Draw the help text
+ xHelp = 30 + t_panel_width
+ yHelp = 10
+
+ if self.ObjectMode or self.ProfileMode:
+ if self.ProfileMode:
+ help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
+ else:
+ help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
+
+ else:
+ help_txt =[
+ ["Profil Brush", self.carver_prefs.Key_Brush],\
+ ["Move Cursor", "Ctrl + LMB"]
+ ]
+
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ if self.CreateMode is False:
+ help_txt +=[
+ ["Create geometry", self.carver_prefs.Key_Create],\
+ ]
+ else:
+ help_txt +=[
+ ["Cut", self.carver_prefs.Key_Create],\
+ ]
+ if self.CutMode == RECTANGLE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "LMB"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == CIRCLE:
+ help_txt +=[
+ ["Rotation and Radius", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
+ ["Incremental rotation", "Ctrl"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == LINE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "Space"],\
+ ["Rebool", "Shift"],\
+ ["Snap", "Ctrl"],\
+ ["Scale Snap", "WheelMouse"],\
+ ]
+ else:
+ # ObjectMode
+ help_txt +=[
+ ["Difference", "Space"],\
+ ["Rebool", "Shift + Space"],\
+ ["Duplicate", "Alt + Space"],\
+ ["Scale", self.carver_prefs.Key_Scale],\
+ ["Rotation", "LMB + Move"],\
+ ["Step Angle", "CTRL + LMB + Move"],\
+ ]
+
+ if self.ProfileMode:
+ help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
+
+ help_txt +=[
+ ["Create / Delete rows", chr(8597)],\
+ ["Create / Delete cols", chr(8596)],\
+ ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
+ ]
+
+ blf.size(0, round(15 * ui_scale), 72)
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
+
+ if self.ProfileMode:
+ xrect = region.width - t_panel_width - 80
+ yrect = 80
+ coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
+
+ # Draw rectangle background in the lower right
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Use numpy to get the vertices and indices of the profile object to draw
+ WidthProfil = 50
+ location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
+ ProfilScale = 20.0
+ coords = []
+ mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
+ mesh.calc_loop_triangles()
+ vertices = np.empty((len(mesh.vertices), 3), 'f')
+ indices = np.empty((len(mesh.loop_triangles), 3), 'i')
+ mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
+ mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
+
+ for idx, vals in enumerate(vertices):
+ coords.append([
+ vals[0] * ProfilScale + location.x,
+ vals[1] * ProfilScale + location.y,
+ vals[2] * ProfilScale + location.z
+ ])
+
+ #Draw the silhouette of the mesh
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+
+ if self.CutMode:
+
+ if len(self.mouse_path) > 1:
+ x0 = self.mouse_path[0][0]
+ y0 = self.mouse_path[0][1]
+ x1 = self.mouse_path[1][0]
+ y1 = self.mouse_path[1][1]
+
+ # Cut rectangle
+ if self.CutType == RECTANGLE:
+ coords = [
+ (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
+ (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
+ ]
+ indices = ((0, 1, 2), (2, 0, 3))
+
+ self.rectangle_coord = coords
+
+ draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+
+ #Draw points
+ draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Cut Line
+ elif self.CutType == LINE:
+ coords = []
+ indices = []
+ top_grid = False
+
+ for idx, vals in enumerate(self.mouse_path):
+ coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
+ indices.append([idx])
+
+ # Draw lines
+ if self.Closed:
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+ else:
+ draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw points
+ draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
+
+ # Draw polygon
+ if (self.shift) or (self.CreateMode and self.Closed):
+ draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Circle Cut
+ elif self.CutType == CIRCLE:
+ # Create a circle using a tri fan
+ tris_coords, indices = draw_circle(self, x0, y0)
+
+ # Remove the vertex in the center to get the outer line of the circle
+ line_coords = tris_coords[1:]
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
+ if self.ShowCursor:
+ region = context.region
+ rv3d = context.space_data.region_3d
+
+ if self.ObjectMode:
+ ob = self.ObjectBrush
+ if self.ProfileMode:
+ ob = self.ProfileBrush
+ mat = ob.matrix_world
+
+ # 50% alpha, 2 pixel width line
+ bgl.glEnable(bgl.GL_BLEND)
+
+ bbox = [mat @ Vector(b) for b in ob.bound_box]
+ objBBDiagonal = objDiagonal(self.CurrentSelection[0])
+
+ if self.shift:
+ gl_size = 4
+ UIColor = (0.5, 1.0, 0.0, 1.0)
+ else:
+ gl_size = 2
+ UIColor = (1.0, 0.8, 0.0, 1.0)
+
+ line_coords = []
+ idx = 0
+ CRadius = ((bbox[7] - bbox[0]).length) / 2
+ for i in range(int(len(self.CLR_C) / 3)):
+ vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
+ self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
+ self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
+ vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
+ if vector2d is not None:
+ line_coords.append((vector2d[0], vector2d[1]))
+ idx += 1
+ if len(line_coords) > 0 :
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
+
+ # Object display
+ if self.quat_rot is not None:
+ ob.location = self.CurLoc
+ v = Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob.location += self.quat_rot @ v
+
+ e = Euler()
+ e.x = 0.0
+ e.y = 0.0
+ e.z = self.aRotZ / 25.0
+
+ qe = e.to_quaternion()
+ qRot = self.quat_rot @ qe
+ ob.rotation_mode = 'QUATERNION'
+ ob.rotation_quaternion = qRot
+ ob.rotation_mode = 'XYZ'
+
+ if self.ProfileMode:
+ if self.ProfileBrush is not None:
+ self.ProfileBrush.location = self.CurLoc
+ self.ProfileBrush.rotation_mode = 'QUATERNION'
+ self.ProfileBrush.rotation_quaternion = qRot
+ self.ProfileBrush.rotation_mode = 'XYZ'
+
+ # Opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)
diff --git a/object_carver/carver_operator.py b/object_carver/carver_operator.py
index c75a5ab7..95fa4af0 100644
--- a/object_carver/carver_operator.py
+++ b/object_carver/carver_operator.py
@@ -2,340 +2,340 @@ import bpy
import bpy_extras
import sys
from bpy.props import (
- BoolProperty,
- IntProperty,
- PointerProperty,
- StringProperty,
- EnumProperty,
- )
+ BoolProperty,
+ IntProperty,
+ PointerProperty,
+ StringProperty,
+ EnumProperty,
+ )
from mathutils import (
- Vector,
- )
+ Vector,
+ )
from bpy_extras.view3d_utils import (
- region_2d_to_vector_3d,
- region_2d_to_origin_3d,
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_vector_3d,
+ region_2d_to_origin_3d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
from .carver_profils import (
- Profils
- )
+ Profils
+ )
from .carver_utils import (
- duplicateObject,
- UndoListUpdate,
- createMeshFromData,
- SelectObject,
- Selection_Save_Restore,
- Selection_Save,
- Selection_Restore,
- update_grid,
- objDiagonal,
- Undo,
- UndoAdd,
- Pick,
- rot_axis_quat,
- MoveCursor,
- Picking,
- CreateCutSquare,
- CreateCutCircle,
- CreateCutLine,
- boolean_operation,
- update_bevel,
- CreateBevel,
- Rebool,
- Snap_Cursor,
- )
+ duplicateObject,
+ UndoListUpdate,
+ createMeshFromData,
+ SelectObject,
+ Selection_Save_Restore,
+ Selection_Save,
+ Selection_Restore,
+ update_grid,
+ objDiagonal,
+ Undo,
+ UndoAdd,
+ Pick,
+ rot_axis_quat,
+ MoveCursor,
+ Picking,
+ CreateCutSquare,
+ CreateCutCircle,
+ CreateCutLine,
+ boolean_operation,
+ update_bevel,
+ CreateBevel,
+ Rebool,
+ Snap_Cursor,
+ )
from .carver_draw import draw_callback_px
# Modal Operator
class CARVER_OT_operator(bpy.types.Operator):
- bl_idname = "carver.operator"
- bl_label = "Carver"
- bl_description = "Cut or create Meshes in Object mode"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "carver.operator"
+ bl_label = "Carver"
+ bl_description = "Cut or create Meshes in Object mode"
+ bl_options = {'REGISTER', 'UNDO'}
- def __init__(self):
- context = bpy.context
- # Carve mode: Cut, Object, Profile
- self.CutMode = False
- self.CreateMode = False
- self.ObjectMode = False
- self.ProfileMode = False
+ def __init__(self):
+ context = bpy.context
+ # Carve mode: Cut, Object, Profile
+ self.CutMode = False
+ self.CreateMode = False
+ self.ObjectMode = False
+ self.ProfileMode = False
- # Create mode
- self.ExclusiveCreateMode = False
- if len(context.selected_objects) == 0:
- self.ExclusiveCreateMode = True
- self.CreateMode = True
+ # Create mode
+ self.ExclusiveCreateMode = False
+ if len(context.selected_objects) == 0:
+ self.ExclusiveCreateMode = True
+ self.CreateMode = True
- # Cut type (Rectangle, Circle, Line)
- self.rectangle = 0
- self.line = 1
- self.circle = 2
+ # Cut type (Rectangle, Circle, Line)
+ self.rectangle = 0
+ self.line = 1
+ self.circle = 2
- # Cut Rectangle coordinates
- self.rectangle_coord = []
+ # Cut Rectangle coordinates
+ self.rectangle_coord = []
- # Selected type of cut
- self.CutType = 0
+ # Selected type of cut
+ self.CutType = 0
- # Boolean operation
- self.difference = 0
- self.union = 1
-
- self.BoolOps = self.difference
-
- self.CurrentSelection = context.selected_objects.copy()
- self.CurrentActive = context.active_object
- self.all_sel_obj_list = context.selected_objects.copy()
- self.save_active_obj = None
-
- args = (self, context)
- self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
-
- self.mouse_path = [(0, 0), (0, 0)]
-
- # Keyboard event
- self.shift = False
- self.ctrl = False
- self.alt = False
-
- self.dont_apply_boolean = context.scene.mesh_carver.DontApply
- self.Auto_BevelUpdate = True
-
- # Circle variables
- self.stepAngle = [2, 4, 5, 6, 9, 10, 15, 20, 30, 40, 45, 60, 72, 90]
- self.step = 4
-
- # Primitives Position
- self.xpos = 0
- self.ypos = 0
- self.InitPosition = False
-
- # Close polygonal shape
- self.Closed = False
-
- # Depth Cursor
- self.snapCursor = context.scene.mesh_carver.DepthCursor
-
- # Help
- self.AskHelp = False
-
- # Working object
- self.OpsObj = context.active_object
-
- # Rebool forced (cut line)
- self.ForceRebool = False
-
- self.ViewVector = Vector()
- self.CurrentObj = None
-
- # Brush
- self.BrushSolidify = False
- self.WidthSolidify = False
- self.CarveDepth = False
- self.BrushDepth = False
- self.BrushDepthOffset = 0.0
- self.snap = False
-
- self.ObjectScale = False
-
- #Init create circle primitive
- self.CLR_C = []
-
- # Cursor location
- self.CurLoc = Vector((0.0, 0.0, 0.0))
- self.SavCurLoc = Vector((0.0, 0.0, 0.0))
-
- # Mouse region
- self.mouse_region = -1, -1
- self.SavMousePos = None
- self.xSavMouse = 0
-
- # Scale, rotate object
- self.ascale = 0
- self.aRotZ = 0
- self.nRotZ = 0
- self.quat_rot_axis = None
- self.quat_rot = None
-
- self.RandomRotation = context.scene.mesh_carver.ORandom
-
- self.ShowCursor = True
-
- self.Instantiate = context.scene.mesh_carver.OInstanciate
-
- self.ProfileBrush = None
- self.ObjectBrush = None
-
- self.InitBrush = {
- 'location' : None,
- 'scale' : None,
- 'rotation_quaternion' : None,
- 'rotation_euler' : None,
- 'display_type' : 'WIRE',
- 'show_in_front' : False
- }
-
- # Array variables
- self.nbcol = 1
- self.nbrow = 1
- self.gapx = 0
- self.gapy = 0
- self.scale_x = 1
- self.scale_y = 1
- self.GridScaleX = False
- self.GridScaleY = False
-
- @classmethod
- def poll(cls, context):
- ob = None
- if len(context.selected_objects) > 0:
- ob = context.selected_objects[0]
- # Test if selected object or none (for create mode)
- return (
- (ob and ob.type == 'MESH' and context.mode == 'OBJECT') or
- (context.mode == 'OBJECT' and ob is None) or
- (context.mode == 'EDIT_MESH'))
-
- def modal(self, context, event):
- PI = 3.14156
- region_types = {'WINDOW', 'UI'}
- win = context.window
-
- # Find the limit of the view3d region
- self.check_region(context,event)
-
- for area in win.screen.areas:
- if area.type == 'VIEW_3D':
- for region in area.regions:
- if not region_types or region.type in region_types:
- region.tag_redraw()
-
- # Change the snap increment value using the wheel mouse
- if self.CutMode:
- if self.alt is False:
- if self.ctrl and (self.CutType in (self.line, self.rectangle)):
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
-
- if event.type == 'WHEELUPMOUSE':
- space.overlay.grid_subdivisions += 1
- elif event.type == 'WHEELDOWNMOUSE':
- space.overlay.grid_subdivisions -= 1
-
- if event.type in {
- 'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
- 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
- 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
- return {'PASS_THROUGH'}
-
- try:
- # [Shift]
- self.shift = True if event.shift else False
-
- # [Ctrl]
- self.ctrl = True if event.ctrl else False
-
- # [Alt]
- self.alt = False
-
- # [Alt] press : Init position variable before moving the cut brush with LMB
- if event.alt:
- if self.InitPosition is False:
- self.xpos = 0
- self.ypos = 0
- self.last_mouse_region_x = event.mouse_region_x
- self.last_mouse_region_y = event.mouse_region_y
- self.InitPosition = True
- self.alt = True
-
- # [Alt] release : update the coordinates
- if self.InitPosition and self.alt is False:
- for i in range(0, len(self.mouse_path)):
- l = list(self.mouse_path[i])
- l[0] += self.xpos
- l[1] += self.ypos
- self.mouse_path[i] = tuple(l)
-
- self.xpos = self.ypos = 0
- self.InitPosition = False
-
- if event.type == 'SPACE' and event.value == 'PRESS':
- # If object or profile mode is TRUE : Confirm the cut
- if self.ObjectMode or self.ProfileMode:
- # If array, remove double with intersect meshes
- if ((self.nbcol + self.nbrow) > 3):
- # Go in edit mode mode
- bpy.ops.object.mode_set(mode='EDIT')
- # Remove duplicate vertices
- bpy.ops.mesh.remove_doubles()
- # Return in object mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- if self.alt:
- # Save selected objects
- self.all_sel_obj_list = context.selected_objects.copy()
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- if self.ObjectMode:
- SelectObject(self, self.ObjectBrush)
- else:
- SelectObject(self, self.ProfileBrush)
- duplicateObject(self)
- else:
- # Brush Cut
- self.Cut()
- # Save selected objects
- if self.ObjectMode:
- if len(self.ObjectBrush.children) > 0:
- self.all_sel_obj_list = context.selected_objects.copy()
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- if self.ObjectMode:
- SelectObject(self, self.ObjectBrush)
- else:
- SelectObject(self, self.ProfileBrush)
- duplicateObject(self)
-
- UndoListUpdate(self)
-
- # Save cursor position
- self.SavMousePos = self.CurLoc
- else:
- if self.CutMode is False:
- # Cut Mode
- self.CutType += 1
- if self.CutType > 2:
- self.CutType = 0
- else:
- if self.CutType == self.line:
- # Cuts creation
- CreateCutLine(self, context)
- if self.CreateMode:
- # Object creation
- self.CreateGeometry()
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
- # Cursor Snap
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Object Instantiate
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
-
- return {'FINISHED'}
- else:
- self.Cut()
- UndoListUpdate(self)
+ # Boolean operation
+ self.difference = 0
+ self.union = 1
+
+ self.BoolOps = self.difference
+
+ self.CurrentSelection = context.selected_objects.copy()
+ self.CurrentActive = context.active_object
+ self.all_sel_obj_list = context.selected_objects.copy()
+ self.save_active_obj = None
+
+ args = (self, context)
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
+
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ # Keyboard event
+ self.shift = False
+ self.ctrl = False
+ self.alt = False
+
+ self.dont_apply_boolean = context.scene.mesh_carver.DontApply
+ self.Auto_BevelUpdate = True
+
+ # Circle variables
+ self.stepAngle = [2, 4, 5, 6, 9, 10, 15, 20, 30, 40, 45, 60, 72, 90]
+ self.step = 4
+
+ # Primitives Position
+ self.xpos = 0
+ self.ypos = 0
+ self.InitPosition = False
+
+ # Close polygonal shape
+ self.Closed = False
+
+ # Depth Cursor
+ self.snapCursor = context.scene.mesh_carver.DepthCursor
+
+ # Help
+ self.AskHelp = False
+
+ # Working object
+ self.OpsObj = context.active_object
+
+ # Rebool forced (cut line)
+ self.ForceRebool = False
+
+ self.ViewVector = Vector()
+ self.CurrentObj = None
+
+ # Brush
+ self.BrushSolidify = False
+ self.WidthSolidify = False
+ self.CarveDepth = False
+ self.BrushDepth = False
+ self.BrushDepthOffset = 0.0
+ self.snap = False
+
+ self.ObjectScale = False
+
+ #Init create circle primitive
+ self.CLR_C = []
+
+ # Cursor location
+ self.CurLoc = Vector((0.0, 0.0, 0.0))
+ self.SavCurLoc = Vector((0.0, 0.0, 0.0))
+
+ # Mouse region
+ self.mouse_region = -1, -1
+ self.SavMousePos = None
+ self.xSavMouse = 0
+
+ # Scale, rotate object
+ self.ascale = 0
+ self.aRotZ = 0
+ self.nRotZ = 0
+ self.quat_rot_axis = None
+ self.quat_rot = None
+
+ self.RandomRotation = context.scene.mesh_carver.ORandom
+
+ self.ShowCursor = True
+
+ self.Instantiate = context.scene.mesh_carver.OInstanciate
+
+ self.ProfileBrush = None
+ self.ObjectBrush = None
+
+ self.InitBrush = {
+ 'location' : None,
+ 'scale' : None,
+ 'rotation_quaternion' : None,
+ 'rotation_euler' : None,
+ 'display_type' : 'WIRE',
+ 'show_in_front' : False
+ }
+
+ # Array variables
+ self.nbcol = 1
+ self.nbrow = 1
+ self.gapx = 0
+ self.gapy = 0
+ self.scale_x = 1
+ self.scale_y = 1
+ self.GridScaleX = False
+ self.GridScaleY = False
+
+ @classmethod
+ def poll(cls, context):
+ ob = None
+ if len(context.selected_objects) > 0:
+ ob = context.selected_objects[0]
+ # Test if selected object or none (for create mode)
+ return (
+ (ob and ob.type == 'MESH' and context.mode == 'OBJECT') or
+ (context.mode == 'OBJECT' and ob is None) or
+ (context.mode == 'EDIT_MESH'))
+
+ def modal(self, context, event):
+ PI = 3.14156
+ region_types = {'WINDOW', 'UI'}
+ win = context.window
+
+ # Find the limit of the view3d region
+ self.check_region(context,event)
+
+ for area in win.screen.areas:
+ if area.type == 'VIEW_3D':
+ for region in area.regions:
+ if not region_types or region.type in region_types:
+ region.tag_redraw()
+
+ # Change the snap increment value using the wheel mouse
+ if self.CutMode:
+ if self.alt is False:
+ if self.ctrl and (self.CutType in (self.line, self.rectangle)):
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+
+ if event.type == 'WHEELUPMOUSE':
+ space.overlay.grid_subdivisions += 1
+ elif event.type == 'WHEELDOWNMOUSE':
+ space.overlay.grid_subdivisions -= 1
+
+ if event.type in {
+ 'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
+ 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
+ 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
+ return {'PASS_THROUGH'}
+
+ try:
+ # [Shift]
+ self.shift = True if event.shift else False
+
+ # [Ctrl]
+ self.ctrl = True if event.ctrl else False
+
+ # [Alt]
+ self.alt = False
+
+ # [Alt] press : Init position variable before moving the cut brush with LMB
+ if event.alt:
+ if self.InitPosition is False:
+ self.xpos = 0
+ self.ypos = 0
+ self.last_mouse_region_x = event.mouse_region_x
+ self.last_mouse_region_y = event.mouse_region_y
+ self.InitPosition = True
+ self.alt = True
+
+ # [Alt] release : update the coordinates
+ if self.InitPosition and self.alt is False:
+ for i in range(0, len(self.mouse_path)):
+ l = list(self.mouse_path[i])
+ l[0] += self.xpos
+ l[1] += self.ypos
+ self.mouse_path[i] = tuple(l)
+
+ self.xpos = self.ypos = 0
+ self.InitPosition = False
+
+ if event.type == 'SPACE' and event.value == 'PRESS':
+ # If object or profile mode is TRUE : Confirm the cut
+ if self.ObjectMode or self.ProfileMode:
+ # If array, remove double with intersect meshes
+ if ((self.nbcol + self.nbrow) > 3):
+ # Go in edit mode mode
+ bpy.ops.object.mode_set(mode='EDIT')
+ # Remove duplicate vertices
+ bpy.ops.mesh.remove_doubles()
+ # Return in object mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ if self.alt:
+ # Save selected objects
+ self.all_sel_obj_list = context.selected_objects.copy()
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ if self.ObjectMode:
+ SelectObject(self, self.ObjectBrush)
+ else:
+ SelectObject(self, self.ProfileBrush)
+ duplicateObject(self)
+ else:
+ # Brush Cut
+ self.Cut()
+ # Save selected objects
+ if self.ObjectMode:
+ if len(self.ObjectBrush.children) > 0:
+ self.all_sel_obj_list = context.selected_objects.copy()
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ if self.ObjectMode:
+ SelectObject(self, self.ObjectBrush)
+ else:
+ SelectObject(self, self.ProfileBrush)
+ duplicateObject(self)
+
+ UndoListUpdate(self)
+
+ # Save cursor position
+ self.SavMousePos = self.CurLoc
+ else:
+ if self.CutMode is False:
+ # Cut Mode
+ self.CutType += 1
+ if self.CutType > 2:
+ self.CutType = 0
+ else:
+ if self.CutType == self.line:
+ # Cuts creation
+ CreateCutLine(self, context)
+ if self.CreateMode:
+ # Object creation
+ self.CreateGeometry()
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ # Cursor Snap
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Object Instantiate
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+
+ return {'FINISHED'}
+ else:
+ self.Cut()
+ UndoListUpdate(self)
#-----------------------------------------------------
@@ -343,1005 +343,1005 @@ class CARVER_OT_operator(bpy.types.Operator):
#-----------------------------------------------------
- # Object creation
- if event.type == self.carver_prefs.Key_Create and event.value == 'PRESS':
- if self.ExclusiveCreateMode is False:
- self.CreateMode = not self.CreateMode
-
- # Auto Bevel Update
- if event.type == self.carver_prefs.Key_Update and event.value == 'PRESS':
- self.Auto_BevelUpdate = not self.Auto_BevelUpdate
-
- # Boolean operation type
- if event.type == self.carver_prefs.Key_Bool and event.value == 'PRESS':
- if (self.ProfileMode is True) or (self.ObjectMode is True):
- if self.BoolOps == self.difference:
- self.BoolOps = self.union
- else:
- self.BoolOps = self.difference
-
- # Brush Mode
- if event.type == self.carver_prefs.Key_Brush and event.value == 'PRESS':
- self.dont_apply_boolean = False
- if (self.ProfileMode is False) and (self.ObjectMode is False):
- self.ProfileMode = True
- else:
- self.ProfileMode = False
- if self.ObjectBrush is not None:
- if self.ObjectMode is False:
- self.ObjectMode = True
- self.BrushSolidify = False
- self.CList = self.OB_List
-
- Selection_Save_Restore(self)
- context.scene.mesh_carver.nProfile = self.nProfil
- else:
- self.ObjectMode = False
- else:
- self.BrushSolidify = False
- Selection_Save_Restore(self)
-
- if self.ProfileMode:
- createMeshFromData(self)
- self.ProfileBrush = bpy.data.objects["CT_Profil"]
- Selection_Save(self)
- self.BrushSolidify = True
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ProfileBrush.select_set(True)
- context.view_layer.objects.active = self.ProfileBrush
- # Set xRay
- self.ProfileBrush.show_in_front = True
-
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- Selection_Restore(self)
-
- self.CList = self.CurrentSelection
- else:
- if self.ObjectBrush is not None:
- if self.ObjectMode is False:
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- #Store active and selected objects
- Selection_Save(self)
-
- #Remove Carver modifier
- self.BrushSolidify = False
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
-
- #Restore selected and active object
- Selection_Restore(self)
- else:
- if self.SolidifyPossible:
- #Store active and selected objects
- Selection_Save(self)
- self.BrushSolidify = True
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- # Set xRay
- self.ObjectBrush.show_in_front = True
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- #Restore selected and active object
- Selection_Restore(self)
-
- # Help display
- if event.type == self.carver_prefs.Key_Help and event.value == 'PRESS':
- self.AskHelp = not self.AskHelp
-
- # Instantiate object
- if event.type == self.carver_prefs.Key_Instant and event.value == 'PRESS':
- self.Instantiate = not self.Instantiate
-
- # Close polygonal shape
- if event.type == self.carver_prefs.Key_Close and event.value == 'PRESS':
- if self.CreateMode:
- self.Closed = not self.Closed
-
- if event.type == self.carver_prefs.Key_Apply and event.value == 'PRESS':
- self.dont_apply_boolean = not self.dont_apply_boolean
-
- # Scale object
- if event.type == self.carver_prefs.Key_Scale and event.value == 'PRESS':
- if self.ObjectScale is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.ObjectScale = True
-
- # Grid : Snap on grid
- if event.type == self.carver_prefs.Key_Snap and event.value == 'PRESS':
- self.snap = not self.snap
-
- # Array : Add column
- if event.type == 'UP_ARROW' and event.value == 'PRESS':
- self.nbrow += 1
- update_grid(self, context)
-
- # Array : Delete column
- elif event.type == 'DOWN_ARROW' and event.value == 'PRESS':
- self.nbrow -= 1
- update_grid(self, context)
-
- # Array : Add row
- elif event.type == 'RIGHT_ARROW' and event.value == 'PRESS':
- self.nbcol += 1
- update_grid(self, context)
-
- # Array : Delete row
- elif event.type == 'LEFT_ARROW' and event.value == 'PRESS':
- self.nbcol -= 1
- update_grid(self, context)
-
- # Array : Scale gap between columns
- if event.type == self.carver_prefs.Key_Gapy and event.value == 'PRESS':
- if self.GridScaleX is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.GridScaleX = True
-
- # Array : Scale gap between rows
- if event.type == self.carver_prefs.Key_Gapx and event.value == 'PRESS':
- if self.GridScaleY is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.GridScaleY = True
-
- # Cursor depth or solidify pattern
- if event.type == self.carver_prefs.Key_Depth and event.value == 'PRESS':
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- self.snapCursor = not self.snapCursor
- else:
- # Solidify
-
- if (self.ObjectMode or self.ProfileMode) and (self.SolidifyPossible):
- solidify = True
-
- if self.ObjectMode:
- z = self.ObjectBrush.data.vertices[0].co.z
- ErrorMarge = 0.01
- for v in self.ObjectBrush.data.vertices:
- if abs(v.co.z - z) > ErrorMarge:
- solidify = False
- self.CarveDepth = True
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- break
-
- if solidify:
- if self.ObjectMode:
- for mb in self.ObjectBrush.modifiers:
- if mb.type == 'SOLIDIFY':
- AlreadySoldify = True
- else:
- for mb in self.ProfileBrush.modifiers:
- if mb.type == 'SOLIDIFY':
- AlreadySoldify = True
-
- if AlreadySoldify is False:
- Selection_Save(self)
- self.BrushSolidify = True
-
- bpy.ops.object.select_all(action='TOGGLE')
- if self.ObjectMode:
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- # Active le xray
- self.ObjectBrush.show_in_front = True
- else:
- self.ProfileBrush.select_set(True)
- context.view_layer.objects.active = self.ProfileBrush
- # Active le xray
- self.ProfileBrush.show_in_front = True
-
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
-
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- Selection_Restore(self)
-
- self.WidthSolidify = not self.WidthSolidify
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- if event.type == self.carver_prefs.Key_BrushDepth and event.value == 'PRESS':
- if self.ObjectMode:
- self.CarveDepth = False
-
- self.BrushDepth = True
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- # Random rotation
- if event.type == 'R' and event.value == 'PRESS':
- self.RandomRotation = not self.RandomRotation
-
- # Undo
- if event.type == 'Z' and event.value == 'PRESS':
- if self.ctrl:
- if (self.CutType == self.line) and (self.CutMode):
- if len(self.mouse_path) > 1:
- self.mouse_path[len(self.mouse_path) - 1:] = []
- else:
- Undo(self)
-
- # Mouse move
- if event.type == 'MOUSEMOVE' :
- if self.ObjectMode or self.ProfileMode:
- fac = 50.0
- if self.shift:
- fac = 500.0
- if self.WidthSolidify:
- if self.ObjectMode:
- bpy.data.objects[self.ObjectBrush.name].modifiers[
- "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
- elif self.ProfileMode:
- bpy.data.objects[self.ProfileBrush.name].modifiers[
- "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- elif self.CarveDepth:
- for v in self.ObjectBrush.data.vertices:
- v.co.z += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- elif self.BrushDepth:
- self.BrushDepthOffset += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- else:
- if (self.GridScaleX):
- self.gapx += (event.mouse_region_x - self.mouse_region[0]) / 50
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- update_grid(self, context)
- return {'RUNNING_MODAL'}
-
- elif (self.GridScaleY):
- self.gapy += (event.mouse_region_x - self.mouse_region[0]) / 50
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- update_grid(self, context)
- return {'RUNNING_MODAL'}
-
- elif self.ObjectScale:
- self.ascale = -(event.mouse_region_x - self.mouse_region[0])
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- if self.ObjectMode:
- self.ObjectBrush.scale.x -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.x <= 0.0:
- self.ObjectBrush.scale.x = 0.0
- self.ObjectBrush.scale.y -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.y <= 0.0:
- self.ObjectBrush.scale.y = 0.0
- self.ObjectBrush.scale.z -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.z <= 0.0:
- self.ObjectBrush.scale.z = 0.0
-
- elif self.ProfileMode:
- if self.ProfileBrush is not None:
- self.ProfileBrush.scale.x -= float(self.ascale) / 150.0
- self.ProfileBrush.scale.y -= float(self.ascale) / 150.0
- self.ProfileBrush.scale.z -= float(self.ascale) / 150.0
- else:
- if self.LMB:
- if self.ctrl:
- self.aRotZ = - \
- ((int((event.mouse_region_x - self.xSavMouse) / 10.0) * PI / 4.0) * 25.0)
- else:
- self.aRotZ -= event.mouse_region_x - self.mouse_region[0]
- self.ascale = 0.0
-
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- else:
- target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
- if target_hit is not None:
- self.ShowCursor = True
- up_vector = Vector((0.0, 0.0, 1.0))
- quat_rot_axis = rot_axis_quat(up_vector, target_normal)
- self.quat_rot = target_eul_rotation @ quat_rot_axis
- MoveCursor(quat_rot_axis, target_hit, self)
- self.SavCurLoc = target_hit
- if self.ctrl:
- if self.SavMousePos is not None:
- xEcart = abs(self.SavMousePos.x - self.SavCurLoc.x)
- yEcart = abs(self.SavMousePos.y - self.SavCurLoc.y)
- zEcart = abs(self.SavMousePos.z - self.SavCurLoc.z)
- if (xEcart > yEcart) and (xEcart > zEcart):
- self.CurLoc = Vector(
- (target_hit.x, self.SavMousePos.y, self.SavMousePos.z))
- if (yEcart > xEcart) and (yEcart > zEcart):
- self.CurLoc = Vector(
- (self.SavMousePos.x, target_hit.y, self.SavMousePos.z))
- if (zEcart > xEcart) and (zEcart > yEcart):
- self.CurLoc = Vector(
- (self.SavMousePos.x, self.SavMousePos.y, target_hit.z))
- else:
- self.CurLoc = target_hit
- else:
- self.CurLoc = target_hit
- else:
- if self.CutMode:
- if self.alt is False:
- if self.ctrl :
- # Find the closest position on the overlay grid and snap the mouse on it
- # Draw a mini grid around the cursor
- mouse_pos = [[event.mouse_region_x, event.mouse_region_y]]
- Snap_Cursor(self, context, event, mouse_pos)
-
- else:
- if len(self.mouse_path) > 0:
- self.mouse_path[len(self.mouse_path) -
- 1] = (event.mouse_region_x, event.mouse_region_y)
- else:
- # [ALT] press, update position
- self.xpos += (event.mouse_region_x - self.last_mouse_region_x)
- self.ypos += (event.mouse_region_y - self.last_mouse_region_y)
-
- self.last_mouse_region_x = event.mouse_region_x
- self.last_mouse_region_y = event.mouse_region_y
-
- elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
- if self.ObjectMode or self.ProfileMode:
- if self.LMB is False:
- target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
- if target_hit is not None:
- up_vector = Vector((0.0, 0.0, 1.0))
- self.quat_rot_axis = rot_axis_quat(up_vector, target_normal)
- self.quat_rot = target_eul_rotation @ self.quat_rot_axis
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.xSavMouse = event.mouse_region_x
-
- if self.ctrl:
- self.nRotZ = int((self.aRotZ / 25.0) / (PI / 4.0))
- self.aRotZ = self.nRotZ * (PI / 4.0) * 25.0
-
- self.LMB = True
-
- # LEFTMOUSE
- elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE' and self.in_view_3d:
- if self.ObjectMode or self.ProfileMode:
- # Rotation and scale
- self.LMB = False
- if self.ObjectScale is True:
- self.ObjectScale = False
-
- if self.GridScaleX is True:
- self.GridScaleX = False
-
- if self.GridScaleY is True:
- self.GridScaleY = False
-
- if self.WidthSolidify:
- self.WidthSolidify = False
-
- if self.CarveDepth is True:
- self.CarveDepth = False
-
- if self.BrushDepth is True:
- self.BrushDepth = False
-
- else:
- if self.CutMode is False:
- if self.ctrl:
- Picking(context, event)
-
- else:
-
- if self.CutType == self.line:
- if self.CutMode is False:
- self.mouse_path.clear()
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
- else:
- self.mouse_path[0] = (event.mouse_region_x, event.mouse_region_y)
- self.mouse_path[1] = (event.mouse_region_x, event.mouse_region_y)
- self.CutMode = True
- else:
- if self.CutType != self.line:
- # Cut creation
- if self.CutType == self.rectangle:
- CreateCutSquare(self, context)
- if self.CutType == self.circle:
- CreateCutCircle(self, context)
- if self.CutType == self.line:
- CreateCutLine(self, context)
-
- if self.CreateMode:
- # Object creation
- self.CreateGeometry()
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
- # Depth Cursor
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Instantiate object
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
- # Apply operation
- context.scene.mesh_carver.DontApply = self.dont_apply_boolean
-
- # if Object mode, set initiale state
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- # remove solidify
- Selection_Save(self)
- self.BrushSolidify = False
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
-
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
-
- Selection_Restore(self)
-
- context.scene.mesh_carver.nProfile = self.nProfil
-
- return {'FINISHED'}
- else:
- self.Cut()
- UndoListUpdate(self)
- else:
- # Line
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
-
- # Change brush profil or circle subdivisions
- elif (event.type == 'COMMA' and event.value == 'PRESS') or \
- (event.type == self.carver_prefs.Key_Subrem and event.value == 'PRESS'):
- # Brush profil
- if self.ProfileMode:
- self.nProfil += 1
- if self.nProfil >= self.MaxProfil:
- self.nProfil = 0
- createMeshFromData(self)
- # Circle subdivisions
- if self.CutType == self.circle:
- self.step += 1
- if self.step >= len(self.stepAngle):
- self.step = len(self.stepAngle) - 1
- # Change brush profil or circle subdivisions
- elif (event.type == 'PERIOD' and event.value == 'PRESS') or \
- (event.type == self.carver_prefs.Key_Subadd and event.value == 'PRESS'):
- # Brush profil
- if self.ProfileMode:
- self.nProfil -= 1
- if self.nProfil < 0:
- self.nProfil = self.MaxProfil - 1
- createMeshFromData(self)
- # Circle subdivisions
- if self.CutType == self.circle:
- if self.step > 0:
- self.step -= 1
- # Quit
- elif event.type in {'RIGHTMOUSE', 'ESC'}:
- # Depth Cursor
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Instantiate object
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random Rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
- # Apply boolean operation
- context.scene.mesh_carver.DontApply = self.dont_apply_boolean
-
- # Reset Object
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- # Remove solidify modifier
- Selection_Save(self)
- self.BrushSolidify = False
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
-
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
- bpy.ops.object.select_all(action='TOGGLE')
-
- Selection_Restore(self)
-
- Selection_Save_Restore(self)
- context.view_layer.objects.active = self.CurrentActive
- context.scene.mesh_carver.nProfile = self.nProfil
-
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- # Remove Copy Object Brush
- if bpy.data.objects.get("CarverBrushCopy") is not None:
- brush = bpy.data.objects["CarverBrushCopy"]
- self.ObjectBrush.data = bpy.data.meshes[brush.data.name]
- bpy.ops.object.select_all(action='DESELECT')
- bpy.data.objects["CarverBrushCopy"].select_set(True)
- bpy.ops.object.delete()
-
- return {'FINISHED'}
-
- return {'RUNNING_MODAL'}
-
- except:
- print("\n[Carver MT ERROR]\n")
- import traceback
- traceback.print_exc()
-
- context.window.cursor_modal_set("DEFAULT")
- context.area.header_text_set(None)
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- self.report({'WARNING'},
- "Operation finished. Failure during Carving (Check the console for more info)")
-
- return {'FINISHED'}
-
- def cancel(self, context):
- # Note: used to prevent memory leaks on quitting Blender while the modal operator
- # is still running, gets called on return {"CANCELLED"}
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- def invoke(self, context, event):
- if context.area.type != 'VIEW_3D':
- self.report({'WARNING'},
- "View3D not found or not currently active. Operation Cancelled")
- self.cancel(context)
- return {'CANCELLED'}
-
- # test if some other object types are selected that are not meshes
- for obj in context.selected_objects:
- if obj.type != "MESH":
- self.report({'WARNING'},
- "Some selected objects are not of the Mesh type. Operation Cancelled")
- self.cancel(context)
- return {'CANCELLED'}
-
- if context.mode == 'EDIT_MESH':
- bpy.ops.object.mode_set(mode='OBJECT')
-
- #Load the Carver preferences
- self.carver_prefs = bpy.context.preferences.addons[__package__].preferences
-
- # Get default patterns
- self.Profils = []
- for p in Profils:
- self.Profils.append((p[0], p[1], p[2], p[3]))
-
- for o in context.scene.objects:
- if not o.name.startswith(self.carver_prefs.ProfilePrefix):
- continue
- # In-scene profiles may have changed, remove them to refresh
- for m in bpy.data.meshes:
- if m.name.startswith(self.carver_prefs.ProfilePrefix):
- bpy.data.meshes.remove(m)
-
- vertices = []
- for v in o.data.vertices:
- vertices.append((v.co.x, v.co.y, v.co.z))
-
- faces = []
- for f in o.data.polygons:
- face = []
- for v in f.vertices:
- face.append(v)
-
- faces.append(face)
-
- self.Profils.append(
- (o.name,
- Vector((o.location.x, o.location.y, o.location.z)),
- vertices, faces)
- )
-
- self.nProfil = context.scene.mesh_carver.nProfile
- self.MaxProfil = len(self.Profils)
-
-
- # reset selected profile if last profile exceeds length of array
- if self.nProfil >= self.MaxProfil:
- self.nProfil = context.scene.mesh_carver.nProfile = 0
-
- if len(context.selected_objects) > 1:
- self.ObjectBrush = context.active_object
-
- # Copy the brush object
- ob = bpy.data.objects.new("CarverBrushCopy", context.object.data.copy())
- ob.location = self.ObjectBrush.location
- context.collection.objects.link(ob)
- context.view_layer.update()
-
- # Save default variables
- self.InitBrush['location'] = self.ObjectBrush.location.copy()
- self.InitBrush['scale'] = self.ObjectBrush.scale.copy()
- self.InitBrush['rotation_quaternion'] = self.ObjectBrush.rotation_quaternion.copy()
- self.InitBrush['rotation_euler'] = self.ObjectBrush.rotation_euler.copy()
- self.InitBrush['display_type'] = self.ObjectBrush.display_type
- self.InitBrush['show_in_front'] = self.ObjectBrush.show_in_front
-
- # Test if flat object
- z = self.ObjectBrush.data.vertices[0].co.z
- ErrorMarge = 0.01
- self.SolidifyPossible = True
- for v in self.ObjectBrush.data.vertices:
- if abs(v.co.z - z) > ErrorMarge:
- self.SolidifyPossible = False
- break
-
- self.CList = []
- self.OPList = []
- self.RList = []
- self.OB_List = []
-
- for obj in context.selected_objects:
- if obj != self.ObjectBrush:
- self.OB_List.append(obj)
-
- # Left button
- self.LMB = False
-
- # Undo Variables
- self.undo_index = 0
- self.undo_limit = context.preferences.edit.undo_steps
- self.undo_list = []
-
- # Boolean operations type
- self.BooleanType = 0
-
- self.UList = []
- self.UList_Index = -1
- self.UndoOps = []
-
- context.window_manager.modal_handler_add(self)
- return {'RUNNING_MODAL'}
-
- #Get the region area where the operator is used
- def check_region(self,context,event):
- if context.area != None:
- if context.area.type == "VIEW_3D" :
- for region in context.area.regions:
- if region.type == "TOOLS":
- t_panel = region
- elif region.type == "UI":
- ui_panel = region
-
- view_3d_region_x = Vector((context.area.x + t_panel.width, context.area.x + context.area.width - ui_panel.width))
- view_3d_region_y = Vector((context.region.y, context.region.y+context.region.height))
-
- if (event.mouse_x > view_3d_region_x[0] and event.mouse_x < view_3d_region_x[1] \
- and event.mouse_y > view_3d_region_y[0] and event.mouse_y < view_3d_region_y[1]):
- self.in_view_3d = True
- else:
- self.in_view_3d = False
- else:
- self.in_view_3d = False
-
- def CreateGeometry(self):
- context = bpy.context
- in_local_view = False
-
- for area in context.screen.areas:
- if area.type == 'VIEW_3D':
- if area.spaces[0].local_view is not None:
- in_local_view = True
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- if self.ExclusiveCreateMode:
- # Default width
- objBBDiagonal = 0.5
- else:
- ActiveObj = self.CurrentSelection[0]
- if ActiveObj is not None:
- # Object dimensions
- objBBDiagonal = objDiagonal(ActiveObj) / 4
- subdivisions = 2
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.select_mode(type="EDGE")
- if self.snapCursor is False:
- bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
- bpy.ops.mesh.extrude_region_move(
- TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
-
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.normals_make_consistent()
- bpy.ops.object.mode_set(mode='OBJECT')
-
- saved_location_0 = context.scene.cursor.location.copy()
- bpy.ops.view3d.snap_cursor_to_active()
- saved_location = context.scene.cursor.location.copy()
- bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
- context.scene.cursor.location = saved_location
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
- context.scene.cursor.location = saved_location_0
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- for o in self.all_sel_obj_list:
- bpy.data.objects[o.name].select_set(True)
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- self.CutMode = False
- self.mouse_path.clear()
- self.mouse_path = [(0, 0), (0, 0)]
-
- def Cut(self):
- context = bpy.context
-
- # Local view ?
- in_local_view = False
- for area in context.screen.areas:
- if area.type == 'VIEW_3D':
- if area.spaces[0].local_view is not None:
- in_local_view = True
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- # Save cursor position
- CursorLocation = context.scene.cursor.location.copy()
-
- #List of selected objects
- selected_obj_list = []
-
- #Cut Mode with line
- if (self.ObjectMode is False) and (self.ProfileMode is False):
-
- #Compute the bounding Box
- objBBDiagonal = objDiagonal(self.CurrentSelection[0])
- if self.dont_apply_boolean:
- subdivisions = 1
- else:
- subdivisions = 32
-
- # Get selected objects
- selected_obj_list = context.selected_objects.copy()
-
- bpy.ops.object.select_all(action='TOGGLE')
-
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.select_mode(type="EDGE")
- #Translate the created mesh away from the view
- if (self.snapCursor is False) or (self.ForceRebool):
- bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
- #Extrude the mesh region and move the result
- bpy.ops.mesh.extrude_region_move(
- TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.normals_make_consistent()
- bpy.ops.object.mode_set(mode='OBJECT')
- else:
- # Create list
- if self.ObjectMode:
- for o in self.CurrentSelection:
- if o != self.ObjectBrush:
- selected_obj_list.append(o)
- self.CurrentObj = self.ObjectBrush
- else:
- selected_obj_list = self.CurrentSelection
- self.CurrentObj = self.ProfileBrush
-
- for obj in self.CurrentSelection:
- UndoAdd(self, "MESH", obj)
-
- # List objects create with rebool
- lastSelected = []
-
- for ActiveObj in selected_obj_list:
- context.scene.cursor.location = CursorLocation
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- # Select cut object
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Select object to cut
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='DESELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Boolean operation
- if (self.shift is False) and (self.ForceRebool is False):
- if self.ObjectMode or self.ProfileMode:
- if self.BoolOps == self.union:
- boolean_operation(bool_type="UNION")
- else:
- boolean_operation(bool_type="DIFFERENCE")
- else:
- boolean_operation(bool_type="DIFFERENCE")
-
- # Apply booleans
- if self.dont_apply_boolean is False:
- BMname = "CT_" + self.CurrentObj.name
- for mb in ActiveObj.modifiers:
- if (mb.type == 'BOOLEAN') and (mb.name == BMname):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
- except:
- bpy.ops.object.modifier_remove(modifier=BMname)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
-
- bpy.ops.object.select_all(action='TOGGLE')
- else:
- if self.ObjectMode or self.ProfileMode:
- for mb in self.CurrentObj.modifiers:
- if (mb.type == 'SOLIDIFY') and (mb.name == "CT_SOLIDIFY"):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
-
- # Rebool
- Rebool(context, self)
-
- # Test if not empty object
- if context.selected_objects[0]:
- rebool_RT = context.selected_objects[0]
- if len(rebool_RT.data.vertices) > 0:
- # Create Bevel for new objects
- CreateBevel(context, context.selected_objects[0])
-
- UndoAdd(self, "REBOOL", context.selected_objects[0])
-
- context.scene.cursor.location = ActiveObj.location
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
- else:
- bpy.ops.object.delete(use_global=False)
-
- context.scene.cursor.location = CursorLocation
-
- if self.ObjectMode:
- context.view_layer.objects.active = self.ObjectBrush
- if self.ProfileMode:
- context.view_layer.objects.active = self.ProfileBrush
-
- if self.dont_apply_boolean is False:
- # Apply booleans
- BMname = "CT_" + self.CurrentObj.name
- for mb in ActiveObj.modifiers:
- if (mb.type == 'BOOLEAN') and (mb.name == BMname):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
- except:
- bpy.ops.object.modifier_remove(modifier=BMname)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
- # Get new objects created with rebool operations
- if len(context.selected_objects) > 0:
- if self.shift is True:
- # Get the last object selected
- lastSelected.append(context.selected_objects[0])
-
- context.scene.cursor.location = CursorLocation
-
- if self.dont_apply_boolean is False:
- # Remove cut object
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.delete(use_global=False)
- else:
- if self.ObjectMode:
- self.ObjectBrush.display_type = self.InitBrush['display_type']
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- # Select cut objects
- for obj in lastSelected:
- bpy.data.objects[obj.name].select_set(True)
-
- for ActiveObj in selected_obj_list:
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
- # Update bevel
- list_act_obj = context.selected_objects.copy()
- if self.Auto_BevelUpdate:
- update_bevel(context)
-
- # Re-select initial objects
- bpy.ops.object.select_all(action='TOGGLE')
- if self.ObjectMode:
- # Re-select brush
- self.ObjectBrush.select_set(True)
- for ActiveObj in selected_obj_list:
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
-
- # If object has children, set "Wire" draw type
- if self.ObjectBrush is not None:
- if len(self.ObjectBrush.children) > 0:
- self.ObjectBrush.display_type = "WIRE"
- if self.ProfileMode:
- self.ProfileBrush.display_type = "WIRE"
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- # Reset variables
- self.CutMode = False
- self.mouse_path.clear()
- self.mouse_path = [(0, 0), (0, 0)]
-
- self.ForceRebool = False
-
- # bpy.ops.mesh.customdata_custom_splitnormals_clear()
+ # Object creation
+ if event.type == self.carver_prefs.Key_Create and event.value == 'PRESS':
+ if self.ExclusiveCreateMode is False:
+ self.CreateMode = not self.CreateMode
+
+ # Auto Bevel Update
+ if event.type == self.carver_prefs.Key_Update and event.value == 'PRESS':
+ self.Auto_BevelUpdate = not self.Auto_BevelUpdate
+
+ # Boolean operation type
+ if event.type == self.carver_prefs.Key_Bool and event.value == 'PRESS':
+ if (self.ProfileMode is True) or (self.ObjectMode is True):
+ if self.BoolOps == self.difference:
+ self.BoolOps = self.union
+ else:
+ self.BoolOps = self.difference
+
+ # Brush Mode
+ if event.type == self.carver_prefs.Key_Brush and event.value == 'PRESS':
+ self.dont_apply_boolean = False
+ if (self.ProfileMode is False) and (self.ObjectMode is False):
+ self.ProfileMode = True
+ else:
+ self.ProfileMode = False
+ if self.ObjectBrush is not None:
+ if self.ObjectMode is False:
+ self.ObjectMode = True
+ self.BrushSolidify = False
+ self.CList = self.OB_List
+
+ Selection_Save_Restore(self)
+ context.scene.mesh_carver.nProfile = self.nProfil
+ else:
+ self.ObjectMode = False
+ else:
+ self.BrushSolidify = False
+ Selection_Save_Restore(self)
+
+ if self.ProfileMode:
+ createMeshFromData(self)
+ self.ProfileBrush = bpy.data.objects["CT_Profil"]
+ Selection_Save(self)
+ self.BrushSolidify = True
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ProfileBrush.select_set(True)
+ context.view_layer.objects.active = self.ProfileBrush
+ # Set xRay
+ self.ProfileBrush.show_in_front = True
+
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ Selection_Restore(self)
+
+ self.CList = self.CurrentSelection
+ else:
+ if self.ObjectBrush is not None:
+ if self.ObjectMode is False:
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ #Store active and selected objects
+ Selection_Save(self)
+
+ #Remove Carver modifier
+ self.BrushSolidify = False
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+
+ #Restore selected and active object
+ Selection_Restore(self)
+ else:
+ if self.SolidifyPossible:
+ #Store active and selected objects
+ Selection_Save(self)
+ self.BrushSolidify = True
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ # Set xRay
+ self.ObjectBrush.show_in_front = True
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ #Restore selected and active object
+ Selection_Restore(self)
+
+ # Help display
+ if event.type == self.carver_prefs.Key_Help and event.value == 'PRESS':
+ self.AskHelp = not self.AskHelp
+
+ # Instantiate object
+ if event.type == self.carver_prefs.Key_Instant and event.value == 'PRESS':
+ self.Instantiate = not self.Instantiate
+
+ # Close polygonal shape
+ if event.type == self.carver_prefs.Key_Close and event.value == 'PRESS':
+ if self.CreateMode:
+ self.Closed = not self.Closed
+
+ if event.type == self.carver_prefs.Key_Apply and event.value == 'PRESS':
+ self.dont_apply_boolean = not self.dont_apply_boolean
+
+ # Scale object
+ if event.type == self.carver_prefs.Key_Scale and event.value == 'PRESS':
+ if self.ObjectScale is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.ObjectScale = True
+
+ # Grid : Snap on grid
+ if event.type == self.carver_prefs.Key_Snap and event.value == 'PRESS':
+ self.snap = not self.snap
+
+ # Array : Add column
+ if event.type == 'UP_ARROW' and event.value == 'PRESS':
+ self.nbrow += 1
+ update_grid(self, context)
+
+ # Array : Delete column
+ elif event.type == 'DOWN_ARROW' and event.value == 'PRESS':
+ self.nbrow -= 1
+ update_grid(self, context)
+
+ # Array : Add row
+ elif event.type == 'RIGHT_ARROW' and event.value == 'PRESS':
+ self.nbcol += 1
+ update_grid(self, context)
+
+ # Array : Delete row
+ elif event.type == 'LEFT_ARROW' and event.value == 'PRESS':
+ self.nbcol -= 1
+ update_grid(self, context)
+
+ # Array : Scale gap between columns
+ if event.type == self.carver_prefs.Key_Gapy and event.value == 'PRESS':
+ if self.GridScaleX is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.GridScaleX = True
+
+ # Array : Scale gap between rows
+ if event.type == self.carver_prefs.Key_Gapx and event.value == 'PRESS':
+ if self.GridScaleY is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.GridScaleY = True
+
+ # Cursor depth or solidify pattern
+ if event.type == self.carver_prefs.Key_Depth and event.value == 'PRESS':
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ self.snapCursor = not self.snapCursor
+ else:
+ # Solidify
+
+ if (self.ObjectMode or self.ProfileMode) and (self.SolidifyPossible):
+ solidify = True
+
+ if self.ObjectMode:
+ z = self.ObjectBrush.data.vertices[0].co.z
+ ErrorMarge = 0.01
+ for v in self.ObjectBrush.data.vertices:
+ if abs(v.co.z - z) > ErrorMarge:
+ solidify = False
+ self.CarveDepth = True
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ break
+
+ if solidify:
+ if self.ObjectMode:
+ for mb in self.ObjectBrush.modifiers:
+ if mb.type == 'SOLIDIFY':
+ AlreadySoldify = True
+ else:
+ for mb in self.ProfileBrush.modifiers:
+ if mb.type == 'SOLIDIFY':
+ AlreadySoldify = True
+
+ if AlreadySoldify is False:
+ Selection_Save(self)
+ self.BrushSolidify = True
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ if self.ObjectMode:
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ # Active le xray
+ self.ObjectBrush.show_in_front = True
+ else:
+ self.ProfileBrush.select_set(True)
+ context.view_layer.objects.active = self.ProfileBrush
+ # Active le xray
+ self.ProfileBrush.show_in_front = True
+
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ Selection_Restore(self)
+
+ self.WidthSolidify = not self.WidthSolidify
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ if event.type == self.carver_prefs.Key_BrushDepth and event.value == 'PRESS':
+ if self.ObjectMode:
+ self.CarveDepth = False
+
+ self.BrushDepth = True
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ # Random rotation
+ if event.type == 'R' and event.value == 'PRESS':
+ self.RandomRotation = not self.RandomRotation
+
+ # Undo
+ if event.type == 'Z' and event.value == 'PRESS':
+ if self.ctrl:
+ if (self.CutType == self.line) and (self.CutMode):
+ if len(self.mouse_path) > 1:
+ self.mouse_path[len(self.mouse_path) - 1:] = []
+ else:
+ Undo(self)
+
+ # Mouse move
+ if event.type == 'MOUSEMOVE' :
+ if self.ObjectMode or self.ProfileMode:
+ fac = 50.0
+ if self.shift:
+ fac = 500.0
+ if self.WidthSolidify:
+ if self.ObjectMode:
+ bpy.data.objects[self.ObjectBrush.name].modifiers[
+ "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
+ elif self.ProfileMode:
+ bpy.data.objects[self.ProfileBrush.name].modifiers[
+ "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ elif self.CarveDepth:
+ for v in self.ObjectBrush.data.vertices:
+ v.co.z += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ elif self.BrushDepth:
+ self.BrushDepthOffset += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ else:
+ if (self.GridScaleX):
+ self.gapx += (event.mouse_region_x - self.mouse_region[0]) / 50
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ update_grid(self, context)
+ return {'RUNNING_MODAL'}
+
+ elif (self.GridScaleY):
+ self.gapy += (event.mouse_region_x - self.mouse_region[0]) / 50
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ update_grid(self, context)
+ return {'RUNNING_MODAL'}
+
+ elif self.ObjectScale:
+ self.ascale = -(event.mouse_region_x - self.mouse_region[0])
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ if self.ObjectMode:
+ self.ObjectBrush.scale.x -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.x <= 0.0:
+ self.ObjectBrush.scale.x = 0.0
+ self.ObjectBrush.scale.y -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.y <= 0.0:
+ self.ObjectBrush.scale.y = 0.0
+ self.ObjectBrush.scale.z -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.z <= 0.0:
+ self.ObjectBrush.scale.z = 0.0
+
+ elif self.ProfileMode:
+ if self.ProfileBrush is not None:
+ self.ProfileBrush.scale.x -= float(self.ascale) / 150.0
+ self.ProfileBrush.scale.y -= float(self.ascale) / 150.0
+ self.ProfileBrush.scale.z -= float(self.ascale) / 150.0
+ else:
+ if self.LMB:
+ if self.ctrl:
+ self.aRotZ = - \
+ ((int((event.mouse_region_x - self.xSavMouse) / 10.0) * PI / 4.0) * 25.0)
+ else:
+ self.aRotZ -= event.mouse_region_x - self.mouse_region[0]
+ self.ascale = 0.0
+
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ else:
+ target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
+ if target_hit is not None:
+ self.ShowCursor = True
+ up_vector = Vector((0.0, 0.0, 1.0))
+ quat_rot_axis = rot_axis_quat(up_vector, target_normal)
+ self.quat_rot = target_eul_rotation @ quat_rot_axis
+ MoveCursor(quat_rot_axis, target_hit, self)
+ self.SavCurLoc = target_hit
+ if self.ctrl:
+ if self.SavMousePos is not None:
+ xEcart = abs(self.SavMousePos.x - self.SavCurLoc.x)
+ yEcart = abs(self.SavMousePos.y - self.SavCurLoc.y)
+ zEcart = abs(self.SavMousePos.z - self.SavCurLoc.z)
+ if (xEcart > yEcart) and (xEcart > zEcart):
+ self.CurLoc = Vector(
+ (target_hit.x, self.SavMousePos.y, self.SavMousePos.z))
+ if (yEcart > xEcart) and (yEcart > zEcart):
+ self.CurLoc = Vector(
+ (self.SavMousePos.x, target_hit.y, self.SavMousePos.z))
+ if (zEcart > xEcart) and (zEcart > yEcart):
+ self.CurLoc = Vector(
+ (self.SavMousePos.x, self.SavMousePos.y, target_hit.z))
+ else:
+ self.CurLoc = target_hit
+ else:
+ self.CurLoc = target_hit
+ else:
+ if self.CutMode:
+ if self.alt is False:
+ if self.ctrl :
+ # Find the closest position on the overlay grid and snap the mouse on it
+ # Draw a mini grid around the cursor
+ mouse_pos = [[event.mouse_region_x, event.mouse_region_y]]
+ Snap_Cursor(self, context, event, mouse_pos)
+
+ else:
+ if len(self.mouse_path) > 0:
+ self.mouse_path[len(self.mouse_path) -
+ 1] = (event.mouse_region_x, event.mouse_region_y)
+ else:
+ # [ALT] press, update position
+ self.xpos += (event.mouse_region_x - self.last_mouse_region_x)
+ self.ypos += (event.mouse_region_y - self.last_mouse_region_y)
+
+ self.last_mouse_region_x = event.mouse_region_x
+ self.last_mouse_region_y = event.mouse_region_y
+
+ elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
+ if self.ObjectMode or self.ProfileMode:
+ if self.LMB is False:
+ target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
+ if target_hit is not None:
+ up_vector = Vector((0.0, 0.0, 1.0))
+ self.quat_rot_axis = rot_axis_quat(up_vector, target_normal)
+ self.quat_rot = target_eul_rotation @ self.quat_rot_axis
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.xSavMouse = event.mouse_region_x
+
+ if self.ctrl:
+ self.nRotZ = int((self.aRotZ / 25.0) / (PI / 4.0))
+ self.aRotZ = self.nRotZ * (PI / 4.0) * 25.0
+
+ self.LMB = True
+
+ # LEFTMOUSE
+ elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE' and self.in_view_3d:
+ if self.ObjectMode or self.ProfileMode:
+ # Rotation and scale
+ self.LMB = False
+ if self.ObjectScale is True:
+ self.ObjectScale = False
+
+ if self.GridScaleX is True:
+ self.GridScaleX = False
+
+ if self.GridScaleY is True:
+ self.GridScaleY = False
+
+ if self.WidthSolidify:
+ self.WidthSolidify = False
+
+ if self.CarveDepth is True:
+ self.CarveDepth = False
+
+ if self.BrushDepth is True:
+ self.BrushDepth = False
+
+ else:
+ if self.CutMode is False:
+ if self.ctrl:
+ Picking(context, event)
+
+ else:
+
+ if self.CutType == self.line:
+ if self.CutMode is False:
+ self.mouse_path.clear()
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+ else:
+ self.mouse_path[0] = (event.mouse_region_x, event.mouse_region_y)
+ self.mouse_path[1] = (event.mouse_region_x, event.mouse_region_y)
+ self.CutMode = True
+ else:
+ if self.CutType != self.line:
+ # Cut creation
+ if self.CutType == self.rectangle:
+ CreateCutSquare(self, context)
+ if self.CutType == self.circle:
+ CreateCutCircle(self, context)
+ if self.CutType == self.line:
+ CreateCutLine(self, context)
+
+ if self.CreateMode:
+ # Object creation
+ self.CreateGeometry()
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ # Depth Cursor
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Instantiate object
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+ # Apply operation
+ context.scene.mesh_carver.DontApply = self.dont_apply_boolean
+
+ # if Object mode, set initiale state
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ # remove solidify
+ Selection_Save(self)
+ self.BrushSolidify = False
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+
+ Selection_Restore(self)
+
+ context.scene.mesh_carver.nProfile = self.nProfil
+
+ return {'FINISHED'}
+ else:
+ self.Cut()
+ UndoListUpdate(self)
+ else:
+ # Line
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+
+ # Change brush profil or circle subdivisions
+ elif (event.type == 'COMMA' and event.value == 'PRESS') or \
+ (event.type == self.carver_prefs.Key_Subrem and event.value == 'PRESS'):
+ # Brush profil
+ if self.ProfileMode:
+ self.nProfil += 1
+ if self.nProfil >= self.MaxProfil:
+ self.nProfil = 0
+ createMeshFromData(self)
+ # Circle subdivisions
+ if self.CutType == self.circle:
+ self.step += 1
+ if self.step >= len(self.stepAngle):
+ self.step = len(self.stepAngle) - 1
+ # Change brush profil or circle subdivisions
+ elif (event.type == 'PERIOD' and event.value == 'PRESS') or \
+ (event.type == self.carver_prefs.Key_Subadd and event.value == 'PRESS'):
+ # Brush profil
+ if self.ProfileMode:
+ self.nProfil -= 1
+ if self.nProfil < 0:
+ self.nProfil = self.MaxProfil - 1
+ createMeshFromData(self)
+ # Circle subdivisions
+ if self.CutType == self.circle:
+ if self.step > 0:
+ self.step -= 1
+ # Quit
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ # Depth Cursor
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Instantiate object
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random Rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+ # Apply boolean operation
+ context.scene.mesh_carver.DontApply = self.dont_apply_boolean
+
+ # Reset Object
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ # Remove solidify modifier
+ Selection_Save(self)
+ self.BrushSolidify = False
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ Selection_Restore(self)
+
+ Selection_Save_Restore(self)
+ context.view_layer.objects.active = self.CurrentActive
+ context.scene.mesh_carver.nProfile = self.nProfil
+
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ # Remove Copy Object Brush
+ if bpy.data.objects.get("CarverBrushCopy") is not None:
+ brush = bpy.data.objects["CarverBrushCopy"]
+ self.ObjectBrush.data = bpy.data.meshes[brush.data.name]
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.data.objects["CarverBrushCopy"].select_set(True)
+ bpy.ops.object.delete()
+
+ return {'FINISHED'}
+
+ return {'RUNNING_MODAL'}
+
+ except:
+ print("\n[Carver MT ERROR]\n")
+ import traceback
+ traceback.print_exc()
+
+ context.window.cursor_modal_set("DEFAULT")
+ context.area.header_text_set(None)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ self.report({'WARNING'},
+ "Operation finished. Failure during Carving (Check the console for more info)")
+
+ return {'FINISHED'}
+
+ def cancel(self, context):
+ # Note: used to prevent memory leaks on quitting Blender while the modal operator
+ # is still running, gets called on return {"CANCELLED"}
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ def invoke(self, context, event):
+ if context.area.type != 'VIEW_3D':
+ self.report({'WARNING'},
+ "View3D not found or not currently active. Operation Cancelled")
+ self.cancel(context)
+ return {'CANCELLED'}
+
+ # test if some other object types are selected that are not meshes
+ for obj in context.selected_objects:
+ if obj.type != "MESH":
+ self.report({'WARNING'},
+ "Some selected objects are not of the Mesh type. Operation Cancelled")
+ self.cancel(context)
+ return {'CANCELLED'}
+
+ if context.mode == 'EDIT_MESH':
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ #Load the Carver preferences
+ self.carver_prefs = bpy.context.preferences.addons[__package__].preferences
+
+ # Get default patterns
+ self.Profils = []
+ for p in Profils:
+ self.Profils.append((p[0], p[1], p[2], p[3]))
+
+ for o in context.scene.objects:
+ if not o.name.startswith(self.carver_prefs.ProfilePrefix):
+ continue
+ # In-scene profiles may have changed, remove them to refresh
+ for m in bpy.data.meshes:
+ if m.name.startswith(self.carver_prefs.ProfilePrefix):
+ bpy.data.meshes.remove(m)
+
+ vertices = []
+ for v in o.data.vertices:
+ vertices.append((v.co.x, v.co.y, v.co.z))
+
+ faces = []
+ for f in o.data.polygons:
+ face = []
+ for v in f.vertices:
+ face.append(v)
+
+ faces.append(face)
+
+ self.Profils.append(
+ (o.name,
+ Vector((o.location.x, o.location.y, o.location.z)),
+ vertices, faces)
+ )
+
+ self.nProfil = context.scene.mesh_carver.nProfile
+ self.MaxProfil = len(self.Profils)
+
+
+ # reset selected profile if last profile exceeds length of array
+ if self.nProfil >= self.MaxProfil:
+ self.nProfil = context.scene.mesh_carver.nProfile = 0
+
+ if len(context.selected_objects) > 1:
+ self.ObjectBrush = context.active_object
+
+ # Copy the brush object
+ ob = bpy.data.objects.new("CarverBrushCopy", context.object.data.copy())
+ ob.location = self.ObjectBrush.location
+ context.collection.objects.link(ob)
+ context.view_layer.update()
+
+ # Save default variables
+ self.InitBrush['location'] = self.ObjectBrush.location.copy()
+ self.InitBrush['scale'] = self.ObjectBrush.scale.copy()
+ self.InitBrush['rotation_quaternion'] = self.ObjectBrush.rotation_quaternion.copy()
+ self.InitBrush['rotation_euler'] = self.ObjectBrush.rotation_euler.copy()
+ self.InitBrush['display_type'] = self.ObjectBrush.display_type
+ self.InitBrush['show_in_front'] = self.ObjectBrush.show_in_front
+
+ # Test if flat object
+ z = self.ObjectBrush.data.vertices[0].co.z
+ ErrorMarge = 0.01
+ self.SolidifyPossible = True
+ for v in self.ObjectBrush.data.vertices:
+ if abs(v.co.z - z) > ErrorMarge:
+ self.SolidifyPossible = False
+ break
+
+ self.CList = []
+ self.OPList = []
+ self.RList = []
+ self.OB_List = []
+
+ for obj in context.selected_objects:
+ if obj != self.ObjectBrush:
+ self.OB_List.append(obj)
+
+ # Left button
+ self.LMB = False
+
+ # Undo Variables
+ self.undo_index = 0
+ self.undo_limit = context.preferences.edit.undo_steps
+ self.undo_list = []
+
+ # Boolean operations type
+ self.BooleanType = 0
+
+ self.UList = []
+ self.UList_Index = -1
+ self.UndoOps = []
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ #Get the region area where the operator is used
+ def check_region(self,context,event):
+ if context.area != None:
+ if context.area.type == "VIEW_3D" :
+ for region in context.area.regions:
+ if region.type == "TOOLS":
+ t_panel = region
+ elif region.type == "UI":
+ ui_panel = region
+
+ view_3d_region_x = Vector((context.area.x + t_panel.width, context.area.x + context.area.width - ui_panel.width))
+ view_3d_region_y = Vector((context.region.y, context.region.y+context.region.height))
+
+ if (event.mouse_x > view_3d_region_x[0] and event.mouse_x < view_3d_region_x[1] \
+ and event.mouse_y > view_3d_region_y[0] and event.mouse_y < view_3d_region_y[1]):
+ self.in_view_3d = True
+ else:
+ self.in_view_3d = False
+ else:
+ self.in_view_3d = False
+
+ def CreateGeometry(self):
+ context = bpy.context
+ in_local_view = False
+
+ for area in context.screen.areas:
+ if area.type == 'VIEW_3D':
+ if area.spaces[0].local_view is not None:
+ in_local_view = True
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ if self.ExclusiveCreateMode:
+ # Default width
+ objBBDiagonal = 0.5
+ else:
+ ActiveObj = self.CurrentSelection[0]
+ if ActiveObj is not None:
+ # Object dimensions
+ objBBDiagonal = objDiagonal(ActiveObj) / 4
+ subdivisions = 2
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.select_mode(type="EDGE")
+ if self.snapCursor is False:
+ bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
+ bpy.ops.mesh.extrude_region_move(
+ TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
+
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ saved_location_0 = context.scene.cursor.location.copy()
+ bpy.ops.view3d.snap_cursor_to_active()
+ saved_location = context.scene.cursor.location.copy()
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ context.scene.cursor.location = saved_location
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ context.scene.cursor.location = saved_location_0
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ for o in self.all_sel_obj_list:
+ bpy.data.objects[o.name].select_set(True)
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ self.CutMode = False
+ self.mouse_path.clear()
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ def Cut(self):
+ context = bpy.context
+
+ # Local view ?
+ in_local_view = False
+ for area in context.screen.areas:
+ if area.type == 'VIEW_3D':
+ if area.spaces[0].local_view is not None:
+ in_local_view = True
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ # Save cursor position
+ CursorLocation = context.scene.cursor.location.copy()
+
+ #List of selected objects
+ selected_obj_list = []
+
+ #Cut Mode with line
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+
+ #Compute the bounding Box
+ objBBDiagonal = objDiagonal(self.CurrentSelection[0])
+ if self.dont_apply_boolean:
+ subdivisions = 1
+ else:
+ subdivisions = 32
+
+ # Get selected objects
+ selected_obj_list = context.selected_objects.copy()
+
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.select_mode(type="EDGE")
+ #Translate the created mesh away from the view
+ if (self.snapCursor is False) or (self.ForceRebool):
+ bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
+ #Extrude the mesh region and move the result
+ bpy.ops.mesh.extrude_region_move(
+ TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ else:
+ # Create list
+ if self.ObjectMode:
+ for o in self.CurrentSelection:
+ if o != self.ObjectBrush:
+ selected_obj_list.append(o)
+ self.CurrentObj = self.ObjectBrush
+ else:
+ selected_obj_list = self.CurrentSelection
+ self.CurrentObj = self.ProfileBrush
+
+ for obj in self.CurrentSelection:
+ UndoAdd(self, "MESH", obj)
+
+ # List objects create with rebool
+ lastSelected = []
+
+ for ActiveObj in selected_obj_list:
+ context.scene.cursor.location = CursorLocation
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ # Select cut object
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Select object to cut
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Boolean operation
+ if (self.shift is False) and (self.ForceRebool is False):
+ if self.ObjectMode or self.ProfileMode:
+ if self.BoolOps == self.union:
+ boolean_operation(bool_type="UNION")
+ else:
+ boolean_operation(bool_type="DIFFERENCE")
+ else:
+ boolean_operation(bool_type="DIFFERENCE")
+
+ # Apply booleans
+ if self.dont_apply_boolean is False:
+ BMname = "CT_" + self.CurrentObj.name
+ for mb in ActiveObj.modifiers:
+ if (mb.type == 'BOOLEAN') and (mb.name == BMname):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
+ except:
+ bpy.ops.object.modifier_remove(modifier=BMname)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ else:
+ if self.ObjectMode or self.ProfileMode:
+ for mb in self.CurrentObj.modifiers:
+ if (mb.type == 'SOLIDIFY') and (mb.name == "CT_SOLIDIFY"):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+
+ # Rebool
+ Rebool(context, self)
+
+ # Test if not empty object
+ if context.selected_objects[0]:
+ rebool_RT = context.selected_objects[0]
+ if len(rebool_RT.data.vertices) > 0:
+ # Create Bevel for new objects
+ CreateBevel(context, context.selected_objects[0])
+
+ UndoAdd(self, "REBOOL", context.selected_objects[0])
+
+ context.scene.cursor.location = ActiveObj.location
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ else:
+ bpy.ops.object.delete(use_global=False)
+
+ context.scene.cursor.location = CursorLocation
+
+ if self.ObjectMode:
+ context.view_layer.objects.active = self.ObjectBrush
+ if self.ProfileMode:
+ context.view_layer.objects.active = self.ProfileBrush
+
+ if self.dont_apply_boolean is False:
+ # Apply booleans
+ BMname = "CT_" + self.CurrentObj.name
+ for mb in ActiveObj.modifiers:
+ if (mb.type == 'BOOLEAN') and (mb.name == BMname):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
+ except:
+ bpy.ops.object.modifier_remove(modifier=BMname)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+ # Get new objects created with rebool operations
+ if len(context.selected_objects) > 0:
+ if self.shift is True:
+ # Get the last object selected
+ lastSelected.append(context.selected_objects[0])
+
+ context.scene.cursor.location = CursorLocation
+
+ if self.dont_apply_boolean is False:
+ # Remove cut object
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.delete(use_global=False)
+ else:
+ if self.ObjectMode:
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ # Select cut objects
+ for obj in lastSelected:
+ bpy.data.objects[obj.name].select_set(True)
+
+ for ActiveObj in selected_obj_list:
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+ # Update bevel
+ list_act_obj = context.selected_objects.copy()
+ if self.Auto_BevelUpdate:
+ update_bevel(context)
+
+ # Re-select initial objects
+ bpy.ops.object.select_all(action='TOGGLE')
+ if self.ObjectMode:
+ # Re-select brush
+ self.ObjectBrush.select_set(True)
+ for ActiveObj in selected_obj_list:
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+
+ # If object has children, set "Wire" draw type
+ if self.ObjectBrush is not None:
+ if len(self.ObjectBrush.children) > 0:
+ self.ObjectBrush.display_type = "WIRE"
+ if self.ProfileMode:
+ self.ProfileBrush.display_type = "WIRE"
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ # Reset variables
+ self.CutMode = False
+ self.mouse_path.clear()
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ self.ForceRebool = False
+
+ # bpy.ops.mesh.customdata_custom_splitnormals_clear()
class CarverProperties(bpy.types.PropertyGroup):
- DepthCursor: BoolProperty(
- name="DepthCursor",
- default=False
- )
- OInstanciate: BoolProperty(
- name="Obj_Instantiate",
- default=False
- )
- ORandom: BoolProperty(
- name="Random_Rotation",
- default=False
- )
- DontApply: BoolProperty(
- name="Dont_Apply",
- default=False
- )
- nProfile: IntProperty(
- name="Num_Profile",
- default=0
- )
+ DepthCursor: BoolProperty(
+ name="DepthCursor",
+ default=False
+ )
+ OInstanciate: BoolProperty(
+ name="Obj_Instantiate",
+ default=False
+ )
+ ORandom: BoolProperty(
+ name="Random_Rotation",
+ default=False
+ )
+ DontApply: BoolProperty(
+ name="Dont_Apply",
+ default=False
+ )
+ nProfile: IntProperty(
+ name="Num_Profile",
+ default=0
+ )
def register():
- from bpy.utils import register_class
- bpy.utils.register_class(CARVER_OT_operator)
- bpy.utils.register_class(CarverProperties)
- bpy.types.Scene.mesh_carver = bpy.props.PointerProperty(type=CarverProperties)
+ from bpy.utils import register_class
+ bpy.utils.register_class(CARVER_OT_operator)
+ bpy.utils.register_class(CarverProperties)
+ bpy.types.Scene.mesh_carver = bpy.props.PointerProperty(type=CarverProperties)
def unregister():
- from bpy.utils import unregister_class
- bpy.utils.unregister_class(CarverProperties)
- bpy.utils.unregister_class(CARVER_OT_operator)
- del bpy.types.Scene.mesh_carver
+ from bpy.utils import unregister_class
+ bpy.utils.unregister_class(CarverProperties)
+ bpy.utils.unregister_class(CARVER_OT_operator)
+ del bpy.types.Scene.mesh_carver
diff --git a/object_carver/carver_preferences.py b/object_carver/carver_preferences.py
index b7131193..1e6bc7ab 100644
--- a/object_carver/carver_preferences.py
+++ b/object_carver/carver_preferences.py
@@ -1,194 +1,194 @@
import bpy
from bpy.props import (
- BoolProperty,
- IntProperty,
- PointerProperty,
- StringProperty,
+ BoolProperty,
+ IntProperty,
+ PointerProperty,
+ StringProperty,
)
class CarverPrefs(bpy.types.AddonPreferences):
- bl_idname = __name__
+ bl_idname = __name__
- Enable_Tab_01: BoolProperty(
- name="Info",
- description="Some general information and settings about the add-on",
- default=False
- )
- Enable_Tab_02: BoolProperty(
- name="Hotkeys",
- description="List of the shortcuts used during carving",
- default=False
- )
- bpy.types.Scene.Key_Create: StringProperty(
- name="Object creation",
- description="Object creation",
- maxlen=1,
- default="C"
- )
- bpy.types.Scene.Key_Update: StringProperty(
- name="Auto Bevel Update",
- description="Auto Bevel Update",
- maxlen=1,
- default="A",
- )
- bpy.types.Scene.Key_Bool: StringProperty(
- name="Boolean type",
- description="Boolean operation type",
- maxlen=1,
- default="T",
- )
- bpy.types.Scene.Key_Brush: StringProperty(
- name="Brush Mode",
- description="Brush Mode",
- maxlen=1,
- default="B",
- )
- bpy.types.Scene.Key_Help: StringProperty(
- name="Help display",
- description="Help display",
- maxlen=1,
- default="H",
- )
- bpy.types.Scene.Key_Instant: StringProperty(
- name="Instantiate",
- description="Instantiate object",
- maxlen=1,
- default="I",
- )
- bpy.types.Scene.Key_Close: StringProperty(
- name="Close polygonal shape",
- description="Close polygonal shape",
- maxlen=1,
- default="X",
- )
- bpy.types.Scene.Key_Apply: StringProperty(
- name="Apply operation",
- description="Apply operation",
- maxlen=1,
- default="Q",
- )
- bpy.types.Scene.Key_Scale: StringProperty(
- name="Scale object",
- description="Scale object",
- maxlen=1,
- default="S",
- )
- bpy.types.Scene.Key_Gapy: StringProperty(
- name="Gap rows",
- description="Scale gap between columns",
- maxlen=1,
- default="J",
- )
- bpy.types.Scene.Key_Gapx: StringProperty(
- name="Gap columns",
- description="Scale gap between columns",
- maxlen=1,
- default="U",
- )
- bpy.types.Scene.Key_Depth: StringProperty(
- name="Depth",
- description="Cursor depth or solidify pattern",
- maxlen=1,
- default="D",
- )
- bpy.types.Scene.Key_BrushDepth: StringProperty(
- name="Brush Depth",
- description="Brush depth",
- maxlen=1,
- default="C",
- )
- bpy.types.Scene.Key_Subadd: StringProperty(
- name="Add subdivision",
- description="Add subdivision",
- maxlen=1,
- default="X",
- )
- bpy.types.Scene.Key_Subrem: StringProperty(
- name="Remove subdivision",
- description="Remove subdivision",
- maxlen=1,
- default="W",
- )
- bpy.types.Scene.Key_Randrot: StringProperty(
- name="Random rotation",
- description="Random rotation",
- maxlen=1,
- default="R",
- )
- bpy.types.Scene.ProfilePrefix: StringProperty(
- name="Profile prefix",
- description="Prefix to look for profiles with",
- default="Carver_Profile-"
- )
+ Enable_Tab_01: BoolProperty(
+ name="Info",
+ description="Some general information and settings about the add-on",
+ default=False
+ )
+ Enable_Tab_02: BoolProperty(
+ name="Hotkeys",
+ description="List of the shortcuts used during carving",
+ default=False
+ )
+ bpy.types.Scene.Key_Create: StringProperty(
+ name="Object creation",
+ description="Object creation",
+ maxlen=1,
+ default="C"
+ )
+ bpy.types.Scene.Key_Update: StringProperty(
+ name="Auto Bevel Update",
+ description="Auto Bevel Update",
+ maxlen=1,
+ default="A",
+ )
+ bpy.types.Scene.Key_Bool: StringProperty(
+ name="Boolean type",
+ description="Boolean operation type",
+ maxlen=1,
+ default="T",
+ )
+ bpy.types.Scene.Key_Brush: StringProperty(
+ name="Brush Mode",
+ description="Brush Mode",
+ maxlen=1,
+ default="B",
+ )
+ bpy.types.Scene.Key_Help: StringProperty(
+ name="Help display",
+ description="Help display",
+ maxlen=1,
+ default="H",
+ )
+ bpy.types.Scene.Key_Instant: StringProperty(
+ name="Instantiate",
+ description="Instantiate object",
+ maxlen=1,
+ default="I",
+ )
+ bpy.types.Scene.Key_Close: StringProperty(
+ name="Close polygonal shape",
+ description="Close polygonal shape",
+ maxlen=1,
+ default="X",
+ )
+ bpy.types.Scene.Key_Apply: StringProperty(
+ name="Apply operation",
+ description="Apply operation",
+ maxlen=1,
+ default="Q",
+ )
+ bpy.types.Scene.Key_Scale: StringProperty(
+ name="Scale object",
+ description="Scale object",
+ maxlen=1,
+ default="S",
+ )
+ bpy.types.Scene.Key_Gapy: StringProperty(
+ name="Gap rows",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="J",
+ )
+ bpy.types.Scene.Key_Gapx: StringProperty(
+ name="Gap columns",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="U",
+ )
+ bpy.types.Scene.Key_Depth: StringProperty(
+ name="Depth",
+ description="Cursor depth or solidify pattern",
+ maxlen=1,
+ default="D",
+ )
+ bpy.types.Scene.Key_BrushDepth: StringProperty(
+ name="Brush Depth",
+ description="Brush depth",
+ maxlen=1,
+ default="C",
+ )
+ bpy.types.Scene.Key_Subadd: StringProperty(
+ name="Add subdivision",
+ description="Add subdivision",
+ maxlen=1,
+ default="X",
+ )
+ bpy.types.Scene.Key_Subrem: StringProperty(
+ name="Remove subdivision",
+ description="Remove subdivision",
+ maxlen=1,
+ default="W",
+ )
+ bpy.types.Scene.Key_Randrot: StringProperty(
+ name="Random rotation",
+ description="Random rotation",
+ maxlen=1,
+ default="R",
+ )
+ bpy.types.Scene.ProfilePrefix: StringProperty(
+ name="Profile prefix",
+ description="Prefix to look for profiles with",
+ default="Carver_Profile-"
+ )
- def draw(self, context):
- scene = context.scene
- layout = self.layout
- print("DRAW !")
+ def draw(self, context):
+ scene = context.scene
+ layout = self.layout
+ print("DRAW !")
- icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
- box = layout.box()
+ icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
+ box = layout.box()
- box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
- if self.Enable_Tab_01:
- box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
- box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
- icon="LAYER_USED")
- box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
- icon="LAYER_USED")
- box.prop(scene, "ProfilePrefix", text="Profile prefix")
+ box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
+ if self.Enable_Tab_01:
+ box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
+ box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
+ icon="LAYER_USED")
+ box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
+ icon="LAYER_USED")
+ box.prop(scene, "ProfilePrefix", text="Profile prefix")
- icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
- box = layout.box()
- box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
- if self.Enable_Tab_02:
- split = box.split(align=True)
- box = split.box()
- col = box.column(align=True)
- col.label(text="Object Creation:")
- col.prop(scene, "Key_Create", text="")
- col.label(text="Auto bevel update:")
- col.prop(scene, "Key_Update", text="")
- col.label(text="Boolean operation type:")
- col.prop(scene, "Key_Bool", text="")
- col.label(text="Brush Depth:")
- col.prop(scene, "Key_BrushDepth", text="")
+ icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
+ box = layout.box()
+ box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
+ if self.Enable_Tab_02:
+ split = box.split(align=True)
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Object Creation:")
+ col.prop(scene, "Key_Create", text="")
+ col.label(text="Auto bevel update:")
+ col.prop(scene, "Key_Update", text="")
+ col.label(text="Boolean operation type:")
+ col.prop(scene, "Key_Bool", text="")
+ col.label(text="Brush Depth:")
+ col.prop(scene, "Key_BrushDepth", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Brush Mode:")
- col.prop(scene, "Key_Brush", text="")
- col.label(text="Help display:")
- col.prop(scene, "Key_Help", text="")
- col.label(text="Instantiate object:")
- col.prop(scene, "Key_Instant", text="")
- col.label(text="Random rotation:")
- col.prop(scene, "Key_Randrot", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Brush Mode:")
+ col.prop(scene, "Key_Brush", text="")
+ col.label(text="Help display:")
+ col.prop(scene, "Key_Help", text="")
+ col.label(text="Instantiate object:")
+ col.prop(scene, "Key_Instant", text="")
+ col.label(text="Random rotation:")
+ col.prop(scene, "Key_Randrot", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Close polygonal shape:")
- col.prop(scene, "Key_Close", text="")
- col.label(text="Apply operation:")
- col.prop(scene, "Key_Apply", text="")
- col.label(text="Scale object:")
- col.prop(scene, "Key_Scale", text="")
- col.label(text="Subdiv add:")
- col.prop(scene, "Key_Subadd", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Close polygonal shape:")
+ col.prop(scene, "Key_Close", text="")
+ col.label(text="Apply operation:")
+ col.prop(scene, "Key_Apply", text="")
+ col.label(text="Scale object:")
+ col.prop(scene, "Key_Scale", text="")
+ col.label(text="Subdiv add:")
+ col.prop(scene, "Key_Subadd", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Gap rows:")
- col.prop(scene, "Key_Gapy", text="")
- col.label(text="Gap columns:")
- col.prop(scene, "Key_Gapx", text="")
- col.label(text="Depth / Solidify:")
- col.prop(scene, "Key_Depth", text="")
- col.label(text="Subdiv Remove:")
- col.prop(scene, "Key_Subrem", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Gap rows:")
+ col.prop(scene, "Key_Gapy", text="")
+ col.label(text="Gap columns:")
+ col.prop(scene, "Key_Gapx", text="")
+ col.label(text="Depth / Solidify:")
+ col.prop(scene, "Key_Depth", text="")
+ col.label(text="Subdiv Remove:")
+ col.prop(scene, "Key_Subrem", text="")
def register():
- bpy.utils.register_class(CarverPrefs)
+ bpy.utils.register_class(CarverPrefs)
def unregister():
- bpy.utils.unregister_class(CarverPrefs)
+ bpy.utils.unregister_class(CarverPrefs)
diff --git a/object_carver/carver_profils.py b/object_carver/carver_profils.py
index d19478c9..9c99bf97 100644
--- a/object_carver/carver_profils.py
+++ b/object_carver/carver_profils.py
@@ -1,409 +1,409 @@
from mathutils import (
- Vector,
+ Vector,
)
Profils = [
- ("TEST",
- Vector((0,0,1)),
- [(-1, 1, 0.032334), (1, 1, 0.032334),(-1, -1, 0.032334), (1, -1, 0.01032334)],
- [(0, 1, 2), (2,1,3)]),
- ("CTP_4882",
- Vector((2.61824, -5.56469, 0)),
- [(-1.156501, 0.799282, 0.032334),
- (-0.967583, 0.838861, 0.032334),
- (-1.10386, 0.846403, 0.032334),
- (-1.034712, 0.86089, 0.032334),
- (-1.88472, -0.564419, 0.032334),
- (-1.924299, -0.375502, 0.032334),
- (-1.93184, -0.511778, 0.032334),
- (-1.946327, -0.44263, 0.032334),
- (-0.219065, -0.869195, 0.032334),
- (-0.149916, -0.854708, 0.032334),
- (-0.286193, -0.847167, 0.032334),
- (-0.097275, -0.807588, 0.032334),
- (0.692551, 0.434324, 0.032334),
- (0.678064, 0.503472, 0.032334),
- (0.670523, 0.367196, 0.032334),
- (0.630943, 0.556113, 0.032334),
- (-0.780424, -0.44263, 0.032334),
- (-0.765937, -0.511778, 0.032334),
- (-0.758396, -0.375502, 0.032334),
- (-0.718817, -0.564419, 0.032334),
- (-0.53496, 0.556113, 0.032334),
- (-0.49538, 0.367196, 0.032334),
- (-0.487839, 0.503472, 0.032334),
- (-0.473352, 0.434324, 0.032334),
- (-1.263178, -0.807588, 0.032334),
- (-1.452096, -0.847167, 0.032334),
- (-1.315819, -0.854708, 0.032334),
- (-1.384968, -0.869195, 0.032334),
- (0.131191, 0.86089, 0.032334),
- (0.062043, 0.846403, 0.032334),
- (0.19832, 0.838861, 0.032334),
- (0.009402, 0.799282, 0.032334),
- (0.946838, -0.869195, 0.032334),
- (1.015987, -0.854708, 0.032334),
- (0.87971, -0.847167, 0.032334),
- (1.068628, -0.807588, 0.032334),
- (1.858454, 0.434324, 0.032334),
- (1.843967, 0.503472, 0.032334),
- (1.836426, 0.367196, 0.032334),
- (1.796846, 0.556113, 0.032334),
- (0.385479, -0.44263, 0.032334),
- (0.399966, -0.511778, 0.032334),
- (0.407507, -0.375502, 0.032334),
- (0.447086, -0.564419, 0.032334),
- (1.297095, 0.86089, 0.032334),
- (1.227946, 0.846403, 0.032334),
- (1.364223, 0.838861, 0.032334),
- (1.175305, 0.799282, 0.032334),
- ],
- [[16, 17, 19], [5, 4, 24], [14, 12, 15], [14, 15, 31], [10, 8, 11], [15, 30, 31], [19, 10, 11],
- [11, 14, 31], [31, 18, 11], [8, 9, 11], [18, 16, 19], [12, 13, 15], [18, 19, 11], [28, 29, 31],
- [30, 28, 31], [24, 21, 0], [23, 22, 20], [20, 1, 0], [3, 2, 0], [0, 5, 24], [7, 6, 4], [4, 25, 24],
- [27, 26, 24], [21, 23, 20], [1, 3, 0], [5, 7, 4], [25, 27, 24], [21, 20, 0], [40, 41, 43], [38, 36, 39],
- [38, 39, 47], [34, 32, 35], [39, 46, 47], [43, 34, 35], [35, 38, 47], [47, 42, 35], [32, 33, 35],
- [42, 40, 43], [36, 37, 39], [42, 43, 35], [44, 45, 47], [46, 44, 47]]),
- ("CTP_8354",
- Vector((-0.06267, -2.43829, -0.0)),
- [(-0.534254, -1.0, 0.032334),
- (-1.0, -0.534254, 0.032334),
- (-0.654798, -0.98413, 0.032334),
- (-0.767127, -0.937602, 0.032334),
- (-0.863586, -0.863586, 0.032334),
- (-0.937602, -0.767127, 0.032334),
- (-0.98413, -0.654798, 0.032334),
- (1.0, -0.534254, 0.032334),
- (0.534254, -1.0, 0.032334),
- (0.98413, -0.654798, 0.032334),
- (0.937602, -0.767127, 0.032334),
- (0.863586, -0.863586, 0.032334),
- (0.767127, -0.937602, 0.032334),
- (0.654798, -0.98413, 0.032334),
- (-1.0, 0.534254, 0.032334),
- (-0.534254, 1.0, 0.032334),
- (-0.98413, 0.654798, 0.032334),
- (-0.937602, 0.767127, 0.032334),
- (-0.863586, 0.863586, 0.032334),
- (-0.767127, 0.937602, 0.032334),
- (-0.654798, 0.98413, 0.032334),
- (0.534254, 1.0, 0.032334),
- (1.0, 0.534254, 0.032334),
- (0.654798, 0.98413, 0.032334),
- (0.767127, 0.937602, 0.032334),
- (0.863586, 0.863586, 0.032334),
- (0.937602, 0.767127, 0.032334),
- (0.98413, 0.654798, 0.032334),
- (-0.763998, 0.518786, 0.032334),
- (-0.763998, -0.518786, 0.032334),
- (-0.754202, -0.593189, 0.032334),
- (-0.731454, -0.648108, 0.032334),
- (-0.695267, -0.695267, 0.032334),
- (-0.648108, -0.731454, 0.032334),
- (-0.593189, -0.754202, 0.032334),
- (-0.518786, -0.763998, 0.032334),
- (0.518786, -0.763998, 0.032334),
- (0.593189, -0.754202, 0.032334),
- (0.648108, -0.731454, 0.032334),
- (0.695267, -0.695267, 0.032334),
- (0.731454, -0.648108, 0.032334),
- (0.754202, -0.593189, 0.032334),
- (0.763998, -0.518786, 0.032334),
- (0.763998, 0.518786, 0.032334),
- (0.754202, 0.593189, 0.032334),
- (0.731454, 0.648108, 0.032334),
- (0.695267, 0.695267, 0.032334),
- (0.648108, 0.731454, 0.032334),
- (0.593189, 0.754202, 0.032334),
- (0.518786, 0.763998, 0.032334),
- (-0.518786, 0.763998, 0.032334),
- (-0.593189, 0.754202, 0.032334),
- (-0.648108, 0.731454, 0.032334),
- (-0.695267, 0.695267, 0.032334),
- (-0.731454, 0.648108, 0.032334),
- (-0.754202, 0.593189, 0.032334),
- (0.518786, 0.518786, 0.032334),
- (-0.518786, 0.518786, 0.032334),
- (0.518786, -0.518786, 0.032334),
- (-0.518786, -0.518786, 0.032334),
- (-0.593189, 0.518786, 0.032334),
- (-0.593189, -0.518786, 0.032334),
- (0.518786, -0.593189, 0.032334),
- (-0.518786, -0.593189, 0.032334),
- (-0.593189, -0.593189, 0.032334),
- (0.593189, 0.518786, 0.032334),
- (0.593189, -0.518786, 0.032334),
- (0.593189, -0.593189, 0.032334),
- (-0.593189, 0.593189, 0.032334),
- (-0.518786, 0.593189, 0.032334),
- (0.518786, 0.593189, 0.032334),
- (0.593189, 0.593189, 0.032334),
- (-0.648108, 0.593189, 0.032334),
- (-0.648108, 0.518786, 0.032334),
- (-0.648108, -0.518786, 0.032334),
- (-0.648108, -0.593189, 0.032334),
- (-0.695267, 0.593189, 0.032334),
- (-0.695267, 0.518786, 0.032334),
- (-0.695267, -0.518786, 0.032334),
- (-0.695267, -0.593189, 0.032334),
- (0.648108, 0.593189, 0.032334),
- (0.648108, 0.518786, 0.032334),
- (0.648108, -0.518786, 0.032334),
- (0.648108, -0.593189, 0.032334),
- (0.695267, 0.593189, 0.032334),
- (0.695267, 0.518786, 0.032334),
- (0.695267, -0.518786, 0.032334),
- (0.695267, -0.593189, 0.032334),
- ],
- [[87, 39, 40, 41], [29, 28, 14, 1], [30, 29, 1, 6], [31, 30, 6, 5], [32, 31, 5, 4], [33, 32, 4, 3],
- [34, 33, 3, 2], [35, 34, 2, 0], [36, 35, 0, 8], [37, 36, 8, 13], [38, 37, 13, 12], [39, 38, 12, 11],
- [40, 39, 11, 10], [41, 40, 10, 9], [42, 41, 9, 7], [43, 42, 7, 22], [44, 43, 22, 27], [45, 44, 27, 26],
- [46, 45, 26, 25], [47, 46, 25, 24], [48, 47, 24, 23], [49, 48, 23, 21], [50, 49, 21, 15], [51, 50, 15, 20],
- [52, 51, 20, 19], [53, 52, 19, 18], [54, 53, 18, 17], [55, 54, 17, 16], [28, 55, 16, 14], [68, 69, 50, 51],
- [63, 35, 36, 62], [69, 57, 56, 70], [84, 85, 43, 44], [64, 34, 35, 63], [57, 59, 58, 56], [85, 86, 42, 43],
- [60, 61, 59, 57], [73, 74, 61, 60], [72, 68, 51, 52], [75, 33, 34, 64], [61, 64, 63, 59], [59, 63, 62, 58],
- [86, 87, 41, 42], [74, 75, 64, 61], [58, 62, 67, 66], [56, 58, 66, 65], [70, 56, 65, 71], [62, 36, 37, 67],
- [49, 70, 71, 48], [50, 69, 70, 49], [60, 57, 69, 68], [73, 60, 68, 72], [46, 84, 44, 45], [78, 79, 75, 74],
- [77, 78, 74, 73], [77, 73, 72, 76], [76, 72, 52, 53], [79, 32, 33, 75], [29, 30, 79, 78], [28, 29, 78, 77],
- [28, 77, 76, 55], [55, 76, 53, 54], [30, 31, 32, 79], [66, 67, 83, 82], [65, 66, 82, 81], [71, 65, 81, 80],
- [48, 71, 80, 47], [67, 37, 38, 83], [82, 83, 87, 86], [81, 82, 86, 85], [80, 81, 85, 84], [47, 80, 84, 46],
- [83, 38, 39, 87]]),
- ("CTP_5585",
- Vector((5.0114, -2.4281, 0.0)),
- [(-0.490711, -1.0, 0.032334),
- (-1.0, -0.490711, 0.032334),
- (1.0, -0.490711, 0.032334),
- (0.490711, -1.0, 0.032334),
- (-1.0, 0.490711, 0.032334),
- (-0.490711, 1.0, 0.032334),
- (0.490711, 1.0, 0.032334),
- (1.0, 0.490711, 0.032334),
- (-0.51852, 0.291276, 0.032334),
- (-0.51852, -0.291276, 0.032334),
- (-0.291276, -0.51852, 0.032334),
- (0.291276, -0.51852, 0.032334),
- (0.51852, -0.291276, 0.032334),
- (0.51852, 0.291276, 0.032334),
- (0.291276, 0.51852, 0.032334),
- (-0.291276, 0.51852, 0.032334),
- ],
- [[11, 12, 13, 14], [9, 8, 4, 1], [10, 9, 1, 0], [11, 10, 0, 3], [12, 11, 3, 2], [13, 12, 2, 7],
- [14, 13, 7, 6], [15, 14, 6, 5], [8, 15, 5, 4], [9, 10, 15, 8], [10, 11, 14, 15]]),
- ("CTP_6960",
- Vector((-0.11417, 2.48371, -0.0)),
- [(0.0, 1.0, 0.016827),
- (-0.382683, 0.92388, 0.016827),
- (-0.707107, 0.707107, 0.016827),
- (-0.92388, 0.382683, 0.016827),
- (-1.0, -0.0, 0.016827),
- (-0.92388, -0.382684, 0.016827),
- (-0.707107, -0.707107, 0.016827),
- (-0.382683, -0.92388, 0.016827),
- (-0.0, -1.0, 0.016827),
- (0.382683, -0.92388, 0.016827),
- (0.707107, -0.707107, 0.016827),
- (0.92388, -0.382684, 0.016827),
- (1.0, 0.0, 0.016827),
- (0.923879, 0.382684, 0.016827),
- (0.707107, 0.707107, 0.016827),
- (0.382683, 0.92388, 0.016827),
- (-0.0, 0.546859, 0.016827),
- (-0.209274, 0.505231, 0.016827),
- (-0.386687, 0.386687, 0.016827),
- (-0.505231, 0.209274, 0.016827),
- (-0.546859, -0.0, 0.016827),
- (-0.505231, -0.209274, 0.016827),
- (-0.386687, -0.386687, 0.016827),
- (-0.209274, -0.505231, 0.016827),
- (-0.0, -0.546859, 0.016827),
- (0.209274, -0.505231, 0.016827),
- (0.386687, -0.386688, 0.016827),
- (0.505231, -0.209274, 0.016827),
- (0.546858, 0.0, 0.016827),
- (0.505231, 0.209274, 0.016827),
- (0.386687, 0.386688, 0.016827),
- (0.209273, 0.505232, 0.016827),
- ],
- [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
- [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
- [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
- ("CTP_5359",
- Vector((5.50446, 2.41669, -0.0)),
- [(0.0, 0.714247, 0.023261),
- (-0.382683, 0.659879, 0.023261),
- (-0.707107, 0.505049, 0.023261),
- (-0.92388, 0.273331, 0.023261),
- (-1.0, -0.0, 0.023261),
- (-0.92388, -0.273331, 0.023261),
- (-0.707107, -0.505049, 0.023261),
- (-0.382683, -0.659879, 0.023261),
- (-0.0, -0.714247, 0.023261),
- (0.382683, -0.659879, 0.023261),
- (0.707107, -0.505049, 0.023261),
- (0.92388, -0.273331, 0.023261),
- (1.0, 0.0, 0.023261),
- (0.923879, 0.273331, 0.023261),
- (0.707107, 0.505049, 0.023261),
- (0.382683, 0.659879, 0.023261),
- (-0.0, 0.303676, 0.023261),
- (-0.162705, 0.28056, 0.023261),
- (-0.30064, 0.214731, 0.023261),
- (-0.392805, 0.116212, 0.023261),
- (-0.425169, -0.0, 0.023261),
- (-0.392805, -0.116212, 0.023261),
- (-0.30064, -0.214731, 0.023261),
- (-0.162705, -0.28056, 0.023261),
- (-0.0, -0.303676, 0.023261),
- (0.162705, -0.28056, 0.023261),
- (0.30064, -0.214731, 0.023261),
- (0.392805, -0.116212, 0.023261),
- (0.425169, 0.0, 0.023261),
- (0.392805, 0.116212, 0.023261),
- (0.30064, 0.214731, 0.023261),
- (0.162705, 0.28056, 0.023261),
- ],
- [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
- [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
- [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
- ("CTP_5424",
- Vector((2.61824, 2.34147, 0.0)),
- [(1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- (0.783867, -0.259989, 0.032334),
- (-0.393641, 0.857073, 0.032334),
- (0.73142, -0.116299, 0.032334),
- (0.657754, 0.02916, 0.032334),
- (0.564682, 0.172804, 0.032334),
- (0.454497, 0.311098, 0.032334),
- (0.329912, 0.440635, 0.032334),
- (0.193995, 0.558227, 0.032334),
- (0.050092, 0.660978, 0.032334),
- (-0.098254, 0.746358, 0.032334),
- (-0.247389, 0.812263, 0.032334),
- ],
- [[3, 0, 2], [10, 9, 2], [2, 1, 4], [2, 4, 13], [5, 3, 2], [6, 5, 2], [2, 13, 12], [2, 12, 11], [7, 6, 2],
- [8, 7, 2], [2, 11, 10], [9, 8, 2]]),
- ("CTP_3774",
- Vector((2.61824, -2.52425, 0.0)),
- [(1.0, 0.0, 0.020045),
- (-1.0, 0.0, 0.020045),
- (0.31903, -0.664947, 0.020045),
- (-0.31903, -0.664947, 0.020045),
- (-0.31903, 1.0, 0.020045),
- (0.31903, 1.0, 0.020045),
- (0.31903, 0.0, 0.020045),
- (-0.31903, 0.0, 0.020045),
- (-1.0, 0.614333, 0.020045),
- (-0.614333, 1.0, 0.020045),
- (-0.970643, 0.761921, 0.020045),
- (-0.887041, 0.887041, 0.020045),
- (-0.761921, 0.970643, 0.020045),
- (0.614333, 1.0, 0.020045),
- (1.0, 0.614333, 0.020045),
- (0.761921, 0.970643, 0.020045),
- (0.887041, 0.887041, 0.020045),
- (0.970643, 0.761921, 0.020045),
- (-0.31903, 0.614333, 0.020045),
- (0.31903, 0.614333, 0.020045),
- (0.31903, 0.761921, 0.020045),
- (-0.31903, 0.761921, 0.020045),
- (0.31903, 0.887041, 0.020045),
- (-0.31903, 0.887041, 0.020045),
- (0.614333, 0.614333, 0.020045),
- (0.614333, 0.0, 0.020045),
- (0.614333, 0.761921, 0.020045),
- (0.614333, 0.887041, 0.020045),
- (-0.614333, 0.761921, 0.020045),
- (-0.614333, 0.0, 0.020045),
- (-0.614333, 0.887041, 0.020045),
- (-0.614333, 0.614333, 0.020045),
- ],
- [[6, 25, 24, 19], [6, 19, 18, 7], [2, 6, 7, 3], [1, 29, 31, 8], [8, 31, 28, 10], [19, 24, 26, 20],
- [18, 19, 20, 21], [21, 20, 22, 23], [10, 28, 30, 11], [20, 26, 27, 22], [22, 27, 13, 5], [23, 22, 5, 4],
- [11, 30, 9, 12], [17, 16, 27, 26], [14, 17, 26, 24], [24, 25, 0, 14], [15, 13, 27, 16], [9, 30, 23, 4],
- [31, 29, 7, 18], [28, 31, 18, 21], [30, 28, 21, 23]]),
- ("CTP_4473",
- Vector((7.31539, 0.0, 0.0)),
- [(0.24549, -1.0, 0.022454),
- (-0.24549, -1.0, 0.022454),
- (-0.24549, 1.0, 0.022454),
- (0.24549, 1.0, 0.022454),
- (1.0, 0.267452, 0.022454),
- (1.0, -0.267452, 0.022454),
- (-1.0, -0.267452, 0.022454),
- (-1.0, 0.267452, 0.022454),
- (0.24549, 0.267452, 0.022454),
- (0.24549, -0.267452, 0.022454),
- (-0.24549, 0.267452, 0.022454),
- (-0.24549, -0.267452, 0.022454),
- ],
- [[8, 3, 2, 10], [0, 9, 11, 1], [4, 8, 9, 5], [8, 10, 11, 9], [10, 7, 6, 11]]),
- ("CTP_4003",
- Vector((4.91276, 0.0, 0.0)),
- [(-1.0, -1.0, 0.026945),
- (1.0, -1.0, 0.026945),
- (-1.0, 1.0, 0.026945),
- (-0.026763, -1.0, 0.026945),
- (-0.026763, 1.0, 0.026945),
- (1.0, -0.026763, 0.026945),
- (0.238983, 0.965014, 0.026945),
- (0.486619, 0.86244, 0.026945),
- (0.699268, 0.699268, 0.026945),
- (0.86244, 0.486619, 0.026945),
- (0.965014, 0.238983, 0.026945),
- (0.238983, -1.0, 0.026945),
- (0.486619, -1.0, 0.026945),
- (0.699268, -1.0, 0.026945),
- (0.86244, -1.0, 0.026945),
- (-0.026763, 0.479676, 0.026945),
- (0.486619, 0.479676, 0.026945),
- (0.699268, 0.479676, 0.026945),
- (0.238983, 0.479676, 0.026945),
- (0.865316, 0.479676, 0.026945),
- (-1.0, 0.479676, 0.026945),
- (0.86244, 0.479676, 0.026945),
- (-0.026763, 0.238983, 0.026945),
- (0.486619, 0.238983, 0.026945),
- (0.699268, 0.238983, 0.026945),
- (0.238983, 0.238983, 0.026945),
- (-1.0, 0.238983, 0.026945),
- (0.86244, 0.238983, 0.026945),
- (-0.026763, -0.026763, 0.026945),
- (0.486619, -0.026763, 0.026945),
- (0.699268, -0.026763, 0.026945),
- (0.238983, -0.026763, 0.026945),
- (-1.0, -0.026763, 0.026945),
- (0.86244, -0.026763, 0.026945),
- ],
- [[0, 3, 28, 32], [4, 15, 18, 6], [6, 18, 16, 7], [7, 16, 17, 8], [8, 17, 21, 9], [9, 21, 19], [18, 15, 22, 25],
- [19, 21, 27, 10], [16, 18, 25, 23], [17, 16, 23, 24], [20, 15, 4, 2], [21, 17, 24, 27], [27, 24, 30, 33],
- [23, 25, 31, 29], [24, 23, 29, 30], [25, 22, 28, 31], [26, 22, 15, 20], [10, 27, 33, 5], [31, 28, 3, 11],
- [33, 30, 13, 14], [29, 31, 11, 12], [5, 33, 14, 1], [30, 29, 12, 13], [32, 28, 22, 26]]),
- ("CTP_3430",
- Vector((2.61824, 0.0, 0.0)),
- [(-1.0, -1.0, 0.032334),
- (1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- ],
- [[0, 1, 3, 2]]),
- ("CTP_7175",
- Vector((0.0, 0.0, 0.0)),
- [(-1.0, -1.0, 0.032334),
- (1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (-0.636126, 0.636126, 0.032334),
- (-0.636126, -0.636126, 0.032334),
- (0.636126, -0.636126, 0.032334),
- (0.636126, 0.636126, 0.032334),
- ],
- [[10, 9, 2, 0], [11, 10, 0, 1], [12, 11, 1, 3], [9, 12, 3, 2]]),
+ ("TEST",
+ Vector((0,0,1)),
+ [(-1, 1, 0.032334), (1, 1, 0.032334),(-1, -1, 0.032334), (1, -1, 0.01032334)],
+ [(0, 1, 2), (2,1,3)]),
+ ("CTP_4882",
+ Vector((2.61824, -5.56469, 0)),
+ [(-1.156501, 0.799282, 0.032334),
+ (-0.967583, 0.838861, 0.032334),
+ (-1.10386, 0.846403, 0.032334),
+ (-1.034712, 0.86089, 0.032334),
+ (-1.88472, -0.564419, 0.032334),
+ (-1.924299, -0.375502, 0.032334),
+ (-1.93184, -0.511778, 0.032334),
+ (-1.946327, -0.44263, 0.032334),
+ (-0.219065, -0.869195, 0.032334),
+ (-0.149916, -0.854708, 0.032334),
+ (-0.286193, -0.847167, 0.032334),
+ (-0.097275, -0.807588, 0.032334),
+ (0.692551, 0.434324, 0.032334),
+ (0.678064, 0.503472, 0.032334),
+ (0.670523, 0.367196, 0.032334),
+ (0.630943, 0.556113, 0.032334),
+ (-0.780424, -0.44263, 0.032334),
+ (-0.765937, -0.511778, 0.032334),
+ (-0.758396, -0.375502, 0.032334),
+ (-0.718817, -0.564419, 0.032334),
+ (-0.53496, 0.556113, 0.032334),
+ (-0.49538, 0.367196, 0.032334),
+ (-0.487839, 0.503472, 0.032334),
+ (-0.473352, 0.434324, 0.032334),
+ (-1.263178, -0.807588, 0.032334),
+ (-1.452096, -0.847167, 0.032334),
+ (-1.315819, -0.854708, 0.032334),
+ (-1.384968, -0.869195, 0.032334),
+ (0.131191, 0.86089, 0.032334),
+ (0.062043, 0.846403, 0.032334),
+ (0.19832, 0.838861, 0.032334),
+ (0.009402, 0.799282, 0.032334),
+ (0.946838, -0.869195, 0.032334),
+ (1.015987, -0.854708, 0.032334),
+ (0.87971, -0.847167, 0.032334),
+ (1.068628, -0.807588, 0.032334),
+ (1.858454, 0.434324, 0.032334),
+ (1.843967, 0.503472, 0.032334),
+ (1.836426, 0.367196, 0.032334),
+ (1.796846, 0.556113, 0.032334),
+ (0.385479, -0.44263, 0.032334),
+ (0.399966, -0.511778, 0.032334),
+ (0.407507, -0.375502, 0.032334),
+ (0.447086, -0.564419, 0.032334),
+ (1.297095, 0.86089, 0.032334),
+ (1.227946, 0.846403, 0.032334),
+ (1.364223, 0.838861, 0.032334),
+ (1.175305, 0.799282, 0.032334),
+ ],
+ [[16, 17, 19], [5, 4, 24], [14, 12, 15], [14, 15, 31], [10, 8, 11], [15, 30, 31], [19, 10, 11],
+ [11, 14, 31], [31, 18, 11], [8, 9, 11], [18, 16, 19], [12, 13, 15], [18, 19, 11], [28, 29, 31],
+ [30, 28, 31], [24, 21, 0], [23, 22, 20], [20, 1, 0], [3, 2, 0], [0, 5, 24], [7, 6, 4], [4, 25, 24],
+ [27, 26, 24], [21, 23, 20], [1, 3, 0], [5, 7, 4], [25, 27, 24], [21, 20, 0], [40, 41, 43], [38, 36, 39],
+ [38, 39, 47], [34, 32, 35], [39, 46, 47], [43, 34, 35], [35, 38, 47], [47, 42, 35], [32, 33, 35],
+ [42, 40, 43], [36, 37, 39], [42, 43, 35], [44, 45, 47], [46, 44, 47]]),
+ ("CTP_8354",
+ Vector((-0.06267, -2.43829, -0.0)),
+ [(-0.534254, -1.0, 0.032334),
+ (-1.0, -0.534254, 0.032334),
+ (-0.654798, -0.98413, 0.032334),
+ (-0.767127, -0.937602, 0.032334),
+ (-0.863586, -0.863586, 0.032334),
+ (-0.937602, -0.767127, 0.032334),
+ (-0.98413, -0.654798, 0.032334),
+ (1.0, -0.534254, 0.032334),
+ (0.534254, -1.0, 0.032334),
+ (0.98413, -0.654798, 0.032334),
+ (0.937602, -0.767127, 0.032334),
+ (0.863586, -0.863586, 0.032334),
+ (0.767127, -0.937602, 0.032334),
+ (0.654798, -0.98413, 0.032334),
+ (-1.0, 0.534254, 0.032334),
+ (-0.534254, 1.0, 0.032334),
+ (-0.98413, 0.654798, 0.032334),
+ (-0.937602, 0.767127, 0.032334),
+ (-0.863586, 0.863586, 0.032334),
+ (-0.767127, 0.937602, 0.032334),
+ (-0.654798, 0.98413, 0.032334),
+ (0.534254, 1.0, 0.032334),
+ (1.0, 0.534254, 0.032334),
+ (0.654798, 0.98413, 0.032334),
+ (0.767127, 0.937602, 0.032334),
+ (0.863586, 0.863586, 0.032334),
+ (0.937602, 0.767127, 0.032334),
+ (0.98413, 0.654798, 0.032334),
+ (-0.763998, 0.518786, 0.032334),
+ (-0.763998, -0.518786, 0.032334),
+ (-0.754202, -0.593189, 0.032334),
+ (-0.731454, -0.648108, 0.032334),
+ (-0.695267, -0.695267, 0.032334),
+ (-0.648108, -0.731454, 0.032334),
+ (-0.593189, -0.754202, 0.032334),
+ (-0.518786, -0.763998, 0.032334),
+ (0.518786, -0.763998, 0.032334),
+ (0.593189, -0.754202, 0.032334),
+ (0.648108, -0.731454, 0.032334),
+ (0.695267, -0.695267, 0.032334),
+ (0.731454, -0.648108, 0.032334),
+ (0.754202, -0.593189, 0.032334),
+ (0.763998, -0.518786, 0.032334),
+ (0.763998, 0.518786, 0.032334),
+ (0.754202, 0.593189, 0.032334),
+ (0.731454, 0.648108, 0.032334),
+ (0.695267, 0.695267, 0.032334),
+ (0.648108, 0.731454, 0.032334),
+ (0.593189, 0.754202, 0.032334),
+ (0.518786, 0.763998, 0.032334),
+ (-0.518786, 0.763998, 0.032334),
+ (-0.593189, 0.754202, 0.032334),
+ (-0.648108, 0.731454, 0.032334),
+ (-0.695267, 0.695267, 0.032334),
+ (-0.731454, 0.648108, 0.032334),
+ (-0.754202, 0.593189, 0.032334),
+ (0.518786, 0.518786, 0.032334),
+ (-0.518786, 0.518786, 0.032334),
+ (0.518786, -0.518786, 0.032334),
+ (-0.518786, -0.518786, 0.032334),
+ (-0.593189, 0.518786, 0.032334),
+ (-0.593189, -0.518786, 0.032334),
+ (0.518786, -0.593189, 0.032334),
+ (-0.518786, -0.593189, 0.032334),
+ (-0.593189, -0.593189, 0.032334),
+ (0.593189, 0.518786, 0.032334),
+ (0.593189, -0.518786, 0.032334),
+ (0.593189, -0.593189, 0.032334),
+ (-0.593189, 0.593189, 0.032334),
+ (-0.518786, 0.593189, 0.032334),
+ (0.518786, 0.593189, 0.032334),
+ (0.593189, 0.593189, 0.032334),
+ (-0.648108, 0.593189, 0.032334),
+ (-0.648108, 0.518786, 0.032334),
+ (-0.648108, -0.518786, 0.032334),
+ (-0.648108, -0.593189, 0.032334),
+ (-0.695267, 0.593189, 0.032334),
+ (-0.695267, 0.518786, 0.032334),
+ (-0.695267, -0.518786, 0.032334),
+ (-0.695267, -0.593189, 0.032334),
+ (0.648108, 0.593189, 0.032334),
+ (0.648108, 0.518786, 0.032334),
+ (0.648108, -0.518786, 0.032334),
+ (0.648108, -0.593189, 0.032334),
+ (0.695267, 0.593189, 0.032334),
+ (0.695267, 0.518786, 0.032334),
+ (0.695267, -0.518786, 0.032334),
+ (0.695267, -0.593189, 0.032334),
+ ],
+ [[87, 39, 40, 41], [29, 28, 14, 1], [30, 29, 1, 6], [31, 30, 6, 5], [32, 31, 5, 4], [33, 32, 4, 3],
+ [34, 33, 3, 2], [35, 34, 2, 0], [36, 35, 0, 8], [37, 36, 8, 13], [38, 37, 13, 12], [39, 38, 12, 11],
+ [40, 39, 11, 10], [41, 40, 10, 9], [42, 41, 9, 7], [43, 42, 7, 22], [44, 43, 22, 27], [45, 44, 27, 26],
+ [46, 45, 26, 25], [47, 46, 25, 24], [48, 47, 24, 23], [49, 48, 23, 21], [50, 49, 21, 15], [51, 50, 15, 20],
+ [52, 51, 20, 19], [53, 52, 19, 18], [54, 53, 18, 17], [55, 54, 17, 16], [28, 55, 16, 14], [68, 69, 50, 51],
+ [63, 35, 36, 62], [69, 57, 56, 70], [84, 85, 43, 44], [64, 34, 35, 63], [57, 59, 58, 56], [85, 86, 42, 43],
+ [60, 61, 59, 57], [73, 74, 61, 60], [72, 68, 51, 52], [75, 33, 34, 64], [61, 64, 63, 59], [59, 63, 62, 58],
+ [86, 87, 41, 42], [74, 75, 64, 61], [58, 62, 67, 66], [56, 58, 66, 65], [70, 56, 65, 71], [62, 36, 37, 67],
+ [49, 70, 71, 48], [50, 69, 70, 49], [60, 57, 69, 68], [73, 60, 68, 72], [46, 84, 44, 45], [78, 79, 75, 74],
+ [77, 78, 74, 73], [77, 73, 72, 76], [76, 72, 52, 53], [79, 32, 33, 75], [29, 30, 79, 78], [28, 29, 78, 77],
+ [28, 77, 76, 55], [55, 76, 53, 54], [30, 31, 32, 79], [66, 67, 83, 82], [65, 66, 82, 81], [71, 65, 81, 80],
+ [48, 71, 80, 47], [67, 37, 38, 83], [82, 83, 87, 86], [81, 82, 86, 85], [80, 81, 85, 84], [47, 80, 84, 46],
+ [83, 38, 39, 87]]),
+ ("CTP_5585",
+ Vector((5.0114, -2.4281, 0.0)),
+ [(-0.490711, -1.0, 0.032334),
+ (-1.0, -0.490711, 0.032334),
+ (1.0, -0.490711, 0.032334),
+ (0.490711, -1.0, 0.032334),
+ (-1.0, 0.490711, 0.032334),
+ (-0.490711, 1.0, 0.032334),
+ (0.490711, 1.0, 0.032334),
+ (1.0, 0.490711, 0.032334),
+ (-0.51852, 0.291276, 0.032334),
+ (-0.51852, -0.291276, 0.032334),
+ (-0.291276, -0.51852, 0.032334),
+ (0.291276, -0.51852, 0.032334),
+ (0.51852, -0.291276, 0.032334),
+ (0.51852, 0.291276, 0.032334),
+ (0.291276, 0.51852, 0.032334),
+ (-0.291276, 0.51852, 0.032334),
+ ],
+ [[11, 12, 13, 14], [9, 8, 4, 1], [10, 9, 1, 0], [11, 10, 0, 3], [12, 11, 3, 2], [13, 12, 2, 7],
+ [14, 13, 7, 6], [15, 14, 6, 5], [8, 15, 5, 4], [9, 10, 15, 8], [10, 11, 14, 15]]),
+ ("CTP_6960",
+ Vector((-0.11417, 2.48371, -0.0)),
+ [(0.0, 1.0, 0.016827),
+ (-0.382683, 0.92388, 0.016827),
+ (-0.707107, 0.707107, 0.016827),
+ (-0.92388, 0.382683, 0.016827),
+ (-1.0, -0.0, 0.016827),
+ (-0.92388, -0.382684, 0.016827),
+ (-0.707107, -0.707107, 0.016827),
+ (-0.382683, -0.92388, 0.016827),
+ (-0.0, -1.0, 0.016827),
+ (0.382683, -0.92388, 0.016827),
+ (0.707107, -0.707107, 0.016827),
+ (0.92388, -0.382684, 0.016827),
+ (1.0, 0.0, 0.016827),
+ (0.923879, 0.382684, 0.016827),
+ (0.707107, 0.707107, 0.016827),
+ (0.382683, 0.92388, 0.016827),
+ (-0.0, 0.546859, 0.016827),
+ (-0.209274, 0.505231, 0.016827),
+ (-0.386687, 0.386687, 0.016827),
+ (-0.505231, 0.209274, 0.016827),
+ (-0.546859, -0.0, 0.016827),
+ (-0.505231, -0.209274, 0.016827),
+ (-0.386687, -0.386687, 0.016827),
+ (-0.209274, -0.505231, 0.016827),
+ (-0.0, -0.546859, 0.016827),
+ (0.209274, -0.505231, 0.016827),
+ (0.386687, -0.386688, 0.016827),
+ (0.505231, -0.209274, 0.016827),
+ (0.546858, 0.0, 0.016827),
+ (0.505231, 0.209274, 0.016827),
+ (0.386687, 0.386688, 0.016827),
+ (0.209273, 0.505232, 0.016827),
+ ],
+ [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
+ [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
+ [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
+ ("CTP_5359",
+ Vector((5.50446, 2.41669, -0.0)),
+ [(0.0, 0.714247, 0.023261),
+ (-0.382683, 0.659879, 0.023261),
+ (-0.707107, 0.505049, 0.023261),
+ (-0.92388, 0.273331, 0.023261),
+ (-1.0, -0.0, 0.023261),
+ (-0.92388, -0.273331, 0.023261),
+ (-0.707107, -0.505049, 0.023261),
+ (-0.382683, -0.659879, 0.023261),
+ (-0.0, -0.714247, 0.023261),
+ (0.382683, -0.659879, 0.023261),
+ (0.707107, -0.505049, 0.023261),
+ (0.92388, -0.273331, 0.023261),
+ (1.0, 0.0, 0.023261),
+ (0.923879, 0.273331, 0.023261),
+ (0.707107, 0.505049, 0.023261),
+ (0.382683, 0.659879, 0.023261),
+ (-0.0, 0.303676, 0.023261),
+ (-0.162705, 0.28056, 0.023261),
+ (-0.30064, 0.214731, 0.023261),
+ (-0.392805, 0.116212, 0.023261),
+ (-0.425169, -0.0, 0.023261),
+ (-0.392805, -0.116212, 0.023261),
+ (-0.30064, -0.214731, 0.023261),
+ (-0.162705, -0.28056, 0.023261),
+ (-0.0, -0.303676, 0.023261),
+ (0.162705, -0.28056, 0.023261),
+ (0.30064, -0.214731, 0.023261),
+ (0.392805, -0.116212, 0.023261),
+ (0.425169, 0.0, 0.023261),
+ (0.392805, 0.116212, 0.023261),
+ (0.30064, 0.214731, 0.023261),
+ (0.162705, 0.28056, 0.023261),
+ ],
+ [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
+ [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
+ [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
+ ("CTP_5424",
+ Vector((2.61824, 2.34147, 0.0)),
+ [(1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ (0.783867, -0.259989, 0.032334),
+ (-0.393641, 0.857073, 0.032334),
+ (0.73142, -0.116299, 0.032334),
+ (0.657754, 0.02916, 0.032334),
+ (0.564682, 0.172804, 0.032334),
+ (0.454497, 0.311098, 0.032334),
+ (0.329912, 0.440635, 0.032334),
+ (0.193995, 0.558227, 0.032334),
+ (0.050092, 0.660978, 0.032334),
+ (-0.098254, 0.746358, 0.032334),
+ (-0.247389, 0.812263, 0.032334),
+ ],
+ [[3, 0, 2], [10, 9, 2], [2, 1, 4], [2, 4, 13], [5, 3, 2], [6, 5, 2], [2, 13, 12], [2, 12, 11], [7, 6, 2],
+ [8, 7, 2], [2, 11, 10], [9, 8, 2]]),
+ ("CTP_3774",
+ Vector((2.61824, -2.52425, 0.0)),
+ [(1.0, 0.0, 0.020045),
+ (-1.0, 0.0, 0.020045),
+ (0.31903, -0.664947, 0.020045),
+ (-0.31903, -0.664947, 0.020045),
+ (-0.31903, 1.0, 0.020045),
+ (0.31903, 1.0, 0.020045),
+ (0.31903, 0.0, 0.020045),
+ (-0.31903, 0.0, 0.020045),
+ (-1.0, 0.614333, 0.020045),
+ (-0.614333, 1.0, 0.020045),
+ (-0.970643, 0.761921, 0.020045),
+ (-0.887041, 0.887041, 0.020045),
+ (-0.761921, 0.970643, 0.020045),
+ (0.614333, 1.0, 0.020045),
+ (1.0, 0.614333, 0.020045),
+ (0.761921, 0.970643, 0.020045),
+ (0.887041, 0.887041, 0.020045),
+ (0.970643, 0.761921, 0.020045),
+ (-0.31903, 0.614333, 0.020045),
+ (0.31903, 0.614333, 0.020045),
+ (0.31903, 0.761921, 0.020045),
+ (-0.31903, 0.761921, 0.020045),
+ (0.31903, 0.887041, 0.020045),
+ (-0.31903, 0.887041, 0.020045),
+ (0.614333, 0.614333, 0.020045),
+ (0.614333, 0.0, 0.020045),
+ (0.614333, 0.761921, 0.020045),
+ (0.614333, 0.887041, 0.020045),
+ (-0.614333, 0.761921, 0.020045),
+ (-0.614333, 0.0, 0.020045),
+ (-0.614333, 0.887041, 0.020045),
+ (-0.614333, 0.614333, 0.020045),
+ ],
+ [[6, 25, 24, 19], [6, 19, 18, 7], [2, 6, 7, 3], [1, 29, 31, 8], [8, 31, 28, 10], [19, 24, 26, 20],
+ [18, 19, 20, 21], [21, 20, 22, 23], [10, 28, 30, 11], [20, 26, 27, 22], [22, 27, 13, 5], [23, 22, 5, 4],
+ [11, 30, 9, 12], [17, 16, 27, 26], [14, 17, 26, 24], [24, 25, 0, 14], [15, 13, 27, 16], [9, 30, 23, 4],
+ [31, 29, 7, 18], [28, 31, 18, 21], [30, 28, 21, 23]]),
+ ("CTP_4473",
+ Vector((7.31539, 0.0, 0.0)),
+ [(0.24549, -1.0, 0.022454),
+ (-0.24549, -1.0, 0.022454),
+ (-0.24549, 1.0, 0.022454),
+ (0.24549, 1.0, 0.022454),
+ (1.0, 0.267452, 0.022454),
+ (1.0, -0.267452, 0.022454),
+ (-1.0, -0.267452, 0.022454),
+ (-1.0, 0.267452, 0.022454),
+ (0.24549, 0.267452, 0.022454),
+ (0.24549, -0.267452, 0.022454),
+ (-0.24549, 0.267452, 0.022454),
+ (-0.24549, -0.267452, 0.022454),
+ ],
+ [[8, 3, 2, 10], [0, 9, 11, 1], [4, 8, 9, 5], [8, 10, 11, 9], [10, 7, 6, 11]]),
+ ("CTP_4003",
+ Vector((4.91276, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.026945),
+ (1.0, -1.0, 0.026945),
+ (-1.0, 1.0, 0.026945),
+ (-0.026763, -1.0, 0.026945),
+ (-0.026763, 1.0, 0.026945),
+ (1.0, -0.026763, 0.026945),
+ (0.238983, 0.965014, 0.026945),
+ (0.486619, 0.86244, 0.026945),
+ (0.699268, 0.699268, 0.026945),
+ (0.86244, 0.486619, 0.026945),
+ (0.965014, 0.238983, 0.026945),
+ (0.238983, -1.0, 0.026945),
+ (0.486619, -1.0, 0.026945),
+ (0.699268, -1.0, 0.026945),
+ (0.86244, -1.0, 0.026945),
+ (-0.026763, 0.479676, 0.026945),
+ (0.486619, 0.479676, 0.026945),
+ (0.699268, 0.479676, 0.026945),
+ (0.238983, 0.479676, 0.026945),
+ (0.865316, 0.479676, 0.026945),
+ (-1.0, 0.479676, 0.026945),
+ (0.86244, 0.479676, 0.026945),
+ (-0.026763, 0.238983, 0.026945),
+ (0.486619, 0.238983, 0.026945),
+ (0.699268, 0.238983, 0.026945),
+ (0.238983, 0.238983, 0.026945),
+ (-1.0, 0.238983, 0.026945),
+ (0.86244, 0.238983, 0.026945),
+ (-0.026763, -0.026763, 0.026945),
+ (0.486619, -0.026763, 0.026945),
+ (0.699268, -0.026763, 0.026945),
+ (0.238983, -0.026763, 0.026945),
+ (-1.0, -0.026763, 0.026945),
+ (0.86244, -0.026763, 0.026945),
+ ],
+ [[0, 3, 28, 32], [4, 15, 18, 6], [6, 18, 16, 7], [7, 16, 17, 8], [8, 17, 21, 9], [9, 21, 19], [18, 15, 22, 25],
+ [19, 21, 27, 10], [16, 18, 25, 23], [17, 16, 23, 24], [20, 15, 4, 2], [21, 17, 24, 27], [27, 24, 30, 33],
+ [23, 25, 31, 29], [24, 23, 29, 30], [25, 22, 28, 31], [26, 22, 15, 20], [10, 27, 33, 5], [31, 28, 3, 11],
+ [33, 30, 13, 14], [29, 31, 11, 12], [5, 33, 14, 1], [30, 29, 12, 13], [32, 28, 22, 26]]),
+ ("CTP_3430",
+ Vector((2.61824, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.032334),
+ (1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ ],
+ [[0, 1, 3, 2]]),
+ ("CTP_7175",
+ Vector((0.0, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.032334),
+ (1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (-0.636126, 0.636126, 0.032334),
+ (-0.636126, -0.636126, 0.032334),
+ (0.636126, -0.636126, 0.032334),
+ (0.636126, 0.636126, 0.032334),
+ ],
+ [[10, 9, 2, 0], [11, 10, 0, 1], [12, 11, 1, 3], [9, 12, 3, 2]]),
]
diff --git a/object_carver/carver_utils.py b/object_carver/carver_utils.py
index ce66052f..495aa1ce 100644
--- a/object_carver/carver_utils.py
+++ b/object_carver/carver_utils.py
@@ -8,934 +8,934 @@ import sys
import random
import bmesh
from mathutils import (
- Euler,
- Matrix,
- Vector,
- Quaternion,
+ Euler,
+ Matrix,
+ Vector,
+ Quaternion,
)
from mathutils.geometry import (
- intersect_line_plane,
+ intersect_line_plane,
)
from math import (
- sin,
- cos,
- pi,
- )
+ sin,
+ cos,
+ pi,
+ )
import bpy_extras
from bpy_extras import view3d_utils
from bpy_extras.view3d_utils import (
- region_2d_to_vector_3d,
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_vector_3d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
# Cut Square
def CreateCutSquare(self, context):
- """ Create a rectangle mesh """
- far_limit = 10000.0
- faces=[]
-
- # Get the mouse coordinates
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Square')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Square', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- if self.snapCursor:
- plane_point = context.scene.cursor.location
- else:
- plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
-
- # Find the intersection of a line going thru each vertex and the infinite plane
- for v_co in self.rectangle_coord:
- vec = region_2d_to_vector_3d(region, rv3d, v_co)
- p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
- p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
- faces.append(bm.verts.new(intersect_line_plane(p0, p1, plane_point, plane_direction)))
-
- # Update vertices index
- bm.verts.index_update()
- # New faces
- t_face = bm.faces.new(faces)
- # Set mesh
- bm.to_mesh(me)
+ """ Create a rectangle mesh """
+ far_limit = 10000.0
+ faces=[]
+
+ # Get the mouse coordinates
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Square')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Square', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ if self.snapCursor:
+ plane_point = context.scene.cursor.location
+ else:
+ plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
+
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for v_co in self.rectangle_coord:
+ vec = region_2d_to_vector_3d(region, rv3d, v_co)
+ p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
+ p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
+ faces.append(bm.verts.new(intersect_line_plane(p0, p1, plane_point, plane_direction)))
+
+ # Update vertices index
+ bm.verts.index_update()
+ # New faces
+ t_face = bm.faces.new(faces)
+ # Set mesh
+ bm.to_mesh(me)
# Cut Line
def CreateCutLine(self, context):
- """ Create a polygon mesh """
- far_limit = 10000.0
- vertices = []
- faces = []
- loc = []
-
- # Get the mouse coordinates
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Line')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Line', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- if self.snapCursor:
- plane_point = context.scene.cursor.location
- else:
- plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
-
- # Use dict to remove doubles
- # Find the intersection of a line going thru each vertex and the infinite plane
- for idx, v_co in enumerate(list(dict.fromkeys(self.mouse_path))):
- vec = region_2d_to_vector_3d(region, rv3d, v_co)
- p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
- p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
- loc.append(intersect_line_plane(p0, p1, plane_point, plane_direction))
- vertices.append(bm.verts.new(loc[idx]))
-
- if idx > 0:
- bm.edges.new([vertices[idx-1],vertices[idx]])
-
- faces.append(vertices[idx])
-
- # Update vertices index
- bm.verts.index_update()
-
- # Nothing is selected, create close geometry
- if self.CreateMode:
- if self.Closed and len(vertices) > 1:
- bm.edges.new([vertices[-1], vertices[0]])
- bm.faces.new(faces)
- else:
- # Create faces if more than 2 vertices
- if len(vertices) > 1 :
- bm.edges.new([vertices[-1], vertices[0]])
- bm.faces.new(faces)
-
- bm.to_mesh(me)
+ """ Create a polygon mesh """
+ far_limit = 10000.0
+ vertices = []
+ faces = []
+ loc = []
+
+ # Get the mouse coordinates
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Line')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Line', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ if self.snapCursor:
+ plane_point = context.scene.cursor.location
+ else:
+ plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
+
+ # Use dict to remove doubles
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for idx, v_co in enumerate(list(dict.fromkeys(self.mouse_path))):
+ vec = region_2d_to_vector_3d(region, rv3d, v_co)
+ p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
+ p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
+ loc.append(intersect_line_plane(p0, p1, plane_point, plane_direction))
+ vertices.append(bm.verts.new(loc[idx]))
+
+ if idx > 0:
+ bm.edges.new([vertices[idx-1],vertices[idx]])
+
+ faces.append(vertices[idx])
+
+ # Update vertices index
+ bm.verts.index_update()
+
+ # Nothing is selected, create close geometry
+ if self.CreateMode:
+ if self.Closed and len(vertices) > 1:
+ bm.edges.new([vertices[-1], vertices[0]])
+ bm.faces.new(faces)
+ else:
+ # Create faces if more than 2 vertices
+ if len(vertices) > 1 :
+ bm.edges.new([vertices[-1], vertices[0]])
+ bm.faces.new(faces)
+
+ bm.to_mesh(me)
# Cut Circle
def CreateCutCircle(self, context):
- """ Create a circle mesh """
- far_limit = 10000.0
- FacesList = []
-
- # Get the mouse coordinates
- mouse_pos_x = self.mouse_path[0][0]
- mouse_pos_y = self.mouse_path[0][1]
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_point = context.scene.cursor.location if self.snapCursor else Vector((0.0, 0.0, 0.0))
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Circle')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Circle', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Create a circle using a tri fan
- tris_fan, indices = draw_circle(self, mouse_pos_x, mouse_pos_y)
-
- # Remove the vertex in the center to get the outer line of the circle
- verts = tris_fan[1:]
-
- # Find the intersection of a line going thru each vertex and the infinite plane
- for vert in verts:
- vec = region_2d_to_vector_3d(region, rv3d, vert)
- p0 = region_2d_to_location_3d(region, rv3d, vert, vec)
- p1 = p0 + plane_direction * far_limit
- loc0 = intersect_line_plane(p0, p1, plane_point, plane_direction)
- t_v0 = bm.verts.new(loc0)
- FacesList.append(t_v0)
-
- bm.verts.index_update()
- bm.faces.new(FacesList)
- bm.to_mesh(me)
+ """ Create a circle mesh """
+ far_limit = 10000.0
+ FacesList = []
+
+ # Get the mouse coordinates
+ mouse_pos_x = self.mouse_path[0][0]
+ mouse_pos_y = self.mouse_path[0][1]
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_point = context.scene.cursor.location if self.snapCursor else Vector((0.0, 0.0, 0.0))
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Circle')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Circle', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Create a circle using a tri fan
+ tris_fan, indices = draw_circle(self, mouse_pos_x, mouse_pos_y)
+
+ # Remove the vertex in the center to get the outer line of the circle
+ verts = tris_fan[1:]
+
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for vert in verts:
+ vec = region_2d_to_vector_3d(region, rv3d, vert)
+ p0 = region_2d_to_location_3d(region, rv3d, vert, vec)
+ p1 = p0 + plane_direction * far_limit
+ loc0 = intersect_line_plane(p0, p1, plane_point, plane_direction)
+ t_v0 = bm.verts.new(loc0)
+ FacesList.append(t_v0)
+
+ bm.verts.index_update()
+ bm.faces.new(FacesList)
+ bm.to_mesh(me)
def create_2d_circle(self, step, radius, rotation = 0):
- """ Create the vertices of a 2d circle at (0,0) """
- verts = []
- for angle in range(0, 360, step):
- verts.append(math.cos(math.radians(angle + rotation)) * radius)
- verts.append(math.sin(math.radians(angle + rotation)) * radius)
- verts.append(0.0)
- verts.append(math.cos(math.radians(0.0 + rotation)) * radius)
- verts.append(math.sin(math.radians(0.0 + rotation)) * radius)
- verts.append(0.0)
- return(verts)
+ """ Create the vertices of a 2d circle at (0,0) """
+ verts = []
+ for angle in range(0, 360, step):
+ verts.append(math.cos(math.radians(angle + rotation)) * radius)
+ verts.append(math.sin(math.radians(angle + rotation)) * radius)
+ verts.append(0.0)
+ verts.append(math.cos(math.radians(0.0 + rotation)) * radius)
+ verts.append(math.sin(math.radians(0.0 + rotation)) * radius)
+ verts.append(0.0)
+ return(verts)
def draw_circle(self, mouse_pos_x, mouse_pos_y):
- """ Return the coordinates + indices of a circle using a triangle fan """
- tris_verts = []
- indices = []
- segments = int(360 / self.stepAngle[self.step])
- radius = self.mouse_path[1][0] - self.mouse_path[0][0]
- rotation = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 2
+ """ Return the coordinates + indices of a circle using a triangle fan """
+ tris_verts = []
+ indices = []
+ segments = int(360 / self.stepAngle[self.step])
+ radius = self.mouse_path[1][0] - self.mouse_path[0][0]
+ rotation = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 2
- # Get the vertices of a 2d circle
- verts = create_2d_circle(self, self.stepAngle[self.step], radius, rotation)
+ # Get the vertices of a 2d circle
+ verts = create_2d_circle(self, self.stepAngle[self.step], radius, rotation)
- # Create the first vertex at mouse position for the center of the circle
- tris_verts.append(Vector((mouse_pos_x + self.xpos , mouse_pos_y + self.ypos)))
+ # Create the first vertex at mouse position for the center of the circle
+ tris_verts.append(Vector((mouse_pos_x + self.xpos , mouse_pos_y + self.ypos)))
- # For each vertex of the circle, add the mouse position and the translation
- for idx in range(int(len(verts) / 3) - 1):
- tris_verts.append(Vector((verts[idx * 3] + mouse_pos_x + self.xpos, \
- verts[idx * 3 + 1] + mouse_pos_y + self.ypos)))
- i1 = idx+1
- i2 = idx+2 if idx+2 <= segments else 1
- indices.append((0,i1,i2))
+ # For each vertex of the circle, add the mouse position and the translation
+ for idx in range(int(len(verts) / 3) - 1):
+ tris_verts.append(Vector((verts[idx * 3] + mouse_pos_x + self.xpos, \
+ verts[idx * 3 + 1] + mouse_pos_y + self.ypos)))
+ i1 = idx+1
+ i2 = idx+2 if idx+2 <= segments else 1
+ indices.append((0,i1,i2))
- return(tris_verts, indices)
+ return(tris_verts, indices)
# Object dimensions (SCULPT Tools tips)
def objDiagonal(obj):
- return ((obj.dimensions[0]**2) + (obj.dimensions[1]**2) + (obj.dimensions[2]**2))**0.5
+ return ((obj.dimensions[0]**2) + (obj.dimensions[1]**2) + (obj.dimensions[2]**2))**0.5
# Bevel Update
def update_bevel(context):
- selection = context.selected_objects.copy()
- active = context.active_object
+ selection = context.selected_objects.copy()
+ active = context.active_object
- if len(selection) > 0:
- for obj in selection:
- bpy.ops.object.select_all(action='DESELECT')
- obj.select_set(True)
- context.view_layer.objects.active = obj
+ if len(selection) > 0:
+ for obj in selection:
+ bpy.ops.object.select_all(action='DESELECT')
+ obj.select_set(True)
+ context.view_layer.objects.active = obj
- # Test object name
- # Subdive mode : Only bevel weight
- if obj.data.name.startswith("S_") or obj.data.name.startswith("S "):
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.region_to_loop()
- bpy.ops.transform.edge_bevelweight(value=1)
- bpy.ops.object.mode_set(mode='OBJECT')
+ # Test object name
+ # Subdive mode : Only bevel weight
+ if obj.data.name.startswith("S_") or obj.data.name.startswith("S "):
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.region_to_loop()
+ bpy.ops.transform.edge_bevelweight(value=1)
+ bpy.ops.object.mode_set(mode='OBJECT')
- else:
- # No subdiv mode : bevel weight + Crease + Sharp
- CreateBevel(context, obj)
+ else:
+ # No subdiv mode : bevel weight + Crease + Sharp
+ CreateBevel(context, obj)
- bpy.ops.object.select_all(action='DESELECT')
+ bpy.ops.object.select_all(action='DESELECT')
- for obj in selection:
- obj.select_set(True)
- context.view_layer.objects.active = active
+ for obj in selection:
+ obj.select_set(True)
+ context.view_layer.objects.active = active
# Create bevel
def CreateBevel(context, CurrentObject):
- # Save active object
- SavActive = context.active_object
+ # Save active object
+ SavActive = context.active_object
- # Test if initial object has bevel
- bevel_modifier = False
- for modifier in SavActive.modifiers:
- if modifier.name == 'Bevel':
- bevel_modifier = True
+ # Test if initial object has bevel
+ bevel_modifier = False
+ for modifier in SavActive.modifiers:
+ if modifier.name == 'Bevel':
+ bevel_modifier = True
- if bevel_modifier:
- # Active "CurrentObject"
- context.view_layer.objects.active = CurrentObject
+ if bevel_modifier:
+ # Active "CurrentObject"
+ context.view_layer.objects.active = CurrentObject
- bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.object.mode_set(mode='EDIT')
- # Edge mode
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- # Clear all
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.mark_sharp(clear=True)
- bpy.ops.transform.edge_crease(value=-1)
- bpy.ops.transform.edge_bevelweight(value=-1)
+ # Edge mode
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ # Clear all
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.mark_sharp(clear=True)
+ bpy.ops.transform.edge_crease(value=-1)
+ bpy.ops.transform.edge_bevelweight(value=-1)
- bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.mesh.select_all(action='DESELECT')
- # Select (in radians) all 30° sharp edges
- bpy.ops.mesh.edges_select_sharp(sharpness=0.523599)
- # Apply bevel weight + Crease + Sharp to the selected edges
- bpy.ops.mesh.mark_sharp()
- bpy.ops.transform.edge_crease(value=1)
- bpy.ops.transform.edge_bevelweight(value=1)
+ # Select (in radians) all 30° sharp edges
+ bpy.ops.mesh.edges_select_sharp(sharpness=0.523599)
+ # Apply bevel weight + Crease + Sharp to the selected edges
+ bpy.ops.mesh.mark_sharp()
+ bpy.ops.transform.edge_crease(value=1)
+ bpy.ops.transform.edge_bevelweight(value=1)
- bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.mesh.select_all(action='DESELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
- CurrentObject.data.use_customdata_edge_bevel = True
+ CurrentObject.data.use_customdata_edge_bevel = True
- for i in range(len(CurrentObject.data.edges)):
- if CurrentObject.data.edges[i].select is True:
- CurrentObject.data.edges[i].bevel_weight = 1.0
- CurrentObject.data.edges[i].use_edge_sharp = True
+ for i in range(len(CurrentObject.data.edges)):
+ if CurrentObject.data.edges[i].select is True:
+ CurrentObject.data.edges[i].bevel_weight = 1.0
+ CurrentObject.data.edges[i].use_edge_sharp = True
- bevel_modifier = False
- for m in CurrentObject.modifiers:
- if m.name == 'Bevel':
- bevel_modifier = True
+ bevel_modifier = False
+ for m in CurrentObject.modifiers:
+ if m.name == 'Bevel':
+ bevel_modifier = True
- if bevel_modifier is False:
- bpy.ops.object.modifier_add(type='BEVEL')
- mod = context.object.modifiers[-1]
- mod.limit_method = 'WEIGHT'
- mod.width = 0.01
- mod.profile = 0.699099
- mod.use_clight_overlap = False
- mod.segments = 3
- mod.loop_slide = False
+ if bevel_modifier is False:
+ bpy.ops.object.modifier_add(type='BEVEL')
+ mod = context.object.modifiers[-1]
+ mod.limit_method = 'WEIGHT'
+ mod.width = 0.01
+ mod.profile = 0.699099
+ mod.use_clight_overlap = False
+ mod.segments = 3
+ mod.loop_slide = False
- bpy.ops.object.shade_smooth()
+ bpy.ops.object.shade_smooth()
- context.object.data.use_auto_smooth = True
- context.object.data.auto_smooth_angle = 1.0471975
+ context.object.data.use_auto_smooth = True
+ context.object.data.auto_smooth_angle = 1.0471975
- # Restore the active object
- context.view_layer.objects.active = SavActive
+ # Restore the active object
+ context.view_layer.objects.active = SavActive
def MoveCursor(qRot, location, self):
- """ In brush mode : Draw a circle around the brush """
- if qRot is not None:
- verts = create_2d_circle(self, 10, 1)
- self.CLR_C.clear()
- vc = Vector()
- for idx in range(int(len(verts) / 3)):
- vc.x = verts[idx * 3]
- vc.y = verts[idx * 3 + 1]
- vc.z = verts[idx * 3 + 2]
- vc = qRot @ vc
- self.CLR_C.append(vc.x)
- self.CLR_C.append(vc.y)
- self.CLR_C.append(vc.z)
+ """ In brush mode : Draw a circle around the brush """
+ if qRot is not None:
+ verts = create_2d_circle(self, 10, 1)
+ self.CLR_C.clear()
+ vc = Vector()
+ for idx in range(int(len(verts) / 3)):
+ vc.x = verts[idx * 3]
+ vc.y = verts[idx * 3 + 1]
+ vc.z = verts[idx * 3 + 2]
+ vc = qRot @ vc
+ self.CLR_C.append(vc.x)
+ self.CLR_C.append(vc.y)
+ self.CLR_C.append(vc.z)
def rot_axis_quat(vector1, vector2):
- """ Find the rotation (quaternion) from vector 1 to vector 2"""
- vector1 = vector1.normalized()
- vector2 = vector2.normalized()
- cosTheta = vector1.dot(vector2)
- rotationAxis = Vector((0.0, 0.0, 0.0))
- if (cosTheta < -1 + 0.001):
- v = Vector((0.0, 1.0, 0.0))
- #Get the vector at the right angles to both
- rotationAxis = vector1.cross(v)
- rotationAxis = rotationAxis.normalized()
- q = Quaternion()
- q.w = 0.0
- q.x = rotationAxis.x
- q.y = rotationAxis.y
- q.z = rotationAxis.z
- else:
- rotationAxis = vector1.cross(vector2)
- s = math.sqrt((1.0 + cosTheta) * 2.0)
- invs = 1 / s
- q = Quaternion()
- q.w = s * 0.5
- q.x = rotationAxis.x * invs
- q.y = rotationAxis.y * invs
- q.z = rotationAxis.z * invs
- return q
+ """ Find the rotation (quaternion) from vector 1 to vector 2"""
+ vector1 = vector1.normalized()
+ vector2 = vector2.normalized()
+ cosTheta = vector1.dot(vector2)
+ rotationAxis = Vector((0.0, 0.0, 0.0))
+ if (cosTheta < -1 + 0.001):
+ v = Vector((0.0, 1.0, 0.0))
+ #Get the vector at the right angles to both
+ rotationAxis = vector1.cross(v)
+ rotationAxis = rotationAxis.normalized()
+ q = Quaternion()
+ q.w = 0.0
+ q.x = rotationAxis.x
+ q.y = rotationAxis.y
+ q.z = rotationAxis.z
+ else:
+ rotationAxis = vector1.cross(vector2)
+ s = math.sqrt((1.0 + cosTheta) * 2.0)
+ invs = 1 / s
+ q = Quaternion()
+ q.w = s * 0.5
+ q.x = rotationAxis.x * invs
+ q.y = rotationAxis.y * invs
+ q.z = rotationAxis.z * invs
+ return q
# Picking (template)
def Picking(context, event):
- """ Put the 3d cursor on the closest object"""
-
- # get the context arguments
- scene = context.scene
- region = context.region
- rv3d = context.region_data
- coord = event.mouse_region_x, event.mouse_region_y
-
- # get the ray from the viewport and mouse
- view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
- ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- ray_target = ray_origin + view_vector
-
- def visible_objects_and_duplis():
- depsgraph = context.evaluated_depsgraph_get()
- for dup in depsgraph.object_instances:
- if dup.is_instance: # Real dupli instance
- obj = dup.instance_object.original
- yield (obj, dup.matrix.copy())
- else: # Usual object
- obj = dup.object.original
- yield (obj, obj.matrix_world.copy())
-
- def obj_ray_cast(obj, matrix):
- # get the ray relative to the object
- matrix_inv = matrix.inverted()
- ray_origin_obj = matrix_inv @ ray_origin
- ray_target_obj = matrix_inv @ ray_target
- ray_direction_obj = ray_target_obj - ray_origin_obj
- # cast the ray
- success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
- if success:
- return location, normal, face_index
- return None, None, None
-
- # cast rays and find the closest object
- best_length_squared = -1.0
- best_obj = None
-
- # cast rays and find the closest object
- for obj, matrix in visible_objects_and_duplis():
- if obj.type == 'MESH':
- hit, normal, face_index = obj_ray_cast(obj, matrix)
- if hit is not None:
- hit_world = matrix @ hit
- length_squared = (hit_world - ray_origin).length_squared
- if best_obj is None or length_squared < best_length_squared:
- scene.cursor.location = hit_world
- best_length_squared = length_squared
- best_obj = obj
- else:
- if best_obj is None:
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- loc = region_2d_to_location_3d(region, rv3d, coord, depth_location)
- scene.cursor.location = loc
+ """ Put the 3d cursor on the closest object"""
+
+ # get the context arguments
+ scene = context.scene
+ region = context.region
+ rv3d = context.region_data
+ coord = event.mouse_region_x, event.mouse_region_y
+
+ # get the ray from the viewport and mouse
+ view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
+ ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+ ray_target = ray_origin + view_vector
+
+ def visible_objects_and_duplis():
+ depsgraph = context.evaluated_depsgraph_get()
+ for dup in depsgraph.object_instances:
+ if dup.is_instance: # Real dupli instance
+ obj = dup.instance_object.original
+ yield (obj, dup.matrix.copy())
+ else: # Usual object
+ obj = dup.object.original
+ yield (obj, obj.matrix_world.copy())
+
+ def obj_ray_cast(obj, matrix):
+ # get the ray relative to the object
+ matrix_inv = matrix.inverted()
+ ray_origin_obj = matrix_inv @ ray_origin
+ ray_target_obj = matrix_inv @ ray_target
+ ray_direction_obj = ray_target_obj - ray_origin_obj
+ # cast the ray
+ success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
+ if success:
+ return location, normal, face_index
+ return None, None, None
+
+ # cast rays and find the closest object
+ best_length_squared = -1.0
+ best_obj = None
+
+ # cast rays and find the closest object
+ for obj, matrix in visible_objects_and_duplis():
+ if obj.type == 'MESH':
+ hit, normal, face_index = obj_ray_cast(obj, matrix)
+ if hit is not None:
+ hit_world = matrix @ hit
+ length_squared = (hit_world - ray_origin).length_squared
+ if best_obj is None or length_squared < best_length_squared:
+ scene.cursor.location = hit_world
+ best_length_squared = length_squared
+ best_obj = obj
+ else:
+ if best_obj is None:
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ loc = region_2d_to_location_3d(region, rv3d, coord, depth_location)
+ scene.cursor.location = loc
def Pick(context, event, self, ray_max=10000.0):
- region = context.region
- rv3d = context.region_data
- coord = event.mouse_region_x, event.mouse_region_y
- view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
- ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- ray_target = ray_origin + (view_vector * ray_max)
-
- def obj_ray_cast(obj, matrix):
- matrix_inv = matrix.inverted()
- ray_origin_obj = matrix_inv @ ray_origin
- ray_target_obj = matrix_inv @ ray_target
- success, hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
- if success:
- return hit, normal, face_index
- return None, None, None
-
- best_length_squared = ray_max * ray_max
- best_obj = None
- for obj in self.CList:
- matrix = obj.matrix_world
- hit, normal, face_index = obj_ray_cast(obj, matrix)
- rotation = obj.rotation_euler.to_quaternion()
- if hit is not None:
- hit_world = matrix @ hit
- length_squared = (hit_world - ray_origin).length_squared
- if length_squared < best_length_squared:
- best_length_squared = length_squared
- best_obj = obj
- hits = hit_world
- ns = normal
- fs = face_index
-
- if best_obj is not None:
- return hits, ns, rotation
-
- return None, None, None
+ region = context.region
+ rv3d = context.region_data
+ coord = event.mouse_region_x, event.mouse_region_y
+ view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
+ ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+ ray_target = ray_origin + (view_vector * ray_max)
+
+ def obj_ray_cast(obj, matrix):
+ matrix_inv = matrix.inverted()
+ ray_origin_obj = matrix_inv @ ray_origin
+ ray_target_obj = matrix_inv @ ray_target
+ success, hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
+ if success:
+ return hit, normal, face_index
+ return None, None, None
+
+ best_length_squared = ray_max * ray_max
+ best_obj = None
+ for obj in self.CList:
+ matrix = obj.matrix_world
+ hit, normal, face_index = obj_ray_cast(obj, matrix)
+ rotation = obj.rotation_euler.to_quaternion()
+ if hit is not None:
+ hit_world = matrix @ hit
+ length_squared = (hit_world - ray_origin).length_squared
+ if length_squared < best_length_squared:
+ best_length_squared = length_squared
+ best_obj = obj
+ hits = hit_world
+ ns = normal
+ fs = face_index
+
+ if best_obj is not None:
+ return hits, ns, rotation
+
+ return None, None, None
def SelectObject(self, copyobj):
- copyobj.select_set(True)
+ copyobj.select_set(True)
- for child in copyobj.children:
- SelectObject(self, child)
+ for child in copyobj.children:
+ SelectObject(self, child)
- if copyobj.parent is None:
- bpy.context.view_layer.objects.active = copyobj
+ if copyobj.parent is None:
+ bpy.context.view_layer.objects.active = copyobj
# Undo
def printUndo(self):
- for l in self.UList:
- print(l)
+ for l in self.UList:
+ print(l)
def UndoAdd(self, type, obj):
- """ Create a backup mesh before apply the action to the object """
- if obj is None:
- return
+ """ Create a backup mesh before apply the action to the object """
+ if obj is None:
+ return
- if type != "DUPLICATE":
- bm = bmesh.new()
- bm.from_mesh(obj.data)
- self.UndoOps.append((obj, type, bm))
- else:
- self.UndoOps.append((obj, type, None))
+ if type != "DUPLICATE":
+ bm = bmesh.new()
+ bm.from_mesh(obj.data)
+ self.UndoOps.append((obj, type, bm))
+ else:
+ self.UndoOps.append((obj, type, None))
def UndoListUpdate(self):
- self.UList.append((self.UndoOps.copy()))
- self.UList_Index += 1
- self.UndoOps.clear()
+ self.UList.append((self.UndoOps.copy()))
+ self.UList_Index += 1
+ self.UndoOps.clear()
def Undo(self):
- if self.UList_Index < 0:
- return
- # get previous mesh
- for o in self.UList[self.UList_Index]:
- if o[1] == "MESH":
- bm = o[2]
- bm.to_mesh(o[0].data)
+ if self.UList_Index < 0:
+ return
+ # get previous mesh
+ for o in self.UList[self.UList_Index]:
+ if o[1] == "MESH":
+ bm = o[2]
+ bm.to_mesh(o[0].data)
- SelectObjList = bpy.context.selected_objects.copy()
- Active_Obj = bpy.context.active_object
- bpy.ops.object.select_all(action='TOGGLE')
+ SelectObjList = bpy.context.selected_objects.copy()
+ Active_Obj = bpy.context.active_object
+ bpy.ops.object.select_all(action='TOGGLE')
- for o in self.UList[self.UList_Index]:
- if o[1] == "REBOOL":
- o[0].select_set(True)
- o[0].hide_viewport = False
+ for o in self.UList[self.UList_Index]:
+ if o[1] == "REBOOL":
+ o[0].select_set(True)
+ o[0].hide_viewport = False
- if o[1] == "DUPLICATE":
- o[0].select_set(True)
- o[0].hide_viewport = False
+ if o[1] == "DUPLICATE":
+ o[0].select_set(True)
+ o[0].hide_viewport = False
- bpy.ops.object.delete(use_global=False)
+ bpy.ops.object.delete(use_global=False)
- for so in SelectObjList:
- bpy.data.objects[so.name].select_set(True)
- bpy.context.view_layer.objects.active = Active_Obj
+ for so in SelectObjList:
+ bpy.data.objects[so.name].select_set(True)
+ bpy.context.view_layer.objects.active = Active_Obj
- self.UList_Index -= 1
- self.UList[self.UList_Index + 1:] = []
+ self.UList_Index -= 1
+ self.UList[self.UList_Index + 1:] = []
def duplicateObject(self):
- if self.Instantiate:
- bpy.ops.object.duplicate_move_linked(
- OBJECT_OT_duplicate={
- "linked": True,
- "mode": 'TRANSLATION',
- },
- TRANSFORM_OT_translate={
- "value": (0, 0, 0),
- },
- )
- else:
- bpy.ops.object.duplicate_move(
- OBJECT_OT_duplicate={
- "linked": False,
- "mode": 'TRANSLATION',
- },
- TRANSFORM_OT_translate={
- "value": (0, 0, 0),
- },
- )
-
- ob_new = bpy.context.active_object
-
- ob_new.location = self.CurLoc
- v = Vector()
- v.x = v.y = 0.0
- v.z = self.BrushDepthOffset
- ob_new.location += self.qRot * v
-
- if self.ObjectMode:
- ob_new.scale = self.ObjectBrush.scale
- if self.ProfileMode:
- ob_new.scale = self.ProfileBrush.scale
-
- e = Euler()
- e.x = e.y = 0.0
- e.z = self.aRotZ / 25.0
-
- # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
- if (self.alt is True) and ((self.nbcol + self.nbrow) < 3):
- if self.RandomRotation:
- e.z += random.random()
-
- qe = e.to_quaternion()
- qRot = self.qRot * qe
- ob_new.rotation_mode = 'QUATERNION'
- ob_new.rotation_quaternion = qRot
- ob_new.rotation_mode = 'XYZ'
-
- if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
- ob_new.hide_viewport = True
-
- if self.BrushSolidify:
- ob_new.display_type = "SOLID"
- ob_new.show_in_front = False
-
- for o in bpy.context.selected_objects:
- UndoAdd(self, "DUPLICATE", o)
-
- if len(bpy.context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
- for o in self.all_sel_obj_list:
- o.select_set(True)
-
- bpy.context.view_layer.objects.active = self.OpsObj
+ if self.Instantiate:
+ bpy.ops.object.duplicate_move_linked(
+ OBJECT_OT_duplicate={
+ "linked": True,
+ "mode": 'TRANSLATION',
+ },
+ TRANSFORM_OT_translate={
+ "value": (0, 0, 0),
+ },
+ )
+ else:
+ bpy.ops.object.duplicate_move(
+ OBJECT_OT_duplicate={
+ "linked": False,
+ "mode": 'TRANSLATION',
+ },
+ TRANSFORM_OT_translate={
+ "value": (0, 0, 0),
+ },
+ )
+
+ ob_new = bpy.context.active_object
+
+ ob_new.location = self.CurLoc
+ v = Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob_new.location += self.qRot * v
+
+ if self.ObjectMode:
+ ob_new.scale = self.ObjectBrush.scale
+ if self.ProfileMode:
+ ob_new.scale = self.ProfileBrush.scale
+
+ e = Euler()
+ e.x = e.y = 0.0
+ e.z = self.aRotZ / 25.0
+
+ # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
+ if (self.alt is True) and ((self.nbcol + self.nbrow) < 3):
+ if self.RandomRotation:
+ e.z += random.random()
+
+ qe = e.to_quaternion()
+ qRot = self.qRot * qe
+ ob_new.rotation_mode = 'QUATERNION'
+ ob_new.rotation_quaternion = qRot
+ ob_new.rotation_mode = 'XYZ'
+
+ if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
+ ob_new.hide_viewport = True
+
+ if self.BrushSolidify:
+ ob_new.display_type = "SOLID"
+ ob_new.show_in_front = False
+
+ for o in bpy.context.selected_objects:
+ UndoAdd(self, "DUPLICATE", o)
+
+ if len(bpy.context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+ for o in self.all_sel_obj_list:
+ o.select_set(True)
+
+ bpy.context.view_layer.objects.active = self.OpsObj
def update_grid(self, context):
- """
- Thanks to batFINGER for his help :
- source : http://blender.stackexchange.com/questions/55864/multiple-meshes-not-welded-with-pydata
- """
- verts = []
- edges = []
- faces = []
- numface = 0
-
- if self.nbcol < 1:
- self.nbcol = 1
- if self.nbrow < 1:
- self.nbrow = 1
- if self.gapx < 0:
- self.gapx = 0
- if self.gapy < 0:
- self.gapy = 0
-
- # Get the data from the profils or the object
- if self.ProfileMode:
- brush = bpy.data.objects.new(
- self.Profils[self.nProfil][0],
- bpy.data.meshes[self.Profils[self.nProfil][0]]
- )
- obj = bpy.data.objects["CT_Profil"]
- obfaces = brush.data.polygons
- obverts = brush.data.vertices
- lenverts = len(obverts)
- else:
- brush = bpy.data.objects["CarverBrushCopy"]
- obj = context.selected_objects[0]
- obverts = brush.data.vertices
- obfaces = brush.data.polygons
- lenverts = len(brush.data.vertices)
-
- # Gap between each row / column
- gapx = self.gapx
- gapy = self.gapy
-
- # Width of each row / column
- widthx = brush.dimensions.x * self.scale_x
- widthy = brush.dimensions.y * self.scale_y
-
- # Compute the corners so the new object will be always at the center
- left = -((self.nbcol - 1) * (widthx + gapx)) / 2
- start = -((self.nbrow - 1) * (widthy + gapy)) / 2
-
- for i in range(self.nbrow * self.nbcol):
- row = i % self.nbrow
- col = i // self.nbrow
- startx = left + ((widthx + gapx) * col)
- starty = start + ((widthy + gapy) * row)
-
- # Add random rotation
- if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
- rotmat = Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
- for v in obverts:
- v.co = v.co @ rotmat
-
- verts.extend([((v.co.x - startx, v.co.y - starty, v.co.z)) for v in obverts])
- faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
- numface += 1
-
- # Update the mesh
- # Create mesh data
- mymesh = bpy.data.meshes.new("CT_Profil")
- # Generate mesh data
- mymesh.from_pydata(verts, edges, faces)
- # Calculate the edges
- mymesh.update(calc_edges=True)
- # Update data
- obj.data = mymesh
- # Make the object active to remove doubles
- context.view_layer.objects.active = obj
+ """
+ Thanks to batFINGER for his help :
+ source : http://blender.stackexchange.com/questions/55864/multiple-meshes-not-welded-with-pydata
+ """
+ verts = []
+ edges = []
+ faces = []
+ numface = 0
+
+ if self.nbcol < 1:
+ self.nbcol = 1
+ if self.nbrow < 1:
+ self.nbrow = 1
+ if self.gapx < 0:
+ self.gapx = 0
+ if self.gapy < 0:
+ self.gapy = 0
+
+ # Get the data from the profils or the object
+ if self.ProfileMode:
+ brush = bpy.data.objects.new(
+ self.Profils[self.nProfil][0],
+ bpy.data.meshes[self.Profils[self.nProfil][0]]
+ )
+ obj = bpy.data.objects["CT_Profil"]
+ obfaces = brush.data.polygons
+ obverts = brush.data.vertices
+ lenverts = len(obverts)
+ else:
+ brush = bpy.data.objects["CarverBrushCopy"]
+ obj = context.selected_objects[0]
+ obverts = brush.data.vertices
+ obfaces = brush.data.polygons
+ lenverts = len(brush.data.vertices)
+
+ # Gap between each row / column
+ gapx = self.gapx
+ gapy = self.gapy
+
+ # Width of each row / column
+ widthx = brush.dimensions.x * self.scale_x
+ widthy = brush.dimensions.y * self.scale_y
+
+ # Compute the corners so the new object will be always at the center
+ left = -((self.nbcol - 1) * (widthx + gapx)) / 2
+ start = -((self.nbrow - 1) * (widthy + gapy)) / 2
+
+ for i in range(self.nbrow * self.nbcol):
+ row = i % self.nbrow
+ col = i // self.nbrow
+ startx = left + ((widthx + gapx) * col)
+ starty = start + ((widthy + gapy) * row)
+
+ # Add random rotation
+ if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
+ rotmat = Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
+ for v in obverts:
+ v.co = v.co @ rotmat
+
+ verts.extend([((v.co.x - startx, v.co.y - starty, v.co.z)) for v in obverts])
+ faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
+ numface += 1
+
+ # Update the mesh
+ # Create mesh data
+ mymesh = bpy.data.meshes.new("CT_Profil")
+ # Generate mesh data
+ mymesh.from_pydata(verts, edges, faces)
+ # Calculate the edges
+ mymesh.update(calc_edges=True)
+ # Update data
+ obj.data = mymesh
+ # Make the object active to remove doubles
+ context.view_layer.objects.active = obj
def boolean_operation(bool_type="DIFFERENCE"):
- ActiveObj = bpy.context.active_object
- sel_index = 0 if bpy.context.selected_objects[0] != bpy.context.active_object else 1
+ ActiveObj = bpy.context.active_object
+ sel_index = 0 if bpy.context.selected_objects[0] != bpy.context.active_object else 1
- # bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- bool_name = "CT_" + bpy.context.selected_objects[sel_index].name
- BoolMod = ActiveObj.modifiers.new(bool_name, "BOOLEAN")
- BoolMod.object = bpy.context.selected_objects[sel_index]
- BoolMod.operation = bool_type
- bpy.context.selected_objects[sel_index].display_type = 'WIRE'
- while ActiveObj.modifiers.find(bool_name) > 0:
- bpy.ops.object.modifier_move_up(modifier=bool_name)
+ # bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ bool_name = "CT_" + bpy.context.selected_objects[sel_index].name
+ BoolMod = ActiveObj.modifiers.new(bool_name, "BOOLEAN")
+ BoolMod.object = bpy.context.selected_objects[sel_index]
+ BoolMod.operation = bool_type
+ bpy.context.selected_objects[sel_index].display_type = 'WIRE'
+ while ActiveObj.modifiers.find(bool_name) > 0:
+ bpy.ops.object.modifier_move_up(modifier=bool_name)
def Rebool(context, self):
- target_obj = context.active_object
+ target_obj = context.active_object
- Brush = context.selected_objects[1]
- Brush.display_type = "WIRE"
+ Brush = context.selected_objects[1]
+ Brush.display_type = "WIRE"
- #Deselect all
- bpy.ops.object.select_all(action='TOGGLE')
+ #Deselect all
+ bpy.ops.object.select_all(action='TOGGLE')
- target_obj.display_type = "SOLID"
- target_obj.select_set(True)
- bpy.ops.object.duplicate()
+ target_obj.display_type = "SOLID"
+ target_obj.select_set(True)
+ bpy.ops.object.duplicate()
- rebool_obj = context.active_object
+ rebool_obj = context.active_object
- m = rebool_obj.modifiers.new("CT_INTERSECT", "BOOLEAN")
- m.operation = "INTERSECT"
- m.object = Brush
+ m = rebool_obj.modifiers.new("CT_INTERSECT", "BOOLEAN")
+ m.operation = "INTERSECT"
+ m.object = Brush
- m = target_obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
- m.operation = "DIFFERENCE"
- m.object = Brush
+ m = target_obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
+ m.operation = "DIFFERENCE"
+ m.object = Brush
- for mb in target_obj.modifiers:
- if mb.type == 'BEVEL':
- mb.show_viewport = False
+ for mb in target_obj.modifiers:
+ if mb.type == 'BEVEL':
+ mb.show_viewport = False
- if self.ObjectBrush or self.ProfileBrush:
- rebool_obj.show_in_front = False
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ if self.ObjectBrush or self.ProfileBrush:
+ rebool_obj.show_in_front = False
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- if self.dont_apply_boolean is False:
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_INTERSECT")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ if self.dont_apply_boolean is False:
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_INTERSECT")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- bpy.ops.object.select_all(action='TOGGLE')
+ bpy.ops.object.select_all(action='TOGGLE')
- for mb in target_obj.modifiers:
- if mb.type == 'BEVEL':
- mb.show_viewport = True
+ for mb in target_obj.modifiers:
+ if mb.type == 'BEVEL':
+ mb.show_viewport = True
- context.view_layer.objects.active = target_obj
- target_obj.select_set(True)
- if self.dont_apply_boolean is False:
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_DIFFERENCE")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ context.view_layer.objects.active = target_obj
+ target_obj.select_set(True)
+ if self.dont_apply_boolean is False:
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_DIFFERENCE")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- bpy.ops.object.select_all(action='TOGGLE')
+ bpy.ops.object.select_all(action='TOGGLE')
- rebool_obj.select_set(True)
+ rebool_obj.select_set(True)
def createMeshFromData(self):
- if self.Profils[self.nProfil][0] not in bpy.data.meshes:
- # Create mesh and object
- me = bpy.data.meshes.new(self.Profils[self.nProfil][0])
- # Create mesh from given verts, faces.
- me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
- me.validate(verbose=True, clean_customdata=True)
- # Update mesh with new data
- me.update()
-
- if "CT_Profil" not in bpy.data.objects:
- ob = bpy.data.objects.new("CT_Profil", bpy.data.meshes[self.Profils[self.nProfil][0]])
- ob.location = Vector((0.0, 0.0, 0.0))
-
- # Link object to scene and make active
- bpy.context.collection.objects.link(ob)
- bpy.context.view_layer.update()
- bpy.context.view_layer.objects.active = ob
- ob.select_set(True)
- ob.location = Vector((10000.0, 0.0, 0.0))
- ob.display_type = "WIRE"
-
- self.SolidifyPossible = True
- else:
- bpy.data.objects["CT_Profil"].data = bpy.data.meshes[self.Profils[self.nProfil][0]]
+ if self.Profils[self.nProfil][0] not in bpy.data.meshes:
+ # Create mesh and object
+ me = bpy.data.meshes.new(self.Profils[self.nProfil][0])
+ # Create mesh from given verts, faces.
+ me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
+ me.validate(verbose=True, clean_customdata=True)
+ # Update mesh with new data
+ me.update()
+
+ if "CT_Profil" not in bpy.data.objects:
+ ob = bpy.data.objects.new("CT_Profil", bpy.data.meshes[self.Profils[self.nProfil][0]])
+ ob.location = Vector((0.0, 0.0, 0.0))
+
+ # Link object to scene and make active
+ bpy.context.collection.objects.link(ob)
+ bpy.context.view_layer.update()
+ bpy.context.view_layer.objects.active = ob
+ ob.select_set(True)
+ ob.location = Vector((10000.0, 0.0, 0.0))
+ ob.display_type = "WIRE"
+
+ self.SolidifyPossible = True
+ else:
+ bpy.data.objects["CT_Profil"].data = bpy.data.meshes[self.Profils[self.nProfil][0]]
def Selection_Save_Restore(self):
- if "CT_Profil" in bpy.data.objects:
- Selection_Save(self)
- bpy.ops.object.select_all(action='DESELECT')
- bpy.data.objects["CT_Profil"].select_set(True)
- bpy.context.view_layer.objects.active = bpy.data.objects["CT_Profil"]
- if bpy.data.objects["CT_Profil"] in self.all_sel_obj_list:
- self.all_sel_obj_list.remove(bpy.data.objects["CT_Profil"])
- bpy.ops.object.delete(use_global=False)
- Selection_Restore(self)
+ if "CT_Profil" in bpy.data.objects:
+ Selection_Save(self)
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.data.objects["CT_Profil"].select_set(True)
+ bpy.context.view_layer.objects.active = bpy.data.objects["CT_Profil"]
+ if bpy.data.objects["CT_Profil"] in self.all_sel_obj_list:
+ self.all_sel_obj_list.remove(bpy.data.objects["CT_Profil"])
+ bpy.ops.object.delete(use_global=False)
+ Selection_Restore(self)
def Selection_Save(self):
- obj_name = getattr(bpy.context.active_object, "name", None)
- self.all_sel_obj_list = bpy.context.selected_objects.copy()
- self.save_active_obj = obj_name
+ obj_name = getattr(bpy.context.active_object, "name", None)
+ self.all_sel_obj_list = bpy.context.selected_objects.copy()
+ self.save_active_obj = obj_name
def Selection_Restore(self):
- for o in self.all_sel_obj_list:
- o.select_set(True)
- if self.save_active_obj:
- bpy.context.view_layer.objects.active = bpy.data.objects.get(self.save_active_obj, None)
+ for o in self.all_sel_obj_list:
+ o.select_set(True)
+ if self.save_active_obj:
+ bpy.context.view_layer.objects.active = bpy.data.objects.get(self.save_active_obj, None)
def Snap_Cursor(self, context, event, mouse_pos):
- """ Find the closest position on the overlay grid and snap the mouse on it """
- # Get the context arguments
- region = context.region
- rv3d = context.region_data
-
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
-
- # Get the grid overlay for the VIEW_3D
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
-
- # Use the grid scale and subdivision to get the increment
- increment = (grid_scale / grid_subdivisions)
- half_increment = increment / 2
-
- # Convert the 2d location of the mouse in 3d
- for index, loc in enumerate(reversed(mouse_pos)):
- mouse_loc_3d = region_2d_to_location_3d(region, rv3d, loc, (0, 0, 0))
-
- # Get the remainder from the mouse location and the ratio
- # Test if the remainder > to the half of the increment
- for i in range(3):
- modulo = mouse_loc_3d[i] % increment
- if modulo < half_increment:
- modulo = - modulo
- else:
- modulo = increment - modulo
-
- # Add the remainder to get the closest location on the grid
- mouse_loc_3d[i] = mouse_loc_3d[i] + modulo
-
- # Get the snapped 2d location
- snap_loc_2d = location_3d_to_region_2d(region, rv3d, mouse_loc_3d)
-
- # Replace the last mouse location by the snapped location
- if len(self.mouse_path) > 0:
- self.mouse_path[len(self.mouse_path) - (index + 1) ] = tuple(snap_loc_2d)
+ """ Find the closest position on the overlay grid and snap the mouse on it """
+ # Get the context arguments
+ region = context.region
+ rv3d = context.region_data
+
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+
+ # Get the grid overlay for the VIEW_3D
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+
+ # Use the grid scale and subdivision to get the increment
+ increment = (grid_scale / grid_subdivisions)
+ half_increment = increment / 2
+
+ # Convert the 2d location of the mouse in 3d
+ for index, loc in enumerate(reversed(mouse_pos)):
+ mouse_loc_3d = region_2d_to_location_3d(region, rv3d, loc, (0, 0, 0))
+
+ # Get the remainder from the mouse location and the ratio
+ # Test if the remainder > to the half of the increment
+ for i in range(3):
+ modulo = mouse_loc_3d[i] % increment
+ if modulo < half_increment:
+ modulo = - modulo
+ else:
+ modulo = increment - modulo
+
+ # Add the remainder to get the closest location on the grid
+ mouse_loc_3d[i] = mouse_loc_3d[i] + modulo
+
+ # Get the snapped 2d location
+ snap_loc_2d = location_3d_to_region_2d(region, rv3d, mouse_loc_3d)
+
+ # Replace the last mouse location by the snapped location
+ if len(self.mouse_path) > 0:
+ self.mouse_path[len(self.mouse_path) - (index + 1) ] = tuple(snap_loc_2d)
def mini_grid(self, context, color):
- """ Draw a snap mini grid around the cursor based on the overlay grid"""
- # Get the context arguments
- region = context.region
- rv3d = context.region_data
-
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
- screen_height = context.screen.areas[i].height
- screen_width = context.screen.areas[i].width
-
- #Draw the snap grid, only in ortho view
- if not space.region_3d.is_perspective :
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
- increment = (grid_scale / grid_subdivisions)
-
- # Get the 3d location of the mouse forced to a snap value in the operator
- mouse_coord = self.mouse_path[len(self.mouse_path) - 1]
-
- snap_loc = region_2d_to_location_3d(region, rv3d, mouse_coord, (0, 0, 0))
-
- # Add the increment to get the closest location on the grid
- snap_loc[0] += increment
- snap_loc[1] += increment
-
- # Get the 2d location of the snap location
- snap_loc = location_3d_to_region_2d(region, rv3d, snap_loc)
- origin = location_3d_to_region_2d(region, rv3d, (0,0,0))
-
- # Get the increment value
- snap_value = snap_loc[0] - mouse_coord[0]
-
- grid_coords = []
-
- # Draw lines on X and Z axis from the cursor through the screen
- grid_coords = [
- (0, mouse_coord[1]), (screen_width, mouse_coord[1]),
- (mouse_coord[0], 0), (mouse_coord[0], screen_height)
- ]
-
- # Draw a mlini grid around the cursor to show the snap options
- grid_coords += [
- (mouse_coord[0] + snap_value, mouse_coord[1] + 25 + snap_value),
- (mouse_coord[0] + snap_value, mouse_coord[1] - 25 - snap_value),
- (mouse_coord[0] + 25 + snap_value, mouse_coord[1] + snap_value),
- (mouse_coord[0] - 25 - snap_value, mouse_coord[1] + snap_value),
- (mouse_coord[0] - snap_value, mouse_coord[1] + 25 + snap_value),
- (mouse_coord[0] - snap_value, mouse_coord[1] - 25 - snap_value),
- (mouse_coord[0] + 25 + snap_value, mouse_coord[1] - snap_value),
- (mouse_coord[0] - 25 - snap_value, mouse_coord[1] - snap_value),
- ]
- draw_shader(self, color, 0.3, 'LINES', grid_coords, size=2)
+ """ Draw a snap mini grid around the cursor based on the overlay grid"""
+ # Get the context arguments
+ region = context.region
+ rv3d = context.region_data
+
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+ screen_height = context.screen.areas[i].height
+ screen_width = context.screen.areas[i].width
+
+ #Draw the snap grid, only in ortho view
+ if not space.region_3d.is_perspective :
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+ increment = (grid_scale / grid_subdivisions)
+
+ # Get the 3d location of the mouse forced to a snap value in the operator
+ mouse_coord = self.mouse_path[len(self.mouse_path) - 1]
+
+ snap_loc = region_2d_to_location_3d(region, rv3d, mouse_coord, (0, 0, 0))
+
+ # Add the increment to get the closest location on the grid
+ snap_loc[0] += increment
+ snap_loc[1] += increment
+
+ # Get the 2d location of the snap location
+ snap_loc = location_3d_to_region_2d(region, rv3d, snap_loc)
+ origin = location_3d_to_region_2d(region, rv3d, (0,0,0))
+
+ # Get the increment value
+ snap_value = snap_loc[0] - mouse_coord[0]
+
+ grid_coords = []
+
+ # Draw lines on X and Z axis from the cursor through the screen
+ grid_coords = [
+ (0, mouse_coord[1]), (screen_width, mouse_coord[1]),
+ (mouse_coord[0], 0), (mouse_coord[0], screen_height)
+ ]
+
+ # Draw a mlini grid around the cursor to show the snap options
+ grid_coords += [
+ (mouse_coord[0] + snap_value, mouse_coord[1] + 25 + snap_value),
+ (mouse_coord[0] + snap_value, mouse_coord[1] - 25 - snap_value),
+ (mouse_coord[0] + 25 + snap_value, mouse_coord[1] + snap_value),
+ (mouse_coord[0] - 25 - snap_value, mouse_coord[1] + snap_value),
+ (mouse_coord[0] - snap_value, mouse_coord[1] + 25 + snap_value),
+ (mouse_coord[0] - snap_value, mouse_coord[1] - 25 - snap_value),
+ (mouse_coord[0] + 25 + snap_value, mouse_coord[1] - snap_value),
+ (mouse_coord[0] - 25 - snap_value, mouse_coord[1] - snap_value),
+ ]
+ draw_shader(self, color, 0.3, 'LINES', grid_coords, size=2)
def draw_shader(self, color, alpha, type, coords, size=1, indices=None):
- """ Create a batch for a draw type """
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glEnable(bgl.GL_LINE_SMOOTH)
- if type =='POINTS':
- bgl.glPointSize(size)
- else:
- bgl.glLineWidth(size)
- try:
- if len(coords[0])>2:
- shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
- else:
- shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
- batch = batch_for_shader(shader, type, {"pos": coords}, indices=indices)
- shader.bind()
- shader.uniform_float("color", (color[0], color[1], color[2], alpha))
- batch.draw(shader)
- bgl.glLineWidth(1)
- bgl.glPointSize(1)
- bgl.glDisable(bgl.GL_LINE_SMOOTH)
- bgl.glDisable(bgl.GL_BLEND)
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ """ Create a batch for a draw type """
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glEnable(bgl.GL_LINE_SMOOTH)
+ if type =='POINTS':
+ bgl.glPointSize(size)
+ else:
+ bgl.glLineWidth(size)
+ try:
+ if len(coords[0])>2:
+ shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
+ else:
+ shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
+ batch = batch_for_shader(shader, type, {"pos": coords}, indices=indices)
+ shader.bind()
+ shader.uniform_float("color", (color[0], color[1], color[2], alpha))
+ batch.draw(shader)
+ bgl.glLineWidth(1)
+ bgl.glPointSize(1)
+ bgl.glDisable(bgl.GL_LINE_SMOOTH)
+ bgl.glDisable(bgl.GL_BLEND)
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
diff --git a/object_collection_manager/internals.py b/object_collection_manager/internals.py
index e2e6a64b..64c48150 100644
--- a/object_collection_manager/internals.py
+++ b/object_collection_manager/internals.py
@@ -214,4 +214,3 @@ def send_report(message):
bpy.ops.view3d.cm_send_report(ctx, 'INVOKE_DEFAULT', message=message)
bpy.app.timers.register(report)
-
diff --git a/oscurart_tools/files/reload_images.py b/oscurart_tools/files/reload_images.py
index 68b5c61b..8461e26d 100644
--- a/oscurart_tools/files/reload_images.py
+++ b/oscurart_tools/files/reload_images.py
@@ -33,5 +33,3 @@ class reloadImages (Operator):
for imgs in bpy.data.images:
imgs.reload()
return {'FINISHED'}
-
-
diff --git a/oscurart_tools/files/save_incremental.py b/oscurart_tools/files/save_incremental.py
index b10db327..d7eb4652 100644
--- a/oscurart_tools/files/save_incremental.py
+++ b/oscurart_tools/files/save_incremental.py
@@ -66,5 +66,3 @@ class saveIncrementalBackup (bpy.types.Operator):
def execute(self, context):
saveBkp(self, context)
return {'FINISHED'}
-
-
diff --git a/oscurart_tools/mesh/apply_linked_meshes.py b/oscurart_tools/mesh/apply_linked_meshes.py
index 0bd7bf47..63e7f907 100644
--- a/oscurart_tools/mesh/apply_linked_meshes.py
+++ b/oscurart_tools/mesh/apply_linked_meshes.py
@@ -53,8 +53,3 @@ class ApplyLRT(bpy.types.Operator):
def execute(self, context):
applyLRTEx(self, context)
return {'FINISHED'}
-
-
-
-
-
diff --git a/oscurart_tools/mesh/flipped_uvs.py b/oscurart_tools/mesh/flipped_uvs.py
index 14d1be4c..13d837f1 100644
--- a/oscurart_tools/mesh/flipped_uvs.py
+++ b/oscurart_tools/mesh/flipped_uvs.py
@@ -57,4 +57,4 @@ class selectFlippedUvs(bpy.types.Operator):
def execute(self, context):
defSelectFlippedUvs(self, context)
- return {'FINISHED'} \ No newline at end of file
+ return {'FINISHED'}
diff --git a/oscurart_tools/mesh/overlap_island.py b/oscurart_tools/mesh/overlap_island.py
index 68b3d339..c6b70cd2 100644
--- a/oscurart_tools/mesh/overlap_island.py
+++ b/oscurart_tools/mesh/overlap_island.py
@@ -95,6 +95,3 @@ class OscOverlapUv(Operator):
def execute(self, context):
DefOscOverlapUv(self,self.offset,self.rotate)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/overlap_uvs.py b/oscurart_tools/mesh/overlap_uvs.py
index 2960bb3d..d0d13752 100644
--- a/oscurart_tools/mesh/overlap_uvs.py
+++ b/oscurart_tools/mesh/overlap_uvs.py
@@ -128,4 +128,3 @@ class PasteUvIsland(Operator):
def execute(self, context):
defPasteUvsIsland(self, self.uvOffset, self.rotateUv, context)
return {'FINISHED'}
-
diff --git a/oscurart_tools/mesh/remove_modifiers.py b/oscurart_tools/mesh/remove_modifiers.py
index 186588ce..db015200 100644
--- a/oscurart_tools/mesh/remove_modifiers.py
+++ b/oscurart_tools/mesh/remove_modifiers.py
@@ -42,6 +42,3 @@ class RemoveModifiers(bpy.types.Operator):
def execute(self, context):
funcRemoveModifiers(self,context)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/select_doubles.py b/oscurart_tools/mesh/select_doubles.py
index b2a7d434..6551824a 100644
--- a/oscurart_tools/mesh/select_doubles.py
+++ b/oscurart_tools/mesh/select_doubles.py
@@ -72,6 +72,3 @@ class SelectDoubles(Operator):
def execute(self, context):
SelDoubles(self, context,self.distance)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/vertex_color_id.py b/oscurart_tools/mesh/vertex_color_id.py
index 2eb9790d..6c68938a 100644
--- a/oscurart_tools/mesh/vertex_color_id.py
+++ b/oscurart_tools/mesh/vertex_color_id.py
@@ -65,6 +65,3 @@ class createVCMask(bpy.types.Operator):
def execute(self, context):
vertexColorMask(self, context)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/object/distribute.py b/oscurart_tools/object/distribute.py
index 991d664b..a0fb6263 100644
--- a/oscurart_tools/object/distribute.py
+++ b/oscurart_tools/object/distribute.py
@@ -67,4 +67,3 @@ class DistributeOsc(Operator):
self.Booly = True
self.Boolz = True
return context.window_manager.invoke_props_dialog(self)
-
diff --git a/oscurart_tools/object/search_and_select.py b/oscurart_tools/object/search_and_select.py
index 707c7188..63787af4 100644
--- a/oscurart_tools/object/search_and_select.py
+++ b/oscurart_tools/object/search_and_select.py
@@ -57,6 +57,3 @@ class SearchAndSelectOt(bpy.types.Operator):
self.count = True
self.end = True
return context.window_manager.invoke_props_dialog(self)
-
-
-
diff --git a/oscurart_tools/render/batch_maker.py b/oscurart_tools/render/batch_maker.py
index fed15dcc..ca386546 100644
--- a/oscurart_tools/render/batch_maker.py
+++ b/oscurart_tools/render/batch_maker.py
@@ -48,4 +48,3 @@ class oscBatchMaker (bpy.types.Operator):
def execute(self, context):
batchMaker(self.bin)
return {'FINISHED'}
-
diff --git a/oscurart_tools/render/material_overrides.py b/oscurart_tools/render/material_overrides.py
index 5720d293..faa9be63 100644
--- a/oscurart_tools/render/material_overrides.py
+++ b/oscurart_tools/render/material_overrides.py
@@ -175,4 +175,3 @@ class OscOverridesKill(bpy.types.Operator):
ovlist = context.scene.ovlist
ovlist.remove(self.index)
return {'FINISHED'}
-
diff --git a/power_sequencer/scripts/BPSRender/bpsrender/__init__.py b/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
index 35a40273..f14cfb6a 100644
--- a/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
+++ b/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
@@ -14,4 +14,3 @@
# You should have received a copy of the GNU General Public License along with Power Sequencer. If
# not, see <https://www.gnu.org/licenses/>.
#
-
diff --git a/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py b/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
index a6486c01..fc40d772 100644
--- a/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
+++ b/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
@@ -8,4 +8,4 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 0.5764706134796143, 0.16078431904315948)
lampdata.energy = 8.43048#22600lm/21.446(=lux)*0.004(distance) *2 for distance is the point of half strength
lampdata.distance = 1.0
-lampdata.falloff_type = 'INVERSE_SQUARE' \ No newline at end of file
+lampdata.falloff_type = 'INVERSE_SQUARE'
diff --git a/presets/pov/world/4_Cartoony_Sky.py b/presets/pov/world/4_Cartoony_Sky.py
index 90b87bf5..c2410a35 100644
--- a/presets/pov/world/4_Cartoony_Sky.py
+++ b/presets/pov/world/4_Cartoony_Sky.py
@@ -16,4 +16,4 @@ scene.pov.media_scattering_type = '4'
scene.pov.media_samples = 35
scene.pov.media_diffusion_color = (0.20000000298023224, 0.4000000059604645, 1.0)
scene.pov.media_absorption_color = (0.0, 0.0, 0.0)
-scene.pov.media_eccentricity = 0.0 \ No newline at end of file
+scene.pov.media_eccentricity = 0.0
diff --git a/presets/pov/world/5_Under_Water.py b/presets/pov/world/5_Under_Water.py
index 36af4196..5dfd9c59 100644
--- a/presets/pov/world/5_Under_Water.py
+++ b/presets/pov/world/5_Under_Water.py
@@ -16,4 +16,4 @@ scene.pov.media_scattering_type = '5'
scene.pov.media_samples = 35
scene.pov.media_diffusion_color = (0.000034, 0.000034, 0.000017)
scene.pov.media_absorption_color = (0.00000455, 0.00000165, 0.00000031)
-scene.pov.media_eccentricity = 0.7 \ No newline at end of file
+scene.pov.media_eccentricity = 0.7
diff --git a/rigify/base_generate.py b/rigify/base_generate.py
index ea1415c9..7141d77e 100644
--- a/rigify/base_generate.py
+++ b/rigify/base_generate.py
@@ -465,4 +465,3 @@ class BaseGenerator:
for bone in self.obj.data.bones:
if bone.parent is None:
self.__build_rig_tree_rec(bone, None, handled)
-
diff --git a/rigify/rot_mode.py b/rigify/rot_mode.py
index 9398a737..6ea9f241 100644
--- a/rigify/rot_mode.py
+++ b/rigify/rot_mode.py
@@ -11,7 +11,7 @@ This script/addon:
TO-DO:
- To convert object's rotation mode (already done in Mutant Bob script,
- but not done in this one.
+ but not done in this one.
- To understand "EnumProperty" and write it well.
- Code clean
- ...
diff --git a/rigify/utils/metaclass.py b/rigify/utils/metaclass.py
index 77ce4b6b..9e169e05 100644
--- a/rigify/utils/metaclass.py
+++ b/rigify/utils/metaclass.py
@@ -168,4 +168,3 @@ class SingletonPluginMetaclass(StagedMetaclass):
owner.plugin_list.append(new_obj)
owner.plugin_list.sort(key=lambda obj: obj.priority, reverse=True)
return new_obj
-
diff --git a/space_view3d_math_vis/draw.py b/space_view3d_math_vis/draw.py
index 8adeeb0b..60467faa 100644
--- a/space_view3d_math_vis/draw.py
+++ b/space_view3d_math_vis/draw.py
@@ -244,4 +244,4 @@ def draw_bounding_boxes(matrices, scale, color):
single_color_shader.bind()
single_color_shader.uniform_float("color", color)
- batch.draw(single_color_shader) \ No newline at end of file
+ batch.draw(single_color_shader)
diff --git a/space_view3d_pie_menus/pie_origin.py b/space_view3d_pie_menus/pie_origin.py
index f1edf279..bc74fd1b 100644
--- a/space_view3d_pie_menus/pie_origin.py
+++ b/space_view3d_pie_menus/pie_origin.py
@@ -277,7 +277,7 @@ class PIE_MT_OriginPivot(Menu):
# 2 - BOTTOM
pie.operator("object.pivotobottom_edit", text="Origin to Bottom",
icon='TRIA_DOWN')
- # 8 - TOP
+ # 8 - TOP
pie.operator("object.setorigintoselected_edit", text="Origin To Selected",
icon='SNAP_INCREMENT')
# 7 - TOP - LEFT
diff --git a/space_view3d_spacebar_menu/__init__.py b/space_view3d_spacebar_menu/__init__.py
index c46aea7f..51a7d4dd 100644
--- a/space_view3d_spacebar_menu/__init__.py
+++ b/space_view3d_spacebar_menu/__init__.py
@@ -827,20 +827,20 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
# Text Edit Mode
def menu_func(self, context):
- layout = self.layout
-
- layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL')
- layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D')
- layout.separator()
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM')
- layout.menu("VIEW3D_MT_Animation_Player",
- text="Animation", icon='PLAY')
- layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART')
- layout.operator("object.editmode_toggle", text="Enter Object Mode",
- icon='OBJECT_DATA')
- layout.separator()
- layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT')
+ layout = self.layout
+
+ layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL')
+ layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D')
+ layout.separator()
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM')
+ layout.menu("VIEW3D_MT_Animation_Player",
+ text="Animation", icon='PLAY')
+ layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART')
+ layout.operator("object.editmode_toggle", text="Enter Object Mode",
+ icon='OBJECT_DATA')
+ layout.separator()
+ layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT')
# Preferences utility functions
diff --git a/space_view3d_spacebar_menu/edit_mesh.py b/space_view3d_spacebar_menu/edit_mesh.py
index eff16c0d..c7098c69 100644
--- a/space_view3d_spacebar_menu/edit_mesh.py
+++ b/space_view3d_spacebar_menu/edit_mesh.py
@@ -20,13 +20,13 @@
import bpy
from bpy.types import (
- Operator,
- Menu,
- )
+ Operator,
+ Menu,
+ )
from bpy.props import (
- BoolProperty,
- StringProperty,
- )
+ BoolProperty,
+ StringProperty,
+ )
from .object_menus import *
from .snap_origin_cursor import *
@@ -36,210 +36,210 @@ from .snap_origin_cursor import *
# ********** Edit Multiselect **********
class VIEW3D_MT_Edit_Multi(Menu):
- bl_label = "Mode Select"
+ bl_label = "Mode Select"
- def draw(self, context):
- layout = self.layout
+ def draw(self, context):
+ layout = self.layout
- layout.operator("selectedit.vertex", text="Vertex", icon='VERTEXSEL')
- layout.operator("selectedit.edge", text="Edge", icon='EDGESEL')
- layout.operator("selectedit.face", text="Face", icon='FACESEL')
- layout.operator("selectedit.vertsfaces", text="Vertex/Faces", icon='VERTEXSEL')
- layout.operator("selectedit.vertsedges", text="Vertex/Edges", icon='EDGESEL')
- layout.operator("selectedit.edgesfaces", text="Edges/Faces", icon='FACESEL')
- layout.operator("selectedit.vertsedgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
+ layout.operator("selectedit.vertex", text="Vertex", icon='VERTEXSEL')
+ layout.operator("selectedit.edge", text="Edge", icon='EDGESEL')
+ layout.operator("selectedit.face", text="Face", icon='FACESEL')
+ layout.operator("selectedit.vertsfaces", text="Vertex/Faces", icon='VERTEXSEL')
+ layout.operator("selectedit.vertsedges", text="Vertex/Edges", icon='EDGESEL')
+ layout.operator("selectedit.edgesfaces", text="Edges/Faces", icon='FACESEL')
+ layout.operator("selectedit.vertsedgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
# ********** Edit Mesh Edge **********
class VIEW3D_MT_EditM_Edge(Menu):
- bl_label = "Edges"
+ bl_label = "Edges"
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("mesh.mark_seam")
- layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
- layout.separator()
+ layout.operator("mesh.mark_seam")
+ layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
+ layout.separator()
- layout.operator("mesh.mark_sharp")
- layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
- layout.operator("mesh.extrude_move_along_normals", text="Extrude")
- layout.separator()
+ layout.operator("mesh.mark_sharp")
+ layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
+ layout.operator("mesh.extrude_move_along_normals", text="Extrude")
+ layout.separator()
- layout.operator("mesh.edge_rotate",
- text="Rotate Edge CW").direction = 'CW'
- layout.operator("mesh.edge_rotate",
- text="Rotate Edge CCW").direction = 'CCW'
- layout.separator()
+ layout.operator("mesh.edge_rotate",
+ text="Rotate Edge CW").direction = 'CW'
+ layout.operator("mesh.edge_rotate",
+ text="Rotate Edge CCW").direction = 'CCW'
+ layout.separator()
- layout.operator("TFM_OT_edge_slide", text="Edge Slide")
- layout.operator("mesh.loop_multi_select", text="Edge Loop")
- layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
- layout.operator("mesh.loop_to_region")
- layout.operator("mesh.region_to_loop")
+ layout.operator("TFM_OT_edge_slide", text="Edge Slide")
+ layout.operator("mesh.loop_multi_select", text="Edge Loop")
+ layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
+ layout.operator("mesh.loop_to_region")
+ layout.operator("mesh.region_to_loop")
# multiple edit select modes.
class VIEW3D_OT_selecteditVertex(Operator):
- bl_idname = "selectedit.vertex"
- bl_label = "Vertex Mode"
- bl_description = "Vert Select"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.vertex"
+ bl_label = "Vertex Mode"
+ bl_description = "Vert Select"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "EDGE, FACE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "EDGE, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditEdge(Operator):
- bl_idname = "selectedit.edge"
- bl_label = "Edge Mode"
- bl_description = "Edge Select"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.edge"
+ bl_label = "Edge Mode"
+ bl_description = "Edge Select"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- if bpy.ops.mesh.select_mode != "VERT, FACE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ if bpy.ops.mesh.select_mode != "VERT, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditFace(Operator):
- bl_idname = "selectedit.face"
- bl_label = "Multiedit Face"
- bl_description = "Face Mode"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.face"
+ bl_label = "Multiedit Face"
+ bl_description = "Face Mode"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
- if bpy.ops.mesh.select_mode != "VERT, EDGE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ return {'FINISHED'}
# Components Multi Selection Mode
class VIEW3D_OT_selecteditVertsEdges(Operator):
- bl_idname = "selectedit.vertsedges"
- bl_label = "Verts Edges Mode"
- bl_description = "Vert/Edge Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsedges"
+ bl_label = "Verts Edges Mode"
+ bl_description = "Vert/Edge Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditEdgesFaces(Operator):
- bl_idname = "selectedit.edgesfaces"
- bl_label = "Edges Faces Mode"
- bl_description = "Edge/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.edgesfaces"
+ bl_label = "Edges Faces Mode"
+ bl_description = "Edge/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditVertsFaces(Operator):
- bl_idname = "selectedit.vertsfaces"
- bl_label = "Verts Faces Mode"
- bl_description = "Vert/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsfaces"
+ bl_label = "Verts Faces Mode"
+ bl_description = "Vert/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditVertsEdgesFaces(Operator):
- bl_idname = "selectedit.vertsedgesfaces"
- bl_label = "Verts Edges Faces Mode"
- bl_description = "Vert/Edge/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsedgesfaces"
+ bl_label = "Verts Edges Faces Mode"
+ bl_description = "Vert/Edge/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
# ********** Normals / Auto Smooth Menu **********
# Thanks to marvin.k.breuer for the Autosmooth part of the menu
def menu_func(self, context):
- layout = self.layout
- obj = context.object
- obj_data = context.active_object.data
- layout.separator()
- layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth")
+ layout = self.layout
+ obj = context.object
+ obj_data = context.active_object.data
+ layout.separator()
+ layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth")
- # Auto Smooth Angle - two tab spaces to align it with the rest of the menu
- layout.prop(obj_data, "auto_smooth_angle",
- text=" Auto Smooth Angle")
+ # Auto Smooth Angle - two tab spaces to align it with the rest of the menu
+ layout.prop(obj_data, "auto_smooth_angle",
+ text=" Auto Smooth Angle")
# List The Classes #
classes = (
- VIEW3D_MT_Edit_Multi,
- VIEW3D_MT_EditM_Edge,
- VIEW3D_OT_selecteditVertex,
- VIEW3D_OT_selecteditEdge,
- VIEW3D_OT_selecteditFace,
- VIEW3D_OT_selecteditVertsEdges,
- VIEW3D_OT_selecteditEdgesFaces,
- VIEW3D_OT_selecteditVertsFaces,
- VIEW3D_OT_selecteditVertsEdgesFaces,
+ VIEW3D_MT_Edit_Multi,
+ VIEW3D_MT_EditM_Edge,
+ VIEW3D_OT_selecteditVertex,
+ VIEW3D_OT_selecteditEdge,
+ VIEW3D_OT_selecteditFace,
+ VIEW3D_OT_selecteditVertsEdges,
+ VIEW3D_OT_selecteditEdgesFaces,
+ VIEW3D_OT_selecteditVertsFaces,
+ VIEW3D_OT_selecteditVertsEdgesFaces,
)
# Register Classes & Hotkeys #
def register():
- for cls in classes:
- bpy.utils.register_class(cls)
+ for cls in classes:
+ bpy.utils.register_class(cls)
- bpy.types.VIEW3D_MT_edit_mesh_normals.append(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_normals.append(menu_func)
# Unregister Classes & Hotkeys #
def unregister():
- for cls in reversed(classes):
- bpy.utils.unregister_class(cls)
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
- bpy.types.VIEW3D_MT_edit_mesh_normals.remove(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_normals.remove(menu_func)
if __name__ == "__main__":
- register()
+ register()
diff --git a/space_view3d_spacebar_menu/snap_origin_cursor.py b/space_view3d_spacebar_menu/snap_origin_cursor.py
index f10f2dfc..b150a492 100644
--- a/space_view3d_spacebar_menu/snap_origin_cursor.py
+++ b/space_view3d_spacebar_menu/snap_origin_cursor.py
@@ -20,283 +20,283 @@
import bpy
from bpy.types import (
- Operator,
- Menu,
- )
+ Operator,
+ Menu,
+)
from bpy.props import (
- BoolProperty,
- StringProperty,
- )
+ BoolProperty,
+ StringProperty,
+)
from .object_menus import *
# ********** Object Snap Cursor **********
class VIEW3D_MT_Snap_Context(Menu):
- bl_label = "Snapping"
+ bl_label = "Snapping"
- def draw(self, context):
- layout = self.layout
- toolsettings = context.tool_settings
- layout.prop(toolsettings, "use_snap")
- layout.prop(toolsettings, "snap_elements", expand=True)
+ def draw(self, context):
+ layout = self.layout
+ toolsettings = context.tool_settings
+ layout.prop(toolsettings, "use_snap")
+ layout.prop(toolsettings, "snap_elements", expand=True)
class VIEW3D_MT_Snap_Origin(Menu):
- bl_label = "Snap Origin"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'EXEC_AREA'
- layout.operator("object.origin_set",
- text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
- layout.separator()
- layout.operator("object.origin_set",
- text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
- layout.operator("object.origin_set",
- text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
- layout.operator("object.origin_set",
- text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS'
+ bl_label = "Snap Origin"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'EXEC_AREA'
+ layout.operator("object.origin_set",
+ text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
+ layout.separator()
+ layout.operator("object.origin_set",
+ text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
+ layout.operator("object.origin_set",
+ text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
+ layout.operator("object.origin_set",
+ text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS'
class VIEW3D_MT_CursorMenu(Menu):
- bl_label = "Snap To"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.menu("VIEW3D_MT_Snap_Context")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
- layout.operator("view3d.snap_cursor_selected_to_center",
- text="Selection and Cursor to World Origin")
+ bl_label = "Snap To"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.menu("VIEW3D_MT_Snap_Context")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
+ layout.operator("view3d.snap_cursor_selected_to_center",
+ text="Selection and Cursor to World Origin")
class VIEW3D_MT_CursorMenuLite(Menu):
- bl_label = "Snap to"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
- layout.operator("view3d.snap_cursor_selected_to_center",
- text="Selection and Cursor to World Origin")
+ bl_label = "Snap to"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
+ layout.operator("view3d.snap_cursor_selected_to_center",
+ text="Selection and Cursor to World Origin")
# Code thanks to Isaac Weaver (wisaac) D1963
class VIEW3D_OT_SnapCursSelToCenter(Operator):
- bl_idname = "view3d.snap_cursor_selected_to_center"
- bl_label = "Snap Cursor & Selection to World Origin"
- bl_description = ("Snap 3D cursor and selected objects to the center \n"
- "Works only in Object Mode")
+ bl_idname = "view3d.snap_cursor_selected_to_center"
+ bl_label = "Snap Cursor & Selection to World Origin"
+ bl_description = ("Snap 3D cursor and selected objects to the center \n"
+ "Works only in Object Mode")
- @classmethod
- def poll(cls, context):
- return (context.area.type == "VIEW_3D" and context.mode == "OBJECT")
+ @classmethod
+ def poll(cls, context):
+ return (context.area.type == "VIEW_3D" and context.mode == "OBJECT")
- def execute(self, context):
- context.scene.cursor.location = (0, 0, 0)
- for obj in context.selected_objects:
- obj.location = (0, 0, 0)
- return {'FINISHED'}
+ def execute(self, context):
+ context.scene.cursor.location = (0, 0, 0)
+ for obj in context.selected_objects:
+ obj.location = (0, 0, 0)
+ return {'FINISHED'}
# Cursor Edge Intersection Defs #
def abs(val):
- if val > 0:
- return val
- return -val
+ if val > 0:
+ return val
+ return -val
def edgeIntersect(context, operator):
- from mathutils.geometry import intersect_line_line
+ from mathutils.geometry import intersect_line_line
- obj = context.active_object
+ obj = context.active_object
- if (obj.type != "MESH"):
- operator.report({'ERROR'}, "Object must be a mesh")
- return None
+ if (obj.type != "MESH"):
+ operator.report({'ERROR'}, "Object must be a mesh")
+ return None
- edges = []
- mesh = obj.data
- verts = mesh.vertices
+ edges = []
+ mesh = obj.data
+ verts = mesh.vertices
- is_editmode = (obj.mode == 'EDIT')
- if is_editmode:
- bpy.ops.object.mode_set(mode='OBJECT')
+ is_editmode = (obj.mode == 'EDIT')
+ if is_editmode:
+ bpy.ops.object.mode_set(mode='OBJECT')
- for e in mesh.edges:
- if e.select:
- edges.append(e)
+ for e in mesh.edges:
+ if e.select:
+ edges.append(e)
- if len(edges) > 2:
- break
+ if len(edges) > 2:
+ break
- if is_editmode:
- bpy.ops.object.mode_set(mode='EDIT')
+ if is_editmode:
+ bpy.ops.object.mode_set(mode='EDIT')
- if len(edges) != 2:
- operator.report({'ERROR'},
- "Operator requires exactly 2 edges to be selected")
- return
+ if len(edges) != 2:
+ operator.report({'ERROR'},
+ "Operator requires exactly 2 edges to be selected")
+ return
- line = intersect_line_line(verts[edges[0].vertices[0]].co,
- verts[edges[0].vertices[1]].co,
- verts[edges[1].vertices[0]].co,
- verts[edges[1].vertices[1]].co)
+ line = intersect_line_line(verts[edges[0].vertices[0]].co,
+ verts[edges[0].vertices[1]].co,
+ verts[edges[1].vertices[0]].co,
+ verts[edges[1].vertices[1]].co)
- if line is None:
- operator.report({'ERROR'}, "Selected edges do not intersect")
- return
+ if line is None:
+ operator.report({'ERROR'}, "Selected edges do not intersect")
+ return
- point = line[0].lerp(line[1], 0.5)
- context.scene.cursor.location = obj.matrix_world @ point
+ point = line[0].lerp(line[1], 0.5)
+ context.scene.cursor.location = obj.matrix_world @ point
# Cursor Edge Intersection Operator #
class VIEW3D_OT_CursorToEdgeIntersection(Operator):
- bl_idname = "view3d.snap_cursor_to_edge_intersection"
- bl_label = "Cursor to Edge Intersection"
- bl_description = "Finds the mid-point of the shortest distance between two edges"
+ bl_idname = "view3d.snap_cursor_to_edge_intersection"
+ bl_label = "Cursor to Edge Intersection"
+ bl_description = "Finds the mid-point of the shortest distance between two edges"
- @classmethod
- def poll(cls, context):
- obj = context.active_object
- return (obj is not None and obj.type == 'MESH')
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj is not None and obj.type == 'MESH')
- def execute(self, context):
- # Prevent unsupported Execution in Local View modes
- space = bpy.context.space_data
- if space.local_view:
- self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
- return {'FINISHED'}
- edgeIntersect(context, self)
- return {'FINISHED'}
+ def execute(self, context):
+ # Prevent unsupported Execution in Local View modes
+ space = bpy.context.space_data
+ if space.local_view:
+ self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
+ return {'FINISHED'}
+ edgeIntersect(context, self)
+ return {'FINISHED'}
# Origin To Selected Edit Mode #
def vfeOrigin(context):
- try:
- cursorPositionX = context.scene.cursor.location[0]
- cursorPositionY = context.scene.cursor.location[1]
- cursorPositionZ = context.scene.cursor.location[2]
- bpy.ops.view3d.snap_cursor_to_selected()
- bpy.ops.object.mode_set()
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
- bpy.ops.object.mode_set(mode='EDIT')
- context.scene.cursor.location[0] = cursorPositionX
- context.scene.cursor.location[1] = cursorPositionY
- context.scene.cursor.location[2] = cursorPositionZ
- return True
- except:
- return False
+ try:
+ cursorPositionX = context.scene.cursor.location[0]
+ cursorPositionY = context.scene.cursor.location[1]
+ cursorPositionZ = context.scene.cursor.location[2]
+ bpy.ops.view3d.snap_cursor_to_selected()
+ bpy.ops.object.mode_set()
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
+ bpy.ops.object.mode_set(mode='EDIT')
+ context.scene.cursor.location[0] = cursorPositionX
+ context.scene.cursor.location[1] = cursorPositionY
+ context.scene.cursor.location[2] = cursorPositionZ
+ return True
+ except:
+ return False
class VIEW3D_OT_SetOriginToSelected(Operator):
- bl_idname = "object.setorigintoselected"
- bl_label = "Set Origin to Selected"
- bl_description = "Set Origin to Selected"
+ bl_idname = "object.setorigintoselected"
+ bl_label = "Set Origin to Selected"
+ bl_description = "Set Origin to Selected"
- @classmethod
- def poll(cls, context):
- return (context.area.type == "VIEW_3D" and context.active_object is not None)
+ @classmethod
+ def poll(cls, context):
+ return (context.area.type == "VIEW_3D" and context.active_object is not None)
- def execute(self, context):
- check = vfeOrigin(context)
- if not check:
- self.report({"ERROR"}, "Set Origin to Selected could not be performed")
- return {'CANCELLED'}
+ def execute(self, context):
+ check = vfeOrigin(context)
+ if not check:
+ self.report({"ERROR"}, "Set Origin to Selected could not be performed")
+ return {'CANCELLED'}
- return {'FINISHED'}
+ return {'FINISHED'}
# ********** Edit Mesh Cursor **********
class VIEW3D_MT_EditCursorMenu(Menu):
- bl_label = "Snap To"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("object.setorigintoselected",
- text="Origin to Selected V/F/E")
- layout.separator()
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.menu("VIEW3D_MT_Snap_Context")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.operator("view3d.snap_cursor_to_edge_intersection",
- text="Cursor to Edge Intersection")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
+ bl_label = "Snap To"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("object.setorigintoselected",
+ text="Origin to Selected V/F/E")
+ layout.separator()
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.menu("VIEW3D_MT_Snap_Context")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.operator("view3d.snap_cursor_to_edge_intersection",
+ text="Cursor to Edge Intersection")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
# List The Classes #
classes = (
- VIEW3D_MT_CursorMenu,
- VIEW3D_MT_CursorMenuLite,
- VIEW3D_MT_Snap_Context,
- VIEW3D_MT_Snap_Origin,
- VIEW3D_OT_SnapCursSelToCenter,
- VIEW3D_OT_CursorToEdgeIntersection,
- VIEW3D_OT_SetOriginToSelected,
- VIEW3D_MT_EditCursorMenu,
+ VIEW3D_MT_CursorMenu,
+ VIEW3D_MT_CursorMenuLite,
+ VIEW3D_MT_Snap_Context,
+ VIEW3D_MT_Snap_Origin,
+ VIEW3D_OT_SnapCursSelToCenter,
+ VIEW3D_OT_CursorToEdgeIntersection,
+ VIEW3D_OT_SetOriginToSelected,
+ VIEW3D_MT_EditCursorMenu,
)
# Register Classes & Hotkeys #
def register():
- for cls in classes:
- bpy.utils.register_class(cls)
+ for cls in classes:
+ bpy.utils.register_class(cls)
# Unregister Classes & Hotkeys #
def unregister():
- for cls in reversed(classes):
- bpy.utils.unregister_class(cls)
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
if __name__ == "__main__":
- register()
+ register()
diff --git a/space_view3d_stored_views/io.py b/space_view3d_stored_views/io.py
index 4f9aaa83..83a5499d 100644
--- a/space_view3d_stored_views/io.py
+++ b/space_view3d_stored_views/io.py
@@ -340,4 +340,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/space_view3d_stored_views/operators.py b/space_view3d_stored_views/operators.py
index 4cf8a2cf..284e785c 100644
--- a/space_view3d_stored_views/operators.py
+++ b/space_view3d_stored_views/operators.py
@@ -179,4 +179,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/space_view3d_stored_views/properties.py b/space_view3d_stored_views/properties.py
index 0bf95097..51666ce2 100644
--- a/space_view3d_stored_views/properties.py
+++ b/space_view3d_stored_views/properties.py
@@ -134,4 +134,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/sun_position/geo.py b/sun_position/geo.py
index 6d49f2ad..59c27e39 100644
--- a/sun_position/geo.py
+++ b/sun_position/geo.py
@@ -36,7 +36,7 @@ class Parser:
def add(self, name, pattern, virtual=False):
""" Adds a new named pattern (regular expression) that can reference previously added patterns by %(pattern_name)s.
- Virtual patterns can be used to make expressions more compact but don't show up in the parse tree. """
+ Virtual patterns can be used to make expressions more compact but don't show up in the parse tree. """
self.raw_patterns[name] = "(?:" + pattern + ")"
self.virtual[name] = virtual
@@ -169,7 +169,7 @@ def get_coordinate(b):
def parse_position(s):
""" Takes a (utf8-encoded) string describing a position and returns a tuple of floats for latitude and longitude in degrees.
- Tries to be as tolerant as possible with input. Returns None if parsing doesn't succeed. """
+ Tries to be as tolerant as possible with input. Returns None if parsing doesn't succeed. """
parse_tree = position_parser.parse("position", s)
if parse_tree == None: return None