Jump to content

MullinRJ

Member
  • Posts

    2,012
  • Joined

  • Last visited

Posts posted by MullinRJ

  1. Hello @SamIWas,

      For your symbol popup item, look at:  CreateThumbnailPopup(dialogID, item_number);

    Sorry, I don't have any example code to populate it.

     

       I assume your LayerName popup menu is already populated, but if not, use:  
    GetChoiceCount(dialogID, menuID, Cnt);
    AddChoice(dialogID, menuID, 'menu item text', Cnt);

    in a loop to add items to the end of the menu. This code would go in the SetupDialogC section of the dialog handler.

     

       To select an existing menu item to be the chosen item, use:  SelectChoice(dialogID, menuID, menuPos, TRUE);

    where menuPos is the position of the Active Layer Name in your list. I believe counting in SelectChoice is 1-based, but if I'm wrong, it's 0-based. Easy enough to test.

    This code also goes in the SetupDialogC section of the dialog handler.

     

    HTH,

    Raymond

     

  2. 1 hour ago, Jayme McColgan said:

    so heres a slightly different question... 

    how do i loop through all symbols in the resource browser and build a list if a symbol has a certain record attached to it.

    in this case i need to build a choice list for a dropdown in a dialog box.= based off symbols that have a specific record attached to it.

     

     

       Here's a very useful script you'll have a hard time ferreting out of the Script Documentation. Sorry, it's in Pascal, so you'll have to Pythonize it. Like you, it's bed time. I assume you can build your list from this. Good luck, good night.

     

    PROCEDURE xxx;
    { Show the name of each symbol definition that has the record name 'Bob' attached to it. }
    CONST
    	RecName = 'Bob';
    
    	function DoIt2It(H :Handle) :Boolean;
    	Begin
    		if (Eval(H, (R IN [RecName])) = 1) then
    			AlrtDialog(GetName(H));		{ show Symbol Name }
    	End;		{ DoIt2It }
    
    BEGIN
    	ForEachObjectInList(DoIt2It, 0, 0, FSymDef);
    END;
    Run(xxx);

     

    Raymond

  3. 26 minutes ago, Jayme McColgan said:

    can't really seem to figure out how to do that for the items that live in the resource browser. I'm not trying to work on symbols that are placed in my drawing...

     

    Which items? Different items reside in different lists. The SymbolDefs are in their own list. The Resource Manager presents items from multiple lists, making it look like they are all under one roof, but they are not.

     

    Raymond

  4. 10 hours ago, zoomer said:

    If VW 2021 is the last VW version supported on Big Sur (macOS 11),

    VW 2020 should be the last VW version supported under macOS 10.15 Catalina.

     

    Hi @zoomer,

       Interesting, but VW 2022 works perfectly under OS 10.15.x. VW 2022 OS support is why I updated my OS last summer, and until November all VW versions were working. I am able to draw in VW 2020, and even run scripts, without a problem. It is only when I try to open the Plug-in Manager that VW crashes.

     

       In your comment above, I think you may have confused macOS 11 with macOS 10.11. I do that a lot. I just went back to the release notes of VW 2020, 2021, and 2022 and looked at the OS support notes, every SP release. This is what I found:

    VW 2022 – macOS 10.12.6, 10.13.6, & 10.14 are no longer supported. Use macOS 10.15 (Catalina.)

    VW 2021 – macOS 10.11.6 is no longer supported. Use macOS 10.12.

    VW 2020 – No OS restriction notes posted.

     

    10 hours ago, zoomer said:

    But maybe one of the latest macOS security patches caused a problem for VW 2020 SP6 ?

     

    The thought crossed my mind. It's pretty easy to reload back versions of VW. Not so with macOS'es.

     

    Thank you kindly for your reply,

    Raymond

  5. Hello,
       I am out of ideas. My friends are out of suggestions. Hopefully someone reading this may have some insight. As of a few weeks ago, VW 2020 SP6 (580724) started crashing every time I try to open the Plug-in Manager, CMD-Shift-Z, or menu Tools>Plug-ins>Plug-in Manager. Prior to the first crash, VW 2020 worked reliably. I am currently running Mac OS 10.15.7. When I boot under 10.12.6, VW 2020 works as expected, so I am guessing it has something to do with the OS, but that's purely a guess.

     

       Things I have tried:
    1) Remove the 2020 User Folder and reboot. VW 2020 rebuilds a new User Folder, but crashes when I try to open the Plug-in Manager.
    2) Delete the RM Cache under \Library\Application support\Vectorworks RMCache\rm2020. Same result after computer reboot, crash on opening Plug-in Manager.
    3) Ran Uninstall.app in the VW 2020 folder then copied VW 2020 SP6 from a backup drive to the Applications folder. Same result, crash on opening Plug-in Manager. 
    4) Copy VW 2020 SP5 from a backup drive to the Applications folder. Same result, crash on opening Plug-in Manager.


    5) Reboot under OS 10.12.6. VW 2020 SP6 works as expected.

     

    Note – VW 2019 (and earlier), VW 2021, and VW 2022 still working just fine. I updated the OS from 10.14.x to 10.15.x on 20 Jul 2021. Everything was working in VW 2020 until mid November, and I have no idea what happened.

     

    Any advice welcome.

     

    Thank you,

    Raymond

  6. Hello @Jayme McColgan,

       I'm not sure. I know you can display Symbols as a dialog control item, so possibly you could create a temporary symbol and update it as you change dialog fields, then update the dialog display to show the change. See vs.CreateSymbolDisplayControl() and vs.CreateSymDispCtrlN(). Also, you can launch another dialog with the push of a button in the first dialog. This I've done before. What you put in the second dialog is wide open, but you must close the second dialog to return control to the first.

     

    Good luck,

    Raymond

  7. Hi @Jiajing,

       I got an email from the Forum from your earlier post which you since modified, so you may already have the answer, but in case not, here is a more explicit use of the call.

     

    Xdesired = 123                # your desired image width
    Himg = vs.FSActLayer()        # handle to image object
    (x1, y1), (x2, y2) = vs.GetBBox(Himg)
    xcen, ycen = vs.HCenter(Himg)
    scaleF = Xdesired / (x2-x1)   # for uniform scaling
    vs.HScale2D(Himg, xcen, ycen, scaleF, scaleF, False)

     

    HTH,

    Raymond

    • Like 1
  8. Hello @Jayme McColgan,

       Since the dialog event handler script runs every time you type in your dialog, you can process each character as you type it and update another field at the same time. Use vs.GetItemText() ro read your typed data. In the IF clause for the EditText item use vs.SetControlText() to update a static text field. 

     

       You can also change EditReal and EditInteger fields in real time with calls to vs.SetEditReal() and vs.SetEditInteger(), respectively. This can be used when two fields are linked like Radius and Diameter of a circle or arc. Changing one updates the other.

     

       To your second question, I haven't tried this in the sense you are referring, but you could play with vs.SetEdgeBinding(). I've used it in resizable dialogs but never in a fixed dialog. Also, there is vs.AlignItemEdge(). I've tried to get things to right align with it but haven't done so satisfactorily, and always resorted to other layout methods.

     

    HTH,

    Raymond

    • Like 1
  9. Hello Riley,

       From your date of 1995, I suspect the files were created with MC 5, or earlier. When I opened your files I got errors. Initially I got a "This file was saved in a BETA version" error when I opened the files in older versions of the program. Then I tried forcing the file types and creators to MiniCAD versions 2 through 6 but received a " Resource Manager" error. You're right the files are small. These files are almost as small as blank documents. I am wondering if all of the file's data are present. If your files had any complexity to them they should be somewhat bigger.

     

       If you find different backups please try back. Sorry I cannot help further at this time.

     

    Raymond

  10. Nice result. Yeah, it takes some time to figure out where some of the "missing" pieces are in VectorScript. Spend some time looking at coding examples posted in these Fora. And when using the Script Reference, check both the HTML and the online Developer site. Sometimes they differ, mostly in the comments added to the online pages. As a quick resort, post questions here. It's a large brain trust.

     

    7 hours ago, Sloader said:

    I can't see a way to import a shapefile which is a shame.

    Do you mean manually or programmatically? The former can be done under menu File>Import>Import Shapefile..., but the latter is currently unsupported (best I can tell). I have imported one or two Shapefiles years ago, for grins, and they ended up being huge in polygon counts. It is possible VW will choke on larger ones, but it should be able to be done. If you need to do it programmatically, then your best bet is to add a post to the Feedback>Wishlist section of this Forum.

     

    All the best,

    Raymond

  11. I haven't tested your code, but one thing stands out. You place the symbol with CreatedSymbol=vs.Symbol('Canopy-1', X, Y, 0) but vs.Symbol does not return a handle as a result and I suspect CreatedSymbol is 0, or nil, after execution. Therefore your next line SymbolHandle= vs.GetObject(CreatedSymbol) is going to return a nil value since vs.GetObject(nil) is nil.

     

    What you probably want is:

    vs.Symbol('Canopy-1', X, Y, 0)    # place symbol

    SymbolHandle = vs.LNewObj()  # get handle to new symbol instance

    vs.SetRecord(SymbolHandle, 'canopyPNTSRec')   # attach record to symbol instance

     

    Ain't programming fun?

     

    HTH,

    Raymond

  12. Hello, @Elle.

       I think it has to do with your Zoom Level and Layer Scale combined. When you zoom out far enough at any grid setting, the grid will disappear at some point. Either Zoom In, or reduce your Layer Scale (or both) to see the reference grid. Consider how many grid lines you'd have on screen at 1/2" spacing, zoomed out to 29%, with a Layer Scale of 1:100 (numbers I gathered from your screen shot above.) I think your screen would be solid blue if all of the reference grid lines displayed. 

     

       You can also change your reference grid to 36", or larger, if you need to work at that zoom and layer scale. Play with the settings. I believe you can find something that works for you.

     

    HTH,

    Raymond

    • Like 2
  13. Hey Sam,

       Like you, it did not at first make sense to me either, but with a little experimentation it appears both ends of the dimension need to be on the object for the association to stick. I am surprised there is not a similar call that requires 2 handles to specify the object AND the dimension. Oh well, c'est la vie. 

     

       I've never used this, but have you played with AddAssociation()? The documentation is no worse than that of AssociateLinearDimension().

     

    Raymond

  14. Try narrowing your criteria.  vs.ForEachObject() looks at EVERY object in the drawing unless you tell it not to. As you create symbols, you are adding them to the end of the list of searchable objects, so vs.ForEachObject() processes them right after looking at every object that was on your design layer when the script started. In some situations, this can result in an infinite loop. In one of my examples above I suggested adding (T=Locus) to your criteria. Try it. Doing so will tell vs.ForEachObject() to only look at Loci, and your new symbols will escape processing. Then you can add the vs.DelObject() line back.

     

    Raymond

    • Like 1
  15. Thanks, Josh.

       Ya just learned me sumthin' new. It works like a charm. I guess it's an SDK PIO.

     

    PROCEDURE OnePass;
    { Create the Wide Flange PIO, move it into position, then hatch it. }
    VAR
    	H, Beam_Handle :Handle;
    
    BEGIN
    	Beam_Handle := CreateCustomObject('Wide Flange', 0, 0, 0);
    	SetObjectVariableBoolean(Beam_Handle, 1167, true);
    	HMove(Beam_Handle, 50, 0);
    
    	SymbolToGroup(Beam_Handle, 1);		{ decompose PIO }
    	
    	H := LActLayer; 			{ top object on active layer }
    	message(H, '  ', GetTypeN(H));
    END;
    Run(OnePass);

     

     

    16 minutes ago, JBenghiat said:

    What’s your end goal? If it’s primarily to make an extr(ud)e of the beam, storing the flange PIO in the profile group might be the way to go.

     

     Or he could use the 'Wide Flange - 3D' and avoid all the muss and fuss.

     

    Thanks again,

    Raymond

  16. @LarryO,

       I think you may be running into another fundamental problem with PIO's. The Wide Flange gets placed with your first command CreateCustomObject(), but the geometry does not exist until after your script runs. I tried to decompose it as Josh suggested, and I tried to step in and get a handle to the first object inside, and failed. From my experience, all of my attempts yielded NIL handles. That indicates the geometry does not exist when your script is running. 

     

       If you ran 2 scripts, one to create the object, and then another to convert it to a group, you would succeed. However, this is a manual approach and you are trying to achieve everything in one script. You can move the insertion point in your script, but the flange geometry is not generated until your script finishes. I don't think there is a way around this.

     

       To see what I'm talking about, try these two scripts manually, and it will work. If you combine them into one script, it will fail.

    PROCEDURE FirstPass;
    { Create the Wide Flange PIO then move it into position. }
    VAR
    	Beam_Handle :Handle;
    
    BEGIN
    	Beam_Handle := CreateCustomObject('Wide Flange', 0, 0, 0);
    	HMove(Beam_Handle, 50, 0);
    END;
    Run(FirstPass);
    
    {********************}
    
    PROCEDURE SecondPass;
    { Decompose Wide Flange PIO to a Polyline, and get handle to Polyline. } 
    VAR
    	H, Beam_Handle :Handle;
    
    BEGIN
    	Beam_Handle := FSActLayer;
    	SymbolToGroup(Beam_Handle, 1);	{ decompose PIO }
    	
    	H := LActLayer; 				{ top object on active layer }
    	message(H, '  ', GetTypeN(H));
    END;
    Run(SecondPass);

     

    Raymond

     

    • Like 1
  17. @Sloader,

       To scale a symbol there are 4 object variables (object attribute values set by an index, rather than by an explicit VecorScript call.)

     

    From the Script Function Reference Appendix:

    101 = Symbol Scale Type   (ObjectVariableInt)
                1 (None)    
                2 (Symmetric)
                3 (Asymmetric)

    102 = Symbol X Scale Factor        (ObjectVariableReal)
    103 = Symbol Y Scale Factor        (ObjectVariableReal)
    104 = Symbol Z Scale Factor        (ObjectVariableReal)
     

    Example:

    First set ObjVar 101 to 2, or 3, then set ObjVars 102 and 103:

    vs.SetObjectVariableInt(h, 101, 2)

    vs.SetObjectVariableReal(h, 102, XscaleF)

     

    or:

    vs.SetObjectVariableInt(h, 101, 3)

    vs.SetObjectVariableReal(h, 102, XscaleF)

    vs.SetObjectVariableReal(h, 103, YscaleF)

    If you set ObjVar 101 to 1, then the 3 scaling object variables are ignored and the effective scale factor is 1.0.

     

     

    You can also attach the record to the symbol and copy all of the fields from the locus record to symbol record. Then you can delete the locus with no loss of data.

     

    Raymond

     

    • Like 1
  18. Good morning, @Sloader.

       As you may already surmise, SetHDef() doesn't work with loci. Also, SetHDef() requires two handles, so if it did work you would need to type:

    vs.SetHDef(h, vs.GetObject(newsym1))

     

    That said, here is a simple way to achieve the same result:

    def ReplaceRAND1s(h):
    	X, Y = vs.GetLocPt(h)
    	vs.Symbol(newsym1, X, Y, 0)
    	vs.DelObject(h)

     

       If you have a lot of objects in your file, this may run a little faster, as it will only look at 2D Loci with the attached record:

    vs.ForEachObject(ReplaceRAND1s,("INSYMBOL & INVIEWPORT & (T=Locus) & ('canopyPNTSRec'.'RAND_COLOU'=1)") )

     

    HTH,

    Raymond

     

    PS - Your criteria statement is valid, does not need reformatting for Python.

    • Like 1
  19. Sam,

       After much wrong guessing, it comes back to the simple things. Ha, "simple"!!!  The list you want to interrogate is the Name List, though you don't have to do it manually, unless you want to.

     

       Use Name2Index() to find the index of a LineType name that's in the name list, then negate that index to set the LineType index in SetLineTypeChoice(), not SetLineWeightChoice().

     

       Here's an example script.

     

    LineStyle menu example.txt

     

    Raymond

  20. @michaelk,

       At first I thought you exposed a bug, but after several days of visiting this post and rereading your code snippet for the umpteenth time I think your confusion is self inflicted.

     

       If you remove the SetTextWrap(LNewObj, TRUE); line, do you still get unpredictable results? I suspect not, but If so then you may have found a bug, but I have not been able to reproduce it in my very limited testing.

     

       In the following, I use "Text Object" to refer to the text on the page (blue selection handles et al.), and I use "Text Block" to mean the characters of text in your text variable S1. The Text Block's length can only be changed by changing the Font Face, Size, Style, etc., so you can treat it like a constant until you change any of the text's attributes. 

     

       Now back to your code snippet, with the SetTextWrap(LNewObj, TRUE); line in place you are telling VW to force the text block to use Wrapping, even though the length of the text block is unchanged from its default value, and VW responds in kind. Please note that the Text Wrap checkbox in the OIP does not control a real text attribute. It does not save a boolean value with the file and there is no way to set it to be ON by default. What is saved is the WIDTH of the text block. When the calculated text width does not equal the text block width, either because it was changed manually or programmatically, the Wrap Text checkbox gets set. If you CLEAR the Wrap Text checkbox, either manually or programmatically, the text object's width is set to be equal to the calculated width of the text block (which is affected by Font Face, Size, Style, etc.)

     

       What you see on the screen when the Text Object's width does NOT equal the Text Block's length should be predictable. What you see on the screen, when the Text Block's length exactly equals Text Object's width, is affected by what the text block contains.

    1) If the Text Block ends in a printable character, the block will wrap the last word (assuming the block contains a white space and words) to the next line.

    2) If the Text Block ends with a Space or a Tab character, no visible word wrapping occurs.

    3) If the Text Block ends with a Carriage Return, the text block already has a second line, so the first line's appearance is governed by 1) and 2) above.

     

       If you don't care to digest all of the minutiae I've just blathered above, then play with this test code and make you own observations.  

     

    PROCEDURE xxx;
    { Script to show how OIP "Wrap Text" affects word wrapping with different string endings. }
    { Change constant "kWordWrap" from FALSE to TRUE to see effects of wrapping. }
    { Document settings are INCHES, Layer Scale = 1, Font = Arial, Point Size = 12.}
    { 28 Oct 2021 - Raymond J Mullin }
    CONST
    	Tb = chr(9);
    	CR = chr(13);
    	Sp = chr(32);
    	kWordWrap = FALSE;
    VAR
    	S, S1, S2, S3 :String;
    
    	procedure PlaceText(TxtBlk :String; X, Y :Real);
    	Begin
    		MoveTo(X, Y);
    		BeginText;
    			TxtBlk
    		EndText;
    		SetTextWrap(LNewObj, kWordWrap);
    	End;		{ PlaceText }
    	
    BEGIN
    	S := concat('Abysmal echo duck lamps');
    	S1 := concat(S, Sp);
    	S2 := concat(S, Tb);
    	S3 := concat(S, CR);
    
    	PlaceText(S, 0, 0);
    	PlaceText(S1, 0, -0.5);
    	PlaceText(S2, 0, -1.0);
    	PlaceText(S3, 0, -1.5);
    
    	SysBeep;
    END;
    Run(xxx);

     

    HTH,

    Raymond

     

    PS - I tried @Pat Stanford's example and was able to get the string to word wrap when using Tabs instead of Carriage Returns, but not with Spaces. No idea why.

    If you are trying to predict how raw character data will wrap, I leave it to you to investigate further. If you limit yourself to human readable words, you may have better results.

     

    • Like 1
×
×
  • Create New...