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

base_exporter.py « primitive_exporters « io_export_dxf - git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 02d2747ec26ee70ab457bf3950b55fe5b00be772 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# SPDX-License-Identifier: GPL-2.0-or-later

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 transferred 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 is not 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 doesn't work yet for negative scaled curve-objects!
#        return ZRotation,Zrotmatrix,OCS_origin,ECS_origin