Jump to content

MullinRJ

Member
  • Content Count

    1,462
  • Joined

  • Last visited

Posts posted by MullinRJ


  1. Hi @Taproot ,

     

    41 minutes ago, Taproot said:

    I see that Type 10 = Text Objects, but I don't know how to further limit the selection via font.

    Could you assist me in that regard?

     

       You have a good eye, but there is not an easy way in VS to describe how to determine the font assigned to a text block. Rather than try to guide you through it, I made the changes to the previous script and posted it below. As you can see, it still took me about an hour to do this and I still took the easy way out by only checking the first character of a text block to check the font assignment. See next paragraph.

     

       I modified the previous script to only change the font type of Arial text blocks. You can specify the font to be changed by changing the constant "kFontNm" at the top of the program. There is one caveat, this script assumes that if a text block starts with a character in the Arial font, the whole text block is Arial. This script does not change individual characters within a text block. That can be done, but requires a bit more time to code.

     

    <<< THIS SCRIPT IS LIGHTLY TESTED — VERY LIGHTLY TESTED.  USE AT YOUR OWN RISK,  AND PLEASE TRY IT ON A TEST FILE FIRST. >>>

     

       Also, I corrected a mistake in the previous script that did not pass back the point size in variable "PointSize" from the FormatTextDialog() procedure. That is now corrected in the above script and in the one posted below.

     

       If anyone finds any problems with this script, please write back and I'll have @PatStanford get right on it. 😉

     

    PROCEDURE ChangeSomeFonts;
    { Changes the font of all text on a drawing to the selected font }
    { Traverses into groups, symbols and viewport annotations }
    
    { January 6, 2012 }
    { © 2012, Coviana, Inc - Pat Stanford pat@coviana.com }
    { Licensed under the GNU Lesser General Public License }
    
    { 17 February 2020 - R. Mullin }
    { Added ability to set the Point Size of all text objects at the same time. }
    { Same GNU License as above. }
    
    { 7 October 2020 - R. Mullin }
    { Only change Text Blocks with name specified in constant "kFontNm" to target font name "kNewFontNm". }
    { Same GNU License as above. }
    
    CONST
    	kFontNm = 'Arial';				{ change from this font name }
    VAR
    	Hd :Handle;
    	NewFontNm :String;
    	FontID, dummyInt :Integer;
    	PointSize, dummyReal	:Real;
    
    	Procedure ChangeFont(Hd :Handle);
    	Var
    		FID :Integer;
    	Begin
    		if (GetTypeN(Hd) = 10) then begin
    			FID := GetTextFont(Hd, 0);	{ assumes all characters in txtBlk are the same fontID }
    			if (FontID = FID) then begin
    				SetTextFont(Hd, 0, len(GetText(Hd)), GetFontID(NewFontNm));
    				SetTextSize(Hd, 0, len(GetText(Hd)), PointSize);
    			end;		{ if (FontID = FID) }
    		end;		{ if GetTypeN() }
    	End;		{ ChangeFont }
    
    BEGIN
    	FontID := GetFontID(kFontNm);			{ existing FontID }
    	FormatTextDialog(NewFontNm, dummyInt, PointSize, dummyInt, dummyReal, dummyInt, dummyInt, 60);
    	ForEachObject(ChangeFont, INSYMBOL & INOBJECT & INVIEWPORT & ALL);
    END;
    Run(ChangeSomeFonts);

     

    HTH,

    Raymond

     


  2. Hi @josue Corona ,

       There is not a single command that will do that. There are commands in the VS language that will return intersection points between objects:

    LineCircleIntersect()
    LineEllipseIntersect()
    LineLineIntersection()

    EllipseEllipseIntersect()

     

       And there are other commands that will determine if the points in question are on Line segments, or Arc segments:

    PtOnArc()
    PtOnLine()

     

       But to use these the way you are probably hoping for will require a fair amount of coding to take the points they return and manipulate your target object to break at the right spots. If you like Analytic Geometry you can get there from here. If not, you might consider hiring someone who does.

     

    Not sure if this helps,

    Raymond


  3. @WhoCanDo ,

       I don't know what changed with the DMTBN() command. However, there are 32 new VS commands in VW 2021 that interface with Excel files. I have not used them so I cannot comment on them beyond their existence. Perhaps you can loop through your Worksheet's cells and export each cell to an Excel file. It seems more tedious than simply exporting to a text file, but it may give you more control. If you're lucky,  @Pat Stanford  has dabbled with these and can shed some light. 

     

       These are the commands listed in the Script reference. Documentation is what you'd expect – thin.

     

    Excel_Convert
    EXL_AddSheet
    EXL_CloseBook
    EXL_DeleteSheet
    EXL_GetCellAlignment
    EXL_GetCellBordeDiff
    EXL_GetCellBorderB
    EXL_GetCellBorderL
    EXL_GetCellBorderR
    EXL_GetCellBorderT
    EXL_GetCellFill
    EXL_GetCellFont
    EXL_GetCellStyle
    EXL_GetCellValue
    EXL_GetSheetCnt
    EXL_GetSheetIndex
    EXL_GetSheetName
    EXL_GetSheetSize
    EXL_IsCellValid
    EXL_NewBook
    EXL_ReadFile
    EXL_SaveAndCloseBook
    EXL_SetCellAlignment
    EXL_SetCellBorderB
    EXL_SetCellBorderL
    EXL_SetCellBorderR
    EXL_SetCellBorderT
    EXL_SetCellFont
    EXL_SetCellNumber
    EXL_SetCellNumFormula
    EXL_SetCellStrFormula
    EXL_SetCellString
     

    Good luck,

    Raymond


  4. Hi @Sebastiaan ,

       I'm seeing that. After too much trial and error, I've come to the same conclusion.

     

    Oddly, this works to show all 40 of the LDs'.

    =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'0')))

     

    BUT, this does not work as expected:

    =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'1')))

     

       It only shows LD's with channels 3-9, and 20. What I've noticed is that the DATABASE() engine is comparing strings, and not numerical values (as you'd like).

    Strings starting with "2xxx" through "9xxx" satisfy the equation, but strings "10" to "19" and "101" to "120" don't satisfy it because the first character in each string is a "1".

     

       You really need a VALUE() function, and that only appears to work in a worksheet cell, and not in a Database row.

     

       Sorry, I'm stumped.

     

    Raymond

     

    • Like 2

  5. @Sebastiaan ,

       Like Pat, I don't have a file to test this, but if a LD does not yet have a channel then this might work.

     

    =DATABASE( (NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'<>'') & (VALUE('Lighting Device'.'Channel')>=1) & (VALUE('Lighting Device'.'Channel')<=100)) )
     

    This expression checks for an empty channel string before it tests the values in the channel

     

    HTH,

    Raymond


  6. Hi @matteoluigi ,

       You can get the handle to any named object using GetObject() like this:

     

        H := GetObject('Wohnungstypen-Auto');
        if (H <> nil) & (GetTypeN(H) = 18) then begin    { type 18 = Worksheet }

           { do worksheet stuff here }
        end;        { if }

     

       It is always wise to check a handle's validity and type before using it.

     

    HTH,

    Raymond

     

     

    • Like 2

  7. @matteoluigi ,

       There is a problem with your syntax of the 6 IF statements. Where you have  "  ))=1)  "  you should have  "  ))) =1  "

     

    Your last parenthesis should be to the left of the "=". The syntax is essentially   " COUNT ( ... ) = aNumber ".

     

     

    28 minutes ago, matteoluigi said:

    does there also exist sth like else if?

     

    Yes you can have statements lilke:

     

    if ( ) then begin end

    else if ( ) begin end

    else if ( ) begin end

    else begin end;

     

    Notice there is only 1 semicolon at the end, and not after each else if clause.

     

    HTH,

    Raymond


  8. Using: Message(GetTypeN(FSActLayer));

     

    If I select a free standing Door I get type 86 (Plug-In object).

     

    If I select a a Door in a Wall I get type 68 (Wall object).

     

    To see the Door on a test wall I have in an open document, I needed to use:

    Message(GetTypeN(NextObj(NextObj(NextObj(NextObj(NextObj(NextObj(NextObj(FIn3D(FSActLayer))))))))));

     

    As you can see, the door object is deep inside the Wall object. The number of objects in front of it are not exact, and are determined by the wall's construction. You should use a loop to look for the Door, or possibly try ForEachObjectAtPoint(). There may be a more direct way to get to the Door-in-Wall that someone else can point to. I've just done a cursory quick dive at this. 

     

    Again, make sure your handle is pointing to a Door object before trying to access its record.

     

    HTH,

    Raymond


  9. 17 minutes ago, Paolo said:

    Maybe this should work:

     

    FUNCTION HasPlugin( itemUniversalName  :STRING; VAR PaletteName  :STRING) : BOOLEAN;

     

    @Paolo ,

       I did a quick test and it looks like the function HasPlugin() only returns TRUE if you have the plug-in installed in your workspace. Loading a plug-in after you have a resource/object of the same name will cause a conflict, but I don't know how VW responds in that scenario. I can only assume it causes more confusion.

     

    Raymond

     

     

     

    • Like 1

  10. Hi @Paolo ,

       No, Plug-in names use the same name space as custom objects that you name manually, or by script. The only name space that I know of that is managed separately are the Layer Names. You can have objects, like Symbols, with the same name as a Layer and VW will not raise a conflict. 

     

       I know this is confusing, but you are now on the right track. 

     

    Raymond


  11. Hi @Paolo.

       I know from testing on several versions of VW that "Siding" is not a reserved word. Would you please post a problem file so that we may investigate further? It's possible that your Mouldings Plug-ins package is using the name "Siding" and that is preventing you from using it again.

     

       Also, have you restarted VW to see if the issue goes away? If it does vanish after a restart, does it reappear a little later?

     

    Thank you,

    Raymond


  12. Hi @Paolo ,

       Your test script needs an EndFolder command to compile correctly and run. Also, Name2Index() will always return "0" for a name that does not exist. 

     

    PROCEDURE test;
    VAR
    	h : handle;
    BEGIN
    	h := GetObject('Siding');
    	if (h = nil) then message('No object with this name! ''Siding'' exists');
    
    	NameObject('Siding');
    	BeginFolderN(16);
    	EndFolder;
    END;
    Run(test);

     

    Another problem with your script is if the folder "Siding" exists, VW will not delete it and create it again, a new folder named "Folder"  will be created, then after that VW will create "Folder-2", then "Folder-3", etc., each time your test script is rerun.

     

    I believe @Pat Stanford 's approach is the right way to go – test for the handle's existence, then test for the handle's type – but you have to do different things based on:

    1) if "Siding" does not exist (create your folder)

    2) "Siding" exists, and it IS a Folder Type (do nothing; or delete the existing folder and recreate it from scratch)

    3) "Siding" exists, but it IS NOT a Folder Type (execute your escape plan)

     

    HTH,

    Raymond

     


  13. Hello Kars (@Kars Keizer),

     

    I'm not to sure this is related, but it is confusing. From the Script Reference Appendix I get:

     

    1830877465_RenderSettings.thumb.png.06e8682899670742d3d175b10ade2876.png

     

    and 6 appears to be "Final Shaded". When I run your script I get "Hidden Line", as read from the VW View>Rendering menu. I tried different constants and 5 gave me "Final Shaded Polygon", again as read from the VW View>Rendering menu. On a whim, try different constants. It may or may not work as it may also be platform dependent. I am on a MAC and you are on a PC. It's worth a try.

     

    If you find the numbers are wrong, you may have found a bug in the documentation.

     

    Raymond

     


  14. Hello @WhoCanDo ,

       The constraint settings can be accessed by preference numbers. Here's a routine I wrote a couple of years ago that will do what you're looking for.

    	function GetSnaps :String;
    	{ Return a string with the current SNAP settings. }
    	Var
    		S :String;
    	Begin
    		S := '';
    		if GetPref(37) then S := 'A';			{ Snap to Grid }
    		if GetPref(1312) then S := concat(S, 'S');	{ Snap to Angle }
    		if GetPref(1314) then S := concat(S, 'D');	{ Smart Points }
    		if GetPref(1316) then S := concat(S, 'F');	{ Smart Edge }
    	
    		if GetPref(38) then S := concat(S, 'Q');	{ Snap to Object }
    		if GetPref(1313) then S := concat(S, 'W');	{ Snap to Intersection }
    		if GetPref(1315) then S := concat(S, 'E');	{ Snap to Distance }
    		if GetPref(1317) then S := concat(S, 'R');	{ Snap to Tangent }
    		GetSnaps := S;
    	End;		{ GetSnaps }

     Enjoy,

    Raymond


  15. Hi Lyle,

       There is now. This script gives you an option to draw the circles on the Ground Plane, or elevate them to the height of the 3D Locus by changing the value of constant "Circles3D". See comments in script. I also added a dialog to let you specify the circle's diameter before the script runs.
     

    Procedure Loci3DToCircle;
    
    { Replaces every Loci in a drawing with a Circle }
    { centered at the insertion point of the loci. Use with care after backing up }
    { the original drawing. Use at your own risk. Here there }
    { be dragons. No warranty expressed or implied.   ;-)  }
    
    { Adjust the Const Radius = 1' to a unit an size appropriate to the requirement }
    { All Circles created will use the default class, color, etc of the document. }
    
    { January 28, 2015}
    { July 15, 2011}
    { © 2011-2015, Coviana, Inc - Pat Stanford pat@coviana.com}
    { Licensed under the GNU Lesser General Public License}
    
    { 08 Aug 2020 - Raymond J Mullin }
    { This is a modification of Pat Stanford's script to convert 2D Loci to circles. }
    { This script will convert 3D Loci to Circles on the Ground Plane if constant Circles3D is FALSE, }
    { or it will elevate the circles to the Z height of the 3D Loci if constant Circles3D is TRUE. }
    { This script will also use a dialog for the user to set the Circle's Diameter. }
    
    Const	
    	Radius = 6";
    	Circles3D = TRUE;	{ Circles on Ground Plane if FALSE. Floating circles if TRUE. }
    Var
    	Diam :Real;
    
    
    	Procedure DoAction(H :Handle);
    	Var
    		X, Y, Z : Real;
    	Begin
    		GetLocus3D(H, X, Y, Z);
    		ArcByCenter(X, Y, Diam/2, 0, 360);	
    		SetObjectVariableBoolean(LNewObj, 1160, FALSE);	{ circle on Gnd Plane }
    		if Circles3D then Move3DObj(LNewObj, 0, 0, Z);	{ elevate circle }
    		DelObject(H);					{ delete 3D Locus }
    	End;		{ DoAction }
    
    
    BEGIN
    	Diam := RealDialog('What Diameter?', Num2StrF(Radius*2));
    	if not DidCancel then
    		ForEachObject(DoAction, T=LOCUS3D);
    END;
    Run(Loci3DToCircle);

     

    Have fun,

    Raymond

     

    • Like 2

  16. Perhaps it is because the DrawingLabels update after your script finishes, in which case you have already reset the Automatic Drawing Coordination back before any DrawingLabel code runs. If this is the case, I don't know of a way to get around it in one script.

     

    Raymond 


  17. Hi Julian,

       Here's one for lower case.

    PROCEDURE TEST;
    CONST
    	CR = chr(13);
    VAR
    	S :String;
    
    	function LowerCase(S :String) :String;
    	{ Convert string S to lower case. }
    	Var
    		Ch :Char;
    		I, StrLen, ChVal :Integer;
    		T :String;
    	Begin
    		T := '';
    		StrLen := len(S);
    		for I := 1 to StrLen do begin
    			Ch := copy(S, I, 1);
    			ChVal := ord(Ch);
    			if (ChVal > 64) & (ChVal < 91) then
    				T := concat(T, chr(ChVal+32))
    			else T := concat(T, Ch);
    		end;		{ for }
    		LowerCase := T;
    	End;		{ LowerCase }
    
    
    BEGIN
    	S := '0123456789 !@#$%^&*()_+ ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz';
    	message(S, CR, LowerCase(S));
    END;
    Run(TEST);

     

    Raymond

    • Like 1

 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×
×
  • Create New...