@@ -557,10 +557,11 @@ class standardAttributes(baseObj):
557557 [],
558558 ['location' , 'text' ],
559559 []],
560- 'extrusion' :[ ['pos' , 'color' , 'start_face_color' , 'end_face_color' ],
560+ 'extrusion' :[ ['pos' , 'color' , 'start_face_color' , 'end_face_color' , 'start_normal' , 'end_normal' ],
561561 [ 'axis' , 'size' , 'up' ],
562562 ['path' , 'shape' , 'visible' , 'opacity' ,'shininess' , 'emissive' ,
563- 'show_start_face' , 'show_end_face' , 'smooth' ,
563+ 'show_start_face' , 'show_end_face' , 'smooth' , 'smooth_joints' , 'sharp_joints' ,
564+ 'scale' , 'xscale' , 'yscale' , 'twist' ,
564565 'make_trail' , 'trail_type' , 'interval' , 'show_start_face' , 'show_end_face' ,
565566 'retain' , 'trail_color' , 'trail_radius' , 'texture' , 'pickable' ],
566567 ['red' , 'green' , 'blue' ,'length' , 'width' , 'height' ] ],
@@ -630,8 +631,11 @@ def setup(self, args):
630631 if a in args :
631632 argsToSend .append (a )
632633 val = args [a ]
633- if isinstance (val , vector ): setattr (self , '_' + a , vector (val )) ## '_' bypasses setters; copy of val
634- else : raise AttributeError (a + ' must be a vector' )
634+ if objName == 'extrusion' and a == 'color' :
635+ setattr (self , '_' + a , val ) # '_' bypasses setters
636+ else :
637+ if isinstance (val , vector ): setattr (self , '_' + a , vector (val )) # '_' bypasses setters; copy of val
638+ else : raise AttributeError (a + ' must be a vector' )
635639 del args [a ]
636640
637641 # Track side effects of modifying size, axis, or up
@@ -715,14 +719,11 @@ def setup(self, args):
715719 if _special_clone is not None : cmd ["_cloneid" ] = _special_clone
716720 self .appendcmd (cmd )
717721
718- # if ('frame' in args and args['frame'] is not None):
719- # frame.objects.append(self)
720- # frame.update_obj_list()
721-
722722 # attribute vectors have these methods which call self.addattr()
723723 # The vector class calls a change function when there's a change in x, y, or z.
724724 noSize = ['points' , 'label' , 'vertex' , 'triangle' , 'quad' , 'attach_arrow' , 'attach_trail' ]
725- self ._color .on_change = self ._on_color_change
725+ if not (objName == 'extrusion' ): #
726+ self ._color .on_change = self ._on_color_change
726727 if objName not in noSize :
727728 self ._axis .on_change = self ._on_axis_change
728729 self ._size .on_change = self ._on_size_change
@@ -836,6 +837,9 @@ def color(self):
836837 return self ._color
837838 @color .setter
838839 def color (self ,value ):
840+ if isinstance (self ._color , list ): # may be a list of extrusion colors of the form [ [1,0,0], [0,1,0] ]
841+ self ._color = vector (0 ,0 ,0 ) # change list to a vector
842+ self ._color .value = value # modify the vector
839843 self ._color .value = value
840844 if not self ._constructing :
841845 self .addattr ('color' )
@@ -3175,6 +3179,8 @@ def handle_event(self, evt): ## events and scene info updates
31753179 obj ._descender = p [1 ]
31763180 obj ._up .value = list_to_vec (evt ['up' ])
31773181 else :
3182+ if obj ._objName == 'extrusion' :
3183+ obj ._color = obj ._firstcolor # use the first segment color to represent multicolor extrusions
31783184 # Set attribute_vector.value, which avoids nullifying the
31793185 # on_change functions that detect changes in e.g. obj.pos.y
31803186 obj ._pos .value = list_to_vec (p )
@@ -3774,16 +3780,14 @@ def __init__(self, **args):
37743780 savesize = args ['size' ]
37753781 del args ['size' ]
37763782 self ._shape = [ ]
3777- pozz = args ['path' ]
3778- npozz = []
3779- for pp in pozz :
3780- npozz .append (pp .value ) ## convert vectors to lists
3781- args ['path' ] = npozz [:]
3782- self ._show_start_face = True
3783- self ._show_end_face = True
3783+ self ._pathlength = len (args ['path' ])
3784+ args ['path' ] = self .vecs_to_list (args , 'path' )
37843785 if 'color' in args :
3785- self ._start_face_color = args ['color' ]
3786- self ._end_face_color = args ['color' ]
3786+ if isinstance (args ['color' ], vector ): args ['_firstcolor' ] = args ['color' ]
3787+ else : args ['_firstcolor' ] = args ['color' ][0 ]
3788+ args ['color' ] = self .vecs_to_list (args , 'color' )
3789+ else :
3790+ args ['_firstcolor' ] = vector (1 ,1 ,1 )
37873791
37883792 super (extrusion , self ).setup (args )
37893793
@@ -3792,6 +3796,16 @@ def __init__(self, **args):
37923796 if savesize is not None :
37933797 self ._size = savesize
37943798
3799+ def vecs_to_list (self , a , attr ):
3800+ pozz = a [attr ]
3801+ if isinstance (pozz , vector ): return pozz .value
3802+ if len (pozz ) != self ._pathlength :
3803+ raise AttributeError ("The " + attr + " list must be the same length as the list of points on the path (" + str (self ._pathlength )+ ")." )
3804+ npozz = []
3805+ for pp in pozz :
3806+ npozz .append (pp .value ) ## convert vectors to lists
3807+ return npozz [:]
3808+
37953809 @property
37963810 def axis (self ):
37973811 return self ._axis
@@ -3876,6 +3890,34 @@ def smooth(self):
38763890 def smooth (self , value ):
38773891 raise AttributeError ('smooth cannot be changed after extrusion is created' )
38783892
3893+ def checkjointlist (self , js , name ):
3894+ if not isinstance (js , list ): raise AttributeError (name + ' must be a list of joint indices.' )
3895+ for k in js :
3896+ if k < 0 or k > self ._pathlength :
3897+ raise AttributeError (str (k )+ ' is not in the range of joints in the path (0-' + str (self ._pathlength - 1 )+ ').' )
3898+
3899+ @property
3900+ def smooth_joints (self ):
3901+ if self ._constructing :
3902+ self .checkjointlist (self ._smooth_joints , 'smooth_joints' )
3903+ return self ._smooth_joints
3904+ else :
3905+ return None
3906+ @smooth_joints .setter
3907+ def smooth_joints (self , value ):
3908+ raise AttributeError ('smooth_joints cannot be changed after extrusion is created' )
3909+
3910+ @property
3911+ def sharp_joints (self ):
3912+ if self ._constructing :
3913+ self .checkjointlist (self ._sharp_joints , 'sharp_joints' )
3914+ return self ._sharp_joints
3915+ else :
3916+ return None
3917+ @sharp_joints .setter
3918+ def sharp_joints (self , value ):
3919+ raise AttributeError ('sharp_joints cannot be changed after extrusion is created' )
3920+
38793921 @property
38803922 def show_start_face (self ):
38813923 if self ._constructing :
@@ -3916,6 +3958,76 @@ def end_face_color(self):
39163958 def end_face_color (self ,value ):
39173959 raise AttributeError ('end_face_color cannot be changed after extrusion is created' )
39183960
3961+ @property
3962+ def start_normal (self ):
3963+ if self ._constructing :
3964+ return self ._start_normal
3965+ else :
3966+ return None
3967+ @start_normal .setter
3968+ def start_normal (self ,value ):
3969+ raise AttributeError ('start_normal cannot be changed after extrusion is created' )
3970+
3971+ @property
3972+ def end_normal (self ):
3973+ if self ._constructing :
3974+ return self ._end_normal
3975+ else :
3976+ return None
3977+ @end_normal .setter
3978+ def end_normal (self ,value ):
3979+ raise AttributeError ('end_normal cannot be changed after extrusion is created' )
3980+
3981+ @property
3982+ def twist (self ):
3983+ if self ._constructing :
3984+ return self ._twist
3985+ else :
3986+ return None
3987+ @twist .setter
3988+ def twist (self ,value ):
3989+ raise AttributeError ('twist cannot be changed after extrusion is created' )
3990+
3991+ @property
3992+ def scale (self ):
3993+ if self ._constructing :
3994+ return self ._scale
3995+ else :
3996+ return None
3997+ @scale .setter
3998+ def scale (self ,value ):
3999+ raise AttributeError ('scale cannot be changed after extrusion is created' )
4000+
4001+ @property
4002+ def xscale (self ):
4003+ if self ._constructing :
4004+ return self ._xscale
4005+ else :
4006+ return None
4007+ @xscale .setter
4008+ def xscale (self ,value ):
4009+ raise AttributeError ('xscale cannot be changed after extrusion is created' )
4010+
4011+ @property
4012+ def yscale (self ):
4013+ if self ._constructing :
4014+ return self ._yscale
4015+ else :
4016+ return None
4017+ @yscale .setter
4018+ def yscale (self ,value ):
4019+ raise AttributeError ('xscale cannot be changed after extrusion is created' )
4020+
4021+ @property
4022+ def yscale (self ):
4023+ if self ._constructing :
4024+ return self ._yscale
4025+ else :
4026+ return None
4027+ @yscale .setter
4028+ def yscale (self ,value ):
4029+ raise AttributeError ('xscale cannot be changed after extrusion is created' )
4030+
39194031class text (standardAttributes ):
39204032
39214033 def __init__ (self , ** args ):
0 commit comments