1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # vert class and overloading experiments
7 from math
import acos
, pi
, sin
, cos
, atan
, tan
8 from mathutils
import Vector
9 from bpy_extras
.object_utils
import AddObjectHelper
11 # PKHG>DBG change the DBG_info and use extra_DBG_info
12 DBG_info
= {"MeshInfo": False, "StrutMesh": False, "HubMesh": False}
15 def extra_DBG_info(name
="value from DBG_info", info_text
="default\n", info_obj
=None):
17 DBG_keys
= DBG_info
.keys()
20 print(info_text
, info_obj
)
22 sgn
= lambda x
: (x
> 0) - (x
< 0) # missing signum function in Python
25 def vefm_add_object(selfobj
):
26 for i
in range(len(selfobj
.verts
)):
27 selfobj
.verts
[i
].index
= i
28 v
= [el
.vector
for el
in selfobj
.verts
]
30 e
= [[edge
.a
.index
, edge
.b
.index
] for edge
in selfobj
.edges
]
32 if type(selfobj
.faces
[0]) == type([]):
33 # PKHG should be a list of vertices, which have an index
34 f
= [[v
.index
for v
in face
] for face
in selfobj
.faces
]
36 f
= [[v
.index
for v
in face
.vertices
] for face
in selfobj
.faces
]
38 m
= bpy
.data
.meshes
.new(name
=selfobj
.name
)
39 m
.from_pydata(v
, e
, f
)
40 # useful for development when the mesh may be invalid.
41 m
.validate(verbose
=False)
48 def __init__(self
, vec
=(0, 0, 0)): # default x = 0, y = 0, z = 0):
49 self
.vector
= Vector(vec
)
50 self
.length
= self
.vector
.length
58 self
.length
= self
.vector
.length
63 tmp
= 1.0 / self
.length
64 self
.vector
= tmp
* self
.vector
69 if self
.faces
[:] == []:
70 print("vefm vertex L68 pkhg:*****ERROR**** findnormal has no faces")
72 for currentface
in self
.faces
:
73 target
.append(currentface
.normal
)
74 self
.normal
= average(target
).centroid()
75 self
.normal
.findlength()
77 print("******ERROR*** length zero in findnormal, j = (0,1,0) replaced")
78 self
.normal
= vertex((0, 1, 0))
79 self
.normal
.normalize()
81 def clockwise(self
): # PKHG self is a vertex
83 start
= self
.boundarystart()
89 for i
in range(len(self
.edges
)):
91 self
.tempfaces
.append(start
)
92 for corner
in start
.corners
:
93 if corner
[0] is not self
:
95 elif corner
[0] is self
:
96 self
.tempedges
.append(corner
[1])
98 for facey
in nextedge
.faces
:
99 if facey
is not start
:
102 self
.edges
= self
.tempedges
103 self
.faces
= self
.tempfaces
105 def boundarystart(self
):
109 def __add__(self
, other
):
110 if isinstance(other
, Vector
):
111 tmp
= self
.vector
+ other
113 tmp
= self
.vector
+ other
.vector
116 def __sub__(self
, other
):
117 if isinstance(other
, Vector
):
118 tmp
= self
.vector
- other
120 tmp
= self
.vector
- other
.vector
123 def __mul__(self
, other
):
124 tmp
= self
.vector
* other
127 def __truediv__(self
, other
):
129 tmp
= self
.vector
* denom
133 return vertex(-self
.vector
)
137 # Takes in two vertices(vectors), returns the cross product.
138 def __init__(self
, v1
, v2
):
142 def docrossproduct(self
):
143 tmp
= self
.v1
.vector
.cross(self
.v2
.vector
)
148 # Takes a list of vertices and returns the average. If two verts are passed, returns midpoint.
149 def __init__(self
, vertlist
):
150 self
.vertlist
= vertlist
154 # PKHG avoid emptylist problems
156 nr_vertices
= len(self
.vertlist
)
158 divisor
= 1.0 / len(self
.vertlist
)
159 elif nr_vertices
== 0:
160 print("\n***WARNING*** empty list in vefm_271.centroid! L158")
161 for vert
in self
.vertlist
:
162 tmp
= tmp
+ vert
.vector
168 def __init__(self
, a
=0, b
=0):
176 self
.vect
= 0 # PKHG becomes b - a
177 self
.vectb
= 0 # PKHG becomes a - b
183 self
.vect
= self
.b
- self
.a
184 self
.vectb
= self
.a
- self
.b
186 def findlength(self
):
187 self
.vect
.findlength()
188 self
.vectb
.length
= self
.vect
.length
190 def findnormal(self
):
192 self
.normal
= self
.faces
[0].normal
# average([self.a, self.b]).centroid()
194 self
.normal
= average([self
.faces
[0].normal
, self
.faces
[1].normal
]).centroid()
195 self
.normal
.normalize()
199 def __init__(self
, vertices
=[]):
200 # PKHG ok good for tri's at least
201 self
.vertices
= vertices
# List of vertex instances
202 self
.edges
= [] # Will be filled with the sides of the face
203 self
.boundary
= 0 # When set will have bool and id of edge concerned
204 self
.normal
= 0 # Face normal found through cross product
206 self
.spokes
= [] # Vectors of the bisecting angles from each corner to the centre + dotproduct
210 # dotproduct is misleading name, it is the hook between two vectors!
211 def dotproduct(self
, v1
, v2
):
214 if v1
.length
== 0 or v2
.length
== 0:
215 print("\nPKHG warning, ===== vefm_271 dotproduct L212 ======"
216 " at least one zero vector 0 used")
218 dot
= v1
.vector
.dot(v2
.vector
)
219 costheta
= dot
/ (v1
.length
* v2
.length
)
223 def orderedges(self
):
225 finish
= len(self
.vertices
)
226 for i
in range(finish
):
227 current
= self
.vertices
[i
]
229 next
= self
.vertices
[0]
231 next
= self
.vertices
[i
+ 1]
232 for edge
in face
.edges
:
233 if edge
.a
== current
and edge
.b
== next
:
234 face
.clockw
.append(edge
.vect
)
235 face
.aclockw
.append(edge
.vectb
)
237 if edge
.b
== current
and edge
.a
== next
:
238 face
.clockw
.append(edge
.vectb
)
239 face
.aclockw
.append(edge
.vect
)
241 for edge
in face
.edges
:
242 if edge
.a
== current
and edge
.b
== next
:
243 face
.clockw
.append(edge
.vect
)
244 face
.aclockw
.append(edge
.vectb
)
246 if edge
.b
== current
and edge
.a
== next
:
247 face
.clockw
.append(edge
.vectb
)
248 face
.aclockw
.append(edge
.vect
)
253 # This function identifies and stores the vectors coming from each vertex
254 # allowing easier calculation of cross and dot products.
255 finish
= len(self
.vertices
)
257 for i
in range(finish
):
258 current
= self
.vertices
[i
]
260 next
= self
.vertices
[0]
262 next
= self
.vertices
[i
+ 1]
264 previous
= self
.vertices
[-1]
266 previous
= self
.vertices
[i
- 1]
267 corner
= [current
] # PKHG new for each vertex = current
272 for edge
in self
.edges
:
273 if finish
== 3 and len(self
.edges
) == 2 and i
== 2:
276 # next and previous are vertex with respect to ith vertex
277 if edge
.a
is current
or edge
.b
is current
: # does this edge contain our current vert
278 if edge
.a
is current
:
281 rightvect
= edge
.vect
282 if edge
.b
is previous
:
285 elif edge
.b
is current
:
288 rightvect
= edge
.vectb
289 if edge
.a
is previous
:
291 leftvect
= edge
.vectb
292 corner
.append(rightedge
)
293 corner
.append(leftedge
)
294 if rightedge
and leftedge
:
296 dotty
= self
.dotproduct(rightvect
, leftvect
)
298 self
.corners
.append(corner
)
300 def findnormal(self
):
301 one
= self
.corners
[1][2]
302 two
= self
.corners
[1][1]
303 if one
.a
is self
.corners
[1][0]:
305 elif one
.b
is self
.corners
[1][0]:
307 if two
.a
is self
.corners
[1][0]:
309 elif two
.b
is self
.corners
[1][0]:
311 self
.normal
= crossp(one
, two
).docrossproduct()
312 self
.normal
.findlength()
313 self
.normal
.normalize()
316 for corner
in self
.corners
:
321 one
= vertex(right
.vect
.vector
)
322 elif right
.b
is vert
:
323 one
= vertex(right
.vectb
.vector
)
325 two
= vertex(left
.vect
.vector
)
327 two
= vertex(left
.vectb
.vector
)
333 self
.spokes
.append(spoke
)
336 centre
= average(self
.vertices
).centroid()
337 for point
in self
.vertices
:
338 newedge
= edge(point
, centre
)
339 self
.spokes
.append(newedge
)
343 def __init__(self
, name
="GD_mesh"):
351 self
.vertedgeflag
= 0
352 self
.vertfaceflag
= 0
353 self
.faceedgeflag
= 0
354 self
.boundaryflag
= 0
355 self
.vertnormalflag
= 0
356 self
.edgenormalflag
= 0
357 self
.facenormalflag
= 0
364 def power(self
, a
, b
): # Returns a power, including negative numbers
365 result
= sgn(a
) * (abs(a
) ** b
)
368 def sign(self
, d
): # Works out the sign of a number.
371 def ellipsecomp(self
, efactor
, theta
):
372 if theta
== self
.a90
:
374 elif theta
== self
.a180
:
376 elif theta
== self
.a270
:
378 elif theta
== self
.a360
:
381 result
= atan(tan(theta
) / efactor
** 0.5)
383 if theta
> self
.a180
:
384 result
= result
+ self
.a180
385 elif theta
< self
.a180
:
386 result
= result
+ self
.a180
389 if theta
> self
.a180
:
390 result
= result
+ self
.a180
391 elif theta
< self
.a180
:
395 def connectivity(self
):
401 def superell(self
, n1
, uv
, turn
):
408 r
= self
.power(1.0 / (t1
+ t2
), (1.0 / n1
))
411 def superform(self
, m
, n1
, n2
, n3
, uv
, a
, b
, twist
):
412 t1
= cos(m
* (uv
+ twist
) * .25) * a
415 t2
= sin(m
* (uv
+ twist
) * .25) * b
418 r
= self
.power(1.0 / (t1
+ t2
), n1
)
421 def dovertedge(self
):
422 if not self
.vertedgeflag
:
423 for vert
in self
.verts
:
425 for currentedge
in self
.edges
:
426 currentedge
.a
.edges
.append(currentedge
)
427 currentedge
.b
.edges
.append(currentedge
)
428 self
.vertedgeflag
= 1
430 def dovertface(self
):
431 if not self
.vertfaceflag
:
432 for vert
in self
.verts
:
434 for face
in self
.faces
:
435 for vert
in face
.vertices
:
436 vert
.faces
.append(face
)
437 self
.vertfaceflag
= 1
439 def dofaceedge(self
):
440 self
.dovertedge() # just in case they haven't been done
442 if not self
.faceedgeflag
:
443 for edge
in self
.edges
:
445 for face
in self
.faces
:
447 for face
in self
.faces
:
448 finish
= len(face
.vertices
)
449 for i
in range(finish
):
450 current
= face
.vertices
[i
]
452 next
= face
.vertices
[0]
454 next
= face
.vertices
[i
+ 1]
455 for edge
in current
.edges
:
456 if edge
.a
is current
or edge
.b
is current
:
457 if edge
.b
is next
or edge
.a
is next
:
458 edge
.faces
.append(face
)
459 face
.edges
.append(edge
)
460 self
.faceedgeflag
= 1
463 if not self
.boundaryflag
:
464 for edge
in self
.edges
:
465 if len(edge
.faces
) < 2:
467 edge
.faces
[0].boundary
= 1
471 # The functions below turn the basic triangular faces into
472 # hexagonal faces, creating the buckyball effect.
473 # PKHG seems to work only for meshes with tri's ;-)
478 # PKHG renumbering the index of the verts
479 for i
in range(len(self
.verts
)):
480 self
.verts
[i
].index
= i
481 # PKHG renumbering the index of the edges
482 for i
in range(len(self
.edges
)):
483 self
.edges
[i
].index
= i
487 for edge
in self
.edges
:
489 self
.hexshorten(edge
, hexvert_counter
)
490 hexvert_counter
+= 2 # PKHG two new vertices done
492 for face
in self
.faces
:
493 self
.makehexfaces(face
)
495 for vert
in self
.verts
:
497 self
.hexvertface(vert
)
498 self
.verts
= self
.hexverts
499 self
.edges
= self
.hexedges
500 self
.faces
= self
.hexfaces
501 self
.vertedgeflag
= 0
502 self
.vertfaceflag
= 0
503 self
.faceedgeflag
= 0
505 def hexshorten(self
, currentedge
, hexvert_counter
):
506 third
= vertex(currentedge
.vect
/ 3.0)
507 newvert1
= vertex(currentedge
.a
.vector
)
508 newvert2
= vertex(currentedge
.b
.vector
)
509 newvert1
= newvert1
+ third
510 newvert1
.index
= hexvert_counter
511 newvert2
= newvert2
- third
512 newvert2
.index
= hexvert_counter
+ 1 # PKHG caller adjusts +=2
513 newedge
= edge(newvert1
, newvert2
)
514 newedge
.index
= currentedge
.index
515 self
.hexverts
.append(newvert1
)
516 self
.hexverts
.append(newvert2
)
517 self
.hexedges
.append(newedge
)
519 def makehexfaces(self
, currentface
):
521 currentface
.docorners()
522 for corner
in currentface
.corners
:
524 rightedge
= corner
[1]
527 rid
= rightedge
.index
529 if leftedge
.a
is vert
:
530 vertices
.append(self
.hexedges
[lid
].a
)
531 elif leftedge
.b
is vert
:
532 vertices
.append(self
.hexedges
[lid
].b
)
534 if rightedge
.a
is vert
:
535 vertices
.append(self
.hexedges
[rid
].a
)
536 elif rightedge
.b
is vert
:
537 vertices
.append(self
.hexedges
[rid
].b
)
539 newface
= face(vertices
)
540 newedge1
= edge(vertices
[0], vertices
[1])
541 newedge2
= edge(vertices
[2], vertices
[3])
542 newedge3
= edge(vertices
[4], vertices
[5])
543 self
.hexfaces
.append(newface
)
544 self
.hexedges
.append(newedge1
)
545 self
.hexedges
.append(newedge2
)
546 self
.hexedges
.append(newedge3
)
548 def hexvertface(self
, vert
):
550 for edge
in vert
.edges
:
553 vertices
.append(self
.hexedges
[eid
].a
)
555 vertices
.append(self
.hexedges
[eid
].b
)
556 newface
= face(vertices
)
557 self
.hexfaces
.append(newface
)
563 for i
in range(len(self
.verts
)):
564 self
.verts
[i
].index
= i
565 for i
in range(len(self
.edges
)):
566 self
.edges
[i
].index
= i
568 star_vert_counter
= 0
569 for currentedge
in self
.edges
:
570 newvert
= average([currentedge
.a
, currentedge
.b
]).centroid()
571 newvert
.index
= star_vert_counter
572 star_vert_counter
+= 1
573 self
.starverts
.append(newvert
)
574 star_face_counter
= 0
575 star_edge_counter
= 0
576 for currentface
in self
.faces
:
577 currentface
.docorners()
579 for corner
in currentface
.corners
:
580 vert
= self
.starverts
[corner
[1].index
]
581 vertices
.append(vert
)
582 newface
= face(vertices
)
583 newface
.index
= star_face_counter
584 star_face_counter
+= 1
585 newedge1
= edge(vertices
[0], vertices
[1])
586 newedge1
.index
= star_edge_counter
587 newedge2
= edge(vertices
[1], vertices
[2])
588 newedge2
.index
= star_edge_counter
+ 1
589 newedge3
= edge(vertices
[2], vertices
[0])
590 newedge3
.index
= star_edge_counter
+ 2
591 star_edge_counter
+= 3
592 self
.starfaces
.append(newface
)
593 self
.staredges
.append(newedge1
)
594 self
.staredges
.append(newedge2
)
595 self
.staredges
.append(newedge3
)
596 for vert
in self
.verts
:
599 for currentedge
in vert
.edges
:
600 eid
= currentedge
.index
601 vertices
.append(self
.starverts
[eid
])
602 newface
= face(vertices
)
603 newface
.index
= star_face_counter
604 star_face_counter
+= 1
605 self
.starfaces
.append(newface
)
606 self
.verts
= self
.starverts
607 self
.edges
= self
.staredges
608 self
.faces
= self
.starfaces
609 self
.vertedgeflag
= 0
610 self
.vertfaceflag
= 0
611 self
.faceedgeflag
= 0
614 self
.class2verts
= []
615 self
.class2edges
= []
616 self
.class2faces
= []
618 newvertstart
= len(self
.verts
)
619 newedgestart
= len(self
.edges
)
620 counter_verts
= len(self
.verts
)
621 for i
in range(counter_verts
):
622 self
.verts
[i
].index
= i
623 for i
in range(len(self
.edges
)):
624 self
.edges
[i
].index
= i
625 for i
in range(len(self
.faces
)):
626 self
.faces
[i
].index
= i
628 for currentface
in self
.faces
:
629 currentface
.docorners()
630 newvert
= average(currentface
.vertices
).centroid()
631 newvert
.index
= counter_verts
634 self
.verts
.append(newvert
)
635 newedge1
= edge(currentface
.vertices
[0], newvert
)
636 newedge2
= edge(currentface
.vertices
[1], newvert
)
637 newedge3
= edge(currentface
.vertices
[2], newvert
)
639 self
.edges
.append(newedge1
)
640 self
.edges
.append(newedge2
)
641 self
.edges
.append(newedge3
)
642 for currentedge
in range(newedgestart
):
643 self
.edges
[currentedge
].a
= self
.verts
[self
.edges
[currentedge
].faces
[0].index
+ newvertstart
]
644 self
.edges
[currentedge
].b
= self
.verts
[self
.edges
[currentedge
].faces
[1].index
+ newvertstart
]
645 self
.edges
[currentedge
].findvect()
647 for currentvert
in range(newvertstart
):
648 vert
= self
.verts
[currentvert
]
651 for currentface
in vert
.faces
:
652 eid
= currentface
.index
653 vertices
.append(self
.verts
[newvertstart
+ eid
])
655 for i
in range(len(vertices
)):
656 if i
== len(vertices
) - 1:
659 next
= vertices
[i
+ 1]
661 newface
= face([vert
, vertices
[i
], next
])
662 self
.class2faces
.append(newface
)
664 self
.faces
= self
.class2faces
665 self
.vertedgeflag
= 0
666 self
.vertfaceflag
= 0
667 self
.faceedgeflag
= 0
674 counter_verts
= len(self
.verts
)
675 for i
in range(counter_verts
):
676 self
.verts
[i
].index
= i
677 for i
in range(len(self
.edges
)):
678 self
.edges
[i
].index
= i
679 for i
in range(len(self
.faces
)):
680 self
.faces
[i
].index
= i
683 for currentface
in self
.faces
:
684 currentface
.docorners()
685 newvert
= average(currentface
.vertices
).centroid()
686 newvert
.index
= counter_verts
# PKHG needed in >= 2.59
688 self
.dualverts
.append(newvert
)
689 for vert
in self
.verts
:
692 for currentface
in vert
.faces
:
693 eid
= currentface
.index
694 vertices
.append(self
.dualverts
[eid
])
695 newface
= face(vertices
)
696 self
.dualfaces
.append(newface
)
697 for currentedge
in self
.edges
:
698 currentedge
.a
= self
.dualverts
[currentedge
.faces
[0].index
]
699 currentedge
.b
= self
.dualverts
[currentedge
.faces
[1].index
]
700 self
.verts
= self
.dualverts
702 self
.faces
= self
.dualfaces
703 self
.vertedgeflag
= 0
704 self
.vertfaceflag
= 0
705 self
.faceedgeflag
= 0
708 class facetype(mesh
):
709 def __init__(self
, basegeodesic
, parameters
, width
, height
, relative
):
711 self
.detach
= parameters
[0]
712 self
.endtype
= parameters
[1]
713 self
.coords
= parameters
[2]
714 self
.base
= basegeodesic
715 self
.relative
= relative
718 if not self
.relative
:
719 newwidth
= self
.findrelative()
720 self
.width
= width
* newwidth
722 self
.base
.connectivity()
723 for coord
in self
.coords
:
724 coord
[0] = coord
[0] * self
.width
725 coord
[1] = coord
[1] * self
.height
726 if not self
.base
.facenormalflag
:
727 for currentface
in self
.base
.faces
:
729 currentface
.docorners()
730 currentface
.findnormal()
732 self
.base
.facenormalflag
= 1
733 if self
.endtype
== 4 and not self
.base
.vertnormalflag
:
734 for currentvert
in self
.base
.verts
:
735 currentvert
.findnormal()
736 self
.base
.vertnormalflag
= 1
739 def findrelative(self
):
740 centre
= average(self
.base
.faces
[0].vertices
).centroid()
742 for point
in self
.base
.faces
[0].vertices
:
743 newedge
= edge(centre
, point
)
744 edgelist
.append(newedge
)
747 extra
= edg
.vect
.length
748 length
= length
+ extra
750 length
= length
/ len(edgelist
)
754 def createfaces(self
):
756 for point
in self
.base
.verts
:
757 self
.verts
.append(point
)
758 if self
.endtype
== 4:
759 self
.createghostverts()
760 for currentface
in self
.base
.faces
:
761 self
.doface(currentface
)
763 def createghostverts(self
):
764 self
.ghoststart
= len(self
.verts
)
765 for vert
in self
.base
.verts
:
766 newvert
= vert
+ (vert
.normal
* self
.coords
[-1][1])
767 self
.verts
.append(newvert
)
769 def doface(self
, candidate
):
775 for vert
in candidate
.vertices
:
780 for point
in candidate
.vertices
:
781 newvert
= vertex(point
.vector
)
782 self
.verts
.append(newvert
)
785 finish
= len(self
.coords
)
786 if self
.endtype
== 1 or self
.endtype
== 4:
788 for i
in range(finish
):
789 up
= candidate
.normal
* self
.coords
[i
][1]
791 for j
in range(len(candidate
.vertices
)):
792 dotfac
= candidate
.corners
[j
][3] * 0.5
793 vec
= (candidate
.spokes
[j
] * (self
.coords
[i
][0] / sin(dotfac
)))
795 newvert
= candidate
.vertices
[j
] + vec
+ up
797 self
.verts
.append(newvert
)
799 if self
.endtype
== 4:
801 for i
in range(len(candidate
.vertices
)):
802 vert
= self
.verts
[candidate
.vertices
[i
].index
+ self
.ghoststart
]
808 if self
.endtype
== 3:
810 for i
in range(len(grid
) - 1):
811 for j
in range(len(grid
[i
]) - 1):
814 three
= grid
[i
+ 1][j
+ 1]
815 four
= grid
[i
+ 1][j
]
816 newface
= face([one
, two
, three
, four
])
817 self
.faces
.append(newface
)
818 if self
.endtype
== 2:
819 finalfaceverts
= grid
[-1]
820 newface
= face(finalfaceverts
[:-1])
821 self
.faces
.append(newface
)
822 if self
.endtype
== 1:
823 lastvert
= average(candidate
.vertices
).centroid()
824 up
= candidate
.normal
* self
.coords
[-1][1]
825 newvert
= lastvert
+ up
826 self
.verts
.append(newvert
)
828 for i
in range(len(ring
) - 1):
829 newface
= face([newvert
, ring
[i
], ring
[i
+ 1]])
830 self
.faces
.append(newface
)
833 class importmesh(mesh
):
834 def __init__(self
, meshname
, breakquadflag
):
837 obj
= bpy
.data
.objects
[meshname
]
838 bpy
.context
.view_layer
.objects
.active
= obj
841 if not breakquadflag
:
842 bpy
.ops
.object.mode_set(mode
='EDIT')
843 impmesh
= bmesh
.new() # create an empty BMesh
844 impmesh
.from_mesh(obj
.data
) # fill it in from a Mesh
845 bpy
.ops
.object.mode_set(mode
='OBJECT')
848 bpy
.ops
.object.mode_set(mode
='EDIT')
849 bpy
.ops
.mesh
.quads_convert_to_tris()
850 impmesh
= bmesh
.new() # create an empty BMesh
851 impmesh
.from_mesh(obj
.data
) # fill it in from a Mesh
852 bpy
.ops
.object.mode_set(mode
='OBJECT')
854 for v
in impmesh
.verts
:
857 self
.verts
.append(vert
)
858 # PKHG verts is now a list of vertex, so to say a copy of the Vectors
861 for e
in impmesh
.edges
:
864 a
= self
.verts
[vert
.index
]
866 newedge
= edge(tmp
[0], tmp
[1])
867 newedge
.index
= e
.index
868 self
.edges
.append(newedge
)
870 extra_DBG_info("MeshInfo", "vefm L868 the mesh impmesh", impmesh
.faces
[:])
872 for f
in impmesh
.faces
:
874 for vert
in f
.verts
: # PKHG a list! of indices ??? PKHG>???
875 a
= self
.verts
[vert
.index
] # PKHG verts contains already vertex objects
878 newface
.index
= f
.index
# indexcount
879 self
.faces
.append(newface
)
884 for i
in range(len(self
.verts
)):
886 self
.verts
[i
].index
= i
887 for i
in range(len(self
.verts
)):
888 target
= self
.surroundingverts(self
.verts
[i
])
889 for j
in range(len(target
)): # go through those verts
890 temptarg
= self
.temp
[target
[j
].index
]
891 flag
= 0 # set a flag up
893 for k
in range(len(temptarg
)): # go through temp list for each of those verts
895 if temptarg
[k
] == i
: # if we find a match to the current vert...
896 flag
= 1 # raise the flag
898 if flag
== 0: # if there is no flag after all that...
899 self
.temp
[target
[j
].index
].append(i
) # add current vert to temp list of this surrounding vert
900 self
.temp
[i
].append(target
[j
].index
) # add this surrounding vert to the current temp list
901 newedge
= edge(self
.verts
[i
], self
.verts
[target
[j
].index
])
902 self
.edges
.append(newedge
) # add the newly found edge to the edges list
904 for edg
in self
.edges
:
906 self
.vertedgeflag
= 0
907 self
.vertedgeflag
= 0
910 def surroundingverts(self
, vert
):
911 ''' Find the verts surrounding vert'''
912 surround
= [] # list to be filled and returned
913 for faces
in vert
.faces
: # loop through faces attached to vert
914 finish
= len(faces
.vertices
)
915 for i
in range(finish
):
917 next
= faces
.vertices
[0]
919 next
= faces
.vertices
[i
+ 1]
920 if vert
== faces
.vertices
[i
]:
921 surround
.append(next
)
924 def breakquad(self
, quad_face
):
925 ''' turn quads into triangles'''
926 distance1
= quad_face
.vertices
[0] - quad_face
.vertices
[2]
927 distance2
= quad_face
.vertices
[1] - quad_face
.vertices
[3]
928 distance1
.findlength()
929 distance2
.findlength()
930 if abs(distance1
.length
) < abs(distance2
.length
):
931 self
.faces
[quad_face
.index
] = face([quad_face
.vertices
[0], quad_face
.vertices
[1], quad_face
.vertices
[2]])
932 self
.faces
.append(face([quad_face
.vertices
[0], quad_face
.vertices
[2], quad_face
.vertices
[3]]))
934 self
.faces
[quad_face
.index
] = face([quad_face
.vertices
[0], quad_face
.vertices
[1], quad_face
.vertices
[3]])
935 self
.faces
.append(face([quad_face
.vertices
[1], quad_face
.vertices
[2], quad_face
.vertices
[3]]))
939 def __init__(self
, base
, struttype
, width
, height
, length
, widthtog
, heighttog
,
940 lengthtog
, meshname
, stretchflag
, lift
):
942 extra_DBG_info(name
="StrutMesh", info_text
="vefm L940\nstrut called: ",
943 info_obj
=[base
, struttype
, width
, height
, length
, widthtog
,
944 heighttog
, lengthtog
, meshname
, stretchflag
, lift
])
946 # put in strut prep stuff here
947 if struttype
is None:
950 divvy
= len(base
.faces
[0].edges
)
951 for lengf
in base
.faces
[0].edges
:
952 lengf
.vect
.findlength()
953 total
= total
+ lengf
.vect
.length
954 yardstick
= total
/ divvy
958 self
.width
= width
* yardstick
962 self
.height
= height
* yardstick
966 self
.shrink
= length
* yardstick
967 if not base
.facenormalflag
:
968 for currentface
in base
.faces
:
969 currentface
.docorners()
970 currentface
.findnormal()
971 base
.facenormalflag
= 1
972 for edj
in base
.edges
:
974 side
= edge(edj
.a
, edj
.b
)
977 edj
.cross
= crossp(edj
.normal
, edj
.unit
).docrossproduct()
978 template
= importmesh(meshname
, 0)
981 for vert
in template
.verts
:
982 if vert
.vector
.x
> maxx
:
984 if vert
.vector
.x
< minx
:
986 for edj
in base
.edges
:
987 start
= len(self
.verts
)
988 centre
= average([edj
.a
, edj
.b
]).centroid()
989 split
= edj
.vect
.length
/ 2
990 # PKHG no division by zero!!
993 tmp
= 1.0 / (maxx
- minx
)
994 dubbl
= edj
.vect
.length
* tmp
995 # PKHG end no division by zero!!
996 diffplus
= split
- maxx
997 diffminus
= -split
- minx
998 for point
in template
.verts
:
999 ay
= (edj
.normal
* point
.vector
.z
* self
.height
) + (edj
.normal
* lift
)
1000 ce
= edj
.cross
* point
.vector
.y
* self
.width
1003 be
= edj
.unit
* self
.shrink
* dubbl
* point
.vector
.x
1005 if point
.vector
.x
> 0.0:
1006 be
= edj
.unit
* self
.shrink
* (point
.vector
.x
+ diffplus
)
1007 elif point
.vector
.x
< 0.0:
1008 be
= edj
.unit
* self
.shrink
* (point
.vector
.x
+ diffminus
)
1009 elif point
.vector
.x
== 0.0:
1010 be
= edj
.unit
* self
.shrink
* point
.vector
.x
1012 newvert
= centre
+ de
1013 self
.verts
.append(newvert
)
1014 for edjy
in template
.edges
:
1015 one
= edjy
.a
.index
+ start
1016 two
= edjy
.b
.index
+ start
1017 newedge
= edge(self
.verts
[one
], self
.verts
[two
])
1018 self
.edges
.append(newedge
)
1019 for facey
in template
.faces
:
1021 for verty
in facey
.vertices
:
1022 index
= verty
.index
+ start
1023 faceverts
.append(self
.verts
[index
])
1024 newface
= face(faceverts
)
1025 self
.faces
.append(newface
)
1026 self
.vertedgeflag
= 0
1027 self
.vertedgeflag
= 0
1032 def __init__(self
, base
, hubtype
, width
, height
, length
,
1033 widthtog
, heighttog
, lengthtog
, meshname
):
1038 # put in strut prep stuff here
1039 extra_DBG_info("vefm L1037 HubMesh", "base is ", str(dir(base
)) + "\n and meshname = " + meshname
)
1043 divvy
= len(base
.faces
[0].edges
)
1044 for lengf
in base
.verts
[0].edges
:
1045 lengf
.vect
.findlength()
1046 total
= total
+ lengf
.vect
.length
1047 yardstick
= total
/ divvy
1051 self
.width
= width
* yardstick
1053 self
.height
= height
1055 self
.height
= height
* yardstick
1057 self
.shrink
= length
1059 self
.shrink
= length
* yardstick
1061 if not base
.facenormalflag
:
1062 for currentface
in base
.faces
:
1063 currentface
.docorners()
1064 currentface
.findnormal()
1065 base
.facenormalflag
= 1
1067 for apex
in base
.verts
:
1069 side
= edge(apex
.edges
[0].a
, apex
.edges
[0].b
)
1070 apex
.unit
= side
.vect
# PKHG is Vector: b - a
1071 apex
.unit
.normalize()
1072 apex
.cross
= crossp(apex
.normal
, apex
.unit
).docrossproduct()
1073 apex
.unit
= crossp(apex
.cross
, apex
.normal
).docrossproduct()
1075 template
= importmesh(meshname
, 0)
1076 for apex
in base
.verts
:
1077 start
= len(self
.verts
)
1079 for point
in template
.verts
:
1080 ay
= apex
.normal
* point
.vector
.z
* self
.height
1081 ce
= apex
.cross
* point
.vector
.y
* self
.width
1082 be
= apex
.unit
* point
.vector
.x
* self
.shrink
1084 newvert
= centre
+ de
1085 self
.verts
.append(newvert
)
1086 for edjy
in template
.edges
:
1087 one
= edjy
.a
.index
+ start
1088 two
= edjy
.b
.index
+ start
1089 newedge
= edge(self
.verts
[one
], self
.verts
[two
])
1090 self
.edges
.append(newedge
)
1091 for facey
in template
.faces
:
1093 for verty
in facey
.vertices
:
1094 index
= verty
.index
+ start
1095 faceverts
.append(self
.verts
[index
])
1096 newface
= face(faceverts
)
1097 self
.faces
.append(newface
)
1098 self
.vertedgeflag
= 0
1099 self
.vertedgeflag
= 0
1103 # ???PKHG TODO Nmesh used yet wrong!
1104 def finalfill(source
, target
):
1105 if source
== target
: # PKHG: otherwise >infinite< loop
1106 print("\n***WARNING*** vefm_271.finalfill L1104 source == target empty mesh used")
1108 # PKHG_??? maybe renumverting and checking faces with >=4 5 vertices?
1111 for point
in source
.verts
:
1112 newvert
= vertex(point
.vector
)
1113 newvert
.index
= count
1114 target
.verts
.append(newvert
)
1115 point
.index
= count
# PKHG_INFO source renumbered too!
1119 for facey
in source
.faces
:
1120 row
= len(facey
.vertices
)
1123 for el
in facey
.vertices
:
1124 tmp
= tmp
+ target
.verts
[el
.index
].vector
1126 centre
= vertex(tmp
)
1127 centre
.index
= count
# PKHG_??? give it a good index
1130 target
.verts
.append(centre
)
1131 for i
in range(row
):
1133 a
= target
.verts
[facey
.vertices
[-1].index
]
1134 b
= target
.verts
[facey
.vertices
[0].index
]
1136 a
= target
.verts
[facey
.vertices
[i
].index
]
1137 b
= target
.verts
[facey
.vertices
[i
+ 1].index
]
1138 target
.faces
.append([a
, b
, centre
])
1142 for j
in range(len(facey
.vertices
)):
1143 a
= facey
.vertices
[j
]
1144 f
.append(target
.verts
[a
.index
])
1146 target
.faces
.append(f
)