Jump to content

MullinRJ

Member
  • Posts

    1,990
  • Joined

  • Last visited

Everything posted by MullinRJ

  1. In your Event Loop, the variable ITEM identifies the exact control that was pressed. You can trap it with: case item of ???1: begin end;???{ OK Button } ???2: begin end;???{ Cancel Button } ???21..40: begin ???{ do stuff here if control 21 - 40 gets pressed } ???end; end;???{ case } This will work even if you only populate 15 of the 20 possible control numbers. HTH, Raymond
  2. Preston, Are you using PASTE, or PASTE IN PLACE? The latter keeps items registered even when pasting on layers at different scales. Also, you can change the scale of any layer at any time and not lose your registration. Lastly, are you importing DXF Layers as CLASSES (default) or as LAYERS? That setting is under the Graphic Attributes tab, which you will find behind the Set Custom Options... button if you are importing multiple DXF/DWG files at once. If you use the As Layers option it should split your data to design layers for you. HTH, Raymond
  3. Hi Who, You can get the handle of the 1st object in a group with: ???h2a := FinGroup(GrpHand); and get a handle to the next object in the group with: ???h2b := NextObj(h2a); If they happen to be Polys, so much the better. OR, you can duplicate the group with: ???Grouplic8Hand := hDuplicate(GrpHand, 0, 0); OR, move pieces into a Group with: ???boo := SetParent(h2, GrpHand); or out of a Group with: ???boo := SetParent(h2, GetParent(GrpHand)); If you want to merge the two polys in your group into one (assuming they overlap), you might use: ???h3 := AddSurface(h2a, h2b); and then ungroup it with: ???hUngroup(GrpHand); I'm not sure which approach, if any, would work for you. I'll let you pick. Have fun, Raymond
  4. Mr. Gog, You are going to run into trouble if Get3DOrientation() ever fails. In such a case, your code will never move to the next object and will wind up in an endless loop. You need to put H1:=NextSObj(H1); outside the IF statement and place it as the last statement in the WHILE loop. Raymond PS - Why did you create inline code and not use a user defined function? For small programs such as this, it's not a real issue, but as soon as you get up to 50 lines or more, user defined procedures and function will make the main body of your code read much more easily. In the following example, the main routine becomes 3 lines inside the WHILE loop: generate a random number, scale the object by that number, get the next selected object. In a year or two, which version of the script do you think will be easier to read? Procedure RandomScaleSelected; { Scale selected 3D objects by a random factor between 0.6 and 1.0 } Var ???H1: Handle; ???R1: Real; ???procedure ScaleIt3D(H :Handle; SF :Real); ???{ Scale a 3D object around its center by scale factor SF. } ???Var ??????mirror :Boolean; ??????X, Y, Z, Xrot, Yrot, Zrot :Real; ???Begin ??????if Get3DOrientation(H, Xrot, Yrot, Zrot, mirror) then begin ?????????Get3DCntr(H1, X, Y, Z);?????????????????????{ Get 3D center } ?????????Set3DRot(H, 0, 0, -Zrot, X, Y, Z);????????{ unrotate it } ?????????Set3DRot(H, 0, -Yrot, 0, X, Y, Z); ?????????Set3DRot(H, -Xrot, 0, 0, X, Y, Z); ?????????HScale3D(H, X, Y, Z, SF, SF, SF);???????{ scale it } ?????????Set3DRot(H,?Xrot, Yrot, Zrot, X, Y, Z);???{ re-rotate it } ??????end;??????{ if } ???End;??????{ ScaleIt3D } Begin ???H1 := FSActLayer; ???While (H1<>Nil) do Begin ??????R1 := Random * 0.4 + 0.6; ??????ScaleIt3D(H1, R1); ??????H1 := NextSObj(H1); ???End; ???RedrawAll; End; Run(RandomScaleSelected);
  5. If you replace HScale3D() with the following procedure, you will be able to scale 3D objects in place, even if they are rotated. Raymond procedure ScaleIt3D(H :Handle; X, Y, Z, SF :Real); { Scale a 3D object by scale factor SF around point (X, Y, Z) } Var mirror :Boolean; Xrot, Yrot, Zrot :Real; Begin if Get3DOrientation(H, Xrot, Yrot, Zrot, mirror) then begin { unrotate it } Set3DRot(H, 0, 0, -Zrot, X, Y, Z); Set3DRot(H, 0, -Yrot, 0, X, Y, Z); Set3DRot(H, -Xrot, 0, 0, X, Y, Z); { scale it } HScale3D(H, X, Y, Z, SF, SF, SF); { re-rotate it } Set3DRot(H,?Xrot, Yrot, Zrot, X, Y, Z); end; { if } End; { ScaleIt3D }
  6. Hi Orlando, In an IF THEN ELSE statement, you cannot have a semi-colon between END and ELSE. A semi-colon there tells the compiler that your IF statement ends after the THEN clause. The ELSE should be kicking an error. Use a semi-colon only after the last END. Use this format: IF ( ) THEN begin end ELSE begin end; I haven't run your script, so I cannot comment further. Happy scripting, Raymond
  7. You can use single characters, but not strings, in a case statement. CH :Char; case CH of ???'a' : begin end; ???'b' : begin end; ???'c' :begin end; ???'d' :begin end; ???'e' :begin end; ???'f' :begin end; ???'g' :begin end; ???'h', 'i', 'j', 'k' :begin end; ???'l' .. 'p' :begin end; ???'q', 'r', 's' :begin end; ???'t', 'u', 'v' :begin end; ???'w' :begin end; ???'x', 'y', 'z' :begin end; end;???{ case } As a rule, case statements only work with enumerated types, that is, variables that have an integer value. HTH, Raymond
  8. From VS Function Reference Appendix Project 2D - 1005 - TRUE of FALSE - ObjectVariableBoolean To turn it on, use: SetObjectVariableBoolean(HandleVP, 1005, True); Raymond
  9. 31? It took me a minute, but I was able visualize 30 from your picture; and the equator makes 31. I love your art, it's a drug for sober people. Thanks, Raymond
  10. This one's an easy one to guess. By trial usage I determined the following: PtOnLine returns TRUE if point Pt is on the line segment defined between points BegPt and EndPt, inclusive; or within a distance, defined by Tolerance, of that line segment. Otherwise it returns FALSE. Pt = point to be tested, stored as a vector (Pt.x, Pt.y, Pt.z) BegPt = first point of line segment, stored as a vector (BegPt.x, BegPt.y, BegPt.z) EndPt = second point of line segment, stored as a vector (EndPt.x, EndPt.y, EndPt.z) Notes: 1) For 2D lines and points, the z component of the three vectors is 0. 2) Because of the nature of real numbers stored in computers, Tolerance should not be set to 0. Make it a suitably small number for your use. 1e-6 or 1e-9 should work for most architectural needs. Anything greater than 1e-323 will work for the number system employed by VW (at least as I've tested it on a Mac).
  11. There is also this function: PtOnLine(Pt, BegPt, EndPt: VECTOR; Tolerance: REAL) : BOOLEAN; Use it in a loop for each side of your Poly. Raymond
  12. Thanks, Ray. I pasted it in again. I appears to be working now. Raymond
  13. To toggle autosave, use this one line script: ???setpref(24, not getpref(24)); To quickly find any constant that is used for a standard preference, go to: VW Preference Constants Raymond
  14. Hi Who, ???You're definitely on the right track. However, you need to calculate the angle you want to rotate from points 1 and 3 before you call the RotatePoint() function. This is most easily done with vector function Vec2Ang(). Since point 1 is the center of interest (and rotation) subtract it from point 3 and stuff it into vector V as follows: V.x := x3 - x1; V.y := y3 - y1; AngleOfPt3 := Vec2Ang(V);???{ relative to point 1 } The following script is not what you want, but it executes in a humorous way. Try it. PROCEDURE yyy; VAR H :Handle; x1, y1, x2, y2, x3, y3, AngleOfPt3 :Real; V :Vector; BEGIN repeat if (MouseDown(x1, y1)) then begin moveto(x1, y1); x2 := x1 + 580; y2 := y1; closepoly; poly (30,#90,x2,#0,30,#-90); H := lnewobj; end; until (H <> Nil); repeat getmouse (x3, y3); V.x := x3 - x1; V.y := y3 - y1; AngleOfPt3 := Vec2Ang(V); RotatePoint (x1, y1, AngleOfPt3); redraw; until (MouseDown (x3, y3)); END; Run(yyy); Since you are in a loop, each time through you will rotate your object again, so your script has to remember how much it rotated the object the last time through and subtract that off for the current pass through the loop. This example should be more to your liking. PROCEDURE xxx; VAR H :Handle; x1, y1, x2, y2, x3, y3 :Real; AngleOfPt3, lastPt3Ang :Real; V :Vector; BEGIN repeat if (MouseDown(x1, y1)) then begin moveto(x1, y1); x2 := x1 + 580; y2 := y1; closepoly; poly (30,#90,x2,#0,30,#-90); H := lnewobj; end; until (H <> Nil); lastPt3Ang := 0; repeat getmouse (x3, y3); V.x := x3 - x1; V.y := y3 - y1; AngleOfPt3 := Vec2Ang(V); RotatePoint (x1, y1, AngleOfPt3 - lastPt3Ang); { rotate by delta angle } lastPt3Ang := AngleOfPt3; redraw; until (MouseDown (x3, y3)); END; Run(xxx); HTH, Raymond
  15. I refrain from trusting bibles and rely more heavily on observation. I'm from the school of trial and error. Bibles are full of good intentions, but historically are not factual. Without knowing what you are trying to do, I cannot offer sound advice on which path to take. There's usually more than one way to approach each problem, so if this command doesn't suit your needs, others might. You are right, the bible does say that, but the code acts differently. If you want it to work as advertised, you should file a bug. In the meantime, describe what you are trying to do and maybe someone out here can suggest a decent solution or workaround. Raymond PS - In your search for truth, keep good notes.
  16. Mattie, ???I don't think it ever worked the way you want. It would be nice if it did. Perhaps if you temporarily open up your snap radius to as large as it will go before clicking then resetting it after you get your object, it might act more like you desire. ???Use pref numbers 1009 and 1010 with GetPref() and SetPref(). If you need help with this, write back. Raymond
  17. Hi Matie, Two things, you are missing a few lines from the example that is posted in the VS Function Reference. The full script is (with one line added): PROCEDURE GetClosestPtExample; VAR ???obj :HANDLE; ???ptX, ptY :REAL; ???index :INTEGER; ???containedObj :LONGINT; BEGIN ???GetPt(ptX, ptY); ???obj := PickObject(ptX, ptY); { you need this line } ???GetClosestPt(obj, ptX, ptY, index, containedObj); ???SetPenFore(obj, 65535, 0, 0); ???{ the following line shows the values of your variables at the end of the script } ???message('obj= ', obj, ' X= ', ptx, ' Y= ', pty, ' ', index, ' ', containedObj); END; RUN(GetClosestPtExample); Second, when you run the script and click in the drawing you have to be close enough to an object for it to be selected; the same as you would if you were trying to select it manually. Clicking in an open region will return zero in your "obj" variable. HTH, Raymond
  18. There is no link from a Symbol Definition (where you are) to symbol instances. You will have to search the document to find any instances. Use one of the ForEachObject...() commands. If it's out there you should be able to find it. Raymond
  19. Personally, I'd invest in a full keyboard. There's no need to shell out $50-$100 for a new one. I just bought a BT keyboard at a used equipment flea market for $10 on Saturday. It works very nicely. (I'm typing on it now.) Shop around - EBay, Amazon, etc. If you find one you like, you'll also have a spare for emergencies. Bottom line: If you plan to use your computer a lot, you'll be using your keyboard a lot. Get one you are comfortable with. Raymond
  20. What happens when you import in 2008, save the file and open it in 2010? Raymond
  21. Use ForEachObjectInList() and pass a handle to the first SymbolDef in the Symbol List. Add the following line and create a similar function that filters object by class so that you don't change everything. This is in addition to the code you already have. ForEachObjectInList(ChangeNameInSyms, 0, 2, FSymDef); { ALL objs, DEEP, SymDef List } HTH, Raymond
  22. oldList: ARRAY[1..kTOT_CLASS] OF STRING: newList: ARRAY[1..kTOT_CLASS] OF STRING: Hi Andrew, ???Both of these lines end in COLONS and should end in SEMICOLONS. They're typos. Change them as follows and you should be good. oldList: ARRAY[1..kTOT_CLASS] OF STRING; newList: ARRAY[1..kTOT_CLASS] OF STRING; ???The remaining errors are only due to the pseudo-code. Put in your specifics and it should compile. ???One thing to note when a compiler kicks an error, sometimes the error is on the immediately preceding line. If you can't find an error on the one reported, look at the previous one. Raymond
  23. VW does not have a setting for LINECAPS. Would that it did. I control all of my linecaps outside of VW, but this is not a viable solution for the masses and requires a LOT of forethought when trying to draft with multiple trimmings on the ends of Lines, Arcs, Polylines and Polygons. File a WISH. It's a major shortcoming of minor feature that should have been implemented long ago. While you are waiting, you might try to script a solution, or pay someone to do it for you, that will convert centerlines to outlines. Good luck. Raymond
  24. Yes, Reshaper is written in VectorScript for Vectorworks, so it will work (should work) on both Mac and Windows platforms equally. That has been one of the challenges in its development, to make it work the same on both as there are minor differences in the way VS performs on the two machines (mostly in the Modern Dialog calls). The sad thing is when I get it right, nobody notices. :-p If you'd like to try it, send me the last 6 digits of your VW serial number and I'll send you a copy and a DEMO KEY that will enable Reshaper for 30 days. Also, tell me what version of the software you want it for. From your signature I'd guess you'd want it for VW 2009, but I have versions of Reshaper working from VW 11 to VW 15 (2010). Raymond PS - Oh yeah, an address might help. info@siriussolutions.net
  25. Hi Brian, ???Set the page size with the Page Setup menu under the File menu. Raymond
×
×
  • Create New...