Jump to content

Patrick Winkler

Member
  • Posts

    225
  • Joined

  • Last visited

Posts posted by Patrick Winkler

  1. I'm not sure which resoltuion to use for ConvertToPolygon().  http://developer.vectorworks.net/index.php/VS:ConvertToPolygon

     

    <50 is obvious to less.

    90 and 100 convert a cirlce to 32pt polys and 150 to 64 pt polys.

    In this case 90 should be enough as even in renderworks my eyes can't spot a difference to the higher resolutions.

     

    It would be good to know how the resoltution effects the outcome (why do 90, 100 create the same ) and if there is a maximum value.

     

    5a1d23c5ef017_Bildschirmfoto2017-11-28um09_50_59.thumb.png.c98411b4b790fee8cedd0c8d4aea51fa.png

     

    regards, Patrick

  2. To make sure the center stays at the same location  the bounding box must always have the same size.

    This can be accomplished by palcing an invisible circle into the symbol. ( set fill and penstyle to empty.)

     

    5a1c2eb12ee8d_Bildschirmfoto2017-11-27um16_24_58.thumb.png.489230ef97008c9e1410305e9b48f526.png

  3. This node gives you the center of the Bounding Box.

     

    '''
        Changed on 22.02.2016 : Wrong Var was used in the calcul. of the center    
        Changed on 04.04.2016 : Created the 'def GetBBoxN (h)'
        Changed on 18.04.2016 : set Initialize function: Marionette.InitializeView
        Changed on 27.11.2017 : Force TopView
        
        author: patrick winkler
    '''
    
    import vs
    import Marionette
    
    @Marionette.NodeDefinition
    class Params(metaclass = Marionette.OrderedClass):
        this = Marionette.Node( 'Get Bounding Box' )
        this.SetDescription("Returns the bounding box's coordinates of the projection of an object on the screen plane")
        
        # IMPORTANT:  SetThe View to Top while Execution - The BB Values are otherwise incorrect!!!!
        this.SetInitFunc(Marionette.InitializeView)
        this.SetFinalFunc (Marionette.RestoreView)    
        
        obj = Marionette.PortIn(vs.Handle(0))
        obj.SetDescription( "The input object" )
        
        topL2D = Marionette.PortOut()
        topL2D.SetDescription( "The top left coordinates of the bounding box" )
        
        botR2D = Marionette.PortOut()        
        botR2D.SetDescription( "The bottom right coordinatesr of the bounding box" )
    
        width = Marionette.PortOut()        
        width.SetDescription("The width of the bounding box.")    
        
        height = Marionette.PortOut()        
        height.SetDescription("The height of the bounding box.")
    
        center = Marionette.PortOut()        
        center.SetDescription("The centerpoint of the bounding box.")
    
    def RunNode(self):    
        def GetBBoxN (h, top_view = True):
            '''
                Returns top left point, bottom right point, width, height and center of the object bounding box (as tuple).
                
                IMPORTANT: The result depends on the view in VW if top_view is False. 
            '''    
            if top_view:
                # Change the view to Top temporarily
                orig_view = vs.GetView()
                vs.SetView(0, 0, 0, 0, 0, 0)
            
            box = vs.GetBBox(h)
            topL2D = box[0]
            botR2D = box[1]
            
            center = [None, None]
            
            BB_width  = botR2D[0] - topL2D[0]
            BB_height = topL2D[1] - botR2D[1]
                
            center[0] = topL2D[0] + BB_width / 2
            center[1] = topL2D[1] - BB_height / 2
            
            center = tuple (center)
                
            if top_view:
                # Restore the original view
                xAngle, yAngle, zAngle, offset = orig_view
                xDistance, yDistance, zDistance = offset
                
                vs.SetView(xAngle, yAngle, zAngle, xDistance, yDistance, zDistance)
            
            return (topL2D, botR2D, BB_width, BB_height, center)
        
        obj = self.Params.obj.value    
        
        if not obj:
            raise ValueError('No object handle was provided!')
        
        topL2D, botR2D, BB_width, BB_height, center = GetBBoxN(obj, top_view = True)
        
        # SET THE OUT PORTS
        self.Params.topL2D.value = topL2D
        self.Params.botR2D.value = botR2D
        
        self.Params.width.value = BB_width
        self.Params.height.value = BB_height
        
        self.Params.center.value = tuple (center)
        

     

     

  4. Function is a great timesaver node.

     

    Here is a version with two more optional params.

    I have to contain myself from using it to extensive because the readability of the code could suffer.

    It would be great for the future if the function was displayed on the node.

     

    function_N.vwx

     

    59e0b0afdd218_Bildschirmfoto2017-10-13um14_24_59.png.90b671f37d6dcacbfff2475e38a3a0f0.png

     

    • Like 1
  5. Hans,

     

    you just mentioned the solution. I forgot that there is a transfrommatrix-node.

    The Rotate3D node could be fixed by checking the type for PlugIn objects and

    using TransfMatrix in case.  (@Marissa Farrel   :))

  6. Hello together,

     

    when using the pydev debugger I noticed that vs.Handle provides some attributes that make scripting a bit more comfortable.

    Hopefully more attributes will follow.

     

    vs_Handle_Atriibutes.png.121a1da6c8ebdcb1332b9c3b4f7c11fb.png

     

    def test():
        vs.CreateText('Hello!!')    
        h = vs.LNewObj() 
                
        print ('Type', h.type)
        print ('Parent', h.parent)
        print ('Parent Type', h.parent.type)
        
        

    regards,

    Patrick

     

    • Like 4
  7.  

     

    @Marionette.NodeDefinition
    class Params(metaclass = Marionette.OrderedClass):
    	
    	def get_SymDefs_in_File ():
    		'''
    			Returns all Symbol-Definitions as list found in the active Document.
    		'''
    		
    		syms = []	
    		
    		SYMBOL_DEFINI_TYPE = 16	
    		 
    		CURRENT_DOC = 0 
    		Res_List, NumItems = vs.BuildResourceList (SYMBOL_DEFINI_TYPE, CURRENT_DOC, '')
    		
    		for i in range (NumItems):
    			# Die Resourcelist beginnt nicht wie üblich mit dem Index 0 sondern mit 1 
    			i += 1
    			
    			h = vs.GetResourceFromList (Res_List, i)		   
    			
    			syms.append ( vs.GetName(h))
    		
    		return syms
    	###
    
    	this = Marionette.Node( 'Get Sym' )
    	
    	sym_list = get_SymDefs_in_File ()
    	
    	sym_popUp = Marionette.OIPControl( 'Syms', Marionette.WidgetType.Popup, 0, sym_list)
    	
    	sym = Marionette.PortOut()   
    	
    	
    def RunNode(self):
    	sel_idx = self.Params.sym_popUp.value
    	self.Params.sym.value = self.Params.sym_popUp.popupChoices[sel_idx]

     

    Unfortunately you have to run it to refresh the popup values.

     

  8. I've changed the Marionette.py to make it capable of showing the exceution order.

    I think this can also be helpfull in other cases then global var handling.

     

    You have to replace the Marionette.py inside the marionett plugin by the attached one (on your own risk).

    It only shows the order on the first outport if there is a vw class named 'mrnt_show_order' in the doc otherwise it shows the number of output values as usual.

     

    598db3a9efe2c_Bildschirmfoto2017-08-11um15_35_39.png.6af19a8dae51ca03a085d4161fad5a2e.png

    Marionette.py.zip

    • Like 1
  9. On 8.9.2016 at 9:30 PM, Marissa Farrell said:

    A magician never reveals her secrets ;)

     

    In all seriousness, I'll be more than happy to give you a run down of my tricks once I stomp out some of the work I've got going on here. I've been a little swamped with testing 2017 features/installers/etc., but I would imagine once we release I should have the reigns loosened up on me at least a little. (Not that they're incredibly tight to begin with - how do you think I learned Marionette AND Python in less than a year?!)

    I'll keep in touch on this :) 

     

    I hope meanwhile you found time to finish your script.

    I'm still curious about your solution.

     

  10. Hi Dom,

     

    handling global vars looks like a dangerous thing to me.

    You have to be very carefull when connecting the nodes because it can change the flow of the network (first connected -> frist executed)

    which may lead to inconsistent values. (global var is accesed before assigned...).

     

    It seems that the flow also depends on the node from which you run the network.

     

    I've attached an example.

     

    regards

     

     

     

    global_var_test_v2017.vwx

    • Like 1
  11. You got it pat ;)

     

    I could solve it by replacing the += with .append:

     

    def RunNode(self):
    
    	dir = self.Params.dir.value
    	obj = self.Params.obj.value
    	
    	a = 0
    	b = self.Params.step.value
    	c = self.Params.count.value	
    	list = []
    	if c != 0:		
    		list = [a+n*b for n in range(c)]
    	objs = []
    	for i in range(len(list)):
    		if dir == 0:
    			objs.append (vs.HDuplicate(obj, list[i], 0)) # Changed += to append
    		elif dir == 1:
    			objs.append (vs.HDuplicate(obj, 0, list[i])) #  Changed += to append
    		self.Params.array.value = objs

     

    The node creates 5 duplicates so you get 6 object s in total at the end. The original was not passed out the Linear Array node.

    I appended a Delete-node to the Line-node, maybe you want to at it rather to the output list of linear array.

     

    597845bdebbf8_Bildschirmfoto2017-07-26um09_29_58.png.f588489eca6dee84ab50c2329ce0c9f7.png

     

    regards

     

  12. Thanks pat.

    I needed some attempts to get back from the str to the vs.Handle.

     

    The cells get filled with this code:

    h = vs.WSScript_GetObject()
    h_str = str(h) 
    vs.WSScript_SetResStr(h_str)

    Then another script iterates trough all objects and compares the handle strings:

     

    def get_handle_from_str (h_str):
    	h_dict = {} # key: handle_str val: handle
    
    	def collect_handles(h):
    		nonlocal h_dict
    		h_dict[str(h)] = h 
    		
    	vs.ForEachObject (collect_handles, 'All')
    	
    	try:
    		h = h_dict [h_str]
    	except KeyError:		
    		print ('Handle could not be found.')
    		h = None
    	
    	print (h_dict)
    	return h
    
    # EXAMPLE
    h = get_handle_from_str ('AEC62080')
    vs.SetSelect (h)

    It's kind of unpracticle and carries the risk if inconsistency but it works.

     

     

    ws_test.vwx.zip

  13. Hi Matt,

     

    any Python-IDE can do this.

     

    You can either put the vs.py next to your other py modules or better add a search path to the project that links to a folder where the vs.py is located.

    Then you have to import it in the modules where vs-functions are called.

     

    import vs

     

    I use pydev for eclipse. The search path can be added in the project properties.

     

    595b4aea75f86_Bildschirmfoto2017-07-04um09_58_52.png.29704ada90b96da76be7ac686b06d662.png

     

     

    • Like 2
×
×
  • Create New...