diff options
author | Remigiusz Fiedler <migius@gmx.net> | 2012-07-11 03:16:32 +0400 |
---|---|---|
committer | Remigiusz Fiedler <migius@gmx.net> | 2012-07-11 03:16:32 +0400 |
commit | 1dd571efee1758e622f48a42f46ce8dbc1a507af (patch) | |
tree | 061cd8c6d7d0ac5ebce89184d56a05cc650e56e2 /io_export_dxf/primitive_exporters | |
parent | 891ce0209b978ba8407bbb739e12db1562ea02b6 (diff) |
DXF-exporter script moved from addons_contrib to official addons folder
Diffstat (limited to 'io_export_dxf/primitive_exporters')
-rw-r--r-- | io_export_dxf/primitive_exporters/__init__.py | 10 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/base_exporter.py | 195 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/camera_exporter.py | 55 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/curve_exporter.py | 260 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/empty_exporter.py | 20 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/insert_exporter.py | 75 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/lamp_exporter.py | 21 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/mesh_exporter.py | 154 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/text_exporter.py | 89 | ||||
-rw-r--r-- | io_export_dxf/primitive_exporters/viewborder_exporter.py | 24 |
10 files changed, 903 insertions, 0 deletions
diff --git a/io_export_dxf/primitive_exporters/__init__.py b/io_export_dxf/primitive_exporters/__init__.py new file mode 100644 index 00000000..8e49ba00 --- /dev/null +++ b/io_export_dxf/primitive_exporters/__init__.py @@ -0,0 +1,10 @@ +""" +This package contains actual primitive exporter classes. +They are imported and instantiated according object type +that is being exported from export_dxf.py in ../ + +NOTE: Only MESH exporter has been ported since it is imho +mostly used. I am not specialist on Autocad so I cannot +guest how many time the other primitive are used. That's +why they are left unported. +""" diff --git a/io_export_dxf/primitive_exporters/base_exporter.py b/io_export_dxf/primitive_exporters/base_exporter.py new file mode 100644 index 00000000..b85dc127 --- /dev/null +++ b/io_export_dxf/primitive_exporters/base_exporter.py @@ -0,0 +1,195 @@ +import mathutils + +class BasePrimitiveDXFExporter(object): + + INSTANCES = False + PROJECTION = False + HIDDEN_LINES = False + + def __init__(self, settings): + self._settings = settings + + def projected_co(self, verts, matrix): + """ converts coordinates of points from OCS to WCS->ScreenCS + needs matrix: a projection matrix + needs verts: a list of vectors[x,y,z] + returns a list of [x,y,z] + """ + #print 'deb:projected_co() verts=', verts #--------- + temp_verts = [matrix*mathutils.Vector(v) for v in verts] + #print 'deb:projected_co() temp_verts=', temp_verts #--------- + + # if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val + # else:locZ = 0.0 + locZ = 0.0 + + if self.PROJECTION: + if self.PERSPECTIVE: + clipStart = 10.0 + for v in temp_verts: + coef = - clipStart / v[2] + v[0] *= coef + v[1] *= coef + v[2] = locZ + for v in temp_verts: + v[2] = locZ + temp_verts = [v[:3] for v in temp_verts] + #print 'deb:projected_co() out_verts=', temp_verts #--------- + return temp_verts + + def isLeftHand(self, matrix): + #Is the matrix a left-hand-system, or not? + ma = matrix.to_euler().to_matrix() + crossXY = self.M_CrossVecs(ma[0], ma[1]) + check = self.M_DotVecs(ma[2], crossXY) + if check < 0.00001: return 1 + return 0 + + #----------------------------------------------------- + def hidden_status(self, faces, mx, mx_n): + # sort out back-faces = with normals pointed away from camera + #print 'HIDDEN_LINES: caution! not full implemented yet' + front_faces = [] + front_edges = [] + for f in faces: + #print 'deb: face=', f #--------- + #print 'deb: dir(face)=', dir(f) #--------- + # get its normal-vector in localCS + vec_normal = f.no.copy() + #print 'deb: vec_normal=', vec_normal #------------------ + # must be transfered to camera/view-CS + vec_normal *= mx_n + #vec_normal *= mb.rotationPart() + #print 'deb:2vec_normal=', vec_normal #------------------ + #vec_normal *= mw0.rotationPart() + #print 'deb:3vec_normal=', vec_normal, '\n' #------------------ + + + frontFace = False + if not self.PERSPECTIVE: #for ortho mode ---------- + # normal must point the Z direction-hemisphere + if vec_normal[2] > 0.00001: + frontFace = True + else: + v = f.verts[0] + vert = mathutils.Vector(v.co) * mx + if mathutils.DotVecs(vert, vec_normal) < 0.00001: + frontFace = True + + if frontFace: + front_faces.append(f.index) + for key in f.edge_keys: + #this test can be done faster with set() + if key not in front_edges: + front_edges.append(key) + + #print 'deb: amount of visible faces=', len(front_faces) #--------- + #print 'deb: visible faces=', front_faces #--------- + #print 'deb: amount of visible edges=', len(front_edges) #--------- + #print 'deb: visible edges=', front_edges #--------- + return front_faces, front_edges + + #----------------------------------------------------- + def toGlobalOrigin(self, points): + """relocates points to the new location + needs a list of points [x,y,z] + """ + # if GUI_A['g_origin_on'].val: + # for p in points: + # p[0] += G_ORIGIN[0] + # p[1] += G_ORIGIN[1] + # p[2] += G_ORIGIN[2] + return points + + #---- migration to 2.49------------------------------------------------- + + #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!') + def M_CrossVecs(self, v1,v2): + if 'cross' in dir(mathutils.Vector()): + return v1.cross(v2) #for up2.49 + else: + return mathutils.CrossVecs(v1,v2) #for pre2.49 + + def M_DotVecs(self, v1,v2): + if 'cross' in dir(mathutils.Vector()): + return v1.dot(v2) #for up2.49 + else: + return mathutils.DotVecs(v1,v2) #for pre2.49 + +#----------------------------------------------------- + def getExtrusion(self, matrix): + """ calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors """ + AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector + Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]] + if AZaxis[2]==1.0: + Extrusion = None + AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector + else: + threshold = 1.0 / 64.0 + if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold: + # AXaxis is the intersection WorldPlane and ExtrusionPlane + AXaxis = self.M_CrossVecs(WORLDY,AZaxis) + else: + AXaxis = self.M_CrossVecs(WORLDZ,AZaxis) + #print 'deb:\n' #------------- + #print 'deb:getExtrusion() Extrusion=', Extrusion #--------- + return Extrusion, AXaxis.normalize() + + #----------------------------------------------------- +# def getZRotation(AXaxis, rot_matrix_invert): +# """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis +# +# """ +# # this works: Xaxis is the obj.matrix-Xaxis vector +# # but not correct for all orientations +# #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector +# ##Xaxis.normalize() # = ArbitraryXvector +# #ZRotation = - mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians +# +# # this works for all orientations, maybe a bit faster +# # transform AXaxis into OCS:Object-Coord-System +# #rot_matrix = normalizeMat(matrix.rotationPart()) +# #rot_matrix_invert = rot_matrix.invert() +# vec = AXaxis * rot_matrix_invert +# ##vec = AXaxis * matrix.copy().invert() +# ##vec.normalize() # not needed for atan2() +# #print '\ndeb:getExtrusion() vec=', vec #--------- +# ZRotation = - atan2(vec[1],vec[0]) #output in radians +# +# #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #--------- +# return ZRotation +# +# +# #----------------------------------------------------- +# def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ): +# """given +# """ +# if 1: +# rot_matrix = normalizeMat(mx.to_euler().to_matrix()) +# #TODO: workaround for blender negative-matrix.invert() +# # partially done: works only for rotX,rotY==0.0 +# if sizeX<0.0: rot_matrix[0] *= -1 +# if sizeY<0.0: rot_matrix[1] *= -1 +# #if sizeZ<0.0: rot_matrix[2] *= -1 +# rot_matrix_invert = rot_matrix.invert() +# else: #TODO: to check, why below rot_matrix_invert is not equal above one +# rot_euler_matrix = euler2matrix(rotX,rotY,rotZ) +# rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ) +# +# # OCS_origin is Global_Origin in ObjectCoordSystem +# OCS_origin = mathutils.Vector(WCS_loc) * rot_matrix_invert +# #print 'deb: OCS_origin=', OCS_origin #--------- +# +# ZRotation = rotZ +# if Extrusion!=None: +# ZRotation = getZRotation(AXaxis,rot_matrix_invert) +# #Zrotmatrix = mathutils.RotationMatrix(-ZRotation, 3, "Z") +# rs, rc = sin(ZRotation), cos(ZRotation) +# Zrotmatrix = mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0]) +# #print 'deb: Zrotmatrix=\n', Zrotmatrix #-------------- +# +# # ECS_origin is Global_Origin in EntityCoordSystem +# ECS_origin = OCS_origin * Zrotmatrix +# #print 'deb: ECS_origin=', ECS_origin #--------- +# #TODO: it doesnt work yet for negative scaled curve-objects! +# return ZRotation,Zrotmatrix,OCS_origin,ECS_origin diff --git a/io_export_dxf/primitive_exporters/camera_exporter.py b/io_export_dxf/primitive_exporters/camera_exporter.py new file mode 100644 index 00000000..e31166ed --- /dev/null +++ b/io_export_dxf/primitive_exporters/camera_exporter.py @@ -0,0 +1,55 @@ +from .base_exporter import BasePrimitiveDXFExporter + + +class CameraDXFExporter(BasePrimitiveDXFExporter): + pass + + +#----------------------------------------------------- +def exportCamera(ob, mx, mw, **common): + """converts Camera-Object to desired projection and representation(DXF-Entity type) + """ + location = mathutils.Vector(ob.loc) + [location] = projected_co([location], mx) + [location] = toGlobalOrigin([location]) + view_name=validDXFr12name(('CAM_'+ ob.name)) + + camera = Camera.Get(ob.getData(name_only=True)) + #print 'deb: camera=', dir(camera) #------------------ + if camera.type=='persp': + mode = 1+2+4+16 + # mode flags: 1=persp, 2=frontclip, 4=backclip,16=FrontZ + elif camera.type=='ortho': + mode = 0+2+4+16 + + leftBottom=(0.0,0.0) # default + rightTop=(1.0,1.0) # default + center=(0.0,0.0) # default + + direction = mathutils.Vector(0.0,0.0,1.0) * mx.to_euler().to_matrix() # in W-C-S + direction.normalize() + target=mathutils.Vector(ob.loc) - direction # in W-C-S + #ratio=1.0 + width=height= camera.scale # for ortho-camera + lens = camera.lens # for persp-camera + frontClipping = -(camera.clipStart - 1.0) + backClipping = -(camera.clipEnd - 1.0) + + entities, vport, view = [], None, None + c = camera_as_list[GUI_A['camera_as'].val] + if c=="POINT": # export as POINT + dxfPOINT = DXF.Point(points=[location],**common) + entities.append(dxfPOINT) + elif c=="VIEW": # export as VIEW + view = DXF.View(name=view_name, + center=center, width=width, height=height, + frontClipping=frontClipping,backClipping=backClipping, + direction=direction,target=target,lens=lens,mode=mode + ) + elif c=="VPORT": # export as VPORT + vport = DXF.VPort(name=view_name, + center=center, ratio=1.0, height=height, + frontClipping=frontClipping,backClipping=backClipping, + direction=direction,target=target,lens=lens,mode=mode + ) + return entities, vport, view diff --git a/io_export_dxf/primitive_exporters/curve_exporter.py b/io_export_dxf/primitive_exporters/curve_exporter.py new file mode 100644 index 00000000..d74a459f --- /dev/null +++ b/io_export_dxf/primitive_exporters/curve_exporter.py @@ -0,0 +1,260 @@ +from .base_exporter import BasePrimitiveDXFExporter + + +class CurveDXFExporter(BasePrimitiveDXFExporter): + pass + +#----------------------------------------------------- +def exportCurve(ob, mx, mw, **common): + """converts Curve-Object to desired projection and representation(DXF-Entity type) + """ + entities = [] + block = None + curve = ob.getData() + #print 'deb: curve=', dir(curve) #--------- + # TODO: should be: if curve.users>1 and not (PERSPECTIVE or (PROJECTION and HIDDEN_MODE): + if INSTANCES and curve.users>1 and not PROJECTION: + if curve.name in BLOCKREGISTRY.keys(): + insert_name = BLOCKREGISTRY[curve.name] + # write INSERT to entities + entities = exportInsert(ob, mx,insert_name, **common) + else: + # generate geom_output in ObjectCS + imx = mathutils.Matrix().identity() + WCS_loc = [0,0,0] # WCS_loc is object location in WorldCoordSystem + #print 'deb: WCS_loc=', WCS_loc #--------- + sizeX = sizeY = sizeZ = 1.0 + rotX = rotY = rotZ = 0.0 + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None + AXaxis = imx[0].copy().resize3D() # = ArbitraryXvector + OCS_origin = [0,0,0] + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(imx) + + # no thickness/width for POLYLINEs converted into Screen-C-S + #print 'deb: curve.ext1=', curve.ext1 #--------- + if curve.ext1: Thickness = curve.ext1 * sizeZ + if curve.ext2 and sizeX==sizeY: + Width = curve.ext2 * sizeX + if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(imx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + + entities = writeCurveEntities(curve, imx, + Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, + WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, + **common) + + if entities: # if not empty block + # write BLOCK definition and INSERT entity + # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name) + BLOCKREGISTRY[curve.name]=validDXFr12name(('CU_'+ curve.name)) + insert_name = BLOCKREGISTRY[curve.name] + block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities) + # write INSERT as entity + entities = exportInsert(ob, mx, insert_name, **common) + + else: # no other instances, so go the standard way + WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem + #print 'deb: WCS_loc=', WCS_loc #--------- + sizeX = ob.SizeX + sizeY = ob.SizeY + sizeZ = ob.SizeZ + rotX = ob.RotX + rotY = ob.RotY + rotZ = ob.RotZ + #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- + + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = None,None,None,None + AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector + OCS_origin = [0,0,0] + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(mx) + + # no thickness/width for POLYLINEs converted into Screen-C-S + #print 'deb: curve.ext1=', curve.ext1 #--------- + if curve.ext1: Thickness = curve.ext1 * sizeZ + if curve.ext2 and sizeX==sizeY: + Width = curve.ext2 * sizeX + if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + entities = writeCurveEntities(curve, mx, + Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, + WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, + **common) + + return entities, block + + +#------------------------------------------------- +def writeCurveEntities(curve, mx, + Thickness,Extrusion,ZRotation,Elevation,AXaxis,Zrotmatrix, + WCS_loc,OCS_origin,ECS_origin,sizeX,sizeY,sizeZ, + **common): + """help routine for exportCurve() + """ + entities = [] + width1,width2 = None, None + if 1: + for cur in curve: + #print 'deb: START cur=', cur #-------------- + #print 'deb: dir(curve):',dir(cur) #--------- + #print 'deb: curve.type:',cur.type #--------- + points = [] + flags = [] + pflag70, pflag75 = 0,0 + + if cur.type==4: # is NURBS + #if cur.isNurb(): + #print 'deb:isNurb --------------' #--------- + pflag70 = 4 + orderU = cur.orderU + # curve type: + # 0: curvNoFitted + # 5: curvQuadraticBspline + # 6: curvCubicBspline + # 8: curvBezier + if orderU<=4: pflag75 = 5 + elif orderU>=5: pflag75 = 6 + + vflag70 = 16 + i = -2 + for point in cur: + #print 'deb:isNurb point=', point #--------- + i+=1 + if i==orderU-1: i = 0 + if i: + flags.append([16, [width1,width2]]) + else: + flags.append([8, [width1,width2]]) + vec = point[0:3] + #print 'deb: vec=', vec #--------- + pkt = mathutils.Vector(vec) + #print 'deb: pkt=', pkt #--------- + points.append(pkt) + if not cur.isCyclic(): + points = points[1:-1] + flags = flags[1:-1] + elif cur.type==1: # is Bezier + #print 'deb:isBezier --------------' #--------- + pflag75 = 8 + vflag70 = 1 + for point in cur: + #print 'deb:isBezier point=', point #--------- + #print 'deb:isBezier point=', point.getTriple() #--------- + ptan1,pfit,ptan2 = point.getTriple() + #print 'deb: point=', pt #--------- + ptan1 = mathutils.Vector(ptan1) + pfit = mathutils.Vector(pfit) + ptan2 = mathutils.Vector(ptan2) + #print 'deb: pkt=', pkt #--------- + points.append(ptan1) + flags.append([2, [width1,width2]]) + points.append(pfit) + flags.append([1, [width1,width2]]) + points.append(ptan2) + flags.append([2, [width1,width2]]) + if not cur.isCyclic(): + points = points[1:-1] + flags = flags[1:-1] + elif cur.type==0: # is Polygon + #print 'deb:isPolygon --------------' #--------- + #pflag70 = 4 + pflag75 = 0 + for point in cur: + #print 'deb:isPoly point=', point #--------- + vec = point[0:3] + #print 'deb: vec=', vec #--------- + pkt = mathutils.Vector(vec) + #print 'deb: pkt=', pkt #--------- + points.append(pkt) + flags.append([None, [width1,width2]]) + + #print 'deb: points', points #-------------- + if len(points)>1: + c = curve_as_list[GUI_A['curve_as'].val] + + if c=="POLYLINE": # export Curve as POLYLINE + if not PROJECTION: + # recalculate points(2d=X,Y) into Entity-Coords-System + for p in points: # list of vectors + p[0] *= sizeX + p[1] *= sizeY + p2 = p * Zrotmatrix + p2[0] += ECS_origin[0] + p2[1] += ECS_origin[1] + p[0],p[1] = p2[0],p2[1] + else: + points = projected_co(points, mx) + #print 'deb: points', points #-------------- + + if cur.isCyclic(): closed = 1 + else: closed = 0 + points = toGlobalOrigin(points) + points_temp = [] + for p,f in zip(points,flags): + points_temp.append([p,f[0],f[1]]) + points = points_temp + #print 'deb: points', points #-------------- + + if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene + + common['extrusion']= Extrusion + ##common['rotation']= ZRotation + ##common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + + flag70, flag75 = pflag70+closed, pflag75 + if 0: #DEBUG + p=AXaxis[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + p=ECS_origin[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + common['color']= 5 + p=OCS_origin[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + #OCS_origin=[0,0,0] #only debug---------------- + dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common) + entities.append(dxfPLINE) + + dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common) + entities.append(dxfPLINE) + if Thickness: + common['thickness']= -Thickness + dxfPLINE = DXF.PolyLine(points,OCS_origin, flag70=flag70, flag75=flag70, width=0.0,**common) + entities.append(dxfPLINE) + + elif c=="LINEs": # export Curve as multiple LINEs + points = projected_co(points, mx) + if cur.isCyclic(): points.append(points[0]) + #print 'deb: points', points #-------------- + points = toGlobalOrigin(points) + + if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene + common['extrusion']= Extrusion + common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + for i in range(len(points)-1): + linepoints = [points[i], points[i+1]] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + if Thickness: + common['thickness']= -Thickness + for i in range(len(points)-1): + linepoints = [points[i], points[i+1]] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + + elif c=="POINTs": # export Curve as multiple POINTs + points = projected_co(points, mx) + for p in points: + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities diff --git a/io_export_dxf/primitive_exporters/empty_exporter.py b/io_export_dxf/primitive_exporters/empty_exporter.py new file mode 100644 index 00000000..e849409e --- /dev/null +++ b/io_export_dxf/primitive_exporters/empty_exporter.py @@ -0,0 +1,20 @@ +from .base_exporter import BasePrimitiveDXFExporter + + +class EmptyDXFExporter(BasePrimitiveDXFExporter): + pass + +#----------------------------------------------------- +def exportEmpty(ob, mx, mw, **common): + """converts Empty-Object to desired projection and representation(DXF-Entity type) + """ + p = mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toGlobalOrigin([p]) + + entities = [] + c = empty_as_list[GUI_A['empty_as'].val] + if c=="POINT": # export Empty as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities diff --git a/io_export_dxf/primitive_exporters/insert_exporter.py b/io_export_dxf/primitive_exporters/insert_exporter.py new file mode 100644 index 00000000..80cf7dbd --- /dev/null +++ b/io_export_dxf/primitive_exporters/insert_exporter.py @@ -0,0 +1,75 @@ + +from .base_exporter import BasePrimitiveDXFExporter + + +class InsertDXFExporter(BasePrimitiveDXFExporter): + pass + +#----------------------------------------------------- +def exportInsert(ob, mx, insert_name, **common): + """converts Object to DXF-INSERT in given orientation + """ + WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem + sizeX = ob.SizeX + sizeY = ob.SizeY + sizeZ = ob.SizeZ + rotX = ob.RotX + rotY = ob.RotY + rotZ = ob.RotZ + #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- + + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + + AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(mx) + + entities = [] + + if 1: + if not PROJECTION: + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + ZRotation *= r2d + point = ECS_origin + else: #TODO: fails correct location + point1 = mathutils.Vector(ob.loc) + [point] = projected_co([point1], mx) + if PERSPECTIVE: + clipStart = 10.0 + coef = -clipStart / (point1*mx)[2] + #print 'deb: coef=', coef #-------------- + #TODO: ? sizeX *= coef + #sizeY *= coef + #sizeZ *= coef + + #print 'deb: point=', point #-------------- + [point] = toGlobalOrigin([point]) + + #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene + common['extrusion']= Extrusion + #common['elevation']= Elevation + #print 'deb: common=', common #------------------ + if 0: #DEBUG + #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]] + linepoints = [[0,0,0], point] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + + xscale=sizeX + yscale=sizeY + zscale=sizeZ + cols=None + colspacing=None + rows=None + rowspacing=None + + dxfINSERT = DXF.Insert(insert_name,point=point,rotation=ZRotation,\ + xscale=xscale,yscale=yscale,zscale=zscale,\ + cols=cols,colspacing=colspacing,rows=rows,rowspacing=rowspacing,\ + **common) + entities.append(dxfINSERT) + + return entities + diff --git a/io_export_dxf/primitive_exporters/lamp_exporter.py b/io_export_dxf/primitive_exporters/lamp_exporter.py new file mode 100644 index 00000000..01a65abd --- /dev/null +++ b/io_export_dxf/primitive_exporters/lamp_exporter.py @@ -0,0 +1,21 @@ +from .base_exporter import BasePrimitiveDXFExporter + + +class LampDXFExporter(BasePrimitiveDXFExporter): + pass + +#----------------------------------------------------- +def exportLamp(ob, mx, mw, **common): + """converts Lamp-Object to desired projection and representation(DXF-Entity type) + """ + p = mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toGlobalOrigin([p]) + + entities = [] + c = lamp_as_list[GUI_A['lamp_as'].val] + if c=="POINT": # export as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities + diff --git a/io_export_dxf/primitive_exporters/mesh_exporter.py b/io_export_dxf/primitive_exporters/mesh_exporter.py new file mode 100644 index 00000000..56509e32 --- /dev/null +++ b/io_export_dxf/primitive_exporters/mesh_exporter.py @@ -0,0 +1,154 @@ + +import mathutils +from .base_exporter import BasePrimitiveDXFExporter +import copy + +class MeshDXFExporter(BasePrimitiveDXFExporter): + + def export(self, ctx, drawing, ob, mx, mx_n, **kwargs): + """ + Converts Mesh-Object to desired projection and representation(DXF-Entity type) + """ + me = self._getMeshData(ctx, ob, self._settings) + # idea: me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state + # the .transform-method is fast, but bad, cause invasive: + # it manipulates original geometry and by retransformation lefts back rounding-errors + # we dont want to manipulate original data! + #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug? + if me.vertices: + # check if there are more instances of this mesh (if used by other objects), then write to BLOCK/INSERT + if self.INSTANCES and me.users>1 and not self.PROJECTION and not (ob.modifiers and self._settings['apply_modifiers']): + if drawing.containsBlock(me.name): + entities = self._writeInsert(drawing, ob, mx, me.name) + else: + # generate geom_output in ObjectCS + allpoints = [v.co for v in me.vertices] + identity_matrix = mathutils.Matrix().identity() + allpoints = self.projected_co(allpoints, identity_matrix) + #allpoints = toGlobalOrigin(allpoints) + faces=[] + edges=[] + for e in me.edges: edges.append(e.key) + faces = [[v.index for v in f.verts] for f in me.faces] + entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs) + if entities: # if not empty block + # write BLOCK definition and INSERT entity + # BLOCKREGISTRY = dictionary 'blender_name':'dxf_name'.append(me.name) +# BLOCKREGISTRY[me.name]=self.validDXFr12name(('ME_'+ me.name)) +# insert_name = BLOCKREGISTRY[me.name] + drawing.addBlock(me.name, flag=0,base=(0,0,0),entities=entities) +# block = DXF.Block(insert_name,flag=0,base=(0,0,0),entities=entities) + # write INSERT as entity + entities = self._writeInsert(ob, mx, me.name, **(kwargs)) + + else: # no other instances, so go the standard way + return self._standard_way(drawing, me, mx, mx_n) + + def _writeInsert(self, drawing, ob, mx, insert_name, **kwargs): + from insert_exporter import InsertDXFExporter + ex = InsertDXFExporter(self._settings) + ex.export(drawing, ob, mx, insert_name, **(kwargs)) + + def _getMeshData(self, ctx, obj, settings): + if obj.modifiers and settings['apply_modifiers']: + #this gets mesh with applied modifiers + data = obj.to_mesh(ctx.scene, True, 'PREVIEW') + else: + # me = ob.getData(mesh=1) # is a Mesh if mesh>0 (otherwise it is a NMesh) + data = obj.data + return data + + def _standard_way(self, drawing, me, mx, mx_n, **kwargs): + allpoints = [v.co for v in me.vertices] + allpoints = self.projected_co(allpoints, mx) + allpoints = self.toGlobalOrigin(allpoints) + faces=[] + edges=[] + me.update(calc_tessface=True) + me_faces = me.tessfaces + #print('deb: allpoints=\n', allpoints) #--------- + #print('deb: me_faces=\n', me_faces) #--------- + if me_faces and self.PROJECTION and self.HIDDEN_LINES: + #if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- + faces, edges = self.hidden_status(me_faces, mx, mx_n) + faces = [[v.index for v in me_faces[f_nr].vertices] for f_nr in faces] + else: + #if DEBUG: print 'deb:exportMesh STANDARD mode' #--------- + for e in me.edges: edges.append(e.key) + #faces = [f.index for f in me.faces] + ##faces = [[v.index for v in f.vertices] for f in me.faces] + faces = me_faces + #faces = [[allpoints[v.index] for v in f.vertices] for f in me.faces] + #print('deb: allpoints=\n', allpoints) #--------- + #print('deb: edges=\n', edges) #--------- + #print('deb: faces=\n', faces) #--------- + if self.isLeftHand(mx): # then change vertex-order in every face + for f in faces: + f.reverse() + #f = [f[-1]] + f[:-1] #TODO: might be needed + #print('deb: faces=\n', faces) #--------- + entities = self._writeMeshEntities(allpoints, edges, faces, **kwargs) + # TODO: rewrite + for type, args in entities: + drawing.addEntity(type, **(args)) + return True + + def _writeMeshEntities(self, allpoints, edges, faces, **kwargs): + """help routine for exportMesh() + """ + entities = [] + c = self._settings['mesh_as'] + if c=='POINTs': # export Mesh as multiple POINTs + for p in allpoints: + args = copy.copy(kwargs) + args['points'] = [p] + entities.append(('Point', args)) + elif c=='LINEs' or (not faces): + if edges and allpoints: +# if exportsettings['verbose']: +# mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene + for e in edges: + points = [allpoints[e[0]], allpoints[e[1]]] + args = copy.copy(kwargs) + args['points'] = points + entities.append(('Line', args)) + elif c in ('POLYFACE','POLYLINE'): + if faces and allpoints: + #TODO: purge allpoints: left only vertices used by faces +# if exportsettings['verbose']: +# mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + if not (self.PROJECTION and self.HIDDEN_LINES): + faces = [[v+1 for v in f.vertices] for f in faces] + else: + # for back-Faces-mode remove face-free vertices + map=verts_state= [0]*len(allpoints) + for f in faces: + for v in f: + verts_state[v]=1 + if 0 in verts_state: # if dirty state + i,newverts=0,[] + for used_i,used in enumerate(verts_state): + if used: + newverts.append(allpoints[used_i]) + map[used_i]=i + i+=1 + allpoints = newverts + faces = [[map[v]+1 for v in f] for f in faces] + args = copy.copy(kwargs) + args['flag70'] = 64 + args['flag75'] = 0 + args['width'] = 0.0 + args['points'] = [allpoints, faces] + entities.append(('PolyLine', args)) + elif c=='3DFACEs': + if faces and allpoints: +# if exportsettings['verbose']: +# mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + for f in faces: + points = [allpoints[v_id] for v_id in f.vertices] + args = copy.copy(kwargs) + args['points'] = points +# print(args) + entities.append(('Face', args)) + + return entities diff --git a/io_export_dxf/primitive_exporters/text_exporter.py b/io_export_dxf/primitive_exporters/text_exporter.py new file mode 100644 index 00000000..c7e9d173 --- /dev/null +++ b/io_export_dxf/primitive_exporters/text_exporter.py @@ -0,0 +1,89 @@ +from .base_exporter import BasePrimitiveDXFExporter + + +class TextDXFExporter(BasePrimitiveDXFExporter): + pass + +#----------------------------------------------------- +def exportText(ob, mx, mw, **common): + """converts Text-Object to desired projection and representation(DXF-Entity type) + """ + text3d = ob.getData() + textstr = text3d.getText() + WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem + sizeX = ob.SizeX + sizeY = ob.SizeY + sizeZ = ob.SizeZ + rotX = ob.RotX + rotY = ob.RotY + rotZ = ob.RotZ + #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- + + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + + AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(mx) + + # no thickness/width for TEXTs converted into ScreenCS + if text3d.getExtrudeDepth(): + Thickness = text3d.getExtrudeDepth() * sizeZ + + #Horizontal text justification type, code 72, (optional, default = 0) + # integer codes (not bit-coded) + #0=left, 1=center, 2=right + #3=aligned, 4=middle, 5=fit + Alignment = None + alignment = text3d.getAlignment().value + if alignment in (1,2): Alignment = alignment + + textHeight = text3d.getSize() / 1.7 + textFlag = 0 + if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored + if sizeZ < 0.0: textFlag |= 4 # vertical mirrored + + entities = [] + c = text_as_list[GUI_A['text_as'].val] + + if c=="TEXT": # export text as TEXT + if not PROJECTION: + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + ZRotation *= r2d + point = ECS_origin + else: #TODO: fails correct location + point1 = mathutils.Vector(ob.loc) + [point] = projected_co([point1], mx) + if PERSPECTIVE: + clipStart = 10.0 + coef = -clipStart / (point1*mx)[2] + textHeight *= coef + #print 'deb: coef=', coef #-------------- + + #print 'deb: point=', point #-------------- + [point] = toGlobalOrigin([point]) + point2 = point + + #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene + common['extrusion']= Extrusion + #common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + if 0: #DEBUG + #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]] + linepoints = [[0,0,0], point] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + + dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ + flag=textFlag,height=textHeight,justifyhor=Alignment,**common) + entities.append(dxfTEXT) + if Thickness: + common['thickness']= -Thickness + dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ + flag=textFlag,height=textHeight,justifyhor=Alignment,**common) + entities.append(dxfTEXT) + return entities + + diff --git a/io_export_dxf/primitive_exporters/viewborder_exporter.py b/io_export_dxf/primitive_exporters/viewborder_exporter.py new file mode 100644 index 00000000..680e4a54 --- /dev/null +++ b/io_export_dxf/primitive_exporters/viewborder_exporter.py @@ -0,0 +1,24 @@ +from base_exporter import BasePrimitiveDXFExporter + + +class ViewBorderDXFExporter(BasePrimitiveDXFExporter): + + def export(self, ob, mx, mw, **common): + """converts Lamp-Object to desired projection and representation(DXF-Entity type) + """ + identity_matrix = mathutils.Matrix().identity() + points = projected_co(border, identity_matrix) + closed = 1 + points = toGlobalOrigin(points) + c = settings['curve_as'] + if c=="LINEs": # export Curve as multiple LINEs + for i in range(len(points)-1): + linepoints = [points[i], points[i+1]] + dxfLINE = DXF.Line(linepoints,paperspace=espace,color=LAYERCOLOR_DEF) + entities.append(dxfLINE) + else: + fag70, flag75 = closed, 0 + dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag70=flag70, flag75=flag70, width=0.0, paperspace=espace, color=LAYERCOLOR_DEF) + #dxfPLINE = DXF.PolyLine(points,points[0],[closed,0,0], paperspace=espace, color=LAYERCOLOR_DEF) + d.append(dxfPLINE) + |