Jump to content


  • Content Count

  • Joined

  • Last visited

Posts posted by MullinRJ

  1. @josue Corona ,

       I assume you mean to do this with VectorScript, considering where you posted your question?


       Here's a short script showing how to copy a view. The attached file shows the same thing, using the 1st design layer to set the view and a selected viewport to receive the view setting.  You can use a similar approach to get the view rotations of a working plane by using the GetWorkingPlane() command.

    PROCEDURE xxx;
    { Example script to copy a Design Layer view and apply it to a Viewport. }
    { Select a Viewport. Run script. }
    { The script copies the view from the First Design Layer to the selected VP. }
    { 19 Jul 2019 - Raymond J Mullin }
    	Hdl, Hvp :Handle;
    	procedure ApplyViewFromDLtoVP(Hdl, Hvp :Handle);
    	{ Copy the view from design layer (Hdl) to viewport (Hvp). }
    		B :Boolean;
    		Vr, Vc :Vector;
    		if (GetTypeN(Hvp) = 122) & (GetTypeN(Hdl) = 31) then
    			if GetViewMatrix(Hdl, Vc.x, Vc.y, Vc.z,   Vr.x, Vr.y, Vr.z) then
    				B := SetViewMatrix(Hvp, Vc.x, Vc.y, Vc.z,   Vr.x, Vr.y, Vr.z);
    	End;	{ ApplyViewFromDLtoVP}
    	Hvp := FSActLayer;		{ handle to selected VP }
    	Hdl := FLayer;			{ handle to an arbitrary design layer }
    	ApplyViewFromDLtoVP(Hdl, Hvp);		


       Not knowing what version of VW you are running I exported the file as v2016, (and for others using older versions.) Please add a signature to your profile. It really will help people answer your questions more accurately.




    Copy View from DL to VP v2016.vwx


  2. VW 2011 was the first version that accepted Carriage Return (CR) characters in the Message Window; and Windows and Mac have different codes to accomplish this. The Mac uses CHR(13) for a CR while Windows uses CHR(13), CHR(10).


    So for Mac:

    Message('Line 1', chr(13), 'Line 2'); 


    Message('Line 1', chr(10), 'Line 2'); 


    Message('Line 1', chr(13), chr(10), 'Line 2');


    and for Windows:

    Message('Line 1', chr(13), chr(10), 'Line 2');


    all produce the same output.



    x + VectorScript Message


    Line 1

    Line 2





    • Like 2

  3. 6 hours ago, The Hamma said:

    This modification corrects the issue but it seems to me that if the points are read from HCenter as inches then they should be passed to RegularPolygon as inches.


    @The Hamma ,

       That would make perfect sense, but RegularPolygon() is one of those procedures that always takes its input as mm, and not document units. So, YES, you have to scale the  inputs to be mm before calling RegularPolygon(). Unfortunately, the documentation does not reflect that. Welcome to the quirky world of VS programming.   )



  4. Josue,

       The script @Pat Stanford showed you does not work when you are editing inside a Viewport's Annotation Space, nor inside any other container objects, i.e., Symbols, Groups, Profile space of 3D objects, etc. This is because of limitations of the FSActLayer function which only returns handles from selected objects on Design Layers and Sheet Layers.


       Do a search on "Waldo" in the Vectorscript Forum. You will get several hits that will show you a few lines that will return a handle to a selected object inside a container, like the Viewport's Annotation Space. Waldo is the nickname given to this kind of code that gets you a handle when you are not on a Design or Sheet Layer. Reference "Where's Waldo" to see where the name came from.


    Have fun and good luck,



  5. 2 hours ago, Ride said:

    Strange, it works through printing.  


    As it was explained to me recently by Gunther Miller, the PRINT menu command is supported by APPLE, and the EXPORT menu options are support by Vectorworks. Thanks for submitting the BUG.



  6. Thank you for that.


    Could you attach a screenshot of the OIP? There are a lot of settings for this marker, and that would be a lot easier than listing them all separately. Or better yet, attach a small file that has your offending marker in it for others to examine. This should save a lot of guessing if the answer is not obvious.



  7. Hi Max,

       As I said, it is a "minimized" script. I must leave something for you to do  ;-).  Do you have the Script Reference handy? There are similar calls for 3D Symbol queries, and the naming of new symbols is very subjective. If you don't want the script to rewrite an existing one, then you will have to search for the existence of the new name. If you find it you will have to increment or change yours accordingly then check again, but there are many ways to approach this. Be creative.


       Gotta run now. If you have more questions post again. Heck, @PatStanford hasn't even weighed in on this. If he does you'll get another load of advice to follow.


    I'll check back later,


  8. Hi Max,

       There is no need to duplicate a symbol instance to decompose a copy of it. Just decompose the original instance inside BeginSym() and EndSym, giving it a new name. To avoid problems later, it is best to do all your dirty work at the origin. Move symbol to (0, 0) and unrotate before demo and rebuild. To leave an instance in place, place the new symbol at the same XY/Rot as the original symbol when you are done. Here a minimized script to do just that.

    PROCEDURE MakeUnique;
    	Selection : HANDLE;
    	X, Y, Rot :Real;
    	Selection := FSActLayer;	{ get handle to Sym }
    	GetSymLoc(Selection, X, Y);	{ get insertion point }
    	Rot := hAngle(Selection);	{ get rotation }
    	hMove(Selection, -X, -Y);	{ movet to origin }
    	hRotate(Selection, 0, 0, -Rot);	{ unrotate }
    	BeginSym('Sym New');
    		SymbolToGroup(Selection, 0);
    		if (GetTypeN(LActLayer) = 11) then Ungroup;
    	Symbol('Sym New', X, Y, Rot);	{ place new symbol on drawing }
    	Sysbeep;	{ make noise when done }





  9. Hi Julian,

       Interesting approach. I knew you'd approach it differently than I. When you said your code might be quicker, it got me thinking. Your code is definitely more concise (quicker to code), but with the create and delete operations the execution speed can be an issue if large numbers of Polys need processing.


       For small object counts (<1000), both routines execute fast enough to be efficient. However, given enough objects the NURBS routine can appear painfully slow. I measured the two routines processing 1K, 10K, and 100K 3D Polygons. Each poly had 10 vertices. Here's what I got.


       Poly  |       JC        RM    |      JC         RM

    Count  |    Ticks    Ticks  |    Time     Time

        1K    |       57           4    |     .95s       .07 s

      10K    |    551         21    |    9.2 s     0.35 s

    100K    |  5586      175    |  93.1 s     2.92 s


       Sam, Bottom Line: pick the routine that will work best for your application based on your expected object count. 1-1000 Polys, shorter code looks better and is easier to support. >1000 Polys, summing the vertex distances will be much faster. VectorScript can get data from objects and process numbers and calculations much faster than it can create and delete objects. Just something to keep in mind when designing your coding approach.




  10. 1 hour ago, Pat Stanford said:

    It looks like the tricky part is having to pass the -1 to the unused vertices in the SetBinaryConstraint call.  


    Hi @Pat Stanford , you guessed it. I initially got hung up using "0". Once I used -1, it got easier. The second and third modes, Collinear and Parallel were much easier to guess how they worked, and with the tech note using symbol wasn't too hard either.


    1 hour ago, Pat Stanford said:

    Can you think of any case where you would need to enter two points on an individual object to create a constraint?


    Not to make two points of the same object coincident, but the call uses two points on an object to define an edge for Parallel, and Collinear. I'm not sure that's wha you mean, though.



  11. Hi Sam,

       After a quick search, I could not find a function that works on 3D Poly, like hPerim() works on 2D Polys. It may be out there, but I could write the routine to sum the legs faster than I could search for a function that does or doesn't exist. But, @Pat Stanford is correct, I've already done that and found one in my script archive. Damn, I wrote it more than a decade ago. I'm getting old.


       Hey, it's another example using Vectors. DOUBLE BONUS!

    PROCEDURE Get3DPolyLen_Example; 
    { 20 Dec 2008 - Raymond J Mullin } 
    	function Get3DPolyLen(H :Handle) :Real;
    	{ Return the perimiter length of 3DPoly H. If H is not a 3DPoly, return 0. }
    		I, N :Integer; 
    		L :Real; 
    		P0, Pa, Pb :Vector;
    		L := 0;
    		if (GetType(H) = 25) then begin 
    			N := GetVertNum(H); 
    			GetPolyPt3D(H, 0, P0.x, P0.y, P0.z);	{ 1st vertex }
    			Pa := P0;		{ copy of 1st vertex }
    			for I := 1 to N-1 do begin 
    				GetPolyPt3D(H, I, Pb.x, Pb.y, Pb.z); 	{ vertices 2 through N }
    				L := L + Norm(Pb-Pa);		{ NORM is the vector DISTANCE function }
    				Pa := Pb;
    			end;		{ for }
    			if IsPolyClosed(H) then  
    				L := L + Norm(P0-Pb);	{ distance from last to first points }
    		end;		{ if GetType }
    		Get3DPolyLen := L;
    	End;		{ Get3DPolyLen }
    	AlrtDialog(concat('3D Poly Length = ', Num2StrF(Get3DPolyLen(FSActLayer)))); 





    PS - if a native function exists, my bet is @Julian Carr or @JBenghiat would know.

  12. @boro,

       It took a bit of trial and error for me to figure out how the SetBinaryConsrtaint() function works, but I finally got it. It is NOT intuitive! Here is a very simple example showing how to join the endpoints of two lines together. 

    PROCEDURE SBC_1_Example;
    { Constrain two lines to share a common point. }
    { In this example, Pt1 of Line 1 (obj1VertA = 1) is to be coincident to Pt2 of Line 2 (obj2VertA = 2). }
    { Line 1 will move so its StartPoint is coincident with Line 2's EndPoint. Line 2 will not move. }
    { The angles of both lines will remain unchanged. }
    {  }
    { Select two lines and run the script. Line 1 is the first selected object and Line 2 is the second. }
    { For option 1 (Coincident Points), the second vertex of each object is not needed, so -1 is passed to }
    { the "obj1VertB" and "obj2VertB" parameters, while 0 is passed to both "containedObj" parameters. }
    {  }
    { At the end of the script, the Message Window shows the function's result (T/F) amd the numeric type }
    { of each selected object (LineType = 2).}
    { 27 Apr 2019 - Raymond J Mullin } 
    	H1, H2	:HANDLE;
    	result	:BOOLEAN;
    	H1 := FSActLayer;		{ Line 1 handle }
    	H2 := NextSObj(H1);		{ Line 2 handle }
    	result := SetBinaryConstraint(1, H1, H2, 1, -1, 2, -1, 0, 0);
    	message(result, '  ', GetTypeN(H1), '  ', GetTypeN(H2));




  13. Boro,

       I just tried this for the first time and it seems to work. Use the Constrain Coincident tool to attach one endpoint of a Line to Symbol A and use it again to attach the other end of the Line to Symbol B. Now when you move either Symbol A or Symbol B the endpoints of the Line will move to stay "attached" to each symbol. It works when done manually. I assume it can be scripted.


       Additionally, if you move the Line, then both symbols will move, too.


    Good luck,


  14. Tom,

       Do you realize Jim is not gone, he's just not an employee at the moment? Your statement is pretty harsh, and I don't think the rest of the VW employees deserve it, but good luck in your future endeavors. I'm sure you will be missed here, too.



  15. 3 hours ago, herbieherb said:

    Is there a way to find out if an image is a png or a jpg?


    Yes. This one liner will show the compression used on a placed image:


    vs.Message(vs.GetObjectVariableLongInt(vs.FSActLayer(), 532))   # 1 = JPEG, 2 = PNG



    • 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.